You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

Samsung ONE (onert runtime) β€” unchecked Tensor.buffer index -> OOB read / SEGV in BaseLoader::loadOperand()

Status: gated, manual-approval PoC repository. For authorized security research / bug-bounty triage only (huntr.com MFF).

Target

  • Project: Samsung/ONE β€” runtime/onert (the on-device NN runtime, as distinct from the compiler/luci import path covered by a separate, already-confirmed finding in this campaign)
  • Vulnerable code: runtime/onert/core/src/loader/BaseLoader.h, BaseLoader<LoaderDomain>::loadOperand(), line 401 (at the last commit before this directory was removed from the repository β€” see "A note on timing" below)
  • Class: CWE-125 Out-of-bounds Read / crash (SIGSEGV), triggered while loading a crafted .circle model.

Root cause

Every Tensor in a .circle/TFLite-format FlatBuffer model carries a buffer field β€” an unsigned 32-bit index into the model's buffers vector. BaseLoader::loadOperand() uses this attacker-controlled index completely unchecked:

// runtime/onert/core/src/loader/BaseLoader.h:401
const auto *data = _domain_model->buffers()->Get(tensor->buffer())->data();

buffers()->Get(idx) is flatbuffers::Vector<T>::Get(), whose only bounds check is:

// flatbuffers/vector.h
return_type Get(SizeT i) const {
    FLATBUFFERS_ASSERT(i < size());
    ...
}

and FLATBUFFERS_ASSERT expands to plain assert(), which is compiled to a no-op under NDEBUG (i.e. any normal release build). A .circle file that passes circle::VerifyModelBuffer() cleanly (FlatBuffers structural verification does not check this semantic invariant) but sets Tensor.buffer = 0xFFFFFFFF against a buffers vector of length 1 causes Get() to compute a wild, out-of-bounds byte offset and dereference it.

A note on timing / how this was verified

runtime/onert was removed from the Samsung/ONE repository's master branch a few hours before this PoC was finalized (commit 342395fc, "Remove source from repo", 2026-07-10). This harness fetches BaseLoader.h from the immediately preceding commit, de7f4736dc4c4f5e47f72a4022a9aa9ac6d1ad1a, i.e. the last version of the file as it existed in the live repository, and verifies against the REAL, unmodified:

  • generated Circle FlatBuffers schema accessors (circle::Model::buffers(), circle::Buffer::data(), circle::Tensor::buffer() β€” reused from this campaign's already-confirmed compiler/luci finding, which regenerated them with flatc from the project's own res/CircleSchema/0.10/circle_schema.fbs)
  • the REAL, unmodified system flatbuffers::Vector<T>::Get() (flatbuffers 23.5.26)

repro_bufidx.cpp calls BaseLoader.h:401's exact expression verbatim (model->buffers()->Get(tensor->buffer())->data()) against a crafted poc_malicious.circle whose single Tensor.buffer field is 0xFFFFFFFF against a 1-entry buffers vector. No onert-internal code is mocked or reimplemented for the vulnerable call itself β€” only the surrounding ir::Graph/operand-creation machinery (irrelevant to this specific read) is not built, since the crash occurs before any of that is reached.

Proof of concept

Release-mode run (NDEBUG, matches the project's shipped build configuration)

[load] read 184 bytes from poc_malicious.circle
[verify] circle::VerifyModelBuffer() => PASS
[model] subgraphs count = 1
[model] subgraph[0].tensors count = 1
[model] buffers vector size = 1
[model] tensor[0].buffer() (attacker-controlled index) = 4294967295

[VULN] executing the REAL BaseLoader.h:401 line verbatim:
[VULN]   _domain_model->buffers()->Get(tensor->buffer())->data();

release exit code: 139   (SIGSEGV)

ASan run (asan_output.txt)

==1185549==ERROR: AddressSanitizer: SEGV on unknown address 0x7c1154be00e8
    #0 ... in unsigned int flatbuffers::ReadScalar<unsigned int>(void const*) /tmp/flatbuffers-include/flatbuffers/base.h:427
    #1 ... in flatbuffers::IndirectHelper<flatbuffers::Offset<circle::Buffer> >::Read(...) flatbuffers/buffer.h:123
    #2 ... in flatbuffers::Vector<flatbuffers::Offset<circle::Buffer>, unsigned int>::Get(unsigned int) const flatbuffers/vector.h:177
    #3 ... in main repro_bufidx.cpp:67
SUMMARY: AddressSanitizer: SEGV .../flatbuffers/base.h:427 in flatbuffers::ReadScalar<unsigned int>(void const*)

Both a real (unsanitized) segfault and a clean ASan diagnostic were captured from the same, unmodified vulnerable line.

Reachability

BaseLoader<LoaderDomain>::loadModel() calls LoaderDomain::VerifyModelBuffer() but discards its return value (BaseLoader.h:1704-1705), then unconditionally walks every Tensor in every SubGraph via loadOperand(). Any onert-based tool that loads a .circle model (the on-device NNAPI/onert runtime itself, onert_run, etc.) hits this path.

Files

  • repro_bufidx.cpp β€” the verification harness (see file header comment for full methodology)
  • poc_malicious.circle β€” the crafted 184-byte malicious model (build_malicious_circle.py/simulate_baseloader.py from the draft, kept for provenance β€” note simulate_baseloader.py only hand-decoded the FlatBuffer bytes with struct; it did not exercise real Samsung/ONE or real FlatBuffers code. This repo replaces that simulation with a real, dynamically-verified reproduction.)
  • BaseLoader.h β€” the real vulnerable header, fetched at the last commit before its removal
  • gen/mio/circle/schema_generated.h β€” real, flatc-generated Circle schema accessors (reused from this campaign's already-confirmed compiler/luci finding)
  • asan_output.txt β€” captured AddressSanitizer trace
  • repro_bufidx_release / repro_bufidx_asan β€” compiled binaries for direct reproduction

Build & run

g++ -std=c++17 -O2 -DNDEBUG -I. -I<flatbuffers-include> -o repro_bufidx_release repro_bufidx.cpp
./repro_bufidx_release poc_malicious.circle   # segfaults (exit 139)

g++ -std=c++17 -O0 -g -DNDEBUG -fsanitize=address,undefined \
    -I. -I<flatbuffers-include> -o repro_bufidx_asan repro_bufidx.cpp
./repro_bufidx_asan poc_malicious.circle      # clean ASan SEGV report
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