Browse Source

avcodec/cfhd: Keep track of which subbands have been read

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>
(cherry picked from commit da8c86dd8b)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
tags/n4.4
Michael Niedermayer 4 years ago
parent
commit
6a7a39878f
2 changed files with 27 additions and 0 deletions
  1. +26
    -0
      libavcodec/cfhd.c
  2. +1
    -0
      libavcodec/cfhd.h

+ 26
- 0
libavcodec/cfhd.c View File

@@ -221,6 +221,7 @@ static void free_buffers(CFHDContext *s)
int i, j; int i, j;


for (i = 0; i < FF_ARRAY_ELEMS(s->plane); i++) { 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_buf);
av_freep(&s->plane[i].idwt_tmp); av_freep(&s->plane[i].idwt_tmp);
s->plane[i].idwt_size = 0; s->plane[i].idwt_size = 0;
@@ -230,6 +231,12 @@ static void free_buffers(CFHDContext *s)


for (j = 0; j < 10; j++) for (j = 0; j < 10; j++)
s->plane[i].l_h[j] = NULL; 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_height = 0;
s->a_width = 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)); 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); 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); bytestream2_seek(&gb, bytes, SEEK_CUR);


av_log(avctx, AV_LOG_DEBUG, "End subband coeffs %i extra %i\n", count, count - expected); 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: finish:
if (s->subband_num_actual != 255) if (s->subband_num_actual != 255)
s->codebook = 0; s->codebook = 0;
@@ -919,6 +929,22 @@ finish:
goto end; 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) { if (s->transform_type == 0 && s->sample_type != 1) {
for (plane = 0; plane < s->planes && !ret; plane++) { for (plane = 0; plane < s->planes && !ret; plane++) {
/* level 1 */ /* level 1 */


+ 1
- 0
libavcodec/cfhd.h View File

@@ -114,6 +114,7 @@ typedef struct SubBand {
int width; int width;
int a_height; int a_height;
int height; int height;
int8_t read_ok;
} SubBand; } SubBand;


typedef struct Plane { typedef struct Plane {


Loading…
Cancel
Save