Compare commits
10 Commits
b751b36c3a
...
83a78a3787
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
83a78a3787 | ||
|
|
c9b0cb4933 | ||
|
|
6e34385447 | ||
|
|
cd9b6f07ea | ||
|
|
b8c8878d51 | ||
|
|
8a5b268b7a | ||
|
|
0538d98c5b | ||
|
|
44715e0f75 | ||
|
|
55903e6c99 | ||
|
|
34a400bd1c |
86
backport-CVE-2019-9278.patch
Normal file
86
backport-CVE-2019-9278.patch
Normal file
@ -0,0 +1,86 @@
|
||||
From 75aa73267fdb1e0ebfbc00369e7312bac43d0566 Mon Sep 17 00:00:00 2001
|
||||
From: Marcus Meissner <meissner@suse.de>
|
||||
Date: Sat, 18 Jan 2020 09:29:42 +0100
|
||||
Subject: [PATCH] fix CVE-2019-9278
|
||||
|
||||
avoid the use of unsafe integer overflow checking constructs (unsigned integer operations cannot overflow, so "u1 + u2 > u1" can be optimized away)
|
||||
|
||||
check for the actual sizes, which should also handle the overflows
|
||||
document other places google patched, but do not seem relevant due to other restrictions
|
||||
|
||||
fixes https://github.com/libexif/libexif/issues/26
|
||||
---
|
||||
libexif/exif-data.c | 28 ++++++++++++++++++----------
|
||||
1 file changed, 18 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/libexif/exif-data.c b/libexif/exif-data.c
|
||||
index a6f9c94f..6332cd1a 100644
|
||||
--- a/libexif/exif-data.c
|
||||
+++ b/libexif/exif-data.c
|
||||
@@ -192,9 +192,15 @@ exif_data_load_data_entry (ExifData *data, ExifEntry *entry,
|
||||
doff = offset + 8;
|
||||
|
||||
/* Sanity checks */
|
||||
- if ((doff + s < doff) || (doff + s < s) || (doff + s > size)) {
|
||||
+ if (doff >= size) {
|
||||
exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
|
||||
- "Tag data past end of buffer (%u > %u)", doff+s, size);
|
||||
+ "Tag starts past end of buffer (%u > %u)", doff, size);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (s > size - doff) {
|
||||
+ exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
|
||||
+ "Tag data goes past end of buffer (%u > %u)", doff+s, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -315,13 +321,14 @@ exif_data_load_data_thumbnail (ExifData *data, const unsigned char *d,
|
||||
unsigned int ds, ExifLong o, ExifLong s)
|
||||
{
|
||||
/* Sanity checks */
|
||||
- if ((o + s < o) || (o + s < s) || (o + s > ds) || (o > ds)) {
|
||||
- exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
|
||||
- "Bogus thumbnail offset (%u) or size (%u).",
|
||||
- o, s);
|
||||
+ if (o >= ds) {
|
||||
+ exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Bogus thumbnail offset (%u).", o);
|
||||
+ return;
|
||||
+ }
|
||||
+ if (s > ds - o) {
|
||||
+ exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Bogus thumbnail size (%u), max would be %u.", s, ds-o);
|
||||
return;
|
||||
}
|
||||
-
|
||||
if (data->data)
|
||||
exif_mem_free (data->priv->mem, data->data);
|
||||
if (!(data->data = exif_data_alloc (data, s))) {
|
||||
@@ -947,7 +954,7 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
|
||||
exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
|
||||
"IFD 0 at %i.", (int) offset);
|
||||
|
||||
- /* Sanity check the offset, being careful about overflow */
|
||||
+ /* ds is restricted to 16 bit above, so offset is restricted too, and offset+8 should not overflow. */
|
||||
if (offset > ds || offset + 6 + 2 > ds)
|
||||
return;
|
||||
|
||||
@@ -956,6 +963,7 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
|
||||
|
||||
/* IFD 1 offset */
|
||||
n = exif_get_short (d + 6 + offset, data->priv->order);
|
||||
+ /* offset < 2<<16, n is 16 bit at most, so this op will not overflow */
|
||||
if (offset + 6 + 2 + 12 * n + 4 > ds)
|
||||
return;
|
||||
|
||||
@@ -964,8 +972,8 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
|
||||
exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
|
||||
"IFD 1 at %i.", (int) offset);
|
||||
|
||||
- /* Sanity check. */
|
||||
- if (offset > ds || offset + 6 > ds) {
|
||||
+ /* Sanity check. ds is ensured to be above 6 above, offset is 16bit */
|
||||
+ if (offset > ds - 6) {
|
||||
exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
"ExifData", "Bogus offset of IFD1.");
|
||||
} else {
|
||||
|
||||
34
backport-CVE-2020-0093.patch
Normal file
34
backport-CVE-2020-0093.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 5ae5973bed1947f4d447dc80b76d5cefadd90133 Mon Sep 17 00:00:00 2001
|
||||
From: Marcus Meissner <marcus@jet.franken.de>
|
||||
Date: Sat, 16 May 2020 16:47:42 +0200
|
||||
Subject: [PATCH] libexif: Fix read buffer overflow (CVE-2020-0093)
|
||||
|
||||
Make sure the number of bytes being copied from doesn't exceed the
|
||||
source buffer size.
|
||||
|
||||
From Android repo:
|
||||
https://android.googlesource.com/platform/external/libexif/+/0335ffc17f9b9a4831c242bb08ea92f605fde7a6%5E%21/#F0
|
||||
|
||||
Test: testPocBug_148705132
|
||||
Bug: 148705132
|
||||
|
||||
fixes https://github.com/libexif/libexif/issues/42
|
||||
---
|
||||
libexif/exif-data.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libexif/exif-data.c b/libexif/exif-data.c
|
||||
index 6332cd1a..65ae93d5 100644
|
||||
--- a/libexif/exif-data.c
|
||||
+++ b/libexif/exif-data.c
|
||||
@@ -308,7 +308,9 @@ exif_data_save_data_entry (ExifData *data, ExifEntry *e,
|
||||
/* Write the data. Fill unneeded bytes with 0. Do not crash with
|
||||
* e->data is NULL */
|
||||
if (e->data) {
|
||||
- memcpy (*d + 6 + doff, e->data, s);
|
||||
+ unsigned int len = s;
|
||||
+ if (e->size < s) len = e->size;
|
||||
+ memcpy (*d + 6 + doff, e->data, len);
|
||||
} else {
|
||||
memset (*d + 6 + doff, 0, s);
|
||||
}
|
||||
58
backport-CVE-2020-0181_CVE-2020-0198.patch
Normal file
58
backport-CVE-2020-0181_CVE-2020-0198.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From ce03ad7ef4e8aeefce79192bf5b6f69fae396f0c Mon Sep 17 00:00:00 2001
|
||||
From: Marcus Meissner <marcus@jet.franken.de>
|
||||
Date: Mon, 8 Jun 2020 17:27:06 +0200
|
||||
Subject: [PATCH] fixed another unsigned integer overflow
|
||||
|
||||
first fixed by google in android fork,
|
||||
https://android.googlesource.com/platform/external/libexif/+/1e187b62682ffab5003c702657d6d725b4278f16%5E%21/#F0
|
||||
|
||||
(use a more generic overflow check method, also check second overflow instance.)
|
||||
|
||||
https://security-tracker.debian.org/tracker/CVE-2020-0198
|
||||
---
|
||||
libexif/exif-data.c | 10 ++++++----
|
||||
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/libexif/exif-data.c b/libexif/exif-data.c
|
||||
index 8b280d3a..b495726d 100644
|
||||
--- a/libexif/exif-data.c
|
||||
+++ b/libexif/exif-data.c
|
||||
@@ -47,6 +47,8 @@
|
||||
#undef JPEG_MARKER_APP1
|
||||
#define JPEG_MARKER_APP1 0xe1
|
||||
|
||||
+#define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
|
||||
+
|
||||
static const unsigned char ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00};
|
||||
|
||||
struct _ExifDataPrivate
|
||||
@@ -327,7 +329,7 @@ exif_data_load_data_thumbnail (ExifData *data, const unsigned char *d,
|
||||
exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Bogus thumbnail offset (%u).", o);
|
||||
return;
|
||||
}
|
||||
- if (s > ds - o) {
|
||||
+ if (CHECKOVERFLOW(o,ds,s)) {
|
||||
exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData", "Bogus thumbnail size (%u), max would be %u.", s, ds-o);
|
||||
return;
|
||||
}
|
||||
@@ -420,9 +422,9 @@ exif_data_load_data_content (ExifData *data, ExifIfd ifd,
|
||||
}
|
||||
|
||||
/* Read the number of entries */
|
||||
- if ((offset + 2 < offset) || (offset + 2 < 2) || (offset + 2 > ds)) {
|
||||
+ if (CHECKOVERFLOW(offset, ds, 2)) {
|
||||
exif_log (data->priv->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifData",
|
||||
- "Tag data past end of buffer (%u > %u)", offset+2, ds);
|
||||
+ "Tag data past end of buffer (%u+2 > %u)", offset, ds);
|
||||
return;
|
||||
}
|
||||
n = exif_get_short (d + offset, data->priv->order);
|
||||
@@ -431,7 +433,7 @@ exif_data_load_data_content (ExifData *data, ExifIfd ifd,
|
||||
offset += 2;
|
||||
|
||||
/* Check if we have enough data. */
|
||||
- if (offset + 12 * n > ds) {
|
||||
+ if (CHECKOVERFLOW(offset, ds, 12*n)) {
|
||||
n = (ds - offset) / 12;
|
||||
exif_log (data->priv->log, EXIF_LOG_CODE_DEBUG, "ExifData",
|
||||
"Short data; only loading %hu entries...", n);
|
||||
37
backport-CVE-2020-0452.patch
Normal file
37
backport-CVE-2020-0452.patch
Normal file
@ -0,0 +1,37 @@
|
||||
Backported of:
|
||||
|
||||
From 9266d14b5ca4e29b970fa03272318e5f99386e06 Mon Sep 17 00:00:00 2001
|
||||
From: Marcus Meissner <marcus@jet.franken.de>
|
||||
Date: Thu, 5 Nov 2020 09:50:08 +0100
|
||||
Subject: [PATCH] fixed a incorrect overflow check that could be optimized
|
||||
away.
|
||||
|
||||
inspired by:
|
||||
https://android.googlesource.com/platform/external/libexif/+/8e7345f3bc0bad06ac369d6cbc1124c8ceaf7d4b
|
||||
|
||||
https://source.android.com/security/bulletin/2020-11-01
|
||||
|
||||
CVE-2020-0452
|
||||
Index: libexif-0.6.21/libexif/exif-entry.c
|
||||
===================================================================
|
||||
--- libexif-0.6.21.orig/libexif/exif-entry.c
|
||||
+++ libexif-0.6.21/libexif/exif-entry.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
+#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
@@ -1376,8 +1377,8 @@ exif_entry_get_value (ExifEntry *e, char
|
||||
case EXIF_TAG_XP_KEYWORDS:
|
||||
case EXIF_TAG_XP_SUBJECT:
|
||||
{
|
||||
- /* Sanity check the size to prevent overflow */
|
||||
- if (e->size+sizeof(unsigned short) < e->size) break;
|
||||
+ /* Sanity check the size to prevent overflow. Note EXIF files are 64kb at most. */
|
||||
+ if (e->size >= 65536 - sizeof(uint16_t)*2) break;
|
||||
|
||||
/* The tag may not be U+0000-terminated , so make a local
|
||||
U+0000-terminated copy before converting it */
|
||||
304
backport-CVE-2020-13112.patch
Normal file
304
backport-CVE-2020-13112.patch
Normal file
@ -0,0 +1,304 @@
|
||||
From 435e21f05001fb03f9f186fa7cbc69454afd00d1 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 | 19 +++++++++++++++---
|
||||
libexif/fuji/exif-mnote-data-fuji.c | 23 ++++++++++++++++------
|
||||
libexif/olympus/exif-mnote-data-olympus.c | 24 ++++++++++++++++-------
|
||||
libexif/pentax/exif-mnote-data-pentax.c | 18 +++++++++++++----
|
||||
4 files changed, 64 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/libexif/canon/exif-mnote-data-canon.c b/libexif/canon/exif-mnote-data-canon.c
|
||||
index 9cea4e4..9cfe781 100644
|
||||
--- a/libexif/canon/exif-mnote-data-canon.c
|
||||
+++ b/libexif/canon/exif-mnote-data-canon.c
|
||||
@@ -35,6 +35,8 @@
|
||||
/* Total size limit to prevent abuse by DoS */
|
||||
#define FAILSAFE_SIZE_MAX 1000000L
|
||||
|
||||
+#define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))
|
||||
+
|
||||
static void
|
||||
exif_mnote_data_canon_clear (ExifMnoteDataCanon *n)
|
||||
{
|
||||
@@ -213,7 +215,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;
|
||||
@@ -238,7 +240,7 @@ exif_mnote_data_canon_load (ExifMnoteData *ne,
|
||||
for (i = c, o = datao; i; --i, o += 12) {
|
||||
size_t s;
|
||||
memset(&n->entries[tcount], 0, sizeof(MnoteCanonEntry));
|
||||
- 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;
|
||||
@@ -253,6 +255,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).
|
||||
@@ -269,7 +281,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 efcf654..08bee21 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,8 +197,9 @@ exif_mnote_data_fuji_load (ExifMnoteData *en,
|
||||
tcount = 0;
|
||||
for (i = c, o = datao; i; --i, o += 12) {
|
||||
size_t s;
|
||||
+
|
||||
memset(&n->entries[tcount], 0, sizeof(MnoteFujiEntry));
|
||||
- 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;
|
||||
@@ -211,6 +214,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).
|
||||
@@ -222,8 +234,7 @@ 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 9bf0855..45e4bc5 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;
|
||||
@@ -431,7 +434,7 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
|
||||
for (i = c, o = o2; i; --i, o += 12) {
|
||||
size_t s;
|
||||
memset(&n->entries[tcount], 0, sizeof(MnoteOlympusEntry));
|
||||
- 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;
|
||||
@@ -452,6 +455,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).
|
||||
@@ -470,7 +481,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,
|
||||
@@ -479,8 +490,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 1de77b8..7312827 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;
|
||||
@@ -278,7 +280,7 @@ exif_mnote_data_pentax_load (ExifMnoteData *en,
|
||||
for (i = c, o = datao; i; --i, o += 12) {
|
||||
size_t s;
|
||||
memset(&n->entries[tcount], 0, sizeof(MnotePentaxEntry));
|
||||
- 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;
|
||||
@@ -293,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).
|
||||
@@ -305,8 +316,7 @@ 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.27.0
|
||||
|
||||
58
backport-CVE-2020-13114.patch
Normal file
58
backport-CVE-2020-13114.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From eeec66abade83264169872acfbe14ed0e1e68d9d Mon Sep 17 00:00:00 2001
|
||||
From: yangcheng1203 <yangcheng87@huawei.com>
|
||||
Date: Mon, 26 Jul 2021 14:37:06 +0800
|
||||
Subject: [PATCH] CVE-2020-13114
|
||||
|
||||
---
|
||||
libexif/canon/exif-mnote-data-canon.c | 21 +++++++++++++++++++++
|
||||
1 file changed, 21 insertions(+)
|
||||
|
||||
diff --git a/libexif/canon/exif-mnote-data-canon.c b/libexif/canon/exif-mnote-data-canon.c
|
||||
index eb53598..3d8c790 100644
|
||||
--- a/libexif/canon/exif-mnote-data-canon.c
|
||||
+++ b/libexif/canon/exif-mnote-data-canon.c
|
||||
@@ -32,6 +32,9 @@
|
||||
|
||||
#define DEBUG
|
||||
|
||||
+/* Total size limit to prevent abuse by DoS */
|
||||
+#define FAILSAFE_SIZE_MAX 1000000L
|
||||
+
|
||||
static void
|
||||
exif_mnote_data_canon_clear (ExifMnoteDataCanon *n)
|
||||
{
|
||||
@@ -202,6 +205,7 @@ exif_mnote_data_canon_load (ExifMnoteData *ne,
|
||||
ExifMnoteDataCanon *n = (ExifMnoteDataCanon *) ne;
|
||||
ExifShort c;
|
||||
size_t i, tcount, o, datao;
|
||||
+ long failsafe_size = 0;
|
||||
|
||||
if (!n || !buf || !buf_size) {
|
||||
exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
@@ -280,6 +284,23 @@ exif_mnote_data_canon_load (ExifMnoteData *ne,
|
||||
memcpy (n->entries[tcount].data, buf + dataofs, s);
|
||||
}
|
||||
|
||||
+ /* Track the size of decoded tag data. A malicious file could
|
||||
+ * be crafted to cause extremely large values here without
|
||||
+ * tripping any buffer range checks. This is especially bad
|
||||
+ * with the libexif representation of Canon MakerNotes because
|
||||
+ * some arrays are turned into individual tags that the
|
||||
+ * application must loop around. */
|
||||
+ failsafe_size += mnote_canon_entry_count_values(&n->entries[tcount]);
|
||||
+
|
||||
+ if (failsafe_size > FAILSAFE_SIZE_MAX) {
|
||||
+ /* Abort if the total size of the data in the tags extraordinarily large, */
|
||||
+ exif_mem_free (ne->mem, n->entries[tcount].data);
|
||||
+ exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA,
|
||||
+ "ExifMnoteCanon", "Failsafe tag size overflow (%lu > %ld)",
|
||||
+ failsafe_size, FAILSAFE_SIZE_MAX);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
/* Tag was successfully parsed */
|
||||
++tcount;
|
||||
}
|
||||
--
|
||||
1.8.3.1
|
||||
|
||||
34
backport-fuzz-stack-overflow.patch
Normal file
34
backport-fuzz-stack-overflow.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 49a74b371c322a1e55e242a230a7bb577ebe065b Mon Sep 17 00:00:00 2001
|
||||
From: Marcus Meissner <marcus@jet.franken.de>
|
||||
Date: Mon, 6 Sep 2021 08:42:56 +0200
|
||||
Subject: [PATCH] replace tail recursion by direct loop, in case the compiler
|
||||
does not translate it into a tail recursion it could be used to cause stack
|
||||
overruns (oss-fuzz)
|
||||
|
||||
---
|
||||
libexif/exif-loader.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/libexif/exif-loader.c b/libexif/exif-loader.c
|
||||
index e376465..5c48faf 100644
|
||||
--- a/libexif/exif-loader.c
|
||||
+++ b/libexif/exif-loader.c
|
||||
@@ -154,6 +154,7 @@ exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
+begin:
|
||||
if (!eld || (len && !buf))
|
||||
return 0;
|
||||
|
||||
@@ -310,7 +311,7 @@ exif_loader_write (ExifLoader *eld, unsigned char *buf, unsigned int len)
|
||||
* to read all data we need. Fill it with new data.
|
||||
*/
|
||||
eld->b_len = 0;
|
||||
- return exif_loader_write (eld, buf, len);
|
||||
+ goto begin;
|
||||
}
|
||||
|
||||
ExifLoader *
|
||||
--
|
||||
2.27.0
|
||||
38
backport-fuzz-timeout-and-out-of-memory.patch
Normal file
38
backport-fuzz-timeout-and-out-of-memory.patch
Normal file
@ -0,0 +1,38 @@
|
||||
From e93be918878ab98ee45430858e96cb302ffee2bc Mon Sep 17 00:00:00 2001
|
||||
From: Marcus Meissner <marcus@jet.franken.de>
|
||||
Date: Sat, 30 Jan 2021 14:06:08 +0100
|
||||
Subject: [PATCH] limit the amount of tags we allow in the makernote here.
|
||||
|
||||
due to memory layout the max amount of 65536 tags could be used
|
||||
to exhaust lots of memory and time during parsing,
|
||||
as each tag can reuse the same memory range.
|
||||
|
||||
(Memory usage DOS (2GB+) and compute dos (several minutes on fast machine, but not endless))
|
||||
|
||||
This fixes OSS-FUZZ issue 27280.
|
||||
|
||||
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=27280
|
||||
---
|
||||
libexif/olympus/exif-mnote-data-olympus.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/libexif/olympus/exif-mnote-data-olympus.c b/libexif/olympus/exif-mnote-data-olympus.c
|
||||
index 45e4bc5..0c68d51 100644
|
||||
--- a/libexif/olympus/exif-mnote-data-olympus.c
|
||||
+++ b/libexif/olympus/exif-mnote-data-olympus.c
|
||||
@@ -419,6 +419,13 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
|
||||
c = exif_get_short (buf + o2, n->order);
|
||||
o2 += 2;
|
||||
|
||||
+ /* Just use an arbitrary max tag limit here to avoid needing to much memory or time. There are 150 named tags currently.
|
||||
+ * The format allows specifying the same range of memory as often as it can, so this multiplies quickly. */
|
||||
+ if (c > 300) {
|
||||
+ exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, "ExifMnoteOlympus", "Too much tags (%d) in Olympus MakerNote", c);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
/* Remove any old entries */
|
||||
exif_mnote_data_olympus_clear (n);
|
||||
|
||||
--
|
||||
2.27.0
|
||||
33
libexif.spec
33
libexif.spec
@ -1,7 +1,7 @@
|
||||
Name: libexif
|
||||
Summary: Library for extracting extra information from image files
|
||||
Version: 0.6.21
|
||||
Release: 22
|
||||
Release: 26
|
||||
License: LGPLv2+
|
||||
URL: https://libexif.github.io/
|
||||
Source0: https://downloads.sourceforge.net/%{name}/%{name}-%{version}.tar.bz2
|
||||
@ -14,8 +14,16 @@ Patch6004: libexif-bugfix-integer-overflow.patch
|
||||
Patch6005: libexif-bugfix-unsigned-int.patch
|
||||
Patch6006: libexif-bugfix-overflow.patch
|
||||
Patch6007: libexif-bugfix-large-loop-in-exif_loader_get_data.patch
|
||||
Patch6008: CVE-2020-13113.patch
|
||||
Patch6008: backport-CVE-2020-13113.patch
|
||||
Patch6009: backport-CVE-2020-13114.patch
|
||||
Patch9001: libexif-bugfix-integer-overflow-pentax.patch
|
||||
Patch6010: backport-CVE-2020-13112.patch
|
||||
Patch6011: backport-CVE-2019-9278.patch
|
||||
Patch6012: backport-CVE-2020-0181_CVE-2020-0198.patch
|
||||
Patch6013: backport-CVE-2020-0093.patch
|
||||
Patch6014: backport-fuzz-stack-overflow.patch
|
||||
Patch6015: backport-fuzz-timeout-and-out-of-memory.patch
|
||||
Patch6016: backport-CVE-2020-0452.patch
|
||||
|
||||
BuildRequires: autoconf automake doxygen gettext-devel libtool pkgconfig git
|
||||
|
||||
@ -73,11 +81,26 @@ make check
|
||||
%doc libexif-api.html NEWS
|
||||
|
||||
%changelog
|
||||
* Mon Jul 26 202 yangcheng <yangcheng87@huawei.com> - 0.6.21-22
|
||||
* Mon Jan 15 2024 zhouwenpei <zhouwenpei1@h-partners.com> - 0.6.21-26
|
||||
- fix CVE-2020-0452
|
||||
|
||||
* Tue Oct 18 2022 wangkerong <wangkerong@h-partners.com> - 0.6.21-25
|
||||
- fix fuzz test error
|
||||
|
||||
* Mon Oct 17 2022 wangkerong <wangkerong@h-partners.com> - 0.6.21-24
|
||||
- fix CVE-2019-9278,CVE-2020-0181,CVE-2020-0198,CVE-2020-0093
|
||||
|
||||
* Tue Sep 28 2021 wangkerong <wangkerong@huawei.com> - 0.6.21-23
|
||||
- Type:CVE
|
||||
- Id:CVE-2020-13113
|
||||
- Id:CVE-2020-13112
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2020-13113
|
||||
- DESC:fix CVE-2020-13112
|
||||
|
||||
* Mon Jul 26 2021 yangcheng <yangcheng87@huawei.com> - 0.6.21-22
|
||||
- Type:CVE
|
||||
- Id:CVE-2020-13113,CVE-2020-13114
|
||||
- SUG:NA
|
||||
- DESC:fix CVE-2020-13113 CVE-2020-13114
|
||||
|
||||
* Sat Aug 8 2020 yanan <yanan@huawei.com> - 0.6.21-21
|
||||
- Type:bugfix
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user