Arm NN ONNX Unsqueeze out-of-range-axis heap-buffer-overflow write

This repository contains a minimal differential reproduction for a native heap-buffer-overflow write in Arm NN's ONNX Unsqueeze parser.

Arm NN commit: 2b61cecc9df7a43fca1463795062cf359e6be820

Files

  • models/control-axis-zero.onnx: checker-valid Unsqueeze model with axes=[0]; parses successfully.
  • models/trigger-axis-eight.onnx: checker-valid Unsqueeze model with axes=[8]; AddressSanitizer reports a four-byte heap-buffer-overflow write during model loading.
  • generate_models.py: deterministic ONNX fixture generator.
  • harness.cpp: minimal public-API loader.
  • asan-output.txt: representative sanitizer report.
  • armnn-onnx-unsqueeze-axis-oob-write-poc.zip: source, fixtures, and logs.

Root cause

src/armnnOnnxParser/OnnxParser.cpp:2428-2431 inserts a dimension at each model-controlled axis without first checking that the axis is no greater than the vector's current size:

for(uint i = 0; i < dims.size(); i++)
{
    targetShape.insert(targetShape.begin() + armnn::numeric_cast<int>(dims[i]), 1);
}

For the rank-one input in the trigger, targetShape.size() is one. The model's axis value of eight forms an invalid iterator beyond the vector allocation. The subsequent std::vector::insert writes four bytes into poisoned heap memory.

Reproduction

Build Arm NN with its ONNX parser and ASan/UBSan, compile harness.cpp, then:

./harness models/control-axis-zero.onnx

ASAN_OPTIONS=abort_on_error=1:detect_leaks=0 \
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
./harness models/trigger-axis-eight.onnx

Expected control:

parsed successfully

Expected trigger:

ERROR: AddressSanitizer: heap-buffer-overflow
WRITE of size 4
    #2 armnnOnnxParser::OnnxParserImpl::ParseUnsqueeze(...)
0x... is located 24 bytes after 8-byte region [0x...,0x...)
SUMMARY: AddressSanitizer: heap-buffer-overflow

Three interleaved control runs exited 0. Three trigger runs exited 134 with the same sanitizer signature.

Fixture integrity

9a69aeeda881718fd5e10e0d3bdac1498920149fed04f707faae406475180437  control-axis-zero.onnx
4bad644776b7e848a571aa29a2425f67771eb8c405ed3ef0d35f10305d0e40c6  trigger-axis-eight.onnx

Both files are 166 bytes and pass ONNX 1.18.0's onnx.checker.check_model(). Their security-relevant difference is the axes value: zero versus eight.

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