qcacld-3.0: Update pmk cache only for connected BSSID

In OKC enabled cases, when multiple pmk entries exist, the user
space sends set_pmksa command for BSSID other than the connected
bssid. In that case driver updates the global pmksa cache with
the new PMK received for the non-connected BSSID. This results
in invalid pmk sent to firmware.

To avoid this, update the pmk cache only for connected BSSID.

Change-Id: I006595ea5b913d439007a8fb9d767454a71eeac1
CRs-Fixed: 2937182
This commit is contained in:
Pragaspathi Thilagaraj 2021-06-30 00:07:07 +05:30 • committed by Madan Koyyalamudi
commit ee2255dcd2
5 changed files with 56 additions and 47 deletions

View file

@ -6286,10 +6286,12 @@ static int __wlan_hdd_cfg80211_keymgmt_set_key(struct wiphy *wiphy,
struct wireless_dev *wdev,
const void *data, int data_len)
{
uint8_t local_pmk[SIR_ROAM_SCAN_PSK_SIZE];
struct net_device *dev = wdev->netdev;
struct hdd_adapter *hdd_adapter = WLAN_HDD_GET_PRIV_PTR(dev);
struct hdd_context *hdd_ctx;
struct hdd_station_ctx *sta_ctx =
WLAN_HDD_GET_STATION_CTX_PTR(hdd_adapter);
struct wlan_crypto_pmksa pmksa;
int status;
struct pmkid_mode_bits pmkid_modes;
mac_handle_t mac_handle;
@ -6323,11 +6325,15 @@ static int __wlan_hdd_cfg80211_keymgmt_set_key(struct wiphy *wiphy,
sme_update_roam_key_mgmt_offload_enabled(mac_handle,
hdd_adapter->vdev_id,
&pmkid_modes);
qdf_mem_zero(&local_pmk, SIR_ROAM_SCAN_PSK_SIZE);
qdf_mem_copy(local_pmk, data, data_len);
sme_roam_set_psk_pmk(mac_handle, hdd_adapter->vdev_id,
local_pmk, data_len, true);
qdf_mem_zero(&local_pmk, SIR_ROAM_SCAN_PSK_SIZE);
qdf_mem_zero(&pmksa, sizeof(pmksa));
pmksa.pmk_len = data_len;
qdf_mem_copy(pmksa.pmk, data, data_len);
qdf_mem_copy(&pmksa.bssid, &sta_ctx->conn_info.bssid,
QDF_MAC_ADDR_SIZE);
sme_roam_set_psk_pmk(mac_handle, &pmksa, hdd_adapter->vdev_id, true);
qdf_mem_zero(&pmksa, sizeof(pmksa));
return 0;
}
@ -22648,8 +22654,7 @@ static QDF_STATUS wlan_hdd_set_pmksa_cache(struct hdd_adapter *adapter,
}
if (result == QDF_STATUS_SUCCESS && pmk_cache->pmk_len) {
sme_roam_set_psk_pmk(mac_handle, adapter->vdev_id,
pmk_cache->pmk, pmk_cache->pmk_len,
sme_roam_set_psk_pmk(mac_handle, pmksa, adapter->vdev_id,
false);
sme_set_pmk_cache_ft(mac_handle, adapter->vdev_id, pmk_cache);
}

View file

@ -631,9 +631,18 @@ sme_get_roam_scan_ch(mac_handle_t mac_handle,
void sme_get_pmk_info(mac_handle_t mac_handle, uint8_t session_id,
tPmkidCacheInfo *pmk_cache);
QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle, uint8_t sessionId,
uint8_t *psk_pmk, size_t pmk_len,
bool update_to_fw);
/**
* sme_roam_set_psk_pmk - Set the PMK to vdev cache
* @mac_handle: Opaque Mac handle
* @pmksa: Pointer to pmksa cache
* @vdev_id: Vdev id
* @update_to_fw: Send RSO update config command to firmware to update
*
* Return: QDF_STATUS
*/
QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle,
struct wlan_crypto_pmksa *pmksa,
uint8_t vdev_id, bool update_to_fw);
/**
* sme_set_pmk_cache_ft() - a wrapper function to request CSR to save MDID
@ -667,9 +676,9 @@ sme_set_roam_scan_ch_event_cb(mac_handle_t mac_handle,
}
static inline
QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle, uint8_t sessionId,
uint8_t *psk_pmk, size_t pmk_len,
bool update_to_fw)
QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle,
struct wlan_crypto_pmksa *pmksa,
uint8_t vdev_id, bool update_to_fw)
{
return QDF_STATUS_SUCCESS;
}

View file

@ -3871,33 +3871,18 @@ void sme_get_pmk_info(mac_handle_t mac_handle, uint8_t session_id,
#endif
#ifdef WLAN_FEATURE_ROAM_OFFLOAD
/*
* sme_roam_set_psk_pmk() - a wrapper function to request CSR to save PSK/PMK
* This is a synchronous call.
* @mac_handle: Global structure
* @sessionId: SME sessionId
* @pPSK_PMK: pointer to an array of Psk[]/Pmk
* @pmk_len: Length could be only 16 bytes in case if LEAP
* connections. Need to pass this information to
* firmware.
* @update_to_fw: True - send RSO update to firmware after updating
* session->psk_pmk.
* False - Copy the pmk to session->psk_pmk and return
*
* Return: QDF_STATUS -status whether PSK/PMK is set or not
*/
QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle, uint8_t sessionId,
uint8_t *psk_pmk, size_t pmk_len,
bool update_to_fw)
QDF_STATUS sme_roam_set_psk_pmk(mac_handle_t mac_handle,
struct wlan_crypto_pmksa *pmksa,
uint8_t vdev_id, bool update_to_fw)
{
QDF_STATUS status = QDF_STATUS_E_FAILURE;
struct mac_context *mac = MAC_CONTEXT(mac_handle);
status = sme_acquire_global_lock(&mac->sme);
if (QDF_IS_STATUS_SUCCESS(status)) {
if (CSR_IS_SESSION_VALID(mac, sessionId))
status = csr_roam_set_psk_pmk(mac, sessionId, psk_pmk,
pmk_len, update_to_fw);
if (CSR_IS_SESSION_VALID(mac, vdev_id))
status = csr_roam_set_psk_pmk(mac, pmksa, vdev_id,
update_to_fw);
else
status = QDF_STATUS_E_INVAL;
sme_release_global_lock(&mac->sme);

View file

@ -13862,27 +13862,37 @@ void csr_get_pmk_info(struct mac_context *mac_ctx, uint8_t session_id,
pmk_cache->pmk_len = session->pmk_len;
}
QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint32_t sessionId,
uint8_t *psk_pmk, size_t pmk_len,
bool update_to_fw)
QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac,
struct wlan_crypto_pmksa *pmksa,
uint8_t vdev_id, bool update_to_fw)
{
struct csr_roam_session *pSession = CSR_GET_SESSION(mac, sessionId);
struct csr_roam_session *pSession = CSR_GET_SESSION(mac, vdev_id);
struct qdf_mac_addr connected_bssid = {0};
if (!pSession) {
sme_err("session %d not found", sessionId);
sme_err("session %d not found", vdev_id);
return QDF_STATUS_E_FAILURE;
}
qdf_mem_copy(pSession->psk_pmk, psk_pmk, sizeof(pSession->psk_pmk));
pSession->pmk_len = pmk_len;
if (csr_is_auth_type_ese(mac->roam.roamSession[sessionId].
qdf_copy_macaddr(&connected_bssid, &pSession->connectedProfile.bssid);
if (csr_is_conn_state_connected_infra(mac, vdev_id) &&
!pmksa->ssid_len &&
!qdf_is_macaddr_equal(&connected_bssid, &pmksa->bssid)) {
sme_debug("Set pmksa received for non-connected bss");
return QDF_STATUS_E_INVAL;
}
pSession->pmk_len = pmksa->pmk_len;
qdf_mem_copy(pSession->psk_pmk, pmksa->pmk, pSession->pmk_len);
if (csr_is_auth_type_ese(mac->roam.roamSession[vdev_id].
connectedProfile.AuthType)) {
sme_debug("PMK update is not required for ESE");
return QDF_STATUS_SUCCESS;
}
if (update_to_fw)
csr_roam_update_cfg(mac, sessionId,
csr_roam_update_cfg(mac, vdev_id,
REASON_ROAM_PSK_PMK_CHANGED);
return QDF_STATUS_SUCCESS;

View file

@ -725,9 +725,9 @@ void csr_get_pmk_info(struct mac_context *mac_ctx, uint8_t session_id,
*
* Return QDF_STATUS - usually it succeed unless sessionId is not found
*/
QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac, uint32_t sessionId,
uint8_t *psk_pmk, size_t pmk_len,
bool update_to_fw);
QDF_STATUS csr_roam_set_psk_pmk(struct mac_context *mac,
struct wlan_crypto_pmksa *pmksa,
uint8_t vdev_id, bool update_to_fw);
/**
* csr_set_pmk_cache_ft() - store MDID in PMK cache