From 9a6c2733cdc184bb282805ef8c8be058603d9827 Mon Sep 17 00:00:00 2001 From: Amit Mehta Date: Thu, 29 Jul 2021 17:36:24 +0530 Subject: [PATCH] qcacmn: Acquire lock while accessing rx tid in rx defrag store fragment Currently, we are Flushing fragments for peer as part of rx defrag clean up. There is the possibility that frag flush is called while we are accessing frags in rx defrag store fragment path in parallel. Which will cause access after the free issue. Adding lock in rx defrag store fragment path to avoid any parallel flush while accessing the frags. Change-Id: Ic27caab58429d776449f4b774eb7163ffa6215ac CRs-Fixed: 2995156 --- dp/wifi3.0/dp_rx_defrag.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dp/wifi3.0/dp_rx_defrag.c b/dp/wifi3.0/dp_rx_defrag.c index fa469baf667f..eb8fd5a2c3df 100644 --- a/dp/wifi3.0/dp_rx_defrag.c +++ b/dp/wifi3.0/dp_rx_defrag.c @@ -1483,6 +1483,9 @@ static QDF_STATUS dp_rx_defrag(struct dp_peer *peer, unsigned tid, struct dp_soc *soc = vdev->pdev->soc; uint8_t status = 0; + if (!cur) + return QDF_STATUS_E_DEFRAG_ERROR; + hdr_space = dp_rx_defrag_hdrsize(soc, cur); index = hal_rx_msdu_is_wlan_mcast(cur) ? dp_sec_mcast : dp_sec_ucast; @@ -1853,9 +1856,11 @@ dp_rx_defrag_store_fragment(struct dp_soc *soc, * If the earlier sequence was dropped, this will be the fresh start. * Else, continue with next fragment in a given sequence */ + qdf_spin_lock_bh(&rx_tid->tid_lock); status = dp_rx_defrag_fraglist_insert(peer, tid, &rx_reorder_array_elem->head, &rx_reorder_array_elem->tail, frag, &all_frag_present); + qdf_spin_unlock_bh(&rx_tid->tid_lock); /* * Currently, we can have only 6 MSDUs per-MPDU, if the current @@ -1909,6 +1914,7 @@ dp_rx_defrag_store_fragment(struct dp_soc *soc, "All fragments received for sequence: %d", rxseq); /* Process the fragments */ + qdf_spin_lock_bh(&rx_tid->tid_lock); status = dp_rx_defrag(peer, tid, rx_reorder_array_elem->head, rx_reorder_array_elem->tail); if (QDF_IS_STATUS_ERROR(status)) { @@ -1927,12 +1933,14 @@ dp_rx_defrag_store_fragment(struct dp_soc *soc, "%s: Failed to return link desc", __func__); dp_rx_defrag_cleanup(peer, tid); + qdf_spin_unlock_bh(&rx_tid->tid_lock); goto end; } /* Re-inject the fragments back to REO for further processing */ status = dp_rx_defrag_reo_reinject(peer, tid, rx_reorder_array_elem->head); + qdf_spin_unlock_bh(&rx_tid->tid_lock); if (QDF_IS_STATUS_SUCCESS(status)) { rx_reorder_array_elem->head = NULL; rx_reorder_array_elem->tail = NULL;