mac80211: fix letting drivers iterate over keys
authorFelix Fietkau <nbd@nbd.name>
Sun, 6 Oct 2024 15:43:23 +0000 (17:43 +0200)
committerFelix Fietkau <nbd@nbd.name>
Sun, 13 Oct 2024 10:56:03 +0000 (12:56 +0200)
Skip non-uploaded keys to avoid corner cases

Signed-off-by: Felix Fietkau <nbd@nbd.name>
package/kernel/mac80211/patches/subsys/341-wifi-mac80211-skip-non-uploaded-keys-in-ieee80211_it.patch [new file with mode: 0644]

diff --git a/package/kernel/mac80211/patches/subsys/341-wifi-mac80211-skip-non-uploaded-keys-in-ieee80211_it.patch b/package/kernel/mac80211/patches/subsys/341-wifi-mac80211-skip-non-uploaded-keys-in-ieee80211_it.patch
new file mode 100644 (file)
index 0000000..b426d68
--- /dev/null
@@ -0,0 +1,79 @@
+From: Felix Fietkau <nbd@nbd.name>
+Date: Sun, 6 Oct 2024 17:34:08 +0200
+Subject: [PATCH] wifi: mac80211: skip non-uploaded keys in ieee80211_iter_keys
+
+Sync iterator conditions with ieee80211_iter_keys_rcu.
+
+Fixes: 830af02f24fb ("mac80211: allow driver to iterate keys")
+Signed-off-by: Felix Fietkau <nbd@nbd.name>
+---
+
+--- a/net/mac80211/key.c
++++ b/net/mac80211/key.c
+@@ -987,6 +987,26 @@ void ieee80211_reenable_keys(struct ieee
+       }
+ }
++static void
++ieee80211_key_iter(struct ieee80211_hw *hw,
++                 struct ieee80211_vif *vif,
++                 struct ieee80211_key *key,
++                 void (*iter)(struct ieee80211_hw *hw,
++                              struct ieee80211_vif *vif,
++                              struct ieee80211_sta *sta,
++                              struct ieee80211_key_conf *key,
++                              void *data),
++                 void *iter_data)
++{
++      /* skip keys of station in removal process */
++      if (key->sta && key->sta->removed)
++              return;
++      if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
++              return;
++      iter(hw, vif, key->sta ? &key->sta->sta : NULL,
++           &key->conf, iter_data);
++}
++
+ void ieee80211_iter_keys(struct ieee80211_hw *hw,
+                        struct ieee80211_vif *vif,
+                        void (*iter)(struct ieee80211_hw *hw,
+@@ -1005,16 +1025,13 @@ void ieee80211_iter_keys(struct ieee8021
+       if (vif) {
+               sdata = vif_to_sdata(vif);
+               list_for_each_entry_safe(key, tmp, &sdata->key_list, list)
+-                      iter(hw, &sdata->vif,
+-                           key->sta ? &key->sta->sta : NULL,
+-                           &key->conf, iter_data);
++                      ieee80211_key_iter(hw, vif, key, iter, iter_data);
+       } else {
+               list_for_each_entry(sdata, &local->interfaces, list)
+                       list_for_each_entry_safe(key, tmp,
+                                                &sdata->key_list, list)
+-                              iter(hw, &sdata->vif,
+-                                   key->sta ? &key->sta->sta : NULL,
+-                                   &key->conf, iter_data);
++                              ieee80211_key_iter(hw, &sdata->vif, key,
++                                                 iter, iter_data);
+       }
+ }
+ EXPORT_SYMBOL(ieee80211_iter_keys);
+@@ -1031,17 +1048,8 @@ _ieee80211_iter_keys_rcu(struct ieee8021
+ {
+       struct ieee80211_key *key;
+-      list_for_each_entry_rcu(key, &sdata->key_list, list) {
+-              /* skip keys of station in removal process */
+-              if (key->sta && key->sta->removed)
+-                      continue;
+-              if (!(key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
+-                      continue;
+-
+-              iter(hw, &sdata->vif,
+-                   key->sta ? &key->sta->sta : NULL,
+-                   &key->conf, iter_data);
+-      }
++      list_for_each_entry_rcu(key, &sdata->key_list, list)
++              ieee80211_key_iter(hw, &sdata->vif, key, iter, iter_data);
+ }
+ void ieee80211_iter_keys_rcu(struct ieee80211_hw *hw,