mirror of https://gitee.com/openkylin/linux.git
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:
parent
6daf43216f
commit
f95f59fe5d
|
@ -781,6 +781,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
|
||||||
struct mwifiex_sta_node *sta_ptr;
|
struct mwifiex_sta_node *sta_ptr;
|
||||||
u8 *peer, *pos, *end;
|
u8 *peer, *pos, *end;
|
||||||
u8 i, action, basic;
|
u8 i, action, basic;
|
||||||
|
__le16 cap = 0;
|
||||||
int ie_len = 0;
|
int ie_len = 0;
|
||||||
|
|
||||||
if (len < (sizeof(struct ethhdr) + 3))
|
if (len < (sizeof(struct ethhdr) + 3))
|
||||||
|
@ -792,18 +793,9 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
|
||||||
|
|
||||||
peer = buf + ETH_ALEN;
|
peer = buf + ETH_ALEN;
|
||||||
action = *(buf + sizeof(struct ethhdr) + 2);
|
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,
|
dev_dbg(priv->adapter->dev,
|
||||||
"rx:tdls action: peer=%pM, action=%d\n", peer, action);
|
"rx:tdls action: peer=%pM, action=%d\n", peer, action);
|
||||||
|
|
||||||
sta_ptr = mwifiex_add_sta_entry(priv, peer);
|
|
||||||
if (!sta_ptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case WLAN_TDLS_SETUP_REQUEST:
|
case WLAN_TDLS_SETUP_REQUEST:
|
||||||
if (len < (sizeof(struct ethhdr) + TDLS_REQ_FIX_LEN))
|
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;
|
pos = buf + sizeof(struct ethhdr) + 4;
|
||||||
/* payload 1+ category 1 + action 1 + dialog 1 */
|
/* 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;
|
ie_len = len - sizeof(struct ethhdr) - TDLS_REQ_FIX_LEN;
|
||||||
pos += 2;
|
pos += 2;
|
||||||
break;
|
break;
|
||||||
|
@ -821,7 +813,7 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
|
||||||
return;
|
return;
|
||||||
/* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/
|
/* payload 1+ category 1 + action 1 + dialog 1 + status code 2*/
|
||||||
pos = buf + sizeof(struct ethhdr) + 6;
|
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;
|
ie_len = len - sizeof(struct ethhdr) - TDLS_RESP_FIX_LEN;
|
||||||
pos += 2;
|
pos += 2;
|
||||||
break;
|
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;
|
ie_len = len - sizeof(struct ethhdr) - TDLS_CONFIRM_FIX_LEN;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_warn(priv->adapter->dev, "Unknown TDLS frame type.\n");
|
dev_dbg(priv->adapter->dev, "Unknown TDLS frame type.\n");
|
||||||
return;
|
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]) {
|
for (end = pos + ie_len; pos + 1 < end; pos += 2 + pos[1]) {
|
||||||
if (pos + 2 + pos[1] > end)
|
if (pos + 2 + pos[1] > end)
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue