| From: Jouni Malinen <jouni@codeaurora.org> |
| Date: Wed, 11 Sep 2019 16:03:05 +0300 |
| Subject: mac80211: Do not send Layer 2 Update frame before authorization |
| |
| commit 3e493173b7841259a08c5c8e5cbe90adb349da7e upstream. |
| |
| The Layer 2 Update frame is used to update bridges when a station roams |
| to another AP even if that STA does not transmit any frames after the |
| reassociation. This behavior was described in IEEE Std 802.11F-2003 as |
| something that would happen based on MLME-ASSOCIATE.indication, i.e., |
| before completing 4-way handshake. However, this IEEE trial-use |
| recommended practice document was published before RSN (IEEE Std |
| 802.11i-2004) and as such, did not consider RSN use cases. Furthermore, |
| IEEE Std 802.11F-2003 was withdrawn in 2006 and as such, has not been |
| maintained amd should not be used anymore. |
| |
| Sending out the Layer 2 Update frame immediately after association is |
| fine for open networks (and also when using SAE, FT protocol, or FILS |
| authentication when the station is actually authenticated by the time |
| association completes). However, it is not appropriate for cases where |
| RSN is used with PSK or EAP authentication since the station is actually |
| fully authenticated only once the 4-way handshake completes after |
| authentication and attackers might be able to use the unauthenticated |
| triggering of Layer 2 Update frame transmission to disrupt bridge |
| behavior. |
| |
| Fix this by postponing transmission of the Layer 2 Update frame from |
| station entry addition to the point when the station entry is marked |
| authorized. Similarly, send out the VLAN binding update only if the STA |
| entry has already been authorized. |
| |
| Signed-off-by: Jouni Malinen <jouni@codeaurora.org> |
| Reviewed-by: Johannes Berg <johannes@sipsolutions.net> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| [bwh: Backported to 3.16: adjust context] |
| Signed-off-by: Ben Hutchings <ben@decadent.org.uk> |
| --- |
| net/mac80211/cfg.c | 11 +++-------- |
| net/mac80211/sta_info.c | 4 ++++ |
| 2 files changed, 7 insertions(+), 8 deletions(-) |
| |
| --- a/net/mac80211/cfg.c |
| +++ b/net/mac80211/cfg.c |
| @@ -1436,7 +1436,6 @@ static int ieee80211_add_station(struct |
| struct sta_info *sta; |
| struct ieee80211_sub_if_data *sdata; |
| int err; |
| - int layer2_update; |
| |
| if (params->vlan) { |
| sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); |
| @@ -1481,18 +1480,12 @@ static int ieee80211_add_station(struct |
| if (!test_sta_flag(sta, WLAN_STA_TDLS_PEER)) |
| rate_control_rate_init(sta); |
| |
| - layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
| - sdata->vif.type == NL80211_IFTYPE_AP; |
| - |
| err = sta_info_insert_rcu(sta); |
| if (err) { |
| rcu_read_unlock(); |
| return err; |
| } |
| |
| - if (layer2_update) |
| - cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr); |
| - |
| rcu_read_unlock(); |
| |
| return 0; |
| @@ -1596,7 +1589,9 @@ static int ieee80211_change_station(stru |
| atomic_inc(&sta->sdata->bss->num_mcast_sta); |
| } |
| |
| - cfg80211_send_layer2_update(sta->sdata->dev, sta->sta.addr); |
| + if (sta->sta_state == IEEE80211_STA_AUTHORIZED) |
| + cfg80211_send_layer2_update(sta->sdata->dev, |
| + sta->sta.addr); |
| } |
| |
| err = sta_apply_parameters(local, sta, params); |
| --- a/net/mac80211/sta_info.c |
| +++ b/net/mac80211/sta_info.c |
| @@ -1666,6 +1666,10 @@ int sta_info_move_state(struct sta_info |
| atomic_inc(&sta->sdata->bss->num_mcast_sta); |
| set_bit(WLAN_STA_AUTHORIZED, &sta->_flags); |
| } |
| + if (sta->sdata->vif.type == NL80211_IFTYPE_AP_VLAN || |
| + sta->sdata->vif.type == NL80211_IFTYPE_AP) |
| + cfg80211_send_layer2_update(sta->sdata->dev, |
| + sta->sta.addr); |
| break; |
| default: |
| break; |