YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
Arm NN native StridedSlice short-vector heap OOB read
Arm NN's native FlatBuffers deserializer accepts a StridedSliceDescriptor
whose begin, end, and stride vectors are equally sized but shorter than
the input tensor rank. Normal graph optimization iterates over the input rank
and indexes the descriptor vectors without a bounds check.
The included trigger uses a rank-four input and one-element descriptor vectors.
It produces a deterministic AddressSanitizer heap-buffer-overflow read 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
ParseStridedSlice() checks only that the three vectors have equal lengths:
if (!(flatBufferBegin->size() == flatBufferEnd->size() &&
flatBufferBegin->size() == flatBufferStride->size()))
{
throw ParseException(...);
}
It does not require that their length matches the input tensor rank. The
vectors are then copied into StridedSliceDescriptor.
StridedSliceLayer::InferOutputShapes() sets outputDims from the rank-four
input and unconditionally indexes the one-element vectors:
for (unsigned int i = 0; i < outputDims; ++i)
{
int stride = m_Param.m_Stride[i];
int start = m_Param.GetStartForAxis(inputShape, i);
int stop = m_Param.GetStopForAxis(inputShape, i, start);
// ...
}
At i == 1, m_Stride[1] is read immediately after its four-byte allocation.
Reproduction
From the workspace root:
./cyber/huntr-mfv/candidates/armnn-flatbuffers-stridedslice-short-vectors-oob-read/reproduce.sh
Verified in three fresh processes per model:
| Model | Result |
|---|---|
control.armnn |
exit 0, 0, 0 |
trigger.armnn |
ASan heap-buffer-overflow, exit 134, 134, 134 |
Every trigger reports:
ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 4
0 bytes after 4-byte region
Symbolization of stable image offsets:
0x1b5c48 armnn::StridedSliceLayer::InferOutputShapes(...) + 5788
0x1b621c armnn::StridedSliceLayer::ValidateTensorShapesFromInputs() + 728
0x259960 armnn::Graph::InferTensorInfos() + 1160
Fixture hashes
d3c58af950037f547a3d09ff919b11392bf4df32d311dbf7540a21af3ef1bdad control.armnn
96295c98acad82d6ceeade0c7c84653c4eef013a950c268e83b95597f890f0e8 trigger.armnn
The control uses four begin, end, and stride values for a rank-four
input. The trigger changes all three vectors to one value while preserving
their parser-enforced equality.
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 a native StridedSliceDescriptor unless the descriptor vector length
is compatible with the input rank and mask semantics. Add a defensive bounds
check in StridedSliceLayer::InferOutputShapes() before indexed access.
Prior art
Automated Hugging Face, GitHub, and local scans returned zero matches. Manual searches found no report with this native parser source, short-vector invariant, and shape-inference sink. The local TFLite StridedSlice investigation tested vectors longer than the rank through a different parser; it is not the same issue.