qcacld-3.0: Fix to avoid race condition during acs scan

Currently, driver allows multiple acs scan requests at a time. Due to this
race conditions can occur and causes "use after free" issue for variable
channelList. To avoid race condition, driver should allow only one acs scan
request at a time.

Add a new atomic variable to make sure that if one acs scan request
is in process, the driver should reject all further acs scan requests.

Change-Id: I7aa2f4df0dd4c6ca8ff791fe462d142fc7b3e691
CRs-Fixed: 2176354
This commit is contained in:
Abhinav Kumar 2018-02-13 13:00:39 +05:30 • committed by snandini
commit 5eda62d43c
3 changed files with 14 additions and 0 deletions

View file

@ -1688,6 +1688,7 @@ struct hdd_context {
/* Lock to control access to dnbs and coex avoid freq list */
struct mutex avoid_freq_lock;
#endif
qdf_atomic_t is_acs_allowed;
#ifdef WLAN_FEATURE_TSF
/* indicate whether tsf has been initialized */
qdf_atomic_t tsf_ready_flag;

View file

@ -2510,6 +2510,12 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
goto out;
}
if (qdf_atomic_inc_return(&hdd_ctx->is_acs_allowed) > 1) {
hdd_err("ACS rejected as previous req already in progress");
status = -EINVAL;
goto out;
}
sap_config = &adapter->session.ap.sap_config;
if (sap_config->acs_cfg.ch_list)
qdf_mem_free(sap_config->acs_cfg.ch_list);
@ -2520,12 +2526,14 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
wlan_hdd_cfg80211_do_acs_policy);
if (status) {
hdd_err("Invalid ATTR");
qdf_atomic_set(&hdd_ctx->is_acs_allowed, 0);
goto out;
}
if (!tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]) {
hdd_err("Attr hw_mode failed");
status = -EINVAL;
qdf_atomic_set(&hdd_ctx->is_acs_allowed, 0);
goto out;
}
hw_mode = nla_get_u8(tb[QCA_WLAN_VENDOR_ATTR_ACS_HW_MODE]);
@ -2607,6 +2615,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
if (!sap_config->acs_cfg.ch_list) {
hdd_err("ACS config alloc fail");
status = -ENOMEM;
qdf_atomic_set(&hdd_ctx->is_acs_allowed, 0);
goto out;
}
@ -2625,6 +2634,7 @@ static int __wlan_hdd_cfg80211_do_acs(struct wiphy *wiphy,
if (!sap_config->acs_cfg.ch_list) {
hdd_err("ACS config alloc fail");
status = -ENOMEM;
qdf_atomic_set(&hdd_ctx->is_acs_allowed, 0);
goto out;
}

View file

@ -214,6 +214,8 @@ int hdd_sap_context_init(struct hdd_context *hdd_ctx)
qdf_wake_lock_create(&hdd_ctx->sap_wake_lock, "qcom_sap_wakelock");
qdf_spinlock_create(&hdd_ctx->sap_update_info_lock);
qdf_atomic_init(&hdd_ctx->is_acs_allowed);
return 0;
}
@ -2550,6 +2552,7 @@ QDF_STATUS hdd_hostapd_sap_event_cb(tpSap_Event pSapEvent,
/* send vendor event to hostapd only for hostapd based acs*/
if (!hdd_ctx->config->force_sap_acs)
wlan_hdd_cfg80211_acs_ch_select_evt(adapter);
qdf_atomic_set(&hdd_ctx->is_acs_allowed, 0);
return QDF_STATUS_SUCCESS;
case eSAP_ECSA_CHANGE_CHAN_IND:
hdd_debug("Channel change indication from peer for channel %d",