[vlc-devel] [PATCH] demux: avformat: fix tracks initialization to prevent crash

Romain Vimont rom at rom1v.com
Wed Nov 1 10:21:06 CET 2017


Thanks for the merge :)

This patch fixes the crash when avformat_find_stream_info() updates
nb_streams.

However, according to the ffmpeg documentation:

> If AVFMTCTX_NOHEADER is set in ctx_flags, then new streams may also
> appear in av_read_frame().

<https://www.ffmpeg.org/doxygen/3.0/structAVFormatContext.html#acfefb6b6cf21e87a0dcbd1a547ba2348>

If this happens, then a similar crash might occur.

However, I don't know whether yet another stream may be added by
av_read_frame() when avformat_find_stream_info(), which calls
read_frame_internal(), has already been called.

<https://www.ffmpeg.org/doxygen/3.0/libavformat_2utils_8c_source.html#l03311>

This should at least be possible with a specially crafted stream that
avoids to call read_frame_internal() by breaking beforehand:

<https://www.ffmpeg.org/doxygen/3.0/libavformat_2utils_8c_source.html#l03295>

I have no video triggering this behavior.

Le mercredi  1 novembre 2017 à  9:34 +0100, Thomas Guillem a écrit :
> Hello,
> 
> Thanks for the fix! I think I just spotted this issue yesterday and
> didn't had the time to fix it.
> 
> Regards,
> Thomas.
> 
> On Wed, Nov 1, 2017, at 01:04, Romain Vimont wrote:
> > The 'tracks' array was created before the possible update of nb_streams
> > in avformat_find_stream_info(). As a consequence, it was then accessed
> > out of bounds.
> > 
> > On the following video, nb_streams is updated from 0 to 2 by
> > avformat_find_stream_info():
> > 
> >     $ youtube-dl https://bambuser.com/v/6908002 -o sample.flv
> >     ...
> >     $ ./vlc sample.flv
> >     *** Error in `./vlc': free(): invalid next size (fast):
> >     0x00007f85f4c376a0 ***
> >     ...
> > 
> > bisect/bad is 6cb816a2556937e63f49d5e703b98e2a760419ec.
> > 
> > Signed-off-by: Romain Vimont <rom at rom1v.com>
> > ---
> >  modules/demux/avformat/demux.c | 23 +++++++++++++++--------
> >  1 file changed, 15 insertions(+), 8 deletions(-)
> > 
> > diff --git a/modules/demux/avformat/demux.c
> > b/modules/demux/avformat/demux.c
> > index 9b242b06cd..2f3b907410 100644
> > --- a/modules/demux/avformat/demux.c
> > +++ b/modules/demux/avformat/demux.c
> > @@ -328,13 +328,7 @@ int OpenDemux( vlc_object_t *p_this )
> >      free( psz_url );
> >  
> >      char *psz_opts = var_InheritString( p_demux, "avformat-options" );
> > -    const unsigned int nb_streams = p_sys->ic->nb_streams;
> > -    p_sys->tracks = calloc( nb_streams, sizeof(*p_sys->tracks) );
> > -    if( !p_sys->tracks )
> > -    {
> > -        CloseDemux( p_this );
> > -        return VLC_ENOMEM;
> > -    }
> > +    unsigned nb_streams = p_sys->ic->nb_streams;
> >  
> >      AVDictionary *options[nb_streams ? nb_streams : 1];
> >      options[0] = NULL;
> > @@ -349,7 +343,6 @@ int OpenDemux( vlc_object_t *p_this )
> >      }
> >      vlc_avcodec_lock(); /* avformat calls avcodec behind our back!!! */
> >      error = avformat_find_stream_info( p_sys->ic, options );
> > -    /* FIXME: what if nb_streams change after that call? */
> >      vlc_avcodec_unlock();
> >      AVDictionaryEntry *t = NULL;
> >      while ((t = av_dict_get(options[0], "", t, AV_DICT_IGNORE_SUFFIX)))
> >      {
> > @@ -360,6 +353,20 @@ int OpenDemux( vlc_object_t *p_this )
> >          av_dict_free(&options[i]);
> >      }
> >  
> > +    nb_streams = p_sys->ic->nb_streams; /* it may have changed */
> > +    if( !nb_streams )
> > +    {
> > +        msg_Err( p_demux, "No streams found");
> > +        CloseDemux( p_this );
> > +        return VLC_EGENERIC;
> > +    }
> > +    p_sys->tracks = calloc( nb_streams, sizeof(*p_sys->tracks) );
> > +    if( !p_sys->tracks )
> > +    {
> > +        CloseDemux( p_this );
> > +        return VLC_ENOMEM;
> > +    }
> > +
> >      if( error < 0 )
> >      {
> >          msg_Warn( p_demux, "Could not find stream info: %s",
> > -- 
> > 2.11.0
> > 
> > _______________________________________________
> > vlc-devel mailing list
> > To unsubscribe or modify your subscription options:
> > https://mailman.videolan.org/listinfo/vlc-devel
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel


More information about the vlc-devel mailing list