Check bounds of jpg_img_off and jpg_img_len. (#858)

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

@ -34,6 +34,8 @@
#include "basicio.hpp"
#include "error.hpp"
#include "futils.hpp"
#include "enforce.hpp"
#include "safe_op.hpp"
// + standard includes
#include <string>
@ -289,17 +291,31 @@ namespace Exiv2 {
clearMetadata();
io_->seek(84,BasicIo::beg);
if (io_->seek(84,BasicIo::beg) != 0) throw Error(kerFailedToReadImageData);
byte jpg_img_offset [4];
io_->read(jpg_img_offset, 4);
if (io_->read(jpg_img_offset, 4) != 4) throw Error(kerFailedToReadImageData);
byte jpg_img_length [4];
io_->read(jpg_img_length, 4);
long jpg_img_off = Exiv2::getULong((const byte *) jpg_img_offset, bigEndian);
long jpg_img_len = Exiv2::getULong((const byte *) jpg_img_length, bigEndian);
if (io_->read(jpg_img_length, 4) != 4) throw Error(kerFailedToReadImageData);
uint32_t jpg_img_off_u32 = Exiv2::getULong((const byte *) jpg_img_offset, bigEndian);
uint32_t jpg_img_len_u32 = Exiv2::getULong((const byte *) jpg_img_length, bigEndian);
enforce(Safe::add(jpg_img_off_u32, jpg_img_len_u32) <= io_->size(), kerCorruptedMetadata);
#if LONG_MAX < UINT_MAX
enforce(jpg_img_off_u32 <= static_cast<uint32_t>(std::numeric_limits<long>::max()),
kerCorruptedMetadata);
enforce(jpg_img_len_u32 <= static_cast<uint32_t>(std::numeric_limits<long>::max()),
kerCorruptedMetadata);
#endif
long jpg_img_off = static_cast<long>(jpg_img_off_u32);
long jpg_img_len = static_cast<long>(jpg_img_len_u32);
enforce(jpg_img_len >= 12, kerCorruptedMetadata);
DataBuf buf(jpg_img_len - 12);
io_->seek(jpg_img_off + 12,BasicIo::beg);
io_->read(buf.pData_, buf.size_ - 12);
if (io_->seek(jpg_img_off + 12,BasicIo::beg) != 0) throw Error(kerFailedToReadImageData);
io_->read(buf.pData_, buf.size_);
if (io_->error() || io_->eof()) throw Error(kerFailedToReadImageData);
io_->seek(0,BasicIo::beg); // rewind

Binary file not shown.

Binary file not shown.

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
from system_tests import CaseMeta, path
class OutOfMemoryInRafImageReadMetadata(metaclass=CaseMeta):
"""
Regression test for the bug described in:
https://github.com/Exiv2/exiv2/issues/857
There is no bounds check on the value of jpg_img_len in
RafImage::readMetadata(), leading to an out-of-memory error.
"""
url = "https://github.com/Exiv2/exiv2/issues/857"
filename1 = path("$data_path/issue_857_poc.raf")
filename2 = path("$data_path/issue_857_coverage.raf")
commands = ["$exiv2 $filename1", "$exiv2 $filename2"]
stdout = ["", ""]
stderr = [
"""Exiv2 exception in print action for file $filename1:
$kerCorruptedMetadata
""",
"""Exiv2 exception in print action for file $filename2:
This does not look like a TIFF image
"""
]
retval = [1,1]
Loading…
Cancel
Save