From f8df7c48c66c20b663f9adb2d1b8b32e73757d1e Mon Sep 17 00:00:00 2001 From: dogsheng <960055655@qq.com> Date: Wed, 25 Dec 2019 15:45:26 +0800 Subject: [PATCH] Package init --- 0001-CVE-2018-19535.patch | 37 +++++ 0001-CVE-2019-13112.patch | 80 +++++++++++ 0002-CVE-2018-19535.patch | 86 ++++++++++++ 0002-CVE-2019-13112.patch | 23 +++ 0003-CVE-2018-19535.patch | 113 +++++++++++++++ CVE-2018-16336.patch | 146 ++++++++++++++++++++ CVE-2018-17581.patch | 41 ++++++ CVE-2018-4868.patch | 72 ++++++++++ CVE-2019-13110-Avoid-integer-overflow.patch | 61 ++++++++ exiv2-CVE-2017-14865.patch | 61 ++++++++ exiv2-CVE-2017-18005_1.patch | 25 ++++ exiv2-CVE-2017-18005_2.patch | 27 ++++ exiv2.spec | 24 +++- 13 files changed, 793 insertions(+), 3 deletions(-) create mode 100644 0001-CVE-2018-19535.patch create mode 100644 0001-CVE-2019-13112.patch create mode 100644 0002-CVE-2018-19535.patch create mode 100644 0002-CVE-2019-13112.patch create mode 100644 0003-CVE-2018-19535.patch create mode 100644 CVE-2018-16336.patch create mode 100644 CVE-2018-17581.patch create mode 100644 CVE-2018-4868.patch create mode 100644 CVE-2019-13110-Avoid-integer-overflow.patch create mode 100644 exiv2-CVE-2017-14865.patch create mode 100644 exiv2-CVE-2017-18005_1.patch create mode 100644 exiv2-CVE-2017-18005_2.patch diff --git a/0001-CVE-2018-19535.patch b/0001-CVE-2018-19535.patch new file mode 100644 index 0000000..96a739d --- /dev/null +++ b/0001-CVE-2018-19535.patch @@ -0,0 +1,37 @@ +From 03173751b4d7053d6ddf52a15904e8f751f78f56 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= +Date: Sun, 2 Sep 2018 14:39:52 +0200 +Subject: [PATCH] Fix bug in PngChunk::readRawProfile + +- Now it takes into account text.size_ when searching for a newline +char. +--- + src/pngchunk_int.cpp | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/pngchunk.cpp b/src/pngchunk.cpp +index 58281b3ff..755872c94 100644 +--- a/src/pngchunk.cpp ++++ b/src/pngchunk.cpp +@@ -629,11 +629,19 @@ namespace Exiv2 { + + + sp = (char*)text.pData_+1; ++ int pointerPos = 1; + + // Look for newline +- +- while (*sp != '\n') ++ while (*sp != '\n' && pointerPos < (text.size_ - 1)) ++ { + sp++; ++ pointerPos++; ++ } ++ ++ if (pointerPos == (text.size_ - 1)) ++ { ++ return DataBuf(); ++ } + + // Look for length + diff --git a/0001-CVE-2019-13112.patch b/0001-CVE-2019-13112.patch new file mode 100644 index 0000000..ec25a51 --- /dev/null +++ b/0001-CVE-2019-13112.patch @@ -0,0 +1,80 @@ +From b0410707780daff1126a460cb294c144e36e408e Mon Sep 17 00:00:00 2001 +From: Kevin Backhouse +Date: Mon, 13 May 2019 14:57:09 +0100 +Subject: [PATCH] Add bounds check on allocation size. + +--- + src/pngchunk.cpp | 20 +++++++++++++++++--- + 1 files changed, 17 insertions(+), 3 deletions(-) + +diff --git a/src/pngchunk.cpp b/src/pngchunk.cpp +index bf389ee13..64a370e5f 100644 +--- a/src/pngchunk.cpp ++++ b/src/pngchunk.cpp +@@ -625,8 +625,12 @@ namespace Exiv2 { + const char *sp = (char*) text.pData_+1; // current byte (space pointer) + const char *eot = (char*) text.pData_+text.size_; // end of text + ++ if (sp >= eot) { ++ return DataBuf(); ++ } ++ + // Look for newline +- while (*sp != '\n' && sp < eot ) ++ while (*sp != '\n') + { + sp++; + if ( sp == eot ) +@@ -635,9 +639,12 @@ namespace Exiv2 { + } + } + sp++ ; // step over '\n' ++ if (sp == eot) { ++ return DataBuf(); ++ } + + // Look for length +- while ( (*sp == '\0' || *sp == ' ' || *sp == '\n') && sp < eot ) ++ while (*sp == '\0' || *sp == ' ' || *sp == '\n') + { + sp++; + if (sp == eot ) +@@ -647,7 +654,7 @@ namespace Exiv2 { + } + + const char* startOfLength = sp; +- while ( ('0' <= *sp && *sp <= '9') && sp < eot) ++ while ('0' <= *sp && *sp <= '9') + { + sp++; + if (sp == eot ) +@@ -656,8 +663,13 @@ namespace Exiv2 { + } + } + sp++ ; // step over '\n' ++ if (sp == eot) { ++ return DataBuf(); ++ } + + long length = (long) atol(startOfLength); ++ enforce(length >= 0, Exiv2::kerCorruptedMetadata); ++ enforce(length <= (eot - sp)/2, Exiv2::kerCorruptedMetadata); + + // Allocate space + if (length == 0) +@@ -682,6 +694,7 @@ namespace Exiv2 { + + for (long i = 0; i < (long) nibbles; i++) + { ++ enforce(sp < eot, Exiv2::kerCorruptedMetadata); + while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f') + { + if (*sp == '\0') +@@ -693,6 +706,7 @@ namespace Exiv2 { + } + + sp++; ++ enforce(sp < eot, Exiv2::kerCorruptedMetadata); + } + + if (i%2 == 0) diff --git a/0002-CVE-2018-19535.patch b/0002-CVE-2018-19535.patch new file mode 100644 index 0000000..a39fc9a --- /dev/null +++ b/0002-CVE-2018-19535.patch @@ -0,0 +1,86 @@ +From cf3ba049a2792ec2a4a877e343f5dd9654da53dc Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= +Date: Mon, 3 Sep 2018 08:51:08 +0200 +Subject: [PATCH] Fix more issues in PngChunk::readRawProfile + +--- + src/pngchunk.cpp | 36 +++++++++++++----------- + 1 files changed, 20 insertions(+), 16 deletions(-) + +diff --git a/src/pngchunk.cpp b/src/pngchunk.cpp +index 755872c94..9b3faf1aa 100644 +--- a/src/pngchunk.cpp ++++ b/src/pngchunk.cpp +@@ -606,11 +606,6 @@ namespace Exiv2 { + DataBuf PngChunk::readRawProfile(const DataBuf& text,bool iTXt) + { + DataBuf info; +- register long i; +- register unsigned char *dp; +- const char *sp; +- unsigned int nibbles; +- long length; + unsigned char unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, + 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0, +@@ -627,8 +622,7 @@ namespace Exiv2 { + return info; + } + +- +- sp = (char*)text.pData_+1; ++ const char *sp = (char*)text.pData_+1; + int pointerPos = 1; + + // Look for newline +@@ -638,20 +632,30 @@ namespace Exiv2 { + pointerPos++; + } + ++ // Look for length ++ while ((*sp == '\0' || *sp == ' ' || *sp == '\n') && pointerPos < (text.size_ - 1)) ++ { ++ sp++; ++ pointerPos++; ++ } ++ + if (pointerPos == (text.size_ - 1)) + { + return DataBuf(); + } + +- // Look for length ++ long length = (long) atol(sp); + +- while (*sp == '\0' || *sp == ' ' || *sp == '\n') ++ while (*sp != ' ' && *sp != '\n' && pointerPos < (text.size_ - 1)) ++ { + sp++; ++ pointerPos++; ++ } + +- length = (long) atol(sp); +- +- while (*sp != ' ' && *sp != '\n') +- sp++; ++ if (pointerPos == (text.size_ - 1)) ++ { ++ return DataBuf(); ++ } + + // Allocate space + +@@ -674,10 +678,10 @@ namespace Exiv2 { + + // Copy profile, skipping white space and column 1 "=" signs + +- dp = (unsigned char*)info.pData_; +- nibbles = length * 2; ++ unsigned char *dp = (unsigned char*)info.pData_; ++ unsigned int nibbles = length * 2; + +- for (i = 0; i < (long) nibbles; i++) ++ for (long i = 0; i < (long) nibbles; i++) + { + while (*sp < '0' || (*sp > '9' && *sp < 'a') || *sp > 'f') + { diff --git a/0002-CVE-2019-13112.patch b/0002-CVE-2019-13112.patch new file mode 100644 index 0000000..a48b740 --- /dev/null +++ b/0002-CVE-2019-13112.patch @@ -0,0 +1,23 @@ +From bcaca801fb0a3a594b35ab06044d1e8055ec04a7 Mon Sep 17 00:00:00 2001 +From: Kevin Backhouse +Date: Tue, 14 May 2019 09:58:42 +0100 +Subject: [PATCH] Merge two enforces into one. + +--- + src/pngchunk.cpp | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/pngchunk.cpp b/src/pngchunk.cpp +index 64a370e5f..714b95b48 100644 +--- a/src/pngchunk.cpp ++++ b/src/pngchunk.cpp +@@ -668,8 +668,7 @@ namespace Exiv2 { + } + + long length = (long) atol(startOfLength); +- enforce(length >= 0, Exiv2::kerCorruptedMetadata); +- enforce(length <= (eot - sp)/2, Exiv2::kerCorruptedMetadata); ++ enforce(0 <= length && length <= (eot - sp)/2, Exiv2::kerCorruptedMetadata); + + // Allocate space + if (length == 0) diff --git a/0003-CVE-2018-19535.patch b/0003-CVE-2018-19535.patch new file mode 100644 index 0000000..8004af9 --- /dev/null +++ b/0003-CVE-2018-19535.patch @@ -0,0 +1,113 @@ +From 8b480bc5b2cc2abb8cf6fe4e16c24e58916464d2 Mon Sep 17 00:00:00 2001 +From: Robin Mills +Date: Mon, 10 Sep 2018 20:54:53 +0200 +Subject: [PATCH] Fixes in PngChunk::readRawProfile + +--- + src/pngchunk.cpp | 55 ++++++++++++++++++++++---------------------- + 1 file changed, 27 insertions(+), 28 deletions(-) + +diff --git a/src/pngchunk.cpp b/src/pngchunk.cpp +index 9b3faf1aa..f81b560aa 100644 +--- a/src/pngchunk.cpp ++++ b/src/pngchunk.cpp +@@ -607,11 +607,11 @@ namespace Exiv2 { + { + DataBuf info; + unsigned char unhex[103]={0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, +- 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, +- 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0, +- 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, +- 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12, +- 13,14,15}; ++ 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, ++ 0,0,0,0,0,0,0,0,0,1, 2,3,4,5,6,7,8,9,0,0, ++ 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0, ++ 0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,10,11,12, ++ 13,14,15}; + if (text.size_ == 0) { + return DataBuf(); + } +@@ -622,52 +622,51 @@ namespace Exiv2 { + return info; + } + +- const char *sp = (char*)text.pData_+1; +- int pointerPos = 1; ++ const char *sp = (char*) text.pData_+1; // current byte (space pointer) ++ const char *eot = (char*) text.pData_+text.size_; // end of text + + // Look for newline +- while (*sp != '\n' && pointerPos < (text.size_ - 1)) ++ while (*sp != '\n' && sp < eot ) + { + sp++; +- pointerPos++; ++ if ( sp == eot ) ++ { ++ return DataBuf(); ++ } + } ++ sp++ ; // step over '\n' + + // Look for length +- while ((*sp == '\0' || *sp == ' ' || *sp == '\n') && pointerPos < (text.size_ - 1)) ++ while ( (*sp == '\0' || *sp == ' ' || *sp == '\n') && sp < eot ) + { + sp++; +- pointerPos++; +- } +- +- if (pointerPos == (text.size_ - 1)) +- { +- return DataBuf(); ++ if (sp == eot ) ++ { ++ return DataBuf(); ++ } + } + +- long length = (long) atol(sp); +- +- while (*sp != ' ' && *sp != '\n' && pointerPos < (text.size_ - 1)) ++ const char* startOfLength = sp; ++ while ( ('0' <= *sp && *sp <= '9') && sp < eot) + { + sp++; +- pointerPos++; ++ if (sp == eot ) ++ { ++ return DataBuf(); ++ } + } ++ sp++ ; // step over '\n' + +- if (pointerPos == (text.size_ - 1)) +- { +- return DataBuf(); +- } ++ long length = (long) atol(startOfLength); + + // Allocate space +- + if (length == 0) + { + #ifdef DEBUG + std::cerr << "Exiv2::PngChunk::readRawProfile: Unable To Copy Raw Profile: invalid profile length\n"; + #endif + } +- + info.alloc(length); +- + if (info.size_ != length) + { + #ifdef DEBUG +@@ -678,7 +677,7 @@ namespace Exiv2 { + + // Copy profile, skipping white space and column 1 "=" signs + +- unsigned char *dp = (unsigned char*)info.pData_; ++ unsigned char *dp = (unsigned char*)info.pData_; // decode pointer + unsigned int nibbles = length * 2; + + for (long i = 0; i < (long) nibbles; i++) diff --git a/CVE-2018-16336.patch b/CVE-2018-16336.patch new file mode 100644 index 0000000..17cfcfa --- /dev/null +++ b/CVE-2018-16336.patch @@ -0,0 +1,146 @@ +From 35b3e596edacd2437c2c5d3dd2b5c9502626163d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= +Date: Fri, 17 Aug 2018 16:41:05 +0200 +Subject: [PATCH] Add overflow & overread checks to PngChunk::parseTXTChunk() + +This function was creating a lot of new pointers and strings without +properly checking the array bounds. This commit adds several calls +to enforce(), making sure that the pointers stay within bounds. +Strings are now created using the helper function +string_from_unterminated() to prevent overreads in the constructor of +std::string. + +This fixes #400 +--- + src/pngchunk_int.cpp | 63 ++++++++++++++++++++++++++------------------ + 1 file changed, 37 insertions(+), 26 deletions(-) + +diff --git a/src/pngchunk.cpp b/src/pngchunk.cpp +index e087e47cb..f13594bd8 100644 +--- a/src/pngchunk.cpp ++++ b/src/pngchunk.cpp +@@ -34,6 +34,7 @@ + #include "image.hpp" + #include "error.hpp" + #include "enforce.hpp" ++#include "safe_op.hpp" + + // + standard includes + #include +@@ -55,6 +54,13 @@ EXIV2_RCSID("@(#) $Id: pngchunk.cpp 3777 2015-05-02 11:55:40Z ahuggel $") + + #include // To uncompress or compress text chunk + ++/* Added as support of CVE-2018-16336 */ ++std::string string_from_unterminated(const char* data, size_t data_length) ++{ ++ const size_t StringLength = strnlen(data, data_length); ++ ++ return std::string(data, StringLength); ++} + /* + + URLs to find informations about PNG chunks : +@@ -133,6 +135,8 @@ namespace Exiv2 { + + if(type == zTXt_Chunk) + { ++ enforce(data.size_ >= Safe::add(keysize, 2), Exiv2::kerCorruptedMetadata); ++ + // Extract a deflate compressed Latin-1 text chunk + + // we get the compression method after the key +@@ -149,11 +153,13 @@ namespace Exiv2 { + // compressed string after the compression technique spec + const byte* compressedText = data.pData_ + keysize + 2; + unsigned int compressedTextSize = data.size_ - keysize - 2; ++ enforce(compressedTextSize < data.size_, kerCorruptedMetadata); + + zlibUncompress(compressedText, compressedTextSize, arr); + } + else if(type == tEXt_Chunk) + { ++ enforce(data.size_ >= Safe::add(keysize, 1), Exiv2::kerCorruptedMetadata); + // Extract a non-compressed Latin-1 text chunk + + // the text comes after the key, but isn't null terminated +@@ -164,7 +170,8 @@ namespace Exiv2 { + } + else if(type == iTXt_Chunk) + { ++ enforce(data.size_ >= Safe::add(keysize, 3), Exiv2::kerCorruptedMetadata); + const int nullSeparators = std::count(&data.pData_[keysize+3], &data.pData_[data.size_], '\0'); + + enforce(nullSeparators >= 2, Exiv2::kerCorruptedMetadata); + +@@ -178,40 +185,44 @@ namespace Exiv2 { + enforce(compressionMethod == 0x00, Exiv2::kerCorruptedMetadata); + // language description string after the compression technique spec +- std::string languageText((const char*)(data.pData_ + keysize + 3)); +- unsigned int languageTextSize = static_cast(languageText.size()); ++ const size_t languageTextMaxSize = data.size_ - keysize - 3; ++ std::string languageText = ++ string_from_unterminated((const char*)(data.pData_ + Safe::add(keysize, 3)), languageTextMaxSize); ++ const unsigned int languageTextSize = static_cast(languageText.size()); ++ ++ enforce(data.size_ >= Safe::add(static_cast(Safe::add(keysize, 4)), languageTextSize), ++ Exiv2::kerCorruptedMetadata); + // translated keyword string after the language description +- std::string translatedKeyText((const char*)(data.pData_ + keysize + 3 + languageTextSize +1)); +- unsigned int translatedKeyTextSize = static_cast(translatedKeyText.size()); ++ std::string translatedKeyText = ++ string_from_unterminated((const char*)(data.pData_ + keysize + 3 + languageTextSize + 1), ++ data.size_ - (keysize + 3 + languageTextSize + 1)); ++ const unsigned int translatedKeyTextSize = static_cast(translatedKeyText.size()); + +- if ( compressionFlag == 0x00 ) +- { +- // then it's an uncompressed iTXt chunk +-#ifdef DEBUG +- std::cout << "Exiv2::PngChunk::parseTXTChunk: We found an uncompressed iTXt field\n"; +-#endif ++ if ((compressionFlag == 0x00) || (compressionFlag == 0x01 && compressionMethod == 0x00)) { ++ enforce(Safe::add(static_cast(keysize + 3 + languageTextSize + 1), ++ Safe::add(translatedKeyTextSize, 1u)) <= data.size_, ++ Exiv2::kerCorruptedMetadata); + +- // the text comes after the translated keyword, but isn't null terminated + const byte* text = data.pData_ + keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1; +- long textsize = data.size_ - (keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1); ++ const long textsize = data.size_ - (keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1); + +- arr.alloc(textsize); +- arr = DataBuf(text, textsize); +- } +- else if ( compressionFlag == 0x01 && compressionMethod == 0x00 ) +- { +- // then it's a zlib compressed iTXt chunk ++ if (compressionFlag == 0x00) { ++ // then it's an uncompressed iTXt chunk + #ifdef DEBUG +- std::cout << "Exiv2::PngChunk::parseTXTChunk: We found a zlib compressed iTXt field\n"; ++ std::cout << "Exiv2::PngChunk::parseTXTChunk: We found an uncompressed iTXt field\n"; + #endif + +- // the compressed text comes after the translated keyword, but isn't null terminated +- const byte* compressedText = data.pData_ + keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1; +- long compressedTextSize = data.size_ - (keysize + 3 + languageTextSize + 1 + translatedKeyTextSize + 1); ++ arr.alloc(textsize); ++ arr = DataBuf(text, textsize); ++ } else if (compressionFlag == 0x01 && compressionMethod == 0x00) { ++ // then it's a zlib compressed iTXt chunk ++#ifdef DEBUG ++ std::cout << "Exiv2::PngChunk::parseTXTChunk: We found a zlib compressed iTXt field\n"; ++#endif + +- zlibUncompress(compressedText, compressedTextSize, arr); +- } +- else +- { ++ // the compressed text comes after the translated keyword, but isn't null terminated ++ zlibUncompress(text, textsize, arr); ++ } ++ } else { + // then it isn't zlib compressed and we are sunk + #ifdef DEBUG + std::cerr << "Exiv2::PngChunk::parseTXTChunk: Non-standard iTXt compression method.\n"; diff --git a/CVE-2018-17581.patch b/CVE-2018-17581.patch new file mode 100644 index 0000000..1870805 --- /dev/null +++ b/CVE-2018-17581.patch @@ -0,0 +1,41 @@ +From b3d077dcaefb6747fff8204490f33eba5a144edb Mon Sep 17 00:00:00 2001 +From: Robin Mills +Date: Sat, 13 Oct 2018 11:38:56 +0200 +Subject: [PATCH] Fix #460 by adding more checks in + CiffDirectory::readDirectory + +--- + src/crwimage.cpp | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/src/crwimage.cpp b/src/crwimage.cpp +index 0c04761..ebe1da7 100644 +--- a/src/crwimage.cpp ++++ b/src/crwimage.cpp +@@ -451,16 +451,21 @@ namespace Exiv2 { + uint32_t size, + ByteOrder byteOrder) + { ++ if (size < 4) ++ throw Error(33); + uint32_t o = getULong(pData + size - 4, byteOrder); +- if (size < 2 || o > size-2) throw Error(33); ++ if ( o+2 > size ) ++ throw Error(33); + uint16_t count = getUShort(pData + o, byteOrder); + #ifdef DEBUG + std::cout << "Directory at offset " << std::dec << o + <<", " << count << " entries \n"; + #endif + o += 2; ++ if ( (o + (count * 10)) > size ) ++ throw Error(33); ++ + for (uint16_t i = 0; i < count; ++i) { +- if (size < 10 || o > size-10) throw Error(33); + uint16_t tag = getUShort(pData + o, byteOrder); + CiffComponent::AutoPtr m; + switch (CiffComponent::typeId(tag)) { +-- +2.19.1 + diff --git a/CVE-2018-4868.patch b/CVE-2018-4868.patch new file mode 100644 index 0000000..74fbd32 --- /dev/null +++ b/CVE-2018-4868.patch @@ -0,0 +1,72 @@ +From fcb42570519f8cf924b0302b09062a60aa565fbe Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= +Date: Tue, 9 Jan 2018 21:18:36 +0100 +Subject: [PATCH 1/2] Add check for DataBuf.size_ in Jp2Image::readMetadata() + +When parsing a subBox that is a ColorHeader, a length is extracted +from the input file and fed directly into DataBuf() (which calls +malloc). A crafted input file can provide arbitrarily (up to +max(uint32_t)-8) large values and result in excessive memory +allocation. + +This commit adds a check for the new size of DataBuf so that it is not +larger than the remaining size of the file. + +This fixes #202 aka CVE-2018-4868 +--- + src/jp2image.cpp | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/src/jp2image.cpp b/src/jp2image.cpp +index 20727844d..8dd6c9c1b 100644 +--- a/src/jp2image.cpp ++++ b/src/jp2image.cpp +@@ -268,7 +268,12 @@ namespace Exiv2 + #endif + + const long pad = 3 ; // 3 padding bytes 2 0 0 +- DataBuf data(Safe::add(subBox.length, static_cast(8))); ++ const size_t data_length = Safe::add(subBox.length, static_cast(8)); ++ // data_length makes no sense if it is larger than the rest of the file ++ if (data_length > io_->size() - io_->tell()) { ++ throw Error(58); ++ } ++ DataBuf data(data_length); + io_->read(data.pData_,data.size_); + const long iccLength = getULong(data.pData_+pad, bigEndian); + // subtracting pad from data.size_ is safe: + +From 72de0f96f35d05ba68b28f4fa82f51a1df2778ca Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Dan=20=C4=8Cerm=C3=A1k?= +Date: Tue, 9 Jan 2018 21:27:20 +0100 +Subject: [PATCH 2/2] Added reproducer for CVE-2018-4868 to the test suite + +--- + tests/bugfixes/github/test_CVE_2018_4868.py | 18 ++++++++++++++++++ + 1 files changed, 18 insertions(+) + create mode 100644 tests/bugfixes/github/test_CVE_2018_4868.py + +diff --git a/tests/bugfixes/github/test_CVE_2018_4868.py b/tests/bugfixes/github/test_CVE_2018_4868.py +new file mode 100644 +index 000000000..434eec6b4 +--- /dev/null ++++ b/tests/bugfixes/github/test_CVE_2018_4868.py +@@ -0,0 +1,18 @@ ++# -*- coding: utf-8 -*- ++ ++import system_tests ++ ++ ++class TestCvePoC(system_tests.Case): ++ ++ url = "https://github.com/Exiv2/exiv2/issues/202" ++ cve_url = "http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-4868" ++ found_by = ["afl", "topsecLab", "xcainiao"] ++ ++ filename = "{data_path}/exiv2-memorymmap-error" ++ commands = ["{exiv2} " + filename] ++ stdout = [""] ++ stderr = ["""{exiv2_exception_msg} """ + filename + """: ++{error_58_message} ++"""] ++ retval = [1] diff --git a/CVE-2019-13110-Avoid-integer-overflow.patch b/CVE-2019-13110-Avoid-integer-overflow.patch new file mode 100644 index 0000000..60c958c --- /dev/null +++ b/CVE-2019-13110-Avoid-integer-overflow.patch @@ -0,0 +1,61 @@ +From c0ecc2ae36f34462be98623deb85ba1747ae2175 Mon Sep 17 00:00:00 2001 +From: Kevin Backhouse +Date: Mon, 13 May 2019 16:56:29 +0100 +Subject: [PATCH] Avoid integer overflow. + +--- + src/crwimage.cpp | 4 ++-- + tests/bugfixes/github/test_issue_843.py | 22 ++++++++++++++++++++++ + 2 files changed, 24 insertions(+), 2 deletions(-) + create mode 100644 tests/bugfixes/github/test_issue_843.py + +diff --git a/src/crwimage.cpp b/src/crwimage.cpp +index c2fd5f3a5..4080c0787 100644 +--- a/src/crwimage.cpp ++++ b/src/crwimage.cpp +@@ -281,7 +281,7 @@ namespace Exiv2 { + if (size < 4) + throw Error(33); + uint32_t o = getULong(pData + size - 4, byteOrder); +- if ( o+2 > size ) ++ if ( o > size-2 ) + throw Error(33); + uint16_t count = getUShort(pData + o, byteOrder); + #ifdef DEBUG +@@ -289,7 +289,7 @@ namespace Exiv2 { + <<", " << count << " entries \n"; + #endif + o += 2; +- if ( (o + (count * 10)) > size ) ++ if ( static_cast(count) * 10 > size-o ) + throw Error(33); + + for (uint16_t i = 0; i < count; ++i) { +diff --git a/tests/bugfixes/github/test_issue_843.py b/tests/bugfixes/github/test_issue_843.py +new file mode 100644 +index 000000000..2df9c1cf8 +--- /dev/null ++++ b/tests/bugfixes/github/test_issue_843.py +@@ -0,0 +1,22 @@ ++# -*- coding: utf-8 -*- ++ ++from system_tests import CaseMeta, path ++ ++ ++class IntegerOverflowInCiffDirectoryReadDirectory(metaclass=CaseMeta): ++ """ ++ Regression test for the bug described in: ++ https://github.com/Exiv2/exiv2/issues/843 ++ ++ An integer overflow causes an out-of-bounds read. ++ """ ++ url = "https://github.com/Exiv2/exiv2/issues/843" ++ ++ filename = path("$data_path/issue_843_poc.crw") ++ commands = ["$exiv2 $filename"] ++ stdout = [""] ++ stderr = [ ++ """$exiv2_exception_message $filename: ++$kerCorruptedMetadata ++"""] ++ retval = [1] diff --git a/exiv2-CVE-2017-14865.patch b/exiv2-CVE-2017-14865.patch new file mode 100644 index 0000000..b82a2a5 --- /dev/null +++ b/exiv2-CVE-2017-14865.patch @@ -0,0 +1,61 @@ +From d3c2b9938583440f87ce9115de5a7e8cd8f8db57 Mon Sep 17 00:00:00 2001 +From: clanmills +Date: Sun, 11 Jun 2017 11:56:20 +0100 +Subject: [PATCH] #1297 Fix submitted. + +--- + src/error.cpp | 2 ++ + src/image.cpp | 11 ++++++----- + 2 files changed, 8 insertions(+), 5 deletions(-) + +diff --git a/src/image.cpp b/src/image.cpp +index 0d8280455..0db66eb04 100644 +--- a/src/image.cpp ++++ b/src/image.cpp +@@ -332,7 +332,7 @@ namespace Exiv2 { + + static bool typeValid(uint16_t type) + { +- return type >= 1 && type <= 13 ; ++ return type >= 1 && type <= 13 ; + } + + void Image::printIFDStructure(BasicIo& io, std::ostream& out, Exiv2::PrintStructureOption option,uint32_t start,bool bSwap,char c,int depth) +@@ -352,12 +352,12 @@ namespace Exiv2 { + uint16_t dirLength = byteSwap2(dir,0,bSwap); + + bool tooBig = dirLength > 500; ++ if ( tooBig ) throw Error(55); + + if ( bFirst && bPrint ) { + out << Internal::indent(depth) << Internal::stringFormat("STRUCTURE OF TIFF FILE (%c%c): ",c,c) << io.path() << std::endl; + if ( tooBig ) out << Internal::indent(depth) << "dirLength = " << dirLength << std::endl; + } +- if (tooBig) break; + + // Read the dictionary + for ( int i = 0 ; i < dirLength ; i ++ ) { +@@ -374,10 +374,11 @@ namespace Exiv2 { + uint32_t count = byteSwap4(dir,4,bSwap); + uint32_t offset = byteSwap4(dir,8,bSwap); + +- // Break for unknown tag types else we may get segfault. ++ // Break for unknown tag types else we may segfault. + if ( !typeValid(type) ) { + std::cerr << "invalid type value detected in Image::printIFDStructure: " << type << std::endl; + start = 0; // break from do loop ++ throw Error(56); + break; // break from for loop + } + +@@ -411,8 +412,8 @@ namespace Exiv2 { + if ( bPrint ) { + uint32_t address = start + 2 + i*12 ; + out << Internal::indent(depth) +- << Internal::stringFormat("%8u | %#06x %-25s |%10s |%9u |%10u | " +- ,address,tag,tagName(tag,25),typeName(type),count,offset); ++ << Internal::stringFormat("%8u | %#06x %-25s |%10s |%9u |%10u | " ++ ,address,tag,tagName(tag,25),typeName(type),count,offset); + if ( isShortType(type) ){ + for ( size_t k = 0 ; k < kount ; k++ ) { + out << sp << byteSwap2(buf,k*size,bSwap); diff --git a/exiv2-CVE-2017-18005_1.patch b/exiv2-CVE-2017-18005_1.patch new file mode 100644 index 0000000..074ee61 --- /dev/null +++ b/exiv2-CVE-2017-18005_1.patch @@ -0,0 +1,25 @@ +From 1c76ecbd66263b2ed14c82e41917ab3d7e8b0ef9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= +Date: Tue, 19 Dec 2017 19:52:41 +0100 +Subject: [PATCH] Only print items (Params::prValue) when size > 0 + +--- + src/actions.cpp | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/actions.cpp b/src/actions.cpp +index e5baa75fc..3125cf54f 100644 +--- a/src/actions.cpp ++++ b/src/actions.cpp +@@ -704,8 +704,9 @@ namespace Action { + << std::setfill(' ') << std::right + << md.size(); + } +- if (Params::instance().printItems_ & Params::prValue) { +- if (!first) std::cout << " "; ++ if (Params::instance().printItems_ & Params::prValue && md.size() > 0) { ++ if (!first) ++ std::cout << " "; + first = false; + if ( Params::instance().binary_ + && ( md.typeId() == Exiv2::undefined diff --git a/exiv2-CVE-2017-18005_2.patch b/exiv2-CVE-2017-18005_2.patch new file mode 100644 index 0000000..2de87ed --- /dev/null +++ b/exiv2-CVE-2017-18005_2.patch @@ -0,0 +1,27 @@ +From 85e8a48bc2da364869ffd1aaeabc09edcfa03067 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Luis=20D=C3=ADaz=20M=C3=A1s?= +Date: Tue, 19 Dec 2017 19:54:17 +0100 +Subject: [PATCH] Move condition in if statement to discard work earlier + +--- + src/actions.cpp | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/src/actions.cpp b/src/actions.cpp +index 3125cf54f..fea22d373 100644 +--- a/src/actions.cpp ++++ b/src/actions.cpp +@@ -708,10 +708,9 @@ namespace Action { + if (!first) std::cout << " "; + first = false; +- if ( Params::instance().binary_ +- && ( md.typeId() == Exiv2::undefined ++ if (md.size() > 128 && Params::instance().binary_ && ( ++ md.typeId() == Exiv2::undefined + || md.typeId() == Exiv2::unsignedByte +- || md.typeId() == Exiv2::signedByte) +- && md.size() > 128) { ++ || md.typeId() == Exiv2::signedByte)) { + std::cout << _("(Binary value suppressed)") << std::endl; + return true; + } diff --git a/exiv2.spec b/exiv2.spec index 771173a..37bc8f4 100644 --- a/exiv2.spec +++ b/exiv2.spec @@ -1,6 +1,6 @@ Name: exiv2 Version: 0.26 -Release: 14 +Release: 15 Summary: Exif, IPTC and XMP metadata and the ICC Profile License: GPLv2+ URL: http://www.exiv2.org/ @@ -40,6 +40,18 @@ Patch6007: CVE-2019-13110.patch Patch6008: CVE-2019-13113.patch Patch6009: CVE-2019-13114.patch Patch6010: CVE-2019-14982.patch +Patch6011: exiv2-CVE-2017-14865.patch +Patch6012: exiv2-CVE-2017-18005_1.patch +Patch6013: exiv2-CVE-2017-18005_2.patch +Patch6014: 0001-CVE-2018-19535.patch +Patch6015: 0002-CVE-2018-19535.patch +Patch6016: 0003-CVE-2018-19535.patch +Patch6017: 0001-CVE-2019-13112.patch +Patch6018: 0002-CVE-2019-13112.patch +Patch6019: CVE-2018-16336.patch +Patch6020: CVE-2018-17581.patch +Patch6021: CVE-2019-13110-Avoid-integer-overflow.patch +Patch6022: CVE-2018-4868.patch Provides: exiv2-libs Obsoletes: exiv2-libs @@ -105,11 +117,17 @@ test -x %{buildroot}%{_libdir}/libexiv2.so %{_datadir}/doc/html/ %changelog -* Wed Sep 25 2019 huzunhao - 0.26-12.14 +* Sat Dec 21 2019 openEuler Buildteam - 0.26-15 +- Type:cves +- ID:NA +- SUG:NA +- DESC:Add CVE patches + +* Wed Sep 25 2019 huzunhao - 0.26-14 - Type:cves - ID:CVE-2019-14982 - SUG:NA - DESC:fix CVE-2019-14982 -* Sat Sep 21 2019 Yanjie Guan - 0.26-12.13 +* Sat Sep 21 2019 Yanjie Guan - 0.26-13 - Package init for openEuler