Index: main/udptl.c =================================================================== --- main/udptl.c (revision 172437) +++ main/udptl.c (working copy) @@ -139,7 +139,7 @@ static struct ast_udptl_protocol *protos; static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len); -static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, int ifp_len); +static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, int buflen, uint8_t *ifp, int ifp_len); static inline int udptl_debug_test_addr(struct sockaddr_in *addr) { @@ -237,7 +237,7 @@ } /*- End of function --------------------------------------------------------*/ -static int encode_open_type(uint8_t *buf, int *len, const uint8_t *data, int num_octets) +static int encode_open_type(uint8_t *buf, int buflen, int *len, const uint8_t *data, int num_octets) { int enclen; int octet_idx; @@ -253,6 +253,10 @@ for (octet_idx = 0; ; num_octets -= enclen, octet_idx += enclen) { if ((enclen = encode_length(buf, len, num_octets)) < 0) return -1; + if (enclen + *len > buflen) { + ast_log(LOG_ERROR, "Buffer overflow detected (%d + %d > %d)\n", enclen, *len, buflen); + return -1; + } if (enclen > 0) { memcpy(&buf[*len], &data[octet_idx], enclen); *len += enclen; @@ -473,9 +477,9 @@ } /*- End of function --------------------------------------------------------*/ -static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, int ifp_len) +static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, int buflen, uint8_t *ifp, int ifp_len) { - uint8_t fec[LOCAL_FAX_MAX_DATAGRAM]; + uint8_t fec[LOCAL_FAX_MAX_DATAGRAM * 2]; int i; int j; int seq; @@ -505,7 +509,7 @@ buf[len++] = seq & 0xFF; /* Encode the primary IFP packet */ - if (encode_open_type(buf, &len, ifp, ifp_len) < 0) + if (encode_open_type(buf, buflen, &len, ifp, ifp_len) < 0) return -1; /* Encode the appropriate type of error recovery information */ @@ -533,8 +537,12 @@ /* Encode the elements */ for (i = 0; i < entries; i++) { j = (entry - i - 1) & UDPTL_BUF_MASK; - if (encode_open_type(buf, &len, s->tx[j].buf, s->tx[j].buf_len) < 0) + if (encode_open_type(buf, buflen, &len, s->tx[j].buf, s->tx[j].buf_len) < 0) { + if (option_debug) { + ast_log(LOG_DEBUG, "Encoding failed at i=%d, j=%d\n", i, j); + } return -1; + } } break; case UDPTL_ERROR_CORRECTION_FEC: @@ -571,7 +579,7 @@ fec[j] ^= s->tx[i].buf[j]; } } - if (encode_open_type(buf, &len, fec, high_tide) < 0) + if (encode_open_type(buf, buflen, &len, fec, high_tide) < 0) return -1; } break; @@ -872,7 +880,7 @@ int seq; int len; int res; - uint8_t buf[LOCAL_FAX_MAX_DATAGRAM]; + uint8_t buf[LOCAL_FAX_MAX_DATAGRAM * 2]; /* If we have no peer, return immediately */ if (s->them.sin_addr.s_addr == INADDR_ANY) @@ -891,7 +899,7 @@ seq = s->tx_seq_no & 0xFFFF; /* Cook up the UDPTL packet, with the relevant EC info. */ - len = udptl_build_packet(s, buf, f->data, f->datalen); + len = udptl_build_packet(s, buf, sizeof(buf), f->data, f->datalen); if (len > 0 && s->them.sin_port && s->them.sin_addr.s_addr) { if ((res = sendto(s->fd, buf, len, 0, (struct sockaddr *) &s->them, sizeof(s->them))) < 0)