Skip to Content
Viewing release/v0.5.0-alpha.3 docs — not the stable branch. Changes vs main · Go to main

Threat Model

Relevant source files

The threat model is a living document whose line citations refer to commit f2e38bc (2026-07-03). It carries an audit erratum, and several of its gaps have since been addressed in code. This page summarizes it and marks where the code at this release has moved on.

Audit erratum (2026-07-11), as recorded in the source document: at the audited commit (C-01) user-pointer validation was numeric only, (C-06) JIT pages were RWX and recompiled per hook fire, and (H-02) the x86 clock treated HPET ticks as nanoseconds. At this release, user copies go through the page-walking kernel_usermem contract (Memory), and both shipped profiles set JIT_ALLOWED = false with a test asserting it stays false “until C-06 redesign”. H-02 is why legacy x86 QEMU timings are invalid (Current Results).

Assets

AssetLocationNotes
Kernel imagekernel/ (Limine on x86_64)Compromise is total
BPF verifierkernel_bpf/src/verifier/The load-bearing safety gate; zero unsafe
BPF interpreterkernel_bpf/src/execution/interpreter.rsMust match the verifier’s semantics
JITkernel_bpf/src/execution/jit_aarch64.rsNot enabled in any shipped profile (ADR-0004)
Attach pointsGPIO, PWM, IIO, timer, syscall, scheduler hooksPhysical actuation is the highest-consequence output
BPF mapskernel_bpf/src/maps/Shared state between programs and kernel
Signing trust storekernel_bpf/src/signing/ (Ed25519)One compiled-in production key
Persistent staterootfsNo integrity protection at rest
Control linkshrike_link UART to RP2040Fail-safe state machine on link loss

Adversaries

#AdversaryIn scopeVerdict
A1Malicious BPF author (program bytes fully attacker-chosen)Yes, primaryThe threat the verifier exists for
A2Compromised userspace (arbitrary syscalls)YesSyscall boundary validated; per-process BPF capabilities now gate commands
A3Remote network attackerPartiallyNo NIC driver exists; OTA is out-of-band (SD card / serial)
A4OTA man-in-the-middlePartiallyPrograms are Ed25519-authenticated; the kernel image itself is unsigned
A5Physical access (JTAG, SD swap, side channels)NoA robot in an attacker’s hands is the attacker’s robot
A6Supply chain (malicious dependency)Acknowledged, not defendedSmall no_std dependency tree; no vendoring or cargo vet gate
A7Speculative execution via BPFKnown gapNo Spectre mitigations (#89)

Trust boundaries

  • B1 userspace to kernel: every user pointer/length crosses the bounded UserMemory adapter.
  • B2 BPF load: authenticate, authorize, normalize, verify. Nothing executes unverified.
  • B3 BPF runtime: programs reach the kernel only through helpers whose signatures and argument bounds were checked at verify time.
  • B4 attach: attachment checks the hook context and passes utilization admission.
  • Bootloader: the Limine handoff is trusted and unverified; there is no secure or measured boot.

Mitigation map

AttackPrimary defense
A1 out-of-bounds accessStack bounds and ranged dereference checks for map-value, ctx and packet pointers; per-map value sizes and per-program-type ctx sizes
A1 unbounded executionVerifier recorded-state budget (8,192 states, 64 per pc) plus an interpreter hard instruction limit (100k embedded / 1M cloud)
A1 stack / call-depth abuseProfile stack bound; BPF-to-BPF inlining capped at MAX_CALL_DEPTH = 8 with an expansion size cap
A1 helper contract abusevalidate_helper_call with privilege tier and pointer-argument bounds; helper IDs unified with the runtime table
A1 arithmetic corruptionDivision/modulo-by-zero rejection, uninitialized-register rejection, tnum plus signed/unsigned range tracking
A1 real-time starvationStatic WCET budget at verify time; utilization admission at attach (see Verifier Assurance)
A2 syscall boundarykernel/src/syscall/validation.rs; attach-time GPIO pin and PWM chip/channel validation
A4 program authenticityEd25519 trusted-signer, hash and signature verification; raw instruction loads rejected when enforcement is on
Execution engine integrityInterpreter only in shipped profiles

Gaps

IDGap (as filed)Status at this release
G1Spectre-class speculation unmitigated (#89)Open
G2No privilege check at attach (#176)The normative trust policy now gates trace/scheduler/device attach with per-process BpfCapabilities; init lacks device attach and actuation rights
G3JIT output not independently checked (#177)Moot for shipped profiles (no JIT); remains a precondition in ADR-0004
G4Signature enforcement default-off, no key provisioning (#20)Production builds are signed-only with a build-time key; unsigned needs bpf-unsigned-development. Key provisioning beyond the build-time key is not described
G5No secure / measured boot (#178)Open
G6Dependency supply chain unaudited (#179)Open
G7Kernel image and persistent state unsigned at restOpen

TCB and the seL4 comparison

Measured with wc -l over *.rs (excluding tests/) at f2e38bc:

ComponentLoC
Kernel core (kernel/src)20,756
BPF subsystem (kernel_bpf)26,258
of which verifier7,649 (zero unsafe)
All kernel crates36,564
axiomos TCB (order of magnitude)about 57k LoC Rust

seL4, by contrast, has about 8,700 LoC of C plus about 600 asm with machine-checked functional correctness down to the binary. The repository’s own reading: the axiomos TCB is about six times larger, and it is trusted, not proven. The differentiator is not assurance depth but that untrusted, hot-swappable robotics logic is a first-class kernel object with static safety and timing admission. Formal work is limited to a Lean 4 proof-of-concept for the tnum domain (formal/, #91); see Testing & Verification.

Last updated on