From ee6770181ec59b616fc4e00927966e3cd2cfbe51 Mon Sep 17 00:00:00 2001 From: Arif Hussain Date: Thu, 26 Jan 2017 17:50:13 -0800 Subject: [PATCH] qcacld-3.0: Avoid session and peer with same MAC address vdev create request with selfMAC address matching to any of the peer MAC address cause crash in firmware, So before creating new session/peer make sure that there is no peer/session with same MAC address. Change-Id: I7be415365ab7112b013b478139deb451863d52d8 CRs-Fixed: 1115373 --- core/hdd/src/wlan_hdd_cfg80211.c | 25 ++++++++++++++++ core/mac/src/pe/lim/lim_process_auth_frame.c | 31 ++++++++++++++++++++ core/sme/src/common/sme_api.c | 26 ++++++++++++++-- 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index dfc51043487b..c65af76cca9c 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -14813,11 +14813,14 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, { int status; u16 channel; + const u8 *bssid = NULL; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 15, 0)) const u8 *bssid_hint = req->bssid_hint; #else const u8 *bssid_hint = NULL; #endif + hdd_adapter_list_node_t *adapter_node = NULL, *next_adapter = NULL; + hdd_adapter_t *adapter; hdd_adapter_t *pAdapter = WLAN_HDD_GET_PRIV_PTR(ndev); hdd_context_t *pHddCtx; @@ -14858,6 +14861,28 @@ static int __wlan_hdd_cfg80211_connect(struct wiphy *wiphy, if (0 != status) return status; + if (req->bssid) + bssid = req->bssid; + else if (bssid_hint) + bssid = bssid_hint; + + if (bssid) { + status = hdd_get_front_adapter(pHddCtx, &adapter_node); + while (NULL != adapter_node && QDF_STATUS_SUCCESS == status) { + adapter = adapter_node->pAdapter; + if (!qdf_mem_cmp(adapter->macAddressCurrent.bytes, + bssid, QDF_MAC_ADDR_SIZE)) { + hdd_err("Vdev %d exist with same MAC address " + MAC_ADDRESS_STR, adapter->sessionId, + MAC_ADDR_ARRAY(bssid)); + return -EINVAL; + } + status = hdd_get_next_adapter(pHddCtx, adapter_node, + &next_adapter); + adapter_node = next_adapter; + } + } + if (true == wlan_hdd_reassoc_bssid_hint(pAdapter, req, &status)) return status; diff --git a/core/mac/src/pe/lim/lim_process_auth_frame.c b/core/mac/src/pe/lim/lim_process_auth_frame.c index 88070347cbaa..e48157521974 100644 --- a/core/mac/src/pe/lim/lim_process_auth_frame.c +++ b/core/mac/src/pe/lim/lim_process_auth_frame.c @@ -428,6 +428,37 @@ static void lim_process_auth_frame_type1(tpAniSirGlobal mac_ctx, if (lim_is_auth_algo_supported(mac_ctx, (tAniAuthType) rx_auth_frm_body->authAlgoNumber, pe_session)) { + int i = 0; + tCsrRoamSession *session; + + for (i = 0; i < mac_ctx->sme.max_intf_count; i++) { + + if (!CSR_IS_SESSION_VALID(mac_ctx, i)) + continue; + + session = CSR_GET_SESSION(mac_ctx, i); + if (!session || qdf_mem_cmp(&session->selfMacAddr, + mac_hdr->sa, sizeof(tSirMacAddr))) { + continue; + } + + pe_debug("vdev with id %d exist with same MAC " + MAC_ADDRESS_STR, session->sessionId, + MAC_ADDR_ARRAY(mac_hdr->sa)); + + auth_frame->authAlgoNumber = + rx_auth_frm_body->authAlgoNumber; + auth_frame->authTransactionSeqNumber = + rx_auth_frm_body->authTransactionSeqNumber + 1; + auth_frame->authStatusCode = + eSIR_MAC_WME_INVALID_PARAMS_STATUS; + + lim_send_auth_mgmt_frame(mac_ctx, auth_frame, + mac_hdr->sa, LIM_NO_WEP_IN_FC, + pe_session, false); + return; + } + switch (rx_auth_frm_body->authAlgoNumber) { case eSIR_OPEN_SYSTEM: lim_process_auth_open_system_algo(mac_ctx, mac_hdr, diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index fcda3c2c595e..2e8dc8e9f42b 100644 --- a/core/sme/src/common/sme_api.c +++ b/core/sme/src/common/sme_api.c @@ -65,6 +65,7 @@ #include "wlan_reg_services_api.h" #include #include "wlan_reg_ucfg_api.h" +#include "ol_txrx.h" static tSelfRecoveryStats g_self_recovery_stats; @@ -5668,19 +5669,38 @@ QDF_STATUS sme_open_session(tHalHandle hHal, csr_roam_completeCallback callback, void *pContext, uint8_t *pSelfMacAddr, uint8_t session_id, uint32_t type, uint32_t subType) { - QDF_STATUS status; + QDF_STATUS status = QDF_STATUS_E_INVAL; tpAniSirGlobal pMac = PMAC_STRUCT(hHal); + struct cdp_pdev *pdev; + ol_txrx_peer_handle peer; + uint8_t peer_id; QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_INFO_HIGH, "%s: type=%d, session_id %d subType=%d addr:%pM", __func__, type, session_id, subType, pSelfMacAddr); + pdev = cds_get_context(QDF_MODULE_ID_TXRX); + + if (NULL == pdev) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + "%s: Failed to get pdev handler", __func__); + return status; + } + status = sme_acquire_global_lock(&pMac->sme); if (QDF_IS_STATUS_ERROR(status)) return status; - status = csr_roam_open_session(pMac, callback, pContext, pSelfMacAddr, - session_id, type, subType); + peer = ol_txrx_find_peer_by_addr(pdev, pSelfMacAddr, &peer_id); + if (peer) { + QDF_TRACE(QDF_MODULE_ID_SAP, QDF_TRACE_LEVEL_ERROR, + "%s: Peer=%d exist with same MAC", + __func__, peer_id); + status = QDF_STATUS_E_INVAL; + } else { + status = csr_roam_open_session(pMac, callback, pContext, + pSelfMacAddr, session_id, type, subType); + } sme_release_global_lock(&pMac->sme); MTRACE(qdf_trace(QDF_MODULE_ID_SME, TRACE_CODE_SME_RX_HDD_OPEN_SESSION,