From a2514156dfd5ec10fa30e72dbc6496e0b8c87846 Mon Sep 17 00:00:00 2001
From: Dengdui Huang <huangdengdui@huawei.com>
Date: Thu, 15 Aug 2024 17:29:32 +0800
Subject: [PATCH 09/27] hikptool/nic: add check for the value from FW

The value obtained from the firmware is unreliable,
and the software needs to verify the validity.

Signed-off-by: Dengdui Huang <huangdengdui@huawei.com>
---
 net/nic/nic_fd/hikp_nic_fd.c       | 44 +++++++++++++++++++++++++++---
 net/nic/nic_qos/hikp_nic_qos.c     |  8 ++++--
 net/nic/nic_queue/hikp_nic_queue.c |  8 ++++--
 net/nic/nic_rss/hikp_nic_rss.c     |  8 ++++--
 4 files changed, 55 insertions(+), 13 deletions(-)

diff --git a/net/nic/nic_fd/hikp_nic_fd.c b/net/nic/nic_fd/hikp_nic_fd.c
index e699bf9..3d6a9dc 100644
--- a/net/nic/nic_fd/hikp_nic_fd.c
+++ b/net/nic/nic_fd/hikp_nic_fd.c
@@ -550,7 +550,7 @@ static void hikp_nic_show_fd_counter(const void *data)
 
 static int hikp_nic_fd_get_blk(struct hikp_cmd_header *req_header,
 			       const struct nic_fd_req_para *req_data,
-			       void *buf, uint32_t buf_len, struct nic_fd_rsp_head *rsp_head)
+			       void *buf, size_t buf_len, struct nic_fd_rsp_head *rsp_head)
 {
 	struct hikp_cmd_ret *cmd_ret;
 	struct nic_fd_rsp *rsp;
@@ -563,10 +563,12 @@ static int hikp_nic_fd_get_blk(struct hikp_cmd_header *req_header,
 	}
 
 	rsp = (struct nic_fd_rsp *)cmd_ret->rsp_data;
-	if (rsp->rsp_head.cur_blk_size > buf_len) {
+	if (rsp->rsp_head.cur_blk_size > buf_len ||
+	    rsp->rsp_head.cur_blk_size > sizeof(rsp->rsp_data)) {
 		HIKP_ERROR_PRINT("nic_fd block context copy size error, "
-				 "buffer size=%u, data size=%u.\n",
-				 buf_len, rsp->rsp_head.cur_blk_size);
+				 "dst buffer size=%zu, src buffer size=%zu, "
+				 "data size=%u.\n", buf_len, sizeof(rsp->rsp_data),
+				 rsp->rsp_head.cur_blk_size);
 		ret = -EINVAL;
 		goto out;
 	}
@@ -657,7 +659,19 @@ static int hikp_nic_query_fd_rules(struct hikp_cmd_header *req_header, const str
 					 idx, ret);
 			return ret;
 		}
+		if (rsp_head.cur_blk_entry_cnt + entry_cnt > g_fd_hw_info.alloc.stage_entry_num[stage]) {
+			HIKP_ERROR_PRINT("The sum of entry number (%u) after block-%u "
+					 "is over the maximum entry nubmer (%u) of this stage.",
+					 rsp_head.cur_blk_entry_cnt + entry_cnt, idx,
+					 g_fd_hw_info.alloc.stage_entry_num[stage]);
+			return -EINVAL;
+		}
 		entry_cnt += rsp_head.cur_blk_entry_cnt;
+		if (rsp_head.next_entry_idx <= idx) {
+			HIKP_ERROR_PRINT("The next entry index (%u) is less than or equal with the curent(%u).\n",
+					 rsp_head.next_entry_idx, idx);
+			return -EINVAL;
+		}
 		idx = rsp_head.next_entry_idx;
 		if (req_data.query_single_entry == 1)
 			break;
@@ -702,7 +716,19 @@ static int hikp_nic_query_fd_counter(struct hikp_cmd_header *req_header, const s
 					 idx, ret);
 			return ret;
 		}
+		if (rsp_head.cur_blk_entry_cnt + entry_size > g_fd_hw_info.alloc.stage_counter_num[stage]) {
+			HIKP_ERROR_PRINT("The sum of entry number (%u) after block-%u "
+					 "is over the maximum counter nubmer (%u) of this stage.",
+					 rsp_head.cur_blk_entry_cnt + entry_size, idx,
+					 g_fd_hw_info.alloc.stage_counter_num[stage]);
+			return -EINVAL;
+		}
 		entry_size += rsp_head.cur_blk_entry_cnt;
+		if (rsp_head.next_entry_idx <= idx) {
+			HIKP_ERROR_PRINT("The next entry index (%u) is less than or equal with the curent(%u).\n",
+					 rsp_head.next_entry_idx, idx);
+			return -EINVAL;
+		}
 		idx = rsp_head.next_entry_idx;
 		if (req_data.query_single_entry == 1)
 			break;
