aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat
diff options
context:
space:
mode:
authorJohn Stebbins <jstebbins@jetheaddev.com>2017-11-26 07:32:30 -0800
committerMichael Niedermayer <michael@niedermayer.cc>2017-12-07 23:38:06 +0100
commitf7357facd8334863fd665b58d9b5487df4e9f583 (patch)
tree7dcbc9efd56b8591ff28c606bd7f64e920413254 /libavformat
parented87667bd3d4bf45fb1bc173d2ba28b17add9145 (diff)
downloadffmpeg-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.c31
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];