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
This commit is contained in:
Pragaspathi Thilagaraj 2018-08-08 19:00:36 +05:30 committed by nshrivas
parent b0c53a848e
commit 0d1159e96d
4 changed files with 40 additions and 17 deletions

View File

@ -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");

View File

@ -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

View File

@ -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;
}

View File

@ -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);