From 607863acaec85671f8c2afd81079ae4c605e3468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 28 Sep 2013 23:32:39 +0300 Subject: [PATCH 01/12] riffdec: Add sanity checks for the sample rate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids a division by zero for G726. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit d07aa3f02b73ab1371c13ac7898338380ca0932b) Signed-off-by: Luca Barbato --- libavformat/riff.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavformat/riff.c b/libavformat/riff.c index e9463c0973..09d8dbbdb2 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -653,6 +653,11 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size) if (size > 0) avio_skip(pb, size); } + if (codec->sample_rate <= 0) { + av_log(NULL, AV_LOG_ERROR, + "Invalid sample rate: %d\n", codec->sample_rate); + return AVERROR_INVALIDDATA; + } codec->codec_id = ff_wav_codec_get_id(id, codec->bits_per_coded_sample); if (codec->codec_id == AV_CODEC_ID_AAC_LATM) { /* channels and sample_rate values are those prior to applying SBR and/or PS */ From a89868d714705af1b0b004fa790a889e9ba792cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 28 Sep 2013 23:38:40 +0300 Subject: [PATCH 02/12] electronicarts: Add more sanity checking for the number of channels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit a9221e39600a31ee13e736e9e47743cde23f0280) Signed-off-by: Luca Barbato Conflicts: libavformat/electronicarts.c --- libavformat/electronicarts.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index ebb4c124dd..b85b4c2678 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -439,8 +439,9 @@ static int ea_read_header(AVFormatContext *s) } if (ea->audio_codec) { - if (ea->num_channels <= 0) { - av_log(s, AV_LOG_WARNING, "Unsupported number of channels: %d\n", ea->num_channels); + if (ea->num_channels <= 0 || ea->num_channels > 2) { + av_log(s, AV_LOG_WARNING, + "Unsupported number of channels: %d\n", ea->num_channels); ea->audio_codec = 0; return 1; } From ad1223d6bcc69e1639951aedcdae40822bf41042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 28 Sep 2013 23:42:40 +0300 Subject: [PATCH 03/12] bfi: Avoid divisions by zero MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a zero-length video packet is to be returned, just return AVERROR(EAGAIN) and switch back to the audio stream. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit 9fc7184d1a9af8d97b3fc5c2ef9d0a647d6617ea) Signed-off-by: Luca Barbato --- libavformat/bfi.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libavformat/bfi.c b/libavformat/bfi.c index e60bbf4cab..5d7ccb85e6 100644 --- a/libavformat/bfi.c +++ b/libavformat/bfi.c @@ -140,9 +140,7 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt) pkt->pts = bfi->audio_frame; bfi->audio_frame += ret; - } - - else { + } else if (bfi->video_size > 0) { //Tossing a video packet at the video decoder. ret = av_get_packet(pb, pkt, bfi->video_size); @@ -154,6 +152,9 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt) /* One less frame to read. A cursory decrement. */ bfi->nframes--; + } else { + /* Empty video packet */ + ret = AVERROR(EAGAIN); } bfi->avflag = !bfi->avflag; From 10f384e4f5d0ee692cacaf90d629d8bc2178b092 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 28 Sep 2013 23:46:04 +0300 Subject: [PATCH 04/12] bfi: Add some very basic sanity checks for input packet sizes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit 640a2427aafa774b83316b7a8c5c2bdc28bfd269) Signed-off-by: Luca Barbato --- libavformat/bfi.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavformat/bfi.c b/libavformat/bfi.c index 5d7ccb85e6..19060e760f 100644 --- a/libavformat/bfi.c +++ b/libavformat/bfi.c @@ -132,6 +132,10 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt) video_offset = avio_rl32(pb); audio_size = video_offset - audio_offset; bfi->video_size = chunk_size - video_offset; + if (audio_size < 0 || bfi->video_size < 0) { + av_log(s, AV_LOG_ERROR, "Invalid audio/video offsets or chunk size\n"); + return AVERROR_INVALIDDATA; + } //Tossing an audio packet at the audio decoder. ret = av_get_packet(pb, pkt, audio_size); From c10f3fed259c23e6887f68cdf3e7d4ae87026f65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sat, 28 Sep 2013 23:57:36 +0300 Subject: [PATCH 05/12] mov: Make sure the read sample count is nonnegative MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This avoids setting a negative number of frames, ending up with a negative average frame rate. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit c231987662194d009dd91bfc57c678e0e70ca161) Signed-off-by: Luca Barbato --- libavformat/mov.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavformat/mov.c b/libavformat/mov.c index 2ae19c9358..6b89a2d1ba 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1659,6 +1659,10 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) sample_count=avio_rb32(pb); sample_duration = avio_rb32(pb); + if (sample_count < 0) { + av_log(c->fc, AV_LOG_ERROR, "Invalid sample_count=%d\n", sample_count); + return AVERROR_INVALIDDATA; + } sc->stts_data[i].count= sample_count; sc->stts_data[i].duration= sample_duration; From a63e83cd4b43c3dcef38f7fefe41c002a263af0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 29 Sep 2013 00:12:04 +0300 Subject: [PATCH 06/12] pngdec: Stop trying to decode once inflate returns Z_STREAM_END MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If the input buffer contains more data after the deflate stream, the loop previously left running infinitely, with inflate returning Z_STREAM_END. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit a81cad8f86d1feb7e4bfae29e43f3e994935a5c7) Signed-off-by: Luca Barbato --- libavcodec/pngdec.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 9c340eacb4..6c2df12c7d 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -378,6 +378,10 @@ static int png_decode_idat(PNGDecContext *s, int length) s->zstream.avail_out = s->crow_size; s->zstream.next_out = s->crow_buf; } + if (ret == Z_STREAM_END && s->zstream.avail_in > 0) { + av_log(NULL, AV_LOG_WARNING, "%d undecompressed bytes left in buffer\n", s->zstream.avail_in); + return 0; + } } return 0; } From 812955a12b190012c134be33a93f27308953eb2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 29 Sep 2013 00:38:50 +0300 Subject: [PATCH 07/12] pcx: Consume the whole packet if giving up due to missing palette MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Previously, we returned 0, meaning successful decoding but 0 bytes consumed, leading to an infinite loop. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit 9fb0de86b49e9fb0709a8ad1e1875e35da841887) Signed-off-by: Luca Barbato --- libavcodec/pcx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c index ba3703a712..9c79aff1ae 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -196,6 +196,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } if (*buf++ != 12) { av_log(avctx, AV_LOG_ERROR, "expected palette after image data\n"); + ret = buf_size; goto end; } From 145de32896b37a508f11bcf11dfcc94487301716 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 29 Sep 2013 00:53:58 +0300 Subject: [PATCH 08/12] xan: Use bytestream2 to limit reading to within the buffer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit 30db94dc399f6e4ef8905049d9b740556f0fce47) Signed-off-by: Luca Barbato --- libavcodec/xan.c | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/libavcodec/xan.c b/libavcodec/xan.c index 8c90bb6ab0..0dd81f5681 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -283,8 +283,8 @@ static int xan_wc3_decode_frame(XanContext *s) { /* pointers to segments inside the compressed chunk */ const unsigned char *huffman_segment; - const unsigned char *size_segment; - const unsigned char *vector_segment; + GetByteContext size_segment; + GetByteContext vector_segment; const unsigned char *imagedata_segment; int huffman_offset, size_offset, vector_offset, imagedata_offset, imagedata_size; @@ -304,8 +304,8 @@ static int xan_wc3_decode_frame(XanContext *s) { return AVERROR_INVALIDDATA; huffman_segment = s->buf + huffman_offset; - size_segment = s->buf + size_offset; - vector_segment = s->buf + vector_offset; + bytestream2_init(&size_segment, s->buf + size_offset, s->size - size_offset); + bytestream2_init(&vector_segment, s->buf + vector_offset, s->size - vector_offset); imagedata_segment = s->buf + imagedata_offset; if (xan_huffman_decode(opcode_buffer, opcode_buffer_size, @@ -357,19 +357,17 @@ static int xan_wc3_decode_frame(XanContext *s) { case 9: case 19: - size = *size_segment++; + size = bytestream2_get_byte(&size_segment); break; case 10: case 20: - size = AV_RB16(&size_segment[0]); - size_segment += 2; + size = bytestream2_get_be16(&size_segment); break; case 11: case 21: - size = AV_RB24(size_segment); - size_segment += 3; + size = bytestream2_get_be24(&size_segment); break; } @@ -391,9 +389,9 @@ static int xan_wc3_decode_frame(XanContext *s) { } } else { /* run-based motion compensation from last frame */ - motion_x = sign_extend(*vector_segment >> 4, 4); - motion_y = sign_extend(*vector_segment & 0xF, 4); - vector_segment++; + uint8_t vector = bytestream2_get_byte(&vector_segment); + motion_x = sign_extend(vector >> 4, 4); + motion_y = sign_extend(vector & 0xF, 4); /* copy a run of pixels from the previous frame */ xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y); From 09ace619d6ccb2c0a45b5fdead29f926409fa129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 29 Sep 2013 00:59:50 +0300 Subject: [PATCH 09/12] xan: Only read within the data that actually was initialized MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit fc739b3eefa0b58d64e7661621da94a94dbc8a82) Signed-off-by: Luca Barbato --- libavcodec/xan.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/libavcodec/xan.c b/libavcodec/xan.c index 0dd81f5681..369f89b18e 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -104,6 +104,7 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len, int ptr_len = src_len - 1 - byte*2; unsigned char val = ival; unsigned char *dest_end = dest + dest_len; + unsigned char *dest_start = dest; GetBitContext gb; if (ptr_len < 0) @@ -119,13 +120,13 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len, if (val < 0x16) { if (dest >= dest_end) - return 0; + return dest_len; *dest++ = val; val = ival; } } - return 0; + return dest - dest_start; } /** @@ -274,7 +275,7 @@ static int xan_wc3_decode_frame(XanContext *s) { unsigned char flag = 0; int size = 0; int motion_x, motion_y; - int x, y; + int x, y, ret; unsigned char *opcode_buffer = s->buffer1; unsigned char *opcode_buffer_end = s->buffer1 + s->buffer1_size; @@ -308,9 +309,10 @@ static int xan_wc3_decode_frame(XanContext *s) { bytestream2_init(&vector_segment, s->buf + vector_offset, s->size - vector_offset); imagedata_segment = s->buf + imagedata_offset; - if (xan_huffman_decode(opcode_buffer, opcode_buffer_size, - huffman_segment, s->size - huffman_offset) < 0) + if ((ret = xan_huffman_decode(opcode_buffer, opcode_buffer_size, + huffman_segment, s->size - huffman_offset)) < 0) return AVERROR_INVALIDDATA; + opcode_buffer_end = opcode_buffer + ret; if (imagedata_segment[0] == 2) { xan_unpack(s->buffer2, s->buffer2_size, From 3ac156b707932e93ed5e1f23ca866e251fafb743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 29 Sep 2013 01:04:05 +0300 Subject: [PATCH 10/12] xxan: Disallow odd width MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Decoded data is always written in pairs within this decoder. This fixes writes out of bounds. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit aa0dd52434768da64f1f3d8ae92bcf980c1adffc) Signed-off-by: Luca Barbato --- libavcodec/xxan.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c index 84ffdecdff..7a0cdc48c6 100644 --- a/libavcodec/xxan.c +++ b/libavcodec/xxan.c @@ -49,6 +49,10 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Invalid frame height: %d.\n", avctx->height); return AVERROR(EINVAL); } + if (avctx->width & 1) { + av_log(avctx, AV_LOG_ERROR, "Invalid frame width: %d.\n", avctx->width); + return AVERROR(EINVAL); + } s->buffer_size = avctx->width * avctx->height; s->y_buffer = av_malloc(s->buffer_size); From f06e39fe6b272a11782c023c31eec43bfce3138d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 29 Sep 2013 01:24:20 +0300 Subject: [PATCH 11/12] rpza: Fix a buffer size check MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We read 2 bytes for 15 out of 16 pixels, therefore we need to have at least 30 bytes, not 16. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit 7ba0cedbfeff5671b264d1d7e90777057b5714c6) Signed-off-by: Luca Barbato --- libavcodec/rpza.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c index 57d4d2d228..59b15c6d4f 100644 --- a/libavcodec/rpza.c +++ b/libavcodec/rpza.c @@ -203,7 +203,7 @@ static void rpza_decode_stream(RpzaContext *s) /* Fill block with 16 colors */ case 0x00: - if (s->size - stream_ptr < 16) + if (s->size - stream_ptr < 30) return; block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { From 7e350b7ddd19af856b55634233d609e29baab646 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 29 Sep 2013 13:02:27 +0300 Subject: [PATCH 12/12] pcx: Check the packet size before assuming it fits a palette MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes reads out of bounds. Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org Signed-off-by: Martin Storsjö (cherry picked from commit d1d99e3befea5d411ac3aae72dbdecce94f8b547) Signed-off-by: Luca Barbato Conflicts: libavcodec/pcx.c --- libavcodec/pcx.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c index 9c79aff1ae..223429d35e 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -184,7 +184,13 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } else if (nplanes == 1 && bits_per_pixel == 8) { const uint8_t *palstart = bufstart + buf_size - 769; - for (y=0; y