libheif icon indicating copy to clipboard operation
libheif copied to clipboard

oss-fuzz reports "graphicsmagick:coder_HEIF_fuzzer: Abrt in std::terminate" in GraphicsMagick oss-fuzz testing

Open bobfriesenhahn opened this issue 4 months ago • 21 comments

oss-fuzz issue 42535687 has been open since May 20th. Although it only occurs while using libheif, I was not aware that it was due to a libheif implementation feature. There appears to be an ordering/race condition related to C++ object destruction.

The most recent crash looks like this:

[Environment] ASAN_OPTIONS=handle_abort=2
	+----------------------------------------Release Build Stacktrace----------------------------------------+
	Command: /mnt/scratch0/clusterfuzz/bot/builds/clusterfuzz-builds-honggfuzz_graphicsmagick_364babd4f1406e0e2b68256230a27a3911dd0072/revisions/coder_HEIF_fuzzer
	Time ran: 9.153208017349243
	
	Accepting input from '[STDIN]'
	Usage for fuzzing: honggfuzz -P [flags] -- /mnt/scratch0/clusterfuzz/bot/builds/clusterfuzz-builds-honggfuzz_graphicsmagick_364babd4f1406e0e2b68256230a27a3911dd0072/revisions/coder_HEIF_fuzzer
	12:30:30 0:3.427734  0.030u 470 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	libc++abi: terminating due to uncaught exception of type std::__1::system_error: recursive_mutex lock failed: Invalid argument
	AddressSanitizer:DEADLYSIGNAL
	=================================================================
	==470==ERROR: AddressSanitizer: ABRT on unknown address 0x0539000001d6 (pc 0x7da5d33cc00b bp 0x7ffce926be40 sp 0x7ffce926bab0 T0)
	    #0 0x7da5d33cc00b in raise /build/glibc-LcI20x/glibc-2.31/sysdeps/unix/sysv/linux/raise.c:51:1
	    #1 0x7da5d33ab858 in abort /build/glibc-LcI20x/glibc-2.31/stdlib/abort.c:79:7
	    #2 0x58d5a057d5c5 in abort_message
	    #3 0x58d5a05ce0da in demangling_terminate_handler() cxa_default_handlers.cpp:0
	    #4 0x58d5a057d122 in std::__terminate(void (*)())
	    #5 0x58d5a057d0d7 in std::terminate()
	    #6 0x58d59fca655d in __clang_call_terminate
	    #7 0x58d59fcd5723 in Magick::MagickCleanUp::~MagickCleanUp() /src/graphicsmagick/Magick++/lib/Image.cpp:4274:3
	    #8 0x7da5d33cf8a6 in __run_exit_handlers /build/glibc-LcI20x/glibc-2.31/stdlib/exit.c:108:8
	    #9 0x7da5d33cfa5f in exit /build/glibc-LcI20x/glibc-2.31/stdlib/exit.c:139:3
	    #10 0x7da5d33ad089 in __libc_start_main /build/glibc-LcI20x/glibc-2.31/csu/libc-start.c:342:3
	    #11 0x58d59fbc2e4d in _start

while an older one looks like this:

