Both legacy and MLD add_interface paths publish the vif in vif_id_to_mac before operations which can fail. mac80211 does not call remove_interface after a failed add, leaving a stale pointer which can later be dereferenced. Clear the mapping on every failure after publication. Fixes: 698478c49294 ("iwlwifi: mvm: add an option to dereference vif by id") Fixes: cb145863e7ab ("wifi: iwlwifi: mvm: add link to firmware earlier") Signed-off-by: Jiale Yao --- drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c | 6 +++++- drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c | 4 +++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c index 5bd246e37943..83b1e355ec35 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c @@ -1748,7 +1748,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, ret = iwl_mvm_mac_ctxt_add(mvm, vif); if (ret) - goto out_unlock; + goto out_clear_vif; ret = iwl_mvm_power_update_mac(mvm); if (ret) @@ -1792,12 +1792,16 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, if (!ret && (vif->type == NL80211_IFTYPE_AP || vif->type == NL80211_IFTYPE_ADHOC)) ret = iwl_mvm_alloc_bcast_mcast_sta(mvm, vif); + if (ret) + goto out_clear_vif; goto out_unlock; out_remove_mac: mvmvif->deflink.phy_ctxt = NULL; iwl_mvm_mac_ctxt_remove(mvm, vif); + out_clear_vif: + RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL); out_unlock: mutex_unlock(&mvm->mutex); diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c index 6ea9a7c8da0c..314794b8a26f 100644 --- a/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c +++ b/drivers/net/wireless/intel/iwlwifi/mvm/mld-mac80211.c @@ -46,7 +46,7 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw, ret = iwl_mvm_mld_mac_ctxt_add(mvm, vif); if (ret) - return ret; + goto out_clear_vif; /* beacon filtering */ ret = iwl_mvm_disable_beacon_filter(mvm, vif); @@ -106,6 +106,8 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw, out_remove_mac: mvmvif->link[0] = NULL; iwl_mvm_mld_mac_ctxt_remove(mvm, vif); + out_clear_vif: + RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL); return ret; } -- 2.34.1