diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-09-08 22:37:31 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-09-08 22:37:31 +0200 |
commit | 78d7d8fe9170f38ee0b2ab6f731ff1a61c712db5 (patch) | |
tree | 3fa4f47e3f1cca5a0cf39b42a5d171dec9a5b53f /libavcodec/wavpack.c | |
parent | 04c13dca8812e8302686887b6e8201d4ad25b7d8 (diff) | |
parent | 6376362d15ccbc02e15d0b3b7a7a5d862efd6b91 (diff) | |
download | ffmpeg-78d7d8fe9170f38ee0b2ab6f731ff1a61c712db5.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
Employ FF_ARRAY_ELEMS instead of manually calculating array length.
Fixed invalid access in wavpack decoder on corrupted bitstream.
Fixed invalid writes in wavpack decoder on corrupted bitstreams.
Fixed invalid access in wavpack decoder on corrupted extra bits sub-blocks.
rtpdec_asf: Fix integer underflow that could allow remote code execution
Conflicts:
libavformat/rtpdec_asf.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavcodec/wavpack.c')
-rw-r--r-- | libavcodec/wavpack.c | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 9da1f91d1d..870437d6f4 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -292,7 +292,14 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, int channel } }else{ t = get_unary_0_33(gb); - if(t >= 2) t = get_bits(gb, t - 1) | (1 << (t-1)); + if(t >= 2){ + if(get_bits_left(gb) < t-1) + goto error; + t = get_bits(gb, t - 1) | (1 << (t-1)); + }else{ + if(get_bits_left(gb) < 0) + goto error; + } ctx->zeroes = t; if(ctx->zeroes){ memset(ctx->ch[0].median, 0, sizeof(ctx->ch[0].median)); @@ -303,24 +310,24 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, int channel } } - if(get_bits_count(gb) >= ctx->data_size){ - *last = 1; - return 0; - } - if(ctx->zero){ t = 0; ctx->zero = 0; }else{ t = get_unary_0_33(gb); - if(get_bits_count(gb) >= ctx->data_size){ - *last = 1; - return 0; - } + if(get_bits_left(gb) < 0) + goto error; if(t == 16) { t2 = get_unary_0_33(gb); - if(t2 < 2) t += t2; - else t += get_bits(gb, t2 - 1) | (1 << (t2 - 1)); + if(t2 < 2){ + if(get_bits_left(gb) < 0) + goto error; + t += t2; + }else{ + if(get_bits_left(gb) < t2 - 1) + goto error; + t += get_bits(gb, t2 - 1) | (1 << (t2 - 1)); + } } if(ctx->one){ @@ -360,9 +367,13 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, int channel } if(!c->error_limit){ ret = base + get_tail(gb, add); + if (get_bits_left(gb) <= 0) + goto error; }else{ int mid = (base*2 + add + 1) >> 1; while(add > c->error_limit){ + if(get_bits_left(gb) <= 0) + goto error; if(get_bits1(gb)){ add -= (mid - base); base = mid; @@ -376,6 +387,10 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, int channel if(ctx->hybrid_bitrate) c->slow_level += wp_log2(ret) - LEVEL_DECAY(c->slow_level); return sign ? ~ret : ret; + +error: + *last = 1; + return 0; } static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, int S) @@ -385,7 +400,7 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, in if(s->extra_bits){ S <<= s->extra_bits; - if(s->got_extra_bits){ + if(s->got_extra_bits && get_bits_left(&s->gb_extra_bits) >= s->extra_bits){ S |= get_bits(&s->gb_extra_bits, s->extra_bits); *crc = *crc * 9 + (S&0xffff) * 3 + ((unsigned)S>>16); } @@ -581,7 +596,10 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, vo count++; }while(!last && count < s->max_samples); - s->samples_left -= count; + if (last) + s->samples_left = 0; + else + s->samples_left -= count; if(!s->samples_left){ wv_reset_saved_context(s); if(crc != s->CRC){ @@ -659,7 +677,10 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb, void count++; }while(!last && count < s->max_samples); - s->samples_left -= count; + if (last) + s->samples_left = 0; + else + s->samples_left -= count; if(!s->samples_left){ wv_reset_saved_context(s); if(crc != s->CRC){ @@ -1114,7 +1135,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, int16_t *dst = (int16_t*)samples + 1; int16_t *src = (int16_t*)samples; int cnt = samplecount; - while(cnt--){ + while(cnt-- > 0){ *dst = *src; src += channel_stride; dst += channel_stride; @@ -1123,7 +1144,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, int32_t *dst = (int32_t*)samples + 1; int32_t *src = (int32_t*)samples; int cnt = samplecount; - while(cnt--){ + while(cnt-- > 0){ *dst = *src; src += channel_stride; dst += channel_stride; @@ -1132,7 +1153,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, float *dst = (float*)samples + 1; float *src = (float*)samples; int cnt = samplecount; - while(cnt--){ + while(cnt-- > 0){ *dst = *src; src += channel_stride; dst += channel_stride; |