Commit 4d45145b authored by Johannes Berg's avatar Johannes Berg
Browse files

wifi: cfg80211: hold wiphy lock when sending wiphy



Sending the wiphy out might cause calls to the driver,
notably get_txq_stats() and get_antenna(). These aren't
very important, since the normally have their own locks
and/or just send out static data, but if the contract
should be that the wiphy lock is always held, these are
also affected. Fix that.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 7d2d0ff4
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -129,6 +129,7 @@ int cfg80211_dev_rename(struct cfg80211_registered_device *rdev,
	int result;

	ASSERT_RTNL();
	lockdep_assert_wiphy(&rdev->wiphy);

	/* Ignore nop renames */
	if (strcmp(newname, wiphy_name(&rdev->wiphy)) == 0)
@@ -195,6 +196,8 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
			continue;
		nl80211_notify_iface(rdev, wdev, NL80211_CMD_DEL_INTERFACE);
	}

	wiphy_lock(&rdev->wiphy);
	nl80211_notify_wiphy(rdev, NL80211_CMD_DEL_WIPHY);

	wiphy_net_set(&rdev->wiphy, net);
@@ -203,6 +206,8 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
	WARN_ON(err);

	nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
	wiphy_unlock(&rdev->wiphy);

	list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
		if (!wdev->netdev)
			continue;
@@ -941,8 +946,10 @@ int wiphy_register(struct wiphy *wiphy)
	rdev->wiphy.features |= NL80211_FEATURE_SCAN_FLUSH;

	rtnl_lock();
	wiphy_lock(&rdev->wiphy);
	res = device_add(&rdev->wiphy.dev);
	if (res) {
		wiphy_unlock(&rdev->wiphy);
		rtnl_unlock();
		return res;
	}
@@ -956,6 +963,7 @@ int wiphy_register(struct wiphy *wiphy)

	cfg80211_debugfs_rdev_add(rdev);
	nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
	wiphy_unlock(&rdev->wiphy);

	/* set up regulatory info */
	wiphy_regulatory_register(wiphy);
+3 −0
Original line number Diff line number Diff line
@@ -3081,6 +3081,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
		if (state->filter_wiphy != -1 &&
		    state->filter_wiphy != rdev->wiphy_idx)
			continue;
		wiphy_lock(&rdev->wiphy);
		/* attempt to fit multiple wiphy data chunks into the skb */
		do {
			ret = nl80211_send_wiphy(rdev, NL80211_CMD_NEW_WIPHY,
@@ -3107,6 +3108,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
				    cb->min_dump_alloc < 4096) {
					cb->min_dump_alloc = 4096;
					state->split_start = 0;
					wiphy_unlock(&rdev->wiphy);
					rtnl_unlock();
					return 1;
				}
@@ -3114,6 +3116,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
				break;
			}
		} while (state->split_start > 0);
		wiphy_unlock(&rdev->wiphy);
		break;
	}
	rtnl_unlock();