diff options
author | mnicholson <mnicholson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2011-02-21 14:57:15 +0000 |
---|---|---|
committer | mnicholson <mnicholson@f38db490-d61c-443f-a65b-d21fe96a405b> | 2011-02-21 14:57:15 +0000 |
commit | 9047761bc3e0c9b18021cdf66f1582634f6933a1 (patch) | |
tree | 03462d4cf103630ab9bdf547fec5f9cfb47efef3 | |
parent | a4f43315b16ab05abd2930f8ef94f667d0da1df5 (diff) |
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: http://svn.digium.com/svn/asterisk/branches/1.4@308413 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r-- | main/udptl.c | 49 |
1 files changed, 23 insertions, 26 deletions
diff --git a/main/udptl.c b/main/udptl.c index b25f8f46d..fc1f2ccd1 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 */ |