Skip to content

Commit

Permalink
Add a failsafe on the maximum number of Canon MakerNote subtags.
Browse files Browse the repository at this point in the history
A malicious file could be crafted to cause extremely large values in some
tags without tripping any buffer range checks.  This is bad with the libexif
representation of Canon MakerNotes because some arrays are turned into
individual tags that the application must loop around.

The largest value I've seen for failsafe_size in a (very small) sample of valid
Canon files is <5000.  The limit is set two orders of magnitude larger to avoid
tripping up falsely in case some models use much larger values.

Patch from Google.

CVE-2020-13114
  • Loading branch information
dfandrich authored and msmeissn committed May 16, 2020
1 parent bbd35b1 commit e6a38a1
Showing 1 changed file with 21 additions and 0 deletions.
21 changes: 21 additions & 0 deletions libexif/canon/exif-mnote-data-canon.c
Expand Up @@ -32,6 +32,9 @@

#define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize ))

/* Total size limit to prevent abuse by DoS */
#define FAILSAFE_SIZE_MAX 1000000L

static void
exif_mnote_data_canon_clear (ExifMnoteDataCanon *n)
{
Expand Down Expand Up @@ -204,6 +207,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,
Expand Down Expand Up @@ -295,6 +299,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;
}
Expand Down

0 comments on commit e6a38a1

Please sign in to comment.