Package: asterisk / 1:1.6.2.9-2+squeeze12

AST-2011-002 Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
From: Leif Madsen <lmadsen@digium.com>
Date: Mon, 21 Feb 2011 18:34:23 +0000
Subject: Multiple array overflow and crash vulnerabilities in UDPTL code
Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=308507

When decoding UDPTL packets, multiple stack and heap based arrays can be
made to overflow by specially crafted packets. Systems doing T.38 pass
through or termination are vulnerable.

See also: http://downloads.asterisk.org/pub/security/AST-2011-002.html

---
 main/udptl.c |   48 +++++++++++++++++++++---------------------------
 1 files changed, 21 insertions(+), 27 deletions(-)

diff --git a/main/udptl.c b/main/udptl.c
index d120c27..eba362e 100644
--- a/main/udptl.c
+++ b/main/udptl.c
@@ -217,38 +217,29 @@ static int decode_length(uint8_t *buf, unsigned int limit, unsigned int *len, un
 	}
 	*pvalue = (buf[*len] & 0x3F) << 14;
 	(*len)++;
-	/* Indicate we have a fragment */
+	/* We have a fragment.  Currently we don't process fragments. */
+	ast_debug(1, "UDPTL packet with length greater than 16K received, decoding will fail\n");
 	return 1;
 }
 /*- End of function --------------------------------------------------------*/
 
 static int decode_open_type(uint8_t *buf, unsigned int limit, unsigned int *len, const uint8_t **p_object, unsigned int *p_num_octets)
 {
-	unsigned int octet_cnt;
-	unsigned int octet_idx;
-	unsigned int i;
-	int length; /* a negative length indicates the limit has been reached in decode_length. */
-	const uint8_t **pbuf;
+	unsigned int octet_cnt = 0;
 
-	for (octet_idx = 0, *p_num_octets = 0; ; octet_idx += octet_cnt) {
-		octet_cnt = 0;
-		if ((length = decode_length(buf, limit, len, &octet_cnt)) < 0)
-			return -1;
-		if (octet_cnt > 0) {
-			*p_num_octets += octet_cnt;
+	if (decode_length(buf, limit, len, &octet_cnt) != 0)
+		return -1;
 
-			pbuf = &p_object[octet_idx];
-			i = 0;
-			/* Make sure the buffer contains at least the number of bits requested */
-			if ((*len + octet_cnt) > limit)
-				return -1;
+	if (octet_cnt > 0) {
+		/* Make sure the buffer contains at least the number of bits requested */
+		if ((*len + octet_cnt) > limit)
+			return -1;
 
-			*pbuf = &buf[*len];
-			*len += octet_cnt;
-		}
-		if (length == 0)
-			break;
+		*p_num_octets = octet_cnt;
+		*p_object = &buf[*len];
+		*len += octet_cnt;
 	}
+
 	return 0;
 }
 /*- End of function --------------------------------------------------------*/
@@ -335,8 +326,8 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, unsigned int len)
 	const uint8_t *data;
 	unsigned int ifp_len;
 	int repaired[16];
-	const uint8_t *bufs[16];
-	unsigned int lengths[16];
+	const uint8_t *bufs[ARRAY_LEN(s->f) - 1];
+	unsigned int lengths[ARRAY_LEN(s->f) - 1];
 	int span;
 	int entries;
 	int ifp_no;
@@ -366,13 +357,13 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, unsigned int len)
 			do {
 				if ((stat2 = decode_length(buf, len, &ptr, &count)) < 0)
 					return -1;
-				for (i = 0; i < count; i++) {
+				for (i = 0; i < count && total_count + i < ARRAY_LEN(bufs); i++) {
 					if ((stat1 = decode_open_type(buf, len, &ptr, &bufs[total_count + i], &lengths[total_count + i])) != 0)
 						return -1;
 				}
-				total_count += count;
+				total_count += i;
 			}
-			while (stat2 > 0);
+			while (stat2 > 0 && total_count < ARRAY_LEN(bufs));
 			/* Step through in reverse order, so we go oldest to newest */
 			for (i = total_count; i > 0; i--) {
 				if (seq_no - i >= s->rx_seq_no) {
@@ -435,6 +426,9 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, unsigned int len)
 		if (ptr + 1 > len)
 			return -1;
 		entries = buf[ptr++];
+		if (entries > MAX_FEC_ENTRIES) {
+			return -1;
+		}
 		s->rx[x].fec_entries = entries;
 
 		/* Decode the elements */
-- 
1.7.2.3