fix cve-2021-29464 cve-2021-29463 cve-2021-29473
This commit is contained in:
parent
050bf70d50
commit
6ce4fdcb4c
26
backport-0001-CVE-2021-29463.patch
Normal file
26
backport-0001-CVE-2021-29463.patch
Normal file
@ -0,0 +1,26 @@
|
||||
From caa4e6745a76a23bb80127cf54c0d65096ae684c Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Backhouse <kev@semmle.com>
|
||||
Date: Tue, 30 Apr 2019 09:26:18 +0100
|
||||
Subject: [PATCH] Avoid negative integer overflow when `filesize <
|
||||
io_->tell()`.
|
||||
|
||||
This fixes #791.
|
||||
---
|
||||
src/webpimage.cpp | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/webpimage.cpp b/src/webpimage.cpp
|
||||
index 9d7272c..6fe2ddb 100644
|
||||
--- a/src/webpimage.cpp
|
||||
+++ b/src/webpimage.cpp
|
||||
@@ -45,6 +45,7 @@
|
||||
#include "tiffimage_int.hpp"
|
||||
#include "convert.hpp"
|
||||
#include "enforce.hpp"
|
||||
+#include "safe_op.hpp"
|
||||
|
||||
#include <cmath>
|
||||
#include <iomanip>
|
||||
--
|
||||
2.23.0
|
||||
|
||||
116
backport-0002-CVE-2021-29463.patch
Normal file
116
backport-0002-CVE-2021-29463.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From caa4e6745a76a23bb80127cf54c0d65096ae684c Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Backhouse <kev@semmle.com>
|
||||
Date: Tue, 30 Apr 2019 09:26:18 +0100
|
||||
Subject: [PATCH] Avoid negative integer overflow when `filesize <
|
||||
io_->tell()`.
|
||||
|
||||
This fixes #791.
|
||||
---
|
||||
src/webpimage.cpp | 33 +++++++++++++++++++++------------
|
||||
1 file changed, 21 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/src/webpimage.cpp b/src/webpimage.cpp
|
||||
index 51a200b..9d7272c 100644
|
||||
--- a/src/webpimage.cpp
|
||||
+++ b/src/webpimage.cpp
|
||||
@@ -67,6 +67,15 @@ namespace Exiv2 {
|
||||
namespace Exiv2 {
|
||||
using namespace Exiv2::Internal;
|
||||
|
||||
+ // This static function is a temporary fix in v0.27. In the next version,
|
||||
+ // it will be added as a method of BasicIo.
|
||||
+ 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);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
WebPImage::WebPImage(BasicIo::AutoPtr io)
|
||||
: Image(ImageType::webp, mdNone, io)
|
||||
{
|
||||
@@ -512,7 +521,7 @@ namespace Exiv2 {
|
||||
DataBuf chunkId(5);
|
||||
chunkId.pData_[4] = '\0' ;
|
||||
|
||||
- io_->readOrThrow(data, WEBP_TAG_SIZE * 3, Exiv2::kerCorruptedMetadata);
|
||||
+ readOrThrow(*io_, data, WEBP_TAG_SIZE * 3, Exiv2::kerCorruptedMetadata);
|
||||
|
||||
const uint32_t filesize = Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian) + 8;
|
||||
enforce(filesize <= io_->size(), Exiv2::kerCorruptedMetadata);
|
||||
@@ -532,8 +541,8 @@ namespace Exiv2 {
|
||||
|
||||
chunkId.pData_[4] = '\0' ;
|
||||
while ( !io_->eof() && (uint64_t) io_->tell() < filesize) {
|
||||
- io_->readOrThrow(chunkId.pData_, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
- io_->readOrThrow(size_buff, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
+ readOrThrow(*io_, chunkId.pData_, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
+ readOrThrow(*io_, size_buff, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
const uint32_t size = Exiv2::getULong(size_buff, littleEndian);
|
||||
enforce(io_->tell() <= filesize, Exiv2::kerCorruptedMetadata);
|
||||
enforce(size <= (filesize - io_->tell()), Exiv2::kerCorruptedMetadata);
|
||||
@@ -545,8 +554,8 @@ namespace Exiv2 {
|
||||
|
||||
has_canvas_data = true;
|
||||
byte size_buf[WEBP_TAG_SIZE];
|
||||
-
|
||||
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
+
|
||||
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
|
||||
// Fetch width
|
||||
memcpy(&size_buf, &payload.pData_[4], 3);
|
||||
@@ -561,7 +570,7 @@ namespace Exiv2 {
|
||||
enforce(size >= 10, Exiv2::kerCorruptedMetadata);
|
||||
|
||||
has_canvas_data = true;
|
||||
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
byte size_buf[WEBP_TAG_SIZE];
|
||||
|
||||
// Fetch width""
|
||||
@@ -582,7 +591,7 @@ namespace Exiv2 {
|
||||
byte size_buf_w[2];
|
||||
byte size_buf_h[3];
|
||||
|
||||
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
|
||||
// Fetch width
|
||||
memcpy(&size_buf_w, &payload.pData_[1], 2);
|
||||
@@ -599,8 +608,8 @@ namespace Exiv2 {
|
||||
|
||||
has_canvas_data = true;
|
||||
byte size_buf[WEBP_TAG_SIZE];
|
||||
-
|
||||
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
+
|
||||
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
|
||||
// Fetch width
|
||||
memcpy(&size_buf, &payload.pData_[6], 3);
|
||||
@@ -612,10 +621,10 @@ namespace Exiv2 {
|
||||
size_buf[3] = 0;
|
||||
pixelHeight_ = Exiv2::getULong(size_buf, littleEndian) + 1;
|
||||
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ICCP)) {
|
||||
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
this->setIccProfile(payload);
|
||||
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_EXIF)) {
|
||||
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
|
||||
byte size_buff[2];
|
||||
byte exifLongHeader[] = { 0xFF, 0x01, 0xFF, 0xE1 };
|
||||
@@ -696,7 +705,7 @@ namespace Exiv2 {
|
||||
|
||||
if (rawExifData) free(rawExifData);
|
||||
} else if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_XMP)) {
|
||||
- io_->readOrThrow(payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
xmpPacket_.assign(reinterpret_cast<char*>(payload.pData_), payload.size_);
|
||||
if (xmpPacket_.size() > 0 && XmpParser::decode(xmpData_, xmpPacket_)) {
|
||||
#ifndef SUPPRESS_WARNINGS
|
||||
--
|
||||
2.23.0
|
||||
|
||||
123
backport-CVE-2021-29463.patch
Normal file
123
backport-CVE-2021-29463.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From 783b3a6ff15ed6f82a8f8e6c8a6f3b84a9b04d4b Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Backhouse <kevinbackhouse@github.com>
|
||||
Date: Mon, 19 Apr 2021 18:06:00 +0100
|
||||
Subject: [PATCH] Improve bound checking in WebPImage::doWriteMetadata()
|
||||
|
||||
---
|
||||
src/webpimage.cpp | 41 ++++++++++++++++++++++++++++++-----------
|
||||
1 file changed, 30 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/src/webpimage.cpp b/src/webpimage.cpp
|
||||
index c12e8fb..51a200b 100644
|
||||
--- a/src/webpimage.cpp
|
||||
+++ b/src/webpimage.cpp
|
||||
@@ -144,7 +144,7 @@ namespace Exiv2 {
|
||||
DataBuf chunkId(WEBP_TAG_SIZE+1);
|
||||
chunkId.pData_ [WEBP_TAG_SIZE] = '\0';
|
||||
|
||||
- io_->read(data, WEBP_TAG_SIZE * 3);
|
||||
+ readOrThrow(*io_, data, WEBP_TAG_SIZE * 3, Exiv2::kerCorruptedMetadata);
|
||||
uint64_t filesize = Exiv2::getULong(data + WEBP_TAG_SIZE, littleEndian);
|
||||
|
||||
/* Set up header */
|
||||
@@ -183,13 +183,20 @@ namespace Exiv2 {
|
||||
case we have any exif or xmp data, also check
|
||||
for any chunks with alpha frame/layer set */
|
||||
while ( !io_->eof() && (uint64_t) io_->tell() < filesize) {
|
||||
- io_->read(chunkId.pData_, WEBP_TAG_SIZE);
|
||||
- io_->read(size_buff, WEBP_TAG_SIZE);
|
||||
- long size = Exiv2::getULong(size_buff, littleEndian);
|
||||
+ readOrThrow(*io_, chunkId.pData_, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
+ readOrThrow(*io_, size_buff, WEBP_TAG_SIZE, Exiv2::kerCorruptedMetadata);
|
||||
+ const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian);
|
||||
+
|
||||
+ // Check that `size_u32` is safe to cast to `long`.
|
||||
+ enforce(size_u32 <= static_cast<size_t>(std::numeric_limits<unsigned int>::max()),
|
||||
+ Exiv2::kerCorruptedMetadata);
|
||||
+ const long size = static_cast<long>(size_u32);
|
||||
DataBuf payload(size);
|
||||
- io_->read(payload.pData_, payload.size_);
|
||||
- byte c;
|
||||
- if ( payload.size_ % 2 ) io_->read(&c,1);
|
||||
+ readOrThrow(*io_, payload.pData_, payload.size_, Exiv2::kerCorruptedMetadata);
|
||||
+ if ( payload.size_ % 2 ) {
|
||||
+ byte c;
|
||||
+ readOrThrow(*io_, &c, 1, Exiv2::kerCorruptedMetadata);
|
||||
+ }
|
||||
|
||||
/* Chunk with information about features
|
||||
used in the file. */
|
||||
@@ -197,6 +204,7 @@ namespace Exiv2 {
|
||||
has_vp8x = true;
|
||||
}
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X) && !has_size) {
|
||||
+ enforce(size >= 10, Exiv2::kerCorruptedMetadata);
|
||||
has_size = true;
|
||||
byte size_buf[WEBP_TAG_SIZE];
|
||||
|
||||
@@ -225,6 +233,7 @@ namespace Exiv2 {
|
||||
}
|
||||
#endif
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8) && !has_size) {
|
||||
+ enforce(size >= 10, Exiv2::kerCorruptedMetadata);
|
||||
has_size = true;
|
||||
byte size_buf[2];
|
||||
|
||||
@@ -242,11 +251,13 @@ namespace Exiv2 {
|
||||
|
||||
/* Chunk with with lossless image data. */
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8L) && !has_alpha) {
|
||||
+ enforce(size >= 5, Exiv2::kerCorruptedMetadata);
|
||||
if ((payload.pData_[5] & WEBP_VP8X_ALPHA_BIT) == WEBP_VP8X_ALPHA_BIT) {
|
||||
has_alpha = true;
|
||||
}
|
||||
}
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8L) && !has_size) {
|
||||
+ enforce(size >= 5, Exiv2::kerCorruptedMetadata);
|
||||
has_size = true;
|
||||
byte size_buf_w[2];
|
||||
byte size_buf_h[3];
|
||||
@@ -274,11 +285,13 @@ namespace Exiv2 {
|
||||
|
||||
/* Chunk with animation frame. */
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ANMF) && !has_alpha) {
|
||||
+ enforce(size >= 6, Exiv2::kerCorruptedMetadata);
|
||||
if ((payload.pData_[5] & 0x2) == 0x2) {
|
||||
has_alpha = true;
|
||||
}
|
||||
}
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_ANMF) && !has_size) {
|
||||
+ enforce(size >= 12, Exiv2::kerCorruptedMetadata);
|
||||
has_size = true;
|
||||
byte size_buf[WEBP_TAG_SIZE];
|
||||
|
||||
@@ -307,16 +320,22 @@ namespace Exiv2 {
|
||||
|
||||
io_->seek(12, BasicIo::beg);
|
||||
while ( !io_->eof() && (uint64_t) io_->tell() < filesize) {
|
||||
- io_->read(chunkId.pData_, 4);
|
||||
- io_->read(size_buff, 4);
|
||||
+ readOrThrow(*io_, chunkId.pData_, 4, Exiv2::kerCorruptedMetadata);
|
||||
+ readOrThrow(*io_, size_buff, 4, Exiv2::kerCorruptedMetadata);
|
||||
+
|
||||
+ const uint32_t size_u32 = Exiv2::getULong(size_buff, littleEndian);
|
||||
|
||||
- long size = Exiv2::getULong(size_buff, littleEndian);
|
||||
+ // Check that `size_u32` is safe to cast to `long`.
|
||||
+ enforce(size_u32 <= static_cast<size_t>(std::numeric_limits<unsigned int>::max()),
|
||||
+ Exiv2::kerCorruptedMetadata);
|
||||
+ const long size = static_cast<long>(size_u32);
|
||||
|
||||
DataBuf payload(size);
|
||||
- io_->read(payload.pData_, size);
|
||||
+ readOrThrow(*io_, payload.pData_, size, Exiv2::kerCorruptedMetadata);
|
||||
if ( io_->tell() % 2 ) io_->seek(+1,BasicIo::cur); // skip pad
|
||||
|
||||
if (equalsWebPTag(chunkId, WEBP_CHUNK_HEADER_VP8X)) {
|
||||
+ enforce(size >= 1, Exiv2::kerCorruptedMetadata);
|
||||
if (has_icc){
|
||||
payload.pData_[0] |= WEBP_VP8X_ICC_BIT;
|
||||
} else {
|
||||
--
|
||||
2.23.0
|
||||
|
||||
55
backport-CVE-2021-29464.patch
Normal file
55
backport-CVE-2021-29464.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From f9308839198aca5e68a65194f151a1de92398f54 Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Backhouse <kevinbackhouse@github.com>
|
||||
Date: Tue, 20 Apr 2021 12:04:13 +0100
|
||||
Subject: [PATCH] Better bounds checking in Jp2Image::encodeJp2Header()
|
||||
|
||||
---
|
||||
src/jp2image.cpp | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/src/jp2image.cpp b/src/jp2image.cpp
|
||||
index 0825d99..f9be021 100644
|
||||
--- a/src/jp2image.cpp
|
||||
+++ b/src/jp2image.cpp
|
||||
@@ -650,6 +650,7 @@ namespace Exiv2
|
||||
#ifdef DEBUG
|
||||
std::cout << "Jp2Image::encodeJp2Header subbox: "<< toAscii(subBox.type) << " length = " << subBox.length << std::endl;
|
||||
#endif
|
||||
+ enforce(subBox.length <= length - count, Exiv2::kerCorruptedMetadata);
|
||||
count += subBox.length;
|
||||
newBox.type = subBox.type;
|
||||
} else {
|
||||
@@ -658,12 +659,13 @@ namespace Exiv2
|
||||
count = length;
|
||||
}
|
||||
|
||||
- int32_t newlen = subBox.length;
|
||||
+ uint32_t newlen = subBox.length;
|
||||
if ( newBox.type == kJp2BoxTypeColorHeader ) {
|
||||
bWroteColor = true ;
|
||||
if ( ! iccProfileDefined() ) {
|
||||
const char* pad = "\x01\x00\x00\x00\x00\x00\x10\x00\x00\x05\x1cuuid";
|
||||
uint32_t psize = 15;
|
||||
+ enforce(newlen <= output.size_ - outlen, Exiv2::kerCorruptedMetadata);
|
||||
ul2Data((byte*)&newBox.length,psize ,bigEndian);
|
||||
ul2Data((byte*)&newBox.type ,newBox.type,bigEndian);
|
||||
::memcpy(output.pData_+outlen ,&newBox ,sizeof(newBox));
|
||||
@@ -672,6 +674,7 @@ namespace Exiv2
|
||||
} else {
|
||||
const char* pad = "\0x02\x00\x00";
|
||||
uint32_t psize = 3;
|
||||
+ enforce(newlen <= output.size_ - outlen, Exiv2::kerCorruptedMetadata);
|
||||
ul2Data((byte*)&newBox.length,psize+iccProfile_.size_,bigEndian);
|
||||
ul2Data((byte*)&newBox.type,newBox.type,bigEndian);
|
||||
::memcpy(output.pData_+outlen ,&newBox ,sizeof(newBox) );
|
||||
@@ -680,6 +683,7 @@ namespace Exiv2
|
||||
newlen = psize + iccProfile_.size_;
|
||||
}
|
||||
} else {
|
||||
+ enforce(newlen <= output.size_ - outlen, Exiv2::kerCorruptedMetadata);
|
||||
::memcpy(output.pData_+outlen,boxBuf.pData_+inlen,subBox.length);
|
||||
}
|
||||
|
||||
--
|
||||
2.23.0
|
||||
|
||||
24
backport-CVE-2021-29473.patch
Normal file
24
backport-CVE-2021-29473.patch
Normal file
@ -0,0 +1,24 @@
|
||||
From e6a0982f7cd9282052b6e3485a458d60629ffa0b Mon Sep 17 00:00:00 2001
|
||||
From: Kevin Backhouse <kevinbackhouse@github.com>
|
||||
Date: Fri, 23 Apr 2021 11:44:44 +0100
|
||||
Subject: [PATCH] Add bounds check in Jp2Image::doWriteMetadata().
|
||||
|
||||
---
|
||||
src/jp2image.cpp | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/src/jp2image.cpp b/src/jp2image.cpp
|
||||
index f9be021..40eca0d 100644
|
||||
--- a/src/jp2image.cpp
|
||||
+++ b/src/jp2image.cpp
|
||||
@@ -888,6 +888,7 @@ namespace Exiv2
|
||||
|
||||
case kJp2BoxTypeUuid:
|
||||
{
|
||||
+ enforce(boxBuf.size_ >= 24, Exiv2::kerCorruptedMetadata);
|
||||
if(memcmp(boxBuf.pData_ + 8, kJp2UuidExif, 16) == 0)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
--
|
||||
2.23.0
|
||||
|
||||
13
exiv2.spec
13
exiv2.spec
@ -1,6 +1,6 @@
|
||||
Name: exiv2
|
||||
Version: 0.26
|
||||
Release: 25
|
||||
Release: 26
|
||||
Summary: Exif, IPTC and XMP metadata and the ICC Profile
|
||||
License: GPLv2+
|
||||
URL: http://www.exiv2.org/
|
||||
@ -62,6 +62,11 @@ Patch6029: CVE-2021-3482.patch
|
||||
Patch6030: backport-CVE-2021-29457.patch
|
||||
Patch6031: backport-CVE-2021-29458.patch
|
||||
Patch6032: backport-CVE-2021-29470.patch
|
||||
Patch6033: backport-0001-CVE-2021-29463.patch
|
||||
Patch6034: backport-0002-CVE-2021-29463.patch
|
||||
Patch6035: backport-CVE-2021-29464.patch
|
||||
Patch6036: backport-CVE-2021-29463.patch
|
||||
Patch6037: backport-CVE-2021-29473.patch
|
||||
|
||||
Provides: exiv2-libs
|
||||
Obsoletes: exiv2-libs
|
||||
@ -125,6 +130,12 @@ test -x %{buildroot}%{_libdir}/libexiv2.so
|
||||
%{_datadir}/doc/html/
|
||||
|
||||
%changelog
|
||||
* Wed May 12 2021 wangkerong <wangkerong@huawei.com> - 0.26-26
|
||||
- Type:cves
|
||||
- ID:CVE-2021-29464 CVE-2021-29463 CVE-2021-29473
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2021-29464,CVE-2021-29463,CVE-2021-29473
|
||||
|
||||
* Sat May 08 2021 wangkerong <wangkerong@huawei.com> - 0.26-25
|
||||
- Type:cve
|
||||
- ID:CVE-2021-29470
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user