Skip to content

GHSA-6jj8-cxcr-j8hm on CTRL-OS 26.05

Aliases: GHSA-6jj8-cxcr-j8hm

Packages: openexr

Status: Plausible

Advisory Information

Summary

A crafted deep scanline EXR can trigger a heap out-of-bounds write in OpenEXR v3.4.12's exrmetrics tool when the file is read with pixel type conversion enabled, such as --time read --pixelmode float or --bench. The file stores deep HALF channel samples, but exrmetrics asks the reader to decode those channels as FLOAT while allocating the backing deep sample buffers using the original HALF sample size.

Confirmed locally: ASAN reports heap-buffer-overflow, WRITE of size 4 in generic_unpack_deep_pointers() at src/lib/OpenEXRCore/unpack.c:1374, and UBSAN reports a misaligned float store at the same sink. The original build reaches the same path and exits with rc=0, so this PoC confirms silent memory corruption under sanitizers but does not show an original-build crash.

Details

Root cause:

  • src/bin/exrmetrics/exrmetrics.cpp:1052-1077 rewrites outHeaders[p].channels() when pixelMode != PIXELMODE_ORIGINAL; with --pixelmode float, HALF input channels become FLOAT in the output header.
  • initAndReadDeepScanLine() creates DeepSlice entries from outHeader.channels() at src/bin/exrmetrics/exrmetrics.cpp:342-355, so the deep framebuffer requests 4-byte FLOAT samples.
  • The same function allocates sampleData[channelNumber] from in.header().channels() at src/bin/exrmetrics/exrmetrics.cpp:382-387, so the PoC's HALF channels receive only 2 bytes per sample.
  • in.readPixels() at src/bin/exrmetrics/exrmetrics.cpp:403 reaches generic_unpack_deep_pointers().
  • src/lib/OpenEXRCore/unpack.c:1374 executes the HALF-to-FLOAT deep unpack path and writes 4-byte FLOAT values into buffers sized for 2-byte HALF samples.

PoC header highlights:

file format version: 2, flags 0x800
type: "deepscanline"
dataWindow: (0 0) - (255 255)
compression: zips
channels: A, B, G, R, Z are HALF; materialid, modelid, particleid are UINT

Local verification with the attached file produced:

  • original: rc=0, command completes without a visible crash
  • ASAN: rc=134, heap-buffer-overflow, WRITE of size 4
  • UBSAN: rc=134, misaligned float store at unpack.c:1374
  • MSAN: rc=134, aborts during static initialization before the input is read, so it is not evidence for this PoC

PoC

Reproduction

poc.zip contains:

README.md
poc_exrmetrics_deep_half_to_float_oob.exr
repro/run_repro.sh
logs/full_asan_time_read_float.log
logs/full_ubsan_time_read_float.log
logs/full_msan_time_read_float.log
logs/original_time_read_float.log
logs/exrheader.log
logs/exrcheck.log

Run from the OpenEXR v3.4.12 workspace root:

mkdir -p artifacts/tmp/report29-poc
unzip -o 'report/29. OpenEXR exrmetrics deep pixelmode heap buffer overflow/poc.zip' -d artifacts/tmp/report29-poc

artifacts/tmp/report29-poc/repro/run_repro.sh "$PWD" header
artifacts/tmp/report29-poc/repro/run_repro.sh "$PWD" check
artifacts/tmp/report29-poc/repro/run_repro.sh "$PWD" original
artifacts/tmp/report29-poc/repro/run_repro.sh "$PWD" asan
artifacts/tmp/report29-poc/repro/run_repro.sh "$PWD" ubsan
artifacts/tmp/report29-poc/repro/run_repro.sh "$PWD" msan

Expected results:

