wifi: iwlwifi: mld: don't dereference a pointer before NULL checking it

In iwl_mld_remove_link, the link->fw_id is saved at the beginning of the
function so we have it after we freed the link.

But the link pointer can be NULL, and is not checked when the fw_id is
stored.

Fix it by simply freeing the link at the end of the function.

fFixes: 0e66a39f4f0e ("wifi: iwlwifi: fix potential use after free in iwl_mld_remove_link()")
Reviewed-by: Johannes Berg <johannes.berg@intel.com>
Link: https://patch.msgid.link/20260515151351.371f40fc6711.I6a82cfe9655564e9c5731af91c36493b26b1208e@changeid
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
This commit is contained in:
Miri Korenblit 2026-05-15 15:14:56 +03:00
parent 2becb38a3e
commit d733ed481f

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
/*
* Copyright (C) 2024-2025 Intel Corporation
* Copyright (C) 2024-2026 Intel Corporation
*/
#include "constants.h"
@ -504,7 +504,6 @@ void iwl_mld_remove_link(struct iwl_mld *mld,
struct iwl_mld_vif *mld_vif = iwl_mld_vif_from_mac80211(bss_conf->vif);
struct iwl_mld_link *link = iwl_mld_link_from_mac80211(bss_conf);
bool is_deflink = link == &mld_vif->deflink;
u8 fw_id = link->fw_id;
if (WARN_ON(!link || link->active))
return;
@ -512,15 +511,15 @@ void iwl_mld_remove_link(struct iwl_mld *mld,
iwl_mld_rm_link_from_fw(mld, bss_conf);
/* Continue cleanup on failure */
if (!is_deflink)
kfree_rcu(link, rcu_head);
RCU_INIT_POINTER(mld_vif->link[bss_conf->link_id], NULL);
if (WARN_ON(fw_id >= mld->fw->ucode_capa.num_links))
if (WARN_ON(link->fw_id >= mld->fw->ucode_capa.num_links))
return;
RCU_INIT_POINTER(mld->fw_id_to_bss_conf[fw_id], NULL);
RCU_INIT_POINTER(mld->fw_id_to_bss_conf[link->fw_id], NULL);
if (!is_deflink)
kfree_rcu(link, rcu_head);
}
void iwl_mld_handle_missed_beacon_notif(struct iwl_mld *mld,