staging: wfx: fix potential dead lock between join and scan
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>
This commit is contained in:
parent
b3a71adf4d
commit
f214b7b6e7
@ -88,6 +88,11 @@ void wfx_hw_scan_work(struct work_struct *work)
|
|||||||
|
|
||||||
mutex_lock(&wvif->wdev->conf_mutex);
|
mutex_lock(&wvif->wdev->conf_mutex);
|
||||||
mutex_lock(&wvif->scan_lock);
|
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);
|
update_probe_tmpl(wvif, &hw_req->req);
|
||||||
chan_cur = 0;
|
chan_cur = 0;
|
||||||
do {
|
do {
|
||||||
|
@ -353,6 +353,7 @@ void wfx_reset(struct wfx_vif *wvif)
|
|||||||
if (wvif_count(wvif->wdev) <= 1)
|
if (wvif_count(wvif->wdev) <= 1)
|
||||||
hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
|
hif_set_block_ack_policy(wvif, 0xFF, 0xFF);
|
||||||
wfx_tx_unlock(wvif->wdev);
|
wfx_tx_unlock(wvif->wdev);
|
||||||
|
wvif->join_in_progress = false;
|
||||||
wvif->bss_not_support_ps_poll = false;
|
wvif->bss_not_support_ps_poll = false;
|
||||||
cancel_delayed_work_sync(&wvif->beacon_loss_work);
|
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);
|
wfx_set_mfp(wvif, bss);
|
||||||
cfg80211_put_bss(wvif->wdev->hw->wiphy, bss);
|
cfg80211_put_bss(wvif->wdev->hw->wiphy, bss);
|
||||||
|
|
||||||
|
wvif->join_in_progress = true;
|
||||||
ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen);
|
ret = hif_join(wvif, conf, wvif->channel, ssid, ssidlen);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
ieee80211_connection_loss(wvif->vif);
|
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,
|
static void wfx_join_finalize(struct wfx_vif *wvif,
|
||||||
struct ieee80211_bss_conf *info)
|
struct ieee80211_bss_conf *info)
|
||||||
{
|
{
|
||||||
|
wvif->join_in_progress = false;
|
||||||
hif_set_association_mode(wvif, info);
|
hif_set_association_mode(wvif, info);
|
||||||
hif_keep_alive_period(wvif, 0);
|
hif_keep_alive_period(wvif, 0);
|
||||||
// beacon_loss_count is defined to 7 in net/mac80211/mlme.c. Let's use
|
// beacon_loss_count is defined to 7 in net/mac80211/mlme.c. Let's use
|
||||||
|
@ -69,6 +69,8 @@ struct wfx_vif {
|
|||||||
u32 link_id_map;
|
u32 link_id_map;
|
||||||
|
|
||||||
bool after_dtim_tx_allowed;
|
bool after_dtim_tx_allowed;
|
||||||
|
bool join_in_progress;
|
||||||
|
|
||||||
struct delayed_work beacon_loss_work;
|
struct delayed_work beacon_loss_work;
|
||||||
|
|
||||||
struct tx_policy_cache tx_policy_cache;
|
struct tx_policy_cache tx_policy_cache;
|
||||||
|
Loading…
Reference in New Issue
Block a user