git: 86a0941db702 - main - LinuxKPI: 802.11: do not delete keys while still assoc
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 29 Aug 2025 13:19:05 UTC
The branch main has been updated by bz: URL: https://cgit.FreeBSD.org/src/commit/?id=86a0941db7028a5eb4d56aaa34998b833e5de174 commit 86a0941db7028a5eb4d56aaa34998b833e5de174 Author: Bjoern A. Zeeb <bz@FreeBSD.org> AuthorDate: 2025-05-24 20:09:51 +0000 Commit: Bjoern A. Zeeb <bz@FreeBSD.org> CommitDate: 2025-08-29 13:18:43 +0000 LinuxKPI: 802.11: do not delete keys while still assoc While we are still associated we cannot delete the keys as packets may still go out and if the firmware has no more keys it will raise and exception. This can happen given net80211 has its own mind when to do this and we, in various places, unlock and re-lock the com lock, so are open to races. Sponsored by: The FreeBSD Foundation MFC after: 3 days --- sys/compat/linuxkpi/common/src/linux_80211.c | 40 +++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/sys/compat/linuxkpi/common/src/linux_80211.c b/sys/compat/linuxkpi/common/src/linux_80211.c index cf0aca4493aa..3f850653bc7c 100644 --- a/sys/compat/linuxkpi/common/src/linux_80211.c +++ b/sys/compat/linuxkpi/common/src/linux_80211.c @@ -1350,6 +1350,7 @@ lkpi_iv_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) lhw = ic->ic_softc; hw = LHW_TO_HW(lhw); lvif = VAP_TO_LVIF(vap); + vif = LVIF_TO_VIF(lvif); /* * Make sure we do not make it here without going through @@ -1357,6 +1358,23 @@ lkpi_iv_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) */ lockdep_assert_wiphy(hw->wiphy); + /* + * While we are assoc we may still send packets. We cannot delete the + * keys as otherwise packets could go out unencrypted. Some firmware + * does not like this and will fire an assert. + * net80211 needs to drive this better but given we want the disassoc + * frame out and have to unlock we are open to a race currently. + * This check should prevent problems. + * How to test: run 800Mbit/s UDP traffic and during that restart your + * supplicant. You want to survive that. + */ + if (vif->cfg.assoc) { + if (linuxkpi_debug_80211 & D80211_TRACE_HW_CRYPTO) + ic_printf(ic, "%d %lu %s: vif still assoc; not deleting keys\n", + curthread->td_tid, jiffies, __func__); + return (0); + } + if (IEEE80211_KEY_UNDEFINED(k)) { ic_printf(ic, "%s: vap %p key %p is undefined: %p %u\n", __func__, vap, k, k->wk_cipher, k->wk_keyix); @@ -1401,7 +1419,6 @@ lkpi_iv_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) kc->keyidx, kc->hw_key_idx, kc->flags, IEEE80211_KEY_FLAG_BITS); #endif - vif = LVIF_TO_VIF(lvif); error = lkpi_80211_mo_set_key(hw, DISABLE_KEY, vif, sta, kc); if (error != 0) { ic_printf(ic, "%d %lu %s: set_key cmd %d(%s) for sta %6D failed: %d\n", @@ -2831,6 +2848,14 @@ _lkpi_sta_assoc_to_down(struct ieee80211vap *vap, enum ieee80211_state nstate, i bss_changed = 0; bss_changed |= lkpi_disassoc(sta, vif, lhw); +#ifdef LKPI_80211_HW_CRYPTO + /* + * In theory we remove keys here but there must not exist any for this + * state change until we clean them up again into small steps and no + * code duplication. + */ +#endif + lkpi_lsta_dump(lsta, ni, __func__, __LINE__); /* Adjust sta and change state (from NONE) to NOTEXIST. */ @@ -3366,6 +3391,16 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int #ifdef LKPI_80211_HW_CRYPTO if (lkpi_hwcrypto) { + /* + * In theory we only need to do this if we changed assoc. + * If we were not assoc, there should be no keys and we + * should not be here. + */ +#ifdef notyet + KASSERT((bss_changed & BSS_CHANGED_ASSOC) != 0, ("%s: " + "trying to remove keys but were not assoc: %#010jx, lvif %p\n", + __func__, (uintmax_t)bss_changed, lvif)); +#endif error = lkpi_sta_del_keys(hw, vif, lsta); if (error != 0) { ic_printf(vap->iv_ic, "%s:%d: lkpi_sta_del_keys " @@ -3427,6 +3462,9 @@ lkpi_sta_run_to_init(struct ieee80211vap *vap, enum ieee80211_state nstate, int * 4) call unassign_vif_chanctx * 5) call lkpi_hw_conf_idle * 6) call remove_chanctx + * + * Note: vif->driver_flags & IEEE80211_VIF_REMOVE_AP_AFTER_DISASSOC + * might change this. */ bss_changed |= lkpi_disassoc(sta, vif, lhw);