From 86a1b9d7c275a3dba69e7ab099f8d5f71f69f6a8 Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Mon, 22 Jun 2020 14:35:42 +0200 Subject: mac80211: fix control port tx status check The initial control port tx status patch assumed, that we have IEEE 802.11 frames, but actually ethernet frames are stored in the ack skb. Fix this by checking for the correct ethertype and skb protocol 802.3. Also allow tx status reports for ETH_P_PREAUTH, as preauth frames can also be send over the nl80211 control port. Fixes: a7528198add8 ("mac80211: support control port TX status reporting") Reported-by: Jouni Malinen Signed-off-by: Markus Theil Reported-by: kernel test robot Link: https://lore.kernel.org/r/20200622123542.173695-1-markus.theil@tu-ilmenau.de Signed-off-by: Johannes Berg --- net/mac80211/status.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'net') diff --git a/net/mac80211/status.c b/net/mac80211/status.c index 7b1bacac39c6..cbc40b358ba2 100644 --- a/net/mac80211/status.c +++ b/net/mac80211/status.c @@ -639,11 +639,23 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local, u64 cookie = IEEE80211_SKB_CB(skb)->ack.cookie; struct ieee80211_sub_if_data *sdata; struct ieee80211_hdr *hdr = (void *)skb->data; + __be16 ethertype = 0; + + if (skb->len >= ETH_HLEN && skb->protocol == cpu_to_be16(ETH_P_802_3)) + skb_copy_bits(skb, 2 * ETH_ALEN, ðertype, ETH_TLEN); rcu_read_lock(); sdata = ieee80211_sdata_from_skb(local, skb); if (sdata) { - if (ieee80211_is_any_nullfunc(hdr->frame_control)) + if (ethertype == sdata->control_port_protocol || + ethertype == cpu_to_be16(ETH_P_PREAUTH)) + cfg80211_control_port_tx_status(&sdata->wdev, + cookie, + skb->data, + skb->len, + acked, + GFP_ATOMIC); + else if (ieee80211_is_any_nullfunc(hdr->frame_control)) cfg80211_probe_status(sdata->dev, hdr->addr1, cookie, acked, info->status.ack_signal, @@ -654,12 +666,8 @@ static void ieee80211_report_ack_skb(struct ieee80211_local *local, skb->data, skb->len, acked, GFP_ATOMIC); else - cfg80211_control_port_tx_status(&sdata->wdev, - cookie, - skb->data, - skb->len, - acked, - GFP_ATOMIC); + pr_warn("Unknown status report in ack skb\n"); + } rcu_read_unlock(); -- cgit v1.2.3 From 01da2e059dc326d02091a62b81a795a393e3719f Mon Sep 17 00:00:00 2001 From: Pavel Machek Date: Thu, 4 Jun 2020 23:41:57 +0200 Subject: mac80211: simplify mesh code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Doing mod_timer() conditionaly is easier than conditionally unlocking and jumping around... Signed-off-by: Pavel Machek (CIP) Acked-by: Linus Lüssing Link: https://lore.kernel.org/r/20200604214157.GA9737@amd Signed-off-by: Johannes Berg --- net/mac80211/mesh_hwmp.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) (limited to 'net') diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c index aa5150929996..02cde0fd08fe 100644 --- a/net/mac80211/mesh_hwmp.c +++ b/net/mac80211/mesh_hwmp.c @@ -1105,11 +1105,8 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata) ttl, lifetime, 0, ifmsh->preq_id++, sdata); spin_lock_bh(&mpath->state_lock); - if (mpath->flags & MESH_PATH_DELETED) { - spin_unlock_bh(&mpath->state_lock); - goto enddiscovery; - } - mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); + if (!(mpath->flags & MESH_PATH_DELETED)) + mod_timer(&mpath->timer, jiffies + mpath->discovery_timeout); spin_unlock_bh(&mpath->state_lock); enddiscovery: -- cgit v1.2.3 From 78fb5b541b7ae57ac39187ccb3097e606004cf9b Mon Sep 17 00:00:00 2001 From: Seevalamuthu Mariappan Date: Tue, 9 Jun 2020 15:45:54 +0530 Subject: mac80211: Fix dropping broadcast packets in 802.11 encap Broadcast pkts like arp are getting dropped in 'ieee80211_8023_xmit'. Fix this by replacing is_valid_ether_addr api with is_zero_ether_addr. Fixes: 50ff477a8639 ("mac80211: add 802.11 encapsulation offloading support") Signed-off-by: Seevalamuthu Mariappan Link: https://lore.kernel.org/r/1591697754-4975-1-git-send-email-seevalam@codeaurora.org Signed-off-by: Johannes Berg --- net/mac80211/tx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e9ce658141f5..3374df016c58 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -4206,7 +4206,7 @@ static void ieee80211_8023_xmit(struct ieee80211_sub_if_data *sdata, (!sta || !test_sta_flag(sta, WLAN_STA_TDLS_PEER))) ra = sdata->u.mgd.bssid; - if (!is_valid_ether_addr(ra)) + if (is_zero_ether_addr(ra)) goto out_free; multicast = is_multicast_ether_addr(ra); -- cgit v1.2.3 From 5af7fef39d7952c0f5551afa7b821ee7b6c9dd3d Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Wed, 17 Jun 2020 10:26:36 +0200 Subject: mac80211: skip mpath lookup also for control port tx When using 802.1X over mesh networks, at first an ordinary mesh peering is established, then the 802.1X EAPOL dialog happens, afterwards an authenticated mesh peering exchange (AMPE) happens, finally the peering is complete and we can set the STA authorized flag. As 802.1X is an intermediate step here and key material is not yet exchanged for stations we have to skip mesh path lookup for these EAPOL frames. Otherwise the already configure mesh group encryption key would be used to send a mesh path request which no one can decipher, because we didn't already establish key material on both peers, like with SAE and directly using AMPE. Signed-off-by: Markus Theil Link: https://lore.kernel.org/r/20200617082637.22670-2-markus.theil@tu-ilmenau.de [remove pointless braces, remove unnecessary local variable, the list can only process one such frame (or its fragments)] Signed-off-by: Johannes Berg --- net/mac80211/tx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index 3374df016c58..1a2941e5244f 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3996,6 +3996,9 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, skb_list_walk_safe(skb, skb, next) { skb_mark_not_on_list(skb); + if (skb->protocol == sdata->control_port_protocol) + ctrl_flags |= IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP; + skb = ieee80211_build_hdr(sdata, skb, info_flags, sta, ctrl_flags, cookie); if (IS_ERR(skb)) { @@ -5371,7 +5374,8 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, return -EINVAL; if (proto == sdata->control_port_protocol) - ctrl_flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO; + ctrl_flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO | + IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP; if (unencrypted) flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; -- cgit v1.2.3 From 0b467b63870d9c05c81456aa9bfee894ab2db3b6 Mon Sep 17 00:00:00 2001 From: Markus Theil Date: Thu, 25 Jun 2020 12:42:14 +0200 Subject: mac80211: allow rx of mesh eapol frames with default rx key Without this patch, eapol frames cannot be received in mesh mode, when 802.1X should be used. Initially only a MGTK is defined, which is found and set as rx->key, when there are no other keys set. ieee80211_drop_unencrypted would then drop these eapol frames, as they are data frames without encryption and there exists some rx->key. Fix this by differentiating between mesh eapol frames and other data frames with existing rx->key. Allow mesh mesh eapol frames only if they are for our vif address. With this patch in-place, ieee80211_rx_h_mesh_fwding continues after the ieee80211_drop_unencrypted check and notices, that these eapol frames have to be delivered locally, as they should. Signed-off-by: Markus Theil Link: https://lore.kernel.org/r/20200625104214.50319-1-markus.theil@tu-ilmenau.de [small code cleanups] Signed-off-by: Johannes Berg --- net/mac80211/rx.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) (limited to 'net') diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index a88ab6fb16f2..5c5af4b5fc08 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c @@ -2396,6 +2396,7 @@ static int ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx) static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) { + struct ieee80211_hdr *hdr = (void *)rx->skb->data; struct sk_buff *skb = rx->skb; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); @@ -2406,6 +2407,31 @@ static int ieee80211_drop_unencrypted(struct ieee80211_rx_data *rx, __le16 fc) if (status->flag & RX_FLAG_DECRYPTED) return 0; + /* check mesh EAPOL frames first */ + if (unlikely(rx->sta && ieee80211_vif_is_mesh(&rx->sdata->vif) && + ieee80211_is_data(fc))) { + struct ieee80211s_hdr *mesh_hdr; + u16 hdr_len = ieee80211_hdrlen(fc); + u16 ethertype_offset; + __be16 ethertype; + + if (!ether_addr_equal(hdr->addr1, rx->sdata->vif.addr)) + goto drop_check; + + /* make sure fixed part of mesh header is there, also checks skb len */ + if (!pskb_may_pull(rx->skb, hdr_len + 6)) + goto drop_check; + + mesh_hdr = (struct ieee80211s_hdr *)(skb->data + hdr_len); + ethertype_offset = hdr_len + ieee80211_get_mesh_hdrlen(mesh_hdr) + + sizeof(rfc1042_header); + + if (skb_copy_bits(rx->skb, ethertype_offset, ðertype, 2) == 0 && + ethertype == rx->sdata->control_port_protocol) + return 0; + } + +drop_check: /* Drop unencrypted frames if key is set. */ if (unlikely(!ieee80211_has_protected(fc) && !ieee80211_is_any_nullfunc(fc) && -- cgit v1.2.3 From bc7a39b4272b9672d806d422b6850e8c1a09914c Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 26 Jun 2020 12:49:39 +0300 Subject: nl80211: don't return err unconditionally in nl80211_start_ap() When a memory leak was fixed, a return err was changed to goto err, but, accidentally, the if (err) was removed, so now we always exit at this point. Fix it by adding if (err) back. Fixes: 9951ebfcdf2b ("nl80211: fix potential leak in AP start") Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20200626124931.871ba5b31eee.I97340172d92164ee92f3c803fe20a8a6e97714e1@changeid Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'net') diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 263ae395ad44..f31698fd4a7e 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5016,7 +5016,8 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) err = nl80211_parse_he_obss_pd( info->attrs[NL80211_ATTR_HE_OBSS_PD], ¶ms.he_obss_pd); - goto out; + if (err) + goto out; } if (info->attrs[NL80211_ATTR_HE_BSS_COLOR]) { -- cgit v1.2.3 From 60a0121f8fa64b0f4297aa6fef8207500483a874 Mon Sep 17 00:00:00 2001 From: Luca Coelho Date: Fri, 26 Jun 2020 12:49:40 +0300 Subject: nl80211: fix memory leak when parsing NL80211_ATTR_HE_BSS_COLOR If there is an error when parsing the NL80211_ATTR_HE_BSS_COLOR attribute, we return immediately without freeing param.acl. Fit it by using goto out instead of returning immediately. Fixes: 5c5e52d1bb96 ("nl80211: add handling for BSS color") Signed-off-by: Luca Coelho Link: https://lore.kernel.org/r/iwlwifi.20200626124931.7ad2a3eb894f.I60905fb70bd20389a3b170db515a07275e31845e@changeid Signed-off-by: Johannes Berg --- net/wireless/nl80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'net') diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f31698fd4a7e..0e07fb8585fb 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -5025,7 +5025,7 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info) info->attrs[NL80211_ATTR_HE_BSS_COLOR], ¶ms.he_bss_color); if (err) - return err; + goto out; } nl80211_calculate_ap_params(¶ms); -- cgit v1.2.3