[vlc-commits] mux: mp4: fix use after free
Francois Cartegnie
git at videolan.org
Fri Jan 11 10:19:47 CET 2019
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Thu Jan 10 18:08:01 2019 +0100| [29933f9e5e6401e1b3e86b197f631dae61f8bcfd] | committer: Francois Cartegnie
mux: mp4: fix use after free
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=29933f9e5e6401e1b3e86b197f631dae61f8bcfd
---
modules/mux/mp4/libmp4mux.c | 5 ++++
modules/mux/mp4/libmp4mux.h | 1 +
modules/mux/mp4/mp4.c | 57 +++++++++++++++++++++++----------------------
3 files changed, 35 insertions(+), 28 deletions(-)
diff --git a/modules/mux/mp4/libmp4mux.c b/modules/mux/mp4/libmp4mux.c
index 480a87f859..3519e50983 100644
--- a/modules/mux/mp4/libmp4mux.c
+++ b/modules/mux/mp4/libmp4mux.c
@@ -237,6 +237,11 @@ uint32_t mp4mux_track_GetDefaultSampleSize(const mp4mux_trackinfo_t *t)
return t->i_trex_default_size;
}
+const es_format_t * mp4mux_track_GetFmt(const mp4mux_trackinfo_t *t)
+{
+ return &t->fmt;
+}
+
bool mp4mux_track_HasBFrames(const mp4mux_trackinfo_t *t)
{
return t->b_hasbframes;
diff --git a/modules/mux/mp4/libmp4mux.h b/modules/mux/mp4/libmp4mux.h
index 8a58aa560b..11b059d3e9 100644
--- a/modules/mux/mp4/libmp4mux.h
+++ b/modules/mux/mp4/libmp4mux.h
@@ -54,6 +54,7 @@ void mp4mux_track_SetSamplePriv(mp4mux_trackinfo_t *, const uint8_t *, siz
bool mp4mux_track_HasSamplePriv(const mp4mux_trackinfo_t *);
vlc_tick_t mp4mux_track_GetDefaultSampleDuration(const mp4mux_trackinfo_t *);
uint32_t mp4mux_track_GetDefaultSampleSize(const mp4mux_trackinfo_t *);
+const es_format_t * mp4mux_track_GetFmt(const mp4mux_trackinfo_t *);
/* ELST */
typedef struct
diff --git a/modules/mux/mp4/mp4.c b/modules/mux/mp4/mp4.c
index d85de415d1..1d5cd8d5ef 100644
--- a/modules/mux/mp4/mp4.c
+++ b/modules/mux/mp4/mp4.c
@@ -129,7 +129,6 @@ typedef struct mp4_fragqueue_t
typedef struct
{
mp4mux_trackinfo_t *tinfo;
- const es_format_t *p_fmt;
mux_extradata_builder_t *extrabuilder;
@@ -528,7 +527,6 @@ static int AddStream(sout_mux_t *p_mux, sout_input_t *p_input)
p_stream->extrabuilder = mux_extradata_builder_New(p_input->p_fmt->i_codec,
EXTRADATA_ISOBMFF);
- p_stream->p_fmt = p_input->p_fmt;
p_input->p_sys = p_stream;
@@ -621,7 +619,7 @@ static block_t * BlockDequeue(sout_input_t *p_input, mp4_stream_t *p_stream)
mp4mux_track_SetSamplePriv(p_stream->tinfo, p_extra, i_extra);
}
- switch(p_stream->p_fmt->i_codec)
+ switch(mp4mux_track_GetFmt(p_stream->tinfo)->i_codec)
{
case VLC_CODEC_AV1:
p_block = AV1_Pack_Sample(p_block);
@@ -681,7 +679,7 @@ static int MuxStream(sout_mux_t *p_mux, sout_input_t *p_input, mp4_stream_t *p_s
p_sys->i_start_dts = p_stream->i_first_dts;
}
- if (p_stream->p_fmt->i_cat != SPU_ES)
+ if (mp4mux_track_GetFmt(p_stream->tinfo)->i_cat != SPU_ES)
{
/* Fix length of the sample */
if (block_FifoCount(p_input->p_fifo) > 0)
@@ -689,23 +687,23 @@ static int MuxStream(sout_mux_t *p_mux, sout_input_t *p_input, mp4_stream_t *p_s
block_t *p_next = block_FifoShow(p_input->p_fifo);
if ( p_next->i_flags & BLOCK_FLAG_DISCONTINUITY )
{ /* we have no way to know real length except by decoding */
- if ( p_stream->p_fmt->i_cat == VIDEO_ES )
+ if ( mp4mux_track_GetFmt(p_stream->tinfo)->i_cat == VIDEO_ES )
{
p_data->i_length = vlc_tick_from_samples(
- p_stream->p_fmt->video.i_frame_rate_base,
- p_stream->p_fmt->video.i_frame_rate );
+ mp4mux_track_GetFmt(p_stream->tinfo)->video.i_frame_rate_base,
+ mp4mux_track_GetFmt(p_stream->tinfo)->video.i_frame_rate );
if( p_data->i_flags & BLOCK_FLAG_SINGLE_FIELD )
p_data->i_length >>= 1;
msg_Dbg( p_mux, "video track %u fixup to %"PRId64" for sample %u",
mp4mux_track_GetID(p_stream->tinfo), p_data->i_length,
mp4mux_track_GetSampleCount(p_stream->tinfo) );
}
- else if ( p_stream->p_fmt->i_cat == AUDIO_ES &&
- p_stream->p_fmt->audio.i_rate &&
+ else if ( mp4mux_track_GetFmt(p_stream->tinfo)->i_cat == AUDIO_ES &&
+ mp4mux_track_GetFmt(p_stream->tinfo)->audio.i_rate &&
p_data->i_nb_samples )
{
p_data->i_length = vlc_tick_from_samples(p_data->i_nb_samples,
- p_stream->p_fmt->audio.i_rate);
+ mp4mux_track_GetFmt(p_stream->tinfo)->audio.i_rate);
msg_Dbg( p_mux, "audio track %u fixup to %"PRId64" for sample %u",
mp4mux_track_GetID(p_stream->tinfo), p_data->i_length,
mp4mux_track_GetSampleCount(p_stream->tinfo) );
@@ -781,12 +779,12 @@ static int MuxStream(sout_mux_t *p_mux, sout_input_t *p_input, mp4_stream_t *p_s
}
/* Add SPU clearing tag (duration tb fixed on next SPU or stream end )*/
- if ( p_stream->p_fmt->i_cat == SPU_ES && sample.i_length > 0 )
+ if ( mp4mux_track_GetFmt(p_stream->tinfo)->i_cat == SPU_ES && sample.i_length > 0 )
{
block_t *p_empty = NULL;
- if(p_stream->p_fmt->i_codec == VLC_CODEC_SUBT||
- p_stream->p_fmt->i_codec == VLC_CODEC_QTXT||
- p_stream->p_fmt->i_codec == VLC_CODEC_TX3G)
+ if(mp4mux_track_GetFmt(p_stream->tinfo)->i_codec == VLC_CODEC_SUBT||
+ mp4mux_track_GetFmt(p_stream->tinfo)->i_codec == VLC_CODEC_QTXT||
+ mp4mux_track_GetFmt(p_stream->tinfo)->i_codec == VLC_CODEC_TX3G)
{
p_empty = block_Alloc(3);
if(p_empty)
@@ -797,13 +795,13 @@ static int MuxStream(sout_mux_t *p_mux, sout_input_t *p_input, mp4_stream_t *p_s
p_empty->p_buffer[2] = ' ';
}
}
- else if(p_stream->p_fmt->i_codec == VLC_CODEC_TTML)
+ else if(mp4mux_track_GetFmt(p_stream->tinfo)->i_codec == VLC_CODEC_TTML)
{
p_empty = block_Alloc(40);
if(p_empty)
memcpy(p_empty->p_buffer, "<tt><body><div><p></p></div></body></tt>", 40);
}
- else if(p_stream->p_fmt->i_codec == VLC_CODEC_WEBVTT)
+ else if(mp4mux_track_GetFmt(p_stream->tinfo)->i_codec == VLC_CODEC_WEBVTT)
{
p_empty = block_Alloc(8);
if(p_empty)
@@ -1143,7 +1141,8 @@ static bo_t *GetMoofBox(sout_mux_t *p_mux, size_t *pi_mdat_total_size,
/* Add keyframe entry if needed */
if (p_stream->b_hasiframes && (p_entry->p_block->i_flags & BLOCK_FLAG_TYPE_I) &&
- (p_stream->p_fmt->i_cat == VIDEO_ES || p_stream->p_fmt->i_cat == AUDIO_ES))
+ (mp4mux_track_GetFmt(p_stream->tinfo)->i_cat == VIDEO_ES ||
+ mp4mux_track_GetFmt(p_stream->tinfo)->i_cat == AUDIO_ES))
{
AddKeyframeEntry(p_stream, i_write_pos, i_trak, i_sample, i_time);
}
@@ -1306,8 +1305,8 @@ static void WriteFragments(sout_mux_t *p_mux, bool b_flush)
/* set a barrier so we try to align to keyframe */
if (p_stream->b_hasiframes &&
p_stream->i_last_iframe_time > p_stream->i_written_duration &&
- (p_stream->p_fmt->i_cat == VIDEO_ES ||
- p_stream->p_fmt->i_cat == AUDIO_ES) )
+ (mp4mux_track_GetFmt(p_stream->tinfo)->i_cat == VIDEO_ES ||
+ mp4mux_track_GetFmt(p_stream->tinfo)->i_cat == AUDIO_ES) )
{
i_barrier_time = __MIN(i_barrier_time, p_stream->i_last_iframe_time);
}
@@ -1348,21 +1347,22 @@ static void WriteFragments(sout_mux_t *p_mux, bool b_flush)
* This is the end boundary case. */
static void LengthLocalFixup(sout_mux_t *p_mux, const mp4_stream_t *p_stream, block_t *p_entrydata)
{
- if ( p_stream->p_fmt->i_cat == VIDEO_ES && p_stream->p_fmt->video.i_frame_rate )
+ if ( mp4mux_track_GetFmt(p_stream->tinfo)->i_cat == VIDEO_ES &&
+ mp4mux_track_GetFmt(p_stream->tinfo)->video.i_frame_rate )
{
p_entrydata->i_length = vlc_tick_from_samples(
- p_stream->p_fmt->video.i_frame_rate_base,
- p_stream->p_fmt->video.i_frame_rate);
+ mp4mux_track_GetFmt(p_stream->tinfo)->video.i_frame_rate_base,
+ mp4mux_track_GetFmt(p_stream->tinfo)->video.i_frame_rate);
msg_Dbg(p_mux, "video track %d fixup to %"PRId64" for sample %u",
mp4mux_track_GetID(p_stream->tinfo), p_entrydata->i_length,
mp4mux_track_GetSampleCount(p_stream->tinfo) - 1);
}
- else if (p_stream->p_fmt->i_cat == AUDIO_ES &&
- p_stream->p_fmt->audio.i_rate &&
- p_entrydata->i_nb_samples && p_stream->p_fmt->audio.i_rate)
+ else if (mp4mux_track_GetFmt(p_stream->tinfo)->i_cat == AUDIO_ES &&
+ mp4mux_track_GetFmt(p_stream->tinfo)->audio.i_rate &&
+ p_entrydata->i_nb_samples && mp4mux_track_GetFmt(p_stream->tinfo)->audio.i_rate)
{
p_entrydata->i_length = vlc_tick_from_samples(p_entrydata->i_nb_samples,
- p_stream->p_fmt->audio.i_rate);
+ mp4mux_track_GetFmt(p_stream->tinfo)->audio.i_rate);
msg_Dbg(p_mux, "audio track %d fixup to %"PRId64" for sample %u",
mp4mux_track_GetID(p_stream->tinfo), p_entrydata->i_length,
mp4mux_track_GetSampleCount(p_stream->tinfo) - 1);
@@ -1492,7 +1492,7 @@ static int MuxFrag(sout_mux_t *p_mux)
p_stream->p_held_entry->i_run = p_stream->i_current_run;
p_stream->p_held_entry->p_next = NULL;
- if (p_stream->p_fmt->i_cat == VIDEO_ES )
+ if (mp4mux_track_GetFmt(p_stream->tinfo)->i_cat == VIDEO_ES )
{
if (!p_stream->b_hasiframes && (p_currentblock->i_flags & BLOCK_FLAG_TYPE_I))
p_stream->b_hasiframes = true;
@@ -1509,7 +1509,8 @@ static int MuxFrag(sout_mux_t *p_mux)
for (unsigned int i=0; i<p_sys->i_nb_streams; i++)
{
const mp4_stream_t *p_s = p_sys->pp_streams[i];
- if (p_s->p_fmt->i_cat != VIDEO_ES && p_s->p_fmt->i_cat != AUDIO_ES)
+ if (mp4mux_track_GetFmt(p_stream->tinfo)->i_cat != VIDEO_ES &&
+ mp4mux_track_GetFmt(p_stream->tinfo)->i_cat != AUDIO_ES)
continue;
if (mp4mux_track_GetDuration(p_s->tinfo) < i_min_read_duration)
i_min_read_duration = mp4mux_track_GetDuration(p_s->tinfo);
More information about the vlc-commits
mailing list