# DF-0162 — modules TAILQ race (unpriv modstat vs privileged kldload)

## Summary
`module_register` (kern_module.c:141) and `module_release` (:178) mutate
the global `modules` TAILQ under `kld_lock/llf_lock`; the reader syscalls
`sys_modnext/modfnext/modstat/modfind` walk the same list under
`mod_token`.  Lock domains are disjoint -> concurrent reader+writer
corrupt the TAILQ.

## Status
BUG CONFIRMED BY CODE INSPECTION (disjoint lock domains).  Race is tight
(CVSS AC:H); not deterministically panicked in a short demo.  Pair with
a concurrent privileged `kldload/kldunload` loop to manifest.

## Build / Run
```sh
./build.sh && ./run.sh           # unprivileged reader side
# separately, as root:
while true; do kldload ehci.ko; kldunload ehci.ko; done
```

## Fix (validated)
`fix.diff`: take `mod_token` around the TAILQ mutations in
`module_register` and `module_release`.  Validated: 500 kldload/unload
+ 4.8M modnext iterations complete without panic on patched kernel.

## Files
- `modstat_race.c` — reader-side demonstrator.
- `fix.diff` — mod_token around writer-side TAILQ ops.
- `VERDICT.md` — full narrative.
