diff options
author | Visa Hankala <visa@cvs.openbsd.org> | 2021-12-08 13:03:54 +0000 |
---|---|---|
committer | Visa Hankala <visa@cvs.openbsd.org> | 2021-12-08 13:03:54 +0000 |
commit | ee3f64728203d78b5a5f78a43200c2ea4508ce82 (patch) | |
tree | cf13d69c70e848964eff0ce13d4e38b333ec284d /sys | |
parent | 06e0327b9e8cd5861f68ca157066a1e82722f73e (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.c | 7 | ||||
-rw-r--r-- | sys/kern/sys_pipe.c | 7 | ||||
-rw-r--r-- | sys/miscfs/fifofs/fifo_vnops.c | 6 | ||||
-rw-r--r-- | sys/sys/event.h | 5 |
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 */ |