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>] [day] [month] [year] [list]
Message-ID: <68889806.a00a0220.34d93b.0004.GAE@google.com>
Date: Tue, 29 Jul 2025 02:44:38 -0700
From: syzbot <syzbot+6641a61fe0e2e89ae8c5@...kaller.appspotmail.com>
To: steffen.klassert@...unet.com
Cc: steffen.klassert@...unet.com, linux-kernel@...r.kernel.org, 
	syzkaller-bugs@...glegroups.com
Subject: Re: [syzbot] [net?] WARNING in xfrm_state_fini (3)

> On Tue, Jul 29, 2025 at 12:08:31AM -0700, syzbot wrote:
>> Hello,
>> 
>> syzbot found the following issue on:
>> 
>> HEAD commit:    038d61fd6422 Linux 6.16
>> git tree:       upstream
>> console+strace: https://syzkaller.appspot.com/x/log.txt?x=11b88cf0580000
>> kernel config:  https://syzkaller.appspot.com/x/.config?x=4066f1c76cfbc4fe
>> dashboard link: https://syzkaller.appspot.com/bug?extid=6641a61fe0e2e89ae8c5
>> compiler:       Debian clang version 20.1.7 (++20250616065708+6146a88f6049-1~exp1~20250616065826.132), Debian LLD 20.1.7
>> syz repro:      https://syzkaller.appspot.com/x/repro.syz?x=16ca1782580000
>> C reproducer:   https://syzkaller.appspot.com/x/repro.c?x=140194a2580000
>> 
>> Downloadable assets:
>> disk image: https://storage.googleapis.com/syzbot-assets/6505c612be11/disk-038d61fd.raw.xz
>> vmlinux: https://storage.googleapis.com/syzbot-assets/e466ef29c1ca/vmlinux-038d61fd.xz
>> kernel image: https://storage.googleapis.com/syzbot-assets/b6d3d8fc5cbb/bzImage-038d61fd.xz
>> 
>> IMPORTANT: if you fix the issue, please add the following tag to the commit:
>> Reported-by: syzbot+6641a61fe0e2e89ae8c5@...kaller.appspotmail.com
>
>
> #syz test:

want either no args or 2 args (repo, branch), got 7

