summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2023-08-16 16:38:04 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-10-10 23:00:40 +0300
commitc797498e860e9a435a651bbf0789433684ce6dd8 (patch)
treefe7ef2bef06c22837730866c1148c5b9a2e832cc /include
parent3fcc6d7d5f40dad56dee7bde787b7e23edd4b93c (diff)
downloadlinux-c797498e860e9a435a651bbf0789433684ce6dd8.tar.xz
wifi: cfg80211: fix cqm_config access race
[ Upstream commit 37c20b2effe987b806c8de6d12978e4ffeff026f ] Max Schulze reports crashes with brcmfmac. The reason seems to be a race between userspace removing the CQM config and the driver calling cfg80211_cqm_rssi_notify(), where if the data is freed while cfg80211_cqm_rssi_notify() runs it will crash since it assumes wdev->cqm_config is set. This can't be fixed with a simple non-NULL check since there's nothing we can do for locking easily, so use RCU instead to protect the pointer, but that requires pulling the updates out into an asynchronous worker so they can sleep and call back into the driver. Since we need to change the free anyway, also change it to go back to the old settings if changing the settings fails. Reported-and-tested-by: Max Schulze <max.schulze@online.de> Closes: https://lore.kernel.org/r/ac96309a-8d8d-4435-36e6-6d152eb31876@online.de Fixes: 4a4b8169501b ("cfg80211: Accept multiple RSSI thresholds for CQM") Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'include')
-rw-r--r--include/net/cfg80211.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index f2144db89183..ab64bb94c92f 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -5877,7 +5877,8 @@ struct wireless_dev {
} wext;
#endif
- struct cfg80211_cqm_config *cqm_config;
+ struct wiphy_work cqm_rssi_work;
+ struct cfg80211_cqm_config __rcu *cqm_config;
struct list_head pmsr_list;
spinlock_t pmsr_lock;