import libexif-0.6.21-17.el8_2

This commit is contained in:
CentOS Sources 2020-06-15 08:13:38 -04:00 committed by Andrew Lukoshko
parent 4306388686
commit fbbda3048a
2 changed files with 321 additions and 2 deletions

View File

@ -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

View File

@ -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