>
> From 2e9d56e8788104715de30b6eb91b30e321735f41 Mon Sep 17 00:00:00 2001
> From: Steffen Klassert <steffen.klassert@...unet.com>
> Date: Tue, 29 Jul 2025 11:41:07 +0200
> Subject: [PATCH] Reapply "xfrm: destroy xfrm_state synchronously on net exit
>  path"
>
> This reverts commit 2a198bbec6913ae1c90ec963750003c6213668c7.
> ---
>  include/net/xfrm.h      | 12 +++++++++---
>  net/ipv6/xfrm6_tunnel.c |  2 +-
>  net/key/af_key.c        |  2 +-
>  net/xfrm/xfrm_state.c   | 23 ++++++++++++++---------
>  net/xfrm/xfrm_user.c    |  2 +-
>  5 files changed, 26 insertions(+), 15 deletions(-)
>
> diff --git a/include/net/xfrm.h b/include/net/xfrm.h
> index f3014e4f54fc..91d52a380e37 100644
> --- a/include/net/xfrm.h
> +++ b/include/net/xfrm.h
> @@ -915,7 +915,7 @@ static inline void xfrm_pols_put(struct xfrm_policy **pols, int npols)
>  		xfrm_pol_put(pols[i]);
>  }
>  
> -void __xfrm_state_destroy(struct xfrm_state *);
> +void __xfrm_state_destroy(struct xfrm_state *, bool);
>  
>  static inline void __xfrm_state_put(struct xfrm_state *x)
>  {
> @@ -925,7 +925,13 @@ static inline void __xfrm_state_put(struct xfrm_state *x)
>  static inline void xfrm_state_put(struct xfrm_state *x)
>  {
>  	if (refcount_dec_and_test(&x->refcnt))
> -		__xfrm_state_destroy(x);
> +		__xfrm_state_destroy(x, false);
> +}
> +
> +static inline void xfrm_state_put_sync(struct xfrm_state *x)
> +{
> +	if (refcount_dec_and_test(&x->refcnt))
> +		__xfrm_state_destroy(x, true);
>  }
>  
>  static inline void xfrm_state_hold(struct xfrm_state *x)
> @@ -1763,7 +1769,7 @@ struct xfrmk_spdinfo {
>  
>  struct xfrm_state *xfrm_find_acq_byseq(struct net *net, u32 mark, u32 seq, u32 pcpu_num);
>  int xfrm_state_delete(struct xfrm_state *x);
> -int xfrm_state_flush(struct net *net, u8 proto, bool task_valid);
> +int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync);
>  int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valid);
>  int xfrm_dev_policy_flush(struct net *net, struct net_device *dev,
>  			  bool task_valid);
> diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
> index 5120a763da0d..7fd8bc08e6eb 100644
> --- a/net/ipv6/xfrm6_tunnel.c
> +++ b/net/ipv6/xfrm6_tunnel.c
> @@ -334,7 +334,7 @@ static void __net_exit xfrm6_tunnel_net_exit(struct net *net)
>  	struct xfrm6_tunnel_net *xfrm6_tn = xfrm6_tunnel_pernet(net);
>  	unsigned int i;
>  
> -	xfrm_state_flush(net, IPSEC_PROTO_ANY, false);
> +	xfrm_state_flush(net, 0, false, true);
>  	xfrm_flush_gc();
>  
>  	for (i = 0; i < XFRM6_TUNNEL_SPI_BYADDR_HSIZE; i++)
> diff --git a/net/key/af_key.c b/net/key/af_key.c
> index b5d761700776..efc2a91f4c48 100644
> --- a/net/key/af_key.c
> +++ b/net/key/af_key.c
> @@ -1766,7 +1766,7 @@ static int pfkey_flush(struct sock *sk, struct sk_buff *skb, const struct sadb_m
>  	if (proto == 0)
>  		return -EINVAL;
>  
> -	err = xfrm_state_flush(net, proto, true);
> +	err = xfrm_state_flush(net, proto, true, false);
>  	err2 = unicast_flush_resp(sk, hdr);
>  	if (err || err2) {
>  		if (err == -ESRCH) /* empty table - go quietly */
> diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
> index 97ff756191ba..0ec7d22aaff3 100644
> --- a/net/xfrm/xfrm_state.c
> +++ b/net/xfrm/xfrm_state.c
> @@ -592,7 +592,7 @@ void xfrm_state_free(struct xfrm_state *x)
>  }
>  EXPORT_SYMBOL(xfrm_state_free);
>  
> -static void xfrm_state_gc_destroy(struct xfrm_state *x)
> +static void ___xfrm_state_destroy(struct xfrm_state *x)
>  {
>  	if (x->mode_cbs && x->mode_cbs->destroy_state)
>  		x->mode_cbs->destroy_state(x);
> @@ -631,7 +631,7 @@ static void xfrm_state_gc_task(struct work_struct *work)
>  	synchronize_rcu();
>  
>  	hlist_for_each_entry_safe(x, tmp, &gc_list, gclist)
> -		xfrm_state_gc_destroy(x);
> +		___xfrm_state_destroy(x);
>  }
>  
>  static enum hrtimer_restart xfrm_timer_handler(struct hrtimer *me)
> @@ -795,14 +795,19 @@ void xfrm_dev_state_free(struct xfrm_state *x)
>  }
>  #endif
>  
> -void __xfrm_state_destroy(struct xfrm_state *x)
> +void __xfrm_state_destroy(struct xfrm_state *x, bool sync)
>  {
>  	WARN_ON(x->km.state != XFRM_STATE_DEAD);
>  
> -	spin_lock_bh(&xfrm_state_gc_lock);
> -	hlist_add_head(&x->gclist, &xfrm_state_gc_list);
> -	spin_unlock_bh(&xfrm_state_gc_lock);
> -	schedule_work(&xfrm_state_gc_work);
> +	if (sync) {
> +		synchronize_rcu();
> +		___xfrm_state_destroy(x);
> +	} else {
> +		spin_lock_bh(&xfrm_state_gc_lock);
> +		hlist_add_head(&x->gclist, &xfrm_state_gc_list);
> +		spin_unlock_bh(&xfrm_state_gc_lock);
> +		schedule_work(&xfrm_state_gc_work);
> +	}
>  }
>  EXPORT_SYMBOL(__xfrm_state_destroy);
>  
> @@ -917,7 +922,7 @@ xfrm_dev_state_flush_secctx_check(struct net *net, struct net_device *dev, bool
>  }
>  #endif
>  
> -int xfrm_state_flush(struct net *net, u8 proto, bool task_valid)
> +int xfrm_state_flush(struct net *net, u8 proto, bool task_valid, bool sync)
>  {
>  	int i, err = 0, cnt = 0;
>  
> @@ -3278,7 +3283,7 @@ void xfrm_state_fini(struct net *net)
>  	unsigned int sz;
>  
>  	flush_work(&net->xfrm.state_hash_work);
> -	xfrm_state_flush(net, IPSEC_PROTO_ANY, false);
> +	xfrm_state_flush(net, 0, false, true);
>  	flush_work(&xfrm_state_gc_work);
>  
>  	WARN_ON(!list_empty(&net->xfrm.state_all));
> diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
> index 684239018bec..1db18f470f42 100644
> --- a/net/xfrm/xfrm_user.c
> +++ b/net/xfrm/xfrm_user.c
> @@ -2635,7 +2635,7 @@ static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
>  	struct xfrm_usersa_flush *p = nlmsg_data(nlh);
>  	int err;
>  
> -	err = xfrm_state_flush(net, p->proto, true);
> +	err = xfrm_state_flush(net, p->proto, true, false);
>  	if (err) {
>  		if (err == -ESRCH) /* empty table */
>  			return 0;
> -- 
> 2.43.0
>

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