PyPI · pillow
Pillow JPEG2000 tiled decode retains a growing scratch buffer and can be used for denial of service
src/libImaging/Jpeg2KDecode.c:853 accumulates total_component_width across every tile in a JPEG2000 image instead of recomputing it per tile. That accumulated value is then used in the tile_bytes calculation at src/libImaging/Jpeg2KDecode.c:868, which can make the decoder grow state->buffer via realloc at src/libImaging/Jpeg2KDecode.c:876 up to roughly one full image's decompressed size even when each tile is small. A crafted tiled JPEG2000 file can therefore force substantially higher transient memory usage and trigger out-of-memory failures during decoding. Based on current evidence, the supported impact is denial of service, not memory corruption.
src/libImaging/Jpeg2KDecode.c:853total_component_width is initialized only once before the tile loop and keeps growing across tiles. It is then used to derive tile_bytes, so later tiles are treated as if they had the combined component width of all earlier tiles.tile_bytes is promoted into tile_info.data_size, then state->buffer is grown with realloc at src/libImaging/Jpeg2KDecode.c:876.Image.open(...).load() decoding.The attached helper script and testcase were used: exercise_j2k_tile_realloc.zip
Generate the testcase:
pythonexercise_j2k_tile_realloc.py make poc_3664_rgba_tile1832.jp2 \
--size 3664 --tile 1832
Expected geometry from the helper:
3664 x 3664RGBA1832 x 1832 (2x2 tiles)image_bytes=53699584maxrss_kb=180264maxrss_kb=138404Load it with the current vulnerable build:
python exercise_j2k_tile_realloc.py load poc_3664_rgba_tile1832.jp2
Load it again under a 160 MB address-space cap:
python exercise_j2k_tile_realloc.py load poc_3664_rgba_tile1832.jp2 --limit-mb 160
Conservative impact: denial of service through memory exhaustion during JPEG2000 decoding.
Is your project exposed to this? Stateward checks every dependency on every pull request and flags it only if your code actually reaches it.
Check my repoSources: CISA KEV (public domain), OSV.dev & GitHub Advisory Database (CC-BY-4.0), FIRST EPSS, NVD/CWE (public domain). Served live from the Stateward advisory database.