From: Xue <xuechaojing(a)huawei.com>
commit 90429e5002e3beb6148ad9549c63eccb2831bcf5 openEuler-1.0
driver inclusion
category:bugfix
bugzilla:4472
CVE:NA
------------------------------------------------------------------------
This patch adds card_id protection.
Reviewed-by: Wu Like <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 | 27 ++++++++++++++++---
1 file changed, 24 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c
b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c
index f65892c6273f..96fb8db66656 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c
@@ -56,6 +56,10 @@ u64 g_card_phy_addr[MAX_CARD_NUM] = {0};
/* lock for g_card_vir_addr */
struct mutex g_addr_lock;
int card_id;
+unsigned long card_id_flag;
+enum hinic_card_id_status {
+ HINIC_CARD_ID_USE = BIT(0),
+};
/* dbgtool character device name, class name, dev path*/
#define CHR_DEV_DBGTOOL "dbgtool_chr_dev"
@@ -125,18 +129,20 @@ int hinic_mem_mmap(struct file *filp, struct vm_area_struct *vma)
if (vmsize > (PAGE_SIZE * (1 << DBGTOOL_PAGE_ORDER))) {
pr_err("Map size = %lu is bigger than alloc\n", vmsize);
+ clear_bit(HINIC_CARD_ID_USE, &card_id_flag);
return -EAGAIN;
}
if (offset && !is_valid_phy_addr((u64)offset) &&
!hinic_is_valid_bar_addr((u64)offset)) {
pr_err("offset is invalid\n");
+ clear_bit(HINIC_CARD_ID_USE, &card_id_flag);
return -EAGAIN;
}
/* old version of tool set vma->vm_pgoff to 0 */
phy_addr = offset ? offset : g_card_phy_addr[card_id];
-
+ clear_bit(HINIC_CARD_ID_USE, &card_id_flag);
if (!phy_addr) {
pr_err("Card_id = %d physical address is 0\n", card_id);
return -EAGAIN;
@@ -551,7 +557,7 @@ long dbgtool_knl_unlocked_ioctl(struct file *pfile,
struct dbgtool_param param;
struct dbgtool_k_glb_info *dbgtool_info;
struct card_node *card_info = NULL;
- int i;
+ int i, cnt = 0;
(void)memset(¶m, 0, sizeof(param));
@@ -573,7 +579,22 @@ long dbgtool_knl_unlocked_ioctl(struct file *pfile,
pr_err("Can't find this card %s\n", param.chip_name);
return -EFAULT;
}
- card_id = i;
+
+ while (cnt < 10) {
+ if (!test_and_set_bit(HINIC_CARD_ID_USE, &card_id_flag))
+ break;
+ usleep_range(500, 1000);
+ cnt++;
+ }
+
+ if (cnt < 10) {
+ card_id = i;
+ } else {
+ pr_err("Card id in using!\n");
+ clear_bit(HINIC_CARD_ID_USE, &card_id_flag);
+ return -EFAULT;
+ }
+
dbgtool_info = (struct dbgtool_k_glb_info *)card_info->dbgtool_info;
down(&dbgtool_info->dbgtool_sem);
--
2.31.0