Commit a105f528 authored by Michael Niedermayer's avatar Michael Niedermayer

avcodec/error_resilience: avoid accessing previous or next frames tables beyond height

The height of tables can be rounded up for MBAFF but this does not imply that is also true
for the previous frames

Fixes out of array reads
Fixes: c106b36fa36db8ff8f3ed0c82be7bea2/asan_heap-oob_32699f0_6321_467b9a1d7e03d7cfd310b7e65dc53bcc.mov

Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
Signed-off-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
parent 603ebab8
...@@ -381,14 +381,19 @@ static void guess_mv(ERContext *s) ...@@ -381,14 +381,19 @@ static void guess_mv(ERContext *s)
#define MV_UNCHANGED 1 #define MV_UNCHANGED 1
const int mb_stride = s->mb_stride; const int mb_stride = s->mb_stride;
const int mb_width = s->mb_width; const int mb_width = s->mb_width;
const int mb_height = s->mb_height; int mb_height = s->mb_height;
int i, depth, num_avail; int i, depth, num_avail;
int mb_x, mb_y, mot_step, mot_stride; int mb_x, mb_y, mot_step, mot_stride;
if (s->last_pic.f && s->last_pic.f->data[0])
mb_height = FFMIN(mb_height, (s->last_pic.f->height+15)>>4);
if (s->next_pic.f && s->next_pic.f->data[0])
mb_height = FFMIN(mb_height, (s->next_pic.f->height+15)>>4);
set_mv_strides(s, &mot_step, &mot_stride); set_mv_strides(s, &mot_step, &mot_stride);
num_avail = 0; num_avail = 0;
for (i = 0; i < s->mb_num; i++) { for (i = 0; i < mb_width * mb_height; i++) {
const int mb_xy = s->mb_index2xy[i]; const int mb_xy = s->mb_index2xy[i];
int f = 0; int f = 0;
int error = s->error_status_table[mb_xy]; int error = s->error_status_table[mb_xy];
...@@ -413,7 +418,7 @@ static void guess_mv(ERContext *s) ...@@ -413,7 +418,7 @@ static void guess_mv(ERContext *s)
if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||
num_avail <= mb_width / 2) { num_avail <= mb_width / 2) {
for (mb_y = 0; mb_y < s->mb_height; mb_y++) { for (mb_y = 0; mb_y < mb_height; mb_y++) {
for (mb_x = 0; mb_x < s->mb_width; mb_x++) { for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
const int mb_xy = mb_x + mb_y * s->mb_stride; const int mb_xy = mb_x + mb_y * s->mb_stride;
int mv_dir = (s->last_pic.f && s->last_pic.f->data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD; int mv_dir = (s->last_pic.f && s->last_pic.f->data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD;
...@@ -442,7 +447,7 @@ static void guess_mv(ERContext *s) ...@@ -442,7 +447,7 @@ static void guess_mv(ERContext *s)
int score_sum = 0; int score_sum = 0;
changed = 0; changed = 0;
for (mb_y = 0; mb_y < s->mb_height; mb_y++) { for (mb_y = 0; mb_y < mb_height; mb_y++) {
for (mb_x = 0; mb_x < s->mb_width; mb_x++) { for (mb_x = 0; mb_x < s->mb_width; mb_x++) {
const int mb_xy = mb_x + mb_y * s->mb_stride; const int mb_xy = mb_x + mb_y * s->mb_stride;
int mv_predictor[8][2] = { { 0 } }; int mv_predictor[8][2] = { { 0 } };
...@@ -675,7 +680,7 @@ skip_last_mv: ...@@ -675,7 +680,7 @@ skip_last_mv:
if (none_left) if (none_left)
return; return;
for (i = 0; i < s->mb_num; i++) { for (i = 0; i < mb_width * mb_height; i++) {
int mb_xy = s->mb_index2xy[i]; int mb_xy = s->mb_index2xy[i];
if (fixed[mb_xy]) if (fixed[mb_xy])
fixed[mb_xy] = MV_FROZEN; fixed[mb_xy] = MV_FROZEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment