From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id DE477A0C47 for ; Mon, 26 Jul 2021 15:54:40 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D89EB40F35; Mon, 26 Jul 2021 15:54:40 +0200 (CEST) Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) by mails.dpdk.org (Postfix) with ESMTP id BC889410F0 for ; Mon, 26 Jul 2021 15:54:37 +0200 (CEST) Received: by mail-wm1-f44.google.com with SMTP id k14-20020a05600c1c8eb02901f13dd1672aso54042wms.0 for ; Mon, 26 Jul 2021 06:54:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=tW5fc8AJbkdtWYmq0IZggBugmWaKhCnGOa+oAeRvDuM=; b=K+MiatabYt/ydapBAU7H3re1KbR3BB1kTJO6mCTNkIOqR+VM3qzBqGA55NDcdCfQWY UURgR3Fl8TaxRtzebRtjQJhtsGTzzAt128SZWjMWUmdYA5xklDXjfIyUSiRZLLp82WoW CsGl9CsRKOTc1z6dviqO2T69ca9titCJKcMGfnRp4nOHbFsoDGeOlc0IZqUOTQEdf3RT h7eZ82RW5UJoFKALKk/lCw62+0EJK4OzMwWveXYg53Pud5uZZ+MRi6sGWdJH1IKBOCRF yE0gG7CGVXDdc/L/hbHssPRWPQt2Zwb52RVIOe1+w1hWNySc0suW4/1lRcw4PR/9pAQt ZfqA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=tW5fc8AJbkdtWYmq0IZggBugmWaKhCnGOa+oAeRvDuM=; b=THYv/FD5S9zRyzQdWI3vlqCB1eGpx0tq/oJva6pGt8IPhSAEmdbWiwHTpVI10C4sdx O4/K1krrEevzzoDHhrTRLhYtrEuM97DIEhZiMCJhvJBmEkD7OkhdJu13rb50g91oo8Lj dhGN29ZxLIOt+nhMjQjXaI4ZHPRp7MqyYe6THebkxNgLJOgqzW+B7wRuSdM99W5pvnF2 eRkcAVQSd559Ne9p/y48J+T5drUecnfybvDLldSgRLyYkMrQAA9FQySKE0LPkt1g3XI2 5GgwQYRQ3BL3QLx1RQt/V82TOuoLuN1ANcJpow/uZY6YYQ35rSZlhO4krPMCWKk7FDGk vyJg== X-Gm-Message-State: AOAM532bJuKW+XisvcSsnsXrHhuLE/DgcvINpsk0duW164X7/oEIC9ww pTRbcW2F5RtDrKnIjkAJzls= X-Google-Smtp-Source: ABdhPJwNcfkDXOXpS0ui2lQMohV5umsZkz0omOJQcFcjGnrhbSCpopIA9/DTjLNtWlUPW+HRZF6K+w== X-Received: by 2002:a1c:9851:: with SMTP id a78mr1260034wme.123.1627307677496; Mon, 26 Jul 2021 06:54:37 -0700 (PDT) Received: from localhost ([137.220.125.106]) by smtp.gmail.com with ESMTPSA id n5sm41321856wri.31.2021.07.26.06.54.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Jul 2021 06:54:37 -0700 (PDT) From: luca.boccassi@gmail.com To: Xiao Wang Cc: Maxime Coquelin , dpdk stable Date: Mon, 26 Jul 2021 14:52:45 +0100 Message-Id: <20210726135322.149850-22-luca.boccassi@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210726135322.149850-1-luca.boccassi@gmail.com> References: <20210712130551.2462159-1-luca.boccassi@gmail.com> <20210726135322.149850-1-luca.boccassi@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-stable] patch 'vhost: check header for legacy dequeue offload' has been queued to stable release 20.11.3 X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" Hi, FYI, your patch has been queued to stable release 20.11.3 Note it hasn't been pushed to http://dpdk.org/browse/dpdk-stable yet. It will be pushed if I get no objections before 07/28/21. So please shout if anyone has objections. Also note that after the patch there's a diff of the upstream commit vs the patch applied to the branch. This will indicate if there was any rebasing needed to apply to the stable branch. If there were code changes for rebasing (ie: not only metadata diffs), please double check that the rebase was correctly done. Queued patches are on a temporary branch at: https://github.com/bluca/dpdk-stable This queued commit can be viewed at: https://github.com/bluca/dpdk-stable/commit/2df90802c6f7cd84fa91ba3552d31c2fc5ca5270 Thanks. Luca Boccassi --- >From 2df90802c6f7cd84fa91ba3552d31c2fc5ca5270 Mon Sep 17 00:00:00 2001 From: Xiao Wang Date: Mon, 21 Jun 2021 16:21:04 +0800 Subject: [PATCH] vhost: check header for legacy dequeue offload [ upstream commit 706ba48665844b859fcf0bd9526ec5da28b915da ] When parsing the virtio net header and packet header for dequeue offload, we need to perform sanity check on the packet header to ensure: - No out-of-boundary memory access. - The packet header and virtio_net header are valid and aligned. Fixes: d0cf91303d73 ("vhost: add Tx offload capabilities") Signed-off-by: Xiao Wang Reviewed-by: Maxime Coquelin --- lib/librte_vhost/virtio_net.c | 117 ++++++++++++++++++++++++++-------- 1 file changed, 89 insertions(+), 28 deletions(-) diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c index 6c7c0b0f0e..e165a70afc 100644 --- a/lib/librte_vhost/virtio_net.c +++ b/lib/librte_vhost/virtio_net.c @@ -1797,14 +1797,17 @@ virtio_net_with_host_offload(struct virtio_net *dev) return false; } -static void -parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr) +static int +parse_headers(struct rte_mbuf *m, uint8_t *l4_proto) { struct rte_ipv4_hdr *ipv4_hdr; struct rte_ipv6_hdr *ipv6_hdr; - void *l3_hdr = NULL; struct rte_ether_hdr *eth_hdr; uint16_t ethertype; + uint16_t data_len = rte_pktmbuf_data_len(m); + + if (data_len < sizeof(struct rte_ether_hdr)) + return -EINVAL; eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *); @@ -1812,6 +1815,10 @@ parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr) ethertype = rte_be_to_cpu_16(eth_hdr->ether_type); if (ethertype == RTE_ETHER_TYPE_VLAN) { + if (data_len < sizeof(struct rte_ether_hdr) + + sizeof(struct rte_vlan_hdr)) + goto error; + struct rte_vlan_hdr *vlan_hdr = (struct rte_vlan_hdr *)(eth_hdr + 1); @@ -1819,70 +1826,118 @@ parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr) ethertype = rte_be_to_cpu_16(vlan_hdr->eth_proto); } - l3_hdr = (char *)eth_hdr + m->l2_len; - switch (ethertype) { case RTE_ETHER_TYPE_IPV4: - ipv4_hdr = l3_hdr; - *l4_proto = ipv4_hdr->next_proto_id; + if (data_len < m->l2_len + sizeof(struct rte_ipv4_hdr)) + goto error; + ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv4_hdr *, + m->l2_len); m->l3_len = rte_ipv4_hdr_len(ipv4_hdr); - *l4_hdr = (char *)l3_hdr + m->l3_len; + if (data_len < m->l2_len + m->l3_len) + goto error; m->ol_flags |= PKT_TX_IPV4; + *l4_proto = ipv4_hdr->next_proto_id; break; case RTE_ETHER_TYPE_IPV6: - ipv6_hdr = l3_hdr; - *l4_proto = ipv6_hdr->proto; + if (data_len < m->l2_len + sizeof(struct rte_ipv6_hdr)) + goto error; + ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct rte_ipv6_hdr *, + m->l2_len); m->l3_len = sizeof(struct rte_ipv6_hdr); - *l4_hdr = (char *)l3_hdr + m->l3_len; m->ol_flags |= PKT_TX_IPV6; + *l4_proto = ipv6_hdr->proto; break; default: - m->l3_len = 0; - *l4_proto = 0; - *l4_hdr = NULL; + /* a valid L3 header is needed for further L4 parsing */ + goto error; + } + + /* both CSUM and GSO need a valid L4 header */ + switch (*l4_proto) { + case IPPROTO_TCP: + if (data_len < m->l2_len + m->l3_len + + sizeof(struct rte_tcp_hdr)) + goto error; + break; + case IPPROTO_UDP: + if (data_len < m->l2_len + m->l3_len + + sizeof(struct rte_udp_hdr)) + goto error; break; + case IPPROTO_SCTP: + if (data_len < m->l2_len + m->l3_len + + sizeof(struct rte_sctp_hdr)) + goto error; + break; + default: + goto error; } + + return 0; + +error: + m->l2_len = 0; + m->l3_len = 0; + m->ol_flags = 0; + return -EINVAL; } static __rte_always_inline void vhost_dequeue_offload_legacy(struct virtio_net_hdr *hdr, struct rte_mbuf *m) { - uint16_t l4_proto = 0; - void *l4_hdr = NULL; + uint8_t l4_proto = 0; struct rte_tcp_hdr *tcp_hdr = NULL; + uint16_t tcp_len; + uint16_t data_len = rte_pktmbuf_data_len(m); + + if (parse_headers(m, &l4_proto) < 0) + return; - parse_ethernet(m, &l4_proto, &l4_hdr); if (hdr->flags == VIRTIO_NET_HDR_F_NEEDS_CSUM) { if (hdr->csum_start == (m->l2_len + m->l3_len)) { switch (hdr->csum_offset) { case (offsetof(struct rte_tcp_hdr, cksum)): - if (l4_proto == IPPROTO_TCP) - m->ol_flags |= PKT_TX_TCP_CKSUM; + if (l4_proto != IPPROTO_TCP) + goto error; + m->ol_flags |= PKT_TX_TCP_CKSUM; break; case (offsetof(struct rte_udp_hdr, dgram_cksum)): - if (l4_proto == IPPROTO_UDP) - m->ol_flags |= PKT_TX_UDP_CKSUM; + if (l4_proto != IPPROTO_UDP) + goto error; + m->ol_flags |= PKT_TX_UDP_CKSUM; break; case (offsetof(struct rte_sctp_hdr, cksum)): - if (l4_proto == IPPROTO_SCTP) - m->ol_flags |= PKT_TX_SCTP_CKSUM; + if (l4_proto != IPPROTO_SCTP) + goto error; + m->ol_flags |= PKT_TX_SCTP_CKSUM; break; default: - break; + goto error; } + } else { + goto error; } } - if (l4_hdr && hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { + if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) { switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) { case VIRTIO_NET_HDR_GSO_TCPV4: case VIRTIO_NET_HDR_GSO_TCPV6: - tcp_hdr = l4_hdr; + if (l4_proto != IPPROTO_TCP) + goto error; + tcp_hdr = rte_pktmbuf_mtod_offset(m, + struct rte_tcp_hdr *, + m->l2_len + m->l3_len); + tcp_len = (tcp_hdr->data_off & 0xf0) >> 2; + if (data_len < m->l2_len + m->l3_len + tcp_len) + goto error; m->ol_flags |= PKT_TX_TCP_SEG; m->tso_segsz = hdr->gso_size; - m->l4_len = (tcp_hdr->data_off & 0xf0) >> 2; + m->l4_len = tcp_len; break; case VIRTIO_NET_HDR_GSO_UDP: + if (l4_proto != IPPROTO_UDP) + goto error; m->ol_flags |= PKT_TX_UDP_SEG; m->tso_segsz = hdr->gso_size; m->l4_len = sizeof(struct rte_udp_hdr); @@ -1890,9 +1945,15 @@ vhost_dequeue_offload_legacy(struct virtio_net_hdr *hdr, struct rte_mbuf *m) default: VHOST_LOG_DATA(WARNING, "unsupported gso type %u.\n", hdr->gso_type); - break; + goto error; } } + return; + +error: + m->l2_len = 0; + m->l3_len = 0; + m->ol_flags = 0; } static __rte_always_inline void -- 2.30.2 --- Diff of the applied patch vs upstream commit (please double-check if non-empty: --- --- - 2021-07-26 13:53:17.007293391 +0100 +++ 0022-vhost-check-header-for-legacy-dequeue-offload.patch 2021-07-26 13:53:15.841292454 +0100 @@ -1 +1 @@ -From 706ba48665844b859fcf0bd9526ec5da28b915da Mon Sep 17 00:00:00 2001 +From 2df90802c6f7cd84fa91ba3552d31c2fc5ca5270 Mon Sep 17 00:00:00 2001 @@ -5,0 +6,2 @@ +[ upstream commit 706ba48665844b859fcf0bd9526ec5da28b915da ] + @@ -12 +13,0 @@ -Cc: stable@dpdk.org @@ -17 +18 @@ - lib/vhost/virtio_net.c | 117 +++++++++++++++++++++++++++++++---------- + lib/librte_vhost/virtio_net.c | 117 ++++++++++++++++++++++++++-------- @@ -20,5 +21,5 @@ -diff --git a/lib/vhost/virtio_net.c b/lib/vhost/virtio_net.c -index b93482587c..aa30d147b6 100644 ---- a/lib/vhost/virtio_net.c -+++ b/lib/vhost/virtio_net.c -@@ -2259,14 +2259,17 @@ virtio_net_with_host_offload(struct virtio_net *dev) +diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c +index 6c7c0b0f0e..e165a70afc 100644 +--- a/lib/librte_vhost/virtio_net.c ++++ b/lib/librte_vhost/virtio_net.c +@@ -1797,14 +1797,17 @@ virtio_net_with_host_offload(struct virtio_net *dev) @@ -45 +46 @@ -@@ -2274,6 +2277,10 @@ parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr) +@@ -1812,6 +1815,10 @@ parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr) @@ -56 +57 @@ -@@ -2281,70 +2288,118 @@ parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr) +@@ -1819,70 +1826,118 @@ parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr) @@ -199 +200 @@ -@@ -2352,9 +2407,15 @@ vhost_dequeue_offload_legacy(struct virtio_net_hdr *hdr, struct rte_mbuf *m) +@@ -1890,9 +1945,15 @@ vhost_dequeue_offload_legacy(struct virtio_net_hdr *hdr, struct rte_mbuf *m)