[FFmpeg-devel,2/2] avcodec/lcldec: Check mthread_inlen instead of cliping

Submitted by Michael Niedermayer on July 27, 2019, 10:31 p.m.

Details

Message ID 20190727223122.28243-2-michael@niedermayer.cc
State Accepted
Commit 4d4734bdc881de3af0ebe5935890a81423c80fdf
Headers show

Commit Message

Michael Niedermayer July 27, 2019, 10:31 p.m.
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 | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

Comments

Michael Niedermayer Aug. 23, 2019, 1:15 p.m.
On Sun, Jul 28, 2019 at 12:31:22AM +0200, Michael Niedermayer wrote:
> 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 | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)

will apply

[...]

Patch hide | download patch | download mbox

diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c
index c3787b3cbe..ae7426144d 100644
--- a/libavcodec/lcldec.c
+++ b/libavcodec/lcldec.c
@@ -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);