Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(915)

Unified Diff: libexif/olympus/exif-mnote-data-olympus.c

Issue 1585593002: libexif: Fix out of bound reads in exif_mnote_data_olympus_load(). (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/libexif/sources.git@master
Patch Set: address comments Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: libexif/olympus/exif-mnote-data-olympus.c
diff --git a/libexif/olympus/exif-mnote-data-olympus.c b/libexif/olympus/exif-mnote-data-olympus.c
index 099671de8d79afb9164aa90e2f450af353bfc319..617826b8ae5701358b77f0ba46abfbb4f8055903 100644
--- a/libexif/olympus/exif-mnote-data-olympus.c
+++ b/libexif/olympus/exif-mnote-data-olympus.c
@@ -37,6 +37,16 @@
*/
/*#define EXIF_OVERCOME_SANYO_OFFSET_BUG */
+static int will_overflow(size_t num1, size_t num2)
+{
+ return num1 > (size_t)-1 - num2;
+}
+
+static int exceeds_buffer(size_t buf_size, size_t offset, size_t len)
+{
+ return buf_size < len || offset > buf_size - len;
+}
+
static enum OlympusVersion
exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
unsigned int buf_size);
@@ -241,13 +251,13 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
ExifShort c;
size_t i, tcount, o, o2, datao = 6, base = 0;
- if (!n || !buf || !buf_size) {
+ if (!n || !buf || !buf_size || will_overflow(n->offset, 6)) {
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
"ExifMnoteDataOlympus", "Short MakerNote");
return;
}
o2 = 6 + n->offset; /* Start of interesting data */
- if ((o2 + 10 < o2) || (o2 + 10 < 10) || (o2 + 10 > buf_size)) {
+ if (exceeds_buffer(buf_size, o2, 10)) {
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
"ExifMnoteDataOlympus", "Short MakerNote");
return;
@@ -288,7 +298,6 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
else if (buf[o2 + 6 + 1] == 1)
n->order = EXIF_BYTE_ORDER_MOTOROLA;
o2 += 8;
- if (o2 + 2 > buf_size) return;
c = exif_get_short (buf + o2, n->order);
if ((!(c & 0xFF)) && (c > 0x500)) {
if (n->order == EXIF_BYTE_ORDER_INTEL) {
@@ -303,6 +312,7 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
/* Olympus S760, S770 */
datao = o2;
o2 += 8;
+ if (exceeds_buffer(buf_size, o2, 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]);
@@ -313,12 +323,13 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
n->order = EXIF_BYTE_ORDER_MOTOROLA;
/* The number of entries is at position 8+4. */
+ if (will_overflow(o2, 4)) return;
o2 += 4;
break;
case nikonV1:
o2 += 6;
- if (o2 >= buf_size) return;
+ if (exceeds_buffer(buf_size, o2, 8)) return;
exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
"Parsing Nikon maker note v1 (0x%02x, %02x, %02x, "
"%02x, %02x, %02x, %02x, %02x)...",
@@ -333,7 +344,6 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
base = MNOTE_NIKON1_TAG_BASE;
/* Fix endianness, if needed */
- if (o2 + 2 > buf_size) return;
c = exif_get_short (buf + o2, n->order);
if ((!(c & 0xFF)) && (c > 0x500)) {
if (n->order == EXIF_BYTE_ORDER_INTEL) {
@@ -346,7 +356,7 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
case nikonV2:
o2 += 6;
- if (o2 >= buf_size) return;
+ if (exceeds_buffer(buf_size, o2, 8)) return;
exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
"Parsing Nikon maker note v2 (0x%02x, %02x, %02x, "
"%02x, %02x, %02x, %02x, %02x)...",
@@ -366,8 +376,8 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
* Byte order. From here the data offset
* gets calculated.
*/
+ if (exceeds_buffer(buf_size, o2, 2)) return;
datao = o2;
- if (o2 >= buf_size) return;
if (!strncmp ((char *)&buf[o2], "II", 2))
n->order = EXIF_BYTE_ORDER_INTEL;
else if (!strncmp ((char *)&buf[o2], "MM", 2))
@@ -382,10 +392,12 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
o2 += 2;
/* Skip 2 unknown bytes (00 2A). */
+ if (will_overflow(o2, 2)) return;
o2 += 2;
/* Go to where the number of entries is. */
- if (o2 + 4 > buf_size) return;
+ if (exceeds_buffer(buf_size, o2, 4)) return;
+ if (will_overflow(datao, exif_get_long (buf + o2, n->order))) return;
o2 = datao + exif_get_long (buf + o2, n->order);
break;
@@ -406,7 +418,7 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
}
/* Sanity check the offset */
- if ((o2 + 2 < o2) || (o2 + 2 < 2) || (o2 + 2 > buf_size)) {
+ if (exceeds_buffer(buf_size, o2, 2)) {
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
"ExifMnoteOlympus", "Short MakerNote");
return;
@@ -430,7 +442,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 (exceeds_buffer(buf_size, o, 12)) {
exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
"ExifMnoteOlympus", "Short MakerNote");
break;
@@ -478,8 +490,7 @@ exif_mnote_data_olympus_load (ExifMnoteData *en,
}
#endif
}
- if ((dataofs + s < dataofs) || (dataofs + s < s) ||
- (dataofs + s > buf_size)) {
+ if (exceeds_buffer(buf_size, dataofs, s)) {
exif_log (en->log, EXIF_LOG_CODE_DEBUG,
"ExifMnoteOlympus",
"Tag data past end of buffer (%u > %u)",
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698