Browse Source

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
Arif Hussain 8 năm trước cách đây
mục cha
commit
ee6770181e

+ 25 - 0
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;
 

+ 31 - 0
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,

+ 23 - 3
core/sme/src/common/sme_api.c

@@ -65,6 +65,7 @@
 #include "wlan_reg_services_api.h"
 #include <wlan_scan_ucfg_api.h>
 #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,