[PATCH net v3] ipv6: seg6: clear IPv4 control block on IPIP decapsulation

David Lee <[email protected]>
Newsgroups org.kernel.vger.netdev,org.kernel.vger.linux-kernel,org.kernel.vger.stable
Message-ID <[email protected]>
From: Kyle Zeng <[email protected]>

End.DX4 and End.DT4 decapsulate an IPv4 packet through
decap_and_validate() and send it directly to IPv4 routing. The inner
packet therefore bypasses ip_rcv_core(), which normally clears IPCB
before IPv4 interprets skb->cb.

The skb instead retains IP6CB data from the outer packet. IPv6
extension-header offsets overlap IPv4 option fields, so IPv4 can treat
those offsets as saved option metadata. __ip_options_echo() can then
copy beyond the allocation for saved options.

Separate End.DX4 and End.DT4 reproducers on the unpatched v7.2-rc5
kernel both produced:

  BUG: KASAN: slab-out-of-bounds in __ip_options_echo()
  Write of size 255

The End.DX4 trace passes through input_action_end_dx4_finish() and
input_action_end_dx4(), while the End.DT4 trace passes through
input_action_end_dt4().

When decap_and_validate() handles IPPROTO_IPIP, save the ingress
interface from IP6CB, clear IPCB, and restore the saved value. Doing
this in the common decapsulation path covers End.DX4, End.DT4, and
End.DT46's IPv4 arm.

Use IP6CB(skb)->iif rather than skb->skb_iif. These actions run after
l3mdev processing, which can replace skb_iif with the L3 master;
IP6CB iif still records the receiving interface set at IPv6 ingress.

Fixes: 891ef8dd2a8d ("ipv6: sr: implement additional seg6local actions")
Cc: [email protected]
Suggested-by: Andrea Mayer <[email protected]>
Assisted-by: Codex:gpt-5.6-sol Codex:gpt-5.5-cyber
Signed-off-by: Kyle Zeng <[email protected]>
Co-developed-by: David Lee <[email protected]>
Signed-off-by: David Lee <[email protected]>
---
Changes in v3:
- Clear IPCB in the common IPPROTO_IPIP decapsulation path so End.DX4,
  End.DT4, and End.DT46's IPv4 arm are covered.
- Preserve the ingress interface from IP6CB instead of skb->skb_iif,
  which can identify the VRF master after l3mdev processing.
- Update the Fixes tag to the commit that introduced End.DX4.
- Include the End.DX4 and End.DT4 KASAN evidence.

v2: https://lore.kernel.org/netdev/[email protected]/
v1: https://lore.kernel.org/all/[email protected]/

 net/ipv6/seg6_local.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c
index 2b41e4c0dddd..95ea0b62729a 100644
--- a/net/ipv6/seg6_local.c
+++ b/net/ipv6/seg6_local.c
@@ -256,6 +256,13 @@ static bool decap_and_validate(struct sk_buff *skb, int proto)
 	if (iptunnel_pull_offloads(skb))
 		return false;
 
+	if (proto == IPPROTO_IPIP) {
+		int iif = IP6CB(skb)->iif;
+
+		memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
+		IPCB(skb)->iif = iif;
+	}
+
 	return true;
 }
 
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.