From 584991dccfd347cd2e1675ab262998f6c335d3c0 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Mon, 2 Nov 2009 13:32:03 +0100 Subject: 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 Signed-off-by: John W. Linville --- net/wireless/nl80211.c | 34 +++++++++++++++++++++++++++------- 1 file changed, 27 insertions(+), 7 deletions(-) (limited to 'net/wireless/nl80211.c') diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c index f48394126bf..8ed62b6c172 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) goto out; } - request->n_channels = n_channels; if (n_ssids) request->ssids = (void *)&request->channels[n_channels]; request->n_ssids = n_ssids; @@ -2999,32 +2998,53 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info) request->ie = (void *)(request->channels + n_channels); } + i = 0; if (info->attrs[NL80211_ATTR_SCAN_FREQUENCIES]) { /* user specified, bail out if channel not found */ - request->n_channels = n_channels; - i = 0; nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_FREQUENCIES], tmp) { - request->channels[i] = ieee80211_get_channel(wiphy, nla_get_u32(attr)); - if (!request->channels[i]) { + struct ieee80211_channel *chan; + + chan = ieee80211_get_channel(wiphy, nla_get_u32(attr)); + + if (!chan) { err = -EINVAL; goto out_free; } + + /* ignore disabled channels */ + if (chan->flags & IEEE80211_CHAN_DISABLED) + continue; + + request->channels[i] = chan; i++; } } else { /* all channels */ - i = 0; for (band = 0; band < IEEE80211_NUM_BANDS; band++) { int j; if (!wiphy->bands[band]) continue; for (j = 0; j < wiphy->bands[band]->n_channels; j++) { - request->channels[i] = &wiphy->bands[band]->channels[j]; + struct ieee80211_channel *chan; + + chan = &wiphy->bands[band]->channels[j]; + + if (chan->flags & IEEE80211_CHAN_DISABLED) + continue; + + request->channels[i] = chan; i++; } } } + if (!i) { + err = -EINVAL; + goto out_free; + } + + request->n_channels = i; + i = 0; if (info->attrs[NL80211_ATTR_SCAN_SSIDS]) { nla_for_each_nested(attr, info->attrs[NL80211_ATTR_SCAN_SSIDS], tmp) { -- cgit v1.2.3