summaryrefslogtreecommitdiffstats
path: root/sys/net/bpf_zerocopy.c
diff options
context:
space:
mode:
authormelifaro <melifaro@FreeBSD.org>2012-05-21 22:17:29 +0000
committermelifaro <melifaro@FreeBSD.org>2012-05-21 22:17:29 +0000
commit34ec5c86502577f86de209389836d93646d78b9b (patch)
tree90fdcda4302fb38114d697df37798071b681dc3e /sys/net/bpf_zerocopy.c
parent1c776bfa6e8c09481f7796562d3b3f95d7f76aa8 (diff)
downloadFreeBSD-src-34ec5c86502577f86de209389836d93646d78b9b.zip
FreeBSD-src-34ec5c86502577f86de209389836d93646d78b9b.tar.gz
Fix old panic when BPF consumer attaches to destroying interface.
'flags' field is added to the end of bpf_if structure. Currently the only flag is BPFIF_FLAG_DYING which is set on bpf detach and checked by bpf_attachd() Problem can be easily triggered on SMP stable/[89] by the following command (sort of): 'while true; do ifconfig vlan222 create vlan 222 vlandev em0 up ; tcpdump -pi vlan222 & ; ifconfig vlan222 destroy ; done' Fix possible use-after-free when BPF detaches itself from interface, freeing bpf_bif memory, while interface is still UP and there can be routes via this interface. Freeing is now delayed till ifnet_departure_event is received via eventhandler(9) api. Convert bpfd rwlock back to mutex due lack of performance gain (currently checking if packet matches filter is done without holding bpfd lock and we have to acquire write lock if packet matches) Approved by: kib(mentor) MFC in: 4 weeks
Diffstat (limited to 'sys/net/bpf_zerocopy.c')
-rw-r--r--sys/net/bpf_zerocopy.c10
1 files changed, 5 insertions, 5 deletions
diff --git a/sys/net/bpf_zerocopy.c b/sys/net/bpf_zerocopy.c
index b060f4d..1b32629 100644
--- a/sys/net/bpf_zerocopy.c
+++ b/sys/net/bpf_zerocopy.c
@@ -515,14 +515,14 @@ bpf_zerocopy_ioctl_rotzbuf(struct thread *td, struct bpf_d *d,
struct zbuf *bzh;
bzero(bz, sizeof(*bz));
- BPFD_WLOCK(d);
+ BPFD_LOCK(d);
if (d->bd_hbuf == NULL && d->bd_slen != 0) {
ROTATE_BUFFERS(d);
bzh = (struct zbuf *)d->bd_hbuf;
bz->bz_bufa = (void *)bzh->zb_uaddr;
bz->bz_buflen = d->bd_hlen;
}
- BPFD_WUNLOCK(d);
+ BPFD_UNLOCK(d);
return (0);
}
@@ -570,10 +570,10 @@ bpf_zerocopy_ioctl_setzbuf(struct thread *td, struct bpf_d *d,
* We only allow buffers to be installed once, so atomically check
* that no buffers are currently installed and install new buffers.
*/
- BPFD_WLOCK(d);
+ BPFD_LOCK(d);
if (d->bd_hbuf != NULL || d->bd_sbuf != NULL || d->bd_fbuf != NULL ||
d->bd_bif != NULL) {
- BPFD_WUNLOCK(d);
+ BPFD_UNLOCK(d);
zbuf_free(zba);
zbuf_free(zbb);
return (EINVAL);
@@ -593,6 +593,6 @@ bpf_zerocopy_ioctl_setzbuf(struct thread *td, struct bpf_d *d,
* shared management region.
*/
d->bd_bufsize = bz->bz_buflen - sizeof(struct bpf_zbuf_header);
- BPFD_WUNLOCK(d);
+ BPFD_UNLOCK(d);
return (0);
}
OpenPOWER on IntegriCloud