YAML Metadata Warning:empty or missing yaml metadata in repo card
Check out the documentation for more information.
PoC: OOB read via negative subgraph index in Samsung ONE Circle loader (CWE-125/129)
Loading a crafted .circle model reads out of bounds.
Root cause
runtime/onert/core/src/loader/CircleLoader.cc loadSubgraph():
// _tensor_to_operand is a std::vector sized to circle_subg->tensors()->size()
for (const std::int32_t input_ind : *circle_subg->inputs()) // attacker int32 from .circle
subg->addInput(tensorIdxToOperandIdx(input_ind),
_tensor_names.at(_tensor_to_operand[input_ind])); // L138: unchecked operator[]
// ... same pattern for outputs (L142)
The subgraph inputs/outputs indices are signed int32 read straight from the .circle FlatBuffer.
A negative index (e.g. -2) reaches _tensor_to_operand[input_ind] via unchecked operator[],
reading before the vector's backing storage. Only -1 is special-cased ("optional") elsewhere; other
negative (or oversized) indices are not validated against the tensor count before this indexing on a
normal model load.
Reproduce (AddressSanitizer)
circle_negative_subgraph_index_harness.cpp reproduces the indexing verbatim with a std::vector of the
same role:
g++ -fsanitize=address -g -O0 circle_negative_subgraph_index_harness.cpp -o poc && ./poc
# ==ERROR: AddressSanitizer: heap-buffer-overflow READ of size 4
# #0 main ... (_tensor_to_operand[input_ind])
# 0x... is located 8 bytes before 8-byte region <- negative index reads before the vector allocation
A real trigger is a .circle flatbuffer whose subgraph inputs (or outputs) vector contains a
negative tensor index other than -1.
Fix
Validate each subgraph input/output index is in [0, tensors()->size()) before indexing (use .at() or
an explicit range check), treating only -1 as the optional sentinel.