From: Shaozhengchao <shaozhengchao(a)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(a)huawei.com>
Reviewed-by: Luoshaokai <luoshaokai(a)huawei.com>
Signed-off-by: Yang Yingliang <yangyingliang(a)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;
}
--
1.8.3