mirror of
git://git.openembedded.org/meta-openembedded
synced 2026-05-18 20:23:20 +00:00
exiv2: patch CVE-2021-37621
Details: https://nvd.nist.gov/vuln/detail/CVE-2021-37621 Backport the patch that is referenced by the NVD advisory. The regression test contains a binary patch, that couldn't be applied in the do_patch task. Due to this the test was not backported. It was however applied manually and executed successfully during the preparation of this patch. Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
This commit is contained in:
parent
4f2440f62f
commit
08fe7e8f61
25
meta-oe/recipes-support/exiv2/exiv2/CVE-2021-37621-1.patch
Normal file
25
meta-oe/recipes-support/exiv2/exiv2/CVE-2021-37621-1.patch
Normal file
@ -0,0 +1,25 @@
|
||||
From 4fbd3390829f8418e1ec95252c2fd6b851850508 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Backhouse <kevinbackhouse@github.com>
|
||||
Date: Tue, 13 Jul 2021 22:50:16 +0100
|
||||
Subject: [PATCH] dirLength == 0 can cause an infinite loop.
|
||||
|
||||
CVE: CVE-2021-37621
|
||||
Upstream-Status: Backport [https://github.com/Exiv2/exiv2/commit/191cd2690608f19335d82ed2be36c7ce8bdc60b9]
|
||||
Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
|
||||
---
|
||||
src/image.cpp | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/src/image.cpp b/src/image.cpp
|
||||
index 2fa41e5..7c2eaa9 100644
|
||||
--- a/src/image.cpp
|
||||
+++ b/src/image.cpp
|
||||
@@ -353,6 +353,8 @@ namespace Exiv2 {
|
||||
throw Error(kerCorruptedMetadata);
|
||||
}
|
||||
uint16_t dirLength = byteSwap2(dir,0,bSwap);
|
||||
+ // Prevent infinite loops. (GHSA-m479-7frc-gqqg)
|
||||
+ enforce(dirLength > 0, kerCorruptedMetadata);
|
||||
|
||||
bool tooBig = dirLength > 500;
|
||||
if ( tooBig ) throw Error(kerTiffDirectoryTooLarge);
|
||||
187
meta-oe/recipes-support/exiv2/exiv2/CVE-2021-37621-2.patch
Normal file
187
meta-oe/recipes-support/exiv2/exiv2/CVE-2021-37621-2.patch
Normal file
@ -0,0 +1,187 @@
|
||||
From 2973c3277af6922209a80985eccbd50b48088be6 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Backhouse <kevinbackhouse@github.com>
|
||||
Date: Tue, 13 Jul 2021 22:53:40 +0100
|
||||
Subject: [PATCH] Defensive programming in Image::printIFDStructure
|
||||
|
||||
CVE: CVE-2021-37621
|
||||
Upstream-Status: Backport [https://github.com/Exiv2/exiv2/commit/d9fd4c4272df172ae89c0a9c41341adc75ebba86]
|
||||
Signed-off-by: Gyorgy Sarvari <skandigraun@gmail.com>
|
||||
---
|
||||
src/image.cpp | 82 +++++++++++++++++++++++++++++++--------------------
|
||||
1 file changed, 50 insertions(+), 32 deletions(-)
|
||||
|
||||
diff --git a/src/image.cpp b/src/image.cpp
|
||||
index 7c2eaa9..6b1b1d8 100644
|
||||
--- a/src/image.cpp
|
||||
+++ b/src/image.cpp
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "image.hpp"
|
||||
#include "image_int.hpp"
|
||||
#include "error.hpp"
|
||||
+#include "enforce.hpp"
|
||||
#include "futils.hpp"
|
||||
#include "safe_op.hpp"
|
||||
#include "slice.hpp"
|
||||
@@ -149,6 +150,19 @@ namespace {
|
||||
// class member definitions
|
||||
namespace Exiv2 {
|
||||
|
||||
+ // BasicIo::read() with error checking
|
||||
+ static void readOrThrow(BasicIo& iIo, byte* buf, long rcount, ErrorCode err) {
|
||||
+ const long nread = iIo.read(buf, rcount);
|
||||
+ enforce(nread == rcount, err);
|
||||
+ enforce(!iIo.error(), err);
|
||||
+ }
|
||||
+
|
||||
+ // BasicIo::seek() with error checking
|
||||
+ static void seekOrThrow(BasicIo& iIo, long offset, BasicIo::Position pos, ErrorCode err) {
|
||||
+ const int r = iIo.seek(offset, pos);
|
||||
+ enforce(r == 0, err);
|
||||
+ }
|
||||
+
|
||||
Image::Image(int imageType,
|
||||
uint16_t supportedMetadata,
|
||||
BasicIo::AutoPtr io)
|
||||
@@ -347,11 +361,8 @@ namespace Exiv2 {
|
||||
|
||||
do {
|
||||
// Read top of directory
|
||||
- const int seekSuccess = !io.seek(start,BasicIo::beg);
|
||||
- const long bytesRead = io.read(dir.pData_, 2);
|
||||
- if (!seekSuccess || bytesRead == 0) {
|
||||
- throw Error(kerCorruptedMetadata);
|
||||
- }
|
||||
+ seekOrThrow(io, start, BasicIo::beg, kerCorruptedMetadata);
|
||||
+ readOrThrow(io, dir.pData_, 2, kerCorruptedMetadata);
|
||||
uint16_t dirLength = byteSwap2(dir,0,bSwap);
|
||||
// Prevent infinite loops. (GHSA-m479-7frc-gqqg)
|
||||
enforce(dirLength > 0, kerCorruptedMetadata);
|
||||
@@ -378,7 +389,7 @@ namespace Exiv2 {
|
||||
}
|
||||
bFirst = false;
|
||||
|
||||
- io.read(dir.pData_, 12);
|
||||
+ readOrThrow(io, dir.pData_, 12, kerCorruptedMetadata);
|
||||
uint16_t tag = byteSwap2(dir,0,bSwap);
|
||||
uint16_t type = byteSwap2(dir,2,bSwap);
|
||||
uint32_t count = byteSwap4(dir,4,bSwap);
|
||||
@@ -411,20 +422,27 @@ namespace Exiv2 {
|
||||
// if ( offset > io.size() ) offset = 0; // Denial of service?
|
||||
|
||||
// #55 and #56 memory allocation crash test/data/POC8
|
||||
- long long allocate = (long long) size*count + pad+20;
|
||||
- if ( allocate > (long long) io.size() ) {
|
||||
+ const uint64_t allocate64 = static_cast<uint64_t>(size) * count + pad + 20;
|
||||
+ if ( allocate64 > io.size() ) {
|
||||
throw Error(kerInvalidMalloc);
|
||||
}
|
||||
- DataBuf buf((long)allocate); // allocate a buffer
|
||||
+ // Overflow check
|
||||
+ enforce(allocate64 <= static_cast<uint64_t>(std::numeric_limits<uint32_t>::max()), kerCorruptedMetadata);
|
||||
+ enforce(allocate64 <= static_cast<uint64_t>(std::numeric_limits<long>::max()), kerCorruptedMetadata);
|
||||
+ const long allocate = static_cast<long>(allocate64);
|
||||
+ DataBuf buf(allocate); // allocate a buffer
|
||||
std::memset(buf.pData_, 0, buf.size_);
|
||||
std::memcpy(buf.pData_,dir.pData_+8,4); // copy dir[8:11] into buffer (short strings)
|
||||
- const bool bOffsetIsPointer = count*size > 4;
|
||||
+
|
||||
+ // We have already checked that this multiplication cannot overflow.
|
||||
+ const uint32_t count_x_size = count*size;
|
||||
+ const bool bOffsetIsPointer = count_x_size > 4;
|
||||
|
||||
if ( bOffsetIsPointer ) { // read into buffer
|
||||
- size_t restore = io.tell(); // save
|
||||
- io.seek(offset,BasicIo::beg); // position
|
||||
- io.read(buf.pData_,count*size);// read
|
||||
- io.seek(restore,BasicIo::beg); // restore
|
||||
+ const long restore = io.tell(); // save
|
||||
+ seekOrThrow(io, offset, BasicIo::beg, kerCorruptedMetadata); // position
|
||||
+ readOrThrow(io, buf.pData_, static_cast<long>(count_x_size), kerCorruptedMetadata); // read
|
||||
+ seekOrThrow(io, restore, BasicIo::beg, kerCorruptedMetadata); // restore
|
||||
}
|
||||
|
||||
if ( bPrint ) {
|
||||
@@ -463,10 +481,10 @@ namespace Exiv2 {
|
||||
|
||||
if ( option == kpsRecursive && (tag == 0x8769 /* ExifTag */ || tag == 0x014a/*SubIFDs*/ || type == tiffIfd) ) {
|
||||
for ( size_t k = 0 ; k < count ; k++ ) {
|
||||
- size_t restore = io.tell();
|
||||
+ const long restore = io.tell();
|
||||
uint32_t offset = byteSwap4(buf,k*size,bSwap);
|
||||
printIFDStructure(io,out,option,offset,bSwap,c,depth);
|
||||
- io.seek(restore,BasicIo::beg);
|
||||
+ seekOrThrow(io, restore, BasicIo::beg, kerCorruptedMetadata);
|
||||
}
|
||||
} else if ( option == kpsRecursive && tag == 0x83bb /* IPTCNAA */ ) {
|
||||
|
||||
@@ -474,38 +492,38 @@ namespace Exiv2 {
|
||||
throw Error(kerCorruptedMetadata);
|
||||
}
|
||||
|
||||
- const size_t restore = io.tell();
|
||||
- io.seek(offset, BasicIo::beg); // position
|
||||
+ const long restore = io.tell();
|
||||
+ seekOrThrow(io, offset, BasicIo::beg, kerCorruptedMetadata); // position
|
||||
std::vector<byte> bytes(count) ; // allocate memory
|
||||
// TODO: once we have C++11 use bytes.data()
|
||||
- const long read_bytes = io.read(&bytes[0], count);
|
||||
- io.seek(restore, BasicIo::beg);
|
||||
+ readOrThrow(io, &bytes[0], count, kerCorruptedMetadata);
|
||||
+ seekOrThrow(io, restore, BasicIo::beg, kerCorruptedMetadata);
|
||||
// TODO: once we have C++11 use bytes.data()
|
||||
- IptcData::printStructure(out, makeSliceUntil(&bytes[0], read_bytes), depth);
|
||||
+ IptcData::printStructure(out, makeSliceUntil(&bytes[0], count), depth);
|
||||
|
||||
} else if ( option == kpsRecursive && tag == 0x927c /* MakerNote */ && count > 10) {
|
||||
- size_t restore = io.tell(); // save
|
||||
+ const long restore = io.tell(); // save
|
||||
|
||||
uint32_t jump= 10 ;
|
||||
byte bytes[20] ;
|
||||
const char* chars = (const char*) &bytes[0] ;
|
||||
- io.seek(offset,BasicIo::beg); // position
|
||||
- io.read(bytes,jump ) ; // read
|
||||
+ seekOrThrow(io, offset, BasicIo::beg, kerCorruptedMetadata); // position
|
||||
+ readOrThrow(io, bytes, jump, kerCorruptedMetadata) ; // read
|
||||
bytes[jump]=0 ;
|
||||
if ( ::strcmp("Nikon",chars) == 0 ) {
|
||||
// tag is an embedded tiff
|
||||
- byte* bytes=new byte[count-jump] ; // allocate memory
|
||||
- io.read(bytes,count-jump) ; // read
|
||||
- MemIo memIo(bytes,count-jump) ; // create a file
|
||||
+ const long byteslen = count-jump;
|
||||
+ DataBuf bytes(byteslen); // allocate a buffer
|
||||
+ readOrThrow(io, bytes.pData_, byteslen, kerCorruptedMetadata); // read
|
||||
+ MemIo memIo(bytes.pData_, byteslen) ; // create a file
|
||||
printTiffStructure(memIo,out,option,depth);
|
||||
- delete[] bytes ; // free
|
||||
} else {
|
||||
// tag is an IFD
|
||||
- io.seek(0,BasicIo::beg); // position
|
||||
+ seekOrThrow(io, 0, BasicIo::beg, kerCorruptedMetadata); // position
|
||||
printIFDStructure(io,out,option,offset,bSwap,c,depth);
|
||||
}
|
||||
|
||||
- io.seek(restore,BasicIo::beg); // restore
|
||||
+ seekOrThrow(io, restore, BasicIo::beg, kerCorruptedMetadata); // restore
|
||||
}
|
||||
}
|
||||
|
||||
@@ -518,7 +536,7 @@ namespace Exiv2 {
|
||||
}
|
||||
}
|
||||
if ( start ) {
|
||||
- io.read(dir.pData_, 4);
|
||||
+ readOrThrow(io, dir.pData_, 4, kerCorruptedMetadata);
|
||||
start = tooBig ? 0 : byteSwap4(dir,0,bSwap);
|
||||
}
|
||||
} while (start) ;
|
||||
@@ -538,7 +556,7 @@ namespace Exiv2 {
|
||||
DataBuf dir(dirSize);
|
||||
|
||||
// read header (we already know for certain that we have a Tiff file)
|
||||
- io.read(dir.pData_, 8);
|
||||
+ readOrThrow(io, dir.pData_, 8, kerCorruptedMetadata);
|
||||
char c = (char) dir.pData_[0] ;
|
||||
bool bSwap = ( c == 'M' && isLittleEndianPlatform() )
|
||||
|| ( c == 'I' && isBigEndianPlatform() )
|
||||
@ -28,6 +28,8 @@ SRC_URI = "https://github.com/Exiv2/${BPN}/releases/download/v${PV}/${BP}-Source
|
||||
file://CVE-2021-37619.patch \
|
||||
file://CVE-2021-37620-1.patch \
|
||||
file://CVE-2021-37620-2.patch \
|
||||
file://CVE-2021-37621-1.patch \
|
||||
file://CVE-2021-37621-2.patch \
|
||||
"
|
||||
SRC_URI[sha256sum] = "a79f5613812aa21755d578a297874fb59a85101e793edc64ec2c6bd994e3e778"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user