]> git.sesse.net Git - ffmpeg/commitdiff
avcodec/cfhd: Keep track of which subbands have been read
authorMichael Niedermayer <michael@niedermayer.cc>
Sat, 3 Apr 2021 14:04:48 +0000 (16:04 +0200)
committerMichael Niedermayer <michael@niedermayer.cc>
Sat, 3 Apr 2021 17:27:21 +0000 (19:27 +0200)
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@niedermayer.cc>
libavcodec/cfhd.c
libavcodec/cfhd.h

index 8bf910cde6d070a7513c9c822c80e064ea956ddc..6f13207cc147e91e3ee85be142adccba6b8e5ddd 100644 (file)
@@ -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,22 @@ finish:
         goto end;
     }
 
+    for (plane = 0; plane < s->planes; plane++) {
+        int o, level;
+
+        for (level = 0; level < (s->transform_type == 0 ? DWT_LEVELS : DWT_LEVELS_3D) ; level++) {
+            if (s->transform_type == 2)
+                if (level == 2 || level == 5)
+                    continue;
+            for (o = !!level; o < 4 ; o++) {
+                if (!s->plane[plane].band[level][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 */
index 4ec2a2ce8b6796e8e753190317dcda3d280b5c55..19e5c7cf03b8504444ecb5389238dcf62a119e8c 100644 (file)
@@ -114,6 +114,7 @@ typedef struct SubBand {
     int width;
     int a_height;
     int height;
+    int8_t read_ok;
 } SubBand;
 
 typedef struct Plane {