GHSA-f667-c4wm-c8gq
CVE Information
Summary
A crafted tiled EXR can trigger a heap out-of-bounds write in OpenEXR v3.4.12 on 32-bit/ILP32 builds when read through the public
TiledRgbaInputFileRGBA API. The file uses a small 40x40dataWindowbut a 65537x65537 tile size. On ILP32, theArray2D<Rgba>tile-conversion buffer size calculation overflows, allocates a much smaller heap buffer, and tile decode writes past that allocation.Confirmed locally: the 32-bit original build crashes with SIGSEGV, ASAN reports a heap-buffer-overflow write, and UBSAN reports the signed integer overflow that causes the under-allocation.
Details
Root cause:
src/lib/OpenEXR/ImfTiledRgbaFile.cpp:599-604copiesTileDescription::xSize/ySizeinto_tileXSize/_tileYSizeand calls_buf.resizeErase(_tileYSize, _tileXSize)for theFromYaconversion path.src/lib/OpenEXR/ImfArray.h:212-218allocatesnew T[sizeX * sizeY]without checked multiplication.- On ILP32,
longis 32-bit, so65537 * 65537overflows to a small positive value before allocation.src/lib/OpenEXRCore/unpack.c:1285, reached throughTiledRgbaInputFile::readTile(), then writes decoded samples using tile-derived layout assumptions and overruns the under-sized heap buffer.PoC header highlights:
dataWindow: (0, 0) - (39, 39) channels: A, B, G, Y, all HALF tile size: 65537 x 65537Local verification with the attached file produced:
- 32-bit original: SIGSEGV,
rc=139- 32-bit ASAN:
heap-buffer-overflow,WRITE of size 2- 32-bit UBSAN: signed integer overflow at
ImfArray.h:214PoC
Reproduction
poc.zipcontains:README.md poc_ilp32_tiledrgba_xy_65537_abgy.exr repro/repro_tiledrgba_readtile_ilp32.cpp repro/build_repro.sh repro/run_repro.shRun from the OpenEXR v3.4.12 workspace root after building the existing 32-bit OpenEXR variants under
builds/ilp32_original,builds/ilp32_asan, andbuilds/ilp32_ubsan:mkdir -p artifacts/tmp/report25-poc unzip -o 'report/25. OpenEXR ILP32 TiledRgbaInputFile large tile Array2D heap OOB write/poc.zip' -d artifacts/tmp/report25-poc artifacts/tmp/report25-poc/repro/build_repro.sh original artifacts/tmp/report25-poc/repro/build_repro.sh asan artifacts/tmp/report25-poc/repro/build_repro.sh ubsan artifacts/tmp/report25-poc/repro/run_repro.sh original artifacts/tmp/report25-poc/repro/run_repro.sh asan artifacts/tmp/report25-poc/repro/run_repro.sh ubsanExpected results:
original -> SIGSEGV, rc=139 ASAN -> heap-buffer-overflow, WRITE of size 2 UBSAN -> signed integer overflow: 65537 * 65537 cannot be represented in type 'long'ASAN / UBSAN log excerpt
Representative ASAN output:
ERROR: AddressSanitizer: heap-buffer-overflow WRITE of size 2 #0 generic_unpack src/lib/OpenEXRCore/unpack.c:1285 #6 TiledRgbaInputFile::FromYa::readTile src/lib/OpenEXR/ImfTiledRgbaFile.cpp:669 allocated by: #1 Array2D<Rgba>::resizeErase(long,long) src/lib/OpenEXR/ImfArray.h:214 #2 TiledRgbaInputFile::FromYa::FromYa src/lib/OpenEXR/ImfTiledRgbaFile.cpp:604Representative UBSAN output:
src/lib/OpenEXR/ImfArray.h:214:26: runtime error: signed integer overflow: 65537 * 65537 cannot be represented in type 'long'Impact
An attacker who can supply a crafted tiled EXR to an application using a 32-bit/ILP32 OpenEXR build and the public
TiledRgbaInputFiletile-read API can trigger heap memory corruption during tile decoding. The confirmed impact is original-binary crash plus ASAN-confirmed heap out-of-bounds write on affected 32-bit builds.