diff options
-rw-r--r-- | net/wireless/nl80211.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index 7a7b621d45fd..d44ab216c0ec 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -1307,7 +1307,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 portid, u32 seq, int flag | |||
1307 | 1307 | ||
1308 | static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | 1308 | static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) |
1309 | { | 1309 | { |
1310 | int idx = 0; | 1310 | int idx = 0, ret; |
1311 | int start = cb->args[0]; | 1311 | int start = cb->args[0]; |
1312 | struct cfg80211_registered_device *dev; | 1312 | struct cfg80211_registered_device *dev; |
1313 | 1313 | ||
@@ -1317,9 +1317,29 @@ static int nl80211_dump_wiphy(struct sk_buff *skb, struct netlink_callback *cb) | |||
1317 | continue; | 1317 | continue; |
1318 | if (++idx <= start) | 1318 | if (++idx <= start) |
1319 | continue; | 1319 | continue; |
1320 | if (nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid, | 1320 | ret = nl80211_send_wiphy(skb, NETLINK_CB(cb->skb).portid, |
1321 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 1321 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
1322 | dev) < 0) { | 1322 | dev); |
1323 | if (ret < 0) { | ||
1324 | /* | ||
1325 | * If sending the wiphy data didn't fit (ENOBUFS or | ||
1326 | * EMSGSIZE returned), this SKB is still empty (so | ||
1327 | * it's not too big because another wiphy dataset is | ||
1328 | * already in the skb) and we've not tried to adjust | ||
1329 | * the dump allocation yet ... then adjust the alloc | ||
1330 | * size to be bigger, and return 1 but with the empty | ||
1331 | * skb. This results in an empty message being RX'ed | ||
1332 | * in userspace, but that is ignored. | ||
1333 | * | ||
1334 | * We can then retry with the larger buffer. | ||
1335 | */ | ||
1336 | if ((ret == -ENOBUFS || ret == -EMSGSIZE) && | ||
1337 | !skb->len && | ||
1338 | cb->min_dump_alloc < 4096) { | ||
1339 | cb->min_dump_alloc = 4096; | ||
1340 | mutex_unlock(&cfg80211_mutex); | ||
1341 | return 1; | ||
1342 | } | ||
1323 | idx--; | 1343 | idx--; |
1324 | break; | 1344 | break; |
1325 | } | 1345 | } |
@@ -1336,7 +1356,7 @@ static int nl80211_get_wiphy(struct sk_buff *skb, struct genl_info *info) | |||
1336 | struct sk_buff *msg; | 1356 | struct sk_buff *msg; |
1337 | struct cfg80211_registered_device *dev = info->user_ptr[0]; | 1357 | struct cfg80211_registered_device *dev = info->user_ptr[0]; |
1338 | 1358 | ||
1339 | msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | 1359 | msg = nlmsg_new(4096, GFP_KERNEL); |
1340 | if (!msg) | 1360 | if (!msg) |
1341 | return -ENOMEM; | 1361 | return -ENOMEM; |
1342 | 1362 | ||