summaryrefslogtreecommitdiffstats
path: root/sys/net/bpf.c
diff options
context:
space:
mode:
authorrwatson <rwatson@FreeBSD.org>2005-02-28 14:04:09 +0000
committerrwatson <rwatson@FreeBSD.org>2005-02-28 14:04:09 +0000
commit6ae9352b09bd5c0af855e71bbd9a6838d2950e02 (patch)
treee1e87cb88975d35417f1c94ef44a9e4c0d9d9614 /sys/net/bpf.c
parentba21b23c122a23109e176c3990b811bfa09878b7 (diff)
downloadFreeBSD-src-6ae9352b09bd5c0af855e71bbd9a6838d2950e02.zip
FreeBSD-src-6ae9352b09bd5c0af855e71bbd9a6838d2950e02.tar.gz
In bpf_setf(), protect against races between multiple user threads
attempting to change the BPF filter on a BPF descriptor at the same time: retrieve the old filter pointer under the same locked region as setting the new pointer. MFC after: 3 days
Diffstat (limited to 'sys/net/bpf.c')
-rw-r--r--sys/net/bpf.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index a9734ab..1381b06 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -947,11 +947,11 @@ bpf_setf(d, fp)
struct bpf_insn *fcode, *old;
u_int flen, size;
- old = d->bd_filter;
if (fp->bf_insns == NULL) {
if (fp->bf_len != 0)
return (EINVAL);
BPFD_LOCK(d);
+ old = d->bd_filter;
d->bd_filter = NULL;
reset_d(d);
BPFD_UNLOCK(d);
@@ -968,6 +968,7 @@ bpf_setf(d, fp)
if (copyin((caddr_t)fp->bf_insns, (caddr_t)fcode, size) == 0 &&
bpf_validate(fcode, (int)flen)) {
BPFD_LOCK(d);
+ old = d->bd_filter;
d->bd_filter = fcode;
reset_d(d);
BPFD_UNLOCK(d);
OpenPOWER on IntegriCloud