YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
Arm NN .armnn deserializer β memory-safety PoC model files
Malicious Arm NN Flatbuffers (.armnn) model files that corrupt memory when loaded via
armnnDeserializer::IDeserializer::CreateNetworkFromBinary(). Tested on ARM-software/armnn HEAD
f8beb5a9 (src/armnnDeserializer/Deserializer.cpp).
| File | Result | Sink |
|---|---|---|
armnn_write_oob.armnn |
stack out-of-bounds WRITE (CWE-787) | ToTensorInfo, Deserializer.cpp:756 |
armnn_read_oob.armnn |
out-of-bounds READ (CWE-125, same root cause) | GetInputs/GetBaseLayer, Deserializer.cpp:839/286 |
armnn_valid.armnn |
loads cleanly (negative control) | β |
Root cause
CreateNetworkFromBinary runs the FlatBuffers structural verifier (VerifyGraphBuffer), which does
not range-check scalar values. Attacker-controlled fields are then used without validation:
ToTensorInfowritesdimensionsSpecificity[i]into a fixedbool[armnn::MaxNumOfTensorDimensions](=bool[5]);iis bounded only by the attackerdimensionSpecificityvector length β stack overflow.GetInputspassesConnection.sourceLayerIndexthroughCHECKED_NON_NEGATIVE(lower bound only) intolayers()->Get(index)β out-of-bounds.
In release builds (-DNDEBUG) the FlatBuffers debug assert is compiled out, so these are raw OOB accesses.
Reproduce
Self-contained harness (uses the project ArmnnSchema.fbs generated header + FlatBuffers headers):
c++ -std=c++17 -DNDEBUG -fsanitize=address -g -I. -Iflatbuffers_include harness_dimspec.cpp -o h_write
./h_write armnn_write_oob.armnn # AddressSanitizer: stack-buffer-overflow WRITE in ToTensorInfo
./h_write armnn_valid.armnn # clean
c++ -std=c++17 -DNDEBUG -fsanitize=address -g -I. -Iflatbuffers_include harness_read.cpp -o h_read
./h_read armnn_read_oob.armnn # AddressSanitizer: heap-buffer-overflow READ in GetBaseLayer
Also reproducible via ExecuteNetwork built with -fsanitize=address:
ExecuteNetwork -m armnn_write_oob.armnn -f armnn-binary.
Suggested fix
ToTensorInfo: rejectdimensionSpecificity->size() > MaxNumOfTensorDimensions.GetInputs/GetBaseLayer: addinputId < graph->layers()->size().
Crash-only proof of concept.