git: 3c38dce87ecd - main - LinuxKPI: 802.11: avoid recursive wiphy lock
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 11 Sep 2025 15:16:17 UTC
The branch main has been updated by bz:
URL: https://cgit.FreeBSD.org/src/commit/?id=3c38dce87ecd2c87744e4b7ff1904ee841f88a47
commit 3c38dce87ecd2c87744e4b7ff1904ee841f88a47
Author: Bjoern A. Zeeb <bz@FreeBSD.org>
AuthorDate: 2025-09-11 14:44:10 +0000
Commit: Bjoern A. Zeeb <bz@FreeBSD.org>
CommitDate: 2025-09-11 15:13:34 +0000
LinuxKPI: 802.11: avoid recursive wiphy lock
When freeing the last reference of the net80211 node the net80211
node_free() code may directly call into the crypto code to delete
the keys. While we still holding the wiphy lock this would lead to
a recursion on the non-recursive wiphy lock. Defer freeing the
reference until we are back under the net80211 com lock.
Reported by: Mark Phillips (mark freebsdfoundation.org) on 15.0-ALPHA1
MFC after: 3 days
---
sys/compat/linuxkpi/common/src/linux_80211.c | 54 ++++++++++++++++++----------
1 file changed, 36 insertions(+), 18 deletions(-)
diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c
index d00734001a59..bc4b334de28e 100644
--- a/sys/compat/linuxkpi/common/src/linux_80211.c
+++ b/sys/compat/linuxkpi/common/src/linux_80211.c
@@ -2568,12 +2568,6 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int
lvif->lvif_bss_synched = false;
LKPI_80211_LVIF_UNLOCK(lvif);
lkpi_lsta_remove(lsta, lvif);
- /*
- * The very last release the reference on the ni for the ni/lsta on
- * lvif->lvif_bss. Upon return from this both ni and lsta are invalid
- * and potentially freed.
- */
- ieee80211_free_node(ni);
/* conf_tx */
@@ -2582,6 +2576,18 @@ lkpi_sta_auth_to_scan(struct ieee80211vap *vap, enum ieee80211_state nstate, int
out:
wiphy_unlock(hw->wiphy);
IEEE80211_LOCK(vap->iv_ic);
+ if (error == 0) {
+ /*
+ * We do this outside the wiphy lock as net80211::node_free() may call
+ * into crypto code to delete keys and we have a recursed on
+ * non-recursive sx panic. Also only do this if we get here w/o error.
+ *
+ * The very last release the reference on the ni for the ni/lsta on
+ * lvif->lvif_bss. Upon return from this both ni and lsta are invalid
+ * and potentially freed.
+ */
+ ieee80211_free_node(ni);
+ }
return (error);
}
@@ -2906,12 +2912,6 @@ _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum ieee80211_state nstate, i
lvif->lvif_bss_synched = false;
LKPI_80211_LVIF_UNLOCK(lvif);
lkpi_lsta_remove(lsta, lvif);
- /*
- * The very last release the reference on the ni for the ni/lsta on
- * lvif->lvif_bss. Upon return from this both ni and lsta are invalid
- * and potentially freed.
- */
- ieee80211_free_node(ni);
/* conf_tx */
@@ -2921,6 +2921,18 @@ _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum ieee80211_state nstate, i
out:
wiphy_unlock(hw->wiphy);
IEEE80211_LOCK(vap->iv_ic);
+ if (error == EALREADY) {
+ /*
+ * We do this outside the wiphy lock as net80211::node_free() may call
+ * into crypto code to delete keys and we have a recursed on
+ * non-recursive sx panic. Also only do this if we get here w/o error.
+ *
+ * The very last release the reference on the ni for the ni/lsta on
+ * lvif->lvif_bss. Upon return from this both ni and lsta are invalid
+ * and potentially freed.
+ */
+ ieee80211_free_node(ni);
+ }
outni:
return (error);
}
@@ -3522,12 +3534,6 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int
lvif->lvif_bss = NULL;
lvif->lvif_bss_synched = false;
LKPI_80211_LVIF_UNLOCK(lvif);
- /*
- * The very last release the reference on the ni for the ni/lsta on
- * lvif->lvif_bss. Upon return from this both ni and lsta are invalid
- * and potentially freed.
- */
- ieee80211_free_node(ni);
/* conf_tx */
@@ -3537,6 +3543,18 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int
out:
wiphy_unlock(hw->wiphy);
IEEE80211_LOCK(vap->iv_ic);
+ if (error == EALREADY) {
+ /*
+ * We do this outside the wiphy lock as net80211::node_free() may call
+ * into crypto code to delete keys and we have a recursed on
+ * non-recursive sx panic. Also only do this if we get here w/o error.
+ *
+ * The very last release the reference on the ni for the ni/lsta on
+ * lvif->lvif_bss. Upon return from this both ni and lsta are invalid
+ * and potentially freed.
+ */
+ ieee80211_free_node(ni);
+ }
outni:
return (error);
}