Эх сурвалжийг харах

qcacld-3.0: Fix NULL pointer dereferencing issues

Fix below issues:
1) check cds_get_context results before use
2) remove function calls from ASSERTs
3) make sure variables are initialized before use
4) check pointers for NULL before dereferencing

Change-Id: Iac92e6f2d1030a7dd12469e34341135bea7c781f
CRs-Fixed: 1047286
(cherry picked from commit a2547fd35fc517abfbc96363768b5d036d59d057)
Himanshu Agarwal 8 жил өмнө
parent
commit
f03f81036d

+ 1 - 1
core/bmi/src/ol_fw.c

@@ -289,7 +289,7 @@ __ol_transfer_bin_file(struct ol_context *ol_ctx, ATH_BIN_FILE file,
 #endif
 
 	if (file == ATH_BOARD_DATA_FILE) {
-		uint32_t board_ext_address;
+		uint32_t board_ext_address = 0;
 		int32_t board_ext_data_size;
 
 		temp_eeprom = qdf_mem_malloc(fw_entry_size);

+ 28 - 19
core/dp/htt/htt_tx.c

@@ -1599,11 +1599,21 @@ htt_tx_desc_init(htt_pdev_handle pdev,
 	void *qdf_ctx = cds_get_context(QDF_MODULE_ID_QDF_DEVICE);
 	QDF_STATUS status;
 
-	if (!qdf_ctx) {
+	if (qdf_unlikely(!qdf_ctx)) {
 		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
 			"%s: qdf_ctx is NULL", __func__);
 		return;
 	}
+	if (qdf_unlikely(!msdu_info)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			"%s: bad arg: msdu_info is NULL", __func__);
+		return;
+	}
+	if (qdf_unlikely(!tso_info)) {
+		QDF_TRACE(QDF_MODULE_ID_TXRX, QDF_TRACE_LEVEL_ERROR,
+			"%s: bad arg: tso_info is NULL", __func__);
+		return;
+	}
 
 	word0 = (uint32_t *) htt_tx_desc;
 	word1 = word0 + 1;
@@ -1639,24 +1649,23 @@ htt_tx_desc_init(htt_pdev_handle pdev,
 	 */
 
 	local_word0 = 0;
-	if (msdu_info) {
-		HTT_H2T_MSG_TYPE_SET(local_word0, HTT_H2T_MSG_TYPE_TX_FRM);
-		HTT_TX_DESC_PKT_TYPE_SET(local_word0, pkt_type);
-		HTT_TX_DESC_PKT_SUBTYPE_SET(local_word0, pkt_subtype);
-		HTT_TX_DESC_VDEV_ID_SET(local_word0, msdu_info->info.vdev_id);
-		HTT_TX_DESC_EXT_TID_SET(local_word0, htt_get_ext_tid(type,
-						ext_header_data, msdu_info));
-		HTT_TX_DESC_EXTENSION_SET(local_word0, desc_ext_required);
-		HTT_TX_DESC_EXT_TID_SET(local_word0, msdu_info->info.ext_tid);
-		HTT_TX_DESC_CKSUM_OFFLOAD_SET(local_word0,
-					      msdu_info->action.cksum_offload);
-		if (pdev->cfg.is_high_latency)
-			HTT_TX_DESC_TX_COMP_SET(local_word0, msdu_info->action.
-								tx_comp_req);
-		HTT_TX_DESC_NO_ENCRYPT_SET(local_word0,
-					   msdu_info->action.do_encrypt ?
-					   0 : 1);
-	}
+
+	HTT_H2T_MSG_TYPE_SET(local_word0, HTT_H2T_MSG_TYPE_TX_FRM);
+	HTT_TX_DESC_PKT_TYPE_SET(local_word0, pkt_type);
+	HTT_TX_DESC_PKT_SUBTYPE_SET(local_word0, pkt_subtype);
+	HTT_TX_DESC_VDEV_ID_SET(local_word0, msdu_info->info.vdev_id);
+	HTT_TX_DESC_EXT_TID_SET(local_word0, htt_get_ext_tid(type,
+					ext_header_data, msdu_info));
+	HTT_TX_DESC_EXTENSION_SET(local_word0, desc_ext_required);
+	HTT_TX_DESC_EXT_TID_SET(local_word0, msdu_info->info.ext_tid);
+	HTT_TX_DESC_CKSUM_OFFLOAD_SET(local_word0,
+				      msdu_info->action.cksum_offload);
+	if (pdev->cfg.is_high_latency)
+		HTT_TX_DESC_TX_COMP_SET(local_word0, msdu_info->action.
+							tx_comp_req);
+	HTT_TX_DESC_NO_ENCRYPT_SET(local_word0,
+				   msdu_info->action.do_encrypt ?
+				   0 : 1);
 
 	*word0 = local_word0;
 

+ 10 - 0
core/dp/txrx/ol_tx.c

@@ -1867,6 +1867,16 @@ void ol_tso_seg_list_init(struct ol_txrx_pdev_t *pdev, uint32_t num_seg)
 	c_element = qdf_mem_malloc(sizeof(struct qdf_tso_seg_elem_t));
 	pdev->tso_seg_pool.freelist = c_element;
 	for (i = 0; i < (num_seg - 1); i++) {
+		if (qdf_unlikely(!c_element)) {
+			TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
+				   "%s: ERROR: c_element NULL for seg %d",
+				   __func__, i);
+			QDF_BUG(0);
+			pdev->tso_seg_pool.pool_size = i;
+			qdf_spinlock_create(&pdev->tso_seg_pool.tso_mutex);
+			return;
+		}
+
 		c_element->next =
 			qdf_mem_malloc(sizeof(struct qdf_tso_seg_elem_t));
 		c_element = c_element->next;

+ 18 - 1
core/dp/txrx/ol_txrx_flow_control.c

@@ -157,6 +157,11 @@ void ol_tx_dump_flow_pool_info(void)
 
 
 	TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Global Pool");
+	if (!pdev) {
+		TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "ERROR: pdev NULL");
+		QDF_ASSERT(0); /* traceback */
+		return;
+	}
 	TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Total %d :: Available %d",
 		pdev->tx_desc.pool_size, pdev->tx_desc.num_free);
 	TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "Invalid flow_pool %d",
@@ -413,6 +418,13 @@ int ol_tx_delete_flow_pool(struct ol_tx_flow_pool_t *pool, bool force)
 	if (!pool) {
 		TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
 		   "%s: pool is NULL\n", __func__);
+		QDF_ASSERT(0);
+		return -ENOMEM;
+	}
+	if (!pdev) {
+		TXRX_PRINT(TXRX_PRINT_LEVEL_ERR,
+		   "%s: pdev is NULL\n", __func__);
+		QDF_ASSERT(0);
 		return -ENOMEM;
 	}
 
