net: hns3: fix for buffer overflow smatch warning
authorYunsheng Lin <linyunsheng@huawei.com>
Sat, 10 Mar 2018 03:29:29 +0000 (11:29 +0800)
committerDavid S. Miller <davem@davemloft.net>
Mon, 12 Mar 2018 02:53:32 +0000 (22:53 -0400)
This patch fixes the buffer overflow warning by refactoring
hclgevf_bind_ring_to_vector and hclge_get_ring_chain_from_mbx.

Fixes: e2cb1dec9779 ("net: hns3: Add HNS3 VF HCL(Hardware Compatibility Layer) Support")
Fixes: dde1a86e93ca ("net: hns3: Add mailbox support to PF driver")
Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: Peng Li <lipeng321@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hclge_mbx.h
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mbx.c
drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c

index 3e9203ea42a692b23f633793485a5030a69c2972..e6e1d221b5c81def262428eae7852ef4024ba77a 100644 (file)
@@ -57,6 +57,8 @@ enum hclge_mbx_vlan_cfg_subcode {
 
 #define HCLGE_MBX_MAX_MSG_SIZE 16
 #define HCLGE_MBX_MAX_RESP_DATA_SIZE   8
+#define HCLGE_MBX_RING_MAP_BASIC_MSG_NUM       3
+#define HCLGE_MBX_RING_NODE_VARIABLE_NUM       3
 
 struct hclgevf_mbx_resp_status {
        struct mutex mbx_mutex; /* protects against contending sync cmd resp */
index ed34ca3c3ea4cc7610791b9fa86c6570e34b742b..e3e4ded1e98fbc40a59c8c39a87a6617a5f1ed08 100644 (file)
@@ -105,14 +105,17 @@ static int hclge_get_ring_chain_from_mbx(
                        struct hnae3_ring_chain_node *ring_chain,
                        struct hclge_vport *vport)
 {
-#define HCLGE_RING_NODE_VARIABLE_NUM           3
-#define HCLGE_RING_MAP_MBX_BASIC_MSG_NUM       3
        struct hnae3_ring_chain_node *cur_chain, *new_chain;
        int ring_num;
        int i;
 
        ring_num = req->msg[2];
 
+       if (ring_num > ((HCLGE_MBX_VF_MSG_DATA_NUM -
+               HCLGE_MBX_RING_MAP_BASIC_MSG_NUM) /
+               HCLGE_MBX_RING_NODE_VARIABLE_NUM))
+               return -ENOMEM;
+
        hnae_set_bit(ring_chain->flag, HNAE3_RING_TYPE_B, req->msg[3]);
        ring_chain->tqp_index =
                        hclge_get_queue_id(vport->nic.kinfo.tqp[req->msg[4]]);
@@ -128,18 +131,18 @@ static int hclge_get_ring_chain_from_mbx(
                        goto err;
 
                hnae_set_bit(new_chain->flag, HNAE3_RING_TYPE_B,
-                            req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i +
-                            HCLGE_RING_MAP_MBX_BASIC_MSG_NUM]);
+                            req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i +
+                            HCLGE_MBX_RING_MAP_BASIC_MSG_NUM]);
 
                new_chain->tqp_index =
                hclge_get_queue_id(vport->nic.kinfo.tqp
-                       [req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i +
-                       HCLGE_RING_MAP_MBX_BASIC_MSG_NUM + 1]]);
+                       [req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i +
+                       HCLGE_MBX_RING_MAP_BASIC_MSG_NUM + 1]]);
 
                hnae_set_field(new_chain->int_gl_idx, HCLGE_INT_GL_IDX_M,
                               HCLGE_INT_GL_IDX_S,
-                              req->msg[HCLGE_RING_NODE_VARIABLE_NUM * i +
-                              HCLGE_RING_MAP_MBX_BASIC_MSG_NUM + 2]);
+                              req->msg[HCLGE_MBX_RING_NODE_VARIABLE_NUM * i +
+                              HCLGE_MBX_RING_MAP_BASIC_MSG_NUM + 2]);
 
                cur_chain->next = new_chain;
                cur_chain = new_chain;
