aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/mlme.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2013-06-19 07:05:42 -0400
committerJohannes Berg <johannes.berg@intel.com>2013-06-19 12:55:39 -0400
commit959867fa55d0cb55fb3d08656e5e62607167617f (patch)
treeaeac7b16c571f062380fa99508d64df7cc1f4565 /net/mac80211/mlme.c
parent86e8cf98de3e74bbfb0003501e0004bf1e5e2618 (diff)
cfg80211: require passing BSS struct back to cfg80211_assoc_timeout
Doing so will allow us to hold the BSS (not just ref it) over the association process, thus ensuring that it doesn't time out and gets invisible to the user (e.g. in 'iw wlan0 link'.) This also fixes a leak in mac80211 where it doesn't always release the BSS struct properly in all cases where calling this function. This leak was reported by Ben Greear. Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/mac80211/mlme.c')
-rw-r--r--net/mac80211/mlme.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 34d54fe81483..ae31968d42d3 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -2795,8 +2795,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
2795 if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) { 2795 if (!ieee80211_assoc_success(sdata, bss, mgmt, len)) {
2796 /* oops -- internal error -- send timeout for now */ 2796 /* oops -- internal error -- send timeout for now */
2797 ieee80211_destroy_assoc_data(sdata, false); 2797 ieee80211_destroy_assoc_data(sdata, false);
2798 cfg80211_put_bss(sdata->local->hw.wiphy, bss); 2798 cfg80211_assoc_timeout(sdata->dev, bss);
2799 cfg80211_assoc_timeout(sdata->dev, mgmt->bssid);
2800 return; 2799 return;
2801 } 2800 }
2802 sdata_info(sdata, "associated\n"); 2801 sdata_info(sdata, "associated\n");
@@ -3513,13 +3512,10 @@ void ieee80211_sta_work(struct ieee80211_sub_if_data *sdata)
3513 time_after(jiffies, ifmgd->assoc_data->timeout)) { 3512 time_after(jiffies, ifmgd->assoc_data->timeout)) {
3514 if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) || 3513 if ((ifmgd->assoc_data->need_beacon && !ifmgd->have_beacon) ||
3515 ieee80211_do_assoc(sdata)) { 3514 ieee80211_do_assoc(sdata)) {
3516 u8 bssid[ETH_ALEN]; 3515 struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
3517
3518 memcpy(bssid, ifmgd->assoc_data->bss->bssid, ETH_ALEN);
3519 3516
3520 ieee80211_destroy_assoc_data(sdata, false); 3517 ieee80211_destroy_assoc_data(sdata, false);
3521 3518 cfg80211_assoc_timeout(sdata->dev, bss);
3522 cfg80211_assoc_timeout(sdata->dev, bssid);
3523 } 3519 }
3524 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started) 3520 } else if (ifmgd->assoc_data && ifmgd->assoc_data->timeout_started)
3525 run_again(sdata, ifmgd->assoc_data->timeout); 3521 run_again(sdata, ifmgd->assoc_data->timeout);
@@ -4445,8 +4441,11 @@ void ieee80211_mgd_stop(struct ieee80211_sub_if_data *sdata)
4445 cancel_work_sync(&ifmgd->chswitch_work); 4441 cancel_work_sync(&ifmgd->chswitch_work);
4446 4442
4447 sdata_lock(sdata); 4443 sdata_lock(sdata);
4448 if (ifmgd->assoc_data) 4444 if (ifmgd->assoc_data) {
4445 struct cfg80211_bss *bss = ifmgd->assoc_data->bss;
4449 ieee80211_destroy_assoc_data(sdata, false); 4446 ieee80211_destroy_assoc_data(sdata, false);
4447 cfg80211_assoc_timeout(sdata->dev, bss);
4448 }
4450 if (ifmgd->auth_data) 4449 if (ifmgd->auth_data)
4451 ieee80211_destroy_auth_data(sdata, false); 4450 ieee80211_destroy_auth_data(sdata, false);
4452 del_timer_sync(&ifmgd->timer); 4451 del_timer_sync(&ifmgd->timer);