[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