linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org
Cc: "Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
	stable@vger.kernel.org,
	"Toshiaki Makita" <toshiaki.makita1@gmail.com>,
	"Daniel Borkmann" <daniel@iogearbox.net>,
	"Toke Høiland-Jørgensen" <toke@redhat.com>,
	"David S. Miller" <davem@davemloft.net>,
	"Sasha Levin" <sashal@kernel.org>
Subject: [PATCH 4.4 14/39] vlan: consolidate VLAN parsing code and limit max parsing depth
Date: Thu, 10 Dec 2020 15:26:25 +0100	[thread overview]
Message-ID: <20201210142601.602997730@linuxfoundation.org> (raw)
In-Reply-To: <20201210142600.887734129@linuxfoundation.org>

From: Toke Høiland-Jørgensen <toke@redhat.com>

[ Upstream commit 469aceddfa3ed16e17ee30533fae45e90f62efd8 ]

Toshiaki pointed out that we now have two very similar functions to extract
the L3 protocol number in the presence of VLAN tags. And Daniel pointed out
that the unbounded parsing loop makes it possible for maliciously crafted
packets to loop through potentially hundreds of tags.

Fix both of these issues by consolidating the two parsing functions and
limiting the VLAN tag parsing to a max depth of 8 tags. As part of this,
switch over __vlan_get_protocol() to use skb_header_pointer() instead of
pskb_may_pull(), to avoid the possible side effects of the latter and keep
the skb pointer 'const' through all the parsing functions.

v2:
- Use limit of 8 tags instead of 32 (matching XMIT_RECURSION_LIMIT)

Reported-by: Toshiaki Makita <toshiaki.makita1@gmail.com>
Reported-by: Daniel Borkmann <daniel@iogearbox.net>
Fixes: d7bf2ebebc2b ("sched: consistently handle layer3 header accesses in the presence of VLANs")
Signed-off-by: Toke Høiland-Jørgensen <toke@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
 include/linux/if_vlan.h | 29 ++++++++++++++++++++++-------
 include/net/inet_ecn.h  |  1 +
 2 files changed, 23 insertions(+), 7 deletions(-)

diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index dd676ba758ee7..40429b818b457 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -30,6 +30,8 @@
 #define VLAN_ETH_DATA_LEN	1500	/* Max. octets in payload	 */
 #define VLAN_ETH_FRAME_LEN	1518	/* Max. octets in frame sans FCS */
 
+#define VLAN_MAX_DEPTH	8		/* Max. number of nested VLAN tags parsed */
+
 /*
  * 	struct vlan_hdr - vlan header
  * 	@h_vlan_TCI: priority and VLAN ID
@@ -478,10 +480,10 @@ static inline int vlan_get_tag(const struct sk_buff *skb, u16 *vlan_tci)
  * Returns the EtherType of the packet, regardless of whether it is
  * vlan encapsulated (normal or hardware accelerated) or not.
  */
