From: Timothy B. Terriberry Date: Tue, 19 Oct 2010 22:40:46 +0000 (-0700) Subject: Improve handling of invalid frames. X-Git-Tag: 1.0_branch~804^2~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=09bcc1f710ea65dc158639479288fb1908ff0c53;p=profile%2Fivi%2Flibvpx.git 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 --- diff --git a/vp8/decoder/decodframe.c b/vp8/decoder/decodframe.c index efe0ad8..2d81d61 100644 --- a/vp8/decoder/decodframe.c +++ b/vp8/decoder/decodframe.c @@ -462,7 +462,7 @@ static void setup_token_decoder(VP8D_COMP *pbi, 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 @@ int vp8_decode_frame(VP8D_COMP *pbi) 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 @@ int vp8_decode_frame(VP8D_COMP *pbi) (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); diff --git a/vp8/decoder/onyxd_if.c b/vp8/decoder/onyxd_if.c index 7d716b0..884c38d 100644 --- a/vp8/decoder/onyxd_if.c +++ b/vp8/decoder/onyxd_if.c @@ -327,9 +327,13 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign 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 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign 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 @@ int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsign #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; }