Package: asterisk / 1:1.6.2.9-2+squeeze12

AST-2012-007 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
From 69d64225c1edc7cdaff5bdd1981ad06bd4ee08d1 Mon Sep 17 00:00:00 2001
From: Richard Mudgett <rmudgett@digium.com>
Date: Fri, 25 May 2012 16:28:04 +0000
Subject: Fix IAX receiving HOLD without suggested MOH class crash.
Bug: https://issues.asterisk.org/jira/browse/ASTERISK-19597
Origin: http://svnview.digium.com/svn/asterisk?view=rev&rev=367781
CVE: CVE-2012-2947

A remotely exploitable crash vulnerability exists in the IAX2 channel
driver if an established call is placed on hold without a suggested
music class. For this to occur, the following must take place:

1. The setting mohinterpret=passthrough must be set on the end placing
   the call on hold.
2. A call must be established.
3. The call is placed on hold without a suggested music-on-hold class name.

When these conditions are true, Asterisk will attempt to use an invalid
pointer to a music-on-hold class name. Use of the invalid pointer will
either cause a crash or the music-on-hold class name will be garbage.

A music-on-hold class is created in the default configuration if proper
sound files exist in /usr/share/asterisk/moh . As of Wheezy the package
also Recommends a set of such sound files.

Patch copied as-is from branch 1.8.

---
 channels/chan_iax2.c |   30 ++++++++++++++++++++----------
 1 file changed, 20 insertions(+), 10 deletions(-)

diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 869fc84..e76979d 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -1842,24 +1842,25 @@ static void send_signaling(struct chan_iax2_pvt *pvt)
  *  we have received a destination call number. */
 static int queue_signalling(struct chan_iax2_pvt *pvt, struct ast_frame *f)
 {
-	struct signaling_queue_entry *new;
+	struct signaling_queue_entry *qe;
 
 	if (f->frametype == AST_FRAME_IAX || !pvt->hold_signaling) {
 		return 1; /* do not queue this frame */
-	} else if (!(new = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
+	} else if (!(qe = ast_calloc(1, sizeof(struct signaling_queue_entry)))) {
 		return -1;  /* out of memory */
 	}
 
-	memcpy(&new->f, f, sizeof(new->f)); /* copy ast_frame into our queue entry */
-
-	if (new->f.datalen) { /* if there is data in this frame copy it over as well */
-		if (!(new->f.data.ptr = ast_calloc(1, new->f.datalen))) {
-			free_signaling_queue_entry(new);
+	/* copy ast_frame into our queue entry */
+	qe->f = *f;
+	if (qe->f.datalen) {
+		/* if there is data in this frame copy it over as well */
+		if (!(qe->f.data.ptr = ast_malloc(qe->f.datalen))) {
+			free_signaling_queue_entry(qe);
 			return -1;
 		}
-		memcpy(new->f.data.ptr, f->data.ptr, sizeof(*new->f.data.ptr));
+		memcpy(qe->f.data.ptr, f->data.ptr, qe->f.datalen);
 	}
-	AST_LIST_INSERT_TAIL(&pvt->signaling_queue, new, next);
+	AST_LIST_INSERT_TAIL(&pvt->signaling_queue, qe, next);
 
 	return 0;
 }
@@ -4160,7 +4161,16 @@ static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtr
 	int needfree = 0;
 	struct ast_channel *owner = NULL;
 	struct ast_channel *bridge = NULL;
-	
+
+	/*
+	 * Clear fr->af.data if there is no data in the buffer.  Things
+	 * like AST_CONTROL_HOLD without a suggested music class must
+	 * have a NULL pointer.
+	 */
+	if (!fr->af.datalen) {
+		memset(&fr->af.data, 0, sizeof(fr->af.data));
+	}
+
 	/* Attempt to recover wrapped timestamps */
 	unwrap_timestamp(fr);
 
-- 
1.7.10