diff options
Diffstat (limited to 'debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md')
| -rw-r--r-- | debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md b/debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md new file mode 100644 index 0000000..26f1ffb --- /dev/null +++ b/debug/risc-v-gsp-rm-vm/docs/12-INJECTION-SDK.md @@ -0,0 +1,149 @@ +# 12 — Injection SDK specification (v1, demo ABI) + +> **# TOOL IN DEVELOPMENT - NOT READY YET!** See 00 for status and +> [`GREEN-EYE-ROADMAP.md`](../GREEN-EYE-ROADMAP.md) §H1/H3 for the program. + +## 1. Goals and non-goals + +**Goals** +* a repeatable, scriptable way to compile a piece of RV64 code, load it into a + live firmware target, register it, invoke it, and observe it with the same + hooks/sessions/analysis as firmware; +* a clear ABI so services can be written once and run under the demo uproc + today and under a simulated RM core later; +* an evidence trail: every load, registration and invocation is recorded. + +**Non-goals (v1)** +* shipping any injected code (development-only); +* hot-patching signed firmware on hardware; +* bypassing security boundaries (the simulator is a study environment). + +## 2. Blob contract + +* **Format:** ELF64 `EM_RISCV`, `RV64IMAC`, soft-float ABI, one or more + `PT_LOAD` segments. +* **Position independence:** built PIC (`-fPIC`, `-mcmodel=medany`, + `-mno-relax`, `-fno-asynchronous-unwind-tables`), no dynamic relocations. + The loader verifies by writing segments at the chosen load address; the SDK + `make relocs` target must report none. +* **Self-sufficiency:** no libc, no global data containing addresses. + Caller-provided addresses (future RM-core tables) arrive as arguments. +* **Entry symbol:** `ge_demo_service_dispatch` by default (override with + `--entry`/`entry_symbol=`). +* **Optional metadata:** a `ge_service_t` block can be exported for future + loaders (`magic 0x47455356`, version 1, name, dispatch). + +## 3. ABI v1 + +```c +typedef ge_u64 (*ge_service_fn)(ge_u64 cmd, ge_u64 a0, ge_u64 a1); +``` + +* `a0`, `a1`, `a2` registers carry `(cmd, a0, a1)` on entry. +* The return value is `a0`. +* The service may use `a3..a7`, `t0..t6`, `s0..s11` and the stack; the + injector supplies a private stack below the scratch page. +* Traps do not return: the call loop times out, records the stop, restores + registers and raises `RspTimeout`. +* No calling convention for callbacks in v1; the loader registers a **single + dispatch entry** per slot. + +## 4. Demo registration model + +* The firmware exposes eight handler slots (`gsp_ctrl.handlers[0..7]`). +* Mailbox commands **16..23** select slot `cmd-16`. +* On dispatch the firmware calls + `handlers[slot](arg0, arg1, arg2)` — i.e. `cmd = arg0`, parameters + `arg1`, `arg2`. +* Slots 0..5 are used by the built-in demo RPCs; **slot 6** is the SDK + default (`--slot`). + +### Control-block fields used (demo) + +| Field | Offset | Role | +|---|---|---| +| `mailbox` | `+0x20` | command (`16 + slot` selects an injected service) | +| `arg0` | `+0x28` | service command | +| `arg1` | `+0x30` | parameter 0 | +| `arg2` | `+0x38` | parameter 1 | +| `result` | `+0x40` | service return value | +| `handlers` | `+0x150` | eight entry slots | + +Offsets are demo-firmware-specific; use `greeneye/inject.py` constants and the +schema at `firmware/uproc_demo/gsp_ctrl.schema.json` rather than hardcoding. + +## 5. Lifecycle + +``` +compile (PIC) ──► verify relocations ──► load PT_LOADs at load_addr + │ │ + │ ├─► register entry in slot + │ └─► record "service_injected" + ▼ +invoke_remote (direct call) invoke_via_firmware (mailbox dispatch) + └──────────────► both record call_enter/call_return events +``` + +* **Load address:** default `ram_base + 0x01000000`, auto-shrunk to fit if + the image is larger; explicit with `--load-addr`. +* **Cleanup:** v1 does not unregister automatically. A service is removed by + zeroing its slot and (optionally) clearing the blob; sessions record the + injection so runs are reproducible from a known state. +* **Multiple services:** one per slot; multi-entry services are one dispatch + with subcommands. + +## 6. Observability contract + +The injector records, in the session directory: +* `service_injected` — path, name, load address, entry address, slot, size; +* `mem_write` events for every segment written; +* `call_enter` / `call_return` — address, args, return value; +* hook/watch events from user instrumentation inside the service; +* `qemu.log`-style blobs are not applicable (no probe here), but the TCG + trace can be enabled for full coverage. + +Comparison of injected-service runs uses the standard `greeneye compare` +profiles, so a change in a service's behaviour is visible like any firmware +change. + +## 7. Building (reference) + +```makefile +CC := clang +LLD ?= /usr/lib/llvm-18/bin/ld.lld +CFLAGS := --target=riscv64-unknown-elf -march=rv64imac -mabi=lp64 \ + -mcmodel=medany -mno-relax -fPIC -ffreestanding -nostdlib \ + -fno-builtin -fno-stack-protector -fno-asynchronous-unwind-tables -O2 +$(LLD) -m elf64lriscv --no-relax -e ge_demo_service_dispatch -o service.elf service.o +``` + +The tracked SDK (`sdk/`) is the executable reference. + +## 8. Versioning and compatibility + +* ABI version 1 is the demo contract described here. +* Future ABI v2 (RM-core shim) will pass a call table and a service context + instead of relying on firmware slots; blobs declare their ABI via the + optional metadata block so loaders can refuse mismatches. +* Breaking ABI changes require a compatibility shim plus a note in the + session metadata and this document. + +## 9. Security and safety + +* Injected code runs with the simulator's full privileges; the bridge and + injector are local-only tools. +* Never inject into a guest or a shipped environment; never use injection to + bypass a hardware protection. +* Fuzzing/mutation harnesses (roadmap H4.3) must run against the simulator + or re-hosted code, with sessions attached as evidence. +* Treat every injected service as untrusted code for the purposes of + watching: it may corrupt firmware state, so always record and restart clean + after crashes. + +## 10. Roadmap hooks + +* **H1.3** — RM service registration and RM-core call interception. +* **H3** — native-simulator loader with snapshots and branch exploration. +* **H4** — differential testing of injected services across firmware + versions and capability inference from their access patterns. +* **H5** — services spanning GSP and adjacent microcontrollers. |
