Add bounds check of resourceSize. (#856)

v0.27.3
Kevin Backhouse 6 years ago committed by Luis Díaz Más
parent 80cd0d2990
commit 1c1436e94e

@ -203,6 +203,8 @@ namespace Exiv2 {
while (resourcesLength > 0) while (resourcesLength > 0)
{ {
enforce(resourcesLength >= 8, Exiv2::kerCorruptedMetadata);
resourcesLength -= 8;
if (io_->read(buf, 8) != 8) if (io_->read(buf, 8) != 8)
{ {
throw Error(kerNotAnImage, "Photoshop"); throw Error(kerNotAnImage, "Photoshop");
@ -216,9 +218,13 @@ namespace Exiv2 {
uint32_t resourceNameLength = buf[6] & ~1; uint32_t resourceNameLength = buf[6] & ~1;
// skip the resource name, plus any padding // skip the resource name, plus any padding
enforce(resourceNameLength <= resourcesLength, Exiv2::kerCorruptedMetadata);
resourcesLength -= resourceNameLength;
io_->seek(resourceNameLength, BasicIo::cur); io_->seek(resourceNameLength, BasicIo::cur);
// read resource size // read resource size
enforce(resourcesLength >= 4, Exiv2::kerCorruptedMetadata);
resourcesLength -= 4;
if (io_->read(buf, 4) != 4) if (io_->read(buf, 4) != 4)
{ {
throw Error(kerNotAnImage, "Photoshop"); throw Error(kerNotAnImage, "Photoshop");
@ -230,11 +236,12 @@ namespace Exiv2 {
std::cerr << std::hex << "resourceId: " << resourceId << std::dec << " length: " << resourceSize << std::hex << "\n"; std::cerr << std::hex << "resourceId: " << resourceId << std::dec << " length: " << resourceSize << std::hex << "\n";
#endif #endif
enforce(resourceSize <= resourcesLength, Exiv2::kerCorruptedMetadata);
readResourceBlock(resourceId, resourceSize); readResourceBlock(resourceId, resourceSize);
resourceSize = (resourceSize + 1) & ~1; // pad to even resourceSize = (resourceSize + 1) & ~1; // pad to even
enforce(resourceSize <= resourcesLength, Exiv2::kerCorruptedMetadata);
resourcesLength -= resourceSize;
io_->seek(curOffset + resourceSize, BasicIo::beg); io_->seek(curOffset + resourceSize, BasicIo::beg);
resourcesLength -= Safe::add(Safe::add(static_cast<uint32_t>(12), resourceNameLength),
resourceSize);
} }
} // PsdImage::readMetadata } // PsdImage::readMetadata

Binary file not shown.

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
from system_tests import CaseMeta, path
class OutOfMemoryInPsdImageReadMetadata(metaclass=CaseMeta):
"""
Regression test for the bug described in:
https://github.com/Exiv2/exiv2/issues/855
There is no bounds check on the value of resourceSize,
leading to an out-of-memory error.
"""
url = "https://github.com/Exiv2/exiv2/issues/855"
filename = path("$data_path/issue_855_poc.psd")
commands = ["$exiv2 $filename"]
stdout = [""]
stderr = ["""Warning: Failed to decode IPTC metadata.
Exiv2 exception in print action for file $filename:
corrupted image metadata
"""
]
retval = [1]
Loading…
Cancel
Save