From 67e2ef5ccd38869e79f308d80b740daedb845911 Mon Sep 17 00:00:00 2001 From: Kevin Backhouse Date: Fri, 30 Jul 2021 17:35:14 +0100 Subject: [PATCH] Check size before allocation to avoid out-of-memory errors. --- src/jp2image.cpp | 11 ++++++++--- tests/bugfixes/github/test_issue_1522.py | 14 +++++--------- tests/bugfixes/github/test_issue_1812.py | 5 ++--- .../github/test_issue_ghsa_7569_phvm_vwc2.py | 9 +++------ 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/jp2image.cpp b/src/jp2image.cpp index a6789d27..61e03f21 100644 --- a/src/jp2image.cpp +++ b/src/jp2image.cpp @@ -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(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(&box.length), bigEndian); box.type = getLong(reinterpret_cast(&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(&subBox), sizeof(subBox)) == sizeof(subBox) && io_->tell() < position + static_cast(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(&subBox.length), bigEndian); subBox.type = getLong(reinterpret_cast(&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()) diff --git a/tests/bugfixes/github/test_issue_1522.py b/tests/bugfixes/github/test_issue_1522.py index e5831b25..38a58ed9 100644 --- a/tests/bugfixes/github/test_issue_1522.py +++ b/tests/bugfixes/github/test_issue_1522.py @@ -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: . diff --git a/tests/bugfixes/github/test_issue_1812.py b/tests/bugfixes/github/test_issue_1812.py index 0385199a..803b9e19 100644 --- a/tests/bugfixes/github/test_issue_1812.py +++ b/tests/bugfixes/github/test_issue_1812.py @@ -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] diff --git a/tests/bugfixes/github/test_issue_ghsa_7569_phvm_vwc2.py b/tests/bugfixes/github/test_issue_ghsa_7569_phvm_vwc2.py index c201576b..c211c450 100644 --- a/tests/bugfixes/github/test_issue_ghsa_7569_phvm_vwc2.py +++ b/tests/bugfixes/github/test_issue_ghsa_7569_phvm_vwc2.py @@ -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]