[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