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
This commit is contained in:
Abhinav Kumar
2018-08-09 11:49:46 +05:30
committed by nshrivas
vanhempi 70ef8f4a4d
commit 0a8461343d
2 muutettua tiedostoa jossa 72 lisäystä ja 93 poistoa

Näytä tiedosto

@@ -464,15 +464,6 @@ static void wma_vdev_detach_callback(void *ctx)
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 @@ static QDF_STATUS wma_handle_vdev_detach(tp_wma_handle wma_handle,
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 @@ out:
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 @@ void wma_vdev_resp_timer(void *data)
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);

Näytä tiedosto

@@ -2942,6 +2942,76 @@ void wma_vdev_init(struct wma_txrx_node *vdev)
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 @@ QDF_STATUS wma_wmi_service_close(void)
{
void *cds_ctx;
tp_wma_handle wma_handle;
struct beacon_info *bcn;
int i;
WMA_LOGD("%s: Enter", __func__);
@@ -4493,74 +4562,6 @@ QDF_STATUS wma_wmi_service_close(void)
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]);
}