Commit 2d6e4e76 authored by Luciano Coelho's avatar Luciano Coelho

wl12xx: lock the RCU when accessing sta via ieee80211_find_sta()

We were calling ieee80211_find_sta() and the sta returned by it
without locking the RCU, which is required by mac80211.

Fix this and reorganize slightly the area of the code where the sta is
used.
Reported-by: default avatarJonathan DE CESCO <jonathanc@ti.com>
Signed-off-by: default avatarLuciano Coelho <coelho@ti.com>
parent a8aaaf53
...@@ -2219,7 +2219,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, ...@@ -2219,7 +2219,7 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
bool do_join = false, set_assoc = false; bool do_join = false, set_assoc = false;
bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS); bool is_ibss = (wl->bss_type == BSS_TYPE_IBSS);
int ret; int ret;
struct ieee80211_sta *sta = ieee80211_find_sta(vif, bss_conf->bssid); struct ieee80211_sta *sta;
if (is_ibss) { if (is_ibss) {
ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf, ret = wl1271_bss_beacon_info_changed(wl, vif, bss_conf,
...@@ -2378,36 +2378,42 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl, ...@@ -2378,36 +2378,42 @@ static void wl1271_bss_info_changed_sta(struct wl1271 *wl,
if (ret < 0) if (ret < 0)
goto out; goto out;
/* rcu_read_lock();
* Takes care of: New association with HT enable, sta = ieee80211_find_sta(vif, bss_conf->bssid);
* HT information change in beacon. if (sta) {
*/ /* handle new association with HT and HT information change */
if (sta && if ((changed & BSS_CHANGED_HT) &&
(changed & BSS_CHANGED_HT) && (bss_conf->channel_type != NL80211_CHAN_NO_HT)) {
(bss_conf->channel_type != NL80211_CHAN_NO_HT)) { ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, true); true);
if (ret < 0) { if (ret < 0) {
wl1271_warning("Set ht cap true failed %d", ret); wl1271_warning("Set ht cap true failed %d",
goto out; ret);
} rcu_read_unlock();
goto out;
}
ret = wl1271_acx_set_ht_information(wl, ret = wl1271_acx_set_ht_information(wl,
bss_conf->ht_operation_mode); bss_conf->ht_operation_mode);
if (ret < 0) { if (ret < 0) {
wl1271_warning("Set ht information failed %d", ret); wl1271_warning("Set ht information failed %d",
goto out; ret);
rcu_read_unlock();
goto out;
}
} }
} /* handle new association without HT and disassociation */
/* else if (changed & BSS_CHANGED_ASSOC) {
* Takes care of: New association without HT, ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap,
* Disassociation. false);
*/ if (ret < 0) {
else if (sta && (changed & BSS_CHANGED_ASSOC)) { wl1271_warning("Set ht cap false failed %d",
ret = wl1271_acx_set_ht_capabilities(wl, &sta->ht_cap, false); ret);
if (ret < 0) { rcu_read_unlock();
wl1271_warning("Set ht cap false failed %d", ret); goto out;
goto out; }
} }
} }
rcu_read_unlock();
if (changed & BSS_CHANGED_ARP_FILTER) { if (changed & BSS_CHANGED_ARP_FILTER) {
__be32 addr = bss_conf->arp_addr_list[0]; __be32 addr = bss_conf->arp_addr_list[0];
......
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