From 4df30f71147b7bedd4457bcfa0e4efe01085af9f Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 12 Jan 2012 11:12:24 -0800 Subject: [PATCH] utils: Check for extradata size overflows. --- libavcodec/internal.h | 7 +++++++ libavcodec/utils.c | 3 +++ libavformat/utils.c | 4 +++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/libavcodec/internal.h b/libavcodec/internal.h index b5a04546f3..1c2d0daaef 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -94,4 +94,11 @@ unsigned int avpriv_toupper4(unsigned int x); int avpriv_lock_avformat(void); int avpriv_unlock_avformat(void); +/** + * Maximum size in bytes of extradata. + * This value was chosen such that every bit of the buffer is + * addressable by a 32-bit signed integer as used by get_bits. + */ +#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - FF_INPUT_BUFFER_PADDING_SIZE) + #endif /* AVCODEC_INTERNAL_H */ diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 2bc1dcf5da..6f4d7e68da 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -610,6 +610,9 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD int ret = 0; AVDictionary *tmp = NULL; + if (avctx->extradata_size < 0 || avctx->extradata_size >= FF_MAX_EXTRADATA_SIZE) + return AVERROR(EINVAL); + if (options) av_dict_copy(&tmp, *options, 0); diff --git a/libavformat/utils.c b/libavformat/utils.c index a79665801f..373f06831d 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2442,9 +2442,11 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) } if(st->parser && st->parser->parser->split && !st->codec->extradata){ int i= st->parser->parser->split(st->codec, pkt->data, pkt->size); - if(i){ + if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) { st->codec->extradata_size= i; st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (!st->codec->extradata) + return AVERROR(ENOMEM); memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size); memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE); }