Browse code

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>

Mans Rullgard authored on 2011/08/11 02:52:11
Showing 1 changed files
... ...
@@ -130,12 +130,14 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb,
130 130
                 r++;
131 131
             mask = -(level_code & 1);
132 132
             level = (level^mask) - mask;
133
-        } else {
133
+        } else if (level_code >= 0) {
134 134
             level = r->rltab[level_code][0];
135 135
             if(!level) //end of block signal
136 136
                 break;
137 137
             run   = r->rltab[level_code][1];
138 138
             r += r->rltab[level_code][2];
139
+        } else {
140
+            break;
139 141
         }
140 142
         level_buf[i] = level;
141 143
         run_buf[i] = run;
... ...
@@ -189,7 +191,8 @@ static inline int decode_residual_inter(AVSContext *h) {
189 189
 
190 190
 static int decode_mb_i(AVSContext *h, int cbp_code) {
191 191
     GetBitContext *gb = &h->s.gb;
192
-    int block, pred_mode_uv;
192
+    unsigned pred_mode_uv;
193
+    int block;
193 194
     uint8_t top[18];
194 195
     uint8_t *left = NULL;
195 196
     uint8_t *d;
... ...
@@ -445,6 +448,8 @@ static inline int check_for_slice(AVSContext *h) {
445 445
     if((show_bits_long(gb,24+align) & 0xFFFFFF) == 0x000001) {
446 446
         skip_bits_long(gb,24+align);
447 447
         h->stc = get_bits(gb,8);
448
+        if (h->stc >= h->mb_height)
449
+            return 0;
448 450
         decode_slice_header(h,gb);
449 451
         return 1;
450 452
     }
... ...
@@ -659,7 +664,7 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size,
659 659
     buf_end = buf + buf_size;
660 660
     for(;;) {
661 661
         buf_ptr = ff_find_start_code(buf_ptr,buf_end, &stc);
662
-        if(stc & 0xFFFFFE00)
662
+        if((stc & 0xFFFFFE00) || buf_ptr == buf_end)
663 663
             return FFMAX(0, buf_ptr - buf - s->parse_context.last_index);
664 664
         input_size = (buf_end - buf_ptr)*8;
665 665
         switch(stc) {