YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

Arm NN ONNX pooling short kernel_shape heap over-read

Status: reproduced 3/3 with AddressSanitizer; final prior-art gate open.

Arm NN's ONNX parser requires the pooling kernel_shape attribute to exist, but does not require it to contain the two spatial dimensions that AddPoolingLayer() reads. A checker-valid ONNX model with a one-element kernel_shape makes the parser read four bytes immediately beyond the attribute vector during model loading.

Tested against Arm NN commit 2b61cecc9df7a43fca1463795062cf359e6be820.

Root cause

ReadMandatoryNodeUint32ListAttribute() returns the model-controlled attribute as a vector. AddPoolingLayer() indexes elements zero and one without checking the vector length:

std::vector<uint32_t> kernel_shape =
    ReadMandatoryNodeUint32ListAttribute(node, "kernel_shape");
...
desc.m_PoolWidth  = kernel_shape[1];
desc.m_PoolHeight = kernel_shape[0];

Affected source:

https://github.com/ARM-software/armnn/blob/2b61cecc9df7a43fca1463795062cf359e6be820/src/armnnOnnxParser/OnnxParser.cpp#L1357-L1363

Differential proof

Both files pass onnx.checker.check_model() with ONNX 1.18.0.

Artifact kernel_shape Size Arm NN result
control-two-element-kernel-shape.onnx [2, 2] 214 bytes parses; exit 0
trigger-one-element-kernel-shape.onnx [2] 212 bytes ASan heap-buffer-overflow read; exit 134

Three independent trigger executions produced the same ASan classification, read size, allocation boundary, and parser frame. Three interleaved control executions parsed successfully.

ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 4
    #0 OnnxParserImpl::AddPoolingLayer
0 bytes after 4-byte region
SUMMARY: AddressSanitizer: heap-buffer-overflow

SHA-256:

1b70091779a90c7a2595a178c1bae5531348fa71c327d0970d1488160d8992a4  control-two-element-kernel-shape.onnx
0dd62b3ad68f03e43f1e4fcf2c7f1f91e53aff2f1ca81426b7babbb6e54de054  trigger-one-element-kernel-shape.onnx

Reproduce

Build current Arm NN with its ONNX parser and -fsanitize=address,undefined -fno-omit-frame-pointer. Compile harness.cpp against libarmnnOnnxParser, libarmnn, and the same protobuf library.

python3 generate_models.py

ASAN_OPTIONS=abort_on_error=1:detect_leaks=0 \
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
./harness models/control-two-element-kernel-shape.onnx

ASAN_OPTIONS=abort_on_error=1:detect_leaks=0 \
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
./harness models/trigger-one-element-kernel-shape.onnx

Impact

An application that loads an untrusted .onnx model through Arm NN's public parser API can suffer a native out-of-bounds read before inference. The demonstrated impact is deterministic denial of service. This report does not claim disclosure of the adjacent bytes or code execution.

AddPoolingLayer() is shared by AveragePool and MaxPool, so the same missing validation affects both operator paths.

Suggested remediation

Before indexing pooling attributes, require:

  • kernel_shape.size() == 2;
  • strides.empty() || strides.size() == 2;
  • pads.empty() || pads.size() == 4.

Reject other lengths with ParseException. Add regression tests for zero- and one-element kernel_shape, one-element strides, and one- through three-element pads.

Novelty

The final exact scan returned zero Hugging Face, Arm NN GitHub, or local matches for AddPoolingLayer, kernel_shape[1], the ASan class, or the affected line. Manual issue and pull-request searches likewise returned zero.

Adjacent public Arm NN findings affect the native FlatBuffer deserializer, TFLite auxiliary tensors, or generic tensor-shape multiplication. None validates the ONNX pooling attribute lengths or repairs this function.

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