mwifiex: remove redundant TDLS setup action frame check and avoid leaks

The unwanted frame types are already handled in 'default' case
of the switch/case below.
The str_ptr is allocated but it can be leaked if the length check
fails in the REQUEST/RESP cases. Fix it by allocating sta_ptr
after the length checks.

Reported-by: Paul Stewart <pstew@chromium.org>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: Avinash Patil <patila@marvell.com>
Signed-off-by: Paul Stewart <pstew@chromium.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:
Bing Zhao 2014-07-14 20:53:34 -07:00 committed by John W. Linville
parent 6daf43216f
commit f95f59fe5d

View File

@ -781,6 +781,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
struct mwifiex_sta_node *sta_ptr;
u8 *peer, *pos, *end;
u8 i, action, basic;
__le16 cap = 0;
int ie_len = 0;
if (len < (sizeof(struct ethhdr) + 3))
@ -792,18 +793,9 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
peer = buf + ETH_ALEN;
action = *(buf + sizeof(struct ethhdr) + 2);
/* just handle TDLS setup request/response/confirm */
if (action > WLAN_TDLS_SETUP_CONFIRM)
return;
dev_dbg(priv->adapter->dev,
"rx:tdls action: peer=%pM, action=%d\n", peer, action);
sta_ptr = mwifiex_add_sta_entry(priv, peer);
if (!sta_ptr)
return;
switch (action) {
case WLAN_TDLS_SETUP_REQUEST:
if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN))
@ -811,7 +803,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
pos = buf + sizeof(struct ethhdr) + 4;
/* payload 1+ category 1 + action 1 + dialog 1 */
sta_ptr->tdls_cap.capab = cpu_to_le16(*(u16 *)pos);
cap = cpu_to_le16(*(u16 *)pos);
ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN;
pos += 2;
break;
@ -821,7 +813,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
return;
/* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/
pos = buf + sizeof(struct ethhdr) + 6;
sta_ptr->tdls_cap.capab = cpu_to_le16(*(u16 *)pos);
cap = cpu_to_le16(*(u16 *)pos);
ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN;
pos += 2;
break;
@ -833,10 +825,16 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN;
break;
default:
dev_warn(priv->adapter->dev, "Unknown TDLS frame type.\n");
dev_dbg(priv->adapter->dev, "Unknown TDLS frame type.\n");
return;
}
sta_ptr = mwifiex_add_sta_entry(priv, peer);
if (!sta_ptr)
return;
sta_ptr->tdls_cap.capab = cap;
for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) {
if (pos + 2 + pos[1] > end)
break;