* [PATCH net-next v3] erspan: drop packets with an unknown ERSPAN version
@ 2026-11-08 19:35 Haishuang Yan
2026-11-09 11:37 ` netdev-bot+sashiko
0 siblings, 1 reply; 2+ messages in thread
From: Haishuang Yan @ 2026-11-08 19:35 UTC (permalink / raw)
To: netdev
Cc: David Ahern, Ido Schimmel, David S. Miller, Eric Dumazet,
Jakub Kicinski, Paolo Abeni, Simon Horman, William Tu,
linux-kernel
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, so it is
passed up as the start of the inner Ethernet frame, and in collect_md
mode the metadata is filled from the wrong part of the header. The
ETH_HLEN pull in __iptunnel_pull_header() still covers the bytes that
are copied, so nothing is read past the pulled data.
Reject such packets, as a packet with a truncated ERSPAN header already
is.
On IPv4, a packet with a 4-byte GRE header is taken as type I without
looking at the protocol. gre_parse_header() treats an ETH_P_ERSPAN2
packet as carrying an ERSPAN header whatever the GRE header length,
but erspan_rcv() then skips that header's version and passes it up as
the inner frame. Type I only uses ETH_P_ERSPAN, so check the protocol
too. Such a packet now goes through the type III path and its version
check.
Signed-off-by: Haishuang Yan <yanhaishuang@cmss.chinamobile.com>
---
Tested on net-next fa5196392691 (x86_64 KVM guest), with hand-built
GRE/ERSPAN packets sent over a veth into erspan and ip6erspan devices,
in plain and collect_md mode: version 0 packets and ERSPAN2 packets
with a 4-byte GRE header and version 0 or 3 are now dropped, version 1
and 2 packets are unchanged, and erspan v1/v2 ping over IPv4 and IPv6
still works.
v3:
- Also check the protocol when classifying a packet as type I, so that
an ETH_P_ERSPAN2 packet with a 4-byte GRE header gets the version
check too (Sashiko).
v2: https://lore.kernel.org/netdev/20261107130030.35220-1-yanhaishuang@cmss.chinamobile.com/
- Drop the Fixes tags and correct the commit message: the ETH_HLEN pull
of __iptunnel_pull_header() covers the metadata copy, so there is no
out of bounds read (Ido, Sashiko).
- Drop the patch that skipped the type III sub-header, as no device is
known to send it (Ido).
v1: https://lore.kernel.org/netdev/20261018090236.2487997-1-yanhaishuang@cmss.chinamobile.com/
net/ipv4/ip_gre.c | 12 +++++++-----
net/ipv6/ip6_gre.c | 3 +++
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 5485586fa0e6..f8a7c4353502 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -255,13 +255,13 @@ static void gre_err(struct sk_buff *skb, u32 info)
ipgre_err(skb, info, &tpi);
}
-static bool is_erspan_type1(int gre_hdr_len)
+static bool is_erspan_type1(const struct tnl_ptk_info *tpi, int gre_hdr_len)
{
/* Both ERSPAN type I (version 0) and type II (version 1) use
* protocol 0x88BE, but the type I has only 4-byte GRE header,
* while type II has 8-byte.
*/
- return gre_hdr_len == 4;
+ return tpi->proto == htons(ETH_P_ERSPAN) && gre_hdr_len == 4;
}
static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
@@ -282,7 +282,7 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
itn = net_generic(net, erspan_net_id);
iph = ip_hdr(skb);
- if (is_erspan_type1(gre_hdr_len)) {
+ if (is_erspan_type1(tpi, gre_hdr_len)) {
ver = 0;
__set_bit(IP_TUNNEL_NO_KEY_BIT, flags);
tunnel = ip_tunnel_lookup(itn, skb->dev->ifindex, flags,
@@ -301,10 +301,12 @@ static int erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
}
if (tunnel) {
- if (is_erspan_type1(gre_hdr_len))
+ if (is_erspan_type1(tpi, 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 b5d6ed8f0c36..46fac89a0743 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;
base-commit: fa5196392691051963726787944db872420dfa75
--
2.43.0
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH net-next v3] erspan: drop packets with an unknown ERSPAN version
2026-11-08 19:35 [PATCH net-next v3] erspan: drop packets with an unknown ERSPAN version Haishuang Yan
@ 2026-11-09 11:37 ` netdev-bot+sashiko
0 siblings, 0 replies; 2+ messages in thread
From: netdev-bot+sashiko @ 2026-11-09 11:37 UTC (permalink / raw)
To: yanhaishuang
Cc: netdev, dsahern, idosch, davem, edumazet, kuba, pabeni, horms,
witu, linux-kernel
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.
Critical: 0 · High: 0 · Medium: 1 · Low: 0
If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).
- [Medium] On IPv6, the new ERSPAN version check in ip6erspan_rcv()
(net/ipv6/ip6_gre.c) can read its version from the wrong bytes, so…
--
erspan: drop packets with an unknown ERSPAN version
This patch makes the IPv4 and IPv6 ERSPAN receive paths drop packets
whose ERSPAN version is not 1 (type II) or 2 (type III). On IPv4, it
also checks for ETH_P_ERSPAN when classifying a packet as type I, so a
4-byte-GRE ETH_P_ERSPAN2 packet now gets the version check too.
> diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
> index b5d6ed8f0c369..46fac89a07437 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;
> +
[Severity: Medium]
Can some type I packets still get through this check on IPv6?
gre_parse_header() treats an ETH_P_ERSPAN packet with a 4-byte GRE
header as type I, with no ERSPAN header. In that case it leaves
tpi->key at 0:
net/ipv4/gre_demux.c:gre_parse_header() {
...
if ((greh->protocol == htons(ETH_P_ERSPAN) && hdr_len != 4) ||
greh->protocol == htons(ETH_P_ERSPAN2)) {
...
}
The IPv6 gre_rcv() pulls the GRE header first. It then passes every
ETH_P_ERSPAN and ETH_P_ERSPAN2 packet to ip6erspan_rcv(), which has no
type I branch and reads the version straight from skb->data:
ershdr = (struct erspan_base_hdr *)skb->data;
ver = ershdr->ver;
For a 4-byte-GRE ETH_P_ERSPAN packet, ver is the high nibble of the
first byte of the inner Ethernet destination MAC. If that nibble is 1
or 2:
- the new check passes
- erspan_hdr_len(ver) strips 8 or 12 bytes of the real inner frame
- the tunnel lookup uses key 0 instead of a session ID
- in collect_md mode, erspan_metadata is filled from inner frame bytes
The commit message describes the version 0 case like this:
"passed up as the start of the inner Ethernet frame, and in
collect_md mode the metadata is filled from the wrong part of the
header"
This is the same symptom, with the offset wrong in the other
direction. Whether such a packet is dropped now depends on the inner
destination MAC. Nibbles 0 and 3-15 are rejected. Nibbles 1 and 2 are
accepted, and the frame is passed up from the wrong offset.
In v3, the IPv4 side was brought in line with gre_parse_header() by
checking tpi->proto in is_erspan_type1(). Would ip6erspan_rcv() need a
matching change? It could reject packets where tpi->proto ==
htons(ETH_P_ERSPAN) && gre_hdr_len == 4, since ip6erspan_tap_validate()
only allows versions 1 and 2 for IPv6 ERSPAN devices.
> if (unlikely(!pskb_may_pull(skb, len)))
> return PACKET_REJECT;
>
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261108193504.73393-1-yanhaishuang%40cmss.chinamobile.com
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-09 11:37 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-08 19:35 [PATCH net-next v3] erspan: drop packets with an unknown ERSPAN version Haishuang Yan
2026-11-09 11:37 ` netdev-bot+sashiko
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®