From 65ace7a19d5893669c3d5a436133d395ac78fb2f Mon Sep 17 00:00:00 2001 From: Chaithanya Garrepalli Date: Wed, 24 Nov 2021 19:01:00 +0530 Subject: [PATCH] qcacmn: fix use after free of hal_soc pointer In case of WIN hal_soc will be freed in wifi down path, this pointer is not valid at pdev_detach or soc_detach. Change to populate dmac source ring flag to dp_soc as access is needed at pdev_detach or soc_detach Change-Id: I628746bdd05ba3791d3d0e6b6dfdf160ed368e9a --- dp/wifi3.0/be/dp_be.c | 8 ++++---- dp/wifi3.0/dp_main.c | 10 ++++++---- dp/wifi3.0/dp_types.h | 5 ++++- wlan_cfg/wlan_cfg.h | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/dp/wifi3.0/be/dp_be.c b/dp/wifi3.0/be/dp_be.c index 499757849a..33886165e6 100644 --- a/dp/wifi3.0/be/dp_be.c +++ b/dp/wifi3.0/be/dp_be.c @@ -935,7 +935,7 @@ static void dp_soc_srng_deinit_be(struct dp_soc *soc) dp_soc_ppe_srng_deinit(soc); - if (hal_dmac_cmn_src_rxbuf_ring_get(soc->hal_soc)) { + if (soc->features.dmac_cmn_src_rxbuf_ring_enabled) { for (i = 0; i < soc->num_rx_refill_buf_rings; i++) { dp_srng_deinit(soc, &soc->rx_refill_buf_ring[i], RXDMA_BUF, 0); @@ -949,7 +949,7 @@ static void dp_soc_srng_free_be(struct dp_soc *soc) dp_soc_ppe_srng_free(soc); - if (hal_dmac_cmn_src_rxbuf_ring_get(soc->hal_soc)) { + if (soc->features.dmac_cmn_src_rxbuf_ring_enabled) { for (i = 0; i < soc->num_rx_refill_buf_rings; i++) dp_srng_free(soc, &soc->rx_refill_buf_ring[i]); } @@ -964,7 +964,7 @@ static QDF_STATUS dp_soc_srng_alloc_be(struct dp_soc *soc) soc_cfg_ctx = soc->wlan_cfg_ctx; ring_size = wlan_cfg_get_dp_soc_rxdma_refill_ring_size(soc_cfg_ctx); - if (hal_dmac_cmn_src_rxbuf_ring_get(soc->hal_soc)) { + if (soc->features.dmac_cmn_src_rxbuf_ring_enabled) { for (i = 0; i < soc->num_rx_refill_buf_rings; i++) { if (dp_srng_alloc(soc, &soc->rx_refill_buf_ring[i], RXDMA_BUF, ring_size, 0)) { @@ -991,7 +991,7 @@ static QDF_STATUS dp_soc_srng_init_be(struct dp_soc *soc) { int i = 0; - if (hal_dmac_cmn_src_rxbuf_ring_get(soc->hal_soc)) { + if (soc->features.dmac_cmn_src_rxbuf_ring_enabled) { for (i = 0; i < soc->num_rx_refill_buf_rings; i++) { if (dp_srng_init(soc, &soc->rx_refill_buf_ring[i], RXDMA_BUF, 0, 0)) { diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 40d5351b39..19caefe5be 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -12544,6 +12544,8 @@ dp_soc_attach(struct cdp_ctrl_objmgr_psoc *ctrl_psoc, &soc->rx_mon_pkt_tlv_size); soc->idle_link_bm_id = hal_get_idle_link_bm_id(soc->hal_soc, params->mlo_chip_id); + soc->features.dmac_cmn_src_rxbuf_ring_enabled = + hal_dmac_cmn_src_rxbuf_ring_get(soc->hal_soc); soc->arch_id = arch_id; soc->link_desc_id_start = dp_get_link_desc_id_start(soc->arch_id); @@ -13267,7 +13269,7 @@ static void dp_pdev_srng_deinit(struct dp_pdev *pdev) struct dp_soc *soc = pdev->soc; uint8_t i; - if (!hal_dmac_cmn_src_rxbuf_ring_get(soc->hal_soc)) + if (!soc->features.dmac_cmn_src_rxbuf_ring_enabled) dp_srng_deinit(soc, &soc->rx_refill_buf_ring[pdev->lmac_id], RXDMA_BUF, pdev->lmac_id); @@ -13308,7 +13310,7 @@ static QDF_STATUS dp_pdev_srng_init(struct dp_pdev *pdev) soc_cfg_ctx = soc->wlan_cfg_ctx; - if (!hal_dmac_cmn_src_rxbuf_ring_get(soc->hal_soc)) { + if (!soc->features.dmac_cmn_src_rxbuf_ring_enabled) { if (dp_srng_init(soc, &soc->rx_refill_buf_ring[pdev->lmac_id], RXDMA_BUF, 0, pdev->lmac_id)) { dp_init_err("%pK: dp_srng_init failed rx refill ring", @@ -13363,7 +13365,7 @@ static void dp_pdev_srng_free(struct dp_pdev *pdev) struct dp_soc *soc = pdev->soc; uint8_t i; - if (!hal_dmac_cmn_src_rxbuf_ring_get(soc->hal_soc)) + if (!soc->features.dmac_cmn_src_rxbuf_ring_enabled) dp_srng_free(soc, &soc->rx_refill_buf_ring[pdev->lmac_id]); if (!soc->rxdma2sw_rings_not_supported) { @@ -13394,7 +13396,7 @@ static QDF_STATUS dp_pdev_srng_alloc(struct dp_pdev *pdev) soc_cfg_ctx = soc->wlan_cfg_ctx; ring_size = wlan_cfg_get_dp_soc_rxdma_refill_ring_size(soc_cfg_ctx); - if (!hal_dmac_cmn_src_rxbuf_ring_get(soc->hal_soc)) { + if (!soc->features.dmac_cmn_src_rxbuf_ring_enabled) { if (dp_srng_alloc(soc, &soc->rx_refill_buf_ring[pdev->lmac_id], RXDMA_BUF, ring_size, 0)) { dp_init_err("%pK: dp_srng_alloc failed rx refill ring", diff --git a/dp/wifi3.0/dp_types.h b/dp/wifi3.0/dp_types.h index 285b802aa6..655cabfa06 100644 --- a/dp/wifi3.0/dp_types.h +++ b/dp/wifi3.0/dp_types.h @@ -1701,9 +1701,12 @@ struct dp_arch_ops { /** * struct dp_soc_features: Data structure holding the SOC level feature flags. * @pn_in_reo_dest: PN provided by hardware in the REO destination ring. + * @dmac_cmn_src_rxbuf_ring_enabled: Flag to indicate DMAC mode common Rx + * buffer source rings */ struct dp_soc_features { - uint8_t pn_in_reo_dest; + uint8_t pn_in_reo_dest:1, + dmac_cmn_src_rxbuf_ring_enabled:1; }; enum sysfs_printing_mode { diff --git a/wlan_cfg/wlan_cfg.h b/wlan_cfg/wlan_cfg.h index 34845f3be1..000fa6bc3b 100644 --- a/wlan_cfg/wlan_cfg.h +++ b/wlan_cfg/wlan_cfg.h @@ -1947,7 +1947,6 @@ wlan_cfg_get_rx_rel_ring_id(struct wlan_cfg_dp_soc_ctxt *cfg); void wlan_cfg_set_rx_rel_ring_id(struct wlan_cfg_dp_soc_ctxt *cfg, uint8_t wbm2sw_ring_id); -#endif #if defined(WLAN_FEATURE_11BE_MLO) && defined(WLAN_MLO_MULTI_CHIP) /** @@ -1983,3 +1982,4 @@ uint8_t wlan_cfg_mlo_lmac_peer_id_msb_get_by_chip_id(struct wlan_cfg_dp_soc_ctxt *cfg, uint8_t chip_id); #endif +#endif /*__WLAN_CFG_H*/