aboutsummaryrefslogtreecommitdiffstats
path: root/net/wireless/nl80211.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r--net/wireless/nl80211.c178
1 files changed, 36 insertions, 142 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 5bcf3a5b6465..74cdb1a0cf31 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -59,7 +59,7 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
59 int wiphy_idx = -1; 59 int wiphy_idx = -1;
60 int ifidx = -1; 60 int ifidx = -1;
61 61
62 assert_cfg80211_lock(); 62 ASSERT_RTNL();
63 63
64 if (!have_ifidx && !have_wdev_id) 64 if (!have_ifidx && !have_wdev_id)
65 return ERR_PTR(-EINVAL); 65 return ERR_PTR(-EINVAL);
@@ -80,7 +80,6 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
80 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx) 80 if (have_wdev_id && rdev->wiphy_idx != wiphy_idx)
81 continue; 81 continue;
82 82
83 mutex_lock(&rdev->devlist_mtx);
84 list_for_each_entry(wdev, &rdev->wdev_list, list) { 83 list_for_each_entry(wdev, &rdev->wdev_list, list) {
85 if (have_ifidx && wdev->netdev && 84 if (have_ifidx && wdev->netdev &&
86 wdev->netdev->ifindex == ifidx) { 85 wdev->netdev->ifindex == ifidx) {
@@ -92,7 +91,6 @@ __cfg80211_wdev_from_attrs(struct net *netns, struct nlattr **attrs)
92 break; 91 break;
93 } 92 }
94 } 93 }
95 mutex_unlock(&rdev->devlist_mtx);
96 94
97 if (result) 95 if (result)
98 break; 96 break;
@@ -109,7 +107,7 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
109 struct cfg80211_registered_device *rdev = NULL, *tmp; 107 struct cfg80211_registered_device *rdev = NULL, *tmp;
110 struct net_device *netdev; 108 struct net_device *netdev;
111 109
112 assert_cfg80211_lock(); 110 ASSERT_RTNL();
113 111
114 if (!attrs[NL80211_ATTR_WIPHY] && 112 if (!attrs[NL80211_ATTR_WIPHY] &&
115 !attrs[NL80211_ATTR_IFINDEX] && 113 !attrs[NL80211_ATTR_IFINDEX] &&
@@ -128,14 +126,12 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
128 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32); 126 tmp = cfg80211_rdev_by_wiphy_idx(wdev_id >> 32);
129 if (tmp) { 127 if (tmp) {
130 /* make sure wdev exists */ 128 /* make sure wdev exists */
131 mutex_lock(&tmp->devlist_mtx);
132 list_for_each_entry(wdev, &tmp->wdev_list, list) { 129 list_for_each_entry(wdev, &tmp->wdev_list, list) {
133 if (wdev->identifier != (u32)wdev_id) 130 if (wdev->identifier != (u32)wdev_id)
134 continue; 131 continue;
135 found = true; 132 found = true;
136 break; 133 break;
137 } 134 }
138 mutex_unlock(&tmp->devlist_mtx);
139 135
140 if (!found) 136 if (!found)
141 tmp = NULL; 137 tmp = NULL;
@@ -182,19 +178,6 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
182/* 178/*
183 * This function returns a pointer to the driver 179 * This function returns a pointer to the driver
184 * that the genl_info item that is passed refers to. 180 * that the genl_info item that is passed refers to.
185 * If successful, it returns non-NULL and also locks
186 * the driver's mutex!
187 *
188 * This means that you need to call cfg80211_unlock_rdev()
189 * before being allowed to acquire &cfg80211_mutex!
190 *
191 * This is necessary because we need to lock the global
192 * mutex to get an item off the list safely, and then
193 * we lock the rdev mutex so it doesn't go away under us.
194 *
195 * We don't want to keep cfg80211_mutex locked
196 * for all the time in order to allow requests on
197 * other interfaces to go through at the same time.
198 * 181 *
199 * The result of this can be a PTR_ERR and hence must 182 * The result of this can be a PTR_ERR and hence must
200 * be checked with IS_ERR() for errors. 183 * be checked with IS_ERR() for errors.
@@ -202,20 +185,7 @@ __cfg80211_rdev_from_attrs(struct net *netns, struct nlattr **attrs)
202static struct cfg80211_registered_device * 185static struct cfg80211_registered_device *
203cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info) 186cfg80211_get_dev_from_info(struct net *netns, struct genl_info *info)
204{ 187{
205 struct cfg80211_registered_device *rdev; 188 return __cfg80211_rdev_from_attrs(netns, info->attrs);
206
207 mutex_lock(&cfg80211_mutex);
208 rdev = __cfg80211_rdev_from_attrs(netns, info->attrs);
209
210 /* if it is not an error we grab the lock on
211 * it to assure it won't be going away while
212 * we operate on it */
213 if (!IS_ERR(rdev))
214 mutex_lock(&rdev->mtx);
215
216 mutex_unlock(&cfg80211_mutex);
217
218 return rdev;
219} 189}
220 190
221/* policy for the attributes */ 191/* policy for the attributes */
@@ -456,7 +426,6 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
456 int err; 426 int err;
457 427
458 rtnl_lock(); 428 rtnl_lock();
459 mutex_lock(&cfg80211_mutex);
460 429
461 if (!cb->args[0]) { 430 if (!cb->args[0]) {
462 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 431 err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
@@ -485,14 +454,12 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
485 *rdev = wiphy_to_dev(wiphy); 454 *rdev = wiphy_to_dev(wiphy);
486 *wdev = NULL; 455 *wdev = NULL;
487 456
488 mutex_lock(&(*rdev)->devlist_mtx);
489 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) { 457 list_for_each_entry(tmp, &(*rdev)->wdev_list, list) {
490 if (tmp->identifier == cb->args[1]) { 458 if (tmp->identifier == cb->args[1]) {
491 *wdev = tmp; 459 *wdev = tmp;
492 break; 460 break;
493 } 461 }
494 } 462 }
495 mutex_unlock(&(*rdev)->devlist_mtx);
496 463
497 if (!*wdev) { 464 if (!*wdev) {
498 err = -ENODEV; 465 err = -ENODEV;
@@ -500,19 +467,14 @@ static int nl80211_prepare_wdev_dump(struct sk_buff *skb,
500 } 467 }
501 } 468 }
502 469
503 cfg80211_lock_rdev(*rdev);
504
505 mutex_unlock(&cfg80211_mutex);
506 return 0; 470 return 0;
507 out_unlock: 471 out_unlock:
508 mutex_unlock(&cfg80211_mutex);
509 rtnl_unlock(); 472 rtnl_unlock();
510 return err; 473 return err;
511} 474}
512 475
513static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev) 476static void nl80211_finish_wdev_dump(struct cfg80211_registered_device *rdev)
514{ 477{
515 cfg80211_unlock_rdev(rdev);
516 rtnl_unlock(); 478 rtnl_unlock();
517} 479}
518 480
@@ -1568,7 +1530,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1568 struct nlattr **tb = nl80211_fam.attrbuf; 1530 struct nlattr **tb = nl80211_fam.attrbuf;
1569 int res; 1531 int res;
1570 1532
1571 mutex_lock(&cfg80211_mutex); 1533 rtnl_lock();
1572 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, 1534 res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,
1573 tb, nl80211_fam.maxattr, nl80211_policy); 1535 tb, nl80211_fam.maxattr, nl80211_policy);
1574 if (res == 0) { 1536 if (res == 0) {
@@ -1582,10 +1544,8 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1582 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); 1544 int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]);
1583 1545
1584 netdev = dev_get_by_index(sock_net(skb->sk), ifidx); 1546 netdev = dev_get_by_index(sock_net(skb->sk), ifidx);
1585 if (!netdev) { 1547 if (!netdev)
1586 mutex_unlock(&cfg80211_mutex);
1587 return -ENODEV; 1548 return -ENODEV;
1588 }
1589 if (netdev->ieee80211_ptr) { 1549 if (netdev->ieee80211_ptr) {
1590 dev = wiphy_to_dev( 1550 dev = wiphy_to_dev(
1591 netdev->ieee80211_ptr->wiphy); 1551 netdev->ieee80211_ptr->wiphy);
@@ -1629,7 +1589,6 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1629 !skb->len && 1589 !skb->len &&
1630 cb->min_dump_alloc < 4096) { 1590 cb->min_dump_alloc < 4096) {
1631 cb->min_dump_alloc = 4096; 1591 cb->min_dump_alloc = 4096;
1632 mutex_unlock(&cfg80211_mutex);
1633 return 1; 1592 return 1;
1634 } 1593 }
1635 idx--; 1594 idx--;
@@ -1638,7 +1597,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb)
1638 } while (cb->args[1] > 0); 1597 } while (cb->args[1] > 0);
1639 break; 1598 break;
1640 } 1599 }
1641 mutex_unlock(&cfg80211_mutex); 1600 rtnl_unlock();
1642 1601
1643 cb->args[0] = idx; 1602 cb->args[0] = idx;
1644 1603
@@ -1793,7 +1752,6 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1793 if (result) 1752 if (result)
1794 return result; 1753 return result;
1795 1754
1796 mutex_lock(&rdev->devlist_mtx);
1797 switch (iftype) { 1755 switch (iftype) {
1798 case NL80211_IFTYPE_AP: 1756 case NL80211_IFTYPE_AP:
1799 case NL80211_IFTYPE_P2P_GO: 1757 case NL80211_IFTYPE_P2P_GO:
@@ -1817,7 +1775,6 @@ static int __nl80211_set_channel(struct cfg80211_registered_device *rdev,
1817 default: 1775 default:
1818 result = -EINVAL; 1776 result = -EINVAL;
1819 } 1777 }
1820 mutex_unlock(&rdev->devlist_mtx);
1821 1778
1822 return result; 1779 return result;
1823} 1780}
@@ -1866,6 +1823,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1866 u32 frag_threshold = 0, rts_threshold = 0; 1823 u32 frag_threshold = 0, rts_threshold = 0;
1867 u8 coverage_class = 0; 1824 u8 coverage_class = 0;
1868 1825
1826 ASSERT_RTNL();
1827
1869 /* 1828 /*
1870 * Try to find the wiphy and netdev. Normally this 1829 * Try to find the wiphy and netdev. Normally this
1871 * function shouldn't need the netdev, but this is 1830 * function shouldn't need the netdev, but this is
@@ -1875,31 +1834,25 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1875 * also passed a netdev to set_wiphy, so that it is 1834 * also passed a netdev to set_wiphy, so that it is
1876 * possible to let that go to the right netdev! 1835 * possible to let that go to the right netdev!
1877 */ 1836 */
1878 mutex_lock(&cfg80211_mutex);
1879 1837
1880 if (info->attrs[NL80211_ATTR_IFINDEX]) { 1838 if (info->attrs[NL80211_ATTR_IFINDEX]) {
1881 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]); 1839 int ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);
1882 1840
1883 netdev = dev_get_by_index(genl_info_net(info), ifindex); 1841 netdev = dev_get_by_index(genl_info_net(info), ifindex);
1884 if (netdev && netdev->ieee80211_ptr) { 1842 if (netdev && netdev->ieee80211_ptr)
1885 rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy); 1843 rdev = wiphy_to_dev(netdev->ieee80211_ptr->wiphy);
1886 mutex_lock(&rdev->mtx); 1844 else
1887 } else
1888 netdev = NULL; 1845 netdev = NULL;
1889 } 1846 }
1890 1847
1891 if (!netdev) { 1848 if (!netdev) {
1892 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info), 1849 rdev = __cfg80211_rdev_from_attrs(genl_info_net(info),
1893 info->attrs); 1850 info->attrs);
1894 if (IS_ERR(rdev)) { 1851 if (IS_ERR(rdev))
1895 mutex_unlock(&cfg80211_mutex);
1896 return PTR_ERR(rdev); 1852 return PTR_ERR(rdev);
1897 }
1898 wdev = NULL; 1853 wdev = NULL;
1899 netdev = NULL; 1854 netdev = NULL;
1900 result = 0; 1855 result = 0;
1901
1902 mutex_lock(&rdev->mtx);
1903 } else 1856 } else
1904 wdev = netdev->ieee80211_ptr; 1857 wdev = netdev->ieee80211_ptr;
1905 1858
@@ -1912,8 +1865,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
1912 result = cfg80211_dev_rename( 1865 result = cfg80211_dev_rename(
1913 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME])); 1866 rdev, nla_data(info->attrs[NL80211_ATTR_WIPHY_NAME]));
1914 1867
1915 mutex_unlock(&cfg80211_mutex);
1916
1917 if (result) 1868 if (result)
1918 goto bad_res; 1869 goto bad_res;
1919 1870
@@ -2120,7 +2071,6 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
2120 } 2071 }
2121 2072
2122 bad_res: 2073 bad_res:
2123 mutex_unlock(&rdev->mtx);
2124 if (netdev) 2074 if (netdev)
2125 dev_put(netdev); 2075 dev_put(netdev);
2126 return result; 2076 return result;
@@ -2218,7 +2168,7 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2218 struct cfg80211_registered_device *rdev; 2168 struct cfg80211_registered_device *rdev;
2219 struct wireless_dev *wdev; 2169 struct wireless_dev *wdev;
2220 2170
2221 mutex_lock(&cfg80211_mutex); 2171 rtnl_lock();
2222 list_for_each_entry(rdev, &cfg80211_rdev_list, list) { 2172 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {
2223 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk))) 2173 if (!net_eq(wiphy_net(&rdev->wiphy), sock_net(skb->sk)))
2224 continue; 2174 continue;
@@ -2228,7 +2178,6 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2228 } 2178 }
2229 if_idx = 0; 2179 if_idx = 0;
2230 2180
2231 mutex_lock(&rdev->devlist_mtx);
2232 list_for_each_entry(wdev, &rdev->wdev_list, list) { 2181 list_for_each_entry(wdev, &rdev->wdev_list, list) {
2233 if (if_idx < if_start) { 2182 if (if_idx < if_start) {
2234 if_idx++; 2183 if_idx++;
@@ -2237,17 +2186,15 @@ static int nl80211_dump_interface(struct sk_buff *skb, struct netlink_callback *
2237 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid, 2186 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).portid,
2238 cb->nlh->nlmsg_seq, NLM_F_MULTI, 2187 cb->nlh->nlmsg_seq, NLM_F_MULTI,
2239 rdev, wdev) < 0) { 2188 rdev, wdev) < 0) {
2240 mutex_unlock(&rdev->devlist_mtx);
2241 goto out; 2189 goto out;
2242 } 2190 }
2243 if_idx++; 2191 if_idx++;
2244 } 2192 }
2245 mutex_unlock(&rdev->devlist_mtx);
2246 2193
2247 wp_idx++; 2194 wp_idx++;
2248 } 2195 }
2249 out: 2196 out:
2250 mutex_unlock(&cfg80211_mutex); 2197 rtnl_unlock();
2251 2198
2252 cb->args[0] = wp_idx; 2199 cb->args[0] = wp_idx;
2253 cb->args[1] = if_idx; 2200 cb->args[1] = if_idx;
@@ -2480,11 +2427,9 @@ static int nl80211_new_interface(struct sk_buff *skb, struct genl_info *info)
2480 INIT_LIST_HEAD(&wdev->mgmt_registrations); 2427 INIT_LIST_HEAD(&wdev->mgmt_registrations);
2481 spin_lock_init(&wdev->mgmt_registrations_lock); 2428 spin_lock_init(&wdev->mgmt_registrations_lock);
2482 2429
2483 mutex_lock(&rdev->devlist_mtx);
2484 wdev->identifier = ++rdev->wdev_id; 2430 wdev->identifier = ++rdev->wdev_id;
2485 list_add_rcu(&wdev->list, &rdev->wdev_list); 2431 list_add_rcu(&wdev->list, &rdev->wdev_list);
2486 rdev->devlist_generation++; 2432 rdev->devlist_generation++;
2487 mutex_unlock(&rdev->devlist_mtx);
2488 break; 2433 break;
2489 default: 2434 default:
2490 break; 2435 break;
@@ -2993,8 +2938,6 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
2993 struct wireless_dev *wdev; 2938 struct wireless_dev *wdev;
2994 bool ret = false; 2939 bool ret = false;
2995 2940
2996 mutex_lock(&rdev->devlist_mtx);
2997
2998 list_for_each_entry(wdev, &rdev->wdev_list, list) { 2941 list_for_each_entry(wdev, &rdev->wdev_list, list) {
2999 if (wdev->iftype != NL80211_IFTYPE_AP && 2942 if (wdev->iftype != NL80211_IFTYPE_AP &&
3000 wdev->iftype != NL80211_IFTYPE_P2P_GO) 2943 wdev->iftype != NL80211_IFTYPE_P2P_GO)
@@ -3008,8 +2951,6 @@ static bool nl80211_get_ap_channel(struct cfg80211_registered_device *rdev,
3008 break; 2951 break;
3009 } 2952 }
3010 2953
3011 mutex_unlock(&rdev->devlist_mtx);
3012
3013 return ret; 2954 return ret;
3014} 2955}
3015 2956
@@ -3171,13 +3112,10 @@ static int nl80211_start_ap(struct sk_buff *skb, struct genl_info *info)
3171 params.radar_required = true; 3112 params.radar_required = true;
3172 } 3113 }
3173 3114
3174 mutex_lock(&rdev->devlist_mtx);
3175 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 3115 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
3176 params.chandef.chan, 3116 params.chandef.chan,
3177 CHAN_MODE_SHARED, 3117 CHAN_MODE_SHARED,
3178 radar_detect_width); 3118 radar_detect_width);
3179 mutex_unlock(&rdev->devlist_mtx);
3180
3181 if (err) 3119 if (err)
3182 return err; 3120 return err;
3183 3121
@@ -4914,18 +4852,13 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
4914 void *hdr = NULL; 4852 void *hdr = NULL;
4915 struct nlattr *nl_reg_rules; 4853 struct nlattr *nl_reg_rules;
4916 unsigned int i; 4854 unsigned int i;
4917 int err = -EINVAL;
4918
4919 mutex_lock(&cfg80211_mutex);
4920 4855
4921 if (!cfg80211_regdomain) 4856 if (!cfg80211_regdomain)
4922 goto out; 4857 return -EINVAL;
4923 4858
4924 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 4859 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4925 if (!msg) { 4860 if (!msg)
4926 err = -ENOBUFS; 4861 return -ENOBUFS;
4927 goto out;
4928 }
4929 4862
4930 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0, 4863 hdr = nl80211hdr_put(msg, info->snd_portid, info->snd_seq, 0,
4931 NL80211_CMD_GET_REG); 4864 NL80211_CMD_GET_REG);
@@ -4984,8 +4917,7 @@ static int nl80211_get_reg(struct sk_buff *skb, struct genl_info *info)
4984 nla_nest_end(msg, nl_reg_rules); 4917 nla_nest_end(msg, nl_reg_rules);
4985 4918
4986 genlmsg_end(msg, hdr); 4919 genlmsg_end(msg, hdr);
4987 err = genlmsg_reply(msg, info); 4920 return genlmsg_reply(msg, info);
4988 goto out;
4989 4921
4990nla_put_failure_rcu: 4922nla_put_failure_rcu:
4991 rcu_read_unlock(); 4923 rcu_read_unlock();
@@ -4993,10 +4925,7 @@ nla_put_failure:
4993 genlmsg_cancel(msg, hdr); 4925 genlmsg_cancel(msg, hdr);
4994put_failure: 4926put_failure:
4995 nlmsg_free(msg); 4927 nlmsg_free(msg);
4996 err = -EMSGSIZE; 4928 return -EMSGSIZE;
4997out:
4998 mutex_unlock(&cfg80211_mutex);
4999 return err;
5000} 4929}
5001 4930
5002static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info) 4931static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
@@ -5062,12 +4991,9 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
5062 } 4991 }
5063 } 4992 }
5064 4993
5065 mutex_lock(&cfg80211_mutex);
5066
5067 r = set_regdom(rd); 4994 r = set_regdom(rd);
5068 /* set_regdom took ownership */ 4995 /* set_regdom took ownership */
5069 rd = NULL; 4996 rd = NULL;
5070 mutex_unlock(&cfg80211_mutex);
5071 4997
5072 bad_reg: 4998 bad_reg:
5073 kfree(rd); 4999 kfree(rd);
@@ -5117,7 +5043,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5117 if (!rdev->ops->scan) 5043 if (!rdev->ops->scan)
5118 return -EOPNOTSUPP; 5044 return -EOPNOTSUPP;
5119 5045
5120 mutex_lock(&rdev->sched_scan_mtx);
5121 if (rdev->scan_req) { 5046 if (rdev->scan_req) {
5122 err = -EBUSY; 5047 err = -EBUSY;
5123 goto unlock; 5048 goto unlock;
@@ -5303,7 +5228,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
5303 } 5228 }
5304 5229
5305 unlock: 5230 unlock:
5306 mutex_unlock(&rdev->sched_scan_mtx);
5307 return err; 5231 return err;
5308} 5232}
5309 5233
@@ -5375,8 +5299,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
5375 if (ie_len > wiphy->max_sched_scan_ie_len) 5299 if (ie_len > wiphy->max_sched_scan_ie_len)
5376 return -EINVAL; 5300 return -EINVAL;
5377 5301
5378 mutex_lock(&rdev->sched_scan_mtx);
5379
5380 if (rdev->sched_scan_req) { 5302 if (rdev->sched_scan_req) {
5381 err = -EINPROGRESS; 5303 err = -EINPROGRESS;
5382 goto out; 5304 goto out;
@@ -5544,7 +5466,6 @@ static int nl80211_start_sched_scan(struct sk_buff *skb,
5544out_free: 5466out_free:
5545 kfree(request); 5467 kfree(request);
5546out: 5468out:
5547 mutex_unlock(&rdev->sched_scan_mtx);
5548 return err; 5469 return err;
5549} 5470}
5550 5471
@@ -5552,17 +5473,12 @@ static int nl80211_stop_sched_scan(struct sk_buff *skb,
5552 struct genl_info *info) 5473 struct genl_info *info)
5553{ 5474{
5554 struct cfg80211_registered_device *rdev = info->user_ptr[0]; 5475 struct cfg80211_registered_device *rdev = info->user_ptr[0];
5555 int err;
5556 5476
5557 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) || 5477 if (!(rdev->wiphy.flags & WIPHY_FLAG_SUPPORTS_SCHED_SCAN) ||
5558 !rdev->ops->sched_scan_stop) 5478 !rdev->ops->sched_scan_stop)
5559 return -EOPNOTSUPP; 5479 return -EOPNOTSUPP;
5560 5480
5561 mutex_lock(&rdev->sched_scan_mtx); 5481 return __cfg80211_stop_sched_scan(rdev, false);
5562 err = __cfg80211_stop_sched_scan(rdev, false);
5563 mutex_unlock(&rdev->sched_scan_mtx);
5564
5565 return err;
5566} 5482}
5567 5483
5568static int nl80211_start_radar_detection(struct sk_buff *skb, 5484static int nl80211_start_radar_detection(struct sk_buff *skb,
@@ -5594,12 +5510,11 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
5594 if (!rdev->ops->start_radar_detection) 5510 if (!rdev->ops->start_radar_detection)
5595 return -EOPNOTSUPP; 5511 return -EOPNOTSUPP;
5596 5512
5597 mutex_lock(&rdev->devlist_mtx);
5598 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype, 5513 err = cfg80211_can_use_iftype_chan(rdev, wdev, wdev->iftype,
5599 chandef.chan, CHAN_MODE_SHARED, 5514 chandef.chan, CHAN_MODE_SHARED,
5600 BIT(chandef.width)); 5515 BIT(chandef.width));
5601 if (err) 5516 if (err)
5602 goto err_locked; 5517 return err;
5603 5518
5604 err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef); 5519 err = rdev->ops->start_radar_detection(&rdev->wiphy, dev, &chandef);
5605 if (!err) { 5520 if (!err) {
@@ -5607,9 +5522,6 @@ static int nl80211_start_radar_detection(struct sk_buff *skb,
5607 wdev->cac_started = true; 5522 wdev->cac_started = true;
5608 wdev->cac_start_time = jiffies; 5523 wdev->cac_start_time = jiffies;
5609 } 5524 }
5610err_locked:
5611 mutex_unlock(&rdev->devlist_mtx);
5612
5613 return err; 5525 return err;
5614} 5526}
5615 5527
@@ -6472,6 +6384,8 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6472 void *data = NULL; 6384 void *data = NULL;
6473 int data_len = 0; 6385 int data_len = 0;
6474 6386
6387 rtnl_lock();
6388
6475 if (cb->args[0]) { 6389 if (cb->args[0]) {
6476 /* 6390 /*
6477 * 0 is a valid index, but not valid for args[0], 6391 * 0 is a valid index, but not valid for args[0],
@@ -6483,18 +6397,16 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6483 nl80211_fam.attrbuf, nl80211_fam.maxattr, 6397 nl80211_fam.attrbuf, nl80211_fam.maxattr,
6484 nl80211_policy); 6398 nl80211_policy);
6485 if (err) 6399 if (err)
6486 return err; 6400 goto out_err;
6487 6401
6488 mutex_lock(&cfg80211_mutex);
6489 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk), 6402 rdev = __cfg80211_rdev_from_attrs(sock_net(skb->sk),
6490 nl80211_fam.attrbuf); 6403 nl80211_fam.attrbuf);
6491 if (IS_ERR(rdev)) { 6404 if (IS_ERR(rdev)) {
6492 mutex_unlock(&cfg80211_mutex); 6405 err = PTR_ERR(rdev);
6493 return PTR_ERR(rdev); 6406 goto out_err;
6494 } 6407 }
6495 phy_idx = rdev->wiphy_idx; 6408 phy_idx = rdev->wiphy_idx;
6496 rdev = NULL; 6409 rdev = NULL;
6497 mutex_unlock(&cfg80211_mutex);
6498 6410
6499 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA]) 6411 if (nl80211_fam.attrbuf[NL80211_ATTR_TESTDATA])
6500 cb->args[1] = 6412 cb->args[1] =
@@ -6506,14 +6418,11 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6506 data_len = nla_len((void *)cb->args[1]); 6418 data_len = nla_len((void *)cb->args[1]);
6507 } 6419 }
6508 6420
6509 mutex_lock(&cfg80211_mutex);
6510 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx); 6421 rdev = cfg80211_rdev_by_wiphy_idx(phy_idx);
6511 if (!rdev) { 6422 if (!rdev) {
6512 mutex_unlock(&cfg80211_mutex); 6423 err = -ENOENT;
6513 return -ENOENT; 6424 goto out_err;
6514 } 6425 }
6515 cfg80211_lock_rdev(rdev);
6516 mutex_unlock(&cfg80211_mutex);
6517 6426
6518 if (!rdev->ops->testmode_dump) { 6427 if (!rdev->ops->testmode_dump) {
6519 err = -EOPNOTSUPP; 6428 err = -EOPNOTSUPP;
@@ -6554,7 +6463,7 @@ static int nl80211_testmode_dump(struct sk_buff *skb,
6554 /* see above */ 6463 /* see above */
6555 cb->args[0] = phy_idx + 1; 6464 cb->args[0] = phy_idx + 1;
6556 out_err: 6465 out_err:
6557 cfg80211_unlock_rdev(rdev); 6466 rtnl_unlock();
6558 return err; 6467 return err;
6559} 6468}
6560 6469
@@ -8189,9 +8098,7 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
8189 if (wdev->p2p_started) 8098 if (wdev->p2p_started)
8190 return 0; 8099 return 0;
8191 8100
8192 mutex_lock(&rdev->devlist_mtx);
8193 err = cfg80211_can_add_interface(rdev, wdev->iftype); 8101 err = cfg80211_can_add_interface(rdev, wdev->iftype);
8194 mutex_unlock(&rdev->devlist_mtx);
8195 if (err) 8102 if (err)
8196 return err; 8103 return err;
8197 8104
@@ -8200,9 +8107,7 @@ static int nl80211_start_p2p_device(struct sk_buff *skb, struct genl_info *info)
8200 return err; 8107 return err;
8201 8108
8202 wdev->p2p_started = true; 8109 wdev->p2p_started = true;
8203 mutex_lock(&rdev->devlist_mtx);
8204 rdev->opencount++; 8110 rdev->opencount++;
8205 mutex_unlock(&rdev->devlist_mtx);
8206 8111
8207 return 0; 8112 return 0;
8208} 8113}
@@ -8218,11 +8123,7 @@ static int nl80211_stop_p2p_device(struct sk_buff *skb, struct genl_info *info)
8218 if (!rdev->ops->stop_p2p_device) 8123 if (!rdev->ops->stop_p2p_device)
8219 return -EOPNOTSUPP; 8124 return -EOPNOTSUPP;
8220 8125
8221 mutex_lock(&rdev->devlist_mtx);
8222 mutex_lock(&rdev->sched_scan_mtx);
8223 cfg80211_stop_p2p_device(rdev, wdev); 8126 cfg80211_stop_p2p_device(rdev, wdev);
8224 mutex_unlock(&rdev->sched_scan_mtx);
8225 mutex_unlock(&rdev->devlist_mtx);
8226 8127
8227 return 0; 8128 return 0;
8228} 8129}
@@ -8365,11 +8266,11 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8365 info->user_ptr[0] = rdev; 8266 info->user_ptr[0] = rdev;
8366 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV || 8267 } else if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV ||
8367 ops->internal_flags & NL80211_FLAG_NEED_WDEV) { 8268 ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
8368 mutex_lock(&cfg80211_mutex); 8269 ASSERT_RTNL();
8270
8369 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info), 8271 wdev = __cfg80211_wdev_from_attrs(genl_info_net(info),
8370 info->attrs); 8272 info->attrs);
8371 if (IS_ERR(wdev)) { 8273 if (IS_ERR(wdev)) {
8372 mutex_unlock(&cfg80211_mutex);
8373 if (rtnl) 8274 if (rtnl)
8374 rtnl_unlock(); 8275 rtnl_unlock();
8375 return PTR_ERR(wdev); 8276 return PTR_ERR(wdev);
@@ -8380,7 +8281,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8380 8281
8381 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) { 8282 if (ops->internal_flags & NL80211_FLAG_NEED_NETDEV) {
8382 if (!dev) { 8283 if (!dev) {
8383 mutex_unlock(&cfg80211_mutex);
8384 if (rtnl) 8284 if (rtnl)
8385 rtnl_unlock(); 8285 rtnl_unlock();
8386 return -EINVAL; 8286 return -EINVAL;
@@ -8394,7 +8294,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8394 if (dev) { 8294 if (dev) {
8395 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP && 8295 if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP &&
8396 !netif_running(dev)) { 8296 !netif_running(dev)) {
8397 mutex_unlock(&cfg80211_mutex);
8398 if (rtnl) 8297 if (rtnl)
8399 rtnl_unlock(); 8298 rtnl_unlock();
8400 return -ENETDOWN; 8299 return -ENETDOWN;
@@ -8403,17 +8302,12 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8403 dev_hold(dev); 8302 dev_hold(dev);
8404 } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) { 8303 } else if (ops->internal_flags & NL80211_FLAG_CHECK_NETDEV_UP) {
8405 if (!wdev->p2p_started) { 8304 if (!wdev->p2p_started) {
8406 mutex_unlock(&cfg80211_mutex);
8407 if (rtnl) 8305 if (rtnl)
8408 rtnl_unlock(); 8306 rtnl_unlock();
8409 return -ENETDOWN; 8307 return -ENETDOWN;
8410 } 8308 }
8411 } 8309 }
8412 8310
8413 cfg80211_lock_rdev(rdev);
8414
8415 mutex_unlock(&cfg80211_mutex);
8416
8417 info->user_ptr[0] = rdev; 8311 info->user_ptr[0] = rdev;
8418 } 8312 }
8419 8313
@@ -8423,8 +8317,6 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
8423static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb, 8317static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
8424 struct genl_info *info) 8318 struct genl_info *info)
8425{ 8319{
8426 if (info->user_ptr[0])
8427 cfg80211_unlock_rdev(info->user_ptr[0]);
8428 if (info->user_ptr[1]) { 8320 if (info->user_ptr[1]) {
8429 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) { 8321 if (ops->internal_flags & NL80211_FLAG_NEED_WDEV) {
8430 struct wireless_dev *wdev = info->user_ptr[1]; 8322 struct wireless_dev *wdev = info->user_ptr[1];
@@ -8446,7 +8338,8 @@ static struct genl_ops nl80211_ops[] = {
8446 .dumpit = nl80211_dump_wiphy, 8338 .dumpit = nl80211_dump_wiphy,
8447 .policy = nl80211_policy, 8339 .policy = nl80211_policy,
8448 /* can be retrieved by unprivileged users */ 8340 /* can be retrieved by unprivileged users */
8449 .internal_flags = NL80211_FLAG_NEED_WIPHY, 8341 .internal_flags = NL80211_FLAG_NEED_WIPHY |
8342 NL80211_FLAG_NEED_RTNL,
8450 }, 8343 },
8451 { 8344 {
8452 .cmd = NL80211_CMD_SET_WIPHY, 8345 .cmd = NL80211_CMD_SET_WIPHY,
@@ -8461,7 +8354,8 @@ static struct genl_ops nl80211_ops[] = {
8461 .dumpit = nl80211_dump_interface, 8354 .dumpit = nl80211_dump_interface,
8462 .policy = nl80211_policy, 8355 .policy = nl80211_policy,
8463 /* can be retrieved by unprivileged users */ 8356 /* can be retrieved by unprivileged users */
8464 .internal_flags = NL80211_FLAG_NEED_WDEV, 8357 .internal_flags = NL80211_FLAG_NEED_WDEV |
8358 NL80211_FLAG_NEED_RTNL,
8465 }, 8359 },
8466 { 8360 {
8467 .cmd = NL80211_CMD_SET_INTERFACE, 8361 .cmd = NL80211_CMD_SET_INTERFACE,
@@ -8620,6 +8514,7 @@ static struct genl_ops nl80211_ops[] = {
8620 .cmd = NL80211_CMD_GET_REG, 8514 .cmd = NL80211_CMD_GET_REG,
8621 .doit = nl80211_get_reg, 8515 .doit = nl80211_get_reg,
8622 .policy = nl80211_policy, 8516 .policy = nl80211_policy,
8517 .internal_flags = NL80211_FLAG_NEED_RTNL,
8623 /* can be retrieved by unprivileged users */ 8518 /* can be retrieved by unprivileged users */
8624 }, 8519 },
8625 { 8520 {
@@ -8627,6 +8522,7 @@ static struct genl_ops nl80211_ops[] = {
8627 .doit = nl80211_set_reg, 8522 .doit = nl80211_set_reg,
8628 .policy = nl80211_policy, 8523 .policy = nl80211_policy,
8629 .flags = GENL_ADMIN_PERM, 8524 .flags = GENL_ADMIN_PERM,
8525 .internal_flags = NL80211_FLAG_NEED_RTNL,
8630 }, 8526 },
8631 { 8527 {
8632 .cmd = NL80211_CMD_REQ_SET_REG, 8528 .cmd = NL80211_CMD_REQ_SET_REG,
@@ -9082,8 +8978,6 @@ static int nl80211_add_scan_req(struct sk_buff *msg,
9082 struct nlattr *nest; 8978 struct nlattr *nest;
9083 int i; 8979 int i;
9084 8980
9085 lockdep_assert_held(&rdev->sched_scan_mtx);
9086
9087 if (WARN_ON(!req)) 8981 if (WARN_ON(!req))
9088 return 0; 8982 return 0;
9089 8983