Skip to content

Commit de4e543

Browse files
andywolkticpu
authored andcommitted
[mod_opus] Sanitize frame size when parsing Opus packets.
1 parent 72827d0 commit de4e543

File tree

1 file changed

+17
-13
lines changed

1 file changed

+17
-13
lines changed

src/mod/codecs/mod_opus/opus_parse.c

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ static opus_int16 switch_opus_get_silk_frame_ms_per_flag(int16_t config, opus_in
9797
* for stereo : the mid frame VAD_flags and the LBRR_flag could be obtained
9898
* yet, to get the LBRR_flags of the mid frame the routine should be modified
9999
* to skip the side VAD flags and the side LBRR flag and to get the mid LBRR_symbol */
100-
static void switch_opus_get_VAD_LBRR_flags(const uint8_t *buf, opus_int16 silk_frame_nb_flags,
100+
static switch_bool_t switch_opus_get_VAD_LBRR_flags(const uint8_t *buf, opus_int16 buf_size, opus_int16 silk_frame_nb_flags,
101101
opus_int16 *VAD_flags, opus_int16 *LBRR_flags, opus_int16 *nb_VAD1, opus_int16 *nb_FEC)
102102
{
103103
const opus_int16 *ptr_pdf_cum;
@@ -109,6 +109,10 @@ static void switch_opus_get_VAD_LBRR_flags(const uint8_t *buf, opus_int16 silk_f
109109
opus_int16 nb_vad, nb_fec;
110110
int i;
111111

112+
if (buf_size <= 0) {
113+
return SWITCH_FALSE;
114+
}
115+
112116
nb_vad = 0;
113117
nb_fec = 0;
114118

@@ -143,6 +147,9 @@ static void switch_opus_get_VAD_LBRR_flags(const uint8_t *buf, opus_int16 silk_f
143147
if (silk_frame_nb_flags == 1) {
144148
LBRR_flags[0] = 1;
145149
nb_fec = 1;
150+
} else if (buf_size < 2) {
151+
/* not enough data in the buffer to get LBRR_symbol and LBRR_flags */
152+
return SWITCH_FALSE;
146153
} else { /* get LBRR_symbol then LBRR_flags */
147154
/* LBRR symbol is encoded with range encoder : range on 8 bits
148155
* silk_frame_nb_flags = 2 ; 3 possible values for LBRR_flags(1) | LBRR_flags(0))= 01, 10, 11
@@ -182,7 +189,7 @@ static void switch_opus_get_VAD_LBRR_flags(const uint8_t *buf, opus_int16 silk_f
182189
*nb_VAD1 = nb_vad;
183190
*nb_FEC = nb_fec;
184191

185-
return;
192+
return SWITCH_TRUE;
186193
}
187194

188195
/* Parse the packet to retrieve informations about its content
@@ -197,7 +204,7 @@ switch_bool_t switch_opus_packet_parse(const uint8_t *payload, int payload_lengt
197204
int16_t vad_flags_per_silk_frame, fec_flags_per_silk_frame;
198205
opus_int16 frame_sizes[48];
199206
const unsigned char *frame_data[48];
200-
opus_int16 packet_LBBR_FLAGS[3 * 48], packet_VAD_FLAGS[3 * 48];
207+
opus_int16 packet_LBBR_FLAGS[3 * 48] = { 0 }, packet_VAD_FLAGS[3 * 48] = { 0 };
201208
opus_int16 *ptr_LBBR_FLAGS, *ptr_VAD_FLAGS;
202209
opus_int16 silk_frame_nb_flags, silk_size_frame_ms_per_flag;
203210
opus_int16 silk_frame_nb_fec, silk_frame_nb_vad1;
@@ -276,14 +283,6 @@ switch_bool_t switch_opus_packet_parse(const uint8_t *payload, int payload_lengt
276283

277284
packet_info->ptime_ts = packet_info->frames * sample_per_frame;
278285

279-
if (frame_sizes[0] <= 1) {
280-
if (debug) {
281-
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "opus_packet_parse: opus_packet_parse frame size too small.\n");
282-
}
283-
284-
return SWITCH_FALSE;
285-
}
286-
287286
/* +---------------+-----------+-----------+-------------------+
288287
| Configuration | Mode | Bandwidth | Frame Sizes |
289288
| Number(s) | | | |
@@ -319,8 +318,11 @@ switch_bool_t switch_opus_packet_parse(const uint8_t *payload, int payload_lengt
319318
ptr_VAD_FLAGS = packet_VAD_FLAGS;
320319

321320
for (f = 0; f < packet_info->frames; f++) {
322-
switch_opus_get_VAD_LBRR_flags(frame_data[f], silk_frame_nb_flags, ptr_VAD_FLAGS, ptr_LBBR_FLAGS,
323-
&silk_frame_nb_vad1, &silk_frame_nb_fec);
321+
if (!switch_opus_get_VAD_LBRR_flags(frame_data[f], frame_sizes[f], silk_frame_nb_flags, ptr_VAD_FLAGS, ptr_LBBR_FLAGS,
322+
&silk_frame_nb_vad1, &silk_frame_nb_fec)) {
323+
continue; /* ignore frame as it was abnormal */
324+
}
325+
324326
packet_info->vad += silk_frame_nb_vad1;
325327
packet_info->fec += silk_frame_nb_fec;
326328
packet_info->vad_ms += silk_frame_nb_vad1 * silk_size_frame_ms_per_flag;
@@ -370,6 +372,8 @@ switch_bool_t switch_opus_packet_parse(const uint8_t *payload, int payload_lengt
370372
* Parse the VAD and LBRR flags in each Opus frame
371373
* */
372374
for (f = 0; f < packet_info->frames; f++) {
375+
if (frame_sizes[f] <= 0) continue;
376+
373377
if (frame_data[f][0] & 0x80) {
374378
packet_info->vad++;
375379
}

0 commit comments

Comments
 (0)