From 2e714923c39d6abcd6f67c4c8a4f456548f54d54 Mon Sep 17 00:00:00 2001 From: Matthew Nicholson Date: Mon, 21 Feb 2011 14:57:15 +0000 Subject: [PATCH] Properly check the bounds of arrays when decoding UDPTL packets. Also, remove broken support for receiving UDPTL packets larger than 16k. That shouldn't ever happen anyway. AST-2011-002 FAX-281 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.4@308413 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- main/udptl.c | 49 +++++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 26 deletions(-) diff --git a/main/udptl.c b/main/udptl.c index b25f8f46d0..fc1f2ccd15 100644 --- a/main/udptl.c +++ b/main/udptl.c @@ -173,37 +173,31 @@ static int decode_length(uint8_t *buf, int limit, int *len, int *pvalue) } *pvalue = (buf[*len] & 0x3F) << 14; (*len)++; - /* Indicate we have a fragment */ + /* We have a fragment. Currently we don't process fragments. */ + if (option_debug) { + ast_log(LOG_DEBUG, "UDPTL packet with length greater than 16K received, decoding will fail\n"); + } return 1; } /*- End of function --------------------------------------------------------*/ static int decode_open_type(uint8_t *buf, int limit, int *len, const uint8_t **p_object, int *p_num_octets) { - int octet_cnt; - int octet_idx; - int stat; - int i; - const uint8_t **pbuf; + int octet_cnt = 0; - for (octet_idx = 0, *p_num_octets = 0; ; octet_idx += octet_cnt) { - if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0) - return -1; - if (octet_cnt > 0) { - *p_num_octets += octet_cnt; + if (decode_length(buf, limit, len, &octet_cnt) != 0) + return -1; - pbuf = &p_object[octet_idx]; - i = 0; - /* Make sure the buffer contains at least the number of bits requested */ - if ((*len + octet_cnt) > limit) - return -1; + if (octet_cnt > 0) { + /* Make sure the buffer contains at least the number of bits requested */ + if ((*len + octet_cnt) > limit) + return -1; - *pbuf = &buf[*len]; - *len += octet_cnt; - } - if (stat == 0) - break; + *p_num_octets = octet_cnt; + *p_object = &buf[*len]; + *len += octet_cnt; } + return 0; } /*- End of function --------------------------------------------------------*/ @@ -288,8 +282,8 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len) const uint8_t *data; int ifp_len; int repaired[16]; - const uint8_t *bufs[16]; - int lengths[16]; + const uint8_t *bufs[ARRAY_LEN(s->f) - 1]; + int lengths[ARRAY_LEN(s->f) - 1]; int span; int entries; int ifp_no; @@ -319,13 +313,13 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len) do { if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0) return -1; - for (i = 0; i < count; i++) { + for (i = 0; i < count && total_count + i < ARRAY_LEN(bufs); i++) { if ((stat = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0) return -1; } - total_count += count; + total_count += i; } - while (stat2 > 0); + while (stat2 > 0 && total_count < ARRAY_LEN(bufs)); /* Step through in reverse order, so we go oldest to newest */ for (i = total_count; i > 0; i--) { if (seq_no - i >= s->rx_seq_no) { @@ -388,6 +382,9 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len) if (ptr + 1 > len) return -1; entries = buf[ptr++]; + if (entries > MAX_FEC_ENTRIES) { + return -1; + } s->rx[x].fec_entries = entries; /* Decode the elements */ -- 2.47.2