PoC β€” Heap out-of-bounds write & over-read in the Arm NN deserializer (.armnn model load)

Security research artifact for responsible disclosure (Protect AI / huntr Model File Vulnerability program). These files are malformed Arm NN model files that trigger memory-safety bugs in ARM-software/armnn's armnnDeserializer when loaded. They are crash/where-it-corrupts proof-of-concepts, not weaponized exploits. Do not load them with an unhardened build outside a sandbox.

Affected project: ARM-software/armnn β€” armnnDeserializer (src/armnnDeserializer/Deserializer.cpp β†’ armnnUtils::Permute), reached via the public API armnnDeserializer::IDeserializer::CreateNetworkFromBinary. Version: HEAD f8beb5a9 (v26.01). Format: .armnn (Arm NN FlatBuffers). Class: CWE-787 (OOB Write) / CWE-190 (Integer Overflow) / CWE-125 (OOB Read) / CWE-843 (Type Confusion).

Root cause

ParseConstant (default m_WeightsLayoutScheme <= 0 path) permutes constant-tensor weights into a freshly allocated buffer. Two validation gaps make this memory-unsafe when the model is untrusted:

  1. Unchecked integer overflow. TensorShape::GetNumElements() multiplies the dimensions in unsigned int with no overflow check (src/armnn/Tensor.cpp:181), and GetNumBytes() = GetDataTypeSize() * GetNumElements() likewise. A dimension product of 2^32 wraps to 0, so permuteBuffer = new unsigned char[GetNumBytes()] is under-allocated, while armnnUtils::Permute iterates the true product of dimensions β†’ OOB write.
  2. No data-type/width cross-check. ToConstTensor only checks data->size() == GetNumElements() (element count); it never verifies the union member width (ByteData/ShortData/IntData/LongData = 1/2/4/8 bytes) matches the tensor's declared dataType width. This (a) lets the over-read read GetNumBytes() from a smaller buffer β†’ OOB read whose content surfaces in the returned INetwork (heap disclosure), and (b) lets the source stay larger than the destination so the OOB write content is attacker-supplied.

armnnUtils::Permute/PermuteLoop::Unroll receive srcEnd/dstEnd but only null-check them β€” they are never enforced as bounds at the memcpy.

Files (models/)

file effect when loaded (under ASAN)
combined_chain.armnn one model, both bugs β€” two ConstantLayers (write + leak), single CreateNetworkFromBinary call. ASAN aborts at the first OOB (write-first β†’ WRITE).
constweight_controlled_write.armnn controlled-content heap OOB WRITE β€” dims=[1,1,2,2147483680] (product 2^32+64 β†’ wraps to 64), dataType=QAsymmU8 (dst=64 B), data via IntData (256 B of 0x41). Overflowing byte written at dstOff=64 is the attacker's 0x41.
constweight_widthconfusion.armnn heap OOB READ / info-leak β€” Float32 tensor (GetNumBytes()=4000) with ByteData of only 1000 B β†’ 3000 B over-read copied into the network constant.
constweight_allocoverflow.armnn minimal length-only WRITE variant β€” dims=[65536,65536,1,1], empty data β†’ new[0] β†’ WRITE of size 4 at offset 0.

*.json are the human-readable sources (compiled to .armnn with flatc -b ArmnnSchema.fbs <f>.json). asan_*.txt are the full AddressSanitizer reports.

Reproduce

# 1. flatbuffers v24.3.25 (flatc + libflatbuffers.a)
# 2. Build armnn deserializer only, no ACL backends, with ASAN:
cmake -GNinja .. -DBUILD_ARMNN_DESERIALIZER=ON -DARMNNREF=OFF -DBUILD_UNIT_TESTS=OFF \
  -DBUILD_SHARED_LIBS=OFF -DCMAKE_CXX_COMPILER=clang++ \
  -DCMAKE_CXX_FLAGS="-fsanitize=address -g -O1" \
  -DFLATC_DIR=<flatc_dir> -DFLATBUFFERS_INCLUDE_PATH=<inc> -DFLATBUFFERS_LIBRARY=<libflatbuffers.a>
ninja armnnDeserializer
# (Deserializer.cpp + armnnUtils compiled with -DNDEBUG to match a Release build, so the
#  flatbuffers debug assert is removed and the real OOB access is exercised.)

# 3. A ~15-line driver that calls IDeserializer::CreateNetworkFromBinary(bytes):
./driver models/constweight_controlled_write.armnn   # -> AddressSanitizer: heap-buffer-overflow WRITE
./driver models/constweight_widthconfusion.armnn     # -> AddressSanitizer: heap-buffer-overflow READ
./driver models/combined_chain.armnn                 # -> WRITE (first layer)

Disclosure

Reported responsibly via the huntr / Protect AI Model File Vulnerability program; Arm notified in parallel. No weaponized control-flow-hijack chain is included β€” these are the underlying memory-safety primitives only.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support