From c321f2abca6a5bd4b1600ffa35bf2175dd55b388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Wed, 2 Nov 2011 17:54:00 +0200 Subject: [PATCH 01/84] avcodec: Remove a misplaced and useless attribute_deprecated MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If attribute_deprecated is used in an enum declaration, it should follow the 'enum' keyword, otherwise it's ignored silently. This is the only case of attribute_deprecated for enum declarations currently. Currently, this attribute_deprecated doesn't have any effect. If moved to the right place, it emits a warning every single time avcodec.h is included, like this: avcodec.h:2827: warning: ‘AVLPCType’ is deprecated (declared at avcodec.h:543) There is already a working attribute_deprecated for the corresponding field in AVCodecContext, so therefore this one shouldn't be needed. Signed-off-by: Martin Storsjö (cherry picked from commit 1b6da627d49e98fe7661c9aa9ec4e16ab04dfda4) Signed-off-by: Martin Storsjö --- libavcodec/avcodec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 2dbdc86e6a..179d97c91c 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -520,7 +520,7 @@ enum AVChromaLocation{ /** * LPC analysis type */ -attribute_deprecated enum AVLPCType { +enum AVLPCType { AV_LPC_TYPE_DEFAULT = -1, ///< use the codec default LPC type AV_LPC_TYPE_NONE = 0, ///< do not use LPC prediction or use all zero coefficients AV_LPC_TYPE_FIXED = 1, ///< fixed LPC coefficients From ccd528cc32024195c0ae1e5420223bff6ffc5317 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 25 Jan 2012 15:27:11 -0800 Subject: [PATCH 02/84] qdm2: Check data block size for bytes to bits overflow. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit dac56d9ce01eb9963f28f26b97a81db5cbd46c1c) Signed-off-by: Reinhard Tartler --- libavcodec/qdm2.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 7e7051fc6d..184c97dfb6 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -1816,6 +1816,10 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) extradata += 4; s->checksum_size = AV_RB32(extradata); + if (s->checksum_size >= 1U << 28) { + av_log(avctx, AV_LOG_ERROR, "data block size too large (%u)\n", s->checksum_size); + return AVERROR_INVALIDDATA; + } s->fft_order = av_log2(s->fft_size) + 1; s->fft_frame_size = 2 * s->fft_size; // complex has two floats From 3b5e1494c6e4bee4a0823b02d1342185252461d6 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 14 Feb 2012 11:50:57 -0800 Subject: [PATCH 03/84] golomb: avoid infinite loop on all-zero input (or end of buffer). Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit c6643fddba73560f26f90d327c84d8832222a720) Signed-off-by: Reinhard Tartler --- libavcodec/golomb.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index 503aa1416a..e19064c642 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -123,7 +123,7 @@ static inline int svq3_get_ue_golomb(GetBitContext *gb){ }else{ int ret = 1; - while (1) { + do { buf >>= 32 - 8; LAST_SKIP_BITS(re, gb, FFMIN(ff_interleaved_golomb_vlc_len[buf], 8)); @@ -135,7 +135,7 @@ static inline int svq3_get_ue_golomb(GetBitContext *gb){ ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; UPDATE_CACHE(re, gb); buf = GET_CACHE(re, gb); - } + } while (ret); CLOSE_READER(re, gb); return ret - 1; From ec961c89194aa090ab39f2cd4336479c909e532b Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 15 Feb 2012 09:52:11 -0800 Subject: [PATCH 04/84] flac: fix infinite loops on all-zero input or end-of-stream. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 52e4018be47697a60f4f18f83551766df31f5adf) Signed-off-by: Reinhard Tartler --- libavcodec/flacdec.c | 9 +++++++++ libavcodec/golomb.h | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 7331c5cdd1..c74ebb0c14 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -420,7 +420,16 @@ static inline int decode_subframe(FLACContext *s, int channel) type = get_bits(&s->gb, 6); if (get_bits1(&s->gb)) { + int left = get_bits_left(&s->gb); wasted = 1; + if ( left < 0 || + (left < s->curr_bps && !show_bits_long(&s->gb, left)) || + !show_bits_long(&s->gb, s->curr_bps)) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid number of wasted bits > available bits (%d) - left=%d\n", + s->curr_bps, left); + return AVERROR_INVALIDDATA; + } while (!get_bits1(&s->gb)) wasted++; s->curr_bps -= wasted; diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index e19064c642..5f720c03f3 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -301,7 +301,7 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int return buf; }else{ int i; - for(i=0; SHOW_UBITS(re, gb, 1) == 0; i++){ + for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) { LAST_SKIP_BITS(re, gb, 1); UPDATE_CACHE(re, gb); } From 0fbde741cbca76e826d0dce446480b02da5f6706 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 24 Jan 2012 18:43:43 -0800 Subject: [PATCH 05/84] wma: Clip WMA1 and WMA2 frame length to 11 bits. The MDCT buffers in the decoder are only sized for up to 11 bits. The reverse engineered documentation for WMA1/2 headers say that that for all samplerates above 32kHz 11 bits are used. 12 and 13 bit support were added for WMAPro. I was unable to make any Microsoft tools generate a test file at a samplerate above 48kHz. Discovered by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit d78bb1a4b2a3a415b68e4e6dd448779eccec64e3) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavcodec/wma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/wma.c b/libavcodec/wma.c index 4cdffcd101..d82fde7b18 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -85,7 +85,7 @@ int av_cold ff_wma_get_frame_len_bits(int sample_rate, int version, } else if (sample_rate <= 22050 || (sample_rate <= 32000 && version == 1)) { frame_len_bits = 10; - } else if (sample_rate <= 48000) { + } else if (sample_rate <= 48000 || version < 3) { frame_len_bits = 11; } else if (sample_rate <= 96000) { frame_len_bits = 12; From bf9f26cef73eea9d9c2e73b89a5fe88e5aedc737 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 22 Feb 2012 11:05:42 -0800 Subject: [PATCH 06/84] aac: fix infinite loop on end-of-frame with sequence of 1-bits. Based-on-work-by: Ronald S. Bultje Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 1cd9a6154bc1ac1193c703cea980ed21c3e53792) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavcodec/aacdec.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index f1203d307e..cf7b43d53f 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -752,19 +752,20 @@ static int decode_band_types(AACContext *ac, enum BandType band_type[120], av_log(ac->avctx, AV_LOG_ERROR, "invalid band type\n"); return -1; } - while ((sect_len_incr = get_bits(gb, bits)) == (1 << bits) - 1) + do { + sect_len_incr = get_bits(gb, bits); sect_end += sect_len_incr; - sect_end += sect_len_incr; - if (get_bits_left(gb) < 0) { - av_log(ac->avctx, AV_LOG_ERROR, overread_err); - return -1; - } - if (sect_end > ics->max_sfb) { - av_log(ac->avctx, AV_LOG_ERROR, - "Number of bands (%d) exceeds limit (%d).\n", - sect_end, ics->max_sfb); - return -1; - } + if (get_bits_left(gb) < 0) { + av_log(ac->avctx, AV_LOG_ERROR, overread_err); + return -1; + } + if (sect_end > ics->max_sfb) { + av_log(ac->avctx, AV_LOG_ERROR, + "Number of bands (%d) exceeds limit (%d).\n", + sect_end, ics->max_sfb); + return -1; + } + } while (sect_len_incr == (1 << bits) - 1); for (; k < sect_end; k++) { band_type [idx] = sect_band_type; band_type_run_end[idx++] = sect_end; From dd7b323d9a2f6ddc0e277403fdbd06226306f4a1 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 25 Jan 2012 14:34:21 -0800 Subject: [PATCH 07/84] matroskadec: Pad AAC extradata. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit d2ee8c17793201ce969afd1f433ba1580c143cd2) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavformat/matroskadec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index fad554f09f..5c814f483f 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1384,7 +1384,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap) } else if (codec_id == CODEC_ID_AAC && !track->codec_priv.size) { int profile = matroska_aac_profile(track->codec_id); int sri = matroska_aac_sri(track->audio.samplerate); - extradata = av_malloc(5); + extradata = av_mallocz(5 + FF_INPUT_BUFFER_PADDING_SIZE); if (extradata == NULL) return AVERROR(ENOMEM); extradata[0] = (profile << 3) | ((sri&0x0E) >> 1); From 6c12293f6c3c91d5fbbb1146ad0f77b887abed48 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 24 Feb 2012 16:12:18 -0800 Subject: [PATCH 08/84] matroska: don't overwrite string values until read/alloc was succesful. This prevents certain tags with a default value assigned to them (as per the EBML syntax elements) from ever being assigned a NULL value. Other parts of the code rely on these being non-NULL (i.e. they don't check for NULL before e.g. using the string in strcmp() or similar), and thus in effect this prevents crashes when reading of such specific tags fails, either because of low memory or because of targeted file corruption. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit cd40c31ee9ad2cca6f3635950b002fd46be07e98) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavformat/matroskadec.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 5c814f483f..f74d028923 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -636,16 +636,19 @@ static int ebml_read_float(AVIOContext *pb, int size, double *num) */ static int ebml_read_ascii(AVIOContext *pb, int size, char **str) { - av_free(*str); + char *res; + /* EBML strings are usually not 0-terminated, so we allocate one * byte more, read the string and NULL-terminate it ourselves. */ - if (!(*str = av_malloc(size + 1))) + if (!(res = av_malloc(size + 1))) return AVERROR(ENOMEM); - if (avio_read(pb, (uint8_t *) *str, size) != size) { - av_freep(str); + if (avio_read(pb, (uint8_t *) res, size) != size) { + av_free(res); return AVERROR(EIO); } - (*str)[size] = '\0'; + (res)[size] = '\0'; + av_free(*str); + *str = res; return 0; } From fd3af2950ace3b78e3003432873509dd3544f982 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 25 Jan 2012 16:12:42 -0800 Subject: [PATCH 09/84] smacker: Sanity check huffman tables found in the headers. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 9adf25c1cf78dbf1d71bf386c49dc74cb8a60df0) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavcodec/smacker.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index fd88fd2c60..eb4427c100 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -127,12 +127,12 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref */ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx) { + if (hc->current + 1 >= hc->length) { + av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); + return -1; + } if(!get_bits1(gb)){ //Leaf int val, i1, i2, b1, b2; - if(hc->current >= hc->length){ - av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); - return -1; - } b1 = get_bits_count(gb); i1 = ctx->v1->table ? get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3) : 0; b1 = get_bits_count(gb) - b1; @@ -156,7 +156,7 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx hc->values[hc->current++] = val; return 1; } else { //Node - int r = 0, t; + int r = 0, r_new, t; t = hc->current++; r = smacker_decode_bigtree(gb, hc, ctx); @@ -164,8 +164,10 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx return r; hc->values[t] = SMK_NODE | r; r++; - r += smacker_decode_bigtree(gb, hc, ctx); - return r; + r_new = smacker_decode_bigtree(gb, hc, ctx); + if (r_new < 0) + return r_new; + return r + r_new; } } @@ -180,6 +182,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int VLC vlc[2]; int escapes[3]; DBCtx ctx; + int err = 0; if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow av_log(smk->avctx, AV_LOG_ERROR, "size too large\n"); @@ -253,7 +256,8 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int huff.current = 0; huff.values = av_mallocz(huff.length * sizeof(int)); - smacker_decode_bigtree(gb, &huff, &ctx); + if (smacker_decode_bigtree(gb, &huff, &ctx) < 0) + err = -1; skip_bits1(gb); if(ctx.last[0] == -1) ctx.last[0] = huff.current++; if(ctx.last[1] == -1) ctx.last[1] = huff.current++; @@ -272,7 +276,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int av_free(tmp2.lengths); av_free(tmp2.values); - return 0; + return err; } static int decode_header_trees(SmackVContext *smk) { From ce99c1bfb5968ea680c6c48a52c407677db2fe82 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 11 Feb 2012 08:42:28 -0800 Subject: [PATCH 10/84] swscale: enforce a minimum filtersize. At very small dimensions, this calculation could lead to zero-sized filters, which leads to uninitialized output, zero-sized allocations, loop overflows in SIMD that uses do{..}while(i++ Signed-off-by: Reinhard Tartler --- libswscale/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswscale/utils.c b/libswscale/utils.c index ac22dfe688..221b993305 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -289,7 +289,7 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi if (xInc <= 1<<16) filterSize= 1 + sizeFactor; // upscale else filterSize= 1 + (sizeFactor*srcW + dstW - 1)/ dstW; - if (filterSize > srcW-2) filterSize=srcW-2; + filterSize = av_clip(filterSize, 1, srcW - 2); FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); From b2b2dc61fa95279f78a8c425f02bdca09bdf2821 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 22 Feb 2012 16:46:31 -0800 Subject: [PATCH 11/84] swscale: fix overflows in filterPos[] calculation for large sizes. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 19a65b5be47944c607a9e979edb098924d95f2e4) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libswscale/utils.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libswscale/utils.c b/libswscale/utils.c index 221b993305..0aeec6f0fc 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -270,7 +270,7 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi xDstInSrc+= xInc; } } else { - int xDstInSrc; + int64_t xDstInSrc; int sizeFactor; if (flags&SWS_BICUBIC) sizeFactor= 4; @@ -822,8 +822,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) if (!dstFilter) dstFilter= &dummyFilter; if (!srcFilter) srcFilter= &dummyFilter; - c->lumXInc= ((srcW<<16) + (dstW>>1))/dstW; - c->lumYInc= ((srcH<<16) + (dstH>>1))/dstH; + c->lumXInc= (((int64_t)srcW<<16) + (dstW>>1))/dstW; + c->lumYInc= (((int64_t)srcH<<16) + (dstH>>1))/dstH; c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[dstFormat]); c->srcFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[srcFormat]); c->vRounder= 4* 0x0001000100010001ULL; @@ -885,8 +885,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) else c->canMMX2BeUsed=0; - c->chrXInc= ((c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW; - c->chrYInc= ((c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH; + c->chrXInc= (((int64_t)c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW; + c->chrYInc= (((int64_t)c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH; // match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst // but only for the FAST_BILINEAR mode otherwise do correct scaling @@ -901,8 +901,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) } //we don't use the x86 asm scaler if MMX is available else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX) { - c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20; - c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20; + c->lumXInc = ((int64_t)(srcW-2)<<16)/(dstW-2) - 20; + c->chrXInc = ((int64_t)(c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20; } } From 0fe53216340e2bab1bb07df6fcdc14f742f3e69c Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 22 Feb 2012 16:48:38 -0800 Subject: [PATCH 12/84] swscale: take first/lastline over/underflows into account for MMX. Fixes crashes for extremely large resizes (several 100-fold). Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 1d8c4af396b6ed84c84b5ebf0bf1163c4a7a3017) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libswscale/x86/swscale_mmx.c | 38 ++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/libswscale/x86/swscale_mmx.c b/libswscale/x86/swscale_mmx.c index f855a75212..a245106dd9 100644 --- a/libswscale/x86/swscale_mmx.c +++ b/libswscale/x86/swscale_mmx.c @@ -132,6 +132,44 @@ void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufI const int16_t **chrUSrcPtr= (const int16_t **) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL; int i; + + if (firstLumSrcY < 0 || firstLumSrcY + vLumFilterSize > c->srcH) { + const int16_t **tmpY = (const int16_t **) lumPixBuf + 2 * vLumBufSize; + int neg = -firstLumSrcY, i, end = FFMIN(c->srcH - firstLumSrcY, vLumFilterSize); + for (i = 0; i < neg; i++) + tmpY[i] = lumSrcPtr[neg]; + for ( ; i < end; i++) + tmpY[i] = lumSrcPtr[i]; + for ( ; i < vLumFilterSize; i++) + tmpY[i] = tmpY[i-1]; + lumSrcPtr = tmpY; + + if (alpSrcPtr) { + const int16_t **tmpA = (const int16_t **) alpPixBuf + 2 * vLumBufSize; + for (i = 0; i < neg; i++) + tmpA[i] = alpSrcPtr[neg]; + for ( ; i < end; i++) + tmpA[i] = alpSrcPtr[i]; + for ( ; i < vLumFilterSize; i++) + tmpA[i] = tmpA[i - 1]; + alpSrcPtr = tmpA; + } + } + if (firstChrSrcY < 0 || firstChrSrcY + vChrFilterSize > c->chrSrcH) { + const int16_t **tmpU = (const int16_t **) chrUPixBuf + 2 * vChrBufSize; + int neg = -firstChrSrcY, i, end = FFMIN(c->chrSrcH - firstChrSrcY, vChrFilterSize); + for (i = 0; i < neg; i++) { + tmpU[i] = chrUSrcPtr[neg]; + } + for ( ; i < end; i++) { + tmpU[i] = chrUSrcPtr[i]; + } + for ( ; i < vChrFilterSize; i++) { + tmpU[i] = tmpU[i - 1]; + } + chrUSrcPtr = tmpU; + } + if (flags & SWS_ACCURATE_RND) { int s= APCK_SIZE / 8; for (i=0; i Date: Fri, 17 Feb 2012 12:10:33 -0800 Subject: [PATCH 13/84] cook: prevent div-by-zero if channels is zero. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 941fc1ea1ed7f7d99a8b9e2607b41f2f2820394a) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavcodec/cook.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/cook.c b/libavcodec/cook.c index a8fa01e5d2..429b4d0155 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -1066,6 +1066,10 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->sample_rate = avctx->sample_rate; q->nb_channels = avctx->channels; q->bit_rate = avctx->bit_rate; + if (!q->nb_channels) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); + return AVERROR_INVALIDDATA; + } /* Initialize RNG. */ av_lfg_init(&q->random_state, 0); From 4509129e9d04c93a3de4005787a058d1b950eb03 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 17 Feb 2012 12:28:26 -0800 Subject: [PATCH 14/84] als: prevent infinite loop in zero_remaining(). Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit af468015d972c0dec5c8c37b2685ffa5cbe4ae87) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavcodec/alsdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index 17c54900f7..f2944c6038 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -1010,7 +1010,7 @@ static void zero_remaining(unsigned int b, unsigned int b_max, { unsigned int count = 0; - while (b < b_max) + for (; b < b_max; b++) count += div_blocks[b]; if (count) From 2380a3d37f0b94436db53aa56491cbc9203bc8fe Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 17 Feb 2012 15:00:47 -0800 Subject: [PATCH 15/84] huffyuv: error out on bit overrun. On EOF, get_bits() will continuously return 0, causing an infinite loop. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 84c202cc37024bd78261e4222e46631ea73c48dd) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavcodec/huffyuv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index a399142d59..d211964eca 100644 --- a/libavcodec/huffyuv.c +++ b/libavcodec/huffyuv.c @@ -184,7 +184,7 @@ static int read_len_table(uint8_t *dst, GetBitContext *gb){ if(repeat==0) repeat= get_bits(gb, 8); //printf("%d %d\n", val, repeat); - if(i+repeat > 256) { + if(i+repeat > 256 || get_bits_left(gb) < 0) { av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n"); return -1; } From 9a331217b00be566e8cc7afcd4df916b43e1756b Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 17 Feb 2012 12:21:18 -0800 Subject: [PATCH 16/84] asf: prevent packet_size_left from going negative if hdrlen > pktlen. This prevents failed assertions further down in the packet processing where we require non-negative values for packet_size_left. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 41afac7f7a67c634c86b1d17fc930e9183d4aaa0) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavformat/asfdec.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 16bba93c37..603886754d 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -789,6 +789,13 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb) asf->packet_segments = 1; asf->packet_segsizetype = 0x80; } + if (rsize > packet_length - padsize) { + asf->packet_size_left = 0; + av_log(s, AV_LOG_ERROR, + "invalid packet header length %d for pktlen %d-%d at %"PRId64"\n", + rsize, packet_length, padsize, avio_tell(pb)); + return -1; + } asf->packet_size_left = packet_length - padsize - rsize; if (packet_length < asf->hdr.min_pktsize) padsize += asf->hdr.min_pktsize - packet_length; From 33149928edef047fb6391cf8a84602a213c62921 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 17 Feb 2012 16:27:36 -0800 Subject: [PATCH 17/84] mjpegb: don't return 0 at the end of frame decoding. Return 0 indicates "please return the same data again", i.e. it causes an infinite loop. Instead, return that we consumed the buffer if we finished decoding succesfully, or return an error if an error occurred. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 74699ac8c8b562e9f8d26e21482b89585365774a) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavcodec/mjpegbdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c index 837304ea74..454ba6ffc9 100644 --- a/libavcodec/mjpegbdec.c +++ b/libavcodec/mjpegbdec.c @@ -66,7 +66,7 @@ read_header: if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g')) { av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n"); - return 0; + return AVERROR_INVALIDDATA; } field_size = get_bits_long(&hgb, 32); /* field size */ @@ -142,7 +142,7 @@ read_header: picture->quality*= FF_QP2LAMBDA; } - return buf_ptr - buf; + return buf_size; } AVCodec ff_mjpegb_decoder = { From 18b2f23ef83cf317fcf0de6035878407ba68829c Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 22 Feb 2012 12:19:52 -0800 Subject: [PATCH 18/84] truemotion2: error out if the huffman tree has no nodes. This prevents crashers and errors further down when reading nodes in the empty tree. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 2b83e8b7005d531bc78b0fd4f699e9faa54ce9bb) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavcodec/truemotion2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index 23abade214..6ca97338e1 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -132,7 +132,7 @@ static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code) huff.val_bits, huff.max_bits); return -1; } - if((huff.nodes < 0) || (huff.nodes > 0x10000)) { + if((huff.nodes <= 0) || (huff.nodes > 0x10000)) { av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree nodes: %i\n", huff.nodes); return -1; } From cd6c5e16c6ae536435bfde9b455b0aca6e09cbae Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 23 Feb 2012 11:53:27 -0800 Subject: [PATCH 19/84] swf: check return values for av_get/new_packet(). Prevents crashers when using the packet if allocation failed. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 31632e73f47d25e2077fce729571259ee6354854) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavformat/swfdec.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c index eec9524ecf..2df3520722 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -84,7 +84,7 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) SWFContext *swf = s->priv_data; AVIOContext *pb = s->pb; AVStream *vst = NULL, *ast = NULL, *st = 0; - int tag, len, i, frame, v; + int tag, len, i, frame, v, res; for(;;) { uint64_t pos = avio_tell(pb); @@ -147,7 +147,8 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) st = s->streams[i]; if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) { frame = avio_rl16(pb); - av_get_packet(pb, pkt, len-2); + if ((res = av_get_packet(pb, pkt, len-2)) < 0) + return res; pkt->pos = pos; pkt->pts = frame; pkt->stream_index = st->index; @@ -160,9 +161,11 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1) { if (st->codec->codec_id == CODEC_ID_MP3) { avio_skip(pb, 4); - av_get_packet(pb, pkt, len-4); + if ((res = av_get_packet(pb, pkt, len-4)) < 0) + return res; } else { // ADPCM, PCM - av_get_packet(pb, pkt, len); + if ((res = av_get_packet(pb, pkt, len)) < 0) + return res; } pkt->pos = pos; pkt->stream_index = st->index; @@ -186,7 +189,8 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) st = vst; } avio_rl16(pb); /* BITMAP_ID */ - av_new_packet(pkt, len-2); + if ((res = av_new_packet(pkt, len-2)) < 0) + return res; avio_read(pb, pkt->data, 4); if (AV_RB32(pkt->data) == 0xffd8ffd9 || AV_RB32(pkt->data) == 0xffd9ffd8) { From b1d9a808633f695aa74b5c8b59eb628bc1bea1e2 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 23 Feb 2012 10:47:50 -0800 Subject: [PATCH 20/84] tiff: Prevent overreads in the type_sizes array. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 447363870f2f91e125e07ac2d0820359a5d86b06) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavcodec/tiff.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 6bfef220f4..71a4e70e3e 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -288,6 +288,11 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * count = tget_long(&buf, s->le); off = tget_long(&buf, s->le); + if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) { + av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n", type); + return 0; + } + if(count == 1){ switch(type){ case TIFF_BYTE: @@ -309,10 +314,12 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * value = -1; buf = start + off; } - }else if(type_sizes[type] * count <= 4){ - buf -= 4; - }else{ - buf = start + off; + } else { + if (count <= 4 && type_sizes[type] * count <= 4) { + buf -= 4; + } else { + buf = start + off; + } } if(buf && (buf < start || buf > end_buf)){ From d10c22d33ce3d134025bc7fb0b2acbd58a0cef50 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 23 Feb 2012 16:09:36 -0800 Subject: [PATCH 21/84] lcl: error out if uncompressed input buffer is smaller than framesize. This prevents crashes when trying to read beyond the end of the buffer while decoding frame data. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit be129271eac04f91393bf42a490ec631e1a9abea) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavcodec/lcldec.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index 70414d4d55..017df55da7 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -223,8 +223,29 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac len = mszh_dlen; } break; - case COMP_MSZH_NOCOMP: + case COMP_MSZH_NOCOMP: { + int bppx2; + switch (c->imgtype) { + case IMGTYPE_YUV111: + case IMGTYPE_RGB24: + bppx2 = 6; + break; + case IMGTYPE_YUV422: + case IMGTYPE_YUV211: + bppx2 = 4; + break; + case IMGTYPE_YUV411: + case IMGTYPE_YUV420: + bppx2 = 3; + break; + default: + bppx2 = 0; // will error out below + break; + } + if (len < ((width * height * bppx2) >> 1)) + return AVERROR_INVALIDDATA; break; + } default: av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n"); return -1; From 25784c040904d3b5bc532583495b0a473360e246 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 24 Feb 2012 16:27:53 -0800 Subject: [PATCH 22/84] kgv1: release reference picture on size change. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 6c4c27adb61b2881a94ce5c7d97ee1c8adadb5fe) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavcodec/kgv1dec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c index 88c54bf817..e26fd81ffb 100644 --- a/libavcodec/kgv1dec.c +++ b/libavcodec/kgv1dec.c @@ -54,8 +54,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (av_image_check_size(w, h, 0, avctx)) return -1; - if (w != avctx->width || h != avctx->height) + if (w != avctx->width || h != avctx->height) { + if (c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); avcodec_set_dimensions(avctx, w, h); + } maxcnt = w * h; From 678737c26be4fb93dc6b3ede04b8231bd39b2e3b Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 24 Feb 2012 14:11:04 -0800 Subject: [PATCH 23/84] fraps: release reference buffer on pix_fmt change. Prevents crash when trying to copy from a non-existing plane in e.g. a RGB32 reference image to a YUV420P target image Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 830f70442a87a31f7c75565e9380e3caf8333b8a) Signed-off-by: Anton Khirnov Signed-off-by: Reinhard Tartler --- libavcodec/fraps.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index 2bbc7b9f01..90989e8f08 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -134,7 +134,7 @@ static int decode_frame(AVCodecContext *avctx, uint32_t *luma1,*luma2,*cb,*cr; uint32_t offs[4]; int i, j, is_chroma, planes; - + enum PixelFormat pix_fmt; header = AV_RL32(buf); version = header & 0xff; @@ -151,12 +151,16 @@ static int decode_frame(AVCodecContext *avctx, if (header_size == 8) buf+=4; + pix_fmt = version & 1 ? PIX_FMT_BGR24 : PIX_FMT_YUVJ420P; + if (avctx->pix_fmt != pix_fmt && f->data[0]) { + avctx->release_buffer(avctx, f); + } + avctx->pix_fmt = pix_fmt; + switch(version) { case 0: default: /* Fraps v0 is a reordered YUV420 */ - avctx->pix_fmt = PIX_FMT_YUVJ420P; - if ( (buf_size != avctx->width*avctx->height*3/2+header_size) && (buf_size != header_size) ) { av_log(avctx, AV_LOG_ERROR, @@ -204,8 +208,6 @@ static int decode_frame(AVCodecContext *avctx, case 1: /* Fraps v1 is an upside-down BGR24 */ - avctx->pix_fmt = PIX_FMT_BGR24; - if ( (buf_size != avctx->width*avctx->height*3+header_size) && (buf_size != header_size) ) { av_log(avctx, AV_LOG_ERROR, @@ -240,7 +242,6 @@ static int decode_frame(AVCodecContext *avctx, * Fraps v2 is Huffman-coded YUV420 planes * Fraps v4 is virtually the same */ - avctx->pix_fmt = PIX_FMT_YUVJ420P; planes = 3; f->reference = 1; f->buffer_hints = FF_BUFFER_HINTS_VALID | @@ -283,7 +284,6 @@ static int decode_frame(AVCodecContext *avctx, case 3: case 5: /* Virtually the same as version 4, but is for RGB24 */ - avctx->pix_fmt = PIX_FMT_BGR24; planes = 3; f->reference = 1; f->buffer_hints = FF_BUFFER_HINTS_VALID | From 811989e91092bfa8cbcf6305eee7c1353da99809 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 22 Feb 2012 11:33:24 -0800 Subject: [PATCH 24/84] rm: prevent infinite loops for index parsing. Specifically, prevent jumping back in the file for the next index, since this can lead to infinite loops where we jump between indexes referring to each other, and don't read indexes that don't fit in the file. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit aac07a7a4c2c7a4a29cf6dbc88c1b9fdd191b99d) Signed-off-by: Reinhard Tartler --- libavformat/rmdec.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index fbc4d0cee6..dbfeb927cf 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -350,8 +350,19 @@ static int rm_read_index(AVFormatContext *s) st = s->streams[n]; break; } - if (n == s->nb_streams) + if (n == s->nb_streams) { + av_log(s, AV_LOG_ERROR, + "Invalid stream index %d for index at pos %"PRId64"\n", + str_id, avio_tell(pb)); goto skip; + } else if ((avio_size(pb) - avio_tell(pb)) / 14 < n_pkts) { + av_log(s, AV_LOG_ERROR, + "Nr. of packets in packet index for stream index %d " + "exceeds filesize (%"PRId64" at %"PRId64" = %d)\n", + str_id, avio_size(pb), avio_tell(pb), + (avio_size(pb) - avio_tell(pb)) / 14); + goto skip; + } for (n = 0; n < n_pkts; n++) { avio_skip(pb, 2); @@ -363,9 +374,12 @@ static int rm_read_index(AVFormatContext *s) } skip: - if (next_off && avio_tell(pb) != next_off && - avio_seek(pb, next_off, SEEK_SET) < 0) + if (next_off && avio_tell(pb) < next_off && + avio_seek(pb, next_off, SEEK_SET) < 0) { + av_log(s, AV_LOG_ERROR, + "Non-linear index detected, not supported\n"); return -1; + } } while (next_off); return 0; From a02da9ceaf298e57bd6f579ea6158164d32ed18e Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Sun, 26 Feb 2012 10:50:45 +0100 Subject: [PATCH 25/84] Fix parser not to clobber has_b_frames when extradata is set. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Because in contrast to the decoder, the parser does not setup low_delay. The code in parse_nal_units would always end up setting has_b_frames to "1", except when stream is explicitly marked as low delay. Since the parser itself would create 'extradata', simply reopening the parser would cause this. This happens for instance in estimate_timings_from_pts(), which causes the parser to be reopened on the same stream. This fixes Libav #22 and FFmpeg (trac) #360 CC: libav-stable@libav.org Based on a patch by Reimar Döffinger (commit 31ac0ac29b6bba744493f7d1040757a3f51b9ad7) Comments and description adapted by Reinhard Tartler. Signed-off-by: Reinhard Tartler (cherry picked from commit 790a367d9ecd04360f78616765ee723f3fe65645) Signed-off-by: Reinhard Tartler --- libavcodec/h264_parser.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index c39baeb739..4263c4b2e9 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -251,6 +251,13 @@ static int h264_parse(AVCodecParserContext *s, h->got_first = 1; if (avctx->extradata_size) { h->s.avctx = avctx; + // must be done like in the decoder. + // otherwise opening the parser, creating extradata, + // and then closing and opening again + // will cause has_b_frames to be always set. + // NB: estimate_timings_from_pts behaves exactly like this. + if (!avctx->has_b_frames) + h->s.low_delay = 1; ff_h264_decode_extradata(h); } } From 117b8b00cc12efb473402a8d6ab1e9013ea0a851 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 10 Jan 2012 17:01:26 -0800 Subject: [PATCH 26/84] vorbis: fix overflows in floor1[] vector and inverse db table index. (cherry picked from commit 24947d4988012f1f0fd467c83418615adc11c3e8) Signed-off-by: Reinhard Tartler --- libavcodec/vorbis.c | 19 +++++++++---------- libavcodec/vorbisdec.c | 10 +++++----- 2 files changed, 14 insertions(+), 15 deletions(-) diff --git a/libavcodec/vorbis.c b/libavcodec/vorbis.c index cc039be190..20be707313 100644 --- a/libavcodec/vorbis.c +++ b/libavcodec/vorbis.c @@ -150,7 +150,7 @@ void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values) } } -static inline void render_line_unrolled(intptr_t x, uint8_t y, int x1, +static inline void render_line_unrolled(intptr_t x, int y, int x1, intptr_t sy, int ady, int adx, float *buf) { @@ -162,30 +162,30 @@ static inline void render_line_unrolled(intptr_t x, uint8_t y, int x1, if (err >= 0) { err += ady - adx; y += sy; - buf[x++] = ff_vorbis_floor1_inverse_db_table[y]; + buf[x++] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; } - buf[x] = ff_vorbis_floor1_inverse_db_table[y]; + buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; } if (x <= 0) { if (err + ady >= 0) y += sy; - buf[x] = ff_vorbis_floor1_inverse_db_table[y]; + buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; } } -static void render_line(int x0, uint8_t y0, int x1, int y1, float *buf) +static void render_line(int x0, int y0, int x1, int y1, float *buf) { int dy = y1 - y0; int adx = x1 - x0; int ady = FFABS(dy); int sy = dy < 0 ? -1 : 1; - buf[x0] = ff_vorbis_floor1_inverse_db_table[y0]; + buf[x0] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y0)]; if (ady*2 <= adx) { // optimized common case render_line_unrolled(x0, y0, x1, sy, ady, adx, buf); } else { int base = dy / adx; int x = x0; - uint8_t y = y0; + int y = y0; int err = -adx; ady -= FFABS(base) * adx; while (++x < x1) { @@ -195,7 +195,7 @@ static void render_line(int x0, uint8_t y0, int x1, int y1, float *buf) err -= adx; y += sy; } - buf[x] = ff_vorbis_floor1_inverse_db_table[y]; + buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; } } } @@ -204,8 +204,7 @@ void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values, uint16_t *y_list, int *flag, int multiplier, float *out, int samples) { - int lx, i; - uint8_t ly; + int lx, ly, i; lx = 0; ly = y_list[0] * multiplier; for (i = 1; i < values; i++) { diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 572e06ebc3..d6850b7f48 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -1232,20 +1232,20 @@ static int vorbis_floor1_decode(vorbis_context *vc, floor1_flag[i] = 1; if (val >= room) { if (highroom > lowroom) { - floor1_Y_final[i] = val - lowroom + predicted; + floor1_Y_final[i] = av_clip_uint16(val - lowroom + predicted); } else { - floor1_Y_final[i] = predicted - val + highroom - 1; + floor1_Y_final[i] = av_clip_uint16(predicted - val + highroom - 1); } } else { if (val & 1) { - floor1_Y_final[i] = predicted - (val + 1) / 2; + floor1_Y_final[i] = av_clip_uint16(predicted - (val + 1) / 2); } else { - floor1_Y_final[i] = predicted + val / 2; + floor1_Y_final[i] = av_clip_uint16(predicted + val / 2); } } } else { floor1_flag[i] = 0; - floor1_Y_final[i] = predicted; + floor1_Y_final[i] = av_clip_uint16(predicted); } av_dlog(NULL, " Decoded floor(%d) = %u / val %u\n", From 18caebca4c91605fd0a9f5bc339a63be9a6c977a Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Fri, 17 Feb 2012 12:21:22 -0800 Subject: [PATCH 27/84] asf: error out on ridiculously large minpktsize values. They cause various issues further down in demuxing. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 6e57a02b9f639af53acfa9fc742c1341400818f8) Signed-off-by: Reinhard Tartler --- libavformat/asfdec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 603886754d..61721704d5 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -202,6 +202,8 @@ static int asf_read_file_properties(AVFormatContext *s, int64_t size) asf->hdr.flags = avio_rl32(pb); asf->hdr.min_pktsize = avio_rl32(pb); asf->hdr.max_pktsize = avio_rl32(pb); + if (asf->hdr.min_pktsize >= (1U<<29)) + return AVERROR_INVALIDDATA; asf->hdr.max_bitrate = avio_rl32(pb); s->packet_size = asf->hdr.max_pktsize; @@ -616,7 +618,9 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) if (gsize < 24) return -1; if (!ff_guidcmp(&g, &ff_asf_file_header)) { - asf_read_file_properties(s, gsize); + int ret = asf_read_file_properties(s, gsize); + if (ret < 0) + return ret; } else if (!ff_guidcmp(&g, &ff_asf_stream_header)) { asf_read_stream_properties(s, gsize); } else if (!ff_guidcmp(&g, &ff_asf_comment_header)) { From a2d5e741a889bfed621e18a94ff266d49d280557 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 28 Feb 2012 16:13:46 -0800 Subject: [PATCH 28/84] asf: don't seek back on EOF. Seeking back on EOF will reset the EOF flag, causing us to re-enter the loop to find the next marker in the ASF file, thus potentially causing an infinite loop. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit bb6d5411e1e1a8e0608b1af1c4addee654dcbac5) Signed-off-by: Reinhard Tartler --- libavformat/asfdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 61721704d5..47d5b190c3 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -761,7 +761,7 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb) c= avio_r8(pb); d= avio_r8(pb); rsize+=3; - }else{ + } else if (!pb->eof_reached) { avio_seek(pb, -1, SEEK_CUR); //FIXME } From f28ec733798ceb2fc4a9c8a9c39c73e8d447310f Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 23 Feb 2012 11:19:33 -0800 Subject: [PATCH 29/84] vp56: error out on invalid stream dimensions. Prevents crashes when playing corrupt vp5/6 streams. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 8bc396fc0e8769a056375c1c211f389ce0e3ecc5) Signed-off-by: Reinhard Tartler --- libavcodec/vp5.c | 5 +++++ libavcodec/vp6.c | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c index d61163e64c..2b975801d0 100644 --- a/libavcodec/vp5.c +++ b/libavcodec/vp5.c @@ -55,6 +55,11 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, } rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */ cols = vp56_rac_gets(c, 8); /* number of stored macroblock cols */ + if (!rows || !cols) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", + cols << 4, rows << 4); + return 0; + } vp56_rac_gets(c, 8); /* number of displayed macroblock rows */ vp56_rac_gets(c, 8); /* number of displayed macroblock cols */ vp56_rac_gets(c, 2); diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index 02fe70bf7f..b0d8642465 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -75,6 +75,10 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, cols = buf[3]; /* number of stored macroblock cols */ /* buf[4] is number of displayed macroblock rows */ /* buf[5] is number of displayed macroblock cols */ + if (!rows || !cols) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", cols << 4, rows << 4); + return 0; + } if (!s->macroblocks || /* first frame */ 16*cols != s->avctx->coded_width || @@ -95,7 +99,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, vrt_shift = 5; s->sub_version = sub_version; } else { - if (!s->sub_version) + if (!s->sub_version || !s->avctx->coded_width || !s->avctx->coded_height) return 0; if (separated_coeff || !s->filter_header) { From 4f64456a144d89cc026048816031e8c3dcd29737 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 28 Feb 2012 18:21:31 -0800 Subject: [PATCH 30/84] swscale: fix another integer overflow. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 791de61bbb0d2bceb1037597b310e2a4a94494fd) Signed-off-by: Reinhard Tartler --- libswscale/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libswscale/utils.c b/libswscale/utils.c index 0aeec6f0fc..70a38b5962 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -1002,7 +1002,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) c->vLumBufSize= c->vLumFilterSize; c->vChrBufSize= c->vChrFilterSize; for (i=0; ichrDstH / dstH; + int chrI = (int64_t) i * c->chrDstH / dstH; int nextSlice= FFMAX(c->vLumFilterPos[i ] + c->vLumFilterSize - 1, ((c->vChrFilterPos[chrI] + c->vChrFilterSize - 1)<chrSrcVSubSample)); From 87a1169ab85d4232daff457b16c2fac9280fe608 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 28 Feb 2012 19:00:39 -0800 Subject: [PATCH 31/84] qtrle: return error on decode_init() failure. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit e54ae60e46f737b8e9a96548971091f7ab6b8f7c) Signed-off-by: Reinhard Tartler --- libavcodec/qtrle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c index e14c306c6b..6f65d1ec66 100644 --- a/libavcodec/qtrle.c +++ b/libavcodec/qtrle.c @@ -414,7 +414,7 @@ static av_cold int qtrle_decode_init(AVCodecContext *avctx) default: av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n", avctx->bits_per_coded_sample); - break; + return AVERROR_INVALIDDATA; } s->frame.data[0] = NULL; From e15d137ecfa9e78797e7f25b5aa32834f00f2559 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 28 Feb 2012 17:04:33 -0800 Subject: [PATCH 32/84] rpza: error out on buffer overreads. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 78e9852a2e3b198ecd69ffa0deab3fa22a8e5378) Signed-off-by: Reinhard Tartler --- libavcodec/rpza.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c index 958f103865..d1803fccc5 100644 --- a/libavcodec/rpza.c +++ b/libavcodec/rpza.c @@ -183,6 +183,8 @@ static void rpza_decode_stream(RpzaContext *s) color4[1] |= ((11 * ta + 21 * tb) >> 5); color4[2] |= ((21 * ta + 11 * tb) >> 5); + if (s->size - stream_ptr < n_blocks * 4) + return; while (n_blocks--) { block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { @@ -200,6 +202,8 @@ static void rpza_decode_stream(RpzaContext *s) /* Fill block with 16 colors */ case 0x00: + if (s->size - stream_ptr < 16) + return; block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++){ From ced190c96c1fa99ca395ad02290f9784f07b07ee Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 28 Feb 2012 19:00:48 -0800 Subject: [PATCH 33/84] vmnc: return error on decode_init() failure. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 07a180972fb369bb59bf6d4f8edb4598c51e80d2) Signed-off-by: Reinhard Tartler --- libavcodec/vmnc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c index f95bef7e1d..4521d1598b 100644 --- a/libavcodec/vmnc.c +++ b/libavcodec/vmnc.c @@ -483,6 +483,7 @@ static av_cold int decode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", c->bpp); + return AVERROR_INVALIDDATA; } return 0; From d680295d0c3662793292338d0fd01b044601f338 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 1 Mar 2012 09:41:22 -0800 Subject: [PATCH 34/84] huffyuv: do not abort on unknown pix_fmt; instead, return an error. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 63c9de6469005974288f4e4d89fc79a590e38c06) Signed-off-by: Reinhard Tartler --- libavcodec/huffyuv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index d211964eca..eb13d87f87 100644 --- a/libavcodec/huffyuv.c +++ b/libavcodec/huffyuv.c @@ -514,7 +514,7 @@ s->bgr32=1; } break; default: - assert(0); + return AVERROR_INVALIDDATA; } alloc_temp(s); From bd0d32d13181c452906011e33000fc4328771005 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 29 Feb 2012 17:50:28 -0800 Subject: [PATCH 35/84] lcl: return negative error codes on decode_init() errors. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit bd17a40a7e0eba21b5d27c67aff795e2910766e4) Signed-off-by: Reinhard Tartler --- libavcodec/lcldec.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index 017df55da7..8f203eb740 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -476,7 +476,7 @@ static av_cold int decode_init(AVCodecContext *avctx) if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); - return 1; + return AVERROR_INVALIDDATA; } /* Check codec type */ @@ -525,7 +525,7 @@ static av_cold int decode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); - return 1; + return AVERROR_INVALIDDATA; } /* Detect compression method */ @@ -542,7 +542,7 @@ static av_cold int decode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); - return 1; + return AVERROR_INVALIDDATA; } break; #if CONFIG_ZLIB_DECODER @@ -560,7 +560,7 @@ static av_cold int decode_init(AVCodecContext *avctx) default: if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) { av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression); - return 1; + return AVERROR_INVALIDDATA; } av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression); } @@ -568,14 +568,14 @@ static av_cold int decode_init(AVCodecContext *avctx) #endif default: av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); - return 1; + return AVERROR_INVALIDDATA; } /* Allocate decompression buffer */ if (c->decomp_size) { if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 1; + return AVERROR(ENOMEM); } } @@ -601,7 +601,7 @@ static av_cold int decode_init(AVCodecContext *avctx) if (zret != Z_OK) { av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); av_freep(&c->decomp_buf); - return 1; + return AVERROR_UNKNOWN; } } #endif From b56b7b9081d5b9048732c0db171c7b6af9831bad Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 1 Mar 2012 14:07:22 -0800 Subject: [PATCH 36/84] rv10/20: Fix a buffer overread caused by losing track of the remaining buffer size. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 2f6528537fdd88820f3a4683d5e595d7b3a62689) Signed-off-by: Reinhard Tartler --- libavcodec/rv10.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index 223500c356..3ac0378d7d 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -653,8 +653,12 @@ static int rv10_decode_frame(AVCodecContext *avctx, if(!avctx->slice_count){ slice_count = (*buf++) + 1; + buf_size--; slices_hdr = buf + 4; buf += 8 * slice_count; + buf_size -= 8 * slice_count; + if (buf_size <= 0) + return AVERROR_INVALIDDATA; }else slice_count = avctx->slice_count; @@ -693,7 +697,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...) } - return buf_size; + return avpkt->size; } AVCodec ff_rv10_decoder = { From 88b47010c4e2ed0d756f30c54b0d88153c33aec5 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Fri, 27 Jan 2012 14:24:07 -0800 Subject: [PATCH 37/84] wmadec: Verify bitstream size makes sense before calling init_get_bits. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind (cherry picked from commit 48f1e5212c90b511c90fa0449655abb06a9edda2) Signed-off-by: Reinhard Tartler --- libavcodec/wmadec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 479b34c3e0..c8e1de2c32 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -864,6 +864,8 @@ static int wma_decode_superframe(AVCodecContext *avctx, /* read each frame starting from bit_offset */ pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3; + if (pos >= MAX_CODED_SUPERFRAME_SIZE * 8) + return AVERROR_INVALIDDATA; init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8); len = pos & 7; if (len > 0) From 433aaeb2f1cf679f254f5f1c7220b4100bc89c68 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 1 Mar 2012 17:01:22 -0800 Subject: [PATCH 38/84] matroska: check buffer size for RM-style byte reordering. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 9c239f6026a170866a4a0c96908980ac2cfaa8b3) Signed-off-by: Reinhard Tartler --- libavformat/matroskadec.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index f74d028923..a70f2ef86a 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1775,15 +1775,31 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, if (!track->audio.pkt_cnt) { if (track->audio.sub_packet_cnt == 0) track->audio.buf_timecode = timecode; - if (st->codec->codec_id == CODEC_ID_RA_288) + if (st->codec->codec_id == CODEC_ID_RA_288) { + if (size < cfs * h / 2) { + av_log(matroska->ctx, AV_LOG_ERROR, + "Corrupt int4 RM-style audio packet size\n"); + return AVERROR_INVALIDDATA; + } for (x=0; xaudio.buf+x*2*w+y*cfs, data+x*cfs, cfs); - else if (st->codec->codec_id == CODEC_ID_SIPR) + } else if (st->codec->codec_id == CODEC_ID_SIPR) { + if (size < w) { + av_log(matroska->ctx, AV_LOG_ERROR, + "Corrupt sipr RM-style audio packet size\n"); + return AVERROR_INVALIDDATA; + } memcpy(track->audio.buf + y*w, data, w); - else + } else { + if (size < sps * w / sps) { + av_log(matroska->ctx, AV_LOG_ERROR, + "Corrupt generic RM-style audio packet size\n"); + return AVERROR_INVALIDDATA; + } for (x=0; xaudio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps); + } if (++track->audio.sub_packet_cnt >= h) { if (st->codec->codec_id == CODEC_ID_SIPR) From c932844882f315928688c704fd9cdcb7eee37d17 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 2 Mar 2012 16:33:33 -0500 Subject: [PATCH 39/84] wmaenc: require a large enough output buffer to prevent overwrites The maximum theoretical frame size is around 17000 bytes. Although in practice it will generally be much smaller, we require a larger buffer just to be safe. CC: libav-stable@libav.org (cherry picked from commit dfc4fdedf8cfc56a505579b1f2c1c5efbce4b97e) Signed-off-by: Reinhard Tartler --- libavcodec/wmaenc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index 3cdb4a0b9b..a002c32b5d 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -355,6 +355,11 @@ static int encode_superframe(AVCodecContext *avctx, } } + if (buf_size < 2 * MAX_CODED_SUPERFRAME_SIZE) { + av_log(avctx, AV_LOG_ERROR, "output buffer size is too small\n"); + return AVERROR(EINVAL); + } + #if 1 total_gain= 128; for(i=64; i; i>>=1){ From 74bd46e82ad6e1cf57b5427a53a5213e7dfa61cd Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 2 Mar 2012 16:10:00 -0500 Subject: [PATCH 40/84] wmaenc: limit block_align to MAX_CODED_SUPERFRAME_SIZE This is near the theoretical limit for wma frame size and is the most that our decoder can handle. Allowing higher bit rates will just end up padding each frame with empty bytes. Fixes invalid writes for avconv when using very high bit rates. CC:libav-stable@libav.org (cherry picked from commit c2b8dea1828f35c808adcf12615893d5c740bc0a) Signed-off-by: Reinhard Tartler --- libavcodec/wmaenc.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index a002c32b5d..5f272f3748 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -71,8 +71,12 @@ static int encode_init(AVCodecContext * avctx){ for(i = 0; i < s->nb_block_sizes; i++) ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 0, 1.0); - avctx->block_align= - s->block_align= avctx->bit_rate*(int64_t)s->frame_len / (avctx->sample_rate*8); + s->block_align = avctx->bit_rate * (int64_t)s->frame_len / + (avctx->sample_rate * 8); + s->block_align = FFMIN(s->block_align, MAX_CODED_SUPERFRAME_SIZE); + avctx->block_align = s->block_align; + avctx->bit_rate = avctx->block_align * 8LL * avctx->sample_rate / + s->frame_len; //av_log(NULL, AV_LOG_ERROR, "%d %d %d %d\n", s->block_align, avctx->bit_rate, s->frame_len, avctx->sample_rate); avctx->frame_size= s->frame_len; From 43e3e7764c498138c28507c5a7dfcd08c0748633 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 2 Mar 2012 16:27:57 -0500 Subject: [PATCH 41/84] wmaenc: limit allowed sample rate to 48kHz ff_wma_init() allows up to 50kHz, but this generates an exponent band size table that requires 65 bands. The code assumes 25 bands in many places, and using sample rates higher than 48kHz will lead to buffer overwrites. CC:libav-stable@libav.org (cherry picked from commit 1ec075cfecac01f9a289965db06f76365b0b1737) Signed-off-by: Reinhard Tartler --- libavcodec/wmaenc.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index 5f272f3748..bf451aa258 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -39,6 +39,12 @@ static int encode_init(AVCodecContext * avctx){ return AVERROR(EINVAL); } + if (avctx->sample_rate > 48000) { + av_log(avctx, AV_LOG_ERROR, "sample rate is too high: %d > 48kHz", + avctx->sample_rate); + return AVERROR(EINVAL); + } + if(avctx->bit_rate < 24*1000) { av_log(avctx, AV_LOG_ERROR, "bitrate too low: got %i, need 24000 or higher\n", avctx->bit_rate); From 58133bb010c1587515ab4a8bf990760ca28b4dda Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 2 Mar 2012 17:11:25 -0500 Subject: [PATCH 42/84] wmaenc: fix m/s stereo encoding for the first frame We need to set ms_stereo in encode_init() in order to avoid incorrectly encoding the first frame as non-m/s while flagging it as m/s. Fixes an uncomfortable pop in the left channel at the start of playback. CC:libav-stable@libav.org (cherry picked from commit 51ddf35c9017018e58c15275ff5b129647a0c94d) Signed-off-by: Reinhard Tartler --- libavcodec/wmaenc.c | 4 +++- tests/ref/acodec/wmav1 | 6 +++--- tests/ref/acodec/wmav2 | 6 +++--- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index bf451aa258..f83dd37520 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -70,6 +70,8 @@ static int encode_init(AVCodecContext * avctx){ s->use_exp_vlc = flags2 & 0x0001; s->use_bit_reservoir = flags2 & 0x0002; s->use_variable_block_len = flags2 & 0x0004; + if (avctx->channels == 2) + s->ms_stereo = 1; ff_wma_init(avctx, flags2); @@ -191,7 +193,7 @@ static int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], } if (s->nb_channels == 2) { - put_bits(&s->pb, 1, s->ms_stereo= 1); + put_bits(&s->pb, 1, !!s->ms_stereo); } for(ch = 0; ch < s->nb_channels; ch++) { diff --git a/tests/ref/acodec/wmav1 b/tests/ref/acodec/wmav1 index 916e4a8ab6..117aa12a8c 100644 --- a/tests/ref/acodec/wmav1 +++ b/tests/ref/acodec/wmav1 @@ -1,4 +1,4 @@ -26a7f6b0f0b7181df8df3fa589f6bf81 *./tests/data/acodec/wmav1.asf +0260385b8a54df11ad349f9ba8240fd8 *./tests/data/acodec/wmav1.asf 106004 ./tests/data/acodec/wmav1.asf -stddev:12245.52 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400 -stddev: 2095.89 PSNR: 29.90 MAXDIFF:27658 bytes: 1056768/ 1058400 +stddev:12241.90 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400 +stddev: 2074.79 PSNR: 29.99 MAXDIFF:27658 bytes: 1056768/ 1058400 diff --git a/tests/ref/acodec/wmav2 b/tests/ref/acodec/wmav2 index 622b6fcc36..43b19b7530 100644 --- a/tests/ref/acodec/wmav2 +++ b/tests/ref/acodec/wmav2 @@ -1,4 +1,4 @@ -7c6c0cb692af01b312ae345723674b5f *./tests/data/acodec/wmav2.asf +bdb4c312fb109f990be83a70f8ec9bdc *./tests/data/acodec/wmav2.asf 106044 ./tests/data/acodec/wmav2.asf -stddev:12249.93 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400 -stddev: 2089.21 PSNR: 29.93 MAXDIFF:27650 bytes: 1056768/ 1058400 +stddev:12246.35 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400 +stddev: 2068.08 PSNR: 30.02 MAXDIFF:27650 bytes: 1056768/ 1058400 From bd37b95383b6bd6b69aa8dba8eebd2cbef2aeed8 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 28 Feb 2012 18:48:27 -0800 Subject: [PATCH 43/84] h264: prevent overreads in intra PCM decoding. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit d1604b3de96575195b219028e2c4f08b2259aa7d) Signed-off-by: Reinhard Tartler --- libavcodec/h264_cabac.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index e8c8503857..ae3318da53 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -1958,6 +1958,8 @@ decode_intra_mb: } // The pixels are stored in the same order as levels in h->mb array. + if ((int) (h->cabac.bytestream_end - ptr) < mb_size) + return -1; memcpy(h->mb, ptr, mb_size); ptr+=mb_size; ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr); From e3e05963c1eff2481da3a2ea9ce662336391e2ca Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 29 Feb 2012 13:55:09 -0800 Subject: [PATCH 44/84] cscd: use negative error values to indicate decode_init() failures. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 8a9faf33f2b4f40afbc3393b2be49867cea0c92d) Signed-off-by: Reinhard Tartler --- libavcodec/cscd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c index 3518929c18..52040bf821 100644 --- a/libavcodec/cscd.c +++ b/libavcodec/cscd.c @@ -228,7 +228,7 @@ static av_cold int decode_init(AVCodecContext *avctx) { av_log(avctx, AV_LOG_ERROR, "CamStudio codec error: invalid depth %i bpp\n", avctx->bits_per_coded_sample); - return 1; + return AVERROR_INVALIDDATA; } c->bpp = avctx->bits_per_coded_sample; c->pic.data[0] = NULL; @@ -241,7 +241,7 @@ static av_cold int decode_init(AVCodecContext *avctx) { c->decomp_buf = av_malloc(c->decomp_size + AV_LZO_OUTPUT_PADDING); if (!c->decomp_buf) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 1; + return AVERROR(ENOMEM); } return 0; } From 54e947273cefc4791d7b9e10823ffd1756cadf17 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sun, 26 Feb 2012 08:57:14 -0800 Subject: [PATCH 45/84] h264: fix mmxext chroma deblock to use correct TC values. (cherry picked from commit b0c4f04338234ee011d7b704621347ef232294fe) Signed-off-by: Reinhard Tartler --- libavcodec/x86/h264_deblock_10bit.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/x86/h264_deblock_10bit.asm b/libavcodec/x86/h264_deblock_10bit.asm index baac725eec..6744661d65 100644 --- a/libavcodec/x86/h264_deblock_10bit.asm +++ b/libavcodec/x86/h264_deblock_10bit.asm @@ -870,7 +870,7 @@ cglobal deblock_v_chroma_10_%1, 5,7-(mmsize/16),8*(mmsize/16) %if mmsize < 16 add r0, mmsize add r5, mmsize - add r4, mmsize/8 + add r4, mmsize/4 dec r6 jg .loop REP_RET From f375e19f37c7d1738cde70e43c3f64c6ab68c928 Mon Sep 17 00:00:00 2001 From: Fabian Greffrath Date: Mon, 5 Mar 2012 16:06:01 +0100 Subject: [PATCH 46/84] Fix format string vulnerability detected by -Wformat-security. Signed-off-by: Diego Biurrun (cherry picked from commit c9dbac36ad4bac07f6c1d06d465e361ab55bcb95) Signed-off-by: Reinhard Tartler --- libavcodec/srtdec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c index 677c5501f8..99cbd9428b 100644 --- a/libavcodec/srtdec.c +++ b/libavcodec/srtdec.c @@ -110,7 +110,7 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end, for (j=sptr-2; j>=0; j--) if (stack[j].param[i][0]) { out += snprintf(out, out_end-out, - stack[j].param[i]); + "%s", stack[j].param[i]); break; } } else { @@ -146,7 +146,7 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end, for (i=0; i Date: Tue, 24 Jan 2012 22:20:26 +0100 Subject: [PATCH 47/84] nsvdec: Fix use of uninitialized streams. Fixes CVE-2011-3940 (Out of bounds read resulting in out of bounds write) Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Michael Niedermayer (cherry picked from commit 5c011706bc752d34bc6ada31d7df2ca0c9af7c6b) Signed-off-by: Alex Converse (cherry picked from commit 6a89b41d9780325ba6d89a37f2aeb925aa68e6a3) Signed-off-by: Reinhard Tartler --- libavformat/nsvdec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index 9adb2f4729..c37300f5a1 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -596,12 +596,12 @@ null_chunk_retry: } /* map back streams to v,a */ - if (s->streams[0]) + if (s->nb_streams > 0) st[s->streams[0]->id] = s->streams[0]; - if (s->streams[1]) + if (s->nb_streams > 1) st[s->streams[1]->id] = s->streams[1]; - if (vsize/* && st[NSV_ST_VIDEO]*/) { + if (vsize && st[NSV_ST_VIDEO]) { nst = st[NSV_ST_VIDEO]->priv_data; pkt = &nsv->ahead[NSV_ST_VIDEO]; av_get_packet(pb, pkt, vsize); @@ -614,7 +614,7 @@ null_chunk_retry: if(st[NSV_ST_VIDEO]) ((NSVStream*)st[NSV_ST_VIDEO]->priv_data)->frame_offset++; - if (asize/*st[NSV_ST_AUDIO]*/) { + if (asize && st[NSV_ST_AUDIO]) { nst = st[NSV_ST_AUDIO]->priv_data; pkt = &nsv->ahead[NSV_ST_AUDIO]; /* read raw audio specific header on the first audio chunk... */ From be524c186b50337db64d34a5726dfe3e8ea94f09 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 26 Jan 2012 17:21:46 -0800 Subject: [PATCH 48/84] nsvdec: Be more careful with av_malloc(). Check results for av_malloc() and fix an overflow in one call. Related to CVE-2011-3940. Based in part on work from Michael Niedermayer. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind (cherry picked from commit 8fd8a48263ff1437f9d02d7e78dc63efb9b5ed3a) Signed-off-by: Reinhard Tartler --- libavformat/nsvdec.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index c37300f5a1..7041523cb0 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -307,7 +307,9 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) char *token, *value; char quote; - p = strings = av_mallocz(strings_size + 1); + p = strings = av_mallocz((size_t)strings_size + 1); + if (!p) + return AVERROR(ENOMEM); endp = strings + strings_size; avio_read(pb, strings, strings_size); while (p < endp) { @@ -342,6 +344,8 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) if((unsigned)table_entries_used >= UINT_MAX / sizeof(uint32_t)) return -1; nsv->nsvs_file_offset = av_malloc((unsigned)table_entries_used * sizeof(uint32_t)); + if (!nsv->nsvs_file_offset) + return AVERROR(ENOMEM); for(i=0;insvs_file_offset[i] = avio_rl32(pb) + size; @@ -349,6 +353,8 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) if(table_entries > table_entries_used && avio_rl32(pb) == MKTAG('T','O','C','2')) { nsv->nsvs_timestamps = av_malloc((unsigned)table_entries_used*sizeof(uint32_t)); + if (!nsv->nsvs_timestamps) + return AVERROR(ENOMEM); for(i=0;insvs_timestamps[i] = avio_rl32(pb); } From 0100c4b1b0736e0f5b3c98f9b0ab8acbef574888 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 26 Jan 2012 17:23:09 -0800 Subject: [PATCH 49/84] nsvdec: Propagate errors Related to CVE-2011-3940. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind (cherry picked from commit c898431ca5ef2a997fe9388b650f658fb60783e5) Conflicts: libavformat/nsvdec.c Signed-off-by: Reinhard Tartler --- libavformat/nsvdec.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index 7041523cb0..67c103d21f 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -523,11 +523,16 @@ static int nsv_read_header(AVFormatContext *s, AVFormatParameters *ap) for (i = 0; i < NSV_MAX_RESYNC_TRIES; i++) { if (nsv_resync(s) < 0) return -1; - if (nsv->state == NSV_FOUND_NSVF) + if (nsv->state == NSV_FOUND_NSVF) { err = nsv_parse_NSVf_header(s, ap); + if (err < 0) + return err; + } /* we need the first NSVs also... */ if (nsv->state == NSV_FOUND_NSVS) { err = nsv_parse_NSVs_header(s, ap); + if (err < 0) + return err; break; /* we just want the first one */ } } From bb737d381f6d6413899a0697f426fb082eac66fc Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 24 Jan 2012 17:48:23 +0100 Subject: [PATCH 50/84] dv: check stype dv: check stype Fixes part1 of CVE-2011-3929 Possibly fixes part of CVE-2011-3936 Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Reviewed-by: Roman Shaposhnik Signed-off-by: Michael Niedermayer Signed-off-by: Alex Converse (cherry picked from commit 635bcfccd439480003b74a665b5aa7c872c1ad6b) Signed-off-by: Reinhard Tartler --- libavformat/dv.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/libavformat/dv.c b/libavformat/dv.c index 4b41e0aa8e..fe6dac600e 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -202,6 +202,12 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame) stype = (as_pack[3] & 0x1f); /* 0 - 2CH, 2 - 4CH, 3 - 8CH */ quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */ + if (stype > 3) { + av_log(c->fctx, AV_LOG_ERROR, "stype %d is invalid\n", stype); + c->ach = 0; + return 0; + } + /* note: ach counts PAIRS of channels (i.e. stereo channels) */ ach = ((int[4]){ 1, 0, 2, 4})[stype]; if (ach == 1 && quant && freq == 2) From 44e182d41e3a73548f3f5e8445ec428d3846e6d6 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Tue, 24 Jan 2012 17:51:40 +0100 Subject: [PATCH 51/84] dv: Fix null pointer dereference due to ach=0 dv: Fix null pointer dereference due to ach=0 Fixes part2 of CVE-2011-3929 Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Reviewed-by: Roman Shaposhnik Signed-off-by: Michael Niedermayer Signed-off-by: Alex Converse (cherry picked from commit 5a396bb3a66a61a68b80f2369d0249729bf85e04) Signed-off-by: Reinhard Tartler --- libavformat/dv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavformat/dv.c b/libavformat/dv.c index fe6dac600e..cd1efddaad 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -341,7 +341,8 @@ int dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, c->audio_pkt[i].pts = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate; ppcm[i] = c->audio_buf[i]; } - dv_extract_audio(buf, ppcm, c->sys); + if (c->ach) + dv_extract_audio(buf, ppcm, c->sys); /* We work with 720p frames split in half, thus even frames have * channels 0,1 and odd 2,3. */ From 00fa6ffe1a0b252d6a81815e51f125225cd0b97a Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 26 Jan 2012 15:08:26 -0800 Subject: [PATCH 52/84] dv: Fix small stack overread related to CVE-2011-3929 and CVE-2011-3936. Found with asan. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Alex Converse (cherry picked from commit 2d1c0dea5f6b91bec7f5fa53ec050913d851e366) Signed-off-by: Reinhard Tartler --- libavformat/dv.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/libavformat/dv.c b/libavformat/dv.c index cd1efddaad..389cf063e6 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -125,10 +125,14 @@ static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4], /* We work with 720p frames split in half, thus even frames have * channels 0,1 and odd 2,3. */ ipcm = (sys->height == 720 && !(frame[1] & 0x0C)) ? 2 : 0; - pcm = ppcm[ipcm++]; /* for each DIF channel */ for (chan = 0; chan < sys->n_difchan; chan++) { + /* next stereo channel (50Mbps and 100Mbps only) */ + pcm = ppcm[ipcm++]; + if (!pcm) + break; + /* for each DIF segment */ for (i = 0; i < sys->difseg_size; i++) { frame += 6 * 80; /* skip DIF segment header */ @@ -176,11 +180,6 @@ static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4], frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */ } } - - /* next stereo channel (50Mbps and 100Mbps only) */ - pcm = ppcm[ipcm++]; - if (!pcm) - break; } return size; From 2c199cb253cb98fdc26b26eba1e401daf4dc1d80 Mon Sep 17 00:00:00 2001 From: Mans Rullgard Date: Tue, 31 Jan 2012 10:20:33 -0800 Subject: [PATCH 53/84] ac3: Do not read past the end of ff_ac3_band_start_tab. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Alex Converse (cherry picked from commit 034b03e7a0e8e4f8f66c82b736f2c0aa7c063ec0) Signed-off-by: Reinhard Tartler --- libavcodec/ac3dsp.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c index 8ce5f8d2c5..cedc81c676 100644 --- a/libavcodec/ac3dsp.c +++ b/libavcodec/ac3dsp.c @@ -108,7 +108,7 @@ static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd, int snr_offset, int floor, const uint8_t *bap_tab, uint8_t *bap) { - int bin, band; + int bin, band, band_end; /* special case, if snr offset is -960, set all bap's to zero */ if (snr_offset == -960) { @@ -120,12 +120,14 @@ static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd, band = ff_ac3_bin_to_band_tab[start]; do { int m = (FFMAX(mask[band] - snr_offset - floor, 0) & 0x1FE0) + floor; - int band_end = FFMIN(ff_ac3_band_start_tab[band+1], end); + band_end = ff_ac3_band_start_tab[++band]; + band_end = FFMIN(band_end, end); + for (; bin < band_end; bin++) { int address = av_clip((psd[bin] - m) >> 5, 0, 63); bap[bin] = bap_tab[address]; } - } while (end > ff_ac3_band_start_tab[band++]); + } while (end > band_end); } static void ac3_update_bap_counts_c(uint16_t mant_cnt[16], uint8_t *bap, From b0888b8a48dbc4a5aa0aaed016b72fbbb7c30261 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 9 Feb 2012 17:11:55 -0800 Subject: [PATCH 54/84] dv: Fix small overread in audio frequency table. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind (cherry picked from commit 0ab3687924457cb4fd81897bd39ab3cc5b699588) Signed-off-by: Reinhard Tartler --- libavformat/dv.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libavformat/dv.c b/libavformat/dv.c index 389cf063e6..9383db2214 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -119,6 +119,9 @@ static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4], if (quant > 1) return -1; /* unsupported quantization */ + if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) + return AVERROR_INVALIDDATA; + size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */ half_ch = sys->difseg_size / 2; @@ -201,6 +204,12 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame) stype = (as_pack[3] & 0x1f); /* 0 - 2CH, 2 - 4CH, 3 - 8CH */ quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */ + if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) { + av_log(c->fctx, AV_LOG_ERROR, + "Unrecognized audio sample rate index (%d)\n", freq); + return 0; + } + if (stype > 3) { av_log(c->fctx, AV_LOG_ERROR, "stype %d is invalid\n", stype); c->ach = 0; From f5ce67d837cd686f12c515e601acd6e2a5df05a7 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 9 Feb 2012 20:21:47 -0800 Subject: [PATCH 55/84] svq3: Prevent illegal reads while parsing extradata. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind (cherry picked from commit 9e1db721c4329f4ac166a0bcc002c8d75f831aba) Signed-off-by: Reinhard Tartler --- libavcodec/svq3.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 09d598c044..662d74d6fb 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -809,7 +809,9 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) MpegEncContext *s = &h->s; int m; unsigned char *extradata; + unsigned char *extradata_end; unsigned int size; + int marker_found = 0; if (ff_h264_decode_init(avctx) < 0) return -1; @@ -829,19 +831,26 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) /* prowl for the "SEQH" marker in the extradata */ extradata = (unsigned char *)avctx->extradata; - for (m = 0; m < avctx->extradata_size; m++) { - if (!memcmp(extradata, "SEQH", 4)) - break; - extradata++; + extradata_end = avctx->extradata + avctx->extradata_size; + if (extradata) { + for (m = 0; m + 8 < avctx->extradata_size; m++) { + if (!memcmp(extradata, "SEQH", 4)) { + marker_found = 1; + break; + } + extradata++; + } } /* if a match was found, parse the extra data */ - if (extradata && !memcmp(extradata, "SEQH", 4)) { + if (marker_found) { GetBitContext gb; int frame_size_code; size = AV_RB32(&extradata[4]); + if (size > extradata_end - extradata - 8) + return AVERROR_INVALIDDATA; init_get_bits(&gb, extradata + 8, size*8); /* 'frame size code' and optional 'width, height' */ From a642953b0f1c87592d2e7bff5b67ed024bc29a64 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 23 Feb 2012 10:22:51 -0800 Subject: [PATCH 56/84] tiff: Make the TIFF_LONG and TIFF_SHORT types unsigned. TIFF v6.0 (unimplemented) adds signed equivalents. (cherry picked from commit e32548d1331ce05a054f1028fcdda8823a4f215a) Signed-off-by: Reinhard Tartler --- libavcodec/tiff.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 71a4e70e3e..1866dab9e7 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -58,24 +58,24 @@ typedef struct TiffContext { LZWState *lzw; } TiffContext; -static int tget_short(const uint8_t **p, int le){ - int v = le ? AV_RL16(*p) : AV_RB16(*p); +static unsigned tget_short(const uint8_t **p, int le) { + unsigned v = le ? AV_RL16(*p) : AV_RB16(*p); *p += 2; return v; } -static int tget_long(const uint8_t **p, int le){ - int v = le ? AV_RL32(*p) : AV_RB32(*p); +static unsigned tget_long(const uint8_t **p, int le) { + unsigned v = le ? AV_RL32(*p) : AV_RB32(*p); *p += 4; return v; } -static int tget(const uint8_t **p, int type, int le){ +static unsigned tget(const uint8_t **p, int type, int le) { switch(type){ case TIFF_BYTE : return *(*p)++; case TIFF_SHORT: return tget_short(p, le); case TIFF_LONG : return tget_long (p, le); - default : return -1; + default : return UINT_MAX; } } @@ -276,7 +276,7 @@ static int init_image(TiffContext *s) static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf) { - int tag, type, count, off, value = 0; + unsigned tag, type, count, off, value = 0; int i, j; uint32_t *pal; const uint8_t *rp, *gp, *bp; @@ -311,7 +311,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * break; } default: - value = -1; + value = UINT_MAX; buf = start + off; } } else { @@ -397,7 +397,7 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * } break; case TIFF_ROWSPERSTRIP: - if(type == TIFF_LONG && value == -1) + if (type == TIFF_LONG && value == UINT_MAX) value = s->avctx->height; if(value < 1){ av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n"); From 4be63587e110c05cda3101abf2e3745d919f3fae Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 17 Feb 2012 13:35:10 -0800 Subject: [PATCH 57/84] h263dec: Disallow width/height changing with frame threads. Fixes CVE-2011-3937 Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Michael Niedermayer (cherry picked from commit 71db86d53b5c6872cea31bf714a1a38ec78feaba) Conflicts: libavcodec/h263dec.c Signed-off-by: Alex Converse Signed-off-by: Reinhard Tartler --- libavcodec/h263dec.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index bc6d613be4..abdaf2bf24 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -552,8 +552,7 @@ retry: #if HAVE_MMX if (s->codec_id == CODEC_ID_MPEG4 && s->xvid_build>=0 && avctx->idct_algo == FF_IDCT_AUTO && (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) { avctx->idct_algo= FF_IDCT_XVIDMMX; - avctx->coded_width= 0; // force reinit -// dsputil_init(&s->dsp, avctx); + ff_dct_common_init(s); s->picture_number=0; } #endif @@ -567,6 +566,12 @@ retry: || s->height != avctx->coded_height) { /* H.263 could change picture size any time */ ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat + + if (HAVE_THREADS && (s->avctx->active_thread_type&FF_THREAD_FRAME)) { + av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0); + return -1; // width / height changed during parallelized decoding + } + s->parse_context.buffer=0; MPV_common_end(s); s->parse_context= pc; From 5015ada0ec11b2ace2588153451775487731b97b Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 21 Feb 2012 14:08:02 -0800 Subject: [PATCH 58/84] mov: Add support for MPEG2 HDV 720p24 (hdv4) (cherry picked from commit 0ad522afb3a3b3d22402ecb82dd4609f7655031b) Signed-off-by: Reinhard Tartler --- libavformat/isom.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/isom.c b/libavformat/isom.c index fb2ce236ee..27c61e7dd1 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -149,6 +149,7 @@ const AVCodecTag codec_movvideo_tags[] = { { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '1') }, /* MPEG2 HDV 720p30 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG2 HDV 1080i60 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '3') }, /* MPEG2 HDV 1080i50 */ + { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '4') }, /* MPEG2 HDV 720p24 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '5') }, /* MPEG2 HDV 720p25 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '6') }, /* MPEG2 HDV 1080p24 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '7') }, /* MPEG2 HDV 1080p25 */ From 853ce33dbc372071fda0a20182b07f00d6eb2a0d Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 21 Feb 2012 15:37:35 -0800 Subject: [PATCH 59/84] mov: Add more HDV and XDCAM FourCCs. Reference: VLC (cherry picked from commit b142496c5630b9bc88fb9eaccae7f6bd62fb23e7) Signed-off-by: Reinhard Tartler --- libavformat/isom.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavformat/isom.c b/libavformat/isom.c index 27c61e7dd1..b865531223 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -154,6 +154,8 @@ const AVCodecTag codec_movvideo_tags[] = { { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '6') }, /* MPEG2 HDV 1080p24 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '7') }, /* MPEG2 HDV 1080p25 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '8') }, /* MPEG2 HDV 1080p30 */ + { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '9') }, /* MPEG2 HDV 720p60 JVC */ + { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', 'a') }, /* MPEG2 HDV 720p50 */ { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'n') }, /* MPEG2 IMX NTSC 525/60 50mb/s produced by FCP */ { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') }, /* MPEG2 IMX PAL 625/50 50mb/s produced by FCP */ { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'n') }, /* MPEG2 IMX NTSC 525/60 40mb/s produced by FCP */ @@ -184,6 +186,8 @@ const AVCodecTag codec_movvideo_tags[] = { { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'd') }, /* XDCAM EX 1080p24 VBR */ { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'e') }, /* XDCAM EX 1080p25 VBR */ { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'f') }, /* XDCAM EX 1080p30 VBR */ + { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', 'd') }, /* XDCAM HD 540p */ + { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', '2') }, /* XDCAM HD422 540p */ { CODEC_ID_MPEG2VIDEO, MKTAG('A', 'V', 'm', 'p') }, /* AVID IMX PAL */ { CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */ From 6dfe865aed25b52b181afddd37e1622d34f57d0b Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Mon, 5 Mar 2012 17:03:32 -0800 Subject: [PATCH 60/84] svq3: protect against negative quantizers. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 11b940a1a8e7e5d5b212935a3ce78aeda577f5f2) Signed-off-by: Reinhard Tartler --- libavcodec/svq3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 662d74d6fb..ec9d791295 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -649,7 +649,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) if (IS_INTRA16x16(mb_type) || (s->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) { s->qscale += svq3_get_se_golomb(&s->gb); - if (s->qscale > 31){ + if (s->qscale > 31u){ av_log(h->s.avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale); return -1; } From f2e412d050ae9a0dcdea515f1c02620c6dcf8c47 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 6 Mar 2012 17:24:20 -0800 Subject: [PATCH 61/84] smacker: error out if palette copy-with-offset overruns palette size. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit a93b572ae4f517ce0c35cf085167c318e9215908) Signed-off-by: Reinhard Tartler --- libavformat/smacker.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/libavformat/smacker.c b/libavformat/smacker.c index a817c31355..7ec8099376 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -261,8 +261,15 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) sz += (t & 0x7F) + 1; pal += ((t & 0x7F) + 1) * 3; } else if(t & 0x40){ /* copy with offset */ - off = avio_r8(s->pb) * 3; + off = avio_r8(s->pb); j = (t & 0x3F) + 1; + if (off + j > 0xff) { + av_log(s, AV_LOG_ERROR, + "Invalid palette update, offset=%d length=%d extends beyond palette size\n", + off, j); + return AVERROR_INVALIDDATA; + } + off *= 3; while(j-- && sz < 256) { *pal++ = oldpal[off + 0]; *pal++ = oldpal[off + 1]; From 4924520513d06b4d9169a1d3e0374d5a48bc02e0 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 6 Mar 2012 16:08:10 -0800 Subject: [PATCH 62/84] raw: move buffer size check up. This way, it protects against overreads for 4bpp/2bpp content also. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit cc5dd632cecc5114717d0b90f8c2be162b1c6ee8) Signed-off-by: Reinhard Tartler --- libavcodec/rawdec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c index 5e8e6c4c43..05a032e62c 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -127,6 +127,9 @@ static int raw_decode(AVCodecContext *avctx, frame->reordered_opaque = avctx->reordered_opaque; frame->pkt_pts = avctx->pkt->pts; + if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0)) + return -1; + //2bpp and 4bpp raw in avi and mov (yes this is ugly ...) if (context->buffer) { int i; @@ -151,9 +154,6 @@ static int raw_decode(AVCodecContext *avctx, avctx->codec_tag == MKTAG('A', 'V', 'u', 'p')) buf += buf_size - context->length; - if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0)) - return -1; - avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height); if((avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length) || (avctx->pix_fmt!=PIX_FMT_PAL8 && From b4a223fd1936f8c7d3dd48f37f49790b0d04f429 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 7 Mar 2012 14:18:14 -0800 Subject: [PATCH 63/84] wma: fix off-by-one in array bounds check. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit b4bccf3e4e58f6fe58043791ca09db01a4343fac) Signed-off-by: Reinhard Tartler --- libavcodec/wmadec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index c8e1de2c32..f0b043feef 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -352,7 +352,7 @@ static int decode_exp_vlc(WMACodecContext *s, int ch) } /* NOTE: this offset is the same as MPEG4 AAC ! */ last_exp += code - 60; - if ((unsigned)last_exp + 60 > FF_ARRAY_ELEMS(pow_tab)) { + if ((unsigned)last_exp + 60 >= FF_ARRAY_ELEMS(pow_tab)) { av_log(s->avctx, AV_LOG_ERROR, "Exponent out of range: %d\n", last_exp); return -1; From bbe316dfb425edecd98e3fbef93c17abe6bb5cb8 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 6 Mar 2012 17:00:29 -0800 Subject: [PATCH 64/84] tiffdec: Prevent illegal memory access caused by recycled pointers. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit fd0be63049ed46660993d0550a4f0847a0b942ea) Signed-off-by: Reinhard Tartler --- libavcodec/tiff.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 1866dab9e7..0a0973c6d9 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -534,6 +534,8 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n"); return -1; } + // Reset these pointers so we can tell if they were set this frame + s->stripsizes = s->stripdata = NULL; /* parse image file directory */ off = tget_long(&buf, le); if (off >= UINT_MAX - 14 || end_buf - orig_buf < off + 14) { From 99536be9d46b49e9496cfe6d49d82d3b0fe5e44c Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 7 Mar 2012 16:29:23 -0800 Subject: [PATCH 65/84] huffyuv: add padding to classic (v1) huffman tables. We slightly overread the input buffer, so we require padding at the end of the buffer, as is documented in the get_bits API. Without padding, we'll read uninitialized data or beyond the end of the .rodata, which may crash. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 4ffe5e2aa5241f8da9afd2c8fbc854dcc916c5f9) Signed-off-by: Reinhard Tartler --- libavcodec/huffyuv.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index eb13d87f87..b25a689d64 100644 --- a/libavcodec/huffyuv.c +++ b/libavcodec/huffyuv.c @@ -82,13 +82,15 @@ typedef struct HYuvContext{ DSPContext dsp; }HYuvContext; -static const unsigned char classic_shift_luma[] = { +#define classic_shift_luma_table_size 42 +static const unsigned char classic_shift_luma[classic_shift_luma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = { 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8, 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70, 69,68, 0 }; -static const unsigned char classic_shift_chroma[] = { +#define classic_shift_chroma_table_size 59 +static const unsigned char classic_shift_chroma[classic_shift_chroma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = { 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183, 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119, 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0 @@ -366,10 +368,10 @@ static int read_old_huffman_tables(HYuvContext *s){ GetBitContext gb; int i; - init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8); + init_get_bits(&gb, classic_shift_luma, classic_shift_luma_table_size*8); if(read_len_table(s->len[0], &gb)<0) return -1; - init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8); + init_get_bits(&gb, classic_shift_chroma, classic_shift_chroma_table_size*8); if(read_len_table(s->len[1], &gb)<0) return -1; From 311361348dc5af77ad189bba846f2fdaff85a5c4 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sun, 11 Mar 2012 07:28:54 -0700 Subject: [PATCH 66/84] dsicinvideo: validate buffer offset before copying pixels. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit c95fefa0420be9cc0f09a95041acf11114aaacd0) Signed-off-by: Reinhard Tartler --- libavcodec/dsicinav.c | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index 11547c2ded..5ba2b1974c 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -145,11 +145,11 @@ static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned c return dst_cur - dst; } -static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) { uint16_t cmd; int i, sz, offset, code; - unsigned char *dst_end = dst + dst_size; + unsigned char *dst_end = dst + dst_size, *dst_start = dst; const unsigned char *src_end = src + src_size; while (src < src_end && dst < dst_end) { @@ -160,6 +160,8 @@ static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned cha } else { cmd = AV_RL16(src); src += 2; offset = cmd >> 4; + if ((int) (dst - dst_start) < offset + 1) + return AVERROR_INVALIDDATA; sz = (cmd & 0xF) + 2; /* don't use memcpy/memmove here as the decoding routine (ab)uses */ /* buffer overlappings to repeat bytes in the destination */ @@ -171,6 +173,8 @@ static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned cha } } } + + return 0; } static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) @@ -200,13 +204,7 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; CinVideoContext *cin = avctx->priv_data; - int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size; - - cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &cin->frame)) { - av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n"); - return -1; - } + int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size, res = 0; palette_type = buf[0]; palette_colors_count = AV_RL16(buf+1); @@ -232,8 +230,6 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, bitmap_frame_size -= 4; } } - memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette)); - cin->frame.palette_has_changed = 1; /* note: the decoding routines below assumes that surface.width = surface.pitch */ switch (bitmap_frame_type) { @@ -266,17 +262,31 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; case 38: - cin_decode_lzss(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + res = cin_decode_lzss(buf, bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], + cin->bitmap_size); + if (res < 0) + return res; break; case 39: - cin_decode_lzss(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + res = cin_decode_lzss(buf, bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], + cin->bitmap_size); + if (res < 0) + return res; cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; } + cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if (avctx->reget_buffer(avctx, &cin->frame)) { + av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n"); + return -1; + } + + memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette)); + cin->frame.palette_has_changed = 1; for (y = 0; y < cin->avctx->height; ++y) memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0], cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width, From 5ae49ddaa447bb4fba287f92ca508caba399ffbd Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 8 Mar 2012 16:32:46 -0800 Subject: [PATCH 67/84] xxan: don't read before start of buffer in av_memcpy_backptr(). Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit f1279e286b00e99f343adb51e251f036a3df6f32) Signed-off-by: Reinhard Tartler --- libavcodec/xxan.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c index 28c868d5ba..daaba6389a 100644 --- a/libavcodec/xxan.c +++ b/libavcodec/xxan.c @@ -129,7 +129,8 @@ static int xan_unpack(uint8_t *dest, const int dest_len, if (size + size2 > dest_end - dest) break; } - if (src + size > src_end || dest + size + size2 > dest_end) + if (src + size > src_end || dest + size + size2 > dest_end || + dest - orig_dest + size < back) return -1; bytestream_get_buffer(&src, dest, size); dest += size; From 81c5b4ddcb08d65b691e944d8d8cdc144c19dc9b Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Wed, 14 Mar 2012 03:02:02 +0000 Subject: [PATCH 68/84] jvdec: unbreak video decoding The safe bitstream reader broke it since the buffer size was specified in bytes instead of bits. Signed-off-by: Janne Grunau CC: libav-stable@libav.org (cherry picked from commit a1c036e961a32f7208e7315dabfa0ee99d779edb) Signed-off-by: Reinhard Tartler --- libavcodec/jvdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c index 5249764347..f2c97526c0 100644 --- a/libavcodec/jvdec.c +++ b/libavcodec/jvdec.c @@ -150,7 +150,7 @@ static int decode_frame(AVCodecContext *avctx, if (video_type == 0 || video_type == 1) { GetBitContext gb; - init_get_bits(&gb, buf, FFMIN(video_size, (buf_end - buf) * 8)); + init_get_bits(&gb, buf, 8 * FFMIN(video_size, buf_end - buf)); for (j = 0; j < avctx->height; j += 8) for (i = 0; i < avctx->width; i += 8) From 8b819fd9d3f363483559a3e9aeb8b78acba47bb7 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Tue, 13 Mar 2012 16:26:44 -0700 Subject: [PATCH 69/84] h264: stricter reference limit enforcement. Progressive images can have only 16 references, error out if there are more, since the data is almost certainly corrupt, and the invalid value will lead to random crashes or invalid writes later on. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit e0febda22d0e0fab094a9c886b0e0f0f662df1ef) Signed-off-by: Reinhard Tartler --- libavcodec/h264.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/libavcodec/h264.c b/libavcodec/h264.c index dbf8e6aca1..f1ccc8af38 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -2869,6 +2869,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->ref_count[1]= h->pps.ref_count[1]; if(h->slice_type_nos != AV_PICTURE_TYPE_I){ + int max_refs = s->picture_structure == PICT_FRAME ? 16 : 32; + if(h->slice_type_nos == AV_PICTURE_TYPE_B){ h->direct_spatial_mv_pred= get_bits1(&s->gb); } @@ -2878,13 +2880,14 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->ref_count[0]= get_ue_golomb(&s->gb) + 1; if(h->slice_type_nos==AV_PICTURE_TYPE_B) h->ref_count[1]= get_ue_golomb(&s->gb) + 1; - - if(h->ref_count[0]-1 > 32-1 || h->ref_count[1]-1 > 32-1){ - av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n"); - h->ref_count[0]= h->ref_count[1]= 1; - return -1; - } } + + if (h->ref_count[0] > max_refs || h->ref_count[1] > max_refs) { + av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n"); + h->ref_count[0] = h->ref_count[1] = 1; + return AVERROR_INVALIDDATA; + } + if(h->slice_type_nos == AV_PICTURE_TYPE_B) h->list_count= 2; else From 90db3c435ea5e77befe186b7079c8a7f4bf457d2 Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Wed, 7 Mar 2012 20:07:17 +0100 Subject: [PATCH 70/84] dca: include libavutil/mathematics.h for possibly missing M_SQRT1_2 Signed-off-by: Janne Grunau Signed-off-by: Reinhard Tartler --- libavcodec/dca.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 19d24c55d1..38a641bd69 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -29,6 +29,7 @@ #include "libavutil/common.h" #include "libavutil/intmath.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mathematics.h" #include "libavutil/audioconvert.h" #include "avcodec.h" #include "dsputil.h" From 137007b5bfbee8992ac088732c39cc1301bb7a3a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 12 Sep 2011 08:55:43 -0400 Subject: [PATCH 71/84] ws_snd: decode to AV_SAMPLE_FMT_U8 instead of S16. 8-bit unsigned is the native sample format. (cherry picked from commit 2322ced8da990835717a176b8d2c32961cfecd3e) Signed-off-by: Reinhard Tartler --- libavcodec/ws-snd1.c | 47 ++++++++++++++++++++++---------------------- 1 file changed, 24 insertions(+), 23 deletions(-) diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c index 534be5661b..959c7bb1d9 100644 --- a/libavcodec/ws-snd1.c +++ b/libavcodec/ws-snd1.c @@ -37,13 +37,11 @@ static const int8_t ws_adpcm_4bit[] = { -9, -8, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 8 }; -#define CLIP8(a) if(a>127)a=127;if(a<-128)a=-128; - static av_cold int ws_snd_decode_init(AVCodecContext * avctx) { // WSSNDContext *c = avctx->priv_data; - avctx->sample_fmt = AV_SAMPLE_FMT_S16; + avctx->sample_fmt = AV_SAMPLE_FMT_U8; return 0; } @@ -56,15 +54,14 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, // WSSNDContext *c = avctx->priv_data; int in_size, out_size; - int sample = 0; + int sample = 128; int i; - short *samples = data; + uint8_t *samples = data; if (!buf_size) return 0; out_size = AV_RL16(&buf[0]); - *data_size = out_size * 2; in_size = AV_RL16(&buf[2]); buf += 4; @@ -76,9 +73,12 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Frame data is larger than input buffer\n"); return -1; } + + *data_size = out_size; + if (in_size == out_size) { for (i = 0; i < out_size; i++) - *samples++ = (*buf++ - 0x80) << 8; + *samples++ = *buf++; return buf_size; } @@ -93,17 +93,17 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, for (count++; count > 0; count--) { code = *buf++; sample += ws_adpcm_2bit[code & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; sample += ws_adpcm_2bit[(code >> 2) & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; sample += ws_adpcm_2bit[(code >> 4) & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; sample += ws_adpcm_2bit[(code >> 6) & 0x3]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; out_size -= 4; } break; @@ -111,11 +111,11 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, for (count++; count > 0; count--) { code = *buf++; sample += ws_adpcm_4bit[code & 0xF]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; sample += ws_adpcm_4bit[code >> 4]; - CLIP8(sample); - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; out_size -= 2; } break; @@ -125,19 +125,20 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, t = count; t <<= 3; sample += t >> 3; - *samples++ = sample << 8; + sample = av_clip_uint8(sample); + *samples++ = sample; out_size--; } else { /* copy */ for (count++; count > 0; count--) { - *samples++ = (*buf++ - 0x80) << 8; + *samples++ = *buf++; out_size--; } - sample = buf[-1] - 0x80; + sample = buf[-1]; } break; default: /* run */ for(count++; count > 0; count--) { - *samples++ = sample << 8; + *samples++ = sample; out_size--; } } From 847c7cd0c8795bb68e8729f74969aa49a5dc10ad Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 12 Sep 2011 09:41:06 -0400 Subject: [PATCH 72/84] ws_snd: add some checks to prevent buffer overread or overwrite. (cherry picked from commit 417364ce1f979031ef6fee661fc15e1869bdb1b4) Signed-off-by: Reinhard Tartler --- libavcodec/ws-snd1.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c index 959c7bb1d9..06bd18c529 100644 --- a/libavcodec/ws-snd1.c +++ b/libavcodec/ws-snd1.c @@ -61,6 +61,11 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, if (!buf_size) return 0; + if (buf_size < 4) { + av_log(avctx, AV_LOG_ERROR, "packet is too small\n"); + return AVERROR(EINVAL); + } + out_size = AV_RL16(&buf[0]); in_size = AV_RL16(&buf[2]); buf += 4; @@ -74,20 +79,37 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, return -1; } - *data_size = out_size; - if (in_size == out_size) { for (i = 0; i < out_size; i++) *samples++ = *buf++; + *data_size = out_size; return buf_size; } - while (out_size > 0) { - int code; + while (out_size > 0 && buf - avpkt->data < buf_size) { + int code, smp, size; uint8_t count; code = (*buf) >> 6; count = (*buf) & 0x3F; buf++; + + /* make sure we don't write more than out_size samples */ + switch (code) { + case 0: smp = 4; break; + case 1: smp = 2; break; + case 2: smp = (count & 0x20) ? 1 : count + 1; break; + default: smp = count + 1; break; + } + if (out_size < smp) { + out_size = 0; + break; + } + + /* make sure we don't read past the input buffer */ + size = ((code == 2 && (count & 0x20)) || code == 3) ? 0 : count + 1; + if ((buf - avpkt->data) + size > buf_size) + break; + switch(code) { case 0: /* ADPCM 2-bit */ for (count++; count > 0; count--) { @@ -144,6 +166,8 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, } } + *data_size = samples - (uint8_t *)data; + return buf_size; } From e676bbb8cfb7401cfc189a88c61e7e7c22557fa7 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 25 Dec 2011 00:10:27 +0100 Subject: [PATCH 73/84] ws_snd1: Fix wrong samples count and crash. Signed-off-by: Michael Niedermayer (cherry picked from commit 9fb7a5af97d8c084c3af2566070d09eae0ab49fc) Addresses CVE-2012-0848 Reviewed-by: Justin Ruggles Signed-off-by: Reinhard Tartler (cherry picked from commit 697a45d861b7cd6a96718383a44f41348487f844) Signed-off-by: Reinhard Tartler --- libavcodec/ws-snd1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c index 06bd18c529..e17c84ca30 100644 --- a/libavcodec/ws-snd1.c +++ b/libavcodec/ws-snd1.c @@ -95,8 +95,8 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, /* make sure we don't write more than out_size samples */ switch (code) { - case 0: smp = 4; break; - case 1: smp = 2; break; + case 0: smp = 4*(count+1); break; + case 1: smp = 2*(count+1); break; case 2: smp = (count & 0x20) ? 1 : count + 1; break; default: smp = count + 1; break; } From f728ad26f0ec87650d2986a892785c0e2b97d161 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 17 Dec 2011 03:18:58 +0100 Subject: [PATCH 74/84] atrac3: Fix crash in tonal component decoding. Add a check to avoid writing past the end of the channel_unit.components[] array. Bug Found by: cosminamironesei Fixes CVE-2012-0853 CC: libav-stable@libav.org Signed-off-by: Michael Niedermayer Signed-off-by: Justin Ruggles (cherry picked from commit c509f4f74713b035a06f79cb4d00e708f5226bc5) Signed-off-by: Reinhard Tartler (cherry picked from commit f43b6e2b1ed47a1254a5d44c700a7fad5e9784be) Signed-off-by: Reinhard Tartler --- libavcodec/atrac3.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index accaae3d65..914998e7d9 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -395,6 +395,8 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent for (k=0; k= 64) + return AVERROR_INVALIDDATA; pComponent[component_count].pos = j * 64 + (get_bits(gb,6)); max_coded_values = 1024 - pComponent[component_count].pos; coded_values = coded_values_per_component + 1; From a207a2fecc6a77735ab0cf209fdba0b4dd942a86 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Thu, 15 Sep 2011 18:08:52 -0400 Subject: [PATCH 75/84] shorten: check for realloc failure (cherry picked from commit 9e5e2c2d010c05c10337e9c1ec9d0d61495e0c9c) Signed-off-by: Reinhard Tartler --- libavcodec/shorten.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index 13381f6c95..7ce58ef0d3 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -113,6 +113,7 @@ static int allocate_buffers(ShortenContext *s) { int i, chan; int *coeffs; + void *tmp_ptr; for (chan=0; chanchannels; chan++) { if(FFMAX(1, s->nmean) >= UINT_MAX/sizeof(int32_t)){ @@ -124,9 +125,15 @@ static int allocate_buffers(ShortenContext *s) return -1; } - s->offset[chan] = av_realloc(s->offset[chan], sizeof(int32_t)*FFMAX(1, s->nmean)); + tmp_ptr = av_realloc(s->offset[chan], sizeof(int32_t)*FFMAX(1, s->nmean)); + if (!tmp_ptr) + return AVERROR(ENOMEM); + s->offset[chan] = tmp_ptr; - s->decoded[chan] = av_realloc(s->decoded[chan], sizeof(int32_t)*(s->blocksize + s->nwrap)); + tmp_ptr = av_realloc(s->decoded[chan], sizeof(int32_t)*(s->blocksize + s->nwrap)); + if (!tmp_ptr) + return AVERROR(ENOMEM); + s->decoded[chan] = tmp_ptr; for (i=0; inwrap; i++) s->decoded[chan][i] = 0; s->decoded[chan] += s->nwrap; @@ -284,8 +291,15 @@ static int shorten_decode_frame(AVCodecContext *avctx, int i, input_buf_size = 0; int16_t *samples = data; if(s->max_framesize == 0){ + void *tmp_ptr; s->max_framesize= 1024; // should hopefully be enough for the first header - s->bitstream= av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, s->max_framesize); + tmp_ptr = av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, + s->max_framesize); + if (!tmp_ptr) { + av_log(avctx, AV_LOG_ERROR, "error allocating bitstream buffer\n"); + return AVERROR(ENOMEM); + } + s->bitstream = tmp_ptr; } if(1 && s->max_framesize){//FIXME truncated From 96ed18cab1048f03ff1c825f46b25d49218f1da4 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sun, 25 Dec 2011 12:28:50 +0100 Subject: [PATCH 76/84] shorten: Use separate pointers for the allocated memory for decoded samples. Fixes invalid free() if any of the buffers are not allocated due to either not decoding a header or an error prior to allocating all buffers. Fixes CVE-2012-0858 CC: libav-stable@libav.org Signed-off-by: Michael Niedermayer Signed-off-by: Justin Ruggles (cherry picked from commit 204cb29b3c84a74cbcd059d353c70c8bdc567d98) Signed-off-by: Reinhard Tartler (cherry picked from commit 6fc3287b9ccece290c5881b92948772bbf72e68c) Signed-off-by: Reinhard Tartler --- libavcodec/shorten.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index 7ce58ef0d3..b8c1908357 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -81,6 +81,7 @@ typedef struct ShortenContext { int channels; int32_t *decoded[MAX_CHANNELS]; + int32_t *decoded_base[MAX_CHANNELS]; int32_t *offset[MAX_CHANNELS]; int *coeffs; uint8_t *bitstream; @@ -130,13 +131,14 @@ static int allocate_buffers(ShortenContext *s) return AVERROR(ENOMEM); s->offset[chan] = tmp_ptr; - tmp_ptr = av_realloc(s->decoded[chan], sizeof(int32_t)*(s->blocksize + s->nwrap)); + tmp_ptr = av_realloc(s->decoded_base[chan], (s->blocksize + s->nwrap) * + sizeof(s->decoded_base[0][0])); if (!tmp_ptr) return AVERROR(ENOMEM); - s->decoded[chan] = tmp_ptr; + s->decoded_base[chan] = tmp_ptr; for (i=0; inwrap; i++) - s->decoded[chan][i] = 0; - s->decoded[chan] += s->nwrap; + s->decoded_base[chan][i] = 0; + s->decoded[chan] = s->decoded_base[chan] + s->nwrap; } coeffs = av_realloc(s->coeffs, s->nwrap * sizeof(*s->coeffs)); @@ -542,8 +544,8 @@ static av_cold int shorten_decode_close(AVCodecContext *avctx) int i; for (i = 0; i < s->channels; i++) { - s->decoded[i] -= s->nwrap; - av_freep(&s->decoded[i]); + s->decoded[i] = NULL; + av_freep(&s->decoded_base[i]); av_freep(&s->offset[i]); } av_freep(&s->bitstream); From 6ae95a0b93e8df15fe5f364535a7214be0817736 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 25 Jan 2012 13:39:24 -0800 Subject: [PATCH 77/84] mjpegbdec: Fix overflow in SOS. Based in part by a fix from Michael Niedermayer Fixes CVE-2011-3947 Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind (cherry picked from commit b57d262412204e54a7ef8fa1b23ff4dcede622e5) Signed-off-by: Reinhard Tartler (cherry picked from commit 083a8a00373b12dc06b8ae4c49eec61fb5e55f4b) Signed-off-by: Reinhard Tartler --- libavcodec/mjpegbdec.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c index 454ba6ffc9..6455b19846 100644 --- a/libavcodec/mjpegbdec.c +++ b/libavcodec/mjpegbdec.c @@ -59,6 +59,9 @@ read_header: s->restart_count = 0; s->mjpb_skiptosod = 0; + if (buf_end - buf_ptr >= 1 << 28) + return AVERROR_INVALIDDATA; + init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8); skip_bits(&hgb, 32); /* reserved zeros */ @@ -109,8 +112,8 @@ read_header: av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%x\n", sod_offs); if (sos_offs) { -// init_get_bits(&s->gb, buf+sos_offs, (buf_end - (buf+sos_offs))*8); - init_get_bits(&s->gb, buf_ptr+sos_offs, field_size*8); + init_get_bits(&s->gb, buf_ptr + sos_offs, + 8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs)); s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16)); s->start_code = SOS; ff_mjpeg_decode_sos(s, NULL, NULL); From 6fe5038753ec8da6770b1872588f5d83f6f13963 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Thu, 23 Jun 2011 13:27:21 +0200 Subject: [PATCH 78/84] nsvdec: Propagate error values instead of returning 0 in nsv_read_header(). This eliminates a warning about a set-but-unused variable. (cherry picked from commit 35fa0d47585cef28cd8191dccf0607d90c7667a6) Signed-off-by: Reinhard Tartler --- libavformat/nsvdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index 67c103d21f..61cc69ffe1 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -542,7 +542,7 @@ static int nsv_read_header(AVFormatContext *s, AVFormatParameters *ap) err = nsv_read_chunk(s, 1); av_dlog(s, "parsed header\n"); - return 0; + return err; } static int nsv_read_chunk(AVFormatContext *s, int fill_header) From 24eabc53bae467cfe57e2c24dee0f33e11e697a1 Mon Sep 17 00:00:00 2001 From: Gaurav Narula Date: Mon, 12 Dec 2011 20:24:54 +0530 Subject: [PATCH 79/84] kvmc: fix invalid reads Signed-off-by: Janne Grunau (cherry picked from commit ad3161ec1d70291efcf40121d703ef73c0b08e5b) Signed-off-by: Reinhard Tartler --- libavcodec/kmvc.c | 82 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 16 deletions(-) diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c index 718cdfd932..033d3d7998 100644 --- a/libavcodec/kmvc.c +++ b/libavcodec/kmvc.c @@ -57,17 +57,21 @@ typedef struct BitBuf { #define kmvc_init_getbits(bb, src) bb.bits = 7; bb.bitbuf = *src++; -#define kmvc_getbit(bb, src, res) {\ +#define kmvc_getbit(bb, src, src_end, res) {\ res = 0; \ if (bb.bitbuf & (1 << bb.bits)) res = 1; \ bb.bits--; \ if(bb.bits == -1) { \ + if (src >= src_end) { \ + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); \ + return AVERROR_INVALIDDATA; \ + } \ bb.bitbuf = *src++; \ bb.bits = 7; \ } \ } -static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, int h) +static int kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int src_size, int w, int h) { BitBuf bb; int res, val; @@ -75,13 +79,18 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, int bx, by; int l0x, l1x, l0y, l1y; int mx, my; + const uint8_t *src_end = src + src_size; kmvc_init_getbits(bb, src); for (by = 0; by < h; by += 8) for (bx = 0; bx < w; bx += 8) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { // fill whole 8x8 block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; for (i = 0; i < 64; i++) BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val; @@ -89,14 +98,22 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, for (i = 0; i < 4; i++) { l0x = bx + (i & 1) * 4; l0y = by + (i & 2) * 2; - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { // fill whole 4x4 block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; for (j = 0; j < 16; j++) BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val; } else { // copy block from already decoded place + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; mx = val & 0xF; my = val >> 4; @@ -108,16 +125,24 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, for (j = 0; j < 4; j++) { l1x = l0x + (j & 1) * 2; l1y = l0y + (j & 2); - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { // fill whole 2x2 block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; BLK(ctx->cur, l1x, l1y) = val; BLK(ctx->cur, l1x + 1, l1y) = val; BLK(ctx->cur, l1x, l1y + 1) = val; BLK(ctx->cur, l1x + 1, l1y + 1) = val; } else { // copy block from already decoded place + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; mx = val & 0xF; my = val >> 4; @@ -140,9 +165,11 @@ static void kmvc_decode_intra_8x8(KmvcContext * ctx, const uint8_t * src, int w, } } } + + return 0; } -static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, int h) +static int kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int src_size, int w, int h) { BitBuf bb; int res, val; @@ -150,15 +177,20 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, int bx, by; int l0x, l1x, l0y, l1y; int mx, my; + const uint8_t *src_end = src + src_size; kmvc_init_getbits(bb, src); for (by = 0; by < h; by += 8) for (bx = 0; bx < w; bx += 8) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { // fill whole 8x8 block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; for (i = 0; i < 64; i++) BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val; @@ -171,14 +203,22 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, for (i = 0; i < 4; i++) { l0x = bx + (i & 1) * 4; l0y = by + (i & 2) * 2; - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { // fill whole 4x4 block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; for (j = 0; j < 16; j++) BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val; } else { // copy block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; mx = (val & 0xF) - 8; my = (val >> 4) - 8; @@ -190,16 +230,24 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, for (j = 0; j < 4; j++) { l1x = l0x + (j & 1) * 2; l1y = l0y + (j & 2); - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { - kmvc_getbit(bb, src, res); + kmvc_getbit(bb, src, src_end, res); if (!res) { // fill whole 2x2 block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; BLK(ctx->cur, l1x, l1y) = val; BLK(ctx->cur, l1x + 1, l1y) = val; BLK(ctx->cur, l1x, l1y + 1) = val; BLK(ctx->cur, l1x + 1, l1y + 1) = val; } else { // copy block + if (src >= src_end) { + av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n"); + return AVERROR_INVALIDDATA; + } val = *src++; mx = (val & 0xF) - 8; my = (val >> 4) - 8; @@ -222,6 +270,8 @@ static void kmvc_decode_inter_8x8(KmvcContext * ctx, const uint8_t * src, int w, } } } + + return 0; } static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt) @@ -299,10 +349,10 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPa memcpy(ctx->cur, ctx->prev, 320 * 200); break; case 3: - kmvc_decode_intra_8x8(ctx, buf, avctx->width, avctx->height); + kmvc_decode_intra_8x8(ctx, buf, buf_size, avctx->width, avctx->height); break; case 4: - kmvc_decode_inter_8x8(ctx, buf, avctx->width, avctx->height); + kmvc_decode_inter_8x8(ctx, buf, buf_size, avctx->width, avctx->height); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD); From cb8a17ddaccdbbe47748ba7ac4ce7303e47732fe Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 29 Dec 2011 09:07:32 -0800 Subject: [PATCH 80/84] kgv1: use avctx->get/release_buffer(). Also fixes crashes on corrupt bitstreams. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org (cherry picked from commit 33cd32b389864f2437c94e6fd7dc109ff5f0ed06) Signed-off-by: Anton Khirnov (cherry picked from commit e537dc230b2e123be8aebdaeee5a7d7787328b0b) Conflicts: libavcodec/kgv1dec.c Signed-off-by: Reinhard Tartler --- libavcodec/kgv1dec.c | 79 ++++++++++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c index e26fd81ffb..c4c3dac016 100644 --- a/libavcodec/kgv1dec.c +++ b/libavcodec/kgv1dec.c @@ -30,10 +30,17 @@ typedef struct { AVCodecContext *avctx; - AVFrame pic; - uint16_t *prev, *cur; + AVFrame prev, cur; } KgvContext; +static void decode_flush(AVCodecContext *avctx) +{ + KgvContext * const c = avctx->priv_data; + + if (c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); +} + static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; @@ -42,7 +49,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac int offsets[7]; uint16_t *out, *prev; int outcnt = 0, maxcnt; - int w, h, i; + int w, h, i, res; if (avpkt->size < 2) return -1; @@ -62,15 +69,15 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac maxcnt = w * h; - out = av_realloc(c->cur, w * h * 2); - if (!out) - return -1; - c->cur = out; - - prev = av_realloc(c->prev, w * h * 2); - if (!prev) - return -1; - c->prev = prev; + c->cur.reference = 3; + if ((res = avctx->get_buffer(avctx, &c->cur)) < 0) + return res; + out = (uint16_t *) c->cur.data[0]; + if (c->prev.data[0]) { + prev = (uint16_t *) c->prev.data[0]; + } else { + prev = NULL; + } for (i = 0; i < 7; i++) offsets[i] = -1; @@ -83,6 +90,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac out[outcnt++] = code; // rgb555 pixel coded directly } else { int count; + int inp_off; uint16_t *inp; if ((code & 0x6000) == 0x6000) { @@ -104,7 +112,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (maxcnt - start < count) break; - inp = prev + start; + if (!prev) { + av_log(avctx, AV_LOG_ERROR, + "Frame reference does not exist\n"); + break; + } + + inp = prev; + inp_off = start; } else { // copy from earlier in this frame int offset = (code & 0x1FFF) + 1; @@ -122,27 +137,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (outcnt < offset) break; - inp = out + outcnt - offset; + inp = out; + inp_off = outcnt - offset; } if (maxcnt - outcnt < count) break; - for (i = 0; i < count; i++) + for (i = inp_off; i < count + inp_off; i++) { out[outcnt++] = inp[i]; + } } } if (outcnt - maxcnt) av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt); - c->pic.data[0] = (uint8_t *)c->cur; - c->pic.linesize[0] = w * 2; - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; + *(AVFrame*)data = c->cur; - FFSWAP(uint16_t *, c->cur, c->prev); + if (c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); + FFSWAP(AVFrame, c->cur, c->prev); return avpkt->size; } @@ -153,28 +169,25 @@ static av_cold int decode_init(AVCodecContext *avctx) c->avctx = avctx; avctx->pix_fmt = PIX_FMT_RGB555; + avctx->flags |= CODEC_FLAG_EMU_EDGE; return 0; } static av_cold int decode_end(AVCodecContext *avctx) { - KgvContext * const c = avctx->priv_data; - - av_freep(&c->cur); - av_freep(&c->prev); - + decode_flush(avctx); return 0; } AVCodec ff_kgv1_decoder = { - "kgv1", - AVMEDIA_TYPE_VIDEO, - CODEC_ID_KGV1, - sizeof(KgvContext), - decode_init, - NULL, - decode_end, - decode_frame, + .name = "kgv1", + .type = AVMEDIA_TYPE_VIDEO, + .id = CODEC_ID_KGV1, + .priv_data_size = sizeof(KgvContext), + .init = decode_init, + .close = decode_end, + .decode = decode_frame, + .flush = decode_flush, .long_name = NULL_IF_CONFIG_SMALL("Kega Game Video"), }; From a0b65938b7cf37680a4ce0667444a217a151c551 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 25 Jan 2012 23:23:35 +0100 Subject: [PATCH 81/84] kgv1dec: Increase offsets array size so it is large enough. Fixes CVE-2011-3945 Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Michael Niedermayer (cherry picked from commit 807a045ab7f51993a2c1b3116016cbbd4f3d20d6) Signed-off-by: Alex Converse (cherry picked from commit a02e8df973f5478ec82f4c507f5b5b191a5ecb6b) (cherry picked from commit d5f2382d0389ed47a566ea536887af908bf9b14f) Signed-off-by: Reinhard Tartler --- libavcodec/kgv1dec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c index c4c3dac016..42bbcae530 100644 --- a/libavcodec/kgv1dec.c +++ b/libavcodec/kgv1dec.c @@ -46,7 +46,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac const uint8_t *buf = avpkt->data; const uint8_t *buf_end = buf + avpkt->size; KgvContext * const c = avctx->priv_data; - int offsets[7]; + int offsets[8]; uint16_t *out, *prev; int outcnt = 0, maxcnt; int w, h, i, res; @@ -79,7 +79,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac prev = NULL; } - for (i = 0; i < 7; i++) + for (i = 0; i < 8; i++) offsets[i] = -1; while (outcnt < maxcnt && buf_end - 2 > buf) { From fd53da21a1707225ba9b69f3452725b175e2d8b8 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Sun, 18 Mar 2012 19:08:15 +0100 Subject: [PATCH 82/84] lcl: use AVERROR_INVALIDDATA instead of AVERROR_UNKNOWN While bogus, this change avoids the necessity to backport AVERROR_UNKNOWN, which is not entirely trivial. Signed-off-by: Reinhard Tartler --- libavcodec/lcldec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index 8f203eb740..be5189a93b 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -601,7 +601,7 @@ static av_cold int decode_init(AVCodecContext *avctx) if (zret != Z_OK) { av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); av_freep(&c->decomp_buf); - return AVERROR_UNKNOWN; + return AVERROR_INVALIDDATA; } } #endif From 1687c55e24cdc9d23401795e86928d3eb37a60f7 Mon Sep 17 00:00:00 2001 From: Reinhard Tartler Date: Sun, 1 Apr 2012 19:08:06 +0200 Subject: [PATCH 83/84] Update RELEASE file for 0.7.5 --- RELEASE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASE b/RELEASE index 0a1ffad4b4..8bd6ba8c5c 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -0.7.4 +0.7.5 From bc5d86d23d1ad377addf54d65ee665327836075e Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 31 Mar 2012 07:52:42 +0200 Subject: [PATCH 84/84] id3v2: fix skipping extended header in id3v2.4 In v2.4, the length includes the length field itself. (cherry picked from commit ddb4431208745ea270dce8fce4cba999f0ed4303) Signed-off-by: Anton Khirnov --- libavformat/id3v2.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index be6c03bbe5..326dd145ef 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -216,8 +216,17 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t unsync = flags & 0x80; - if (isv34 && flags & 0x40) /* Extended header present, just skip over it */ - avio_skip(s->pb, get_size(s->pb, 4)); + if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */ + int extlen = get_size(s->pb, 4); + if (version == 4) + extlen -= 4; // in v2.4 the length includes the length field we just read + + if (extlen < 0) { + reason = "invalid extended header length"; + goto error; + } + avio_skip(s->pb, extlen); + } while (len >= taghdrlen) { unsigned int tflags = 0;