mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-29 17:42:41 +00:00
243 lines
10 KiB
Diff
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, ðhdr,
|
|
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;
|
|
}
|