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 */