From d65d8347314b645051e336aed141aaf32a6c0d02 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Sat, 14 Apr 2012 16:32:56 +0200 Subject: [PATCH 1/3] wmalosslessdec: Reset put bit buffer when num_saved_bits is reset. Fixes CVE-2012-2799 CC:libav-stable@libav.org Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Anton Khirnov --- libavcodec/wmalosslessdec.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c index b97f39752c..df025282ae 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -1230,6 +1230,7 @@ static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, * to decode incomplete frames in the s->len_prefix == 0 case. */ s->num_saved_bits = 0; s->packet_loss = 0; + init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); } } else { @@ -1282,6 +1283,7 @@ static void flush(AVCodecContext *avctx) s->next_packet_start = 0; s->cdlms[0][0].order = 0; s->frame.nb_samples = 0; + init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); } AVCodec ff_wmalossless_decoder = { From 85f477935cd6b34e6ec2716b20e15ce748277a89 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 20 Apr 2012 17:42:18 +0200 Subject: [PATCH 2/3] avsdec: Set dimensions instead of relying on the demuxer. The decode function assumes that the video will have those dimensions. Fixes CVE-2012-2801 CC:libav-stable@libav.org Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Anton Khirnov --- libavcodec/avs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/avs.c b/libavcodec/avs.c index d4e2837212..b8ee1e1ff2 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -158,6 +158,7 @@ avs_decode_frame(AVCodecContext * avctx, static av_cold int avs_decode_init(AVCodecContext * avctx) { avctx->pix_fmt = PIX_FMT_PAL8; + avcodec_set_dimensions(avctx, 318, 198); return 0; } From d9a2e87b1ce44cce23801e7ec6810f8bf994fa23 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 29 Sep 2012 13:45:09 +0200 Subject: [PATCH 3/3] mpeg12: move mpeg_decode_frame() lower Avoids a forward declaration of decode_chunks(). --- libavcodec/mpeg12.c | 92 ++++++++++++++++++++++----------------------- 1 file changed, 44 insertions(+), 48 deletions(-) diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index f80f3812d4..035ee5661d 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -2185,54 +2185,6 @@ int ff_mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size, return END_NOT_FOUND; } -static int decode_chunks(AVCodecContext *avctx, - AVFrame *picture, int *data_size, - const uint8_t *buf, int buf_size); - -/* handle buffering and image synchronisation */ -static int mpeg_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, - AVPacket *avpkt) -{ - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - Mpeg1Context *s = avctx->priv_data; - AVFrame *picture = data; - MpegEncContext *s2 = &s->mpeg_enc_ctx; - av_dlog(avctx, "fill_buffer\n"); - - if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) { - /* special case for last picture */ - if (s2->low_delay == 0 && s2->next_picture_ptr) { - *picture = s2->next_picture_ptr->f; - s2->next_picture_ptr = NULL; - - *data_size = sizeof(AVFrame); - } - return buf_size; - } - - if (s2->flags & CODEC_FLAG_TRUNCATED) { - int next = ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size, NULL); - - if (ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0) - return buf_size; - } - - if (s->mpeg_enc_ctx_allocated == 0 && avctx->codec_tag == AV_RL32("VCR2")) - vcr2_init_sequence(avctx); - - s->slice_count = 0; - - if (avctx->extradata && !avctx->frame_number) { - int ret = decode_chunks(avctx, picture, data_size, avctx->extradata, avctx->extradata_size); - if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) - return ret; - } - - return decode_chunks(avctx, picture, data_size, buf, buf_size); -} - static int decode_chunks(AVCodecContext *avctx, AVFrame *picture, int *data_size, const uint8_t *buf, int buf_size) @@ -2464,6 +2416,50 @@ static int decode_chunks(AVCodecContext *avctx, } } +static int mpeg_decode_frame(AVCodecContext *avctx, + void *data, int *data_size, + AVPacket *avpkt) +{ + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + Mpeg1Context *s = avctx->priv_data; + AVFrame *picture = data; + MpegEncContext *s2 = &s->mpeg_enc_ctx; + av_dlog(avctx, "fill_buffer\n"); + + if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) { + /* special case for last picture */ + if (s2->low_delay == 0 && s2->next_picture_ptr) { + *picture = s2->next_picture_ptr->f; + s2->next_picture_ptr = NULL; + + *data_size = sizeof(AVFrame); + } + return buf_size; + } + + if (s2->flags & CODEC_FLAG_TRUNCATED) { + int next = ff_mpeg1_find_frame_end(&s2->parse_context, buf, buf_size, NULL); + + if (ff_combine_frame(&s2->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0) + return buf_size; + } + + if (s->mpeg_enc_ctx_allocated == 0 && avctx->codec_tag == AV_RL32("VCR2")) + vcr2_init_sequence(avctx); + + s->slice_count = 0; + + if (avctx->extradata && !avctx->frame_number) { + int ret = decode_chunks(avctx, picture, data_size, avctx->extradata, avctx->extradata_size); + if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) + return ret; + } + + return decode_chunks(avctx, picture, data_size, buf, buf_size); +} + + static void flush(AVCodecContext *avctx) { Mpeg1Context *s = avctx->priv_data;