From: Greg Kroah-Hartman Date: Mon, 6 Sep 2021 08:49:05 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v5.10.63~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=0c979ab209b05e92a21222e5b927d716f07869c1;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: ath-export-ath_hw_keysetmac.patch ath-modify-ath_key_delete-to-not-need-full-key-entry.patch ath-use-safer-key-clearing-with-key-cache-entries.patch ath9k-clear-key-cache-explicitly-on-disabling-hardware.patch ath9k-postpone-key-cache-entry-deletion-for-txq-frames-reference-it.patch --- diff --git a/queue-4.4/ath-export-ath_hw_keysetmac.patch b/queue-4.4/ath-export-ath_hw_keysetmac.patch new file mode 100644 index 00000000000..84a553365dd --- /dev/null +++ b/queue-4.4/ath-export-ath_hw_keysetmac.patch @@ -0,0 +1,50 @@ +From d2d3e36498dd8e0c83ea99861fac5cf9e8671226 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 14 Dec 2020 19:21:16 +0200 +Subject: ath: Export ath_hw_keysetmac() + +From: Jouni Malinen + +commit d2d3e36498dd8e0c83ea99861fac5cf9e8671226 upstream. + +ath9k is going to use this for safer management of key cache entries. + +Signed-off-by: Jouni Malinen +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20201214172118.18100-4-jouni@codeaurora.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath.h | 1 + + drivers/net/wireless/ath/key.c | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ath/ath.h ++++ b/drivers/net/wireless/ath/ath.h +@@ -205,6 +205,7 @@ int ath_key_config(struct ath_common *co + struct ieee80211_sta *sta, + struct ieee80211_key_conf *key); + bool ath_hw_keyreset(struct ath_common *common, u16 entry); ++bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac); + void ath_hw_cycle_counters_update(struct ath_common *common); + int32_t ath_hw_get_listen_time(struct ath_common *common); + +--- a/drivers/net/wireless/ath/key.c ++++ b/drivers/net/wireless/ath/key.c +@@ -84,8 +84,7 @@ bool ath_hw_keyreset(struct ath_common * + } + EXPORT_SYMBOL(ath_hw_keyreset); + +-static bool ath_hw_keysetmac(struct ath_common *common, +- u16 entry, const u8 *mac) ++bool ath_hw_keysetmac(struct ath_common *common, u16 entry, const u8 *mac) + { + u32 macHi, macLo; + u32 unicast_flag = AR_KEYTABLE_VALID; +@@ -125,6 +124,7 @@ static bool ath_hw_keysetmac(struct ath_ + + return true; + } ++EXPORT_SYMBOL(ath_hw_keysetmac); + + static bool ath_hw_set_keycache_entry(struct ath_common *common, u16 entry, + const struct ath_keyval *k, diff --git a/queue-4.4/ath-modify-ath_key_delete-to-not-need-full-key-entry.patch b/queue-4.4/ath-modify-ath_key_delete-to-not-need-full-key-entry.patch new file mode 100644 index 00000000000..06cf65081ce --- /dev/null +++ b/queue-4.4/ath-modify-ath_key_delete-to-not-need-full-key-entry.patch @@ -0,0 +1,143 @@ +From 144cd24dbc36650a51f7fe3bf1424a1432f1f480 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 14 Dec 2020 19:21:17 +0200 +Subject: ath: Modify ath_key_delete() to not need full key entry + +From: Jouni Malinen + +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 +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20201214172118.18100-5-jouni@codeaurora.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath.h | 2 - + drivers/net/wireless/ath/ath5k/mac80211-ops.c | 2 - + drivers/net/wireless/ath/ath9k/htc_drv_main.c | 2 - + drivers/net/wireless/ath/ath9k/main.c | 5 +-- + drivers/net/wireless/ath/key.c | 34 +++++++++++++------------- + 5 files changed, 22 insertions(+), 23 deletions(-) + +--- a/drivers/net/wireless/ath/ath.h ++++ b/drivers/net/wireless/ath/ath.h +@@ -199,7 +199,7 @@ struct sk_buff *ath_rxbuf_alloc(struct a + 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, +--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c ++++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c +@@ -522,7 +522,7 @@ ath5k_set_key(struct ieee80211_hw *hw, e + } + break; + case DISABLE_KEY: +- ath_key_delete(common, key); ++ ath_key_delete(common, key->hw_key_idx); + break; + default: + ret = -EINVAL; +--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c ++++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c +@@ -1463,7 +1463,7 @@ static int ath9k_htc_set_key(struct ieee + } + break; + case DISABLE_KEY: +- ath_key_delete(common, key); ++ ath_key_delete(common, key->hw_key_idx); + break; + default: + ret = -EINVAL; +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1526,12 +1526,11 @@ static void ath9k_del_ps_key(struct ath_ + { + 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; + } +@@ -1722,7 +1721,7 @@ static int ath9k_set_key(struct ieee8021 + } + 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) +--- a/drivers/net/wireless/ath/key.c ++++ b/drivers/net/wireless/ath/key.c +@@ -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); diff --git a/queue-4.4/ath-use-safer-key-clearing-with-key-cache-entries.patch b/queue-4.4/ath-use-safer-key-clearing-with-key-cache-entries.patch new file mode 100644 index 00000000000..d56c8cb5b04 --- /dev/null +++ b/queue-4.4/ath-use-safer-key-clearing-with-key-cache-entries.patch @@ -0,0 +1,52 @@ +From 56c5485c9e444c2e85e11694b6c44f1338fc20fd Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 14 Dec 2020 19:21:14 +0200 +Subject: ath: Use safer key clearing with key cache entries + +From: Jouni Malinen + +commit 56c5485c9e444c2e85e11694b6c44f1338fc20fd upstream. + +It is possible for there to be pending frames in TXQs with a reference +to the key cache entry that is being deleted. If such a key cache entry +is cleared, those pending frame in TXQ might get transmitted without +proper encryption. It is safer to leave the previously used key into the +key cache in such cases. Instead, only clear the MAC address to prevent +RX processing from using this key cache entry. + +This is needed in particularly in AP mode where the TXQs cannot be +flushed on station disconnection. This change alone may not be able to +address all cases where the key cache entry might get reused for other +purposes immediately (the key cache entry should be released for reuse +only once the TXQs do not have any remaining references to them), but +this makes it less likely to get unprotected frames and the more +complete changes may end up being significantly more complex. + +Signed-off-by: Jouni Malinen +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20201214172118.18100-2-jouni@codeaurora.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/key.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/key.c ++++ b/drivers/net/wireless/ath/key.c +@@ -583,7 +583,16 @@ EXPORT_SYMBOL(ath_key_config); + */ + void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf *key) + { +- ath_hw_keyreset(common, key->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); ++ else ++ ath_hw_keyreset(common, key->hw_key_idx); + if (key->hw_key_idx < IEEE80211_WEP_NKID) + return; + diff --git a/queue-4.4/ath9k-clear-key-cache-explicitly-on-disabling-hardware.patch b/queue-4.4/ath9k-clear-key-cache-explicitly-on-disabling-hardware.patch new file mode 100644 index 00000000000..b7eac6679e4 --- /dev/null +++ b/queue-4.4/ath9k-clear-key-cache-explicitly-on-disabling-hardware.patch @@ -0,0 +1,35 @@ +From 73488cb2fa3bb1ef9f6cf0d757f76958bd4deaca Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 14 Dec 2020 19:21:15 +0200 +Subject: ath9k: Clear key cache explicitly on disabling hardware + +From: Jouni Malinen + +commit 73488cb2fa3bb1ef9f6cf0d757f76958bd4deaca upstream. + +Now that ath/key.c may not be explicitly clearing keys from the key +cache, clear all key cache entries when disabling hardware to make sure +no keys are left behind beyond this point. + +Signed-off-by: Jouni Malinen +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20201214172118.18100-3-jouni@codeaurora.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath9k/main.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -890,6 +890,11 @@ static void ath9k_stop(struct ieee80211_ + + spin_unlock_bh(&sc->sc_pcu_lock); + ++ /* Clear key cache entries explicitly to get rid of any potentially ++ * remaining keys. ++ */ ++ ath9k_cmn_init_crypto(sc->sc_ah); ++ + ath9k_ps_restore(sc); + + sc->ps_idle = prev_idle; diff --git a/queue-4.4/ath9k-postpone-key-cache-entry-deletion-for-txq-frames-reference-it.patch b/queue-4.4/ath9k-postpone-key-cache-entry-deletion-for-txq-frames-reference-it.patch new file mode 100644 index 00000000000..de4dce2f6f1 --- /dev/null +++ b/queue-4.4/ath9k-postpone-key-cache-entry-deletion-for-txq-frames-reference-it.patch @@ -0,0 +1,161 @@ +From ca2848022c12789685d3fab3227df02b863f9696 Mon Sep 17 00:00:00 2001 +From: Jouni Malinen +Date: Mon, 14 Dec 2020 19:21:18 +0200 +Subject: ath9k: Postpone key cache entry deletion for TXQ frames reference it + +From: Jouni Malinen + +commit ca2848022c12789685d3fab3227df02b863f9696 upstream. + +Do not delete a key cache entry that is still being referenced by +pending frames in TXQs. This avoids reuse of the key cache entry while a +frame might still be transmitted using it. + +To avoid having to do any additional operations during the main TX path +operations, track pending key cache entries in a new bitmap and check +whether any pending entries can be deleted before every new key +add/remove operation. Also clear any remaining entries when stopping the +interface. + +Signed-off-by: Jouni Malinen +Signed-off-by: Kalle Valo +Link: https://lore.kernel.org/r/20201214172118.18100-6-jouni@codeaurora.org +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/wireless/ath/ath9k/hw.h | 1 + drivers/net/wireless/ath/ath9k/main.c | 87 +++++++++++++++++++++++++++++++++- + 2 files changed, 87 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ath/ath9k/hw.h ++++ b/drivers/net/wireless/ath/ath9k/hw.h +@@ -814,6 +814,7 @@ struct ath_hw { + struct ath9k_pacal_info pacal_info; + struct ar5416Stats stats; + struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES]; ++ DECLARE_BITMAP(pending_del_keymap, ATH_KEYMAX); + + enum ath9k_int imask; + u32 imrs2_reg; +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -819,12 +819,80 @@ exit: + ieee80211_free_txskb(hw, skb); + } + ++static bool ath9k_txq_list_has_key(struct list_head *txq_list, u32 keyix) ++{ ++ struct ath_buf *bf; ++ struct ieee80211_tx_info *txinfo; ++ struct ath_frame_info *fi; ++ ++ list_for_each_entry(bf, txq_list, list) { ++ if (bf->bf_state.stale || !bf->bf_mpdu) ++ continue; ++ ++ txinfo = IEEE80211_SKB_CB(bf->bf_mpdu); ++ fi = (struct ath_frame_info *)&txinfo->rate_driver_data[0]; ++ if (fi->keyix == keyix) ++ return true; ++ } ++ ++ return false; ++} ++ ++static bool ath9k_txq_has_key(struct ath_softc *sc, u32 keyix) ++{ ++ struct ath_hw *ah = sc->sc_ah; ++ int i; ++ struct ath_txq *txq; ++ bool key_in_use = false; ++ ++ for (i = 0; !key_in_use && i < ATH9K_NUM_TX_QUEUES; i++) { ++ if (!ATH_TXQ_SETUP(sc, i)) ++ continue; ++ txq = &sc->tx.txq[i]; ++ if (!txq->axq_depth) ++ continue; ++ if (!ath9k_hw_numtxpending(ah, txq->axq_qnum)) ++ continue; ++ ++ ath_txq_lock(sc, txq); ++ key_in_use = ath9k_txq_list_has_key(&txq->axq_q, keyix); ++ if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { ++ int idx = txq->txq_tailidx; ++ ++ while (!key_in_use && ++ !list_empty(&txq->txq_fifo[idx])) { ++ key_in_use = ath9k_txq_list_has_key( ++ &txq->txq_fifo[idx], keyix); ++ INCR(idx, ATH_TXFIFO_DEPTH); ++ } ++ } ++ ath_txq_unlock(sc, txq); ++ } ++ ++ return key_in_use; ++} ++ ++static void ath9k_pending_key_del(struct ath_softc *sc, u8 keyix) ++{ ++ struct ath_hw *ah = sc->sc_ah; ++ struct ath_common *common = ath9k_hw_common(ah); ++ ++ if (!test_bit(keyix, ah->pending_del_keymap) || ++ ath9k_txq_has_key(sc, keyix)) ++ return; ++ ++ /* No more TXQ frames point to this key cache entry, so delete it. */ ++ clear_bit(keyix, ah->pending_del_keymap); ++ ath_key_delete(common, keyix); ++} ++ + static void ath9k_stop(struct ieee80211_hw *hw) + { + struct ath_softc *sc = hw->priv; + struct ath_hw *ah = sc->sc_ah; + struct ath_common *common = ath9k_hw_common(ah); + bool prev_idle; ++ int i; + + ath9k_deinit_channel_context(sc); + +@@ -890,6 +958,9 @@ static void ath9k_stop(struct ieee80211_ + + spin_unlock_bh(&sc->sc_pcu_lock); + ++ for (i = 0; i < ATH_KEYMAX; i++) ++ ath9k_pending_key_del(sc, i); ++ + /* Clear key cache entries explicitly to get rid of any potentially + * remaining keys. + */ +@@ -1692,6 +1763,12 @@ static int ath9k_set_key(struct ieee8021 + if (sta) + an = (struct ath_node *)sta->drv_priv; + ++ /* Delete pending key cache entries if no more frames are pointing to ++ * them in TXQs. ++ */ ++ for (i = 0; i < ATH_KEYMAX; i++) ++ ath9k_pending_key_del(sc, i); ++ + switch (cmd) { + case SET_KEY: + if (sta) +@@ -1721,7 +1798,15 @@ static int ath9k_set_key(struct ieee8021 + } + break; + case DISABLE_KEY: +- ath_key_delete(common, key->hw_key_idx); ++ if (ath9k_txq_has_key(sc, key->hw_key_idx)) { ++ /* Delay key cache entry deletion until there are no ++ * remaining TXQ frames pointing to this entry. ++ */ ++ set_bit(key->hw_key_idx, sc->sc_ah->pending_del_keymap); ++ ath_hw_keysetmac(common, key->hw_key_idx, NULL); ++ } else { ++ 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) diff --git a/queue-4.4/series b/queue-4.4/series index 974453b8250..426248d69d0 100644 --- a/queue-4.4/series +++ b/queue-4.4/series @@ -5,3 +5,8 @@ qede-fix-memset-corruption.patch cryptoloop-add-a-deprecation-warning.patch arm-8918-2-only-build-return_address-if-needed.patch alsa-pcm-fix-divide-error-in-snd_pcm_lib_ioctl.patch +ath-use-safer-key-clearing-with-key-cache-entries.patch +ath9k-clear-key-cache-explicitly-on-disabling-hardware.patch +ath-export-ath_hw_keysetmac.patch +ath-modify-ath_key_delete-to-not-need-full-key-entry.patch +ath9k-postpone-key-cache-entry-deletion-for-txq-frames-reference-it.patch