# DF-5824 VERDICT

**status: reproduced (leak mechanism, deterministic) / impact: none
observable (latent flag corruption) / confidence: certain**

## Root cause (path:line)

`inferior()` sys/kern/kern_proc.c:470-493 — the pid==0 early-return at
478-481 exits without releasing the hold the walk just transferred onto
the pid==0 node (proc0).  Balanced paths: normal loop transfer
(482-487) and the `p == curproc` exit (489-490).  Unbalanced path: 480.

Unprivileged reachability: `sys_setpgid` sys/kern/kern_prot.c:372 —
`if ((targp = pfind(uap->pid)) == NULL || !inferior(targp))` — any
non-descendant pid (e.g. 1) walks inferior() to proc0 and returns via the
leaking branch; the caller's own pfind hold IS released (373), only
inferior's internal hold on proc0 strands.

Effect: `phold()` is `atomic_add_int(&p->p_lock, 1)` (kern_proc.c:341);
PLOCK flags live at bits 28-30 (kern_proc.c:263-266,
PLOCK_MASK = 0x0FFFFFFF).  Unbounded unprivileged growth overflows the
count into the flag bits of proc0's p_lock.

## Runtime proof

* run.log (10M): `setpgid(1,0)` x 10,000,000 → ESRCH 10,000,000 (100% —
  every single call executes the leaking branch; this is a deterministic
  leak, not a race), 6.49 s wall → ~1.54M/s.
* run.log (300M): +300,000,000 in 194.74 s.  Total stranded holds on
  proc0 after both runs: 310,000,000 = 0x1274F0C0 ≥ 0x10000000 →
  **PLOCK_WAITRES bit is set in proc0's p_lock on the live guest**.
* Guest healthy before/after (uptime continuous, sysctl responsive):
  nothing in the current kernel PSTALLs or pholdzombs proc0, so the
  corrupted flag word has no consumer — dormant corruption.

## Impact assessment (honest)

No crash is reachable today because proc0 is immortal and never passes
through proc_move_allproc_zombie/wait.  The finding is filed as a
correctness/refcount-discipline defect with a demonstrated unprivileged
unbounded-growth primitive against a kernel synchronization word — a
latent wedge/panic for any future consumer, plus a permanent accounting
lie (proc0's hold count can never be trusted again after the attack).

## Reproduce

```
cc -O2 -o df5824_leak df5824_leak.c
time ./df5824_leak 10000000     # ~6.5s, 100% ESRCH
time ./df5824_leak 300000000    # ~195s, crosses 2^28 -> flag bit set
```

## Fix status (batch validation)
Applied with the 36 sibling fix.diffs of this batch in findings/poc/_batch41/all_fixes.patch; single in-guest `make -j6 nativekernel KERNCONF=X86_64_GENERIC` completed RC=0 with zero errors under -Werror (full log: findings/poc/_batch41/fix_build8.log). Behavior A/B intentionally skipped for this Info-tier item.
