Menu

#344 FreeImage_LoadFromMemory: AddressSanitizer: allocator is out of memory

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

Hi!
While doing fuzzing I found out that FreeImage_LoadFromMemory tries to allocate huge amount of memory:

==60==ERROR: AddressSanitizer: allocator is out of memory trying to allocate 0x1f0aa262a0 bytes
    #0 0x4e3add in malloc /llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:129:3
    #1 0x522802 in FreeImage_Aligned_Malloc(unsigned long, unsigned long) /freeimage-svn/FreeImage/trunk/Source/FreeImage/BitmapAccess.cpp:183:19
    #2 0x523ef1 in FreeImage_AllocateBitmap(int, unsigned char*, unsigned int, FREE_IMAGE_TYPE, int, int, int, unsigned int, unsigned int, unsigned int) /freeimage-svn/FreeImage/trunk/Source/FreeImage/BitmapAccess.cpp:390:26
    #3 0x527793 in FreeImage_AllocateHeader /freeimage-svn/FreeImage/trunk/Source/FreeImage/BitmapAccess.cpp:482:9
    #4 0x74ee12 in Load(FreeImageIO*, void*, int, int, void*) /freeimage-svn/FreeImage/trunk/Source/FreeImage/PluginPNM.cpp:290:12
    #5 0x589d39 in FreeImage_LoadFromHandle /freeimage-svn/FreeImage/trunk/Source/FreeImage/Plugin.cpp:386:24
    #6 0x575160 in FreeImage_LoadFromMemory /freeimage-svn/FreeImage/trunk/Source/FreeImage/MemoryIO.cpp:88:10
    #7 0x51d137 in LLVMFuzzerTestOneInput /load_from_memory_fuzzer.cc:35:26
    #8 0x449c01 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:611:15
    #9 0x43421c in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6
    #10 0x439f8b in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:860:9
    #11 0x462cd2 in main /llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #12 0x7f086a1f70b2 in __libc_start_main /build/glibc-eX1tMB/glibc-2.31/csu/../csu/libc-start.c:308:16

Also, there are inputs that coud pass sanitizer's checks. For example 28 byte input tries allocates about 13Gb memory (because height parameter is very big).

In function Load located at Source/FreeImage/PluginPNM.cpp:215 there is no checks for big width and height

245                     const int width  = GetInt(io, handle);
(gdb) n
246                     const int height = GetInt(io, handle);
(gdb) n
247                     int maxval = 1;
(gdb) p width    
$1 = 66666
(gdb) p height 
$2 = 666612
(gdb) n
249                     if (width < 0 || height < 0) {
(gdb) 

There are only checks that values are negative, may be we need some checks like:
width * height * some_value < image_size

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-34f40ef0993115491a23a66478f380d7abc236b7
2 Attachments

Discussion


Log in to post a comment.