From 09096fb68713089a8f97c8fa24e9d7f3bb9231d5 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 10 Jun 2017 00:13:07 +0200 Subject: [PATCH] avcodec/h264_parse: Check picture structure when initializing weight table Fixes: runtime error: index 49 out of bounds for type 'int [48][2][2]' Fixes: 2159/clusterfuzz-testcase-minimized-5267945972301824 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer --- libavcodec/h264_parse.c | 15 +++++++++------ libavcodec/h264_parse.h | 3 ++- libavcodec/h264_parser.c | 2 +- libavcodec/h264_slice.c | 3 ++- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/libavcodec/h264_parse.c b/libavcodec/h264_parse.c index ea202e759c..3d20075f6a 100644 --- a/libavcodec/h264_parse.c +++ b/libavcodec/h264_parse.c @@ -26,7 +26,8 @@ int ff_h264_pred_weight_table(GetBitContext *gb, const SPS *sps, const int *ref_count, int slice_type_nos, - H264PredWeightTable *pwt, void *logctx) + H264PredWeightTable *pwt, + int picture_structure, void *logctx) { int list, i, j; int luma_def, chroma_def; @@ -98,11 +99,13 @@ int ff_h264_pred_weight_table(GetBitContext *gb, const SPS *sps, } // for MBAFF - pwt->luma_weight[16 + 2 * i][list][0] = pwt->luma_weight[16 + 2 * i + 1][list][0] = pwt->luma_weight[i][list][0]; - pwt->luma_weight[16 + 2 * i][list][1] = pwt->luma_weight[16 + 2 * i + 1][list][1] = pwt->luma_weight[i][list][1]; - for (j = 0; j < 2; j++) { - pwt->chroma_weight[16 + 2 * i][list][j][0] = pwt->chroma_weight[16 + 2 * i + 1][list][j][0] = pwt->chroma_weight[i][list][j][0]; - pwt->chroma_weight[16 + 2 * i][list][j][1] = pwt->chroma_weight[16 + 2 * i + 1][list][j][1] = pwt->chroma_weight[i][list][j][1]; + if (picture_structure == PICT_FRAME) { + pwt->luma_weight[16 + 2 * i][list][0] = pwt->luma_weight[16 + 2 * i + 1][list][0] = pwt->luma_weight[i][list][0]; + pwt->luma_weight[16 + 2 * i][list][1] = pwt->luma_weight[16 + 2 * i + 1][list][1] = pwt->luma_weight[i][list][1]; + for (j = 0; j < 2; j++) { + pwt->chroma_weight[16 + 2 * i][list][j][0] = pwt->chroma_weight[16 + 2 * i + 1][list][j][0] = pwt->chroma_weight[i][list][j][0]; + pwt->chroma_weight[16 + 2 * i][list][j][1] = pwt->chroma_weight[16 + 2 * i + 1][list][j][1] = pwt->chroma_weight[i][list][j][1]; + } } } if (slice_type_nos != AV_PICTURE_TYPE_B) diff --git a/libavcodec/h264_parse.h b/libavcodec/h264_parse.h index 290da34d44..4d01620125 100644 --- a/libavcodec/h264_parse.h +++ b/libavcodec/h264_parse.h @@ -55,7 +55,8 @@ typedef struct H264POCContext { int ff_h264_pred_weight_table(GetBitContext *gb, const SPS *sps, const int *ref_count, int slice_type_nos, - H264PredWeightTable *pwt, void *logctx); + H264PredWeightTable *pwt, + int picture_structure, void *logctx); /** * Check if the top & left blocks are available if needed & change the diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index bc35a6146e..2564c6c6c3 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -202,7 +202,7 @@ static int scan_mmco_reset(AVCodecParserContext *s, GetBitContext *gb, if ((p->ps.pps->weighted_pred && slice_type_nos == AV_PICTURE_TYPE_P) || (p->ps.pps->weighted_bipred_idc == 1 && slice_type_nos == AV_PICTURE_TYPE_B)) ff_h264_pred_weight_table(gb, p->ps.sps, ref_count, slice_type_nos, - &pwt, logctx); + &pwt, p->picture_structure, logctx); if (get_bits1(gb)) { // adaptive_ref_pic_marking_mode_flag int i; diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 8ba23712a1..23ca32a39d 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -1801,7 +1801,8 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, (pps->weighted_bipred_idc == 1 && sl->slice_type_nos == AV_PICTURE_TYPE_B)) { ret = ff_h264_pred_weight_table(&sl->gb, sps, sl->ref_count, - sl->slice_type_nos, &sl->pwt, h->avctx); + sl->slice_type_nos, &sl->pwt, + picture_structure, h->avctx); if (ret < 0) return ret; }