GitHub Advisoryadvisory · NuGet
GHSA-qh3h-j545-h8c9 ImageMagick has a Stack Buffer Overflow in image.c
HIGH
Official page ↗
- Aliases
- CVE-2025-53101
- Ecosystem
- NuGet
- Packages
- Magick.NET-Q16-AnyCPU, Magick.NET-Q16-HDRI-AnyCPU, Magick.NET-Q16-HDRI-OpenMP-arm64, Magick.NET-Q16-HDRI-OpenMP-x64, Magick.NET-Q16-HDRI-arm64, Magick.NET-Q16-HDRI-x64, Magick.NET-Q16-HDRI-x86, Magick.NET-Q16-OpenMP-arm64, Magick.NET-Q16-OpenMP-x64, Magick.NET-Q16-arm64, Magick.NET-Q16-x64, Magick.NET-Q16-x86, Magick.NET-Q8-AnyCPU, Magick.NET-Q8-OpenMP-arm64, Magick.NET-Q8-OpenMP-x64, Magick.NET-Q8-arm64, Magick.NET-Q8-x64, Magick.NET-Q8-x86
- Severity
- High
- CVSS vector
- CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:H/A:H
- Weaknesses
- CWE-124
- Reviewed
- 2025-08-25
Affected packages
• NuGet Magick.NET-Q16-AnyCPU: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q16-HDRI-AnyCPU: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q16-HDRI-OpenMP-arm64: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q16-HDRI-OpenMP-x64: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q16-HDRI-arm64: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q16-HDRI-x64: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q16-HDRI-x86: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q16-OpenMP-arm64: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q16-OpenMP-x64: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q16-arm64: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q16-x64: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q16-x86: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q8-AnyCPU: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q8-OpenMP-arm64: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q8-OpenMP-x64: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q8-arm64: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q8-x64: < 14.7.0 → fixed in 14.7.0
• NuGet Magick.NET-Q8-x86: < 14.7.0 → fixed in 14.7.0
Description
Hi, we have found a stack buffer overflow and would like to report this issue.
Could you confirm if this qualifies as a security vulnerability? I am happy to provide any additional information needed.
Summary
In ImageMagick's `magick mogrify` command, specifying multiple consecutive `%d` format specifiers in a filename template causes internal pointer arithmetic to generate an address below the beginning of the stack buffer, resulting in a stack overflow through `vsnprintf()`.
Additional information
Upon further investigation, we found that the same issue occurs not only with mogrify but also with the following subcommands: compare, composite, conjure, convert, identify, mogrify, and montage.
Furthermore, we confirmed that this vulnerability has the potential to lead to RCE. RCE is possible when ASLR is disabled and there is a suitable one_gadget in libc, provided that options and filenames can be controlled.
Details
• Vulnerability Type: CWE-124: Buffer Underwrite
• Affected Component: MagickCore/image.c - Format processing within InterpretImageFilename()
• Affected Version: ImageMagick 7.1.1-47 (as of commit 82572afc, June 2025)
• CWE-124: Buffer Underwrite: A vulnerability where writing occurs to memory addresses before the beginning of a buffer. This is caused by a design flaw in fixed offset correction, resulting in negative pointer arithmetic during consecutive format specifier processing.
Reproduction
Tested Environment
• Operating System: Ubuntu 22.04 LTS
• Architecture: x86_64
• Compiler: gcc with AddressSanitizer (gcc version: 11.4.0)
Reproduction Steps
```bash
Clone source
git clone --depth 1 --branch 7.1.1-47 https://github.com/ImageMagick/ImageMagick.git ImageMagick-7.1.1
cd ImageMagick-7.1.1
Build with ASan
CFLAGS="-g -O0 -fsanitize=address -fno-omit-frame-pointer" CXXFLAGS="$CFLAGS" LDFLAGS="-fsanitize=address" ./configure --enable-maintainer-mode --enable-shared && make -j$(nproc) && make install
Trigger crash
./utilities/magick mogrify %d%d
```
Output
```plaintext
==4155==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7ffda834caae at pc 0x7f1ea367fb27 bp 0x7ffda834b680 sp 0x7ffda834ae10
WRITE of size 2 at 0x7ffda834caae thread T0
#0 0x7f1ea367fb26 in __interceptor_vsnprintf ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:1668
#1 0x7f1ea2dc9e3e in FormatLocaleStringList MagickCore/locale.c:470
#2 0x7f1ea2dc9fd9 in FormatLocaleString MagickCore/locale.c:495
#3 0x7f1ea2da0ad5 in InterpretImageFilename MagickCore/image.c:1696
#4 0x7f1ea2c6126b in ReadImages MagickCore/constitute.c:1051
#5 0x7f1ea27ef29b in MogrifyImageCommand MagickWand/mogrify.c:3858
#6 0x7f1ea278e95d in MagickCommandGenesis MagickWand/magick-cli.c:177
#7 0x560813499a0c in MagickMain utilities/magick.c:153
#8 0x560813499cba in main utilities/magick.c:184
#9 0x7f1ea1c0bd8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
#10 0x7f1ea1c0be3f in __libc_start_main_impl ../csu/libc-start.c:392
#11 0x560813499404 in _start (/root/workdir/ImageMagick/utilities/.libs/magick+0x2404)
Address 0x7ffda834caae is located in stack of thread T0 at offset 62 in frame
#0 0x7f1ea2c60f62 in ReadImages MagickCore/constitute.c:1027
This frame has 2 object(s):
[32, 40) 'images' (line 1033)
[64, 4160) 'read_filename' (line 1029) 0x100035061950: f1 f1 00 f2 f2[f2]00 00 00 00 00 00 00 00 00 00
0x100035061960: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100035061970: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100035061980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x100035061990: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x1000350619a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==4155==ABORTING
```
Affected Code
In `MagickCore/image.c`, within the `InterpretImageFilename()` function:
```c
MagickExport size_t InterpretImageFilename(const ImageInfo *image_info,
Image *image,const char *format,int value,char *filename,
ExceptionInfo *exception)
{
...
for (p=strchr(format,'%'); p != (char *) NULL; p=strchr(p+1,'%'))
{
q=(char *) p+1;
if (*q == '%')
{
p=q+1;
continue;
}
field_width=0;
if (*q == '0')
field_width=(ssize_t) strtol(q,&q,10);
switch (*q)
{
case 'd':
case 'o':
case 'x':
{
q++;
c=(*q);
*q='\0';
/*--------Affected--------*/
(void) FormatLocaleString(filename+(p-format-offset),(size_t)
(MagickPathExtent-(p-format-offset)),p,value);
offset+=(4-field_width);
/*--------Affected--------*/
*q=c;
(void) ConcatenateMagickString(filename,q,MagickPathExtent);
canonical=MagickTrue;
if (*(q-1) != '%')
break;
p++;
break;
}
case '[':
{
...
}
default:
break;
}
}
```
Technical Analysis
This vulnerability is caused by an inconsistency in the template expansion processing within `InterpretImageFilename()`.
The format specifiers `%d`, `%o`, and `%x` in templates are replaced with integer values by `FormatLocaleString()`, but the output buffer position is calculated by `filename + (p - format - offset)`.
The `offset` variable is cumulatively incremented to correct the output length of `%d` etc., but the design using a static `offset += (4 - field_width)` causes `offset` to increase excessively when `%` specifiers are consecutive in the template, creating a dangerous state where the write destination address points before `filename`.
The constant `4` was likely chosen based on the character count of typical format specifiers like `%03d` (total of 4 characters: `%`, `0`, `3`, `d`). However, in reality, there are formats with only 2 characters like `%d`, and formats with longer width specifications (e.g., `%010d`), so this uniform constant-based correction is inconsistent with actual template structures.
As a result, when the correction value becomes excessive, `offset` exceeds the relative position `p - format` within the template, generating a negative index. This static and template-independent design of the correction processing is the root cause of this vulnerability.
This causes `vsnprintf()` to write outside the stack buffer range, which is detected by AddressSanitizer as a `stack-buffer-overflow`.
Proposed Fix
In `MagickCore/image.c`, within the `InterpretImageFilename()` function:
```c
MagickExport size_t InterpretImageFilename(const ImageInfo…
Related
Alias · CVE (1)
- CVE-2025-53101 ImageMagick is free and open-source software used for editing and manipulating digital images. vulnerability
Weakness · CWE (1)
- CWE-124 Buffer Underwrite weakness
References
- https://github.com/ImageMagick/ImageMagick/security/advisories/GHSA-qh3h-j545-h8c9 web
- https://nvd.nist.gov/vuln/detail/CVE-2025-53101 advisory
- https://github.com/ImageMagick/ImageMagick/commit/66dc8f51c11b0ae1f1cdeacd381c3e9a4de69774 web
- https://github.com/ImageMagick/ImageMagick6/commit/643deeb60803488373cd4799b24d5786af90972e web
- https://github.com/ImageMagick/ImageMagick package
- https://github.com/dlemstra/Magick.NET/releases/tag/14.7.0 web
- https://lists.debian.org/debian-lts-announce/2025/09/msg00012.html web