Jelajahi Sumber

qcacld-3.0: Acquire sap context before access

Fix potential race condition issue when the sap_context
of adapter is null and it is accessed in work queue -
 __policy_mgr_check_sta_ap_concurrent_ch_intf.
To acquire/release the "sap_context" by get/put API.

Change-Id: I91dacc6d45c377840f7d30f2f9ff902f53ccd8e8
CRs-Fixed: 2592524
Liangwei Dong 5 tahun lalu
induk
melakukan
825d2fc8f3

+ 5 - 7
components/cmn_services/policy_mgr/src/wlan_policy_mgr_action.c

@@ -1979,6 +1979,11 @@ void policy_mgr_check_concurrent_intf_and_restart_sap(
 		policy_mgr_err("Invalid sta_ap_intf_check_work_info");
 		return;
 	}
+	if (!policy_mgr_is_sap_go_existed(psoc)) {
+		policy_mgr_debug(
+			"No action taken at check_concurrent_intf_and_restart_sap");
+		return;
+	}
 	/*
 	 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
 	 * enabled on DFS channel then move the SAP out of DFS channel
@@ -2012,13 +2017,6 @@ void policy_mgr_check_concurrent_intf_and_restart_sap(
 		policy_mgr_get_mcc_to_scc_switch_mode(psoc);
 	policy_mgr_info("MCC to SCC switch: %d chan: %d",
 			mcc_to_scc_switch, op_ch_freq_list[0]);
-
-	if (!policy_mgr_is_sap_go_existed(psoc)) {
-		policy_mgr_debug(
-			"No action taken at check_concurrent_intf_and_restart_sap");
-		return;
-	}
-
 sap_restart:
 	/*
 	 * If sta_sap_scc_on_dfs_chan is true then standalone SAP is not

+ 17 - 5
core/hdd/src/wlan_hdd_hostapd.c

@@ -3092,6 +3092,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
 	struct hdd_adapter *ap_adapter = wlan_hdd_get_adapter_from_vdev(
 					psoc, vdev_id);
 	uint32_t sap_ch_freq, intf_ch_freq;
+	struct sap_context *sap_context;
 
 	if (!ap_adapter) {
 		hdd_err("ap_adapter is NULL");
@@ -3115,12 +3116,20 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
 	}
 
 	hdd_ap_ctx = WLAN_HDD_GET_AP_CTX_PTR(ap_adapter);
-
 	mac_handle = hdd_ctx->mac_handle;
 	if (!mac_handle) {
 		hdd_err("mac_handle is NULL");
 		return QDF_STATUS_E_FAILURE;
 	}
+	sap_context = hdd_ap_ctx->sap_context;
+	if (!sap_context) {
+		hdd_err("sap_context is null");
+		return QDF_STATUS_E_FAILURE;
+	}
+	if (QDF_IS_STATUS_ERROR(wlansap_context_get(sap_context))) {
+		hdd_err("sap_context is invalid");
+		return QDF_STATUS_E_FAILURE;
+	}
 
 	/*
 	 * If STA+SAP sessions are on DFS channel and STA+SAP SCC is
@@ -3142,7 +3151,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
 	 * supported, return from here if DBS is not supported.
 	 * Need to take care of 3 port cases with 2 STA iface in future.
 	 */
-	intf_ch_freq = wlansap_check_cc_intf(hdd_ap_ctx->sap_context);
+	intf_ch_freq = wlansap_check_cc_intf(sap_context);
 	policy_mgr_get_chan_by_session_id(psoc, vdev_id, &sap_ch_freq);
 	hdd_info("sap_vdev %d intf_ch: %d, orig freq: %d",
 		 vdev_id, intf_ch_freq, sap_ch_freq);
@@ -3151,6 +3160,7 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
 		if (QDF_IS_STATUS_ERROR(
 		    policy_mgr_valid_sap_conc_channel_check(
 		    hdd_ctx->psoc, &intf_ch_freq, sap_ch_freq, vdev_id))) {
+			wlansap_context_put(sap_context);
 			hdd_debug("can't move sap to chan(freq): %u",
 				  intf_ch_freq);
 			return QDF_STATUS_E_FAILURE;
@@ -3159,13 +3169,14 @@ QDF_STATUS wlan_hdd_get_channel_for_sap_restart(
 
 sap_restart:
 	if (!intf_ch_freq) {
-		intf_ch_freq = wlansap_get_chan_band_restrict(hdd_ap_ctx->sap_context);
+		intf_ch_freq = wlansap_get_chan_band_restrict(sap_context);
 		if (intf_ch_freq == sap_ch_freq)
 			intf_ch_freq = 0;
-	} else if (hdd_ap_ctx->sap_context)
-		hdd_ap_ctx->sap_context->csa_reason =
+	} else
+		sap_context->csa_reason =
 				CSA_REASON_CONCURRENT_STA_CHANGED_CHANNEL;
 	if (!intf_ch_freq) {
+		wlansap_context_put(sap_context);
 		hdd_debug("interface channel is 0");
 		return QDF_STATUS_E_FAILURE;
 	}
@@ -3183,6 +3194,7 @@ sap_restart:
 	hdd_info("SAP channel change with CSA/ECSA");
 	hdd_sap_restart_chan_switch_cb(psoc, vdev_id, *ch_freq,
 				       ch_params.ch_width, false);
+	wlansap_context_put(sap_context);
 
 	return QDF_STATUS_SUCCESS;
 }

+ 4 - 0
core/sap/src/sap_module.c

@@ -3164,6 +3164,10 @@ qdf_freq_t wlansap_get_chan_band_restrict(struct sap_context *sap_ctx)
 	enum reg_wifi_band sap_band;
 	enum band_info band;
 
+	if (!sap_ctx) {
+		sap_err("sap_ctx NULL parameter");
+		return 0;
+	}
 	if (cds_is_driver_recovering())
 		return 0;