Commit f1940c57 authored by Johannes Berg's avatar Johannes Berg

cfg80211: hold BSS over association process

This fixes the potential issue that the BSS struct that we use
and later assign to wdev->current_bss is removed from the scan
list while associating.

Also warn when we don't have a BSS struct in connect_result
unless it's from a driver that only has the connect() API.
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 959867fa
...@@ -38,6 +38,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss, ...@@ -38,6 +38,7 @@ void cfg80211_rx_assoc_resp(struct net_device *dev, struct cfg80211_bss *bss,
* frame instead of reassoc. * frame instead of reassoc.
*/ */
if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) { if (cfg80211_sme_rx_assoc_resp(wdev, status_code)) {
cfg80211_unhold_bss(bss_from_pub(bss));
cfg80211_put_bss(wiphy, bss); cfg80211_put_bss(wiphy, bss);
return; return;
} }
...@@ -142,6 +143,7 @@ void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss) ...@@ -142,6 +143,7 @@ void cfg80211_assoc_timeout(struct net_device *dev, struct cfg80211_bss *bss)
nl80211_send_assoc_timeout(rdev, dev, bss->bssid, GFP_KERNEL); nl80211_send_assoc_timeout(rdev, dev, bss->bssid, GFP_KERNEL);
cfg80211_sme_assoc_timeout(wdev); cfg80211_sme_assoc_timeout(wdev);
cfg80211_unhold_bss(bss_from_pub(bss));
cfg80211_put_bss(wiphy, bss); cfg80211_put_bss(wiphy, bss);
} }
EXPORT_SYMBOL(cfg80211_assoc_timeout); EXPORT_SYMBOL(cfg80211_assoc_timeout);
...@@ -309,6 +311,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, ...@@ -309,6 +311,8 @@ int cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
goto out; goto out;
err = rdev_assoc(rdev, dev, req); err = rdev_assoc(rdev, dev, req);
if (!err)
cfg80211_hold_bss(bss_from_pub(req->bss));
out: out:
if (err) if (err)
......
...@@ -615,19 +615,24 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, ...@@ -615,19 +615,24 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
kfree(wdev->connect_keys); kfree(wdev->connect_keys);
wdev->connect_keys = NULL; wdev->connect_keys = NULL;
wdev->ssid_len = 0; wdev->ssid_len = 0;
if (bss) {
cfg80211_unhold_bss(bss_from_pub(bss));
cfg80211_put_bss(wdev->wiphy, bss); cfg80211_put_bss(wdev->wiphy, bss);
}
return; return;
} }
if (!bss) if (!bss) {
WARN_ON_ONCE(!wiphy_to_dev(wdev->wiphy)->ops->connect);
bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
wdev->ssid, wdev->ssid_len, wdev->ssid, wdev->ssid_len,
WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS,
WLAN_CAPABILITY_ESS); WLAN_CAPABILITY_ESS);
if (WARN_ON(!bss)) if (WARN_ON(!bss))
return; return;
cfg80211_hold_bss(bss_from_pub(bss)); cfg80211_hold_bss(bss_from_pub(bss));
}
wdev->current_bss = bss_from_pub(bss); wdev->current_bss = bss_from_pub(bss);
cfg80211_upload_connect_keys(wdev); cfg80211_upload_connect_keys(wdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment