[vlc-commits] mp4: fix heap read overflow and integer overflow

Rémi Denis-Courmont git at videolan.org
Sun Nov 12 15:40:39 CET 2017


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Nov 12 16:39:09 2017 +0200| [9d73515921d47bea41dad24280992f5180059fbd] | committer: Rémi Denis-Courmont

mp4: fix heap read overflow and integer overflow

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

 modules/demux/mp4/libmp4.c | 49 ++++++++++++++++++++++++++++++----------------
 1 file changed, 32 insertions(+), 17 deletions(-)

diff --git a/modules/demux/mp4/libmp4.c b/modules/demux/mp4/libmp4.c
index 4f575bdc21..21af23306e 100644
--- a/modules/demux/mp4/libmp4.c
+++ b/modules/demux/mp4/libmp4.c
@@ -1517,19 +1517,30 @@ static int MP4_ReadBox_cslg( stream_t *p_stream, MP4_Box_t *p_box )
     MP4_READBOX_EXIT( 1 );
 }
 
-static int MP4_ReadLengthDescriptor( uint8_t **pp_peek, int64_t  *i_read )
+static uint64_t MP4_ReadLengthDescriptor( uint8_t **restrict bufp,
+                                         int64_t *restrict lenp )
 {
-    unsigned int i_b;
-    unsigned int i_len = 0;
+    unsigned char *buf = *bufp;
+    int64_t len = *lenp;
+    unsigned char b;
+    uint64_t value = 0;
+
     do
     {
-        i_b = **pp_peek;
+        if (unlikely(len == 0))
+            return -1; /* end of bit stream */
+        if (unlikely(value > (UINT64_MAX >> 7)))
+            return -1; /* integer overflow */
+
+        b = *(buf++);
+        len--;
+        value = (value << 7) + (b & 0x7f);
+    }
+    while (b & 0x80);
 
-        (*pp_peek)++;
-        (*i_read)--;
-        i_len = ( i_len << 7 ) + ( i_b&0x7f );
-    } while( i_b&0x80 );
-    return( i_len );
+    *bufp = buf;
+    *lenp = len;
+    return value;
 }
 
 
@@ -1546,7 +1557,7 @@ static void MP4_FreeBox_esds( MP4_Box_t *p_box )
 static int MP4_ReadBox_esds( stream_t *p_stream, MP4_Box_t *p_box )
 {
 #define es_descriptor p_box->data.p_esds->es_descriptor
-    unsigned int i_len;
+    uint64_t i_len;
     unsigned int i_flags;
     unsigned int i_type;
 
@@ -1559,9 +1570,11 @@ static int MP4_ReadBox_esds( stream_t *p_stream, MP4_Box_t *p_box )
     if( i_type == 0x03 ) /* MP4ESDescrTag ISO/IEC 14496-1 8.3.3 */
     {
         i_len = MP4_ReadLengthDescriptor( &p_peek, &i_read );
+        if( unlikely(i_len == UINT64_C(-1)) )
+            MP4_READBOX_EXIT( 0 );
 
 #ifdef MP4_VERBOSE
-        msg_Dbg( p_stream, "found esds MPEG4ESDescr (%dBytes)",
+        msg_Dbg( p_stream, "found esds MPEG4ESDescr (%"PRIu64" bytes)",
                  i_len );
 #endif
 
@@ -1610,10 +1623,11 @@ static int MP4_ReadBox_esds( stream_t *p_stream, MP4_Box_t *p_box )
     }
 
     i_len = MP4_ReadLengthDescriptor( &p_peek, &i_read );
-
+    if( unlikely(i_len == UINT64_C(-1)) )
+        MP4_READBOX_EXIT( 0 );
 #ifdef MP4_VERBOSE
-        msg_Dbg( p_stream, "found esds MP4DecConfigDescr (%dBytes)",
-                 i_len );
+    msg_Dbg( p_stream, "found esds MP4DecConfigDescr (%"PRIu64" bytes)",
+             i_len );
 #endif
 
     es_descriptor.p_decConfigDescr =
@@ -1637,10 +1651,11 @@ static int MP4_ReadBox_esds( stream_t *p_stream, MP4_Box_t *p_box )
     }
 
     i_len = MP4_ReadLengthDescriptor( &p_peek, &i_read );
-
+    if( unlikely(i_len == UINT64_C(-1)) )
+        MP4_READBOX_EXIT( 0 );
 #ifdef MP4_VERBOSE
-        msg_Dbg( p_stream, "found esds MP4DecSpecificDescr (%dBytes)",
-                 i_len );
+    msg_Dbg( p_stream, "found esds MP4DecSpecificDescr (%"PRIu64" bytes)",
+             i_len );
 #endif
     if( i_len > i_read )
         MP4_READBOX_EXIT( 0 );



More information about the vlc-commits mailing list