|
32 | 32 |
|
33 | 33 | #define CHECKOVERFLOW(offset,datasize,structsize) (( offset >= datasize) || (structsize > datasize) || (offset > datasize - structsize )) |
34 | 34 |
|
| 35 | +/* Total size limit to prevent abuse by DoS */ |
| 36 | +#define FAILSAFE_SIZE_MAX 1000000L |
| 37 | + |
35 | 38 | static void |
36 | 39 | exif_mnote_data_canon_clear (ExifMnoteDataCanon *n) |
37 | 40 | { |
@@ -204,6 +207,7 @@ exif_mnote_data_canon_load (ExifMnoteData *ne, |
204 | 207 | ExifMnoteDataCanon *n = (ExifMnoteDataCanon *) ne; |
205 | 208 | ExifShort c; |
206 | 209 | size_t i, tcount, o, datao; |
| 210 | + long failsafe_size = 0; |
207 | 211 |
|
208 | 212 | if (!n || !buf || !buf_size) { |
209 | 213 | exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA, |
@@ -295,6 +299,23 @@ exif_mnote_data_canon_load (ExifMnoteData *ne, |
295 | 299 | memcpy (n->entries[tcount].data, buf + dataofs, s); |
296 | 300 | } |
297 | 301 |
|
| 302 | + /* Track the size of decoded tag data. A malicious file could |
| 303 | + * be crafted to cause extremely large values here without |
| 304 | + * tripping any buffer range checks. This is especially bad |
| 305 | + * with the libexif representation of Canon MakerNotes because |
| 306 | + * some arrays are turned into individual tags that the |
| 307 | + * application must loop around. */ |
| 308 | + failsafe_size += mnote_canon_entry_count_values(&n->entries[tcount]); |
| 309 | + |
| 310 | + if (failsafe_size > FAILSAFE_SIZE_MAX) { |
| 311 | + /* Abort if the total size of the data in the tags extraordinarily large, */ |
| 312 | + exif_mem_free (ne->mem, n->entries[tcount].data); |
| 313 | + exif_log (ne->log, EXIF_LOG_CODE_CORRUPT_DATA, |
| 314 | + "ExifMnoteCanon", "Failsafe tag size overflow (%lu > %ld)", |
| 315 | + failsafe_size, FAILSAFE_SIZE_MAX); |
| 316 | + break; |
| 317 | + } |
| 318 | + |
298 | 319 | /* Tag was successfully parsed */ |
299 | 320 | ++tcount; |
300 | 321 | } |
|
0 commit comments