Skip to content

Commit 1033176

Browse files
committed
wifi: cfg80211: hold wiphy mutex for send_interface
Given all the locking rework in mac80211, we pretty much need to get into the driver with the wiphy mutex held in all callbacks. This is already mostly the case, but as Johan reported, in the get_txpower it may not be true. Lock the wiphy mutex around nl80211_send_iface(), then is also around callers of nl80211_notify_iface(). This is easy to do, fixes the problem, and aligns the locking between various calls to it in different parts of the code of cfg80211. Fixes: 0e8185c ("wifi: mac80211: check wiphy mutex in ops") Reported-by: Johan Hovold <johan@kernel.org> Closes: https://lore.kernel.org/r/ZVOXX6qg4vXEx8dX@hovoldconsulting.com Tested-by: Johan Hovold <johan+linaro@kernel.org> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
1 parent 8e2f6f2 commit 1033176

2 files changed

Lines changed: 7 additions & 2 deletions

File tree

net/wireless/core.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,13 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
191191
return err;
192192
}
193193

194+
wiphy_lock(&rdev->wiphy);
194195
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
195196
if (!wdev->netdev)
196197
continue;
197198
nl80211_notify_iface(rdev, wdev, NL80211_CMD_DEL_INTERFACE);
198199
}
199200

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

203203
wiphy_net_set(&rdev->wiphy, net);
@@ -206,13 +206,13 @@ int cfg80211_switch_netns(struct cfg80211_registered_device *rdev,
206206
WARN_ON(err);
207207

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

211210
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
212211
if (!wdev->netdev)
213212
continue;
214213
nl80211_notify_iface(rdev, wdev, NL80211_CMD_NEW_INTERFACE);
215214
}
215+
wiphy_unlock(&rdev->wiphy);
216216

217217
return 0;
218218
}

net/wireless/nl80211.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3822,6 +3822,8 @@ static int nl80211_send_iface(struct sk_buff *msg, u32 portid, u32 seq, int flag
38223822
struct net_device *dev = wdev->netdev;
38233823
void *hdr;
38243824

3825+
lockdep_assert_wiphy(&rdev->wiphy);
3826+
38253827
WARN_ON(cmd != NL80211_CMD_NEW_INTERFACE &&
38263828
cmd != NL80211_CMD_DEL_INTERFACE &&
38273829
cmd != NL80211_CMD_SET_INTERFACE);
@@ -3989,6 +3991,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
39893991

39903992
if_idx = 0;
39913993

3994+
wiphy_lock(&rdev->wiphy);
39923995
list_for_each_entry(wdev, &rdev->wiphy.wdev_list, list) {
39933996
if (if_idx < if_start) {
39943997
if_idx++;
@@ -3998,10 +4001,12 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
39984001
cb->nlh->nlmsg_seq, NLM_F_MULTI,
39994002
rdev, wdev,
40004003
NL80211_CMD_NEW_INTERFACE) < 0) {
4004+
wiphy_unlock(&rdev->wiphy);
40014005
goto out;
40024006
}
40034007
if_idx++;
40044008
}
4009+
wiphy_unlock(&rdev->wiphy);
40054010

40064011
wp_idx++;
40074012
}

0 commit comments

Comments
 (0)