|
Takashi Iwai |
60e80e |
From 3edc6b0d6c061a70d8ca3c3c72eb1f58ce29bfb1 Mon Sep 17 00:00:00 2001
|
|
Takashi Iwai |
60e80e |
From: Wen Gong <wgong@codeaurora.org>
|
|
Takashi Iwai |
60e80e |
Date: Tue, 11 May 2021 20:02:51 +0200
|
|
Takashi Iwai |
60e80e |
Subject: [PATCH] mac80211: extend protection against mixed key and fragment cache attacks
|
|
Takashi Iwai |
60e80e |
Git-commit: 3edc6b0d6c061a70d8ca3c3c72eb1f58ce29bfb1
|
|
Takashi Iwai |
60e80e |
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/jberg/mac80211-next.git
|
|
Takashi Iwai |
60e80e |
Patch-mainline: Queued in subsystem maintainer repo
|
|
Takashi Iwai |
60e80e |
References: CVE-2020-24586 bsc#1185859
|
|
Takashi Iwai |
60e80e |
|
|
Takashi Iwai |
60e80e |
For some chips/drivers, e.g., QCA6174 with ath10k, the decryption is
|
|
Takashi Iwai |
60e80e |
done by the hardware, and the Protected bit in the Frame Control field
|
|
Takashi Iwai |
60e80e |
is cleared in the lower level driver before the frame is passed to
|
|
Takashi Iwai |
60e80e |
mac80211. In such cases, the condition for ieee80211_has_protected() is
|
|
Takashi Iwai |
60e80e |
not met in ieee80211_rx_h_defragment() of mac80211 and the new security
|
|
Takashi Iwai |
60e80e |
validation steps are not executed.
|
|
Takashi Iwai |
60e80e |
|
|
Takashi Iwai |
60e80e |
Extend mac80211 to cover the case where the Protected bit has been
|
|
Takashi Iwai |
60e80e |
cleared, but the frame is indicated as having been decrypted by the
|
|
Takashi Iwai |
60e80e |
hardware. This extends protection against mixed key and fragment cache
|
|
Takashi Iwai |
60e80e |
attack for additional drivers/chips. This fixes CVE-2020-24586 and
|
|
Takashi Iwai |
60e80e |
CVE-2020-24587 for such cases.
|
|
Takashi Iwai |
60e80e |
|
|
Takashi Iwai |
60e80e |
Tested-on: QCA6174 hw3.2 PCI WLAN.RM.4.4.1-00110-QCARMSWP-1
|
|
Takashi Iwai |
60e80e |
|
|
Takashi Iwai |
60e80e |
Cc: stable@vger.kernel.org
|
|
Takashi Iwai |
60e80e |
Signed-off-by: Wen Gong <wgong@codeaurora.org>
|
|
Takashi Iwai |
60e80e |
Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
|
|
Takashi Iwai |
60e80e |
Link: https://lore.kernel.org/r/20210511200110.037aa5ca0390.I7bb888e2965a0db02a67075fcb5deb50eb7408aa@changeid
|
|
Takashi Iwai |
60e80e |
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
|
Takashi Iwai |
60e80e |
Acked-by: Takashi Iwai <tiwai@suse.de>
|
|
Takashi Iwai |
60e80e |
|
|
Takashi Iwai |
60e80e |
---
|
|
Takashi Iwai |
60e80e |
net/mac80211/rx.c | 13 +++++++++++--
|
|
Takashi Iwai |
60e80e |
1 file changed, 11 insertions(+), 2 deletions(-)
|
|
Takashi Iwai |
60e80e |
|
|
Takashi Iwai |
60e80e |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
|
|
Takashi Iwai |
60e80e |
index 22a925899a9e..1bb43edd47b6 100644
|
|
Takashi Iwai |
60e80e |
--- a/net/mac80211/rx.c
|
|
Takashi Iwai |
60e80e |
+++ b/net/mac80211/rx.c
|
|
Takashi Iwai |
60e80e |
@@ -2229,6 +2229,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
|
|
Takashi Iwai |
60e80e |
unsigned int frag, seq;
|
|
Takashi Iwai |
60e80e |
struct ieee80211_fragment_entry *entry;
|
|
Takashi Iwai |
60e80e |
struct sk_buff *skb;
|
|
Takashi Iwai |
60e80e |
+ struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(rx->skb);
|
|
Takashi Iwai |
60e80e |
|
|
Takashi Iwai |
60e80e |
hdr = (struct ieee80211_hdr *)rx->skb->data;
|
|
Takashi Iwai |
60e80e |
fc = hdr->frame_control;
|
|
Takashi Iwai |
60e80e |
@@ -2287,7 +2288,9 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
|
|
Takashi Iwai |
60e80e |
sizeof(rx->key->u.gcmp.rx_pn[queue]));
|
|
Takashi Iwai |
60e80e |
BUILD_BUG_ON(IEEE80211_CCMP_PN_LEN !=
|
|
Takashi Iwai |
60e80e |
IEEE80211_GCMP_PN_LEN);
|
|
Takashi Iwai |
60e80e |
- } else if (rx->key && ieee80211_has_protected(fc)) {
|
|
Takashi Iwai |
60e80e |
+ } else if (rx->key &&
|
|
Takashi Iwai |
60e80e |
+ (ieee80211_has_protected(fc) ||
|
|
Takashi Iwai |
60e80e |
+ (status->flag & RX_FLAG_DECRYPTED))) {
|
|
Takashi Iwai |
60e80e |
entry->is_protected = true;
|
|
Takashi Iwai |
60e80e |
entry->key_color = rx->key->color;
|
|
Takashi Iwai |
60e80e |
}
|
|
Takashi Iwai |
60e80e |
@@ -2332,13 +2335,19 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
|
|
Takashi Iwai |
60e80e |
return RX_DROP_UNUSABLE;
|
|
Takashi Iwai |
60e80e |
memcpy(entry->last_pn, pn, IEEE80211_CCMP_PN_LEN);
|
|
Takashi Iwai |
60e80e |
} else if (entry->is_protected &&
|
|
Takashi Iwai |
60e80e |
- (!rx->key || !ieee80211_has_protected(fc) ||
|
|
Takashi Iwai |
60e80e |
+ (!rx->key ||
|
|
Takashi Iwai |
60e80e |
+ (!ieee80211_has_protected(fc) &&
|
|
Takashi Iwai |
60e80e |
+ !(status->flag & RX_FLAG_DECRYPTED)) ||
|
|
Takashi Iwai |
60e80e |
rx->key->color != entry->key_color)) {
|
|
Takashi Iwai |
60e80e |
/* Drop this as a mixed key or fragment cache attack, even
|
|
Takashi Iwai |
60e80e |
* if for TKIP Michael MIC should protect us, and WEP is a
|
|
Takashi Iwai |
60e80e |
* lost cause anyway.
|
|
Takashi Iwai |
60e80e |
*/
|
|
Takashi Iwai |
60e80e |
return RX_DROP_UNUSABLE;
|
|
Takashi Iwai |
60e80e |
+ } else if (entry->is_protected && rx->key &&
|
|
Takashi Iwai |
60e80e |
+ entry->key_color != rx->key->color &&
|
|
Takashi Iwai |
60e80e |
+ (status->flag & RX_FLAG_DECRYPTED)) {
|
|
Takashi Iwai |
60e80e |
+ return RX_DROP_UNUSABLE;
|
|
Takashi Iwai |
60e80e |
}
|
|
Takashi Iwai |
60e80e |
|
|
Takashi Iwai |
60e80e |
skb_pull(rx->skb, ieee80211_hdrlen(fc));
|
|
Takashi Iwai |
60e80e |
--
|
|
Takashi Iwai |
60e80e |
2.26.2
|
|
Takashi Iwai |
60e80e |
|