[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