From 627c97d9222ce740183124bc06e26a24c28a3a30 Mon Sep 17 00:00:00 2001 From: visa Date: Wed, 16 Jun 2021 14:26:30 +0000 Subject: [PATCH] kqueue: kq_lock is needed when updating kn_status The kn_status field of struct knote is part of kqueue's internal state. When kn_status is being updated, kq_lock has to be locked. This is true even with MP-unsafe event filters. OK mpi@ --- sys/kern/kern_event.c | 19 ++++++++++++++----- sys/sys/event.h | 5 +++-- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c index 48d3400613a..ed2b1d16f8e 100644 --- a/sys/kern/kern_event.c +++ b/sys/kern/kern_event.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_event.c,v 1.166 2021/06/11 04:29:54 visa Exp $ */ +/* $OpenBSD: kern_event.c,v 1.167 2021/06/16 14:26:30 visa Exp $ */ /*- * Copyright (c) 1999,2000,2001 Jonathan Lemon @@ -328,10 +328,15 @@ filt_procattach(struct knote *kn) void filt_procdetach(struct knote *kn) { + struct kqueue *kq = kn->kn_kq; struct process *pr = kn->kn_ptr.p_process; - int s; + int s, status; + + mtx_enter(&kq->kq_lock); + status = kn->kn_status; + mtx_leave(&kq->kq_lock); - if (kn->kn_status & KN_DETACHED) + if (status & KN_DETACHED) return; s = splhigh(); @@ -342,6 +347,7 @@ filt_procdetach(struct knote *kn) int filt_proc(struct knote *kn, long hint) { + struct kqueue *kq = kn->kn_kq; u_int event; /* @@ -363,8 +369,11 @@ filt_proc(struct knote *kn, long hint) struct process *pr = kn->kn_ptr.p_process; int s; - s = splhigh(); + mtx_enter(&kq->kq_lock); kn->kn_status |= KN_DETACHED; + mtx_leave(&kq->kq_lock); + + s = splhigh(); kn->kn_flags |= (EV_EOF | EV_ONESHOT); kn->kn_data = W_EXITCODE(pr->ps_xexit, pr->ps_xsig); klist_remove_locked(&pr->ps_klist, kn); @@ -391,7 +400,7 @@ filt_proc(struct knote *kn, long hint) kev.fflags = kn->kn_sfflags; kev.data = kn->kn_id; /* parent */ kev.udata = kn->kn_udata; /* preserve udata */ - error = kqueue_register(kn->kn_kq, &kev, NULL); + error = kqueue_register(kq, &kev, NULL); if (error) kn->kn_fflags |= NOTE_TRACKERR; } diff --git a/sys/sys/event.h b/sys/sys/event.h index 27e9d974efc..4df0d934ed0 100644 --- a/sys/sys/event.h +++ b/sys/sys/event.h @@ -1,4 +1,4 @@ -/* $OpenBSD: event.h,v 1.55 2021/06/02 13:56:28 visa Exp $ */ +/* $OpenBSD: event.h,v 1.56 2021/06/16 14:26:30 visa Exp $ */ /*- * Copyright (c) 1999,2000,2001 Jonathan Lemon @@ -228,6 +228,7 @@ struct filterops { * Locking: * I immutable after creation * o object lock + * q kn_kq->kq_lock */ struct knote { SLIST_ENTRY(knote) kn_link; /* for fd */ @@ -235,7 +236,7 @@ struct knote { TAILQ_ENTRY(knote) kn_tqe; struct kqueue *kn_kq; /* [I] which queue we are on */ struct kevent kn_kevent; - int kn_status; + int kn_status; /* [q] */ int kn_sfflags; /* [o] saved filter flags */ __int64_t kn_sdata; /* [o] saved data field */ union { -- 2.20.1