CVE-2026-59949: yawkat LZ4 Java: JVM Crash via Null Byte Array in lz4-java Streaming XXHash JNI (StreamingXXHash32JNI / StreamingXXHash64JNI)
Summary
Insufficient validation of byte array arguments in JNI-based XXHash implementations in lz4-java 1.11.0 and earlier allows callers to crash the JVM by passing an invalid array reference or invalid range to native XXHash methods.
This affects applications where an attacker can influence the byte array object or the off / len arguments passed to affected XXHash APIs. It does not affect the common case where only the contents of a valid byte array are attacker-controlled.
Java-based XXHash implementations are not affected.
Details
The JNI-backed XXHash implementations pass caller-provided byte array arguments to native code. The affected APIs are:
- XXHashFactory.nativeInstance().hash32().hash(byte[] buf, int off, int len, int seed) - XXHashFactory.nativeInstance().hash64().hash(byte[] buf, int off, int len, long seed) - XXHashFactory.nativeInstance().newStreamingHash32(seed).update(byte[] bytes, int off, int len) - XXHashFactory.nativeInstance().newStreamingHash64(seed).update(byte[] bytes, int off, int len)
Before the fix, the streaming JNI implementations did not validate bytes, off, or len before calling XXHashJNI.XXH32update / XXHashJNI.XXH64update. The non-streaming JNI implementations called SafeUtils.checkRange, but SafeUtils.checkRange(byte[], int, int) skipped all array access when len == 0, so a null byte array with a zero length could still reach JNI.
As a result:
- hash(null, 0, 0, seed) and update(null, 0, 0) could pass a null array reference to JNI, causing a fatal JVM crash in GetPrimitiveArrayCritical. - update(new byte[16], 0, Integer.MAXVALUE) could cause native XXHash code to read far beyond the end of the Java array, causing a fatal JVM crash and potentially exposing in-process memory to the native routine before the crash.
The oversized-length non-streaming hash(new byte[16], 0, Integer.MAXVALUE, seed) case was already rejected in Java before this fix. The missing validation affected the streaming oversized-length case and the zero-length null-array case for both streaming and non-streaming JNI XXHash APIs.
The impact of this vulnerability depends on how user code uses the XXHash API. Code that hashes attacker-controlled byte contents in a valid, correctly bounded array is not affected. Code may be affected if an attacker can cause the application to pass a null array, an attacker-controlled offset, or an attacker-controlled length to the native XXHash API. The primary impact is denial of service due to JVM termination. For oversized lengths, native code may also read outside the Java array before the process crashes.
Mitigation
lz4-java 1.11.1 fixes this issue without requiring changes in user code.
If you cannot upgrade, avoid passing attacker-controlled array references, offsets, or lengths to JNI-backed XXHash APIs. In particular, validate that arrays are non-null and that off and len describe a range fully contained in the array before calling native XXHash methods.
Using XXHashFactory.safeInstance() avoids the JNI boundary and is not affected by this native crash behavior.
Other sources
Insufficient validation of byte array arguments in JNI-based XXHash implementations in lz4-java 1.11.0 and earlier allows callers to crash the JVM by passing an invalid array reference or invalid range to native XXHash methods. This affects applications where an attacker can influence the byte array object or the off/len arguments passed to affected XXHash APIs.
The primary risk is denial of service through JVM termination. For oversized-length cases, native code may also read memory outside the Java array before crashing, potentially exposing in-process data.
Affected packages: - at.yawk.lz4:lz4-java <= 1.11.0 - org.lz4:lz4-java <= 1.8.1
Fixed in at.yawk.lz4:lz4-java 1.11.1.
Workaround: Use XXHashFactory.safeInstance() instead of nativeInstance(), as Java-based XXHash implementations are unaffected. Additionally, validate that arrays are non-null and that offset/length parameters fall within array bounds before calling native XXHash methods.
— Red Hat
yawkat LZ4 Java provides LZ4 compression for Java. Prior to 1.11.1, JNI-backed XXHash implementations fail to validate the byte array object and the off and len arguments in XXHashFactory.nativeInstance().hash32().hash(), XXHashFactory.nativeInstance().hash64().hash(), XXHashFactory.nativeInstance().newStreamingHash32().update(), and XXHashFactory.nativeInstance().newStreamingHash64().update(), allowing null arrays or oversized ranges to reach native code, read outside the Java array, and fatally terminate the JVM. This issue is fixed in version 1.11.1.
— MITRE
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
maven/at.yawk.lz4:lz4-javato a version that resolves this vulnerability.Fixed in 1.11.1 - Upgrade
Upgrade
at.yawk.lz4:lz4-javato a version that resolves this vulnerability.Fixed in 1.11.1 - Compensating control
If upgrading is not possible, use XXHashFactory.safeInstance() instead of XXHashFactory.nativeInstance(); Java-based XXHash implementations are not affected.
- Compensating control
Before calling native XXHash methods, validate that byte arrays are non-null and that off and len describe a range fully contained within the array.
Event History
Frequently Asked Questions
What is the severity of CVE-2026-59949?
CVE-2026-59949 has a medium severity rating of 6.5.
How do I fix CVE-2026-59949?
To fix CVE-2026-59949, upgrade to lz4-java version 1.11.1 or later.
What type of vulnerability is CVE-2026-59949?
CVE-2026-59949 is classified as a null pointer dereference vulnerability.
What applications are affected by CVE-2026-59949?
CVE-2026-59949 affects applications using JNI-based XXHash implementations in lz4-java versions 1.11.0 and earlier.
What can an attacker do with CVE-2026-59949?
An attacker can crash the JVM by passing an invalid array reference or range to native XXHash methods.