From 87c93f01794232be35da5db855061861fa67bb2f Mon Sep 17 00:00:00 2001 From: visa Date: Mon, 13 Dec 2021 14:56:55 +0000 Subject: [PATCH] Revise EVFILT_EXCEPT filters Restrict the circumstances where EVFILT_EXCEPT filters trigger: * when out-of-band data is present and NOTE_OOB is requested. * when the channel is fully closed and consumer is poll(2). This should clarify the logic and suppress events that kqueue-based poll(2) does not except. OK mpi@ --- sys/kern/sys_pipe.c | 13 +++++++------ sys/kern/tty_pty.c | 17 +++++++++-------- sys/kern/uipc_socket.c | 15 +++++++-------- sys/miscfs/fifofs/fifo_vnops.c | 12 +++++------- 4 files changed, 28 insertions(+), 29 deletions(-) diff --git a/sys/kern/sys_pipe.c b/sys/kern/sys_pipe.c index fa103c6f4d4..34448410f12 100644 --- a/sys/kern/sys_pipe.c +++ b/sys/kern/sys_pipe.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_pipe.c,v 1.132 2021/12/13 14:54:22 visa Exp $ */ +/* $OpenBSD: sys_pipe.c,v 1.133 2021/12/13 14:56:55 visa Exp $ */ /* * Copyright (c) 1996 John S. Dyson @@ -1079,19 +1079,20 @@ int filt_pipeexcept_common(struct knote *kn, struct pipe *rpipe) { struct pipe *wpipe; + int active = 0; rw_assert_wrlock(rpipe->pipe_lock); wpipe = pipe_peer(rpipe); - if ((rpipe->pipe_state & PIPE_EOF) || wpipe == NULL) { - kn->kn_flags |= EV_EOF; - if (kn->kn_flags & __EV_POLL) + if (kn->kn_flags & __EV_POLL) { + if ((rpipe->pipe_state & PIPE_EOF) || wpipe == NULL) { kn->kn_flags |= __EV_HUP; - return (1); + active = 1; + } } - return (0); + return (active); } int diff --git a/sys/kern/tty_pty.c b/sys/kern/tty_pty.c index bf213d2a118..f719155fa85 100644 --- a/sys/kern/tty_pty.c +++ b/sys/kern/tty_pty.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tty_pty.c,v 1.110 2021/10/24 00:02:25 jsg Exp $ */ +/* $OpenBSD: tty_pty.c,v 1.111 2021/12/13 14:56:55 visa Exp $ */ /* $NetBSD: tty_pty.c,v 1.33.4.1 1996/06/02 09:08:11 mrg Exp $ */ /* @@ -727,6 +727,7 @@ filt_ptcexcept(struct knote *kn, long hint) { struct pt_softc *pti = (struct pt_softc *)kn->kn_hook; struct tty *tp; + int active = 0; tp = pti->pt_tty; @@ -736,18 +737,18 @@ filt_ptcexcept(struct knote *kn, long hint) ((pti->pt_flags & PF_UCNTL) && pti->pt_ucntl)) { kn->kn_fflags |= NOTE_OOB; kn->kn_data = 1; - return (1); + active = 1; } - return (0); } - if (!ISSET(tp->t_state, TS_CARR_ON)) { - kn->kn_flags |= EV_EOF; - if (kn->kn_flags & __EV_POLL) + + if (kn->kn_flags & __EV_POLL) { + if (!ISSET(tp->t_state, TS_CARR_ON)) { kn->kn_flags |= __EV_HUP; - return (1); + active = 1; + } } - return (0); + return (active); } const struct filterops ptcread_filtops = { diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 6c0b47af006..2615019023b 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uipc_socket.c,v 1.269 2021/11/11 16:35:09 mvs Exp $ */ +/* $OpenBSD: uipc_socket.c,v 1.270 2021/12/13 14:56:55 visa Exp $ */ /* $NetBSD: uipc_socket.c,v 1.21 1996/02/04 02:17:52 christos Exp $ */ /* @@ -2263,14 +2263,13 @@ filt_soexcept_common(struct knote *kn, struct socket *so) kn->kn_data -= so->so_oobmark; rv = 1; } - } else if (so->so_state & SS_CANTRCVMORE) { - kn->kn_flags |= EV_EOF; - if (kn->kn_flags & __EV_POLL) { - if (so->so_state & SS_ISDISCONNECTED) - kn->kn_flags |= __EV_HUP; + } + + if (kn->kn_flags & __EV_POLL) { + if (so->so_state & SS_ISDISCONNECTED) { + kn->kn_flags |= __EV_HUP; + rv = 1; } - kn->kn_fflags = so->so_error; - rv = 1; } return rv; diff --git a/sys/miscfs/fifofs/fifo_vnops.c b/sys/miscfs/fifofs/fifo_vnops.c index 86b4486fc33..d95f34e5a13 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.88 2021/12/13 14:54:22 visa Exp $ */ +/* $OpenBSD: fifo_vnops.c,v 1.89 2021/12/13 14:56:55 visa Exp $ */ /* $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */ /* @@ -708,13 +708,11 @@ filt_fifoexcept_common(struct knote *kn, struct socket *so) soassertlocked(so); - if (so->so_state & SS_CANTRCVMORE) { - kn->kn_flags |= EV_EOF; - if (kn->kn_flags & __EV_POLL) { - if (so->so_state & SS_ISDISCONNECTED) - kn->kn_flags |= __EV_HUP; + if (kn->kn_flags & __EV_POLL) { + if (so->so_state & SS_ISDISCONNECTED) { + kn->kn_flags |= __EV_HUP; + rv = 1; } - rv = 1; } return (rv); -- 2.20.1