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 for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251106175926.686885-1-kuniyu@google.com>
Date: Thu,  6 Nov 2025 17:59:17 +0000
From: Kuniyuki Iwashima <kuniyu@...gle.com>
To: syzbot+cif2d6d318f7e85f0b@...kaller.appspotmail.com
Cc: davem@...emloft.net, edumazet@...gle.com, hoang.h.le@...tech.com.au, 
	horms@...nel.org, jmaloy@...hat.com, kuba@...nel.org, kuni1840@...il.com, 
	kuniyu@...gle.com, netdev@...r.kernel.org, pabeni@...hat.com, 
	syzbot@...ts.linux.dev, syzbot@...kaller.appspotmail.com, 
	syzkaller-bugs@...glegroups.com, tipc-discussion@...ts.sourceforge.net
Subject: [syzbot ci] Re: tipc: Fix use-after-free in tipc_mon_reinit_self().

From: syzbot ci <syzbot+cif2d6d318f7e85f0b@...kaller.appspotmail.com>
Date: Thu, 06 Nov 2025 01:38:49 -0800
> syzbot ci has tested the following series
> 
> [v1] tipc: Fix use-after-free in tipc_mon_reinit_self().
> https://lore.kernel.org/all/20251106053309.401275-1-kuniyu@google.com
> * [PATCH v1 net] tipc: Fix use-after-free in tipc_mon_reinit_self().
> 
> and found the following issue:
> possible deadlock in tipc_mon_reinit_self
> 
> Full report is available here:
> https://ci.syzbot.org/series/bfabf013-65e3-4ca9-8f54-0c7eef8be01a
> 
> ***
> 
> possible deadlock in tipc_mon_reinit_self
> 
> tree:      net
> URL:       https://kernel.googlesource.com/pub/scm/linux/kernel/git/netdev/net.git
> base:      3d18a84eddde169d6dbf3c72cc5358b988c347d0
> arch:      amd64
> compiler:  Debian clang version 20.1.8 (++20250708063551+0c9f909b7976-1~exp1~20250708183702.136), Debian LLD 20.1.8
> config:    https://ci.syzbot.org/builds/b2774856-e331-420e-a340-5107ec4b06f9/config
> C repro:   https://ci.syzbot.org/findings/1f0a4298-b797-4217-8d6d-15f98c0ffd38/c_repro
> syz repro: https://ci.syzbot.org/findings/1f0a4298-b797-4217-8d6d-15f98c0ffd38/syz_repro
> 
> tipc: Started in network mode
> tipc: Node identity 4, cluster identity 4711
> tipc: Node number set to 4
> ============================================
> WARNING: possible recursive locking detected
> syzkaller #0 Not tainted
> --------------------------------------------
> syz.0.17/5963 is trying to acquire lock:
> ffffffff8f2cb1c8 (rtnl_mutex){+.+.}-{4:4}, at: tipc_mon_reinit_self+0x25/0x360 net/tipc/monitor.c:714
> 
> but task is already holding lock:
> ffffffff8f2cb1c8 (rtnl_mutex){+.+.}-{4:4}, at: __tipc_nl_compat_doit net/tipc/netlink_compat.c:358 [inline]
> ffffffff8f2cb1c8 (rtnl_mutex){+.+.}-{4:4}, at: tipc_nl_compat_doit+0x1fd/0x5f0 net/tipc/netlink_compat.c:393
> 
> other info that might help us debug this:
>  Possible unsafe locking scenario:
> 
>        CPU0
>        ----
>   lock(rtnl_mutex);
>   lock(rtnl_mutex);
> 
>  *** DEADLOCK ***
> 
>  May be due to missing lock nesting notation
> 
> 3 locks held by syz.0.17/5963:
>  #0: ffffffff8f331050 (cb_lock){++++}-{4:4}, at: genl_rcv+0x19/0x40 net/netlink/genetlink.c:1218
>  #1: ffffffff8f330e68 (genl_mutex){+.+.}-{4:4}, at: genl_lock net/netlink/genetlink.c:35 [inline]
>  #1: ffffffff8f330e68 (genl_mutex){+.+.}-{4:4}, at: genl_op_lock net/netlink/genetlink.c:60 [inline]
>  #1: ffffffff8f330e68 (genl_mutex){+.+.}-{4:4}, at: genl_rcv_msg+0x10d/0x790 net/netlink/genetlink.c:1209
>  #2: ffffffff8f2cb1c8 (rtnl_mutex){+.+.}-{4:4}, at: __tipc_nl_compat_doit net/tipc/netlink_compat.c:358 [inline]
>  #2: ffffffff8f2cb1c8 (rtnl_mutex){+.+.}-{4:4}, at: tipc_nl_compat_doit+0x1fd/0x5f0 net/tipc/netlink_compat.c:393
> 
> stack backtrace:
> CPU: 1 UID: 0 PID: 5963 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) 
> Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014
> Call Trace:
>  <TASK>
>  dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120
>  print_deadlock_bug+0x28b/0x2a0 kernel/locking/lockdep.c:3041
>  check_deadlock kernel/locking/lockdep.c:3093 [inline]
>  validate_chain+0x1a3f/0x2140 kernel/locking/lockdep.c:3895
>  __lock_acquire+0xab9/0xd20 kernel/locking/lockdep.c:5237
>  lock_acquire+0x120/0x360 kernel/locking/lockdep.c:5868
>  __mutex_lock_common kernel/locking/mutex.c:598 [inline]
>  __mutex_lock+0x187/0x1350 kernel/locking/mutex.c:760
>  tipc_mon_reinit_self+0x25/0x360 net/tipc/monitor.c:714
>  tipc_net_finalize+0x115/0x190 net/tipc/net.c:140
>  tipc_net_init+0x104/0x190 net/tipc/net.c:122
>  __tipc_nl_net_set+0x3b9/0x5a0 net/tipc/net.c:263

