Sophie

Sophie

distrib > Mageia > 6 > armv7hl > media > core-updates-src > by-pkgid > 253a1c8fd5fcfd81e33bbaa6330f699e > files > 3

exiv2-0.26-2.2.mga6.src.rpm

https://github.com/Exiv2/exiv2/pull/120
https://github.com/Exiv2/exiv2/commit/2d957cc2be6e6e9e5548baacf1ee12b0ac81cc43
For completeness sake, the following issues were fixed:
CVE-2017-14864, CVE-2017-14862 and CVE-2017-14859
CVE-2017-14860
CVE-2017-11337, CVE-2017-11338, CVE-2017-11339, CVE-2017-11340
CVE-2017-11553, CVE-2017-12955, CVE-2017-12956, CVE-2017-12957
CVE-2017-11683
CVE-2017-11592
CVE-2017-11591
https://github.com/Exiv2/exiv2/pull/79
https://github.com/D4N/exiv2/commit/6cf8d085a7ac67cd5b021dfff36795f50e249eb2
CVE-2017-11336
https://github.com/Exiv2/exiv2/issues/124
https://github.com/Exiv2/exiv2/issues/76
CVE-2017-14857
diff --git a/include/exiv2/value.hpp b/include/exiv2/value.hpp
index 64a8ca7f..b61c0f44 100644
--- a/include/exiv2/value.hpp
+++ b/include/exiv2/value.hpp
@@ -44,6 +44,7 @@
 #include <sstream>
 #include <memory>
 #include <cstring>
+#include <climits>
 
 // *****************************************************************************
 // namespace extensions
@@ -1658,19 +1659,21 @@ namespace Exiv2 {
         ok_ = true;
         return static_cast<long>(value_[n]);
     }
+// #55 crash when value_[n].first == LONG_MIN
+#define LARGE_INT 1000000
     // Specialization for rational
     template<>
     inline long ValueType<Rational>::toLong(long n) const
     {
-        ok_ = (value_[n].second != 0);
+        ok_ = (value_[n].second != 0 && -LARGE_INT < value_[n].first && value_[n].first < LARGE_INT);
         if (!ok_) return 0;
         return value_[n].first / value_[n].second;
     }
     // Specialization for unsigned rational
     template<>
     inline long ValueType<URational>::toLong(long n) const
     {
-        ok_ = (value_[n].second != 0);
+        ok_ = (value_[n].second != 0 && value_[n].first < LARGE_INT);
         if (!ok_) return 0;
         return value_[n].first / value_[n].second;
     }
