In ath12k_mac_op_assign_vif_chanctx(), arvif is obtained from ath12k_mac_assign_link_vif() and then passed to ath12k_mac_assign_vif_to_vdev(). Inside that function, when the target radio (ar) differs from arvif->ar (multi-radio configuration), the old arvif is freed via ath12k_mac_unassign_link_vif() -> kfree() and a new one is allocated internally. However, only the ar pointer is returned to the caller — the caller's arvif still points to the freed memory. The caller then continues to dereference this stale arvif pointer at multiple locations (arvif->vdev_id, arvif->punct_bitmap, arvif->is_started, etc.), resulting in a use-after-free. Fix this by re-fetching arvif from ahvif->link[link_id] after ath12k_mac_assign_vif_to_vdev() returns, since the link pointer is always updated when a new arvif is assigned. Fixes: 477cabfdb776 ("wifi: ath12k: modify link arvif creation and removal for MLO") Cc: stable@vger.kernel.org Signed-off-by: James Kim --- drivers/net/wireless/ath/ath12k/mac.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/drivers/net/wireless/ath/ath12k/mac.c b/drivers/net/wireless/ath/ath12k/mac.c index b253d1e3f405..ee44a8b59e9b 100644 --- a/drivers/net/wireless/ath/ath12k/mac.c +++ b/drivers/net/wireless/ath/ath12k/mac.c @@ -12069,6 +12069,17 @@ ath12k_mac_op_assign_vif_chanctx(struct ieee80211_hw *hw, return -EINVAL; } + /* ath12k_mac_assign_vif_to_vdev() may free and reassign arvif + * internally when switching radios (ar != arvif->ar). Refresh + * arvif from ahvif->link[]. + */ + arvif = wiphy_dereference(hw->wiphy, ahvif->link[link_id]); + if (!arvif) { + ath12k_hw_warn(ah, "failed to get arvif for link %u after vdev assignment", + link_id); + return -ENOENT; + } + ab = ar->ab; ath12k_dbg(ab, ATH12K_DBG_MAC, -- 2.43.0