File CVE-2020-19716.patch of Package exiv2-0_26.26338

From 109d5df7abd329f141b500c92a00178d35a6bef3 Mon Sep 17 00:00:00 2001
From: Kevin Backhouse <kev@semmle.com>
Date: Thu, 16 May 2019 14:30:12 +0100
Subject: [PATCH] Check bounds of jpg_img_off and jpg_img_len. (#858)

---
 src/rafimage.cpp                        |  30 ++++++++++++++++++------
 test/data/issue_857_coverage.raf        | Bin 0 -> 5550 bytes
 test/data/issue_857_poc.raf             | Bin 0 -> 5550 bytes
 tests/bugfixes/github/test_issue_857.py |  28 ++++++++++++++++++++++
 4 files changed, 51 insertions(+), 7 deletions(-)
 create mode 100644 test/data/issue_857_coverage.raf
 create mode 100644 test/data/issue_857_poc.raf
 create mode 100644 tests/bugfixes/github/test_issue_857.py

Index: exiv2-0.26/src/rafimage.cpp
===================================================================
--- exiv2-0.26.orig/src/rafimage.cpp
+++ exiv2-0.26/src/rafimage.cpp
@@ -39,6 +39,8 @@ EXIV2_RCSID("@(#) $Id$")
 #include "basicio.hpp"
 #include "error.hpp"
 #include "futils.hpp"
+#include "enforce.hpp"
+#include "safe_op.hpp"
 
 // + standard includes
 #include <string>
@@ -295,16 +297,30 @@ 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(14);
 
         io_->seek(0,BasicIo::beg); // rewind
openSUSE Build Service is sponsored by