summaryrefslogtreecommitdiffstats
path: root/sys/net/bpf_buffer.c
diff options
context:
space:
mode:
authorghelmer <ghelmer@FreeBSD.org>2012-12-10 16:14:44 +0000
committerghelmer <ghelmer@FreeBSD.org>2012-12-10 16:14:44 +0000
commit726beb3d43000997e7410621a0c31a65b05ebb31 (patch)
tree05f79a3e8fd1361998dd0dc02f1088df035c8960 /sys/net/bpf_buffer.c
parent2160ff58527c3253bc5fe11f85c2e3d0fa680688 (diff)
downloadFreeBSD-src-726beb3d43000997e7410621a0c31a65b05ebb31.zip
FreeBSD-src-726beb3d43000997e7410621a0c31a65b05ebb31.tar.gz
Changes to resolve races in bpfread() and catchpacket() that, at worst,
cause kernel panics. Add a flag to the bpf descriptor to indicate whether the hold buffer is in use. In bpfread(), set the "hold buffer in use" flag before dropping the descriptor lock during the call to bpf_uiomove(). Everywhere else the hold buffer is used or changed, wait while the hold buffer is in use by bpfread(). Add a KASSERT in bpfread() after re-acquiring the descriptor lock to assist uncovering any additional hold buffer races.
Diffstat (limited to 'sys/net/bpf_buffer.c')
-rw-r--r--sys/net/bpf_buffer.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/sys/net/bpf_buffer.c b/sys/net/bpf_buffer.c
index 64bb982..74e1ae4 100644
--- a/sys/net/bpf_buffer.c
+++ b/sys/net/bpf_buffer.c
@@ -79,6 +79,8 @@ __FBSDID("$FreeBSD$");
#include <net/bpf_buffer.h>
#include <net/bpfdesc.h>
+#define PRINET 26 /* interruptible */
+
/*
* Implement historical kernel memory buffering model for BPF: two malloc(9)
* kernel buffers are hung off of the descriptor. The size is fixed prior to
@@ -189,6 +191,9 @@ bpf_buffer_ioctl_sblen(struct bpf_d *d, u_int *i)
return (EINVAL);
}
+ while (d->bd_hbuf_in_use)
+ mtx_sleep(&d->bd_hbuf_in_use, &d->bd_lock,
+ PRINET, "bd_hbuf", 0);
/* Free old buffers if set */
if (d->bd_fbuf != NULL)
free(d->bd_fbuf, M_BPF);
OpenPOWER on IntegriCloud