ath: Modify ath_key_delete() to not need full key entry
authorJouni Malinen <jouni@codeaurora.org>
Mon, 14 Dec 2020 17:21:17 +0000 (19:21 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 22 Sep 2021 09:42:56 +0000 (11:42 +0200)
commit 144cd24dbc36650a51f7fe3bf1424a1432f1f480 upstream.

tkip_keymap can be used internally to avoid the reference to key->cipher
and with this, only the key index value itself is needed. This allows
ath_key_delete() call to be postponed to be handled after the upper
layer STA and key entry have already been removed. This is needed to
make ath9k key cache management safer.

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Link: https://lore.kernel.org/r/20201214172118.18100-5-jouni@codeaurora.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/wireless/ath/ath.h
drivers/net/wireless/ath/ath5k/mac80211-ops.c
drivers/net/wireless/ath/ath9k/htc_drv_main.c
drivers/net/wireless/ath/ath9k/main.c
drivers/net/wireless/ath/key.c

index eff4e4075e0c26eda4bfc1345b2bd5fee8e8d8b4..135600405dd09d1681644c6032b85c58bb415dc3 100644 (file)
@@ -199,7 +199,7 @@ struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
 bool ath_is_mybeacon(struct ath_common *common, struct ieee80211_hdr *hdr);
 
 void ath_hw_setbssidmask(struct ath_common *common);
-void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key);
+void ath_key_delete(struct ath_common *common, u8 hw_key_idx);
 int ath_key_config(struct ath_common *common,
                          struct ieee80211_vif *vif,
                          struct ieee80211_sta *sta,
index 16e052d02c94088006e380dd95bc9bec1ba28f88..0f4836fc3b7c1f74efe11f838cabc60633c74724 100644 (file)
@@ -522,7 +522,7 @@ ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
                }
                break;
        case DISABLE_KEY:
-               ath_key_delete(common, key);
+               ath_key_delete(common, key->hw_key_idx);
                break;
        default:
                ret = -EINVAL;
index a553c91d41a143c90c374e6fff78131e835fb3a4..7d670a71b7b8bc8696dd0c357fd9cbe3f5f5ff09 100644 (file)
@@ -1460,7 +1460,7 @@ static int ath9k_htc_set_key(struct ieee80211_hw *hw,
                }
                break;
        case DISABLE_KEY:
-               ath_key_delete(common, key);
+               ath_key_delete(common, key->hw_key_idx);
                break;
        default:
                ret = -EINVAL;
index d814b8504ec28107c9e4feb601847df8814a8e12..84b3858f43a10ad56ad61e38d0679ecb82ae1c36 100644 (file)
@@ -1544,12 +1544,11 @@ static void ath9k_del_ps_key(struct ath_softc *sc,
 {
        struct ath_common *common = ath9k_hw_common(sc->sc_ah);
        struct ath_node *an = (struct ath_node *) sta->drv_priv;
-       struct ieee80211_key_conf ps_key = { .hw_key_idx = an->ps_key };
 
        if (!an->ps_key)
            return;
 
-       ath_key_delete(common, &ps_key);
+       ath_key_delete(common, an->ps_key);
        an->ps_key = 0;
        an->key_idx[0] = 0;
 }
@@ -1740,7 +1739,7 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
                }
                break;
        case DISABLE_KEY:
-               ath_key_delete(common, key);
+               ath_key_delete(common, key->hw_key_idx);
                if (an) {
                        for (i = 0; i < ARRAY_SIZE(an->key_idx); i++) {
                                if (an->key_idx[i] != key->hw_key_idx)
index cb266cf3c77c7871665ce304d379bd2e427071b7..61b59a804e308d8358903d3f81950a85c97afdf0 100644 (file)
@@ -581,38 +581,38 @@ EXPORT_SYMBOL(ath_key_config);
 /*
  * Delete Key.
  */
-void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key)
+void ath_key_delete(struct ath_common *common, u8 hw_key_idx)
 {
        /* Leave CCMP and TKIP (main key) configured to avoid disabling
         * encryption for potentially pending frames already in a TXQ with the
         * keyix pointing to this key entry. Instead, only clear the MAC address
         * to prevent RX processing from using this key cache entry.
         */
-       if (test_bit(key->hw_key_idx, common->ccmp_keymap) ||
-           test_bit(key->hw_key_idx, common->tkip_keymap))
-               ath_hw_keysetmac(common, key->hw_key_idx, NULL);
+       if (test_bit(hw_key_idx, common->ccmp_keymap) ||
+           test_bit(hw_key_idx, common->tkip_keymap))
+               ath_hw_keysetmac(common, hw_key_idx, NULL);
        else
-               ath_hw_keyreset(common, key->hw_key_idx);
-       if (key->hw_key_idx < IEEE80211_WEP_NKID)
+               ath_hw_keyreset(common, hw_key_idx);
+       if (hw_key_idx < IEEE80211_WEP_NKID)
                return;
 
-       clear_bit(key->hw_key_idx, common->keymap);
-       clear_bit(key->hw_key_idx, common->ccmp_keymap);
-       if (key->cipher != WLAN_CIPHER_SUITE_TKIP)
+       clear_bit(hw_key_idx, common->keymap);
+       clear_bit(hw_key_idx, common->ccmp_keymap);
+       if (!test_bit(hw_key_idx, common->tkip_keymap))
                return;
 
-       clear_bit(key->hw_key_idx + 64, common->keymap);
+       clear_bit(hw_key_idx + 64, common->keymap);
 
-       clear_bit(key->hw_key_idx, common->tkip_keymap);
-       clear_bit(key->hw_key_idx + 64, common->tkip_keymap);
+       clear_bit(hw_key_idx, common->tkip_keymap);
+       clear_bit(hw_key_idx + 64, common->tkip_keymap);
 
        if (!(common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED)) {
-               ath_hw_keyreset(common, key->hw_key_idx + 32);
-               clear_bit(key->hw_key_idx + 32, common->keymap);
-               clear_bit(key->hw_key_idx + 64 + 32, common->keymap);
+               ath_hw_keyreset(common, hw_key_idx + 32);
+               clear_bit(hw_key_idx + 32, common->keymap);
+               clear_bit(hw_key_idx + 64 + 32, common->keymap);
 
-               clear_bit(key->hw_key_idx + 32, common->tkip_keymap);
-               clear_bit(key->hw_key_idx + 64 + 32, common->tkip_keymap);
+               clear_bit(hw_key_idx + 32, common->tkip_keymap);
+               clear_bit(hw_key_idx + 64 + 32, common->tkip_keymap);
        }
 }
 EXPORT_SYMBOL(ath_key_delete);