summaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorMiri Korenblit <miriam.rachel.korenblit@intel.com>2025-03-06 12:37:59 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-03-28 21:58:48 +0100
commit0272d4af7f92997541d8bbf4c51918b93ded6ee2 (patch)
tree3d20b84721e67b299dfa1ab119372bff5343aa31 /net
parentd02c9acd68950a444acda18d514e2b41f846cb7f (diff)
downloadlinux-0272d4af7f92997541d8bbf4c51918b93ded6ee2.tar.gz
linux-0272d4af7f92997541d8bbf4c51918b93ded6ee2.tar.bz2
linux-0272d4af7f92997541d8bbf4c51918b93ded6ee2.zip
wifi: cfg80211: cancel wiphy_work before freeing wiphy
[ Upstream commit 72d520476a2fab6f3489e8388ab524985d6c4b90 ] A wiphy_work can be queued from the moment the wiphy is allocated and initialized (i.e. wiphy_new_nm). When a wiphy_work is queued, the rdev::wiphy_work is getting queued. If wiphy_free is called before the rdev::wiphy_work had a chance to run, the wiphy memory will be freed, and then when it eventally gets to run it'll use invalid memory. Fix this by canceling the work before freeing the wiphy. Fixes: a3ee4dc84c4e ("wifi: cfg80211: add a work abstraction with special semantics") Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com> Reviewed-by: Johannes Berg <johannes.berg@intel.com> Link: https://patch.msgid.link/20250306123626.efd1d19f6e07.I48229f96f4067ef73f5b87302335e2fd750136c9@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net')
-rw-r--r--net/wireless/core.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 2bed30621fa6..74904f88edfa 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1146,6 +1146,13 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
{
struct cfg80211_internal_bss *scan, *tmp;
struct cfg80211_beacon_registration *reg, *treg;
+ unsigned long flags;
+
+ spin_lock_irqsave(&rdev->wiphy_work_lock, flags);
+ WARN_ON(!list_empty(&rdev->wiphy_work_list));
+ spin_unlock_irqrestore(&rdev->wiphy_work_lock, flags);
+ cancel_work_sync(&rdev->wiphy_work);
+
rfkill_destroy(rdev->wiphy.rfkill);
list_for_each_entry_safe(reg, treg, &rdev->beacon_registrations, list) {
list_del(&reg->list);