cfg80211: fix wext iw_freq parsing
authorJohannes Berg <johannes@sipsolutions.net>
Fri, 8 May 2009 07:42:33 +0000 (09:42 +0200)
committerJohn W. Linville <linville@tuxdriver.com>
Mon, 11 May 2009 19:23:54 +0000 (15:23 -0400)
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>
net/wireless/wext-compat.c

index 5ef82f2ca88f08e13c0b78cf4b01524dbbd275dd..abf6b0a047d8bead66c711c9dfa41a18b03b673d 100644 (file)
@@ -296,22 +296,34 @@ EXPORT_SYMBOL_GPL(cfg80211_wext_siwmlme);
 struct ieee80211_channel *cfg80211_wext_freq(struct wiphy *wiphy,
                                             struct iw_freq *freq)
 {
+       struct ieee80211_channel *chan;
+       int f;
+
+       /*
+        * Parse frequency - return NULL for auto and
+        * -EINVAL for impossible things.
+        */
        if (freq->e == 0) {
                if (freq->m < 0)
                        return NULL;
-               else
-                       return ieee80211_get_channel(wiphy,
-                               ieee80211_channel_to_frequency(freq->m));
+               f = ieee80211_channel_to_frequency(freq->m);
        } else {
                int i, div = 1000000;
                for (i = 0; i < freq->e; i++)
                        div /= 10;
-               if (div > 0)
-                       return ieee80211_get_channel(wiphy, freq->m / div);
-               else
+               if (div <= 0)
                        return ERR_PTR(-EINVAL);
+               f = freq->m / div;
        }
 
+       /*
+        * Look up channel struct and return -EINVAL when
+        * it cannot be found.
+        */
+       chan = ieee80211_get_channel(wiphy, f);
+       if (!chan)
+               return ERR_PTR(-EINVAL);
+       return chan;
 }
 EXPORT_SYMBOL_GPL(cfg80211_wext_freq);