Index: main/udptl.c =================================================================== --- main/udptl.c (revision 172437) +++ main/udptl.c (working copy) @@ -67,6 +67,9 @@ static int udptlfecspan; static int udptlmaxdatagram; +static char last_function[80]; +#define LLF ast_copy_string(last_function, __PRETTY_FUNCTION__, sizeof(last_function)) + #define LOCAL_FAX_MAX_DATAGRAM 400 #define MAX_FEC_ENTRIES 5 #define MAX_FEC_SPAN 5 @@ -143,6 +146,7 @@ static inline int udptl_debug_test_addr(struct sockaddr_in *addr) { + LLF; if (udptldebug == 0) return 0; if (udptldebugaddr.sin_addr.s_addr) { @@ -156,6 +160,7 @@ static int decode_length(uint8_t *buf, int limit, int *len, int *pvalue) { + LLF; if (*len >= limit) return -1; if ((buf[*len] & 0x80) == 0) { @@ -187,6 +192,7 @@ int i; const uint8_t **pbuf; + LLF; for (octet_idx = 0, *p_num_octets = 0; ; octet_idx += octet_cnt) { if ((stat = decode_length(buf, limit, len, &octet_cnt)) < 0) return -1; @@ -213,6 +219,7 @@ { int multiplier; + LLF; if (value < 0x80) { /* 1 octet */ buf[*len] = value; @@ -243,6 +250,7 @@ int octet_idx; uint8_t zero_byte; + LLF; /* If open type is of zero length, add a single zero byte (10.1) */ if (num_octets == 0) { zero_byte = 0; @@ -291,6 +299,7 @@ int entries; int ifp_no; + LLF; ptr = 0; ifp_no = 0; memset(&s->f[0], 0, sizeof(s->f[0])); @@ -317,10 +326,18 @@ if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0) return -1; for (i = 0; i < count; i++) { + if (total_count + i >= (sizeof(lengths) / sizeof(lengths[0]))) { + ast_log(LOG_ERROR, "Buffer overflow detected!\n"); + return -1; + } if ((stat = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0) return -1; } total_count += count; + if (total_count >= (sizeof(lengths) / sizeof(lengths[0]))) { + ast_log(LOG_ERROR, "Buffer overflow detected!\n"); + return -1; + } } while (stat2 > 0); /* Step through in reverse order, so we go oldest to newest */ @@ -329,6 +346,11 @@ /* This one wasn't seen before */ /* Decode the secondary IFP packet */ //fprintf(stderr, "Secondary %d, len %d\n", seq_no - i, lengths[i - 1]); + if (ifp_no >= 16) { + /* Heap corruption, not stack corruption */ + ast_log(LOG_ERROR, "Buffer overflow detected!\n"); + return -1; + } s->f[ifp_no].frametype = AST_FRAME_MODEM; s->f[ifp_no].subclass = AST_MODEM_T38; @@ -487,6 +509,7 @@ int limit; int high_tide; + LLF; seq = s->tx_seq_no & 0xFFFF; /* Map the sequence number to an entry in the circular buffer */ @@ -561,14 +584,29 @@ high_tide = 0; for (i = (limit - span*entries) & UDPTL_BUF_MASK; i != limit; i = (i + entries) & UDPTL_BUF_MASK) { if (high_tide < s->tx[i].buf_len) { - for (j = 0; j < high_tide; j++) - fec[j] ^= s->tx[i].buf[j]; - for ( ; j < s->tx[i].buf_len; j++) - fec[j] = s->tx[i].buf[j]; + for (j = 0; j < high_tide; j++) { + if (j < LOCAL_FAX_MAX_DATAGRAM) { + fec[j] ^= s->tx[i].buf[j]; + } else { + ast_log(LOG_WARNING, "Possible buffer overflow!\n"); + } + } + for ( ; j < s->tx[i].buf_len; j++) { + if (j < LOCAL_FAX_MAX_DATAGRAM) { + fec[j] = s->tx[i].buf[j]; + } else { + ast_log(LOG_WARNING, "Possible buffer overflow!\n"); + } + } high_tide = s->tx[i].buf_len; } else { - for (j = 0; j < s->tx[i].buf_len; j++) - fec[j] ^= s->tx[i].buf[j]; + for (j = 0; j < s->tx[i].buf_len; j++) { + if (j < LOCAL_FAX_MAX_DATAGRAM) { + fec[j] ^= s->tx[i].buf[j]; + } else { + ast_log(LOG_WARNING, "Possible buffer overflow!\n"); + } + } } } if (encode_open_type(buf, &len, fec, high_tide) < 0) @@ -609,6 +647,7 @@ struct ast_udptl *udptl = cbdata; struct ast_frame *f; + LLF; if ((f = ast_udptl_read(udptl))) { if (udptl->callback) udptl->callback(udptl, f, udptl->data); @@ -626,6 +665,7 @@ len = sizeof(sin); + LLF; /* Cache where the header will go */ res = recvfrom(udptl->fd, udptl->rawdata + AST_FRIENDLY_OFFSET, @@ -749,6 +789,7 @@ int i; long int flags; + LLF; if (!(udptl = ast_calloc(1, sizeof(*udptl)))) return NULL; @@ -820,6 +861,7 @@ struct ast_udptl *ast_udptl_new(struct sched_context *sched, struct io_context *io, int callbackmode) { struct in_addr ia; + LLF; memset(&ia, 0, sizeof(ia)); return ast_udptl_new_with_bindaddr(sched, io, callbackmode, ia); } @@ -828,6 +870,7 @@ { int res; + LLF; if ((res = setsockopt(udptl->fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) ast_log(LOG_WARNING, "UDPTL unable to set TOS to %d\n", tos); return res; @@ -874,6 +917,7 @@ int res; uint8_t buf[LOCAL_FAX_MAX_DATAGRAM]; + LLF; /* If we have no peer, return immediately */ if (s->them.sin_addr.s_addr == INADDR_ANY) return 0; @@ -975,6 +1019,7 @@ void *pvt1; int to; + LLF; ast_channel_lock(c0); while (ast_channel_trylock(c1)) { ast_channel_unlock(c0); @@ -1176,6 +1221,7 @@ udptlfecspan = 0; udptlmaxdatagram = 0; + LLF; if ((cfg = ast_config_load("udptl.conf"))) { if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) { udptlstart = atoi(s);