Files
wlan-ap/feeds/wifi-ax/mac80211/patches/pending/213-mac80211-frag.patch
John Crispin c3d02f8719 mac80211/ath11k: backport krak2 mitigation
Signed-off-by: John Crispin <john@phrozen.org>
2021-06-29 19:15:56 -04:00

243 lines
10 KiB
Diff

From patchwork Tue May 11 18:02:44 2021
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
X-Patchwork-Submitter: Johannes Berg <johannes@sipsolutions.net>
X-Patchwork-Id: 12251641
X-Patchwork-Delegate: johannes@sipsolutions.net
Return-Path: <linux-wireless-owner@kernel.org>
X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on
aws-us-west-2-korg-lkml-1.web.codeaurora.org
X-Spam-Level:
X-Spam-Status: No, score=-16.8 required=3.0 tests=BAYES_00,
HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH,
MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT
autolearn=unavailable autolearn_force=no version=3.4.0
Received: from mail.kernel.org (mail.kernel.org [198.145.29.99])
by smtp.lore.kernel.org (Postfix) with ESMTP id 5E0C4C43617
for <linux-wireless@archiver.kernel.org>;
Tue, 11 May 2021 18:03:20 +0000 (UTC)
Received: from vger.kernel.org (vger.kernel.org [23.128.96.18])
by mail.kernel.org (Postfix) with ESMTP id 2E1D461625
for <linux-wireless@archiver.kernel.org>;
Tue, 11 May 2021 18:03:20 +0000 (UTC)
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
id S231693AbhEKSEZ (ORCPT
<rfc822;linux-wireless@archiver.kernel.org>);
Tue, 11 May 2021 14:04:25 -0400
Received: from lindbergh.monkeyblade.net ([23.128.96.19]:41156 "EHLO
lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org
with ESMTP id S231561AbhEKSEV (ORCPT
<rfc822;linux-wireless@vger.kernel.org>);
Tue, 11 May 2021 14:04:21 -0400
Received: from sipsolutions.net (s3.sipsolutions.net
[IPv6:2a01:4f8:191:4433::2])
by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D055CC06175F;
Tue, 11 May 2021 11:03:10 -0700 (PDT)
Received: by sipsolutions.net with esmtpsa
(TLS1.3:ECDHE_X25519__RSA_PSS_RSAE_SHA256__AES_256_GCM:256)
(Exim 4.94.2)
(envelope-from <johannes@sipsolutions.net>)
id 1lgWir-007aAS-9o; Tue, 11 May 2021 20:03:09 +0200
From: Johannes Berg <johannes@sipsolutions.net>
To: linux-wireless@vger.kernel.org
Cc: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>, stable@vger.kernel.org
Subject: [PATCH 03/18] mac80211: properly handle A-MSDUs that start with an
RFC 1042 header
Date: Tue, 11 May 2021 20:02:44 +0200
Message-Id:
<20210511200110.0b2b886492f0.I23dd5d685fe16d3b0ec8106e8f01b59f499dffed@changeid>
X-Mailer: git-send-email 2.30.2
In-Reply-To: <20210511180259.159598-1-johannes@sipsolutions.net>
References: <20210511180259.159598-1-johannes@sipsolutions.net>
MIME-Version: 1.0
Precedence: bulk
List-ID: <linux-wireless.vger.kernel.org>
X-Mailing-List: linux-wireless@vger.kernel.org
From: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
Properly parse A-MSDUs whose first 6 bytes happen to equal a rfc1042
header. This can occur in practice when the destination MAC address
equals AA:AA:03:00:00:00. More importantly, this simplifies the next
patch to mitigate A-MSDU injection attacks.
Cc: stable@vger.kernel.org
Signed-off-by: Mathy Vanhoef <Mathy.Vanhoef@kuleuven.be>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/cfg80211.h | 4 ++--
net/mac80211/rx.c | 2 +-
net/wireless/util.c | 4 ++--
3 files changed, 5 insertions(+), 5 deletions(-)
Index: backports-20200902_001-4.4.60-931c337125/include/net/cfg80211.h
===================================================================
--- backports-20200902_001-4.4.60-931c337125.orig/include/net/cfg80211.h
+++ backports-20200902_001-4.4.60-931c337125/include/net/cfg80211.h
@@ -5631,7 +5631,7 @@ unsigned int ieee80211_get_mesh_hdrlen(s
*/
int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
const u8 *addr, enum nl80211_iftype iftype,
- u8 data_offset);
+ u8 data_offset, bool is_amsdu);
/**
* ieee80211_data_to_8023 - convert an 802.11 data frame to 802.3
@@ -5643,7 +5643,7 @@ int ieee80211_data_to_8023_exthdr(struct
static inline int ieee80211_data_to_8023(struct sk_buff *skb, const u8 *addr,
enum nl80211_iftype iftype)
{
- return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0);
+ return ieee80211_data_to_8023_exthdr(skb, NULL, addr, iftype, 0, false);
}
/**
Index: backports-20200902_001-4.4.60-931c337125/net/mac80211/rx.c
===================================================================
--- backports-20200902_001-4.4.60-931c337125.orig/net/mac80211/rx.c
+++ backports-20200902_001-4.4.60-931c337125/net/mac80211/rx.c
@@ -6,7 +6,7 @@
* Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>
* Copyright 2013-2014 Intel Mobile Communications GmbH
* Copyright(c) 2015 - 2017 Intel Deutschland GmbH
- * Copyright (C) 2018-2020 Intel Corporation
+ * Copyright (C) 2018-2021 Intel Corporation
*/
#include <linux/jiffies.h>
@@ -2555,13 +2555,13 @@ static bool ieee80211_frame_allowed(stru
struct ethhdr *ehdr = (struct ethhdr *) rx->skb->data;
/*
- * Allow EAPOL frames to us/the PAE group address regardless
- * of whether the frame was encrypted or not.
- */
- if (ehdr->h_proto == rx->sdata->control_port_protocol &&
- (ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) ||
- ether_addr_equal(ehdr->h_dest, pae_group_addr)))
- return true;
+ * Allow EAPOL frames to us/the PAE group address regardless of
+ * whether the frame was encrypted or not, and always disallow
+ * all other destination addresses for them.
+ */
+ if (unlikely(ehdr->h_proto == rx->sdata->control_port_protocol))
+ return ether_addr_equal(ehdr->h_dest, rx->sdata->vif.addr) ||
+ ether_addr_equal(ehdr->h_dest, pae_group_addr);
if (ieee80211_802_1x_port_control(rx) ||
ieee80211_drop_unencrypted(rx, fc))
@@ -2632,7 +2632,26 @@ static void ieee80211_deliver_skb_to_loc
cfg80211_rx_control_port(dev, skb, noencrypt);
dev_kfree_skb(skb);
} else {
+ struct ethhdr *ehdr = (void *)skb_mac_header(skb);
memset(skb->cb, 0, sizeof(skb->cb));
+ /*
+ * 802.1X over 802.11 requires that the authenticator address
+ * be used for EAPOL frames. However, 802.1X allows the use of
+ * the PAE group address instead. If the interface is part of
+ * a bridge and we pass the frame with the PAE group address,
+ * then the bridge will forward it to the network (even if the
+ * client was not associated yet), which isn't supposed to
+ * happen.
+ * To avoid that, rewrite the destination address to our own
+ * address, so that the authenticator (e.g. hostapd) will see
+ * the frame, but bridge won't forward it anywhere else. Note
+ * that due to earlier filtering, the only other address can
+ * be the PAE group address.
+ */
+ if (unlikely(skb->protocol == sdata->control_port_protocol &&
+ !ether_addr_equal(ehdr->h_dest, sdata->vif.addr)))
+ ether_addr_copy(ehdr->h_dest, sdata->vif.addr);
+
netif_rx_nss(rx, skb);
}
}
@@ -2672,6 +2691,7 @@ ieee80211_deliver_skb(struct ieee80211_r
if ((sdata->vif.type == NL80211_IFTYPE_AP ||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN) &&
!(sdata->flags & IEEE80211_SDATA_DONT_BRIDGE_PACKETS) &&
+ ehdr->h_proto != rx->sdata->control_port_protocol &&
(sdata->vif.type != NL80211_IFTYPE_AP_VLAN || !sdata->u.vlan.sta)) {
if (is_multicast_ether_addr(ehdr->h_dest) &&
ieee80211_vif_get_num_mcast_if(sdata) != 0) {
@@ -2781,7 +2801,7 @@ __ieee80211_rx_h_amsdu(struct ieee80211_
if (ieee80211_data_to_8023_exthdr(skb, &ethhdr,
rx->sdata->vif.addr,
rx->sdata->vif.type,
- data_offset))
+ data_offset, true))
return RX_DROP_UNUSABLE;
ieee80211_amsdu_to_8023s(skb, &frame_list, dev->dev_addr,
@@ -2838,6 +2858,23 @@ ieee80211_rx_h_amsdu(struct ieee80211_rx
if (is_multicast_ether_addr(hdr->addr1))
return RX_DROP_UNUSABLE;
+ if (rx->key) {
+ /*
+ * We should not receive A-MSDUs on pre-HT connections,
+ * and HT connections cannot use old ciphers. Thus drop
+ * them, as in those cases we couldn't even have SPP
+ * A-MSDUs or such.
+ */
+ switch (rx->key->conf.cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ case WLAN_CIPHER_SUITE_TKIP:
+ return RX_DROP_UNUSABLE;
+ default:
+ break;
+ }
+ }
+
return __ieee80211_rx_h_amsdu(rx, 0);
}
Index: backports-20200902_001-4.4.60-931c337125/net/wireless/util.c
===================================================================
--- backports-20200902_001-4.4.60-931c337125.orig/net/wireless/util.c
+++ backports-20200902_001-4.4.60-931c337125/net/wireless/util.c
@@ -474,7 +474,7 @@ EXPORT_SYMBOL(ieee80211_get_mesh_hdrlen)
int ieee80211_data_to_8023_exthdr(struct sk_buff *skb, struct ethhdr *ehdr,
const u8 *addr, enum nl80211_iftype iftype,
- u8 data_offset)
+ u8 data_offset, bool is_amsdu)
{
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
struct {
@@ -562,7 +562,7 @@ int ieee80211_data_to_8023_exthdr(struct
skb_copy_bits(skb, hdrlen, &payload, sizeof(payload));
tmp.h_proto = payload.proto;
- if (likely((ether_addr_equal(payload.hdr, rfc1042_header) &&
+ if (likely((!is_amsdu && ether_addr_equal(payload.hdr, rfc1042_header) &&
tmp.h_proto != htons(ETH_P_AARP) &&
tmp.h_proto != htons(ETH_P_IPX)) ||
ether_addr_equal(payload.hdr, bridge_tunnel_header)))
@@ -708,6 +708,9 @@ void ieee80211_amsdu_to_8023s(struct sk_
remaining = skb->len - offset;
if (subframe_len > remaining)
goto purge;
+ /* mitigate A-MSDU aggregation injection attacks */
+ if (ether_addr_equal(eth.h_dest, rfc1042_header))
+ goto purge;
offset += sizeof(struct ethhdr);
last = remaining <= subframe_len + padding;
Index: backports-20200902_001-4.4.60-931c337125/drivers/net/wireless/ath/ath11k/nss.c
===================================================================
--- backports-20200902_001-4.4.60-931c337125.orig/drivers/net/wireless/ath/ath11k/nss.c
+++ backports-20200902_001-4.4.60-931c337125/drivers/net/wireless/ath/ath11k/nss.c
@@ -477,7 +477,7 @@ static int ath11k_nss_deliver_rx(struct
}
if (ieee80211_data_to_8023_exthdr(skb, NULL, vif->addr, vif->type,
- data_offs - hdr_len)) {
+ data_offs - hdr_len, false)) {
dev_kfree_skb_any(skb);
return -EINVAL;
}