diff options
author | John Stebbins <jstebbins@jetheaddev.com> | 2017-11-26 07:32:30 -0800 |
---|---|---|
committer | Michael Niedermayer <michael@niedermayer.cc> | 2017-12-07 23:38:06 +0100 |
commit | f7357facd8334863fd665b58d9b5487df4e9f583 (patch) | |
tree | 7dcbc9efd56b8591ff28c606bd7f64e920413254 /libavformat | |
parent | ed87667bd3d4bf45fb1bc173d2ba28b17add9145 (diff) | |
download | ffmpeg-f7357facd8334863fd665b58d9b5487df4e9f583.tar.gz |
lavf/mov: fix huge alloc in mov_read_ctts
An invalid file may cause huge alloc. Delay expansion of ctts entries
until the number of samples is known in mov_build_index.
Fixes: 23
Found-by: zhao dongzhuo, AD-lab of Venustech
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
(cherry picked from commit 2d015d3bf9fed59c65a3819a35fedbb8b7dde623)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/mov.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index 57cef83bba..9a6c3b3e46 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2716,7 +2716,7 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) { AVStream *st; MOVStreamContext *sc; - unsigned int i, j, entries, ctts_count = 0; + unsigned int i, entries, ctts_count = 0; if (c->fc->nb_streams < 1) return 0; @@ -2749,9 +2749,8 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) continue; } - /* Expand entries such that we have a 1-1 mapping with samples. */ - for (j = 0; j < count; j++) - add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size, 1, duration); + add_ctts_entry(&sc->ctts_data, &ctts_count, &sc->ctts_allocated_size, + count, duration); av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n", count, duration); @@ -3349,6 +3348,8 @@ static void mov_build_index(MOVContext *mov, AVStream *st) unsigned int stps_index = 0; unsigned int i, j; uint64_t stream_size = 0; + MOVStts *ctts_data_old = sc->ctts_data; + unsigned int ctts_count_old = sc->ctts_count; if (sc->elst_count) { int i, edit_start_index = 0, multiple_edits = 0; @@ -3417,6 +3418,28 @@ static void mov_build_index(MOVContext *mov, AVStream *st) } st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries); + if (ctts_data_old) { + // Expand ctts entries such that we have a 1-1 mapping with samples + if (sc->sample_count >= UINT_MAX / sizeof(*sc->ctts_data)) + return; + sc->ctts_count = 0; + sc->ctts_allocated_size = 0; + sc->ctts_data = av_fast_realloc(NULL, &sc->ctts_allocated_size, + sc->sample_count * sizeof(*sc->ctts_data)); + if (!sc->ctts_data) { + av_free(ctts_data_old); + return; + } + for (i = 0; i < ctts_count_old && + sc->ctts_count < sc->sample_count; i++) + for (j = 0; j < ctts_data_old[i].count && + sc->ctts_count < sc->sample_count; j++) + add_ctts_entry(&sc->ctts_data, &sc->ctts_count, + &sc->ctts_allocated_size, 1, + ctts_data_old[i].duration); + av_free(ctts_data_old); + } + for (i = 0; i < sc->chunk_count; i++) { int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX; current_offset = sc->chunk_offsets[i]; |