summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorVisa Hankala <visa@cvs.openbsd.org>2021-12-08 13:03:54 +0000
committerVisa Hankala <visa@cvs.openbsd.org>2021-12-08 13:03:54 +0000
commitee3f64728203d78b5a5f78a43200c2ea4508ce82 (patch)
treecf13d69c70e848964eff0ce13d4e38b333ec284d /sys
parent06e0327b9e8cd5861f68ca157066a1e82722f73e (diff)
Fix select(2) exceptfds handling of FIFOs and pipes
Prevent select(2) from indicating an exceptional condition when the other end of a FIFO or pipe is closed. Originally, select(2) returned an exceptfds event only with a pty or socket that has out-of-band data pending. millert@ says that OpenBSD diverged from this by accident when poll(2) and select(2) were changed to use the same backend code in year 2003. OK millert@
Diffstat (limited to 'sys')
-rw-r--r--sys/kern/sys_generic.c7
-rw-r--r--sys/kern/sys_pipe.c7
-rw-r--r--sys/miscfs/fifofs/fifo_vnops.c6
-rw-r--r--sys/sys/event.h5
4 files changed, 18 insertions, 7 deletions
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
index 39a8ab7ae83..8fdfb8d8b84 100644
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_generic.c,v 1.144 2021/11/30 02:58:33 visa Exp $ */
+/* $OpenBSD: sys_generic.c,v 1.145 2021/12/08 13:03:52 visa Exp $ */
/* $NetBSD: sys_generic.c,v 1.24 1996/03/29 00:25:32 cgd Exp $ */
/*
@@ -762,7 +762,7 @@ pselregister(struct proc *p, fd_set *pibits[3], fd_set *pobits[3], int nfd,
DPRINTFN(2, "select fd %d mask %d serial %lu\n",
fd, msk, p->p_kq_serial);
EV_SET(&kev, fd, evf[msk],
- EV_ADD|EV_ENABLE|__EV_POLL,
+ EV_ADD|EV_ENABLE|__EV_POLL|__EV_SELECT,
evff[msk], 0, (void *)(p->p_kq_serial));
#ifdef KTRACE
if (KTRPOINT(p, KTR_STRUCT))
@@ -775,7 +775,8 @@ pselregister(struct proc *p, fd_set *pibits[3], fd_set *pobits[3], int nfd,
/* FALLTHROUGH */
case EOPNOTSUPP:/* No underlying kqfilter */
case EINVAL: /* Unimplemented filter */
- case EPERM: /* Specific to FIFO */
+ case EPERM: /* Specific to FIFO and
+ * __EV_SELECT */
error = 0;
break;
case EPIPE: /* Specific to pipes */
diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c
index 3ece79221b3..4da474aa257 100644
--- a/sys/kern/sys_pipe.c
+++ b/sys/kern/sys_pipe.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sys_pipe.c,v 1.130 2021/12/07 14:06:16 visa Exp $ */
+/* $OpenBSD: sys_pipe.c,v 1.131 2021/12/08 13:03:52 visa Exp $ */
/*
* Copyright (c) 1996 John S. Dyson
@@ -922,6 +922,11 @@ pipe_kqfilter(struct file *fp, struct knote *kn)
klist_insert_locked(&wpipe->pipe_sel.si_note, kn);
break;
case EVFILT_EXCEPT:
+ if (kn->kn_flags & __EV_SELECT) {
+ /* Prevent triggering exceptfds. */
+ error = EPERM;
+ break;
+ }
kn->kn_fop = &pipe_efiltops;
kn->kn_hook = rpipe;
klist_insert_locked(&rpipe->pipe_sel.si_note, kn);
diff --git a/sys/miscfs/fifofs/fifo_vnops.c b/sys/miscfs/fifofs/fifo_vnops.c
index c039fd411ec..ca8d40f6de0 100644
--- a/sys/miscfs/fifofs/fifo_vnops.c
+++ b/sys/miscfs/fifofs/fifo_vnops.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fifo_vnops.c,v 1.85 2021/10/24 11:23:22 mpi Exp $ */
+/* $OpenBSD: fifo_vnops.c,v 1.86 2021/12/08 13:03:52 visa Exp $ */
/* $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */
/*
@@ -540,6 +540,10 @@ fifo_kqfilter(void *v)
sb = &so->so_snd;
break;
case EVFILT_EXCEPT:
+ if (ap->a_kn->kn_flags & __EV_SELECT) {
+ /* Prevent triggering exceptfds. */
+ return (EPERM);
+ }
ap->a_kn->kn_fop = &fifoexcept_filtops;
so = fip->fi_readsock;
sb = &so->so_rcv;
diff --git a/sys/sys/event.h b/sys/sys/event.h
index 20a1fd33c82..5004978e348 100644
--- a/sys/sys/event.h
+++ b/sys/sys/event.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: event.h,v 1.59 2021/11/29 15:54:04 visa Exp $ */
+/* $OpenBSD: event.h,v 1.60 2021/12/08 13:03:53 visa Exp $ */
/*-
* Copyright (c) 1999,2000,2001 Jonathan Lemon <jlemon@FreeBSD.org>
@@ -74,7 +74,7 @@ struct kevent {
#define EV_RECEIPT 0x0040 /* force EV_ERROR on success, data=0 */
#define EV_DISPATCH 0x0080 /* disable event after reporting */
-#define EV_SYSFLAGS 0xF000 /* reserved by system */
+#define EV_SYSFLAGS 0xf800 /* reserved by system */
#define EV_FLAG1 0x2000 /* filter-specific flag */
/* returned values */
@@ -141,6 +141,7 @@ struct klist {
#ifdef _KERNEL
/* kernel-only flags */
+#define __EV_SELECT 0x0800 /* match behavior of select */
#define __EV_POLL 0x1000 /* match behavior of poll & select */
#define __EV_HUP EV_FLAG1 /* device or socket disconnected */