import libexif-0.6.21-17.el8_2
This commit is contained in:
parent
4306388686
commit
fbbda3048a
|
@ -0,0 +1,312 @@
|
|||
From d74c049a9d1e3e8c10150d50c401747250ae221c Mon Sep 17 00:00:00 2001
|
||||
From: Dan Fandrich <dan@coneharvesters.com>
|
||||
Date: Sat, 16 May 2020 17:32:28 +0200
|
||||
Subject: [PATCH] Fix MakerNote tag size overflow issues at read time.
|
||||
|
||||
Check for a size overflow while reading tags, which ensures that the
|
||||
size is always consistent for the given components and type of the
|
||||
entry, making checking further down superfluous.
|
||||
|
||||
This provides an alternate fix for
|
||||
https://sourceforge.net/p/libexif/bugs/125/ CVE-2016-6328 and for all
|
||||
the MakerNote types. Likely, this makes both commits 41bd0423 and
|
||||
89e5b1c1 redundant as it ensures that MakerNote entries are well-formed
|
||||
when they're populated.
|
||||
|
||||
Some improvements on top by Marcus Meissner <marcus@jet.franken.de>
|
||||
|
||||
CVE-2020-13112
|
||||
---
|
||||
libexif/canon/exif-mnote-data-canon.c | 22 +++++++++++++++++----
|
||||
libexif/fuji/exif-mnote-data-fuji.c | 24 +++++++++++++++++------
|
||||
libexif/olympus/exif-mnote-data-olympus.c | 24 ++++++++++++++++-------
|
||||
libexif/pentax/exif-mnote-data-pentax.c | 20 +++++++++++++++----
|
||||
4 files changed, 69 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/libexif/canon/exif-mnote-data-canon.c b/libexif/canon/exif-mnote-data-canon.c
|
||||
index eb53598..622c86b 100644
|
||||
--- a/libexif/canon/exif-mnote-data-canon.c
|
||||
+++ b/libexif/canon/exif-mnote-data-canon.c
|
||||
@@ -32,6 +32,8 @@
|
||||
|
||||
#define DEBUG
|
||||
|
||||
+#define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
|
||||
+
|
||||
static void
|
||||
exif_mnote_data_canon_clear (ExifMnoteDataCanon *n)
|
||||
{
|
||||
@@ -209,7 +211,7 @@ exif_mnote_data_canon_load (ExifMnoteData *ne,
|
||||
return;
|
||||
}
|
||||
datao = 6 + n->offset;
|
||||
- if ((datao + 2 < datao) || (datao + 2 < 2) || (datao + 2 > buf_size)) {
|
||||
+ if (CHECKOVERFLOW(datao, buf_size, 2)) {
|
||||
exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
"ExifMnoteCanon", "Short MakerNote");
|
||||
return;
|
||||
@@ -233,11 +235,12 @@ exif_mnote_data_canon_load (ExifMnoteData *ne,
|
||||
tcount = 0;
|
||||
for (i = c, o = datao; i; --i, o += 12) {
|
||||
size_t s;
|
||||
- if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) {
|
||||
+
|
||||
+ if (CHECKOVERFLOW(o,buf_size,12)) {
|
||||
exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
"ExifMnoteCanon", "Short MakerNote");
|
||||
break;
|
||||
- }
|
||||
+ }
|
||||
|
||||
n->entries[tcount].tag = exif_get_short (buf + o, n->order);
|
||||
n->entries[tcount].format = exif_get_short (buf + o + 2, n->order);
|
||||
@@ -248,6 +251,16 @@ exif_mnote_data_canon_load (ExifMnoteData *ne,
|
||||
"Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
|
||||
mnote_canon_tag_get_name (n->entries[tcount].tag));
|
||||
|
||||
+ /* Check if we overflow the multiplication. Use buf_size as the max size for integer overflow detection,
|
||||
+ * we will check the buffer sizes closer later. */
|
||||
+ if ( exif_format_get_size (n->entries[tcount].format) &&
|
||||
+ buf_size / exif_format_get_size (n->entries[tcount].format) < n->entries[tcount].components
|
||||
+ ) {
|
||||
+ exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
+ "ExifMnoteCanon", "Tag size overflow detected (%u * %lu)", exif_format_get_size (n->entries[tcount].format), n->entries[tcount].components);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
/*
|
||||
* Size? If bigger than 4 bytes, the actual data is not
|
||||
* in the entry but somewhere else (offset).
|
||||
@@ -264,7 +277,8 @@ exif_mnote_data_canon_load (ExifMnoteData *ne,
|
||||
} else {
|
||||
size_t dataofs = o + 8;
|
||||
if (s > 4) dataofs = exif_get_long (buf + dataofs, n->order) + 6;
|
||||
- if ((dataofs + s < s) || (dataofs + s < dataofs) || (dataofs + s > buf_size)) {
|
||||
+
|
||||
+ if (CHECKOVERFLOW(dataofs, buf_size, s)) {
|
||||
exif_log (ne->log, EXIF_LOG_CODE_DEBUG,
|
||||
"ExifMnoteCanon",
|
||||
"Tag data past end of buffer (%u > %u)",
|
||||
diff --git a/libexif/fuji/exif-mnote-data-fuji.c b/libexif/fuji/exif-mnote-data-fuji.c
|
||||
index 9514654..a0bcb67 100644
|
||||
--- a/libexif/fuji/exif-mnote-data-fuji.c
|
||||
+++ b/libexif/fuji/exif-mnote-data-fuji.c
|
||||
@@ -28,6 +28,8 @@
|
||||
|
||||
#include "exif-mnote-data-fuji.h"
|
||||
|
||||
+#define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
|
||||
+
|
||||
struct _MNoteFujiDataPrivate {
|
||||
ExifByteOrder order;
|
||||
};
|
||||
@@ -162,16 +164,16 @@ exif_mnote_data_fuji_load (ExifMnoteData *en,
|
||||
return;
|
||||
}
|
||||
datao = 6 + n->offset;
|
||||
- if ((datao + 12 < datao) || (datao + 12 < 12) || (datao + 12 > buf_size)) {
|
||||
+ if (CHECKOVERFLOW(datao, buf_size, 12)) {
|
||||
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
"ExifMnoteDataFuji", "Short MakerNote");
|
||||
return;
|
||||
}
|
||||
|
||||
n->order = EXIF_BYTE_ORDER_INTEL;
|
||||
+
|
||||
datao += exif_get_long (buf + datao + 8, EXIF_BYTE_ORDER_INTEL);
|
||||
- if ((datao + 2 < datao) || (datao + 2 < 2) ||
|
||||
- (datao + 2 > buf_size)) {
|
||||
+ if (CHECKOVERFLOW(datao, buf_size, 2)) {
|
||||
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
"ExifMnoteDataFuji", "Short MakerNote");
|
||||
return;
|
||||
@@ -195,7 +197,8 @@ exif_mnote_data_fuji_load (ExifMnoteData *en,
|
||||
tcount = 0;
|
||||
for (i = c, o = datao; i; --i, o += 12) {
|
||||
size_t s;
|
||||
- if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) {
|
||||
+
|
||||
+ if (CHECKOVERFLOW(o, buf_size, 12)) {
|
||||
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
"ExifMnoteDataFuji", "Short MakerNote");
|
||||
break;
|
||||
@@ -210,6 +213,15 @@ exif_mnote_data_fuji_load (ExifMnoteData *en,
|
||||
"Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
|
||||
mnote_fuji_tag_get_name (n->entries[tcount].tag));
|
||||
|
||||
+ /* Check if we overflow the multiplication. Use buf_size as the max size for integer overflow detection,
|
||||
+ * we will check the buffer sizes closer later. */
|
||||
+ if ( exif_format_get_size (n->entries[tcount].format) &&
|
||||
+ buf_size / exif_format_get_size (n->entries[tcount].format) < n->entries[tcount].components
|
||||
+ ) {
|
||||
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
+ "ExifMnoteDataFuji", "Tag size overflow detected (%u * %lu)", exif_format_get_size (n->entries[tcount].format), n->entries[tcount].components);
|
||||
+ continue;
|
||||
+ }
|
||||
/*
|
||||
* Size? If bigger than 4 bytes, the actual data is not
|
||||
* in the entry but somewhere else (offset).
|
||||
@@ -221,8 +233,8 @@ exif_mnote_data_fuji_load (ExifMnoteData *en,
|
||||
if (s > 4)
|
||||
/* The data in this case is merely a pointer */
|
||||
dataofs = exif_get_long (buf + dataofs, n->order) + 6 + n->offset;
|
||||
- if ((dataofs + s < dataofs) || (dataofs + s < s) ||
|
||||
- (dataofs + s >= buf_size)) {
|
||||
+
|
||||
+ if (CHECKOVERFLOW(dataofs, buf_size, s)) {
|
||||
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
"ExifMnoteDataFuji", "Tag data past end of "
|
||||
"buffer (%u >= %u)", dataofs + s, buf_size);
|
||||
diff --git a/libexif/olympus/exif-mnote-data-olympus.c b/libexif/olympus/exif-mnote-data-olympus.c
|
||||
index 099671d..4d158ce 100644
|
||||
--- a/libexif/olympus/exif-mnote-data-olympus.c
|
||||
+++ b/libexif/olympus/exif-mnote-data-olympus.c
|
||||
@@ -37,6 +37,8 @@
|
||||
*/
|
||||
/*#define EXIF_OVERCOME_SANYO_OFFSET_BUG */
|
||||
|
||||
+#define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
|
||||
+
|
||||
static enum OlympusVersion
|
||||
exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
|
||||
unsigned int buf_size);
|
||||
@@ -247,7 +249,7 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
|
||||
return;
|
||||
}
|
||||
o2 = 6 + n->offset; /* Start of interesting data */
|
||||
- if ((o2 + 10 < o2) || (o2 + 10 < 10) || (o2 + 10 > buf_size)) {
|
||||
+ if (CHECKOVERFLOW(o2,buf_size,10)) {
|
||||
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
"ExifMnoteDataOlympus", "Short MakerNote");
|
||||
return;
|
||||
@@ -303,6 +305,7 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
|
||||
/* Olympus S760, S770 */
|
||||
datao = o2;
|
||||
o2 += 8;
|
||||
+ if (CHECKOVERFLOW(o2,buf_size,4)) return;
|
||||
exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
|
||||
"Parsing Olympus maker note v2 (0x%02x, %02x, %02x, %02x)...",
|
||||
buf[o2], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]);
|
||||
@@ -346,7 +349,7 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
|
||||
|
||||
case nikonV2:
|
||||
o2 += 6;
|
||||
- if (o2 >= buf_size) return;
|
||||
+ if (CHECKOVERFLOW(o2,buf_size,12)) return;
|
||||
exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
|
||||
"Parsing Nikon maker note v2 (0x%02x, %02x, %02x, "
|
||||
"%02x, %02x, %02x, %02x, %02x)...",
|
||||
@@ -406,7 +409,7 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
|
||||
}
|
||||
|
||||
/* Sanity check the offset */
|
||||
- if ((o2 + 2 < o2) || (o2 + 2 < 2) || (o2 + 2 > buf_size)) {
|
||||
+ if (CHECKOVERFLOW(o2,buf_size,2)) {
|
||||
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
"ExifMnoteOlympus", "Short MakerNote");
|
||||
return;
|
||||
@@ -430,7 +433,7 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
|
||||
tcount = 0;
|
||||
for (i = c, o = o2; i; --i, o += 12) {
|
||||
size_t s;
|
||||
- if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) {
|
||||
+ if (CHECKOVERFLOW(o, buf_size, 12)) {
|
||||
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
"ExifMnoteOlympus", "Short MakerNote");
|
||||
break;
|
||||
@@ -451,6 +454,14 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
|
||||
n->entries[tcount].components,
|
||||
(int)exif_format_get_size(n->entries[tcount].format)); */
|
||||
|
||||
+ /* Check if we overflow the multiplication. Use buf_size as the max size for integer overflow detection,
|
||||
+ * we will check the buffer sizes closer later. */
|
||||
+ if (exif_format_get_size (n->entries[tcount].format) &&
|
||||
+ buf_size / exif_format_get_size (n->entries[tcount].format) < n->entries[tcount].components
|
||||
+ ) {
|
||||
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifMnoteOlympus", "Tag size overflow detected (%u * %lu)", exif_format_get_size (n->entries[tcount].format), n->entries[tcount].components);
|
||||
+ continue;
|
||||
+ }
|
||||
/*
|
||||
* Size? If bigger than 4 bytes, the actual data is not
|
||||
* in the entry but somewhere else (offset).
|
||||
@@ -469,7 +480,7 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
|
||||
* tag in its MakerNote. The offset is actually the absolute
|
||||
* position in the file instead of the position within the IFD.
|
||||
*/
|
||||
- if (dataofs + s > buf_size && n->version == sanyoV1) {
|
||||
+ if (dataofs > (buf_size - s) && n->version == sanyoV1) {
|
||||
/* fix pointer */
|
||||
dataofs -= datao + 6;
|
||||
exif_log (en->log, EXIF_LOG_CODE_DEBUG,
|
||||
@@ -478,8 +489,7 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
|
||||
}
|
||||
#endif
|
||||
}
|
||||
- if ((dataofs + s < dataofs) || (dataofs + s < s) ||
|
||||
- (dataofs + s > buf_size)) {
|
||||
+ if (CHECKOVERFLOW(dataofs, buf_size, s)) {
|
||||
exif_log (en->log, EXIF_LOG_CODE_DEBUG,
|
||||
"ExifMnoteOlympus",
|
||||
"Tag data past end of buffer (%u > %u)",
|
||||
diff --git a/libexif/pentax/exif-mnote-data-pentax.c b/libexif/pentax/exif-mnote-data-pentax.c
|
||||
index 757bb72..319d4c6 100644
|
||||
--- a/libexif/pentax/exif-mnote-data-pentax.c
|
||||
+++ b/libexif/pentax/exif-mnote-data-pentax.c
|
||||
@@ -28,6 +28,8 @@
|
||||
#include <libexif/exif-byte-order.h>
|
||||
#include <libexif/exif-utils.h>
|
||||
|
||||
+#define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
|
||||
+
|
||||
static void
|
||||
exif_mnote_data_pentax_clear (ExifMnoteDataPentax *n)
|
||||
{
|
||||
@@ -224,7 +226,7 @@ exif_mnote_data_pentax_load (ExifMnoteData *en,
|
||||
return;
|
||||
}
|
||||
datao = 6 + n->offset;
|
||||
- if ((datao + 8 < datao) || (datao + 8 < 8) || (datao + 8 > buf_size)) {
|
||||
+ if (CHECKOVERFLOW(datao, buf_size, 8)) {
|
||||
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
"ExifMnoteDataPentax", "Short MakerNote");
|
||||
return;
|
||||
@@ -277,7 +279,8 @@ exif_mnote_data_pentax_load (ExifMnoteData *en,
|
||||
tcount = 0;
|
||||
for (i = c, o = datao; i; --i, o += 12) {
|
||||
size_t s;
|
||||
- if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) {
|
||||
+
|
||||
+ if (CHECKOVERFLOW(o,buf_size,12)) {
|
||||
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
"ExifMnoteDataPentax", "Short MakerNote");
|
||||
break;
|
||||
@@ -292,6 +295,15 @@ exif_mnote_data_pentax_load (ExifMnoteData *en,
|
||||
"Loading entry 0x%x ('%s')...", n->entries[tcount].tag,
|
||||
mnote_pentax_tag_get_name (n->entries[tcount].tag));
|
||||
|
||||
+ /* Check if we overflow the multiplication. Use buf_size as the max size for integer overflow detection,
|
||||
+ * we will check the buffer sizes closer later. */
|
||||
+ if ( exif_format_get_size (n->entries[tcount].format) &&
|
||||
+ buf_size / exif_format_get_size (n->entries[tcount].format) < n->entries[tcount].components
|
||||
+ ) {
|
||||
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
+ "ExifMnoteDataPentax", "Tag size overflow detected (%u * %lu)", exif_format_get_size (n->entries[tcount].format), n->entries[tcount].components);
|
||||
+ break;
|
||||
+ }
|
||||
/*
|
||||
* Size? If bigger than 4 bytes, the actual data is not
|
||||
* in the entry but somewhere else (offset).
|
||||
@@ -304,8 +316,8 @@ exif_mnote_data_pentax_load (ExifMnoteData *en,
|
||||
if (s > 4)
|
||||
/* The data in this case is merely a pointer */
|
||||
dataofs = exif_get_long (buf + dataofs, n->order) + 6;
|
||||
- if ((dataofs + s < dataofs) || (dataofs + s < s) ||
|
||||
- (dataofs + s > buf_size)) {
|
||||
+
|
||||
+ if (CHECKOVERFLOW(dataofs, buf_size, s)) {
|
||||
exif_log (en->log, EXIF_LOG_CODE_DEBUG,
|
||||
"ExifMnoteDataPentax", "Tag data past end "
|
||||
"of buffer (%u > %u)", dataofs + s, buf_size);
|
||||
--
|
||||
2.26.2
|
||||
|
|
@ -1,13 +1,15 @@
|
|||
Summary: Library for extracting extra information from image files
|
||||
Name: libexif
|
||||
Version: 0.6.21
|
||||
Release: 16%{?dist}
|
||||
Release: 17%{?dist}
|
||||
Group: System Environment/Libraries
|
||||
License: LGPLv2+
|
||||
URL: http://libexif.sourceforge.net/
|
||||
Source0: http://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.bz2
|
||||
# CVE-2016-6328, RHBZ#1366239
|
||||
Patch0: 41bd04234b104312f54d25822f68738ba8d7133d.patch
|
||||
Patch0: 41bd04234b104312f54d25822f68738ba8d7133d.patch
|
||||
# RHBZ#1840344
|
||||
Patch1: CVE-2020-13112.patch
|
||||
|
||||
BuildRequires: autoconf
|
||||
BuildRequires: automake
|
||||
|
@ -42,6 +44,7 @@ API Documentation for programmers wishing to use libexif in their programs.
|
|||
%prep
|
||||
%setup -q
|
||||
%patch0 -p1
|
||||
%patch1 -p1
|
||||
|
||||
%build
|
||||
autoreconf -fiv
|
||||
|
@ -75,6 +78,10 @@ make check
|
|||
%doc libexif-api.html
|
||||
|
||||
%changelog
|
||||
* Mon Jun 01 2020 Michael Catanzaro <mcatanzaro@redhat.com> - 0.6.21-17
|
||||
- Add patch for CVE-2020-13112
|
||||
- Resolves: #1840952
|
||||
|
||||
* Wed Feb 07 2018 Fedora Release Engineering <releng@fedoraproject.org> - 0.6.21-16
|
||||
- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
|
||||
|
||||
|
|
Loading…
Reference in New Issue