mirror of
https://github.com/openwrt/openwrt.git
synced 2025-01-07 14:28:50 +00:00
69 lines
2.6 KiB
Diff
69 lines
2.6 KiB
Diff
|
From: Wen Gong <wgong@codeaurora.org>
|
||
|
Date: Tue, 11 May 2021 20:02:51 +0200
|
||
|
Subject: [PATCH] mac80211: extend protection against mixed key and
|
||
|
fragment cache attacks
|
||
|
|
||
|
For some chips/drivers, e.g., QCA6174 with ath10k, the decryption is
|
||
|
done by the hardware, and the Protected bit in the Frame Control field
|
||
|
is cleared in the lower level driver before the frame is passed to
|
||
|
mac80211. In such cases, the condition for ieee80211_has_protected() is
|
||
|
not met in ieee80211_rx_h_defragment() of mac80211 and the new security
|
||
|
validation steps are not executed.
|
||
|
|
||
|
Extend mac80211 to cover the case where the Protected bit has been
|
||
|
cleared, but the frame is indicated as having been decrypted by the
|
||
|
hardware. This extends protection against mixed key and fragment cache
|
||
|
attack for additional drivers/chips. This fixes CVE-2020-24586 and
|
||
|
CVE-2020-24587 for such cases.
|
||
|
|
||
|
Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00110-QCARMSWP-1
|
||
|
|
||
|
Cc: stable@vger.kernel.org
|
||
|
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
||
|
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
||
|
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||
|
---
|
||
|
|
||
|
--- a/net/mac80211/rx.c
|
||
|
+++ b/net/mac80211/rx.c
|
||
|
@@ -2239,6 +2239,7 @@ ieee80211_rx_h_defragment(struct ieee802
|
||
|
unsigned int frag, seq;
|
||
|
struct ieee80211_fragment_entry *entry;
|
||
|
struct sk_buff *skb;
|
||
|
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
||
|
|
||
|
hdr = (struct ieee80211_hdr *)rx->skb->data;
|
||
|
fc = hdr->frame_control;
|
||
|
@@ -2297,7 +2298,9 @@ ieee80211_rx_h_defragment(struct ieee802
|
||
|
sizeof(rx->key->u.gcmp.rx_pn[queue]));
|
||
|
BUILD_BUG_ON(IEEE80211_CCMP_PN_LEN !=
|
||
|
IEEE80211_GCMP_PN_LEN);
|
||
|
- } else if (rx->key && ieee80211_has_protected(fc)) {
|
||
|
+ } else if (rx->key &&
|
||
|
+ (ieee80211_has_protected(fc) ||
|
||
|
+ (status->flag & RX_FLAG_DECRYPTED))) {
|
||
|
entry->is_protected = true;
|
||
|
entry->key_color = rx->key->color;
|
||
|
}
|
||
|
@@ -2342,13 +2345,19 @@ ieee80211_rx_h_defragment(struct ieee802
|
||
|
return RX_DROP_UNUSABLE;
|
||
|
memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN);
|
||
|
} else if (entry->is_protected &&
|
||
|
- (!rx->key || !ieee80211_has_protected(fc) ||
|
||
|
+ (!rx->key ||
|
||
|
+ (!ieee80211_has_protected(fc) &&
|
||
|
+ !(status->flag & RX_FLAG_DECRYPTED)) ||
|
||
|
rx->key->color != entry->key_color)) {
|
||
|
/* Drop this as a mixed key or fragment cache attack, even
|
||
|
* if for TKIP Michael MIC should protect us, and WEP is a
|
||
|
* lost cause anyway.
|
||
|
*/
|
||
|
return RX_DROP_UNUSABLE;
|
||
|
+ } else if (entry->is_protected && rx->key &&
|
||
|
+ entry->key_color != rx->key->color &&
|
||
|
+ (status->flag & RX_FLAG_DECRYPTED)) {
|
||
|
+ return RX_DROP_UNUSABLE;
|
||
|
}
|
||
|
|
||
|
skb_pull(rx->skb, ieee80211_hdrlen(fc));
|