Commit 67a4cce4a89718d252b61aaf58882c69c0e2f6e3
1 parent
52f095ee88
Exists in
master
and in
7 other branches
[PATCH] mac80211: make ieee802_11_parse_elems return void
Some APs send management frames with junk padding after the last IE. We already account for a similar problem with some Apple Airport devices, but at least one device is known to send more than a single extra byte. The device in question is the Draytek Vigor2900: http://www.draytek.com.au/products/Vigor2900.php The junk in question looks like an IE that runs off the end of the frame. This cause us to return ParseFailed. Since the frame in question is an association response, this causes us to fail to associate with this AP. The return code from ieee802_11_parse_elems is superfluous. All callers still check for the presence of the specific IEs that interest them anyway. So, remove the return code so the parse never "fails". Acked-by: Michael Wu <flamingice@sourmilk.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Showing 1 changed file with 9 additions and 46 deletions Side-by-side Diff
net/mac80211/ieee80211_sta.c
... | ... | @@ -108,14 +108,11 @@ |
108 | 108 | u8 wmm_param_len; |
109 | 109 | }; |
110 | 110 | |
111 | -enum ParseRes { ParseOK = 0, ParseUnknown = 1, ParseFailed = -1 }; | |
112 | - | |
113 | -static enum ParseRes ieee802_11_parse_elems(u8 *start, size_t len, | |
114 | - struct ieee802_11_elems *elems) | |
111 | +static void ieee802_11_parse_elems(u8 *start, size_t len, | |
112 | + struct ieee802_11_elems *elems) | |
115 | 113 | { |
116 | 114 | size_t left = len; |
117 | 115 | u8 *pos = start; |
118 | - int unknown = 0; | |
119 | 116 | |
120 | 117 | memset(elems, 0, sizeof(*elems)); |
121 | 118 | |
... | ... | @@ -126,15 +123,8 @@ |
126 | 123 | elen = *pos++; |
127 | 124 | left -= 2; |
128 | 125 | |
129 | - if (elen > left) { | |
130 | -#if 0 | |
131 | - if (net_ratelimit()) | |
132 | - printk(KERN_DEBUG "IEEE 802.11 element parse " | |
133 | - "failed (id=%d elen=%d left=%d)\n", | |
134 | - id, elen, left); | |
135 | -#endif | |
136 | - return ParseFailed; | |
137 | - } | |
126 | + if (elen > left) | |
127 | + return; | |
138 | 128 | |
139 | 129 | switch (id) { |
140 | 130 | case WLAN_EID_SSID: |
141 | 131 | |
142 | 132 | |
... | ... | @@ -201,28 +191,15 @@ |
201 | 191 | elems->ext_supp_rates_len = elen; |
202 | 192 | break; |
203 | 193 | default: |
204 | -#if 0 | |
205 | - printk(KERN_DEBUG "IEEE 802.11 element parse ignored " | |
206 | - "unknown element (id=%d elen=%d)\n", | |
207 | - id, elen); | |
208 | -#endif | |
209 | - unknown++; | |
210 | 194 | break; |
211 | 195 | } |
212 | 196 | |
213 | 197 | left -= elen; |
214 | 198 | pos += elen; |
215 | 199 | } |
216 | - | |
217 | - /* Do not trigger error if left == 1 as Apple Airport base stations | |
218 | - * send AssocResps that are one spurious byte too long. */ | |
219 | - | |
220 | - return unknown ? ParseUnknown : ParseOK; | |
221 | 200 | } |
222 | 201 | |
223 | 202 | |
224 | - | |
225 | - | |
226 | 203 | static int ecw2cw(int ecw) |
227 | 204 | { |
228 | 205 | int cw = 1; |
... | ... | @@ -931,12 +908,7 @@ |
931 | 908 | |
932 | 909 | printk(KERN_DEBUG "%s: replying to auth challenge\n", dev->name); |
933 | 910 | pos = mgmt->u.auth.variable; |
934 | - if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) | |
935 | - == ParseFailed) { | |
936 | - printk(KERN_DEBUG "%s: failed to parse Auth(challenge)\n", | |
937 | - dev->name); | |
938 | - return; | |
939 | - } | |
911 | + ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | |
940 | 912 | if (!elems.challenge) { |
941 | 913 | printk(KERN_DEBUG "%s: no challenge IE in shared key auth " |
942 | 914 | "frame\n", dev->name); |
... | ... | @@ -1230,12 +1202,7 @@ |
1230 | 1202 | aid &= ~(BIT(15) | BIT(14)); |
1231 | 1203 | |
1232 | 1204 | pos = mgmt->u.assoc_resp.variable; |
1233 | - if (ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems) | |
1234 | - == ParseFailed) { | |
1235 | - printk(KERN_DEBUG "%s: failed to parse AssocResp\n", | |
1236 | - dev->name); | |
1237 | - return; | |
1238 | - } | |
1205 | + ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems); | |
1239 | 1206 | |
1240 | 1207 | if (!elems.supp_rates) { |
1241 | 1208 | printk(KERN_DEBUG "%s: no SuppRates element in AssocResp\n", |
... | ... | @@ -1459,7 +1426,7 @@ |
1459 | 1426 | struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); |
1460 | 1427 | struct ieee802_11_elems elems; |
1461 | 1428 | size_t baselen; |
1462 | - int channel, invalid = 0, clen; | |
1429 | + int channel, clen; | |
1463 | 1430 | struct ieee80211_sta_bss *bss; |
1464 | 1431 | struct sta_info *sta; |
1465 | 1432 | struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); |
... | ... | @@ -1505,9 +1472,7 @@ |
1505 | 1472 | #endif /* CONFIG_MAC80211_IBSS_DEBUG */ |
1506 | 1473 | } |
1507 | 1474 | |
1508 | - if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, | |
1509 | - &elems) == ParseFailed) | |
1510 | - invalid = 1; | |
1475 | + ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | |
1511 | 1476 | |
1512 | 1477 | if (sdata->type == IEEE80211_IF_TYPE_IBSS && elems.supp_rates && |
1513 | 1478 | memcmp(mgmt->bssid, sdata->u.sta.bssid, ETH_ALEN) == 0 && |
... | ... | @@ -1724,9 +1689,7 @@ |
1724 | 1689 | if (baselen > len) |
1725 | 1690 | return; |
1726 | 1691 | |
1727 | - if (ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, | |
1728 | - &elems) == ParseFailed) | |
1729 | - return; | |
1692 | + ieee802_11_parse_elems(mgmt->u.beacon.variable, len - baselen, &elems); | |
1730 | 1693 | |
1731 | 1694 | if (elems.erp_info && elems.erp_info_len >= 1) |
1732 | 1695 | ieee80211_handle_erp_ie(dev, elems.erp_info[0]); |