GHSA-rw5h-3q4v-c3vc
CVE Information
OpenEXR v3.4.13 PyOpenEXR prefixed literal RGB key collision heap buffer overflow
Summary
A crafted flat scanline EXR can make the PyOpenEXR wrapper reuse a 2D NumPy array allocated for a literal channel such as
leftas the destination buffer for coalesced prefixed RGB channelsleft.R,left.G, andleft.B. The wrapper then installs three RGBSlices withxStride = itemsize * 3into the undersized 2D buffer. Opening the file with the default public API,OpenEXR.File(path), triggers a heap out-of-bounds write during normal pixel decode.This was revalidated on OpenEXR v3.4.13 and the local current
mainbuild. The non-sanitized/original Python extension aborts with heap corruption, and ASAN reportsheap-buffer-overflowwith aWRITE of size 2insrc/lib/OpenEXRCore/unpack.c:924. The control file containing onlyleft.R/G/Bopens cleanly.Affected and reproduced builds
The local validation matrix is:
target build case rc classification v3.4.13 original control 0 clean v3.4.13 original poc 134 original heap corruption abort v3.4.13 asan control 0 clean v3.4.13 asan poc 134 ASAN heap-buffer-overflow WRITE v3.4.13 ubsan control 0 clean v3.4.13 ubsan poc 134 original heap corruption abort v3.4.13 msan control 1 MSAN import failure (__msan_retval_tls) v3.4.13 msan poc 1 MSAN import failure (__msan_retval_tls) main original control 0 clean main original poc 134 original heap corruption abort main asan control 0 clean main asan poc 134 ASAN heap-buffer-overflow WRITE main ubsan control 0 clean main ubsan poc 134 original heap corruption abort
mainis still affected in this workspace:
main originalPoC: rc 134, original heap corruption abort.main ASANPoC: rc 134,AddressSanitizer: heap-buffer-overflow,WRITE of size 2, sinksources/openexr-main/src/lib/OpenEXRCore/unpack.c:924, PyOpenEXR pathsources/openexr-main/src/wrappers/python/PyOpenEXR.cpp:583.The PoC file also passes
exrcheckin this tree:$ builds/original/bin/exrcheck poc_materials/poc/prefixed_literal_half_left_rgb.exr file report/55. OpenEXR v3.4.13 PyOpenEXR prefixed literal RGB key collision heap buffer overflow/poc_materials/poc/prefixed_literal_half_left_rgb.exr OKRoot cause details
The vulnerable invariant is in
src/wrappers/python/PyOpenEXR.cppfor flat channel loading. Withseparate_channels=false, each physical EXR channel name is first mapped throughchannelNameToRGBA().For v3.4.13:
PyOpenEXR.cpp:250-254starts with the physical EXR channel name and may rewriteleft.R,left.G, andleft.Bto the same Python channel keyleft.PyOpenEXR.cpp:258-299allocates a newPyChannelonly when the Python key does not already exist. A literalleftchannel is not in the RGB set, so it creates a 2D array with shape(height, width). For this PoC that buffer is only 32 bytes:2 * 8 * sizeof(half).PyOpenEXR.cpp:316-344later reuses the existingchannels["left"]object forleft.R/G/B, multipliesxStrideby three, offsets the lane pointer for G/B, and callsSlice::Make()using the same undersized 2D buffer.PyOpenEXR.cpp:957-1004maps a prefixed RGB triplet such asleft.R/G/Bto the prefix keyleft.The current local
maintree has the same behavior atPyOpenEXR.cpp:478,PyOpenEXR.cpp:482-523,PyOpenEXR.cpp:542-568, andPyOpenEXR.cpp:1181-1228.The PoC declares these public channel names:
left HALF left.B HALF left.G HALF left.R HALFBecause
ChannelListiteration is sorted, the literalleftchannel is processed beforeleft.B,left.G, andleft.R. The 2Dleftarray already exists when the prefixed RGB channels attempt to coalesce into the same key. There is no validation that the reusedPyChannelwas originally allocated with a 3-lane RGB shape.PoC package contents
The cleaned
poc.zipshould contain only the files needed to reproduce and verify this report:
reproduce.shpoc_materials/poc/prefixed_literal_half_left_rgb.exr— crashing PoC; literalleftplusleft.R/G/B, allHALF.poc_materials/poc/prefixed_rgb_no_literal.exr— clean control with onlyleft.R/G/B.poc_materials/src/repro_prefixed_key_collision.py— default PyOpenEXR reproducer.poc_materials/src/gen_prefixed_key_collision.cpp— generator used to produce the PoC/control from public OpenEXR writer APIs.- selected final reproduction logs under
poc_materials/logs/.Reproduction
From the extracted
poc.zipdirectory, pointOPENEXR_ROOTat the OpenEXR workspace containing the required v3.4.13 and main Python builds:OPENEXR_ROOT=/home/br0nzu/openexr/v3.4.13 ./reproduce.shFrom the original report directory inside this workspace, this also works:
bash reproduce.shExpected final line:
PASS: prefixed literal/RGB key-collision heap OOB reproduced on v3.4.13 and main original+ASAN; controls clean. MSAN Python extension build currently fails at import on this host.Impact
A malformed but public EXR file can corrupt heap memory in processes that use the default PyOpenEXR reader API. The demonstrated primitive is a heap out-of-bounds write into/after a NumPy allocation controlled by the wrapper's decoded pixel destination layout. The demonstrated impact is reliable process crash in original builds and sanitizer-confirmed heap buffer overflow write in ASAN builds.
Any application, pipeline tool, or service that accepts untrusted EXR files and opens them with
OpenEXR.File(path)withoutseparate_channels=Truecan be impacted. This report does not prove arbitrary code execution, but heap out-of-bounds writes in image decode paths are security-relevant because crafted media can be supplied by an untrusted party and decoded by automated asset-processing systems.A robust fix should reject literal channel keys that collide with coalesced RGB/RGBA group keys, or validate that any reused channel entry was allocated with the expected RGB/RGBA shape and matching pixel type before installing additional slices.
Full validation output
reproduce.sh stdout
reproduce_run.outtarget build case rc classification v3.4.13 original control 0 clean v3.4.13 original poc 134 original heap corruption abort v3.4.13 asan control 0 clean v3.4.13 asan poc 134 ASAN heap-buffer-overflow WRITE v3.4.13 ubsan control 0 clean v3.4.13 ubsan poc 134 original heap corruption abort v3.4.13 msan control 1 MSAN import failure (__msan_retval_tls) v3.4.13 msan poc 1 MSAN import failure (__msan_retval_tls) main original control 0 clean main original poc 134 original heap corruption abort main asan control 0 clean main asan poc 134 ASAN heap-buffer-overflow WRITE main ubsan control 0 clean main ubsan poc 134 original heap corruption abort PASS: prefixed literal/RGB key-collision heap OOB reproduced on v3.4.13 and main original+ASAN; controls clean. MSAN Python extension build currently fails at import on this host.reproduce.sh stderr
reproduce_run.errreport/55. OpenEXR v3.4.13 PyOpenEXR prefixed literal RGB key collision heap buffer overflow/reproduce.sh: line 17: 5641 Aborted env "${envargs[@]}" timeout --preserve-status 20s python3 "$PY" "$file" > "$prefix.out" 2> "$prefix.err" report/55. OpenEXR v3.4.13 PyOpenEXR prefixed literal RGB key collision heap buffer overflow/reproduce.sh: line 17: 5654 Aborted env "${envargs[@]}" timeout --preserve-status 20s python3 "$PY" "$file" > "$prefix.out" 2> "$prefix.err" report/55. OpenEXR v3.4.13 PyOpenEXR prefixed literal RGB key collision heap buffer overflow/reproduce.sh: line 17: 5662 Aborted env "${envargs[@]}" timeout --preserve-status 20s python3 "$PY" "$file" > "$prefix.out" 2> "$prefix.err" report/55. OpenEXR v3.4.13 PyOpenEXR prefixed literal RGB key collision heap buffer overflow/reproduce.sh: line 17: 5680 Aborted env "${envargs[@]}" timeout --preserve-status 20s python3 "$PY" "$file" > "$prefix.out" 2> "$prefix.err" report/55. OpenEXR v3.4.13 PyOpenEXR prefixed literal RGB key collision heap buffer overflow/reproduce.sh: line 17: 5691 Aborted env "${envargs[@]}" timeout --preserve-status 20s python3 "$PY" "$file" > "$prefix.out" 2> "$prefix.err" report/55. OpenEXR v3.4.13 PyOpenEXR prefixed literal RGB key collision heap buffer overflow/reproduce.sh: line 17: 5699 Aborted env "${envargs[@]}" timeout --preserve-status 20s python3 "$PY" "$file" > "$prefix.out" 2> "$prefix.err"v3.4.13 original PoC stdout
reproduce_v3.4.13_original_poc.outkeys ['left'] shape (2, 8) dtype float16 nbytes 32 raw_first96 [0, 73, 0, 77, 128, 79, 128, 73, 64, 77, 192, 79, 0, 74, 128, 77, 192, 86, 208, 86, 224, 86, 240, 86, 0, 87, 16, 87, 32, 87, 48, 87] values_first8 [[10.0], [20.0], [30.0], [11.0], [21.0], [31.0], [12.0], [22.0]] sep_keys ['left', 'left.B', 'left.G', 'left.R']v3.4.13 original PoC stderr
reproduce_v3.4.13_original_poc.errdouble free or corruption (out) timeout: the monitored command dumped corev3.4.13 ASAN control stdout
reproduce_v3.4.13_asan_control.outkeys ['left'] shape (2, 8, 3) dtype float16 nbytes 96 raw_first96 [0, 73, 0, 77, 128, 79, 128, 73, 64, 77, 192, 79, 0, 74, 128, 77, 0, 80, 128, 74, 192, 77, 32, 80, 0, 75, 0, 78, 64, 80, 128, 75, 64, 78, 96, 80, 0, 76, 128, 78, 128, 80, 64, 76, 192, 78, 160, 80, 128, 76, 0, 79, 192, 80, 192, 76, 64, 79, 224, 80, 0, 77, 128, 79, 0, 81, 64, 77, 192, 79, 32, 81, 128, 77, 0, 80, 64, 81, 192, 77, 32, 80, 96, 81, 0, 78, 64, 80, 128, 81, 64, 78, 96, 80, 160, 81] values_first8 [[10.0, 20.0, 30.0], [11.0, 21.0, 31.0], [12.0, 22.0, 32.0], [13.0, 23.0, 33.0], [14.0, 24.0, 34.0], [15.0, 25.0, 35.0], [16.0, 26.0, 36.0], [17.0, 27.0, 37.0]] sep_keys ['left.B', 'left.G', 'left.R']v3.4.13 ASAN control stderr
reproduce_v3.4.13_asan_control.err(empty)v3.4.13 ASAN PoC stdout
reproduce_v3.4.13_asan_poc.out(empty)v3.4.13 ASAN PoC stderr
reproduce_v3.4.13_asan_poc.err================================================================= ==5655==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50300004d042 at pc 0x799bf02c3113 bp 0x7ffc00876290 sp 0x7ffc00876280 WRITE of size 2 at 0x50300004d042 thread T0 #0 0x799bf02c3112 in unpack_16bit_4chan /home/br0nzu/openexr/v3.4.13/sources/openexr-3.4.13/src/lib/OpenEXRCore/unpack.c:924 #1 0x799bf02accaf in exr_decoding_run /home/br0nzu/openexr/v3.4.13/sources/openexr-3.4.13/src/lib/OpenEXRCore/decoding.c:664 #2 0x799bf07838d6 in Imf_3_4::(anonymous namespace)::ScanLineProcess::run_decode(_priv_exr_context_t const*, int, Imf_3_4::FrameBuffer const*, int, int, std::vector<Imf_3_4::Slice, std::allocator<Imf_3_4::Slice> > const&) /home/br0nzu/openexr/v3.4.13/sources/openexr-3.4.13/src/lib/OpenEXR/ImfScanLineInputFile.cpp:586 #3 0x799bf078166c in Imf_3_4::ScanLineInputFile::Data::readPixels(Imf_3_4::FrameBuffer const&, int, int) /home/br0nzu/openexr/v3.4.13/sources/openexr-3.4.13/src/lib/OpenEXR/ImfScanLineInputFile.cpp:500 #4 0x799bf07175b9 in Imf_3_4::InputFile::Data::readPixels(int, int) /home/br0nzu/openexr/v3.4.13/sources/openexr-3.4.13/src/lib/OpenEXR/ImfInputFile.cpp:458 #5 0x799bf0a50990 in (anonymous namespace)::PyPart::readPixels(Imf_3_4::MultiPartInputFile&, Imf_3_4::ChannelList const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, Imath_3_1::Box<Imath_3_1::Vec2<int> > const&, bool) /home/br0nzu/openexr/v3.4.13/sources/openexr-3.4.13/src/wrappers/python/PyOpenEXR.cpp:359 #6 0x799bf0a50990 in (anonymous namespace)::PyFile::PyFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, bool) /home/br0nzu/openexr/v3.4.13/sources/openexr-3.4.13/src/wrappers/python/PyOpenEXR.cpp:219 #7 0x799bf0a49450 in _ZN8pybind116detail8initimpl23construct_or_initializeIN12_GLOBAL__N_16PyFileEJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbETnNSt9enable_ifIXsr3std16is_constructibleIT_DpT0_EE5valueEiE4typeELi0EEEPSC_DpOSD_ /usr/include/pybind11/detail/init.h:76 #8 0x799bf0a49450 in _ZZN8pybind116detail8initimpl11constructorIJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbEE7executeINS_6class_IN12_GLOBAL__N_16PyFileEJEEEJNS_3argENS_5arg_vESG_A548_cETnNSt9enable_ifIXntsrT_9has_aliasEiE4typeELi0EEEvRSJ_DpRKT0_ENKUlRNS0_16value_and_holderES8_bbE_clESS_S8_bb /usr/include/pybind11/detail/init.h:206 #9 0x799bf0a49450 in _ZNO8pybind116detail15argument_loaderIJRNS0_16value_and_holderENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbEE9call_implIvRZNS0_8initimpl11constructorIJS9_bbEE7executeINS_6class_IN12_GLOBAL__N_16PyFileEJEEEJNS_3argENS_5arg_vESL_A548_cETnNSt9enable_ifIXntsrT_9has_aliasEiE4typeELi0EEEvRSO_DpRKT0_EUlS3_S9_bbE_JLm0ELm1ELm2ELm3EENS0_9void_typeEEESO_OT0_St16integer_sequenceImJXspT1_EEEOT2_ /usr/include/pybind11/detail/../cast.h:1480 #10 0x799bf0a49450 in _ZNO8pybind116detail15argument_loaderIJRNS0_16value_and_holderENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbEE4callIvNS0_9void_typeERZNS0_8initimpl11constructorIJS9_bbEE7executeINS_6class_IN12_GLOBAL__N_16PyFileEJEEEJNS_3argENS_5arg_vESM_A548_cETnNSt9enable_ifIXntsrT_9has_aliasEiE4typeELi0EEEvRSP_DpRKT0_EUlS3_S9_bbE_EENSO_IXsr3std7is_voidISP_EE5valueESC_E4typeEOT1_ /usr/include/pybind11/detail/../cast.h:1454 #11 0x799bf0a4905d in _ZZN8pybind1112cpp_function10initializeIZNS_6detail8initimpl11constructorIJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbEE7executeINS_6class_IN12_GLOBAL__N_16PyFileEJEEEJNS_3argENS_5arg_vESI_A548_cETnNSt9enable_ifIXntsrT_9has_aliasEiE4typeELi0EEEvRSL_DpRKT0_EUlRNS2_16value_and_holderESA_bbE_vJSU_SA_bbEJNS_4nameENS_9is_methodENS_7siblingENS2_24is_new_style_constructorESH_SI_SI_SJ_EEEvOSL_PFT0_DpT1_EDpRKT2_ENKUlRNS2_13function_callEE_clES1B_ /usr/include/pybind11/pybind11.h:254 #12 0x799bf0a4905d in _ZZN8pybind1112cpp_function10initializeIZNS_6detail8initimpl11constructorIJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbEE7executeINS_6class_IN12_GLOBAL__N_16PyFileEJEEEJNS_3argENS_5arg_vESI_A548_cETnNSt9enable_ifIXntsrT_9has_aliasEiE4typeELi0EEEvRSL_DpRKT0_EUlRNS2_16value_and_holderESA_bbE_vJSU_SA_bbEJNS_4nameENS_9is_methodENS_7siblingENS2_24is_new_style_constructorESH_SI_SI_SJ_EEEvOSL_PFT0_DpT1_EDpRKT2_ENUlRNS2_13function_callEE_8__invokeES1B_ /usr/include/pybind11/pybind11.h:224 #13 0x799bf0a8e99e in pybind11::cpp_function::dispatcher(_object*, _object*, _object*) /usr/include/pybind11/pybind11.h:946 #14 0x5821ee (/usr/bin/python3.12+0x5821ee) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #15 0x5492b4 in _PyObject_MakeTpCall (/usr/bin/python3.12+0x5492b4) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #16 0x54cfc6 (/usr/bin/python3.12+0x54cfc6) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #17 0x59e300 (/usr/bin/python3.12+0x59e300) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #18 0x599c52 (/usr/bin/python3.12+0x599c52) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #19 0x799bf0a81357 in pybind11_meta_call /usr/include/pybind11/detail/class.h:187 #20 0x5492b4 in _PyObject_MakeTpCall (/usr/bin/python3.12+0x5492b4) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #21 0x5d7388 in _PyEval_EvalFrameDefault (/usr/bin/python3.12+0x5d7388) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #22 0x5d58ba in PyEval_EvalCode (/usr/bin/python3.12+0x5d58ba) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #23 0x608b51 (/usr/bin/python3.12+0x608b51) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #24 0x6b5262 (/usr/bin/python3.12+0x6b5262) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #25 0x6b4fc9 in _PyRun_SimpleFileObject (/usr/bin/python3.12+0x6b4fc9) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #26 0x6b4dfe in _PyRun_AnyFileObject (/usr/bin/python3.12+0x6b4dfe) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #27 0x6bce64 in Py_RunMain (/usr/bin/python3.12+0x6bce64) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #28 0x6bc94c in Py_BytesMain (/usr/bin/python3.12+0x6bc94c) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #29 0x799bf542a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 #30 0x799bf542a28a in __libc_start_main_impl ../csu/libc-start.c:360 #31 0x657b04 in _start (/usr/bin/python3.12+0x657b04) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) 0x50300004d042 is located 2 bytes after 32-byte region [0x50300004d020,0x50300004d040) allocated by thread T0 here: #0 0x799bf58fd9c7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 #1 0x799bf26cc65a (/usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-312-x86_64-linux-gnu.so+0xcc65a) (BuildId: 4e90c45f411fba3236c21490996071d3467336f7) #2 0x799bf26e4b02 (/usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-312-x86_64-linux-gnu.so+0xe4b02) (BuildId: 4e90c45f411fba3236c21490996071d3467336f7) #3 0x799bf26e8c55 (/usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-312-x86_64-linux-gnu.so+0xe8c55) (BuildId: 4e90c45f411fba3236c21490996071d3467336f7) #4 0x799bf2731087 (/usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-312-x86_64-linux-gnu.so+0x131087) (BuildId: 4e90c45f411fba3236c21490996071d3467336f7) #5 0x5da85b in _PyEval_EvalFrameDefault (/usr/bin/python3.12+0x5da85b) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #6 0x5d58ba in PyEval_EvalCode (/usr/bin/python3.12+0x5d58ba) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #7 0x608b51 (/usr/bin/python3.12+0x608b51) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #8 0x6b5262 (/usr/bin/python3.12+0x6b5262) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #9 0x6b4fc9 in _PyRun_SimpleFileObject (/usr/bin/python3.12+0x6b4fc9) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #10 0x6b4dfe in _PyRun_AnyFileObject (/usr/bin/python3.12+0x6b4dfe) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #11 0x6bce64 in Py_RunMain (/usr/bin/python3.12+0x6bce64) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #12 0x6bc94c in Py_BytesMain (/usr/bin/python3.12+0x6bc94c) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #13 0x799bf542a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 #14 0x799bf542a28a in __libc_start_main_impl ../csu/libc-start.c:360 #15 0x657b04 in _start (/usr/bin/python3.12+0x657b04) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) SUMMARY: AddressSanitizer: heap-buffer-overflow /home/br0nzu/openexr/v3.4.13/sources/openexr-3.4.13/src/lib/OpenEXRCore/unpack.c:924 in unpack_16bit_4chan Shadow bytes around the buggy address: 0x50300004cd80: 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00 0x50300004ce00: fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 0x50300004ce80: 00 00 fa fa 00 00 00 00 fa fa fd fd fd fd fa fa 0x50300004cf00: 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00 0x50300004cf80: fa fa fd fd fd fd fa fa 00 00 00 00 fa fa 00 00 =>0x50300004d000: 00 00 fa fa 00 00 00 00[fa]fa fd fd fd fd fa fa 0x50300004d080: 00 00 00 00 fa fa 00 00 00 00 fa fa fd fd fd fd 0x50300004d100: fa fa fd fd fd fd fa fa 00 00 00 00 fa fa 00 00 0x50300004d180: 00 00 fa fa fd fd fd fd fa fa fd fd fd fd fa fa 0x50300004d200: 00 00 00 00 fa fa 00 00 00 00 fa fa fd fd fd fd 0x50300004d280: fa fa fd fd fd fd fa fa 00 00 00 00 fa fa 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==5655==ABORTING timeout: the monitored command dumped corev3.4.13 UBSAN PoC stdout
reproduce_v3.4.13_ubsan_poc.outkeys ['left'] shape (2, 8) dtype float16 nbytes 32 raw_first96 [0, 73, 0, 77, 128, 79, 128, 73, 64, 77, 192, 79, 0, 74, 128, 77, 192, 86, 208, 86, 224, 86, 240, 86, 0, 87, 16, 87, 32, 87, 48, 87] values_first8 [[10.0], [20.0], [30.0], [11.0], [21.0], [31.0], [12.0], [22.0]] sep_keys ['left', 'left.B', 'left.G', 'left.R']v3.4.13 UBSAN PoC stderr
reproduce_v3.4.13_ubsan_poc.errdouble free or corruption (out) timeout: the monitored command dumped coremain original PoC stdout
reproduce_main_original_poc.outkeys ['left'] shape (2, 8) dtype float16 nbytes 32 raw_first96 [0, 73, 0, 77, 128, 79, 128, 73, 64, 77, 192, 79, 0, 74, 128, 77, 192, 86, 208, 86, 224, 86, 240, 86, 0, 87, 16, 87, 32, 87, 48, 87] values_first8 [[10.0], [20.0], [30.0], [11.0], [21.0], [31.0], [12.0], [22.0]] sep_keys ['left', 'left.B', 'left.G', 'left.R']main original PoC stderr
reproduce_main_original_poc.errdouble free or corruption (out) timeout: the monitored command dumped coremain ASAN control stdout
reproduce_main_asan_control.outkeys ['left'] shape (2, 8, 3) dtype float16 nbytes 96 raw_first96 [0, 73, 0, 77, 128, 79, 128, 73, 64, 77, 192, 79, 0, 74, 128, 77, 0, 80, 128, 74, 192, 77, 32, 80, 0, 75, 0, 78, 64, 80, 128, 75, 64, 78, 96, 80, 0, 76, 128, 78, 128, 80, 64, 76, 192, 78, 160, 80, 128, 76, 0, 79, 192, 80, 192, 76, 64, 79, 224, 80, 0, 77, 128, 79, 0, 81, 64, 77, 192, 79, 32, 81, 128, 77, 0, 80, 64, 81, 192, 77, 32, 80, 96, 81, 0, 78, 64, 80, 128, 81, 64, 78, 96, 80, 160, 81] values_first8 [[10.0, 20.0, 30.0], [11.0, 21.0, 31.0], [12.0, 22.0, 32.0], [13.0, 23.0, 33.0], [14.0, 24.0, 34.0], [15.0, 25.0, 35.0], [16.0, 26.0, 36.0], [17.0, 27.0, 37.0]] sep_keys ['left.B', 'left.G', 'left.R']main ASAN control stderr
reproduce_main_asan_control.err(empty)main ASAN PoC stdout
reproduce_main_asan_poc.out(empty)main ASAN PoC stderr
reproduce_main_asan_poc.err================================================================= ==5692==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50300004d042 at pc 0x784025ac3113 bp 0x7ffccf7d8790 sp 0x7ffccf7d8780 WRITE of size 2 at 0x50300004d042 thread T0 #0 0x784025ac3112 in unpack_16bit_4chan /home/br0nzu/openexr/v3.4.13/sources/openexr-main/src/lib/OpenEXRCore/unpack.c:924 #1 0x784025aaccaf in exr_decoding_run /home/br0nzu/openexr/v3.4.13/sources/openexr-main/src/lib/OpenEXRCore/decoding.c:664 #2 0x784025f87296 in Imf_4_0::(anonymous namespace)::ScanLineProcess::run_decode(_priv_exr_context_t const*, int, Imf_4_0::FrameBuffer const*, int, int, std::vector<Imf_4_0::Slice, std::allocator<Imf_4_0::Slice> > const&) /home/br0nzu/openexr/v3.4.13/sources/openexr-main/src/lib/OpenEXR/ImfScanLineInputFile.cpp:586 #3 0x784025f8505c in Imf_4_0::ScanLineInputFile::Data::readPixels(Imf_4_0::FrameBuffer const&, int, int) /home/br0nzu/openexr/v3.4.13/sources/openexr-main/src/lib/OpenEXR/ImfScanLineInputFile.cpp:500 #4 0x784025f1b0a9 in Imf_4_0::InputFile::Data::readPixels(int, int) /home/br0nzu/openexr/v3.4.13/sources/openexr-main/src/lib/OpenEXR/ImfInputFile.cpp:458 #5 0x78402629de24 in (anonymous namespace)::PyPart::readPixels(Imf_4_0::MultiPartInputFile&, Imf_4_0::ChannelList const&, std::vector<unsigned long, std::allocator<unsigned long> > const&, std::set<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, Imath_3_1::Box<Imath_3_1::Vec2<int> > const&, bool) /home/br0nzu/openexr/v3.4.13/sources/openexr-main/src/wrappers/python/PyOpenEXR.cpp:583 #6 0x78402629de24 in (anonymous namespace)::PyFile::readPartsFromOpenInput(bool) /home/br0nzu/openexr/v3.4.13/sources/openexr-main/src/wrappers/python/PyOpenEXR.cpp:443 #7 0x784026296916 in (anonymous namespace)::PyFile::PyFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, bool, bool, int) /home/br0nzu/openexr/v3.4.13/sources/openexr-main/src/wrappers/python/PyOpenEXR.cpp:362 #8 0x784026296916 in _ZN8pybind116detail8initimpl23construct_or_initializeIN12_GLOBAL__N_16PyFileEJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbiETnNSt9enable_ifIXsr3std16is_constructibleIT_DpT0_EE5valueEiE4typeELi0EEEPSC_DpOSD_ /usr/include/pybind11/detail/init.h:76 #9 0x784026296916 in _ZZN8pybind116detail8initimpl11constructorIJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbiEE7executeINS_6class_IN12_GLOBAL__N_16PyFileEJEEEJNS_3argENS_5arg_vESG_SG_A641_cETnNSt9enable_ifIXntsrT_9has_aliasEiE4typeELi0EEEvRSJ_DpRKT0_ENKUlRNS0_16value_and_holderES8_bbiE_clESS_S8_bbi /usr/include/pybind11/detail/init.h:206 #10 0x784026296916 in _ZNO8pybind116detail15argument_loaderIJRNS0_16value_and_holderENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbiEE9call_implIvRZNS0_8initimpl11constructorIJS9_bbiEE7executeINS_6class_IN12_GLOBAL__N_16PyFileEJEEEJNS_3argENS_5arg_vESL_SL_A641_cETnNSt9enable_ifIXntsrT_9has_aliasEiE4typeELi0EEEvRSO_DpRKT0_EUlS3_S9_bbiE_JLm0ELm1ELm2ELm3ELm4EENS0_9void_typeEEESO_OT0_St16integer_sequenceImJXspT1_EEEOT2_ /usr/include/pybind11/detail/../cast.h:1480 #11 0x784026296916 in _ZNO8pybind116detail15argument_loaderIJRNS0_16value_and_holderENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbiEE4callIvNS0_9void_typeERZNS0_8initimpl11constructorIJS9_bbiEE7executeINS_6class_IN12_GLOBAL__N_16PyFileEJEEEJNS_3argENS_5arg_vESM_SM_A641_cETnNSt9enable_ifIXntsrT_9has_aliasEiE4typeELi0EEEvRSP_DpRKT0_EUlS3_S9_bbiE_EENSO_IXsr3std7is_voidISP_EE5valueESC_E4typeEOT1_ /usr/include/pybind11/detail/../cast.h:1454 #12 0x784026296296 in _ZZN8pybind1112cpp_function10initializeIZNS_6detail8initimpl11constructorIJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbiEE7executeINS_6class_IN12_GLOBAL__N_16PyFileEJEEEJNS_3argENS_5arg_vESI_SI_A641_cETnNSt9enable_ifIXntsrT_9has_aliasEiE4typeELi0EEEvRSL_DpRKT0_EUlRNS2_16value_and_holderESA_bbiE_vJSU_SA_bbiEJNS_4nameENS_9is_methodENS_7siblingENS2_24is_new_style_constructorESH_SI_SI_SI_SJ_EEEvOSL_PFT0_DpT1_EDpRKT2_ENKUlRNS2_13function_callEE_clES1B_ /usr/include/pybind11/pybind11.h:254 #13 0x784026296296 in _ZZN8pybind1112cpp_function10initializeIZNS_6detail8initimpl11constructorIJNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbiEE7executeINS_6class_IN12_GLOBAL__N_16PyFileEJEEEJNS_3argENS_5arg_vESI_SI_A641_cETnNSt9enable_ifIXntsrT_9has_aliasEiE4typeELi0EEEvRSL_DpRKT0_EUlRNS2_16value_and_holderESA_bbiE_vJSU_SA_bbiEJNS_4nameENS_9is_methodENS_7siblingENS2_24is_new_style_constructorESH_SI_SI_SI_SJ_EEEvOSL_PFT0_DpT1_EDpRKT2_ENUlRNS2_13function_callEE_8__invokeES1B_ /usr/include/pybind11/pybind11.h:224 #14 0x7840262e772e in pybind11::cpp_function::dispatcher(_object*, _object*, _object*) /usr/include/pybind11/pybind11.h:946 #15 0x5821ee (/usr/bin/python3.12+0x5821ee) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #16 0x5492b4 in _PyObject_MakeTpCall (/usr/bin/python3.12+0x5492b4) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #17 0x54cfc6 (/usr/bin/python3.12+0x54cfc6) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #18 0x59e300 (/usr/bin/python3.12+0x59e300) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #19 0x599c52 (/usr/bin/python3.12+0x599c52) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #20 0x7840262da0e7 in pybind11_meta_call /usr/include/pybind11/detail/class.h:187 #21 0x5492b4 in _PyObject_MakeTpCall (/usr/bin/python3.12+0x5492b4) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #22 0x5d7388 in _PyEval_EvalFrameDefault (/usr/bin/python3.12+0x5d7388) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #23 0x5d58ba in PyEval_EvalCode (/usr/bin/python3.12+0x5d58ba) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #24 0x608b51 (/usr/bin/python3.12+0x608b51) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #25 0x6b5262 (/usr/bin/python3.12+0x6b5262) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #26 0x6b4fc9 in _PyRun_SimpleFileObject (/usr/bin/python3.12+0x6b4fc9) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #27 0x6b4dfe in _PyRun_AnyFileObject (/usr/bin/python3.12+0x6b4dfe) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #28 0x6bce64 in Py_RunMain (/usr/bin/python3.12+0x6bce64) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #29 0x6bc94c in Py_BytesMain (/usr/bin/python3.12+0x6bc94c) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #30 0x78402ac2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 #31 0x78402ac2a28a in __libc_start_main_impl ../csu/libc-start.c:360 #32 0x657b04 in _start (/usr/bin/python3.12+0x657b04) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) 0x50300004d042 is located 2 bytes after 32-byte region [0x50300004d020,0x50300004d040) allocated by thread T0 here: #0 0x78402b0fd9c7 in malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:69 #1 0x784027ecc65a (/usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-312-x86_64-linux-gnu.so+0xcc65a) (BuildId: 4e90c45f411fba3236c21490996071d3467336f7) #2 0x784027ee4b02 (/usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-312-x86_64-linux-gnu.so+0xe4b02) (BuildId: 4e90c45f411fba3236c21490996071d3467336f7) #3 0x784027ee8c55 (/usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-312-x86_64-linux-gnu.so+0xe8c55) (BuildId: 4e90c45f411fba3236c21490996071d3467336f7) #4 0x784027f31087 (/usr/lib/python3/dist-packages/numpy/core/_multiarray_umath.cpython-312-x86_64-linux-gnu.so+0x131087) (BuildId: 4e90c45f411fba3236c21490996071d3467336f7) #5 0x5da85b in _PyEval_EvalFrameDefault (/usr/bin/python3.12+0x5da85b) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #6 0x5d58ba in PyEval_EvalCode (/usr/bin/python3.12+0x5d58ba) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #7 0x608b51 (/usr/bin/python3.12+0x608b51) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #8 0x6b5262 (/usr/bin/python3.12+0x6b5262) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #9 0x6b4fc9 in _PyRun_SimpleFileObject (/usr/bin/python3.12+0x6b4fc9) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #10 0x6b4dfe in _PyRun_AnyFileObject (/usr/bin/python3.12+0x6b4dfe) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #11 0x6bce64 in Py_RunMain (/usr/bin/python3.12+0x6bce64) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #12 0x6bc94c in Py_BytesMain (/usr/bin/python3.12+0x6bc94c) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) #13 0x78402ac2a1c9 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 #14 0x78402ac2a28a in __libc_start_main_impl ../csu/libc-start.c:360 #15 0x657b04 in _start (/usr/bin/python3.12+0x657b04) (BuildId: 7aa38bef4bcd63064ecbd05a66f6120026526b74) SUMMARY: AddressSanitizer: heap-buffer-overflow /home/br0nzu/openexr/v3.4.13/sources/openexr-main/src/lib/OpenEXRCore/unpack.c:924 in unpack_16bit_4chan Shadow bytes around the buggy address: 0x50300004cd80: 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00 0x50300004ce00: fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 0x50300004ce80: 00 00 fa fa 00 00 00 00 fa fa fd fd fd fd fa fa 0x50300004cf00: 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00 0x50300004cf80: fa fa fd fd fd fd fa fa 00 00 00 00 fa fa 00 00 =>0x50300004d000: 00 00 fa fa 00 00 00 00[fa]fa fd fd fd fd fa fa 0x50300004d080: 00 00 00 00 fa fa 00 00 00 00 fa fa fd fd fd fd 0x50300004d100: fa fa fd fd fd fd fa fa 00 00 00 00 fa fa 00 00 0x50300004d180: 00 00 fa fa fd fd fd fd fa fa fd fd fd fd fa fa 0x50300004d200: 00 00 00 00 fa fa 00 00 00 00 fa fa fd fd fd fd 0x50300004d280: fa fa fd fd fd fd fa fa 00 00 00 00 fa fa 00 00 Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==5692==ABORTING timeout: the monitored command dumped coremain UBSAN PoC stdout
reproduce_main_ubsan_poc.outkeys ['left'] shape (2, 8) dtype float16 nbytes 32 raw_first96 [0, 73, 0, 77, 128, 79, 128, 73, 64, 77, 192, 79, 0, 74, 128, 77, 192, 86, 208, 86, 224, 86, 240, 86, 0, 87, 16, 87, 32, 87, 48, 87] values_first8 [[10.0], [20.0], [30.0], [11.0], [21.0], [31.0], [12.0], [22.0]] sep_keys ['left', 'left.B', 'left.G', 'left.R']main UBSAN PoC stderr
reproduce_main_ubsan_poc.errfree(): invalid next size (fast) timeout: the monitored command dumped corev3.4.13 MSAN import-failure control stdout
reproduce_v3.4.13_msan_control.out(empty)v3.4.13 MSAN import-failure control stderr
reproduce_v3.4.13_msan_control.errTraceback (most recent call last): File "/home/br0nzu/openexr/v3.4.13/report/55. OpenEXR v3.4.13 PyOpenEXR prefixed literal RGB key collision heap buffer overflow/poc_materials/src/repro_prefixed_key_collision.py", line 9, in <module> import OpenEXR ImportError: /home/br0nzu/openexr/v3.4.13/builds/python_msan/src/lib/OpenEXRCore/libOpenEXRCore-3_4.so.33: undefined symbol: __msan_retval_tlsv3.4.13 MSAN import-failure PoC stdout
reproduce_v3.4.13_msan_poc.out(empty)v3.4.13 MSAN import-failure PoC stderr
reproduce_v3.4.13_msan_poc.errTraceback (most recent call last): File "/home/br0nzu/openexr/v3.4.13/report/55. OpenEXR v3.4.13 PyOpenEXR prefixed literal RGB key collision heap buffer overflow/poc_materials/src/repro_prefixed_key_collision.py", line 9, in <module> import OpenEXR ImportError: /home/br0nzu/openexr/v3.4.13/builds/python_msan/src/lib/OpenEXRCore/libOpenEXRCore-3_4.so.33: undefined symbol: __msan_retval_tls