# DF-0793 — async TRIM block-free UAF (verification)

**Verdict:** NOT REPRODUCED as filed (the async-TRIM code path is dead code on
current master). Root cause discovered: `ffs_blkfree`'s `MNT_TRIM` gate reads
`ip->i_devvp->v_mount` (devfs mount, never has `MNT_TRIM`) instead of
`ip->i_vnode->v_mount` (the ufs mount). A latent UAF exists and is un-masked by
fixing that pointer; `fix.diff` fixes both the pointer and the missing drain.
See **VERDICT.md** for the full analysis.

## Files

| file | what |
|------|------|
| `VERDICT.md`        | full narrative + evidence |
| `asyncd.c`          | KLD: slow async-TRIM disk (FREEBLKS deferred 2s) |
| `Makefile`          | builds `asyncd.ko` against `/usr/src` |
| `trim_uaf.c`        | syscall harness: mount ufs+trim, fill/delete, umount |
| `trim_race.c`       | aggressive multi-file race harness |
| `fix.diff`          | validated two-part fix (mount pointer + umount drain) |
| `build.sh`/`run.sh` | exact repro commands |
| `fix_build.log`     | full output of the single-fix kernel build (rc=0) |
| `run.log`           | the three-kernel comparison (baseline / expose / full-fix) |
| `env.txt`           | guest environment |
| `manifest.json`     | machine-readable catalog |

## Reproduce (on the DragonFly guest)

The async-TRIM path needs (a) a kernel that consults the right mount pointer
(unpatched master does NOT — that is the bug) and (b) an async device (QEMU's
`vn`/`vbd` complete FREEBLKS synchronously, so they cannot reproduce the
in-flight window). `asyncd.c` supplies (b).

```
# as root on the guest (mount needs privilege; vfs.usermount=0):
./build.sh                       # builds asyncd.ko + trim_uaf
kldload ./asyncd.ko
newfs /dev/asyncd0s0
# trim_uaf mounts /dev/vn0 by default; point it at asyncd0s0:
cc -o trim_uaf_async trim_uaf.c -DDEV=\"/dev/asyncd0s0\"   # or sed
./trim_uaf_async 5
dmesg | grep -c 'asyncd: FREEBLKS'    # unpatched -> 0 (TRIM dead = the bug)
```

## Fix validation

```
ssh dfbsd "cat > /root/fix.diff" < fix.diff
ssh dfbsd "cd /usr/src && patch -p1 < /root/fix.diff"
ssh dfbsd "cd /usr/src && make -j6 nativekernel KERNCONF=X86_64_GENERIC"
# install + reboot, then re-run the harness -> FREEBLKS now flows, no panic
```
