diff options
author | Mans Rullgard <mans@mansr.com> | 2011-08-10 18:52:11 +0100 |
---|---|---|
committer | Reinhard Tartler <siretart@tauware.de> | 2011-08-21 11:23:56 +0200 |
commit | bd968d260aef322fb32e254a3de0d2036c57bd56 (patch) | |
tree | 9e58edbfe54ff7a5cf549c4298ed30376e76aecf /libavcodec | |
parent | 00c5cf4beb0e45e936544a5766b56e241ae03234 (diff) | |
download | ffmpeg-bd968d260aef322fb32e254a3de0d2036c57bd56.tar.gz |
cavs: fix some crashes with invalid bitstreams
This removes all valgrind-reported invalid writes with one
specific test file.
Fixes http://www.ocert.org/advisories/ocert-2011-002.html
Signed-off-by: Mans Rullgard <mans@mansr.com>
(cherry picked from commit 4a71da0f3ab7f5542decd11c81994f849d5b2c78)
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/cavsdec.c | 11 |
1 files changed, 8 insertions, 3 deletions
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index a9e4d37c2a..35c37d0768 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -130,12 +130,14 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb, r++; mask = -(level_code & 1); level = (level^mask) - mask; - } else { + } else if (level_code >= 0) { level = r->rltab[level_code][0]; if(!level) //end of block signal break; run = r->rltab[level_code][1]; r += r->rltab[level_code][2]; + } else { + break; } level_buf[i] = level; run_buf[i] = run; @@ -189,7 +191,8 @@ static inline int decode_residual_inter(AVSContext *h) { static int decode_mb_i(AVSContext *h, int cbp_code) { GetBitContext *gb = &h->s.gb; - int block, pred_mode_uv; + unsigned pred_mode_uv; + int block; uint8_t top[18]; uint8_t *left = NULL; uint8_t *d; @@ -445,6 +448,8 @@ static inline int check_for_slice(AVSContext *h) { if((show_bits_long(gb,24+align) & 0xFFFFFF) == 0x000001) { skip_bits_long(gb,24+align); h->stc = get_bits(gb,8); + if (h->stc >= h->mb_height) + return 0; decode_slice_header(h,gb); return 1; } @@ -659,7 +664,7 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, buf_end = buf + buf_size; for(;;) { buf_ptr = ff_find_start_code(buf_ptr,buf_end, &stc); - if(stc & 0xFFFFFE00) + if((stc & 0xFFFFFE00) || buf_ptr == buf_end) return FFMAX(0, buf_ptr - buf - s->parse_context.last_index); input_size = (buf_end - buf_ptr)*8; switch(stc) { |