summaryrefslogtreecommitdiff
path: root/libavcodec
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2019-10-02 20:48:40 +0200
committerMichael Niedermayer <michael@niedermayer.cc>2019-10-10 14:34:20 +0200
commitf6df99dba1ae64b05d08fba8160d13eb9795042f (patch)
tree06158b77fa68f55a7bc63cb03082205e23697997 /libavcodec
parenta5d29812ec364ad4b83b5c2dba281f1b559a518b (diff)
avcodec/dstdec: Check for input exhaustion
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 Reviewed-by: Paul B Mahol <onemda@gmail.com> Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec')
-rw-r--r--libavcodec/dstdec.c7
1 files changed, 7 insertions, 0 deletions
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 ));