row_mt worker should check for bit reader overflow
This is the row_mt version of bug oss-fuzz:9663. The row_mt worker
should also check if the entropy decoder has read beyond the end of the
data buffer.
Move most of the code inside the first while loop in
row_mt_worker_hook() to the new parse_tile_row_mt() function. The check
for bit reader overflow is performed in parse_tile_row_mt(). One reason
for adding the new parse_tile_row_mt() function is to highlight its
similarity to the decode_tile() function,
Move the set_decode_func_pointers(td, 0x1) call in row_mt_worker_hook()
from inside the first while loop to the outside, so that it is called
only once.
BUG=oss-fuzz:10646,oss-fuzz:9663
Change-Id: I39735bb7dd8b879985e6cf87e8a24b9dbcd01a34
(cherry picked from commit fe9ce8d6c9a26057d77def3e8dde4d87c63b642c)
diff --git a/av1/decoder/decodeframe.c b/av1/decoder/decodeframe.c
index 81cd879..04e9d63 100644
--- a/av1/decoder/decodeframe.c
+++ b/av1/decoder/decodeframe.c
@@ -3436,13 +3436,53 @@
#endif
}
+// This function is very similar to decode_tile(). It would be good to figure
+// out how to share code.
+static void parse_tile_row_mt(AV1Decoder *pbi, ThreadData *const td,
+ TileDataDec *const tile_data) {
+ AV1_COMMON *const cm = &pbi->common;
+ const int sb_mi_size = mi_size_wide[cm->seq_params.sb_size];
+ const int num_planes = av1_num_planes(cm);
+ TileInfo tile_info = tile_data->tile_info;
+ int tile_row = tile_info.tile_row;
+
+ av1_zero_above_context(cm, &td->xd, tile_info.mi_col_start,
+ tile_info.mi_col_end, tile_row);
+ av1_reset_loop_filter_delta(&td->xd, num_planes);
+ av1_reset_loop_restoration(&td->xd, num_planes);
+
+ for (int mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end;
+ mi_row += cm->seq_params.mib_size) {
+ av1_zero_left_context(&td->xd);
+
+ for (int mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
+ mi_col += cm->seq_params.mib_size) {
+ set_cb_buffer(pbi, &td->xd, pbi->cb_buffer_base, num_planes, mi_row,
+ mi_col);
+
+ // Bit-stream parsing of the superblock
+ decode_partition(pbi, td, mi_row, mi_col, td->bit_reader,
+ cm->seq_params.sb_size, 0x1);
+
+ if (aom_reader_has_overflowed(td->bit_reader)) {
+ aom_merge_corrupted_flag(&td->xd.corrupted, 1);
+ return;
+ }
+ }
+ signal_parse_sb_row_done(pbi, tile_data, sb_mi_size);
+ }
+
+ int corrupted =
+ (check_trailing_bits_after_symbol_coder(td->bit_reader)) ? 1 : 0;
+ aom_merge_corrupted_flag(&td->xd.corrupted, corrupted);
+}
+
static int row_mt_worker_hook(void *arg1, void *arg2) {
DecWorkerData *const thread_data = (DecWorkerData *)arg1;
AV1Decoder *const pbi = (AV1Decoder *)arg2;
AV1_COMMON *cm = &pbi->common;
ThreadData *const td = thread_data->td;
uint8_t allow_update_cdf;
- const int sb_mi_size = mi_size_wide[cm->seq_params.sb_size];
AV1DecRowMTInfo *frame_row_mt_info = &pbi->frame_row_mt_info;
td->xd.corrupted = 0;
@@ -3464,10 +3504,11 @@
}
thread_data->error_info.setjmp = 1;
- const int num_planes = av1_num_planes(cm);
allow_update_cdf = cm->large_scale_tile ? 0 : 1;
allow_update_cdf = allow_update_cdf && !cm->disable_cdf_update;
+ set_decode_func_pointers(td, 0x1);
+
assert(cm->tile_cols > 0);
while (1) {
TileJobsDec *cur_job_info = get_dec_job_info(&pbi->tile_mt_info);
@@ -3478,36 +3519,8 @@
tile_worker_hook_init(pbi, thread_data, tile_buffer, tile_data,
allow_update_cdf);
- set_decode_func_pointers(td, 0x1);
-
// decode tile
- TileInfo tile_info = tile_data->tile_info;
- int tile_row = tile_info.tile_row;
-
- av1_zero_above_context(cm, &td->xd, tile_info.mi_col_start,
- tile_info.mi_col_end, tile_row);
- av1_reset_loop_filter_delta(&td->xd, num_planes);
- av1_reset_loop_restoration(&td->xd, num_planes);
-
- for (int mi_row = tile_info.mi_row_start; mi_row < tile_info.mi_row_end;
- mi_row += cm->seq_params.mib_size) {
- av1_zero_left_context(&td->xd);
-
- for (int mi_col = tile_info.mi_col_start; mi_col < tile_info.mi_col_end;
- mi_col += cm->seq_params.mib_size) {
- set_cb_buffer(pbi, &td->xd, pbi->cb_buffer_base, num_planes, mi_row,
- mi_col);
-
- // Bit-stream parsing of the superblock
- decode_partition(pbi, td, mi_row, mi_col, td->bit_reader,
- cm->seq_params.sb_size, 0x1);
- }
- signal_parse_sb_row_done(pbi, tile_data, sb_mi_size);
- }
-
- int corrupted =
- (check_trailing_bits_after_symbol_coder(td->bit_reader)) ? 1 : 0;
- aom_merge_corrupted_flag(&td->xd.corrupted, corrupted);
+ parse_tile_row_mt(pbi, td, tile_data);
} else {
break;
}