index c80a604a545fe0047ce06a88a4803d0dc3d4515b..6c240d6463074e7aa67df9fd9a22d05120d68341 100644 (file)
@@ -533,13 +533,11 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
                                       int vector,
                                       struct hnae3_ring_chain_node *ring_chain)
 {
-#define HCLGEVF_RING_NODE_VARIABLE_NUM         3
-#define HCLGEVF_RING_MAP_MBX_BASIC_MSG_NUM     3
        struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle);
        struct hnae3_ring_chain_node *node;
        struct hclge_mbx_vf_to_pf_cmd *req;
        struct hclgevf_desc desc;
-       int i, vector_id;
+       int i = 0, vector_id;
        int status;
        u8 type;
 
@@ -551,28 +549,33 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
                return vector_id;
        }
 
-       hclgevf_cmd_setup_basic_desc(&desc, HCLGEVF_OPC_MBX_VF_TO_PF, false);
-       type = en ?
-               HCLGE_MBX_MAP_RING_TO_VECTOR : HCLGE_MBX_UNMAP_RING_TO_VECTOR;
-       req->msg[0] = type;
-       req->msg[1] = vector_id; /* vector_id should be id in VF */
-
-       i = 0;
        for (node = ring_chain; node; node = node->next) {
-               i++;
-               /* msg[2] is cause num */
-               req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i] =
+               int idx_offset = HCLGE_MBX_RING_MAP_BASIC_MSG_NUM +
+                                       HCLGE_MBX_RING_NODE_VARIABLE_NUM * i;
+
+               if (i == 0) {
+                       hclgevf_cmd_setup_basic_desc(&desc,
+                                                    HCLGEVF_OPC_MBX_VF_TO_PF,
+                                                    false);
+                       type = en ?
+                               HCLGE_MBX_MAP_RING_TO_VECTOR :
+                               HCLGE_MBX_UNMAP_RING_TO_VECTOR;
+                       req->msg[0] = type;
+                       req->msg[1] = vector_id;
+               }
+
+               req->msg[idx_offset] =
                                hnae_get_bit(node->flag, HNAE3_RING_TYPE_B);
-               req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i + 1] =
-                               node->tqp_index;
-               req->msg[HCLGEVF_RING_NODE_VARIABLE_NUM * i + 2] =
-                               hnae_get_field(node->int_gl_idx,
-                                              HNAE3_RING_GL_IDX_M,
-                                              HNAE3_RING_GL_IDX_S);
-
-               if (i == (HCLGE_MBX_VF_MSG_DATA_NUM -
-                   HCLGEVF_RING_MAP_MBX_BASIC_MSG_NUM) /
-                   HCLGEVF_RING_NODE_VARIABLE_NUM) {
+               req->msg[idx_offset + 1] = node->tqp_index;
+               req->msg[idx_offset + 2] = hnae_get_field(node->int_gl_idx,
+                                                         HNAE3_RING_GL_IDX_M,
+                                                         HNAE3_RING_GL_IDX_S);
+
+               i++;
+               if ((i == (HCLGE_MBX_VF_MSG_DATA_NUM -
+                    HCLGE_MBX_RING_MAP_BASIC_MSG_NUM) /
+                    HCLGE_MBX_RING_NODE_VARIABLE_NUM) ||
+                   !node->next) {
                        req->msg[2] = i;
 
                        status = hclgevf_cmd_send(&hdev->hw, &desc, 1);
@@ -591,17 +594,6 @@ static int hclgevf_bind_ring_to_vector(struct hnae3_handle *handle, bool en,
                }
        }
 
-       if (i > 0) {
-               req->msg[2] = i;
-
-               status = hclgevf_cmd_send(&hdev->hw, &desc, 1);
-               if (status) {
-                       dev_err(&hdev->pdev->dev,
-                               "Map TQP fail, status is %d.\n", status);
-                       return status;
-               }
-       }
-
        return 0;
 }