Skip to content

Commit

Permalink
wireless: Add missing locking to cfg80211_dev_rename
Browse files Browse the repository at this point in the history
device_rename only performs useful and race free validity
checking at the optional sysfs level so depending on it
for all of the validity checking in cfg80211_dev_rename
is racy.

Instead implement all of the needed validity checking
and locking in cfg80211_dev_rename.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Acked-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Eric W. Biederman authored and John W. Linville committed May 14, 2008
1 parent 601ae7f commit 2940bb6
Showing 1 changed file with 28 additions and 5 deletions.
33 changes: 28 additions & 5 deletions net/wireless/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,11 @@ void cfg80211_put_dev(struct cfg80211_registered_device *drv)
int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
char *newname)
{
struct cfg80211_registered_device *drv;
int idx, taken = -1, result, digits;

mutex_lock(&cfg80211_drv_mutex);

/* prohibit calling the thing phy%d when %d is not its number */
sscanf(newname, PHY_NAME "%d%n", &idx, &taken);
if (taken == strlen(newname) && idx != rdev->idx) {
Expand All @@ -156,14 +159,30 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
* deny the name if it is phy<idx> where <idx> is printed
* without leading zeroes. taken == strlen(newname) here
*/
result = -EINVAL;
if (taken == strlen(PHY_NAME) + digits)
return -EINVAL;
goto out_unlock;
}


/* Ignore nop renames */
result = 0;
if (strcmp(newname, dev_name(&rdev->wiphy.dev)) == 0)
goto out_unlock;

/* Ensure another device does not already have this name. */
list_for_each_entry(drv, &cfg80211_drv_list, list) {
result = -EINVAL;
if (strcmp(newname, dev_name(&drv->wiphy.dev)) == 0)
goto out_unlock;
}

/* this will check for collisions */
/* this will only check for collisions in sysfs
* which is not even always compiled in.
*/
result = device_rename(&rdev->wiphy.dev, newname);
if (result)
return result;
goto out_unlock;

if (!debugfs_rename(rdev->wiphy.debugfsdir->d_parent,
rdev->wiphy.debugfsdir,
Expand All @@ -172,9 +191,13 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
printk(KERN_ERR "cfg80211: failed to rename debugfs dir to %s!\n",
newname);

nl80211_notify_dev_rename(rdev);
result = 0;
out_unlock:
mutex_unlock(&cfg80211_drv_mutex);
if (result == 0)
nl80211_notify_dev_rename(rdev);

return 0;
return result;
}

/* exported functions */
Expand Down

0 comments on commit 2940bb6

Please sign in to comment.