diff options
author | Martin Storsjö <martin@martin.st> | 2013-09-11 22:56:55 +0300 |
---|---|---|
committer | Luca Barbato <lu_zero@gentoo.org> | 2014-01-07 09:43:56 +0100 |
commit | b9e90b36cd3b87298b524330640818411b5ff45e (patch) | |
tree | c5443b05bebd4278f03869eeecd0453e37532727 | |
parent | 7981b5c20e614e792967f17d09cf1adfb07ae254 (diff) | |
download | ffmpeg-b9e90b36cd3b87298b524330640818411b5ff45e.tar.gz |
sierravmd: Do sanity checking of frame sizes
Limit the size to INT_MAX/2 (for simplicity) to be sure that
size + BYTES_PER_FRAME_RECORD won't overflow.
Also factorize other existing error return paths.
Reported-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind
CC: libav-stable@libav.org
Signed-off-by: Martin Storsjö <martin@martin.st>
(cherry picked from commit 0ef1660a6365ce60ead8858936b6f3f8ea862826)
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
(cherry picked from commit 153deed18bed43d16b272e8681b2a9b988d2682a)
-rw-r--r-- | libavformat/sierravmd.c | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/libavformat/sierravmd.c b/libavformat/sierravmd.c index 81ff46fea0..3b8da4a769 100644 --- a/libavformat/sierravmd.c +++ b/libavformat/sierravmd.c @@ -88,7 +88,7 @@ static int vmd_read_header(AVFormatContext *s, unsigned char *raw_frame_table; int raw_frame_table_size; int64_t current_offset; - int i, j; + int i, j, ret; unsigned int total_frames; int64_t current_audio_pts = 0; unsigned char chunk[BYTES_PER_FRAME_RECORD]; @@ -169,15 +169,13 @@ static int vmd_read_header(AVFormatContext *s, raw_frame_table = av_malloc(raw_frame_table_size); vmd->frame_table = av_malloc((vmd->frame_count * vmd->frames_per_block + sound_buffers) * sizeof(vmd_frame)); if (!raw_frame_table || !vmd->frame_table) { - av_free(raw_frame_table); - av_free(vmd->frame_table); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto error; } if (avio_read(pb, raw_frame_table, raw_frame_table_size) != raw_frame_table_size) { - av_free(raw_frame_table); - av_free(vmd->frame_table); - return AVERROR(EIO); + ret = AVERROR(EIO); + goto error; } total_frames = 0; @@ -193,6 +191,11 @@ static int vmd_read_header(AVFormatContext *s, avio_read(pb, chunk, BYTES_PER_FRAME_RECORD); type = chunk[0]; size = AV_RL32(&chunk[2]); + if (size > INT_MAX / 2) { + av_log(s, AV_LOG_ERROR, "Invalid frame size\n"); + ret = AVERROR_INVALIDDATA; + goto error; + } if(!size && type != 1) continue; switch(type) { @@ -229,6 +232,11 @@ static int vmd_read_header(AVFormatContext *s, vmd->frame_count = total_frames; return 0; + +error: + av_free(raw_frame_table); + av_free(vmd->frame_table); + return ret; } static int vmd_read_packet(AVFormatContext *s, |