diff --git a/src/basicio.cpp b/src/basicio.cpp
index 95589cd2..f2e1518b 100644
--- a/src/basicio.cpp
+++ b/src/basicio.cpp
@@ -990,6 +990,7 @@ namespace Exiv2 {
     DataBuf FileIo::read(long rcount)
     {
         assert(p_->fp_ != 0);
+        if ( (size_t) rcount > size() ) throw Error(57);
         DataBuf buf(rcount);
         long readCount = read(buf.pData_, buf.size_);
         buf.size_ = readCount;
diff --git a/src/error.cpp b/src/error.cpp
index 80378c19..e90a9c0a 100644
--- a/src/error.cpp
+++ b/src/error.cpp
@@ -106,6 +106,11 @@ namespace {
         { 52, N_("%1 has invalid XMP value type `%2'") }, // %1=key, %2=value type
         { 53, N_("Not a valid ICC Profile") },
         { 54, N_("Not valid XMP") },
+        { 55, N_("tiff directory length is too large") },
+        { 56, N_("invalid type value detected in Image::printIFDStructure") },
+        { 57, N_("invalid memory allocation request") },
+        { 58, N_("corrupted image metadata") },
+        { 59, N_("Arithmetic operation overflow") },
     };
 
 }
diff --git a/src/image.cpp b/src/image.cpp
index 0d828045..ec5b873e 100644
--- a/src/image.cpp
+++ b/src/image.cpp
@@ -399,7 +399,13 @@ namespace Exiv2 {
                                 ;
 
                 // if ( offset > io.size() ) offset = 0; // Denial of service?
-                DataBuf  buf(size*count + pad+20);  // allocate a buffer
+
+                // #55 and #56 memory allocation crash test/data/POC8
+                long long allocate = (long long) size*count + pad+20;
+                if ( allocate > (long long) io.size() ) {
+                    throw Error(57);
+                }
+                DataBuf  buf(allocate);  // allocate a buffer
                 std::memcpy(buf.pData_,dir.pData_+8,4);  // copy dir[8:11] into buffer (short strings)
                 if ( count*size > 4 ) {            // read into buffer
                     size_t   restore = io.tell();  // save
diff --git a/src/jp2image.cpp b/src/jp2image.cpp
index 1892fd43..09d023e2 100644
--- a/src/jp2image.cpp
@@ -269,10 +269,15 @@ namespace Exiv2
                             std::cout << "Exiv2::Jp2Image::readMetadata: "
                                      << "Color data found" << std::endl;
 #endif
-                            long pad = 3 ; // 3 padding bytes 2 0 0
+                            const long pad = 3 ; // 3 padding bytes 2 0 0
                             DataBuf data(subBox.length+8);
                             io_->read(data.pData_,data.size_);
-                            long    iccLength = getULong(data.pData_+pad, bigEndian);
+                            const long    iccLength = getULong(data.pData_+pad, bigEndian);
+                            // subtracting pad from data.size_ is safe:
+                            // size_ is at least 8 and pad = 3
+                            if (iccLength > data.size_ - pad) {
+                                throw Error(58);
+			    }
                             DataBuf icc(iccLength);
                             ::memcpy(icc.pData_,data.pData_+pad,icc.size_);
 #ifdef DEBUG
diff --git a/src/tiffvisitor.cpp b/src/tiffvisitor.cpp
index 74f8d078..4ab733d4 100644
--- a/src/tiffvisitor.cpp
+++ b/src/tiffvisitor.cpp
@@ -47,6 +47,7 @@ EXIV2_RCSID("@(#) $Id$")
 #include <iostream>
 #include <iomanip>
 #include <cassert>
+#include <limits>
 
 // *****************************************************************************
 namespace {
@@ -1294,11 +1295,12 @@ namespace Exiv2 {
             }
             uint16_t tag = getUShort(p, byteOrder());
             TiffComponent::AutoPtr tc = TiffCreator::create(tag, object->group());
-            // The assertion typically fails if a component is not configured in
-            // the TIFF structure table
-            assert(tc.get());
-            tc->setStart(p);
-            object->addChild(tc);
+            if (tc.get()) {
+                tc->setStart(p);
+                object->addChild(tc);
+            } else {
+               EXV_WARNING << "Unable to handle tag " << tag << ".\n";
+            }
             p += 12;
         }
 
@@ -1493,6 +1495,10 @@ namespace Exiv2 {
         }
         p += 4;
         uint32_t isize= 0; // size of Exif.Sony1.PreviewImage
+
+        if (count > std::numeric_limits<uint32_t>::max() / typeSize) {
+            throw Error(59);
+        }
         uint32_t size = typeSize * count;
         uint32_t offset = getLong(p, byteOrder());
         byte* pData = p;
@@ -1516,7 +1522,19 @@ namespace Exiv2 {
                 size = 0;
         }
         if (size > 4) {
+            // setting pData to pData_ + baseOffset() + offset can result in pData pointing to invalid memory,
+            // as offset can be arbitrarily large
+            if ((static_cast<uintptr_t>(baseOffset()) > std::numeric_limits<uintptr_t>::max() - static_cast<uintptr_t>(offset))
+             || (static_cast<uintptr_t>(baseOffset() + offset) > std::numeric_limits<uintptr_t>::max() - reinterpret_cast<uintptr_t>(pData_)))
+            {
+                throw Error(59);
+            }
+            if (pData_ + static_cast<uintptr_t>(baseOffset()) + static_cast<uintptr_t>(offset) > pLast_) {
+                throw Error(58);
+            }
             pData = const_cast<byte*>(pData_) + baseOffset() + offset;
+
+	    // check for size being invalid
             if (size > static_cast<uint32_t>(pLast_ - pData)) {
 #ifndef SUPPRESS_WARNINGS
                 EXV_ERROR << "Upper boundary of data for "
@@ -1536,7 +1554,9 @@ namespace Exiv2 {
             }
         }
         Value::AutoPtr v = Value::create(typeId);
-        assert(v.get());
+        if (!v.get()) {
+            throw Error(58);
+        }
         if ( !isize ) {
         	v->read(pData, size, byteOrder());
         } else {
diff --git a/test/bugfixes-test.sh b/test/bugfixes-test.sh
index f91c6759..c90ae559 100755
--- a/test/bugfixes-test.sh
+++ b/test/bugfixes-test.sh
@@ -602,6 +602,7 @@ source ./functions.source
     runTest exiv2 -pX                   $filename | xmllint --format -
 
     num=1231
+    printf "$num " >&3
     for X in a b; do
       filename=exiv2-bug$num$X.jpg
       echo '------>' Bug $filename '<-------' >&2
@@ -622,13 +623,119 @@ source ./functions.source
     runTest exiv2 -pa                   $filename
 
     num=1252
+    printf "$num " >&3
     for X in a b; do
       filename=exiv2-bug$num$X.exv
       echo '------>' Bug $filename '<-------' >&2
       copyTestFile                      $filename
       runTest exiv2 -pa --grep lens/i   $filename
     done
 
+    num=g55
+    printf "$num " >&3
+    filename=POC8
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename 2>/dev/null
+
+    num=g57
+    printf "$num " >&3
+    filename=POC
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g79
+    printf "$num " >&3
+    filename=POC2
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g52
+    printf "$num " >&3
+    filename=POC5
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g51
+    printf "$num " >&3
+    filename=POC4
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g50
+    printf "$num " >&3
+    filename=POC3
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g53
+    printf "$num " >&3
+    filename=POC6
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g54
+    printf "$num " >&3
+    filename=POC9
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g58
+    printf "$num " >&3
+    filename=POC11
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g59
+    printf "$num " >&3
+    filename=POC12
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g60
+    printf "$num " >&3
+    filename=POC13
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g71
+    printf "$num " >&3
+    filename=003-heap-buffer-over
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g73
+    printf "$num " >&3
+    filename=02-Invalid-mem-def
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g74
+    printf "$num " >&3
+    filename=005-invalid-mem
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
+    num=g75
+    printf "$num " >&3
+    filename=008-invalid-mem
+    echo '------>' Bug $filename '<-------' >&2
+    copyTestFile                      $filename
+    runTest exiv2                     $filename
+
 ) 3>&1 > $results 2>&1
 
 printf "\n"