Repository: libexif/libexif
Fuzzing engine: libfuzzer
Fuzz target: exif_loader_fuzzer
Sanitizer: address
Crash type: Heap-buffer-overflow READ 7

Sanitizer report:
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3665362448
INFO: Loaded 1 modules   (2640 inline 8-bit counters): 2640 [0x563f812ea668, 0x563f812eb0b8), 
INFO: Loaded 1 PC tables (2640 PCs): 2640 [0x563f812eb0b8,0x563f812f55b8), 
/out/exif_loader_fuzzer: Running 1 inputs 1 time(s) each.
Running: /testcase/OSV-2020-1274.poc
=================================================================
==7==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5020000000b6 at pc 0x563f81151a9b bp 0x7ffc75343850 sp 0x7ffc75342ff8
READ of size 7 at 0x5020000000b6 thread T0
SCARINESS: 21 (7-byte-read-heap-buffer-overflow)
    #0 0x563f81151a9a in strncmp /src/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:501:3
    #1 0x563f8121ea26 in exif_entry_get_value /src/libexif/libexif/exif-entry.c:1044:8
    #2 0x563f812118d0 in content_func(_ExifEntry*, void*) /src/exif_loader_fuzzer.cc:8:3
    #3 0x563f81212d64 in exif_content_foreach_entry /src/libexif/libexif/exif-content.c:225:3
    #4 0x563f8121a419 in exif_data_foreach_content /src/libexif/libexif/exif-data.c:1151:3
    #5 0x563f812119b8 in LLVMFuzzerTestOneInput /src/exif_loader_fuzzer.cc:27:3
    #6 0x563f810c6330 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13
    #7 0x563f810b15a5 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:327:6
    #8 0x563f810b703f in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:862:9
    #9 0x563f810e22e2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #10 0x7f2644392082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 0702430aef5fa3dda43986563e9ffcc47efbd75e)
    #11 0x563f810a978d in _start (/out/exif_loader_fuzzer+0x7d78d)

DEDUP_TOKEN: ___interceptor_strncmp--exif_entry_get_value--content_func(_ExifEntry*, void*)
0x5020000000b6 is located 0 bytes after 6-byte region [0x5020000000b0,0x5020000000b6)
allocated by thread T0 here:
    #0 0x563f811d22c9 in calloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:75:3
    #1 0x563f81215e05 in exif_data_alloc /src/libexif/libexif/exif-data.c:78:6
    #2 0x563f81215e05 in exif_data_load_data_entry /src/libexif/libexif/exif-data.c:201:16
    #3 0x563f81215e05 in exif_data_load_data_content /src/libexif/libexif/exif-data.c:514:8
    #4 0x563f81214ac9 in exif_data_load_data /src/libexif/libexif/exif-data.c:955:2
    #5 0x563f81228f90 in exif_loader_get_data /src/libexif/libexif/exif-loader.c:401:2
    #6 0x563f81211999 in LLVMFuzzerTestOneInput /src/exif_loader_fuzzer.cc:22:15
    #7 0x563f810c6330 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:614:13
    #8 0x563f810b15a5 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:327:6
    #9 0x563f810b703f in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:862:9
    #10 0x563f810e22e2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #11 0x7f2644392082 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x24082) (BuildId: 0702430aef5fa3dda43986563e9ffcc47efbd75e)

DEDUP_TOKEN: __interceptor_calloc--exif_data_alloc--exif_data_load_data_entry
SUMMARY: AddressSanitizer: heap-buffer-overflow /src/libexif/libexif/exif-entry.c:1044:8 in exif_entry_get_value
Shadow bytes around the buggy address:
  0x501ffffffe00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x501ffffffe80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x501fffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x501fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x502000000000: fa fa 00 00 fa fa 00 fa fa fa 00 fa fa fa 00 fa
=>0x502000000080: fa fa 00 00 fa fa[06]fa fa fa 00 fa fa fa fd fd
  0x502000000100: fa fa 00 00 fa fa 00 fa fa fa 00 fa fa fa fa fa
  0x502000000180: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000000300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==7==ABORTING


Fix patch:
diff --git a/libexif/exif-entry.c b/libexif/exif-entry.c
index 61260d3..a224ac2 100644
--- a/libexif/exif-entry.c
+++ b/libexif/exif-entry.c
@@ -1040,12 +1040,12 @@ exif_entry_get_value (ExifEntry *e, char *val, unsigned int maxlen)
 		d = 0.;
 		entry = exif_content_get_entry (
 			e->parent->parent->ifd[EXIF_IFD_0], EXIF_TAG_MAKE);
-		if (entry && entry->data &&
+		if (entry && entry->data && entry->size >= 7 &&
 		    !strncmp ((char *)entry->data, "Minolta", 7)) {
 			entry = exif_content_get_entry (
 					e->parent->parent->ifd[EXIF_IFD_0],
 					EXIF_TAG_MODEL);
-			if (entry && entry->data) {
+			if (entry && entry->data && entry->size >= 8) {
 				if (!strncmp ((char *)entry->data, "DiMAGE 7", 8))
 					d = 3.9;
 				else if (!strncmp ((char *)entry->data, "DiMAGE 5", 8))