X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fstaging%2Fdedeckeh.git;a=blobdiff_plain;f=package%2Fkernel%2Fmac80211%2Fpatches%2Fsubsys%2F380-mac80211-assure-all-fragments-are-encrypted.patch;fp=package%2Fkernel%2Fmac80211%2Fpatches%2Fsubsys%2F380-mac80211-assure-all-fragments-are-encrypted.patch;h=69398459f137ba4f94168e49c83f1fa87b83794e;hp=0000000000000000000000000000000000000000;hb=025bd93f36c9923127674ce127e22933592cba6c;hpb=5a9608102b3c444d0c963255f9d016a1d5469d5d diff --git a/package/kernel/mac80211/patches/subsys/380-mac80211-assure-all-fragments-are-encrypted.patch b/package/kernel/mac80211/patches/subsys/380-mac80211-assure-all-fragments-are-encrypted.patch new file mode 100644 index 0000000000..69398459f1 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/380-mac80211-assure-all-fragments-are-encrypted.patch @@ -0,0 +1,69 @@ +From: Mathy Vanhoef +Date: Tue, 11 May 2021 20:02:42 +0200 +Subject: [PATCH] mac80211: assure all fragments are encrypted + +Do not mix plaintext and encrypted fragments in protected Wi-Fi +networks. This fixes CVE-2020-26147. + +Previously, an attacker was able to first forward a legitimate encrypted +fragment towards a victim, followed by a plaintext fragment. The +encrypted and plaintext fragment would then be reassembled. For further +details see Section 6.3 and Appendix D in the paper "Fragment and Forge: +Breaking Wi-Fi Through Frame Aggregation and Fragmentation". + +Because of this change there are now two equivalent conditions in the +code to determine if a received fragment requires sequential PNs, so we +also move this test to a separate function to make the code easier to +maintain. + +Cc: stable@vger.kernel.org +Signed-off-by: Mathy Vanhoef +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2204,6 +2204,16 @@ ieee80211_reassemble_find(struct ieee802 + return NULL; + } + ++static bool requires_sequential_pn(struct ieee80211_rx_data *rx, __le16 fc) ++{ ++ return rx->key && ++ (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || ++ rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && ++ ieee80211_has_protected(fc); ++} ++ + static ieee80211_rx_result debug_noinline + ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) + { +@@ -2248,12 +2258,7 @@ ieee80211_rx_h_defragment(struct ieee802 + /* This is the first fragment of a new frame. */ + entry = ieee80211_reassemble_add(rx->sdata, frag, seq, + rx->seqno_idx, &(rx->skb)); +- if (rx->key && +- (rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP || +- rx->key->conf.cipher == WLAN_CIPHER_SUITE_CCMP_256 || +- rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP || +- rx->key->conf.cipher == WLAN_CIPHER_SUITE_GCMP_256) && +- ieee80211_has_protected(fc)) { ++ if (requires_sequential_pn(rx, fc)) { + int queue = rx->security_idx; + + /* Store CCMP/GCMP PN so that we can verify that the +@@ -2295,11 +2300,7 @@ ieee80211_rx_h_defragment(struct ieee802 + u8 pn[IEEE80211_CCMP_PN_LEN], *rpn; + int queue; + +- if (!rx->key || +- (rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP && +- rx->key->conf.cipher != WLAN_CIPHER_SUITE_CCMP_256 && +- rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP && +- rx->key->conf.cipher != WLAN_CIPHER_SUITE_GCMP_256)) ++ if (!requires_sequential_pn(rx, fc)) + return RX_DROP_UNUSABLE; + memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); + for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) {