From 09e391abd81c3298e230bebb3c4ce159a259d871 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Fri, 29 Mar 2013 12:51:51 +0100 Subject: [PATCH 1/4] matroska: pass the lace size to the matroska_parse_rm_audio Each lace must be independent according to the specification. Fix heap-buffer-overflow in matroska_parse_block for corrupted real media in mkv files. Stricter check than fc43c19a567aa945398dccb491d972c11ec2a065 CC: libav-stable@libav.org (cherry picked from commit 25a80a931a3829f9d730971dbd269aa39cc273f6) Signed-off-by: Reinhard Tartler --- libavformat/matroskadec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 5e94b725f8..147c24cf86 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -2081,7 +2081,8 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, st->codec->codec_id == AV_CODEC_ID_ATRAC3) && st->codec->block_align && track->audio.sub_packet_size) { - res = matroska_parse_rm_audio(matroska, track, st, data, size, + res = matroska_parse_rm_audio(matroska, track, st, data, + lace_size[n], timecode, duration, pos); if (res) goto end; @@ -2097,7 +2098,6 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, if (timecode != AV_NOPTS_VALUE) timecode = duration ? timecode + duration : AV_NOPTS_VALUE; data += lace_size[n]; - size -= lace_size[n]; } end: From 75948682969694613e5226cd48c248eacfa9a425 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 28 Mar 2013 10:34:47 +0100 Subject: [PATCH 2/4] xmv: do not leak memory in the error paths in xmv_read_header() CC: libav-stable@libav.org (cherry picked from commit f8080bd13b5f7fc48204b17fa59a5ce9feb15f07) Signed-off-by: Reinhard Tartler --- libavformat/xmv.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libavformat/xmv.c b/libavformat/xmv.c index 3f926eff9c..6c46a23e86 100644 --- a/libavformat/xmv.c +++ b/libavformat/xmv.c @@ -177,8 +177,10 @@ static int xmv_read_header(AVFormatContext *s) return AVERROR(ENOMEM); xmv->audio = av_malloc(xmv->audio_track_count * sizeof(XMVAudioPacket)); - if (!xmv->audio) - return AVERROR(ENOMEM); + if (!xmv->audio) { + ret = AVERROR(ENOMEM); + goto fail; + } for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) { XMVAudioTrack *track = &xmv->audio_tracks[audio_track]; @@ -212,8 +214,10 @@ static int xmv_read_header(AVFormatContext *s) "(0x%04X)\n", track->flags); ast = avformat_new_stream(s, NULL); - if (!ast) - return AVERROR(ENOMEM); + if (!ast) { + ret = AVERROR(ENOMEM); + goto fail; + } ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = track->codec_id; From ba31b72f462cd95609d13713fff42b1b000a56c7 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 28 Mar 2013 10:09:36 +0100 Subject: [PATCH 3/4] bmv: check for len being valid in bmv_decode_frame(). It can be 0 or -1 for invalid files, which may result in invalid memory access. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit b88f902125ee808c8366e9dcb3f21e4c227483fc) Conflicts: libavcodec/bmv.c --- libavcodec/bmv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c index a7f21eceb2..bcb1380030 100644 --- a/libavcodec/bmv.c +++ b/libavcodec/bmv.c @@ -136,7 +136,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, mode += 1 + advance_mode; if (mode >= 4) mode -= 3; - if (FFABS(dst_end - dst) < len) + if (len <= 0 || FFABS(dst_end - dst) < len) return -1; switch (mode) { case 1: From 858864d350320dd807e349bda017026e61a47fe0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 28 Mar 2013 10:33:02 +0100 Subject: [PATCH 4/4] xmv: check audio track parameters validity. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit d1016dccdcb10486245e5d7c186cc31af54b2a9c) Signed-off-by: Reinhard Tartler --- libavformat/xmv.c | 32 ++++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/libavformat/xmv.c b/libavformat/xmv.c index 6c46a23e86..d491dec8f6 100644 --- a/libavformat/xmv.c +++ b/libavformat/xmv.c @@ -126,6 +126,16 @@ static int xmv_probe(AVProbeData *p) return 0; } +static int xmv_read_close(AVFormatContext *s) +{ + XMVDemuxContext *xmv = s->priv_data; + + av_free(xmv->audio); + av_free(xmv->audio_tracks); + + return 0; +} + static int xmv_read_header(AVFormatContext *s) { XMVDemuxContext *xmv = s->priv_data; @@ -135,6 +145,7 @@ static int xmv_read_header(AVFormatContext *s) uint32_t file_version; uint32_t this_packet_size; uint16_t audio_track; + int ret; avio_skip(pb, 4); /* Next packet size */ @@ -213,6 +224,13 @@ static int xmv_read_header(AVFormatContext *s) av_log(s, AV_LOG_WARNING, "Unsupported 5.1 ADPCM audio stream " "(0x%04X)\n", track->flags); + if (!track->channels || !track->sample_rate) { + av_log(s, AV_LOG_ERROR, "Invalid parameters for audio track %d.\n", + audio_track); + ret = AVERROR_INVALIDDATA; + goto fail; + } + ast = avformat_new_stream(s, NULL); if (!ast) { ret = AVERROR(ENOMEM); @@ -243,6 +261,10 @@ static int xmv_read_header(AVFormatContext *s) xmv->stream_count = xmv->audio_track_count + 1; return 0; + +fail: + xmv_read_close(s); + return ret; } static void xmv_read_extradata(uint8_t *extradata, AVIOContext *pb) @@ -550,16 +572,6 @@ static int xmv_read_packet(AVFormatContext *s, return 0; } -static int xmv_read_close(AVFormatContext *s) -{ - XMVDemuxContext *xmv = s->priv_data; - - av_free(xmv->audio); - av_free(xmv->audio_tracks); - - return 0; -} - AVInputFormat ff_xmv_demuxer = { .name = "xmv", .long_name = NULL_IF_CONFIG_SMALL("Microsoft XMV"),