header   -> valid deep scanline EXR header
check    -> file OK
original -> rc=0, path completes without a visible crash
ASAN    -> rc=134, heap-buffer-overflow WRITE in OpenEXRCore/unpack.c:1374
UBSAN   -> rc=134, misaligned float store at OpenEXRCore/unpack.c:1374
MSAN    -> rc=134, pre-input static-initialization report in ImfCompression.cpp:195

Full ASAN log

ASAN: exrmetrics --time read --pixelmode float

CMD: ASAN_OPTIONS=abort_on_error=1:symbolize=1:detect_leaks=0:allocator_may_return_null=1 builds/asan/bin/exrmetrics --time read --pixelmode float report/29.\ OpenEXR\ exrmetrics\ deep\ pixelmode\ heap\ buffer\ overflow/poc_exrmetrics_deep_half_to_float_oob.exr
=================================================================
==1192210==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x770807eaa828 at pc 0x5dfa53abaf61 bp 0x7ffec6af7ef0 sp 0x7ffec6af7ee8
WRITE of size 4 at 0x770807eaa828 thread T0
    #0 0x5dfa53abaf60 in generic_unpack_deep_pointers /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXRCore/unpack.c:1374:37
    #1 0x5dfa53ab1a7f in exr_decoding_run /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXRCore/decoding.c:664:18
    #2 0x5dfa539821b2 in Imf_3_4::(anonymous namespace)::ScanLineProcess::run_decode(_priv_exr_context_t const*, int, Imf_3_4::DeepFrameBuffer const*, int, int, std::vector<Imf_3_4::DeepSlice, std::allocator<Imf_3_4::DeepSlice>> const&) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp:831:23
    #3 0x5dfa5397ef39 in Imf_3_4::DeepScanLineInputFile::Data::readData(Imf_3_4::DeepFrameBuffer const&, int, int, bool) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp:568:20
    #4 0x5dfa538d0f11 in initAndReadDeepScanLine(std::vector<int, std::allocator<int>>&, std::vector<std::vector<char, std::allocator<char>>, std::allocator<std::vector<char, std::allocator<char>>>>&, std::vector<std::vector<char*, std::allocator<char*>>, std::allocator<std::vector<char*, std::allocator<char*>>>>&, Imf_3_4::DeepFrameBuffer&, Imf_3_4::DeepScanLineInputPart&, std::vector<int, std::allocator<int>> const*, Imf_3_4::Header const&, std::vector<double, std::allocator<double>>&, std::vector<double, std::allocator<double>>&) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/bin/exrmetrics/exrmetrics.cpp:403:12
    #5 0x5dfa538d47bc in initAndReadFile(Imf_3_4::MultiPartInputFile&, std::vector<Imf_3_4::Header, std::allocator<Imf_3_4::Header>> const&, int, std::vector<partData, std::allocator<partData>>&, fileMetrics&, bool) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/bin/exrmetrics/exrmetrics.cpp:707:41
    #6 0x5dfa538d8386 in exrmetrics(char const*, char const*, int, Imf_3_4::Compression, float, int, bool, bool, PixelMode, bool) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/bin/exrmetrics/exrmetrics.cpp:1090:5
    #7 0x5dfa538c4f29 in main /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/bin/exrmetrics/main.cpp:540:41
    #8 0x77080782a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #9 0x77080782a28a in __libc_start_main csu/../csu/libc-start.c:360:3
    #10 0x5dfa537e5664 in _start (/home/br0nzu/openexr/v3.4.12/builds/asan/bin/exrmetrics+0x7a664) (BuildId: 2e4cf55d080a43edeee57cc3e17364ad7ce2826e)

