CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



GHSA-VVP9-7P8X-RFVV
7.5

GHSA-VVP9-7P8X-RFVV: Information Leak via Out-of-Bounds Read in lz4_flex

Amit Schendel
Amit Schendel
Senior Security Researcher

Mar 17, 2026·6 min read·8 visits

PoC Available

Executive Summary (TL;DR)

Unvalidated LZ4 match offsets in lz4_flex < 0.11.4 allow attackers to leak uninitialized memory or reused buffer contents via crafted compressed payloads.

The lz4_flex Rust crate prior to version 0.11.4 contains an information leak vulnerability due to improper validation of LZ4 match offsets. An attacker can craft a malicious LZ4 payload that forces the decompressor to read from uninitialized memory or previously freed buffers, leading to sensitive data exposure.

Vulnerability Overview

lz4_flex is a widely utilized LZ4 decompression and compression library implemented in the Rust programming language. It operates by providing distinct block-based and frame-based APIs to handle LZ4 data streams. Applications integrating this library typically process untrusted, compressed data originating from external sources. The attack surface encompasses any network endpoint or file parsing routine that directly feeds attacker-controlled input into the decompression functions.

A high-severity vulnerability exists in the block decompression implementation of lz4_flex prior to version 0.11.4. The flaw is rooted in the mishandling of LZ4 match offsets, leading to an out-of-bounds read (CWE-125) and subsequent exposure of sensitive information (CWE-200). The specific vulnerability is tracked under the advisory GHSA-VVP9-7P8X-RFVV.

During the decompression process, the library fails to strictly enforce boundary constraints on memory references supplied by the compressed payload. Attackers exploit this by supplying anomalous offset values. This results in the decompressor extracting data from uninitialized memory segments or previously populated buffers, returning this data to the caller as part of the decompressed output.

Root Cause Analysis

The LZ4 compression algorithm achieves data reduction by encoding repetitive sequences as matches. A match is defined by an offset and a length, instructing the decompressor to copy a specific number of bytes from a previously decompressed position in the stream. The decompressor must validate that the requested offset strictly points to a memory location within the already initialized portion of the output buffer or the bounds of a provided external dictionary.

In lz4_flex, the vulnerability resides within the decompress_internal function located in both src/block/decompress.rs and src/block/decompress_safe.rs. The implementation attempts to handle offset bounds by utilizing a clamping operation rather than an explicit validation check. When an offset exceeds the combined length of the currently decompressed output and the external dictionary, the code artificially reduces the offset to the maximum allowable boundary.

This clamping mechanism is fundamentally flawed for memory safety. While it prevents the pointer from incrementing entirely out of the allocated address space, thereby avoiding an immediate segmentation fault, it permits the memory copy operation to read backward from the start of the output buffer. By overriding the intended bounds, the operation reads data preceding the currently initialized contiguous memory block.

If the application reuses an existing buffer or utilizes memory allocation techniques that bypass zero-initialization for performance, this backward read extracts remnant data from the heap. This remnant data is then appended to the active output stream as if it were valid decompressed content, directly causing an information leak.

Code Analysis

The flaw is evident when examining the pointer arithmetic and bound checking logic in the vulnerable versions of lz4_flex. The core issue stems from the offset.min() operation applied to the attacker-controlled offset value.

// Vulnerable implementation in src/block/decompress.rs
let offset = read_u16_ptr(&mut input_ptr) as usize;
let output_len = unsafe { output_ptr.offset_from(output_base) as usize };
let offset = offset.min(output_len + ext_dict.len()); // VULNERABLE CLAMPING

In this vulnerable logic, output_len represents the number of bytes successfully decompressed thus far. If the attacker supplies an offset larger than output_len, the min function restricts the offset to exactly output_len. The subsequent copy operation then reads from output_ptr.sub(offset), which effectively points to output_base. This reads from the absolute beginning of the buffer, regardless of whether that memory was initialized in the current decompression pass.

Commit 055502ee5d297ecd6bf448ac91c055c7f6df9b6d addresses this by replacing the clamping logic with strict boundary validation. The patched implementation enforces an absolute failure state when the offset exceeds the initialized data length.

