avcodec/lcldec: Check mthread_inlen instead of cliping
authorMichael Niedermayer <michael@niedermayer.cc>
Sat, 27 Jul 2019 21:24:25 +0000 (23:24 +0200)
committerMichael Niedermayer <michael@niedermayer.cc>
Fri, 23 Aug 2019 20:24:07 +0000 (22:24 +0200)
Clipping was added in 2009 to avoid crashes.
The clipped case would produce a 2nd slice with 0 input
thus also producing 0 output.
Subsequent checks will cause decoder failure unless both
slices have the same output length. thus the only way this
would not already fail is if the output from both slices
was 0 bytes.

Fixes: Timeout (134sec -> 241ms)
Fixes: 15599/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_MSZH_fuzzer-5658127116009472

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
libavcodec/lcldec.c

index 104defa5f57f648beef789b17a7ef5ebe669b770..046cdc4f8eebd067d156fdc8f97e7c2a2e5e7874 100644 (file)
@@ -190,11 +190,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac
                 ;
             } else if (c->flags & FLAG_MULTITHREAD) {
                 mthread_inlen = AV_RL32(buf);
-                if (len < 8) {
+                if (len < 8 || len - 8 < mthread_inlen) {
                     av_log(avctx, AV_LOG_ERROR, "len %d is too small\n", len);
                     return AVERROR_INVALIDDATA;
                 }
-                mthread_inlen = FFMIN(mthread_inlen, len - 8);
                 mthread_outlen = AV_RL32(buf + 4);
                 mthread_outlen = FFMIN(mthread_outlen, c->decomp_size);
                 mszh_dlen = mszh_decomp(buf + 8, mthread_inlen, c->decomp_buf, c->decomp_size);