Make exit1() wait sysctl(2) `allprocess' loops.
authormvs <mvs@openbsd.org>
Sun, 11 Aug 2024 15:10:53 +0000 (15:10 +0000)
committermvs <mvs@openbsd.org>
Sun, 11 Aug 2024 15:10:53 +0000 (15:10 +0000)
commit1636884352af65901b58f3fdffa7015e5a90939f
tree1d53d275bc6a520956ba752f08211d69ebbdbd23
parentaf5e9d3481ead679693cffde94412bd0e9ca2a19
Make exit1() wait sysctl(2) `allprocess' loops.

Regardless on wired userland memory, KERN_FILE_BYPID and KERN_FILE_BYUID
`allprocess' loops have netlock provided sleep points, so concurrent
process exit(1) could crash kernel.

The main exit1() problem is that process teardown begins while process
is still linked to `allprocess' list, and current code doesn't allow to
unlink it first. Wait for concurrent sysctl(2) `allprocess' loops
between PS_EXITING bit setting and list unlinking. Both KERN_FILE_BYPID
and KERN_FILE_BYUID loops do PS_EXITING check and won't deal with dying
process. Concurrent exit1() thread will wait loops keeping process
linked to `allprocess' list.

Tested with i386 dpb(1) run.
Stress tests and ok bluhm.
sys/kern/kern_exit.c
sys/kern/kern_fork.c
sys/kern/kern_sysctl.c
sys/sys/proc.h