summaryrefslogtreecommitdiff
path: root/sys/net80211
diff options
context:
space:
mode:
authorStefan Sperling <stsp@cvs.openbsd.org>2020-06-08 09:09:59 +0000
committerStefan Sperling <stsp@cvs.openbsd.org>2020-06-08 09:09:59 +0000
commit500b5c9eb3172334815f826c5ee666a5e18ca84d (patch)
treebac0955df68a4ab258aed7fc79b0e236b00e8592 /sys/net80211
parent77ac5fee71b6b751fa92e0f54c139279ab597df6 (diff)
Undo pseudo-driver changes early in ieee80211_ifdetach() to prevent a
use-after-free when a wireless device is detached. Pseudo-driver detach hooks may end up calling back into the driver, e.g. via an ioctl. So these hooks must run before net80211 data structures are freed. Reported by ratchov@ who saw the following trace when athn(4) detached while it was part of a trunk(4) interface. The trunk(4) detach hooks were run after ieee80211_ifdetach() had been run by athn_detach(). These hooks called back into the driver via athn_ioctl() which now operated on freed memory. uvm_fault(0xffffffff81facdd0, 0xb14, 0, 1) -> e kernel: page fault trap, code=0 Stopped at ieee80211_ba_del+0x20: cmpl $0,0x2c(%r15) ddb{0}> ieee80211_ba_del(0) at ieee80211_ba_del+0x20 ieee80211_newstate(ffff8000000c1048,0,ffffffff) at ieee80211_newstate+0xb51 athn_stop(ffff8000000c1048,1) at athn_stop+0x70 athn_ioctl(ffff8000000c1048,80206910,ffff800014d63800) at athn_ioctl+0x15b ifnewlladdr(ffff8000000c1048) at ifnewlladdr+0x100 trunk_port_destroy(ffff800000589800) at trunk_port_destroy+0x320 if_hooks_run(ffff8000000c10b8) at if_hooks_run+0xb0 if_deactivate(ffff8000000c1048) at if_deactivate+0x24 ether_ifdetach(ffff8000000c1048) at ether_ifdetach+0x1d athn_detach(ffff8000000c1000) at athn_detach+0x17b athn_pci_detach(ffff8000000c1000,1) at athn_pci_detach+0x2a config_detach(ffff8000000c1000,1) at config_detach+0x156 config_detach_children(ffff8000000b7500,1) at config_detach_children+0x58 pci_detach_devices(ffff8000000b7500,1) at pci_detach_devices+0x24 ppb_hotplug_remove(ffff800000033e00) at ppb_hotplug_remove+0x35 taskq_thread(ffffffff81f4bd48) at ok mpi@ ratchov@
Diffstat (limited to 'sys/net80211')
-rw-r--r--sys/net80211/ieee80211.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c
index 1d9e875530e..e313d22d1a6 100644
--- a/sys/net80211/ieee80211.c
+++ b/sys/net80211/ieee80211.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ieee80211.c,v 1.83 2020/04/08 09:34:29 stsp Exp $ */
+/* $OpenBSD: ieee80211.c,v 1.84 2020/06/08 09:09:58 stsp Exp $ */
/* $NetBSD: ieee80211.c,v 1.19 2004/06/06 05:45:29 dyoung Exp $ */
/*-
@@ -204,6 +204,14 @@ ieee80211_ifdetach(struct ifnet *ifp)
struct ieee80211com *ic = (void *)ifp;
timeout_del(&ic->ic_bgscan_timeout);
+
+ /*
+ * Undo pseudo-driver changes. Pseudo-driver detach hooks could
+ * call back into the driver, e.g. via ioctl. So deactivate the
+ * interface before freeing net80211-specific data structures.
+ */
+ if_deactivate(ifp);
+
ieee80211_proto_detach(ifp);
ieee80211_crypto_detach(ifp);
ieee80211_node_detach(ifp);