mirror of
https://github.com/Telecominfraproject/wlan-ap.git
synced 2025-10-30 18:07:52 +00:00
mac80211/ath11k: backport krak2 mitigation
Signed-off-by: John Crispin <john@phrozen.org>
This commit is contained in:
committed by
Rick Sommerville
parent
e8418c0c54
commit
bebf6d322d
@@ -0,0 +1,84 @@
|
||||
From 0e23a88c63d6abbeaef8ec90bd29584b7c5068bd Mon Sep 17 00:00:00 2001
|
||||
From: Sriram R <srirrama@codeaurora.org>
|
||||
Date: Thu, 10 Dec 2020 14:20:50 +0530
|
||||
Subject: [PATCH] ath11k: Clear the fragment cache during key install
|
||||
|
||||
Currently the fragment cache setup during peer assoc is
|
||||
cleared during peer delete. In case a key reinstallation
|
||||
happens with the same peer, possibilitites are same fragment cache
|
||||
where some fragments were added before key installation could be clubbed
|
||||
with fragments received after. In ideal cases where
|
||||
this could result in wrong PN since we expect all fragments to
|
||||
have incrementing PN, this behavior could be explioted
|
||||
to mix fragments of different data resulting in a proper
|
||||
unintended reassembled packet to be passed up the stack.
|
||||
|
||||
Signed-off-by: Sriram R <srirrama@codeaurora.org>
|
||||
---
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.c | 19 +++++++++++++++++++
|
||||
drivers/net/wireless/ath/ath11k/dp_rx.h | 1 +
|
||||
drivers/net/wireless/ath/ath11k/mac.c | 6 ++++++
|
||||
3 files changed, 26 insertions(+)
|
||||
|
||||
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.c b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
index 0fa25c1..06bbd6e 100644
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.c
|
||||
@@ -844,6 +844,25 @@ static void ath11k_dp_rx_frags_cleanup(struct dp_rx_tid *rx_tid, bool rel_link_d
|
||||
__skb_queue_purge(&rx_tid->rx_frags);
|
||||
}
|
||||
|
||||
+void ath11k_peer_frags_flush(struct ath11k *ar, struct ath11k_peer *peer)
|
||||
+{
|
||||
+ struct dp_rx_tid *rx_tid;
|
||||
+ int i;
|
||||
+
|
||||
+ lockdep_assert_held(&ar->ab->base_lock);
|
||||
+
|
||||
+ for (i = 0; i <= IEEE80211_NUM_TIDS; i++) {
|
||||
+ rx_tid = &peer->rx_tid[i];
|
||||
+
|
||||
+ spin_unlock_bh(&ar->ab->base_lock);
|
||||
+ del_timer_sync(&rx_tid->frag_timer);
|
||||
+ spin_lock_bh(&ar->ab->base_lock);
|
||||
+
|
||||
+ ath11k_dp_rx_frags_cleanup(rx_tid, true);
|
||||
+
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void ath11k_peer_rx_tid_cleanup(struct ath11k *ar, struct ath11k_peer *peer)
|
||||
{
|
||||
struct dp_rx_tid *rx_tid;
|
||||
diff --git a/drivers/net/wireless/ath/ath11k/dp_rx.h b/drivers/net/wireless/ath/ath11k/dp_rx.h
|
||||
index f005ded..732f9a7 100644
|
||||
--- a/drivers/net/wireless/ath/ath11k/dp_rx.h
|
||||
+++ b/drivers/net/wireless/ath/ath11k/dp_rx.h
|
||||
@@ -68,6 +68,7 @@ int ath11k_dp_peer_rx_pn_replay_config(struct ath11k_vif *arvif,
|
||||
const u8 *peer_addr,
|
||||
enum set_key_cmd key_cmd,
|
||||
struct ieee80211_key_conf *key);
|
||||
+void ath11k_peer_frags_flush(struct ath11k *ar, struct ath11k_peer *peer);
|
||||
void ath11k_peer_rx_tid_cleanup(struct ath11k *ar, struct ath11k_peer *peer);
|
||||
void ath11k_peer_rx_tid_delete(struct ath11k *ar,
|
||||
struct ath11k_peer *peer, u8 tid);
|
||||
diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
index 4c88eab..91d645e 100644
|
||||
--- a/drivers/net/wireless/ath/ath11k/mac.c
|
||||
+++ b/drivers/net/wireless/ath/ath11k/mac.c
|
||||
@@ -3707,6 +3707,12 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
|
||||
*/
|
||||
spin_lock_bh(&ab->base_lock);
|
||||
peer = ath11k_peer_find(ab, arvif->vdev_id, peer_addr);
|
||||
+
|
||||
+ /* flush the fragments cache during key (re)install to
|
||||
+ * ensure all frags in the new frag list belong to the same key.
|
||||
+ */
|
||||
+ if (peer && cmd == SET_KEY)
|
||||
+ ath11k_peer_frags_flush(ar, peer);
|
||||
spin_unlock_bh(&ab->base_lock);
|
||||
|
||||
if (!peer) {
|
||||
--
|
||||
2.7.4
|
||||
|
||||
242
feeds/wifi-ax/mac80211/patches/pending/213-mac80211-frag.patch
Normal file
242
feeds/wifi-ax/mac80211/patches/pending/213-mac80211-frag.patch
Normal file
@@ -0,0 +1,242 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user