diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2017-03-07 19:09:38 +0100 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2017-05-20 03:41:32 +0200 |
commit | 45abce9e05e66e145f82dabccba73c3768526582 (patch) | |
tree | 75a5145e383cfd32447f9a0465365fb62fd35523 | |
parent | efa47b5c9982fdabefd53e945b14db4cc67f5c56 (diff) | |
download | ffmpeg-45abce9e05e66e145f82dabccba73c3768526582.tar.gz |
avcodec/vp568: Check that there is enough data for ff_vp56_init_range_decoder()
Fixes: timeout in 730/clusterfuzz-testcase-5265113739165696 (part 1 of 2)
Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg
Reviewed-by: BBB
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 55d7371fe0c44c025eb0e75215e0685870f31874)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r-- | libavcodec/vp5.c | 5 | ||||
-rw-r--r-- | libavcodec/vp56.h | 2 | ||||
-rw-r--r-- | libavcodec/vp56rac.c | 5 | ||||
-rw-r--r-- | libavcodec/vp6.c | 15 | ||||
-rw-r--r-- | libavcodec/vp8.c | 21 | ||||
-rw-r--r-- | libavcodec/vp9.c | 9 |
6 files changed, 41 insertions, 16 deletions
diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c index 108f16131d..7100bb455d 100644 --- a/libavcodec/vp5.c +++ b/libavcodec/vp5.c @@ -39,8 +39,11 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) { VP56RangeCoder *c = &s->c; int rows, cols; + int ret; - ff_vp56_init_range_decoder(&s->c, buf, buf_size); + ret = ff_vp56_init_range_decoder(&s->c, buf, buf_size); + if (ret < 0) + return ret; s->frames[VP56_FRAME_CURRENT]->key_frame = !vp56_rac_get(c); vp56_rac_get(c); ff_vp56_init_dequant(s, vp56_rac_gets(c, 6)); diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index e5c5bea963..c049399df8 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -224,7 +224,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, */ extern const uint8_t ff_vp56_norm_shift[256]; -void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size); +int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size); static av_always_inline unsigned int vp56_rac_renorm(VP56RangeCoder *c) { diff --git a/libavcodec/vp56rac.c b/libavcodec/vp56rac.c index 6061b7ee72..e70302bf85 100644 --- a/libavcodec/vp56rac.c +++ b/libavcodec/vp56rac.c @@ -37,11 +37,14 @@ const uint8_t ff_vp56_norm_shift[256]= { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, }; -void ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size) +int ff_vp56_init_range_decoder(VP56RangeCoder *c, const uint8_t *buf, int buf_size) { c->high = 255; c->bits = -16; c->buffer = buf; c->end = buf + buf_size; + if (buf_size < 1) + return AVERROR_INVALIDDATA; c->code_word = bytestream_get_be24(&c->buffer); + return 0; } diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index 662126ca70..f0e60a3822 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -52,6 +52,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) int sub_version; int rows, cols; int res = 0; + int ret; int separated_coeff = buf[0] & 1; s->frames[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); @@ -93,7 +94,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) s->avctx->coded_width = 16 * cols; s->avctx->coded_height = 16 * rows; } else { - int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows); + ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows); if (ret < 0) return ret; @@ -105,7 +106,9 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) res = VP56_SIZE_CHANGE; } - ff_vp56_init_range_decoder(c, buf+6, buf_size-6); + ret = ff_vp56_init_range_decoder(c, buf+6, buf_size-6); + if (ret < 0) + return ret; vp56_rac_gets(c, 2); parse_filter_info = s->filter_header; @@ -122,7 +125,9 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) buf += 2; buf_size -= 2; } - ff_vp56_init_range_decoder(c, buf+1, buf_size-1); + ret = ff_vp56_init_range_decoder(c, buf+1, buf_size-1); + if (ret < 0) + return ret; s->golden_frame = vp56_rac_get(c); if (s->filter_header) { @@ -165,7 +170,9 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size) s->parse_coeff = vp6_parse_coeff_huffman; init_get_bits(&s->gb, buf, buf_size<<3); } else { - ff_vp56_init_range_decoder(&s->cc, buf, buf_size); + ret = ff_vp56_init_range_decoder(&s->cc, buf, buf_size); + if (ret < 0) + return ret; s->ccp = &s->cc; } } else { diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 970fe6cd8d..6c6fb8d601 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -260,6 +260,7 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size) { const uint8_t *sizes = buf; int i; + int ret; s->num_coeff_partitions = 1 << vp8_rac_get_uint(&s->c, 2); @@ -273,13 +274,13 @@ static int setup_partitions(VP8Context *s, const uint8_t *buf, int buf_size) if (buf_size - size < 0) return -1; - ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size); + ret = ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, size); + if (ret < 0) + return ret; buf += size; buf_size -= size; } - ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size); - - return 0; + return ff_vp56_init_range_decoder(&s->coeff_partition[i], buf, buf_size); } static void vp7_get_quants(VP8Context *s) @@ -517,7 +518,9 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si memcpy(s->put_pixels_tab, s->vp8dsp.put_vp8_epel_pixels_tab, sizeof(s->put_pixels_tab)); - ff_vp56_init_range_decoder(c, buf, part1_size); + ret = ff_vp56_init_range_decoder(c, buf, part1_size); + if (ret < 0) + return ret; buf += part1_size; buf_size -= part1_size; @@ -569,7 +572,9 @@ static int vp7_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si s->lf_delta.enabled = 0; s->num_coeff_partitions = 1; - ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size); + ret = ff_vp56_init_range_decoder(&s->coeff_partition[0], buf, buf_size); + if (ret < 0) + return ret; if (!s->macroblocks_base || /* first frame */ width != s->avctx->width || height != s->avctx->height || @@ -698,7 +703,9 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si memset(&s->lf_delta, 0, sizeof(s->lf_delta)); } - ff_vp56_init_range_decoder(c, buf, header_size); + ret = ff_vp56_init_range_decoder(c, buf, header_size); + if (ret < 0) + return ret; buf += header_size; buf_size -= header_size; diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index cd03c97aaf..2587083f26 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -880,7 +880,10 @@ static int decode_frame_header(AVCodecContext *ctx, av_log(ctx, AV_LOG_ERROR, "Invalid compressed header size\n"); return AVERROR_INVALIDDATA; } - ff_vp56_init_range_decoder(&s->c, data2, size2); + res = ff_vp56_init_range_decoder(&s->c, data2, size2); + if (res < 0) + return res; + if (vp56_rac_get_prob_branchy(&s->c, 128)) { // marker bit av_log(ctx, AV_LOG_ERROR, "Marker bit was set\n"); return AVERROR_INVALIDDATA; @@ -4129,7 +4132,9 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame, ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0); return AVERROR_INVALIDDATA; } - ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size); + res = ff_vp56_init_range_decoder(&s->c_b[tile_col], data, tile_size); + if (res < 0) + return res; if (vp56_rac_get_prob_branchy(&s->c_b[tile_col], 128)) { // marker bit ff_thread_report_progress(&s->frames[CUR_FRAME].tf, INT_MAX, 0); return AVERROR_INVALIDDATA; |