qcacld-3.0: Use pdev iterate obj list to check for existing WAPI STA

At present, WAPI security mode STA is not allowed to run in
concurerncy with any other vdev.
So, whenever a new vdev is created, policy_mgr_check_privacy_for_new_conn
is called to check the security concurrency of new connection by checking
security of exisitng vdevs and if a STA vdev with WAPI security exists
then the concurrency is not allowed and the api will return false.

In case, while performing this check, the adaptor associated with
the existing vdev is destroyed, there might be a crash as
hdd_wapi_security_sta_exist is still trying to access the security
of that vdev.

To solve this, use wlan_objmgr_pdev_iterate_obj_list with crypto info
to iterate across all the existing vdev and check the security. If
Wapi security STA exists, it will return an argument with value as true
which will be used in policy_mgr_check_privacy_for_new_conn and it will
return false as concurrency is not allowed

Change-Id: Iff811d2406f1c74cec26d457a2a682dd992710b8
CRs-Fixed: 2784406
This commit is contained in:
Utkarsh Bhatnagar 2020-09-25 19:18:47 +05:30 committed by snandini
parent a1952c8ae6
commit 7d9ab089a4
6 changed files with 69 additions and 41 deletions

View File

@ -1442,9 +1442,6 @@ struct policy_mgr_sme_cbacks {
* @get_mode_for_non_connected_vdev: Get the mode for a non
* connected vdev
* @hdd_get_device_mode: Get QDF_OPMODE type for session id (vdev id)
* @hdd_wapi_security_sta_exist: Get whether wapi encription station existing
* or not. Some hw doesn't support WAPI encryption concurrency with other
* encryption type.
* @hdd_is_chan_switch_in_progress: Check if in any adater channel switch is in
* progress
* @wlan_hdd_set_sap_csa_reason: Set the sap csa reason in cases like NAN.
@ -1463,7 +1460,6 @@ struct policy_mgr_hdd_cbacks {
struct wlan_objmgr_psoc *psoc,
uint8_t vdev_id);
enum QDF_OPMODE (*hdd_get_device_mode)(uint32_t session_id);
bool (*hdd_wapi_security_sta_exist)(void);
bool (*hdd_is_chan_switch_in_progress)(void);
bool (*hdd_is_cac_in_progress)(void);
void (*wlan_hdd_set_sap_csa_reason)(struct wlan_objmgr_psoc *psoc,

View File

@ -38,7 +38,7 @@
#include "wlan_cm_roam_public_struct.h"
#include "csr_neighbor_roam.h"
#include "wlan_mlme_main.h"
#include "wlan_mlme_vdev_mgr_interface.h"
/* invalid channel id. */
#define INVALID_CHANNEL_ID 0
@ -2219,11 +2219,15 @@ static bool policy_mgr_is_sub_20_mhz_enabled(struct wlan_objmgr_psoc *psoc)
static bool policy_mgr_check_privacy_for_new_conn(
struct policy_mgr_psoc_priv_obj *pm_ctx)
{
if (!pm_ctx->hdd_cbacks.hdd_wapi_security_sta_exist)
return true;
struct wlan_objmgr_pdev *pdev = pm_ctx->pdev;
if (pm_ctx->hdd_cbacks.hdd_wapi_security_sta_exist() &&
(policy_mgr_get_connection_count(pm_ctx->psoc) > 0))
if (!pdev) {
policy_mgr_debug("pdev is Null");
return true;
}
if (mlme_is_wapi_sta_active(pdev) &&
policy_mgr_get_connection_count(pm_ctx->psoc) > 0)
return false;
return true;

View File

@ -715,8 +715,6 @@ QDF_STATUS policy_mgr_register_hdd_cb(struct wlan_objmgr_psoc *psoc,
hdd_cbacks->get_mode_for_non_connected_vdev;
pm_ctx->hdd_cbacks.hdd_get_device_mode =
hdd_cbacks->hdd_get_device_mode;
pm_ctx->hdd_cbacks.hdd_wapi_security_sta_exist =
hdd_cbacks->hdd_wapi_security_sta_exist;
pm_ctx->hdd_cbacks.hdd_is_chan_switch_in_progress =
hdd_cbacks->hdd_is_chan_switch_in_progress;
pm_ctx->hdd_cbacks.hdd_is_cac_in_progress =

View File

@ -111,6 +111,21 @@ mlme_set_vdev_start_failed(struct wlan_objmgr_vdev *vdev, bool val);
*/
bool mlme_is_connection_fail(struct wlan_objmgr_vdev *vdev);
/**
* mlme_is_wapi_sta_active() - check sta with wapi security exists and is active
* @pdev: pdev pointer
*
* Return: true if sta with wapi security exists
*/
#ifdef FEATURE_WLAN_WAPI
bool mlme_is_wapi_sta_active(struct wlan_objmgr_pdev *pdev);
#else
static inline bool mlme_is_wapi_sta_active(struct wlan_objmgr_pdev *pdev)
{
return false;
}
#endif
QDF_STATUS mlme_set_bigtk_support(struct wlan_objmgr_vdev *vdev, bool val);
bool mlme_get_bigtk_support(struct wlan_objmgr_vdev *vdev);

View File

@ -28,6 +28,7 @@
#include <../../core/src/vdev_mgr_ops.h>
#include "wlan_psoc_mlme_api.h"
#include "target_if_cm_roam_offload.h"
#include "wlan_crypto_global_api.h"
static struct vdev_mlme_ops sta_mlme_ops;
static struct vdev_mlme_ops ap_mlme_ops;
@ -744,6 +745,50 @@ bool mlme_is_connection_fail(struct wlan_objmgr_vdev *vdev)
return mlme_priv->connection_fail;
}
#ifdef FEATURE_WLAN_WAPI
static void mlme_is_sta_vdev_wapi(struct wlan_objmgr_pdev *pdev,
void *object, void *arg)
{
struct wlan_objmgr_vdev *vdev = (struct wlan_objmgr_vdev *)object;
int32_t keymgmt;
bool *is_wapi_sta_exist = (bool *)arg;
QDF_STATUS status;
if (*is_wapi_sta_exist)
return;
if (wlan_vdev_mlme_get_opmode(vdev) != QDF_STA_MODE)
return;
status = wlan_vdev_is_up(vdev);
if (QDF_IS_STATUS_ERROR(status))
return;
keymgmt = wlan_crypto_get_param(vdev, WLAN_CRYPTO_PARAM_KEY_MGMT);
if (keymgmt < 0)
return;
if (keymgmt & ((1 << WLAN_CRYPTO_KEY_MGMT_WAPI_PSK) |
(1 << WLAN_CRYPTO_KEY_MGMT_WAPI_CERT))) {
*is_wapi_sta_exist = true;
mlme_debug("wapi exist for Vdev: %d",
wlan_vdev_get_id(vdev));
}
}
bool mlme_is_wapi_sta_active(struct wlan_objmgr_pdev *pdev)
{
bool is_wapi_sta_exist = false;
wlan_objmgr_pdev_iterate_obj_list(pdev,
WLAN_VDEV_OP,
mlme_is_sta_vdev_wapi,
&is_wapi_sta_exist, 0,
WLAN_MLME_OBJMGR_ID);
return is_wapi_sta_exist;
}
#endif
QDF_STATUS mlme_set_assoc_type(struct wlan_objmgr_vdev *vdev,
enum vdev_assoc_type assoc_type)
{

View File

@ -3254,34 +3254,6 @@ int hdd_assemble_rate_code(uint8_t preamble, uint8_t nss, uint8_t rate)
return set_value;
}
#ifdef FEATURE_WLAN_WAPI
/**
* hdd_wapi_security_sta_exist() - return wapi security sta exist or not
*
* This API returns the wapi security station exist or not
*
* Return: true - wapi security station exist
*/
static bool hdd_wapi_security_sta_exist(void)
{
struct hdd_adapter *adapter = NULL;
struct hdd_context *hdd_ctx = cds_get_context(QDF_MODULE_ID_HDD);
hdd_for_each_adapter(hdd_ctx, adapter) {
if ((adapter->device_mode == QDF_STA_MODE) &&
adapter->wapi_info.wapi_mode &&
(adapter->wapi_info.wapi_auth_mode != WAPI_AUTH_MODE_OPEN))
return true;
}
return false;
}
#else
static bool hdd_wapi_security_sta_exist(void)
{
return false;
}
#endif
#ifdef FEATURE_WLAN_MCC_TO_SCC_SWITCH
static enum policy_mgr_con_mode wlan_hdd_get_mode_for_non_connected_vdev(
struct wlan_objmgr_psoc *psoc, uint8_t vdev_id)
@ -3354,8 +3326,6 @@ static void hdd_register_policy_manager_callback(
hdd_cbacks.get_mode_for_non_connected_vdev =
wlan_hdd_get_mode_for_non_connected_vdev;
hdd_cbacks.hdd_get_device_mode = hdd_get_device_mode;
hdd_cbacks.hdd_wapi_security_sta_exist =
hdd_wapi_security_sta_exist;
hdd_cbacks.hdd_is_chan_switch_in_progress =
hdd_is_chan_switch_in_progress;
hdd_cbacks.hdd_is_cac_in_progress =