Browse Source

qcacld-3.0: Fix double free for master_freq_list

Bring up dual SAP with acs mode in 5G band, when the first SAP start
on DFS channel, the second SAP will choose the same DFS channel with
wlan_hdd_sap_cfg_dfs_override(), but it misses
free/malloc/copy operation for master_freq_list so that the second
SAP use the same master_freq_list pointer as the first SAP, when stop
dual SAP it will cause master_freq_list double free
from sap_undo_acs().

Fix is to add free/malloc/copy operation for master_freq_list.

Change-Id: I2fa2e37899ca0a5ce25941b82b46c5672a27d8eb
CRs-Fixed: 2629301
hqu 5 years ago
parent
commit
9ab959e9b1
1 changed files with 25 additions and 7 deletions
  1. 25 7
      core/hdd/src/wlan_hdd_cfg80211.c

+ 25 - 7
core/hdd/src/wlan_hdd_cfg80211.c

@@ -1746,15 +1746,22 @@ int wlan_hdd_sap_cfg_dfs_override(struct hdd_adapter *adapter)
 		 * MCC restriction. So free ch list allocated in do_acs
 		 * func for Sec AP and realloc for Pri AP ch list size
 		 */
-		if (sap_config->acs_cfg.freq_list)
+		if (sap_config->acs_cfg.freq_list) {
 			qdf_mem_free(sap_config->acs_cfg.freq_list);
+			sap_config->acs_cfg.freq_list = NULL;
+		}
+		if (sap_config->acs_cfg.master_freq_list) {
+			qdf_mem_free(sap_config->acs_cfg.master_freq_list);
+			sap_config->acs_cfg.master_freq_list = NULL;
+		}
 
 		qdf_mem_copy(&sap_config->acs_cfg,
 			     &con_sap_config->acs_cfg,
 			     sizeof(struct sap_acs_cfg));
-		sap_config->acs_cfg.freq_list = qdf_mem_malloc(
-						sizeof(uint32_t) *
-					con_sap_config->acs_cfg.ch_list_count);
+
+		sap_config->acs_cfg.freq_list =
+			qdf_mem_malloc(sizeof(uint32_t) *
+				con_sap_config->acs_cfg.ch_list_count);
 		if (!sap_config->acs_cfg.freq_list) {
 			sap_config->acs_cfg.ch_list_count = 0;
 			return -ENOMEM;
@@ -1762,10 +1769,21 @@ int wlan_hdd_sap_cfg_dfs_override(struct hdd_adapter *adapter)
 		qdf_mem_copy(sap_config->acs_cfg.freq_list,
 			     con_sap_config->acs_cfg.freq_list,
 			     con_sap_config->acs_cfg.ch_list_count *
-			     sizeof(uint32_t));
-		sap_config->acs_cfg.ch_list_count =
-					con_sap_config->acs_cfg.ch_list_count;
+				sizeof(uint32_t));
 
+		sap_config->acs_cfg.master_freq_list =
+			qdf_mem_malloc(sizeof(uint32_t) *
+				con_sap_config->acs_cfg.master_ch_list_count);
+		if (!sap_config->acs_cfg.master_freq_list) {
+			sap_config->acs_cfg.master_ch_list_count = 0;
+			qdf_mem_free(sap_config->acs_cfg.freq_list);
+			sap_config->acs_cfg.freq_list = NULL;
+			return -ENOMEM;
+		}
+		qdf_mem_copy(sap_config->acs_cfg.master_freq_list,
+			     con_sap_config->acs_cfg.master_freq_list,
+			     con_sap_config->acs_cfg.master_ch_list_count *
+				sizeof(uint32_t));
 	} else {
 		sap_config->acs_cfg.pri_ch_freq = con_ch_freq;
 		if (sap_config->acs_cfg.ch_width > eHT_CHANNEL_WIDTH_20MHZ)