Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-65979

CVE-2026-65979: OpenEXR HTJ2K Decoder Buffer Overflow

CVE-2026-65979 is a buffer overflow in OpenEXR HTJ2K decoder affecting versions 3.4.0 through 3.4.12. Attackers can trigger out-of-bounds reads via crafted EXR files. This article covers technical details, impact, and mitigation.

Published:

CVE-2026-65979 Overview

CVE-2026-65979 is an out-of-bounds read vulnerability in OpenEXR, the reference implementation for the EXR image format used across the motion picture industry. The flaw affects versions 3.4.0 through 3.4.12 and resides in the High-Throughput JPEG 2000 (HTJ2K) decoder. The decoder parses a header-length field (PLEN) from a chunk's compressed data but never verifies that this value fits within the available buffer. A crafted EXR file causes the codestream pointer to advance past the end of the buffer, triggering an out-of-bounds read during normal decoding. The Academy Software Foundation resolved the issue in version 3.4.13.

Critical Impact

Processing an untrusted EXR file with a vulnerable OpenEXR build can cause the HTJ2K decoder to read memory beyond the compressed buffer, resulting in denial of service or potential information exposure.

Affected Products

  • OpenEXR 3.4.0 through 3.4.12
  • Applications embedding the OpenEXR HTJ2K decoder (OpenEXRCore)
  • Media pipelines using OpenJPH through OpenEXR's memory-input path

Discovery Timeline

  • 2026-08-25 - CVE-2026-65979 published to the National Vulnerability Database
  • 2026-08-25 - Last updated in NVD database

Technical Details for CVE-2026-65979

Vulnerability Analysis

The vulnerability lives in the HTJ2K decoding path within src/lib/OpenEXRCore/internal_ht.cpp. The decoder calls read_header() on attacker-controlled chunk bytes to determine the size of the JPEG 2000 header. The returned header_sz value is then used to advance the codestream pointer and compute the remaining buffer length passed into the OpenJPH memory-input path. Because the original code does not validate that header_sz is less than or equal to comp_buf_size, a malicious PLEN field pushes the pointer past the end of the compressed buffer. Subsequent reads by OpenJPH occur on memory outside the intended allocation. This behavior maps to [CWE-20] Improper Input Validation and manifests as an out-of-bounds read.

Root Cause

The root cause is missing bounds validation of a length field extracted from untrusted input. The read_header() helper could throw when the header exceeded the buffer, but the caller did not catch the exception, nor did it independently confirm that header_sz <= comp_buf_size before performing pointer arithmetic. The fix wraps read_header() in a try/catch, treats any failure as EXR_ERR_CORRUPT_CHUNK, and adds an explicit size comparison plus a zero-length check on the resulting codestream_sz.

Attack Vector

Exploitation requires an application built against a vulnerable OpenEXR version to decode an EXR file supplied by the attacker. The trigger is local file processing with user interaction, such as opening a rendered frame in a compositing tool or a media conversion utility. No elevated privileges are required, and the malformed chunk is reachable through the normal decoding flow.

cpp
     /* read the channel map */

    size_t header_sz;
-    header_sz = read_header (
-        (uint8_t*) compressed_data, comp_buf_size, cs_to_file_ch);
+    try
+    {
+        header_sz = read_header (
+            (uint8_t*) compressed_data, comp_buf_size, cs_to_file_ch);
+    }
+    catch (...)
+    {
+        return EXR_ERR_CORRUPT_CHUNK;
+    }
+
+    /* this should never be true since read_header() throws an exception if the
+    header is larger than comp_buf_size */
+    if (header_sz > comp_buf_size)
+        return EXR_ERR_CORRUPT_CHUNK;
+
+    const uint64_t codestream_sz = comp_buf_size - header_sz;
+    if (codestream_sz == 0)
+        return EXR_ERR_CORRUPT_CHUNK;
+
    if (static_cast<std::size_t>(decode->channel_count) != cs_to_file_ch.size ())
        return EXR_ERR_CORRUPT_CHUNK;

Source: GitHub Commit c7af2d2 — the patch adds exception handling, an explicit header_sz bounds check, and a zero-length codestream guard before OpenJPH is invoked.

Detection Methods for CVE-2026-65979

Indicators of Compromise

  • Crashes or segmentation faults in processes linked against libOpenEXR or libOpenEXRCore when opening EXR assets
  • EXR files with HTJ2K compression whose PLEN header field is larger than the chunk's compressed data
  • Unexpected EXR_ERR_CORRUPT_CHUNK return codes logged by media processing services

Detection Strategies

  • Inventory build dependencies to identify software linking OpenEXR versions 3.4.0 through 3.4.12
  • Run fuzzing harnesses such as exrcheck against untrusted EXR inputs before publishing them into production pipelines
  • Enable AddressSanitizer in test builds of media tools to surface out-of-bounds reads on sample EXR corpora

Monitoring Recommendations

  • Alert on repeated crashes of render, ingest, or transcode workers that consume user-submitted EXR files
  • Log EXR processing errors from batch pipelines and correlate them with the originating file source
  • Monitor for anomalous file uploads containing HTJ2K-compressed EXR chunks from untrusted users

How to Mitigate CVE-2026-65979

Immediate Actions Required

  • Upgrade OpenEXR to version 3.4.13 or later across all systems that decode EXR content
  • Rebuild and redeploy downstream applications that statically link OpenEXR
  • Restrict ingestion of EXR files to trusted sources until patched builds are rolled out

Patch Information

The fix is included in OpenEXR v3.4.13. Details are documented in GHSA-3j9c-j7c9-x293, and the code change is available in commit c7af2d2. The patch validates header_sz against comp_buf_size and rejects malformed HTJ2K chunks with EXR_ERR_CORRUPT_CHUNK.

Workarounds

  • Disable HTJ2K decoding in workflows that do not require it until the patched release is deployed
  • Sandbox EXR processing in isolated containers with restricted memory and filesystem access
  • Pre-validate EXR files with a hardened parser before passing them to production decoders
bash
# Verify installed OpenEXR version and upgrade to the patched release
pkg-config --modversion OpenEXR
# Build from source at the fixed tag
git clone https://github.com/AcademySoftwareFoundation/openexr.git
cd openexr
git checkout v3.4.13
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
sudo cmake --install build

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.