Skip to content

Commit

Permalink
cfg80211: prohibit scanning the same channel more than once
Browse files Browse the repository at this point in the history
It isn't very useful to scan the same channel more than once
during a given scan, and some hardware (notably iwlwifi) can
only scan a limited number of channels at a time. To prevent
any overflows, simply disallow scanning any channel multiple
times in a given scan command. This is a small change in the
userspace ABI, but the only user, wpa_supplicant, never asks
for a scan with the same frequency listed twice.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Johannes Berg authored and John W. Linville committed Jul 10, 2009
1 parent 386aa23 commit 83f5e2c
Showing 1 changed file with 30 additions and 3 deletions.
33 changes: 30 additions & 3 deletions net/wireless/nl80211.c
Original file line number Diff line number Diff line change
Expand Up @@ -2695,6 +2695,31 @@ static int nl80211_set_reg(struct sk_buff *skb, struct genl_info *info)
return r;
}

static int validate_scan_freqs(struct nlattr *freqs)
{
struct nlattr *attr1, *attr2;
int n_channels = 0, tmp1, tmp2;

nla_for_each_nested(attr1, freqs, tmp1) {
n_channels++;
/*
* Some hardware has a limited channel list for
* scanning, and it is pretty much nonsensical
* to scan for a channel twice, so disallow that
* and don't require drivers to check that the
* channel list they get isn't longer than what
* they can scan, as long as they can scan all
* the channels they registered at once.
*/
nla_for_each_nested(attr2, freqs, tmp2)
if (attr1 != attr2 &&
nla_get_u32(attr1) == nla_get_u32(attr2))
return 0;
}

return n_channels;
}

static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
{
struct cfg80211_registered_device *drv;
Expand All @@ -2704,7 +2729,7 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
struct ieee80211_channel *channel;
struct nlattr *attr;
struct wiphy *wiphy;
int err, tmp, n_ssids = 0, n_channels = 0, i;
int err, tmp, n_ssids = 0, n_channels, i;
enum ieee80211_band band;
size_t ie_len;

Expand Down Expand Up @@ -2735,13 +2760,15 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
}

if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) {
nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp)
n_channels++;
n_channels = validate_scan_freqs(
info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]);
if (!n_channels) {
err = -EINVAL;
goto out;
}
} else {
n_channels = 0;

for (band = 0; band < IEEE80211_NUM_BANDS; band++)
if (wiphy->bands[band])
n_channels += wiphy->bands[band]->n_channels;
Expand Down

0 comments on commit 83f5e2c

Please sign in to comment.