mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH net v2] net: gro: avoid parsing headers from shared fragments
@ 2026-10-31  5:07 Kyle Zeng
  2026-11-10 18:23 ` patchwork-bot+netdevbpf
  0 siblings, 1 reply; 2+ messages in thread
From: Kyle Zeng @ 2026-10-31  5:07 UTC (permalink / raw)
  To: netdev; +Cc: edumazet, davem, linux-kernel, outbounddisclosures

When an skb has an empty linear head, skb_gro_reset_offset() can expose
the first page fragment directly to GRO header parsers. For an
SKBFL_SHARED_FRAG skb, those bytes may still be writable through a file
mapping. Headers validated during receive can therefore differ from the
headers later copied into the linear head and used during completion.

For example, changing an IPv6 destination-options length between the
short and full header fetches in ipv6_gro_pull_exthdrs() can make
ipv6_gro_complete() pass an out-of-bounds offset to udp6_gro_complete().
A userspace reproducer triggered a KASAN slab-out-of-bounds read there
on an unmodified kernel as UID 1000. The same completion path can write
the UDP checksum and length through the invalid offset. The packet has
trusted TCP GSO metadata and spliced file data, so it reaches completion
without an skb zerocopy destructor or a second GRO packet.

Disable the direct-fragment fast path for skbs with externally writable
fragments. With an empty linear head, frag0_len remains zero, so
skb_gro_header_slow() pulls each required header into the linear head
before it is inspected. Subsequent pulls preserve the validated prefix.
This covers both gro_receive_skb() and napi_gro_frags(), including other
protocols using the same helpers. Linear headers and private fragments
retain their existing fast paths.

Codex assisted with review of the supplied report, reproducer and draft
fix, related-path analysis, and this changelog. The patched
net/core/gro.o builds with W=1 using the supplied x86-64 configuration,
allyesconfig and allmodconfig. The fix was checked by code-path analysis;
the reproducer and kernel selftests have not been run on a booted
patched kernel.

The issue was found by an LLM.

Fixes: dff0b0161ad5 ("net: gro: parse ipv6 ext headers without frag0 invalidation")
Cc: stable@kernel.org
Signed-off-by: Kyle Zeng <kylebot@openai.com>
---
I have a reproducer for this issue.

v2:
- add Fixes tag
- explain that the issue was found by LLM

v1: https://lore.kernel.org/netdev/20261030042212.73949-1-kylebot@openai.com/

 net/core/gro.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/core/gro.c b/net/core/gro.c
index 1b033855a20d..d6cf2d497934 100644
--- a/net/core/gro.c
+++ b/net/core/gro.c
@@ -413,7 +413,8 @@ static inline void skb_gro_reset_offset(struct sk_buff *skb, u32 nhoff)
 	headlen = skb_headlen(skb);
 	NAPI_GRO_CB(skb)->frag0 = skb->data;
 	NAPI_GRO_CB(skb)->frag0_len = headlen;
-	if (headlen)
+	/* Shared fragments must be pulled into the linear head before parsing. */
+	if (headlen || skb_has_shared_frag(skb))
 		return;
 
 	pinfo = skb_shinfo(skb);

base-commit: 2a500a04d6f969318c05f46aedb6e73fc1963a00
-- 
2.55.0.openai.911.g06873a30d2f3


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

* Re: [PATCH net v2] net: gro: avoid parsing headers from shared fragments
  2026-10-31  5:07 [PATCH net v2] net: gro: avoid parsing headers from shared fragments Kyle Zeng
@ 2026-11-10 18:23 ` patchwork-bot+netdevbpf
  0 siblings, 0 replies; 2+ messages in thread
From: patchwork-bot+netdevbpf @ 2026-11-10 18:23 UTC (permalink / raw)
  To: Kyle Zeng; +Cc: netdev, edumazet, davem, linux-kernel, outbounddisclosures

Hello:

This patch was applied to netdev/net.git (main)
by Jakub Kicinski <kuba@kernel.org>:

On Fri, 30 Oct 2026 22:07:52 -0700 you wrote:
> When an skb has an empty linear head, skb_gro_reset_offset() can expose
> the first page fragment directly to GRO header parsers. For an
> SKBFL_SHARED_FRAG skb, those bytes may still be writable through a file
> mapping. Headers validated during receive can therefore differ from the
> headers later copied into the linear head and used during completion.
> 
> For example, changing an IPv6 destination-options length between the
> short and full header fetches in ipv6_gro_pull_exthdrs() can make
> ipv6_gro_complete() pass an out-of-bounds offset to udp6_gro_complete().
> A userspace reproducer triggered a KASAN slab-out-of-bounds read there
> on an unmodified kernel as UID 1000. The same completion path can write
> the UDP checksum and length through the invalid offset. The packet has
> trusted TCP GSO metadata and spliced file data, so it reaches completion
> without an skb zerocopy destructor or a second GRO packet.
> 
> [...]

Here is the summary with links:
  - [net,v2] net: gro: avoid parsing headers from shared fragments
    https://git.kernel.org/netdev/net/c/44818c9a826d

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

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

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-31  5:07 [PATCH net v2] net: gro: avoid parsing headers from shared fragments Kyle Zeng
2026-11-10 18:23 ` patchwork-bot+netdevbpf

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®