Sfoglia il codice sorgente

qcacmn: Avoid using freed pdev in dp_rx_bar_stats_cb

dp_reo_cmdlist_destroy frees any pending reo_cmds.
Each reo_cmd is associated with a handler which takes
reo_cmd->data as an input. This reo_cmd->data is a pdev
for dp_rx_bar_stats_cb. So validate pdev before
accessing it further.

Change-Id: I1c2d46d3e3f5ede4491500978153f501ebdeee87
CRs-Fixed: 2478910
Venkata Sharath Chandra Manchala 5 anni fa
parent
commit
2b8a2a0648
2 ha cambiato i file con 26 aggiunte e 0 eliminazioni
  1. 9 0
      dp/wifi3.0/dp_internal.h
  2. 17 0
      dp/wifi3.0/dp_main.c

+ 9 - 0
dp/wifi3.0/dp_internal.h

@@ -861,6 +861,15 @@ uint32_t dp_pdev_tid_stats_display(void *pdev_handle,
 			enum _ol_ath_param_t param, uint32_t value, void *buff);
 #endif
 
+/**
+ * dp_check_pdev_exists() - Validate pdev before use
+ * @soc - dp soc handle
+ * @data - pdev handle
+ *
+ * Return: 0 - success/invalid - failure
+ */
+bool dp_check_pdev_exists(struct dp_soc *soc, struct dp_pdev *data);
+
 /**
  * dp_update_delay_stats() - Update delay statistics in structure
  *                              and fill min, max and avg delay

+ 17 - 0
dp/wifi3.0/dp_main.c

@@ -6625,6 +6625,18 @@ void dp_peer_set_mesh_rx_filter(struct cdp_vdev *vdev_hdl, uint32_t val)
 }
 #endif
 
+bool dp_check_pdev_exists(struct dp_soc *soc, struct dp_pdev *data)
+{
+	uint8_t pdev_count;
+
+	for (pdev_count = 0; pdev_count < MAX_PDEV_CNT; pdev_count++) {
+		if (soc->pdev_list[pdev_count] &&
+		    soc->pdev_list[pdev_count] == data)
+			return true;
+	}
+	return false;
+}
+
 /**
  * dp_rx_bar_stats_cb(): BAR received stats callback
  * @soc: SOC handle
@@ -6639,6 +6651,11 @@ void dp_rx_bar_stats_cb(struct dp_soc *soc, void *cb_ctxt,
 	struct dp_pdev *pdev = (struct dp_pdev *)cb_ctxt;
 	struct hal_reo_queue_status *queue_status = &(reo_status->queue_status);
 
+	if (!dp_check_pdev_exists(soc, pdev)) {
+		dp_err_rl("pdev doesn't exist");
+		return;
+	}
+
 	if (!qdf_atomic_read(&soc->cmn_init_done))
 		return;