From f214b7b6e7c959b4306df8e5c687887c547e38b6 Mon Sep 17 00:00:00 2001 From: =?utf8?q?J=C3=A9r=C3=B4me=20Pouiller?= Date: Fri, 15 May 2020 10:33:19 +0200 Subject: [PATCH] staging: wfx: fix potential dead lock between join and scan MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The device disallows to start a scan request between hif_join() and hif_set_bss_params(). The driver is not protected against that. The worst case happens when association is aborted and hif_set_bss_params() never happens. mac80211 would never ask for scan during the association process. So, this patch just aborts the association in progress when scan is requested. Signed-off-by: Jérôme Pouiller Link: https://lore.kernel.org/r/20200515083325.378539-14-Jerome.Pouiller@silabs.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wfx/scan.c | 5 +++++ drivers/staging/wfx/sta.c | 3 +++ drivers/staging/wfx/wfx.h | 2 ++ 3 files changed, 10 insertions(+) diff --git a/drivers/staging/wfx/scan.c b/drivers/staging/wfx/scan.c index 76761e4..ef411bc 100644 --- a/drivers/staging/wfx/scan.c +++ b/drivers/staging/wfx/scan.c @@ -88,6 +88,11 @@ void wfx_hw_scan_work(struct work_struct *work) mutex_lock(&wvif->wdev->conf_mutex); mutex_lock(&wvif->scan_lock); + if (wvif->join_in_progress) { + dev_info(wvif->wdev->dev, "%s: abort in-progress REQ_JOIN", + __func__); + wfx_reset(wvif); + } update_probe_tmpl(wvif, &hw_req->req); chan_cur = 0; do { diff --git a/drivers/staging/wfx/sta.c b/drivers/staging/wfx/sta.c index 7d9f680..6e9f38d 100644 --- a/drivers/staging/wfx/sta.c +++ b/drivers/staging/wfx/sta.c @@ -353,6 +353,7 @@ void wfx_reset(struct wfx_vif *wvif) if (wvif_count(wvif->wdev) <= 1) hif_set_block_ack_policy(wvif, 0xFF, 0xFF); wfx_tx_unlock(wvif->wdev); + wvif->join_in_progress = false; wvif->bss_not_support_ps_poll = false; cancel_delayed_work_sync(&wvif->beacon_loss_work); } @@ -390,6 +391,7 @@ static void wfx_do_join(struct wfx_vif *wvif) wfx_set_mfp(wvif, bss); cfg80211_put_bss(wvif->wdev->hw->wiphy, bss); + wvif->join_in_progress = true; ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen); if (ret) { ieee80211_connection_loss(wvif->vif); @@ -485,6 +487,7 @@ void wfx_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif) static void wfx_join_finalize(struct wfx_vif *wvif, struct ieee80211_bss_conf *info) { + wvif->join_in_progress = false; hif_set_association_mode(wvif, info); hif_keep_alive_period(wvif, 0); // beacon_loss_count is defined to 7 in net/mac80211/mlme.c. Let's use diff --git a/drivers/staging/wfx/wfx.h b/drivers/staging/wfx/wfx.h index 09a2456..cc9f7d1 100644 --- a/drivers/staging/wfx/wfx.h +++ b/drivers/staging/wfx/wfx.h @@ -69,6 +69,8 @@ struct wfx_vif { u32 link_id_map; bool after_dtim_tx_allowed; + bool join_in_progress; + struct delayed_work beacon_loss_work; struct tx_policy_cache tx_policy_cache; -- 2.7.4