ソースを参照

qcacmn: Fix mem leak while deleting pmksa

Due to commit : I83e8d4c0c8b3ad503aa5894ffdc4a14bc3aeec7a,
while processing set_del_pmk command driver checks pmk_len
to delete pmk. In case if new PMK gets added with 0 lengths,
pmk entry with pmk_len = 0 will never be deleted. It is only
overwritten without freeing due to incorrect logic set_del
pmk logic.

Fix is to modify set and del pmk logic to avoid mem leak.

Change-Id: Idff573d020940dd926d07e1ec4f146eaa1215686
CRs-Fixed: 2696207
Abhinav Kumar 5 年 前
コミット
5839296d1d
1 ファイル変更26 行追加39 行削除
  1. 26 39
      umac/cmn_services/crypto/src/wlan_crypto_global_api.c

+ 26 - 39
umac/cmn_services/crypto/src/wlan_crypto_global_api.c

@@ -356,34 +356,12 @@ QDF_STATUS wlan_crypto_set_pmksa(struct wlan_crypto_params *crypto_params,
 	/* Delete the old entry and then Add new entry */
 	wlan_crypto_del_pmksa(crypto_params, pmksa);
 
-	/* find the empty slot or slot with same bssid */
+	/* find the empty slot as duplicate is already deleted */
 	for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
 		if (!crypto_params->pmksa[i]) {
-			if (!slot_found) {
-				slot_found = true;
-				first_available_slot = i;
-			}
-			continue;
-		}
-		if (qdf_is_macaddr_equal(&pmksa->bssid,
-					 &crypto_params->pmksa[i]->bssid)) {
-			/* current pmksa is already freed in del_pmksa,
-			 * so just use this slot
-			 */
-			crypto_params->pmksa[i] = pmksa;
-			return QDF_STATUS_SUCCESS;
-		} else if (pmksa->ssid_len &&
-			    !qdf_mem_cmp(pmksa->ssid,
-					 crypto_params->pmksa[i]->ssid,
-					 pmksa->ssid_len) &&
-			    !qdf_mem_cmp(pmksa->cache_id,
-					 crypto_params->pmksa[i]->cache_id,
-					 WLAN_CACHE_ID_LEN)){
-			/* current pmksa is already freed in del_pmksa,
-			 * so just use this slot
-			 */
-			crypto_params->pmksa[i] = pmksa;
-			return QDF_STATUS_SUCCESS;
+			slot_found = true;
+			first_available_slot = i;
+			break;
 		}
 	}
 
@@ -400,7 +378,7 @@ static
 QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params,
 				 struct wlan_crypto_pmksa *pmksa)
 {
-	uint8_t i;
+	uint8_t i, j;
 	bool match_found = false;
 	u8 del_pmk[MAX_PMK_LEN] = {0};
 
@@ -417,27 +395,36 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params,
 					pmksa->ssid_len) &&
 			   !qdf_mem_cmp(pmksa->cache_id,
 					crypto_params->pmksa[i]->cache_id,
-					WLAN_CACHE_ID_LEN)){
+					WLAN_CACHE_ID_LEN)) {
 			match_found = true;
 		}
 
 		if (match_found) {
 			qdf_mem_copy(del_pmk, crypto_params->pmksa[i]->pmk,
 				     crypto_params->pmksa[i]->pmk_len);
-			for (i = 0; i < WLAN_CRYPTO_MAX_PMKID; i++) {
-				if (!crypto_params->pmksa[i])
+			/* Free matching entry */
+			qdf_mem_zero(crypto_params->pmksa[i],
+				     sizeof(struct wlan_crypto_pmksa));
+			qdf_mem_free(crypto_params->pmksa[i]);
+			crypto_params->pmksa[i] = NULL;
+
+			/* Find and remove the entries matching the pmk */
+			for (j = 0; j < WLAN_CRYPTO_MAX_PMKID; j++) {
+				if (!crypto_params->pmksa[j])
 					continue;
-				if (crypto_params->pmksa[i]->pmk_len &&
-				    (!qdf_mem_cmp(crypto_params->pmksa[i]->pmk,
-				    del_pmk,
-				    crypto_params->pmksa[i]->pmk_len))) {
-					qdf_mem_zero(crypto_params->pmksa[i],
-						     sizeof(
-						     struct wlan_crypto_pmksa));
-					qdf_mem_free(crypto_params->pmksa[i]);
-					crypto_params->pmksa[i] = NULL;
+				if (crypto_params->pmksa[j]->pmk_len &&
+				    (!qdf_mem_cmp(crypto_params->pmksa[j]->pmk,
+				     del_pmk,
+				     crypto_params->pmksa[j]->pmk_len))) {
+					qdf_mem_zero(crypto_params->pmksa[j],
+					sizeof(struct wlan_crypto_pmksa));
+					qdf_mem_free(crypto_params->pmksa[j]);
+					crypto_params->pmksa[j] = NULL;
 				}
 			}
+			/* reset stored pmk */
+			qdf_mem_zero(del_pmk, MAX_PMK_LEN);
+
 			return QDF_STATUS_SUCCESS;
 		}
 	}