summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2024-11-17 12:21:49 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2024-11-17 12:21:49 +0000
commit4ecbbc09b86badfd4a091455e0cfb5d77d931c4b (patch)
treec64dba9695caa935c201672f52501448e4f64ba4
parentb35763eebd3158c664a4430599eff4543aa370de (diff)
make sure bpfsdetach is holding a bpf_d ref when invalidating stuff.
when bpfsdetach is called by an interface being destroyed, it iterates over the bpf descriptors using the interface and calls vdevgone and klist_invalidate against them. however, i'm not sure the reference the interface holds against the bpf_d is accounted for properly, so vdevgone might drop it to 0 and free it, which makes the klist_invalidate a use after free. avoid this by taking a bpf_d ref before calling vdevgone and klist_invalidate so the memory can't be freed out from under the feet of bpfsdetach. Reported-by: syzbot+b3927f8ad162452a2f39@syzkaller.appspotmail.com i wasn't able to reproduce whatever syzkaller did. it's possible this is a double free, but we'll wait and see if it pops up again. ok mpi@
-rw-r--r--sys/net/bpf.c4
1 files changed, 3 insertions, 1 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index d77ad57ace4..41f62b6584f 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: bpf.c,v 1.225 2024/08/15 12:20:20 dlg Exp $ */
+/* $OpenBSD: bpf.c,v 1.226 2024/11/17 12:21:48 dlg Exp $ */
/* $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */
/*
@@ -1798,8 +1798,10 @@ bpfsdetach(void *p)
break;
while ((bd = SMR_SLIST_FIRST_LOCKED(&bp->bif_dlist))) {
+ bpf_get(bd);
vdevgone(maj, bd->bd_unit, bd->bd_unit, VCHR);
klist_invalidate(&bd->bd_klist);
+ bpf_put(bd);
}
for (tbp = bpf_iflist; tbp; tbp = tbp->bif_next) {