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
diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c
index 670584d..ef66143 100644
--- a/core/wma/src/wma_dev_if.c
+++ b/core/wma/src/wma_dev_if.c
@@ -588,7 +588,6 @@
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 6ac16af..c0c35ad 100644
--- a/core/wma/src/wma_features.c
+++ b/core/wma/src/wma_features.c
@@ -3077,6 +3077,12 @@
*/
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 @@
{
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 @@
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_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 bb22bf0..4563c6c 100644
--- a/core/wma/src/wma_mgmt.c
+++ b/core/wma/src/wma_mgmt.c
@@ -1831,8 +1831,10 @@
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 e483553..fdea743 100644
--- a/core/wma/src/wma_utils.c
+++ b/core/wma/src/wma_utils.c
@@ -2034,8 +2034,9 @@
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 @@
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 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 @@
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_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);