Bugzilla – Bug 1169575
VUL-1: CVE-2020-11765: OpenEXR,openexr: off-by-one error in use of the ImfXdr.h read function by DwaCompressor:Classifier:Classifier
Last modified: 2020-10-21 09:26:35 UTC
CVE-2020-11765 An issue was discovered in OpenEXR before 2.4.1. There is an off-by-one error in use of the ImfXdr.h read function by DwaCompressor::Classifier::Classifier, leading to an out-of-bounds read. References: https://bugs.chromium.org/p/project-zero/issues/detail?id=1987 http://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2020-11765 https://github.com/AcademySoftwareFoundation/openexr/releases/tag/v2.4.1 https://github.com/AcademySoftwareFoundation/openexr/blob/master/CHANGES.md#version-241-february-11-2020 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-11765
Testcases: https://bugs.chromium.org/p/project-zero/issues/detail?id=1987#c1 See the description of the bug for bugN -> CVE-N mapping. Tested with 2.4.0: $ valgrind -q exrmakepreview crash.exr /tmp/out ==713== Invalid write of size 2 ==713== at 0x48E7EDA: Imf_2_4::copyIntoFrameBuffer(char const*&, char*, char*, unsigned long, bool, double, Imf_2_4::Compressor::Format, Imf_2_4::PixelType, Imf_2_4::PixelType) (ImfMisc.cpp:322) ==713== by 0x48CEA15: Imf_2_4::(anonymous namespace)::TileBufferTask::execute() (ImfTiledInputFile.cpp:609) ==713== by 0x5065E8C: ??? (in /usr/lib64/libIlmThread-2_4.so.24.0.0) ==713== by 0x5065C42: IlmThread_2_4::ThreadPool::addTask(IlmThread_2_4::Task*) (in /usr/lib64/libIlmThread-2_4.so.24.0.0) ==713== by 0x48CFFDD: Imf_2_4::TiledInputFile::readTiles(int, int, int, int, int, int) (ImfTiledInputFile.cpp:1204) ==713== by 0x48D0C2A: Imf_2_4::TiledInputFile::readTiles(int, int, int, int, int) (ImfTiledInputFile.cpp:1260) ==713== by 0x48FFA98: Imf_2_4::InputFile::readPixels(int, int) (ImfInputFile.cpp:278) ==713== by 0x10A55F: UnknownInlinedFun (makePreview.cpp:114) ==713== by 0x10A55F: UnknownInlinedFun (makePreview.cpp:158) ==713== by 0x10A55F: main (main.cpp:185) ==713== Address 0x51200c0 is 0 bytes after a block of size 96 alloc'd ==713== at 0x483950F: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==713== by 0x4903086: Imf_2_4::InputFile::setFrameBuffer(Imf_2_4::FrameBuffer const&) (ImfInputFile.cpp:715) ==713== by 0x48F97A7: Imf_2_4::RgbaInputFile::setFrameBuffer(Imf_2_4::Rgba*, unsigned long, unsigned long) (ImfRgbaFile.cpp:1270) ==713== by 0x10A54F: UnknownInlinedFun (makePreview.cpp:113) ==713== by 0x10A54F: UnknownInlinedFun (makePreview.cpp:158) ==713== by 0x10A54F: main (main.cpp:185) ==713== ==713== Invalid write of size 2 ==713== at 0x48E7ED0: Imf_2_4::copyIntoFrameBuffer(char const*&, char*, char*, unsigned long, bool, double, Imf_2_4::Compressor::Format, Imf_2_4::PixelType, Imf_2_4::PixelType) (ImfMisc.cpp:324) ==713== by 0x48CEA15: Imf_2_4::(anonymous namespace)::TileBufferTask::execute() (ImfTiledInputFile.cpp:609) ==713== by 0x5065E8C: ??? (in /usr/lib64/libIlmThread-2_4.so.24.0.0) ==713== by 0x5065C42: IlmThread_2_4::ThreadPool::addTask(IlmThread_2_4::Task*) (in /usr/lib64/libIlmThread-2_4.so.24.0.0) ==713== by 0x48CFFDD: Imf_2_4::TiledInputFile::readTiles(int, int, int, int, int, int) (ImfTiledInputFile.cpp:1204) ==713== by 0x48D0C2A: Imf_2_4::TiledInputFile::readTiles(int, int, int, int, int) (ImfTiledInputFile.cpp:1260) ==713== by 0x48FFA98: Imf_2_4::InputFile::readPixels(int, int) (ImfInputFile.cpp:278) ==713== by 0x10A55F: UnknownInlinedFun (makePreview.cpp:114) ==713== by 0x10A55F: UnknownInlinedFun (makePreview.cpp:158) ==713== by 0x10A55F: main (main.cpp:185) ==713== Address 0x51200c2 is 2 bytes after a block of size 96 alloc'd ==713== at 0x483950F: operator new[](unsigned long) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==713== by 0x4903086: Imf_2_4::InputFile::setFrameBuffer(Imf_2_4::FrameBuffer const&) (ImfInputFile.cpp:715) ==713== by 0x48F97A7: Imf_2_4::RgbaInputFile::setFrameBuffer(Imf_2_4::Rgba*, unsigned long, unsigned long) (ImfRgbaFile.cpp:1270) ==713== by 0x10A54F: UnknownInlinedFun (makePreview.cpp:113) ==713== by 0x10A54F: UnknownInlinedFun (makePreview.cpp:158) ==713== by 0x10A54F: main (main.cpp:185) ==713== ==713== ==713== Process terminating with default action of signal 11 (SIGSEGV): dumping core [..] Error reading pixel data from image file "crash.exr". Error uncompressing DWA data (corrupt rule). $ Tested with 2.4.1: $ valgrind -q exrmakepreview crash.exr /tmp/out Error reading pixel data from image file "crash.exr". Error uncompressing DWA data (corrupt header file). $
Tested with 15/openexr: BEFORE $ valgrind -q exrmakepreview crash.exr /tmp/out [..] ==30694== ==30694== Use of uninitialised value of size 8 ==30694== at 0x4C34C63: memmove (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==30694== by 0x4EAC956: copy (char_traits.h:350) ==30694== by 0x4EAC956: _S_copy (basic_string.h:340) ==30694== by 0x4EAC956: _S_copy_chars (basic_string.h:387) ==30694== by 0x4EAC956: void std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_construct<char*>(char*, char*, std::forward_iterator_tag) [clone .isra.109] (basic_string.tcc:225) ==30694== by 0x4EB4DFE: _M_construct_aux<char const*> (basic_string.h:236) ==30694== by 0x4EB4DFE: _M_construct<char const*> (basic_string.h:255) ==30694== by 0x4EB4DFE: basic_string (basic_string.h:511) ==30694== by 0x4EB4DFE: Classifier (ImfDwaCompressor.cpp:271) ==30694== by 0x4EB4DFE: Imf_2_2::DwaCompressor::uncompress(char const*, int, Imath_2_2::Box<Imath_2_2::Vec2<int> >, char const*&) (ImfDwaCompressor.cpp:2425) ==30694== by 0x4EB6A76: Imf_2_2::DwaCompressor::uncompress(char const*, int, int, char const*&) (ImfDwaCompressor.cpp:2307) ==30694== by 0x4EC484A: Imf_2_2::(anonymous namespace)::LineBufferTask::execute() (ImfScanLineInputFile.cpp:541) ==30694== by 0x6677A1E: IlmThread_2_2::ThreadPool::addTask(IlmThread_2_2::Task*) (in /usr/lib64/libIlmThread-2_2.so.23.0.0) ==30694== by 0x4EC739E: Imf_2_2::ScanLineInputFile::readPixels(int, int) (ImfScanLineInputFile.cpp:1612) ==30694== by 0x4E96785: Imf_2_2::InputFile::readPixels(int, int) (ImfInputFile.cpp:815) ==30694== by 0x4E9DC2B: Imf_2_2::RgbaInputFile::FromYca::readYCAScanLine(int, Imf_2_2::Rgba*) (ImfRgbaFile.cpp:1126) ==30694== by 0x4E9DD66: Imf_2_2::RgbaInputFile::FromYca::readPixels(int) (ImfRgbaFile.cpp:1050) ==30694== by 0x4E9E084: Imf_2_2::RgbaInputFile::FromYca::readPixels(int, int) (ImfRgbaFile.cpp:959) ==30694== by 0x4E9E0F2: Imf_2_2::RgbaInputFile::readPixels(int, int) (ImfRgbaFile.cpp:1298) [..] Error reading pixel data from image file "crash.exr". Error uncompressing DWA data (corrupt rule). $ AFTER $ valgrind -q exrmakepreview crash.exr /tmp/out Error reading pixel data from image file "crash.exr". Error uncompressing DWA data (corrupt header file). $
Used patch from bug 1169549 comment 2: https://github.com/AcademySoftwareFoundation/openexr/commit/e79d2296496a50826a15c667bf92bdc5a05518b4
Tested with 12/openexr: BEFORE $ valgrind -q exrmakepreview crash.exr /tmp/out Cannot read image file "crash.exr". Unknown compression type in image header. $ AFTER $ valgrind -q exrmakepreview crash.exr /tmp/out Cannot read image file "crash.exr". Unknown compression type in image header. $ Considering not affected.
Tested with 11/OpenEXR: BEFORE $ valgrind -q exrmakepreview crash.exr /tmp/out Cannot read image file "crash.exr". Unknown compression type in image header. $ AFTER $ valgrind -q exrmakepreview crash.exr /tmp/out Cannot read image file "crash.exr". Unknown compression type in image header. $ Considering not affected.
Package submitted for: 15/openexr I believe all fixed.
openSUSE-SU-2020:0682-1: An update that solves 7 vulnerabilities and has one errata is now available. Category: security (moderate) Bug References: 1146648,1169549,1169573,1169574,1169575,1169576,1169578,1169580 CVE References: CVE-2020-11758,CVE-2020-11760,CVE-2020-11761,CVE-2020-11762,CVE-2020-11763,CVE-2020-11764,CVE-2020-11765 Sources used: openSUSE Leap 15.1 (src): openexr-2.2.1-lp151.4.9.1
Done