Pārlūkot izejas kodu

qcacld-3.0: Fix double free del_sta_session_req

iface->del_staself_req is used to check if del sta self was defered
and if it is set vdev detatch is called. iface->del_staself_req is
also set in case  del sta self was not defered and thus del sta self
resp may get called twice, assuming it was differed and this result
in double free of del_sta_session_req.

To fix this added a bool to check if the del sta self was defered.

Change-Id: If4c2bc2a5bb6b8761f4130119a96602055d45b77
CRs-Fixed: 2116888
Abhishek Singh 7 gadi atpakaļ
vecāks
revīzija
0d74f9e664
2 mainītis faili ar 7 papildinājumiem un 2 dzēšanām
  1. 1 0
      core/wma/inc/wma.h
  2. 6 2
      core/wma/src/wma_dev_if.c

+ 1 - 0
core/wma/inc/wma.h

@@ -1080,6 +1080,7 @@ struct wma_txrx_node {
 	tAniGetPEStatsRsp *stats_rsp;
 	uint8_t fw_stats_set;
 	void *del_staself_req;
+	bool is_del_sta_defered;
 	qdf_atomic_t bss_status;
 	uint8_t rate_flags;
 	uint8_t nss;

+ 6 - 2
core/wma/src/wma_dev_if.c

@@ -659,8 +659,10 @@ QDF_STATUS wma_vdev_detach(tp_wma_handle wma_handle,
 		WMA_LOGA("BSS is not yet stopped. Defering vdev(vdev id %x) deletion",
 			vdev_id);
 		iface->del_staself_req = pdel_sta_self_req_param;
+		iface->is_del_sta_defered = true;
 		return status;
 	}
+	iface->is_del_sta_defered = false;
 
 	if (!iface->handle) {
 		WMA_LOGE("handle of vdev_id %d is NULL vdev is already freed",
@@ -1732,7 +1734,8 @@ wma_send_del_bss_response(tp_wma_handle wma, struct wma_target_req *req,
 					   (void *)params, 0);
 	}
 
-	if (iface->del_staself_req != NULL) {
+	if (iface->del_staself_req && iface->is_del_sta_defered) {
+		iface->is_del_sta_defered = false;
 		WMA_LOGA("scheduling defered deletion (vdev id %x)",
 			 vdev_id);
 		wma_vdev_detach(wma, iface->del_staself_req, 1);
@@ -3074,7 +3077,8 @@ void wma_vdev_resp_timer(void *data)
 		WMA_LOGA("%s: WMA_DELETE_BSS_REQ timedout", __func__);
 		wma_send_msg_high_priority(wma, WMA_DELETE_BSS_RSP,
 					   (void *)params, 0);
-		if (iface->del_staself_req) {
+		if (iface->del_staself_req && iface->is_del_sta_defered) {
+			iface->is_del_sta_defered = false;
 			WMA_LOGA("scheduling defered deletion(vdev id %x)",
 				 tgt_req->vdev_id);
 			wma_vdev_detach(wma, iface->del_staself_req, 1);