# DF-5732 — DDB trap funnel defeats db_nofault on recoverable memory probes (trigger: `show registers` via db_print.c:68)

## What

`sys/ddb/db_print.c:68` — `db_show_regs()` ends with
`db_print_loc_and_inst(PC_REGS(DDB_REGS), DDB_REGS)` → `db_disasm()` dereferences
`ddb_regs.tf_rip`. `$rip` is a DDB-settable variable (`db_regs[]` entry
`{ "rip", &ddb_regs.tf_rip, NULL }`, sys/platform/pc64/x86_64/db_trace.c:107;
`db_set_cmd` writes it raw, sys/ddb/db_variables.c:120-129).

When `tf_rip` (or, for the same class, any address `x/i` probes) is
noncanonical, `db_disasm` → `db_get_value` → `db_read_bytes` faults *under the
`db_nofault` guard* (sys/platform/pc64/x86_64/db_interface.c:242). But
`trap()`'s DDB funnel (sys/platform/pc64/x86_64/trap.c:414-427) routes **every**
trap taken while `db_active` straight into `trap_fatal()` — full "Fatal trap"
crash banner + register/segment dump — before `kdb_trap()` finally takes the
`db_nofault` longjmp (db_interface.c:140-144) back to the `db>` prompt.

Side effects beyond the noise: the funnel's `++gd_trap_nesting_level`
(trap.c:422) is skipped by the longjmp and leaks; and the abandoned nested
dispatch corrupts session-resume state — the DF-5727 evidence pack captured
`panic: trap: critical section count mismatch! -1892583040/-1` on `cont` after
exactly this funnel (findings/poc/DF-5727/baseline-up.serial.log:547-549).

## Reproduce (decisive run — this file's trigger)

```
# 1. boot guest with socket serial console
findings/poc/DF-5732/serial_vm.sh up

# 2. enter DDB as root (blocks; run in background)
ssh -F dfbsd-qemu/config root@dfbsd 'sysctl debug.enter_debugger=ddb' &

# 3. at the db> prompt on the serial socket:
set $rip = 0xdead000000000000
show registers

# Expected (bug): full register dump, then from db_print.c:68's disasm of $rip:
#   -0x2153000000000000:
#   Fatal trap 9: general protection fault while in kernel mode
#   ... full trap_fatal register/segment dump ...
#   kernel: type 9 trap, code=0
#   db>            <- recovered via db_nofault longjmp (the "quiet" recovery
#                     the guard exists for was NOT quiet)
```

Automated: `python3 findings/poc/DF-5732/drive.py 'set $rip = 0xdead000000000000' 3 'show registers' 6`
(with `DF5732_SOCK=/tmp/opencode/df-5732-ser.sock`).

Sibling trigger, same funnel: `x/i 0xdead000000000000` (see session0-sweep.log).

## Files

- `run4-decisive-setrip-showregisters.log` — the decisive run (banner reproduced)
- `session0-sweep.log` — full modifier/format sweep + `x/i` noncanonical trigger
- `run1-control-valid-xi.log`, `run3-control-held-connection.log` (+ ssh poll) — controls
- `serial-full.log` — complete serial console capture
- `env.txt` — guest identity
- `fix.diff` — funnel fix (authored post-verification, never applied to sys/)
- `verdict.json` / `manifest.json` — machine verdict
