Skip to content

CVE-2026-32740: Verified Repro With Script Download

CVE-2026-32740: libheif: heap-buffer-overflow write decoding 1x4 grid of odd-height tiles

CVE-2026-32740 is verified against libheif · c. Affected versions: <= 1.21.2. Fixed in 1.22.0. Vulnerability class: OOB Write. This high reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00159.

REPRO-2026-00159 libheif · c OOB Write May 23, 2026 CVE entry ↗ .txt
Severity
HIGH
CVSS
8.8
Reproduced in
41m 53s
Tool calls
386
Spend
$6.02
01 · Overview

What Is CVE-2026-32740?

CVE-2026-32740 (GHSA-frfr-f3vg-2g6j) is a high-severity heap-buffer-overflow write vulnerability in libheif's grid tile compositing code, triggered by a crafted HEIF/AVIF image. Pruva reproduced it (reproduction REPRO-2026-00159).

02 · Severity & CVSS

CVE-2026-32740 Severity & CVSS Score

CVE-2026-32740 is rated high severity, with a CVSS base score of 8.8 out of 10.

HIGH threat level
8.8 / 10 CVSS base
Weakness CWE-787 — Out-of-bounds Write

High — serious impact or readily exploitable. Prioritize remediation.

03 · Affected Versions

Affected libheif Versions

libheif · c versions <= 1.21.2 are affected.

How to Reproduce CVE-2026-32740

$ pruva-verify REPRO-2026-00159
or curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00159/artifacts/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh
Run in a VM or disposable container. This exploits a real vulnerability.
06 · Proof of Reproduction

Proof of Reproduction for CVE-2026-32740

Reproduced by Pruva's autonomous agents — 386 tool calls over 42 min. Full root-cause analysis and the complete transcript are below.

How the agent worked 1,461 events · 386 tool calls · 42 min
42 minDuration
386Tool calls
357Reasoning steps
1,461Events
1Dead-ends
Agent activity over 42 min
Support
44
Repro
999
Variant
414
0:0041:53

Root Cause and Exploit Chain for CVE-2026-32740

Summary

CVE-2026-32740 is a heap-buffer-overflow write vulnerability in libheif's grid tile compositing code. When decoding a HEIF/AVIF image containing a grid of YCbCr 4:2:0 tiles with odd heights (e.g., 1×4 grid of 64×65 tiles), the chroma-plane copy logic in HeifPixelImage::copy_image_to() miscalculates the copy bounds. Due to independent ceiling-divisions for the destination offset (ys) and copy height (copy_height), their sum can exceed the allocated chroma plane height by one row. This results in a 32-byte (or 64-byte across Cb+Cr) out-of-bounds heap write of attacker-controlled chroma data.

Impact

  • Package: libheif (C++ HEIF/AVIF decoder/encoder library)
  • Affected versions: <= 1.21.2
  • Fixed version: 1.22.0
  • Risk level: High (CVSS 3.1 base 8.8)
  • Consequences: Any application that decodes untrusted HEIF/AVIF grid images with default build options is exposed. An attacker can craft a malicious file to write 64 bytes of fully controlled chroma data past the end of a heap allocation, enabling heap corruption, potential code execution via heap grooming, or denial of service.

Root Cause

The vulnerable function is HeifPixelImage::copy_image_to() in libheif/pixelimage.cc (v1.21.2, around line 964). When compositing a decoded tile into the grid canvas, the code computes:

uint32_t copy_height = std::min(src_height, channel_height(h - y0, chroma, channel));
uint32_t ys = channel_height(y0, chroma, channel);

For YCbCr 4:2:0, channel_height(n) uses ceiling division (n+1)/2. When the tile origin y0 is odd and the tile height is odd, ys + copy_height can exceed channel_height(total_height) by 1 row:

  • Example: total height = 260 (4 × 65), last tile y0 = 195
  • ys = ceil(195/2) = 98
  • copy_height = ceil(65/2) = 33
  • ys + copy_height = 131
  • channel_height(260) = ceil(260/2) = 130
  • Overflow: 1 row (32 bytes for a 64-pixel-wide chroma row)

The fix (in libheif v1.22.0) rewrites copy_image_to to compute the copy height from the remaining plane size instead of recomputing it from the tile height:

uint32_t copy_width  = std::min(src_width,  channel_width(w, chroma, channel) - xs);
uint32_t copy_height = std::min(src_height, channel_height(h, chroma, channel) - ys);

This ensures ys + copy_height <= channel_height(h, chroma, channel), eliminating the rounding mismatch.

Reproduction Steps

The reproduction is fully automated by repro/reproduction_steps.sh.

What the script does:

  1. Builds libheif v1.21.2 (vulnerable) with AddressSanitizer (-fsanitize=address) and JPEG encoder/decoder support.
  2. Builds libheif v1.22.0 (fixed) with the same ASan flags.
  3. Compiles repro/poc.c — a small C harness that uses the libheif C API to:
    • Create four 64×65 YCbCr 4:2:0 images.
    • Add them as JPEG-encoded tiles into a 1×4 grid (overall 64×260).
    • Write the resulting HEIF to repro/poc.heif.
    • Decode the grid back via heif_decode_image().
  4. Runs the decode step against the vulnerable build and captures ASan stderr to logs/vuln_stderr.txt.
  5. Runs the decode step against the fixed build and captures output to logs/fix_stderr.txt.
  6. Compares the two: confirms ASan heap-buffer-overflow in v1.21.2 and a clean run in v1.22.0.
  7. Writes a JSON runtime manifest with SHA256 of the PoC file and verdict.

