summaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorMaxime Bizon <mbizon@freebox.fr>2010-07-21 17:21:38 +0200
committerJohn W. Linville <linville@tuxdriver.com>2010-07-21 21:13:42 +0200
commit5a652052fedbd7869572c757dd2ffc2ed420c69d (patch)
treec147fefc826f74e84a887a069235c22eadc0f561 /net/wireless
parentb43: silence phy_n sparse warnings (diff)
downloadlinux-5a652052fedbd7869572c757dd2ffc2ed420c69d.tar.xz
linux-5a652052fedbd7869572c757dd2ffc2ed420c69d.zip
cfg80211: fix race between sysfs and cfg80211
device_add() is called before adding the phy to the cfg80211 device list. So if a userspace program uses sysfs uevents to detect new phy devices, and queries nl80211 to get phy info, it can get ENODEV even though the phy exists in sysfs. An easy workaround is to hold the cfg80211 mutex until the phy is present in sysfs/cfg80211/debugfs. Signed-off-by: Maxime Bizon <mbizon@freebox.fr> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/core.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 47fcfd0eebc2..f65c6494ede9 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -472,24 +472,22 @@ int wiphy_register(struct wiphy *wiphy)
/* check and set up bitrates */
ieee80211_set_bitrate_flags(wiphy);
+ mutex_lock(&cfg80211_mutex);
+
res = device_add(&rdev->wiphy.dev);
if (res)
- return res;
+ goto out_unlock;
res = rfkill_register(rdev->rfkill);
if (res)
goto out_rm_dev;
- mutex_lock(&cfg80211_mutex);
-
/* set up regulatory info */
wiphy_update_regulatory(wiphy, NL80211_REGDOM_SET_BY_CORE);
list_add_rcu(&rdev->list, &cfg80211_rdev_list);
cfg80211_rdev_list_generation++;
- mutex_unlock(&cfg80211_mutex);
-
/* add to debugfs */
rdev->wiphy.debugfsdir =
debugfs_create_dir(wiphy_name(&rdev->wiphy),
@@ -509,11 +507,15 @@ int wiphy_register(struct wiphy *wiphy)
}
cfg80211_debugfs_rdev_add(rdev);
+ mutex_unlock(&cfg80211_mutex);
return 0;
- out_rm_dev:
+out_rm_dev:
device_del(&rdev->wiphy.dev);
+
+out_unlock:
+ mutex_unlock(&cfg80211_mutex);
return res;
}
EXPORT_SYMBOL(wiphy_register);