[vlc-devel] [PATCH] demux: avformat: fix tracks initialization to prevent crash
Romain Vimont
rom at rom1v.com
Wed Nov 1 01:04:31 CET 2017
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
More information about the vlc-devel
mailing list