Netdev List
 help / color / mirror / Atom feed
* [PATCH net] net: gro: compare skb->protocol in gro_list_prepare()
@ 2026-11-06 19:51 Eric Dumazet
  2026-11-06 20:21 ` Willem de Bruijn
  2026-11-07 20:28 ` netdev-bot+sashiko
  0 siblings, 2 replies; 4+ messages in thread
From: Eric Dumazet @ 2026-11-06 19:51 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Kuniyuki Iwashima, Willem de Bruijn, Simon Horman, netdev,
	Eric Dumazet, Kyle Zeng

gro_list_prepare() checks whether a held packet may belong to the same
flow as the incoming one by comparing the device, VLAN tag, metadata
and the link-layer header, using dev->hard_header_len as its length.

On devices without a link-layer header (hard_header_len == 0), such as
L3 GRE tunnels, no compared byte carries the outer protocol:
skb->protocol comes from the tunnel header. Packets of different
protocols can then stay eligible, and the GRO handler selected from the
incoming skb->protocol parses the held packet with the wrong layout.

For example, take an IPv4/UDP packet held by UDP GRO and a
VLAN/IPv4/TCP packet received on the same ipgre device.
vlan_gro_receive() reads the first four bytes of the held IPv4 header
as a VLAN header. With crafted values, the held packet survives up to
tcp_gro_receive(), which uses its UDP header as a TCP header. With a
short linear part, the FIN/PSH update of the held packet's TCP flags
can then write into skb_shared_info.

Nested GRO handlers (VLAN, GRE, IPv4, IPv6) already compare their own
next-protocol field. Only the outermost protocol was not checked.

Compare skb->protocol too. On Ethernet devices this is redundant with
compare_ether_header(), but it is cheap.

Fixes: 60769a5dcd87 ("ipv4: gre: add GRO capability")
Reported-by: Kyle Zeng <kylebot@openai.com>
Signed-off-by: Eric Dumaze <edumazet@kernel.org>
---
This issue was discovered by an AI code review agent. It has not been
triggered, and the fix was only compile-tested.

 net/core/gro.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/net/core/gro.c b/net/core/gro.c
index 1b033855a20db6b8b996179f0b81e38393d3864a..08e4731ddb7e6e371790d70a97db2cedad420706 100644
--- a/net/core/gro.c
+++ b/net/core/gro.c
@@ -374,6 +374,7 @@ static void gro_list_prepare(const struct list_head *head,
 		}
 
 		diffs = (unsigned long)p->dev ^ (unsigned long)skb->dev;
+		diffs |= p->protocol != skb->protocol;
 		diffs |= p->vlan_all ^ skb->vlan_all;
 		diffs |= skb_metadata_differs(p, skb);
 		if (maclen == ETH_HLEN)
-- 
2.53.0


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

end of thread, other threads:[~2026-11-09 16:37 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-06 19:51 [PATCH net] net: gro: compare skb->protocol in gro_list_prepare() Eric Dumazet
2026-11-06 20:21 ` Willem de Bruijn
2026-11-07 20:28 ` netdev-bot+sashiko
2026-11-09 16:37   ` Eric Dumazet

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