summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/marvell/mwifiex/ie.c47
1 files changed, 31 insertions, 16 deletions
diff --git a/drivers/net/wireless/marvell/mwifiex/ie.c b/drivers/net/wireless/marvell/mwifiex/ie.c
index 6845eb57b39a..653d347a9a19 100644
--- a/drivers/net/wireless/marvell/mwifiex/ie.c
+++ b/drivers/net/wireless/marvell/mwifiex/ie.c
@@ -329,6 +329,8 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
329 struct ieee80211_vendor_ie *vendorhdr; 329 struct ieee80211_vendor_ie *vendorhdr;
330 u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0; 330 u16 gen_idx = MWIFIEX_AUTO_IDX_MASK, ie_len = 0;
331 int left_len, parsed_len = 0; 331 int left_len, parsed_len = 0;
332 unsigned int token_len;
333 int err = 0;
332 334
333 if (!info->tail || !info->tail_len) 335 if (!info->tail || !info->tail_len)
334 return 0; 336 return 0;
@@ -344,6 +346,12 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
344 */ 346 */
345 while (left_len > sizeof(struct ieee_types_header)) { 347 while (left_len > sizeof(struct ieee_types_header)) {
346 hdr = (void *)(info->tail + parsed_len); 348 hdr = (void *)(info->tail + parsed_len);
349 token_len = hdr->len + sizeof(struct ieee_types_header);
350 if (token_len > left_len) {
351 err = -EINVAL;
352 goto out;
353 }
354
347 switch (hdr->element_id) { 355 switch (hdr->element_id) {
348 case WLAN_EID_SSID: 356 case WLAN_EID_SSID:
349 case WLAN_EID_SUPP_RATES: 357 case WLAN_EID_SUPP_RATES:
@@ -361,17 +369,20 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
361 if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, 369 if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT,
362 WLAN_OUI_TYPE_MICROSOFT_WMM, 370 WLAN_OUI_TYPE_MICROSOFT_WMM,
363 (const u8 *)hdr, 371 (const u8 *)hdr,
364 hdr->len + sizeof(struct ieee_types_header))) 372 token_len))
365 break; 373 break;
366 /* fall through */ 374 /* fall through */
367 default: 375 default:
368 memcpy(gen_ie->ie_buffer + ie_len, hdr, 376 if (ie_len + token_len > IEEE_MAX_IE_SIZE) {
369 hdr->len + sizeof(struct ieee_types_header)); 377 err = -EINVAL;
370 ie_len += hdr->len + sizeof(struct ieee_types_header); 378 goto out;
379 }
380 memcpy(gen_ie->ie_buffer + ie_len, hdr, token_len);
381 ie_len += token_len;
371 break; 382 break;
372 } 383 }
373 left_len -= hdr->len + sizeof(struct ieee_types_header); 384 left_len -= token_len;
374 parsed_len += hdr->len + sizeof(struct ieee_types_header); 385 parsed_len += token_len;
375 } 386 }
376 387
377 /* parse only WPA vendor IE from tail, WMM IE is configured by 388 /* parse only WPA vendor IE from tail, WMM IE is configured by
@@ -381,15 +392,17 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
381 WLAN_OUI_TYPE_MICROSOFT_WPA, 392 WLAN_OUI_TYPE_MICROSOFT_WPA,
382 info->tail, info->tail_len); 393 info->tail, info->tail_len);
383 if (vendorhdr) { 394 if (vendorhdr) {
384 memcpy(gen_ie->ie_buffer + ie_len, vendorhdr, 395 token_len = vendorhdr->len + sizeof(struct ieee_types_header);
385 vendorhdr->len + sizeof(struct ieee_types_header)); 396 if (ie_len + token_len > IEEE_MAX_IE_SIZE) {
386 ie_len += vendorhdr->len + sizeof(struct ieee_types_header); 397 err = -EINVAL;
398 goto out;
399 }
400 memcpy(gen_ie->ie_buffer + ie_len, vendorhdr, token_len);
401 ie_len += token_len;
387 } 402 }
388 403
389 if (!ie_len) { 404 if (!ie_len)
390 kfree(gen_ie); 405 goto out;
391 return 0;
392 }
393 406
394 gen_ie->ie_index = cpu_to_le16(gen_idx); 407 gen_ie->ie_index = cpu_to_le16(gen_idx);
395 gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON | 408 gen_ie->mgmt_subtype_mask = cpu_to_le16(MGMT_MASK_BEACON |
@@ -399,13 +412,15 @@ static int mwifiex_uap_parse_tail_ies(struct mwifiex_private *priv,
399 412
400 if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL, NULL, 413 if (mwifiex_update_uap_custom_ie(priv, gen_ie, &gen_idx, NULL, NULL,
401 NULL, NULL)) { 414 NULL, NULL)) {
402 kfree(gen_ie); 415 err = -EINVAL;
403 return -1; 416 goto out;
404 } 417 }
405 418
406 priv->gen_idx = gen_idx; 419 priv->gen_idx = gen_idx;
420
421 out:
407 kfree(gen_ie); 422 kfree(gen_ie);
408 return 0; 423 return err;
409} 424}
410 425
411/* This function parses different IEs-head & tail IEs, beacon IEs, 426/* This function parses different IEs-head & tail IEs, beacon IEs,