aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2013-09-11 22:56:55 +0300
committerLuca Barbato <lu_zero@gentoo.org>2014-01-07 09:43:56 +0100
commitb9e90b36cd3b87298b524330640818411b5ff45e (patch)
treec5443b05bebd4278f03869eeecd0453e37532727
parent7981b5c20e614e792967f17d09cf1adfb07ae254 (diff)
downloadffmpeg-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.c22
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,