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
This commit is contained in:
Himanshu Agarwal
2017-01-18 20:45:01 +05:30
committed by qcabuildsw
orang tua 9dada4165c
melakukan bb226bc822
3 mengubah file dengan 30 tambahan dan 22 penghapusan

Melihat File

@@ -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.
*
@@ -1443,6 +1443,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);
@@ -1453,17 +1454,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 */

Melihat File

@@ -549,6 +549,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;
@@ -565,8 +566,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);
}
@@ -775,6 +777,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) {
@@ -792,8 +795,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)) {

Melihat File

@@ -2502,6 +2502,7 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle,
uint8_t vdev_id = 0;
QDF_STATUS ret;
struct wlan_lmac_if_mgmt_txrx_rx_ops *mgmt_txrx_rx_ops;
tp_wma_packetdump_cb packetdump_cb;
if (wma_handle == NULL) {
WMA_LOGE("%s: wma handle is NULL", __func__);
@@ -2530,9 +2531,10 @@ static int wma_process_mgmt_tx_completion(tp_wma_handle wma_handle,
qdf_nbuf_unmap_single(wma_handle->qdf_dev, buf,
QDF_DMA_TO_DEVICE);
if (wma_handle->wma_mgmt_tx_packetdump_cb)
wma_handle->wma_mgmt_tx_packetdump_cb(buf,
QDF_STATUS_SUCCESS, vdev_id, TX_MGMT_PKT);
packetdump_cb = wma_handle->wma_mgmt_tx_packetdump_cb;
if (packetdump_cb)
packetdump_cb(buf, QDF_STATUS_SUCCESS,
vdev_id, TX_MGMT_PKT);
if (!mgmt_txrx_rx_ops->mgmt_tx_completion_handler) {
WMA_LOGE("%s: tx completion callback to mgmt txrx layer is NULL",
@@ -3180,6 +3182,7 @@ int wma_form_rx_packet(qdf_nbuf_t buf,
int status;
tp_wma_handle wma_handle = (tp_wma_handle)
cds_get_context(QDF_MODULE_ID_WMA);
tp_wma_packetdump_cb packetdump_cb;
if (!wma_handle) {
WMA_LOGE(FL("wma handle is NULL"));
@@ -3294,12 +3297,12 @@ int wma_form_rx_packet(qdf_nbuf_t buf,
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);
return 0;
}