diff options
author | Alex Converse <alex.converse@gmail.com> | 2012-01-12 11:12:24 -0800 |
---|---|---|
committer | Alex Converse <alex.converse@gmail.com> | 2012-01-12 13:26:13 -0800 |
commit | 4df30f71147b7bedd4457bcfa0e4efe01085af9f (patch) | |
tree | a6fec3f3b2deab2e07269d0b6ca21bd8e11be485 | |
parent | 81dc6a2a3cefc1f1bbbc249052b3374e524d1ea0 (diff) | |
download | ffmpeg-4df30f71147b7bedd4457bcfa0e4efe01085af9f.tar.gz |
utils: Check for extradata size overflows.
-rw-r--r-- | libavcodec/internal.h | 7 | ||||
-rw-r--r-- | libavcodec/utils.c | 3 | ||||
-rw-r--r-- | libavformat/utils.c | 4 |
3 files changed, 13 insertions, 1 deletions
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); } |