summaryrefslogtreecommitdiffstats
path: root/net/wireless/core.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2021-09-27 13:11:06 +0200
committerJohannes Berg <johannes.berg@intel.com>2021-09-27 13:30:33 +0200
commite53e9828a8d2c6545e01ff9711f1221f2fd199ce (patch)
tree173f77b2ee1a45a315d9746095b27a5a7d1e0c06 /net/wireless/core.c
parent63214f02cff9ebd57be00e143de12107c66f5394 (diff)
downloadlinux-e53e9828a8d2c6545e01ff9711f1221f2fd199ce.tar.bz2
cfg80211: always free wiphy specific regdomain
In the (somewhat unlikely) event that we allocate a wiphy, then add a regdomain to it, and then fail registration, we leak the regdomain. Fix this by just always freeing it at the end, in the normal cases we'll free (and NULL) it during wiphy_unregister(). This happened when the wiphy settings were bad, and since they can be controlled by userspace with hwsim, syzbot was able to find this issue. Reported-by: syzbot+1638e7c770eef6b6c0d0@syzkaller.appspotmail.com Fixes: 3e0c3ff36c4c ("cfg80211: allow multiple driver regulatory_hints()") Signed-off-by: Johannes Berg <johannes.berg@intel.com> Link: https://lore.kernel.org/r/20210927131105.68b70cef4674.I4b9f0aa08c2af28555963b9fe3d34395bb72e0cc@changeid Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless/core.c')
-rw-r--r--net/wireless/core.c10
1 files changed, 10 insertions, 0 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 03323121ca50..45be124a98f1 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -1080,6 +1080,16 @@ void cfg80211_dev_free(struct cfg80211_registered_device *rdev)
list_for_each_entry_safe(scan, tmp, &rdev->bss_list, list)
cfg80211_put_bss(&rdev->wiphy, &scan->pub);
mutex_destroy(&rdev->wiphy.mtx);
+
+ /*
+ * The 'regd' can only be non-NULL if we never finished
+ * initializing the wiphy and thus never went through the
+ * unregister path - e.g. in failure scenarios. Thus, it
+ * cannot have been visible to anyone if non-NULL, so we
+ * can just free it here.
+ */
+ kfree(rcu_dereference_raw(rdev->wiphy.regd));
+
kfree(rdev);
}