# DF-0137 — unlocked TAILQ traversal in varsymset_init() during fork

| | |
|---|---|
| Verdict | **REPRODUCED** |
| Impact | kernel panic / local DoS (refcount-corruption race) |
| File | `sys/kern/kern_varsym.c:510, 519-531` (caller `sys/kern/kern_fork.c:646`) |

## Build
```
cc -O2 -o race race.c -lpthread
```

## Run (unprivileged)
```
./race
```

## Expected (bug present)
Within ~seconds, the kernel panics and the guest drops to DDB:
```
panic: assertion "sym->vs_refs > 0" failed in varsymdrop at /usr/src/sys/kern/kern_varsym.c:492
varsymdrop() -> varsymset_clean() -> exit1() -> sys_exit()
```
The ssh session dies (`Connection closed`). The panic is captured in
`dfbsd-qemu/boot.log`.

## Expected (fixed)
The process runs to completion and prints `RACE_DONE: no panic`.

## Mechanism (short)
`varsymset_init()` copies a varsymset via unlocked `TAILQ_FOREACH` and bumps a
shared refcount non-atomically (`varsymdup`, `:510`). `fork1` calls it on the
parent's `p_varsymset`; a concurrent LWP (pthreads share `struct proc`) doing
`varsym_set(VARSYM_PROC)` frees entries / atomically drops refs under `vx_lock`.
The lost non-atomic increment underflows the refcount → `varsymdrop`'s
`KKASSERT` → panic.

See `VERDICT.md` for the full analysis and `fix.diff` for the patch.