0x770807eaa82a is located 0 bytes after 135210-byte region [0x770807e89800,0x770807eaa82a)
allocated by thread T0 here:
    #0 0x5dfa538bead1 in operator new(unsigned long) (/home/br0nzu/openexr/v3.4.12/builds/asan/bin/exrmetrics+0x153ad1) (BuildId: 2e4cf55d080a43edeee57cc3e17364ad7ce2826e)
    #1 0x5dfa538dd2fb in std::__new_allocator<char>::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/new_allocator.h:151:27
    #2 0x5dfa538dd2fb in std::allocator_traits<std::allocator<char>>::allocate(std::allocator<char>&, unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/alloc_traits.h:482:20
    #3 0x5dfa538dd2fb in std::_Vector_base<char, std::allocator<char>>::_M_allocate(unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_vector.h:381:20
    #4 0x5dfa538dd2fb in std::vector<char, std::allocator<char>>::_M_default_append(unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/vector.tcc:663:34
    #5 0x5dfa538d0d83 in std::vector<char, std::allocator<char>>::resize(unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_vector.h:1016:4
    #6 0x5dfa538d0d83 in initAndReadDeepScanLine(std::vector<int, std::allocator<int>>&, std::vector<std::vector<char, std::allocator<char>>, std::allocator<std::vector<char, std::allocator<char>>>>&, std::vector<std::vector<char*, std::allocator<char*>>, std::allocator<std::vector<char*, std::allocator<char*>>>>&, Imf_3_4::DeepFrameBuffer&, Imf_3_4::DeepScanLineInputPart&, std::vector<int, std::allocator<int>> const*, Imf_3_4::Header const&, std::vector<double, std::allocator<double>>&, std::vector<double, std::allocator<double>>&) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/bin/exrmetrics/exrmetrics.cpp:387:35
    #7 0x5dfa538d47bc in initAndReadFile(Imf_3_4::MultiPartInputFile&, std::vector<Imf_3_4::Header, std::allocator<Imf_3_4::Header>> const&, int, std::vector<partData, std::allocator<partData>>&, fileMetrics&, bool) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/bin/exrmetrics/exrmetrics.cpp:707:41
    #8 0x5dfa538d8386 in exrmetrics(char const*, char const*, int, Imf_3_4::Compression, float, int, bool, bool, PixelMode, bool) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/bin/exrmetrics/exrmetrics.cpp:1090:5
    #9 0x5dfa538c4f29 in main /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/bin/exrmetrics/main.cpp:540:41
    #10 0x77080782a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #11 0x77080782a28a in __libc_start_main csu/../csu/libc-start.c:360:3
    #12 0x5dfa537e5664 in _start (/home/br0nzu/openexr/v3.4.12/builds/asan/bin/exrmetrics+0x7a664) (BuildId: 2e4cf55d080a43edeee57cc3e17364ad7ce2826e)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXRCore/unpack.c:1374:37 in generic_unpack_deep_pointers
Shadow bytes around the buggy address:
  0x770807eaa580: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x770807eaa600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x770807eaa680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x770807eaa700: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x770807eaa780: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x770807eaa800: 00 00 00 00 00[02]fa fa fa fa fa fa fa fa fa fa
  0x770807eaa880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x770807eaa900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x770807eaa980: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x770807eaaa00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x770807eaaa80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
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
==1192210==ABORTING
RC=134

Full UBSAN log

UBSAN: exrmetrics --time read --pixelmode float

