1
0
mirror of https://github.com/FFmpeg/FFmpeg.git synced 2024-12-23 12:43:46 +02:00

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 2d015d3bf9)
Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
John Stebbins 2017-11-26 07:32:30 -08:00 committed by Michael Niedermayer
parent ed87667bd3
commit f7357facd8

View File

@ -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];