qcacld-3.0: Fix race condition for get peer

There is a very rare race condition between
ol_txrx_peer_find_by_local_id_inc_ref(running in OL RX
thread context) and ol_txrx_peer_detach(running in MC
thread context) where MC thread 1st got chance and cleared
the peer->valid flag before OL RX thread can increment the
ref count and this led to OL RX thread got a peer without
any ref count which was freed later while OL RX thread was
still using it.

Change:
1 Set peer to NULL if peer valid check fails in
  ol_txrx_peer_find_by_local_id_inc_ref
2 release peer ref cnt for error case in ol_rx_data_cb

Change-Id: Id21350933386464e5814babcb078d9719572af86
CRs-Fixed: 2176704
Esse commit está contido em:
Jingxiang Ge
2018-01-24 13:31:31 +08:00
commit de snandini
commit 9f297069f8

Ver arquivo

@@ -525,6 +525,8 @@ ol_txrx_peer_get_ref_by_local_id(struct cdp_pdev *ppdev,
qdf_spin_unlock_bh(&pdev->local_peer_ids.lock);
if (peer && peer->valid)
ol_txrx_peer_get_ref(peer, dbg_id);
else
peer = NULL;
qdf_spin_unlock_bh(&pdev->peer_ref_mutex);
return peer;
@@ -4984,6 +4986,7 @@ static void ol_rx_data_cb(struct ol_txrx_pdev_t *pdev,
if (qdf_unlikely(!(peer->state >= OL_TXRX_PEER_STATE_CONN) ||
!peer->vdev->rx)) {
qdf_spin_unlock_bh(&peer->peer_info_lock);
ol_txrx_peer_release_ref(peer, PEER_DEBUG_ID_OL_RX_THREAD);
goto free_buf;
}