diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2014-12-16 21:14:40 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2014-12-30 15:38:20 +0100 |
commit | 07a37001a32339a72a8e45ff4f65072b3e506a2c (patch) | |
tree | 8ceccbbe5c1c907c814ee034f100e539a961b3a5 /libavformat | |
parent | ba99e90357c97f7845f1d463f73d9a4a7e77d78a (diff) | |
download | ffmpeg-07a37001a32339a72a8e45ff4f65072b3e506a2c.tar.gz |
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 caa7a3914f499f74b3ee346f26d598ebdc0ec210)
Conflicts:
libavformat/isom.h
Conflicts:
libavformat/isom.h
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/isom.h | 1 | ||||
-rw-r--r-- | libavformat/mov.c | 13 |
2 files changed, 13 insertions, 1 deletions
diff --git a/libavformat/isom.h b/libavformat/isom.h index 828e5005ad..9fc30d418a 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -164,6 +164,7 @@ typedef struct MOVContext { int64_t next_root_atom; ///< offset of the next root atom int *bitrates; ///< bitrates read before streams creation int bitrates_count; + int atom_depth; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/mov.c b/libavformat/mov.c index d19aa16483..407c5902ec 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2984,6 +2984,12 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) MOVAtom a; 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) atom.size = INT64_MAX; while (total_size + 8 <= atom.size && !url_feof(pb)) { @@ -3000,6 +3006,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"); avio_skip(pb, -8); + c->atom_depth --; return 0; } } @@ -3036,13 +3043,16 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) int64_t start_pos = avio_tell(pb); int64_t left; int err = parse(c, pb, a); - if (err < 0) + if (err < 0) { + c->atom_depth --; return err; + } if (c->found_moov && c->found_mdat && ((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) || start_pos + a.size == avio_size(pb))) { if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) c->next_root_atom = start_pos + a.size; + c->atom_depth --; return 0; } left = a.size - avio_tell(pb) + start_pos; @@ -3062,6 +3072,7 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (total_size < atom.size && atom.size < 0x7ffff) avio_skip(pb, atom.size - total_size); + c->atom_depth --; return 0; } |