[PATCH nf v2] ipvs: clear IPv4 options after rebasing tunnel ICMP errors
David Lee <[email protected]> Tue, 4 Aug 2026 06:10:55 +0000
| Newsgroups | gmane.linux.network,gmane.comp.linux.lvs.devel,gmane.comp.security.firewalls.netfilter.devel,gmane.linux.kernel,gmane.linux.kernel.stable |
|---|---|
| Message-ID | <[email protected]> |
From: Kyle Zeng <[email protected]> ip_vs_in_icmp() rebases an skb from the outer ICMP packet to the quoted original request before passing it to icmp_send(). However, IPCB(skb)->opt still describes the outer IPv4 header. A timestamp option in the outer header can therefore leave an offset that points into the quoted transport header after the rebase. __ip_options_echo() treats a byte at that stale location as the option length and copies it into the fixed-size option storage on the __icmp_send() stack, causing a stack out-of-bounds write. Clear the stale option metadata after resetting the network header. Keep the remaining control block fields, including the ingress interface used by the ICMP response path. Fixes: f2edb9f7706d ("ipvs: implement passive PMTUD for IPIP packets") Cc: [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 v2: - Add the nf tree prefix to the subject. - Restore Kyle Zeng as the patch author and correct the sign-off chain. - Move the research credit below the commit-message separator. v1: https://lore.kernel.org/netdev/[email protected]/ Bug found and triaged by OpenAI Security Research and validated by Trail of Bits. Trail of Bits has a reproducer for this bug that triggers a KASAN stack-out-of-bounds write in __ip_options_echo() and can share if needed. net/netfilter/ipvs/ip_vs_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c index bafab9345..fe06c380c 100644 --- a/net/netfilter/ipvs/ip_vs_core.c +++ b/net/netfilter/ipvs/ip_vs_core.c @@ -1951,6 +1951,7 @@ ip_vs_in_icmp(struct netns_ipvs *ipvs, struct sk_buff *skb, int *related, if (pskb_pull(skb, offset2) == NULL) goto ignore_tunnel; skb_reset_network_header(skb); + memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt)); /* Ensure the IP header is present in headroom */ if (!pskb_may_pull(skb, hlen_orig)) goto ignore_tunnel; -- 2.53.0