summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Koleszar <jkoleszar@google.com>2011-08-05 12:27:25 -0400
committerJohn Koleszar <jkoleszar@google.com>2011-08-11 18:07:03 -0400
commit810a06b12caf7206bf8ed78c8abfb04620b2a90c (patch)
tree25d97dbc413e390ea8bb12c29ac6cbd684698415
parentb84e8f20c3aca0f2a65265cf704cc7c15a2c93d4 (diff)
downloadlibvpx-810a06b12caf7206bf8ed78c8abfb04620b2a90c.tar
libvpx-810a06b12caf7206bf8ed78c8abfb04620b2a90c.tar.gz
libvpx-810a06b12caf7206bf8ed78c8abfb04620b2a90c.tar.bz2
libvpx-810a06b12caf7206bf8ed78c8abfb04620b2a90c.zip
Fix potential OOB read with Error Concealment
This patch fixes an OOB read when error concealment is enabled and the partition sizes are corrupt. The partition size read from the bitstream was not being validated in EC mode. Change-Id: Ia81dfd4bce1ab29ee78e42320abe52cee8318974
-rw-r--r--vp8/decoder/decodframe.c45
1 files changed, 35 insertions, 10 deletions
diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c
index 9b35ffd66..5ddf09567 100644
--- a/vp8/decoder/decodframe.c
+++ b/vp8/decoder/decodframe.c
@@ -495,6 +495,15 @@ static void setup_token_decoder_partition_input(VP8D_COMP *pbi)
#endif
}
+
+static int read_is_valid(const unsigned char *start,
+ size_t len,
+ const unsigned char *end)
+{
+ return (start + len > start && start + len <= end);
+}
+
+
static void setup_token_decoder(VP8D_COMP *pbi,
const unsigned char *cx_data)
{
@@ -529,26 +538,42 @@ static void setup_token_decoder(VP8D_COMP *pbi,
for (i = 0; i < num_part; i++)
{
const unsigned char *partition_size_ptr = cx_data + i * 3;
- ptrdiff_t partition_size;
+ ptrdiff_t partition_size, bytes_left;
+
+ bytes_left = user_data_end - partition;
/* Calculate the length of this partition. The last partition
- * size is implicit.
+ * size is implicit. If the partition size can't be read, then
+ * either use the remaining data in the buffer (for EC mode)
+ * or throw an error.
*/
if (i < num_part - 1)
{
- partition_size = read_partition_size(partition_size_ptr);
+ if (read_is_valid(partition_size_ptr, 3, user_data_end))
+ partition_size = read_partition_size(partition_size_ptr);
+ else if(pbi->ec_enabled)
+ partition_size = bytes_left;
+ else
+ vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+ "Truncated partition size data");
}
else
+ partition_size = bytes_left;
+
+ /* Validate the calculated partition length. If the buffer
+ * described by the partition can't be fully read, then restrict
+ * it to the portion that can be (for EC mode) or throw an error.
+ */
+ if (!read_is_valid(partition, partition_size, user_data_end))
{
- partition_size = user_data_end - partition;
+ if(pbi->ec_enabled)
+ partition_size = bytes_left;
+ else
+ vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
+ "Truncated packet or corrupt partition "
+ "%d length", i + 1);
}
- if (!pbi->ec_enabled && (partition + partition_size > user_data_end
- || partition + partition_size < partition))
- vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME,
- "Truncated packet or corrupt partition "
- "%d length", i + 1);
-
if (vp8dx_start_decode(bool_decoder, partition, partition_size))
vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
"Failed to allocate bool decoder %d", i + 1);