Browse Source

qcacld-3.0: Proper mem allocation for lim, pre auth timers

This is qcacld-2.0 to qcacld-3.0 propagation.

Fix mem alloc for pre auth timer and add error handling for limInitMlm.

Currently number of preauth timer is taken as cfg param and memory is
allocated in bulk. In case the memory allocation fails, no error is
returned from limInitMlm, which causes undefined behavior. Also preauth
timers do not need contiguous memory allocation, so allocate an array of
pointers instead of single chunk for pre auth timers.

Change-Id: I92677aa9bb7970034630f4c6487fa9d196ccfb4c
CRs-Fixed: 955557
Naveen Rawat 9 years ago
parent
commit
e6ddcaab1a

+ 1 - 1
core/mac/src/pe/include/lim_global.h

@@ -330,7 +330,7 @@ typedef struct tLimPreAuthNode {
 /* Pre-authentication table definition */
 typedef struct tLimPreAuthTable {
 	uint32_t numEntry;
-	tpLimPreAuthNode pTable;
+	tLimPreAuthNode **pTable;
 } tLimPreAuthTable, *tpLimPreAuthTable;
 
 /* / Per STA context structure definition */

+ 4 - 1
core/mac/src/pe/lim/lim_api.c

@@ -541,7 +541,10 @@ tSirRetStatus lim_start(tpAniSirGlobal pMac)
 		pMac->lim.gLimReturnAfterFirstMatch = 0;
 
 		/* Initialize MLM state machine */
-		lim_init_mlm(pMac);
+		if (eSIR_SUCCESS != lim_init_mlm(pMac)) {
+			lim_log(pMac, LOGE, FL("Init MLM failed."));
+			return eSIR_FAILURE;
+		}
 
 		/* By default return unique scan results */
 		pMac->lim.gLimReturnUniqueResults = true;

+ 11 - 12
core/mac/src/pe/lim/lim_assoc_utils.c

@@ -4900,7 +4900,7 @@ void lim_init_pre_auth_timer_table(tpAniSirGlobal pMac,
 {
 	uint32_t cfgValue;
 	uint32_t authNodeIdx;
-	tpLimPreAuthNode pAuthNode = pPreAuthTimerTable->pTable;
+	tLimPreAuthNode **pAuthNode = pPreAuthTimerTable->pTable;
 
 	/* Get AUTH_RSP Timers value */
 
@@ -4917,8 +4917,8 @@ void lim_init_pre_auth_timer_table(tpAniSirGlobal pMac,
 
 	cfgValue = SYS_MS_TO_TICKS(cfgValue);
 	for (authNodeIdx = 0; authNodeIdx < pPreAuthTimerTable->numEntry;
-	     authNodeIdx++, pAuthNode++) {
-		if (tx_timer_create(pMac, &pAuthNode->timer,
+	     authNodeIdx++) {
+		if (tx_timer_create(pMac, &(pAuthNode[authNodeIdx]->timer),
 			"AUTH RESPONSE TIMEOUT",
 			lim_auth_response_timer_handler, authNodeIdx,
 			cfgValue, 0, TX_NO_ACTIVATE) != TX_SUCCESS) {
@@ -4928,10 +4928,9 @@ void lim_init_pre_auth_timer_table(tpAniSirGlobal pMac,
 				authNodeIdx);
 			return;
 		}
-		pAuthNode->authNodeIdx = (uint8_t) authNodeIdx;
-		pAuthNode->fFree = 1;
+		pAuthNode[authNodeIdx]->authNodeIdx = (uint8_t) authNodeIdx;
+		pAuthNode[authNodeIdx]->fFree = 1;
 	}
-
 }
 
 /** -------------------------------------------------------------
@@ -4945,11 +4944,11 @@ tLimPreAuthNode *lim_acquire_free_pre_auth_node(tpAniSirGlobal pMac,
 						tpLimPreAuthTable pPreAuthTimerTable)
 {
 	uint32_t i;
-	tLimPreAuthNode *pTempNode = pPreAuthTimerTable->pTable;
-	for (i = 0; i < pPreAuthTimerTable->numEntry; i++, pTempNode++) {
-		if (pTempNode->fFree == 1) {
-			pTempNode->fFree = 0;
-			return pTempNode;
+	tLimPreAuthNode **pTempNode = pPreAuthTimerTable->pTable;
+	for (i = 0; i < pPreAuthTimerTable->numEntry; i++) {
+		if (pTempNode[i]->fFree == 1) {
+			pTempNode[i]->fFree = 0;
+			return pTempNode[i];
 		}
 	}
 
@@ -4976,7 +4975,7 @@ tLimPreAuthNode *lim_get_pre_auth_node_from_index(tpAniSirGlobal pMac,
 		return NULL;
 	}
 
-	return pAuthTable->pTable + authNodeIdx;
+	return pAuthTable->pTable[authNodeIdx];
 }
 
 /* Util API to check if the channels supported by STA is within range */

+ 15 - 1
core/mac/src/pe/lim/lim_timer_utils.c

@@ -300,12 +300,24 @@ uint32_t lim_create_timers(tpAniSirGlobal pMac)
 		lim_log(pMac, LOGP, FL("could not retrieve mac preauth value"));
 	pMac->lim.gLimPreAuthTimerTable.numEntry = cfgValue;
 	pMac->lim.gLimPreAuthTimerTable.pTable =
-		qdf_mem_malloc(cfgValue * sizeof(tLimPreAuthNode));
+		qdf_mem_malloc(cfgValue * sizeof(tLimPreAuthNode *));
 
 	if (pMac->lim.gLimPreAuthTimerTable.pTable == NULL) {
 		lim_log(pMac, LOGP, FL("AllocateMemory failed!"));
 		goto err_timer;
 	}
+	qdf_mem_zero(pMac->lim.gLimPreAuthTimerTable.pTable,
+		     cfgValue * sizeof(tLimPreAuthNode *));
+
+	for (i = 0; i < cfgValue; i++) {
+		pMac->lim.gLimPreAuthTimerTable.pTable[i] =
+					qdf_mem_malloc(sizeof(tLimPreAuthNode));
+		if (pMac->lim.gLimPreAuthTimerTable.pTable[i] == NULL) {
+			pMac->lim.gLimPreAuthTimerTable.numEntry = 0;
+			lim_log(pMac, LOGP, FL("AllocateMemory failed!"));
+			goto err_timer;
+		}
+	}
 
 	lim_init_pre_auth_timer_table(pMac, &pMac->lim.gLimPreAuthTimerTable);
 	PELOG1(lim_log(pMac, LOG1,
@@ -425,6 +437,8 @@ err_timer:
 	tx_timer_delete(&pMac->lim.limTimers.gLimActiveToPassiveChannelTimer);
 
 	if (NULL != pMac->lim.gLimPreAuthTimerTable.pTable) {
+		for (i = 0; i < cfgValue; i++)
+			qdf_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable[i]);
 		qdf_mem_free(pMac->lim.gLimPreAuthTimerTable.pTable);
 		pMac->lim.gLimPreAuthTimerTable.pTable = NULL;
 	}

+ 1 - 1
core/mac/src/pe/lim/lim_types.h

@@ -418,7 +418,7 @@ void lim_apply_configuration(tpAniSirGlobal, tpPESession);
 void lim_set_cfg_protection(tpAniSirGlobal pMac, tpPESession pesessionEntry);
 
 /* Function to Initialize MLM state machine on STA */
-void lim_init_mlm(tpAniSirGlobal);
+tSirRetStatus lim_init_mlm(tpAniSirGlobal);
 
 /* Function to cleanup MLM state machine */
 void lim_cleanup_mlm(tpAniSirGlobal);

+ 18 - 36
core/mac/src/pe/lim/lim_utils.c

@@ -518,50 +518,36 @@ void lim_print_msg_name(tpAniSirGlobal pMac, uint16_t logLevel, uint32_t msgType
 }
 
 /**
- * lim_init_mlm()
- *
- ***FUNCTION:
- * This function is called by limProcessSmeMessages() to
+ * lim_init_mlm() -  This function is called by limProcessSmeMessages() to
  * initialize MLM state machine on STA
+ * @pMac: Pointer to Global MAC structure
  *
- ***PARAMS:
- *
- ***LOGIC:
- *
- ***ASSUMPTIONS:
- * NA
- *
- ***NOTE:
- * NA
- *
- * @param  pMac      Pointer to Global MAC structure
- * @return None
+ * @Return: Status of operation
  */
-void lim_init_mlm(tpAniSirGlobal pMac)
+tSirRetStatus lim_init_mlm(tpAniSirGlobal pMac)
 {
 	uint32_t retVal;
 
 	pMac->lim.gLimTimersCreated = 0;
 
-	MTRACE(mac_trace
-		       (pMac, TRACE_CODE_MLM_STATE, NO_SESSION,
-		       pMac->lim.gLimMlmState));
-
+	MTRACE(mac_trace(pMac, TRACE_CODE_MLM_STATE, NO_SESSION,
+			  pMac->lim.gLimMlmState));
 
-	/* / Initialize number of pre-auth contexts */
+	/* Initialize number of pre-auth contexts */
 	pMac->lim.gLimNumPreAuthContexts = 0;
 
-	/* / Initialize MAC based Authentication STA list */
+	/* Initialize MAC based Authentication STA list */
 	lim_init_pre_auth_list(pMac);
 
 	/* Create timers used by LIM */
 	retVal = lim_create_timers(pMac);
-	if (retVal == TX_SUCCESS) {
-		pMac->lim.gLimTimersCreated = 1;
-	} else {
-		lim_log(pMac, LOGP,
-			FL(" lim_create_timers Failed to create lim timers "));
+	if (retVal != TX_SUCCESS) {
+		lim_log(pMac, LOGP, FL("lim_create_timers Failed"));
+		return eSIR_SUCCESS;
 	}
+
+	pMac->lim.gLimTimersCreated = 1;
+	return eSIR_SUCCESS;
 } /*** end lim_init_mlm() ***/
 
 /**
@@ -608,7 +594,7 @@ static void lim_deactivate_del_sta(tpAniSirGlobal mac_ctx, uint32_t bss_entry,
 void lim_cleanup_mlm(tpAniSirGlobal mac_ctx)
 {
 	uint32_t n;
-	tLimPreAuthNode *pAuthNode;
+	tLimPreAuthNode **pAuthNode;
 #ifdef WLAN_FEATURE_11W
 	uint32_t bss_entry;
 	tpDphHashNode sta_ds = NULL;
@@ -674,14 +660,10 @@ void lim_cleanup_mlm(tpAniSirGlobal mac_ctx)
 		/* Deactivate any Authentication response timers */
 		lim_delete_pre_auth_list(mac_ctx);
 
+		/* Delete any Auth rsp timers, which might have been started */
 		for (n = 0; n < mac_ctx->lim.gLimPreAuthTimerTable.numEntry;
-					n++, pAuthNode++) {
-			/*
-			 * Delete any Authentication response
-			 * timers, which might have been started.
-			 */
-			tx_timer_delete(&pAuthNode->timer);
-		}
+				n++)
+			tx_timer_delete(&pAuthNode[n]->timer);
 
 		/* Deactivate and delete Hash Miss throttle timer */
 		tx_timer_deactivate(&lim_timer->