Browse code

Check for out of bound accesses in the 4xm decoder.

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit 9c661e952fbcbf044709f9a7031c68cc4860336b)

Signed-off-by: Michael Niedermayer <michaelni@gmx.at>

Laurent Aimar authored on 2011/10/02 07:38:27
Showing 1 changed files
... ...
@@ -133,7 +133,9 @@ typedef struct FourXContext{
133 133
     GetBitContext pre_gb;          ///< ac/dc prefix
134 134
     GetBitContext gb;
135 135
     const uint8_t *bytestream;
136
+    const uint8_t *bytestream_end;
136 137
     const uint16_t *wordstream;
138
+    const uint16_t *wordstream_end;
137 139
     int mv[256];
138 140
     VLC pre_vlc;
139 141
     int last_dc;
... ...
@@ -308,6 +310,8 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo
308 308
     assert(code>=0 && code<=6);
309 309
 
310 310
     if(code == 0){
311
+        if (f->bytestream_end - f->bytestream < 1)
312
+            return;
311 313
         src += f->mv[ *f->bytestream++ ];
312 314
         if(start > src || src > end){
313 315
             av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
... ...
@@ -325,15 +329,23 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo
325 325
     }else if(code == 3 && f->version<2){
326 326
         mcdc(dst, src, log2w, h, stride, 1, 0);
327 327
     }else if(code == 4){
328
+        if (f->bytestream_end - f->bytestream < 1)
329
+            return;
328 330
         src += f->mv[ *f->bytestream++ ];
329 331
         if(start > src || src > end){
330 332
             av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n");
331 333
             return;
332 334
         }
335
+        if (f->wordstream_end - f->wordstream < 1)
336
+            return;
333 337
         mcdc(dst, src, log2w, h, stride, 1, le2me_16(*f->wordstream++));
334 338
     }else if(code == 5){
339
+        if (f->wordstream_end - f->wordstream < 1)
340
+            return;
335 341
         mcdc(dst, src, log2w, h, stride, 0, le2me_16(*f->wordstream++));
336 342
     }else if(code == 6){
343
+        if (f->wordstream_end - f->wordstream < 2)
344
+            return;
337 345
         if(log2w){
338 346
             dst[0] = le2me_16(*f->wordstream++);
339 347
             dst[1] = le2me_16(*f->wordstream++);
... ...
@@ -355,6 +367,8 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){
355 355
 
356 356
     if(f->version>1){
357 357
         extra=20;
358
+        if (length < extra)
359
+            return -1;
358 360
         bitstream_size= AV_RL32(buf+8);
359 361
         wordstream_size= AV_RL32(buf+12);
360 362
         bytestream_size= AV_RL32(buf+16);
... ...
@@ -365,11 +379,10 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){
365 365
         bytestream_size= FFMAX(length - bitstream_size - wordstream_size, 0);
366 366
     }
367 367
 
368
-    if(bitstream_size+ bytestream_size+ wordstream_size + extra != length
369
-       || bitstream_size  > (1<<26)
370
-       || bytestream_size > (1<<26)
371
-       || wordstream_size > (1<<26)
372
-       ){
368
+    if (bitstream_size > length ||
369
+        bytestream_size > length - bitstream_size ||
370
+        wordstream_size > length - bytestream_size - bitstream_size ||
371
+        extra > length - bytestream_size - bitstream_size - wordstream_size){
373 372
         av_log(f->avctx, AV_LOG_ERROR, "lengths %d %d %d %d\n", bitstream_size, bytestream_size, wordstream_size,
374 373
         bitstream_size+ bytestream_size+ wordstream_size - length);
375 374
         return -1;
... ...
@@ -380,7 +393,9 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){
380 380
     init_get_bits(&f->gb, f->bitstream_buffer, 8*bitstream_size);
381 381
 
382 382
     f->wordstream= (const uint16_t*)(buf + extra + bitstream_size);
383
+    f->wordstream_end= f->wordstream + wordstream_size/2;
383 384
     f->bytestream= buf + extra + bitstream_size + wordstream_size;
385
+    f->bytestream_end = f->bytestream + bytestream_size;
384 386
 
385 387
     init_mv(f);
386 388
 
... ...
@@ -509,7 +524,7 @@ static int decode_i_mb(FourXContext *f){
509 509
     return 0;
510 510
 }
511 511
 
512
-static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf){
512
+static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf, int buf_size){
513 513
     int frequency[512];
514 514
     uint8_t flag[512];
515 515
     int up[512];
... ...
@@ -517,6 +532,7 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const
517 517
     int bits_tab[257];
518 518
     int start, end;
519 519
     const uint8_t *ptr= buf;
520
+    const uint8_t *ptr_end = buf + buf_size;
520 521
     int j;
521 522
 
522 523
     memset(frequency, 0, sizeof(frequency));
... ...
@@ -527,6 +543,8 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const
527 527
     for(;;){
528 528
         int i;
529 529
 
530
+        if (start <= end && ptr_end - ptr < end - start + 1 + 1)
531
+            return NULL;
530 532
         for(i=start; i<=end; i++){
531 533
             frequency[i]= *ptr++;
532 534
         }
... ...
@@ -599,10 +617,13 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){
599 599
     const int height= f->avctx->height;
600 600
     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
601 601
     const int stride= f->current_picture.linesize[0]>>1;
602
+    const uint8_t *buf_end = buf + length;
602 603
 
603 604
     for(y=0; y<height; y+=16){
604 605
         for(x=0; x<width; x+=16){
605 606
             unsigned int color[4], bits;
607
+            if (buf_end - buf < 8)
608
+                return -1;
606 609
             memset(color, 0, sizeof(color));
607 610
 //warning following is purely guessed ...
608 611
             color[0]= bytestream_get_le16(&buf);
... ...
@@ -636,18 +657,23 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){
636 636
     uint16_t *dst= (uint16_t*)f->current_picture.data[0];
637 637
     const int stride= f->current_picture.linesize[0]>>1;
638 638
     const unsigned int bitstream_size= AV_RL32(buf);
639
-    const int token_count av_unused = AV_RL32(buf + bitstream_size + 8);
640
-    unsigned int prestream_size= 4*AV_RL32(buf + bitstream_size + 4);
641
-    const uint8_t *prestream= buf + bitstream_size + 12;
639
+    unsigned int prestream_size;
640
+    const uint8_t *prestream;
641
+
642
+    if (bitstream_size > (1<<26) || length < bitstream_size + 12)
643
+        return -1;
644
+    prestream_size = 4*AV_RL32(buf + bitstream_size + 4);
645
+    prestream = buf + bitstream_size + 12;
642 646
 
643
-    if(prestream_size + bitstream_size + 12 != length
644
-       || bitstream_size > (1<<26)
645
-       || prestream_size > (1<<26)){
647
+    if (prestream_size > (1<<26) ||
648
+        prestream_size != length - (bitstream_size + 12)){
646 649
         av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length);
647 650
         return -1;
648 651
     }
649 652
 
650
-    prestream= read_huffman_tables(f, prestream);
653
+    prestream= read_huffman_tables(f, prestream, buf + length - prestream);
654
+    if (!prestream)
655
+        return -1;
651 656
 
652 657
     init_get_bits(&f->gb, buf + 4, 8*bitstream_size);
653 658
 
... ...
@@ -684,6 +710,8 @@ static int decode_frame(AVCodecContext *avctx,
684 684
     AVFrame *p, temp;
685 685
     int i, frame_4cc, frame_size;
686 686
 
687
+    if (buf_size < 12)
688
+        return AVERROR_INVALIDDATA;
687 689
     frame_4cc= AV_RL32(buf);
688 690
     if(buf_size != AV_RL32(buf+4)+8 || buf_size < 20){
689 691
         av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, AV_RL32(buf+4));
... ...
@@ -696,6 +724,9 @@ static int decode_frame(AVCodecContext *avctx,
696 696
         const int whole_size= AV_RL32(buf+16);
697 697
         CFrameBuffer *cfrm;
698 698
 
699
+        if (data_size < 0 || whole_size < 0)
700
+            return AVERROR_INVALIDDATA;
701
+
699 702
         for(i=0; i<CFRAME_BUFFER_COUNT; i++){
700 703
             if(f->cfrm[i].id && f->cfrm[i].id < avctx->frame_number)
701 704
                 av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id);
... ...
@@ -712,6 +743,8 @@ static int decode_frame(AVCodecContext *avctx,
712 712
         }
713 713
         cfrm= &f->cfrm[i];
714 714
 
715
+        if (data_size > UINT_MAX -  cfrm->size - FF_INPUT_BUFFER_PADDING_SIZE)
716
+            return AVERROR_INVALIDDATA;
715 717
         cfrm->data= av_fast_realloc(cfrm->data, &cfrm->allocated_size, cfrm->size + data_size + FF_INPUT_BUFFER_PADDING_SIZE);
716 718
         if(!cfrm->data){ //explicit check needed as memcpy below might not catch a NULL
717 719
             av_log(f->avctx, AV_LOG_ERROR, "realloc falure");