Samsung ONE Circle ExpandBroadcastConstPass OOB Write PoC

This repository contains a benign model-format vulnerability proof for Samsung ONE Circle. The PoC does not execute code, persist state, access credentials, or make network calls; it only demonstrates a model-carried native crash in a local converter/optimizer path.

Summary

add_overflow_oob_min.circle is a 636-byte Circle FlatBuffer with an Add graph whose model-controlled shape is [1431655766, 3] and constant shape is [1, 3].

In Samsung ONE 1.30.1, circle2circle --expand_broadcast_const reaches luci::ExpandBroadcastConstPass. The pass multiplies output dimensions into a uint32_t allocation size, so 1431655766 * 3 wraps to 2. It then uses the original dimensions as loop/index bounds, writing past the two-float allocation and crashing with SIGSEGV.

The default circle2circle path accepts and rewrites the artifact without crashing. The companion add_overflow_oob_min.tflite is the same FlatBuffer with TFL3 file identifier; one-import-tflite preserves the malformed shape, and the imported Circle artifact crashes the same optimizer pass.

Affected Format

  • Format: Samsung ONE Circle FlatBuffer (CIR0)
  • Tested target: Samsung ONE onecc 1.30.1
  • Trigger path: circle2circle --expand_broadcast_const
  • Supporting import path: one-import-tflite followed by circle2circle --expand_broadcast_const

GitHub marked ONE 1.30.1 as the latest release at local verification time on 2026-05-12. The current upstream master source also still contained the same unchecked uint32_t constant_size multiplication in compiler/luci/pass/src/ExpandBroadcastConstPass.cpp.

Security Impact

The artifact controls tensor dimensions that are used in native allocation and indexing logic. The optimizer pass allocates storage for two FLOAT32 elements after unsigned wraparound, then performs indexed FLOAT32 stores using the unwrapped model dimensions. Local GDB verification placed the crash inside libluci_pass.so during luci::ExpandBroadcastConstPass::run(loco::Graph*), faulting on an indexed float store.

This should be treated as native memory corruption in a model converter/optimizer pass. It is not claimed as arbitrary code execution.

Artifacts

  • add_overflow_oob_min.circle
    • SHA256: 16b35129a92c8250ef79bcbd5b834749af63d707917c7970d1da8a5720849a8f
    • Size: 636 bytes
  • add_overflow_oob_min.tflite
    • SHA256: 76a03afe7e6b4d664b73444911e57c54bb1c97b8e6f7f5e38c8f88cea461e147
    • Size: 636 bytes

Reproduction

Install or unpack Samsung ONE onecc 1.30.1, then run:

export ONE_ROOT=/path/to/onecc-1.30.1
export PATH="$ONE_ROOT/bin:$PATH"
export LD_LIBRARY_PATH="$ONE_ROOT/lib:${LD_LIBRARY_PATH:-}"

python3 verify_circle_expand_broadcast_oob.py --one-root "$ONE_ROOT"

Expected result:

  • circle2circle_default.returncode == 0
  • circle2circle_expand_broadcast_const.returncode == -11 or shell status 139
  • one_import_tflite.returncode == 0
  • imported_circle2circle_expand_broadcast_const.returncode == -11 or shell status 139

Manual minimal commands:

circle2circle add_overflow_oob_min.circle /tmp/default.circle
circle2circle --expand_broadcast_const add_overflow_oob_min.circle /tmp/expanded.circle

The first command should return 0; the second should terminate with SIGSEGV.

Artifact Construction

The Circle artifact was derived from a valid tiny Add graph. The PoC changes the graph input and output tensor shapes to [1431655766, 3], leaves the constant shape as [1, 3], and stores three FLOAT32 values in the constant buffer.

The TFLite companion is the same FlatBuffer with the file identifier changed from CIR0 to TFL3. This checks that the malformed shape can survive the supported TFLite import path before reaching Circle optimization.

Scanner Behavior

ModelScan 0.8.8 reported zero issues and skipped the .circle artifact as unsupported. This is supporting scanner/runtime mismatch evidence only; the primary impact is the native converter crash.

Local Verification Notes

Local verification on 2026-05-12 used Samsung ONE 1.30.1.

GDB confirmed the crash occurs inside libluci_pass.so during luci::ExpandBroadcastConstPass::run(loco::Graph*).

Known-issue checks found related Samsung ONE correctness fixes for ExpandBroadcastConstPass, but not this uint32_t constant_size wraparound leading to SIGSEGV. CVE-2026-41666 / PR #16481 is a separate runtime tensor memory-size calculation issue, not this converter-pass crash.

Limitation

This is a native memory-corruption crash in an optimizer/converter pass, not arbitrary code execution.

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