aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_exit.c
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2020-11-11 13:44:27 +0000
committerMark Johnston <markj@FreeBSD.org>2020-11-11 13:44:27 +0000
commitf52979098d3cde8dc967f050e978ebf97690bf01 (patch)
treec48adcf76e2e47abd2c3787cea4a91840e1dc2ac /sys/kern/kern_exit.c
parent26007fe37c06fe0b61634083befb7f9eb87c08c0 (diff)
downloadsrc-f52979098d3cde8dc967f050e978ebf97690bf01.tar.gz
src-f52979098d3cde8dc967f050e978ebf97690bf01.zip
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
Notes
Notes: svn path=/head/; revision=367588
Diffstat (limited to 'sys/kern/kern_exit.c')
-rw-r--r--sys/kern/kern_exit.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c
index cab69f06163a..4df7842ddc0e 100644
--- a/sys/kern/kern_exit.c
+++ b/sys/kern/kern_exit.c
@@ -358,7 +358,7 @@ exit1(struct thread *td, int rval, int signo)
/*
* Reset any sigio structures pointing to us as a result of
- * F_SETOWN with our pid.
+ * F_SETOWN with our pid. The P_WEXIT flag interlocks with fsetown().
*/
funsetownlst(&p->p_sigiolst);