diff options
| author | Himanshu Agarwal <himanaga@codeaurora.org> | 2017-01-18 20:45:01 +0530 |
|---|---|---|
| committer | qcabuildsw <qcabuildsw@localhost> | 2017-01-20 20:37:16 -0800 |
| commit | dc7854568fde7a222994afc08214a2f12a0a5b0b (patch) | |
| tree | a3bee1c6b569d539ef3b409d3a79c09d6c52cf0d | |
| parent | b255f02525bff9ecf94829a3d57ec76a6bcb326c (diff) | |
qcacld-3.0: Use local variable to avoid race condition in packetdump
Race condiiton is observed as deregistration of 32 tx/rx packetdump
feature and packetdump callback call is happening at the same time
causing NULL pointer dereference.
Use local variable to store packetdump callback to avoid this race
condition.
Change-Id: Id4246d85e3816c0a3b8d0d0c1ef21e5ff053b608
CRs-Fixed: 1112126
| -rw-r--r-- | core/dp/txrx/ol_rx.c | 21 | ||||
| -rw-r--r-- | core/dp/txrx/ol_tx_send.c | 14 | ||||
| -rw-r--r-- | core/wma/src/wma_mgmt.c | 19 |
3 files changed, 31 insertions, 23 deletions
diff --git a/core/dp/txrx/ol_rx.c b/core/dp/txrx/ol_rx.c index 4a29fe4f501a..9e0b4f37b819 100644 --- a/core/dp/txrx/ol_rx.c +++ b/core/dp/txrx/ol_rx.c @@ -1451,6 +1451,7 @@ void ol_rx_pkt_dump_call( v_CONTEXT_t vos_context; ol_txrx_pdev_handle pdev; struct ol_txrx_peer_t *peer = NULL; + tp_ol_packetdump_cb packetdump_cb; vos_context = cds_get_global_context(); pdev = cds_get_context(QDF_MODULE_ID_TXRX); @@ -1461,17 +1462,17 @@ void ol_rx_pkt_dump_call( return; } - if (pdev->ol_rx_packetdump_cb) { - peer = ol_txrx_peer_find_by_id(pdev, peer_id); - if (!peer) { - TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, - "%s: peer with peer id %d is NULL", __func__, - peer_id); - return; - } - pdev->ol_rx_packetdump_cb(msdu, status, peer->vdev->vdev_id, - RX_DATA_PKT); + peer = ol_txrx_peer_find_by_id(pdev, peer_id); + if (!peer) { + TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, + "%s: peer with peer id %d is NULL", __func__, + peer_id); + return; } + + packetdump_cb = pdev->ol_rx_packetdump_cb; + if (packetdump_cb) + packetdump_cb(msdu, status, peer->vdev->vdev_id, RX_DATA_PKT); } /* the msdu_list passed here must be NULL terminated */ diff --git a/core/dp/txrx/ol_tx_send.c b/core/dp/txrx/ol_tx_send.c index 5da7b534cb05..628a9afc9a2c 100644 --- a/core/dp/txrx/ol_tx_send.c +++ b/core/dp/txrx/ol_tx_send.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2011-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -539,6 +539,7 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev, struct ol_tx_desc_t *tx_desc; uint32_t byte_cnt = 0; qdf_nbuf_t netbuf; + tp_ol_packetdump_cb packetdump_cb; union ol_tx_desc_list_elem_t *lcl_freelist = NULL; union ol_tx_desc_list_elem_t *tx_desc_last = NULL; @@ -555,8 +556,9 @@ ol_tx_completion_handler(ol_txrx_pdev_handle pdev, QDF_NBUF_UPDATE_TX_PKT_COUNT(netbuf, QDF_NBUF_TX_PKT_FREE); if (tx_desc->pkt_type != OL_TX_FRM_TSO) { - if (pdev->ol_tx_packetdump_cb) - pdev->ol_tx_packetdump_cb(netbuf, status, + packetdump_cb = pdev->ol_tx_packetdump_cb; + if (packetdump_cb) + packetdump_cb(netbuf, status, tx_desc->vdev->vdev_id, TX_DATA_PKT); } @@ -765,6 +767,7 @@ ol_tx_single_completion_handler(ol_txrx_pdev_handle pdev, { struct ol_tx_desc_t *tx_desc; qdf_nbuf_t netbuf; + tp_ol_packetdump_cb packetdump_cb; tx_desc = ol_tx_desc_find_check(pdev, tx_desc_id); if (tx_desc == NULL) { @@ -782,8 +785,9 @@ ol_tx_single_completion_handler(ol_txrx_pdev_handle pdev, /* Do one shot statistics */ TXRX_STATS_UPDATE_TX_STATS(pdev, status, 1, qdf_nbuf_len(netbuf)); - if (pdev->ol_tx_packetdump_cb) - pdev->ol_tx_packetdump_cb(netbuf, status, + packetdump_cb = pdev->ol_tx_packetdump_cb; + if (packetdump_cb) + packetdump_cb(netbuf, status, tx_desc->vdev->vdev_id, TX_MGMT_PKT); if (OL_TX_DESC_NO_REFS(tx_desc)) { diff --git a/core/wma/src/wma_mgmt.c b/core/wma/src/wma_mgmt.c index 05c141ca5ba4..3a92298b1973 100644 --- a/core/wma/src/wma_mgmt.c +++ b/core/wma/src/wma_mgmt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016 The Linux Foundation. All rights reserved. + * Copyright (c) 2013-2017 The Linux Foundation. All rights reserved. * * Previously licensed under the ISC license by Qualcomm Atheros, Inc. * @@ -2483,6 +2483,7 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle, { struct wmi_desc_t *wmi_desc; ol_txrx_pdev_handle pdev = cds_get_context(QDF_MODULE_ID_TXRX); + tp_wma_packetdump_cb packetdump_cb; if (pdev == NULL) { WMA_LOGE("%s: NULL pdev pointer", __func__); @@ -2503,9 +2504,10 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle, qdf_nbuf_unmap_single(pdev->osdev, wmi_desc->nbuf, QDF_DMA_TO_DEVICE); - if (wma_handle->wma_mgmt_tx_packetdump_cb) - wma_handle->wma_mgmt_tx_packetdump_cb(wmi_desc->nbuf, - QDF_STATUS_SUCCESS, wmi_desc->vdev_id, TX_MGMT_PKT); + packetdump_cb = wma_handle->wma_mgmt_tx_packetdump_cb; + if (packetdump_cb) + packetdump_cb(wmi_desc->nbuf, QDF_STATUS_SUCCESS, + wmi_desc->vdev_id, TX_MGMT_PKT); if (wmi_desc->tx_cmpl_cb) wmi_desc->tx_cmpl_cb(wma_handle->mac_context, @@ -3166,6 +3168,7 @@ static int wma_mgmt_rx_process(void *handle, uint8_t *data, struct ieee80211_frame *wh; uint8_t mgt_type, mgt_subtype; int status; + tp_wma_packetdump_cb packetdump_cb; if (!wma_handle) { WMA_LOGE("%s: Failed to get WMA context", __func__); @@ -3330,12 +3333,12 @@ static int wma_mgmt_rx_process(void *handle, uint8_t *data, return -EINVAL; } + packetdump_cb = wma_handle->wma_mgmt_rx_packetdump_cb; if ((mgt_type == IEEE80211_FC0_TYPE_MGT && mgt_subtype != IEEE80211_FC0_SUBTYPE_BEACON) && - wma_handle->wma_mgmt_rx_packetdump_cb) - wma_handle->wma_mgmt_rx_packetdump_cb(rx_pkt->pkt_buf, - QDF_STATUS_SUCCESS, rx_pkt->pkt_meta.sessionId, - RX_MGMT_PKT); + packetdump_cb) + packetdump_cb(rx_pkt->pkt_buf, QDF_STATUS_SUCCESS, + rx_pkt->pkt_meta.sessionId, RX_MGMT_PKT); wma_handle->mgmt_rx(wma_handle, rx_pkt); return 0; |
