[vlc-commits] mp4: check TRUN size before reading and allocation

Rémi Denis-Courmont git at videolan.org
Fri Nov 24 20:54:43 CET 2017


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Fri Nov 24 20:01:01 2017 +0200| [398e5ff0411180d87a167cca665162fe8b767500] | committer: Rémi Denis-Courmont

mp4: check TRUN size before reading and allocation

This fixes out-of-bound reads.
This avoids allocating stupid amounts of memory.

Note: there is still an infinite loop if count == 0xffffffff
(with a suitably enormous input).

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=398e5ff0411180d87a167cca665162fe8b767500
---

 modules/demux/mp4/libmp4.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 1e64f71c36..4e105cf684 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -1107,23 +1107,28 @@ static void MP4_FreeBox_trun( MP4_Box_t *p_box )
 
 static int MP4_ReadBox_trun(  stream_t *p_stream, MP4_Box_t *p_box )
 {
+    uint32_t count;
+
     MP4_READBOX_ENTER( MP4_Box_data_trun_t, MP4_FreeBox_trun );
 
     MP4_GETVERSIONFLAGS( p_box->data.p_trun );
-
-    MP4_GET4BYTES( p_box->data.p_trun->i_sample_count );
+    MP4_GET4BYTES( count );
 
     if( p_box->data.p_trun->i_flags & MP4_TRUN_DATA_OFFSET )
         MP4_GET4BYTES( p_box->data.p_trun->i_data_offset );
     if( p_box->data.p_trun->i_flags & MP4_TRUN_FIRST_FLAGS )
         MP4_GET4BYTES( p_box->data.p_trun->i_first_sample_flags );
 
-    p_box->data.p_trun->p_samples =
-      calloc( p_box->data.p_trun->i_sample_count, sizeof(MP4_descriptor_trun_sample_t) );
+    if( UINT64_C(16) * count > i_read )
+        MP4_READBOX_EXIT( 0 );
+
+    p_box->data.p_trun->p_samples = vlc_alloc( count,
+                                        sizeof(MP4_descriptor_trun_sample_t) );
     if ( p_box->data.p_trun->p_samples == NULL )
         MP4_READBOX_EXIT( 0 );
+    p_box->data.p_trun->i_sample_count = count;
 
-    for( unsigned int i = 0; i<p_box->data.p_trun->i_sample_count; i++ )
+    for( unsigned int i = 0; i < count; i++ )
     {
         MP4_descriptor_trun_sample_t *p_sample = &p_box->data.p_trun->p_samples[i];
         if( p_box->data.p_trun->i_flags & MP4_TRUN_SAMPLE_DURATION )
@@ -1137,12 +1142,12 @@ static int MP4_ReadBox_trun(  stream_t *p_stream, MP4_Box_t *p_box )
     }
 
 #ifdef MP4_ULTRA_VERBOSE
-    msg_Dbg( p_stream, "read box: \"trun\" version %u flags 0x%x sample count %u",
+    msg_Dbg( p_stream, "read box: \"trun\" version %u flags 0x%x sample count %"PRIu32,
                   p_box->data.p_trun->i_version,
                   p_box->data.p_trun->i_flags,
                   p_box->data.p_trun->i_sample_count );
 
-    for( unsigned int i = 0; i<p_box->data.p_trun->i_sample_count; i++ )
+    for( unsigned int i = 0; i < count; i++ )
     {
         MP4_descriptor_trun_sample_t *p_sample = &p_box->data.p_trun->p_samples[i];
         msg_Dbg( p_stream, "read box: \"trun\" sample %4.4u flags 0x%x "\



More information about the vlc-commits mailing list