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

Side by Side 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 unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* exif-mnote-data-olympus.c 1 /* exif-mnote-data-olympus.c
2 * 2 *
3 * Copyright (c) 2002, 2003 Lutz Mueller <lutz@users.sourceforge.net> 3 * Copyright (c) 2002, 2003 Lutz Mueller <lutz@users.sourceforge.net>
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public 6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 19 matching lines...) Expand all
30 30
31 #define DEBUG 31 #define DEBUG
32 32
33 /* Uncomment this to fix a problem with Sanyo MakerNotes. It's probably best 33 /* Uncomment this to fix a problem with Sanyo MakerNotes. It's probably best
34 * not to in most cases because it seems to only affect the thumbnail tag 34 * not to in most cases because it seems to only affect the thumbnail tag
35 * which is duplicated in IFD 1, and fixing the offset could actually cause 35 * which is duplicated in IFD 1, and fixing the offset could actually cause
36 * problems with other software that expects the broken form. 36 * problems with other software that expects the broken form.
37 */ 37 */
38 /*#define EXIF_OVERCOME_SANYO_OFFSET_BUG */ 38 /*#define EXIF_OVERCOME_SANYO_OFFSET_BUG */
39 39
40 static int will_overflow(size_t num1, size_t num2)
41 {
42 return num1 > (size_t)-1 - num2;
43 }
44
45 static int exceeds_buffer(size_t buf_size, size_t offset, size_t len)
46 {
47 return buf_size < len || offset > buf_size - len;
48 }
49
40 static enum OlympusVersion 50 static enum OlympusVersion
41 exif_mnote_data_olympus_identify_variant (const unsigned char *buf, 51 exif_mnote_data_olympus_identify_variant (const unsigned char *buf,
42 unsigned int buf_size); 52 unsigned int buf_size);
43 53
44 54
45 static void 55 static void
46 exif_mnote_data_olympus_clear (ExifMnoteDataOlympus *n) 56 exif_mnote_data_olympus_clear (ExifMnoteDataOlympus *n)
47 { 57 {
48 ExifMnoteData *d = (ExifMnoteData *) n; 58 ExifMnoteData *d = (ExifMnoteData *) n;
49 unsigned int i; 59 unsigned int i;
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 } 244 }
235 245
236 static void 246 static void
237 exif_mnote_data_olympus_load (ExifMnoteData *en, 247 exif_mnote_data_olympus_load (ExifMnoteData *en,
238 const unsigned char *buf, unsigned int buf_size) 248 const unsigned char *buf, unsigned int buf_size)
239 { 249 {
240 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en; 250 ExifMnoteDataOlympus *n = (ExifMnoteDataOlympus *) en;
241 ExifShort c; 251 ExifShort c;
242 size_t i, tcount, o, o2, datao = 6, base = 0; 252 size_t i, tcount, o, o2, datao = 6, base = 0;
243 253
244 » if (!n || !buf || !buf_size) { 254 » if (!n || !buf || !buf_size || will_overflow(n->offset, 6)) {
245 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, 255 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
246 "ExifMnoteDataOlympus", "Short MakerNote"); 256 "ExifMnoteDataOlympus", "Short MakerNote");
247 return; 257 return;
248 } 258 }
249 o2 = 6 + n->offset; /* Start of interesting data */ 259 o2 = 6 + n->offset; /* Start of interesting data */
250 » if ((o2 + 10 < o2) || (o2 + 10 < 10) || (o2 + 10 > buf_size)) { 260 » if (exceeds_buffer(buf_size, o2, 10)) {
251 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, 261 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
252 "ExifMnoteDataOlympus", "Short MakerNote"); 262 "ExifMnoteDataOlympus", "Short MakerNote");
253 return; 263 return;
254 } 264 }
255 265
256 /* 266 /*
257 * Olympus headers start with "OLYMP" and need to have at least 267 * Olympus headers start with "OLYMP" and need to have at least
258 * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the 268 * a size of 22 bytes (6 for 'OLYMP', 2 other bytes, 2 for the
259 * number of entries, and 12 for one entry. 269 * number of entries, and 12 for one entry.
260 * 270 *
(...skipping 20 matching lines...) Expand all
281 case epsonV1: 291 case epsonV1:
282 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 292 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
283 "Parsing Olympus/Sanyo/Epson maker note v1..."); 293 "Parsing Olympus/Sanyo/Epson maker note v1...");
284 294
285 /* The number of entries is at position 8. */ 295 /* The number of entries is at position 8. */
286 if (buf[o2 + 6] == 1) 296 if (buf[o2 + 6] == 1)
287 n->order = EXIF_BYTE_ORDER_INTEL; 297 n->order = EXIF_BYTE_ORDER_INTEL;
288 else if (buf[o2 + 6 + 1] == 1) 298 else if (buf[o2 + 6 + 1] == 1)
289 n->order = EXIF_BYTE_ORDER_MOTOROLA; 299 n->order = EXIF_BYTE_ORDER_MOTOROLA;
290 o2 += 8; 300 o2 += 8;
291 if (o2 + 2 > buf_size) return;
292 c = exif_get_short (buf + o2, n->order); 301 c = exif_get_short (buf + o2, n->order);
293 if ((!(c & 0xFF)) && (c > 0x500)) { 302 if ((!(c & 0xFF)) && (c > 0x500)) {
294 if (n->order == EXIF_BYTE_ORDER_INTEL) { 303 if (n->order == EXIF_BYTE_ORDER_INTEL) {
295 n->order = EXIF_BYTE_ORDER_MOTOROLA; 304 n->order = EXIF_BYTE_ORDER_MOTOROLA;
296 } else { 305 } else {
297 n->order = EXIF_BYTE_ORDER_INTEL; 306 n->order = EXIF_BYTE_ORDER_INTEL;
298 } 307 }
299 } 308 }
300 break; 309 break;
301 310
302 case olympusV2: 311 case olympusV2:
303 /* Olympus S760, S770 */ 312 /* Olympus S760, S770 */
304 datao = o2; 313 datao = o2;
305 o2 += 8; 314 o2 += 8;
315 if (exceeds_buffer(buf_size, o2, 4)) return;
306 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 316 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
307 "Parsing Olympus maker note v2 (0x%02x, %02x, %02x, %02x )...", 317 "Parsing Olympus maker note v2 (0x%02x, %02x, %02x, %02x )...",
308 buf[o2], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]); 318 buf[o2], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3]);
309 319
310 if ((buf[o2] == 'I') && (buf[o2 + 1] == 'I')) 320 if ((buf[o2] == 'I') && (buf[o2 + 1] == 'I'))
311 n->order = EXIF_BYTE_ORDER_INTEL; 321 n->order = EXIF_BYTE_ORDER_INTEL;
312 else if ((buf[o2] == 'M') && (buf[o2 + 1] == 'M')) 322 else if ((buf[o2] == 'M') && (buf[o2 + 1] == 'M'))
313 n->order = EXIF_BYTE_ORDER_MOTOROLA; 323 n->order = EXIF_BYTE_ORDER_MOTOROLA;
314 324
315 /* The number of entries is at position 8+4. */ 325 /* The number of entries is at position 8+4. */
326 if (will_overflow(o2, 4)) return;
316 o2 += 4; 327 o2 += 4;
317 break; 328 break;
318 329
319 case nikonV1: 330 case nikonV1:
320 o2 += 6; 331 o2 += 6;
321 » » if (o2 >= buf_size) return; 332 » » if (exceeds_buffer(buf_size, o2, 8)) return;
322 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 333 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
323 "Parsing Nikon maker note v1 (0x%02x, %02x, %02x, " 334 "Parsing Nikon maker note v1 (0x%02x, %02x, %02x, "
324 "%02x, %02x, %02x, %02x, %02x)...", 335 "%02x, %02x, %02x, %02x, %02x)...",
325 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3], 336 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
326 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]); 337 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
327 338
328 /* Skip version number */ 339 /* Skip version number */
329 o2 += 1; 340 o2 += 1;
330 341
331 /* Skip an unknown byte (00 or 0A). */ 342 /* Skip an unknown byte (00 or 0A). */
332 o2 += 1; 343 o2 += 1;
333 344
334 base = MNOTE_NIKON1_TAG_BASE; 345 base = MNOTE_NIKON1_TAG_BASE;
335 /* Fix endianness, if needed */ 346 /* Fix endianness, if needed */
336 if (o2 + 2 > buf_size) return;
337 c = exif_get_short (buf + o2, n->order); 347 c = exif_get_short (buf + o2, n->order);
338 if ((!(c & 0xFF)) && (c > 0x500)) { 348 if ((!(c & 0xFF)) && (c > 0x500)) {
339 if (n->order == EXIF_BYTE_ORDER_INTEL) { 349 if (n->order == EXIF_BYTE_ORDER_INTEL) {
340 n->order = EXIF_BYTE_ORDER_MOTOROLA; 350 n->order = EXIF_BYTE_ORDER_MOTOROLA;
341 } else { 351 } else {
342 n->order = EXIF_BYTE_ORDER_INTEL; 352 n->order = EXIF_BYTE_ORDER_INTEL;
343 } 353 }
344 } 354 }
345 break; 355 break;
346 356
347 case nikonV2: 357 case nikonV2:
348 o2 += 6; 358 o2 += 6;
349 » » if (o2 >= buf_size) return; 359 » » if (exceeds_buffer(buf_size, o2, 8)) return;
350 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 360 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
351 "Parsing Nikon maker note v2 (0x%02x, %02x, %02x, " 361 "Parsing Nikon maker note v2 (0x%02x, %02x, %02x, "
352 "%02x, %02x, %02x, %02x, %02x)...", 362 "%02x, %02x, %02x, %02x, %02x)...",
353 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3], 363 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
354 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]); 364 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
355 365
356 /* Skip version number */ 366 /* Skip version number */
357 o2 += 1; 367 o2 += 1;
358 368
359 /* Skip an unknown byte (00 or 0A). */ 369 /* Skip an unknown byte (00 or 0A). */
360 o2 += 1; 370 o2 += 1;
361 371
362 /* Skip 2 unknown bytes (00 00). */ 372 /* Skip 2 unknown bytes (00 00). */
363 o2 += 2; 373 o2 += 2;
364 374
365 /* 375 /*
366 * Byte order. From here the data offset 376 * Byte order. From here the data offset
367 * gets calculated. 377 * gets calculated.
368 */ 378 */
379 if (exceeds_buffer(buf_size, o2, 2)) return;
369 datao = o2; 380 datao = o2;
370 if (o2 >= buf_size) return;
371 if (!strncmp ((char *)&buf[o2], "II", 2)) 381 if (!strncmp ((char *)&buf[o2], "II", 2))
372 n->order = EXIF_BYTE_ORDER_INTEL; 382 n->order = EXIF_BYTE_ORDER_INTEL;
373 else if (!strncmp ((char *)&buf[o2], "MM", 2)) 383 else if (!strncmp ((char *)&buf[o2], "MM", 2))
374 n->order = EXIF_BYTE_ORDER_MOTOROLA; 384 n->order = EXIF_BYTE_ORDER_MOTOROLA;
375 else { 385 else {
376 exif_log (en->log, EXIF_LOG_CODE_DEBUG, 386 exif_log (en->log, EXIF_LOG_CODE_DEBUG,
377 "ExifMnoteDataOlympus", "Unknown " 387 "ExifMnoteDataOlympus", "Unknown "
378 "byte order '%c%c'", buf[o2], 388 "byte order '%c%c'", buf[o2],
379 buf[o2 + 1]); 389 buf[o2 + 1]);
380 return; 390 return;
381 } 391 }
382 o2 += 2; 392 o2 += 2;
383 393
384 /* Skip 2 unknown bytes (00 2A). */ 394 /* Skip 2 unknown bytes (00 2A). */
395 if (will_overflow(o2, 2)) return;
385 o2 += 2; 396 o2 += 2;
386 397
387 /* Go to where the number of entries is. */ 398 /* Go to where the number of entries is. */
388 » » if (o2 + 4 > buf_size) return; 399 » » if (exceeds_buffer(buf_size, o2, 4)) return;
400 » » if (will_overflow(datao, exif_get_long (buf + o2, n->order))) re turn;
389 o2 = datao + exif_get_long (buf + o2, n->order); 401 o2 = datao + exif_get_long (buf + o2, n->order);
390 break; 402 break;
391 403
392 case nikonV0: 404 case nikonV0:
393 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 405 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
394 "Parsing Nikon maker note v0 (0x%02x, %02x, %02x, " 406 "Parsing Nikon maker note v0 (0x%02x, %02x, %02x, "
395 "%02x, %02x, %02x, %02x, %02x)...", 407 "%02x, %02x, %02x, %02x, %02x)...",
396 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3], 408 buf[o2 + 0], buf[o2 + 1], buf[o2 + 2], buf[o2 + 3],
397 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]); 409 buf[o2 + 4], buf[o2 + 5], buf[o2 + 6], buf[o2 + 7]);
398 /* 00 1b is # of entries in Motorola order - the rest should als o be in MM order */ 410 /* 00 1b is # of entries in Motorola order - the rest should als o be in MM order */
399 n->order = EXIF_BYTE_ORDER_MOTOROLA; 411 n->order = EXIF_BYTE_ORDER_MOTOROLA;
400 break; 412 break;
401 413
402 default: 414 default:
403 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus", 415 exif_log (en->log, EXIF_LOG_CODE_DEBUG, "ExifMnoteDataOlympus",
404 "Unknown Olympus variant %i.", n->version); 416 "Unknown Olympus variant %i.", n->version);
405 return; 417 return;
406 } 418 }
407 419
408 /* Sanity check the offset */ 420 /* Sanity check the offset */
409 » if ((o2 + 2 < o2) || (o2 + 2 < 2) || (o2 + 2 > buf_size)) { 421 » if (exceeds_buffer(buf_size, o2, 2)) {
410 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, 422 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
411 "ExifMnoteOlympus", "Short MakerNote"); 423 "ExifMnoteOlympus", "Short MakerNote");
412 return; 424 return;
413 } 425 }
414 426
415 /* Read the number of tags */ 427 /* Read the number of tags */
416 c = exif_get_short (buf + o2, n->order); 428 c = exif_get_short (buf + o2, n->order);
417 o2 += 2; 429 o2 += 2;
418 430
419 /* Remove any old entries */ 431 /* Remove any old entries */
420 exif_mnote_data_olympus_clear (n); 432 exif_mnote_data_olympus_clear (n);
421 433
422 /* Reserve enough space for all the possible MakerNote tags */ 434 /* Reserve enough space for all the possible MakerNote tags */
423 n->entries = exif_mem_alloc (en->mem, sizeof (MnoteOlympusEntry) * c); 435 n->entries = exif_mem_alloc (en->mem, sizeof (MnoteOlympusEntry) * c);
424 if (!n->entries) { 436 if (!n->entries) {
425 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", sizeof (MnoteOly mpusEntry) * c); 437 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", sizeof (MnoteOly mpusEntry) * c);
426 return; 438 return;
427 } 439 }
428 440
429 /* Parse all c entries, storing ones that are successfully parsed */ 441 /* Parse all c entries, storing ones that are successfully parsed */
430 tcount = 0; 442 tcount = 0;
431 for (i = c, o = o2; i; --i, o += 12) { 443 for (i = c, o = o2; i; --i, o += 12) {
432 size_t s; 444 size_t s;
433 » » if ((o + 12 < o) || (o + 12 < 12) || (o + 12 > buf_size)) { 445 » » if (exceeds_buffer(buf_size, o, 12)) {
434 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA, 446 exif_log (en->log, EXIF_LOG_CODE_CORRUPT_DATA,
435 "ExifMnoteOlympus", "Short MakerNote"); 447 "ExifMnoteOlympus", "Short MakerNote");
436 break; 448 break;
437 } 449 }
438 450
439 n->entries[tcount].tag = exif_get_short (buf + o, n->order) + base; 451 n->entries[tcount].tag = exif_get_short (buf + o, n->order) + base;
440 n->entries[tcount].format = exif_get_short (buf + o + 2, n->orde r); 452 n->entries[tcount].format = exif_get_short (buf + o + 2, n->orde r);
441 n->entries[tcount].components = exif_get_long (buf + o + 4, n->order ); 453 n->entries[tcount].components = exif_get_long (buf + o + 4, n->order );
442 n->entries[tcount].order = n->order; 454 n->entries[tcount].order = n->order;
443 455
(...skipping 27 matching lines...) Expand all
471 */ 483 */
472 if (dataofs + s > buf_size && n->version == sanyoV1) { 484 if (dataofs + s > buf_size && n->version == sanyoV1) {
473 /* fix pointer */ 485 /* fix pointer */
474 dataofs -= datao + 6; 486 dataofs -= datao + 6;
475 exif_log (en->log, EXIF_LOG_CODE_DEBUG, 487 exif_log (en->log, EXIF_LOG_CODE_DEBUG,
476 "ExifMnoteOlympus", 488 "ExifMnoteOlympus",
477 "Inconsistent thumbnail tag of fset; attempting to recover"); 489 "Inconsistent thumbnail tag of fset; attempting to recover");
478 } 490 }
479 #endif 491 #endif
480 } 492 }
481 » » » if ((dataofs + s < dataofs) || (dataofs + s < s) || 493 » » » if (exceeds_buffer(buf_size, dataofs, s)) {
482 » » » (dataofs + s > buf_size)) {
483 exif_log (en->log, EXIF_LOG_CODE_DEBUG, 494 exif_log (en->log, EXIF_LOG_CODE_DEBUG,
484 "ExifMnoteOlympus", 495 "ExifMnoteOlympus",
485 "Tag data past end of buffer (%u > %u) ", 496 "Tag data past end of buffer (%u > %u) ",
486 dataofs + s, buf_size); 497 dataofs + s, buf_size);
487 continue; 498 continue;
488 } 499 }
489 500
490 n->entries[tcount].data = exif_mem_alloc (en->mem, s); 501 n->entries[tcount].data = exif_mem_alloc (en->mem, s);
491 if (!n->entries[tcount].data) { 502 if (!n->entries[tcount].data) {
492 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", s); 503 EXIF_LOG_NO_MEMORY(en->log, "ExifMnoteOlympus", s);
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 d->methods.save = exif_mnote_data_olympus_save; 661 d->methods.save = exif_mnote_data_olympus_save;
651 d->methods.count = exif_mnote_data_olympus_count; 662 d->methods.count = exif_mnote_data_olympus_count;
652 d->methods.get_id = exif_mnote_data_olympus_get_id; 663 d->methods.get_id = exif_mnote_data_olympus_get_id;
653 d->methods.get_name = exif_mnote_data_olympus_get_name; 664 d->methods.get_name = exif_mnote_data_olympus_get_name;
654 d->methods.get_title = exif_mnote_data_olympus_get_title; 665 d->methods.get_title = exif_mnote_data_olympus_get_title;
655 d->methods.get_description = exif_mnote_data_olympus_get_description; 666 d->methods.get_description = exif_mnote_data_olympus_get_description;
656 d->methods.get_value = exif_mnote_data_olympus_get_value; 667 d->methods.get_value = exif_mnote_data_olympus_get_value;
657 668
658 return d; 669 return d;
659 } 670 }
OLDNEW
« 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