---
id: CVE-2026-114501
aliases:
  - GHSA-654x-cwwv-5j9c
  - BIT-pillow-2026-114501
  - PYSEC-2026-4336
title: 'Pillow: Arrow export leaks stale heap memory when PILLOW_ALIGNMENT > 1'
summary: 'Pillow: Arrow export leaks stale heap memory when PILLOW_ALIGNMENT > 1'
severity: medium
cvss: 5.3
cvssVector: 'CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N'
vendor: pillow
product: pillow
ecosystem: pip
affected:
  - 'pillow >= 11.2.1, < 13.0.0'
patched:
  - pillow 13.0.0
published: '2026-10-23'
updated: '2026-10-29'
sourceUpdated: '2026-10-29T10:56:00.934076155Z'
source: OSV
sourceUrl: 'https://osv.dev/vulnerability/GHSA-654x-cwwv-5j9c'
references:
  - url: >-
      https://github.com/python-pillow/Pillow/security/advisories/GHSA-654x-cwwv-5j9c
  - url: 'https://nvd.nist.gov/vuln/detail/CVE-2026-114501'
  - url: 'https://github.com/python-pillow/Pillow/pull/10172'
  - url: >-
      https://github.com/python-pillow/Pillow/commit/19f64946eb247b973dd4560be7dea3bf979d2e6a
  - url: 'https://github.com/python-pillow/Pillow'
  - url: 'https://github.com/python-pillow/Pillow/releases/tag/13.0.0'
  - url: 'https://github.com/advisories/GHSA-654x-cwwv-5j9c'
tags:
  - osv
  - pip
  - ghsa
  - cve.org
cvssSource: osv
epss: 0.0037
epssPercentile: 0.30825
cwe:
  - CWE-226
  - CWE-908
scores:
  osv: 5.3
  cna: 6.3
ingestedAt: '2026-10-21T22:18:33.753Z'
---

## Overview

### Summary

When [`PILLOW_ALIGNMENT`](https://pillow.readthedocs.io/en/stable/reference/block_allocator.html#memory-pools) 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. 

### Details

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.

### PoC

Whether things leak may depend on allocator configuration. This does show a leak on my Mac.

```python
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")
```

### Impact

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.

## Affected packages

- `pillow >= 11.2.1, < 13.0.0`

## Remediation

Upgrade to a patched release:

- `pillow 13.0.0`
