All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net] ipv6: sr: restore network header before routing and forwarding
@ 2026-08-28 14:17 Eric Dumazet
  2026-08-30 11:21 ` Ido Schimmel
  0 siblings, 1 reply; 2+ messages in thread
From: Eric Dumazet @ 2026-08-28 14:17 UTC (permalink / raw)
  To: David S . Miller, Jakub Kicinski, Paolo Abeni
  Cc: Ido Schimmel, David Ahern, Simon Horman, netdev, eric.dumazet,
	Eric Dumazet, TencentOS Corvus AI, Jun Yang, Fourie Zhang

ipv6_srh_rcv() runs with skb->data at the Segment Routing Header (SRH)
while skb_network_header() points at the IPv6 header.

When segments_left > 0, ipv6_srh_rcv() previously restored the skb->data
position by pushing sizeof(struct ipv6hdr), assuming the SRH immediately
followed the fixed IPv6 header. If another extension header (such as a
Hop-by-Hop options header) precedes the SRH, skb_network_offset()
remained negative.

This led to two problems:
1. During ip6_route_input(), fib6_rules_early_flow_dissect() invokes
   __skb_flow_dissect() which passes the negative skb_network_offset()
   to flow dissection, breaking BPF and C flow dissector logic.
2. If forwarded via ip6_forward() or redirected via act_mirred, downstream
   handlers (like sch_fragment() or neighbour output) pass the negative
   offset as an unsigned length, triggering OOB memcpy or buffer overflows.

Fix this by pushing -skb_network_offset(skb) before routing, ensuring
skb_network_offset(skb) is 0 for route lookup / flow dissection as well as
downstream forwarding. On the loopback path, pull skb_transport_offset(skb)
to restore skb->data to the SRH before looping back.

Fixes: 1ababeba4a21 ("ipv6: implement dataplane support for rthdr type 4 (Segment Routing Header)")
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Reported-by: Jun Yang <junvyyang@tencent.com>
Reported-by: Fourie Zhang <fouriezhang@tencent.com>
Closes: https://lore.kernel.org/netdev/20260817104128.22681-1-juny24602@gmail.com/
Closes: https://lore.kernel.org/netdev/20260827092345.2301937-1-fouriezhang@tencent.com/
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
 net/ipv6/exthdrs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 51941ad656a36e739388c7da2fcd639ab0e453b5..09a4552f7f08aa8208eb981c0536c58a3561ecbd 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -445,7 +445,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb, struct inet6_dev *idev)
 	hdr->segments_left--;
 	addr = hdr->segments + hdr->segments_left;
 
-	skb_push(skb, sizeof(struct ipv6hdr));
+	skb_push(skb, -skb_network_offset(skb));
 
 	if (skb->ip_summed == CHECKSUM_COMPLETE)
 		seg6_update_csum(skb);
@@ -469,7 +469,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb, struct inet6_dev *idev)
 		}
 		ipv6_hdr(skb)->hop_limit--;
 
-		skb_pull(skb, sizeof(struct ipv6hdr));
+		skb_pull(skb, skb_transport_offset(skb));
 		goto looped_back;
 	}
 
-- 
2.55.0.897.gb25b4bd76c-goog


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

* Re: [PATCH net] ipv6: sr: restore network header before routing and forwarding
  2026-08-28 14:17 [PATCH net] ipv6: sr: restore network header before routing and forwarding Eric Dumazet
@ 2026-08-30 11:21 ` Ido Schimmel
  0 siblings, 0 replies; 2+ messages in thread
From: Ido Schimmel @ 2026-08-30 11:21 UTC (permalink / raw)
  To: Eric Dumazet
  Cc: David S . Miller, Jakub Kicinski, Paolo Abeni, David Ahern,
	Simon Horman, netdev, eric.dumazet, TencentOS Corvus AI, Jun Yang,
	Fourie Zhang

On Fri, Aug 28, 2026 at 02:17:27PM +0000, Eric Dumazet wrote:
> ipv6_srh_rcv() runs with skb->data at the Segment Routing Header (SRH)
> while skb_network_header() points at the IPv6 header.
> 
> When segments_left > 0, ipv6_srh_rcv() previously restored the skb->data
> position by pushing sizeof(struct ipv6hdr), assuming the SRH immediately
> followed the fixed IPv6 header. If another extension header (such as a
> Hop-by-Hop options header) precedes the SRH, skb_network_offset()
> remained negative.
> 
> This led to two problems:
> 1. During ip6_route_input(), fib6_rules_early_flow_dissect() invokes
>    __skb_flow_dissect() which passes the negative skb_network_offset()
>    to flow dissection, breaking BPF and C flow dissector logic.
> 2. If forwarded via ip6_forward() or redirected via act_mirred, downstream
>    handlers (like sch_fragment() or neighbour output) pass the negative
>    offset as an unsigned length, triggering OOB memcpy or buffer overflows.
> 
> Fix this by pushing -skb_network_offset(skb) before routing, ensuring
> skb_network_offset(skb) is 0 for route lookup / flow dissection as well as
> downstream forwarding. On the loopback path, pull skb_transport_offset(skb)
> to restore skb->data to the SRH before looping back.
> 
> Fixes: 1ababeba4a21 ("ipv6: implement dataplane support for rthdr type 4 (Segment Routing Header)")
> Reported-by: TencentOS Corvus AI <corvus@tencent.com>
> Reported-by: Jun Yang <junvyyang@tencent.com>
> Reported-by: Fourie Zhang <fouriezhang@tencent.com>
> Closes: https://lore.kernel.org/netdev/20260817104128.22681-1-juny24602@gmail.com/
> Closes: https://lore.kernel.org/netdev/20260827092345.2301937-1-fouriezhang@tencent.com/
> Signed-off-by: Eric Dumazet <edumazet@google.com>

Reviewed-by: Ido Schimmel <idosch@nvidia.com>

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

end of thread, other threads:[~2026-08-30 11:21 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-28 14:17 [PATCH net] ipv6: sr: restore network header before routing and forwarding Eric Dumazet
2026-08-30 11:21 ` Ido Schimmel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.