git: f8bf6f81d6c2 - stable/14 - kevent: Hold the knlist mutex when invoking f_event(NOTE_FORK)
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 25 Nov 2025 14:02:12 UTC
The branch stable/14 has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=f8bf6f81d6c2b73b065befedddac3bf29f2963de
commit f8bf6f81d6c2b73b065befedddac3bf29f2963de
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-11-18 14:22:04 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-11-25 13:57:14 +0000
kevent: Hold the knlist mutex when invoking f_event(NOTE_FORK)
In general f_event is supposed to be called with the knlist mutex held,
so lock it earlier to follow this protocol. Also make sure that the
update to kn_fflags is synchronized.
Lock the kqueue itself earlier in the case where the knote is activated,
to avoid locking and unlocking the kqueue twice.
PR: 291005
Reported by: Qiu-ji Chen <chenqiuji666@gmail.com>
Reviewed by: kib
MFC after: 1 week
Differential Revision: https://reviews.freebsd.org/D53762
(cherry picked from commit d795c753e262b97a93dc353aa66b858e1b1969d1)
---
sys/kern/kern_event.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/sys/kern/kern_event.c b/sys/kern/kern_event.c
index d1145c37e128..4aba212544f7 100644
--- a/sys/kern/kern_event.c
+++ b/sys/kern/kern_event.c
@@ -603,12 +603,20 @@ knote_fork(struct knlist *list, int pid)
kev.data = kn->kn_id; /* parent */
kev.udata = kn->kn_kevent.udata;/* preserve udata */
error = kqueue_register(kq, &kev, NULL, M_NOWAIT);
+
+ /*
+ * Serialize updates to the kn_kevent fields with threads
+ * scanning the queue.
+ */
+ list->kl_lock(list->kl_lockarg);
if (error)
kn->kn_fflags |= NOTE_TRACKERR;
- if (kn->kn_fop->f_event(kn, NOTE_FORK))
- KNOTE_ACTIVATE(kn, 0);
- list->kl_lock(list->kl_lockarg);
- KQ_LOCK(kq);
+ if (kn->kn_fop->f_event(kn, NOTE_FORK)) {
+ KQ_LOCK(kq);
+ KNOTE_ACTIVATE(kn, 1);
+ } else {
+ KQ_LOCK(kq);
+ }
kn_leave_flux(kn);
KQ_UNLOCK_FLUX(kq);
}