[FFmpeg-devel] [PATCH 3/3] avcodec/fmvc: Require key frames to fill a non trivial part of the buffer

Michael Niedermayer michael at niedermayer.cc
Sat Jun 11 02:10:45 EEST 2022


Keyframes filling only part of the buffer should theoretically be invalid
as they are not really keyframes.

Fixes: Timeout
Fixes: 47879/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_FMVC_fuzzer-6258764937822208

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael at niedermayer.cc>
---
 libavcodec/fmvc.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/libavcodec/fmvc.c b/libavcodec/fmvc.c
index de2bf828f4..36990956e0 100644
--- a/libavcodec/fmvc.c
+++ b/libavcodec/fmvc.c
@@ -284,7 +284,7 @@ static int decode_type2(GetByteContext *gb, PutByteContext *pb)
         }
     }
 
-    return 0;
+    return bytestream2_get_bytes_left_p(pb);
 }
 
 static int decode_type1(GetByteContext *gb, PutByteContext *pb)
@@ -391,7 +391,7 @@ static int decode_type1(GetByteContext *gb, PutByteContext *pb)
         } while (len && bytestream2_get_bytes_left(&gbc) > 0);
     }
 
-    return 0;
+    return bytestream2_get_bytes_left_p(pb);
 }
 
 static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
@@ -414,6 +414,7 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
     if (key_frame) {
         const uint8_t *src;
         unsigned type, size;
+        int left;
         uint8_t *dst;
 
         type = bytestream2_get_le16(gb);
@@ -423,14 +424,17 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *frame,
 
         bytestream2_init_writer(pb, s->buffer, s->buffer_size);
         if (type == 1) {
-            decode_type1(gb, pb);
+            left = decode_type1(gb, pb);
         } else if (type == 2){
-            decode_type2(gb, pb);
+            left = decode_type2(gb, pb);
         } else {
             avpriv_report_missing_feature(avctx, "Compression type %d", type);
             return AVERROR_PATCHWELCOME;
         }
 
+        if (left > s->buffer_size*4/5)
+            return AVERROR_INVALIDDATA;
+
         if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
             return ret;
 
-- 
2.17.1



More information about the ffmpeg-devel mailing list