I missed another path calling tipc_net_finalize under RTNL.

I'll change v2 this way.

---8<---
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c
index 46c8814c3ee6..be1e51efc445 100644
--- a/net/tipc/monitor.c
+++ b/net/tipc/monitor.c
@@ -706,12 +706,13 @@ void tipc_mon_delete(struct net *net, int bearer_id)
 	kfree(mon);
 }
 
-void tipc_mon_reinit_self(struct net *net)
+void tipc_mon_reinit_self(struct net *net, bool rtnl_held)
 {
 	struct tipc_monitor *mon;
 	int bearer_id;
 
-	rtnl_lock();
+	if (!rtnl_held)
+		rtnl_lock();
 
 	for (bearer_id = 0; bearer_id < MAX_BEARERS; bearer_id++) {
 		mon = tipc_monitor(net, bearer_id);
@@ -723,7 +724,8 @@ void tipc_mon_reinit_self(struct net *net)
 		write_unlock_bh(&mon->lock);
 	}
 
-	rtnl_unlock();
+	if (!rtnl_held)
+		rtnl_unlock();
 }
 
 int tipc_nl_monitor_set_threshold(struct net *net, u32 cluster_size)
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 0e95572e56b4..56527f6f548c 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -119,11 +119,11 @@ int tipc_net_init(struct net *net, u8 *node_id, u32 addr)
 	if (node_id)
 		tipc_set_node_id(net, node_id);
 	if (addr)
-		tipc_net_finalize(net, addr);
+		tipc_net_finalize(net, addr, true);
 	return 0;
 }
 
-static void tipc_net_finalize(struct net *net, u32 addr)
+static void tipc_net_finalize(struct net *net, u32 addr, bool rtnl_held)
 {
 	struct tipc_net *tn = tipc_net(net);
 	struct tipc_socket_addr sk = {0, addr};
@@ -137,7 +137,7 @@ static void tipc_net_finalize(struct net *net, u32 addr)
 	tipc_set_node_addr(net, addr);
 	tipc_named_reinit(net);
 	tipc_sk_reinit(net);
-	tipc_mon_reinit_self(net);
+	tipc_mon_reinit_self(net, rtnl_held);
 	tipc_nametbl_publish(net, &ua, &sk, addr);
 }
 
@@ -145,7 +145,7 @@ void tipc_net_finalize_work(struct work_struct *work)
 {
 	struct tipc_net *tn = container_of(work, struct tipc_net, work);
 
-	tipc_net_finalize(tipc_link_net(tn->bcl), tn->trial_addr);
+	tipc_net_finalize(tipc_link_net(tn->bcl), tn->trial_addr, false);
 }
 
 void tipc_net_stop(struct net *net)
---8<---

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