From: Xue <xuechaojing(a)huawei.com>
commit 4a7812da7d7d228896f51502b0a0b92ddc5e820 openEuler-1.0
driver inclusion
category:bugfix
bugzilla:4472
CVE:NA
------------------------------------------------------------------------
1.fix bug in dbgtool init
2.add address security check in hinic_mem_mmap.
Reviewed-by: chiqijun <chiqijun(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 | 33 +++++++++++++++----
drivers/net/ethernet/huawei/hinic/hinic_lld.c | 25 ++++++++++++++
drivers/net/ethernet/huawei/hinic/hinic_lld.h | 1 +
.../net/ethernet/huawei/hinic/hinic_nic_dev.h | 2 +-
4 files changed, 53 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c
b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c
index ff43c04ba740..027fb019677f 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c
@@ -33,6 +33,7 @@
#include "hinic_hwdev.h"
#include "hinic_hw_mgmt.h"
#include "hinic_nic_dev.h"
+#include "hinic_lld.h"
#include "hinic_dbgtool_knl.h"
struct ffm_intr_info {
@@ -104,6 +105,18 @@ static ssize_t dbgtool_knl_write(struct file *pfile,
return 0;
}
+static bool is_valid_phy_addr(u64 offset)
+{
+ int i = 0;
+
+ for (i = 0; i < MAX_CARD_NUM; i++) {
+ if (offset == g_card_phy_addr[i])
+ return true;
+ }
+
+ return false;
+}
+
int hinic_mem_mmap(struct file *filp, struct vm_area_struct *vma)
{
unsigned long vmsize = vma->vm_end - vma->vm_start;
@@ -115,10 +128,12 @@ int hinic_mem_mmap(struct file *filp, struct vm_area_struct *vma)
return -EAGAIN;
}
- if (offset && offset != g_card_phy_addr[card_id]) {
+ if (offset && !is_valid_phy_addr((u64)offset) &&
+ !hinic_is_valid_bar_addr((u64)offset)) {
pr_err("offset is invalid\n");
return -EAGAIN;
}
+
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
@@ -143,7 +158,7 @@ int hinic_mem_mmap(struct file *filp, struct vm_area_struct *vma)
long dbgtool_knl_api_cmd_read(struct dbgtool_param *para,
void **g_func_handle_array)
{
- long ret;
+ long ret = 0;
u8 *cmd;
u16 size;
void *ack;
@@ -224,7 +239,7 @@ long dbgtool_knl_api_cmd_read(struct dbgtool_param *para,
long dbgtool_knl_api_cmd_write(struct dbgtool_param *para,
void **g_func_handle_array)
{
- long ret;
+ long ret = 0;
u8 *cmd;
u16 size;
u32 pf_id;
@@ -410,7 +425,7 @@ long dbgtool_knl_ffm_info_clr(struct dbgtool_param *para,
long dbgtool_knl_msg_to_up(struct dbgtool_param *para,
void **g_func_handle_array)
{
- long ret;
+ long ret = 0;
void *buf_in;
void *buf_out;
u16 out_size;
@@ -525,7 +540,7 @@ long dbgtool_knl_unlocked_ioctl(struct file *pfile,
unsigned int cmd,
unsigned long arg)
{
- long ret;
+ long ret = 0;
unsigned int real_cmd;
struct dbgtool_param param;
struct dbgtool_k_glb_info *dbgtool_info;
@@ -723,6 +738,7 @@ int dbgtool_knl_init(void *vhwdev, void *chip_node)
kzalloc(sizeof(struct dbgtool_k_glb_info), GFP_KERNEL);
if (!dbgtool_info) {
pr_err("Failed to allocate dbgtool_info\n");
+ ret = -EFAULT;
goto dbgtool_info_fail;
}
chip_info->dbgtool_info = dbgtool_info;
@@ -733,15 +749,17 @@ int dbgtool_knl_init(void *vhwdev, void *chip_node)
GFP_KERNEL);
if (!dbgtool_info->ffm) {
pr_err("Failed to allocate cell contexts for a chain\n");
+ ret = -EFAULT;
goto dbgtool_info_ffm_fail;
}
sema_init(&dbgtool_info->dbgtool_sem, 1);
ret = sscanf(chip_info->chip_name, HINIC_CHIP_NAME "%d", &id);
- if (ret < 0)
+ if (ret < 0) {
pr_err("Failed to get hinic id\n");
-
+ goto sscanf_chdev_fail;
+ }
g_card_node_array[id] = chip_info;
chip_info->func_num++;
@@ -801,6 +819,7 @@ int dbgtool_knl_init(void *vhwdev, void *chip_node)
unregister_chrdev_region(dbgtool_dev_id, 1);
alloc_chdev_fail:
g_card_node_array[id] = NULL;
+sscanf_chdev_fail:
kfree(dbgtool_info->ffm);
dbgtool_info_ffm_fail:
kfree(dbgtool_info);
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_lld.c
b/drivers/net/ethernet/huawei/hinic/hinic_lld.c
index 1f0461564dde..86e499d26bc6 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_lld.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_lld.c
@@ -1329,6 +1329,31 @@ static bool __is_func_valid(struct hinic_pcidev *dev)
return true;
}
+bool hinic_is_valid_bar_addr(u64 offset)
+{
+ struct card_node *chip_node = NULL;
+ struct hinic_pcidev *dev;
+
+ lld_dev_hold();
+ list_for_each_entry(chip_node, &g_hinic_chip_list, node) {
+ list_for_each_entry(dev, &chip_node->func_list, node) {
+ if (hinic_func_type(dev->hwdev) == TYPE_VF)
+ continue;
+
+ if (test_bit(HINIC_FUNC_IN_REMOVE, &dev->flag))
+ continue;
+
+ if (offset == pci_resource_start(dev->pcidev, 0)) {
+ lld_dev_put();
+ return true;
+ }
+ }
+ }
+ lld_dev_put();
+
+ return false;
+}
+
void hinic_get_card_info(void *hwdev, void *bufin)
{
struct card_node *chip_node = NULL;
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_lld.h
b/drivers/net/ethernet/huawei/hinic/hinic_lld.h
index 004e96f5c93e..deaeb95d5345 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_lld.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_lld.h
@@ -117,4 +117,5 @@ extern struct hinic_uld_info g_uld_info[SERVICE_T_MAX];
struct pci_device_id *hinic_get_pci_device_id(struct pci_dev *pdev);
bool hinic_is_in_host(void);
+bool hinic_is_valid_bar_addr(u64 offset);
#endif
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_dev.h
b/drivers/net/ethernet/huawei/hinic/hinic_nic_dev.h
index fc34ecffdf03..8524c459bedd 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_nic_dev.h
+++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_dev.h
@@ -30,7 +30,7 @@
#define HINIC_DRV_NAME "hinic"
#define HINIC_CHIP_NAME "hinic"
-#define HINIC_DRV_VERSION "1.8.2.8"
+#define HINIC_DRV_VERSION "1.8.3.1"
struct vf_data_storage;
#define HINIC_FUNC_IS_VF(hwdev) (hinic_func_type(hwdev) == TYPE_VF)
--
2.31.0