[FFmpeg-devel,3/5] avcodec/dstdec: Check for input exhaustion

Submitted by Michael Niedermayer on Oct. 2, 2019, 9:37 p.m.

Details

Message ID 20191002213740.17936-3-michael@niedermayer.cc
State Accepted
Commit f6df99dba1ae64b05d08fba8160d13eb9795042f
Headers show

Commit Message

Michael Niedermayer Oct. 2, 2019, 9:37 p.m.
Fixes: Timeout (239sec -> 16sec)
Fixes: 17811/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_DST_fuzzer-5715508149616640

Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
---
 libavcodec/dstdec.c | 7 +++++++
 1 file changed, 7 insertions(+)

Comments

Paul B Mahol Oct. 8, 2019, 3:41 p.m.
lgtm

On 10/2/19, Michael Niedermayer <michael@niedermayer.cc> wrote:
> Fixes: Timeout (239sec -> 16sec)
> Fixes:
> 17811/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_DST_fuzzer-5715508149616640
>
> Found-by: continuous fuzzing process
> https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg
> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
> ---
>  libavcodec/dstdec.c | 7 +++++++
>  1 file changed, 7 insertions(+)
>
> diff --git a/libavcodec/dstdec.c b/libavcodec/dstdec.c
> index 8a1bc6a738..48271b10f7 100644
> --- a/libavcodec/dstdec.c
> +++ b/libavcodec/dstdec.c
> @@ -56,6 +56,7 @@ static const int8_t probs_code_pred_coeff[3][3] = {
>  typedef struct ArithCoder {
>      unsigned int a;
>      unsigned int c;
> +    int overread;
>  } ArithCoder;
>
>  typedef struct Table {
> @@ -172,6 +173,7 @@ static void ac_init(ArithCoder *ac, GetBitContext *gb)
>  {
>      ac->a = 4095;
>      ac->c = get_bits(gb, 12);
> +    ac->overread = 0;
>  }
>
>  static av_always_inline void ac_get(ArithCoder *ac, GetBitContext *gb, int
> p, int *e)
> @@ -191,6 +193,8 @@ static av_always_inline void ac_get(ArithCoder *ac,
> GetBitContext *gb, int p, in
>      if (ac->a < 2048) {
>          int n = 11 - av_log2(ac->a);
>          ac->a <<= n;
> +        if (get_bits_left(gb) < n)
> +            ac->overread ++;
>          ac->c = (ac->c << n) | get_bits(gb, n);
>      }
>  }
> @@ -339,6 +343,9 @@ static int decode_frame(AVCodecContext *avctx, void
> *data,
>                  prob = 128;
>              }
>
> +            if (ac->overread > 16)
> +                return AVERROR_INVALIDDATA;
> +
>              ac_get(ac, gb, prob, &residual);
>              v = ((predict >> 15) ^ residual) & 1;
>              dsd[((i >> 3) * channels + ch) << 2] |= v << (7 - (i & 0x7 ));
> --
> 2.23.0
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".
Michael Niedermayer Oct. 10, 2019, 11:32 a.m.
On Tue, Oct 08, 2019 at 05:41:35PM +0200, Paul B Mahol wrote:
> lgtm

will apply

thx

[...]

Patch hide | download patch | download mbox

diff --git a/libavcodec/dstdec.c b/libavcodec/dstdec.c
index 8a1bc6a738..48271b10f7 100644
--- a/libavcodec/dstdec.c
+++ b/libavcodec/dstdec.c
@@ -56,6 +56,7 @@  static const int8_t probs_code_pred_coeff[3][3] = {
 typedef struct ArithCoder {
     unsigned int a;
     unsigned int c;
+    int overread;
 } ArithCoder;
 
 typedef struct Table {
@@ -172,6 +173,7 @@  static void ac_init(ArithCoder *ac, GetBitContext *gb)
 {
     ac->a = 4095;
     ac->c = get_bits(gb, 12);
+    ac->overread = 0;
 }
 
 static av_always_inline void ac_get(ArithCoder *ac, GetBitContext *gb, int p, int *e)
@@ -191,6 +193,8 @@  static av_always_inline void ac_get(ArithCoder *ac, GetBitContext *gb, int p, in
     if (ac->a < 2048) {
         int n = 11 - av_log2(ac->a);
         ac->a <<= n;
+        if (get_bits_left(gb) < n)
+            ac->overread ++;
         ac->c = (ac->c << n) | get_bits(gb, n);
     }
 }
@@ -339,6 +343,9 @@  static int decode_frame(AVCodecContext *avctx, void *data,
                 prob = 128;
             }
 
+            if (ac->overread > 16)
+                return AVERROR_INVALIDDATA;
+
             ac_get(ac, gb, prob, &residual);
             v = ((predict >> 15) ^ residual) & 1;
             dsd[((i >> 3) * channels + ch) << 2] |= v << (7 - (i & 0x7 ));