mirror of
https://github.com/xenia-project/FFmpeg.git
synced 2024-11-24 03:59:43 +00:00
avformat/mvdec: Check size in read_table() for validity
This check is redundant with the previous commit but it provides better error messages and feedback while the previous commit ensures that var_read_string() doesnt return uninitialized arrays if it itself is feeded with an invalid size possibly through a different future codepath. Fixes: asan_heap-oob_49b1e5_12_011.movie Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
86e5749285
commit
f1c21a200b
@ -223,7 +223,7 @@ static int parse_video_var(AVFormatContext *avctx, AVStream *st,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void read_table(AVFormatContext *avctx, AVStream *st,
|
||||
static int read_table(AVFormatContext *avctx, AVStream *st,
|
||||
int (*parse)(AVFormatContext *avctx, AVStream *st,
|
||||
const char *name, int size))
|
||||
{
|
||||
@ -238,11 +238,16 @@ static void read_table(AVFormatContext *avctx, AVStream *st,
|
||||
avio_read(pb, name, 16);
|
||||
name[sizeof(name) - 1] = 0;
|
||||
size = avio_rb32(pb);
|
||||
if (size < 0) {
|
||||
av_log(avctx, AV_LOG_ERROR, "entry size %d is invalid\n", size);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if (parse(avctx, st, name, size) < 0) {
|
||||
avpriv_request_sample(avctx, "Variable %s", name);
|
||||
avio_skip(pb, size);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void read_index(AVIOContext *pb, AVStream *st)
|
||||
@ -268,6 +273,7 @@ static int mv_read_header(AVFormatContext *avctx)
|
||||
AVIOContext *pb = avctx->pb;
|
||||
AVStream *ast = NULL, *vst = NULL; //initialization to suppress warning
|
||||
int version, i;
|
||||
int ret;
|
||||
|
||||
avio_skip(pb, 4);
|
||||
|
||||
@ -340,7 +346,8 @@ static int mv_read_header(AVFormatContext *avctx)
|
||||
} else if (!version && avio_rb16(pb) == 3) {
|
||||
avio_skip(pb, 4);
|
||||
|
||||
read_table(avctx, NULL, parse_global_var);
|
||||
if ((ret = read_table(avctx, NULL, parse_global_var)) < 0)
|
||||
return ret;
|
||||
|
||||
if (mv->nb_audio_tracks > 1) {
|
||||
avpriv_request_sample(avctx, "Multiple audio streams support");
|
||||
@ -350,7 +357,8 @@ static int mv_read_header(AVFormatContext *avctx)
|
||||
if (!ast)
|
||||
return AVERROR(ENOMEM);
|
||||
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
|
||||
read_table(avctx, ast, parse_audio_var);
|
||||
if ((read_table(avctx, ast, parse_audio_var)) < 0)
|
||||
return ret;
|
||||
if (mv->acompression == 100 &&
|
||||
mv->aformat == AUDIO_FORMAT_SIGNED &&
|
||||
ast->codec->bits_per_coded_sample == 16) {
|
||||
@ -376,7 +384,8 @@ static int mv_read_header(AVFormatContext *avctx)
|
||||
if (!vst)
|
||||
return AVERROR(ENOMEM);
|
||||
vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
|
||||
read_table(avctx, vst, parse_video_var);
|
||||
if ((ret = read_table(avctx, vst, parse_video_var))<0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (mv->nb_audio_tracks)
|
||||
|
Loading…
Reference in New Issue
Block a user