CVE-2026-112395
### Summary Pillow's libImaging `_decodeTile` decoder, used to decode tiled TIFF images, allocates a per-tile buffer using `realloc(state->buffer, TIFFTileSize(tiff))`. After each `TIFFReadTile` it then iterates `tile_y` from 0 up to `current_tile_length` and calls the configured row unpacker (here `copy4`) with the source pointer `state->buffer + tile_y * row_byte_size`. When libtiff returns a `tile_bytes_size` smaller than the worst-case `row_byte_size * tile_length`, the inner stride-and-copy loop walks past the realloc'd region and `copy4` performs a 1024-byte `memcpy` that reads up to `(tile_length-1) * row_byte_size + row_byte_size` bytes from a buffer sized only to `tile_bytes_size`. The supplied PoC TIFF triggers a 1024-byte over-read exactly 0 bytes past a 196608-byte allocation. An attacker who can convince a Pillow-using application to decode a crafted TIFF can trigger a process crash (DoS) and may cause adjacent heap memory to be copied into the decoded pixel buffer. ### Details Pillow's TIFF decoder, when libtiff reports the file is tiled, takes the `_decodeTile` path. The function: 1. Asks libtiff for `TIFFTileSize(tiff)` (the bytes-per-tile) and `TIFFTileRowSize(tiff)` (the bytes per row *as stored by libtiff*). 2. Reallocates `state->buffer` to exactly `tile_bytes_size`. 3. For each tile origin `(x, y)` and each plane, calls `TIFFReadTile` into `state->buffer`, then walks the tile row by row, calling the configured `ImagingShuffler` (here `copy4`) on each row's worth of source bytes. The validation done before the loop is: ```c if (tile_bytes_size > ((tile_length * state->bits / planes + 7) / 8) * tile_width) { state->errcode = IMAGING_CODEC_BROKEN; return -1; } ``` This rejects oversized libtiff tiles, but it does **not** reject *undersized* ones — i.e. the case where libtiff returns a `tile_bytes_size` strictly **less** than `row_byte_size * tile_length`. The loop body, however, indexes into the buffer assuming the buffer is at least
Properties
- Summary
- Pillow tiled-TIFF decoder reads past tile buffer in copy4 (Unpack.c:1290)
- Severity
- medium
- Nvd fetched at
- 2026-10-20T21:14:08.448323+00:00
- Epss score
- 0.00264
- Cvss score
- 6.5
- Cvss severity
- MEDIUM
- Retrieved at
- 2026-10-21T01:24:48+00:00
- Ghsa published
- 2026-10-20T20:49:26Z
- Source url
- https://github.com/advisories/GHSA-462x-pgg6-55fp
- Ghsa updated
- 2026-10-20T20:49:27Z
- Ghsa id
- GHSA-462x-pgg6-55fp
- Last source
- FIRST EPSS
- Score
- 6.5
- Cvss version
- 3.1
- Cve id
- CVE-2026-112395
- Cvss vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L
- First seen by Signal
- 2026-10-20T00:27:55+00:00
- Is ghsa only
- false
- Vector
- CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:L
- Published at
- 2026-10-19T21:17:07.880
Related Entities (3)
AFFECTS (1)
HAS_WEAKNESS (1)
VULNERABLE_TO (1)
Explore deeper with Ninja Signal's threat intelligence graph