Selaa lähdekoodia

qcacmn: Check for in_use flag before using the txrx desc pool

While accessing txrx desc pool, in_use flags is not used and thus
caller may end up using a txrx desc which is not in use. Also
all the params of txrx desc are not reinitialized once in_use flag
is set to false. This can lead invalid pointers used by caller.

So check for in_use flag before using the txrx desc pool, to avoid
use after in_use is set to false and reinitialized all params to
invalid values.

Also In wlan_mgmt_txrx_mgmt_frame_tx driver forcefully get the peer
ref count. It should use wlan_objmgr_peer_try_get_ref api to get
the peer ref, so that after logical delete the frames are not sent
for the peer.

Change-Id: Ie59e622c095750de8eabc49985b114ec6197be00
CRs-Fixed: 2459212
Abhishek Singh 5 vuotta sitten
vanhempi
sitoutus
6aa5f2907b

+ 7 - 0
umac/cmn_services/mgmt_txrx/core/src/wlan_mgmt_txrx_main.c

@@ -148,6 +148,13 @@ void wlan_mgmt_txrx_desc_put(
 		return;
 	}
 	desc->in_use = false;
+	desc->context = NULL;
+	desc->peer = NULL;
+	desc->nbuf = NULL;
+	desc->tx_dwnld_cmpl_cb = NULL;
+	desc->tx_ota_cmpl_cb = NULL;
+	desc->vdev_id = WLAN_UMAC_VDEV_ID_MAX;
+
 	qdf_list_insert_front(&mgmt_txrx_pdev_ctx->mgmt_desc_pool.free_list,
 			      &desc->entry);
 

+ 4 - 4
umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_tgt_api.c

@@ -1076,7 +1076,7 @@ QDF_STATUS tgt_mgmt_txrx_tx_completion_handler(
 		return QDF_STATUS_E_INVAL;
 	}
 	mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
-	if (!mgmt_desc) {
+	if (!mgmt_desc || !mgmt_desc->in_use) {
 		mgmt_txrx_err("Mgmt desc empty for id %d pdev %pK ",
 				desc_id, pdev);
 		return QDF_STATUS_E_NULL_VALUE;
@@ -1148,7 +1148,7 @@ qdf_nbuf_t tgt_mgmt_txrx_get_nbuf_from_desc_id(
 	}
 
 	mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
-	if (!mgmt_desc) {
+	if (!mgmt_desc || !mgmt_desc->in_use) {
 		mgmt_txrx_err("Mgmt descriptor unavailable for id %d pdev %pK",
 				desc_id, pdev);
 		goto fail;
@@ -1178,7 +1178,7 @@ tgt_mgmt_txrx_get_peer_from_desc_id(
 	}
 
 	mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
-	if (!mgmt_desc) {
+	if (!mgmt_desc || !mgmt_desc->in_use) {
 		mgmt_txrx_err("Mgmt descriptor unavailable for id %d pdev %pK",
 				desc_id, pdev);
 		goto fail;
@@ -1212,7 +1212,7 @@ uint8_t tgt_mgmt_txrx_get_vdev_id_from_desc_id(
 	}
 
 	mgmt_desc = &mgmt_txrx_pdev_ctx->mgmt_desc_pool.pool[desc_id];
-	if (!mgmt_desc) {
+	if (!mgmt_desc || !mgmt_desc->in_use) {
 		mgmt_txrx_err("Mgmt descriptor unavailable for id %d pdev %pK",
 				desc_id, pdev);
 		goto fail;

+ 6 - 1
umac/cmn_services/mgmt_txrx/dispatcher/src/wlan_mgmt_txrx_utils_api.c

@@ -366,13 +366,18 @@ QDF_STATUS wlan_mgmt_txrx_mgmt_frame_tx(struct wlan_objmgr_peer *peer,
 	struct wlan_objmgr_pdev *pdev;
 	struct mgmt_txrx_priv_pdev_context *txrx_ctx;
 	struct wlan_objmgr_vdev *vdev;
+	QDF_STATUS status;
 
 	if (!peer) {
 		mgmt_txrx_err("peer passed is NULL");
 		return QDF_STATUS_E_NULL_VALUE;
 	}
 
-	wlan_objmgr_peer_get_ref(peer, WLAN_MGMT_NB_ID);
+	status = wlan_objmgr_peer_try_get_ref(peer, WLAN_MGMT_NB_ID);
+	if (QDF_IS_STATUS_ERROR(status)) {
+		mgmt_txrx_err("failed to get ref count for peer %pK", peer);
+		return QDF_STATUS_E_NULL_VALUE;
+	}
 
 	vdev = wlan_peer_get_vdev(peer);
 	if (!vdev) {