summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2019-07-03 14:32:03 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2019-07-03 14:32:03 +0000
commit5a008fee306efabded49dd0bbd255351b9b4276e (patch)
treed17b2f7091795ac66d28ee5ec86b0dc9746e22fc
parent4227b7a13fb9aad95d84c0e509cad30f1f3850e7 (diff)
Lock the kernel when removing file descriptors from the descriptor
table. This should prevent a race with kevent when unlocked code closes file descriptors that are fully set up. OK mpi@
-rw-r--r--sys/kern/kern_descrip.c10
-rw-r--r--sys/kern/kern_event.c4
2 files changed, 12 insertions, 2 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index ac144a685ba..e2e4f1c668a 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_descrip.c,v 1.187 2019/06/26 13:27:20 millert Exp $ */
+/* $OpenBSD: kern_descrip.c,v 1.188 2019/07/03 14:32:02 visa Exp $ */
/* $NetBSD: kern_descrip.c,v 1.42 1996/03/30 22:24:38 christos Exp $ */
/*
@@ -663,6 +663,9 @@ finishdup(struct proc *p, struct file *fp, int old, int new,
fd_used(fdp, new);
}
+ /* Prevent race with kevent. */
+ KERNEL_LOCK();
+
/*
* Use `fd_fplock' to synchronize with fd_getfile() so that
* the function no longer creates a new reference to the old file.
@@ -679,6 +682,8 @@ finishdup(struct proc *p, struct file *fp, int old, int new,
closef(oldfp, p);
}
+ KERNEL_UNLOCK();
+
return (0);
}
@@ -738,10 +743,13 @@ fdrelease(struct proc *p, int fd)
fp = fd_getfile(fdp, fd);
if (fp == NULL)
return (EBADF);
+ /* Prevent race with kevent. */
+ KERNEL_LOCK();
fdremove(fdp, fd);
knote_fdclose(p, fd);
fdpunlock(fdp);
error = closef(fp, p);
+ KERNEL_UNLOCK();
fdplock(fdp);
return error;
}
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index ad4a856e895..62fca7f9e98 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_event.c,v 1.105 2019/07/01 16:52:02 cheloha Exp $ */
+/* $OpenBSD: kern_event.c,v 1.106 2019/07/03 14:32:02 visa Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -963,6 +963,8 @@ knote_fdclose(struct proc *p, int fd)
struct kqueue *kq;
struct klist *list;
+ KERNEL_ASSERT_LOCKED();
+
LIST_FOREACH(kq, &p->p_p->ps_kqlist, kq_next) {
if (fd >= kq->kq_knlistsize)
continue;