mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
cfg80211: prohibit scanning the same channel more than once
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>
This commit is contained in:
parent
386aa23dd5
commit
83f5e2cf79
1 changed files with 30 additions and 3 deletions
|
@ -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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue