[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20251120190313.1051-1-slavin452@gmail.com>
Date: Fri, 21 Nov 2025 03:03:13 +0800
From: Slavin Liu <slavin452@...il.com>
To: horms@...ge.net.au,
ja@....bg
Cc: pablo@...filter.org,
kadlec@...filter.org,
fw@...len.de,
phil@....cc,
davem@...emloft.net,
edumazet@...gle.com,
kuba@...nel.org,
pabeni@...hat.com,
netdev@...r.kernel.org,
lvs-devel@...r.kernel.org,
netfilter-devel@...r.kernel.org,
coreteam@...filter.org
Subject: [PATCH net] ipvs: fix ipv4 null-ptr-deref in route error path
The IPv4 code path in __ip_vs_get_out_rt() calls dst_link_failure()
without ensuring skb->dev is set, leading to a NULL pointer dereference
in fib_compute_spec_dst() when ipv4_link_failure() attempts to send
ICMP destination unreachable messages.
The bug was introduced in commit 4115ded13164 ("ipvs: consolidate all
dst checks on transmit in one place") which added the err_unreach error
path with a dst_link_failure(skb) call to both __ip_vs_get_out_rt() and
__ip_vs_get_out_rt_v6(). The IPv6 version was subsequently fixed by
commit 326bf17ea5d4 ("ipvs: fix ipv6 route unreach panic"), but the
fix was never applied to the IPv4 code path.
The crash occurs when:
1. IPVS processes a packet in NAT mode with a misconfigured destination
2. Route lookup fails in __ip_vs_get_out_rt() before establishing a route
3. The error path calls dst_link_failure(skb) with skb->dev == NULL
4. ipv4_link_failure() → ipv4_send_dest_unreach() →
__ip_options_compile() → fib_compute_spec_dst()
5. fib_compute_spec_dst() dereferences NULL skb->dev
Apply the same fix used for IPv6: set skb->dev from skb_dst(skb)->dev
before calling dst_link_failure().
KASAN: null-ptr-deref in range [0x0000000000000328-0x000000000000032f]
CPU: 1 PID: 12732 Comm: syz.1.3469 Not tainted 6.6.114 #2
RIP: 0010:__in_dev_get_rcu include/linux/inetdevice.h:233
RIP: 0010:fib_compute_spec_dst+0x17a/0x9f0 net/ipv4/fib_frontend.c:285
Call Trace:
<TASK>
spec_dst_fill net/ipv4/ip_options.c:232
spec_dst_fill net/ipv4/ip_options.c:229
__ip_options_compile+0x13a1/0x17d0 net/ipv4/ip_options.c:330
ipv4_send_dest_unreach net/ipv4/route.c:1252
ipv4_link_failure+0x702/0xb80 net/ipv4/route.c:1265
dst_link_failure include/net/dst.h:437
__ip_vs_get_out_rt+0x15fd/0x19e0 net/netfilter/ipvs/ip_vs_xmit.c:412
ip_vs_nat_xmit+0x1d8/0xc80 net/netfilter/ipvs/ip_vs_xmit.c:764
Fixes: 4115ded13164 ("ipvs: consolidate all dst checks on transmit in one place")
Signed-off-by: Slavin Liu <slavin452@...il.com>
---
net/netfilter/ipvs/ip_vs_xmit.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/net/netfilter/ipvs/ip_vs_xmit.c b/net/netfilter/ipvs/ip_vs_xmit.c
index 95af252b2939..618fbe1240b5 100644
--- a/net/netfilter/ipvs/ip_vs_xmit.c
+++ b/net/netfilter/ipvs/ip_vs_xmit.c
@@ -409,6 +409,9 @@ __ip_vs_get_out_rt(struct netns_ipvs *ipvs, int skb_af, struct sk_buff *skb,
return -1;
err_unreach:
+ if (!skb->dev)
+ skb->dev = skb_dst(skb)->dev;
+
dst_link_failure(skb);
return -1;
}
--
2.43.0
Powered by blists - more mailing lists