From: Jim Bankoski Date: Fri, 27 Jun 2014 17:03:15 +0000 (-0700) Subject: Better validation of invalid files X-Git-Tag: v1.4.0~1319^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9f37d149c1d323fc9e8fbca586d719866674dcd8;p=platform%2Fupstream%2Flibvpx.git Better validation of invalid files This patch checks that a decoder never tries to reference frame that's outside the range of 2x to 1/16th the size of this frame. Any attempt to do so causes a failure. Change-Id: I5c98fa7bb95ac4f29146f29dd92b62fe96164e4c --- diff --git a/test/invalid_file_test.cc b/test/invalid_file_test.cc index 4933658..d3f370e 100644 --- a/test/invalid_file_test.cc +++ b/test/invalid_file_test.cc @@ -97,6 +97,7 @@ const char *const kVP9InvalidFileTests[] = { "invalid-vp90-01.webm", "invalid-vp90-02.webm", "invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.ivf", + "invalid-vp90-03.webm", }; #define NELEMENTS(x) static_cast(sizeof(x) / sizeof(x[0])) diff --git a/test/test-data.sha1 b/test/test-data.sha1 index bc6f77e..1c960c0 100644 --- a/test/test-data.sha1 +++ b/test/test-data.sha1 @@ -4,6 +4,8 @@ fe346136b9b8c1e6f6084cc106485706915795e4 invalid-vp90-01.webm 25751f5d3b05ff03f0719ad42cd625348eb8961e invalid-vp90-01.webm.res d78e2fceba5ac942246503ec8366f879c4775ca5 invalid-vp90-02.webm 2dadee5306245fa5eeb0f99652d0e17afbcba96d invalid-vp90-02.webm.res +df1a1453feb3c00d7d89746c7003b4163523bff3 invalid-vp90-03.webm +8fe6fd82bf537340f586f97a7ae31fb37ccda302 invalid-vp90-03.webm.res b1f1c3ec79114b9a0651af24ce634afb44a9a419 rush_hour_444.y4m 5184c46ddca8b1fadd16742e8500115bc8f749da vp80-00-comprehensive-001.ivf 65bf1bbbced81b97bd030f376d1b7f61a224793f vp80-00-comprehensive-002.ivf diff --git a/test/test.mk b/test/test.mk index af344e5..f09b0b4 100644 --- a/test/test.mk +++ b/test/test.mk @@ -766,6 +766,8 @@ LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-01.webm.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02.webm LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-02.webm.res +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03.webm +LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-03.webm.res LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.ivf LIBVPX_TEST_DATA-$(CONFIG_VP9_DECODER) += invalid-vp90-2-00-quantizer-00.webm.ivf.s5861_r01-05_b6-.ivf.res diff --git a/vp9/common/vp9_frame_buffers.c b/vp9/common/vp9_frame_buffers.c index a0b1e03..733b3a9 100644 --- a/vp9/common/vp9_frame_buffers.c +++ b/vp9/common/vp9_frame_buffers.c @@ -76,6 +76,7 @@ int vp9_get_frame_buffer(void *cb_priv, size_t min_size, int vp9_release_frame_buffer(void *cb_priv, vpx_codec_frame_buffer_t *fb) { InternalFrameBuffer *const int_fb = (InternalFrameBuffer *)fb->priv; (void)cb_priv; - int_fb->in_use = 0; + if (int_fb) + int_fb->in_use = 0; return 0; } diff --git a/vp9/common/vp9_scale.c b/vp9/common/vp9_scale.c index d3405fc..2f58323 100644 --- a/vp9/common/vp9_scale.c +++ b/vp9/common/vp9_scale.c @@ -33,14 +33,6 @@ static int get_fixed_point_scale_factor(int other_size, int this_size) { return (other_size << REF_SCALE_SHIFT) / this_size; } -static int check_scale_factors(int other_w, int other_h, - int this_w, int this_h) { - return 2 * this_w >= other_w && - 2 * this_h >= other_h && - this_w <= 16 * other_w && - this_h <= 16 * other_h; -} - MV32 vp9_scale_mv(const MV *mv, int x, int y, const struct scale_factors *sf) { const int x_off_q4 = scaled_x(x << SUBPEL_BITS, sf) & SUBPEL_MASK; const int y_off_q4 = scaled_y(y << SUBPEL_BITS, sf) & SUBPEL_MASK; @@ -54,7 +46,7 @@ MV32 vp9_scale_mv(const MV *mv, int x, int y, const struct scale_factors *sf) { void vp9_setup_scale_factors_for_frame(struct scale_factors *sf, int other_w, int other_h, int this_w, int this_h) { - if (!check_scale_factors(other_w, other_h, this_w, this_h)) { + if (!valid_ref_frame_size(other_w, other_h, this_w, this_h)) { sf->x_scale_fp = REF_INVALID_SCALE; sf->y_scale_fp = REF_INVALID_SCALE; return; diff --git a/vp9/common/vp9_scale.h b/vp9/common/vp9_scale.h index 04aae65..ad6f5d7 100644 --- a/vp9/common/vp9_scale.h +++ b/vp9/common/vp9_scale.h @@ -50,6 +50,14 @@ static INLINE int vp9_is_scaled(const struct scale_factors *sf) { (sf->x_scale_fp != REF_NO_SCALE || sf->y_scale_fp != REF_NO_SCALE); } +static INLINE int valid_ref_frame_size(int ref_width, int ref_height, + int this_width, int this_height) { + return 2 * this_width >= ref_width && + 2 * this_height >= ref_height && + this_width <= 16 * ref_width && + this_height <= 16 * ref_height; +} + #ifdef __cplusplus } // extern "C" #endif diff --git a/vp9/decoder/vp9_decodeframe.c b/vp9/decoder/vp9_decodeframe.c index 9220a9e..1effef3 100644 --- a/vp9/decoder/vp9_decodeframe.c +++ b/vp9/decoder/vp9_decodeframe.c @@ -667,9 +667,17 @@ static void setup_frame_size_with_refs(VP9_COMMON *cm, if (!found) read_frame_size(rb, &width, &height); - if (width <= 0 || height <= 0) - vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, - "Referenced frame with invalid size"); + // Check that each of the frames that this frame references has valid + // dimensions. + for (i = 0; i < REFS_PER_FRAME; ++i) { + RefBuffer *const ref_frame = &cm->frame_refs[i]; + const int ref_width = ref_frame->buf->y_width; + const int ref_height = ref_frame->buf->y_height; + + if (!valid_ref_frame_size(ref_width, ref_height, width, height)) + vpx_internal_error(&cm->error, VPX_CODEC_CORRUPT_FRAME, + "Referenced frame has invalid size"); + } apply_frame_size(cm, width, height); setup_display_size(cm, rb); @@ -1142,12 +1150,12 @@ static size_t read_uncompressed_header(VP9Decoder *pbi, setup_frame_size(cm, rb); } else { pbi->refresh_frame_flags = vp9_rb_read_literal(rb, REF_FRAMES); - for (i = 0; i < REFS_PER_FRAME; ++i) { const int ref = vp9_rb_read_literal(rb, REF_FRAMES_LOG2); const int idx = cm->ref_frame_map[ref]; - cm->frame_refs[i].idx = idx; - cm->frame_refs[i].buf = &cm->frame_bufs[idx].buf; + RefBuffer *const ref_frame = &cm->frame_refs[i]; + ref_frame->idx = idx; + ref_frame->buf = &cm->frame_bufs[idx].buf; cm->ref_frame_sign_bias[LAST_FRAME + i] = vp9_rb_read_bit(rb); }