Skip to content

docs: binary safety checks design — ARM + RISC-V opt-in safety profiles#110

Merged
avrabe merged 1 commit into
mainfrom
docs/binary-safety-design
May 14, 2026
Merged

docs: binary safety checks design — ARM + RISC-V opt-in safety profiles#110
avrabe merged 1 commit into
mainfrom
docs/binary-safety-design

Conversation

@avrabe

@avrabe avrabe commented May 14, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds docs/binary-safety-design.md (842 lines) covering eight categories of opt-in runtime safety guards for synth's ARM Cortex-M and RISC-V RV32 targets.
  • Specifies a unified --safety <profile> CLI surface (none / fuzz / rtos / asil-d / paranoid) plus fine-grained --safety-bounds, --safety-stack, --safety-cfi-fwd, --safety-cfi-bwd, --safety-prologue, --safety-poison, --safety-cm-types, --safety-spectre-v1 overrides.
  • For each check, documents the threat model, the hardware-assisted fast path (MPU/PMP, MSPLIM/PSPLIM, BTI, PAC, Zicfilp/Zicfiss, index masking), the software fallback with cycle costs, the per-target applicability matrix (M3..M85, RV32I..RV32GC), the synth code locations that need to change, and the Rocq verification impact.
  • Phase 5 roadmap proposes parameterising coq/Synth/Compilation.v by SafetyProfile so existing T1/T2 lemmas can be re-proven per profile.

Checks covered

  1. Memory bounds (MPU / PMP / software / mask) — generalises the existing --bounds-check flag.
  2. Integer divide-by-zero — existing trap is documented and the RV32 gap is called out.
  3. Signed-division overflow (INT_MIN / -1) — existing trap is documented and the i64/RV32 gap is called out.
  4. Stack overflow (ARMv8-M MSPLIM/PSPLIM hardware path, software canary fallback).
  5. CFI forward-edge (BTI on M55/M85, Zicfilp on RV32, software table fallback).
  6. CFI backward-edge (PAC on M85, Zicfiss on RV32, software shadow stack fallback).
  7. AAPCS prologue/epilogue invariants (compiler-bug canary; motivated by PR fix(opt): systematic AAPCS-clobber audit — sweep all hardcoded R0..R3 usages #108).
  8. Linear-memory poisoning (zero-on-boot, MSan-style shadow as fuzz-only path C).
  9. Component-model type confusion (safe_lift_* family in synth-abi).

Test plan

  • No code changes — design document only. cargo build / cargo test unaffected.
  • Cross-references docs/spectre-policy.md (existing) and docs/design/MEMORY_ARCHITECTURE.md (existing) — links verified to existing files.
  • Cited synth source locations (line numbers in instruction_selector.rs, mpu.rs, pmp.rs) verified against current HEAD on main.
  • References to ARM ARM, RISC-V manual, CompCert, Cranelift, V8, Crocus, Blade cited with retrievable URLs / DOIs.
  • Reviewer pass for: completeness of the per-target matrix, accuracy of cycle-cost claims, and Rocq proof impact in §5.

Open questions for reviewers

The document lists 8 open questions in §6, including:

  • Should the trap handler be unified (one callback) or demuxed by check class?
  • On RV32, should s10 be reserved for a stack-limit pointer when --safety-bounds=soft?
  • Profile-vs-target precedence: warn + fall back, or refuse to compile, when a profile asks for hardware that doesn't exist on the target?
  • PAC key strategy on Cortex-M85: per-boot from TRNG (non-reproducible) vs per-firmware (extractable)?

🤖 Generated with Claude Code

Adds docs/binary-safety-design.md covering eight runtime-guard categories
(memory bounds, divide-by-zero, signed-division overflow, stack overflow,
CFI forward and backward edges, AAPCS prologue/epilogue invariants,
linear-memory poisoning, and component-model type confusion) with a
hardware-fast-path / software-fallback decision tree per check and a
per-target support matrix for Cortex-M3..M85 and RV32I..RV32GC. Specifies
a unified --safety profile CLI surface (none / fuzz / rtos / asil-d /
paranoid) plus fine-grained --safety-X overrides, cross-references
docs/spectre-policy.md for transient-execution coverage, and lays out a
5-phase roadmap including Rocq proof reparameterisation in Phase 5.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@avrabe avrabe merged commit ca6bb44 into main May 14, 2026
7 checks passed
@avrabe avrabe deleted the docs/binary-safety-design branch May 14, 2026 05:32
@codecov

codecov Bot commented May 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

avrabe added a commit that referenced this pull request May 21, 2026
…ds + RV32 div trap + safety-manifest.json (#115)

Implements Phase 1 of docs/binary-safety-design.md (#110).

* CLI: new `--safety-bounds <mpu|software|mask|none>` flag. Keeps
  `--bounds-check` as a deprecated alias mapping to
  `--safety-bounds software`; emits a one-line deprecation notice.
* CompileConfig grows a `safety_bounds: SafetyBounds` field; the ARM
  and RISC-V backends both read it.
* Plumb through `BoundsCheckConfig` (now `SafetyBounds` at the public
  boundary). Existing `None` / `Software` semantics preserved on ARM.
* RV32 selector: ported the software bounds-check sequence
  (`bgeu addr, mem_size, trap_label; ...; trap_label: ebreak`) to
  every i32 load/store and sub-word variant.
* RV32 selector: emit `bne rs2, x0, ok; ebreak; ok: div` (and `divu`,
  `rem`, `remu`) trap-on-zero guards. Mirrors the existing ARM pattern
  (instruction_selector.rs:3895).
* `safety-manifest.json` written alongside the output ELF whenever any
  safety flag is enabled. Schema: synth_version, target_triple,
  safety_bounds, safety_div_zero, safety_div_overflow,
  linear_memory_bytes.

## Hand-tested

* `synth compile examples/wat/simple_add.wat --safety-bounds mpu
  -o /tmp/sa.elf --cortex-m` succeeds; `/tmp/sa.safety-manifest.json`
  contains the expected fields.
* `synth compile examples/wat/simple_add.wat --bounds-check
  -o /tmp/sa.elf --cortex-m` prints the deprecation notice and still
  produces a working ELF.
* `synth compile /tmp/rv_div.wat --backend riscv --target riscv32imac
  --safety-bounds software --all-exports -o /tmp/rv_div.elf` succeeds;
  RV32 ELF contains the div-by-zero trap sequence; manifest emitted.

## Out of scope (later phases per docs/binary-safety-design.md §6)

* Phase 2: stack overflow (MSPLIM/PSPLIM/canary), CFI BTI/PAC
* Phase 3: linear-memory poisoning
* Phase 4: component-model type confusion
* Phase 5: parameterise Compilation.v by SafetyProfile in Rocq

## Verification

* `cargo test --workspace --exclude synth-verify` — all pass (z3-sys
  download blocked in this environment; synth-verify excluded
  accordingly, CI will exercise it).
* `cargo clippy --workspace --exclude synth-verify --all-targets
  -- -D warnings` — clean.
* `cargo fmt --check` — clean.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant