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

Thomas Guillem thomas at gllm.fr
Wed Nov 1 09:34:34 CET 2017


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


More information about the vlc-devel mailing list