# REPRO-2026-00085: Pillow 10.3.0–12.1.0 allows an out-of-bounds write when loading specially crafted PSD images, potentially leading to memory corruption. ## Summary Status: published Severity: Unknown Type: security Confidence: Unknown ## Identifiers REPRO ID: REPRO-2026-00085 GHSA: GHSA-CFH3-3JMP-RVHC ## Package Name: Unknown Ecosystem: Unknown Affected: Unknown Fixed: Unknown ## Root Cause ## Summary Pillow PSD parsing in versions 10.3.0–12.1.0 allows crafted PSD tiles with invalid extents to trigger an out-of-bounds write. The crafted PSDs in the Pillow fix commit cause memory corruption during image loading and can abort the process. ## Impact - Package/component affected: python-pillow/Pillow PSD decoder (tile handling in core decoder) - Affected versions: >=10.3.0 and <12.1.1 - Risk level and consequences: High; memory corruption leading to crashes and potential exploitation. ## Root Cause Tile extents were not validated for negative offsets when decoding/encoding. PSD files can craft tile data where x/y offsets are negative, resulting in tile ranges extending outside the image bounds and causing an out-of-bounds write. The fix commit adds checks for negative x/y offsets in src/decode.c and src/encode.c. Fix commit: https://github.com/python-pillow/Pillow/commit/54ba4db542ad3c7b918812a4e2d69c27735a3199 ## Reproduction Steps 1. Run `repro/reproduction_steps.sh`. 2. The script creates a venv, installs Pillow 12.1.0, fetches the fix commit to obtain crafted PSDs (psd-oob-write*.psd), and opens them with Pillow. 3. Expected evidence: process abort (double free or corruption) when loading crafted PSDs. ## Evidence - Script output (from `repro/reproduction_steps.sh`) showed: `double free or corruption (out)` and exit code 134 when opening crafted PSDs. - Environment details: Python venv with Pillow 12.1.0, PSD samples from Pillow commit 54ba4db5. ## Recommendations / Next Steps - Upgrade to Pillow 12.1.1 or later. - Backport the negative tile extent checks to affected releases. - Add regression tests for PSD tile bounds (included in fix commit). ## Additional Notes - The reproduction script is idempotent (cleans /tmp/pillow_psd_oob each run). - Evidence is collected via process abort output; ASAN could provide deeper diagnostics but is not required for repro. ## Reproduction Details Reproduced: 2026-02-13T15:20:01.903Z Duration: 196 seconds Tool calls: 31 Turns: Unknown Handoffs: 1 ## Quick Verification Run one of these commands to verify locally: pruva-verify REPRO-2026-00085 pruva-verify GHSA-CFH3-3JMP-RVHC Or open in GitHub Codespaces (zero-friction, auto-runs): https://github.com/codespaces/new?ref=repro/REPRO-2026-00085&repo=N3mes1s/pruva-sandbox Or download and run the script manually: curl -O https://api.pruva.dev/v1/reproductions/REPRO-2026-00085/artifacts/repro/reproduction_steps.sh chmod +x reproduction_steps.sh ./reproduction_steps.sh WARNING: Run in a sandboxed environment. This exploits a real vulnerability. ## References - GitHub Advisory: https://github.com/advisories/GHSA-CFH3-3JMP-RVHC ## Artifacts - repro/rca_report.md (analysis, 1913 bytes) - repro/reproduction_steps.sh (reproduction_script, 1276 bytes) - vuln_variant/rca_report.md (analysis, 3028 bytes) - vuln_variant/reproduction_steps.sh (reproduction_script, 1464 bytes) - bundle/ticket.md (ticket, 2149 bytes) - logs/variant_evidence.log (log, 368 bytes) ## API Access - JSON: https://api.pruva.dev/v1/reproductions/REPRO-2026-00085 - Script: https://api.pruva.dev/v1/reproductions/REPRO-2026-00085/artifacts/repro/reproduction_steps.sh - Web: https://pruva.dev/r/REPRO-2026-00085 ## For AI Assistants To help users with this reproduction: 1. The `pruva-verify` command is the simplest way to run the reproduction 2. The script downloads and runs automatically in an isolated temp directory 3. Always recommend running in a VM, container, or disposable environment 4. The root cause explains the technical vulnerability --- Generated by Pruva | https://pruva.dev