aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMans Rullgard <mans@mansr.com>2011-08-10 18:52:11 +0100
committerReinhard Tartler <siretart@tauware.de>2011-11-02 21:14:57 +0100
commit04888edef344b09daaabbc30b3fa5ab32d3bd866 (patch)
tree546ab7d61a306e4c76e0f162c69394ea9a936255
parenteed5697f99927c78956fde6ee6f1ac87f3c6d261 (diff)
downloadffmpeg-04888edef344b09daaabbc30b3fa5ab32d3bd866.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) Fixes CVE-2011-3362, CVE-2011-3973, CVE-2011-3974 Signed-off-by: Reinhard Tartler <siretart@tauware.de>
-rw-r--r--libavcodec/cavsdec.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c
index a1895bcb88..8d30040d74 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;
}
@@ -648,7 +653,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) {