Views
No views yet
.armnn model can give a ReduceLayer an axis that is outside the
input tensor rank. The deserializer copies the serialized axis vector into
ReduceDescriptor::m_vAxis without validating its elements.armnn::Optimize() shape inference, ReduceLayer subtracts the
number of serialized axes from the input rank to size an output-dimension
vector. It then copies every input dimension whose numeric index is not in the
axis vector. An out-of-range axis therefore reduces the allocation without
removing any input dimension from the copy loop. The last copy writes past the
heap allocation.axis = [2]axis = [100]heap-buffer-overflow write in three of
three runs.2b61cecc9df7a43fca1463795062cf359e6be820armnnDeserializer::IDeserializer::CreateNetworkFromBinary()armnn::Optimize()CpuRef./cyber/huntr-mfv/candidates/armnn-flatbuffers-reduce-axis-shape-oob-write/reproduce.sh "$PWD"loaded and optimized 580 bytes1ERROR: AddressSanitizer: heap-buffer-overflow
2WRITE of size 4
3...
4armnn::ReduceLayer::InferOutputShapes(...)
5armnn::ReduceLayer::ValidateTensorShapesFromInputs()
6armnn::Graph::InferTensorInfos()
7armnn::Optimize(...)control-{1,2,3}.txt and trigger-{1,2,3}.txt files contain
three independent runs of each model. Each trigger exits with status 134.1descriptor.m_vAxis =
2 std::vector<unsigned int>(flatBufferAxis->begin(), flatBufferAxis->end());ReduceLayer::InferOutputShapes() then derives:1outputRank = input.GetNumDimensions() -
2 static_cast<unsigned int>(m_Param.m_vAxis.size());
3std::vector<unsigned int> dimSizes(outputRank, 1);[100], so dimSizes has three elements. The following loop finds that none
of the valid input dimensions 0..3 equals 100, then writes all four input
dimensions into that three-element vector:1for (unsigned int i = 0; i < input.GetNumDimensions(); ++i)
2{
3 if (std::find(m_Param.m_vAxis.begin(),
4 m_Param.m_vAxis.end(),
5 i) == m_Param.m_vAxis.end())
6 {
7 dimSizes[outputIndex] = input[i];
8 ++outputIndex;
9 }
10}1e2ccb82ef498586447658446fd23bdaac77b29d77f316d4b6bb77b57f2b25de2 control-axis-2.armnn
2274f197d458ff0f911e3080eab2a4e38fc9e29d69200a2cc3eca22c21f4aa16e trigger-axis-100.armnncmp -l reports a single differing byte at offset 249: octal 002 in the
control and octal 144 (100 decimal) in the trigger.ReduceDescriptor.axis to ReduceLayer::InferOutputShapes() path.InferOutputShapes() should also
validate the descriptor independently and use checked writes rather than
assuming the axis vector contains a unique subset of input dimensions.