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

CVE-2026-52834: jxl-oxide JPEG XL Decoder RCE Vulnerability

CVE-2026-52834 is a remote code execution flaw in jxl-oxide JPEG XL decoder that allows memory corruption through integer overflow on 32-bit platforms. This article covers technical details, affected versions, and patches.

Updated:

CVE-2026-52834 Overview

CVE-2026-52834 is an integer overflow vulnerability in jxl-oxide, a pure Rust implementation of a JPEG XL decoder. The flaw exists in the jxl-grid crate prior to version 0.6.2. Decoding a crafted JPEG XL image on a 32-bit platform can overflow length calculations in AlignedGrid::with_alloc_tracker and related grid and subgrid arithmetic. A 65536 x 65536 frame can pass the frame-area limit while overflowing the usize element count, causing modular, VarDCT, or filter rendering paths to allocate a backing buffer smaller than the logical grid. Subsequent mutable subgrid and raw-pointer operations then perform attacker-controlled out-of-bounds writes.

Critical Impact

Attacker-controlled out-of-bounds writes can cause memory corruption, denial of service, or arbitrary code execution on 32-bit systems decoding untrusted JPEG XL images.

Affected Products

  • jxl-oxide JPEG XL decoder library (Rust)
  • jxl-grid crate versions prior to 0.6.2
  • Applications embedding jxl-oxide on 32-bit platforms

Discovery Timeline

  • 2026-08-19 - CVE-2026-52834 published to NVD
  • 2026-08-19 - Last updated in NVD database

Technical Details for CVE-2026-52834

Vulnerability Analysis

The vulnerability is a heap-based buffer overflow [CWE-122] triggered by an unchecked integer multiplication. In AlignedGrid::with_alloc_tracker, the decoder computes len = width * height using usize arithmetic. On a 32-bit target, usize is 32 bits wide, so a 65536 x 65536 grid produces 2^32, which wraps to zero.

The wrapped value causes vec![S::default(); buf_len] to allocate a buffer far smaller than the logical grid dimensions. Downstream rendering paths in modular, VarDCT, and filter modules operate on the logical dimensions and write past the allocation.

A related overflow exists in shared_subgrid.rs, where stride * (height - 1) + width is used to size subgrid regions without checked arithmetic. Mutable subgrid handles and raw-pointer operations then write attacker-controlled data outside the backing buffer.

Root Cause

The root cause is missing overflow checks on usize multiplications used to compute buffer lengths. The frame-area limit enforced by the decoder does not prevent individual dimension pairs from overflowing when multiplied. A tiny bitstream-controlled cropped frame combined with a huge canvas or requested region reaches the vulnerable composition path in crates/jxl-render/src/blend.rs through ordinary render_frame() calls.

Attack Vector

An attacker crafts a malicious JPEG XL file with dimensions chosen to overflow usize on 32-bit platforms. Delivery vectors include file rendering pipelines, image thumbnailers, and web browsers or preview services that link jxl-oxide. No authentication or user interaction beyond opening or previewing the image is required. Exploitation requires local processing of the file, and attack complexity is high because the attacker must land on a 32-bit build.

