GHSA-qh3h-j545-h8c9: ImageMagick has a Stack Buffer Overflow in image.c
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.SummaryIn 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 informationUpon 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.ReproductionTested Environment**Operating System:** Ubuntu 22.04 LTS**Architecture:** x86_64**Compiler:** gcc with AddressSanitizer (gcc version: 11.4.0)Reproduction StepsOutputAffected CodeIn `MagickCore/image.c`, within the `InterpretImageFilename()` function:Technical AnalysisThis 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 FixIn `MagickCore/image.c`, within the `InterpretImageFilename()` function:By updating `offset` based on the difference between template description length `(q - p)` and the number of output bytes `written`, buffer position consistency is maintained.Correction is performed according to the actual template structure, ensuring stable behavior regardless of format length without relying on static constants.Range checking of `written` allows detection of vsnprintf failures and excessive writes.CommitsFixed in https://github.com/ImageMagick/ImageMagick/commit/66dc8f51c11b0ae1f1cdeacd381c3e9a4de69774 and https://github.com/ImageMagick/ImageMagick6/commit/643deeb60803488373cd4799b24d5786af90972e
CVSS v3.1: 7.4