Commit 02738096 authored by Denis Charmet's avatar Denis Charmet

Check element size before reading it

This should avoid integer overflows inside the libebml causing heap buffer overflow. Since new called by the lib is limited to SIZE_MAX bytes.
parent d3a43ec8
...@@ -527,6 +527,11 @@ matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, EbmlS ...@@ -527,6 +527,11 @@ matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, EbmlS
// find the families of this segment // find the families of this segment
KaxInfo *p_info = static_cast<KaxInfo*>(p_l1); KaxInfo *p_info = static_cast<KaxInfo*>(p_l1);
b_keep_segment = b_initial; b_keep_segment = b_initial;
if( unlikely( p_info->GetSize() >= SIZE_MAX ) )
{
msg_Err( p_demux, "KaxInfo too big aborting" );
break;
}
try try
{ {
p_info->Read(*p_estream, EBML_CLASS_CONTEXT(KaxInfo), i_upper_lvl, p_l2, true); p_info->Read(*p_estream, EBML_CLASS_CONTEXT(KaxInfo), i_upper_lvl, p_l2, true);
......
...@@ -138,6 +138,12 @@ void matroska_segment_c::LoadCues( KaxCues *cues ) ...@@ -138,6 +138,12 @@ void matroska_segment_c::LoadCues( KaxCues *cues )
KaxCueTime &ctime = *(KaxCueTime*)el; KaxCueTime &ctime = *(KaxCueTime*)el;
try try
{ {
if( unlikely( ctime.GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "CueTime size too big");
b_invalid_cue = true;
break;
}
ctime.ReadData( es.I_O() ); ctime.ReadData( es.I_O() );
} }
catch(...) catch(...)
...@@ -155,10 +161,17 @@ void matroska_segment_c::LoadCues( KaxCues *cues ) ...@@ -155,10 +161,17 @@ void matroska_segment_c::LoadCues( KaxCues *cues )
{ {
while( ( el = ep->Get() ) != NULL ) while( ( el = ep->Get() ) != NULL )
{ {
if( unlikely( el->GetSize() >= SIZE_MAX ) )
{
ep->Up();
msg_Err( &sys.demuxer, "Error %s too big, aborting", typeid(*el).name() );
b_invalid_cue = true;
break;
}
if( MKV_IS_ID( el, KaxCueTrack ) ) if( MKV_IS_ID( el, KaxCueTrack ) )
{ {
KaxCueTrack &ctrack = *(KaxCueTrack*)el; KaxCueTrack &ctrack = *(KaxCueTrack*)el;
ctrack.ReadData( es.I_O() ); ctrack.ReadData( es.I_O() );
idx.i_track = uint16( ctrack ); idx.i_track = uint16( ctrack );
} }
...@@ -270,6 +283,13 @@ SimpleTag * matroska_segment_c::ParseSimpleTags( KaxTagSimple *tag, int target_t ...@@ -270,6 +283,13 @@ SimpleTag * matroska_segment_c::ParseSimpleTags( KaxTagSimple *tag, int target_t
{ {
while( ( el = ep->Get() ) != NULL ) while( ( el = ep->Get() ) != NULL )
{ {
if( unlikely( el->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Error %s too big ignoring the tag", typeid(*el).name() );
delete ep;
delete p_simple;
return NULL;
}
if( MKV_IS_ID( el, KaxTagName ) ) if( MKV_IS_ID( el, KaxTagName ) )
{ {
KaxTagName &key = *(KaxTagName*)el; KaxTagName &key = *(KaxTagName*)el;
...@@ -376,6 +396,11 @@ void matroska_segment_c::LoadTags( KaxTags *tags ) ...@@ -376,6 +396,11 @@ void matroska_segment_c::LoadTags( KaxTags *tags )
{ {
try try
{ {
if( unlikely( el->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Invalid size while reading tag");
break;
}
if( MKV_IS_ID( el, KaxTagTargetTypeValue ) ) if( MKV_IS_ID( el, KaxTagTargetTypeValue ) )
{ {
KaxTagTargetTypeValue &value = *(KaxTagTargetTypeValue*)el; KaxTagTargetTypeValue &value = *(KaxTagTargetTypeValue*)el;
...@@ -421,11 +446,10 @@ void matroska_segment_c::LoadTags( KaxTags *tags ) ...@@ -421,11 +446,10 @@ void matroska_segment_c::LoadTags( KaxTags *tags )
catch(...) catch(...)
{ {
msg_Err( &sys.demuxer, "Error while reading tag"); msg_Err( &sys.demuxer, "Error while reading tag");
ep->Up();
break; break;
} }
ep->Up();
} }
ep->Up();
} }
else if( MKV_IS_ID( el, KaxTagSimple ) ) else if( MKV_IS_ID( el, KaxTagSimple ) )
{ {
...@@ -1296,6 +1320,12 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s ...@@ -1296,6 +1320,12 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
} }
break; break;
case 2: case 2:
if( unlikely( el->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Error while reading %s... upping level", typeid(*el).name());
ep->Up();
break;
}
if( MKV_IS_ID( el, KaxClusterTimecode ) ) if( MKV_IS_ID( el, KaxClusterTimecode ) )
{ {
KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el; KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
...@@ -1327,6 +1357,12 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s ...@@ -1327,6 +1357,12 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
} }
break; break;
case 3: case 3:
if( unlikely( el->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Error while reading %s... upping level", typeid(*el).name());
ep->Up();
break;
}
if( MKV_IS_ID( el, KaxBlock ) ) if( MKV_IS_ID( el, KaxBlock ) )
{ {
pp_block = (KaxBlock*)el; pp_block = (KaxBlock*)el;
......
...@@ -90,6 +90,11 @@ void matroska_segment_c::ParseSeekHead( KaxSeekHead *seekhead ) ...@@ -90,6 +90,11 @@ void matroska_segment_c::ParseSeekHead( KaxSeekHead *seekhead )
{ {
while( ( l = ep->Get() ) != NULL ) while( ( l = ep->Get() ) != NULL )
{ {
if( unlikely( l->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer,"%s too big... skipping it", typeid(*l).name() );
continue;
}
if( MKV_IS_ID( l, KaxSeekID ) ) if( MKV_IS_ID( l, KaxSeekID ) )
{ {
KaxSeekID &sid = *(KaxSeekID*)l; KaxSeekID &sid = *(KaxSeekID*)l;
...@@ -720,6 +725,11 @@ void matroska_segment_c::ParseTracks( KaxTracks *tracks ) ...@@ -720,6 +725,11 @@ void matroska_segment_c::ParseTracks( KaxTracks *tracks )
int i_upper_level = 0; int i_upper_level = 0;
/* Master elements */ /* Master elements */
if( unlikely( tracks->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Track too big, aborting" );
return;
}
try try
{ {
tracks->Read( es, EBML_CONTEXT(tracks), i_upper_level, el, true ); tracks->Read( es, EBML_CONTEXT(tracks), i_upper_level, el, true );
...@@ -756,6 +766,11 @@ void matroska_segment_c::ParseInfo( KaxInfo *info ) ...@@ -756,6 +766,11 @@ void matroska_segment_c::ParseInfo( KaxInfo *info )
/* Master elements */ /* Master elements */
m = static_cast<EbmlMaster *>(info); m = static_cast<EbmlMaster *>(info);
if( unlikely( m->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Info too big, aborting" );
return;
}
try try
{ {
m->Read( es, EBML_CONTEXT(info), i_upper_level, el, true ); m->Read( es, EBML_CONTEXT(info), i_upper_level, el, true );
...@@ -879,6 +894,12 @@ void matroska_segment_c::ParseInfo( KaxInfo *info ) ...@@ -879,6 +894,12 @@ void matroska_segment_c::ParseInfo( KaxInfo *info )
KaxChapterTranslate *p_trans = static_cast<KaxChapterTranslate*>( l ); KaxChapterTranslate *p_trans = static_cast<KaxChapterTranslate*>( l );
try try
{ {
if( unlikely( p_trans->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Chapter translate too big, aborting" );
continue;
}
p_trans->Read( es, EBML_CONTEXT(p_trans), i_upper_level, el, true ); p_trans->Read( es, EBML_CONTEXT(p_trans), i_upper_level, el, true );
chapter_translation_c *p_translate = new chapter_translation_c(); chapter_translation_c *p_translate = new chapter_translation_c();
...@@ -1069,6 +1090,11 @@ void matroska_segment_c::ParseAttachments( KaxAttachments *attachments ) ...@@ -1069,6 +1090,11 @@ void matroska_segment_c::ParseAttachments( KaxAttachments *attachments )
EbmlElement *el; EbmlElement *el;
int i_upper_level = 0; int i_upper_level = 0;
if( unlikely( attachments->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Attachments too big, aborting" );
return;
}
try try
{ {
attachments->Read( es, EBML_CONTEXT(attachments), i_upper_level, el, true ); attachments->Read( es, EBML_CONTEXT(attachments), i_upper_level, el, true );
...@@ -1127,6 +1153,11 @@ void matroska_segment_c::ParseChapters( KaxChapters *chapters ) ...@@ -1127,6 +1153,11 @@ void matroska_segment_c::ParseChapters( KaxChapters *chapters )
int i_upper_level = 0; int i_upper_level = 0;
/* Master elements */ /* Master elements */
if( unlikely( chapters->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Chapters too big, aborting" );
return;
}
try try
{ {
chapters->Read( es, EBML_CONTEXT(chapters), i_upper_level, el, true ); chapters->Read( es, EBML_CONTEXT(chapters), i_upper_level, el, true );
...@@ -1196,6 +1227,11 @@ void matroska_segment_c::ParseCluster( bool b_update_start_time ) ...@@ -1196,6 +1227,11 @@ void matroska_segment_c::ParseCluster( bool b_update_start_time )
/* Master elements */ /* Master elements */
m = static_cast<EbmlMaster *>( cluster ); m = static_cast<EbmlMaster *>( cluster );
if( unlikely( m->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Cluster too big, aborting" );
return;
}
try try
{ {
m->Read( es, EBML_CONTEXT(cluster), i_upper_level, el, true ); m->Read( es, EBML_CONTEXT(cluster), i_upper_level, el, true );
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment