From 2db19e3f2a26b5d0b6e7201349bb17cdfbc8c01b Mon Sep 17 00:00:00 2001 From: Kevin Harwell 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 3d8cd72..b43cf14 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);