Skip to content

ImageMagick has Undefined Behavior (function-type-mismatch) in CloneSplayTree

Moderate severity GitHub Reviewed Published Aug 13, 2025 in ImageMagick/ImageMagick • Updated Aug 25, 2025

Package

nuget Magick.NET-Q16-AnyCPU (NuGet)

Affected versions

< 14.8.0

Patched versions

14.8.0
nuget Magick.NET-Q16-HDRI-AnyCPU (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q16-HDRI-OpenMP-arm64 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q16-HDRI-OpenMP-x64 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q16-HDRI-arm64 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q16-HDRI-x64 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q16-HDRI-x86 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q16-OpenMP-arm64 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q16-OpenMP-x64 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q16-arm64 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q16-x64 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q16-x86 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q8-AnyCPU (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q8-OpenMP-arm64 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q8-OpenMP-x64 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q8-arm64 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q8-x64 (NuGet)
< 14.8.0
14.8.0
nuget Magick.NET-Q8-x86 (NuGet)
< 14.8.0
14.8.0

Description

Summary

  • Target: ImageMagick (commit ecc9a5eb456747374bae8e07038ba10b3d8821b3)
  • Type: Undefined Behavior (function-type-mismatch) in splay tree cloning callback
  • Impact: Deterministic abort under UBSan (DoS in sanitizer builds). No crash in a non-sanitized build; likely low security impact.
  • Trigger: Minimal 2-byte input parsed via MagickWand, then coalescing.

Environment

OS: macOS (Apple Silicon/arm64)
Homebrew clang version 20.1.8
Target: arm64-apple-darwin24.5.0
Thread model: posix
InstalledDir: /opt/homebrew/Cellar/llvm/20.1.8/bin
Configuration file: /opt/homebrew/etc/clang/arm64-apple-darwin24.cfg
Homebrew ImageMagick: magick -versionImageMagick 7.1.2-0 Q16-HDRI aarch64
pkg-config: MagickWand-7.Q16HDRI version 7.1.2
Library configure flags (capsule build):
./configure --disable-shared --enable-static --without-modules --without-magick-plus-plus --disable-openmp --without-perl --without-x --with-png=yes --without-jpeg --without-tiff --without-xml --without-lqr --without-gslib
Harness compile flags:
-fsanitize=fuzzer,address,undefined -fno-omit-frame-pointer
pkg-config cflags/libs supplied:
-I<...>/include/ImageMagick-7
-DMAGICKCORE_HDRI_ENABLE=1 -DMAGICKCORE_QUANTUM_DEPTH=16 -DMAGICKCORE_CHANNEL_MASK_DEPTH=32
and linked against MagickWand-7.Q16HDRI and MagickCore-7.Q16HDRI
Sanitizer runtime:
ASan+UBSan defaults. Repro also with UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1

PoC

  • Bytes (hex): 1c 02
  • Base64: HAI=
  • sha256 (optional):

Reproduction

Create PoC:

printf '\x1c\x02' > poc.bin

Option A: libFuzzer harness

  • Run once: ./harness_ImageMagick_... -runs=1 ./poc.bin
  • Expected: UBSan aborts with function-type-mismatch at MagickCore/splay-tree.c:372:43.

Option B: standalone reproducer (C)

  • Compile (ensure PKG_CONFIG_PATH points to your ImageMagick if needed):

/opt/homebrew/opt/llvm/bin/clang -g -O1 -fsanitize=address,undefined $(/opt/homebrew/bin/pkg-config --cflags MagickWand-7.Q16HDRI) repro.c -o repro $(/opt/homebrew/bin/pkg-config --libs MagickWand-7.Q16HDRI)

  • Run:

UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 ./repro ./poc.bin
Observed output (excerpt)
MagickCore/splay-tree.c:372:43: runtime error: call to function ConstantString through pointer to incorrect function type 'void ()(void *)'
string.c:680: note: ConstantString defined here
#0 CloneSplayTree splay-tree.c:372
#1 CloneImageProfiles profile.c:159
#2 CloneImage image.c:832
#3 CoalesceImages layer.c:269
#4 MagickCoalesceImages magick-image.c:1665
#5 main repro.c:XX
Root cause
The splay tree clone callback expects a function pointer of type void *(*)(void *). ConstantString has a different signature (char *ConstantString(const char *)). Calling through the mismatched function type is undefined behavior in C and triggers UBSan’s function-type-mismatch.
The path is exercised during coalescing: CloneImage → CloneImageProfiles → CloneSplayTree.
Scope
Reproduces with a minimal, sanitizer-instrumented, PNG-enabled build and delegates disabled (policy.xml), suggesting the issue is in MagickCore rather than external delegates.
Suggested fix (sketch)
Use a wrapper that matches the expected callback prototype, or adjust the splay-tree callback typedef for const-correctness. For example:
static void *CloneStringShim(const void *p) {
return (void *) ConstantString((const char *) p);
}

/* When setting splay-tree clone_value, use CloneStringShim instead of ConstantString. */

Alternatively, update the clone callback typedefs to use const void* consistently (and return void*) and ensure callers pass a correctly typed wrapper.

Artifacts
Minimised PoC: attached (poc.bin, 2 bytes; base64 HAI=)
Harness source and exact build command (attached)
Full UBSan trace (attached)
Commit SHA and configure flags (above)
Credits
Discovered by: Lumina Mescuwa
Method: libFuzzer + UBSan
Verification

  • UBSan build: Reproduces with halt_on_error=1; aborts at MagickCore/splay-tree.c:372.
  • Non-sanitized Homebrew build (macOS arm64, clang 20.1.8): No crash; repro completes silently.

References

@urban-warrior urban-warrior published to ImageMagick/ImageMagick Aug 13, 2025
Published by the National Vulnerability Database Aug 13, 2025
Published to the GitHub Advisory Database Aug 25, 2025
Reviewed Aug 25, 2025
Last updated Aug 25, 2025

Severity

Moderate

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Local
Attack complexity
Low
Privileges required
None
User interaction
Required
Scope
Unchanged
Confidentiality
None
Integrity
High
Availability
Low

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:H/A:L

EPSS score

Exploit Prediction Scoring System (EPSS)

This score estimates the probability of this vulnerability being exploited within the next 30 days. Data provided by FIRST.
(7th percentile)

Weaknesses

Reliance on Undefined, Unspecified, or Implementation-Defined Behavior

The product uses an API function, data structure, or other entity in a way that relies on properties that are not always guaranteed to hold for that entity. Learn more on MITRE.

CVE ID

CVE-2025-55160

GHSA ID

GHSA-6hgw-6x87-578x

Credits

Loading Checking history
See something to contribute? Suggest improvements for this vulnerability.