# DF-0014 — PoC

`setpgid_panic.c` — race-trigger PoC for the `enterpgrp()` `lwkt_reltoken`-on-
unheld-token claim.

## Verdict: FALSE POSITIVE (error path unreachable)

The `lwkt_reltoken(&prg->proc_token)` at `kern_proc.c:764` IS erroneous code,
but the error branch at `:763` is **dead code**: `sys_setpgid`'s `pfind()` does
`PHOLD(targp)`, which prevents the target from becoming `SZOMB` (via
`PSTALL` in `proc_move_allproc_zombie`) until after `enterpgrp()` returns.
See `VERDICT.md` for the full trace.

## The (claimed) bug

`enterpgrp()` new-pgrp branch (`kern_proc.c:763-768`) calls
`lwkt_reltoken(&prg->proc_token)` at `:764` without the token held.

## Why it doesn't reproduce

- `pfind()` at `kern_prot.c:372` does `PHOLD(targp)` → `p->p_lock ≥ 1`.
- `proc_move_allproc_zombie()` calls `PSTALL(p, "reap1", 0)` at `kern_proc.c:1185`
  which blocks until `p_lock == 0`.
- `PHOLD` is released at `kern_prot.c:415` — AFTER `enterpgrp()` at `:409`.
- So the target stays `SACTIVE` throughout `enterpgrp()`; `pfindn` at `:763`
  always finds it → success path → error branch never runs.

## Build

```
./build.sh
# or: cc -O2 -o setpgid_panic setpgid_panic.c
```

## Run

As an **unprivileged** user:

```
./run.sh
# or: ./setpgid_panic [sweep_max] [parallel] [yield_every]
#     defaults: sweep=150000 parallel=4 yield=0
```

## Expected output (on THIS kernel = master DEV)

No panic, ever. The guest stays up indefinitely. This is the correct behavior
because the error path is unreachable (see VERDICT.md).

(On a hypothetical vulnerable kernel where the error path were reachable, the
expected output would be `panic: lwkt_reltoken: illegal release`.)