Expected evidence:

  • Vulnerable: ERROR: AddressSanitizer: heap-buffer-overflow with a WRITE of size 32 in memcpyHeifPixelImage::copy_image_toImageItem_Grid::decode_and_paste_tile_image.
  • Fixed: No ASan diagnostic; decode completes with Decoded OK.

Evidence

  • Vulnerable ASan log: logs/vuln_stderr.txt
    • Excerpt:
      ==2297==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x52500001118f
      WRITE of size 32 at 0x52500001118f thread T4
          #0 in memcpy
          #1 in HeifPixelImage::copy_image_to(...) pixelimage.cc:964
          #2 in ImageItem_Grid::decode_and_paste_tile_image(...) grid.cc:564
      
  • Fixed run log: logs/fix_stderr.txt
    • Contains only Decoded OK with no ASan error.
  • PoC file: repro/poc.heif (SHA256 recorded in repro/runtime_manifest.json).
  • Build environments:
    • Vulnerable: external/libheif/build_vuln/libheif/libheif.so (v1.21.2 + ASan)
    • Fixed: external/libheif/build_fix/libheif/libheif.so (v1.22.0 + ASan)

Recommendations / Next Steps

  1. Upgrade to libheif >= 1.22.0 to obtain the corrected copy_image_to logic.
  2. Validate that any downstream packages (e.g., heif-convert, image viewers, thumbnailers) are rebuilt against the patched library.
  3. Regression testing: Add a unit test that creates a 1×4 grid of odd-height 4:2:0 tiles and decodes it under ASan, asserting no heap-buffer-overflow.
  4. Fuzzing: The grid tile compositing path is a good target for guided fuzzing with odd-dimension chroma-subsampled tiles.

Additional Notes

  • Idempotency: repro/reproduction_steps.sh has been executed twice consecutively with identical results (ASan overflow on v1.21.2, clean on v1.22.0).
  • Edge cases: The overflow magnitude depends on the chroma row size. For a 64-pixel-wide image, one chroma row is 32 bytes (Cb or Cr), so the total overflow is 64 bytes across both chroma planes. The advisory notes that different tile heights (e.g., 33 or 65) and different canvas sizes can be used to target different heap bucket sizes.
  • Limitations: The PoC requires a codec that preserves odd-height chroma planes correctly (JPEG in this reproduction). The built-in uncompressed codec truncates chroma height for odd dimensions, which would mask the overflow; therefore JPEG tiles are used.

CVE-2026-32740 Reproduction Transcript

The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.

Full session Replay every step — scrub the timeline or play it back.

Event 1/40
0:002:00
0:00
session startedaccounts/fireworks/models/kimi-k2p6 · cve-2026-32740 · cve-2026
0:04
0:05
0:10
0:11
web search
0:17
0:18
web search
0:26
0:27
web search
0:37
0:38
web search
0:45
0:51
1:21
1:22
web search
1:29
1:30
web search
1:34
1:34
2:00

Artifacts and Evidence for CVE-2026-32740

Scripts, logs, diffs, and output captured during the reproduction.

No artifacts available

08 · How to Fix

How to Fix CVE-2026-32740

Upgrade libheif · c to 1.22.0 or later.

Coming soon

Step-by-step mitigation and hardening guidance for CVE-2026-32740 — configuration checks, workarounds where no patch exists, and how to verify you're protected — is on the way.

10 · FAQ

FAQ: CVE-2026-32740

How does the CVE-2026-32740 heap-overflow attack work?

An attacker crafts a HEIF/AVIF image with a 1x4 grid of odd-height tiles. When the chroma-plane compositing code writes a decoded tile into the grid canvas, its miscalculated bounds cause it to write 64 bytes of attacker-controlled chroma data (across Cb and Cr planes) past the end of the allocated chroma-plane heap buffer during a normal decode with default build options, corrupting adjacent heap memory.

Which libheif versions are affected by CVE-2026-32740, and where is it fixed?

Versions <= 1.21.2 are affected. It is fixed in 1.22.0.

How severe is CVE-2026-32740?

It is rated high severity. Any application that decodes untrusted HEIF/AVIF grid images with libheif's default build options is exposed to a heap-buffer-overflow write of fully attacker-controlled data, which can enable heap corruption, potential code execution via heap grooming, or denial of service.

How can I reproduce CVE-2026-32740?

Download the verified script from this page and run it in an isolated environment against libheif <= 1.21.2. It decodes a crafted HEIF/AVIF file containing a 1x4 grid of odd-height tiles and shows the chroma-plane copy writing past the end of the heap allocation, then confirms 1.22.0 no longer overflows.
11 · References

References for CVE-2026-32740

Authoritative sources for CVE-2026-32740 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.