From 24cff9e863ff726452e7661925bfcdcd72bda5c0 Mon Sep 17 00:00:00 2001 From: Abhishek Ambure Date: Tue, 1 Oct 2019 12:09:55 +0530 Subject: [PATCH] qcacld-3.0: Add VDEV null check before calling wlan_vdev_get_dp_handle On passing vdev as argument to "wlan_vdev_get_dp_handle", it returns "dp_handle". "wlan_vdev_get_dp_handle" has BUG_ON check for NULL vdev, so VDEV NULL check is added before calling "wlan_vdev_get_dp_handle". Change-Id: I68ffab078fb35d47e1e771215de610290455b7d7 CRs-Fixed: 2538435 --- core/wma/inc/wma.h | 34 ++++++++++++++-------------------- core/wma/inc/wma_internal.h | 3 +++ core/wma/src/wma_data.c | 16 ++++++++++++++++ core/wma/src/wma_dev_if.c | 20 +++++++++++++++++++- core/wma/src/wma_mgmt.c | 10 ++++++++++ core/wma/src/wma_power.c | 9 +++++++++ core/wma/src/wma_utils.c | 6 ++++++ 7 files changed, 77 insertions(+), 21 deletions(-) diff --git a/core/wma/inc/wma.h b/core/wma/inc/wma.h index 3232404f859e..f81769fcd588 100644 --- a/core/wma/inc/wma.h +++ b/core/wma/inc/wma.h @@ -1891,9 +1891,8 @@ void wma_vdev_update_pause_bitmap(uint8_t vdev_id, uint16_t value) iface = &wma->interfaces[vdev_id]; - if (!iface) { - WMA_LOGE("%s: Failed to get iface: NULL", - __func__); + if (!iface || !iface->vdev) { + WMA_LOGE("%s: Vdev is NULL", __func__); return; } @@ -1925,9 +1924,8 @@ uint16_t wma_vdev_get_pause_bitmap(uint8_t vdev_id) iface = &wma->interfaces[vdev_id]; - if (!iface) { - WMA_LOGE("%s: Failed to get iface: NULL", - __func__); + if (!iface || !iface->vdev) { + WMA_LOGE("%s: Vdev is NULL", __func__); return 0; } @@ -1962,9 +1960,8 @@ struct cdp_vdev *wma_vdev_get_vdev_dp_handle(uint8_t vdev_id) iface = &wma->interfaces[vdev_id]; - if (!iface) { - WMA_LOGE("%s: Failed to get iface: NULL", - __func__); + if (!iface || !iface->vdev) { + WMA_LOGE("%s: Vdev is NULL", __func__); return NULL; } @@ -1989,9 +1986,8 @@ static inline bool wma_vdev_is_device_in_low_pwr_mode(uint8_t vdev_id) iface = &wma->interfaces[vdev_id]; - if (!iface) { - WMA_LOGE("%s: Failed to get iface: NULL", - __func__); + if (!iface || !iface->vdev) { + WMA_LOGE("%s: Vdev is NULL", __func__); return 0; } @@ -2027,7 +2023,7 @@ QDF_STATUS wma_vdev_get_dtim_period(uint8_t vdev_id, uint8_t *value) iface = &wma->interfaces[vdev_id]; - if (!iface || !wlan_vdev_get_dp_handle(iface->vdev)) + if (!iface || !iface->vdev || !wlan_vdev_get_dp_handle(iface->vdev)) return QDF_STATUS_E_FAILURE; *value = iface->dtimPeriod; @@ -2057,7 +2053,7 @@ QDF_STATUS wma_vdev_get_beacon_interval(uint8_t vdev_id, uint16_t *value) iface = &wma->interfaces[vdev_id]; - if (!iface || !wlan_vdev_get_dp_handle(iface->vdev)) + if (!iface || !iface->vdev || !wlan_vdev_get_dp_handle(iface->vdev)) return QDF_STATUS_E_FAILURE; *value = iface->beaconInterval; @@ -2114,9 +2110,8 @@ void wma_vdev_set_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos) iface = &wma->interfaces[vdev_id]; - if (!iface) { - WMA_LOGE("%s: Failed to get iface: NULL", - __func__); + if (!iface || !iface->vdev) { + WMA_LOGE("%s: Vdev is NULL", __func__); return; } @@ -2149,9 +2144,8 @@ void wma_vdev_clear_pause_bit(uint8_t vdev_id, wmi_tx_pause_type bit_pos) iface = &wma->interfaces[vdev_id]; - if (!iface) { - WMA_LOGE("%s: Failed to get iface: NULL", - __func__); + if (!iface || !iface->vdev) { + WMA_LOGE("%s: Vdev is NULL", __func__); return; } diff --git a/core/wma/inc/wma_internal.h b/core/wma/inc/wma_internal.h index 14f9d76921bc..c1315bc80bfd 100644 --- a/core/wma/inc/wma_internal.h +++ b/core/wma/inc/wma_internal.h @@ -541,6 +541,9 @@ struct cdp_vdev *wma_find_vdev_by_id(tp_wma_handle wma, uint8_t vdev_id) if (vdev_id >= wma->max_bssid) return NULL; + if (!wma->interfaces[vdev_id].vdev) + return NULL; + return wlan_vdev_get_dp_handle(wma->interfaces[vdev_id].vdev); } diff --git a/core/wma/src/wma_data.c b/core/wma/src/wma_data.c index 7b9571436683..edb725ffdafe 100644 --- a/core/wma/src/wma_data.c +++ b/core/wma/src/wma_data.c @@ -1444,6 +1444,13 @@ int wma_mcc_vdev_tx_pause_evt_handler(void *handle, uint8_t *event, if (!(vdev_map & 0x1)) { /* No Vdev */ } else { + if (!wma->interfaces[vdev_id].vdev) { + WMA_LOGE("%s: vdev is NULL for %d", __func__, + vdev_id); + /* Test Next VDEV */ + vdev_map >>= 1; + continue; + } dp_handle = wlan_vdev_get_dp_handle (wma->interfaces[vdev_id].vdev); if (!dp_handle) { @@ -2386,6 +2393,11 @@ QDF_STATUS wma_tx_packet(void *wma_context, void *tx_frame, uint16_t frmLen, return QDF_STATUS_E_FAILURE; } iface = &wma_handle->interfaces[vdev_id]; + if (!iface->vdev) { + WMA_LOGE("iface->vdev is NULL"); + cds_packet_free((void *)tx_frame); + return QDF_STATUS_E_FAILURE; + } /* Get the vdev handle from vdev id */ txrx_vdev = wlan_vdev_get_dp_handle(iface->vdev); @@ -3016,6 +3028,10 @@ void wma_tx_abort(uint8_t vdev_id) return; iface = &wma->interfaces[vdev_id]; + if (!iface->vdev) { + WMA_LOGE("%s: iface->vdev is NULL", __func__); + return; + } handle = wlan_vdev_get_dp_handle(iface->vdev); if (!handle) { WMA_LOGE("%s: Failed to get iface handle: %pK", diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c index d235f31aa475..6faaa00fdc51 100644 --- a/core/wma/src/wma_dev_if.c +++ b/core/wma/src/wma_dev_if.c @@ -793,6 +793,11 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle, struct wma_txrx_node *iface = &wma_handle->interfaces[vdev_id]; uint32_t vdev_stop_type; + if (!iface->vdev) { + WMA_LOGE("vdev %d is NULL", vdev_id); + goto send_rsp; + } + if (!wlan_vdev_get_dp_handle(iface->vdev)) { WMA_LOGE("handle of vdev_id %d is NULL vdev is already freed", vdev_id); @@ -2087,6 +2092,14 @@ void wma_send_del_bss_response(tp_wma_handle wma, struct del_bss_resp *resp) vdev_id = resp->vdev_id; iface = &wma->interfaces[vdev_id]; + + if (!iface->vdev) { + WMA_LOGE("%s vdev id %d iface->vdev is NULL", + __func__, vdev_id); + if (resp) + qdf_mem_free(resp); + return; + } handle = wlan_vdev_get_dp_handle(iface->vdev); if (!handle) { WMA_LOGE("%s vdev id %d is already deleted", @@ -4849,6 +4862,11 @@ void wma_delete_bss_ho_fail(tp_wma_handle wma, uint8_t vdev_id) } iface = &wma->interfaces[vdev_id]; + if (!iface->vdev) { + WMA_LOGE("%s: vdev is NULL for vdev_%d", __func__, vdev_id); + goto fail_del_bss_ho_fail; + } + handle = wlan_vdev_get_dp_handle(iface->vdev); if (!iface || !handle) { WMA_LOGE("%s vdev id %d is already deleted", @@ -4993,7 +5011,7 @@ void wma_delete_bss(tp_wma_handle wma, uint8_t vdev_id) } iface = &wma->interfaces[vdev_id]; - if (!iface || !wlan_vdev_get_dp_handle(iface->vdev)) { + if (!iface || !iface->vdev || !wlan_vdev_get_dp_handle(iface->vdev)) { WMA_LOGE("%s vdev id %d is already deleted", __func__, vdev_id); goto out; diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 55d641b25162..c10047368c23 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -546,6 +546,11 @@ int wma_unified_bcntx_status_event_handler(void *handle, /* Check for valid handle to ensure session is not * deleted in any race */ + if (!wma->interfaces[resp_event->vdev_id].vdev) { + WMA_LOGE("%s: vdev is NULL for vdev_%d", + __func__, resp_event->vdev_id); + return -EINVAL; + } dp_handle = wlan_vdev_get_dp_handle (wma->interfaces[resp_event->vdev_id].vdev); if (!dp_handle) { @@ -4730,6 +4735,11 @@ QDF_STATUS wma_mgmt_unified_cmd_send(struct wlan_objmgr_vdev *vdev, return QDF_STATUS_E_INVAL; } + if (!wma_handle->interfaces[mgmt_params->vdev_id].vdev) { + WMA_LOGE("%s: vdev is NULL for vdev_%d", + __func__, mgmt_params->vdev_id); + return QDF_STATUS_E_INVAL; + } txrx_vdev = wlan_vdev_get_dp_handle (wma_handle->interfaces[mgmt_params->vdev_id].vdev); diff --git a/core/wma/src/wma_power.c b/core/wma/src/wma_power.c index f0ed485e8d5c..f1820678660c 100644 --- a/core/wma/src/wma_power.c +++ b/core/wma/src/wma_power.c @@ -721,6 +721,11 @@ void wma_enable_sta_ps_mode(tp_wma_handle wma, tpEnablePsParams ps_req) enum powersave_qpower_mode qpower_config = wma_get_qpower_config(wma); struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; + if (!iface->vdev) { + WMA_LOGE("%s: vdev is NULL for vdev_%d", __func__, vdev_id); + return; + } + if (!wlan_vdev_get_dp_handle(iface->vdev)) { WMA_LOGE("vdev id %d is not active", vdev_id); return; @@ -864,6 +869,10 @@ void wma_enable_uapsd_mode(tp_wma_handle wma, tpEnableUapsdParams ps_req) enum powersave_qpower_mode qpower_config = wma_get_qpower_config(wma); struct wma_txrx_node *iface = &wma->interfaces[vdev_id]; + if (!iface->vdev) { + WMA_LOGE("%s: vdev is NULL for vdev_%d", __func__, vdev_id); + return; + } if (!wlan_vdev_get_dp_handle(iface->vdev)) { WMA_LOGE("vdev id %d is not active", vdev_id); return; diff --git a/core/wma/src/wma_utils.c b/core/wma/src/wma_utils.c index 4f4e3c355074..c991d8e40462 100644 --- a/core/wma/src/wma_utils.c +++ b/core/wma/src/wma_utils.c @@ -1987,6 +1987,12 @@ QDF_STATUS wma_process_ll_stats_clear_req(tp_wma_handle wma, } vdev = wma->interfaces[clearReq->staId].vdev; + if (!vdev) { + WMA_LOGE("%s: vdev is NULL for vdev_%d", + __func__, clearReq->staId); + return QDF_STATUS_E_FAILURE; + } + if (!wlan_vdev_get_dp_handle(vdev)) { WMA_LOGE("%s: vdev_id %d handle is NULL", __func__, clearReq->staId);