# Pillow: Heap over-read in WMF/EMF rendering via 16-bit dimension truncation (Windows builds)

Pillow's Windows-only drawwmf handler sizes a heap allocation from 16-bit truncated EMF/WMF dimensions but copies using full 32-bit values, causing a heap over-read.

- Payout: Research
- Severity: high
- Program: Pillow
- Found by: MegaManSec
- Disclosed: 2026-10-22
- CVE: CVE-2026-96644
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-9v9v-9qvf-h2hj
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-9v9v-9qvf-h2hj
- Tags: area:oss domain:oss impact:data-leak impact:dos kind:research platform:ghsa sev:high tech:python technique:source-review vuln:dos vuln:info-disclosure vuln:memory-corruption

**Target:** Pillow WMF/EMF image plugin and native drawwmf C handler (Windows builds)
**Root cause:** EMF bounding-box dimensions are stored without range checks; the native handler truncates bcWidth/bcHeight into 16-bit DIB header fields for allocation sizing but copies using the untruncated 32-bit dimensions.
**Steps:**
1. Craft a minimal EMF with rclBounds x1=70000, y1=1 so pixel count (70000) passes the decompression-bomb check
2. Set rclFrame non-zero and place the ' EMF' signature at offset 40
3. Open with `Image.open("poc.emf")` and call `im.load()` on a Windows build
4. Allocation uses truncated 16-bit width while the copy uses full 70000, reading past the heap buffer
**How found:** Reporter noticed the EMF branch stores signed 32-bit bounding-box dimensions with no positivity/range check, then compared the 16-bit DIB header fields used for allocation against the full-width copy length in display.c.
**Exploitation:** A crafted EMF/WMF that passes the pixel-count bomb check triggers the native drawwmf handler on Windows; the truncated allocation is over-read during the copy, leaking heap memory or crashing the process.
**Insight:** When a native handler derives allocation size from truncated header fields but copy length from full-width values, look for dimension pairs that keep the pixel-count bomb check small (wide-and-short) while overflowing the truncated field.

