# Circle External Buffer Offset/Size OOB Read Candidate Date: 2026-06-26 Target: Huntr model format `circle` ($1,500 lane) Source snapshot: - Repo: `research/triage/audits/circle-2026-06-26/ONE` - Commit: `de7f4736dc4c4f5e47f72a4022a9aa9ac6d1ad1a` - Last commit: `de7f4736 [exo] Fix exception throw for unknown dialect (#16483)` ## Verdict Submission candidate. I found a verifier-clean Circle file that causes an ASan heap-buffer-overflow in Samsung ONE's `circledump` path. The bug is an external-buffer bounds check gap: `mio_circle::Reader::buffer_info()` checks only `offset` with `std::vector::at()`, while attacker-controlled `size` is returned to callers without validating `offset + size <= raw_file_size`. The strongest demonstrated sink is now the real `circledump::dump_buffer()` code path, compiled directly with the current generated Circle schema and ASan. A production runtime loader impact would still strengthen severity, but this is no longer just a Reader harness. ## Bug Shape Circle's schema permits buffers whose tensor data lives outside the FlatBuffer region: - [circle_schema.fbs](/home/bradd/.openclaw/workspace/research/triage/audits/circle-2026-06-26/ONE/runtime/libs/circle-schema/circle_schema.fbs:1730) - Fields: `offset: ulong`, `size: ulong` - Comment: offset is relative to the beginning of the file and valid if greater than `1`. The vulnerable reader path: - [Reader.cpp](/home/bradd/.openclaw/workspace/research/triage/audits/circle-2026-06-26/ONE/compiler/mio-circle/src/Reader.cpp:101) - `buffer_info()` sets `buff_data = &_rawdata->at(buffer_offset)` at line 125. - It returns `buffer->size()` at line 127. - It does not validate that the returned byte span is inside `_rawdata`. The known caller/sink: - [Dump.cpp](/home/bradd/.openclaw/workspace/research/triage/audits/circle-2026-06-26/ONE/compiler/circledump/src/Dump.cpp:396) - `circledump` calls `reader.buffer_info(i, &buff_data, ext_offset)` and then `dump_buffer(os, buff_data, size, 16)`. - `dump_buffer()` reads `buffer[i]` for up to 16 bytes. ## Artifacts - PoC model: [external_offset_oob.circle](/home/bradd/.openclaw/workspace/research/triage/audits/circle-2026-06-26/poc/external_offset_oob.circle) - SHA256: `20962ae3e01d2489f1ba6766f4d804414e5e5cb490589a23aa986f97abe0abd5` - Size: 232 bytes - External buffer: `offset=231`, `size=4096` - Generator: [make_circle_external_oob.cpp](/home/bradd/.openclaw/workspace/research/triage/audits/circle-2026-06-26/poc/make_circle_external_oob.cpp:1) - Direct upstream Reader probe: [circle_reader_external_oob_probe.cpp](/home/bradd/.openclaw/workspace/research/triage/audits/circle-2026-06-26/poc/circle_reader_external_oob_probe.cpp:1) - ASan stderr: [asan-reader-oob.stderr.txt](/home/bradd/.openclaw/workspace/research/triage/audits/circle-2026-06-26/poc/asan-reader-oob.stderr.txt:1) - Direct `circledump` core driver: [circledump_direct_driver.cpp](/home/bradd/.openclaw/workspace/research/triage/audits/circle-2026-06-26/poc/circledump_direct_driver.cpp:1) - `circledump` ASan stderr: [asan-circledump-direct.stderr.txt](/home/bradd/.openclaw/workspace/research/triage/audits/circle-2026-06-26/poc/asan-circledump-direct.stderr.txt:1) - MFV scan output: `/tmp/mfv-scan-circle-external-oob` ## Reproduction Use FlatBuffers 23.5.26 headers because the generated Circle header asserts that version. I used `/tmp/flatbuffers-23.5.26/include`. ```bash cd /home/bradd/.openclaw/workspace clang++ -std=c++17 -O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer \ -I/tmp/flatbuffers-23.5.26/include \ -Iresearch/triage/audits/circle-2026-06-26/ONE/onert-micro/externals/gen/circle-generated \ research/triage/audits/circle-2026-06-26/poc/make_circle_external_oob.cpp \ -o /tmp/make_circle_external_oob /tmp/make_circle_external_oob \ research/triage/audits/circle-2026-06-26/poc/external_offset_oob.circle rm -rf /tmp/circle-include mkdir -p /tmp/circle-include/mio ln -s /home/bradd/.openclaw/workspace/research/triage/audits/circle-2026-06-26/ONE/onert-micro/externals/gen/circle-generated/circle \ /tmp/circle-include/mio/circle clang++ -std=c++17 -O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer \ -I/tmp/flatbuffers-23.5.26/include \ -I/tmp/circle-include \ -Iresearch/triage/audits/circle-2026-06-26/ONE/compiler/mio-circle/include \ research/triage/audits/circle-2026-06-26/poc/circle_reader_external_oob_probe.cpp \ research/triage/audits/circle-2026-06-26/ONE/compiler/mio-circle/src/Reader.cpp \ research/triage/audits/circle-2026-06-26/ONE/compiler/mio-circle/src/Helper.cpp \ -o /tmp/circle_reader_external_oob_probe ASAN_OPTIONS=abort_on_error=0:symbolize=1 \ /tmp/circle_reader_external_oob_probe \ research/triage/audits/circle-2026-06-26/poc/external_offset_oob.circle ``` Observed: ```text ERROR: AddressSanitizer: heap-buffer-overflow READ of size 1 circle_reader_external_oob_probe.cpp:36 0 bytes after 232-byte region ``` Stronger `circledump` core reproduction: ```bash cd /home/bradd/.openclaw/workspace # Build FlatBuffers 23.5.26 flatc/libflatbuffers, then regenerate the current Circle schema. cmake -S /tmp/flatbuffers-23.5.26 -B /tmp/flatbuffers-23.5.26-build \ -G Ninja -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DCMAKE_BUILD_TYPE=Release cmake --build /tmp/flatbuffers-23.5.26-build --target flatc flatbuffers -j2 rm -rf /tmp/circle-generated-current /tmp/circle-include-current mkdir -p /tmp/circle-generated-current /tmp/circle-include-current/mio/circle /tmp/circle-generated-current/circle /tmp/flatbuffers-23.5.26-build/flatc --cpp -o /tmp/circle-generated-current \ research/triage/audits/circle-2026-06-26/ONE/runtime/libs/circle-schema/circle_schema.fbs ln -sf /tmp/circle-generated-current/circle_schema_generated.h \ /tmp/circle-include-current/mio/circle/schema_generated.h ln -sf /tmp/circle-generated-current/circle_schema_generated.h \ /tmp/circle-generated-current/circle/schema_generated.h clang++ -std=c++17 -O1 -g -fsanitize=address,undefined -fno-omit-frame-pointer \ -I/tmp/flatbuffers-23.5.26/include \ -I/tmp/circle-include-current \ -Iresearch/triage/audits/circle-2026-06-26/ONE/compiler/mio-circle/include \ -Iresearch/triage/audits/circle-2026-06-26/ONE/compiler/circledump/include \ -Iresearch/triage/audits/circle-2026-06-26/ONE/compiler/circledump/src \ research/triage/audits/circle-2026-06-26/poc/circledump_direct_driver.cpp \ research/triage/audits/circle-2026-06-26/ONE/compiler/circledump/src/Dump.cpp \ research/triage/audits/circle-2026-06-26/ONE/compiler/circledump/src/MetadataPrinter.cpp \ research/triage/audits/circle-2026-06-26/ONE/compiler/circledump/src/OpPrinter.cpp \ research/triage/audits/circle-2026-06-26/ONE/compiler/mio-circle/src/Reader.cpp \ research/triage/audits/circle-2026-06-26/ONE/compiler/mio-circle/src/Helper.cpp \ /tmp/flatbuffers-23.5.26-build/libflatbuffers.a \ -o /tmp/circledump_direct_driver_current ASAN_OPTIONS=abort_on_error=0:symbolize=1 \ /tmp/circledump_direct_driver_current \ research/triage/audits/circle-2026-06-26/poc/external_offset_oob.circle ``` Observed: ```text ERROR: AddressSanitizer: heap-buffer-overflow READ of size 1 circledump::dump_buffer(...) Dump.cpp:48 circledump::dump_model(...) Dump.cpp:404 operator<<(...) Dump.cpp:479 circledump_direct_driver.cpp:41 0 bytes after 232-byte region ``` ## Scanner Results `mfv-scan` completed successfully: ```bash tools/model-format-workbench/mfv-scan \ research/triage/audits/circle-2026-06-26/poc/external_offset_oob.circle \ --out /tmp/mfv-scan-circle-external-oob \ --timeout 180 ``` Relevant results: - ModelAudit: no security issues detected. - ModelScan: no issues; scanned zero model files because Circle is unsupported. - PickleScan: not pickle; no dangerous globals. - Magika/file: generic unknown/data detection. This is useful report framing: generic model scanners miss the malformed Circle external-buffer span, while the format-aware reader accepts the file and returns an unsafe pointer/size pair. ## Duplicate Sweep Local: - No prior local Circle submission found in `research/triage`. - Existing local offset/size work is OpenVINO/GGUF/other formats, not Circle. GitHub: - `gh search issues '"external buffer" "offset" "circle"' --repo Samsung/ONE --limit 20`: no results. - `gh search issues '"buffer_info" "offset"' --repo Samsung/ONE --limit 20`: no results. - `gh search issues '"mio_circle" "buffer_info"' --repo Samsung/ONE --limit 20`: no results. - `gh search issues '"Circle" "heap-buffer-overflow"' --repo Samsung/ONE --limit 20`: no results. Web: - Searches for exact `mio_circle::Reader` / `buffer_info` / `Circle external buffer offset size` did not surface a matching public report. - Search noise included unrelated `pybind11 buffer_info` and Samsung non-ONE vulnerabilities. Duplicate risk: low for exact bug class in Circle external buffers. ## Next Steps 1. Search ONE runtime paths for production consumers of external-buffer `offset`/`size`, especially tensor constant loaders. 2. If only developer tooling is affected, submit carefully as malformed model file causing heap OOB read in shipped Circle inspection tooling. 3. If a runtime loader consumes the same unchecked span, upgrade the report impact.