GHSA-pqp9-558c-453q
CVE Information
Summary
A crafted EXR with a non-zero
dataWindow.mincan make OpenEXRUtil's documentedTypedFlatImageChannel<T>::row()API return an invalid heap pointer. When an application loads the file and writes rows throughFlatHalfChannel::row(), the original v3.4.12 build crashes with SIGSEGV, and the ASAN build reports a write to invalid/freed heap memory.Details
Root cause:
src/lib/OpenEXRUtil/ImfFlatImageChannel.hdocumentsrow(int r)as 0-based row access.src/lib/OpenEXRUtil/ImfFlatImageChannel.h:200-203returns_base + r * pixelsPerRow().src/lib/OpenEXRUtil/ImfFlatImageChannel.cpp:131-135adjusts_basebydataWindow.minfor absolute-coordinate pixel access.These models conflict.
operator()(x,y)/at(x,y)use EXR pixel coordinates, butrow(r)is documented as 0-based. For a non-zerodataWindow.min,row(0)points outside the allocated_pixelsstorage.PoC input:
- file:
poc_zip_nonzero_dw.exrdataWindow:(20, 20) - (197, 174)- channels:
B,G,R, all HALFThe attached
poc.zipincludes the EXR input, a minimal row-write reproducer, and build/run scripts. Local verification with those files produced:
- original/plain: SIGSEGV,
rc=139- original/resize: SIGSEGV,
rc=139- ASAN/plain: SEGV caused by WRITE in the
row()write- ASAN/resize:
heap-use-after-free,WRITE of size 2PoC
Reproduction
poc.zipcontains:README.md poc_zip_nonzero_dw.exr repro/repro_row_spray.cpp repro/build_repro.sh repro/run_repro.shRun from the OpenEXR v3.4.12 repository root:
mkdir -p artifacts/tmp/report17-poc unzip -o 'report/17. OpenEXRUtil FlatImageChannel row nonzero dataWindow heap OOB write/poc.zip' -d artifacts/tmp/report17-poc artifacts/tmp/report17-poc/repro/build_repro.sh original artifacts/tmp/report17-poc/repro/build_repro.sh asan artifacts/tmp/report17-poc/repro/run_repro.sh original both artifacts/tmp/report17-poc/repro/run_repro.sh asan bothExpected results:
original/plain -> SIGSEGV, rc=139 original/resize -> SIGSEGV, rc=139 ASAN/plain -> SEGV caused by WRITE in row() write ASAN/resize -> heap-use-after-free, WRITE of size 2ASAN log excerpt
Representative ASAN output from the included reproducer with
resize:ERROR: AddressSanitizer: heap-use-after-free on address 0x52f000028808 WRITE of size 2 at 0x52f000028808 thread T0 #0 ... main ... repro_row_spray.cpp:30:34 freed by thread T0 here: #0 ... operator delete[](void*) #1 ... TypedFlatImageChannel<half>::~TypedFlatImageChannel() ... ImfFlatImageChannel.cpp:75:5 #2 ... FlatImageLevel::clearChannels() ... ImfFlatImageLevel.cpp:125:9 #3 ... Image::resize(...) ... ImfImage.cpp:298:9 previously allocated by thread T0 here: #0 ... operator new[](unsigned long) #1 ... TypedFlatImageChannel<half>::resize() ... ImfFlatImageChannel.cpp:121:15 #2 ... loadImage(...) ... ImfImageIO.cpp:117:17 SUMMARY: AddressSanitizer: heap-use-after-free ... repro_row_spray.cpp:30:34 in mainImpact
This is heap memory corruption reachable from an untrusted EXR file when downstream code uses OpenEXRUtil's documented row API for fast pixel writes. The confirmed effects for the attached PoC are original-binary SIGSEGV and ASAN-confirmed invalid/freed-heap writes. Affected consumers are tools, converters, render pipeline components, or image-processing services that accept untrusted EXR files and use
FlatHalfChannel::row()on loaded images.