From 4cd8d664c45d5f1ef930dfb44df75d8c72aeaaba Mon Sep 17 00:00:00 2001
From: Xue <xuechaojing@huawei.com>
Date: Sat, 11 May 2019 18:33:13 +0800
Subject: [PATCH 2763/2944] openeuler: net: hinic: fix check error in hinic

commit 4bf21e753ab62c628501a456f69f23951f1d8d26 openEuler-1.0

driver inclusion
category:bugfix
bugzilla:4472
CVE:NA

------------------------------------------------------------------------
This patch fix check error in hinic code.

Reviewed-by: WuLike <wulike1@huawei.com>
Signed-off-by: Xue <xuechaojing@huawei.com>
Reviewed-by: Yang Yingliang <yangyingliang@huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
Signed-off-by: Xin Hao <haoxing990@gmail.com>
Reviewed-by: Baolin Wang <baolin.wang@openanolis.org>
---
 drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c | 19 ++++++++++++++++++-
 drivers/net/ethernet/huawei/hinic/hinic_nictool.c     |  9 +++++++++
 drivers/net/ethernet/huawei/hinic/hinic_nictool.h     |  1 +
 3 files changed, 28 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c
index b46b251..82f1ec3 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c
@@ -52,6 +52,8 @@ struct ffm_intr_info {
 void *g_card_node_array[MAX_CARD_NUM] = {0};
 void *g_card_vir_addr[MAX_CARD_NUM] = {0};
 u64 g_card_phy_addr[MAX_CARD_NUM] = {0};
+/* lock for g_card_vir_addr  */
+struct mutex	g_addr_lock;
 int card_id;
 
 /* dbgtool character device name, class name, dev path*/
@@ -113,6 +115,10 @@ int hinic_mem_mmap(struct file *filp, struct vm_area_struct *vma)
 		return -EAGAIN;
 	}
 
+	if (offset && offset != g_card_phy_addr[card_id]) {
+		pr_err("offset is invalid, offset addr %llx\n", offset);
+		return -EAGAIN;
+	}
 	/* old version of tool set vma->vm_pgoff to 0 */
 	phy_addr = offset ? offset : g_card_phy_addr[card_id];
 
@@ -171,6 +177,11 @@ long dbgtool_knl_api_cmd_read(struct dbgtool_param *para,
 	}
 
 	ack_size = para->param.api_rd.ack_size;
