diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7430e80893b1..4c67cc5f45f9 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c @@ -3867,8 +3867,10 @@ static int nl80211_dump_wiphy_parse(struct sk_buff *skb, struct cfg80211_registered_device *rdev; int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); - netdev = __dev_get_by_index(sock_net(skb->sk), ifidx); + rcu_read_lock(); + netdev = dev_get_by_index_rcu(sock_net(skb->sk), ifidx); if (!netdev) { + rcu_read_unlock(); ret = -ENODEV; goto out; } @@ -3877,6 +3879,7 @@ static int nl80211_dump_wiphy_parse(struct sk_buff *skb, netdev->ieee80211_ptr->wiphy); state->filter_wiphy = rdev->wiphy_idx; } + rcu_read_unlock(); } ret = 0; @@ -3891,18 +3894,18 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) struct nl80211_dump_wiphy_state *state = (void *)cb->args[0]; struct cfg80211_registered_device *rdev; - rtnl_lock(); + mutex_lock(&cfg80211_mutex); if (!state) { state = kzalloc_obj(*state); if (!state) { - rtnl_unlock(); + mutex_unlock(&cfg80211_mutex); return -ENOMEM; } state->filter_wiphy = -1; ret = nl80211_dump_wiphy_parse(skb, cb, state); if (ret) { kfree(state); - rtnl_unlock(); + mutex_unlock(&cfg80211_mutex); return ret; } cb->args[0] = (long)state; @@ -3944,7 +3947,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) cb->min_dump_alloc = 4096; state->split_start = 0; wiphy_unlock(&rdev->wiphy); - rtnl_unlock(); + mutex_unlock(&cfg80211_mutex); return 1; } idx--; @@ -3954,7 +3957,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) wiphy_unlock(&rdev->wiphy); break; } - rtnl_unlock(); + mutex_unlock(&cfg80211_mutex); state->start = idx; @@ -4930,7 +4933,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * struct wireless_dev *wdev; int ret; - rtnl_lock(); + mutex_lock(&cfg80211_mutex); if (!cb->args[2]) { struct nl80211_dump_wiphy_state state = { .filter_wiphy = -1, @@ -4993,7 +4996,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback * ret = skb->len; out_unlock: - rtnl_unlock(); + mutex_unlock(&cfg80211_mutex); return ret; }