Commit 487cf6e4 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.
(cherry picked from commit 027380966251622435288af5b0f9bacfec549288)

Conflicts:
	modules/demux/mkv/matroska_segment.cpp
parent 55d4d471
......@@ -525,6 +525,11 @@ matroska_stream_c *demux_sys_t::AnalyseAllSegmentsFound( demux_t *p_demux, EbmlS
// find the families of this segment
KaxInfo *p_info = static_cast<KaxInfo*>(p_l1);
b_keep_segment = b_initial;
if( unlikely( p_info->GetSize() >= SIZE_MAX ) )
{
msg_Err( p_demux, "KaxInfo too big aborting" );
break;
}
try
{
p_info->Read(*p_estream, EBML_CLASS_CONTEXT(KaxInfo), i_upper_lvl, p_l2, true);
......
......@@ -152,6 +152,12 @@ void matroska_segment_c::LoadCues( KaxCues *cues )
KaxCueTime &ctime = *(KaxCueTime*)el;
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() );
}
catch(...)
......@@ -169,10 +175,17 @@ void matroska_segment_c::LoadCues( KaxCues *cues )
{
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 ) )
{
KaxCueTrack &ctrack = *(KaxCueTrack*)el;
ctrack.ReadData( es.I_O() );
idx.i_track = uint16( ctrack );
}
......@@ -279,6 +292,14 @@ void matroska_segment_c::ParseSimpleTags( KaxTagSimple *tag )
{
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;
free(k);
free(v);
return ;
}
if( MKV_IS_ID( el, KaxTagName ) )
{
KaxTagName &key = *(KaxTagName*)el;
......@@ -1563,6 +1584,12 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
}
break;
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 ) )
{
KaxClusterTimecode &ctc = *(KaxClusterTimecode*)el;
......@@ -1594,6 +1621,12 @@ int matroska_segment_c::BlockGet( KaxBlock * & pp_block, KaxSimpleBlock * & pp_s
}
break;
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 ) )
{
pp_block = (KaxBlock*)el;
......
......@@ -70,6 +70,11 @@ void matroska_segment_c::ParseSeekHead( KaxSeekHead *seekhead )
{
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 ) )
{
KaxSeekID &sid = *(KaxSeekID*)l;
......@@ -675,6 +680,11 @@ void matroska_segment_c::ParseTracks( KaxTracks *tracks )
int i_upper_level = 0;
/* Master elements */
if( unlikely( tracks->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Track too big, aborting" );
return;
}
try
{
tracks->Read( es, EBML_CONTEXT(tracks), i_upper_level, el, true );
......@@ -711,6 +721,11 @@ void matroska_segment_c::ParseInfo( KaxInfo *info )
/* Master elements */
m = static_cast<EbmlMaster *>(info);
if( unlikely( m->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Info too big, aborting" );
return;
}
try
{
m->Read( es, EBML_CONTEXT(info), i_upper_level, el, true );
......@@ -834,6 +849,12 @@ void matroska_segment_c::ParseInfo( KaxInfo *info )
KaxChapterTranslate *p_trans = static_cast<KaxChapterTranslate*>( l );
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 );
chapter_translation_c *p_translate = new chapter_translation_c();
......@@ -1024,6 +1045,11 @@ void matroska_segment_c::ParseAttachments( KaxAttachments *attachments )
EbmlElement *el;
int i_upper_level = 0;
if( unlikely( attachments->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Attachments too big, aborting" );
return;
}
try
{
attachments->Read( es, EBML_CONTEXT(attachments), i_upper_level, el, true );
......@@ -1079,6 +1105,11 @@ void matroska_segment_c::ParseChapters( KaxChapters *chapters )
int i_upper_level = 0;
/* Master elements */
if( unlikely( chapters->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Chapters too big, aborting" );
return;
}
try
{
chapters->Read( es, EBML_CONTEXT(chapters), i_upper_level, el, true );
......@@ -1148,6 +1179,11 @@ void matroska_segment_c::ParseCluster( bool b_update_start_time )
/* Master elements */
m = static_cast<EbmlMaster *>( cluster );
if( unlikely( m->GetSize() >= SIZE_MAX ) )
{
msg_Err( &sys.demuxer, "Cluster too big, aborting" );
return;
}
try
{
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