From f16ee17015c1bc6f9cceb9690da7a6083aeb93a7 Mon Sep 17 00:00:00 2001 From: Pragaspathi Thilagaraj Date: Wed, 15 Jul 2020 13:43:34 +0530 Subject: [PATCH] qcacld-3.0: Validate FILS ERP key lengths in connect request If ERP key lengths are greater than maximum valid lengths, currently the connect request is allowed to go through. Allow fils connection to go through only if erp keys are not sent in connect. If erp information is present, validate the rrk, realm, username length. Add changes to lookup pmkid based on bssid also in addition to the existing logic to lookup based on fils cache_id and ssid. Change-Id: Iebde1f382b7db13553b848a459cb4a783744c2a6 CRs-Fixed: 2732050 --- core/hdd/src/wlan_hdd_cfg80211.c | 12 +++++------- core/sme/src/csr/csr_api_roam.c | 7 ++++++- core/sme/src/csr/csr_inside_api.h | 3 ++- core/sme/src/csr/csr_util.c | 11 +++++++---- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/core/hdd/src/wlan_hdd_cfg80211.c b/core/hdd/src/wlan_hdd_cfg80211.c index 97140fd716..09c2bbc650 100644 --- a/core/hdd/src/wlan_hdd_cfg80211.c +++ b/core/hdd/src/wlan_hdd_cfg80211.c @@ -18698,23 +18698,21 @@ static bool wlan_hdd_fils_data_in_limits(struct cfg80211_connect_params *req) req->fils_erp_next_seq_num, req->auth_type, req->fils_erp_username_len, req->fils_erp_rrk_len, req->fils_erp_realm_len); - if (req->fils_erp_rrk_len || req->fils_erp_realm_len || - req->fils_erp_username_len || - req->fils_erp_rrk_len > FILS_MAX_RRK_LENGTH || + + if (req->fils_erp_rrk_len > FILS_MAX_RRK_LENGTH || req->fils_erp_realm_len > FILS_MAX_REALM_LEN || req->fils_erp_username_len > FILS_MAX_KEYNAME_NAI_LENGTH) { hdd_err("length incorrect, user=%zu rrk=%zu realm=%zu", req->fils_erp_username_len, req->fils_erp_rrk_len, req->fils_erp_realm_len); - return true; + return false; } if (!req->fils_erp_rrk || !req->fils_erp_realm || - !req->fils_erp_username) { - hdd_err("buffer incorrect, user=%pK rrk=%pK realm=%pK", + !req->fils_erp_username) + hdd_err("ERP info is NULL, user=%pK rrk=%pK realm=%pK", req->fils_erp_username, req->fils_erp_rrk, req->fils_erp_realm); - } return true; } diff --git a/core/sme/src/csr/csr_api_roam.c b/core/sme/src/csr/csr_api_roam.c index ab2eb6b1fc..8f5c0f495d 100644 --- a/core/sme/src/csr/csr_api_roam.c +++ b/core/sme/src/csr/csr_api_roam.c @@ -14422,6 +14422,7 @@ csr_validate_and_update_fils_info(struct mac_context *mac, uint8_t vdev_id) { uint8_t cache_id[CACHE_ID_LEN] = {0}; + struct qdf_mac_addr bssid; if (!profile->fils_con_info) return QDF_STATUS_SUCCESS; @@ -14440,12 +14441,16 @@ csr_validate_and_update_fils_info(struct mac_context *mac, cache_id[0], cache_id[1]); } + qdf_mem_copy(bssid.bytes, + csr_join_req->bssDescription.bssId, + QDF_MAC_ADDR_SIZE); + if ((!profile->fils_con_info->r_rk_length || !profile->fils_con_info->key_nai_length) && !bss_desc->fils_info_element.is_cache_id_present && !csr_lookup_fils_pmkid(mac, vdev_id, cache_id, csr_join_req->ssId.ssId, - csr_join_req->ssId.length)) + csr_join_req->ssId.length, &bssid)) return QDF_STATUS_E_FAILURE; qdf_mem_copy(&csr_join_req->fils_con_info, diff --git a/core/sme/src/csr/csr_inside_api.h b/core/sme/src/csr/csr_inside_api.h index 5174390c13..9dded50e50 100644 --- a/core/sme/src/csr/csr_inside_api.h +++ b/core/sme/src/csr/csr_inside_api.h @@ -1082,12 +1082,13 @@ bool csr_lookup_pmkid_using_bssid(struct mac_context *mac, * @cache_id: FILS cache id * @ssid: SSID pointer * @ssid_len: SSID length + * @bssid: Pointer to the BSSID to lookup * * Return: True if lookup is successful */ bool csr_lookup_fils_pmkid(struct mac_context *mac, uint8_t vdev_id, uint8_t *cache_id, uint8_t *ssid, - uint8_t ssid_len); + uint8_t ssid_len, struct qdf_mac_addr *bssid); /** * csr_is_pmkid_found_for_peer() - check if pmkid sent by peer is present in PMK cache. Used in SAP mode. diff --git a/core/sme/src/csr/csr_util.c b/core/sme/src/csr/csr_util.c index 2e6778a155..9e23eb6df8 100644 --- a/core/sme/src/csr/csr_util.c +++ b/core/sme/src/csr/csr_util.c @@ -2695,9 +2695,10 @@ bool csr_lookup_pmkid_using_bssid(struct mac_context *mac, bool csr_lookup_fils_pmkid(struct mac_context *mac, uint8_t vdev_id, uint8_t *cache_id, - uint8_t *ssid, uint8_t ssid_len) + uint8_t *ssid, uint8_t ssid_len, + struct qdf_mac_addr *bssid) { - struct wlan_crypto_pmksa *pmksa; + struct wlan_crypto_pmksa *fils_ssid_pmksa, *bssid_lookup_pmksa; struct wlan_objmgr_vdev *vdev; vdev = wlan_objmgr_get_vdev_by_id_from_psoc(mac->psoc, vdev_id, @@ -2707,8 +2708,10 @@ bool csr_lookup_fils_pmkid(struct mac_context *mac, return false; } - pmksa = wlan_crypto_get_fils_pmksa(vdev, cache_id, ssid, ssid_len); - if (!pmksa) { + bssid_lookup_pmksa = wlan_crypto_get_pmksa(vdev, bssid); + fils_ssid_pmksa = + wlan_crypto_get_fils_pmksa(vdev, cache_id, ssid, ssid_len); + if (!fils_ssid_pmksa && !bssid_lookup_pmksa) { sme_err("FILS_PMKSA: Lookup failed"); wlan_objmgr_vdev_release_ref(vdev, WLAN_LEGACY_SME_ID); return false;