diff options
author | Johannes Berg <johannes@sipsolutions.net> | 2009-05-08 03:42:33 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-05-11 15:23:54 -0400 |
commit | 0b258582fef3a9b15b2372d99164859361faa8db (patch) | |
tree | 4467eb0ffbb199f7fd3aeb1418dfc31e7b344c25 /net/wireless | |
parent | aa837e1d6bd1a71b3c30c7738b6c29d41512fe7d (diff) |
cfg80211: fix wext iw_freq parsing
The function to parse a struct iw_freq has a stupid bug,
it returns NULL when the channel cannot be found at all,
but NULL is supposed to mean "auto". Fix this by checking
the return value of ieee80211_get_channel() and returning
ERR_PTR(-EINVAL) if it returned NULL (channel not found).
This fixes an issue where you could say (in IBSS mode)
iwconfig wlan0 channel 21
and it would use channel 1 instead because that's the
first available channel with IBSS allowed (which is what
the "auto" setting uses).
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/wext-compat.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c index 5ef82f2ca88f..abf6b0a047d8 100644 --- a/net/wireless/wext-compat.c +++ b/net/wireless/wext-compat.c | |||
@@ -296,22 +296,34 @@ EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme); | |||
296 | struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, | 296 | struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy, |
297 | struct iw_freq *freq) | 297 | struct iw_freq *freq) |
298 | { | 298 | { |
299 | struct ieee80211_channel *chan; | ||
300 | int f; | ||
301 | |||
302 | /* | ||
303 | * Parse frequency - return NULL for auto and | ||
304 | * -EINVAL for impossible things. | ||
305 | */ | ||
299 | if (freq->e == 0) { | 306 | if (freq->e == 0) { |
300 | if (freq->m < 0) | 307 | if (freq->m < 0) |
301 | return NULL; | 308 | return NULL; |
302 | else | 309 | f = ieee80211_channel_to_frequency(freq->m); |
303 | return ieee80211_get_channel(wiphy, | ||
304 | ieee80211_channel_to_frequency(freq->m)); | ||
305 | } else { | 310 | } else { |
306 | int i, div = 1000000; | 311 | int i, div = 1000000; |
307 | for (i = 0; i < freq->e; i++) | 312 | for (i = 0; i < freq->e; i++) |
308 | div /= 10; | 313 | div /= 10; |
309 | if (div > 0) | 314 | if (div <= 0) |
310 | return ieee80211_get_channel(wiphy, freq->m / div); | ||
311 | else | ||
312 | return ERR_PTR(-EINVAL); | 315 | return ERR_PTR(-EINVAL); |
316 | f = freq->m / div; | ||
313 | } | 317 | } |
314 | 318 | ||
319 | /* | ||
320 | * Look up channel struct and return -EINVAL when | ||
321 | * it cannot be found. | ||
322 | */ | ||
323 | chan = ieee80211_get_channel(wiphy, f); | ||
324 | if (!chan) | ||
325 | return ERR_PTR(-EINVAL); | ||
326 | return chan; | ||
315 | } | 327 | } |
316 | EXPORT_SYMBOL_GPL(cfg80211_wext_freq); | 328 | EXPORT_SYMBOL_GPL(cfg80211_wext_freq); |
317 | 329 | ||