diff options
author | Laurent Aimar <fenrir@videolan.org> | 2011-09-27 01:02:16 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-09-27 15:15:54 +0200 |
commit | 36bf135d4c32973933000a819208df7da9dd3e16 (patch) | |
tree | 1acf0d4a384a335a12868754a719b450c872ad9b | |
parent | 99d7d1510ed2e8dd73152a5dc1a5476faf1a7939 (diff) | |
download | ffmpeg-36bf135d4c32973933000a819208df7da9dd3e16.tar.gz |
Check for various out of bound writes in the bink decoder.
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
-rw-r--r-- | libavcodec/bink.c | 17 |
1 files changed, 13 insertions, 4 deletions
diff --git a/libavcodec/bink.c b/libavcodec/bink.c index e137312693..3c2148b3c6 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -344,14 +344,14 @@ static int read_motion_values(AVCodecContext *avctx, GetBitContext *gb, Bundle * memset(b->cur_dec, v, t); b->cur_dec += t; } else { - do { + while (b->cur_dec < dec_end) { v = GET_HUFF(gb, b->tree); if (v) { sign = -get_bits1(gb); v = (v ^ sign) - sign; } *b->cur_dec++ = v; - } while (b->cur_dec < dec_end); + } } return 0; } @@ -375,7 +375,7 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) memset(b->cur_dec, v, t); b->cur_dec += t; } else { - do { + while (b->cur_dec < dec_end) { v = GET_HUFF(gb, b->tree); if (v < 12) { last = v; @@ -383,10 +383,12 @@ static int read_block_types(AVCodecContext *avctx, GetBitContext *gb, Bundle *b) } else { int run = bink_rlelens[v - 12]; + if (dec_end - b->cur_dec < run) + return -1; memset(b->cur_dec, last, run); b->cur_dec += run; } - } while (b->cur_dec < dec_end); + } } return 0; } @@ -457,6 +459,7 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, { int i, j, len, len2, bsize, sign, v, v2; int16_t *dst = (int16_t*)b->cur_dec; + int16_t *dst_end =( int16_t*)b->data_end; CHECK_READ_VAL(gb, b, len); v = get_bits(gb, start_bits - has_sign); @@ -464,10 +467,14 @@ static int read_dcs(AVCodecContext *avctx, GetBitContext *gb, Bundle *b, sign = -get_bits1(gb); v = (v ^ sign) - sign; } + if (dst_end - dst < 1) + return -1; *dst++ = v; len--; for (i = 0; i < len; i += 8) { len2 = FFMIN(len - i, 8); + if (dst_end - dst < len2) + return -1; bsize = get_bits(gb, 4); if (bsize) { for (j = 0; j < len2; j++) { @@ -535,6 +542,8 @@ static int binkb_read_bundle(BinkContext *c, GetBitContext *gb, int bundle_num) int i, len; CHECK_READ_VAL(gb, b, len); + if (b->data_end - b->cur_dec < len * (1 + (bits > 8))) + return -1; if (bits <= 8) { if (!issigned) { for (i = 0; i < len; i++) |