Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b98c7209 authored by Abhinav Kumar's avatar Abhinav Kumar Committed by nshrivas
Browse files

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
parent f110f994
Loading
Loading
Loading
Loading
+26 −39
Original line number Diff line number Diff line
@@ -326,34 +326,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;
			break;
		}
	}

@@ -370,7 +348,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};

@@ -394,20 +372,29 @@ QDF_STATUS wlan_crypto_del_pmksa(struct wlan_crypto_params *crypto_params,
		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])
					continue;
				if (crypto_params->pmksa[i]->pmk_len &&
				    (!qdf_mem_cmp(crypto_params->pmksa[i]->pmk,
				    del_pmk,
				    crypto_params->pmksa[i]->pmk_len))) {
			/* Free matching entry */
			qdf_mem_zero(crypto_params->pmksa[i],
						     sizeof(
						     struct wlan_crypto_pmksa));
				     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[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;
		}
	}