Menu

#343 Negative file offset leads to overflow in function parse_tiff_ifd

open
nobody
bugs (7)
5
2021-11-06
2021-11-06
No

Hi all,
I found some crashes using libFuzzer. Lets look at this code:
from trunk/Source/LibRawLite/src/metadata/tiff.cpp:50
tiff_get(base, &tag, &type, &len, &save); INT64 savepos = ftell(ifp); if (len > 8 && savepos + len > 2 * fsize) { fseek(ifp, save, SEEK_SET); // Recover tiff-read position!! continue; }

  • tiffget * moves file cursor far away using position from input file (get4()).
    If on line 52 doesn't help because savepos is below zero.

Crash ocurres further at any read. Here is stacktrace.

==72015==ERROR: AddressSanitizer: SEGV on unknown address 0x606fe10000ff (pc 0x7f46345a7d93 bp 0x7fffac4cd360 sp 0x7fffac4ccb18 T0)
==72015==The signal is caused by a READ memory access.
    #0 0x7f46345a7d93  /build/glibc-eX1tMB/glibc-2.31/string/../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:319
    #1 0x4e2f71 in __asan_memcpy /llvm-project/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3
    #2 0x11f38e6 in _MemoryReadProc(void*, unsigned int, unsigned int, void*) /freeimage-svn/FreeImage/trunk/Source/FreeImage/FreeImageIO.cpp:90:4
    #3 0x78186d in LibRaw_freeimage_datastream::read(void*, unsigned long, unsigned long) /freeimage-svn/FreeImage/trunk/Source/FreeImage/PluginRAW.cpp:66:10
    #4 0x1117bc5 in LibRaw::get4() /freeimage-svn/FreeImage/trunk/Source/LibRawLite/src/utils/read_utils.cpp:69:3
    #5 0x1117fcf in LibRaw::getint(int) /freeimage-svn/FreeImage/trunk/Source/LibRawLite/src/utils/read_utils.cpp:73:92
    #6 0x27626d1 in LibRaw::parse_tiff_ifd(int) /freeimage-svn/FreeImage/trunk/Source/LibRawLite/src/metadata/tiff.cpp:463:38
    #7 0x27f265c in LibRaw::parse_tiff(int) /freeimage-svn/FreeImage/trunk/Source/LibRawLite/src/metadata/tiff.cpp:1495:9
    #8 0x2428b20 in LibRaw::identify() /freeimage-svn/FreeImage/trunk/Source/LibRawLite/src/metadata/identify.cpp:503:14
    #9 0x10bd296 in LibRaw::open_datastream(LibRaw_abstract_datastream*) /freeimage-svn/FreeImage/trunk/Source/LibRawLite/src/utils/open.cpp:464:4
    #10 0x7783a8 in Validate(FreeImageIO*, void*) /freeimage-svn/FreeImage/trunk/Source/FreeImage/PluginRAW.cpp:645:21
    #11 0x592cf0 in FreeImage_ValidateFIF /freeimage-svn/FreeImage/trunk/Source/FreeImage/Plugin.cpp:811:95
    #12 0x572cef in FreeImage_GetFileTypeFromHandle /freeimage-svn/FreeImage/trunk/Source/FreeImage/GetType.cpp:43:8
    #13 0x573464 in FreeImage_GetFileTypeFromMemory /freeimage-svn/FreeImage/trunk/Source/FreeImage/GetType.cpp:109:10
    #14 0x51cfdc in LLVMFuzzerTestOneInput /load_from_memory_fuzzer.cc:33:27
    #15 0x449c01 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15
    #16 0x43421c in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6
    #17 0x439f8b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:860:9
    #18 0x462cd2 in main /llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #19 0x7f46345100b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16
    #20 0x42eb3d in _start (/load_from_memory_fuzzer+0x42eb3d)

Use unsigned int for savepos or add to if another check savepos > 0

How to reporduce:

  1. Build and run docker container from here https://github.com/ispras/oss-sydr-fuzz/tree/new-config/projects/freeimage
  2. run fuzzer /load_from_memory_fuzzer /fuzz/crashes/crash-143d28f3c8956cae6688a9e966c9da9864cef2c8
1 Attachments

Discussion


Log in to post a comment.