lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <a05775db-fe29-ed82-d87e-b3f7588c2c84@ssi.bg>
Date: Thu, 20 Nov 2025 23:59:23 +0200 (EET)
From: Julian Anastasov <ja@....bg>
To: Slavin Liu <slavin452@...il.com>
cc: horms@...ge.net.au, 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: Re: [PATCH net] ipvs: fix ipv4 null-ptr-deref in route error path


	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@...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

Regards

--
Julian Anastasov <ja@....bg>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