From: Xue <xuechaojing(a)huawei.com>
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(a)huawei.com>
Signed-off-by: Xue <xuechaojing(a)huawei.com>
Reviewed-by: Yang Yingliang <yangyingliang(a)huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang(a)huawei.com>
Signed-off-by: Xin Hao <haoxing990(a)gmail.com>
---
.../ethernet/huawei/hinic/hinic_dbgtool_knl.c | 19 ++++++++++++++++++-
.../net/ethernet/huawei/hinic/hinic_nictool.c | 9 +++++++++
.../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 b46b251c427c..82f1ec34b944 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 580c8963720d..387752b7f367 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 26b05bb39d58..f903e7782f3c 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_nictool.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_nictool.h
@@ -210,6 +210,7 @@ extern void *g_card_node_array[MAX_CARD_NUM];
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;
--
2.31.0