From b4bccf3e4e58f6fe58043791ca09db01a4343fac Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 7 Mar 2012 14:18:14 -0800 Subject: [PATCH 01/10] wma: fix off-by-one in array bounds check. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/wmadec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 37feca1f7f..a7300594ca 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -356,7 +356,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 94f1b11a6fdfc43e48ffa4d29ba48f6ec3ba39d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Thu, 8 Mar 2012 00:52:53 +0200 Subject: [PATCH 02/10] rtpenc: Fix the AVRational used for av_rescale_q_rnd MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current one has a zero denominator - this is what was intended in 14aecc50fae6. Signed-off-by: Martin Storsjö --- libavformat/rtpenc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index 787eba87b7..5df25e4b88 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -138,7 +138,7 @@ static int rtp_write_header(AVFormatContext *s1) s->max_frames_per_packet = av_rescale_q_rnd(s1->max_delay, AV_TIME_BASE_Q, - (AVRational){ frame_size / st->codec->sample_rate }, + (AVRational){ frame_size, st->codec->sample_rate }, AV_ROUND_DOWN); } } From fd0be63049ed46660993d0550a4f0847a0b942ea Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 6 Mar 2012 17:00:29 -0800 Subject: [PATCH 03/10] tiffdec: Prevent illegal memory access caused by recycled pointers. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/tiff.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 0ff6ceb7cc..9ca91636a1 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -535,6 +535,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 83f15a1228895434a982c840b09edccd1c64e800 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 15 Feb 2012 16:21:34 -0800 Subject: [PATCH 04/10] avs: fix infinite loop on end-of-stream. The codec would keep returning the last decoded frame if the stream contains B-frames, since it wouldn't clear that frame from the list of frames to be returned to the user. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/cavsdec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 1da4eb1922..e3201343be 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -656,6 +656,7 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, if (!s->low_delay && h->DPB[0].f.data[0]) { *data_size = sizeof(AVPicture); *picture = h->DPB[0].f; + memset(&h->DPB[0], 0, sizeof(h->DPB[0])); } return 0; } From 681e72686555c2d334fc20c3c036bc0149139e6b Mon Sep 17 00:00:00 2001 From: Kostya Shishkov Date: Wed, 7 Mar 2012 20:07:17 +0100 Subject: [PATCH 05/10] dca: include libavutil/mathematics.h for possibly missing M_SQRT1_2 --- libavcodec/dca.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 8e4f819109..103f0588e3 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 4c25269cedd042abcb823c42d33609564861c374 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 7 Mar 2012 16:16:20 -0800 Subject: [PATCH 06/10] png: convert to bytestream2 API. Protects against overreads in the input buffer. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/pngdec.c | 69 ++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 39 deletions(-) diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 66afb0e5ad..56bda7c300 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -35,9 +35,7 @@ typedef struct PNGDecContext { PNGDSPContext dsp; - const uint8_t *bytestream; - const uint8_t *bytestream_start; - const uint8_t *bytestream_end; + GetByteContext gb; AVFrame picture1, picture2; AVFrame *current_picture, *last_picture; @@ -362,12 +360,9 @@ static void png_handle_row(PNGDecContext *s) static int png_decode_idat(PNGDecContext *s, int length) { int ret; - s->zstream.avail_in = length; - s->zstream.next_in = s->bytestream; - s->bytestream += length; - - if(s->bytestream > s->bytestream_end) - return -1; + s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb)); + s->zstream.next_in = s->gb.buffer; + bytestream2_skip(&s->gb, length); /* decode one line if possible */ while (s->zstream.avail_in > 0) { @@ -403,15 +398,13 @@ static int decode_frame(AVCodecContext *avctx, avctx->coded_frame= s->current_picture; p = s->current_picture; - s->bytestream_start= - s->bytestream= buf; - s->bytestream_end= buf + buf_size; - /* check signature */ - if (memcmp(s->bytestream, ff_pngsig, 8) != 0 && - memcmp(s->bytestream, ff_mngsig, 8) != 0) + if (buf_size < 8 || + memcmp(buf, ff_pngsig, 8) != 0 && + memcmp(buf, ff_mngsig, 8) != 0) return -1; - s->bytestream+= 8; + + bytestream2_init(&s->gb, buf + 8, buf_size - 8); s->y= s->state=0; // memset(s, 0, sizeof(PNGDecContext)); @@ -423,14 +416,12 @@ static int decode_frame(AVCodecContext *avctx, if (ret != Z_OK) return -1; for(;;) { - int tag32; - if (s->bytestream >= s->bytestream_end) + if (bytestream2_get_bytes_left(&s->gb) <= 0) goto fail; - length = bytestream_get_be32(&s->bytestream); + length = bytestream2_get_be32(&s->gb); if (length > 0x7fffffff) goto fail; - tag32 = bytestream_get_be32(&s->bytestream); - tag = av_bswap32(tag32); + tag = bytestream2_get_le32(&s->gb); av_dlog(avctx, "png: tag=%c%c%c%c length=%u\n", (tag & 0xff), ((tag >> 8) & 0xff), @@ -440,18 +431,18 @@ static int decode_frame(AVCodecContext *avctx, case MKTAG('I', 'H', 'D', 'R'): if (length != 13) goto fail; - s->width = bytestream_get_be32(&s->bytestream); - s->height = bytestream_get_be32(&s->bytestream); + s->width = bytestream2_get_be32(&s->gb); + s->height = bytestream2_get_be32(&s->gb); if(av_image_check_size(s->width, s->height, 0, avctx)){ s->width= s->height= 0; goto fail; } - s->bit_depth = *s->bytestream++; - s->color_type = *s->bytestream++; - s->compression_type = *s->bytestream++; - s->filter_type = *s->bytestream++; - s->interlace_type = *s->bytestream++; - s->bytestream += 4; /* crc */ + s->bit_depth = bytestream2_get_byte(&s->gb); + s->color_type = bytestream2_get_byte(&s->gb); + s->compression_type = bytestream2_get_byte(&s->gb); + s->filter_type = bytestream2_get_byte(&s->gb); + s->interlace_type = bytestream2_get_byte(&s->gb); + bytestream2_skip(&s->gb, 4); /* crc */ s->state |= PNG_IHDR; av_dlog(avctx, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n", s->width, s->height, s->bit_depth, s->color_type, @@ -547,7 +538,7 @@ static int decode_frame(AVCodecContext *avctx, s->state |= PNG_IDAT; if (png_decode_idat(s, length) < 0) goto fail; - s->bytestream += 4; /* crc */ + bytestream2_skip(&s->gb, 4); /* crc */ break; case MKTAG('P', 'L', 'T', 'E'): { @@ -558,16 +549,16 @@ static int decode_frame(AVCodecContext *avctx, /* read the palette */ n = length / 3; for(i=0;ibytestream++; - g = *s->bytestream++; - b = *s->bytestream++; + r = bytestream2_get_byte(&s->gb); + g = bytestream2_get_byte(&s->gb); + b = bytestream2_get_byte(&s->gb); s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b; } for(;i<256;i++) { s->palette[i] = (0xff << 24); } s->state |= PNG_PLTE; - s->bytestream += 4; /* crc */ + bytestream2_skip(&s->gb, 4); /* crc */ } break; case MKTAG('t', 'R', 'N', 'S'): @@ -580,21 +571,21 @@ static int decode_frame(AVCodecContext *avctx, !(s->state & PNG_PLTE)) goto skip_tag; for(i=0;ibytestream++; + v = bytestream2_get_byte(&s->gb); s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24); } - s->bytestream += 4; /* crc */ + bytestream2_skip(&s->gb, 4); /* crc */ } break; case MKTAG('I', 'E', 'N', 'D'): if (!(s->state & PNG_ALLIMAGE)) goto fail; - s->bytestream += 4; /* crc */ + bytestream2_skip(&s->gb, 4); /* crc */ goto exit_loop; default: /* skip tag */ skip_tag: - s->bytestream += length + 4; + bytestream2_skip(&s->gb, length + 4); break; } } @@ -619,7 +610,7 @@ static int decode_frame(AVCodecContext *avctx, *picture= *s->current_picture; *data_size = sizeof(AVFrame); - ret = s->bytestream - s->bytestream_start; + ret = bytestream2_tell(&s->gb); the_end: inflateEnd(&s->zstream); av_free(crow_buf_base); From 4ffe5e2aa5241f8da9afd2c8fbc854dcc916c5f9 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Wed, 7 Mar 2012 16:29:23 -0800 Subject: [PATCH 07/10] 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 --- libavcodec/huffyuv.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index 82b26a912f..278948d195 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 ef0d779706c77ca9007527bd8d41e9400682f4e4 Mon Sep 17 00:00:00 2001 From: Dale Curtis Date: Wed, 7 Mar 2012 14:26:58 -0800 Subject: [PATCH 08/10] Fix uninitialized reads on malformed ogg files. The ogg decoder wasn't padding the input buffer with the appropriate FF_INPUT_BUFFER_PADDING_SIZE bytes. Which led to uninitialized reads in various pieces of parsing code when they thought they had more data than they actually did. Signed-off-by: Dale Curtis Signed-off-by: Ronald S. Bultje --- libavformat/oggdec.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index 79aa98f83d..e04a4e7973 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -70,8 +70,7 @@ static int ogg_save(AVFormatContext *s) for (i = 0; i < ogg->nstreams; i++){ struct ogg_stream *os = ogg->streams + i; - os->buf = av_malloc (os->bufsize); - memset (os->buf, 0, os->bufsize); + os->buf = av_mallocz (os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); memcpy (os->buf, ost->streams[i].buf, os->bufpos); } @@ -168,7 +167,7 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream) os = ogg->streams + idx; os->serial = serial; os->bufsize = DECODER_BUFFER_SIZE; - os->buf = av_malloc(os->bufsize); + os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); os->header = -1; if (new_avstream) { @@ -186,7 +185,7 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream) static int ogg_new_buf(struct ogg *ogg, int idx) { struct ogg_stream *os = ogg->streams + idx; - uint8_t *nb = av_malloc(os->bufsize); + uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); int size = os->bufpos - os->pstart; if(os->buf){ memcpy(nb, os->buf + os->pstart, size); @@ -297,7 +296,7 @@ static int ogg_read_page(AVFormatContext *s, int *str) } if (os->bufsize - os->bufpos < size){ - uint8_t *nb = av_malloc (os->bufsize *= 2); + uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE); memcpy (nb, os->buf, os->bufpos); av_free (os->buf); os->buf = nb; @@ -311,6 +310,7 @@ static int ogg_read_page(AVFormatContext *s, int *str) os->granule = gp; os->flags = flags; + memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE); if (str) *str = idx; From 12623a8026c1657aedce2ef10d58bffba85dee2d Mon Sep 17 00:00:00 2001 From: Aaron Colwell Date: Wed, 7 Mar 2012 14:51:00 -0800 Subject: [PATCH 09/10] vorbisdec: avoid invalid memory access This fixes some invalid memory access caused later in the function by res_chan[] not being set for all channels. This happens when a channel doesn't appear a submap. This change simply returns a decoder error when this situation is detected. Signed-off-by: Ronald S. Bultje --- libavcodec/vorbisdec.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 0d491c82dd..4a7d6097b1 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -1581,6 +1581,9 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) ch_left -= ch; } + if (ch_left > 0) + return AVERROR_INVALIDDATA; + // Inverse coupling for (i = mapping->coupling_steps - 1; i >= 0; --i) { //warning: i has to be signed From ea1d64ab1066145ba919b79a2080f3091d562217 Mon Sep 17 00:00:00 2001 From: Paul B Mahol Date: Tue, 6 Mar 2012 20:26:48 +0000 Subject: [PATCH 10/10] ttadec: unbreak playback of matroska files Matroska demuxer needs to recreate tta header, so just display crc error without aborting. Signed-off-by: Paul B Mahol Signed-off-by: Ronald S. Bultje --- libavcodec/tta.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 269ba86fd9..ad80246525 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -208,8 +208,7 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) { if (avctx->err_recognition & AV_EF_CRCCHECK) { s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE); - if (tta_check_crc(s, avctx->extradata, 18)) - return AVERROR_INVALIDDATA; + tta_check_crc(s, avctx->extradata, 18); } /* signature */