aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormnicholson <mnicholson@f38db490-d61c-443f-a65b-d21fe96a405b>2011-02-21 14:57:15 +0000
committermnicholson <mnicholson@f38db490-d61c-443f-a65b-d21fe96a405b>2011-02-21 14:57:15 +0000
commit9047761bc3e0c9b18021cdf66f1582634f6933a1 (patch)
tree03462d4cf103630ab9bdf547fec5f9cfb47efef3
parenta4f43315b16ab05abd2930f8ef94f667d0da1df5 (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.c49
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 */