PT-2026-76319 · Julia · Imagemagick Jll

Publicado

2026-07-30

·

Atualizado

2026-07-30

CVSS v3.1

5.5

Média

VetorAV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H

Summary

A single root cause in the CLAHE implementation — tile width/height becoming zero — produces two distinct but related unsafe behaviors. Vulnerabilities exists in the CLAHEImage() function of ImageMagick’s MagickCore/enhance.c.
  1. Unsigned integer underflow → out-of-bounds pointer arithmetic (OOB): when tile info.height == 0, the expression tile info.height - 1 (unsigned) wraps to a very large value; using that value in pointer arithmetic yields a huge offset and OOB memory access (leading to memory corruption, SIGSEGV, or resource exhaustion).
  2. Division/modulus by zero: where code performs ... / tile info.width or ... % tile info.height without re-checking for zero, causing immediate division-by-zero crashes under sanitizers or abort at runtime.
Both behaviors are triggered by the same invalid tile condition (e.g., CLI exact -clahe 0x0! or automatic tile derivation dim >> 3 == 0 for very small images).

Details

Unsigned underflow(can lea to OOB)

  • Location: MagickCore/enhance.c, around line 609
  • Version tested: 7.1.2-8 (local ASan(undefined). /UBSan build)
  • Vulnerable code
enhance.c: 609
c
p += (ptrdiff t) clahe info->width * (tile.height - 1);
  • Root Cause
    • If tile.height == 0, then (tile.height - 1) underflows to UINT MAX.
    • Multiplication with clahe info->width yields a huge value close to SIZE MAX.
    • Adding this to p causes pointer arithmetic underflow.

Division-by-zero

  • File / Location: MagickCore/enhance.c, around line 669
  • Version tested: 7.1.2-8 (local ASan(undefined). /UBSan build)
  • vulnerable code
enhance.c: 669-673
c
 if ((image->columns % tile info.width) != 0)
  tile info.x=(ssize t) (tile info.width-(image->columns % tile info.width));
 tile info.y=0;
 if ((image->rows % tile info.height) != 0)
  tile info.y=(ssize t) (tile info.height-(image->rows % tile info.height));
  • Root cause
Missing input validation / bounds checks after computing default tile dimensions:
If either tile info.width or tile info.height is 0, this triggers a division by zero. Zeros can reach this point through:
  1. Exact tiles: CLI clahe 0x0! (the ! forces zero to be used verbatim).
  2. Auto tiles on tiny images: When a requested tile is 0 (no !), the code derives a default from the image size (e.g., dim >> 3). For images with dim < 8, this result is 0 unless clamped.

Reproduction

Unsigned underflow

Environment
Built with AddressSanitizer and UndefinedBehaviorSanitizer enabled.
c
export UBSAN OPTIONS=print stacktrace=1:halt on error=1
export ASAN OPTIONS=abort on error=1:allocator may return null=1:detect leaks=0
Command
bash
./magick xc:black -clahe 0x0 null:
Output
MagickCore/enhance.c:609:6: runtime error: addition of unsigned offset overflowed
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior MagickCore/enhance.c:609:6 in CLAHEImage
./magick -size 10x10 xc:black -clahe 0x0 null:
image memory region corruption. `./magick -size 2000x2000 xc:black -clahe 0x0 null:` image → Significant memory consumption and evidence of memory region corruption. `./magick -size 4000x4000 xc:black -clahe 0x0 null:` image → Much larger memory usage; process appears to be aggressively consuming cache and address space. `./magick -size 8000x8000 xc:black -clahe 0x0 null:` image → Memory usage escalates further and begins exhausting available cache. If left running, the process is likely to crash (DoS) after sustained allocation attempts. ### **Division-by-zero** **Environment:** ASan/UBSan-enabled build. ```c export UBSAN OPTIONS=print stacktrace=1:halt on error=1 export ASAN OPTIONS=abort on error=1:allocator may return null=1:detect leaks=0 ```
Command
bash
./magick -size 16x2 gradient: -type TrueColor -depth 8 -clahe 0x0! null:
Output
image **Notes:** Without sanitizers, the process may terminate with just `Aborted` (still DoS). * * * ## Impact - Primary: Denial-of-Service — crash or sustained resource exhaustion (memory/cache thrash) when processing crafted parameters or small images via CLI or API. Attackers can trivially trigger via `clahe 0x0!` or by uploading very small images to services using ImageMagick. - Secondary (theoretical): OOB memory accesses and memory corruption could potentially be combined with other vulnerabilities to achieve more severe outcomes; however, no reliable code execution was demonstrated from these PoCs alone.

Suggested concrete patch snippets

Apply in CLAHEImage() after tile info is computed but before any division/modulus/pointer arithmetic:
c
if (exact tiles requested && (tile info.width == 0 || tile info.height == 0)) {
 ThrowMagickException(exception, GetMagickModule(), OptionError,
            "CLAHEInvalidTile", "%lux%lu",
            (unsigned long) tile info.width,
            (unsigned long) tile info.height);
 return (Image *) NULL;
}

if (!exact tiles requested) {
 tile info.width = (tile info.width == 0) ? MagickMax((size t)1, image->columns >> 3) : tile info.width;
 tile info.height = (tile info.height == 0) ? MagickMax((size t)1, image->rows  >> 3) : tile info.height;
}

if (tile info.width == 0 || tile info.height == 0) {
 ThrowMagickException(exception, GetMagickModule(), OptionError,
            "CLAHEInvalidTile", "%lux%lu",
            (unsigned long) tile info.width,
            (unsigned long) tile info.height);
 return (Image *) NULL;
}

ssize t tile h minus1 = (ssize t)tile info.height - 1;
if (tile h minus1 < 0) {
 ThrowMagickException(exception, GetMagickModule(), OptionError,
            "CLAHEInvalidTile", "%lux%lu",
            (unsigned long) tile info.width,
            (unsigned long) tile info.height);
 return (Image *) NULL;
}
p += (ptrdiff t) clahe info->width * tile h minus1;
Notes about exact tiles requested: if the CLI/Wand parser already exposes whether ! was present, use it. If not, add a parse-time flag so CLAHEImage can know whether 0 is literal or auto.

Credit

Team Whys

Bug Hunting Master Program, HSpace/Findthegap
Youngmin Kim kunshim@naver.com
Woojin Park
Youngin Won
Siyeon Han
Shinyoung Won

Correção

Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾

Identificadores relacionados

JLSEC-2026-928

Produtos afetados

Imagemagick Jll