* [PATCH net] ipvs: fix ipv4 null-ptr-deref in route error path
@ 2025-11-20 19:03 Slavin Liu
2025-11-20 21:59 ` Julian Anastasov
2025-11-21 8:52 ` [PATCH net v2] " Slavin Liu
0 siblings, 2 replies; 4+ messages in thread
From: Slavin Liu @ 2025-11-20 19:03 UTC (permalink / raw)
To: horms, ja
Cc: pablo, kadlec, fw, phil, davem, edumazet, kuba, pabeni, netdev,
lvs-devel, netfilter-devel, coreteam
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@gmail.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
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH net] ipvs: fix ipv4 null-ptr-deref in route error path
2025-11-20 19:03 [PATCH net] ipvs: fix ipv4 null-ptr-deref in route error path Slavin Liu
@ 2025-11-20 21:59 ` Julian Anastasov
2025-11-21 8:52 ` [PATCH net v2] " Slavin Liu
1 sibling, 0 replies; 4+ messages in thread
From: Julian Anastasov @ 2025-11-20 21:59 UTC (permalink / raw)
To: Slavin Liu
Cc: horms, pablo, kadlec, fw, phil, davem, edumazet, kuba, pabeni,
netdev, lvs-devel, netfilter-devel, coreteam
[-- Attachment #1: Type: text/plain, Size: 3264 bytes --]
Hello,
On Fri, 21 Nov 2025, Slavin Liu wrote:
> 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.
It was not needed for IPv4 at that time because
icmp_send() was safe to use when skb->dev is NULL.
> 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")
I guess, this is a followup to commit 0113d9c9d1cc.
Looks like the problem comes from commit ed0de45a1008 which
starts to use __ip_options_compile(), so the problem is more
recent because we used to call dst_link_failure() even before
commit 4115ded13164. But it is better to fix the problem in
IPVS. Just send v2 with commit ed0de45a1008 in the Fixes tag
and explain that it started to use __ip_options_compile(),
commit 4115ded13164 should not be the culprit.
> Signed-off-by: Slavin Liu <slavin452@gmail.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
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH net v2] ipvs: fix ipv4 null-ptr-deref in route error path
2025-11-20 19:03 [PATCH net] ipvs: fix ipv4 null-ptr-deref in route error path Slavin Liu
2025-11-20 21:59 ` Julian Anastasov
@ 2025-11-21 8:52 ` Slavin Liu
2025-11-24 15:34 ` Julian Anastasov
1 sibling, 1 reply; 4+ messages in thread
From: Slavin Liu @ 2025-11-21 8:52 UTC (permalink / raw)
To: horms, ja
Cc: pablo, kadlec, fw, phil, davem, edumazet, kuba, pabeni, netdev,
lvs-devel, netfilter-devel, coreteam
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 issue emerged after commit ed0de45a1008 ("ipv4: recompile ip options
in ipv4_link_failure") started calling __ip_options_compile() from
ipv4_link_failure(). This code path eventually calls fib_compute_spec_dst()
which dereferences skb->dev. An attempt was made to fix the NULL skb->dev
dereference in commit 0113d9c9d1cc ("ipv4: fix null-deref in
ipv4_link_failure"), but it only addressed the immediate dev_net(skb->dev)
dereference by using a fallback device. The fix was incomplete because
fib_compute_spec_dst() later in the call chain still accesses skb->dev
directly, which remains NULL when IPVS calls dst_link_failure().
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 in commit 326bf17ea5d4 ("ipvs: fix
ipv6 route unreach panic"): 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: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure")
Signed-off-by: Slavin Liu <slavin452@gmail.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
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH net v2] ipvs: fix ipv4 null-ptr-deref in route error path
2025-11-21 8:52 ` [PATCH net v2] " Slavin Liu
@ 2025-11-24 15:34 ` Julian Anastasov
0 siblings, 0 replies; 4+ messages in thread
From: Julian Anastasov @ 2025-11-24 15:34 UTC (permalink / raw)
To: Slavin Liu
Cc: horms, pablo, kadlec, fw, phil, davem, edumazet, kuba, pabeni,
netdev, lvs-devel, netfilter-devel, coreteam
[-- Attachment #1: Type: text/plain, Size: 3083 bytes --]
Hello,
On Fri, 21 Nov 2025, Slavin Liu wrote:
> 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 issue emerged after commit ed0de45a1008 ("ipv4: recompile ip options
> in ipv4_link_failure") started calling __ip_options_compile() from
> ipv4_link_failure(). This code path eventually calls fib_compute_spec_dst()
> which dereferences skb->dev. An attempt was made to fix the NULL skb->dev
> dereference in commit 0113d9c9d1cc ("ipv4: fix null-deref in
> ipv4_link_failure"), but it only addressed the immediate dev_net(skb->dev)
> dereference by using a fallback device. The fix was incomplete because
> fib_compute_spec_dst() later in the call chain still accesses skb->dev
> directly, which remains NULL when IPVS calls dst_link_failure().
>
> 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 in commit 326bf17ea5d4 ("ipvs: fix
> ipv6 route unreach panic"): 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: ed0de45a1008 ("ipv4: recompile ip options in ipv4_link_failure")
> Signed-off-by: Slavin Liu <slavin452@gmail.com>
Looks good to me for the nf tree, thanks!
Acked-by: Julian Anastasov <ja@ssi.bg>
> ---
> 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
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-11-24 15:35 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-20 19:03 [PATCH net] ipvs: fix ipv4 null-ptr-deref in route error path Slavin Liu
2025-11-20 21:59 ` Julian Anastasov
2025-11-21 8:52 ` [PATCH net v2] " Slavin Liu
2025-11-24 15:34 ` Julian Anastasov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).