From 398e5ff0411180d87a167cca665162fe8b767500 Mon Sep 17 00:00:00 2001 From: =?utf8?q?R=C3=A9mi=20Denis-Courmont?= Date: Fri, 24 Nov 2017 20:01:01 +0200 Subject: [PATCH] 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). --- 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; idata.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; idata.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 "\ -- 2.11.4.GIT