shithub: libvpx

Download patch

ref: 09bcc1f710ea65dc158639479288fb1908ff0c53
parent: a8a38bcf10f2beba39a41ce3c469ff02caebd2ca
author: Timothy B. Terriberry <tterribe@xiph.org>
date: Tue Oct 19 11:40:46 EDT 2010

Improve handling of invalid frames.

The code was not checking for frame sizes smaller than 3 bytes, and the
 partition size checks might have failed if the input buffer was within
 16MB of the top of the heap.
In addition, the reference count on the current frame buffer was not
 being decremented on error, so after a small number of errors, no new
 frame buffer could be found and it would run off the list of them.

Change-Id: I0c60dba6adb1e2a29df39754f72a56ab6c776b46

--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -462,7 +462,7 @@
             partition_size = user_data_end - partition;
         }
 
-        if (partition + partition_size > user_data_end)
+        if (user_data_end - partition < partition_size)
             vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
                                "Truncated packet or corrupt partition "
                                "%d length", i + 1);
@@ -564,12 +564,15 @@
     MACROBLOCKD *const xd  = & pbi->mb;
     const unsigned char *data = (const unsigned char *)pbi->Source;
     const unsigned char *const data_end = data + pbi->source_sz;
-    int first_partition_length_in_bytes;
+    unsigned int first_partition_length_in_bytes;
 
     int mb_row;
     int i, j, k, l;
     const int *const mb_feature_data_bits = vp8_mb_feature_data_bits;
 
+    if (data_end - data < 3)
+        vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+                           "Truncated packet");
     pc->frame_type = (FRAME_TYPE)(data[0] & 1);
     pc->version = (data[0] >> 1) & 7;
     pc->show_frame = (data[0] >> 4) & 1;
@@ -577,7 +580,7 @@
         (data[0] | (data[1] << 8) | (data[2] << 16)) >> 5;
     data += 3;
 
-    if (data + first_partition_length_in_bytes > data_end)
+    if (data_end - data < first_partition_length_in_bytes)
         vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
                            "Truncated packet or corrupt partition 0 length");
     vp8_setup_version(pc);
--- a/vp8/decoder/onyxd_if.c
+++ b/vp8/decoder/onyxd_if.c
@@ -327,9 +327,13 @@
 
     pbi->common.error.error_code = VPX_CODEC_OK;
 
+    cm->new_fb_idx = get_free_fb (cm);
+
     if (setjmp(pbi->common.error.jmp))
     {
         pbi->common.error.setjmp = 0;
+        if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
+          cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
         return -1;
     }
 
@@ -345,8 +349,6 @@
     pbi->Source = source;
     pbi->source_sz = size;
 
-    cm->new_fb_idx = get_free_fb (cm);
-
     retcode = vp8_decode_frame(pbi);
 
     if (retcode < 0)
@@ -356,6 +358,8 @@
 #endif
         pbi->common.error.error_code = VPX_CODEC_ERROR;
         pbi->common.error.setjmp = 0;
+        if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
+          cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
         return retcode;
     }