GitHub Advisoryadvisory · NuGet

GHSA-23hg-53q6-hqfg ImageMagick BlobStream Forward-Seek Under-Allocation

LOW Published 2025-09-05 Modified 2025-11-03 Official page ↗
Aliases
CVE-2025-57807
Ecosystem
NuGet
Packages
Magick.NET-Q16-x64, Magick.NET-Q8-x64, Magick.NET-Q16-HDRI-x64, Magick.NET-Q8-OpenMP-x64, Magick.NET-Q16-HDRI-OpenMP-x64, Magick.NET-Q16-OpenMP-x64, Magick.NET-Q8-arm64, Magick.NET-Q16-arm64, Magick.NET-Q16-OpenMP-arm64, Magick.NET-Q8-OpenMP-arm64, Magick.NET-Q16-HDRI-OpenMP-arm64, Magick.NET-Q16-HDRI-arm64
Severity
Low
CVSS vector
CVSS:3.1/AV:L/AC:H/PR:H/UI:R/S:U/C:L/I:L/A:L
Weaknesses
CWE-122, CWE-131, CWE-787
Reviewed
2025-09-05

Affected packages

• NuGet Magick.NET-Q16-x64: < 14.8.2 → fixed in 14.8.2 • NuGet Magick.NET-Q8-x64: < 14.8.2 → fixed in 14.8.2 • NuGet Magick.NET-Q16-HDRI-x64: < 14.8.2 → fixed in 14.8.2 • NuGet Magick.NET-Q8-OpenMP-x64: < 14.8.2 → fixed in 14.8.2 • NuGet Magick.NET-Q16-HDRI-OpenMP-x64: < 14.8.2 → fixed in 14.8.2 • NuGet Magick.NET-Q16-OpenMP-x64: < 14.8.2 → fixed in 14.8.2 • NuGet Magick.NET-Q8-arm64: < 14.8.2 → fixed in 14.8.2 • NuGet Magick.NET-Q16-arm64: < 14.8.2 → fixed in 14.8.2 • NuGet Magick.NET-Q16-OpenMP-arm64: < 14.8.2 → fixed in 14.8.2 • NuGet Magick.NET-Q8-OpenMP-arm64: < 14.8.2 → fixed in 14.8.2 • NuGet Magick.NET-Q16-HDRI-OpenMP-arm64: < 14.8.2 → fixed in 14.8.2 • NuGet Magick.NET-Q16-HDRI-arm64: < 14.8.2 → fixed in 14.8.2

Description

Reporter: Lumina Mescuwa Product: ImageMagick 7 (MagickCore) Component: `MagickCore/blob.c` (Blob I/O - BlobStream) Tested: 7.1.2-0 (source tag) and 7.1.2-1 (Homebrew), macOS arm64, clang-17, Q16-HDRI Impact: Heap out-of-bounds WRITE (attacker-controlled bytes at attacker-chosen offset) → memory corruption; potential code execution --- Executive Summary For memory-backed blobs (BlobStream), `SeekBlob()` permits advancing the stream offset beyond the current end without increasing capacity. The subsequent `WriteBlob()` then expands by `quantum + length` (amortized) instead of `offset + length`, and copies to `data + offset`. When `offset ≫ extent`, the copy targets memory beyond the allocation, producing a deterministic heap write on 64-bit builds. No 2⁶⁴ arithmetic wrap, external delegates, or policy settings are required. --- Affected Scope • Versions confirmed: 7.1.2-0, 7.1.2-1 • Architectures: Observed on macOS arm64; architecture-agnostic on LP64 • Paths: MagickCore blob subsystem — BlobStream (`SeekBlob()` and `WriteBlob()`). • Not required: External delegates; special policies; integer wraparound --- Technical Root Cause Types (LP64): `offset: MagickOffsetType` (signed 64-bit) `extent/length/quantum: size_t` (unsigned 64-bit) `data: unsigned char*` Contract mismatch: • `SeekBlob()` (BlobStream) updates `offset` to arbitrary positions, including past end, without capacity adjustment. • `WriteBlob()` tests `offset + length >= extent` and grows by `length + quantum`, doubles `quantum`, reallocates to `extent + 1`, then: ``` q = data + (size_t)offset; memmove(q, src, length); ``` There is no guarantee that `extent ≥ offset + length` post-growth. With `offset ≫ extent`, `q` is beyond the allocation. Wrap-free demonstration: Initialize `extent=1`, write one byte (`offset=1`), seek to `0x10000000` (256 MiB), then write 3–4 bytes. Growth remains Before copying `length` bytes at `offset`, enforce `extent ≥ offset + length` with overflow-checked arithmetic. The BlobStream growth policy preserves amortized efficiency but fails to enforce this per-write safety invariant. --- Remediation (Principle) In `WriteBlob()` (BlobStream case): 1. Checked requirement: `need = (size_t)offset + length;` → if `need magick_version.txt ``` --- Build & Run the PoC (memory-backed BlobStream) `poc.c`: _Uses private headers (`blob-private.h`) to exercise blob internals; a public-API variant (custom streams) is feasible but unnecessary for triage._ ```c // poc.c include include include include include "MagickCore/blob-private.h" int main(int argc, char **argv) { MagickCoreGenesis(argv[0], MagickTrue); ExceptionInfo *e = AcquireExceptionInfo(); ImageInfo *ii = AcquireImageInfo(); Image *im = AcquireImage(ii, e); if (!im) return 1; // 1-byte memory blob → BlobStream unsigned char *buf = (unsigned char*) malloc(1); buf[0] = 0x41; AttachBl…

Related

Alias · CVE (1)

  • CVE-2025-57807 ImageMagick is free and open-source software used for editing and manipulating digital images. vulnerability

Weakness · CWE (3)

  • CWE-122 Heap-based Buffer Overflow weakness
  • CWE-131 Incorrect Calculation of Buffer Size weakness
  • CWE-787 Out-of-bounds Write weakness

References