untrusted comment: verify with openbsd-71-base.pub
RWR2eHwZTOEiTZu1Ef/K1xXVdqk6Yl1KVYqsIXG14Bs2YkTc1SKAXtCZuWgvbzYT1pnTWKuT1Fct6pq6WYzPzYzqVudcufGaLA4=

OpenBSD 7.1 errata 003, May 16, 2022:

The kernel could crash due to a race in kqueue.

Apply by doing:
    signify -Vep /etc/signify/openbsd-71-base.pub -x 003_kqueue.patch.sig \
        -m - | (cd /usr/src && patch -p0)

And then rebuild and install a new kernel:
    KK=`sysctl -n kern.osversion | cut -d# -f1`
    cd /usr/src/sys/arch/`machine`/compile/$KK
    make obj
    make config
    make
    make install

Index: sys/kern/kern_event.c
===================================================================
RCS file: /cvs/src/sys/kern/kern_event.c,v
diff -u -p -r1.186 kern_event.c
--- sys/kern/kern_event.c	31 Mar 2022 01:41:22 -0000	1.186
+++ sys/kern/kern_event.c	13 May 2022 20:41:18 -0000
@@ -121,8 +121,8 @@ void	knote_dequeue(struct knote *kn);
 int	knote_acquire(struct knote *kn, struct klist *, int);
 void	knote_release(struct knote *kn);
 void	knote_activate(struct knote *kn);
-void	knote_remove(struct proc *p, struct kqueue *kq, struct knlist *list,
-	    int purge);
+void	knote_remove(struct proc *p, struct kqueue *kq, struct knlist **plist,
+	    int idx, int purge);
 
 void	filt_kqdetach(struct knote *kn);
 int	filt_kqueue(struct knote *kn, long hint);
@@ -1563,10 +1563,10 @@ kqueue_purge(struct proc *p, struct kque
 
 	mtx_enter(&kq->kq_lock);
 	for (i = 0; i < kq->kq_knlistsize; i++)
-		knote_remove(p, kq, &kq->kq_knlist[i], 1);
+		knote_remove(p, kq, &kq->kq_knlist, i, 1);
 	if (kq->kq_knhashmask != 0) {
 		for (i = 0; i < kq->kq_knhashmask + 1; i++)
-			knote_remove(p, kq, &kq->kq_knhash[i], 1);
+			knote_remove(p, kq, &kq->kq_knhash, i, 1);
 	}
 	mtx_leave(&kq->kq_lock);
 }
@@ -1801,13 +1801,15 @@ knote(struct klist *list, long hint)
  * remove all knotes from a specified knlist
  */
 void
-knote_remove(struct proc *p, struct kqueue *kq, struct knlist *list, int purge)
+knote_remove(struct proc *p, struct kqueue *kq, struct knlist **plist, int idx,
+    int purge)
 {
 	struct knote *kn;
 
 	MUTEX_ASSERT_LOCKED(&kq->kq_lock);
 
-	while ((kn = SLIST_FIRST(list)) != NULL) {
+	/* Always fetch array pointer as another thread can resize kq_knlist. */
+	while ((kn = SLIST_FIRST(*plist + idx)) != NULL) {
 		KASSERT(kn->kn_kq == kq);
 
 		if (!purge) {
@@ -1875,7 +1877,7 @@ knote_fdclose(struct proc *p, int fd)
 	LIST_FOREACH(kq, &fdp->fd_kqlist, kq_next) {
 		mtx_enter(&kq->kq_lock);
 		if (fd < kq->kq_knlistsize)
-			knote_remove(p, kq, &kq->kq_knlist[fd], 0);
+			knote_remove(p, kq, &kq->kq_knlist, fd, 0);
 		mtx_leave(&kq->kq_lock);
 	}
 }
