{"repro_id":"REPRO-2026-00085","version":2,"title":"Pillow 10.3.0–12.1.0 allows an out-of-bounds write when loading specially crafted PSD images, potentially leading to memory corruption.","repro_type":"security","status":"published","description":"Pillow 10.3.0–12.1.0 allows an out-of-bounds write when loading specially crafted PSD images, potentially leading to memory corruption.","root_cause":"## Summary\nPillow 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.\n\n## Impact\n- Package/component affected: python-pillow/Pillow PSD decoder (tile handling in core decoder)\n- Affected versions: >=10.3.0 and <12.1.1\n- Risk level and consequences: High; memory corruption leading to crashes and potential exploitation.\n\n## Root Cause\nTile 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\n\n## Reproduction Steps\n1. Run `repro/reproduction_steps.sh`.\n2. 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.\n3. Expected evidence: process abort (double free or corruption) when loading crafted PSDs.\n\n## Evidence\n- Script output (from `repro/reproduction_steps.sh`) showed: `double free or corruption (out)` and exit code 134 when opening crafted PSDs.\n- Environment details: Python venv with Pillow 12.1.0, PSD samples from Pillow commit 54ba4db5.\n\n## Recommendations / Next Steps\n- Upgrade to Pillow 12.1.1 or later.\n- Backport the negative tile extent checks to affected releases.\n- Add regression tests for PSD tile bounds (included in fix commit).\n\n## Additional Notes\n- The reproduction script is idempotent (cleans /tmp/pillow_psd_oob each run).\n- Evidence is collected via process abort output; ASAN could provide deeper diagnostics but is not required for repro.\n","ghsa_id":"GHSA-CFH3-3JMP-RVHC","reproduced_at":"2026-02-13T15:20:01.903882+00:00","duration_secs":196.0,"tool_calls":31,"handoffs":1,"quality":{"idempotent_verified":false,"community_verifications":0},"published_at":"2026-02-13T15:20:02.299529+00:00","retracted":false,"artifacts":[{"path":"repro/rca_report.md","filename":"rca_report.md","size":1913,"category":"analysis"},{"path":"repro/reproduction_steps.sh","filename":"reproduction_steps.sh","size":1276,"category":"reproduction_script"},{"path":"vuln_variant/rca_report.md","filename":"rca_report.md","size":3028,"category":"analysis"},{"path":"vuln_variant/reproduction_steps.sh","filename":"reproduction_steps.sh","size":1464,"category":"reproduction_script"},{"path":"bundle/ticket.md","filename":"ticket.md","size":2149,"category":"ticket"},{"path":"logs/variant_evidence.log","filename":"variant_evidence.log","size":368,"category":"log"}]}