CVE-2021-29623 exiv2: a read of uninitialized memory may lead to information leak
Resolves: bz#1964183 CVE-2021-32617 exiv2: DoS due to quadratic complexity in ProcessUTF8Portion Resolves: bz#1964189
This commit is contained in:
parent
4c8da3ae72
commit
99c067b851
26
exiv2-CVE-2021-29623.patch
Normal file
26
exiv2-CVE-2021-29623.patch
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
From 82e46b5524fb904e6660dadd2c6d8e5e47375a1a Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Backhouse <kevinbackhouse@github.com>
|
||||||
|
Date: Tue, 11 May 2021 12:14:33 +0100
|
||||||
|
Subject: [PATCH] Use readOrThrow to check error conditions of iIo.read().
|
||||||
|
|
||||||
|
---
|
||||||
|
src/webpimage.cpp | 6 +++---
|
||||||
|
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/src/webpimage.cpp b/src/webpimage.cpp
|
||||||
|
index 7c64ff3d7..ca26e514a 100644
|
||||||
|
--- a/src/webpimage.cpp
|
||||||
|
+++ b/src/webpimage.cpp
|
||||||
|
@@ -754,9 +754,9 @@ namespace Exiv2 {
|
||||||
|
byte webp[len];
|
||||||
|
byte data[len];
|
||||||
|
byte riff[len];
|
||||||
|
- iIo.read(riff, len);
|
||||||
|
- iIo.read(data, len);
|
||||||
|
- iIo.read(webp, len);
|
||||||
|
+ readOrThrow(iIo, riff, len, Exiv2::kerCorruptedMetadata);
|
||||||
|
+ readOrThrow(iIo, data, len, Exiv2::kerCorruptedMetadata);
|
||||||
|
+ readOrThrow(iIo, webp, len, Exiv2::kerCorruptedMetadata);
|
||||||
|
bool matched_riff = (memcmp(riff, RiffImageId, len) == 0);
|
||||||
|
bool matched_webp = (memcmp(webp, WebPImageId, len) == 0);
|
||||||
|
iIo.seek(-12, BasicIo::cur);
|
125
exiv2-CVE-2021-32617.patch
Normal file
125
exiv2-CVE-2021-32617.patch
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
From c261fbaa2567687eec6a595d3016212fd6ae648d Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kevin Backhouse <kevinbackhouse@github.com>
|
||||||
|
Date: Sun, 16 May 2021 15:05:08 +0100
|
||||||
|
Subject: [PATCH] Fix quadratic complexity performance bug.
|
||||||
|
|
||||||
|
---
|
||||||
|
xmpsdk/src/XMPMeta-Parse.cpp | 57 +++++++++++++++++++++++-------------
|
||||||
|
1 file changed, 36 insertions(+), 21 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/xmpsdk/src/XMPMeta-Parse.cpp b/xmpsdk/src/XMPMeta-Parse.cpp
|
||||||
|
index 9f66fe8..f9c37d7 100644
|
||||||
|
--- a/xmpsdk/src/XMPMeta-Parse.cpp
|
||||||
|
+++ b/xmpsdk/src/XMPMeta-Parse.cpp
|
||||||
|
@@ -976,12 +976,26 @@ ProcessUTF8Portion ( XMLParserAdapter * xmlParser,
|
||||||
|
{
|
||||||
|
const XMP_Uns8 * bufEnd = buffer + length;
|
||||||
|
|
||||||
|
- const XMP_Uns8 * spanStart = buffer;
|
||||||
|
const XMP_Uns8 * spanEnd;
|
||||||
|
-
|
||||||
|
- for ( spanEnd = spanStart; spanEnd < bufEnd; ++spanEnd ) {
|
||||||
|
|
||||||
|
- if ( (0x20 <= *spanEnd) && (*spanEnd <= 0x7E) && (*spanEnd != '&') ) continue; // A regular ASCII character.
|
||||||
|
+ // `buffer` is copied into this std::string. If `buffer` only
|
||||||
|
+ // contains valid UTF-8 and no escape characters, then the copy
|
||||||
|
+ // will be identical to the original, but invalid characters are
|
||||||
|
+ // replaced - usually with a space character. This std::string was
|
||||||
|
+ // added as a performance fix for:
|
||||||
|
+ // https://github.com/Exiv2/exiv2/security/advisories/GHSA-w8mv-g8qq-36mj
|
||||||
|
+ // Previously, the code was repeatedly calling
|
||||||
|
+ // `xmlParser->ParseBuffer()`, which turned out to have quadratic
|
||||||
|
+ // complexity, because expat kept reparsing the entire string from
|
||||||
|
+ // the beginning.
|
||||||
|
+ std::string copy;
|
||||||
|
+
|
||||||
|
+ for ( spanEnd = buffer; spanEnd < bufEnd; ++spanEnd ) {
|
||||||
|
+
|
||||||
|
+ if ( (0x20 <= *spanEnd) && (*spanEnd <= 0x7E) && (*spanEnd != '&') ) {
|
||||||
|
+ copy.push_back(*spanEnd);
|
||||||
|
+ continue; // A regular ASCII character.
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if ( *spanEnd >= 0x80 ) {
|
||||||
|
|
||||||
|
@@ -992,21 +1006,20 @@ ProcessUTF8Portion ( XMLParserAdapter * xmlParser,
|
||||||
|
if ( uniLen > 0 ) {
|
||||||
|
|
||||||
|
// A valid UTF-8 character, keep it as-is.
|
||||||
|
+ copy.append((const char*)spanEnd, uniLen);
|
||||||
|
spanEnd += uniLen - 1; // ! The loop increment will put back the +1.
|
||||||
|
|
||||||
|
} else if ( (uniLen < 0) && (! last) ) {
|
||||||
|
|
||||||
|
// Have a partial UTF-8 character at the end of the buffer and more input coming.
|
||||||
|
- xmlParser->ParseBuffer ( spanStart, (spanEnd - spanStart), false );
|
||||||
|
+ xmlParser->ParseBuffer ( copy.c_str(), copy.size(), false );
|
||||||
|
return (spanEnd - buffer);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Not a valid UTF-8 sequence. Replace the first byte with the Latin-1 equivalent.
|
||||||
|
- xmlParser->ParseBuffer ( spanStart, (spanEnd - spanStart), false );
|
||||||
|
const char * replacement = kReplaceLatin1 [ *spanEnd - 0x80 ];
|
||||||
|
- xmlParser->ParseBuffer ( replacement, strlen ( replacement ), false );
|
||||||
|
- spanStart = spanEnd + 1; // ! The loop increment will do "spanEnd = spanStart".
|
||||||
|
+ copy.append ( replacement );
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1014,11 +1027,12 @@ ProcessUTF8Portion ( XMLParserAdapter * xmlParser,
|
||||||
|
|
||||||
|
// Replace ASCII controls other than tab, LF, and CR with a space.
|
||||||
|
|
||||||
|
- if ( (*spanEnd == kTab) || (*spanEnd == kLF) || (*spanEnd == kCR) ) continue;
|
||||||
|
+ if ( (*spanEnd == kTab) || (*spanEnd == kLF) || (*spanEnd == kCR) ) {
|
||||||
|
+ copy.push_back(*spanEnd);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- xmlParser->ParseBuffer ( spanStart, (spanEnd - spanStart), false );
|
||||||
|
- xmlParser->ParseBuffer ( " ", 1, false );
|
||||||
|
- spanStart = spanEnd + 1; // ! The loop increment will do "spanEnd = spanStart".
|
||||||
|
+ copy.push_back(' ');
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
@@ -1030,18 +1044,21 @@ ProcessUTF8Portion ( XMLParserAdapter * xmlParser,
|
||||||
|
if ( escLen < 0 ) {
|
||||||
|
|
||||||
|
// Have a partial numeric escape in this buffer, wait for more input.
|
||||||
|
- if ( last ) continue; // No more buffers, not an escape, absorb as normal input.
|
||||||
|
- xmlParser->ParseBuffer ( spanStart, (spanEnd - spanStart), false );
|
||||||
|
+ if ( last ) {
|
||||||
|
+ copy.push_back('&');
|
||||||
|
+ continue; // No more buffers, not an escape, absorb as normal input.
|
||||||
|
+ }
|
||||||
|
+ xmlParser->ParseBuffer ( copy.c_str(), copy.size(), false );
|
||||||
|
return (spanEnd - buffer);
|
||||||
|
|
||||||
|
} else if ( escLen > 0 ) {
|
||||||
|
|
||||||
|
// Have a complete numeric escape to replace.
|
||||||
|
- xmlParser->ParseBuffer ( spanStart, (spanEnd - spanStart), false );
|
||||||
|
- xmlParser->ParseBuffer ( " ", 1, false );
|
||||||
|
- spanStart = spanEnd + escLen;
|
||||||
|
- spanEnd = spanStart - 1; // ! The loop continuation will increment spanEnd!
|
||||||
|
+ copy.push_back(' ');
|
||||||
|
+ spanEnd = spanEnd + escLen - 1; // ! The loop continuation will increment spanEnd!
|
||||||
|
|
||||||
|
+ } else {
|
||||||
|
+ copy.push_back('&');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
@@ -1050,8 +1067,8 @@ ProcessUTF8Portion ( XMLParserAdapter * xmlParser,
|
||||||
|
|
||||||
|
XMP_Assert ( spanEnd == bufEnd );
|
||||||
|
|
||||||
|
- if ( spanStart < bufEnd ) xmlParser->ParseBuffer ( spanStart, (spanEnd - spanStart), false );
|
||||||
|
- if ( last ) xmlParser->ParseBuffer ( " ", 1, true );
|
||||||
|
+ copy.push_back(' ');
|
||||||
|
+ xmlParser->ParseBuffer ( copy.c_str(), copy.size(), true );
|
||||||
|
|
||||||
|
return length;
|
||||||
|
|
11
exiv2.spec
11
exiv2.spec
@ -5,7 +5,7 @@ Summary: Exif and Iptc metadata manipulation library
|
|||||||
Name: exiv2
|
Name: exiv2
|
||||||
Version: 0.27.3
|
Version: 0.27.3
|
||||||
%global internal_ver %{version}
|
%global internal_ver %{version}
|
||||||
Release: 7%{?dist}
|
Release: 8%{?dist}
|
||||||
|
|
||||||
License: GPLv2+
|
License: GPLv2+
|
||||||
URL: http://www.exiv2.org/
|
URL: http://www.exiv2.org/
|
||||||
@ -23,6 +23,8 @@ Patch51: exiv2-CVE-2021-29457.patch
|
|||||||
Patch52: exiv2-CVE-2021-29458.patch
|
Patch52: exiv2-CVE-2021-29458.patch
|
||||||
Patch53: exiv2-CVE-2021-29470.patch
|
Patch53: exiv2-CVE-2021-29470.patch
|
||||||
Patch54: exiv2-CVE-2021-29473.patch
|
Patch54: exiv2-CVE-2021-29473.patch
|
||||||
|
Patch55: exiv2-CVE-2021-29623.patch
|
||||||
|
Patch56: exiv2-CVE-2021-32617.patch
|
||||||
|
|
||||||
## upstreamable patches
|
## upstreamable patches
|
||||||
# don't unconditionally use -fcf-protection flag, not supported on all archs
|
# don't unconditionally use -fcf-protection flag, not supported on all archs
|
||||||
@ -142,6 +144,13 @@ test -x %{buildroot}%{_libdir}/libexiv2.so
|
|||||||
|
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue May 25 2021 Jan Grulich <jgrulich@redhat.com> - 0.27.3-8
|
||||||
|
- CVE-2021-29623 exiv2: a read of uninitialized memory may lead to information leak
|
||||||
|
Resolves: bz#1964183
|
||||||
|
|
||||||
|
- CVE-2021-32617 exiv2: DoS due to quadratic complexity in ProcessUTF8Portion
|
||||||
|
Resolves: bz#1964189
|
||||||
|
|
||||||
* Mon May 03 2021 Jan Grulich <jgrulich@redhat.com> - 0.27.3-7
|
* Mon May 03 2021 Jan Grulich <jgrulich@redhat.com> - 0.27.3-7
|
||||||
- CVE-2021-3482: Fix heap-based buffer overflow in Jp2Image::readMetadata()
|
- CVE-2021-3482: Fix heap-based buffer overflow in Jp2Image::readMetadata()
|
||||||
CVE-2021-29458 exiv2: out-of-bounds read in Exiv2::Internal::CrwMap::encode
|
CVE-2021-29458 exiv2: out-of-bounds read in Exiv2::Internal::CrwMap::encode
|
||||||
|
Loading…
Reference in New Issue
Block a user