YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
Arm NN native Batch/Space descriptor vector mismatch OOB reads
Arm NN's native FlatBuffers deserializer accepts BatchToSpaceNd and
SpaceToBatchNd descriptors whose blockShape length exceeds the number of
crops or padList pairs. Normal graph optimization then iterates over every
block-shape entry and indexes the shorter paired vector without a bounds
check.
The included models use two block-shape entries and only one crop or padding
pair. Both trigger deterministic AddressSanitizer heap-buffer-overflow reads
during public .armnn deserialization plus normal armnn::Optimize().
Tested version
- Arm NN commit:
2b61cecc9df7a43fca1463795062cf359e6be820 - Backend selected for optimization:
CpuRef - Instrumentation: AddressSanitizer and UndefinedBehaviorSanitizer
Root cause
ParseBatchToSpaceNd() validates only that the flat crops vector has an even
length. ParseSpaceToBatchNd() does the same for padList. Neither parser
requires:
blockShape.size() == crops.size() / 2
blockShape.size() == padList.size() / 2
The vectors are copied independently into their descriptors. During graph shape inference:
for (unsigned int i = 0; i < m_Param.m_BlockShape.size(); ++i)
{
unsigned int cropSize =
m_Param.m_Crops[i].first + m_Param.m_Crops[i].second;
}
and:
for (unsigned int i = 0; i < m_Param.m_BlockShape.size(); ++i)
{
outputShape[spatialDimension] =
(inputShape[spatialDimension] +
m_Param.m_PadList[i].first +
m_Param.m_PadList[i].second) /
m_Param.m_BlockShape[i];
}
At i == 1, the single-pair m_Crops or m_PadList vector is read
immediately beyond its eight-byte allocation.
Reproduction
From the workspace root:
./cyber/huntr-mfv/candidates/armnn-flatbuffers-batch-space-vector-mismatch-oob-read/reproduce.sh
Verified in three fresh processes per model:
| Model | Result |
|---|---|
control-batch-to-space.armnn |
exit 0, 0, 0 |
control-space-to-batch.armnn |
exit 0, 0, 0 |
trigger-batch-to-space.armnn |
ASan heap-buffer-overflow, exit 134, 134, 134 |
trigger-space-to-batch.armnn |
ASan heap-buffer-overflow, exit 134, 134, 134 |
Symbolized trigger sinks:
armnn::BatchToSpaceNdLayer::InferOutputShapes(...) + 2832
armnn::BatchToSpaceNdLayer::ValidateTensorShapesFromInputs()
armnn::Graph::InferTensorInfos()
armnn::Optimize(...)
armnn::SpaceToBatchNdLayer::InferOutputShapes(...) + 2788
armnn::SpaceToBatchNdLayer::ValidateTensorShapesFromInputs()
armnn::Graph::InferTensorInfos()
armnn::Optimize(...)
Fixture hashes
d0a6dbde7dbcba4e59ae14d49151584da1fa41d4f0348e8065ffd26f9cc915d4 control-batch-to-space.armnn
8c7bfd08cd8a76c41b2b8f931f12e5f1453ebd328c148cfed4c61b4056685bd3 control-space-to-batch.armnn
d8d55eef2c8cbcfc04669c45c8f32d5f9f0021735da890c17aa49d169957777d trigger-batch-to-space.armnn
f0168e3cc41a396b764360e1f01bb092115084fd2f7782c4c0bc5c0fb7d2dee1 trigger-space-to-batch.armnn
Impact
An attacker-controlled .armnn model can trigger a native heap
out-of-bounds read while the network is optimized, before inference.
Suggested fix
Reject each descriptor unless its block-shape length exactly matches the number of crop or padding pairs. Validate the relationship in the deserializer and defensively in each layer's shape-inference method.
Prior art
Automated Hugging Face, GitHub, and local scans returned zero matches. Manual
ARM repository, Huntr, Hugging Face, and web searches found adjacent Arm NN
dimension-vector and padding bugs, but no report for this cross-vector
blockShape versus crops / padList mismatch. The public ParsePad
odd-padList occurrence is a different parser and input invariant.