diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-11-02 07:32:03 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-11-02 15:43:29 -0500 |
commit | 584991dccfd347cd2e1675ab262998f6c335d3c0 (patch) | |
tree | 0cb52e1f06e587561f0e06e1beae7de7faaf5528 /net/wireless | |
parent | 6c085227bd7168fd84976479218f81bf35b5acd7 (diff) |
cfg80211: validate scan channels
Currently it is possible to request a scan on only
disabled channels, which could be problematic for
some drivers. Reject such scans, and also ignore
disabled channels that are given. This resuls in
the scan begin/end event only including channels
that are actually used.
This makes the mac80211 check for disabled channels
superfluous. At the same time, remove the no-IBSS
check from mac80211 -- nothing says that we should
not find any networks on channels that cannot be
used for an IBSS, even when operating in IBSS mode.
Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/wireless')
-rw-r--r-- | net/wireless/nl80211.c | 34 | ||||
-rw-r--r-- | net/wireless/scan.c | 6 |
2 files changed, 33 insertions, 7 deletions
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f48394126bf9..8ed62b6c172b 100644 --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c | |||
@@ -2988,7 +2988,6 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
2988 | goto out; | 2988 | goto out; |
2989 | } | 2989 | } |
2990 | 2990 | ||
2991 | request->n_channels = n_channels; | ||
2992 | if (n_ssids) | 2991 | if (n_ssids) |
2993 | request->ssids = (void *)&request->channels[n_channels]; | 2992 | request->ssids = (void *)&request->channels[n_channels]; |
2994 | request->n_ssids = n_ssids; | 2993 | request->n_ssids = n_ssids; |
@@ -2999,32 +2998,53 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) | |||
2999 | request->ie = (void *)(request->channels + n_channels); | 2998 | request->ie = (void *)(request->channels + n_channels); |
3000 | } | 2999 | } |
3001 | 3000 | ||
3001 | i = 0; | ||
3002 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { | 3002 | if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { |
3003 | /* user specified, bail out if channel not found */ | 3003 | /* user specified, bail out if channel not found */ |
3004 | request->n_channels = n_channels; | ||
3005 | i = 0; | ||
3006 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) { | 3004 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) { |
3007 | request->channels[i] = ieee80211_get_channel(wiphy, nla_get_u32(attr)); | 3005 | struct ieee80211_channel *chan; |
3008 | if (!request->channels[i]) { | 3006 | |
3007 | chan = ieee80211_get_channel(wiphy, nla_get_u32(attr)); | ||
3008 | |||
3009 | if (!chan) { | ||
3009 | err = -EINVAL; | 3010 | err = -EINVAL; |
3010 | goto out_free; | 3011 | goto out_free; |
3011 | } | 3012 | } |
3013 | |||
3014 | /* ignore disabled channels */ | ||
3015 | if (chan->flags & IEEE80211_CHAN_DISABLED) | ||
3016 | continue; | ||
3017 | |||
3018 | request->channels[i] = chan; | ||
3012 | i++; | 3019 | i++; |
3013 | } | 3020 | } |
3014 | } else { | 3021 | } else { |
3015 | /* all channels */ | 3022 | /* all channels */ |
3016 | i = 0; | ||
3017 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 3023 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
3018 | int j; | 3024 | int j; |
3019 | if (!wiphy->bands[band]) | 3025 | if (!wiphy->bands[band]) |
3020 | continue; | 3026 | continue; |
3021 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { | 3027 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { |
3022 | request->channels[i] = &wiphy->bands[band]->channels[j]; | 3028 | struct ieee80211_channel *chan; |
3029 | |||
3030 | chan = &wiphy->bands[band]->channels[j]; | ||
3031 | |||
3032 | if (chan->flags & IEEE80211_CHAN_DISABLED) | ||
3033 | continue; | ||
3034 | |||
3035 | request->channels[i] = chan; | ||
3023 | i++; | 3036 | i++; |
3024 | } | 3037 | } |
3025 | } | 3038 | } |
3026 | } | 3039 | } |
3027 | 3040 | ||
3041 | if (!i) { | ||
3042 | err = -EINVAL; | ||
3043 | goto out_free; | ||
3044 | } | ||
3045 | |||
3046 | request->n_channels = i; | ||
3047 | |||
3028 | i = 0; | 3048 | i = 0; |
3029 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { | 3049 | if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { |
3030 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { | 3050 | nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index 2e8c515f3c5c..e2d344ff6745 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -650,9 +650,15 @@ int cfg80211_wext_siwscan(struct net_device *dev, | |||
650 | i = 0; | 650 | i = 0; |
651 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { | 651 | for (band = 0; band < IEEE80211_NUM_BANDS; band++) { |
652 | int j; | 652 | int j; |
653 | |||
653 | if (!wiphy->bands[band]) | 654 | if (!wiphy->bands[band]) |
654 | continue; | 655 | continue; |
656 | |||
655 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { | 657 | for (j = 0; j < wiphy->bands[band]->n_channels; j++) { |
658 | /* ignore disabled channels */ | ||
659 | if (wiphy->bands[band]->channels[j].flags & | ||
660 | IEEE80211_CHAN_DISABLED) | ||
661 | continue; | ||
656 | 662 | ||
657 | /* If we have a wireless request structure and the | 663 | /* If we have a wireless request structure and the |
658 | * wireless request specifies frequencies, then search | 664 | * wireless request specifies frequencies, then search |