* [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.