CMD: UBSAN_OPTIONS=abort_on_error=1:print_stacktrace=1:symbolize=1:exitcode=86 builds/ubsan/bin/exrmetrics --time read --pixelmode float report/29.\ OpenEXR\ exrmetrics\ deep\ pixelmode\ heap\ buffer\ overflow/poc_exrmetrics_deep_half_to_float_oob.exr
/home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXRCore/unpack.c:1374:37: runtime error: store to misaligned address 0x7b3445c1a012 for type 'float', which requires 4 byte alignment
0x7b3445c1a012: note: pointer points here
 00 00  00 c0 88 3a 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00
              ^ 
    #0 0x5c51b9f645e0 in generic_unpack_deep_pointers /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXRCore/unpack.c:1374:37
    #1 0x5c51b9f5fcfb in exr_decoding_run /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXRCore/decoding.c:664:18
    #2 0x5c51b9e87f10 in Imf_3_4::(anonymous namespace)::ScanLineProcess::run_decode(_priv_exr_context_t const*, int, Imf_3_4::DeepFrameBuffer const*, int, int, std::vector<Imf_3_4::DeepSlice, std::allocator<Imf_3_4::DeepSlice>> const&) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp:831:23
    #3 0x5c51b9e85eb0 in Imf_3_4::DeepScanLineInputFile::Data::readData(Imf_3_4::DeepFrameBuffer const&, int, int, bool) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXR/ImfDeepScanLineInputFile.cpp:568:20
    #4 0x5c51b9df25bb in initAndReadDeepScanLine(std::vector<int, std::allocator<int>>&, std::vector<std::vector<char, std::allocator<char>>, std::allocator<std::vector<char, std::allocator<char>>>>&, std::vector<std::vector<char*, std::allocator<char*>>, std::allocator<std::vector<char*, std::allocator<char*>>>>&, Imf_3_4::DeepFrameBuffer&, Imf_3_4::DeepScanLineInputPart&, std::vector<int, std::allocator<int>> const*, Imf_3_4::Header const&, std::vector<double, std::allocator<double>>&, std::vector<double, std::allocator<double>>&) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/bin/exrmetrics/exrmetrics.cpp:403:12
    #5 0x5c51b9df42f6 in initAndReadFile(Imf_3_4::MultiPartInputFile&, std::vector<Imf_3_4::Header, std::allocator<Imf_3_4::Header>> const&, int, std::vector<partData, std::allocator<partData>>&, fileMetrics&, bool) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/bin/exrmetrics/exrmetrics.cpp:707:41
    #6 0x5c51b9df6741 in exrmetrics(char const*, char const*, int, Imf_3_4::Compression, float, int, bool, bool, PixelMode, bool) /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/bin/exrmetrics/exrmetrics.cpp:1090:5
    #7 0x5c51b9deaa4f in main /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/bin/exrmetrics/main.cpp:540:41
    #8 0x7b3445a2a1c9 in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #9 0x7b3445a2a28a in __libc_start_main csu/../csu/libc-start.c:360:3
    #10 0x5c51b9dbb894 in _start (/home/br0nzu/openexr/v3.4.12/builds/ubsan/bin/exrmetrics+0x173894) (BuildId: 75197c5e5f986c6c87719bc18894e6f1c526f051)

SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXRCore/unpack.c:1374:37 
RC=134

Full MSAN log

MSAN: pre-input static initialization report

