Description
A heap-based buffer overflow occurs when we test exrmaketiled with the latest code of this repo.
The details of the bug as follows:
$ ./exrmaketiled ./bug-testcase/185-openexr-heapoverflow /tmp/out
==18567==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x63100003c7fe at pc 0x7fc23e95a5ab bp 0x7ffe0428e7e0 sp 0x7ffe0428e7d8
READ of size 2 at 0x63100003c7fe thread T0
#0 0x7fc23e95a5aa in hufDecode ../../openexr/OpenEXR/IlmImf/ImfHuf.cpp:898
#1 0x7fc23e95a5aa in Imf_2_2::hufUncompress(char const*, int, unsigned short*, int) ../../openexr/OpenEXR/IlmImf/ImfHuf.cpp:1101
#2 0x7fc23e971ca7 in Imf_2_2::PizCompressor::uncompress(char const*, int, Imath_2_2::Box<Imath_2_2::Vec2 >, char const*&) ../../openexr/OpenEXR/IlmImf/ImfPizCompressor.cpp:576
#3 0x7fc23e974663 in Imf_2_2::PizCompressor::uncompress(char const*, int, int, char const*&) ../../openexr/OpenEXR/IlmImf/ImfPizCompressor.cpp:288
#4 0x7fc23ea66bb7 in execute ../../openexr/OpenEXR/IlmImf/ImfScanLineInputFile.cpp:544
#5 0x7fc23d4081ea in IlmThread_2_2::ThreadPool::addTask(IlmThread_2_2::Task*) ../../openexr/IlmBase/IlmThread/IlmThreadPool.cpp:433
#6 0x7fc23ea7c136 in Imf_2_2::ScanLineInputFile::readPixels(int, int) ../../openexr/OpenEXR/IlmImf/ImfScanLineInputFile.cpp:1617
#7 0x7fc23e904c7c in Imf_2_2::InputFile::readPixels(int, int) ../../openexr/OpenEXR/IlmImf/ImfInputFile.cpp:815
#8 0x4236ed in makeTiled(char const*, char const*, int, Imf_2_2::LevelMode, Imf_2_2::LevelRoundingMode, Imf_2_2::Compression, int, int, std::set<std::string, std::lessstd::string, std::allocatorstd::string > const&, Extrapolation, Extrapolation, bool) ../../openexr/OpenEXR/exrmaketiled/makeTiled.cpp:572
#9 0x405283 in main ../../openexr/OpenEXR/exrmaketiled/main.cpp:426
#10 0x7fc23dd55f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)
#11 0x40692c (/data/xqx/tests/openexr-test/aflbuild/build-openexr/install/bin/exrmaketiled+0x40692c)
0x63100003c7fe is located 2 bytes to the left of 76800-byte region [0x63100003c800,0x63100004f400)
allocated by thread T0 here:
#0 0x7fc23f54a27f in operator new[](unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.1+0x5527f)
#1 0x7fc23e96adf0 in Imf_2_2::PizCompressor::PizCompressor(Imf_2_2::Header const&, unsigned long, unsigned long) ../../openexr/OpenEXR/IlmImf/ImfPizCompressor.cpp:194
SUMMARY: AddressSanitizer: heap-buffer-overflow ../../openexr/OpenEXR/IlmImf/ImfHuf.cpp:898 hufDecode
Shadow bytes around the buggy address:
0x0c627ffff8a0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff8b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff8c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff8d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c627ffff8e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c627ffff8f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa[fa]
0x0c627ffff900: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c627ffff910: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c627ffff920: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c627ffff930: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c627ffff940: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 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
Heap right redzone: fb
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack partial redzone: f4
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Contiguous container OOB:fc
ASan internal: fe
==18567==ABORTING
And you could get the testcase and more details:
/~https://github.com/xiaoqx/pocs/blob/master/185-openexr-heapoverflow
/~https://github.com/xiaoqx/pocs/blob/master/openexr.md