mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-11 17:55:21 +00:00
avformat/mov: check atom nesting depth
Fixes call stack overflow
Fixes: case1_call_stack_overflow.mp4
Found-by: Michal Zalewski <lcamtuf@coredump.cx>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
(cherry picked from commit caa7a3914f
)
Signed-off-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
parent
3d1972d182
commit
d85e25fe0b
@ -189,6 +189,7 @@ typedef struct MOVContext {
|
|||||||
int has_looked_for_mfra;
|
int has_looked_for_mfra;
|
||||||
MOVFragmentIndex** fragment_index_data;
|
MOVFragmentIndex** fragment_index_data;
|
||||||
unsigned fragment_index_count;
|
unsigned fragment_index_count;
|
||||||
|
int atom_depth;
|
||||||
} MOVContext;
|
} MOVContext;
|
||||||
|
|
||||||
int ff_mp4_read_descr_len(AVIOContext *pb);
|
int ff_mp4_read_descr_len(AVIOContext *pb);
|
||||||
|
@ -3388,6 +3388,12 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
MOVAtom a;
|
MOVAtom a;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if (c->atom_depth > 10) {
|
||||||
|
av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
|
c->atom_depth ++;
|
||||||
|
|
||||||
if (atom.size < 0)
|
if (atom.size < 0)
|
||||||
atom.size = INT64_MAX;
|
atom.size = INT64_MAX;
|
||||||
while (total_size + 8 <= atom.size && !avio_feof(pb)) {
|
while (total_size + 8 <= atom.size && !avio_feof(pb)) {
|
||||||
@ -3417,6 +3423,7 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
{
|
{
|
||||||
av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
|
av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
|
||||||
avio_skip(pb, -8);
|
avio_skip(pb, -8);
|
||||||
|
c->atom_depth --;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3453,13 +3460,16 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
int64_t start_pos = avio_tell(pb);
|
int64_t start_pos = avio_tell(pb);
|
||||||
int64_t left;
|
int64_t left;
|
||||||
int err = parse(c, pb, a);
|
int err = parse(c, pb, a);
|
||||||
if (err < 0)
|
if (err < 0) {
|
||||||
|
c->atom_depth --;
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
if (c->found_moov && c->found_mdat &&
|
if (c->found_moov && c->found_mdat &&
|
||||||
((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) ||
|
((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) ||
|
||||||
start_pos + a.size == avio_size(pb))) {
|
start_pos + a.size == avio_size(pb))) {
|
||||||
if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX)
|
if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX)
|
||||||
c->next_root_atom = start_pos + a.size;
|
c->next_root_atom = start_pos + a.size;
|
||||||
|
c->atom_depth --;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
left = a.size - avio_tell(pb) + start_pos;
|
left = a.size - avio_tell(pb) + start_pos;
|
||||||
@ -3479,6 +3489,7 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
|||||||
if (total_size < atom.size && atom.size < 0x7ffff)
|
if (total_size < atom.size && atom.size < 0x7ffff)
|
||||||
avio_skip(pb, atom.size - total_size);
|
avio_skip(pb, atom.size - total_size);
|
||||||
|
|
||||||
|
c->atom_depth --;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user