]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Sep 2021 08:49:22 +0000 (10:49 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Sep 2021 08:49:22 +0000 (10:49 +0200)
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

queue-4.9/ath-export-ath_hw_keysetmac.patch [new file with mode: 0644]
queue-4.9/ath-modify-ath_key_delete-to-not-need-full-key-entry.patch [new file with mode: 0644]
queue-4.9/ath-use-safer-key-clearing-with-key-cache-entries.patch [new file with mode: 0644]
queue-4.9/ath9k-clear-key-cache-explicitly-on-disabling-hardware.patch [new file with mode: 0644]
queue-4.9/ath9k-postpone-key-cache-entry-deletion-for-txq-frames-reference-it.patch [new file with mode: 0644]
queue-4.9/series

diff --git a/queue-4.9/ath-export-ath_hw_keysetmac.patch b/queue-4.9/ath-export-ath_hw_keysetmac.patch
new file mode 100644 (file)
index 0000000..84a5533
--- /dev/null
@@ -0,0 +1,50 @@
+From d2d3e36498dd8e0c83ea99861fac5cf9e8671226 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@codeaurora.org>
+Date: Mon, 14 Dec 2020 19:21:16 +0200
+Subject: ath: Export ath_hw_keysetmac()
+
+From: Jouni Malinen <jouni@codeaurora.org>
+
+commit d2d3e36498dd8e0c83ea99861fac5cf9e8671226 upstream.
+
+ath9k is going to use this for safer management of key cache entries.
+
+Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20201214172118.18100-4-jouni@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.9/ath-modify-ath_key_delete-to-not-need-full-key-entry.patch b/queue-4.9/ath-modify-ath_key_delete-to-not-need-full-key-entry.patch
new file mode 100644 (file)
index 0000000..75e9e14
--- /dev/null
@@ -0,0 +1,143 @@
+From 144cd24dbc36650a51f7fe3bf1424a1432f1f480 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@codeaurora.org>
+Date: Mon, 14 Dec 2020 19:21:17 +0200
+Subject: ath: Modify ath_key_delete() to not need full key entry
+
+From: Jouni Malinen <jouni@codeaurora.org>
+
+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                |    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
+@@ -1460,7 +1460,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
+@@ -1544,12 +1544,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;
+ }
+@@ -1740,7 +1739,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.9/ath-use-safer-key-clearing-with-key-cache-entries.patch b/queue-4.9/ath-use-safer-key-clearing-with-key-cache-entries.patch
new file mode 100644 (file)
index 0000000..d56c8cb
--- /dev/null
@@ -0,0 +1,52 @@
+From 56c5485c9e444c2e85e11694b6c44f1338fc20fd Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@codeaurora.org>
+Date: Mon, 14 Dec 2020 19:21:14 +0200
+Subject: ath: Use safer key clearing with key cache entries
+
+From: Jouni Malinen <jouni@codeaurora.org>
+
+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 <jouni@codeaurora.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20201214172118.18100-2-jouni@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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.9/ath9k-clear-key-cache-explicitly-on-disabling-hardware.patch b/queue-4.9/ath9k-clear-key-cache-explicitly-on-disabling-hardware.patch
new file mode 100644 (file)
index 0000000..c5b1d34
--- /dev/null
@@ -0,0 +1,35 @@
+From 73488cb2fa3bb1ef9f6cf0d757f76958bd4deaca Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@codeaurora.org>
+Date: Mon, 14 Dec 2020 19:21:15 +0200
+Subject: ath9k: Clear key cache explicitly on disabling hardware
+
+From: Jouni Malinen <jouni@codeaurora.org>
+
+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 <jouni@codeaurora.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20201214172118.18100-3-jouni@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -894,6 +894,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.9/ath9k-postpone-key-cache-entry-deletion-for-txq-frames-reference-it.patch b/queue-4.9/ath9k-postpone-key-cache-entry-deletion-for-txq-frames-reference-it.patch
new file mode 100644 (file)
index 0000000..56ce605
--- /dev/null
@@ -0,0 +1,161 @@
+From ca2848022c12789685d3fab3227df02b863f9696 Mon Sep 17 00:00:00 2001
+From: Jouni Malinen <jouni@codeaurora.org>
+Date: Mon, 14 Dec 2020 19:21:18 +0200
+Subject: ath9k: Postpone key cache entry deletion for TXQ frames reference it
+
+From: Jouni Malinen <jouni@codeaurora.org>
+
+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 <jouni@codeaurora.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+Link: https://lore.kernel.org/r/20201214172118.18100-6-jouni@codeaurora.org
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ 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
+@@ -815,6 +815,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
+@@ -821,12 +821,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);
+@@ -894,6 +962,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.
+        */
+@@ -1710,6 +1781,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)
+@@ -1739,7 +1816,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)
index f140f9b6107a8aa97dc677cf25610629dfed4992..92eb0fe331a701b5c44e92da5be0f82f597fc3a3 100644 (file)
@@ -7,3 +7,8 @@ perf-x86-amd-ibs-work-around-erratum-1197.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