Commit 7b5ff7d5 authored by Michael Niedermayer's avatar Michael Niedermayer

avcodec/vp8: Check for bitsteam end in decode_mb_row_no_filter()

Fixes timeout with 686/clusterfuzz-testcase-5853946876788736

this shortcuts (i.e. speeds up) the error and
return-to-user when decoding a truncated frame

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/targets/ffmpeg
Previous version reviewed by: "Ronald S. Bultje" <rsbultje@gmail.com>
Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent 4bd3f1ce
...@@ -2275,7 +2275,7 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame, ...@@ -2275,7 +2275,7 @@ static void vp8_decode_mv_mb_modes(AVCodecContext *avctx, VP8Frame *cur_frame,
#define update_pos(td, mb_y, mb_x) while(0) #define update_pos(td, mb_y, mb_x) while(0)
#endif #endif
static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, static av_always_inline int decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
int jobnr, int threadnr, int is_vp7) int jobnr, int threadnr, int is_vp7)
{ {
VP8Context *s = avctx->priv_data; VP8Context *s = avctx->priv_data;
...@@ -2291,6 +2291,10 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void ...@@ -2291,6 +2291,10 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void
curframe->tf.f->data[1] + 8 * mb_y * s->uvlinesize, curframe->tf.f->data[1] + 8 * mb_y * s->uvlinesize,
curframe->tf.f->data[2] + 8 * mb_y * s->uvlinesize curframe->tf.f->data[2] + 8 * mb_y * s->uvlinesize
}; };
if (c->end <= c->buffer && c->bits >= 0)
return AVERROR_INVALIDDATA;
if (mb_y == 0) if (mb_y == 0)
prev_td = td; prev_td = td;
else else
...@@ -2394,18 +2398,19 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void ...@@ -2394,18 +2398,19 @@ static av_always_inline void decode_mb_row_no_filter(AVCodecContext *avctx, void
update_pos(td, mb_y, mb_x); update_pos(td, mb_y, mb_x);
} }
} }
return 0;
} }
static void vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, static int vp7_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
int jobnr, int threadnr) int jobnr, int threadnr)
{ {
decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1); return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 1);
} }
static void vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata, static int vp8_decode_mb_row_no_filter(AVCodecContext *avctx, void *tdata,
int jobnr, int threadnr) int jobnr, int threadnr)
{ {
decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0); return decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr, 0);
} }
static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata, static av_always_inline void filter_mb_row(AVCodecContext *avctx, void *tdata,
...@@ -2488,13 +2493,16 @@ int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr, ...@@ -2488,13 +2493,16 @@ int vp78_decode_mb_row_sliced(AVCodecContext *avctx, void *tdata, int jobnr,
VP8ThreadData *next_td = NULL, *prev_td = NULL; VP8ThreadData *next_td = NULL, *prev_td = NULL;
VP8Frame *curframe = s->curframe; VP8Frame *curframe = s->curframe;
int mb_y, num_jobs = s->num_jobs; int mb_y, num_jobs = s->num_jobs;
int ret;
td->thread_nr = threadnr; td->thread_nr = threadnr;
for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) { for (mb_y = jobnr; mb_y < s->mb_height; mb_y += num_jobs) {
if (mb_y >= s->mb_height) if (mb_y >= s->mb_height)
break; break;
td->thread_mb_pos = mb_y << 16; td->thread_mb_pos = mb_y << 16;
s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr); ret = s->decode_mb_row_no_filter(avctx, tdata, jobnr, threadnr);
if (ret < 0)
return ret;
if (s->deblock_filter) if (s->deblock_filter)
s->filter_mb_row(avctx, tdata, jobnr, threadnr); s->filter_mb_row(avctx, tdata, jobnr, threadnr);
update_pos(td, mb_y, INT_MAX & 0xFFFF); update_pos(td, mb_y, INT_MAX & 0xFFFF);
......
...@@ -275,7 +275,7 @@ typedef struct VP8Context { ...@@ -275,7 +275,7 @@ typedef struct VP8Context {
*/ */
int mb_layout; int mb_layout;
void (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); int (*decode_mb_row_no_filter)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr); void (*filter_mb_row)(AVCodecContext *avctx, void *tdata, int jobnr, int threadnr);
int vp7; int vp7;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment