mac80211: prevent attacks on TKIP/WEP as well
authorJohannes Berg <johannes.berg@intel.com>
Tue, 11 May 2021 18:02:49 +0000 (20:02 +0200)
committerJohannes Berg <johannes.berg@intel.com>
Tue, 11 May 2021 18:14:11 +0000 (20:14 +0200)
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
Link: https://lore.kernel.org/r/20210511200110.430e8c202313.Ia37e4e5b6b3eaab1a5ae050e015f6c92859dbe27@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/rx.c
net/mac80211/sta_info.h

index b619c47e1d120c174146e8ce2ad59a3e7255c8a1..4454ec47283f8c421fec3403a61c6408429ef638 100644 (file)
@@ -2274,6 +2274,7 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
                         * 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],
@@ -2286,6 +2287,9 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
                                     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;
        }
@@ -2327,6 +2331,14 @@ ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx)
                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));
index 5c56d29a619e6cd12e17f3ad035ea49f2f425bdd..0333072ebd98223bd31d54187644a7b0f6c9c2f2 100644 (file)
@@ -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;
 };