diff options
Diffstat (limited to 'net/wireless/nl80211.c')
-rw-r--r-- | net/wireless/nl80211.c | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 31d265f36d2c..ea74b9dd9d82 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1527,12 +1527,18 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1527 | struct cfg80211_registered_device *dev; | 1527 | struct cfg80211_registered_device *dev; |
1528 | s64 filter_wiphy = -1; | 1528 | s64 filter_wiphy = -1; |
1529 | bool split = false; | 1529 | bool split = false; |
1530 | struct nlattr **tb = nl80211_fam.attrbuf; | 1530 | struct nlattr **tb; |
1531 | int res; | 1531 | int res; |
1532 | 1532 | ||
1533 | /* will be zeroed in nlmsg_parse() */ | ||
1534 | tb = kmalloc(sizeof(*tb) * (NL80211_ATTR_MAX + 1), GFP_KERNEL); | ||
1535 | if (!tb) | ||
1536 | return -ENOMEM; | ||
1537 | |||
1533 | rtnl_lock(); | 1538 | rtnl_lock(); |
1539 | |||
1534 | res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, | 1540 | res = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize, |
1535 | tb, nl80211_fam.maxattr, nl80211_policy); | 1541 | tb, NL80211_ATTR_MAX, nl80211_policy); |
1536 | if (res == 0) { | 1542 | if (res == 0) { |
1537 | split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP]; | 1543 | split = tb[NL80211_ATTR_SPLIT_WIPHY_DUMP]; |
1538 | if (tb[NL80211_ATTR_WIPHY]) | 1544 | if (tb[NL80211_ATTR_WIPHY]) |
@@ -1544,8 +1550,11 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1544 | int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); | 1550 | int ifidx = nla_get_u32(tb[NL80211_ATTR_IFINDEX]); |
1545 | 1551 | ||
1546 | netdev = dev_get_by_index(sock_net(skb->sk), ifidx); | 1552 | netdev = dev_get_by_index(sock_net(skb->sk), ifidx); |
1547 | if (!netdev) | 1553 | if (!netdev) { |
1554 | rtnl_unlock(); | ||
1555 | kfree(tb); | ||
1548 | return -ENODEV; | 1556 | return -ENODEV; |
1557 | } | ||
1549 | if (netdev->ieee80211_ptr) { | 1558 | if (netdev->ieee80211_ptr) { |
1550 | dev = wiphy_to_dev( | 1559 | dev = wiphy_to_dev( |
1551 | netdev->ieee80211_ptr->wiphy); | 1560 | netdev->ieee80211_ptr->wiphy); |
@@ -1554,6 +1563,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1554 | dev_put(netdev); | 1563 | dev_put(netdev); |
1555 | } | 1564 | } |
1556 | } | 1565 | } |
1566 | kfree(tb); | ||
1557 | 1567 | ||
1558 | list_for_each_entry(dev, &cfg80211_rdev_list, list) { | 1568 | list_for_each_entry(dev, &cfg80211_rdev_list, list) { |
1559 | if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) | 1569 | if (!net_eq(wiphy_net(&dev->wiphy), sock_net(skb->sk))) |
@@ -1589,6 +1599,7 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1589 | !skb->len && | 1599 | !skb->len && |
1590 | cb->min_dump_alloc < 4096) { | 1600 | cb->min_dump_alloc < 4096) { |
1591 | cb->min_dump_alloc = 4096; | 1601 | cb->min_dump_alloc = 4096; |
1602 | rtnl_unlock(); | ||
1592 | return 1; | 1603 | return 1; |
1593 | } | 1604 | } |
1594 | idx--; | 1605 | idx--; |