OpenEXR fixes 15 vulnerabilities in EXR file reading
The developers of the OpenEXR library released patch release 3.5.3 on October 31. It fixes 15 vulnerabilities, 10 of which are awaiting CVE numbers. Almost all of them trigger when reading a corrupted or specially prepared EXR file: these are buffer overflows and writes beyond allocated memory. According to the release authors, several of these bugs allowed remote code execution.
For studios this is a concrete risk. EXR sequences arrive from outsourcers, clients, third-party archives and file-sharing services, and they are usually opened without any separate check. For an attack to work, the file does not need to be launched: it is enough for a program built on a vulnerable version of OpenEXR to try to read it. The same day, shortly before 3.5.3, version 3.4.17 was released for the previous branch. It fixes nine of these vulnerabilities, those that apply to the 3.4 branch, so 3.4 users can update without moving to 3.5.
Where the bugs were
The list of fixes covers nearly every path through which an EXR file gets into memory:
- DWAA/DWAB compression: five items, including an out-of-bounds write in the decoder, a leak of uninitialized data on a short compressed stream, and a null pointer dereference with subsampled channels;
- B44 compression: an overflow when computing the size of the uncompressed block, which the authors explicitly mark as a remote code execution opportunity, and a bug in the encoder with subsampling;
- deep images: two bugs when decompressing deep data compressed with ZSTD, and an overflow when re-saving tiled deep files. The latter, in the developers' assessment, may be a consequence of an incomplete fix to an old bug;
- HTJ2K: an incorrect memory access during decoding;
- multipart files: a header with no size limits could make a program parse it with quadratic time and resource cost;
- OpenEXR Python module: a buffer overflow when the names of two RGB channel groups match, and a write at an attacker-chosen offset in the deprecated channel reading interface;
- header attributes: a use of already freed memory if a channel name is longer than 31 bytes, and an overflow due to an unchecked additional channel list.
The bug that the developers explicitly tie to remote code execution is described in the release notes like this:
"Heap out-of-bounds write due to an integer overflow when computing the uncompressed size of a B44 block — remote code execution in OpenEXRCore".
There are no new features or other behavior changes in 3.5.3, apart from a fix for a regression with deep images (see below). Users may notice one more thing: the library now validates input data more strictly and rejects malformed files. The entire test suite now passes without errors under debug checks that catch memory errors, undefined behavior and thread races. The full list of changes is in the CHANGES.md file.
What else is in the release
- Reading deep images on big-endian systems. Since version 3.4.14, on such machines the library received an incorrect sample count table because of a byte order bug. Little-endian systems were not affected. This fix is also in 3.4.17.
- Python 3.15 support for those who write pipeline scripts on a recent interpreter.
- The exrmetrics, exrmultipart and exrcheck utilities received diagnostic and correctness fixes, as did the main decompression paths. The author of these fixes is Alex Khal.
- Platforms. Long-standing build and test bugs on 32-bit Linux (i686) and s390x were fixed, along with build problems on macOS below 10.15 and powerpc, and startup on Windows 7.
Who should update, and how urgently
Judging by the makeup of the vulnerabilities, most of the problems are in long-standing code. Of the 15 items, only two are related to ZSTD compression, which appeared in the 3.5 line with the release of 3.5.0 in September; at the time its biggest gain was on deep data, where files came out 20–30% smaller than with ZIPS. The remaining bugs concern DWA, B44, tiled deep files, header parsing and the Python module. So avoiding the new compression formats probably does little: the part of the library through which renders and comps have long been passing was vulnerable too.
The regression with deep images affects a narrow range of machines. Typical x86 and ARM workstations run little-endian and never noticed it. This fix matters more for those who build OpenEXR for server and more unusual hardware.
Most artists do not install OpenEXR directly: the library is embedded into their own builds by the developers of DCC packages, compositing programs, renderers and viewers. The fix will reach workstations when those vendors release updates; no timelines are given in the release materials. Those who can act on their own are pipeline TDs and studios with their own tools based on the OpenEXR Python module or their own builds of the library. It makes sense for them to move to 3.5.3 or 3.4.17 first, especially if the tools process files from external sources.
Where do third-party EXR files most often come to you from?
- From outsourcers
- From clients