From 2ef84218b2921372aed5fcd06eb7edca3e39d01b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 16 Sep 2013 21:03:34 +0300 Subject: [PATCH 01/14] truemotion2: Use av_freep properly in an error path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit c39f7eba01cd656e8f0eed592f93d11814736650) Signed-off-by: Luca Barbato (cherry picked from commit eac1c3f384eab770d42468f4f244156c1735701d) --- libavcodec/truemotion2.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index 09d9e27c9d..fd5d28c574 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -907,14 +907,14 @@ static av_cold int decode_init(AVCodecContext *avctx){ if (!l->Y1_base || !l->Y2_base || !l->U1_base || !l->V1_base || !l->U2_base || !l->V2_base || !l->last || !l->clast) { - av_freep(l->Y1_base); - av_freep(l->Y2_base); - av_freep(l->U1_base); - av_freep(l->U2_base); - av_freep(l->V1_base); - av_freep(l->V2_base); - av_freep(l->last); - av_freep(l->clast); + av_freep(&l->Y1_base); + av_freep(&l->Y2_base); + av_freep(&l->U1_base); + av_freep(&l->U2_base); + av_freep(&l->V1_base); + av_freep(&l->V2_base); + av_freep(&l->last); + av_freep(&l->clast); return AVERROR(ENOMEM); } l->Y1 = l->Y1_base + l->y_stride * 4 + 4; From 2b71a7884196413d39b90549e58c4488a8f83953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 16 Sep 2013 21:46:50 +0300 Subject: [PATCH 02/14] ffv1: Make sure at least one slice context is initialized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids crashes when initializing the range coder for the first slice context. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit b1db33159fdc2da4bdd8c75e4ff9a7dd0ef2f0c2) Signed-off-by: Luca Barbato --- libavcodec/ffv1.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index 8a6f33f383..917f40d1bc 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -708,6 +708,10 @@ static av_cold int init_slice_contexts(FFV1Context *f){ int i; f->slice_count= f->num_h_slices * f->num_v_slices; + if (f->slice_count <= 0) { + av_log(f->avctx, AV_LOG_ERROR, "Invalid number of slices\n"); + return AVERROR(EINVAL); + } for(i=0; islice_count; i++){ FFV1Context *fs= av_mallocz(sizeof(*fs)); From 0a23055b8ab24800774a7079921791acb92fe0f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 16 Sep 2013 21:27:49 +0300 Subject: [PATCH 03/14] xmv: Add more sanity checks for parameters read from the bitstream MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the number of channels is multiplied by 36 and assigned to to a uint16_t, make sure this calculation didn't overflow. (In certain cases the calculation could overflow leaving the truncated block_align at 0, leading to divisions by zero later.) Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit d4c2a3740fb95f952a87ba320d2bf31f126bdf68) Signed-off-by: Luca Barbato (cherry picked from commit 00516b5491fbd99e4057f21eae231fc02cc596e3) --- libavformat/xmv.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavformat/xmv.c b/libavformat/xmv.c index 8249ce11e3..f0950c0f6b 100644 --- a/libavformat/xmv.c +++ b/libavformat/xmv.c @@ -43,6 +43,8 @@ XMV_AUDIO_ADPCM51_FRONTCENTERLOW | \ XMV_AUDIO_ADPCM51_REARLEFTRIGHT) +#define XMV_BLOCK_ALIGN_SIZE 36 + typedef struct XMVAudioTrack { uint16_t compression; uint16_t channels; @@ -208,7 +210,7 @@ static int xmv_read_header(AVFormatContext *s, track->bit_rate = track->bits_per_sample * track->sample_rate * track->channels; - track->block_align = 36 * track->channels; + track->block_align = XMV_BLOCK_ALIGN_SIZE * track->channels; track->block_samples = 64; track->codec_id = ff_wav_codec_get_id(track->compression, track->bits_per_sample); @@ -225,7 +227,8 @@ 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) { + if (!track->channels || !track->sample_rate || + track->channels >= UINT16_MAX / XMV_BLOCK_ALIGN_SIZE) { av_log(s, AV_LOG_ERROR, "Invalid parameters for audio track %d.\n", audio_track); ret = AVERROR_INVALIDDATA; From 3b169044ca042f1bc82a7e55bbf72062b051c75f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 16 Sep 2013 15:40:57 +0300 Subject: [PATCH 04/14] rv10: Validate the dimensions set from the container MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit 5372cda67109848d22146289e401669266217e80) Signed-off-by: Luca Barbato (cherry picked from commit 0b0f1cd44ece180e12795cfc8d0a0ac5ea3ebe2c) --- libavcodec/rv10.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index 4f64ec29b3..59bd96859e 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -425,12 +425,15 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; static int done=0; - int major_ver, minor_ver, micro_ver; + int major_ver, minor_ver, micro_ver, ret; if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n"); return -1; } + if ((ret = av_image_check_size(avctx->coded_width, + avctx->coded_height, 0, avctx)) < 0) + return ret; MPV_decode_defaults(s); From 75dabbff8b15700c20e42f79a23fd4338a54e71d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Mon, 16 Sep 2013 14:53:15 +0300 Subject: [PATCH 05/14] idroqdec: Make sure a video stream has been allocated before returning packets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit bcbe4f3ceb6ee0210d3a401963518906c8b9b230) Signed-off-by: Luca Barbato (cherry picked from commit de75bc01cda53acfbd9f901639695ade8e650c43) --- libavformat/idroqdec.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavformat/idroqdec.c b/libavformat/idroqdec.c index d63c395b79..ece18b8b4f 100644 --- a/libavformat/idroqdec.c +++ b/libavformat/idroqdec.c @@ -142,6 +142,8 @@ static int roq_read_packet(AVFormatContext *s, break; case RoQ_QUAD_CODEBOOK: + if (roq->video_stream_index < 0) + return AVERROR_INVALIDDATA; /* packet needs to contain both this codebook and next VQ chunk */ codebook_offset = avio_tell(pb) - RoQ_CHUNK_PREAMBLE_SIZE; codebook_size = chunk_size; @@ -184,6 +186,11 @@ static int roq_read_packet(AVFormatContext *s, st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; } case RoQ_QUAD_VQ: + if (chunk_type == RoQ_QUAD_VQ) { + if (roq->video_stream_index < 0) + return AVERROR_INVALIDDATA; + } + /* load up the packet */ if (av_new_packet(pkt, chunk_size + RoQ_CHUNK_PREAMBLE_SIZE)) return AVERROR(EIO); From 036136fa89ac44fd89c7f4730d3039f0b3b92cfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 19 Sep 2013 15:14:56 +0300 Subject: [PATCH 06/14] asv1: Verify the amount of extradata MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The init function reads one byte of extradata. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit f50803354c6acb4575379d7c54ca48ec5d36dd61) Signed-off-by: Luca Barbato --- libavcodec/asv1.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/asv1.c b/libavcodec/asv1.c index 8db23c07ef..cdddfa58af 100644 --- a/libavcodec/asv1.c +++ b/libavcodec/asv1.c @@ -535,6 +535,11 @@ static av_cold int decode_init(AVCodecContext *avctx){ int i; const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; + if (avctx->extradata_size < 1) { + av_log(avctx, AV_LOG_ERROR, "No extradata provided\n"); + return AVERROR_INVALIDDATA; + } + common_init(avctx); init_vlcs(a); ff_init_scantable(a->dsp.idct_permutation, &a->scantable, scantab); From ff8837e9c60a99172565c47d7fcf432418c0dac8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 19 Sep 2013 15:32:02 +0300 Subject: [PATCH 07/14] mpegaudiodec: Validate that the number of channels fits at the given offset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is similar to the fix in 35cbc98b. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit e9d61de96c113ee0ef8082833c7e682df0e23eec) Signed-off-by: Luca Barbato (cherry picked from commit bacf5db1962a6955ce80eea6bbc86c6970d7d360) --- libavcodec/mpegaudiodec.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index adb25ffa38..e2216f3fdb 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -1943,7 +1943,8 @@ static int decode_frame_mp3on4(AVCodecContext *avctx, void *data, avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header); - if (ch + m->nb_channels > avctx->channels) { + if (ch + m->nb_channels > avctx->channels || + s->coff[fr] + m->nb_channels > avctx->channels) { av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec " "channel count\n"); return AVERROR_INVALIDDATA; From 2c3114158510d05346e362d381a3b352175e260e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 19 Sep 2013 15:53:31 +0300 Subject: [PATCH 08/14] qpeg: Add checks for running out of rows in qpeg_decode_inter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit 7a5a55722749a3ab77941914707277b147322cbe) Signed-off-by: Luca Barbato (cherry picked from commit 4d90550cf95eac0451465116d6e53bac37b96927) --- libavcodec/qpeg.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index 9513dd0ad3..9897f16bf3 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -198,6 +198,8 @@ static void qpeg_decode_inter(const uint8_t *src, uint8_t *dst, int size, filled = 0; dst -= stride; height--; + if (height < 0) + break; } } } else if(code >= 0xC0) { /* copy code: 0xC0..0xDF */ @@ -209,6 +211,8 @@ static void qpeg_decode_inter(const uint8_t *src, uint8_t *dst, int size, filled = 0; dst -= stride; height--; + if (height < 0) + break; } } size -= code + 1; From e80071892b14a66b8730dfe21aca76e5b0333f2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 19 Sep 2013 16:02:29 +0300 Subject: [PATCH 09/14] segafilm: Validate the number of audio channels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids divisions by zero later. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit 82e266c6d3fbf3cc74e515b883e66543381a0f2c) Signed-off-by: Luca Barbato (cherry picked from commit 5379c5184b9fe9ef06234638f5629d4c80056e04) --- libavformat/segafilm.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index 5279121383..d5aaf11d38 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -112,6 +112,11 @@ static int film_read_header(AVFormatContext *s, return AVERROR(EIO); film->audio_samplerate = AV_RB16(&scratch[24]); film->audio_channels = scratch[21]; + if (!film->audio_channels || film->audio_channels > 2) { + av_log(s, AV_LOG_ERROR, + "Invalid number of channels: %d\n", film->audio_channels); + return AVERROR_INVALIDDATA; + } film->audio_bits = scratch[22]; if (scratch[23] == 2) film->audio_type = CODEC_ID_ADPCM_ADX; From f23b1cc7d979ab0153d203e2e7ecb0ca48e78abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 19 Sep 2013 16:55:13 +0300 Subject: [PATCH 10/14] wtv: Add more sanity checks for a length read from the file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also make sure the existing length check can't overflow. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit 83c285f88016b087c2f0f4b9ef356ad8ef12d947) Signed-off-by: Luca Barbato (cherry picked from commit 78dc022f6f8a8b87773a209e0fcbea2d5b48396f) --- libavformat/wtv.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavformat/wtv.c b/libavformat/wtv.c index 2d5d7c5cbd..7a668439f9 100644 --- a/libavformat/wtv.c +++ b/libavformat/wtv.c @@ -273,7 +273,12 @@ static AVIOContext * wtvfile_open2(AVFormatContext *s, const uint8_t *buf, int b dir_length = AV_RL16(buf + 16); file_length = AV_RL64(buf + 24); name_size = 2 * AV_RL32(buf + 32); - if (buf + 48 + name_size > buf_end) { + if (name_size < 0) { + av_log(s, AV_LOG_ERROR, + "bad filename length, remaining directory entries ignored\n"); + break; + } + if (48 + name_size > buf_end - buf) { av_log(s, AV_LOG_ERROR, "filename exceeds buffer size; remaining directory entries ignored\n"); break; } From c211ba9b59e8a7c730dfacc536e59f036e77950f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 19 Sep 2013 16:57:47 +0300 Subject: [PATCH 11/14] rl2: Avoid a division by zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit 3ca14aa5964ea5d11f7a15f9fff17924d6096d44) Signed-off-by: Luca Barbato (cherry picked from commit ce1dacb435460dda1f9d453eaaeac44bd502aca4) --- libavformat/rl2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavformat/rl2.c b/libavformat/rl2.c index b2be7c0ca9..b138d7bf46 100644 --- a/libavformat/rl2.c +++ b/libavformat/rl2.c @@ -109,6 +109,10 @@ static av_cold int rl2_read_header(AVFormatContext *s, rate = avio_rl16(pb); channels = avio_rl16(pb); def_sound_size = avio_rl16(pb); + if (!channels || channels > 42) { + av_log(s, AV_LOG_ERROR, "Invalid number of channels: %d\n", channels); + return AVERROR_INVALIDDATA; + } /** setup video stream */ st = avformat_new_stream(s, NULL); From 456a9392103f6ccd63173660804b1029052dc36c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 19 Sep 2013 15:12:06 +0300 Subject: [PATCH 12/14] dca: Validate the lfe parameter MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit a9d50bb578ec04c085a25f1e023f75e0e4499d5e) Signed-off-by: Luca Barbato --- libavcodec/dca.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 169c9b41b9..4d71812d88 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -578,6 +578,11 @@ static int dca_parse_frame_header(DCAContext *s) s->lfe = get_bits(&s->gb, 2); s->predictor_history = get_bits(&s->gb, 1); + if (s->lfe > 2) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid LFE value: %d\n", s->lfe); + return AVERROR_INVALIDDATA; + } + /* TODO: check CRC */ if (s->crc_present) s->header_crc = get_bits(&s->gb, 16); From b29c31c21e6d9d791b413146defb1986032d72b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 20 Sep 2013 00:07:34 +0300 Subject: [PATCH 13/14] wnv1: Make sure the input packet is large enough MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit 91be1103fd1f79d381edf268c32f4166b6c3b6d8) Signed-off-by: Luca Barbato (cherry picked from commit 0c8c6b4419e00d13197a4aea5456b398dca24df0) --- libavcodec/wnv1.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c index f6e4694df2..0cc26dbb60 100644 --- a/libavcodec/wnv1.c +++ b/libavcodec/wnv1.c @@ -70,6 +70,11 @@ static int decode_frame(AVCodecContext *avctx, int prev_y = 0, prev_u = 0, prev_v = 0; uint8_t *rbuf; + if (buf_size < 8) { + av_log(avctx, AV_LOG_ERROR, "Packet is too short\n"); + return AVERROR_INVALIDDATA; + } + rbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); if(!rbuf){ av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n"); From 159993acc7f4e3155510d42c543e09fe972b933c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Fri, 20 Sep 2013 11:16:00 +0300 Subject: [PATCH 14/14] vc1dec: Fix leaks in ff_vc1_decode_init_alloc_tables on errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit ede508443e4bf57dc1e019fac81bf6244b88fbd3) Signed-off-by: Luca Barbato (cherry picked from commit b62704891d2353679e012555ac9e9a49ee63d497) --- libavcodec/vc1dec.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index e1aa4e65d8..328c5a69c5 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -5126,8 +5126,19 @@ static av_cold int vc1_decode_init_alloc_tables(VC1Context *v) if (!v->mv_type_mb_plane || !v->direct_mb_plane || !v->acpred_plane || !v->over_flags_plane || !v->block || !v->cbp_base || !v->ttblk_base || !v->is_intra_base || !v->luma_mv_base || - !v->mb_type_base) - return -1; + !v->mb_type_base) { + av_freep(&v->mv_type_mb_plane); + av_freep(&v->direct_mb_plane); + av_freep(&v->acpred_plane); + av_freep(&v->over_flags_plane); + av_freep(&v->block); + av_freep(&v->cbp_base); + av_freep(&v->ttblk_base); + av_freep(&v->is_intra_base); + av_freep(&v->luma_mv_base); + av_freep(&v->mb_type_base); + return AVERROR(ENOMEM); + } return 0; }