]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
Fix a pair of races in SIGIO registration
authormarkj <markj@FreeBSD.org>
Wed, 11 Nov 2020 13:44:27 +0000 (13:44 +0000)
committermarkj <markj@FreeBSD.org>
Wed, 11 Nov 2020 13:44:27 +0000 (13:44 +0000)
commit952f6a2592696f9c60caf777c31df85c6d11aa41
treec48adcf76e2e47abd2c3787cea4a91840e1dc2ac
parent4da935e1c50d68a40986741296e284122d107b61
Fix a pair of races in SIGIO registration

First, funsetownlst() list looks at the first element of the list to see
whether it's processing a process or a process group list.  Then it
acquires the global sigio lock and processes the list.  However, nothing
prevents the first sigio tracker from being freed by a concurrent
funsetown() before the sigio lock is acquired.

Fix this by acquiring the global sigio lock immediately after checking
whether the list is empty.  Callers of funsetownlst() ensure that new
sigio trackers cannot be added concurrently.

Second, fsetown() uses funsetown() to remove an existing sigio structure
from a file object.  However, funsetown() uses a racy check to avoid the
sigio lock, so two threads may call fsetown() on the same file object,
both observe that no sigio tracker is present, and enqueue two sigio
trackers for the same file object.  However, if the file object is
destroyed, funsetown() will only remove one sigio tracker, and
funsetownlst() may later trigger a use-after-free when it clears the
file object reference for each entry in the list.

Fix this by introducing funsetown_locked(), which avoids the racy check.

Reviewed by: kib
Reported by: pho
Tested by: pho
MFC after: 1 week
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D27157
sys/kern/kern_descrip.c
sys/kern/kern_exit.c
sys/kern/kern_proc.c
sys/sys/signalvar.h