From 0d1159e96dc5d1a46f75d54adc11628e90ec2f98 Mon Sep 17 00:00:00 2001 From: Pragaspathi Thilagaraj Date: Wed, 8 Aug 2018 19:00:36 +0530 Subject: [PATCH] qcacld-3.0: Add vdev_active validation for wmi commands When the host sends a wmi command with invalid vdev id, firmware crashes. So to avoid this check the vdev_active flag for the vdev before sending the wmi command. This changeset validates the vdev_active check for the following commands: WMI_VDEV_CREATE_CMDID WMI_VDEV_DELETE_CMDID WMI_VDEV_START_REQUEST_CMDID WMI_VDEV_RESTART_REQUEST_CMDID WMI_VDEV_UP_CMDID WMI_VDEV_STOP_CMDID WMI_VDEV_DOWN_CMDID WMI_VDEV_SET_PARAM_CMDID WMI_VDEV_WMM_ADDTS_CMDID WMI_VDEV_WMM_DELTS_CMDID This change also removes the flag is_vdev_valid which seems to duplicate the vdev_active flag. Change-Id: If9d4a2b24f8141c26a73f3a012fa99d38b3221bc CRs Fixed: 2312360 --- core/wma/src/wma_dev_if.c | 1 - core/wma/src/wma_features.c | 18 ++++++++---------- core/wma/src/wma_mgmt.c | 6 ++++-- core/wma/src/wma_utils.c | 32 ++++++++++++++++++++++++++++---- 4 files changed, 40 insertions(+), 17 deletions(-) diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index 670584db4621..ef6614398dd0 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -588,7 +588,6 @@ static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle, goto out; } - status = wmi_unified_vdev_delete_send(wma_handle->wmi_handle, vdev_id); if (QDF_IS_STATUS_ERROR(status)) { WMA_LOGE("Unable to remove an interface"); diff --git a/core/wma/src/wma_features.c b/core/wma/src/wma_features.c index 6ac16afc0800..c0c35ad9b47d 100644 --- a/core/wma/src/wma_features.c +++ b/core/wma/src/wma_features.c @@ -3077,6 +3077,12 @@ int wma_pdev_resume_event_handler(void *handle, uint8_t *event, uint32_t len) */ void wma_del_ts_req(tp_wma_handle wma, tDelTsParams *msg) { + if (!wma_is_vdev_valid(msg->sessionId)) { + WMA_LOGE("%s: vdev id:%d is not active ", __func__, + msg->sessionId); + qdf_mem_free(msg); + return; + } if (wmi_unified_del_ts_cmd(wma->wmi_handle, msg->sessionId, TID_TO_WME_AC(msg->userPrio))) { @@ -4368,7 +4374,6 @@ QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma, { struct wma_txrx_node *interface; struct vdev_ie_info_param cmd = {0}; - int ret; if (!ie_info || !wma) { WMA_LOGE(FL("input pointer is NULL")); @@ -4381,17 +4386,12 @@ QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma, return QDF_STATUS_E_INVAL; } - if (ie_info->vdev_id >= wma->max_bssid) { - WMA_LOGE(FL("Invalid vdev_id: %d"), ie_info->vdev_id); - return QDF_STATUS_E_INVAL; - } - - interface = &wma->interfaces[ie_info->vdev_id]; if (!wma_is_vdev_valid(ie_info->vdev_id)) { WMA_LOGE(FL("vdev_id: %d is not active"), ie_info->vdev_id); return QDF_STATUS_E_INVAL; } + interface = &wma->interfaces[ie_info->vdev_id]; cmd.vdev_id = ie_info->vdev_id; cmd.ie_id = ie_info->ie_id; cmd.length = ie_info->length; @@ -4406,9 +4406,7 @@ QDF_STATUS wma_process_set_ie_info(tp_wma_handle wma, QDF_TRACE_HEX_DUMP(QDF_MODULE_ID_WMA, QDF_TRACE_LEVEL_DEBUG, ie_info->data, ie_info->length); - ret = wmi_unified_process_set_ie_info_cmd(wma->wmi_handle, - &cmd); - return ret; + return wmi_unified_process_set_ie_info_cmd(wma->wmi_handle, &cmd); } #ifdef FEATURE_WLAN_APF diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index bb22bf0dc5dd..4563c6c140cc 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -1831,8 +1831,10 @@ static QDF_STATUS wma_setup_install_key_cmd(tp_wma_handle wma_handle, key_params->vdev_id); return QDF_STATUS_E_INVAL; } - if (key_params->vdev_id >= wma_handle->max_bssid) { - WMA_LOGE(FL("Invalid vdev_id: %d"), key_params->vdev_id); + + if (!wma_is_vdev_valid(key_params->vdev_id)) { + WMA_LOGE("%s: vdev id:%d is not active ", __func__, + key_params->vdev_id); return QDF_STATUS_E_INVAL; } diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index e483553fee3c..fdea743c56df 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -2034,8 +2034,9 @@ QDF_STATUS wma_process_ll_stats_get_req(tp_wma_handle wma, return QDF_STATUS_E_FAILURE; } - if (!wma->interfaces[getReq->staId].vdev_active) { - WMA_LOGE("%s: vdev not created yet", __func__); + if (!wma_is_vdev_valid(getReq->staId)) { + WMA_LOGE("%s: vdev:%d not created yet", __func__, + getReq->staId); return QDF_STATUS_E_FAILURE; } @@ -4379,6 +4380,11 @@ wma_send_vdev_start_to_fw(t_wma_handle *wma, struct vdev_start_params *params) QDF_STATUS status; struct wma_txrx_node *vdev = &wma->interfaces[params->vdev_id]; + if (!wma_is_vdev_valid(params->vdev_id)) { + WMA_LOGE("%s: Invalid vdev id:%d", __func__, params->vdev_id); + status = QDF_STATUS_E_FAILURE; + return status; + } wma_acquire_wakelock(&vdev->vdev_start_wakelock, WMA_VDEV_START_REQUEST_TIMEOUT); status = wmi_unified_vdev_start_send(wma->wmi_handle, params); @@ -4393,6 +4399,11 @@ QDF_STATUS wma_send_vdev_stop_to_fw(t_wma_handle *wma, uint8_t vdev_id) QDF_STATUS status; struct wma_txrx_node *vdev = &wma->interfaces[vdev_id]; + if (!wma_is_vdev_valid(vdev_id)) { + WMA_LOGE("%s: Invalid vdev id:%d", __func__, vdev_id); + status = QDF_STATUS_E_FAILURE; + return status; + } wma_acquire_wakelock(&vdev->vdev_stop_wakelock, WMA_VDEV_STOP_REQUEST_TIMEOUT); status = wmi_unified_vdev_stop_send(wma->wmi_handle, vdev_id); @@ -4500,13 +4511,20 @@ QDF_STATUS wma_send_vdev_up_to_fw(t_wma_handle *wma, uint8_t bssid[IEEE80211_ADDR_LEN]) { QDF_STATUS status; - struct wma_txrx_node *vdev = &wma->interfaces[params->vdev_id]; + struct wma_txrx_node *vdev; + + if (!wma_is_vdev_valid(params->vdev_id)) { + WMA_LOGE("%s: Invalid vdev id:%d", __func__, params->vdev_id); + return QDF_STATUS_E_FAILURE; + } if (wma_is_vdev_up(params->vdev_id)) { WMA_LOGD("vdev %d is already up for bssid %pM. Do not send", params->vdev_id, bssid); return QDF_STATUS_SUCCESS; } + + vdev = &wma->interfaces[params->vdev_id]; status = wmi_unified_vdev_up_send(wma->wmi_handle, bssid, params); wma_release_wakelock(&vdev->vdev_start_wakelock); @@ -4516,8 +4534,14 @@ QDF_STATUS wma_send_vdev_up_to_fw(t_wma_handle *wma, QDF_STATUS wma_send_vdev_down_to_fw(t_wma_handle *wma, uint8_t vdev_id) { QDF_STATUS status; - struct wma_txrx_node *vdev = &wma->interfaces[vdev_id]; + struct wma_txrx_node *vdev; + if (!wma_is_vdev_valid(vdev_id)) { + WMA_LOGE("%s: Invalid vdev id:%d", __func__, vdev_id); + return QDF_STATUS_E_FAILURE; + } + + vdev = &wma->interfaces[vdev_id]; wma->interfaces[vdev_id].roaming_in_progress = false; status = wmi_unified_vdev_down_send(wma->wmi_handle, vdev_id); wma_release_wakelock(&vdev->vdev_start_wakelock);