aboutsummaryrefslogtreecommitdiffstats
path: root/main
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2009-02-12 21:27:58 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2009-02-12 21:27:58 +0000
commit5d3e00aa845bee679c34100b3300d8026c90bbc0 (patch)
treee72406058524c4b48d83843b218d3033426f5d1d /main
parent685e6ddf9fe0b1fea27458787ac3d6885d87e1dd (diff)
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: http://svn.digium.com/svn/asterisk/branches/1.6.0@175347 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main')
-rw-r--r--main/udptl.c74
1 files changed, 51 insertions, 23 deletions
diff --git a/main/udptl.c b/main/udptl.c
index 6bfcf47b8..5e8198401 100644
--- a/main/udptl.c
+++ b/main/udptl.c
@@ -86,7 +86,7 @@ static int udptlfecentries;
static int udptlfecspan;
static int udptlmaxdatagram;
-#define LOCAL_FAX_MAX_DATAGRAM 400
+#define LOCAL_FAX_MAX_DATAGRAM 1400
#define MAX_FEC_ENTRIES 5
#define MAX_FEC_SPAN 5
@@ -159,7 +159,7 @@ struct ast_udptl {
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_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)
{
@@ -257,7 +257,7 @@ static int encode_length(uint8_t *buf, int *len, int value)
}
/*- 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;
@@ -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) {
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;
@@ -493,9 +497,9 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, int len)
}
/*- 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;
@@ -525,7 +529,7 @@ static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, i
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 */
@@ -553,8 +557,12 @@ static int udptl_build_packet(struct ast_udptl *s, uint8_t *buf, uint8_t *ifp, i
/* 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:
@@ -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];
}
}
- if (encode_open_type(buf, &len, fec, high_tide) < 0)
+ if (encode_open_type(buf, buflen, &len, fec, high_tide) < 0)
return -1;
}
break;
@@ -888,7 +896,7 @@ int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f)
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)
@@ -907,7 +915,7 @@ int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f)
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)
@@ -1234,17 +1242,25 @@ static void __ast_udptl_reload(int reload)
if (cfg) {
if ((s = ast_variable_retrieve(cfg, "general", "udptlstart"))) {
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;
- if (udptlstart > 65535)
+ }
+ if (udptlstart > 65535) {
+ ast_log(LOG_WARNING, "Ports over 65535 are invalid.\n");
udptlstart = 65535;
+ }
}
if ((s = ast_variable_retrieve(cfg, "general", "udptlend"))) {
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;
- if (udptlend > 65535)
+ }
+ if (udptlend > 65535) {
+ ast_log(LOG_WARNING, "Ports over 65535 are invalid.\n");
udptlend = 65535;
+ }
}
if ((s = ast_variable_retrieve(cfg, "general", "udptlchecksums"))) {
#ifdef SO_NO_CHECK
@@ -1265,24 +1281,36 @@ static void __ast_udptl_reload(int reload)
}
if ((s = ast_variable_retrieve(cfg, "general", "T38FaxMaxDatagram"))) {
udptlmaxdatagram = atoi(s);
- if (udptlmaxdatagram < 0)
- udptlmaxdatagram = 0;
- if (udptlmaxdatagram > LOCAL_FAX_MAX_DATAGRAM)
+ if (udptlmaxdatagram < 100) {
+ ast_log(LOG_WARNING, "Too small T38FaxMaxDatagram size. Defaulting to 100.\n");
+ 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;
+ }
}
if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECentries"))) {
udptlfecentries = atoi(s);
- if (udptlfecentries < 0)
- udptlfecentries = 0;
- if (udptlfecentries > MAX_FEC_ENTRIES)
+ if (udptlfecentries < 1) {
+ ast_log(LOG_WARNING, "Too small UDPTLFECentries value. Defaulting to 1.\n");
+ 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;
+ }
}
if ((s = ast_variable_retrieve(cfg, "general", "UDPTLFECspan"))) {
udptlfecspan = atoi(s);
- if (udptlfecspan < 0)
- udptlfecspan = 0;
- if (udptlfecspan > MAX_FEC_SPAN)
+ if (udptlfecspan < 1) {
+ ast_log(LOG_WARNING, "Too small UDPTLFECspan value. Defaulting to 1.\n");
+ 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;
+ }
}
ast_config_destroy(cfg);
}