aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorHante Meuleman <meuleman@broadcom.com>2012-11-28 15:44:13 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-11-30 14:00:31 -0500
commitb41fc3d740ae80a82167acbe848583da4a74d006 (patch)
treed56ef88463c41c76b3e52bef1d931f1e60638f6d /drivers/net
parent128ce3b6f3b5d3c59dd46de8fff6aef0c1d4ff51 (diff)
brcmfmac: fix bug in setting mgmt ie and parsing vndrs ie.
Parsing vndrs ie was not taking len of tlv itself in account. Setting mgmt ie was missing check for length indicating non configured ie and wrongly checking available length. Reviewed-by: Arend Van Spriel <arend@broadcom.com> Signed-off-by: Hante Meuleman <meuleman@broadcom.com> Signed-off-by: Arend van Spriel <arend@broadcom.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c28
1 files changed, 16 insertions, 12 deletions
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index 5dea1b4fcd6..96bc349d7f6 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -3293,11 +3293,12 @@ brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3293 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER) 3293 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3294 break; 3294 break;
3295next: 3295next:
3296 remaining_len -= ie->len; 3296 remaining_len -= (ie->len + TLV_HDR_LEN);
3297 if (remaining_len <= 2) 3297 if (remaining_len <= TLV_HDR_LEN)
3298 ie = NULL; 3298 ie = NULL;
3299 else 3299 else
3300 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len); 3300 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3301 TLV_HDR_LEN);
3301 } 3302 }
3302 return err; 3303 return err;
3303} 3304}
@@ -3396,11 +3397,11 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3396 } 3397 }
3397 } 3398 }
3398 3399
3399 if (mgmt_ie_buf != NULL) { 3400 if (mgmt_ie_buf && *mgmt_ie_len) {
3400 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) && 3401 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3401 (memcmp(mgmt_ie_buf, curr_ie_buf, 3402 (memcmp(mgmt_ie_buf, curr_ie_buf,
3402 parsed_ie_buf_len) == 0)) { 3403 parsed_ie_buf_len) == 0)) {
3403 WL_TRACE("Previous mgmt IE is equals to current IE"); 3404 WL_TRACE("Previous mgmt IE equals to current IE\n");
3404 goto exit; 3405 goto exit;
3405 } 3406 }
3406 3407
@@ -3438,6 +3439,16 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3438 for (i = 0; i < new_vndr_ies.count; i++) { 3439 for (i = 0; i < new_vndr_ies.count; i++) {
3439 vndrie_info = &new_vndr_ies.ie_info[i]; 3440 vndrie_info = &new_vndr_ies.ie_info[i];
3440 3441
3442 /* verify remained buf size before copy data */
3443 if (remained_buf_len < (vndrie_info->vndrie.len +
3444 VNDR_IE_VSIE_OFFSET)) {
3445 WL_ERR("no space in mgmt_ie_buf: len left %d",
3446 remained_buf_len);
3447 break;
3448 }
3449 remained_buf_len -= (vndrie_info->ie_len +
3450 VNDR_IE_VSIE_OFFSET);
3451
3441 WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n", 3452 WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3442 vndrie_info->vndrie.id, 3453 vndrie_info->vndrie.id,
3443 vndrie_info->vndrie.len, 3454 vndrie_info->vndrie.len,
@@ -3449,13 +3460,6 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3449 vndrie_info->ie_ptr, 3460 vndrie_info->ie_ptr,
3450 vndrie_info->ie_len, 3461 vndrie_info->ie_len,
3451 "add"); 3462 "add");
3452 /* verify remained buf size before copy data */
3453 remained_buf_len -= vndrie_info->ie_len;
3454 if (remained_buf_len < 0) {
3455 WL_ERR("no space in mgmt_ie_buf: len left %d",
3456 remained_buf_len);
3457 break;
3458 }
3459 3463
3460 /* save the parsed IE in wl struct */ 3464 /* save the parsed IE in wl struct */
3461 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr, 3465 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,