summaryrefslogtreecommitdiffstats
path: root/net/wireless
diff options
context:
space:
mode:
authorSara Sharon <sara.sharon@intel.com>2019-01-29 07:00:58 -0500
committerJohannes Berg <johannes.berg@intel.com>2019-02-08 07:56:37 -0500
commitc17fe043a3b79255c6cbe76aafb594849fac0005 (patch)
tree70e7834e2bbadfa4b489e8522101dacfe3137a20 /net/wireless
parentcaf56338c22f00098bf2acd646b0ddc691c80c24 (diff)
cfg80211: fix the IE inheritance of extension IEs
Extension IEs have ID 255 followed by extension ID. Current code is buggy in handling it in two ways: 1. When checking if IE is in the frame, it uses just the ID, which for extension elements is too broad. 2. It uses 0xFF to mark copied IEs, which will result in not copying extension IEs from the subelement. Fix both issue. Signed-off-by: Sara Sharon <sara.sharon@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'net/wireless')
-rw-r--r--net/wireless/scan.c20
1 files changed, 13 insertions, 7 deletions
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 387e5f868684..46ecb10e85fb 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -216,7 +216,13 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
216 continue; 216 continue;
217 } 217 }
218 218
219 tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy, subie_len); 219 if (tmp_old[0] == WLAN_EID_EXTENSION)
220 tmp = (u8 *)cfg80211_find_ext_ie(tmp_old[2], sub_copy,
221 subie_len);
222 else
223 tmp = (u8 *)cfg80211_find_ie(tmp_old[0], sub_copy,
224 subie_len);
225
220 if (!tmp) { 226 if (!tmp) {
221 /* ie in old ie but not in subelement */ 227 /* ie in old ie but not in subelement */
222 if (tmp_old[0] != WLAN_EID_MULTIPLE_BSSID) { 228 if (tmp_old[0] != WLAN_EID_MULTIPLE_BSSID) {
@@ -226,8 +232,9 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
226 } else { 232 } else {
227 /* ie in transmitting ie also in subelement, 233 /* ie in transmitting ie also in subelement,
228 * copy from subelement and flag the ie in subelement 234 * copy from subelement and flag the ie in subelement
229 * as copied (by setting eid field to 0xff). For 235 * as copied (by setting eid field to WLAN_EID_SSID,
230 * vendor ie, compare OUI + type + subType to 236 * which is skipped anyway).
237 * For vendor ie, compare OUI + type + subType to
231 * determine if they are the same ie. 238 * determine if they are the same ie.
232 */ 239 */
233 if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) { 240 if (tmp_old[0] == WLAN_EID_VENDOR_SPECIFIC) {
@@ -237,7 +244,7 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
237 */ 244 */
238 memcpy(pos, tmp, tmp[1] + 2); 245 memcpy(pos, tmp, tmp[1] + 2);
239 pos += tmp[1] + 2; 246 pos += tmp[1] + 2;
240 tmp[0] = 0xff; 247 tmp[0] = WLAN_EID_SSID;
241 } else { 248 } else {
242 memcpy(pos, tmp_old, tmp_old[1] + 2); 249 memcpy(pos, tmp_old, tmp_old[1] + 2);
243 pos += tmp_old[1] + 2; 250 pos += tmp_old[1] + 2;
@@ -246,7 +253,7 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
246 /* copy ie from subelement into new ie */ 253 /* copy ie from subelement into new ie */
247 memcpy(pos, tmp, tmp[1] + 2); 254 memcpy(pos, tmp, tmp[1] + 2);
248 pos += tmp[1] + 2; 255 pos += tmp[1] + 2;
249 tmp[0] = 0xff; 256 tmp[0] = WLAN_EID_SSID;
250 } 257 }
251 } 258 }
252 259
@@ -263,8 +270,7 @@ static size_t cfg80211_gen_new_ie(const u8 *ie, size_t ielen,
263 while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) { 270 while (tmp_new + tmp_new[1] + 2 - sub_copy <= subie_len) {
264 if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP || 271 if (!(tmp_new[0] == WLAN_EID_NON_TX_BSSID_CAP ||
265 tmp_new[0] == WLAN_EID_SSID || 272 tmp_new[0] == WLAN_EID_SSID ||
266 tmp_new[0] == WLAN_EID_MULTI_BSSID_IDX || 273 tmp_new[0] == WLAN_EID_MULTI_BSSID_IDX)) {
267 tmp_new[0] == 0xff)) {
268 memcpy(pos, tmp_new, tmp_new[1] + 2); 274 memcpy(pos, tmp_new, tmp_new[1] + 2);
269 pos += tmp_new[1] + 2; 275 pos += tmp_new[1] + 2;
270 } 276 }