Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f95f59fe authored by Bing Zhao's avatar Bing Zhao Committed by John W. Linville
Browse files

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: default avatarPaul Stewart <pstew@chromium.org>
Signed-off-by: default avatarBing Zhao <bzhao@marvell.com>
Signed-off-by: default avatarAvinash Patil <patila@marvell.com>
Signed-off-by: default avatarPaul Stewart <pstew@chromium.org>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 6daf4321
Loading
Loading
Loading
Loading
+10 −12
Original line number Diff line number Diff line
@@ -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;