From a2f5ce580a0a47e51d271cae4b37836fcdb3320b Mon Sep 17 00:00:00 2001 From: Vignesh Viswanathan Date: Wed, 9 May 2018 20:38:39 +0530 Subject: [PATCH] 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 --- core/hdd/src/wlan_hdd_ioctl.c | 23 +++++++++++++++++++++++ core/sme/inc/sme_api.h | 14 ++++++++++++++ core/sme/src/common/sme_api.c | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 71 insertions(+) diff --git a/core/hdd/src/wlan_hdd_ioctl.c b/core/hdd/src/wlan_hdd_ioctl.c index c1d108dbdde5..a64b089f550f 100644 --- a/core/hdd/src/wlan_hdd_ioctl.c +++ b/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, diff --git a/core/sme/inc/sme_api.h b/core/sme/inc/sme_api.h index 60a1d013b55c..42bf4f0c81ad 100644 --- a/core/sme/inc/sme_api.h +++ b/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 ) */ diff --git a/core/sme/src/common/sme_api.c b/core/sme/src/common/sme_api.c index 0330f2cf9bd5..e15a482c337f 100644 --- a/core/sme/src/common/sme_api.c +++ b/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; +}