Skip to content

Commit

Permalink
Validate reconstructed chunk sizes (#848)
Browse files Browse the repository at this point in the history
Signed-off-by: Peter Hillman <[email protected]>
  • Loading branch information
peterhillman authored Oct 12, 2020
1 parent 51a92d6 commit 84863e1
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 6 deletions.
11 changes: 11 additions & 0 deletions OpenEXR/IlmImf/ImfDeepScanLineInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,17 @@ reconstructLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset);
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample);
//next is unpacked sample table size - skip this too

// check for bad values to prevent overflow
if (packed_offset < 0 ||
packed_sample < 0 ||
(INT64_MAX-packed_offset < packed_sample ) ||
(INT64_MAX-(packed_offset+packed_sample) < 8 ) )
{
throw IEX_NAMESPACE::IoExc("Invalid chunk size");
}


Xdr::skip <StreamIO> (is, packed_offset+packed_sample+8);

if (lineOrder == INCREASING_Y)
Expand Down
34 changes: 31 additions & 3 deletions OpenEXR/IlmImf/ImfMultiPartInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,11 @@ MultiPartInputFile::Data::chunkOffsetReconstruction(OPENEXR_IMF_INTERNAL_NAMESPA
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample);

//add 40 byte header to packed sizes (tile coordinates, packed sizes, unpacked size)
// check for bad values to prevent overflow
if ( (INT64_MAX - packed_offset < packed_sample) || ( INT64_MAX - (packed_offset + packed_sample) < 40ll) )
{
throw IEX_NAMESPACE::IoExc("Invalid chunk size");
}
size_of_chunk=packed_offset+packed_sample + 40ll;
}
else
Expand All @@ -663,6 +668,12 @@ MultiPartInputFile::Data::chunkOffsetReconstruction(OPENEXR_IMF_INTERNAL_NAMESPA
// regular image has 20 bytes of header, 4 byte chunksize;
int chunksize;
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, chunksize);
// check for bad values to prevent overflow
if ( chunksize < 0 )
{
throw IEX_NAMESPACE::IoExc("Invalid chunk size");
}

size_of_chunk=static_cast<Int64>(chunksize) + 20ll;
}
}
Expand Down Expand Up @@ -692,14 +703,27 @@ MultiPartInputFile::Data::chunkOffsetReconstruction(OPENEXR_IMF_INTERNAL_NAMESPA
Int64 packed_sample;
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset);
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample);



// check for bad values to prevent overflow
if ( packed_offset < 0 ||
packed_sample < 0 ||
(INT64_MAX - packed_offset < packed_sample) ||
( INT64_MAX - (packed_offset + packed_sample) < 28ll) )
{
throw IEX_NAMESPACE::IoExc("Invalid chunk size");
}
size_of_chunk=packed_offset+packed_sample + 28ll;
}
else
{
int chunksize;
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, chunksize);

// check for bad values to prevent overflow
if ( chunksize < 0 )
{
throw IEX_NAMESPACE::IoExc("Invalid chunk size");
}
size_of_chunk=static_cast<Int64>(chunksize) + 8ll;
}

Expand All @@ -709,7 +733,11 @@ MultiPartInputFile::Data::chunkOffsetReconstruction(OPENEXR_IMF_INTERNAL_NAMESPA
{
chunk_start+=4;
}


if ( (INT64_MAX - chunk_start) < size_of_chunk )
{
throw IEX_NAMESPACE::IoExc("File pointer overflow during reconstruction");
}
chunk_start+=size_of_chunk;

is.seekg(chunk_start);
Expand Down
5 changes: 5 additions & 0 deletions OpenEXR/IlmImf/ImfScanLineInputFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,11 @@ reconstructLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
int dataSize;
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, dataSize);

// check for bad values to prevent overflow
if ( dataSize < 0 )
{
throw IEX_NAMESPACE::IoExc("Invalid chunk size");
}
Xdr::skip <StreamIO> (is, dataSize);

if (lineOrder == INCREASING_Y)
Expand Down
22 changes: 19 additions & 3 deletions OpenEXR/IlmImf/ImfTileOffsets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,14 +150,30 @@ TileOffsets::findTiles (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, bool isMult
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset_table_size);
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample_size);

// check for bad values to prevent overflow
if ( packed_offset_table_size < 0 ||
packed_sample_size < 0 ||
( INT64_MAX - packed_offset_table_size < packed_sample_size) ||
( INT64_MAX - (packed_offset_table_size + packed_sample_size) ) < 8 )
{
throw IEX_NAMESPACE::IoExc("Invalid deep tile size");
}

// next Int64 is unpacked sample size - skip that too
Xdr::skip <StreamIO> (is, packed_offset_table_size+packed_sample_size+8);

}else{

int dataSize;
}
else
{
int dataSize;
OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, dataSize);

// check for bad values to prevent overflow
if ( dataSize < 0 )
{
throw IEX_NAMESPACE::IoExc("Invalid tile size");
}

Xdr::skip <StreamIO> (is, dataSize);
}
if (skipOnly) continue;
Expand Down

0 comments on commit 84863e1

Please sign in to comment.