[Environment] ASAN_OPTIONS=handle_abort=2
	+----------------------------------------Release Build Stacktrace----------------------------------------+
	Command: /mnt/scratch0/clusterfuzz/resources/platform/linux/unshare -c -n /mnt/scratch0/clusterfuzz/bot/builds/clusterfuzz-builds_graphicsmagick_364babd4f1406e0e2b68256230a27a3911dd0072/revisions/coder_HEIF_fuzzer -runs=100 '/mnt/scratch0/clusterfuzz/bot/inputs/fuzzer-testcases/SIGABRT.PC.7ffff7c5800b.STACK.196078ee6b.CODE.-6.ADDR.0.INSTR.[UNKNOWN].fuzz'
	Time ran: 8.059784650802612
	
	INFO: Running with entropic power schedule (0xFF, 100).
	INFO: Seed: 1615166460
	INFO: Loaded 1 modules   (391574 inline 8-bit counters): 391574 [0x58455bd81330, 0x58455bde0cc6),
	INFO: Loaded 1 PC tables (391574 PCs): 391574 [0x58455bde0cc8,0x58455c3da628),
	/mnt/scratch0/clusterfuzz/bot/builds/clusterfuzz-builds_graphicsmagick_364babd4f1406e0e2b68256230a27a3911dd0072/revisions/coder_HEIF_fuzzer: Running 1 inputs 100 time(s) each.
	Running: /mnt/scratch0/clusterfuzz/bot/inputs/fuzzer-testcases/SIGABRT.PC.7ffff7c5800b.STACK.196078ee6b.CODE.-6.ADDR.0.INSTR.[UNKNOWN].fuzz
	22:39:36 0:0.150752  0.130u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:36 0:0.221803  0.190u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:36 0:0.288175  0.260u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:36 0:0.353714  0.320u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:36 0:0.419365  0.380u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:36 0:0.485075  0.460u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:36 0:0.551264  0.520u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:36 0:0.618885  0.580u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:36 0:0.684139  0.660u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:36 0:0.749638  0.720u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:36 0:0.816136  0.780u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:36 0:0.881352  0.850u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:0.946769  0.920u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.012478  0.980u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.078458  1.040u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.144844  1.110u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.210246  1.170u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.277385  1.250u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.344041  1.310u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.409303  1.370u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.477033  1.440u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.543336  1.510u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.614337  1.570u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.679836  1.650u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.745949  1.710u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.811301  1.780u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:37 0:1.882434  1.850u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:1.947459  1.910u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.014264  1.980u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.080019  2.040u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.147457  2.110u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.212782  2.170u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.279727  2.250u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.345166  2.310u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.411277  2.370u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.477256  2.440u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.544862  2.510u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.612327  2.570u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.678802  2.640u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.743865  2.710u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.810671  2.780u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:38 0:2.876161  2.840u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:2.944075  2.900u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.009283  2.970u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.076384  3.040u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.142171  3.100u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.208545  3.170u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.273873  3.240u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.342908  3.300u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.411618  3.370u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.485878  3.450u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.554080  3.510u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.624430  3.590u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.691874  3.650u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.764778  3.720u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.831968  3.790u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:39 0:3.899832  3.860u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:3.969197  3.930u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.038489  4.000u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.106647  4.070u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.177348  4.140u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.244749  4.200u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.313467  4.270u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.381245  4.330u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.450122  4.410u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.517871  4.470u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.589813  4.540u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.658660  4.620u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.727759  4.680u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.797321  4.760u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:40 0:4.865695  4.820u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:4.932184  4.890u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:5.003661  4.960u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:5.180801  5.030u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:5.250406  5.100u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:5.322645  5.170u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:5.391033  5.240u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:5.457982  5.310u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:5.524536  5.380u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:5.591229  5.440u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:5.658108  5.500u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:5.722914  5.570u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:5.788859  5.630u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:41 0:5.853642  5.700u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:5.922248  5.770u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:5.987059  5.830u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.053640  5.900u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.119894  5.960u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.186020  6.030u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.251065  6.100u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.320028  6.170u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.385374  6.230u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.451998  6.300u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.517101  6.360u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.588369  6.430u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.654644  6.500u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.720871  6.560u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.786316  6.630u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:42 0:6.852573  6.690u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:43 0:6.917696  6.750u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	22:39:43 0:6.983921  6.830u 701648 heif.c/ReadHEIFImage/568/CorruptImage:
	  An error has occurred reading from file ()
	Executed /mnt/scratch0/clusterfuzz/bot/inputs/fuzzer-testcases/SIGABRT.PC.7ffff7c5800b.STACK.196078ee6b.CODE.-6.ADDR.0.INSTR.[UNKNOWN].fuzz in 6912 ms
	***
	*** NOTE: fuzzing was not performed, you have only
	***       executed the target code on a fixed set of inputs.
	***
	libc++abi: terminating due to uncaught exception of type std::__1::system_error: recursive_mutex lock failed: Invalid argument
	AddressSanitizer:DEADLYSIGNAL
	=================================================================
	==701648==ERROR: AddressSanitizer: ABRT on unknown address 0x0539000ab4d0 (pc 0x78db508ef00b bp 0x7fffe7272700 sp 0x7fffe7272370 T0)
	SCARINESS: 10 (signal)
	    #0 0x78db508ef00b in raise /build/glibc-SzIz7B/glibc-2.31/sysdeps/unix/sysv/linux/raise.c:51:1
	    #1 0x78db508ce858 in abort /build/glibc-SzIz7B/glibc-2.31/stdlib/abort.c:79:7
	    #2 0x584557e4f795 in abort_message
	    #3 0x584557ea098a in demangling_terminate_handler() cxa_default_handlers.cpp:0
	    #4 0x584557e4f312 in std::__terminate(void (*)())
	    #5 0x584557e4f2c7 in std::terminate()
	    #6 0x58455755f8dd in __clang_call_terminate
	    #7 0x58455759390c in Magick::MagickCleanUp::~MagickCleanUp() /src/graphicsmagick/Magick++/lib/Image.cpp:4274:3
	    #8 0x78db508f28a6 in __run_exit_handlers /build/glibc-SzIz7B/glibc-2.31/stdlib/exit.c:108:8
	    #9 0x78db508f2a5f in exit /build/glibc-SzIz7B/glibc-2.31/stdlib/exit.c:139:3
	    #10 0x584557401143 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:0:5
	    #11 0x58455742d4e2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:20:10
	    #12 0x78db508d0082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/libc-start.c:308:16
	    #13 0x5845573f212d in _start
	
	AddressSanitizer can not provide additional info.
	SUMMARY: AddressSanitizer: ABRT (/lib/x86_64-linux-gnu/libc.so.6+0x4300b) (BuildId: 1878e6b475720c7c51969e69ab2d276fae6d1dee)
	==701648==ABORTING

Unfortunately, with GraphicsMagick linking against, and initializing, so many 3rd-party libraries, implicit and explicit initialization of those libraries has often been using more execution time than a fairly substantial operation involving reading/writing an image file. Libheif's initialization seems expensive, especially if libheif is not actually used during execution of the program.

In order to lessen the overhead, GraphicsMagick is currently using lazy initialization of libheif like this:

At global scope:

#ifdef HAVE_HEIF_INIT
static MagickBool heif_initialized = MagickFalse;
#endif /* ifdef HAVE_HEIF_INIT */

And in ReadHEIFImage(), which may be called many times:

#ifdef HAVE_HEIF_INIT
  if (!heif_initialized)
    {
      /* heif_init() accepts a 'struct heif_init_params *' argument */
      heif_init((struct heif_init_params *) NULL);
      heif_initialized = MagickTrue;
    }
#endif /* HAVE_HEIF_INIT */
'''

and in UnregisterHEIFImage(), which should be called once:

'''
#ifdef HAVE_HEIF_DEINIT
  if (heif_initialized)
    heif_deinit();
#endif /* HAVE_HEIF_DEINIT */
'''

When Magick++ calls DestroyMagick() then UnregisterHEIFImage() would be called.
Other than a possible multi-thread reentrancy issue if heif_init() is called by multiple threads at once, is there an ordering issue caused by this?

bobfriesenhahn avatar Oct 17 '24 14:10 bobfriesenhahn