public inbox for netdev@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH net] ipv6: rpl: expand skb head when recompressed SRH grows, not only on last segment
@ 2026-04-20 19:32 Greg Kroah-Hartman
  2026-04-21  4:52 ` Kuniyuki Iwashima
  0 siblings, 1 reply; 4+ messages in thread
From: Greg Kroah-Hartman @ 2026-04-20 19:32 UTC (permalink / raw)
  To: netdev
  Cc: linux-kernel, Greg Kroah-Hartman, David S. Miller, David Ahern,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Simon Horman, stable

ipv6_rpl_srh_rcv() processes a Routing Protocol for LLNs Source Routing
Header by decompressing it, swapping the next segment address into
ipv6_hdr->daddr, recompressing, and pushing the new header back. The
recompressed header can be larger than the original when the
address-elision opportunities are worse after the swap.

The function pulls (hdr->hdrlen + 1) << 3 bytes (the old header) and
pushes (chdr->hdrlen + 1) << 3 + sizeof(ipv6hdr) bytes (the new header
plus the IPv6 header).  pskb_expand_head() is called to guarantee
headroom only when segments_left == 0.

A crafted SRH that loops back to the local host (each segment is a local
address, so ip6_route_input() delivers it back to ipv6_rpl_srh_rcv())
with chdr growing on each pass exhausts headroom over several
iterations.  When skb_push() lands skb->data exactly at skb->head,
skb_reset_network_header() stores 0, and skb_mac_header_rebuild()'s
skb_set_mac_header(skb, -skb->mac_len) computes 0 + (u16)(-14) = 65522.
The subsequent memmove writes 14 bytes at skb->head + 65522.

Expand the head whenever there is insufficient room for the push, not
only on the final segment.

Cc: "David S. Miller" <davem@davemloft.net>
Cc: David Ahern <dsahern@kernel.org>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Jakub Kicinski <kuba@kernel.org>
Cc: Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>
Reported-by: Anthropic
Cc: stable <stable@kernel.org>
Assisted-by: gkh_clanker_t1000
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 net/ipv6/exthdrs.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 95558fd6f447..d866ab011e0a 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -592,7 +592,9 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
 	skb_pull(skb, ((hdr->hdrlen + 1) << 3));
 	skb_postpull_rcsum(skb, oldhdr,
 			   sizeof(struct ipv6hdr) + ((hdr->hdrlen + 1) << 3));
-	if (unlikely(!hdr->segments_left)) {
+	if (unlikely(!hdr->segments_left ||
+		     skb_headroom(skb) < sizeof(struct ipv6hdr) +
+					 ((chdr->hdrlen + 1) << 3))) {
 		if (pskb_expand_head(skb, sizeof(struct ipv6hdr) + ((chdr->hdrlen + 1) << 3), 0,
 				     GFP_ATOMIC)) {
 			__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_OUTDISCARDS);
-- 
2.53.0


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

end of thread, other threads:[~2026-04-21  7:48 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-20 19:32 [PATCH net] ipv6: rpl: expand skb head when recompressed SRH grows, not only on last segment Greg Kroah-Hartman
2026-04-21  4:52 ` Kuniyuki Iwashima
2026-04-21  5:50   ` Greg KH
2026-04-21  7:48     ` Greg KH

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