From 497573091a39897cfe3952feb28b99f3728ba303 Mon Sep 17 00:00:00 2001 From: phadiman Date: Tue, 18 Dec 2018 16:13:59 +0530 Subject: [PATCH] qcacmn: Add Sanity Checks Stats are updated periodically and are categorized to soc, pdev, and vdev While the stats are getting updated and if pdev, or vdev gets detached in the same time, the stats handlers will deference a NULL pointer Hence Add basic sanity checks to DP layer for soc, pdev and vdev inside stat handlers Change-Id: Ic4919b9c205679e1d6e7c571c577339be65c1bad --- dp/wifi3.0/dp_main.c | 11 +++++++++-- dp/wifi3.0/dp_rx.c | 3 +++ dp/wifi3.0/dp_rx_mon_status.c | 3 ++- dp/wifi3.0/dp_tx.c | 8 ++++++-- 4 files changed, 20 insertions(+), 5 deletions(-) diff --git a/dp/wifi3.0/dp_main.c b/dp/wifi3.0/dp_main.c index 265188ec18..56d689987e 100644 --- a/dp/wifi3.0/dp_main.c +++ b/dp/wifi3.0/dp_main.c @@ -5980,6 +5980,9 @@ void dp_aggregate_vdev_stats(struct dp_vdev *vdev, soc = vdev->pdev->soc; + if (!vdev) + return; + qdf_mem_copy(vdev_stats, &vdev->stats, sizeof(vdev->stats)); qdf_spin_lock_bh(&soc->peer_ref_mutex); @@ -5988,11 +5991,13 @@ void dp_aggregate_vdev_stats(struct dp_vdev *vdev, qdf_spin_unlock_bh(&soc->peer_ref_mutex); #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE + if (!vdev->pdev) + return; + dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, vdev->pdev->soc, vdev_stats, vdev->vdev_id, UPDATE_VDEV_STATS, vdev->pdev->pdev_id); #endif - } /** @@ -6078,7 +6083,6 @@ static inline void dp_aggregate_pdev_stats(struct dp_pdev *pdev) dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, pdev->soc, &pdev->stats, pdev->pdev_id, UPDATE_PDEV_STATS, pdev->pdev_id); #endif - } /** @@ -6696,6 +6700,9 @@ dp_txrx_host_stats_clr(struct dp_vdev *vdev) { struct dp_peer *peer = NULL; + if (!vdev || !vdev->pdev) + return; + DP_STATS_CLR(vdev->pdev); DP_STATS_CLR(vdev->pdev->soc); DP_STATS_CLR(vdev); diff --git a/dp/wifi3.0/dp_rx.c b/dp/wifi3.0/dp_rx.c index 03b0995b2b..917f50b663 100644 --- a/dp/wifi3.0/dp_rx.c +++ b/dp/wifi3.0/dp_rx.c @@ -1225,6 +1225,9 @@ static void dp_rx_msdu_stats_update(struct dp_soc *soc, if ((soc->process_rx_status) && hal_rx_attn_first_mpdu_get(rx_tlv_hdr)) { #if defined(FEATURE_PERPKT_INFO) && WDI_EVENT_ENABLE + if (!vdev->pdev) + return; + dp_wdi_event_handler(WDI_EVENT_UPDATE_DP_STATS, vdev->pdev->soc, &peer->stats, peer_id, UPDATE_PEER_STATS, diff --git a/dp/wifi3.0/dp_rx_mon_status.c b/dp/wifi3.0/dp_rx_mon_status.c index aeb4e6ef31..8899b8c019 100644 --- a/dp/wifi3.0/dp_rx_mon_status.c +++ b/dp/wifi3.0/dp_rx_mon_status.c @@ -93,7 +93,7 @@ dp_rx_populate_cdp_indication_ppdu(struct dp_pdev *pdev, cdp_rx_ppdu->lsig_a = ppdu_info->rx_status.rate; ast_index = ppdu_info->rx_status.ast_index; - if (ast_index > (WLAN_UMAC_PSOC_MAX_PEERS * 2)) { + if (ast_index >= (WLAN_UMAC_PSOC_MAX_PEERS * 2)) { cdp_rx_ppdu->peer_id = HTT_INVALID_PEER; return; } @@ -528,6 +528,7 @@ dp_rx_mon_status_process_tlv(struct dp_soc *soc, uint32_t mac_id, while (!qdf_nbuf_is_queue_empty(&pdev->rx_status_q)) { status_nbuf = qdf_nbuf_queue_remove(&pdev->rx_status_q); + rx_tlv = qdf_nbuf_data(status_nbuf); rx_tlv_start = rx_tlv; diff --git a/dp/wifi3.0/dp_tx.c b/dp/wifi3.0/dp_tx.c index d63840e407..4ba97d0bcf 100644 --- a/dp/wifi3.0/dp_tx.c +++ b/dp/wifi3.0/dp_tx.c @@ -2636,9 +2636,14 @@ dp_tx_update_peer_stats(struct dp_peer *peer, struct hal_tx_completion_status *ts, uint32_t length) { struct dp_pdev *pdev = peer->vdev->pdev; - struct dp_soc *soc = pdev->soc; + struct dp_soc *soc = NULL; uint8_t mcs, pkt_type; + if (!pdev) + return; + + soc = pdev->soc; + mcs = ts->mcs; pkt_type = ts->pkt_type; @@ -2718,7 +2723,6 @@ dp_tx_update_peer_stats(struct dp_peer *peer, &peer->stats, ts->peer_id, UPDATE_PEER_STATS, pdev->pdev_id); #endif - } #ifdef QCA_LL_TX_FLOW_CONTROL_V2