[FFmpeg-devel] [PATCH 3/3] avcodec/cfhd: Keep track of which subbands have been read

Michael Niedermayer michael at niedermayer.cc
Sat Apr 3 17:39:08 EEST 2021


This avoids use of uninitialized data
also several checks are inside the band reading code
so it is important that it is run at least once

Fixes: out of array accesses
Fixes: 28209/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CFHD_fuzzer-5684714694377472
Fixes: 32124/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CFHD_fuzzer-5425980681355264
Fixes: 30519/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_CFHD_fuzzer-4558757155700736

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/cfhd.c | 20 ++++++++++++++++++++
 libavcodec/cfhd.h |  1 +
 2 files changed, 21 insertions(+)

diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c
index 8bf910cde6..61e02999e9 100644
--- a/libavcodec/cfhd.c
+++ b/libavcodec/cfhd.c
@@ -221,6 +221,7 @@ static void free_buffers(CFHDContext *s)
     int i, j;
 
     for (i = 0; i < FF_ARRAY_ELEMS(s->plane); i++) {
+        Plane *p = &s->plane[i];
         av_freep(&s->plane[i].idwt_buf);
         av_freep(&s->plane[i].idwt_tmp);
         s->plane[i].idwt_size = 0;
@@ -230,6 +231,12 @@ static void free_buffers(CFHDContext *s)
 
         for (j = 0; j < 10; j++)
             s->plane[i].l_h[j] = NULL;
+
+        for (j = 0; j < DWT_LEVELS_3D; j++)
+            p->band[j][0].read_ok =
+            p->band[j][1].read_ok =
+            p->band[j][2].read_ok =
+            p->band[j][3].read_ok = 0;
     }
     s->a_height = 0;
     s->a_width  = 0;
@@ -759,6 +766,8 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
                        lowpass_width * sizeof(*coeff_data));
             }
 
+            s->plane[s->channel_num].band[0][0].read_ok = 1;
+
             av_log(avctx, AV_LOG_DEBUG, "Lowpass coefficients %d\n", lowpass_width * lowpass_height);
         }
 
@@ -891,6 +900,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame,
                 bytestream2_seek(&gb, bytes, SEEK_CUR);
 
             av_log(avctx, AV_LOG_DEBUG, "End subband coeffs %i extra %i\n", count, count - expected);
+            s->plane[s->channel_num].band[s->level][s->subband_num].read_ok = 1;
 finish:
             if (s->subband_num_actual != 255)
                 s->codebook = 0;
@@ -919,6 +929,16 @@ finish:
         goto end;
     }
 
+    for (plane = 0; plane < s->planes; plane++) {
+        int o;
+        for (o = 0; o < 4 ; o++) {
+            if (!s->plane[plane].band[0][o].read_ok) {
+                ret = AVERROR_INVALIDDATA;
+                goto end;
+            }
+        }
+    }
+
     if (s->transform_type == 0 && s->sample_type != 1) {
         for (plane = 0; plane < s->planes && !ret; plane++) {
             /* level 1 */
diff --git a/libavcodec/cfhd.h b/libavcodec/cfhd.h
index 4ec2a2ce8b..19e5c7cf03 100644
--- a/libavcodec/cfhd.h
+++ b/libavcodec/cfhd.h
@@ -114,6 +114,7 @@ typedef struct SubBand {
     int width;
     int a_height;
     int height;
+    int8_t read_ok;
 } SubBand;
 
 typedef struct Plane {
-- 
2.17.1



More information about the ffmpeg-devel mailing list