]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
killpg(): close a race with fork(), part 2
authorKonstantin Belousov <kib@FreeBSD.org>
Thu, 20 Jul 2023 21:19:03 +0000 (00:19 +0300)
committerKonstantin Belousov <kib@FreeBSD.org>
Wed, 26 Jul 2023 15:13:02 +0000 (18:13 +0300)
commit232b922cb363e01ac0dd2a277d93cf74d8485e79
tree20432c058ae489167af2e3ccefd202cb0d73e3c1
parentdfe172484d0e1de0bb32bcab8775eb83e15031c0
killpg(): close a race with fork(), part 2

When we are sending terminating signal to the group, killpg() needs
to guarantee that all group members are to be terminated (it does not
need to ensure that they are terminated on return from killpg()).  The
pg_killsx change eliminates the largest window there, but still, if
a multithreaded process is signalled, the following could happen:
- thread 1 is selected for the signal delivery and gets descheduled
- thread 2 waits for pg_killsx lock, obtains it and forks
- thread 1 continue executing and terminates the process
This scenario allows the child to escape still.

Fix it by single-threading forking parent if a conflict with pg_killsx
is noted.  We try to lock pg_killsx without sleeping, and failure to
acquire it means that a parallel killpg(2) is executed.  Then, stop
other threads for running and in particular, receive signals, to avoid
the situation explained above.

Reviewed by: markj
Tested by: pho
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D41128
sys/kern/kern_fork.c