mac80211: backport upstream fixes for FragAttacks
[openwrt/openwrt.git] / package / kernel / mac80211 / patches / subsys / 387-mac80211-prevent-attacks-on-TKIP-WEP-as-well.patch
diff --git a/package/kernel/mac80211/patches/subsys/387-mac80211-prevent-attacks-on-TKIP-WEP-as-well.patch b/package/kernel/mac80211/patches/subsys/387-mac80211-prevent-attacks-on-TKIP-WEP-as-well.patch
new file mode 100644 (file)
index 0000000..bc582a6
--- /dev/null
@@ -0,0 +1,62 @@
+From: Johannes Berg <johannes.berg@intel.com>
+Date: Tue, 11 May 2021 20:02:49 +0200
+Subject: [PATCH] mac80211: prevent attacks on TKIP/WEP as well
+
+Similar to the issues fixed in previous patches, TKIP and WEP
+should be protected even if for TKIP we have the Michael MIC
+protecting it, and WEP is broken anyway.
+
+However, this also somewhat protects potential other algorithms
+that drivers might implement.
+
+Cc: stable@vger.kernel.org
+Signed-off-by: Johannes Berg <johannes.berg@intel.com>
+---
+
+--- a/net/mac80211/rx.c
++++ b/net/mac80211/rx.c
+@@ -2284,6 +2284,7 @@ ieee80211_rx_h_defragment(struct ieee802
+                        * next fragment has a sequential PN value.
+                        */
+                       entry->check_sequential_pn = true;
++                      entry->is_protected = true;
+                       entry->key_color = rx->key->color;
+                       memcpy(entry->last_pn,
+                              rx->key->u.ccmp.rx_pn[queue],
+@@ -2296,6 +2297,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)) {
++                      entry->is_protected = true;
++                      entry->key_color = rx->key->color;
+               }
+               return RX_QUEUED;
+       }
+@@ -2337,6 +2341,14 @@ ieee80211_rx_h_defragment(struct ieee802
+               if (memcmp(pn, rpn, IEEE80211_CCMP_PN_LEN))
+                       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->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;
+       }
+       skb_pull(rx->skb, ieee80211_hdrlen(fc));
+--- a/net/mac80211/sta_info.h
++++ b/net/mac80211/sta_info.h
+@@ -455,7 +455,8 @@ struct ieee80211_fragment_entry {
+       u16 extra_len;
+       u16 last_frag;
+       u8 rx_queue;
+-      bool check_sequential_pn; /* needed for CCMP/GCMP */
++      u8 check_sequential_pn:1, /* needed for CCMP/GCMP */
++         is_protected:1;
+       u8 last_pn[6]; /* PN of the last fragment if CCMP was used */
+       unsigned int key_color;
+ };