aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2017-03-07 19:09:38 +0100
committerMichael Niedermayer <michael@niedermayer.cc>2017-05-20 03:41:32 +0200
commit45abce9e05e66e145f82dabccba73c3768526582 (patch)
tree75a5145e383cfd32447f9a0465365fb62fd35523
parentefa47b5c9982fdabefd53e945b14db4cc67f5c56 (diff)
downloadffmpeg-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.c5
-rw-r--r--libavcodec/vp56.h2
-rw-r--r--libavcodec/vp56rac.c5
-rw-r--r--libavcodec/vp6.c15
-rw-r--r--libavcodec/vp8.c21
-rw-r--r--libavcodec/vp9.c9
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;