From: visa Date: Sat, 25 Dec 2021 11:04:58 +0000 (+0000) Subject: kqueue: Invalidate revoked vnodes' knotes on the fly X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=ce1591e9cb9181593e791fd1aafd256351177d94;p=openbsd kqueue: Invalidate revoked vnodes' knotes on the fly When a tty device is revoked, the associated knotes should be invalidated. Otherwise the user processes can keep on receiving events from the device. It appears tricky to do the invalidation as part of revocation in a way that does not allow unwanted event registration or clutter the tty code. For now, make the knotes invalid lazily before delivery. OK mpi@ --- diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 109f7895455..33f30f27be8 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_event.c,v 1.177 2021/12/20 16:24:32 visa Exp $ */ +/* $OpenBSD: kern_event.c,v 1.178 2021/12/25 11:04:58 visa Exp $ */ /*- * Copyright (c) 1999,2000,2001 Jonathan Lemon @@ -55,6 +55,7 @@ #include #include #include +#include #include #ifdef DIAGNOSTIC @@ -1381,6 +1382,36 @@ retry: continue; } + /* + * Invalidate knotes whose vnodes have been revoked. + * This is a workaround; it is tricky to clear existing + * knotes and prevent new ones from being registered + * with the current revocation mechanism. + */ + if ((kn->kn_fop->f_flags & FILTEROP_ISFD) && + kn->kn_fp != NULL && + kn->kn_fp->f_type == DTYPE_VNODE) { + struct vnode *vp = kn->kn_fp->f_data; + + if (__predict_false(vp->v_op == &dead_vops && + kn->kn_fop != &dead_filtops)) { + filter_detach(kn); + kn->kn_fop = &dead_filtops; + + /* + * Check if the event should be delivered. + * Use f_event directly because this is + * a special situation. + */ + if (kn->kn_fop->f_event(kn, 0) == 0) { + filter_detach(kn); + knote_drop(kn, p); + mtx_enter(&kq->kq_lock); + continue; + } + } + } + memset(kevp, 0, sizeof(*kevp)); if (filter_process(kn, kevp) == 0) { mtx_enter(&kq->kq_lock);