If creating a persistent jail fails after kern_jail_set() has taken the
persist references (a failing OSD PR_METHOD_CREATE/SET method, or a MAC
label rejection), the half-built prison stays in allprison forever.
With INVARIANTS a jid lookup panics the kernel.
Two flaws:
- prison_deref() ignores PD_KILL for every prison that is not ALIVE. That also skips a prison still being created (INVALID), which is exactly what jail_set(2) relies on PD_KILL to clean up. Ignore only DYING prisons. The defect was introduced in 78f70d4ff9dd.
- PD_KILL was set only after the MAC label step, so a label failure never asked for the kill at all. Set it right after the parameters are validated, before the persist references are taken.
To reproduce the first bug:
jail -c persist name=x meta="$(jot -s '' -b a 5000)"; jls -d
To reproduce the second bug someone needs to write a MAC policy, I failed
to make a one-liner.
Fixes: 78f70d4ff9dd ("jail: fix a regression that creates zombies when removing dying jails")
MFC after: 1 month
Found with: Claude Code Sonnet 5.5