Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 0/2] erspan: fix two header parsing issues on receive
@ 2026-10-18  9:02 Haishuang Yan
  2026-10-18  9:02 ` [PATCH net-next 1/2] erspan: drop packets with an unknown ERSPAN version Haishuang Yan
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Haishuang Yan @ 2026-10-18  9:02 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, David Ahern, Ido Schimmel, William Tu, linux-kernel,
	Haishuang Yan

The ERSPAN type II and III receive paths, in ip_gre and ip6_gre, trust
the header more than they should:

Patch 1 drops packets whose ERSPAN version is neither 1 (type II) nor 2
(type III). With version 0 the ERSPAN header was passed up as the start
of the inner frame, and collect_md copied the metadata from bytes that
were not pulled. This is not urgent, so it goes to net-next with the
Fixes tags.

Patch 2 skips the optional platform specific sub-header of type III,
which follows the header when its O flag is set, as described in
draft-foschiano-erspan-03. Without it, the 8 bytes of sub-header ended
up at the start of the mirrored frame.

Both were checked with hand-built GRE/ERSPAN packets sent over a veth
into erspan and ip6erspan devices, in plain and collect_md mode: before
the series, the version 0 and the O flag packets come out corrupted;
after it, the first is dropped and the second comes out intact, and
type II and type III packets without the sub-header are unchanged. Ping
over erspan and ip6erspan, version 1 and 2, still works.

Haishuang Yan (2):
  erspan: drop packets with an unknown ERSPAN version
  erspan: skip the platform specific sub-header of ERSPAN type III

 include/net/erspan.h |  4 ++++
 net/ipv4/ip_gre.c    | 14 +++++++++++++-
 net/ipv6/ip6_gre.c   | 13 +++++++++++++
 3 files changed, 30 insertions(+), 1 deletion(-)

-- 
2.43.0




^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH net-next 1/2] erspan: drop packets with an unknown ERSPAN version
  2026-10-18  9:02 [PATCH net-next 0/2] erspan: fix two header parsing issues on receive Haishuang Yan
@ 2026-10-18  9:02 ` Haishuang Yan
  2026-10-18  9:02 ` [PATCH net-next 2/2] erspan: skip the platform specific sub-header of ERSPAN type III Haishuang Yan
  2026-10-18  9:09 ` [PATCH net-next 0/2] erspan: fix two header parsing issues on receive netdev-bot+sinfo
  2 siblings, 0 replies; 4+ messages in thread
From: Haishuang Yan @ 2026-10-18  9:02 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, David Ahern, Ido Schimmel, William Tu, linux-kernel,
	Haishuang Yan

The ERSPAN type II and III receive paths take the length of the ERSPAN
header from the version field of the packet, with erspan_hdr_len(), but
never check that the version is one they know: 1 for type II or 2 for
type III.

For any other version, erspan_hdr_len() returns 0 or the type III
length. With version 0, the ERSPAN header is not pulled at all, so it
is passed up as the start of the inner Ethernet frame, and in collect_md
mode the metadata is copied from 8 bytes after the base header, which
pskb_may_pull() did not cover.

Reject such packets, as a packet with a truncated ERSPAN header already
is.

Fixes: f551c91de262 ("net: erspan: introduce erspan v2 for ip_gre")
Fixes: 94d7d8f29287 ("ip6_gre: add erspan v2 support")

Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
---
 net/ipv4/ip_gre.c  | 4 +++-
 net/ipv6/ip6_gre.c | 3 +++
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 3ee437fa3eae..2f112c1edf7c 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -303,8 +303,10 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
 	if (tunnel) {
 		if (is_erspan_type1(gre_hdr_len))
 			len = gre_hdr_len;
-		else
+		else if (ver == ERSPAN_VERSION || ver == ERSPAN_VERSION2)
 			len = gre_hdr_len + erspan_hdr_len(ver);
+		else
+			return PACKET_REJECT;
 
 		if (unlikely(!pskb_may_pull(skb, len)))
 			return PACKET_REJECT;
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 3d08240ea00c..3fe395ed92f9 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -507,6 +507,9 @@ static int ip6erspan_rcv(struct sk_buff *skb,
 	if (tunnel) {
 		int len = erspan_hdr_len(ver);
 
+		if (unlikely(ver != ERSPAN_VERSION && ver != ERSPAN_VERSION2))
+			return PACKET_REJECT;
+
 		if (unlikely(!pskb_may_pull(skb, len)))
 			return PACKET_REJECT;
 
-- 
2.43.0




^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH net-next 2/2] erspan: skip the platform specific sub-header of ERSPAN type III
  2026-10-18  9:02 [PATCH net-next 0/2] erspan: fix two header parsing issues on receive Haishuang Yan
  2026-10-18  9:02 ` [PATCH net-next 1/2] erspan: drop packets with an unknown ERSPAN version Haishuang Yan
@ 2026-10-18  9:02 ` Haishuang Yan
  2026-10-18  9:09 ` [PATCH net-next 0/2] erspan: fix two header parsing issues on receive netdev-bot+sinfo
  2 siblings, 0 replies; 4+ messages in thread
From: Haishuang Yan @ 2026-10-18  9:02 UTC (permalink / raw)
  To: netdev
  Cc: David S . Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Simon Horman, David Ahern, Ido Schimmel, William Tu, linux-kernel,
	Haishuang Yan

The ERSPAN type III header has an O flag, which tells whether an
optional platform specific sub-header of 8 octets follows it. The
ERSPAN payload starts after that sub-header when the flag is set [1].

Linux never sets the flag on transmit, but it ignores it on receive
too. When a peer sends the sub-header, its 8 bytes are passed up as the
start of the mirrored Ethernet frame, so the frame is corrupted.

Pull the sub-header as well when the O flag is set. The collect_md
metadata still only carries the fixed part of the type III header.

[1] https://datatracker.ietf.org/doc/html/draft-foschiano-erspan-03

Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
---
 include/net/erspan.h |  4 ++++
 net/ipv4/ip_gre.c    | 10 ++++++++++
 net/ipv6/ip6_gre.c   | 10 ++++++++++
 3 files changed, 24 insertions(+)

diff --git a/include/net/erspan.h b/include/net/erspan.h
index c6209e7b6c96..0ef4338588c4 100644
--- a/include/net/erspan.h
+++ b/include/net/erspan.h
@@ -94,6 +94,10 @@ enum erspan_encap_type {
 
 #define ERSPAN_V1_MDSIZE	4
 #define ERSPAN_V2_MDSIZE	8
+/* Optional platform specific sub-header of ERSPAN type III, which follows
+ * the header when its O flag is set.
+ */
+#define ERSPAN_V2_SUBHDR_LEN	8
 
 struct erspan_base_hdr {
 #if defined(__LITTLE_ENDIAN_BITFIELD)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 2f112c1edf7c..b24ff0eca30b 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -311,6 +311,16 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
 		if (unlikely(!pskb_may_pull(skb, len)))
 			return PACKET_REJECT;
 
+		if (ver == ERSPAN_VERSION2) {
+			md2 = (struct erspan_md2 *)(skb->data + gre_hdr_len +
+						    sizeof(*ershdr));
+			if (md2->o) {
+				len += ERSPAN_V2_SUBHDR_LEN;
+				if (unlikely(!pskb_may_pull(skb, len)))
+					return PACKET_REJECT;
+			}
+		}
+
 		if (__iptunnel_pull_header(skb,
 					   len,
 					   htons(ETH_P_TEB),
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 3fe395ed92f9..c87a7198e5a8 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -513,6 +513,16 @@ static int ip6erspan_rcv(struct sk_buff *skb,
 		if (unlikely(!pskb_may_pull(skb, len)))
 			return PACKET_REJECT;
 
+		if (ver == ERSPAN_VERSION2) {
+			md2 = (struct erspan_md2 *)(skb->data +
+						    sizeof(*ershdr));
+			if (md2->o) {
+				len += ERSPAN_V2_SUBHDR_LEN;
+				if (unlikely(!pskb_may_pull(skb, len)))
+					return PACKET_REJECT;
+			}
+		}
+
 		if (__iptunnel_pull_header(skb, len,
 					   htons(ETH_P_TEB),
 					   false, false))
-- 
2.43.0




^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH net-next 0/2] erspan: fix two header parsing issues on receive
  2026-10-18  9:02 [PATCH net-next 0/2] erspan: fix two header parsing issues on receive Haishuang Yan
  2026-10-18  9:02 ` [PATCH net-next 1/2] erspan: drop packets with an unknown ERSPAN version Haishuang Yan
  2026-10-18  9:02 ` [PATCH net-next 2/2] erspan: skip the platform specific sub-header of ERSPAN type III Haishuang Yan
@ 2026-10-18  9:09 ` netdev-bot+sinfo
  2 siblings, 0 replies; 4+ messages in thread
From: netdev-bot+sinfo @ 2026-10-18  9:09 UTC (permalink / raw)
  To: Haishuang Yan
  Cc: netdev, David S . Miller, Eric Dumazet, Jakub Kicinski,
	Paolo Abeni, Simon Horman, David Ahern, Ido Schimmel, William Tu,
	linux-kernel

Hi!

This is an automated message. This series looks like a fix, but its
commit messages seem to be missing some information:

 - How the issue was discovered, e.g. hit in production, hit during
   development, syzbot report, manual code inspection, LLM or static
   analysis tool scan.

Please do not repost the series just to address the above. Instead,
reply to this email with the missing information, so that reviewers
can take it into account. If the series needs another revision for
other reasons, please include the information in the commit messages
then.

The evaluation is done by an LLM so it may be wrong, if you think
that is the case please reply and explain.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-18  9:09 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-18  9:02 [PATCH net-next 0/2] erspan: fix two header parsing issues on receive Haishuang Yan
2026-10-18  9:02 ` [PATCH net-next 1/2] erspan: drop packets with an unknown ERSPAN version Haishuang Yan
2026-10-18  9:02 ` [PATCH net-next 2/2] erspan: skip the platform specific sub-header of ERSPAN type III Haishuang Yan
2026-10-18  9:09 ` [PATCH net-next 0/2] erspan: fix two header parsing issues on receive netdev-bot+sinfo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox