untrusted comment: verify with openbsd-66-base.pub
RWSvK/c+cFe24GfJ1f7I1EopRSLZ5MmN+StVmNstQEhEb6cjntr/2lgIvLDRJyw33QiTJbIH9opWMcZ54YasS5jr9weqTWfcBQI=

OpenBSD 6.6 errata 001, October 28, 2019:

Repair bpf(4) race condition during device removal.

Apply by doing:
    signify -Vep /etc/signify/openbsd-66-base.pub -x 001_bpf.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/net/bpf.c
===================================================================
RCS file: /cvs/src/sys/net/bpf.c,v
retrieving revision 1.181
diff -u -p -r1.181 bpf.c
--- sys/net/bpf.c	1 Oct 2019 11:51:13 -0000	1.181
+++ sys/net/bpf.c	24 Oct 2019 18:58:05 -0000
@@ -124,6 +124,13 @@ void	bpf_resetd(struct bpf_d *);
 void	bpf_prog_smr(void *);
 void	bpf_d_smr(void *);
 
+/*
+ * Reference count access to descriptor buffers
+ */
+void	bpf_get(struct bpf_d *);
+void	bpf_put(struct bpf_d *);
+
+
 struct rwlock bpf_sysctl_lk = RWLOCK_INITIALIZER("bpfsz");
 
 int
@@ -318,11 +325,13 @@ bpf_detachd(struct bpf_d *d)
 
 		d->bd_promisc = 0;
 
+		bpf_get(d);
 		mtx_leave(&d->bd_mtx);
 		NET_LOCK();
 		error = ifpromisc(bp->bif_ifp, 0);
 		NET_UNLOCK();
 		mtx_enter(&d->bd_mtx);
+		bpf_put(d);
 
 		if (error && !(error == EINVAL || error == ENODEV ||
 		    error == ENXIO))
@@ -371,6 +380,7 @@ bpfopen(dev_t dev, int flag, int mode, s
 	if (flag & FNONBLOCK)
 		bd->bd_rtout = -1;
 
+	bpf_get(bd);
 	LIST_INSERT_HEAD(&bpf_d_list, bd, bd_list);
 
 	return (0);
@@ -391,13 +401,7 @@ bpfclose(dev_t dev, int flag, int mode, 
 	bpf_wakeup(d);
 	LIST_REMOVE(d, bd_list);
 	mtx_leave(&d->bd_mtx);
-
-	/*
-	 * Wait for the task to finish here, before proceeding to garbage
-	 * collection.
-	 */
-	taskq_barrier(systq);
-	smr_call(&d->bd_smr, bpf_d_smr, d);
+	bpf_put(d);
 
 	return (0);
 }
@@ -431,6 +435,7 @@ bpfread(dev_t dev, struct uio *uio, int 
 	if (d->bd_bif == NULL)
 		return (ENXIO);
 
+	bpf_get(d);
 	mtx_enter(&d->bd_mtx);
 
 	/*
@@ -536,6 +541,7 @@ bpfread(dev_t dev, struct uio *uio, int 
 	d->bd_in_uiomove = 0;
 out:
 	mtx_leave(&d->bd_mtx);
+	bpf_put(d);
 
 	return (error);
 }
@@ -554,7 +560,9 @@ bpf_wakeup(struct bpf_d *d)
 	 * by the KERNEL_LOCK() we have to delay the wakeup to
 	 * another context to keep the hot path KERNEL_LOCK()-free.
 	 */
-	task_add(systq, &d->bd_wake_task);
+	bpf_get(d);
+	if (!task_add(systq, &d->bd_wake_task))
+		bpf_put(d);
 }
 
 void
@@ -569,6 +577,7 @@ bpf_wakeup_cb(void *xd)
 		csignal(d->bd_pgid, d->bd_sig, d->bd_siguid, d->bd_sigeuid);
 
 	selwakeup(&d->bd_sel);
+	bpf_put(d);
 }
 
 int
@@ -586,6 +595,7 @@ bpfwrite(dev_t dev, struct uio *uio, int
 	if (d->bd_bif == NULL)
 		return (ENXIO);
 
+	bpf_get(d);
 	ifp = d->bd_bif->bif_ifp;
 
 	if (ifp == NULL || (ifp->if_flags & IFF_UP) == 0) {
@@ -619,6 +629,7 @@ bpfwrite(dev_t dev, struct uio *uio, int
 	NET_UNLOCK();
 
 out:
+	bpf_put(d);
 	return (error);
 }
 
@@ -694,6 +705,8 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t 
 		}
 	}
 
+	bpf_get(d);
+
 	switch (cmd) {
 	default:
 		error = EINVAL;
@@ -991,6 +1004,7 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t 
 		break;
 	}
 
+	bpf_put(d);
 	return (error);
 }
 
@@ -1178,6 +1192,7 @@ bpfkqfilter(dev_t dev, struct knote *kn)
 		return (EINVAL);
 	}
 
+	bpf_get(d);
 	kn->kn_hook = d;
 	SLIST_INSERT_HEAD(klist, kn, kn_selnext);
 
@@ -1197,6 +1212,7 @@ filt_bpfrdetach(struct knote *kn)
 	KERNEL_ASSERT_LOCKED();
 
 	SLIST_REMOVE(&d->bd_sel.si_note, kn, knote, kn_selnext);
+	bpf_put(d);
 }
 
 int
@@ -1577,6 +1593,25 @@ bpf_d_smr(void *smr)
 		bpf_prog_smr(bd->bd_wfilter);
 
 	free(bd, M_DEVBUF, sizeof(*bd));
+}
+
+void
+bpf_get(struct bpf_d *bd)
+{
+	atomic_inc_int(&bd->bd_ref);
+}
+
+/*
+ * Free buffers currently in use by a descriptor
+ * when the reference count drops to zero.
+ */
+void
+bpf_put(struct bpf_d *bd)
+{
+	if (atomic_dec_int_nv(&bd->bd_ref) > 0)
+		return;
+
+	smr_call(&bd->bd_smr, bpf_d_smr, bd);
 }
 
 void *
Index: sys/net/bpfdesc.h
===================================================================
RCS file: /cvs/src/sys/net/bpfdesc.h,v
retrieving revision 1.38
diff -u -p -r1.38 bpfdesc.h
--- sys/net/bpfdesc.h	18 May 2019 12:59:32 -0000	1.38
+++ sys/net/bpfdesc.h	24 Oct 2019 18:58:05 -0000
@@ -93,6 +93,7 @@ struct bpf_d {
 	pid_t		bd_pgid;	/* process or group id for signal */
 	uid_t		bd_siguid;	/* uid for process that set pgid */
 	uid_t		bd_sigeuid;	/* euid for process that set pgid */
+	u_int		bd_ref;		/* reference count */
 	struct selinfo	bd_sel;		/* bsd select info */
 	int		bd_unit;	/* logical unit number */
 	LIST_ENTRY(bpf_d) bd_list;	/* descriptor list */
