# DF-5792 exploit chain — build & run (exploit-development run, 2026-10-16)

## What this demonstrates

Starting from the verified DF-5792 primitive (closef() walks the
filedesc_to_leader chain under only `p->p_token` while fdfree()
unlinks+kfrees entries under `fdp->fd_spin`), this rig turns the
"unprivileged fatal trap" into a **user-steerable kernel write machine**,
entirely as uid 1001 on the stock kernel:

1. **Race + controlled reclaim** — walkers `open()/close()` a
   VMAYHAVELOCKS vnode (every close walks the family's fdtol chain);
   paced churners fork µs-lived RFMEM babies whose fdfree unlinks+kfrees
   their 40-byte fdtol entry (the exact 40-byte slab zone class); binder
   spinners continuously bind 40-byte AF_UNIX sonames
   (`sun_len`=40, `M_SONAME`, same zone) whose bytes 8..39 are a forged
   `struct filedesc_to_leader` (`fdl_leader` = user page with
   `byte[0x58]=1`, `fdl_next` = user SPIN page). A walker that chases
   into a just-freed entry which a marker reclaimed executes the
   attacker's fields: the ACT branch runs
   (`addl $1,(chunk+4)`, `VOP_ADVLOCK`, `subl $1,(chunk+4)`) and the
   chase `fdtol = *(chunk+0x20)` lands on the attacker's SPIN page —
   the walker parks forever inside `closef()` on a user-controlled
   self-loop (no SMAP on this guest).

2. **Steering + gated kernel write** — flipping `SPIN+0x20` from
   userspace aims the parked kernel walk at ANY address A. Visiting A:
   gate `byte at *(A+0x10)+0x58 != 0`; `++/-- *(int*)(A+4)` (net 0);
   **if `*(int*)(A+4)==0 && *(int*)(A+8)!=0` then `*(int*)(A+8) = 0`
   and `wakeup(A)`**; chase `*(A+0x20)`.
   Victim sonames (2-char path => bytes 4..7 == 0; `+8 = 0x41414141`;
   leader = FLAG1 page; next = SPIN2 re-park) prove the write: their
   `+8..+11` dword reads back 0x00000000 via the pcblist sysctl
   (bcopy of the soname) after a single steering flip.

3. **Repeatable + race-free re-steer** — after the storm is stopped the
   parked walker remains under user-page control; a second steering
   flip performs a second verified zero-write with zero kernel race
   activity (see run_machine_success.log, `[sess2]`).

Readback channel: `net.local.dgram.pcblist` (DF-5816) exports each
bound soname verbatim (`bcopy(unp->un_addr, &xu.xu_addr, sun_len)`),
so the zeroed dword is observable from unprivileged userspace.

## Build / run

```sh
cc -O2 -o exp5792 exp5792.c
./exp5792 [seconds=120]        # as uid 1001 on the stock kernel
```

Expected decisive output (see run_machine_success.log, full untrimmed):

```
*** walker stall detected; steer-verify ***
[verify 0] victim 0xfffff8004f145260 +8..+11 = 00000000 *** KERNEL WRITE VERIFIED ***
*** SUCCESS: parked closef() walk steered to victim; kernel zeroed 4 bytes at a chosen kernel address ***
[sess2] steering SPIN2 -> victim b 0xfffff8004f145288; pre +8..+11 = 41414141
[sess2] post +8..+11 = 00000000 *** SECOND KERNEL WRITE VERIFIED (race-free steer) ***
uid=1001 euid=1001; system alive; one walker parked in kernel spin at our user page
```

## Run-to-run behavior (honest)

The storm necessarily exercises the original racy interleavings, so a
given attempt can end in the ORIGINAL bug's fatal trap
(`closef+0x80: movq 0x10(%rbx),%rax` — the fork's M_ZERO recycle beats
the marker) or a hard freeze (chain corruption from unsynchronized
insert/unlink; observed ~40-60% loss per attempt across the session).
The machine result above was reproduced cleanly (full stream captured);
re-run on a fresh boot (`dfbsd-qemu/vm.sh reset with-src`) if an
attempt dies. The parked walker intentionally never returns from
close(): it is the engine; each success burns one CPU until reboot.

## Files

- `exp5792.c`          — the full exploit (park/steer/write machine)
- `run_machine_success.log` — full untrimmed decisive run (2 verified writes)
- `exp_trap_excerpt.txt` — one fatal-trap loss (original bug signature)
- `fix_ab/`            — A/B against the validated fix kernel