-static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type,
+static inline __be16 __vlan_get_protocol(const struct sk_buff *skb, __be16 type,
 					 int *depth)
 {
-	unsigned int vlan_depth = skb->mac_len;
+	unsigned int vlan_depth = skb->mac_len, parse_depth = VLAN_MAX_DEPTH;
 
 	/* if type is 802.1Q/AD then the header should already be
 	 * present at mac_len - VLAN_HLEN (if mac_len > 0), or at
@@ -496,13 +498,12 @@ static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type,
 			vlan_depth = ETH_HLEN;
 		}
 		do {
-			struct vlan_hdr *vh;
+			struct vlan_hdr vhdr, *vh;
 
-			if (unlikely(!pskb_may_pull(skb,
-						    vlan_depth + VLAN_HLEN)))
+			vh = skb_header_pointer(skb, vlan_depth, sizeof(vhdr), &vhdr);
+			if (unlikely(!vh || !--parse_depth))
 				return 0;
 
-			vh = (struct vlan_hdr *)(skb->data + vlan_depth);
 			type = vh->h_vlan_encapsulated_proto;
 			vlan_depth += VLAN_HLEN;
 		} while (type == htons(ETH_P_8021Q) ||
@@ -522,11 +523,25 @@ static inline __be16 __vlan_get_protocol(struct sk_buff *skb, __be16 type,
  * Returns the EtherType of the packet, regardless of whether it is
  * vlan encapsulated (normal or hardware accelerated) or not.
  */
-static inline __be16 vlan_get_protocol(struct sk_buff *skb)
+static inline __be16 vlan_get_protocol(const struct sk_buff *skb)
 {
 	return __vlan_get_protocol(skb, skb->protocol, NULL);
 }
 
+/* A getter for the SKB protocol field which will handle VLAN tags consistently
+ * whether VLAN acceleration is enabled or not.
+ */
+static inline __be16 skb_protocol(const struct sk_buff *skb, bool skip_vlan)
+{
+	if (!skip_vlan)
+		/* VLAN acceleration strips the VLAN header from the skb and
+		 * moves it to skb->vlan_proto
+		 */
+		return skb_vlan_tag_present(skb) ? skb->vlan_proto : skb->protocol;
+
+	return vlan_get_protocol(skb);
+}
+
 static inline void vlan_set_encap_proto(struct sk_buff *skb,
 					struct vlan_hdr *vhdr)
 {
diff --git a/include/net/inet_ecn.h b/include/net/inet_ecn.h
index dce2d586d9cec..245d999c0eac8 100644
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -3,6 +3,7 @@
 
 #include <linux/ip.h>
 #include <linux/skbuff.h>
+#include <linux/if_vlan.h>
 
 #include <net/inet_sock.h>
 #include <net/dsfield.h>
-- 
2.27.0




  parent reply	other threads:[~2020-12-10 20:17 UTC|newest]

Thread overview: 49+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-10 14:26 [PATCH 4.4 00/39] 4.4.248-rc1 review Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 01/39] net/af_iucv: set correct sk_protocol for child sockets Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 02/39] rose: Fix Null pointer dereference in rose_send_frame() Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 03/39] usbnet: ipheth: fix connectivity with iOS 14 Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 04/39] bonding: wait for sysfs kobject destruction before freeing struct slave Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 05/39] netfilter: bridge: reset skb->pkt_type after NF_INET_POST_ROUTING traversal Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 06/39] net/x25: prevent a couple of overflows Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 07/39] cxgb3: fix error return code in t3_sge_alloc_qset() Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 08/39] net: pasemi: fix error return code in pasemi_mac_open() Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 09/39] dt-bindings: net: correct interrupt flags in examples Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 10/39] Input: xpad - support Ardwiino Controllers Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 11/39] Input: i8042 - add ByteSpeed touchpad to noloop table Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 12/39] powerpc: Stop exporting __clear_user which is now inlined Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 13/39] btrfs: sysfs: init devices outside of the chunk_mutex Greg Kroah-Hartman
2020-12-10 14:26 ` Greg Kroah-Hartman [this message]
2020-12-10 14:26 ` [PATCH 4.4 15/39] geneve: pull IP header before ECN decapsulation Greg Kroah-Hartman
2020-12-10 14:32   ` Eric Dumazet
2020-12-10 14:38     ` Greg Kroah-Hartman
2020-12-10 14:40       ` Greg Kroah-Hartman
2020-12-10 14:53         ` Eric Dumazet
2020-12-10 15:36           ` Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 16/39] usb: gadget: f_fs: Use local copy of descriptors for userspace copy Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 17/39] USB: serial: kl5kusb105: fix memleak on open Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 18/39] USB: serial: ch341: add new Product ID for CH341A Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 19/39] USB: serial: ch341: sort device-id entries Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 20/39] USB: serial: option: add Fibocom NL668 variants Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 21/39] USB: serial: option: add support for Thales Cinterion EXS82 Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 22/39] tty: Fix ->pgrp locking in tiocspgrp() Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 23/39] ALSA: hda/realtek - Add new codec supported for ALC897 Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 24/39] ALSA: hda/generic: Add option to enforce preferred_dacs pairs Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 25/39] tty: Fix ->session locking Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 26/39] cifs: fix potential use-after-free in cifs_echo_request() Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 27/39] i2c: imx: Fix reset of I2SR_IAL flag Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 28/39] i2c: imx: Check for I2SR_IAL after every byte Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 29/39] arm64: assembler: make adr_l work in modules under KASLR Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 30/39] iommu/amd: Set DTE[IntTabLen] to represent 512 IRTEs Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 31/39] spi: Introduce device-managed SPI controller allocation Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 32/39] spi: bcm2835: Fix use-after-free on unbind Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 33/39] spi: bcm2835: Release the DMA channel if probe fails after dma_init Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 34/39] tracing: Fix userstacktrace option for instances Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 35/39] btrfs: cleanup cow block on error Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 36/39] mm/userfaultfd: do not access vma->vm_mm after calling handle_userfault() Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 37/39] gfs2: check for empty rgrp tree in gfs2_ri_update Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 38/39] Input: i8042 - fix error return code in i8042_setup_aux() Greg Kroah-Hartman
2020-12-10 14:26 ` [PATCH 4.4 39/39] x86/uprobes: Do not use prefixes.nbytes when looping over prefixes.bytes Greg Kroah-Hartman
2020-12-10 20:37 ` [PATCH 4.4 00/39] 4.4.248-rc1 review Pavel Machek
2020-12-10 21:24 ` Shuah Khan
2020-12-11  0:05 ` Guenter Roeck
2020-12-11 12:06 ` Naresh Kamboju

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201210142601.602997730@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=daniel@iogearbox.net \
    --cc=davem@davemloft.net \
    --cc=linux-kernel@vger.kernel.org \
    --cc=sashal@kernel.org \
    --cc=stable@vger.kernel.org \
    --cc=toke@redhat.com \
    --cc=toshiaki.makita1@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).