Quellcode durchsuchen

qcacld-3.0: Validate channel list from ioctl before sending to fw

Currently the channel list received from the SETROAMSCANCHANNELS
driver command is passed directly to the FW without checking if it
contains any invalid channels leading the firmware to assert if the
list contains unsupported channels.

Validate the channel list received from the ioctl with the base
channel list and send to firmware only if all the channels in
the list are valid

Change-Id: Ia502eecb97e34de854a75a6af7ffb8ccc02a7e52
CRs-Fixed: 2231242
Vignesh Viswanathan vor 7 Jahren
Ursprung
Commit
a2f5ce580a
3 geänderte Dateien mit 71 neuen und 0 gelöschten Zeilen
  1. 23 0
      core/hdd/src/wlan_hdd_ioctl.c
  2. 14 0
      core/sme/inc/sme_api.h
  3. 34 0
      core/sme/src/common/sme_api.c

+ 23 - 0
core/hdd/src/wlan_hdd_ioctl.c

@@ -1455,6 +1455,13 @@ hdd_parse_set_roam_scan_channels_v1(struct hdd_adapter *adapter,
 		goto exit;
 	}
 
+	if (!sme_validate_channel_list(hdd_ctx->hHal,
+	    channel_list, num_chan)) {
+		hdd_err("List contains invalid channel(s)");
+		ret = -EINVAL;
+		goto exit;
+	}
+
 	status =
 		sme_change_roam_scan_channel_list(hdd_ctx->hHal,
 						  adapter->session_id,
@@ -1524,6 +1531,14 @@ hdd_parse_set_roam_scan_channels_v2(struct hdd_adapter *adapter,
 		}
 		channel_list[i] = channel;
 	}
+
+	if (!sme_validate_channel_list(hdd_ctx->hHal,
+	    channel_list, num_chan)) {
+		hdd_err("List contains invalid channel(s)");
+		ret = -EINVAL;
+		goto exit;
+	}
+
 	status =
 		sme_change_roam_scan_channel_list(hdd_ctx->hHal,
 						  adapter->session_id,
@@ -5287,6 +5302,14 @@ static int drv_cmd_set_ccx_roam_scan_channels(struct hdd_adapter *adapter,
 		ret = -EINVAL;
 		goto exit;
 	}
+
+	if (!sme_validate_channel_list(hdd_ctx->hHal,
+	    ChannelList, numChannels)) {
+		hdd_err("List contains invalid channel(s)");
+		ret = -EINVAL;
+		goto exit;
+	}
+
 	status = sme_set_ese_roam_scan_channel_list(hdd_ctx->hHal,
 						    adapter->session_id,
 						    ChannelList,

+ 14 - 0
core/sme/inc/sme_api.h

@@ -2195,4 +2195,18 @@ static inline int sme_update_he_frag_supp(tHalHandle hal, uint8_t session_id,
  */
 bool sme_is_sta_key_exchange_in_progress(tHalHandle hal, uint8_t session_id);
 
+/*
+ * sme_validate_channel_list() - Validate the given channel list
+ * @hal: handle to global hal context
+ * @chan_list: Pointer to the channel list
+ * @num_channels: number of channels present in the chan_list
+ *
+ * Validates the given channel list with base channels in mac context
+ *
+ * Return: True if all channels in the list are valid, false otherwise
+ */
+bool sme_validate_channel_list(tHalHandle hal,
+				      uint8_t *chan_list,
+				      uint8_t num_channels);
+
 #endif /* #if !defined( __SME_API_H ) */

+ 34 - 0
core/sme/src/common/sme_api.c

@@ -16069,3 +16069,37 @@ bool sme_is_sta_key_exchange_in_progress(tHalHandle hal, uint8_t session_id)
 
 	return CSR_IS_WAIT_FOR_KEY(mac_ctx, session_id);
 }
+
+bool sme_validate_channel_list(tHalHandle hal,
+				      uint8_t *chan_list,
+				      uint8_t num_channels)
+{
+	tpAniSirGlobal mac_ctx = PMAC_STRUCT(hal);
+	uint8_t i = 0;
+	uint8_t j;
+	bool found;
+	struct csr_channel *ch_lst_info = &mac_ctx->scan.base_channels;
+
+	if (!chan_list || !num_channels) {
+		sme_err("Chan list empty %pK or num_channels is 0", chan_list);
+		return false;
+	}
+
+	while (i < num_channels) {
+		found = false;
+		for (j = 0; j < ch_lst_info->numChannels; j++) {
+			if (ch_lst_info->channelList[j] == chan_list[i]) {
+				found = true;
+				break;
+			}
+		}
+
+		if (!found) {
+			sme_debug("Invalid channel %d", chan_list[i]);
+			return false;
+		}
+
+		i++;
+	}
+	return true;
+}