YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
PoC: integer underflow β heap OOB read in ArmNN deserializer ParsePad / ParseBatchToSpaceNd / ParseSpaceToBatchNd (CWE-191 β CWE-125)
Loading a crafted ArmNN model (.armnn) with a Pad (or BatchToSpaceNd / SpaceToBatchNd) layer whose
padList/crops vector is empty reads out of bounds in the deserializer.
Root cause
src/armnnDeserializer/Deserializer.cpp (ParsePad ~2336-2345; same in ParseBatchToSpaceNd ~1396-1403, ParseSpaceToBatchNd ~2920-2927):
if (flatBufferPadList->size() % 2 != 0) throw ParseException(...); // only rejects ODD sizes
for (unsigned int i = 0; i < flatBufferPadList->size() - 1; i += 2) // size()-1 underflows when size()==0
padList.emplace_back(flatBufferPadList->Get(i), flatBufferPadList->Get(i+1)); // Get(0)/Get(1) on empty vector
flatBufferPadList->size() is uint32_t. The only guard rejects odd sizes; an empty list (size 0)
passes (0 % 2 == 0). The loop bound size() - 1 then evaluates as 0u - 1u = 0xFFFFFFFF, so
0u < 0xFFFFFFFFu is true and the body runs. flatbuffers::Vector::Get(i) is data()[i] with no bounds
check in release, so Get(0)/Get(1) read 8 bytes past the empty vector's data region into adjacent
flatbuffer memory β heap OOB read. The flatbuffers::Verifier validates structural offsets but not this
min-length invariant, so an empty padList/crops passes verification. Reachable via
IDeserializer::CreateNetworkFromBinary. Distinct from the filed dimensionSpecificity / ParseSplitter /
ParseConcat bugs (a uint32-underflow class, three additional parsers).
Reproduce (AddressSanitizer)
gcc -fsanitize=address -g -O0 armnn_padlist_underflow_oob_harness.c -o poc && ./poc
# flatBufferPadList->size() = 0 ; size % 2 == 0 -> guard passes
# loop bound size()-1 = 4294967295 (0u-1u underflow); Get(0)/Get(1) on empty vector ...
# ==ERROR: AddressSanitizer: heap-buffer-overflow READ of size 4 ... after the buffer
Affected
- Repository: ARM-software/armnn (commit 51e3253748650f87942163c0b2a51ff38f79a377)
Fix
Reject an empty padList/crops (require size() >= 2 or size() != 0), or use
i + 1 < size() as the loop bound instead of i < size() - 1.