vlc | branch: master | Rémi Denis-Courmont <[email protected]> | 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 ); _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