CMD: MSAN_OPTIONS=abort_on_error=1:symbolize=1:exit_code=87 builds/msan/bin/exrmetrics --time read --pixelmode float report/29.\ OpenEXR\ exrmetrics\ deep\ pixelmode\ heap\ buffer\ overflow/poc_exrmetrics_deep_half_to_float_oob.exr
==1192215==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x58ccf6d352f7 in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_M_get_insert_unique_pos(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_tree.h:2115:7
    #1 0x58ccf6d349a3 in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_M_get_insert_hint_unique_pos(std::_Rb_tree_const_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_tree.h:2224:13
    #2 0x58ccf6d349a3 in std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>> std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_M_insert_unique_<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const&, std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_Alloc_node>(std::_Rb_tree_const_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const&, std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_Alloc_node&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_tree.h:2281:4
    #3 0x58ccf6d349a3 in std::enable_if<__same_value_type<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const*>::value, void>::type std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_M_insert_range_unique<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const*>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const*, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const*) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_tree.h:1104:6
    #4 0x58ccf6d349a3 in std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, Imf_3_4::Compression, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::map(std::initializer_list<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>> const&, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>> const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_map.h:244:14
    #5 0x58ccf6c5f968 in __cxx_global_var_init.24 /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXR/ImfCompression.cpp:195:71
    #6 0x58ccf6c5f968 in _GLOBAL__sub_I_ImfCompression.cpp /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXR/ImfCompression.cpp
    #7 0x796d9102a303 in call_init csu/../csu/libc-start.c:145:3
    #8 0x796d9102a303 in __libc_start_main csu/../csu/libc-start.c:347:5
    #9 0x58ccf6c62944 in _start (/home/br0nzu/openexr/v3.4.12/builds/msan/bin/exrmetrics+0x4a944) (BuildId: 90af55bd5f7ca1b8bb1c9b29a18d5f426f2b7daa)

  Uninitialized value was created by a heap allocation
    #0 0x58ccf6cfb8b0 in operator new(unsigned long) (/home/br0nzu/openexr/v3.4.12/builds/msan/bin/exrmetrics+0xe38b0) (BuildId: 90af55bd5f7ca1b8bb1c9b29a18d5f426f2b7daa)
    #1 0x58ccf6d34fc4 in std::__new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/new_allocator.h:151:27
    #2 0x58ccf6d34fc4 in std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>>::allocate(std::allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>&, unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/alloc_traits.h:482:20
    #3 0x58ccf6d34fc4 in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_M_get_node() /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_tree.h:563:16
    #4 0x58ccf6d34fc4 in std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>* std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_M_create_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const&>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_tree.h:613:23
    #5 0x58ccf6d34fc4 in std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>* std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_Alloc_node::operator()<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const&>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const&) const /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_tree.h:531:18
    #6 0x58ccf6d34fc4 in std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>> std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_M_insert_<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const&, std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_Alloc_node>(std::_Rb_tree_node_base*, std::_Rb_tree_node_base*, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const&, std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_Alloc_node&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_tree.h:1831:19
    #7 0x58ccf6d34a0d in std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>> std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_M_insert_unique_<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const&, std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_Alloc_node>(std::_Rb_tree_const_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const&, std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_Alloc_node&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_tree.h:2284:9
    #8 0x58ccf6d34a0d in std::enable_if<__same_value_type<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const*>::value, void>::type std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::_M_insert_range_unique<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const*>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const*, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression> const*) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_tree.h:1104:6
    #9 0x58ccf6d34a0d in std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>, Imf_3_4::Compression, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>>, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>>::map(std::initializer_list<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>>, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>> const&, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const, Imf_3_4::Compression>> const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/stl_map.h:244:14
    #10 0x58ccf6c5f968 in __cxx_global_var_init.24 /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXR/ImfCompression.cpp:195:71
    #11 0x58ccf6c5f968 in _GLOBAL__sub_I_ImfCompression.cpp /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXR/ImfCompression.cpp
    #12 0x796d9102a303 in call_init csu/../csu/libc-start.c:145:3
    #13 0x796d9102a303 in __libc_start_main csu/../csu/libc-start.c:347:5
    #14 0x58ccf6c62944 in _start (/home/br0nzu/openexr/v3.4.12/builds/msan/bin/exrmetrics+0x4a944) (BuildId: 90af55bd5f7ca1b8bb1c9b29a18d5f426f2b7daa)

SUMMARY: MemorySanitizer: use-of-uninitialized-value /home/br0nzu/openexr/v3.4.12/sources/openexr-3.4.12/src/lib/OpenEXR/ImfCompression.cpp:195:71 in __cxx_global_var_init.24
Exiting
RC=134

Impact

An attacker who can supply a crafted deep scanline EXR to a workflow that runs exrmetrics with pixel conversion options such as --pixelmode float or --bench can trigger heap memory corruption in OpenEXR v3.4.12. The confirmed primitive is a sanitizer-detected heap out-of-bounds write of decoded sample data immediately past buffers allocated too small for the requested converted type.

Updates

2026-08-11 03:50 CEST

Metadata changes:

  • Status for package openexr: “Plausible

2026-08-11 03:30 CEST

Metadata changes:

  • Status for package openexr: “New