]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 3 Jun 2021 06:38:03 +0000 (08:38 +0200)
commit 7e44a0b597f04e67eee8cdcbe7ee706c6f5de38b upstream.

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>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/mac80211/rx.c
net/mac80211/sta_info.h

index bfb9d9db8aff3363cee9ea4ec4a48e5df6f76b28..6db71e0b83767d7e600e62cb4944901e8631ff46 100644 (file)
@@ -2158,6 +2158,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],
@@ -2170,6 +2171,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;
        }
@@ -2211,6 +2215,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 b6e37af561469ea20514ca51c0f7249f54097f58..c33bc5fc0f2d892f6b2e7f11ac9ec1f4923b9cd3 100644 (file)
@@ -429,7 +429,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;
 };