Merged revisions 175334 via svnmerge from

https://origsvn.digium.com/svn/asterisk/trunk

................
  r175334 | tilghman | 2009-02-12 15:25:14 -0600 (Thu, 12 Feb 2009) | 16 lines
  
  Merged revisions 175311 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r175311 | tilghman | 2009-02-12 15:19:40 -0600 (Thu, 12 Feb 2009) | 9 lines
    
    Fix crashes when receiving certain T.38 packets.  Also, increase the maximum
    size of T.38 packets and warn users when they try to set the limits above those
    maximums.
    (closes issue #13050)
     Reported by: schern
     Patches: 
           20090212__bug13050.diff.txt uploaded by Corydon76 (license 14)
     Tested by: schern
  ........
................


git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.6.1@175342 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Tilghman Lesher
2009-02-12 21:27:03 +00:00
parent ab4aba0fb5
commit 051dab14b2

View File

@@ -86,7 +86,7 @@ static int udptlfecentries;
static int udptlfecspan; static int udptlfecspan;
static int udptlmaxdatagram; static int udptlmaxdatagram;
#define LOCAL_FAX_MAX_DATAGRAM 400 #define LOCAL_FAX_MAX_DATAGRAM 1400
#define MAX_FEC_ENTRIES 5 #define MAX_FEC_ENTRIES 5
#define MAX_FEC_SPAN 5 #define MAX_FEC_SPAN 5
@@ -159,7 +159,7 @@ struct ast_udptl {
static AST_RWLIST_HEAD_STATIC(protos, ast_udptl_protocol); static AST_RWLIST_HEAD_STATIC(protos, ast_udptl_protocol);
static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len); 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) static inline int udptl_debug_test_addr(struct sockaddr_in *addr)
{ {
@@ -257,7 +257,7 @@ static int encode_length(uint8_t *buf, int *len, int value)
} }
/*- End of function --------------------------------------------------------*/ /*- 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 enclen;
int octet_idx; int octet_idx;
@@ -273,6 +273,10 @@ static int encode_open_type(uint8_t *buf, int *len, const uint8_t *data, int num
for (octet_idx = 0; ; num_octets -= enclen, octet_idx += enclen) { for (octet_idx = 0; ; num_octets -= enclen, octet_idx += enclen) {
if ((enclen = encode_length(buf, len, num_octets)) < 0) if ((enclen = encode_length(buf, len, num_octets)) < 0)
return -1; 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) { if (enclen > 0) {
memcpy(&buf[*len], &data[octet_idx], enclen); memcpy(&buf[*len], &data[octet_idx], enclen);
*len += enclen; *len += enclen;
@@ -493,9 +497,9 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len)
} }
/*- End of function --------------------------------------------------------*/ /*- 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 i;
int j; int j;
int seq; int seq;
@@ -525,7 +529,7 @@ static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, i
buf[len++] = seq & 0xFF; buf[len++] = seq & 0xFF;
/* Encode the primary IFP packet */ /* 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; return -1;
/* Encode the appropriate type of error recovery information */ /* Encode the appropriate type of error recovery information */
@@ -553,8 +557,12 @@ static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, i
/* Encode the elements */ /* Encode the elements */
for (i = 0; i < entries; i++) { for (i = 0; i < entries; i++) {
j = (entry - i - 1) & UDPTL_BUF_MASK; 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; return -1;
}
} }
break; break;
case UDPTL_ERROR_CORRECTION_FEC: case UDPTL_ERROR_CORRECTION_FEC:
@@ -591,7 +599,7 @@ static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, i
fec[j] ^= s->tx[i].buf[j]; 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; return -1;
} }
break; break;
@@ -888,7 +896,7 @@ int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f)
int seq; int seq;
int len; int len;
int res; 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 we have no peer, return immediately */
if (s->them.sin_addr.s_addr == INADDR_ANY) if (s->them.sin_addr.s_addr == INADDR_ANY)
@@ -907,7 +915,7 @@ int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f)
seq = s->tx_seq_no & 0xFFFF; seq = s->tx_seq_no & 0xFFFF;
/* Cook up the UDPTL packet, with the relevant EC info. */ /* Cook up the UDPTL packet, with the relevant EC info. */
len = udptl_build_packet(s, buf, f->data.ptr, f->datalen); len = udptl_build_packet(s, buf, sizeof(buf), f->data.ptr, f->datalen);
if (len > 0 && s->them.sin_port && s->them.sin_addr.s_addr) { 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) if ((res = sendto(s->fd, buf, len, 0, (struct sockaddr *) &s->them, sizeof(s->them))) < 0)
@@ -1234,17 +1242,25 @@ static void __ast_udptl_reload(int reload)
if (cfg) { if (cfg) {
if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) { if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) {
udptlstart = atoi(s); udptlstart = atoi(s);
if (udptlstart < 1024) if (udptlstart < 1024) {
ast_log(LOG_WARNING, "Ports under 1024 are not allowed for T.38.\n");
udptlstart = 1024; udptlstart = 1024;
if (udptlstart > 65535) }
if (udptlstart > 65535) {
ast_log(LOG_WARNING, "Ports over 65535 are invalid.\n");
udptlstart = 65535; udptlstart = 65535;
}
} }
if ((s = ast_variable_retrieve(cfg, "general", "udptlend"))) { if ((s = ast_variable_retrieve(cfg, "general", "udptlend"))) {
udptlend = atoi(s); udptlend = atoi(s);
if (udptlend < 1024) if (udptlend < 1024) {
ast_log(LOG_WARNING, "Ports under 1024 are not allowed for T.38.\n");
udptlend = 1024; udptlend = 1024;
if (udptlend > 65535) }
if (udptlend > 65535) {
ast_log(LOG_WARNING, "Ports over 65535 are invalid.\n");
udptlend = 65535; udptlend = 65535;
}
} }
if ((s = ast_variable_retrieve(cfg, "general", "udptlchecksums"))) { if ((s = ast_variable_retrieve(cfg, "general", "udptlchecksums"))) {
#ifdef SO_NO_CHECK #ifdef SO_NO_CHECK
@@ -1265,24 +1281,36 @@ static void __ast_udptl_reload(int reload)
} }
if ((s = ast_variable_retrieve(cfg, "general", "T38FaxMaxDatagram"))) { if ((s = ast_variable_retrieve(cfg, "general", "T38FaxMaxDatagram"))) {
udptlmaxdatagram = atoi(s); udptlmaxdatagram = atoi(s);
if (udptlmaxdatagram < 0) if (udptlmaxdatagram < 100) {
udptlmaxdatagram = 0; ast_log(LOG_WARNING, "Too small T38FaxMaxDatagram size. Defaulting to 100.\n");
if (udptlmaxdatagram > LOCAL_FAX_MAX_DATAGRAM) udptlmaxdatagram = 100;
}
if (udptlmaxdatagram > LOCAL_FAX_MAX_DATAGRAM) {
ast_log(LOG_WARNING, "Too large T38FaxMaxDatagram size. Defaulting to %d.\n", LOCAL_FAX_MAX_DATAGRAM);
udptlmaxdatagram = LOCAL_FAX_MAX_DATAGRAM; udptlmaxdatagram = LOCAL_FAX_MAX_DATAGRAM;
}
} }
if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECentries"))) { if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECentries"))) {
udptlfecentries = atoi(s); udptlfecentries = atoi(s);
if (udptlfecentries < 0) if (udptlfecentries < 1) {
udptlfecentries = 0; ast_log(LOG_WARNING, "Too small UDPTLFECentries value. Defaulting to 1.\n");
if (udptlfecentries > MAX_FEC_ENTRIES) udptlfecentries = 1;
}
if (udptlfecentries > MAX_FEC_ENTRIES) {
ast_log(LOG_WARNING, "Too large UDPTLFECentries value. Defaulting to %d.\n", MAX_FEC_ENTRIES);
udptlfecentries = MAX_FEC_ENTRIES; udptlfecentries = MAX_FEC_ENTRIES;
}
} }
if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECspan"))) { if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECspan"))) {
udptlfecspan = atoi(s); udptlfecspan = atoi(s);
if (udptlfecspan < 0) if (udptlfecspan < 1) {
udptlfecspan = 0; ast_log(LOG_WARNING, "Too small UDPTLFECspan value. Defaulting to 1.\n");
if (udptlfecspan > MAX_FEC_SPAN) udptlfecspan = 1;
}
if (udptlfecspan > MAX_FEC_SPAN) {
ast_log(LOG_WARNING, "Too large UDPTLFECspan value. Defaulting to %d.\n", MAX_FEC_SPAN);
udptlfecspan = MAX_FEC_SPAN; udptlfecspan = MAX_FEC_SPAN;
}
} }
ast_config_destroy(cfg); ast_config_destroy(cfg);
} }