From patchwork Wed Jun 17 08:26:36 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Theil X-Patchwork-Id: 11609409 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B840C60D for ; Wed, 17 Jun 2020 08:27:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A1A4B2085B for ; Wed, 17 Jun 2020 08:27:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726629AbgFQI1G (ORCPT ); Wed, 17 Jun 2020 04:27:06 -0400 Received: from smail.rz.tu-ilmenau.de ([141.24.186.67]:49905 "EHLO smail.rz.tu-ilmenau.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726025AbgFQI1F (ORCPT ); Wed, 17 Jun 2020 04:27:05 -0400 Received: from legolas.fritz.box (unknown [87.147.49.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smail.rz.tu-ilmenau.de (Postfix) with ESMTPSA id 257AF580073; Wed, 17 Jun 2020 10:27:03 +0200 (CEST) From: Markus Theil To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Markus Theil Subject: [PATCH v3 1/2] mac80211: skip mpath lookup also for control port tx Date: Wed, 17 Jun 2020 10:26:36 +0200 Message-Id: <20200617082637.22670-2-markus.theil@tu-ilmenau.de> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200617082637.22670-1-markus.theil@tu-ilmenau.de> References: <20200617082637.22670-1-markus.theil@tu-ilmenau.de> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org 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 --- net/mac80211/tx.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c index e9ce658141f5..bd86f85a5b73 100644 --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c @@ -3933,6 +3933,7 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, struct ieee80211_local *local = sdata->local; struct sta_info *sta; struct sk_buff *next; + u32 ctrl_flags_adapted; if (unlikely(skb->len < ETH_HLEN)) { kfree_skb(skb); @@ -3996,8 +3997,12 @@ void __ieee80211_subif_start_xmit(struct sk_buff *skb, skb_list_walk_safe(skb, skb, next) { skb_mark_not_on_list(skb); + ctrl_flags_adapted = ctrl_flags; + if (sdata->control_port_protocol == skb->protocol) + ctrl_flags_adapted |= IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP; + skb = ieee80211_build_hdr(sdata, skb, info_flags, - sta, ctrl_flags, cookie); + sta, ctrl_flags_adapted, cookie); if (IS_ERR(skb)) { kfree_skb_list(next); goto out; @@ -5370,8 +5375,10 @@ int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, proto != cpu_to_be16(ETH_P_PREAUTH)) return -EINVAL; - if (proto == sdata->control_port_protocol) - ctrl_flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO; + if (proto == sdata->control_port_protocol) { + ctrl_flags |= IEEE80211_TX_CTRL_PORT_CTRL_PROTO | + IEEE80211_TX_CTRL_SKIP_MPATH_LOOKUP; + } if (unencrypted) flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; From patchwork Wed Jun 17 08:26:37 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Markus Theil X-Patchwork-Id: 11609407 X-Patchwork-Delegate: johannes@sipsolutions.net Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3742014DD for ; Wed, 17 Jun 2020 08:27:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2B17E20C09 for ; Wed, 17 Jun 2020 08:27:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726625AbgFQI1G (ORCPT ); Wed, 17 Jun 2020 04:27:06 -0400 Received: from smail.rz.tu-ilmenau.de ([141.24.186.67]:49908 "EHLO smail.rz.tu-ilmenau.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725967AbgFQI1F (ORCPT ); Wed, 17 Jun 2020 04:27:05 -0400 Received: from legolas.fritz.box (unknown [87.147.49.100]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smail.rz.tu-ilmenau.de (Postfix) with ESMTPSA id 449E5580075; Wed, 17 Jun 2020 10:27:03 +0200 (CEST) From: Markus Theil To: johannes@sipsolutions.net Cc: linux-wireless@vger.kernel.org, Markus Theil , kernel test robot Subject: [PATCH v3 2/2] mac80211: allow rx of mesh eapol frames with default rx key Date: Wed, 17 Jun 2020 10:26:37 +0200 Message-Id: <20200617082637.22670-3-markus.theil@tu-ilmenau.de> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200617082637.22670-1-markus.theil@tu-ilmenau.de> References: <20200617082637.22670-1-markus.theil@tu-ilmenau.de> MIME-Version: 1.0 Sender: linux-wireless-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-wireless@vger.kernel.org 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. If a check for eapol frames fails, the previous drop check is executed (thanks to a kernel test bot, which found an issue in a previous patch version here). 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. Reported-by: kernel test robot Signed-off-by: Markus Theil --- net/mac80211/rx.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 21854a61a2b7..60293a9fa3dc 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 = (struct ieee80211_hdr *)rx->skb->data; struct sk_buff *skb = rx->skb; struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); @@ -2406,12 +2407,37 @@ 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; + + /* 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 (!pskb_may_pull(rx->skb, ethertype_offset + sizeof(ethertype)) || + !ether_addr_equal(hdr->addr1, rx->sdata->vif.addr)) + goto drop_check; + + skb_copy_bits(rx->skb, ethertype_offset, ðertype, 2); + if (ethertype == rx->sdata->control_port_protocol) + goto pass_frame; + } + +drop_check: /* Drop unencrypted frames if key is set. */ if (unlikely(!ieee80211_has_protected(fc) && !ieee80211_is_any_nullfunc(fc) && ieee80211_is_data(fc) && rx->key)) return -EACCES; +pass_frame: return 0; }