From cad2e582067efca4a9b7b5a76f8350553844fea0 Mon Sep 17 00:00:00 2001 From: Michael Jerris Date: Sat, 10 May 2008 21:10:44 +0000 Subject: [PATCH] catch buffer overflow from invalid stun packet. git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@8354 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_stun.h | 2 +- src/switch_rtp.c | 4 +++- src/switch_stun.c | 7 +++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/include/switch_stun.h b/src/include/switch_stun.h index a4f2100996..874bce79f3 100644 --- a/src/include/switch_stun.h +++ b/src/include/switch_stun.h @@ -221,7 +221,7 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, \param attribute the pointer to increment \return true or false depending on if there are any more attributes */ -#define switch_stun_packet_next_attribute(attribute) (attribute = (switch_stun_packet_attribute_t *) (attribute->value + attribute->length)) && attribute->length +#define switch_stun_packet_next_attribute(attribute, end) (attribute && (attribute = (switch_stun_packet_attribute_t *) (attribute->value + attribute->length)) && ((void *)attribute < end) && attribute->length && ((void *)(attribute + attribute->length) < end)) /*! \brief Obtain the correct length in bytes of a stun packet diff --git a/src/switch_rtp.c b/src/switch_rtp.c index b1e8d660b0..1810d54396 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -238,6 +238,7 @@ static void handle_ice(switch_rtp_t *rtp_session, void *data, switch_size_t len) { switch_stun_packet_t *packet; switch_stun_packet_attribute_t *attr; + void *end_buf; char username[33] = { 0 }; unsigned char buf[512] = { 0 }; switch_size_t cpylen = len; @@ -260,6 +261,7 @@ static void handle_ice(switch_rtp_t *rtp_session, void *data, switch_size_t len) memcpy(buf, data, cpylen); packet = switch_stun_packet_parse(buf, sizeof(buf)); + end_buf = buf + sizeof(buf); rtp_session->last_stun = switch_time_now(); switch_stun_packet_first_attribute(packet, attr); @@ -279,7 +281,7 @@ static void handle_ice(switch_rtp_t *rtp_session, void *data, switch_size_t len) } break; } - } while (switch_stun_packet_next_attribute(attr)); + } while (switch_stun_packet_next_attribute(attr, end_buf)); if ((packet->header.type == SWITCH_STUN_BINDING_REQUEST) && !strcmp(rtp_session->user_ice, username)) { uint8_t stunbuf[512]; diff --git a/src/switch_stun.c b/src/switch_stun.c index d1be4f5f06..3a8bf9b75a 100644 --- a/src/switch_stun.c +++ b/src/switch_stun.c @@ -117,6 +117,7 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_parse(uint8_t * buf, u { switch_stun_packet_t *packet; switch_stun_packet_attribute_t *attr; + void *end_buf = buf + len; if (len < SWITCH_STUN_PACKET_MIN_LEN) { return NULL; @@ -141,7 +142,7 @@ SWITCH_DECLARE(switch_stun_packet_t *) switch_stun_packet_parse(uint8_t * buf, u } break; } - } while (switch_stun_packet_next_attribute(attr)); + } while (switch_stun_packet_next_attribute(attr, end_buf)); return packet; } @@ -273,6 +274,7 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, switch_sockaddr_t *local_addr = NULL, *remote_addr = NULL, *from_addr = NULL; switch_socket_t *sock = NULL; uint8_t buf[256] = { 0 }; + void *end_buf; switch_stun_packet_t *packet; switch_stun_packet_attribute_t *attr; switch_size_t bytes = 0; @@ -335,6 +337,7 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, switch_socket_close(sock); packet = switch_stun_packet_parse(buf, sizeof(buf)); + end_buf = buf + sizeof(buf); switch_stun_packet_first_attribute(packet, attr); do { @@ -350,7 +353,7 @@ SWITCH_DECLARE(switch_status_t) switch_stun_lookup(char **ip, } break; } - } while (switch_stun_packet_next_attribute(attr)); + } while (switch_stun_packet_next_attribute(attr, end_buf)); if (packet->header.type == SWITCH_STUN_BINDING_RESPONSE) { *ip = switch_core_strdup(pool, rip);