From 94c78cb4523c246ec37959436f04e7c946f7494b Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 May 2015 11:31:47 +0200 Subject: mac80211: fix memory leak My recent change here introduced a possible memory leak if the driver registers an invalid cipher schemes. This won't really happen in practice, but fix the leak nonetheless. Fixes: e3a55b5399d55 ("mac80211: validate cipher scheme PN length better") Signed-off-by: Johannes Berg --- net/mac80211/main.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'net/mac80211') diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 3c956c5f99b2..99d27babd9f0 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -770,8 +770,10 @@ static int ieee80211_init_cipher_suites(struct ieee80211_local *local) for (r = 0; r < local->hw.n_cipher_schemes; r++) { suites[w++] = cs[r].cipher; - if (WARN_ON(cs[r].pn_len > IEEE80211_MAX_PN_LEN)) + if (WARN_ON(cs[r].pn_len > IEEE80211_MAX_PN_LEN)) { + kfree(suites); return -EINVAL; + } } } -- cgit v1.2.3 From 464daaf04cb633ae1530652fd23cdea0f0d21dd5 Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Tue, 19 May 2015 14:13:36 +0200 Subject: mac80211: check fast-xmit on station change Drivers with fast-xmit (e.g. ath10k) running in AP_VLAN setups would fail to communicate with connected 4addr stations. The reason was when new station associates it first goes into master AP interface. It is not until later that a dedicated AP_VLAN is created for it and the station itself is moved there. After that Tx directed at the station should use 4addr header. However fast-xmit wasn't recalculated and 3addr header remained to be used. This in turn caused the connected 4addr stations to drop packets coming from the AP until some other event would cause fast-xmit to recalculate for that station (which could never come). Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/mac80211/cfg.c | 1 + 1 file changed, 1 insertion(+) (limited to 'net/mac80211') diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c index 3469bbdc891c..bb9f83640b46 100644 --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c @@ -1411,6 +1411,7 @@ static int ieee80211_change_station(struct wiphy *wiphy, } sta->sdata = vlansdata; + ieee80211_check_fast_xmit(sta); if (sta->sta_state == IEEE80211_STA_AUTHORIZED && prev_4addr != new_4addr) { -- cgit v1.2.3 From c5a71688e1e56e155fb79b8d699322f4f0793cc8 Mon Sep 17 00:00:00 2001 From: Arik Nemtsov Date: Tue, 19 May 2015 14:36:48 +0300 Subject: mac80211: disconnect TDLS stations on STA CSA When a station does a channel switch, it's not well defined what its TDLS peers would do. Avoid a situation when the local side marks a potentially disconnected peer as a TDLS peer. Keeping peers connected through CSA is doubly problematic with the upcoming TDLS WIDER-BW feature which allows peers to widen the BSS channel. The new channel transitioned-to might not be compatible and would require a re-negotiation anyway. Make sure to disallow new TDLS link during CSA. Signed-off-by: Arik Nemtsov Signed-off-by: Emmanuel Grumbach Signed-off-by: Johannes Berg --- net/mac80211/mlme.c | 26 ++++++++++++++++++++++++++ net/mac80211/tdls.c | 6 ++++++ 2 files changed, 32 insertions(+) (limited to 'net/mac80211') diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 3294666f599c..387fe70ab126 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1098,6 +1098,24 @@ static void ieee80211_chswitch_timer(unsigned long data) ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.chswitch_work); } +static void ieee80211_teardown_tdls_peers(struct ieee80211_sub_if_data *sdata) +{ + struct sta_info *sta; + u16 reason = WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED; + + rcu_read_lock(); + list_for_each_entry_rcu(sta, &sdata->local->sta_list, list) { + if (!sta->sta.tdls || sta->sdata != sdata || !sta->uploaded || + !test_sta_flag(sta, WLAN_STA_AUTHORIZED)) + continue; + + ieee80211_tdls_oper_request(&sdata->vif, sta->sta.addr, + NL80211_TDLS_TEARDOWN, reason, + GFP_ATOMIC); + } + rcu_read_unlock(); +} + static void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, u64 timestamp, u32 device_timestamp, @@ -1161,6 +1179,14 @@ ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, return; } + /* + * Drop all TDLS peers - either we disconnect or move to a different + * channel from this point on. There's no telling what our peer will do. + * The TDLS WIDER_BW scenario is also problematic, as peers might now + * have an incompatible wider chandef. + */ + ieee80211_teardown_tdls_peers(sdata); + mutex_lock(&local->mtx); mutex_lock(&local->chanctx_mtx); conf = rcu_dereference_protected(sdata->vif.chanctx_conf, diff --git a/net/mac80211/tdls.c b/net/mac80211/tdls.c index 8a92a920ff17..75e8e3bba538 100644 --- a/net/mac80211/tdls.c +++ b/net/mac80211/tdls.c @@ -1183,6 +1183,12 @@ int ieee80211_tdls_oper(struct wiphy *wiphy, struct net_device *dev, switch (oper) { case NL80211_TDLS_ENABLE_LINK: + if (sdata->vif.csa_active) { + tdls_dbg(sdata, "TDLS: disallow link during CSA\n"); + ret = -EBUSY; + break; + } + rcu_read_lock(); sta = sta_info_get(sdata, peer); if (!sta) { -- cgit v1.2.3 From ab499db80fcf07c18e4053f91a619500f663e90e Mon Sep 17 00:00:00 2001 From: Michal Kazior Date: Fri, 22 May 2015 10:22:40 +0200 Subject: mac80211: prevent possible crypto tx tailroom corruption There was a possible race between ieee80211_reconfig() and ieee80211_delayed_tailroom_dec(). This could result in inability to transmit data if driver crashed during roaming or rekeying and subsequent skbs with insufficient tailroom appeared. This race was probably never seen in the wild because a device driver would have to crash AND recover within 0.5s which is very unlikely. I was able to prove this race exists after changing the delay to 10s locally and crashing ath10k via debugfs immediately after GTK rekeying. In case of ath10k the counter went below 0. This was harmless but other drivers which actually require tailroom (e.g. for WEP ICV or MMIC) could end up with the counter at 0 instead of >0 and introduce insufficient skb tailroom failures because mac80211 would not resize skbs appropriately anymore. Fixes: 8d1f7ecd2af5 ("mac80211: defer tailroom counter manipulation when roaming") Signed-off-by: Michal Kazior Signed-off-by: Johannes Berg --- net/mac80211/main.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'net/mac80211') diff --git a/net/mac80211/main.c b/net/mac80211/main.c index 99d27babd9f0..674164fe5cdb 100644 --- a/net/mac80211/main.c +++ b/net/mac80211/main.c @@ -246,6 +246,7 @@ static void ieee80211_restart_work(struct work_struct *work) { struct ieee80211_local *local = container_of(work, struct ieee80211_local, restart_work); + struct ieee80211_sub_if_data *sdata; /* wait for scan work complete */ flush_workqueue(local->workqueue); @@ -254,6 +255,8 @@ static void ieee80211_restart_work(struct work_struct *work) "%s called with hardware scan in progress\n", __func__); rtnl_lock(); + list_for_each_entry(sdata, &local->interfaces, list) + flush_delayed_work(&sdata->dec_tailroom_needed_wk); ieee80211_scan_cancel(local); ieee80211_reconfig(local); rtnl_unlock(); -- cgit v1.2.3