rust
// Patch in crates/jxl-grid/src/lib.rs replaces unchecked multiplication
// with checked_mul/checked_add to catch usize overflow at decode time.
         height: usize,
         tracker: Option<&AllocTracker>,
     ) -> Result<Self, OutOfMemory> {
-        let len = width * height;
-        let buf_len = len + (Self::ALIGN - 1) / std::mem::size_of::<S>();
+        let len = width
+            .checked_mul(height)
+            .expect("grid dimensions overflow usize");
+        let buf_len = len
+            .checked_add((Self::ALIGN - 1) / std::mem::size_of::<S>())
+            .expect("aligned grid buffer length overflows usize");
         let handle = tracker
             .map(|tracker| tracker.alloc::<S>(buf_len))
             .transpose()?;
         let mut buf = vec![S::default(); buf_len];

         let extra = buf.as_ptr() as usize & (Self::ALIGN - 1);
         let offset = ((Self::ALIGN - extra) % Self::ALIGN) / std::mem::size_of::<S>();
-        buf.resize_with(len + offset, S::default);
+        let len_with_offset = len
+            .checked_add(offset)
+            .expect("aligned grid buffer length overflows usize");
+        buf.resize_with(len_with_offset, S::default);
// Source: https://github.com/tirr-c/jxl-oxide/commit/3986dadd3926a95656a642e74a0702d52f5c92e2

A parallel fix in crates/jxl-grid/src/shared_subgrid.rs guards the subgrid area computation:

rust
         assert!(width > 0);
         assert!(height > 0);
         assert!(width <= stride);
-        assert!(buf.len() >= stride * (height - 1) + width);
+        let required_len = stride
+            .checked_mul(height - 1)
+            .and_then(|offset| offset.checked_add(width))
+            .expect("subgrid area overflows usize");
+        assert!(buf.len() >= required_len);
// Source: https://github.com/tirr-c/jxl-oxide/commit/3986dadd3926a95656a642e74a0702d52f5c92e2

Detection Methods for CVE-2026-52834

Indicators of Compromise

  • JPEG XL files (.jxl) with declared canvas dimensions at or near 65536 x 65536, or with cropped frames that reference a much larger canvas or requested region.
  • Process crashes, panics with messages such as grid dimensions overflow usize, or segmentation faults in processes linking jxl-oxide on 32-bit builds.
  • Unexpected child processes spawned by image renderers, thumbnailers, or browser preview services after processing a .jxl file.

Detection Strategies

  • Inventory Rust dependencies in build pipelines and flag any project pinning jxl-grid below 0.6.2 or jxl-oxide releases prior to 0.12.6.
  • Inspect JPEG XL bitstreams at ingestion boundaries and reject frames whose width * height exceeds u32::MAX when the target build is 32-bit.
  • Monitor telemetry from image-handling processes for abnormal memory writes, heap corruption signals, or repeated crashes tied to .jxl inputs.

Monitoring Recommendations

  • Alert on file uploads or downloads of JPEG XL content into environments known to run 32-bit decoders.
  • Track advisories GHSA-5pmv-rx8r-wmv5 and RUSTSEC-2026-0151 in vulnerability management workflows.
  • Collect endpoint crash telemetry from image preview services and correlate against .jxl file access events.

How to Mitigate CVE-2026-52834

Immediate Actions Required

  • Upgrade jxl-grid to version 0.6.2 or later and rebuild all downstream consumers, including any pinned jxl-oxide releases.
  • Update jxl-oxide to release 0.12.6 or later, which incorporates the patched grid crate.
  • Prioritize remediation on 32-bit builds and embedded targets where usize is 32 bits wide.

Patch Information

The fix is available in jxl-grid 0.6.2 and shipped with jxl-oxide release 0.12.6. Refer to the GitHub Security Advisory GHSA-5pmv-rx8r-wmv5, the Rustsec Advisory RUSTSEC-2026-0151, and the GitHub Release 0.12.6. The patch introduces checked_mul and checked_add around all grid and subgrid length calculations, converting silent overflow into an explicit panic.

Workarounds

  • Restrict decoding to 64-bit builds where usize overflow on 65536 x 65536 dimensions cannot occur.
  • Reject JPEG XL inputs at an application-layer gateway when declared canvas dimensions exceed practical limits for the workload.
  • Sandbox image decoding in a restricted process with seccomp, AppArmor, or equivalent controls to contain memory corruption impact.
bash
# Update Cargo.toml to require the patched versions, then rebuild
# Cargo.toml
[dependencies]
jxl-oxide = ">=0.12.6"
jxl-grid  = ">=0.6.2"

# Refresh the lockfile and verify resolved versions
cargo update -p jxl-grid -p jxl-oxide
cargo tree -i jxl-grid

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.