Просмотр исходного кода

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
Jingxiang Ge 7 лет назад
Родитель
Сommit
9f297069f8
1 измененных файлов с 3 добавлено и 0 удалено
  1. 3 0
      core/dp/txrx/ol_txrx.c

+ 3 - 0
core/dp/txrx/ol_txrx.c

@@ -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;
 	}