qcacld-3.0: Possible mem leak while handling WMA_DEL_STA_SELF_REQ
In wma_vdev_resp_timer(), while handling WMA_DEL_STA_SELF_REQ if
wma_crash_on_fw_timeout() is true, then wma_vdev_resp_timer initiate
SSR and memset iface structure without freeing iface->del_staself_req.
This results mem leak in wma_vdev_resp_timer().
Free all the dynamic memory from iface structure in wma_vdev_deinit()
instead of handling them separately.
Change-Id: I7b16ddc9dfb70638c6f895bd97cd9c106bfad595
CRs-Fixed: 2293099
diff --git a/core/wma/src/wma_dev_if.c b/core/wma/src/wma_dev_if.c
index 7cf2cb8..d3e54ef 100644
--- a/core/wma/src/wma_dev_if.c
+++ b/core/wma/src/wma_dev_if.c
@@ -464,15 +464,6 @@
qdf_mem_free(req_msg);
}
}
- if (iface->addBssStaContext)
- qdf_mem_free(iface->addBssStaContext);
-
-
- if (iface->staKeyParams)
- qdf_mem_free(iface->staKeyParams);
-
- if (iface->stats_rsp)
- qdf_mem_free(iface->stats_rsp);
wma_vdev_deinit(iface);
qdf_mem_zero(iface, sizeof(*iface));
@@ -607,6 +598,7 @@
WMA_LOGE("%s: Failed to fill vdev request for vdev_id %d",
__func__, vdev_id);
status = QDF_STATUS_E_NOMEM;
+ iface->del_staself_req = NULL;
goto out;
}
@@ -632,11 +624,6 @@
vdev_id, generate_rsp);
wma_cdp_vdev_detach(soc, wma_handle, vdev_id);
- if (iface->addBssStaContext)
- qdf_mem_free(iface->addBssStaContext);
- if (iface->staKeyParams)
- qdf_mem_free(iface->staKeyParams);
-
wma_vdev_deinit(iface);
qdf_mem_zero(iface, sizeof(*iface));
wma_vdev_init(iface);
@@ -3656,16 +3643,7 @@
iface->del_staself_req = NULL;
} else {
wma_send_del_sta_self_resp(iface->del_staself_req);
- }
-
- if (iface->addBssStaContext) {
- qdf_mem_free(iface->addBssStaContext);
- iface->addBssStaContext = NULL;
- }
-
- if (iface->staKeyParams) {
- qdf_mem_free(iface->staKeyParams);
- iface->staKeyParams = NULL;
+ iface->del_staself_req = NULL;
}
wma_vdev_deinit(iface);
diff --git a/core/wma/src/wma_main.c b/core/wma/src/wma_main.c
index 9cacab5..cedc06e 100644
--- a/core/wma/src/wma_main.c
+++ b/core/wma/src/wma_main.c
@@ -2942,6 +2942,76 @@
void wma_vdev_deinit(struct wma_txrx_node *vdev)
{
+ struct beacon_info *bcn;
+ tp_wma_handle wma_handle;
+
+ wma_handle = cds_get_context(QDF_MODULE_ID_WMA);
+ /* validate the wma_handle */
+ if (!wma_handle) {
+ WMA_LOGE("%s: Invalid wma handle", __func__);
+ return;
+ }
+
+ bcn = vdev->beacon;
+ if (bcn) {
+ if (bcn->dma_mapped)
+ qdf_nbuf_unmap_single(wma_handle->qdf_dev,
+ bcn->buf, QDF_DMA_TO_DEVICE);
+ qdf_nbuf_free(bcn->buf);
+ qdf_mem_free(bcn);
+ vdev->beacon = NULL;
+ }
+
+ if (vdev->handle) {
+ qdf_mem_free(vdev->handle);
+ vdev->handle = NULL;
+ }
+
+ if (vdev->addBssStaContext) {
+ qdf_mem_free(vdev->addBssStaContext);
+ vdev->addBssStaContext = NULL;
+ }
+
+ if (vdev->staKeyParams) {
+ qdf_mem_free(vdev->staKeyParams);
+ vdev->staKeyParams = NULL;
+ }
+
+ if (vdev->del_staself_req) {
+ qdf_mem_free(vdev->del_staself_req);
+ vdev->del_staself_req = NULL;
+ }
+
+ if (vdev->stats_rsp) {
+ qdf_mem_free(vdev->stats_rsp);
+ vdev->stats_rsp = NULL;
+ }
+
+ if (vdev->psnr_req) {
+ qdf_mem_free(vdev->psnr_req);
+ vdev->psnr_req = NULL;
+ }
+
+ if (vdev->rcpi_req) {
+ qdf_mem_free(vdev->rcpi_req);
+ vdev->rcpi_req = NULL;
+ }
+
+ if (vdev->roam_synch_frame_ind.bcn_probe_rsp) {
+ qdf_mem_free(vdev->roam_synch_frame_ind.bcn_probe_rsp);
+ vdev->roam_synch_frame_ind.bcn_probe_rsp = NULL;
+ }
+
+ if (vdev->roam_synch_frame_ind.reassoc_req) {
+ qdf_mem_free(vdev->roam_synch_frame_ind.reassoc_req);
+ vdev->roam_synch_frame_ind.reassoc_req = NULL;
+ }
+
+ if (vdev->roam_synch_frame_ind.reassoc_rsp) {
+ qdf_mem_free(vdev->roam_synch_frame_ind.reassoc_rsp);
+ vdev->roam_synch_frame_ind.reassoc_rsp = NULL;
+ }
+
qdf_wake_lock_destroy(&vdev->vdev_start_wakelock);
qdf_wake_lock_destroy(&vdev->vdev_stop_wakelock);
qdf_wake_lock_destroy(&vdev->vdev_set_key_wakelock);
@@ -4462,7 +4532,6 @@
{
void *cds_ctx;
tp_wma_handle wma_handle;
- struct beacon_info *bcn;
int i;
WMA_LOGD("%s: Enter", __func__);
@@ -4493,74 +4562,6 @@
wma_handle->wmi_handle = NULL;
for (i = 0; i < wma_handle->max_bssid; i++) {
- bcn = wma_handle->interfaces[i].beacon;
-
- if (bcn) {
- if (bcn->dma_mapped)
- qdf_nbuf_unmap_single(wma_handle->qdf_dev,
- bcn->buf, QDF_DMA_TO_DEVICE);
- qdf_nbuf_free(bcn->buf);
- qdf_mem_free(bcn);
- wma_handle->interfaces[i].beacon = NULL;
- }
-
- if (wma_handle->interfaces[i].handle) {
- qdf_mem_free(wma_handle->interfaces[i].handle);
- wma_handle->interfaces[i].handle = NULL;
- }
-
- if (wma_handle->interfaces[i].addBssStaContext) {
- qdf_mem_free(wma_handle->
- interfaces[i].addBssStaContext);
- wma_handle->interfaces[i].addBssStaContext = NULL;
- }
-
- if (wma_handle->interfaces[i].del_staself_req) {
- qdf_mem_free(wma_handle->interfaces[i].del_staself_req);
- wma_handle->interfaces[i].del_staself_req = NULL;
- }
-
- if (wma_handle->interfaces[i].stats_rsp) {
- qdf_mem_free(wma_handle->interfaces[i].stats_rsp);
- wma_handle->interfaces[i].stats_rsp = NULL;
- }
-
- if (wma_handle->interfaces[i].psnr_req) {
- qdf_mem_free(wma_handle->
- interfaces[i].psnr_req);
- wma_handle->interfaces[i].psnr_req = NULL;
- }
-
- if (wma_handle->interfaces[i].rcpi_req) {
- qdf_mem_free(wma_handle->
- interfaces[i].rcpi_req);
- wma_handle->interfaces[i].rcpi_req = NULL;
- }
-
- if (wma_handle->interfaces[i].roam_synch_frame_ind.
- bcn_probe_rsp) {
- qdf_mem_free(wma_handle->interfaces[i].
- roam_synch_frame_ind.bcn_probe_rsp);
- wma_handle->interfaces[i].roam_synch_frame_ind.
- bcn_probe_rsp = NULL;
- }
-
- if (wma_handle->interfaces[i].roam_synch_frame_ind.
- reassoc_req) {
- qdf_mem_free(wma_handle->interfaces[i].
- roam_synch_frame_ind.reassoc_req);
- wma_handle->interfaces[i].roam_synch_frame_ind.
- reassoc_req = NULL;
- }
-
- if (wma_handle->interfaces[i].roam_synch_frame_ind.
- reassoc_rsp) {
- qdf_mem_free(wma_handle->interfaces[i].
- roam_synch_frame_ind.reassoc_rsp);
- wma_handle->interfaces[i].roam_synch_frame_ind.
- reassoc_rsp = NULL;
- }
-
wma_vdev_deinit(&wma_handle->interfaces[i]);
}