X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fopenwrt.git;a=blobdiff_plain;f=package%2Fkernel%2Fmac80211%2Fpatches%2Fsubsys%2F381-mac80211-prevent-mixed-key-and-fragment-cache-attack.patch;fp=package%2Fkernel%2Fmac80211%2Fpatches%2Fsubsys%2F381-mac80211-prevent-mixed-key-and-fragment-cache-attack.patch;h=de0f89a5b0446f2f7a373c1be2a0aa49911846f8;hp=0000000000000000000000000000000000000000;hb=025bd93f36c9923127674ce127e22933592cba6c;hpb=5a9608102b3c444d0c963255f9d016a1d5469d5d diff --git a/package/kernel/mac80211/patches/subsys/381-mac80211-prevent-mixed-key-and-fragment-cache-attack.patch b/package/kernel/mac80211/patches/subsys/381-mac80211-prevent-mixed-key-and-fragment-cache-attack.patch new file mode 100644 index 0000000000..de0f89a5b0 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/381-mac80211-prevent-mixed-key-and-fragment-cache-attack.patch @@ -0,0 +1,87 @@ +From: Mathy Vanhoef +Date: Tue, 11 May 2021 20:02:43 +0200 +Subject: [PATCH] mac80211: prevent mixed key and fragment cache attacks + +Simultaneously prevent mixed key attacks (CVE-2020-24587) and fragment +cache attacks (CVE-2020-24586). This is accomplished by assigning a +unique color to every key (per interface) and using this to track which +key was used to decrypt a fragment. When reassembling frames, it is +now checked whether all fragments were decrypted using the same key. + +To assure that fragment cache attacks are also prevented, the ID that is +assigned to keys is unique even over (re)associations and (re)connects. +This means fragments separated by a (re)association or (re)connect will +not be reassembled. Because mac80211 now also prevents the reassembly of +mixed encrypted and plaintext fragments, all cache attacks are prevented. + +Cc: stable@vger.kernel.org +Signed-off-by: Mathy Vanhoef +Signed-off-by: Johannes Berg +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -97,6 +97,7 @@ struct ieee80211_fragment_entry { + u8 rx_queue; + bool check_sequential_pn; /* needed for CCMP/GCMP */ + u8 last_pn[6]; /* PN of the last fragment if CCMP was used */ ++ unsigned int key_color; + }; + + +--- a/net/mac80211/key.c ++++ b/net/mac80211/key.c +@@ -799,6 +799,7 @@ int ieee80211_key_link(struct ieee80211_ + struct ieee80211_sub_if_data *sdata, + struct sta_info *sta) + { ++ static atomic_t key_color = ATOMIC_INIT(0); + struct ieee80211_key *old_key; + int idx = key->conf.keyidx; + bool pairwise = key->conf.flags & IEEE80211_KEY_FLAG_PAIRWISE; +@@ -850,6 +851,12 @@ int ieee80211_key_link(struct ieee80211_ + key->sdata = sdata; + key->sta = sta; + ++ /* ++ * Assign a unique ID to every key so we can easily prevent mixed ++ * key and fragment cache attacks. ++ */ ++ key->color = atomic_inc_return(&key_color); ++ + increment_tailroom_need_count(sdata); + + ret = ieee80211_key_replace(sdata, sta, pairwise, old_key, key); +--- a/net/mac80211/key.h ++++ b/net/mac80211/key.h +@@ -128,6 +128,8 @@ struct ieee80211_key { + } debugfs; + #endif + ++ unsigned int color; ++ + /* + * key config, must be last because it contains key + * material as variable length member +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2265,6 +2265,7 @@ ieee80211_rx_h_defragment(struct ieee802 + * next fragment has a sequential PN value. + */ + entry->check_sequential_pn = true; ++ entry->key_color = rx->key->color; + memcpy(entry->last_pn, + rx->key->u.ccmp.rx_pn[queue], + IEEE80211_CCMP_PN_LEN); +@@ -2302,6 +2303,11 @@ ieee80211_rx_h_defragment(struct ieee802 + + if (!requires_sequential_pn(rx, fc)) + return RX_DROP_UNUSABLE; ++ ++ /* Prevent mixed key and fragment cache attacks */ ++ if (entry->key_color != rx->key->color) ++ return RX_DROP_UNUSABLE; ++ + memcpy(pn, entry->last_pn, IEEE80211_CCMP_PN_LEN); + for (i = IEEE80211_CCMP_PN_LEN - 1; i >= 0; i--) { + pn[i]++;