summaryrefslogtreecommitdiffstats
path: root/sys/net/bpfdesc.h
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/bpfdesc.h
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/bpfdesc.h')
-rw-r--r--sys/net/bpfdesc.h13
1 files changed, 6 insertions, 7 deletions
diff --git a/sys/net/bpfdesc.h b/sys/net/bpfdesc.h
index f01a0e1..6d58cc3 100644
--- a/sys/net/bpfdesc.h
+++ b/sys/net/bpfdesc.h
@@ -88,7 +88,7 @@ struct bpf_d {
int bd_sig; /* signal to send upon packet reception */
struct sigio * bd_sigio; /* information for async I/O */
struct selinfo bd_sel; /* bsd select info */
- struct rwlock bd_lock; /* per-descriptor lock */
+ struct mtx bd_lock; /* per-descriptor lock */
struct callout bd_callout; /* for BPF timeouts with select */
struct label *bd_label; /* MAC label for descriptor */
u_int64_t bd_fcount; /* number of packets which matched filter */
@@ -107,12 +107,9 @@ struct bpf_d {
#define BPF_WAITING 1 /* waiting for read timeout in select */
#define BPF_TIMED_OUT 2 /* read timeout has expired in select */
-#define BPFD_RLOCK(bd) rw_rlock(&(bd)->bd_lock)
-#define BPFD_RUNLOCK(bd) rw_runlock(&(bd)->bd_lock)
-#define BPFD_WLOCK(bd) rw_wlock(&(bd)->bd_lock)
-#define BPFD_WUNLOCK(bd) rw_wunlock(&(bd)->bd_lock)
-#define BPFD_WLOCK_ASSERT(bd) rw_assert(&(bd)->bd_lock, RA_WLOCKED)
-#define BPFD_LOCK_ASSERT(bd) rw_assert(&(bd)->bd_lock, RA_LOCKED)
+#define BPFD_LOCK(bd) mtx_lock(&(bd)->bd_lock)
+#define BPFD_UNLOCK(bd) mtx_unlock(&(bd)->bd_lock)
+#define BPFD_LOCK_ASSERT(bd) mtx_assert(&(bd)->bd_lock, MA_OWNED)
#define BPF_PID_REFRESH(bd, td) (bd)->bd_pid = (td)->td_proc->p_pid
#define BPF_PID_REFRESH_CUR(bd) (bd)->bd_pid = curthread->td_proc->p_pid
@@ -159,4 +156,6 @@ struct xbpf_d {
#define BPFIF_WLOCK(bif) rw_wlock(&(bif)->bif_lock)
#define BPFIF_WUNLOCK(bif) rw_wunlock(&(bif)->bif_lock)
+#define BPFIF_FLAG_DYING 1 /* Reject new bpf consumers */
+
#endif
OpenPOWER on IntegriCloud