@@ -512,6 +524,12 @@ struct ol_tx_flow_pool_t *ol_tx_get_flow_pool(uint8_t flow_pool_id)
 	struct ol_tx_flow_pool_t *pool = NULL;
 	bool is_found = false;
 
+	if (!pdev) {
+		TXRX_PRINT(TXRX_PRINT_LEVEL_ERR, "ERROR: pdev NULL");
+		QDF_ASSERT(0); /* traceback */
+		return NULL;
+	}
+
 	qdf_spin_lock_bh(&pdev->tx_desc.flow_pool_list_lock);
 	TAILQ_FOREACH(pool, &pdev->tx_desc.flow_pool_list,
 					 flow_pool_list_elem) {
@@ -529,7 +547,6 @@ struct ol_tx_flow_pool_t *ol_tx_get_flow_pool(uint8_t flow_pool_id)
 		pool = NULL;
 
 	return pool;
-
 }
 
 

+ 4 - 4
core/utils/epping/src/epping_tx.c

@@ -338,14 +338,14 @@ void epping_tx_complete_multiple(void *ctx, HTC_PACKET_QUEUE *pPacketQueue)
 
 		if (!pktSkb) {
 			EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
-				 "%s: pktSkb is NULL", __func__);
-			ASSERT(0);
+				 "%s: NULL skb from hc packet", __func__);
+			QDF_BUG(0);
 		} else {
 			if (htc_pkt->pBuffer != qdf_nbuf_data(pktSkb)) {
 				EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
 				  "%s: htc_pkt buffer not equal to skb->data",
 				  __func__);
-				ASSERT(0);
+				QDF_BUG(0);
 			}
 			/* add this to the list, use faster non-lock API */
 			qdf_nbuf_queue_add(&skb_queue, pktSkb);
@@ -356,7 +356,7 @@ void epping_tx_complete_multiple(void *ctx, HTC_PACKET_QUEUE *pPacketQueue)
 					EPPING_LOG(QDF_TRACE_LEVEL_ERROR,
 					  "%s: htc_pkt length not equal to skb->len",
 					  __func__);
-					ASSERT(0);
+					QDF_BUG(0);
 				}
 			}
 		}