aboutsummaryrefslogtreecommitdiffstats
path: root/main/asterisk/CVE-2021-32558.patch
blob: 522d8d6f4ff78001a0e28a61ddd6aa55815e8c1e (plain)
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
From 852a8780cb45db0dca7c18b364cb0485a1e09840 Mon Sep 17 00:00:00 2001
From: Kevin Harwell <kharwell@sangoma.com>
Date: Mon, 10 May 2021 17:59:00 -0500
Subject: [PATCH] AST-2021-008 - chan_iax2: remote crash on unsupported media format

If chan_iax2 received a packet with an unsupported media format, for
example vp9, then it would set the frame's format to NULL. This could
then result in a crash later when an attempt was made to access the
format.

This patch makes it so chan_iax2 now ignores/drops frames received
with unsupported media format types.

ASTERISK-29392 #close

Change-Id: Ifa869a90dafe33eed8fd9463574fe6f1c0ad3eb1
---

diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 4122c04..c57434b 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -4132,6 +4132,7 @@
 	long ms;
 	long next;
 	struct timeval now = ast_tvnow();
+	struct ast_format *voicefmt;
 
 	/* Make sure we have a valid private structure before going on */
 	ast_mutex_lock(&iaxsl[callno]);
@@ -4151,10 +4152,9 @@
 
 	ms = ast_tvdiff_ms(now, pvt->rxcore);
 
-	if(ms >= (next = jb_next(pvt->jb))) {
-		struct ast_format *voicefmt;
-		voicefmt = ast_format_compatibility_bitfield2format(pvt->voiceformat);
-		ret = jb_get(pvt->jb, &frame, ms, voicefmt ? ast_format_get_default_ms(voicefmt) : 20);
+	voicefmt = ast_format_compatibility_bitfield2format(pvt->voiceformat);
+	if (voicefmt && ms >= (next = jb_next(pvt->jb))) {
+		ret = jb_get(pvt->jb, &frame, ms, ast_format_get_default_ms(voicefmt));
 		switch(ret) {
 		case JB_OK:
 			fr = frame.data;
@@ -4182,7 +4182,7 @@
 				pvt = iaxs[callno];
 			}
 		}
-			break;
+		break;
 		case JB_DROP:
 			iax2_frame_free(frame.data);
 			break;
@@ -6451,8 +6451,14 @@
 		f->frametype = fh->type;
 		if (f->frametype == AST_FRAME_VIDEO) {
 			f->subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1));
+			if (!f->subclass.format) {
+				f->subclass.format = ast_format_none;
+			}
 		} else if (f->frametype == AST_FRAME_VOICE) {
 			f->subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub));
+			if (!f->subclass.format) {
+				f->subclass.format = ast_format_none;
+			}
 		} else {
 			f->subclass.integer = uncompress_subclass(fh->csub);
 		}
@@ -9929,8 +9935,8 @@
 		} else if (iaxs[fr->callno]->voiceformat == 0) {
 			ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
 			iax2_vnak(fr->callno);
-		} else {
-			f.subclass.format = ast_format_compatibility_bitfield2format(iaxs[fr->callno]->voiceformat);
+		} else if ((f.subclass.format = ast_format_compatibility_bitfield2format(
+						iaxs[fr->callno]->voiceformat))) {
 			f.datalen = len;
 			if (f.datalen >= 0) {
 				if (f.datalen)
@@ -10173,11 +10179,17 @@
 		f.frametype = fh->type;
 		if (f.frametype == AST_FRAME_VIDEO) {
 			f.subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub & ~0x40));
+			if (!f.subclass.format) {
+				return 1;
+			}
 			if ((fh->csub >> 6) & 0x1) {
 				f.subclass.frame_ending = 1;
 			}
 		} else if (f.frametype == AST_FRAME_VOICE) {
 			f.subclass.format = ast_format_compatibility_bitfield2format(uncompress_subclass(fh->csub));
+			if (!f.subclass.format) {
+				return 1;
+			}
 		} else {
 			f.subclass.integer = uncompress_subclass(fh->csub);
 		}
@@ -11795,6 +11807,11 @@
 				f.subclass.frame_ending = 1;
 			}
 			f.subclass.format = ast_format_compatibility_bitfield2format(iaxs[fr->callno]->videoformat);
+			if (!f.subclass.format) {
+				ast_variables_destroy(ies.vars);
+				ast_mutex_unlock(&iaxsl[fr->callno]);
+				return 1;
+			}
 		} else {
 			ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
 			iax2_vnak(fr->callno);
@@ -11816,9 +11833,14 @@
 	} else {
 		/* A mini frame */
 		f.frametype = AST_FRAME_VOICE;
-		if (iaxs[fr->callno]->voiceformat > 0)
+		if (iaxs[fr->callno]->voiceformat > 0) {
 			f.subclass.format = ast_format_compatibility_bitfield2format(iaxs[fr->callno]->voiceformat);
-		else {
+			if (!f.subclass.format) {
+				ast_variables_destroy(ies.vars);
+				ast_mutex_unlock(&iaxsl[fr->callno]);
+				return 1;
+			}
+		} else {
 			ast_debug(1, "Received mini frame before first full voice frame\n");
 			iax2_vnak(fr->callno);
 			ast_variables_destroy(ies.vars);