diff options
author | Michael Niedermayer <michael@niedermayer.cc> | 2018-06-27 20:37:09 +0300 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2018-06-28 22:35:01 +0300 |
commit | 2aa9047486dbff12d9e040f917e5f799ed2fd78b (patch) | |
tree | 9a35b6fe556b898c8d52ebceb1d8603196c07669 /libavcodec | |
parent | 95556e27e2c1d56d9e18f5db34d6f756f3011148 (diff) |
avcodec/mpeg4videodec: Check read profile before setting it
Fixes: null pointer dereference
Fixes: ffmpeg_crash_7.avi
Found-by: Thuan Pham, Marcel Böhme, Andrew Santosa and Alexandru Razvan Caciulescu with AFLSmart
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/mpeg4videodec.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index d0ebaac6e8..54a8496244 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -1980,15 +1980,15 @@ static int mpeg4_decode_gop_header(MpegEncContext *s, GetBitContext *gb) return 0; } -static int mpeg4_decode_profile_level(MpegEncContext *s, GetBitContext *gb) +static int mpeg4_decode_profile_level(MpegEncContext *s, GetBitContext *gb, int *profile, int *level) { - s->avctx->profile = get_bits(gb, 4); - s->avctx->level = get_bits(gb, 4); + *profile = get_bits(gb, 4); + *level = get_bits(gb, 4); // for Simple profile, level 0 - if (s->avctx->profile == 0 && s->avctx->level == 8) { - s->avctx->level = 0; + if (*profile == 0 && *level == 8) { + *level = 0; } return 0; @@ -3211,13 +3211,19 @@ int ff_mpeg4_decode_picture_header(Mpeg4DecContext *ctx, GetBitContext *gb) } else if (startcode == GOP_STARTCODE) { mpeg4_decode_gop_header(s, gb); } else if (startcode == VOS_STARTCODE) { - mpeg4_decode_profile_level(s, gb); - if (s->avctx->profile == FF_PROFILE_MPEG4_SIMPLE_STUDIO && - (s->avctx->level > 0 && s->avctx->level < 9)) { + int profile, level; + mpeg4_decode_profile_level(s, gb, &profile, &level); + if (profile == FF_PROFILE_MPEG4_SIMPLE_STUDIO && + (level > 0 && level < 9)) { s->studio_profile = 1; next_start_code_studio(gb); extension_and_user_data(s, gb, 0); + } else if (s->studio_profile) { + avpriv_request_sample(s->avctx, "Mixes studio and non studio profile\n"); + return AVERROR_PATCHWELCOME; } + s->avctx->profile = profile; + s->avctx->level = level; } else if (startcode == VISUAL_OBJ_STARTCODE) { if (s->studio_profile) { if ((ret = decode_studiovisualobject(ctx, gb)) < 0) @@ -3238,6 +3244,7 @@ end: s->avctx->has_b_frames = !s->low_delay; if (s->studio_profile) { + av_assert0(s->avctx->profile == FF_PROFILE_MPEG4_SIMPLE_STUDIO); if (!s->avctx->bits_per_raw_sample) { av_log(s->avctx, AV_LOG_ERROR, "Missing VOL header\n"); return AVERROR_INVALIDDATA; |