From 440f5097c7c402b904285af31c89e4064fadbaff Mon Sep 17 00:00:00 2001 From: James Zern Date: Thu, 4 Sep 2014 15:11:45 -0700 Subject: [PATCH 1/2] vp9: fail decode if block/frame refs are corrupt proceeding using a corrupt (incompletely decoded) frame reference may lead to incorrect assumptions about allocation sizes leading to a crash. Change-Id: I76e74f2e1be127c2e2c7e1174bb3307497dfd23d --- test/invalid_file_test.cc | 3 ++- test/test-data.sha1 | 6 ++++-- test/test.mk | 6 ++++-- vp9/decoder/vp9_decodeframe.c | 7 +++++++ 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/test/invalid_file_test.cc b/test/invalid_file_test.cc index cf86cf50e..39619165a 100644 --- a/test/invalid_file_test.cc +++ b/test/invalid_file_test.cc @@ -113,9 +113,10 @@ TEST_P(InvalidFileTest, ReturnCode) { const DecodeParam kVP9InvalidFileTests[] = { {1, "invalid-vp90-02-v2.webm"}, {1, "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf"}, - {1, "invalid-vp90-03-v2.webm"}, + {1, "invalid-vp90-03-v3.webm"}, {1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf"}, {1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf"}, + {1, "invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf"}, }; VP9_INSTANTIATE_TEST_CASE(InvalidFileTest, diff --git a/test/test-data.sha1 b/test/test-data.sha1 index 61667492e..5f3bc344e 100644 --- a/test/test-data.sha1 +++ b/test/test-data.sha1 @@ -10,8 +10,8 @@ fe346136b9b8c1e6f6084cc106485706915795e4 invalid-vp90-01-v2.webm 25751f5d3b05ff03f0719ad42cd625348eb8961e invalid-vp90-01-v2.webm.res d78e2fceba5ac942246503ec8366f879c4775ca5 invalid-vp90-02-v2.webm 8e2eff4af87d2b561cce2365713269e301457ef3 invalid-vp90-02-v2.webm.res -df1a1453feb3c00d7d89746c7003b4163523bff3 invalid-vp90-03-v2.webm -25dd58c22d23f75304d7ce7f69f4e5b02ef9119a invalid-vp90-03-v2.webm.res +df1a1453feb3c00d7d89746c7003b4163523bff3 invalid-vp90-03-v3.webm +4935c62becc68c13642a03db1e6d3e2331c1c612 invalid-vp90-03-v3.webm.res d637297561dd904eb2c97a9015deeb31c4a1e8d2 invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm 3a204bdbeaa3c6458b77bcebb8366d107267f55d invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm.res a432f96ff0a787268e2f94a8092ab161a18d1b06 park_joy_90p_10_420.y4m @@ -691,3 +691,5 @@ d3ea592c8d7b05d14c7ed48befc0a3aaf7709b7a invalid-vp90-2-09-subpixel-00.ivf.s195 368dccdde5288c13c25695d2eacdc7402cadf613 vp90-2-19-skip.webm.md5 ffe460282df2b0e7d4603c2158653ad96f574b02 vp90-2-19-skip-01.webm bd21bc9eda4a4a36b221d71ede3a139fc3c7bd85 vp90-2-19-skip-01.webm.md5 +b03c408cf23158638da18dbc3323b99a1635c68a invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf +0a3884edb3fd8f9d9b500223e650f7de257b67d8 invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf.res diff --git a/test/test.mk b/test/test.mk index 7c341698f..0ffa19080 100644 --- a/test/test.mk +++ b/test/test.mk @@ -797,8 +797,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v2.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01-v2.webm.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02-v2.webm.res -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v2.webm -LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v2.webm.res +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v3.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03-v3.webm.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.v2.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf @@ -813,6 +813,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.ivf.res +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf.res ifeq ($(CONFIG_DECODE_PERF_TESTS),yes) # BBB VP9 streams diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index 372dc83c8..eba5a5093 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -330,6 +330,9 @@ static void set_ref(VP9_COMMON *const cm, MACROBLOCKD *const xd, if (!vp9_is_valid_scale(&ref_buffer->sf)) vpx_internal_error(&cm->error, VPX_CODEC_UNSUP_BITSTREAM, "Invalid scale factors"); + if (ref_buffer->buf->corrupted) + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, + "Block reference is corrupt"); vp9_setup_pre_planes(xd, idx, ref_buffer->buf, mi_row, mi_col, &ref_buffer->sf); xd->corrupted |= ref_buffer->buf->corrupted; @@ -675,6 +678,10 @@ static void setup_frame_size_with_refs(VP9_COMMON *cm, YV12_BUFFER_CONFIG *const buf = cm->frame_refs[i].buf; width = buf->y_crop_width; height = buf->y_crop_height; + if (buf->corrupted) { + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, + "Frame reference is corrupt"); + } found = 1; break; } From bb4950dfdf0610080648aae5b717384e6c689e63 Mon Sep 17 00:00:00 2001 From: James Zern Date: Thu, 4 Sep 2014 16:05:18 -0700 Subject: [PATCH 2/2] vp9: correct context buffer resize check allocations within vp9_alloc_context_buffers() rely on mi_rows/mi_cols individually, use those to determine whether to realloc rather than stride and stride * rows. this fixes a crash with some fuzzed files for invalid accesses into last_frame_seg_map and above_context. Change-Id: I7b9f40dcf170d443890f3bd2acd285507943c7d4 --- test/invalid_file_test.cc | 2 ++ test/test-data.sha1 | 4 ++++ test/test.mk | 4 ++++ vp9/decoder/vp9_decodeframe.c | 10 ++++++---- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/test/invalid_file_test.cc b/test/invalid_file_test.cc index 39619165a..50e7c234a 100644 --- a/test/invalid_file_test.cc +++ b/test/invalid_file_test.cc @@ -117,6 +117,8 @@ const DecodeParam kVP9InvalidFileTests[] = { {1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf"}, {1, "invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf"}, {1, "invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf"}, + {1, "invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf"}, + {1, "invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.ivf"}, }; VP9_INSTANTIATE_TEST_CASE(InvalidFileTest, diff --git a/test/test-data.sha1 b/test/test-data.sha1 index 5f3bc344e..84b13f934 100644 --- a/test/test-data.sha1 +++ b/test/test-data.sha1 @@ -693,3 +693,7 @@ ffe460282df2b0e7d4603c2158653ad96f574b02 vp90-2-19-skip-01.webm bd21bc9eda4a4a36b221d71ede3a139fc3c7bd85 vp90-2-19-skip-01.webm.md5 b03c408cf23158638da18dbc3323b99a1635c68a invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf 0a3884edb3fd8f9d9b500223e650f7de257b67d8 invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf.res +5e67e24e7f53fd189e565513cef8519b1bd6c712 invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf +741158f67c0d9d23726624d06bdc482ad368afc9 invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf.res +8b1f7bf7e86c0976d277f60e8fcd9539e75a079a invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.ivf +fb79dcbbbb8c82d5a750e339acce66e39a32f15f invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.ivf.res diff --git a/test/test.mk b/test/test.mk index 0ffa19080..c839c92f6 100644 --- a/test/test.mk +++ b/test/test.mk @@ -805,6 +805,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.iv LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-11.webm.ivf.s52984_r01-05_b6-z.ivf.res +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-05-resize.ivf.s59293_r01-05_b6-.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x2_frame_parallel.webm.ivf.s47039_r01-05_b6-.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-08-tile_1x4_frame_parallel_all_key.webm @@ -813,6 +815,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-aq2.webm.ivf.s3984_r01-05_b6-.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s19552_r01-05_b6-.ivf.res +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.ivf +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-09-subpixel-00.ivf.s20492_r01-05_b6-.ivf.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-12-droppable_1.ivf.s3676_r01-05_b6-.ivf.res diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index eba5a5093..6b893348c 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -631,11 +631,13 @@ static void resize_context_buffers(VP9_COMMON *cm, int width, int height) { #endif if (cm->width != width || cm->height != height) { const int new_mi_rows = - calc_mi_size(ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2) >> MI_SIZE_LOG2); + ALIGN_POWER_OF_TWO(height, MI_SIZE_LOG2) >> MI_SIZE_LOG2; const int new_mi_cols = - calc_mi_size(ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2) >> MI_SIZE_LOG2); - if (new_mi_cols > cm->mi_stride || - (new_mi_rows * new_mi_cols > cm->mi_alloc_size)) { + ALIGN_POWER_OF_TWO(width, MI_SIZE_LOG2) >> MI_SIZE_LOG2; + + // Allocations in vp9_alloc_context_buffers() depend on individual + // dimensions as well as the overall size. + if (new_mi_cols > cm->mi_cols || new_mi_rows > cm->mi_rows) { if (vp9_alloc_context_buffers(cm, width, height)) vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, "Failed to allocate context buffers");