added patches for CVE-2017 17723, 17725, 5772
This commit is contained in:
parent
041ff8028b
commit
c884a03d1c
25
0006-1296-Fix-submitted.patch
Normal file
25
0006-1296-Fix-submitted.patch
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
From 2f8681e120d277e418941c4361c83b5028f67fd8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: clanmills <robin@clanmills.com>
|
||||||
|
Date: Sat, 27 May 2017 10:18:17 +0100
|
||||||
|
Subject: [PATCH 6/6] #1296 Fix submitted.
|
||||||
|
|
||||||
|
---
|
||||||
|
src/tiffcomposite.cpp | 2 ++
|
||||||
|
1 file changed, 2 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/src/tiffcomposite.cpp b/src/tiffcomposite.cpp
|
||||||
|
index c6b860d..0c9b9c4 100644
|
||||||
|
--- a/src/tiffcomposite.cpp
|
||||||
|
+++ b/src/tiffcomposite.cpp
|
||||||
|
@@ -1611,6 +1611,8 @@ namespace Exiv2 {
|
||||||
|
uint32_t TiffImageEntry::doWriteImage(IoWrapper& ioWrapper,
|
||||||
|
ByteOrder /*byteOrder*/) const
|
||||||
|
{
|
||||||
|
+ if ( !pValue() ) throw Error(21); // #1296
|
||||||
|
+
|
||||||
|
uint32_t len = pValue()->sizeDataArea();
|
||||||
|
if (len > 0) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
--
|
||||||
|
2.9.4
|
||||||
|
|
59
exiv2-CVE-2017-17723.patch
Normal file
59
exiv2-CVE-2017-17723.patch
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
diff --git a/include/exiv2/value.hpp b/include/exiv2/value.hpp
|
||||||
|
index 64a8ca7..4e9f285 100644
|
||||||
|
--- a/include/exiv2/value.hpp
|
||||||
|
+++ b/include/exiv2/value.hpp
|
||||||
|
@@ -1658,11 +1658,13 @@ 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;
|
||||||
|
}
|
||||||
|
@@ -1670,7 +1672,7 @@ namespace Exiv2 {
|
||||||
|
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 1ede931..eac756f 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/image.cpp b/src/image.cpp
|
||||||
|
index 31b9b81..eeb1f37 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 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
|
420
exiv2-CVE-2017-17725.patch
Normal file
420
exiv2-CVE-2017-17725.patch
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
diff --git a/src/actions.cpp b/src/actions.cpp
|
||||||
|
index 35c7965..cb905f6 100644
|
||||||
|
--- a/src/actions.cpp
|
||||||
|
+++ b/src/actions.cpp
|
||||||
|
@@ -59,6 +59,7 @@ EXIV2_RCSID("@(#) $Id: actions.cpp 4719 2017-03-08 20:42:28Z robinwmills $")
|
||||||
|
#include <ctime>
|
||||||
|
#include <cmath>
|
||||||
|
#include <cassert>
|
||||||
|
+#include <stdexcept>
|
||||||
|
#include <sys/types.h> // for stat()
|
||||||
|
#include <sys/stat.h> // for stat()
|
||||||
|
#ifdef EXV_HAVE_UNISTD_H
|
||||||
|
@@ -236,33 +237,43 @@ namespace Action {
|
||||||
|
}
|
||||||
|
|
||||||
|
int Print::run(const std::string& path)
|
||||||
|
- try {
|
||||||
|
- path_ = path;
|
||||||
|
- int rc = 0;
|
||||||
|
- Exiv2::PrintStructureOption option = Exiv2::kpsNone ;
|
||||||
|
- switch (Params::instance().printMode_) {
|
||||||
|
- case Params::pmSummary: rc = printSummary(); break;
|
||||||
|
- case Params::pmList: rc = printList(); break;
|
||||||
|
- case Params::pmComment: rc = printComment(); break;
|
||||||
|
- case Params::pmPreview: rc = printPreviewList(); break;
|
||||||
|
- case Params::pmStructure: rc = printStructure(std::cout,Exiv2::kpsBasic) ; break;
|
||||||
|
- case Params::pmRecursive: rc = printStructure(std::cout,Exiv2::kpsRecursive) ; break;
|
||||||
|
-
|
||||||
|
- case Params::pmXMP:
|
||||||
|
- option = option == Exiv2::kpsNone ? Exiv2::kpsXMP : option; // drop
|
||||||
|
- case Params::pmIccProfile:{
|
||||||
|
- option = option == Exiv2::kpsNone ? Exiv2::kpsIccProfile : option;
|
||||||
|
- _setmode(_fileno(stdout),O_BINARY);
|
||||||
|
- rc = printStructure(std::cout,option);
|
||||||
|
- } break;
|
||||||
|
+ {
|
||||||
|
+ try {
|
||||||
|
+ path_ = path;
|
||||||
|
+ int rc = 0;
|
||||||
|
+ Exiv2::PrintStructureOption option = Exiv2::kpsNone ;
|
||||||
|
+ switch (Params::instance().printMode_) {
|
||||||
|
+ case Params::pmSummary: rc = printSummary(); break;
|
||||||
|
+ case Params::pmList: rc = printList(); break;
|
||||||
|
+ case Params::pmComment: rc = printComment(); break;
|
||||||
|
+ case Params::pmPreview: rc = printPreviewList(); break;
|
||||||
|
+ case Params::pmStructure: rc = printStructure(std::cout,Exiv2::kpsBasic) ; break;
|
||||||
|
+ case Params::pmRecursive: rc = printStructure(std::cout,Exiv2::kpsRecursive) ; break;
|
||||||
|
+
|
||||||
|
+ case Params::pmXMP:
|
||||||
|
+ if (option == Exiv2::kpsNone)
|
||||||
|
+ option = Exiv2::kpsXMP;
|
||||||
|
+ // drop
|
||||||
|
+ case Params::pmIccProfile:
|
||||||
|
+ if (option == Exiv2::kpsNone)
|
||||||
|
+ option = Exiv2::kpsIccProfile;
|
||||||
|
+ _setmode(_fileno(stdout),O_BINARY);
|
||||||
|
+ rc = printStructure(std::cout,option);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ return rc;
|
||||||
|
+ }
|
||||||
|
+ catch(const Exiv2::AnyError& e) {
|
||||||
|
+ std::cerr << "Exiv2 exception in print action for file "
|
||||||
|
+ << path << ":\n" << e << "\n";
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
+ catch(const std::overflow_error& e) {
|
||||||
|
+ std::cerr << "std::overflow_error exception in print action for file "
|
||||||
|
+ << path << ":\n" << e.what() << "\n";
|
||||||
|
+ return 1;
|
||||||
|
}
|
||||||
|
- return rc;
|
||||||
|
}
|
||||||
|
- catch(const Exiv2::AnyError& e) {
|
||||||
|
- std::cerr << "Exiv2 exception in print action for file "
|
||||||
|
- << path << ":\n" << e << "\n";
|
||||||
|
- return 1;
|
||||||
|
- } // Print::run
|
||||||
|
|
||||||
|
int Print::printStructure(std::ostream& out, Exiv2::PrintStructureOption option)
|
||||||
|
{
|
||||||
|
diff --git a/src/jp2image.cpp b/src/jp2image.cpp
|
||||||
|
index ac31257..4c072d7 100644
|
||||||
|
--- a/src/jp2image.cpp
|
||||||
|
+++ b/src/jp2image.cpp
|
||||||
|
@@ -41,6 +41,7 @@ EXIV2_RCSID("@(#) $Id: jp2image.cpp 4759 2017-04-23 10:58:54Z robinwmills $")
|
||||||
|
#include "error.hpp"
|
||||||
|
#include "futils.hpp"
|
||||||
|
#include "types.hpp"
|
||||||
|
+#include "safe_op.hpp"
|
||||||
|
|
||||||
|
// + standard includes
|
||||||
|
#include <string>
|
||||||
|
@@ -269,8 +270,9 @@ namespace Exiv2
|
||||||
|
std::cout << "Exiv2::Jp2Image::readMetadata: "
|
||||||
|
<< "Color data found" << std::endl;
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
long pad = 3 ; // 3 padding bytes 2 0 0
|
||||||
|
- DataBuf data(subBox.length+8);
|
||||||
|
+ DataBuf data(Safe::add(subBox.length, static_cast<uint32_t>(8)));
|
||||||
|
io_->read(data.pData_,data.size_);
|
||||||
|
long iccLength = getULong(data.pData_+pad, bigEndian);
|
||||||
|
DataBuf icc(iccLength);
|
||||||
|
diff --git a/src/safe_op.hpp b/src/safe_op.hpp
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..014b7f3
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/src/safe_op.hpp
|
||||||
|
@@ -0,0 +1,310 @@
|
||||||
|
+// ********************************************************* -*- C++ -*-
|
||||||
|
+/*
|
||||||
|
+ * Copyright (C) 2004-2017 Exiv2 maintainers
|
||||||
|
+ *
|
||||||
|
+ * This program is part of the Exiv2 distribution.
|
||||||
|
+ *
|
||||||
|
+ * This program is free software; you can redistribute it and/or
|
||||||
|
+ * modify it under the terms of the GNU General Public License
|
||||||
|
+ * as published by the Free Software Foundation; either version 2
|
||||||
|
+ * of the License, or (at your option) any later version.
|
||||||
|
+ *
|
||||||
|
+ * This program is distributed in the hope that it will be useful,
|
||||||
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
+ * GNU General Public License for more details.
|
||||||
|
+ *
|
||||||
|
+ * You should have received a copy of the GNU General Public License
|
||||||
|
+ * along with this program; if not, write to the Free Software
|
||||||
|
+ * Foundation, Inc., 51 Franklin Street, 5th Floor, Boston, MA 02110-1301 USA.
|
||||||
|
+ */
|
||||||
|
+/*!
|
||||||
|
+ @file safe_op.hpp
|
||||||
|
+ @brief Overflow checks for integers
|
||||||
|
+ @author Dan Čermák (D4N)
|
||||||
|
+ <a href="mailto:dan.cermak@cgc-instruments.com">dan.cermak@cgc-instruments.com</a>
|
||||||
|
+ @date 14-Dec-17, D4N: created
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+#ifndef SAFE_OP_HPP_
|
||||||
|
+#define SAFE_OP_HPP_
|
||||||
|
+
|
||||||
|
+#include <limits>
|
||||||
|
+#include <stdexcept>
|
||||||
|
+
|
||||||
|
+#ifdef _MSC_VER
|
||||||
|
+#include <Intsafe.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ * @brief Arithmetic operations with overflow checks
|
||||||
|
+ */
|
||||||
|
+namespace Safe
|
||||||
|
+{
|
||||||
|
+ /*!
|
||||||
|
+ * @brief Helper structs for providing integer overflow checks.
|
||||||
|
+ *
|
||||||
|
+ * This namespace contains the internal helper structs fallback_add_overflow
|
||||||
|
+ * and builtin_add_overflow. Both have a public static member function add
|
||||||
|
+ * with the following interface:
|
||||||
|
+ *
|
||||||
|
+ * bool add(T summand_1, T summand_2, T& result)
|
||||||
|
+ *
|
||||||
|
+ * where T is the type over which the struct is templated.
|
||||||
|
+ *
|
||||||
|
+ * The function performs a check whether the addition summand_1 + summand_2
|
||||||
|
+ * can be performed without an overflow. If the operation would overflow,
|
||||||
|
+ * true is returned and the addition is not performed if it would result in
|
||||||
|
+ * undefined behavior. If no overflow occurs, the sum is saved in result and
|
||||||
|
+ * false is returned.
|
||||||
|
+ *
|
||||||
|
+ * fallback_add_overflow implements a portable but slower overflow check.
|
||||||
|
+ * builtin_add_overflow uses compiler builtins (when available) and should
|
||||||
|
+ * be considerably faster. As builtins are not available for all types,
|
||||||
|
+ * builtin_add_overflow falls back to fallback_add_overflow when no builtin
|
||||||
|
+ * is available.
|
||||||
|
+ */
|
||||||
|
+ namespace Internal
|
||||||
|
+ {
|
||||||
|
+ /*!
|
||||||
|
+ * @brief Helper struct to determine whether a type is signed or unsigned
|
||||||
|
+
|
||||||
|
+ * This struct is a backport of std::is_signed from C++11. It has a public
|
||||||
|
+ * enum with the property VALUE which is true when the type is signed or
|
||||||
|
+ * false if it is unsigned.
|
||||||
|
+ */
|
||||||
|
+ template <typename T>
|
||||||
|
+ struct is_signed
|
||||||
|
+ {
|
||||||
|
+ enum
|
||||||
|
+ {
|
||||||
|
+ VALUE = T(-1) < T(0)
|
||||||
|
+ };
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ /*!
|
||||||
|
+ * @brief Helper struct for SFINAE, from C++11
|
||||||
|
+
|
||||||
|
+ * This struct has a public typedef called type typedef'd to T if B is
|
||||||
|
+ * true. Otherwise there is no typedef.
|
||||||
|
+ */
|
||||||
|
+ template <bool B, class T = void>
|
||||||
|
+ struct enable_if
|
||||||
|
+ {
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ /*!
|
||||||
|
+ * @brief Specialization of enable_if for the case B == true
|
||||||
|
+ */
|
||||||
|
+ template <class T>
|
||||||
|
+ struct enable_if<true, T>
|
||||||
|
+ {
|
||||||
|
+ typedef T type;
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ /*!
|
||||||
|
+ * @brief Fallback overflow checker, specialized via SFINAE
|
||||||
|
+ *
|
||||||
|
+ * This struct implements a 'fallback' addition with an overflow check,
|
||||||
|
+ * i.e. it does not rely on compiler intrinsics. It is specialized via
|
||||||
|
+ * SFINAE for signed and unsigned integer types and provides a public
|
||||||
|
+ * static member function add.
|
||||||
|
+ */
|
||||||
|
+ template <typename T, typename = void>
|
||||||
|
+ struct fallback_add_overflow;
|
||||||
|
+
|
||||||
|
+ /*!
|
||||||
|
+ * @brief Overload of fallback_add_overflow for signed integers
|
||||||
|
+ */
|
||||||
|
+ template <typename T>
|
||||||
|
+ struct fallback_add_overflow<T, typename enable_if<is_signed<T>::VALUE>::type>
|
||||||
|
+ {
|
||||||
|
+ /*!
|
||||||
|
+ * @brief Adds the two summands only if no overflow occurs
|
||||||
|
+ *
|
||||||
|
+ * This function performs a check if summand_1 + summand_2 would
|
||||||
|
+ * overflow and returns true in that case. If no overflow occurs,
|
||||||
|
+ * the sum is saved in result and false is returned.
|
||||||
|
+ *
|
||||||
|
+ * @return true on overflow, false on no overflow
|
||||||
|
+ *
|
||||||
|
+ * The check for an overflow is performed before the addition to
|
||||||
|
+ * ensure that no undefined behavior occurs. The value in result is
|
||||||
|
+ * only valid when the function returns false.
|
||||||
|
+ *
|
||||||
|
+ * Further information:
|
||||||
|
+ * https://wiki.sei.cmu.edu/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow
|
||||||
|
+ */
|
||||||
|
+ static bool add(T summand_1, T summand_2, T& result)
|
||||||
|
+ {
|
||||||
|
+ if (((summand_2 >= 0) && (summand_1 > std::numeric_limits<T>::max() - summand_2)) ||
|
||||||
|
+ ((summand_2 < 0) && (summand_1 < std::numeric_limits<T>::min() - summand_2))) {
|
||||||
|
+ return true;
|
||||||
|
+ } else {
|
||||||
|
+ result = summand_1 + summand_2;
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ /*!
|
||||||
|
+ * @brief Overload of fallback_add_overflow for unsigned integers
|
||||||
|
+ */
|
||||||
|
+ template <typename T>
|
||||||
|
+ struct fallback_add_overflow<T, typename enable_if<!is_signed<T>::VALUE>::type>
|
||||||
|
+ {
|
||||||
|
+ /*!
|
||||||
|
+ * @brief Adds the two summands only if no overflow occurs
|
||||||
|
+ *
|
||||||
|
+ * This function performs a check if summand_1 + summand_2 would
|
||||||
|
+ * overflow and returns true in that case. If no overflow occurs,
|
||||||
|
+ * the sum is saved in result and false is returned.
|
||||||
|
+ *
|
||||||
|
+ * @return true on overflow, false on no overflow
|
||||||
|
+ *
|
||||||
|
+ * Further information:
|
||||||
|
+ * https://wiki.sei.cmu.edu/confluence/display/c/INT30-C.+Ensure+that+unsigned+integer+operations+do+not+wrap
|
||||||
|
+ */
|
||||||
|
+ static bool add(T summand_1, T summand_2, T& result)
|
||||||
|
+ {
|
||||||
|
+ if (summand_1 > std::numeric_limits<T>::max() - summand_2) {
|
||||||
|
+ return true;
|
||||||
|
+ } else {
|
||||||
|
+ result = summand_1 + summand_2;
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+ /*!
|
||||||
|
+ * @brief Overflow checker using compiler intrinsics
|
||||||
|
+ *
|
||||||
|
+ * This struct provides an add function with the same interface &
|
||||||
|
+ * behavior as fallback_add_overload::add but it relies on compiler
|
||||||
|
+ * intrinsics instead. This version should be considerably faster than
|
||||||
|
+ * the fallback version as it can fully utilize available CPU
|
||||||
|
+ * instructions & the compiler's diagnostic.
|
||||||
|
+ *
|
||||||
|
+ * However, as some compilers don't provide intrinsics for certain
|
||||||
|
+ * types, the default implementation of add is the version from falback.
|
||||||
|
+ *
|
||||||
|
+ * The struct is explicitly specialized for each type via #ifdefs for
|
||||||
|
+ * each compiler.
|
||||||
|
+ */
|
||||||
|
+ template <typename T>
|
||||||
|
+ struct builtin_add_overflow
|
||||||
|
+ {
|
||||||
|
+ /*!
|
||||||
|
+ * @brief Add summand_1 and summand_2 and check for overflows.
|
||||||
|
+ *
|
||||||
|
+ * This is the default add() function that uses
|
||||||
|
+ * fallback_add_overflow<T>::add(). All specializations must have
|
||||||
|
+ * exactly the same interface and behave the same way.
|
||||||
|
+ */
|
||||||
|
+ static inline bool add(T summand_1, T summand_2, T& result)
|
||||||
|
+ {
|
||||||
|
+ return fallback_add_overflow<T>::add(summand_1, summand_2, result);
|
||||||
|
+ }
|
||||||
|
+ };
|
||||||
|
+
|
||||||
|
+#if defined(__GNUC__) || defined(__clang__)
|
||||||
|
+#if __GNUC__ >= 5
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ * This macro pastes a specialization of builtin_add_overflow using gcc's &
|
||||||
|
+ * clang's __builtin_(s/u)add(l)(l)_overlow()
|
||||||
|
+ *
|
||||||
|
+ * The add function is implemented by forwarding the parameters to the intrinsic
|
||||||
|
+ * and returning its value.
|
||||||
|
+ *
|
||||||
|
+ * The intrinsics are documented here:
|
||||||
|
+ * https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html#Integer-Overflow-Builtins
|
||||||
|
+ */
|
||||||
|
+#define SPECIALIZE_builtin_add_overflow(type, builtin_name) \
|
||||||
|
+ template <> \
|
||||||
|
+ struct builtin_add_overflow<type> \
|
||||||
|
+ { \
|
||||||
|
+ static inline bool add(type summand_1, type summand_2, type& result) \
|
||||||
|
+ { \
|
||||||
|
+ return builtin_name(summand_1, summand_2, &result); \
|
||||||
|
+ } \
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ SPECIALIZE_builtin_add_overflow(int, __builtin_sadd_overflow);
|
||||||
|
+ SPECIALIZE_builtin_add_overflow(long, __builtin_saddl_overflow);
|
||||||
|
+ SPECIALIZE_builtin_add_overflow(long long, __builtin_saddll_overflow);
|
||||||
|
+
|
||||||
|
+ SPECIALIZE_builtin_add_overflow(unsigned int, __builtin_uadd_overflow);
|
||||||
|
+ SPECIALIZE_builtin_add_overflow(unsigned long, __builtin_uaddl_overflow);
|
||||||
|
+ SPECIALIZE_builtin_add_overflow(unsigned long long, __builtin_uaddll_overflow);
|
||||||
|
+
|
||||||
|
+#undef SPECIALIZE_builtin_add_overflow
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#elif defined(_MSC_VER)
|
||||||
|
+
|
||||||
|
+/*!
|
||||||
|
+ * This macro pastes a specialization of builtin_add_overflow using MSVC's
|
||||||
|
+ * U(Int/Long/LongLong)Add.
|
||||||
|
+ *
|
||||||
|
+ * The add function is implemented by forwarding the parameters to the
|
||||||
|
+ * intrinsic. As MSVC's intrinsics return S_OK on success, this specialization
|
||||||
|
+ * returns whether the intrinsics return value does not equal S_OK. This ensures
|
||||||
|
+ * a uniform interface of the add function (false is returned when no overflow
|
||||||
|
+ * occurs, true on overflow).
|
||||||
|
+ *
|
||||||
|
+ * The intrinsics are documented here:
|
||||||
|
+ * https://msdn.microsoft.com/en-us/library/windows/desktop/ff516460(v=vs.85).aspx
|
||||||
|
+ */
|
||||||
|
+#define SPECIALIZE_builtin_add_overflow_WIN(type, builtin_name) \
|
||||||
|
+ template <> \
|
||||||
|
+ struct builtin_add_overflow<type> \
|
||||||
|
+ { \
|
||||||
|
+ static inline bool add(type summand_1, type summand_2, type& result) \
|
||||||
|
+ { \
|
||||||
|
+ return builtin_name(summand_1, summand_2, &result) != S_OK; \
|
||||||
|
+ } \
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ SPECIALIZE_builtin_add_overflow_WIN(unsigned int, UIntAdd);
|
||||||
|
+ SPECIALIZE_builtin_add_overflow_WIN(unsigned long, ULongAdd);
|
||||||
|
+ SPECIALIZE_builtin_add_overflow_WIN(unsigned long long, ULongLongAdd);
|
||||||
|
+
|
||||||
|
+#undef SPECIALIZE_builtin_add_overflow_WIN
|
||||||
|
+
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ } // namespace Internal
|
||||||
|
+
|
||||||
|
+ /*!
|
||||||
|
+ * @brief Safe addition, throws an exception on overflow.
|
||||||
|
+ *
|
||||||
|
+ * This function returns the result of summand_1 and summand_2 only when the
|
||||||
|
+ * operation would not overflow, otherwise an exception of type
|
||||||
|
+ * std::overflow_error is thrown.
|
||||||
|
+ *
|
||||||
|
+ * @param[in] summand_1, summand_2 summands to be summed up
|
||||||
|
+ * @return the sum of summand_1 and summand_2
|
||||||
|
+ * @throws std::overflow_error if the addition would overflow
|
||||||
|
+ *
|
||||||
|
+ * This function utilizes compiler builtins when available and should have a
|
||||||
|
+ * very small performance hit then. When builtins are unavailable, a more
|
||||||
|
+ * extensive check is required.
|
||||||
|
+ *
|
||||||
|
+ * Builtins are available for the following configurations:
|
||||||
|
+ * - GCC/Clang for signed and unsigned int, long and long long (not char & short)
|
||||||
|
+ * - MSVC for unsigned int, long and long long
|
||||||
|
+ */
|
||||||
|
+ template <typename T>
|
||||||
|
+ T add(T summand_1, T summand_2)
|
||||||
|
+ {
|
||||||
|
+ T res = 0;
|
||||||
|
+ if (Internal::builtin_add_overflow<T>::add(summand_1, summand_2, res)) {
|
||||||
|
+ throw std::overflow_error("Overflow in addition");
|
||||||
|
+ }
|
||||||
|
+ return res;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+} // namespace Safe
|
||||||
|
+
|
||||||
|
+#endif // SAFE_OP_HPP_
|
85
exiv2-CVE-2017-5772.patch
Normal file
85
exiv2-CVE-2017-5772.patch
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
diff --git a/src/cr2image.cpp b/src/cr2image.cpp
|
||||||
|
index 516e170..8a752b0 100644
|
||||||
|
--- a/src/cr2image.cpp
|
||||||
|
+++ b/src/cr2image.cpp
|
||||||
|
@@ -107,8 +107,6 @@ namespace Exiv2 {
|
||||||
|
throw Error(3, "CR2");
|
||||||
|
}
|
||||||
|
clearMetadata();
|
||||||
|
- std::ofstream devnull;
|
||||||
|
- printStructure(devnull, kpsRecursive, 0);
|
||||||
|
ByteOrder bo = Cr2Parser::decode(exifData_,
|
||||||
|
iptcData_,
|
||||||
|
xmpData_,
|
||||||
|
diff --git a/src/crwimage.cpp b/src/crwimage.cpp
|
||||||
|
index 232919c..58240fd 100644
|
||||||
|
--- a/src/crwimage.cpp
|
||||||
|
+++ b/src/crwimage.cpp
|
||||||
|
@@ -131,15 +131,8 @@ namespace Exiv2 {
|
||||||
|
throw Error(33);
|
||||||
|
}
|
||||||
|
clearMetadata();
|
||||||
|
- // read all metadata into memory
|
||||||
|
- // we should put this into clearMetadata(), however it breaks the test suite!
|
||||||
|
- try {
|
||||||
|
- std::ofstream devnull;
|
||||||
|
- printStructure(devnull,kpsRecursive,0);
|
||||||
|
- } catch (Exiv2::Error& /* e */) {
|
||||||
|
- DataBuf file(io().size());
|
||||||
|
- io_->read(file.pData_,file.size_);
|
||||||
|
- }
|
||||||
|
+ DataBuf file( (long) io().size());
|
||||||
|
+ io_->read(file.pData_,file.size_);
|
||||||
|
|
||||||
|
CrwParser::decode(this, io_->mmap(), io_->size());
|
||||||
|
|
||||||
|
diff --git a/src/orfimage.cpp b/src/orfimage.cpp
|
||||||
|
index 25651bd..9bd7a02 100644
|
||||||
|
--- a/src/orfimage.cpp
|
||||||
|
+++ b/src/orfimage.cpp
|
||||||
|
@@ -119,8 +119,6 @@ namespace Exiv2 {
|
||||||
|
throw Error(3, "ORF");
|
||||||
|
}
|
||||||
|
clearMetadata();
|
||||||
|
- std::ofstream devnull;
|
||||||
|
- printStructure(devnull, kpsRecursive, 0);
|
||||||
|
ByteOrder bo = OrfParser::decode(exifData_,
|
||||||
|
iptcData_,
|
||||||
|
xmpData_,
|
||||||
|
diff --git a/src/rw2image.cpp b/src/rw2image.cpp
|
||||||
|
index 07de437..5922602 100644
|
||||||
|
--- a/src/rw2image.cpp
|
||||||
|
+++ b/src/rw2image.cpp
|
||||||
|
@@ -130,8 +130,6 @@ namespace Exiv2 {
|
||||||
|
throw Error(3, "RW2");
|
||||||
|
}
|
||||||
|
clearMetadata();
|
||||||
|
- std::ofstream devnull;
|
||||||
|
- printStructure(devnull, kpsRecursive, 0);
|
||||||
|
ByteOrder bo = Rw2Parser::decode(exifData_,
|
||||||
|
iptcData_,
|
||||||
|
xmpData_,
|
||||||
|
diff --git a/src/tiffimage.cpp b/src/tiffimage.cpp
|
||||||
|
index de66068..98da12b 100644
|
||||||
|
--- a/src/tiffimage.cpp
|
||||||
|
+++ b/src/tiffimage.cpp
|
||||||
|
@@ -185,10 +185,6 @@ namespace Exiv2 {
|
||||||
|
}
|
||||||
|
clearMetadata();
|
||||||
|
|
||||||
|
- // recursively print the structure to /dev/null to ensure all metadata is in memory
|
||||||
|
- // must be recursive to handle NEFs which stores the raw image in a subIFDs
|
||||||
|
- std::ofstream devnull;
|
||||||
|
- printStructure(devnull,kpsRecursive,0);
|
||||||
|
ByteOrder bo = TiffParser::decode(exifData_,
|
||||||
|
iptcData_,
|
||||||
|
xmpData_,
|
||||||
|
@@ -200,7 +196,7 @@ namespace Exiv2 {
|
||||||
|
Exiv2::ExifKey key("Exif.Image.InterColorProfile");
|
||||||
|
Exiv2::ExifData::iterator pos = exifData_.findKey(key);
|
||||||
|
if ( pos != exifData_.end() ) {
|
||||||
|
- iccProfile_.alloc(pos->count());
|
||||||
|
+ iccProfile_.alloc(pos->count()*pos->typeSize());
|
||||||
|
pos->copy(iccProfile_.pData_,bo);
|
||||||
|
}
|
||||||
|
|
10
exiv2.spec
10
exiv2.spec
@ -6,7 +6,7 @@
|
|||||||
Summary: Exif and Iptc metadata manipulation library
|
Summary: Exif and Iptc metadata manipulation library
|
||||||
Name: exiv2
|
Name: exiv2
|
||||||
Version: 0.26
|
Version: 0.26
|
||||||
Release: 9%{?dist}
|
Release: 10%{?dist}
|
||||||
|
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
URL: http://www.exiv2.org/
|
URL: http://www.exiv2.org/
|
||||||
@ -15,6 +15,10 @@ Source0: http://www.exiv2.org/builds/exiv2-%{version}-trunk.tar.gz
|
|||||||
## upstream patches (lookaside cache)
|
## upstream patches (lookaside cache)
|
||||||
Patch6: 0006-1296-Fix-submitted.patch
|
Patch6: 0006-1296-Fix-submitted.patch
|
||||||
|
|
||||||
|
Patch10: exiv2-CVE-2017-17723.patch
|
||||||
|
Patch11: exiv2-CVE-2017-17725.patch
|
||||||
|
Patch12: exiv2-CVE-2017-5772.patch
|
||||||
|
|
||||||
## upstreamable patches
|
## upstreamable patches
|
||||||
Patch100: exiv2-doxygen.patch
|
Patch100: exiv2-doxygen.patch
|
||||||
|
|
||||||
@ -154,6 +158,10 @@ test -x %{buildroot}%{_libdir}/libexiv2.so
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Thu May 03 2018 Germano Massullo <germano.massullo@gmail.com> - 0.26-10
|
||||||
|
- added patches that fix CVE-2017-17723 CVE-2017-17725 CVE-2017-5772
|
||||||
|
- moved 0006-1296-Fix-submitted.patch file from sources to package tree
|
||||||
|
|
||||||
* Tue Feb 20 2018 Rex Dieter <rdieter@fedoraproject.org> - 0.26-9
|
* Tue Feb 20 2018 Rex Dieter <rdieter@fedoraproject.org> - 0.26-9
|
||||||
- BR: gcc-c++
|
- BR: gcc-c++
|
||||||
|
|
||||||
|
1
sources
1
sources
@ -1,2 +1 @@
|
|||||||
SHA512 (exiv2-0.26-trunk.tar.gz) = 0caab1aeaab171201c1d19d21b8484a91d076e78c93c4a5fbb7e21510cc0eaff81b04f45434207d857ba0de5bd6e368743a1cc571d78a27b44e157f6b031f481
|
SHA512 (exiv2-0.26-trunk.tar.gz) = 0caab1aeaab171201c1d19d21b8484a91d076e78c93c4a5fbb7e21510cc0eaff81b04f45434207d857ba0de5bd6e368743a1cc571d78a27b44e157f6b031f481
|
||||||
SHA512 (0006-1296-Fix-submitted.patch) = 3f9242dbd4bfa9dcdf8c9820243b13dc14990373a800c4ebb6cf7eac5653cfefe6f2c47a94fbee4ed24f0d8c2842729d721f6100a2b215e0f663c89bfefe9e32
|
|
||||||
|
Loading…
Reference in New Issue
Block a user