aboutsummaryrefslogtreecommitdiffstats
path: root/main/udptl.c
diff options
context:
space:
mode:
authortilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2009-02-12 21:25:14 +0000
committertilghman <tilghman@f38db490-d61c-443f-a65b-d21fe96a405b>2009-02-12 21:25:14 +0000
commit7a733c01fc946447ddab2198fb2817249e1ac7f2 (patch)
treefb68aad7df409dcfe5f5b7492dad19603ead52a4 /main/udptl.c
parent1e73e209dfc7d075bd7ed41986e5dab3c318a5a8 (diff)
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/trunk@175334 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/udptl.c')
-rw-r--r--main/udptl.c74
1 files changed, 51 insertions, 23 deletions
diff --git a/main/udptl.c b/main/udptl.c
index 9c64d06d4..478ce8f5f 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.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 ((res = sendto(s->fd, buf, len, 0, (struct sockaddr *) &s->them, sizeof(s->them))) < 0)
@@ -1175,17 +1183,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
@@ -1206,24 +1222,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);
}