From: Shaozhengchao shaozhengchao@huawei.com
driver inclusion category:bugfix bugzilla:4472 CVE:NA
-----------------------------------------------------------------------
hinic driver code compliance rectification. 1.Process return value of snprintf and sscanf function. 2.Modify devil number.
Signed-off-by: Shaozhengchao shaozhengchao@huawei.com Reviewed-by: Luoshaokai luoshaokai@huawei.com Signed-off-by: Yang Yingliang yangyingliang@huawei.com --- .../net/ethernet/huawei/hinic/hinic_dbgtool_knl.c | 4 +- drivers/net/ethernet/huawei/hinic/hinic_eqs.c | 24 +++++++--- drivers/net/ethernet/huawei/hinic/hinic_ethtool.c | 56 +++++++++++++++++----- drivers/net/ethernet/huawei/hinic/hinic_hwdev.c | 53 ++++++++++++++------ drivers/net/ethernet/huawei/hinic/hinic_lld.c | 48 ++++++++++++++----- drivers/net/ethernet/huawei/hinic/hinic_main.c | 11 ++++- drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c | 8 +++- drivers/net/ethernet/huawei/hinic/hinic_nictool.c | 12 +++-- 8 files changed, 165 insertions(+), 51 deletions(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c index 1c9c469..535f41a 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_dbgtool_knl.c @@ -768,7 +768,7 @@ int dbgtool_knl_init(void *vhwdev, void *chip_node) 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; } @@ -874,7 +874,7 @@ void dbgtool_knl_deinit(void *vhwdev, void *chip_node) return;
err = sscanf(chip_info->chip_name, HINIC_CHIP_NAME "%d", &id); - if (err < 0) + if (err <= 0) pr_err("Failed to get hinic id\n");
g_card_node_array[id] = NULL; diff --git a/drivers/net/ethernet/huawei/hinic/hinic_eqs.c b/drivers/net/ethernet/huawei/hinic/hinic_eqs.c index 4b2b0c0..3fee9fb 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_eqs.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_eqs.c @@ -1133,15 +1133,27 @@ static int init_eq(struct hinic_eq *eq, struct hinic_hwdev *hwdev, u16 q_id, }
if (type == HINIC_AEQ) { - snprintf(eq->irq_name, sizeof(eq->irq_name), - "hinic_aeq%d@pci:%s", eq->q_id, - pci_name(hwdev->pcidev_hdl)); + err = snprintf(eq->irq_name, sizeof(eq->irq_name), + "hinic_aeq%d@pci:%s", eq->q_id, + pci_name(hwdev->pcidev_hdl)); + if (err <= 0 || err >= (int)sizeof(eq->irq_name)) { + pr_err("Failed snprintf irq_name, function return(%d) and dest_len(%d)\n", + err, (int)sizeof(eq->irq_name)); + err = -EINVAL; + goto req_irq_err; + } err = request_irq(entry->irq_id, aeq_interrupt, 0UL, eq->irq_name, eq); } else { - snprintf(eq->irq_name, sizeof(eq->irq_name), - "hinic_ceq%d@pci:%s", eq->q_id, - pci_name(hwdev->pcidev_hdl)); + err = snprintf(eq->irq_name, sizeof(eq->irq_name), + "hinic_ceq%d@pci:%s", eq->q_id, + pci_name(hwdev->pcidev_hdl)); + if (err <= 0 || err >= (int)sizeof(eq->irq_name)) { + pr_err("Failed snprintf irq_name, function return(%d) and dest_len(%d)\n", + err, (int)sizeof(eq->irq_name)); + err = -EINVAL; + goto req_irq_err; + } err = request_irq(entry->irq_id, ceq_interrupt, 0UL, eq->irq_name, eq); } diff --git a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c index 37d8d38..ac711da 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_ethtool.c @@ -294,12 +294,15 @@ u32 hinic_get_io_stats_size(struct hinic_nic_dev *nic_dev) }
#define QUEUE_STATS_PACK(items, item_idx, array, stats_ptr, qid) { \ - int j; \ + int j, err; \ for (j = 0; j < ARRAY_LEN(array); j++) { \ memcpy((items)[item_idx].name, (array)[j].name, \ HINIC_SHOW_ITEM_LEN); \ - snprintf((items)[item_idx].name, HINIC_SHOW_ITEM_LEN, \ + err = snprintf((items)[item_idx].name, HINIC_SHOW_ITEM_LEN,\ (array)[j].name, (qid)); \ + if (err <= 0 || err >= HINIC_SHOW_ITEM_LEN) \ + pr_err("Failed snprintf: func_ret(%d), dest_len(%d)\n",\ + err, HINIC_SHOW_ITEM_LEN); \ (items)[item_idx].hexadecimal = 0; \ (items)[item_idx].value = \ GET_VALUE_OF_PTR((array)[j].size, \ @@ -335,6 +338,8 @@ void hinic_get_io_stats(struct hinic_nic_dev *nic_dev,
#define LP_DEFAULT_TIME (5) /* seconds */ #define LP_PKT_LEN (1514) +#define OBJ_STR_MAX_LEN (32) +#define SET_LINK_STR_MAX_LEN (128)
#define PORT_DOWN_ERR_IDX 0 enum diag_test_index { @@ -743,16 +748,28 @@ static int hinic_set_settings_to_hw(struct hinic_nic_dev *nic_dev, struct net_device *netdev = nic_dev->netdev; struct hinic_link_ksettings settings = {0}; enum nic_speed_level speed_level = 0; - char set_link_str[128] = {0}; + char set_link_str[SET_LINK_STR_MAX_LEN] = {0}; int err = 0;
- snprintf(set_link_str, sizeof(set_link_str), "%s", - (set_settings & HILINK_LINK_SET_AUTONEG) ? - (autoneg ? "autong enable " : "autong disable ") : ""); + err = snprintf(set_link_str, sizeof(set_link_str), "%s", + (set_settings & HILINK_LINK_SET_AUTONEG) ? + (autoneg ? "autong enable " : "autong disable ") : ""); + if (err < 0 || err >= SET_LINK_STR_MAX_LEN) { + nicif_err(nic_dev, drv, netdev, + "Failed snprintf link state, function return(%d) and dest_len(%d)\n", + err, SET_LINK_STR_MAX_LEN); + return -EFAULT; + } if (set_settings & HILINK_LINK_SET_SPEED) { speed_level = hinic_ethtool_to_hw_speed_level(speed); - snprintf(set_link_str, sizeof(set_link_str), - "%sspeed %d ", set_link_str, speed); + err = snprintf(set_link_str, sizeof(set_link_str), + "%sspeed %d ", set_link_str, speed); + if (err <= 0 || err >= SET_LINK_STR_MAX_LEN) { + nicif_err(nic_dev, drv, netdev, + "Failed snprintf link speed, function return(%d) and dest_len(%d)\n", + err, SET_LINK_STR_MAX_LEN); + return -EFAULT; + } }
settings.valid_bitmap = set_settings; @@ -883,7 +900,12 @@ static void hinic_get_drvinfo(struct net_device *netdev, return; }
- snprintf(info->fw_version, sizeof(info->fw_version), "%s", mgmt_ver); + err = snprintf(info->fw_version, sizeof(info->fw_version), + "%s", mgmt_ver); + if (err <= 0 || err >= (int)sizeof(info->fw_version)) + nicif_err(nic_dev, drv, netdev, + "Failed snprintf fw_version, function return(%d) and dest_len(%d)\n", + err, (int)sizeof(info->fw_version)); }
static u32 hinic_get_msglevel(struct net_device *netdev) @@ -1429,10 +1451,22 @@ static int __hinic_set_coalesce(struct net_device *netdev,
if (queue == COALESCE_ALL_QUEUE) { ori_intr_coal = &nic_dev->intr_coalesce[0]; - snprintf(obj_str, sizeof(obj_str), "for netdev"); + err = snprintf(obj_str, sizeof(obj_str), "for netdev"); + if (err <= 0 || err >= OBJ_STR_MAX_LEN) { + nicif_err(nic_dev, drv, netdev, + "Failed snprintf string, function return(%d) and dest_len(%d)\n", + err, OBJ_STR_MAX_LEN); + return -EFAULT; + } } else { ori_intr_coal = &nic_dev->intr_coalesce[queue]; - snprintf(obj_str, sizeof(obj_str), "for queue %d", queue); + err = snprintf(obj_str, sizeof(obj_str), "for queue %d", queue); + if (err <= 0 || err >= OBJ_STR_MAX_LEN) { + nicif_err(nic_dev, drv, netdev, + "Failed snprintf string, function return(%d) and dest_len(%d)\n", + err, OBJ_STR_MAX_LEN); + return -EFAULT; + } } CHECK_COALESCE_CHANGED(coal, rx_coalesce_usecs, COALESCE_TIMER_CFG_UNIT, ori_intr_coal->coalesce_timer_cfg, obj_str); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hwdev.c b/drivers/net/ethernet/huawei/hinic/hinic_hwdev.c index a31bb6c..c2454f6 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_hwdev.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_hwdev.c @@ -519,6 +519,9 @@ static inline void __set_heartbeat_ehd_detect_delay(struct hinic_hwdev *hwdev, #define HINIC_QUEUE_MAX_DEPTH 12 #define HINIC_MAX_RX_BUFFER_SIZE 15
+#define CAP_INFO_MAC_LEN 512 +#define VENDOR_MAX_LEN 17 + static bool check_root_ctxt(struct hinic_hwdev *hwdev, u16 func_idx, void *buf_in, u16 in_size) { @@ -3891,6 +3894,7 @@ static void __print_cable_info(struct hinic_hwdev *hwdev, char tmp_vendor[17] = {0}; char *port_type = "Unknown port type"; int i; + int err = 0;
if (info->cable_absent) { sdk_info(hwdev->dev_hdl, "Cable unpresent\n"); @@ -3918,24 +3922,45 @@ static void __print_cable_info(struct hinic_hwdev *hwdev,
memcpy(tmp_vendor, info->vendor_name, sizeof(info->vendor_name)); - snprintf(tmp_str, sizeof(tmp_str) - 1, - "Vendor: %s, %s, length: %um, max_speed: %uGbps", - tmp_vendor, port_type, info->cable_length, - info->cable_max_speed); + err = snprintf(tmp_str, sizeof(tmp_str), + "Vendor: %s, %s, length: %um, max_speed: %uGbps", + tmp_vendor, port_type, info->cable_length, + info->cable_max_speed); + if (err <= 0 || err >= CAP_INFO_MAC_LEN) { + sdk_err(hwdev->dev_hdl, + "Failed snprintf cable vendor info, function return(%d) and dest_len(%d)\n", + err, CAP_INFO_MAC_LEN); + return; + } + if (info->port_type == LINK_PORT_FIBRE || info->port_type == LINK_PORT_AOC) { - snprintf(tmp_str, sizeof(tmp_str) - 1, - "%s, %s, Temperature: %u", tmp_str, - info->sfp_type ? "SFP" : "QSFP", info->cable_temp); + err = snprintf(tmp_str, sizeof(tmp_str), + "%s, %s, Temperature: %u", tmp_str, + info->sfp_type ? "SFP" : "QSFP", + info->cable_temp); + if (err <= 0 || err >= CAP_INFO_MAC_LEN) { + sdk_err(hwdev->dev_hdl, + "Failed snprintf cable Temp, function return(%d) and dest_len(%d)\n", + err, CAP_INFO_MAC_LEN); + return; + } + if (info->sfp_type) { - snprintf(tmp_str, sizeof(tmp_str) - 1, - "%s, rx power: %uuW, tx power: %uuW", - tmp_str, info->power[0], info->power[1]); + err = snprintf(tmp_str, sizeof(tmp_str), + "%s, rx power: %uuW, tx power: %uuW", + tmp_str, info->power[0], info->power[1]); } else { - snprintf(tmp_str, sizeof(tmp_str) - 1, - "%s, rx power: %uuw %uuW %uuW %uuW", - tmp_str, info->power[0], info->power[1], - info->power[2], info->power[3]); + err = snprintf(tmp_str, sizeof(tmp_str), + "%s, rx power: %uuw %uuW %uuW %uuW", + tmp_str, info->power[0], info->power[1], + info->power[2], info->power[3]); + } + if (err <= 0 || err >= CAP_INFO_MAC_LEN) { + sdk_err(hwdev->dev_hdl, + "Failed snprintf power info, function return(%d) and dest_len(%d)\n", + err, CAP_INFO_MAC_LEN); + return; } }
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_lld.c b/drivers/net/ethernet/huawei/hinic/hinic_lld.c index 357e050..8a2f280 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_lld.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_lld.c @@ -629,6 +629,7 @@ static void hinic_ignore_minor_version(char *version) { char ver_split[MAX_VER_SPLIT_NUM][MAX_VER_FIELD_LEN] = { {0} }; int max_ver_len, split_num = 0; + int err;
__version_split(version, &split_num, ver_split); if (split_num != MAX_VER_SPLIT_NUM) @@ -637,8 +638,11 @@ static void hinic_ignore_minor_version(char *version) max_ver_len = (int)strlen(version) + 1; memset(version, 0, max_ver_len);
- snprintf(version, max_ver_len, "%s.%s.%s.0", - ver_split[0], ver_split[1], ver_split[2]); + err = snprintf(version, max_ver_len, "%s.%s.%s.0", + ver_split[0], ver_split[1], ver_split[2]); + if (err <= 0 || err >= max_ver_len) + pr_err("Failed snprintf version, function return(%d) and dest_len(%d)\n", + err, max_ver_len); }
static int hinic_detect_version_compatible(struct hinic_pcidev *pcidev) @@ -1152,7 +1156,7 @@ void hinic_get_all_chip_id(void *id_info) lld_dev_hold(); list_for_each_entry(chip_node, &g_hinic_chip_list, node) { err = sscanf(chip_node->chip_name, HINIC_CHIP_NAME "%d", &id); - if (err < 0) + if (err <= 0) pr_err("Failed to get hinic id\n");
card_id->id[i] = id; @@ -1895,6 +1899,7 @@ static int alloc_chip_node(struct hinic_pcidev *pci_adapter) struct card_node *chip_node; unsigned char i; unsigned char parent_bus_number = 0; + int err;
if (!pci_is_root_bus(pci_adapter->pcidev->bus)) parent_bus_number = pci_adapter->pcidev->bus->parent->number; @@ -1931,27 +1936,39 @@ static int alloc_chip_node(struct hinic_pcidev *pci_adapter)
chip_node = kzalloc(sizeof(*chip_node), GFP_KERNEL); if (!chip_node) { - card_bit_map = CLEAR_BIT(card_bit_map, i); sdk_err(&pci_adapter->pcidev->dev, "Failed to alloc chip node\n"); - return -ENOMEM; + goto alloc_chip_err; }
chip_node->dbgtool_attr_file.name = kzalloc(IFNAMSIZ, GFP_KERNEL); if (!(chip_node->dbgtool_attr_file.name)) { - kfree(chip_node); - card_bit_map = CLEAR_BIT(card_bit_map, i); sdk_err(&pci_adapter->pcidev->dev, "Failed to alloc dbgtool attr file name\n"); - return -ENOMEM; + goto alloc_dbgtool_attr_file_err; }
/* parent bus number */ chip_node->dp_bus_num = parent_bus_number;
- snprintf(chip_node->chip_name, IFNAMSIZ, "%s%d", HINIC_CHIP_NAME, i); - snprintf((char *)chip_node->dbgtool_attr_file.name, - IFNAMSIZ, "%s%d", HINIC_CHIP_NAME, i); + err = snprintf(chip_node->chip_name, IFNAMSIZ, "%s%d", + HINIC_CHIP_NAME, i); + if (err <= 0 || err >= IFNAMSIZ) { + sdk_err(&pci_adapter->pcidev->dev, + "Failed snprintf chip_name, function return(%d) and dest_len(%d)\n", + err, IFNAMSIZ); + goto alloc_dbgtool_attr_file_err; + } + + err = snprintf((char *)chip_node->dbgtool_attr_file.name, + IFNAMSIZ, "%s%d", HINIC_CHIP_NAME, i); + if (err <= 0 || err >= IFNAMSIZ) { + sdk_err(&pci_adapter->pcidev->dev, + "Failed snprintf dbgtool_attr_file_name, function return(%d) and dest_len(%d)\n", + err, IFNAMSIZ); + goto alloc_dbgtool_attr_file_err; + } + sdk_info(&pci_adapter->pcidev->dev, "Add new chip %s to global list succeed\n", chip_node->chip_name); @@ -1962,6 +1979,13 @@ static int alloc_chip_node(struct hinic_pcidev *pci_adapter) pci_adapter->chip_node = chip_node;
return 0; + +alloc_dbgtool_attr_file_err: + kfree(chip_node); + +alloc_chip_err: + card_bit_map = CLEAR_BIT(card_bit_map, i); + return -ENOMEM; }
static void free_chip_node(struct hinic_pcidev *pci_adapter) @@ -1976,7 +2000,7 @@ static void free_chip_node(struct hinic_pcidev *pci_adapter) "Delete chip %s from global list succeed\n", chip_node->chip_name); err = sscanf(chip_node->chip_name, HINIC_CHIP_NAME "%u", &id); - if (err < 0) + if (err <= 0) sdk_err(&pci_adapter->pcidev->dev, "Failed to get hinic id\n");
card_bit_map = CLEAR_BIT(card_bit_map, id); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_main.c b/drivers/net/ethernet/huawei/hinic/hinic_main.c index 5960603..9b53a6f 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_main.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_main.c @@ -750,8 +750,15 @@ static int hinic_qps_irq_init(struct hinic_nic_dev *nic_dev) cpumask_set_cpu(local_cpu, &irq_cfg->affinity_mask); }
- snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name), - "%s_qp%d", nic_dev->netdev->name, q_id); + err = snprintf(irq_cfg->irq_name, sizeof(irq_cfg->irq_name), + "%s_qp%d", nic_dev->netdev->name, q_id); + if (err <= 0 || err >= (int)sizeof(irq_cfg->irq_name)) { + nic_err(&pdev->dev, + "Failed snprintf irq_name, function return(%d) and dest_len(%d)\n", + err, (int)sizeof(irq_cfg->irq_name)); + goto req_tx_irq_err; + } + err = hinic_request_irq(irq_cfg, q_id); if (err) { nicif_err(nic_dev, drv, nic_dev->netdev, "Failed to request Rx irq\n"); diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c b/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c index 8d89d30..cac0cdb 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_nic_cfg.c @@ -2175,7 +2175,13 @@ int hinic_get_mgmt_version(void *hwdev, u8 *mgmt_ver) return -EINVAL; }
- snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver); + err = snprintf(mgmt_ver, HINIC_MGMT_VERSION_MAX_LEN, "%s", up_ver.ver); + if (err <= 0 || err >= HINIC_MGMT_VERSION_MAX_LEN) { + nic_err(dev->dev_hdl, + "Failed snprintf fw version, function return(%d) and dest_len(%d)\n", + err, HINIC_MGMT_VERSION_MAX_LEN); + return -EINVAL; + }
return 0; } diff --git a/drivers/net/ethernet/huawei/hinic/hinic_nictool.c b/drivers/net/ethernet/huawei/hinic/hinic_nictool.c index 9a2cb00..46dd9ec 100644 --- a/drivers/net/ethernet/huawei/hinic/hinic_nictool.c +++ b/drivers/net/ethernet/huawei/hinic/hinic_nictool.c @@ -1179,14 +1179,20 @@ static int get_drv_version(void *hwdev, void *buf_in, u32 in_size, { struct drv_version_info *ver_info; char ver_str[MAX_VER_INFO_LEN] = {0}; + int err;
if (*out_size != sizeof(*ver_info)) { pr_err("Unexpect out buf size from user :%d, expect: %lu\n", *out_size, sizeof(*ver_info)); return -EFAULT; } - snprintf(ver_str, sizeof(ver_str), "%s [compiled with the kernel]", - HINIC_DRV_VERSION); + err = snprintf(ver_str, sizeof(ver_str), + "%s [compiled with the kernel]", HINIC_DRV_VERSION); + if (err <= 0 || err >= MAX_VER_INFO_LEN) { + pr_err("Failed snprintf driver version, function return(%d) and dest_len(%d)\n", + err, MAX_VER_INFO_LEN); + return -EFAULT; + } ver_info = (struct drv_version_info *)buf_out; memcpy(ver_info->ver, ver_str, sizeof(ver_str));
@@ -1420,7 +1426,7 @@ static int get_card_func_info(char *dev_name, struct msg_module *nt_msg) }
err = sscanf(dev_name, HINIC_CHIP_NAME "%d", &id); - if (err < 0) { + if (err <= 0) { pr_err("Failed to get hinic id\n"); return err; }