diff --git a/sys/netproto/802_11/wlan/ieee80211_scan_sw.c b/sys/netproto/802_11/wlan/ieee80211_scan_sw.c --- a/sys/netproto/802_11/wlan/ieee80211_scan_sw.c +++ b/sys/netproto/802_11/wlan/ieee80211_scan_sw.c @@ -762,6 +762,22 @@ /* XXX scan state can change! Re-validate scan state! */ + /* + * The vap may have been detached (and ss_vap/ss_ops cleared by + * ieee80211_scan_vdetach under IEEE80211_LOCK) while the lock + * was dropped above for ic_set_channel / radiotap_chan_change / + * ic_scan_curchan. Bail straight through scan_done() instead of + * dereferencing a NULL vap via the DPRINTF/scan_end/scan_done + * paths (which would otherwise fault at the loop-top DPRINTF on + * IEEE80211_DEBUG kernels, or in scan_done on any kernel). + */ + if (ss->ss_vap == NULL || ss->ss_ops == NULL) { + ss_priv->ss_iflags &= ~ISCAN_RUNNING; + ss_priv->ss_iflags |= ISCAN_ABORT; + scan_done(ss, 1); + return; + } + ss_priv->ss_chanmindwell = ticks + ss->ss_mindwell; /* clear mindwell lock and initial channel change flush */ ss_priv->ss_iflags &= ~ISCAN_REP; @@ -908,7 +924,11 @@ * save mode because the beacon indicates we have frames * waiting for us. */ - if (scandone) { + /* + * vap may be NULL if we got here via the scan_curchan_task + * re-validation bail-out after the owning vap was detached. + */ + if (scandone && vap != NULL) { /* * If we're not a scan offload device, come back out of * station powersave. Offload devices handle this themselves.