summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2021-12-20 16:24:33 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2021-12-20 16:24:33 +0000
commit9576a7d105b8dc8cde073ed524b8c938640eb67b (patch)
tree83c43a6badb45f78c4b45d346e67f9a4578af130
parente0261a0fe1ba151aaee365fbfb4d2080ee71d66d (diff)
Make filt_dead() selectively inactive with EVFILT_EXCEPT
When a knote uses the dead event filter, the knote's file descriptor is not supposed to point to an object with pending out-of-band data. Make the knote inactive so that userspace will not receive a spurious event. However, kqueue-based poll(2) should still receive HUP notifications. This lets the system use dead_filtops with less strings attached relative to the filter type.
-rw-r--r--sys/kern/kern_event.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index fc86896c29c..109f7895455 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: kern_event.c,v 1.176 2021/12/20 16:21:07 visa Exp $ */
+/* $OpenBSD: kern_event.c,v 1.177 2021/12/20 16:24:32 visa Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -636,6 +636,17 @@ seltrue_kqfilter(dev_t dev, struct knote *kn)
static int
filt_dead(struct knote *kn, long hint)
{
+ if (kn->kn_filter == EVFILT_EXCEPT) {
+ /*
+ * Do not deliver event because there is no out-of-band data.
+ * However, let HUP condition pass for poll(2).
+ */
+ if ((kn->kn_flags & __EV_POLL) == 0) {
+ kn->kn_flags |= EV_DISABLE;
+ return (0);
+ }
+ }
+
kn->kn_flags |= (EV_EOF | EV_ONESHOT);
if (kn->kn_flags & __EV_POLL)
kn->kn_flags |= __EV_HUP;