staging: wfx: fix potential dead lock between join and scan
authorJérôme Pouiller <jerome.pouiller@silabs.com>
Fri, 15 May 2020 08:33:19 +0000 (10:33 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 15 May 2020 14:00:53 +0000 (16:00 +0200)
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 <jerome.pouiller@silabs.com>
Link: https://lore.kernel.org/r/20200515083325.378539-14-Jerome.Pouiller@silabs.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/wfx/scan.c
drivers/staging/wfx/sta.c
drivers/staging/wfx/wfx.h

index 76761e4..ef411bc 100644 (file)
@@ -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 {
index 7d9f680..6e9f38d 100644 (file)
@@ -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
index 09a2456..cc9f7d1 100644 (file)
@@ -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;