+	if (para->param.api_rd.ack_size == 0) {
+		pr_err("Read cmd ack size is 0\n");
+		ret = -EINVAL;
+		goto alloc_ack_mem_fail;
+	}
 	ack = kzalloc((unsigned long long)ack_size, GFP_KERNEL);
 	if (!ack) {
 		pr_err("Alloc read ack mem fail\n");
@@ -313,12 +324,14 @@ long dbgtool_knl_pf_dev_info_get(struct dbgtool_param *para,
 	unsigned char *tmp;
 	int i;
 
+	mutex_lock(&g_addr_lock);
 	if (!g_card_vir_addr[card_id]) {
 		g_card_vir_addr[card_id] =
 			(void *)__get_free_pages(GFP_KERNEL,
 						 DBGTOOL_PAGE_ORDER);
 		if (!g_card_vir_addr[card_id]) {
 			pr_err("Alloc dbgtool api chain fail!\n");
+			mutex_unlock(&g_addr_lock);
 			return -EFAULT;
 		}
 
@@ -328,11 +341,12 @@ long dbgtool_knl_pf_dev_info_get(struct dbgtool_param *para,
 		g_card_phy_addr[card_id] =
 			virt_to_phys(g_card_vir_addr[card_id]);
 		if (!g_card_phy_addr[card_id]) {
-			pr_err("phy addr for card %d is 0, vir_addr: 0x%p\n",
+			pr_err("phy addr for card %d is 0, vir_addr: 0x%llx\n",
 			       card_id, g_card_vir_addr[card_id]);
 			free_pages((unsigned long)g_card_vir_addr[card_id],
 				   DBGTOOL_PAGE_ORDER);
 			g_card_vir_addr[card_id] = NULL;
+			mutex_unlock(&g_addr_lock);
 			return -EFAULT;
 		}
 
@@ -342,6 +356,7 @@ long dbgtool_knl_pf_dev_info_get(struct dbgtool_param *para,
 			tmp += PAGE_SIZE;
 		}
 	}
+	mutex_unlock(&g_addr_lock);
 
 	chipif_get_all_pf_dev_info(dev_info, card_id, g_func_handle_array);
 
@@ -525,6 +540,7 @@ long dbgtool_knl_unlocked_ioctl(struct file *pfile,
 		return -EFAULT;
 	}
 
+	param.chip_name[IFNAMSIZ - 1] = '\0';
 	for (i = 0; i < MAX_CARD_NUM; i++) {
 		card_info = (struct card_node *)g_card_node_array[i];
 		if (!card_info)
@@ -774,6 +790,7 @@ int dbgtool_knl_init(void *vhwdev, void *chip_node)
 	}
 	g_dbgtool_init_flag = 1;
 	g_dbgtool_ref_cnt = 1;
+	mutex_init(&g_addr_lock);
 
 	return 0;
 
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nictool.c b/drivers/net/ethernet/huawei/hinic/hinic_nictool.c
index 580c8963..387752b 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_nictool.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_nictool.c
@@ -38,6 +38,7 @@
 
 #define MAJOR_DEV_NUM 921
 #define	HINIC_CMDQ_BUF_MAX_SIZE		2048U
+#define MSG_MAX_IN_SIZE	(2048 * 1024)
 
 static dev_t g_dev_id = {0};
 /*lint -save -e104 -e808*/
@@ -99,6 +100,10 @@ static int alloc_buff_in(void *hwdev, struct msg_module *nt_msg,
 		*buf_in = (void *)cmd_buf;
 		cmd_buf->size = (u16)in_size;
 	} else {
+		if (in_size > MSG_MAX_IN_SIZE) {
+			pr_err("In size(%u) more than 2M\n", in_size);
+			return -ENOMEM;
+		}
 		msg_buf = kzalloc(in_size, GFP_KERNEL);
 		*buf_in = msg_buf;
 	}
@@ -1013,6 +1018,7 @@ static int __get_card_usr_api_chain_mem(int card_idx)
 	unsigned char *tmp;
 	int i;
 
+	mutex_lock(&g_addr_lock);
 	card_id = card_idx;
 	if (!g_card_vir_addr[card_idx]) {
 		g_card_vir_addr[card_idx] =
@@ -1021,6 +1027,7 @@ static int __get_card_usr_api_chain_mem(int card_idx)
 		if (!g_card_vir_addr[card_idx]) {
 			pr_err("Alloc api chain memory fail for card %d, virt_addr: %p!\n",
 			       card_idx, g_card_vir_addr[card_idx]);
+			mutex_unlock(&g_addr_lock);
 			return -EFAULT;
 		}
 
@@ -1035,6 +1042,7 @@ static int __get_card_usr_api_chain_mem(int card_idx)
 			free_pages((unsigned long)g_card_vir_addr[card_idx],
 				   DBGTOOL_PAGE_ORDER);
 			g_card_vir_addr[card_idx] = NULL;
+			mutex_unlock(&g_addr_lock);
 			return -EFAULT;
 		}
 
@@ -1044,6 +1052,7 @@ static int __get_card_usr_api_chain_mem(int card_idx)
 			tmp += PAGE_SIZE;
 		}
 	}
+	mutex_unlock(&g_addr_lock);
 
 	return 0;
 }
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nictool.h b/drivers/net/ethernet/huawei/hinic/hinic_nictool.h
index 26b05bb..f903e77 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_nictool.h
@@ -210,6 +210,7 @@ struct hinic_card_func_info {
 extern void *g_card_vir_addr[MAX_CARD_NUM];
 extern u64 g_card_phy_addr[MAX_CARD_NUM];
 extern int card_id;
+extern struct mutex	g_addr_lock;
 
 struct hinic_nic_loop_mode {
 	u32 loop_mode;
-- 
1.8.3.1