// Patched implementation in src/block/decompress.rs
let offset = read_match_offset(&mut input_ptr)? as usize;
let output_len = unsafe { output_ptr.offset_from(output_base) as usize };
if offset > output_len + ext_dict.len() {
    return Err(DecompressError::OffsetOutOfBounds);
}

Additionally, the patch introduces validation to ensure the offset is not zero, which is invalid according to the official LZ4 specification. The read_match_offset helper function now returns a DecompressError::OffsetZero if an empty offset is provided.

Exploitation Methodology

Exploiting this vulnerability requires the attacker to construct a specialized LZ4 payload and deliver it to an application utilizing the lz4_flex block decompression API. The application must process the payload and subsequently handle or expose the resulting output.

The attacker begins by formatting an LZ4 sequence containing a literal payload followed by a match token. The match token is intentionally crafted to specify an offset integer value significantly larger than the length of the preceding literal payload. When the lz4_flex parser encounters this token, it executes the clamping logic, reading from the starting address of the allocated output buffer.

If the target application implements buffer reuse to optimize allocation overhead, the output buffer will contain data from previous processing loops. The crafted offset forces the decompressor to copy this historical data into the current output stream. The application, unaware of the malformation, processes the output containing the leaked memory.

Impact Assessment

The concrete security impact is an uncontrolled information leak originating from the target process's memory space. The severity of the leak is heavily dependent on the surrounding application context and its memory management patterns.

In environments where memory is aggressively pooled and reused, the leaked contents may include sensitive data structures. This includes session tokens, cryptographic keys, authentication credentials, or other users' confidential data processed by the same application thread. The CVSS vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N accurately reflects the unauthenticated, remote nature of the attack and its singular impact on confidentiality.

While the block API was the primary vector identified, developers utilizing the frame API should also verify their integration. Internal helper functions shared across the crate may exhibit similar unchecked boundary logic. The introduction of MemorySanitizer in the upstream continuous integration pipeline indicates that uninitialized reads were a primary focal point during the remediation of this issue.

Remediation and Mitigation

The primary remediation for GHSA-VVP9-7P8X-RFVV is to update the lz4_flex dependency to version 0.11.4 or later. Developers must modify their Cargo.toml file to enforce this minimum version constraint. Recompilation of the application is required to statically link the patched dependency into the final binary.

If immediate patching is technically unfeasible, administrators can implement a defense-in-depth workaround at the application level. By strictly zero-initializing all output buffers prior to passing them to the decompression API, the impact of the out-of-bounds read is mitigated. The copy operation will only extract zero bytes, preventing the exposure of remnant heap data.

However, zero-initialization incurs a measurable performance penalty, negating some of the speed advantages inherent to the LZ4 algorithm. This workaround should only serve as a temporary measure until the patched library can be properly integrated and deployed. Security teams should also verify that downstream dependencies incorporating lz4_flex have published updated releases addressing this advisory.

Fix Analysis (1)

Technical Appendix

CVSS Score
7.5/ 10
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

Affected Systems

lz4_flex Rust crate

Affected Versions Detail

Product
Affected Versions
Fixed Version
lz4_flex
PSeitz
< 0.11.40.11.4
AttributeDetail
CWE IDCWE-125, CWE-200
Attack VectorNetwork
CVSS7.5
Exploit StatusProof-of-Concept (Fuzzer)
ImpactHigh Confidentiality
KEV StatusUnlisted

MITRE ATT&CK Mapping

T1190Exploit Public-Facing Application
Initial Access
T1005Data from Local System
Collection
CWE-125
Out-of-bounds Read

The software reads data past the end, or before the beginning, of the intended buffer.

Vulnerability Timeline

Fix commit 055502ee5d297ecd6bf448ac91c055c7f6df9b6d pushed to repository.
2026-01-15
GHSA-VVP9-7P8X-RFVV published to the GitHub Advisory Database.
2026-01-15
lz4_flex version 0.11.4 released.
2026-01-15

References & Sources

  • [1]GitHub Advisory GHSA-VVP9-7P8X-RFVV
  • [2]Fix Commit 055502ee5d297ecd6bf448ac91c055c7f6df9b6d
  • [3]lz4_flex Repository

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.