From patchwork Mon Dec 2 07:49:24 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Xiaolong Ye X-Patchwork-Id: 63486 X-Patchwork-Delegate: xiaolong.ye@intel.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from dpdk.org (dpdk.org [92.243.14.124]) by inbox.dpdk.org (Postfix) with ESMTP id BA52CA04B5; Mon, 2 Dec 2019 09:07:17 +0100 (CET) Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 072DC1C138; Mon, 2 Dec 2019 08:59:26 +0100 (CET) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by dpdk.org (Postfix) with ESMTP id 18E601C0D1 for ; Mon, 2 Dec 2019 08:59:10 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga008.fm.intel.com ([10.253.24.58]) by orsmga101.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 01 Dec 2019 23:59:10 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.69,268,1571727600"; d="scan'208";a="207993709" Received: from dpdk_yexl_af_xdp.sh.intel.com ([10.67.119.186]) by fmsmga008.fm.intel.com with ESMTP; 01 Dec 2019 23:59:09 -0800 From: Xiaolong Ye To: Beilei Xing , Qi Zhang Cc: dev@dpdk.org, Xiaolong Ye , Sergey Nemov Date: Mon, 2 Dec 2019 15:49:24 +0800 Message-Id: <20191202074935.97629-59-xiaolong.ye@intel.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20191202074935.97629-1-xiaolong.ye@intel.com> References: <20191202074935.97629-1-xiaolong.ye@intel.com> Subject: [dpdk-dev] [PATCH 58/69] net/i40e/base: add limits for nested structures X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" The following virtchnl opcodes operate with structures with nested structures in them which can possible lead to overflow if number of nested structures would be too big. VIRTCHNL_OP_CONFIG_VSI_QUEUES VIRTCHNL_OP_CONFIG_IRQ_MAP VIRTCHNL_OP_ADD_ETH_ADDR VIRTCHNL_OP_DEL_ETH_ADDR VIRTCHNL_OP_ADD_VLAN VIRTCHNL_OP_DEL_VLAN VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP VIRTCHNL_OP_ENABLE_CHANNELS Since message from VF is limited by u16, precalculate the maximum numbers of nested structures which can possibly be sent through virtual channel and exit with error if VF tries to send us more than the maximum limit. This is only a sanity check of the VF message length. Each driver should additionally check these numbers to fit the hardware capabilities. Signed-off-by: Sergey Nemov Reviewed-by: Kirsher Jeffrey T Signed-off-by: Xiaolong Ye --- drivers/net/i40e/base/virtchnl.h | 76 ++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/drivers/net/i40e/base/virtchnl.h b/drivers/net/i40e/base/virtchnl.h index c3495ab39..6384ded7d 100644 --- a/drivers/net/i40e/base/virtchnl.h +++ b/drivers/net/i40e/base/virtchnl.h @@ -719,6 +719,38 @@ VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_iwarp_qvlist_info); #endif +/* Since VF messages are limited by u16 size, precalculate the maximum possible + * values of nested elements in virtchnl structures that virtual channel can + * possibly handle in a single message. + */ +enum virtchnl_vector_limits { + VIRTCHNL_OP_CONFIG_VSI_QUEUES_MAX = + ((u16)(~0) - sizeof(struct virtchnl_vsi_queue_config_info)) / + sizeof(struct virtchnl_queue_pair_info), + + VIRTCHNL_OP_CONFIG_IRQ_MAP_MAX = + ((u16)(~0) - sizeof(struct virtchnl_irq_map_info)) / + sizeof(struct virtchnl_vector_map), + + VIRTCHNL_OP_ADD_DEL_ETH_ADDR_MAX = + ((u16)(~0) - sizeof(struct virtchnl_ether_addr_list)) / + sizeof(struct virtchnl_ether_addr), + + VIRTCHNL_OP_ADD_DEL_VLAN_MAX = + ((u16)(~0) - sizeof(struct virtchnl_vlan_filter_list)) / + sizeof(u16), + +#ifdef VIRTCHNL_IWARP + VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP_MAX = + ((u16)(~0) - sizeof(struct virtchnl_iwarp_qvlist_info)) / + sizeof(struct virtchnl_iwarp_qv_info), +#endif + + VIRTCHNL_OP_ENABLE_CHANNELS_MAX = + ((u16)(~0) - sizeof(struct virtchnl_tc_info)) / + sizeof(struct virtchnl_channel_info), +}; + /* VF reset states - these are written into the RSTAT register: * VFGEN_RSTAT on the VF * When the PF initiates a reset, it writes 0 @@ -1130,6 +1162,13 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode, if (msglen >= valid_len) { struct virtchnl_vsi_queue_config_info *vqc = (struct virtchnl_vsi_queue_config_info *)msg; + + if (vqc->num_queue_pairs > + VIRTCHNL_OP_CONFIG_VSI_QUEUES_MAX) { + err_msg_format = true; + break; + } + valid_len += (vqc->num_queue_pairs * sizeof(struct virtchnl_queue_pair_info)); @@ -1142,8 +1181,16 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode, if (msglen >= valid_len) { struct virtchnl_irq_map_info *vimi = (struct virtchnl_irq_map_info *)msg; + + if (vimi->num_vectors > + VIRTCHNL_OP_CONFIG_IRQ_MAP_MAX) { + err_msg_format = true; + break; + } + valid_len += (vimi->num_vectors * sizeof(struct virtchnl_vector_map)); + if (vimi->num_vectors == 0) err_msg_format = true; } @@ -1158,6 +1205,13 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode, if (msglen >= valid_len) { struct virtchnl_ether_addr_list *veal = (struct virtchnl_ether_addr_list *)msg; + + if (veal->num_elements > + VIRTCHNL_OP_ADD_DEL_ETH_ADDR_MAX) { + err_msg_format = true; + break; + } + valid_len += veal->num_elements * sizeof(struct virtchnl_ether_addr); if (veal->num_elements == 0) @@ -1170,7 +1224,15 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode, if (msglen >= valid_len) { struct virtchnl_vlan_filter_list *vfl = (struct virtchnl_vlan_filter_list *)msg; + + if (vfl->num_elements > + VIRTCHNL_OP_ADD_DEL_VLAN_MAX) { + err_msg_format = true; + break; + } + valid_len += vfl->num_elements * sizeof(u16); + if (vfl->num_elements == 0) err_msg_format = true; } @@ -1199,6 +1261,13 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode, if (msglen >= valid_len) { struct virtchnl_iwarp_qvlist_info *qv = (struct virtchnl_iwarp_qvlist_info *)msg; + + if (qv->num_vectors > + VIRTCHNL_OP_CONFIG_IWARP_IRQ_MAP_MAX) { + err_msg_format = true; + break; + } + if (qv->num_vectors == 0) { err_msg_format = true; break; @@ -1240,6 +1309,13 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode, if (msglen >= valid_len) { struct virtchnl_tc_info *vti = (struct virtchnl_tc_info *)msg; + + if (vti->num_tc > + VIRTCHNL_OP_ENABLE_CHANNELS_MAX) { + err_msg_format = true; + break; + } + valid_len += (vti->num_tc - 1) * sizeof(struct virtchnl_channel_info); if (vti->num_tc == 0)