Browse Source

qcacld-3.0: Fix mem leak in join and reassoc req

If event posting to VDEV state machine fails, the memory allocated
in lim join and reassoc req is not freed, leading to mem leak.

Fix this by freeing the memory in failure cases.

Change-Id: I3769684e6ad64341b73dd6f6343adc8c0d26d04c
CRs-Fixed: 2342487
Abhishek Singh 6 years ago
parent
commit
254d551576

+ 14 - 3
core/mac/src/pe/include/lim_ft.h

@@ -41,8 +41,18 @@ void lim_ft_cleanup_pre_auth_info(tpAniSirGlobal pMac,
 int lim_process_ft_pre_auth_req(tpAniSirGlobal pMac,
 				struct scheduler_msg *pMsg);
 void lim_process_ft_preauth_rsp_timeout(tpAniSirGlobal pMac);
+
+/**
+ * lim_process_mlm_ft_reassoc_req() - Handle the Reassoc request
+ * @pMac: Global MAC context
+ * @reassoc_req: reassoc req
+ *
+ *  This function handles the Reassoc Req from SME
+ *
+ *  Return: None
+ */
 void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac,
-				    tpPESession psessionEntry);
+				    tLimMlmReassocReq *reassoc_req);
 void lim_perform_ft_pre_auth(tpAniSirGlobal pMac, QDF_STATUS status,
 		uint32_t *data, tpPESession psessionEntry);
 void lim_post_ft_pre_auth_rsp(tpAniSirGlobal pMac, QDF_STATUS status,
@@ -70,8 +80,9 @@ static inline void lim_ft_cleanup_pre_auth_info(tpAniSirGlobal pMac,
 {}
 static inline void lim_process_ft_preauth_rsp_timeout(tpAniSirGlobal pMac)
 {}
-static inline void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac,
-						  tpPESession psessionEntry)
+static inline
+void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac,
+				    tLimMlmReassocReq *reassoc_req)
 {}
 static inline void lim_handle_ft_pre_auth_rsp(tpAniSirGlobal pMac,
 		QDF_STATUS status, uint8_t *auth_rsp,

+ 34 - 36
core/mac/src/pe/lim/lim_process_mlm_host_roam.c

@@ -563,69 +563,67 @@ end:
 			     (uint32_t *) &mlmReassocCnf);
 }
 
-/**
- * lim_process_mlm_ft_reassoc_req() - Handle the Reassoc request
- * @pMac: Global MAC context
- * @psessionEntry: PE Session
- *
- *  This function handles the Reassoc Req from SME
- *
- *  Return: None
- */
 void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac,
-				    tpPESession psessionEntry)
+				    tLimMlmReassocReq *reassoc_req)
 {
 	uint8_t chanNum = 0;
-	tLimMlmReassocReq *pMlmReassocReq;
+	tpPESession session;
 	uint16_t caps;
 	uint32_t val;
 	struct scheduler_msg msgQ = {0};
 	QDF_STATUS retCode;
 	uint32_t teleBcnEn = 0;
 
-	chanNum = psessionEntry->currentOperChannel;
+	if (!reassoc_req) {
+		pe_err("reassoc_req is NULL");
+		return;
+	}
+
+	session = pe_find_session_by_session_id(pMac, reassoc_req->sessionId);
+	if (!session) {
+		pe_err("session Does not exist for given session Id");
+		qdf_mem_free(reassoc_req);
+		return;
+	}
+
+	chanNum = session->currentOperChannel;
 
 #ifdef FEATURE_WLAN_DIAG_SUPPORT_LIM    /* FEATURE_WLAN_DIAG_SUPPORT */
 	lim_diag_event_report(pMac, WLAN_PE_DIAG_REASSOCIATING,
-			psessionEntry, 0, 0);
+			session, 0, 0);
 #endif
 
 	/* Nothing to be done if the session is not in STA mode */
