aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Niedermayer <michael@niedermayer.cc>2015-11-14 21:11:52 +0100
committerMichael Niedermayer <michael@niedermayer.cc>2015-11-26 16:58:33 +0100
commit44d82a8fa16c105b239aae2f2364c5bbf91e456d (patch)
treebb9199d45d92d760b141cf46c3847c1101759ff5
parent19c931fe66bc2c524fdafdfb92484ee746ad36f9 (diff)
downloadffmpeg-44d82a8fa16c105b239aae2f2364c5bbf91e456d.tar.gz
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: Michael Niedermayer <michael@niedermayer.cc> (cherry picked from commit a105f52855d08e4ab1ed7306da8e32fc90d6d647) Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
-rw-r--r--libavcodec/error_resilience.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c
index c72c562078..fb71a71df7 100644
--- a/libavcodec/error_resilience.c
+++ b/libavcodec/error_resilience.c
@@ -377,14 +377,19 @@ static void guess_mv(ERContext *s)
#define MV_UNCHANGED 1
const int mb_stride = s->mb_stride;
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 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);
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];
int f = 0;
int error = s->error_status_table[mb_xy];
@@ -409,7 +414,7 @@ static void guess_mv(ERContext *s)
if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) ||
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++) {
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;
@@ -438,7 +443,7 @@ static void guess_mv(ERContext *s)
int score_sum = 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++) {
const int mb_xy = mb_x + mb_y * s->mb_stride;
int mv_predictor[8][2] = { { 0 } };
@@ -671,7 +676,7 @@ skip_last_mv:
if (none_left)
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];
if (fixed[mb_xy])
fixed[mb_xy] = MV_FROZEN;