@@ -808,6 +834,11 @@ static int hikp_nic_check_fd_hw_info(const struct nic_fd_hw_info *hw_info,
 	uint16_t i;
 
 	if (strcmp(fd_cmd->feature_name, NIC_FD_RULES_NAME) == 0) {
+		/* Stage2 does not support query. So only stage1 is verified. */
+		if(hw_info->alloc.stage_entry_num[NIC_FD_STAGE_1] == 0) {
+			HIKP_ERROR_PRINT("The stage1's entry number is zero.\n");
+			return -EINVAL;
+		}
 		if (hw_info->mode > FD_MODE_DEPTH_2K_WIDTH_200B_STAGE_2)
 			HIKP_WARN_PRINT("Unknown fd mode(%u), "
 					"unsupport for displaying meta data info.\n",
@@ -822,6 +853,11 @@ static int hikp_nic_check_fd_hw_info(const struct nic_fd_hw_info *hw_info,
 				return -EOPNOTSUPP;
 			}
 		}
+	} else if (strcmp(fd_cmd->feature_name, NIC_FD_COUNTER_NAME) == 0) {
+		if (hw_info->alloc.stage_counter_num[NIC_FD_STAGE_1] == 0) {
+			HIKP_ERROR_PRINT("The stage1's counter number is zero.\n");
+			return -EINVAL;
+		}
 	}
 
 	return 0;
diff --git a/net/nic/nic_qos/hikp_nic_qos.c b/net/nic/nic_qos/hikp_nic_qos.c
index a09b4f1..9e997e4 100644
--- a/net/nic/nic_qos/hikp_nic_qos.c
+++ b/net/nic/nic_qos/hikp_nic_qos.c
@@ -174,10 +174,12 @@ static int hikp_nic_qos_get_blk(struct hikp_cmd_header *req_header,
 	}
 
 	rsp = (struct nic_qos_rsp *)cmd_ret->rsp_data;
-	if (rsp->rsp_head.cur_blk_size > buf_len) {
+	if (rsp->rsp_head.cur_blk_size > buf_len ||
+	    rsp->rsp_head.cur_blk_size > sizeof(rsp->rsp_data)) {
 		HIKP_ERROR_PRINT("nic_qos block-%u copy size error, "
-				 "buffer size=%zu, data size=%u.\n",
-				 req_data->block_id, buf_len, rsp->rsp_head.cur_blk_size);
+				 "dst buffer size=%zu, src buffer size=%zu, "
+				 "data size=%u.\n", req_data->block_id, buf_len,
+				 sizeof(rsp->rsp_data), rsp->rsp_head.cur_blk_size);
 		ret = -EINVAL;
 		goto out;
 	}
diff --git a/net/nic/nic_queue/hikp_nic_queue.c b/net/nic/nic_queue/hikp_nic_queue.c
index fa3b9d3..c73c8f7 100644
--- a/net/nic/nic_queue/hikp_nic_queue.c
+++ b/net/nic/nic_queue/hikp_nic_queue.c
@@ -246,10 +246,12 @@ static int hikp_nic_queue_get_blk(struct hikp_cmd_header *req_header,
 	}
 
 	rsp = (struct nic_queue_rsp *)cmd_ret->rsp_data;
-	if (rsp->rsp_head.cur_blk_size > buf_len) {
+	if (rsp->rsp_head.cur_blk_size > buf_len ||
+	    rsp->rsp_head.cur_blk_size > sizeof(rsp->rsp_data)) {
 		HIKP_ERROR_PRINT("nic_queue block-%u copy size error, "
-				 "buffer size=%zu, data size=%u.\n",
-				 req_data->block_id, buf_len, rsp->rsp_head.cur_blk_size);
+				 "dst buffer size=%zu, src buffer size=%zu, "
+				 "data size=%u.\n", req_data->block_id, buf_len,
+				 sizeof(rsp->rsp_data), rsp->rsp_head.cur_blk_size);
 		ret = -EINVAL;
 		goto out;
 	}
diff --git a/net/nic/nic_rss/hikp_nic_rss.c b/net/nic/nic_rss/hikp_nic_rss.c
index ff1cfd2..558f931 100644
--- a/net/nic/nic_rss/hikp_nic_rss.c
+++ b/net/nic/nic_rss/hikp_nic_rss.c
@@ -364,10 +364,12 @@ static int hikp_nic_rss_get_blk(struct hikp_cmd_header *req_header,
 	}
 
 	rsp = (struct nic_rss_rsp *)cmd_ret->rsp_data;
-	if (rsp->rsp_head.cur_blk_size > buf_len) {
+	if (rsp->rsp_head.cur_blk_size > buf_len ||
+	    rsp->rsp_head.cur_blk_size > sizeof(rsp->rsp_data)) {
 		HIKP_ERROR_PRINT("nic_rss block-%u copy size error, "
-				 "buffer size=%zu, data size=%u.\n",
-				 req_data->block_id, buf_len, rsp->rsp_head.cur_blk_size);
+				 "dst buffer size=%zu, src buffer size=%zu, "
+				 "data size=%u.\n", req_data->block_id, buf_len,
+				 sizeof(rsp->rsp_data), rsp->rsp_head.cur_blk_size);
 		ret = -EINVAL;
 		goto out;
 	}
-- 
2.45.0.windows.1

