wlan: protect peer list with mutex in __wlan_hdd_cfg80211_tdls_oper
Protect peer list with mutex in __wlan_hdd_cfg80211_tdls_oper
while processing NL80211_TDLS_ENABLE_LINK.
Change-Id: I3d54566465ff6b8495377eac7f9e739843afa5df
CRs-Fixed: 946784
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 75d563e..954214b 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -17792,14 +17792,19 @@
tANI_U16 numCurrTdlsPeers = 0;
hddTdlsPeer_t *connPeer = NULL;
tANI_U8 suppChannelLen = 0;
+ tSirMacAddr peerMac;
+ int channel;
+ tTDLSLinkStatus peer_status = eTDLS_LINK_IDLE;
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
" %s : NL80211_TDLS_ENABLE_LINK for " MAC_ADDRESS_STR,
__func__, MAC_ADDR_ARRAY(peer));
- pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, TRUE);
+ mutex_lock(&pHddCtx->tdls_lock);
+ pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
memset(&staDesc, 0, sizeof(staDesc));
if ( NULL == pTdlsPeer ) {
+ mutex_unlock(&pHddCtx->tdls_lock);
hddLog(VOS_TRACE_LEVEL_ERROR, "%s: " MAC_ADDRESS_STR
" (oper %d) not exsting. ignored",
__func__, MAC_ADDR_ARRAY(peer), (int)oper);
@@ -17816,17 +17821,22 @@
hddLog(VOS_TRACE_LEVEL_ERROR, "%s: Invalid Staion Index %u "
MAC_ADDRESS_STR " failed",
__func__, pTdlsPeer->staId, MAC_ADDR_ARRAY(peer));
+ mutex_unlock(&pHddCtx->tdls_lock);
return -EINVAL;
}
/* before starting tdls connection, set tdls
* off channel established status to default value */
pTdlsPeer->isOffChannelEstablished = FALSE;
+
+ mutex_unlock(&pHddCtx->tdls_lock);
+
/* TDLS Off Channel, Disable tdls channel switch,
when there are more than one tdls link */
numCurrTdlsPeers = wlan_hdd_tdlsConnectedPeers(pAdapter);
if (numCurrTdlsPeers == 2)
{
+ mutex_lock(&pHddCtx->tdls_lock);
/* get connected peer and send disable tdls off chan */
connPeer = wlan_hdd_tdls_get_connected_peer(pAdapter);
if ((connPeer) &&
@@ -17838,12 +17848,16 @@
"TDLS channel switch", __func__);
connPeer->isOffChannelEstablished = FALSE;
+ vos_mem_copy(peerMac, connPeer->peerMac, sizeof (tSirMacAddr));
+ channel = connPeer->peerParams.channel;
+
+ mutex_unlock(&pHddCtx->tdls_lock);
ret = sme_SendTdlsChanSwitchReq(
WLAN_HDD_GET_HAL_CTX(pAdapter),
pAdapter->sessionId,
- connPeer->peerMac,
- connPeer->peerParams.channel,
+ peerMac,
+ channel,
TDLS_OFF_CHANNEL_BW_OFFSET,
TDLS_CHANNEL_SWITCH_DISABLE);
if (ret != VOS_STATUS_SUCCESS) {
@@ -17862,10 +17876,24 @@
: -1),
(connPeer ? (connPeer->isOffChannelConfigured)
: -1));
+ mutex_unlock(&pHddCtx->tdls_lock);
}
}
- if (eTDLS_LINK_CONNECTED != pTdlsPeer->link_status)
+ mutex_lock(&pHddCtx->tdls_lock);
+ pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
+ if ( NULL == pTdlsPeer ) {
+ mutex_unlock(&pHddCtx->tdls_lock);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: " MAC_ADDRESS_STR
+ " (oper %d) peer got freed in other context. ignored",
+ __func__, MAC_ADDR_ARRAY(peer), (int)oper);
+ return -EINVAL;
+ }
+ peer_status = pTdlsPeer->link_status;
+ mutex_unlock(&pHddCtx->tdls_lock);
+
+ if (eTDLS_LINK_CONNECTED != peer_status)
{
if (IS_ADVANCE_TDLS_ENABLE) {
@@ -17899,6 +17927,17 @@
}
}
+ mutex_lock(&pHddCtx->tdls_lock);
+ pTdlsPeer = wlan_hdd_tdls_find_peer(pAdapter, peer, FALSE);
+ if ( NULL == pTdlsPeer ) {
+ mutex_unlock(&pHddCtx->tdls_lock);
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: " MAC_ADDRESS_STR
+ " (oper %d) peer got freed in other context. ignored",
+ __func__, MAC_ADDR_ARRAY(peer), (int)oper);
+ return -EINVAL;
+ }
+
wlan_hdd_tdls_set_peer_link_status(pTdlsPeer,
eTDLS_LINK_CONNECTED,
eTDLS_LINK_SUCCESS);
@@ -17995,10 +18034,15 @@
__func__, pTdlsPeer->peerParams.channel);
pTdlsPeer->isOffChannelEstablished = TRUE;
+ vos_mem_copy(peerMac, pTdlsPeer->peerMac, sizeof (tSirMacAddr));
+ channel = pTdlsPeer->peerParams.channel;
+
+ mutex_unlock(&pHddCtx->tdls_lock);
+
ret = sme_SendTdlsChanSwitchReq(WLAN_HDD_GET_HAL_CTX(pAdapter),
pAdapter->sessionId,
- pTdlsPeer->peerMac,
- pTdlsPeer->peerParams.channel,
+ peerMac,
+ channel,
TDLS_OFF_CHANNEL_BW_OFFSET,
TDLS_CHANNEL_SWITCH_ENABLE);
if (ret != VOS_STATUS_SUCCESS) {
@@ -18015,9 +18059,13 @@
__func__, numCurrTdlsPeers,
pTdlsPeer->isOffChannelSupported,
pTdlsPeer->isOffChannelConfigured);
+ mutex_unlock(&pHddCtx->tdls_lock);
}
}
+ else
+ mutex_unlock(&pHddCtx->tdls_lock);
+
wlan_hdd_tdls_check_bmps(pAdapter);
/* Update TL about the UAPSD masks , to route the packets to firmware */
@@ -18042,6 +18090,7 @@
}
}
}
+
/* stop TCP delack timer if TDLS is enable */
set_bit(WLAN_TDLS_MODE, &pHddCtx->mode);
hdd_manage_delack_timer(pHddCtx);