From patchwork Wed Jan 16 00:45:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Hu, Jiayu" X-Patchwork-Id: 49863 X-Patchwork-Delegate: thomas@monjalon.net Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 65DFF11C5; Wed, 16 Jan 2019 01:45:38 +0100 (CET) Received: from mga17.intel.com (mga17.intel.com [192.55.52.151]) by dpdk.org (Postfix) with ESMTP id 9FCC79E4; Wed, 16 Jan 2019 01:45:36 +0100 (CET) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga107.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 15 Jan 2019 16:45:35 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,484,1539673200"; d="scan'208";a="126358278" Received: from dpdk15.sh.intel.com ([10.67.111.146]) by orsmga002.jf.intel.com with ESMTP; 15 Jan 2019 16:45:34 -0800 From: Jiayu Hu To: dev@dpdk.org Cc: konstantin.ananyev@intel.com, thomas@monjalon.net, Jiayu Hu , stable@dpdk.org Date: Wed, 16 Jan 2019 08:45:33 +0800 Message-Id: <1547599533-124469-1-git-send-email-jiayu.hu@intel.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1547132768-2384-1-git-send-email-jiayu.hu@intel.com> References: <1547132768-2384-1-git-send-email-jiayu.hu@intel.com> Subject: [dpdk-dev] [PATCH v3] gro: add missing invalid TCP header length check 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" When the TCP header length of input packets is invalid (i.e., less than 20 bytes or greater than 60 bytes), check_seq_option() will access illegal memory area when compare TCP Options, which may cause a segmentation fault. This patch adds missing invalid TCP header length check to avoid illegal memory accesses. Fixes: 0d2cbe59b719 ("lib/gro: support TCP/IPv4") Fixes: 9e0b9d2ec0f4 ("gro: support VxLAN GRO") Cc: stable@dpdk.org Signed-off-by: Jiayu Hu Tested-by: Yinan Wang Acked-by: Konstantin Ananyev --- changes in v3: - remove l2 and l3 length checks - rename macro changes in v2: - fix VxLAN header length check bug for VxLAN GRO; - fix ethernet header length check bug; - use sizeof() and macro to present valid header length; - add VLAN related comments since GRO cannot process VLAN tagged packets. lib/librte_gro/gro_tcp4.c | 7 +++++++ lib/librte_gro/gro_tcp4.h | 5 +++++ lib/librte_gro/gro_vxlan_tcp4.c | 7 +++++++ 3 files changed, 19 insertions(+) diff --git a/lib/librte_gro/gro_tcp4.c b/lib/librte_gro/gro_tcp4.c index 2fe9aab..7d128a4 100644 --- a/lib/librte_gro/gro_tcp4.c +++ b/lib/librte_gro/gro_tcp4.c @@ -208,6 +208,13 @@ gro_tcp4_reassemble(struct rte_mbuf *pkt, int cmp; uint8_t find; + /* + * Don't process the packet whose TCP header length is greater + * than 60 bytes or less than 20 bytes. + */ + if (unlikely(INVALID_TCP_HDRLEN(pkt->l4_len))) + return -1; + eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *); ipv4_hdr = (struct ipv4_hdr *)((char *)eth_hdr + pkt->l2_len); tcp_hdr = (struct tcp_hdr *)((char *)ipv4_hdr + pkt->l3_len); diff --git a/lib/librte_gro/gro_tcp4.h b/lib/librte_gro/gro_tcp4.h index 6bb30cd..d979248 100644 --- a/lib/librte_gro/gro_tcp4.h +++ b/lib/librte_gro/gro_tcp4.h @@ -17,6 +17,11 @@ */ #define MAX_IPV4_PKT_LENGTH UINT16_MAX +/* The maximum TCP header length */ +#define MAX_TCP_HLEN 60 +#define INVALID_TCP_HDRLEN(len) \ + (((len) < sizeof(struct tcp_hdr)) || ((len) > MAX_TCP_HLEN)) + /* Header fields representing a TCP/IPv4 flow */ struct tcp4_flow_key { struct ether_addr eth_saddr; diff --git a/lib/librte_gro/gro_vxlan_tcp4.c b/lib/librte_gro/gro_vxlan_tcp4.c index 955ae4b..acb9bc9 100644 --- a/lib/librte_gro/gro_vxlan_tcp4.c +++ b/lib/librte_gro/gro_vxlan_tcp4.c @@ -306,6 +306,13 @@ gro_vxlan_tcp4_reassemble(struct rte_mbuf *pkt, uint16_t hdr_len; uint8_t find; + /* + * Don't process the packet whose TCP header length is greater + * than 60 bytes or less than 20 bytes. + */ + if (unlikely(INVALID_TCP_HDRLEN(pkt->l4_len))) + return -1; + outer_eth_hdr = rte_pktmbuf_mtod(pkt, struct ether_hdr *); outer_ipv4_hdr = (struct ipv4_hdr *)((char *)outer_eth_hdr + pkt->outer_l2_len);