From 2bcc4736028e41862191916ffd711651d14519e1 Mon Sep 17 00:00:00 2001 From: John Koleszar <jkoleszar@google.com> Date: Tue, 11 Jun 2013 10:06:31 -0700 Subject: [PATCH] decode_tiles(): validate buffer reads Previous code indexed using the tile length coded in the bitstream without checking that the read would be valid. Change-Id: Ia5047762223a4f80d75016dd546dc2ef18b6887d --- vp9/decoder/vp9_decodframe.c | 37 ++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c index fa1f8a46d7..f65d7c7cfb 100644 --- a/vp9/decoder/vp9_decodframe.c +++ b/vp9/decoder/vp9_decodframe.c @@ -539,21 +539,19 @@ static void decode_modes_sb(VP9D_COMP *pbi, int mi_row, int mi_col, } static void setup_token_decoder(VP9D_COMP *pbi, - const uint8_t *data, + const uint8_t *data, size_t read_size, vp9_reader *r) { VP9_COMMON *pc = &pbi->common; const uint8_t *data_end = pbi->source + pbi->source_sz; - const size_t partition_size = data_end - data; // 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(data, partition_size, data_end)) + if (!read_is_valid(data, read_size, data_end)) vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet or corrupt partition " - "%d length", 1); + "Truncated packet or corrupt tile length"); - if (vp9_reader_init(r, data, partition_size)) + if (vp9_reader_init(r, data, read_size)) vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR, "Failed to allocate bool decoder %d", 1); } @@ -889,6 +887,7 @@ static void decode_tiles(VP9D_COMP *pbi, VP9_COMMON *const pc = &pbi->common; const uint8_t *data_ptr = data + first_partition_size; + const uint8_t* const data_end = pbi->source + pbi->source_sz; int tile_row, tile_col; // Note: this memset assumes above_context[0], [1] and [2] @@ -925,7 +924,9 @@ static void decode_tiles(VP9D_COMP *pbi, vp9_get_tile_row_offsets(pc, tile_row); for (tile_col = n_cols - 1; tile_col >= 0; tile_col--) { vp9_get_tile_col_offsets(pc, tile_col); - setup_token_decoder(pbi, data_ptr2[tile_row][tile_col], residual_bc); + setup_token_decoder(pbi, data_ptr2[tile_row][tile_col], + data_end - data_ptr2[tile_row][tile_col], + residual_bc); decode_tile(pbi, residual_bc); if (tile_row == pc->tile_rows - 1 && tile_col == n_cols - 1) bc_bak = *residual_bc; @@ -938,18 +939,26 @@ static void decode_tiles(VP9D_COMP *pbi, for (tile_row = 0; tile_row < pc->tile_rows; tile_row++) { vp9_get_tile_row_offsets(pc, tile_row); for (tile_col = 0; tile_col < pc->tile_columns; tile_col++) { + size_t size; + vp9_get_tile_col_offsets(pc, tile_col); has_more = tile_col < pc->tile_columns - 1 || tile_row < pc->tile_rows - 1; - - setup_token_decoder(pbi, data_ptr + (has_more ? 4 : 0), residual_bc); - decode_tile(pbi, residual_bc); - if (has_more) { - const int size = read_be32(data_ptr); - data_ptr += 4 + size; + if (!read_is_valid(data_ptr, 4, data_end)) + vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, + "Truncated packet or corrupt tile length"); + + size = read_be32(data_ptr); + data_ptr += 4; + } else { + size = data_end - data_ptr; } + + setup_token_decoder(pbi, data_ptr, size, residual_bc); + decode_tile(pbi, residual_bc); + data_ptr += size; } } } @@ -1146,7 +1155,7 @@ int vp9_decode_frame(VP9D_COMP *pbi, const uint8_t **p_data_end) { if (!read_is_valid(data, first_partition_size, data_end)) vpx_internal_error(&pc->error, VPX_CODEC_CORRUPT_FRAME, - "Truncated packet or corrupt partition 0 length"); + "Truncated packet or corrupt header length"); xd->mode_info_context = pc->mi; xd->prev_mode_info_context = pc->prev_mi; -- GitLab