Check size before allocation to avoid out-of-memory errors.

This commit is contained in:
Kevin Backhouse 2021-07-30 17:35:14 +01:00
parent 3278270cbe
commit 67e2ef5ccd
No known key found for this signature in database
GPG Key ID: 9DD01852EE40366E
4 changed files with 18 additions and 21 deletions

View File

@ -241,6 +241,7 @@ static void boxes_check(size_t b,size_t m)
<< " length: " << box.length
<< std::endl;
#endif
enforce(box.length <= sizeof(box)+io_->size()-io_->tell() , Exiv2::kerCorruptedMetadata);
if (box.length == 0) return ;
@ -348,6 +349,7 @@ static void boxes_check(size_t b,size_t m)
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::readMetadata: Exif data found" << std::endl ;
#endif
enforce(box.length >= sizeof(box) + sizeof(uuid), kerCorruptedMetadata);
rawData.alloc(box.length - (sizeof(box) + sizeof(uuid)));
bufRead = io_->read(rawData.pData_, rawData.size_);
if (io_->error()) throw Error(kerFailedToReadImageData);
@ -402,6 +404,7 @@ static void boxes_check(size_t b,size_t m)
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::readMetadata: Iptc data found" << std::endl;
#endif
enforce(box.length >= sizeof(box) + sizeof(uuid), kerCorruptedMetadata);
rawData.alloc(box.length - (sizeof(box) + sizeof(uuid)));
bufRead = io_->read(rawData.pData_, rawData.size_);
if (io_->error()) throw Error(kerFailedToReadImageData);
@ -421,6 +424,7 @@ static void boxes_check(size_t b,size_t m)
#ifdef EXIV2_DEBUG_MESSAGES
std::cout << "Exiv2::Jp2Image::readMetadata: Xmp data found" << std::endl;
#endif
enforce(box.length >= sizeof(box) + sizeof(uuid), kerCorruptedMetadata);
rawData.alloc(box.length - static_cast<uint32_t>(sizeof(box) + sizeof(uuid)));
bufRead = io_->read(rawData.pData_, rawData.size_);
if (io_->error())
@ -497,7 +501,7 @@ static void boxes_check(size_t b,size_t m)
position = io_->tell();
box.length = getLong(reinterpret_cast<byte*>(&box.length), bigEndian);
box.type = getLong(reinterpret_cast<byte*>(&box.type), bigEndian);
enforce(box.length <= io_->size()-io_->tell() , Exiv2::kerCorruptedMetadata);
enforce(box.length <= sizeof(box)+io_->size()-io_->tell() , Exiv2::kerCorruptedMetadata);
if (bPrint) {
out << Internal::stringFormat("%8ld | %8ld | ", position - sizeof(box),
@ -517,7 +521,7 @@ static void boxes_check(size_t b,size_t m)
while (io_->read(reinterpret_cast<byte*>(&subBox), sizeof(subBox)) == sizeof(subBox) &&
io_->tell() < position + static_cast<long>(box.length)) // don't read beyond the box!
{
int address = io_->tell() - sizeof(subBox);
const size_t address = io_->tell() - sizeof(subBox);
subBox.length = getLong(reinterpret_cast<byte*>(&subBox.length), bigEndian);
subBox.type = getLong(reinterpret_cast<byte*>(&subBox.type), bigEndian);
@ -537,7 +541,7 @@ static void boxes_check(size_t b,size_t m)
if (subBox.type == kJp2BoxTypeColorHeader) {
long pad = 3; // don't know why there are 3 padding bytes
enforce(data.size_ >= pad, kerCorruptedMetadata);
enforce(data.size_ >= pad + 4, kerCorruptedMetadata);
if (bPrint) {
out << " | pad:";
for (int i = 0; i < 3; i++)
@ -576,6 +580,7 @@ static void boxes_check(size_t b,size_t m)
}
DataBuf rawData;
enforce(box.length >= sizeof(uuid) + sizeof(box), kerCorruptedMetadata);
rawData.alloc(box.length - sizeof(uuid) - sizeof(box));
long bufRead = io_->read(rawData.pData_, rawData.size_);
if (io_->error())

View File

@ -4,20 +4,16 @@ import system_tests
class issue_1522_exif_asan(metaclass=system_tests.CaseMeta):
url = "https://github.com/Exiv2/exiv2/issues/1522"
filename = "$data_path/poc_1522.jp2"
commands = ["$exiv2 $filename"
commands = ["$exiv2 -q $filename"
,"$exiv2 -pS $filename"
]
retval = [ 253,1 ]
stderr = [ """Warning: Failed to decode Exif metadata.
$filename: No Exif data found in the file
retval = [ 1,1 ]
stderr = [ """$exiv2_exception_message $filename:
$kerCorruptedMetadata
""","""$exiv2_exception_message $filename:
$kerCorruptedMetadata
"""]
stdout = ["""File name : $filename
File size : 268 Bytes
MIME type : image/jp2
Image size : 0 x 0
""","""STRUCTURE OF JPEG2000 FILE: $filename
stdout = ["","""STRUCTURE OF JPEG2000 FILE: $filename
address | length | box | data
0 | 12 | jP |
12 | 25 | uuid | Exif: .

View File

@ -18,8 +18,7 @@ class OutOfMemoryInJp2ImageReadMetadata(metaclass=CaseMeta):
filename = path("$data_path/issue_1812_poc.jp2")
commands = ["$exiv2 $filename"]
stdout = [""]
stderr = [
"""$exiv2_exception_message $filename:
$kerInputDataReadFailed
stderr = ["""$exiv2_exception_message $filename:
$kerCorruptedMetadata
"""]
retval = [1]

View File

@ -12,13 +12,10 @@ class Jp2ImageDoWriteMetadataOutOfBoundsRead(metaclass=CaseMeta):
filename1 = path("$data_path/issue_ghsa_7569_phvm_vwc2_poc.jp2")
filename2 = path("$data_path/issue_ghsa_7569_phvm_vwc2_poc.exv")
commands = ["$exiv2 in $filename1"]
commands = ["$exiv2 -q in $filename1"]
stdout = [""]
stderr = [
"""Warning: Directory Thumbnail, entry 0x1000 has unknown Exif (TIFF) type 28928; setting type size 1.
Error: Directory Thumbnail: IFD entry 1 lies outside of the data buffer.
Warning: Directory Thumbnail, entry 0x1000 has unknown Exif (TIFF) type 28928; setting type size 1.
Error: Offset of directory Thumbnail, entry 0x1000 is out of bounds: Offset = 0x2020506a; truncating the entry
$filename1: Could not write metadata to file: $kerCorruptedMetadata
"""Exiv2 exception in insert action for file $filename1:
$kerCorruptedMetadata
"""]
retval = [1]