diff options
author | Stefan Sperling <stsp@cvs.openbsd.org> | 2020-06-08 09:09:59 +0000 |
---|---|---|
committer | Stefan Sperling <stsp@cvs.openbsd.org> | 2020-06-08 09:09:59 +0000 |
commit | 500b5c9eb3172334815f826c5ee666a5e18ca84d (patch) | |
tree | bac0955df68a4ab258aed7fc79b0e236b00e8592 /sys/net80211 | |
parent | 77ac5fee71b6b751fa92e0f54c139279ab597df6 (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.c | 10 |
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); |