Blame SOURCES/exiv2-CVE-2017-17723-2.patch

3f58c5
From 7f5b0778fa301b68c1c88e3820ec3afbd09dd0a5 Mon Sep 17 00:00:00 2001
3f58c5
From: clanmills <robin@clanmills.com>
3f58c5
Date: Wed, 27 Sep 2017 09:20:13 +0100
3f58c5
Subject: Fix https://github.com/Exiv2/exiv2/issues/55
3f58c5
3f58c5
(cherry picked from commit 6e3855aed7ba8bb4731fc4087ca7f9078b2f3d97)
3f58c5
3f58c5
diff --git a/include/exiv2/value.hpp b/include/exiv2/value.hpp
3f58c5
index 2078c6bd..b7d76fef 100644
3f58c5
--- a/include/exiv2/value.hpp
3f58c5
+++ b/include/exiv2/value.hpp
3f58c5
@@ -1659,11 +1659,13 @@ namespace Exiv2 {
3f58c5
         ok_ = true;
3f58c5
         return static_cast<long>(value_[n]);
3f58c5
     }
3f58c5
+// #55 crash when value_[n].first == LONG_MIN
3f58c5
+#define LARGE_INT 1000000
3f58c5
     // Specialization for rational
3f58c5
     template<>
3f58c5
     inline long ValueType<Rational>::toLong(long n) const
3f58c5
     {
3f58c5
-        ok_ = (value_[n].second != 0 && INT_MIN < value_[n].first && value_[n].first < INT_MAX );
3f58c5
+        ok_ = (value_[n].second != 0 && -LARGE_INT < value_[n].first && value_[n].first < LARGE_INT);
3f58c5
         if (!ok_) return 0;
3f58c5
         return value_[n].first / value_[n].second;
3f58c5
     }
3f58c5
@@ -1671,7 +1673,7 @@ namespace Exiv2 {
3f58c5
     template<>
3f58c5
     inline long ValueType<URational>::toLong(long n) const
3f58c5
     {
3f58c5
-        ok_ = (value_[n].second != 0);
3f58c5
+        ok_ = (value_[n].second != 0 && value_[n].first < LARGE_INT);
3f58c5
         if (!ok_) return 0;
3f58c5
         return value_[n].first / value_[n].second;
3f58c5
     }
3f58c5
diff --git a/src/basicio.cpp b/src/basicio.cpp
3f58c5
index 95589cd2..f2e1518b 100644
3f58c5
--- a/src/basicio.cpp
3f58c5
+++ b/src/basicio.cpp
3f58c5
@@ -990,6 +990,7 @@ namespace Exiv2 {
3f58c5
     DataBuf FileIo::read(long rcount)
3f58c5
     {
3f58c5
         assert(p_->fp_ != 0);
3f58c5
+        if ( (size_t) rcount > size() ) throw Error(57);
3f58c5
         DataBuf buf(rcount);
3f58c5
         long readCount = read(buf.pData_, buf.size_);
3f58c5
         buf.size_ = readCount;
3f58c5
diff --git a/src/error.cpp b/src/error.cpp
3f58c5
index 80378c19..e90a9c0a 100644
3f58c5
--- a/src/error.cpp
3f58c5
+++ b/src/error.cpp
3f58c5
@@ -106,6 +106,9 @@ namespace {
3f58c5
         { 52, N_("%1 has invalid XMP value type `%2'") }, // %1=key, %2=value type
3f58c5
         { 53, N_("Not a valid ICC Profile") },
3f58c5
         { 54, N_("Not valid XMP") },
3f58c5
+        { 55, N_("tiff directory length is too large") },
3f58c5
+        { 56, N_("invalid type value detected in Image::printIFDStructure") },
3f58c5
+        { 57, N_("invalid memory allocation request") },
3f58c5
     };
3f58c5
3f58c5
 }
3f58c5
diff --git a/src/image.cpp b/src/image.cpp
3f58c5
index 0d828045..ec5b873e 100644
3f58c5
--- a/src/image.cpp
3f58c5
+++ b/src/image.cpp
3f58c5
@@ -399,7 +399,13 @@ namespace Exiv2 {
3f58c5
                                 ;
3f58c5
3f58c5
                 // if ( offset > io.size() ) offset = 0; // Denial of service?
3f58c5
-                DataBuf  buf(size*count + pad+20);  // allocate a buffer
3f58c5
+
3f58c5
+                // #55 memory allocation crash test/data/POC8
3f58c5
+                long long allocate = (long long) (size*count + pad+20);
3f58c5
+                if ( allocate > (long long) io.size() ) {
3f58c5
+                    throw Error(57);
3f58c5
+                }
3f58c5
+                DataBuf  buf(allocate);  // allocate a buffer
3f58c5
                 std::memcpy(buf.pData_,dir.pData_+8,4);  // copy dir[8:11] into buffer (short strings)
3f58c5
                 if ( count*size > 4 ) {            // read into buffer
3f58c5
                     size_t   restore = io.tell();  // save