-	if (!LIM_IS_STA_ROLE(psessionEntry)) {
+	if (!LIM_IS_STA_ROLE(session)) {
 		pe_err("psessionEntry is not in STA mode");
+		qdf_mem_free(reassoc_req);
 		return;
 	}
 
-	if (NULL == psessionEntry->ftPEContext.pAddBssReq) {
+	if (NULL == session->ftPEContext.pAddBssReq) {
 		pe_err("pAddBssReq is NULL");
 		return;
 	}
-	pMlmReassocReq = qdf_mem_malloc(sizeof(tLimMlmReassocReq));
-	if (!pMlmReassocReq)
-		return;
 
-	qdf_mem_copy(pMlmReassocReq->peerMacAddr,
-		     psessionEntry->bssId, sizeof(tSirMacAddr));
+	qdf_mem_copy(reassoc_req->peerMacAddr,
+		     session->bssId, sizeof(tSirMacAddr));
 
-	if (cfg_get_capability_info(pMac, &caps, psessionEntry) !=
+	if (cfg_get_capability_info(pMac, &caps, session) !=
 			QDF_STATUS_SUCCESS) {
 		/**
 		 * Could not get Capabilities value
 		 * from CFG. Log error.
 		 */
 		pe_err("could not get Capabilities value");
-		qdf_mem_free(pMlmReassocReq);
+		qdf_mem_free(reassoc_req);
 		return;
 	}
 
 	lim_update_caps_info_for_bss(pMac, &caps,
-		psessionEntry->pLimReAssocReq->bssDescription.capabilityInfo);
+		session->pLimReAssocReq->bssDescription.capabilityInfo);
 	pe_debug("Capabilities info FT Reassoc: 0x%X", caps);
 
-	pMlmReassocReq->capabilityInfo = caps;
-
-	/* Update PE sessionId */
-	pMlmReassocReq->sessionId = psessionEntry->peSessionId;
+	reassoc_req->capabilityInfo = caps;
 
 	/* If telescopic beaconing is enabled, set listen interval
 	   to CFG_TELE_BCN_MAX_LI
@@ -637,33 +635,33 @@ void lim_process_mlm_ft_reassoc_req(tpAniSirGlobal pMac,
 		val = pMac->mlme_cfg->sap_cfg.listen_interval;
 
 	if (lim_set_link_state
-		    (pMac, eSIR_LINK_PREASSOC_STATE, psessionEntry->bssId,
-		    psessionEntry->selfMacAddr, NULL, NULL) != QDF_STATUS_SUCCESS) {
-		qdf_mem_free(pMlmReassocReq);
+		    (pMac, eSIR_LINK_PREASSOC_STATE, session->bssId,
+		    session->selfMacAddr, NULL, NULL) != QDF_STATUS_SUCCESS) {
+		qdf_mem_free(reassoc_req);
 		return;
 	}
 
-	pMlmReassocReq->listenInterval = (uint16_t) val;
-	psessionEntry->pLimMlmReassocReq = pMlmReassocReq;
+	reassoc_req->listenInterval = (uint16_t) val;
+	session->pLimMlmReassocReq = reassoc_req;
 
 	/* we need to defer the message until we get response back from HAL */
 	SET_LIM_PROCESS_DEFD_MESGS(pMac, false);
 
 	msgQ.type = SIR_HAL_ADD_BSS_REQ;
 	msgQ.reserved = 0;
-	msgQ.bodyptr = psessionEntry->ftPEContext.pAddBssReq;
+	msgQ.bodyptr = session->ftPEContext.pAddBssReq;
 	msgQ.bodyval = 0;
 
 	pe_debug("Sending SIR_HAL_ADD_BSS_REQ");
-	MTRACE(mac_trace_msg_tx(pMac, psessionEntry->peSessionId, msgQ.type));
+	MTRACE(mac_trace_msg_tx(pMac, session->peSessionId, msgQ.type));
 	retCode = wma_post_ctrl_msg(pMac, &msgQ);
 	if (QDF_STATUS_SUCCESS != retCode) {
-		qdf_mem_free(psessionEntry->ftPEContext.pAddBssReq);
+		qdf_mem_free(session->ftPEContext.pAddBssReq);
 		pe_err("Posting ADD_BSS_REQ to HAL failed, reason: %X",
 			retCode);
 	}
 
-	psessionEntry->ftPEContext.pAddBssReq = NULL;
+	session->ftPEContext.pAddBssReq = NULL;
 	return;
 }
 

+ 55 - 11
core/mac/src/pe/lim/lim_process_sme_req_messages.c

@@ -1192,7 +1192,12 @@ static inline void lim_update_sae_config(tpPESession session,
 static QDF_STATUS lim_send_join_req(tpPESession session,
 				    tLimMlmJoinReq *mlm_join_req)
 {
-	mlme_set_assoc_type(session->vdev, VDEV_ASSOC);
+	QDF_STATUS status;
+
+	status = mlme_set_assoc_type(session->vdev, VDEV_ASSOC);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
 	return wlan_vdev_mlme_sm_deliver_evt(session->vdev,
 					     WLAN_VDEV_SM_EV_START,
 					     sizeof(*mlm_join_req),
@@ -1220,7 +1225,12 @@ static QDF_STATUS lim_send_join_req(tpPESession session,
 static QDF_STATUS lim_send_reassoc_req(tpPESession session,
 				       tLimMlmReassocReq *reassoc_req)
 {
-	mlme_set_assoc_type(session->vdev, VDEV_REASSOC);
+	QDF_STATUS status;
+
+	status = mlme_set_assoc_type(session->vdev, VDEV_REASSOC);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
 	return wlan_vdev_mlme_sm_deliver_evt(session->vdev,
 					     WLAN_VDEV_SM_EV_START,
 					     sizeof(*reassoc_req),
@@ -1245,18 +1255,25 @@ static QDF_STATUS lim_send_reassoc_req(tpPESession session,
  */
 
 #ifdef CONFIG_VDEV_SM
-static QDF_STATUS lim_send_ft_reassoc_req(tpPESession session)
+static QDF_STATUS lim_send_ft_reassoc_req(tpPESession session,
+					  tLimMlmReassocReq *reassoc_req)
 {
-	mlme_set_assoc_type(session->vdev, VDEV_FT_REASSOC);
+	QDF_STATUS status;
+
+	status = mlme_set_assoc_type(session->vdev, VDEV_FT_REASSOC);
+	if (QDF_IS_STATUS_ERROR(status))
+		return status;
+
 	return wlan_vdev_mlme_sm_deliver_evt(session->vdev,
 					     WLAN_VDEV_SM_EV_START,
-					     sizeof(*session),
-					     session);
+					     sizeof(*reassoc_req),
+					     reassoc_req);
 }
 #else
-static QDF_STATUS lim_send_ft_reassoc_req(tpPESession session)
+static QDF_STATUS lim_send_ft_reassoc_req(tpPESession session,
+					  tLimMlmReassocReq *reassoc_req)
 {
-	lim_process_mlm_ft_reassoc_req(session->mac_ctx, session);
+	lim_process_mlm_ft_reassoc_req(session->mac_ctx, reassoc_req);
 
 	return QDF_STATUS_SUCCESS;
 }
@@ -1288,6 +1305,7 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
 	uint16_t ie_len;
 	const uint8_t *vendor_ie;
 	tSirBssDescription *bss_desc;
+	QDF_STATUS status;
 
 	if (!mac_ctx || !msg_buf) {
 		QDF_TRACE(QDF_MODULE_ID_PE, QDF_TRACE_LEVEL_ERROR,
@@ -1731,7 +1749,12 @@ __lim_process_sme_join_req(tpAniSirGlobal mac_ctx, uint32_t *msg_buf)
 		session->isOSENConnection = sme_join_req->isOSENConnection;
 
 		/* Issue LIM_MLM_JOIN_REQ to MLM */
-		lim_send_join_req(session, mlm_join_req);
+		status = lim_send_join_req(session, mlm_join_req);
+		if (QDF_IS_STATUS_ERROR(status)) {
+			qdf_mem_free(mlm_join_req);
+			ret_code = eSIR_SME_REFUSED;
+			goto end;
+		}
 		return;
 
 	} else {
@@ -1811,6 +1834,7 @@ static void __lim_process_sme_reassoc_req(tpAniSirGlobal mac_ctx,
 	int8_t local_pwr_constraint = 0, reg_max = 0;
 	uint32_t tele_bcn_en = 0;
 	uint16_t size;
+	QDF_STATUS status;
 
 	size = __lim_get_sme_join_req_size_for_alloc((uint8_t *)msg_buf);
 	reassoc_req = qdf_mem_malloc(size);
@@ -1925,7 +1949,22 @@ static void __lim_process_sme_reassoc_req(tpAniSirGlobal mac_ctx,
 
 			session_entry->smeSessionId = sme_session_id;
 			session_entry->transactionId = transaction_id;
-			lim_send_ft_reassoc_req(session_entry);
+			mlm_reassoc_req =
+				qdf_mem_malloc(sizeof(*mlm_reassoc_req));
+			if (!mlm_reassoc_req) {
+				ret_code = eSIR_SME_RESOURCES_UNAVAILABLE;
+				goto end;
+			}
+
+			/* Update PE sessionId */
+			mlm_reassoc_req->sessionId = session_entry->peSessionId;
+			status = lim_send_ft_reassoc_req(session_entry,
+							 mlm_reassoc_req);
+			if (QDF_IS_STATUS_ERROR(status)) {
+				qdf_mem_free(mlm_reassoc_req);
+				ret_code = eSIR_SME_REFUSED;
+				goto end;
+			}
 			return;
 		}
 		/*
@@ -2034,7 +2073,12 @@ static void __lim_process_sme_reassoc_req(tpAniSirGlobal mac_ctx,
 				session_entry->peSessionId,
 				session_entry->limSmeState));
 
-	lim_send_reassoc_req(session_entry, mlm_reassoc_req);
+	status = lim_send_reassoc_req(session_entry, mlm_reassoc_req);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		qdf_mem_free(mlm_reassoc_req);
+		ret_code = eSIR_SME_REFUSED;
+		goto end;
+	}
 
 	return;
 end:

+ 2 - 1
core/mac/src/pe/lim/lim_utils.c

@@ -8413,7 +8413,8 @@ QDF_STATUS lim_sta_mlme_vdev_start_send(struct vdev_mlme_obj *vdev_mlme,
 		lim_process_mlm_reassoc_req(mac_ctx, (tLimMlmReassocReq *)data);
 		break;
 	case VDEV_FT_REASSOC:
-		lim_process_mlm_ft_reassoc_req(mac_ctx, (tPESession *)data);
+		lim_process_mlm_ft_reassoc_req(mac_ctx,
+					       (tLimMlmReassocReq *)data);
 		break;
 	default:
 		pe_err("assoc_type %d is invalid", assoc_type);