diff mbox

[FFmpeg-devel] avcodec/opus_parser: Check payload_len in parse_opus_ts_header()

Message ID 20180107021519.22720-1-michael@niedermayer.cc
State Accepted
Commit 1bcd7fefcb3c1ec47978fdc64a9e8dfb9512ae62
Headers show

Commit Message

Michael Niedermayer Jan. 7, 2018, 2:15 a.m. UTC
Fixes: clusterfuzz-testcase-minimized-6134545979277312
Fixes: crbug 797469

Reported-by: Matt Wolenetz <wolenetz@google.com>
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavcodec/opus_parser.c | 16 +++++++++++++---
 1 file changed, 13 insertions(+), 3 deletions(-)

Comments

Michael Niedermayer Jan. 8, 2018, 8:52 p.m. UTC | #1
On Sun, Jan 07, 2018 at 03:15:19AM +0100, Michael Niedermayer wrote:
> Fixes: clusterfuzz-testcase-minimized-6134545979277312
> Fixes: crbug 797469
> 
> Reported-by: Matt Wolenetz <wolenetz@google.com>
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
>  libavcodec/opus_parser.c | 16 +++++++++++++---
>  1 file changed, 13 insertions(+), 3 deletions(-)

applied

[...]
diff mbox

Patch

diff --git a/libavcodec/opus_parser.c b/libavcodec/opus_parser.c
index 893573eb82..28b0933900 100644
--- a/libavcodec/opus_parser.c
+++ b/libavcodec/opus_parser.c
@@ -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;
     int start_trim_flag, end_trim_flag, control_extension_flag, control_extension_length;
     uint8_t flags;
+    uint64_t payload_len_tmp;
 
     GetByteContext gb;
     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;
     control_extension_flag = (flags >> 2) & 1;
 
-    *payload_len = 0;
+    payload_len_tmp = *payload_len = 0;
     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)
         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);
     }
 
+    if (bytestream2_tell(&gb) + payload_len_tmp > buf_len)
+        return NULL;
+
+    *payload_len = payload_len_tmp;
+
     return buf + bytestream2_tell(&gb);
 }
 
@@ -104,6 +110,10 @@  static int opus_find_frame_end(AVCodecParserContext *ctx, AVCodecContext *avctx,
             state = (state << 8) | payload[i];
             if ((state & OPUS_TS_MASK) == OPUS_TS_HEADER) {
                 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;
                 start_found = 1;
                 break;