Browse Source

avcodec/opus_parser: Check payload_len in parse_opus_ts_header()

Fixes: clusterfuzz-testcase-minimized-6134545979277312
Fixes: crbug 797469

Reported-by: Matt Wolenetz <wolenetz@google.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 1bcd7fefcb)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
tags/n3.3.7
Michael Niedermayer 8 years ago
parent
commit
ba2f8469ba
1 changed files with 13 additions and 3 deletions
  1. +13
    -3
      libavcodec/opus_parser.c

+ 13
- 3
libavcodec/opus_parser.c View File

@@ -43,6 +43,7 @@ static const uint8_t *parse_opus_ts_header(const uint8_t *start, int *payload_le
const uint8_t *buf = start + 1; const uint8_t *buf = start + 1;
int start_trim_flag, end_trim_flag, control_extension_flag, control_extension_length; int start_trim_flag, end_trim_flag, control_extension_flag, control_extension_length;
uint8_t flags; uint8_t flags;
uint64_t payload_len_tmp;


GetByteContext gb; GetByteContext gb;
bytestream2_init(&gb, buf, buf_len); bytestream2_init(&gb, buf, buf_len);
@@ -52,11 +53,11 @@ static const uint8_t *parse_opus_ts_header(const uint8_t *start, int *payload_le
end_trim_flag = (flags >> 3) & 1; end_trim_flag = (flags >> 3) & 1;
control_extension_flag = (flags >> 2) & 1; control_extension_flag = (flags >> 2) & 1;


*payload_len = 0;
payload_len_tmp = *payload_len = 0;
while (bytestream2_peek_byte(&gb) == 0xff) while (bytestream2_peek_byte(&gb) == 0xff)
*payload_len += bytestream2_get_byte(&gb);
payload_len_tmp += bytestream2_get_byte(&gb);


*payload_len += bytestream2_get_byte(&gb);
payload_len_tmp += bytestream2_get_byte(&gb);


if (start_trim_flag) if (start_trim_flag)
bytestream2_skip(&gb, 2); bytestream2_skip(&gb, 2);
@@ -67,6 +68,11 @@ static const uint8_t *parse_opus_ts_header(const uint8_t *start, int *payload_le
bytestream2_skip(&gb, control_extension_length); bytestream2_skip(&gb, control_extension_length);
} }


if (bytestream2_tell(&gb) + payload_len_tmp > buf_len)
return NULL;

*payload_len = payload_len_tmp;

return buf + bytestream2_tell(&gb); return buf + bytestream2_tell(&gb);
} }


@@ -104,6 +110,10 @@ static int opus_find_frame_end(AVCodecParserContext *ctx, AVCodecContext *avctx,
state = (state << 8) | payload[i]; state = (state << 8) | payload[i];
if ((state & OPUS_TS_MASK) == OPUS_TS_HEADER) { if ((state & OPUS_TS_MASK) == OPUS_TS_HEADER) {
payload = parse_opus_ts_header(payload, &payload_len, buf_size - i); payload = parse_opus_ts_header(payload, &payload_len, buf_size - i);
if (!payload) {
av_log(avctx, AV_LOG_ERROR, "Error parsing Ogg TS header.\n");
return AVERROR_INVALIDDATA;
}
*header_len = payload - buf; *header_len = payload - buf;
start_found = 1; start_found = 1;
break; break;


Loading…
Cancel
Save