lkml.org 
[lkml]   [2017]   [Apr]   [2]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
Subject`iwlist scan` fails with many networks available
I've spent the past few days in a large hotel and noticed that `iwlist
scan` fails with the error message "Argument list too long".

This seems to be because there are a great many wireless networks in
my vicinity. See: https://bugzilla.kernel.org/show_bug.cgi?id=16384

Using `iw` as recommended in that ticket works, but it's not a great
option for me because `wicd` doesn't support it.

If I'm understanding the relevant code correctly, the attached patch
works around the issue by skipping networks that would not fit in the
scan-results buffer and returning partial results instead of just
erroring out.

This is the first time I've modified the kernel code directly. I have
a couple of questions:

- This seems to be working like I intended, but the condition was a
bit hard to reproduce consistently. Am I inadvertently breaking
things?
- Is there a better way to accomplish this? Reading the `iwlist` code
I'm not entirely sure why this is occurring, because it looks like it
should be allocating a dynamic buffer length.
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 21be56b..fc74091 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -1699,6 +1699,7 @@ static int ieee80211_scan_results(struct cfg80211_registered_device *rdev,
struct iw_request_info *info,
char *buf, size_t len)
{
+ char *maybe_current_ev;
char *current_ev = buf;
char *end_buf = buf + len;
struct cfg80211_internal_bss *bss;
@@ -1709,14 +1710,20 @@ static int ieee80211_scan_results(struct cfg80211_registered_device *rdev,

list_for_each_entry(bss, &rdev->bss_list, list) {
if (buf + len - current_ev <= IW_EV_ADDR_LEN) {
- err = -E2BIG;
+ // Buffer too big to hold another BSS; ignore
break;
}
- current_ev = ieee80211_bss(&rdev->wiphy, info, bss,
- current_ev, end_buf);
- if (IS_ERR(current_ev)) {
- err = PTR_ERR(current_ev);
+ maybe_current_ev = ieee80211_bss(&rdev->wiphy, info, bss,
+ current_ev, end_buf);
+ if (IS_ERR(maybe_current_ev)) {
+ err = PTR_ERR(maybe_current_ev);
+ if (err == -E2BIG) {
+ // Last BSS failed to copy into buffer; ignore
+ err = 0;
+ }
break;
+ } else {
+ current_ev = maybe_current_ev;
}
}
spin_unlock_bh(&rdev->bss_lock);
\
 
 \ /
  Last update: 2017-04-02 23:40    [W:0.067 / U:24.276 seconds]
©2003-2018 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site