Out-of-memory happened in TIFFOpen via a craft file

Summary

A out-of-memory could be triggered by passing a craft tiff file to TIFFOpen() API.

Remote attackers could cause deny-of-services via a craft input (with size smaller than 379 KB).

Version

commit: 4d0329a4 Sep 15

POC program

#include <tiffio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <fstream>
#include <iostream>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
	if(size<=0) return 0;


  // Step 4: Read input data from file
  FILE *in_file = fopen("input_file", "wb");
  if (!in_file) {
    fprintf(stderr, "Failed to open input file\n");
	return 0;
  }
  fwrite(data, sizeof(uint8_t), size, in_file);
  fclose(in_file);

  // Step 1: Open TIFF file
  TIFF *tif = TIFFOpen("input_file", "r+");
  if (!tif) {
    fprintf(stderr, "Failed to open TIFF file\n");
	return 0;
  }

  // Step 3: Close the TIFF file
   TIFFClose(tif);
	return 0;
}

Steps to reproduce

Download the poc input: oom_input

Compile the poc program:

clang++ -fsanitize=fuzzer,address -g -O0 -I/libtiff/include poc.cc -o poc.out libtiff.a -lz -ljpeg -llzma -ljbig

Trigger the bug:

./poc.out oom_input

Platform

Ubuntu 22.04 Clang 15.0.0

ASAN message

    #1 0x556a1dd64428 in fuzzer::PrintStackTrace() /data/home/loydlv/llvm/llvm-project/compiler-rt/lib/fuzzer/FuzzerUtil.cpp:210:5
    #2 0x556a1dd46ad5 in fuzzer::Fuzzer::HandleMalloc(unsigned long) /data/home/loydlv/llvm/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:131:3                                                                                                                       
    #3 0x556a1dd469ea in fuzzer::MallocHook(void const volatile*, unsigned long) /data/home/loydlv/llvm/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:100:6                                                                                                           
    #4 0x556a1de51222 in __sanitizer::RunMallocHooks(void*, unsigned long) /data/home/loydlv/llvm/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common.cpp:325:5                                                                                                 
    #5 0x556a1ddbe56b in __asan::Allocator::Allocate(unsigned long, unsigned long, __sanitizer::BufferedStackTrace*, __asan::AllocType, bool) /data/home/loydlv/llvm/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp:600:5                                            
    #6 0x556a1ddbe905 in __asan::asan_realloc(void*, unsigned long, __sanitizer::BufferedStackTrace*) /data/home/loydlv/llvm/llvm-project/compiler-rt/lib/asan/asan_allocator.cpp:973:36                                                                                   
    #7 0x556a1de40aa8 in __interceptor_realloc /data/home/loydlv/llvm/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:86:10
    #8 0x556a1dea3c0c in _TIFFrealloc /data/home/loydlv/vbd/llm_fuzz/output/build/libtiff/src/libtiff/libtiff/tif_unix.c:339:51
    #9 0x556a1de9a433 in _TIFFreallocExt /data/home/loydlv/vbd/llm_fuzz/output/build/libtiff/src/libtiff/libtiff/tif_open.c:158:12
    #10 0x556a1dea4088 in _TIFFCheckRealloc /data/home/loydlv/vbd/llm_fuzz/output/build/libtiff/src/libtiff/libtiff/tif_aux.c:107:14
    #11 0x556a1dea4100 in _TIFFCheckMalloc /data/home/loydlv/vbd/llm_fuzz/output/build/libtiff/src/libtiff/libtiff/tif_aux.c:125:12
    #12 0x556a1de980dd in allocChoppedUpStripArrays /data/home/loydlv/vbd/llm_fuzz/output/build/libtiff/src/libtiff/libtiff/tif_dirread.c:7267:21                                                                                                                          
    #13 0x556a1de907d9 in ChopUpSingleUncompressedStrip /data/home/loydlv/vbd/llm_fuzz/output/build/libtiff/src/libtiff/libtiff/tif_dirread.c:7381:5                                                                                                                       
    #14 0x556a1de89cdb in TIFFReadDirectory /data/home/loydlv/vbd/llm_fuzz/output/build/libtiff/src/libtiff/libtiff/tif_dirread.c:4977:9                                                                                                                                   
    #15 0x556a1de9b13f in TIFFClientOpenExt /data/home/loydlv/vbd/llm_fuzz/output/build/libtiff/src/libtiff/libtiff/tif_open.c:629:17
    #16 0x556a1dea35bd in TIFFFdOpenExt /data/home/loydlv/vbd/llm_fuzz/output/build/libtiff/src/libtiff/libtiff/tif_unix.c:209:11
    #17 0x556a1dea3b10 in TIFFOpenExt /data/home/loydlv/vbd/llm_fuzz/output/build/libtiff/src/libtiff/libtiff/tif_unix.c:255:11
    #18 0x556a1dea39f0 in TIFFOpen /data/home/loydlv/vbd/llm_fuzz/output/build/libtiff/src/libtiff/libtiff/tif_unix.c:222:12
    #19 0x556a1de7cf11 in LLVMFuzzerTestOneInput /data/home/loydlv/test_dir/crash/libtiff/oom1/poc.cc:37:15
    #20 0x556a1dd48ec2 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /data/home/loydlv/llvm/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:612:13                                                                                            
    #21 0x556a1dd34563 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /data/home/loydlv/llvm/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:324:6                                                                                                
    #22 0x556a1dd39d24 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /data/home/loydlv/llvm/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:860:9                                                                              
    #23 0x556a1dd64be2 in main /data/home/loydlv/llvm/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
    #24 0x7fe4bdebad84 in __libc_start_main ../csu/libc-start.c:302:16
    #25 0x556a1dd2a8dd in _start (/data/home/loydlv/test_dir/crash/libtiff/oom1/poc.out+0x368dd)

SUMMARY: libFuzzer: out-of-memory