syzbot reported the lockdep splat below. [0] sctp_clone_sock() sets the child socket's ipv6_mc_list to NULL, but somehow sock_release() in an error path finally acquires lock_sock() in ipv6_sock_mc_close(). The root cause is that sctp_clone_sock() fetches inet6_sk(newsk) before setting newinet->pinet6, meaning that the parent's ipv6_mc_list was actually cleared. Also, sctp_v6_copy_ip_options() uses inet6_sk() but is called before newinet->pinet6 is set. Let's use inet6_sk() only after setting newinet->pinet6. [0]: WARNING: possible recursive locking detected syzkaller #0 Not tainted syz.0.17/5996 is trying to acquire lock: ffff888031af4c60 (sk_lock-AF_INET6){+.+.}-{0:0}, at: lock_sock include/net/sock.h:1700 [inline] ffff888031af4c60 (sk_lock-AF_INET6){+.+.}-{0:0}, at: ipv6_sock_mc_close+0xd3/0x140 net/ipv6/mcast.c:348 but task is already holding lock: ffff888031af4320 (sk_lock-AF_INET6){+.+.}-{0:0}, at: lock_sock include/net/sock.h:1700 [inline] ffff888031af4320 (sk_lock-AF_INET6){+.+.}-{0:0}, at: sctp_getsockopt+0x135/0xb60 net/sctp/socket.c:8131 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(sk_lock-AF_INET6); lock(sk_lock-AF_INET6); *** DEADLOCK *** May be due to missing lock nesting notation 1 lock held by syz.0.17/5996: #0: ffff888031af4320 (sk_lock-AF_INET6){+.+.}-{0:0}, at: lock_sock include/net/sock.h:1700 [inline] #0: ffff888031af4320 (sk_lock-AF_INET6){+.+.}-{0:0}, at: sctp_getsockopt+0x135/0xb60 net/sctp/socket.c:8131 stack backtrace: CPU: 0 UID: 0 PID: 5996 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/25/2025 Call Trace: dump_stack_lvl+0x189/0x250 lib/dump_stack.c:120 print_deadlock_bug+0x279/0x290 kernel/locking/lockdep.c:3041 check_deadlock kernel/locking/lockdep.c:3093 [inline] validate_chain kernel/locking/lockdep.c:3895 [inline] __lock_acquire+0x2540/0x2cf0 kernel/locking/lockdep.c:5237 lock_acquire+0x117/0x340 kernel/locking/lockdep.c:5868 lock_sock_nested+0x48/0x100 net/core/sock.c:3780 lock_sock include/net/sock.h:1700 [inline] ipv6_sock_mc_close+0xd3/0x140 net/ipv6/mcast.c:348 inet6_release+0x47/0x70 net/ipv6/af_inet6.c:482 __sock_release net/socket.c:653 [inline] sock_release+0x85/0x150 net/socket.c:681 sctp_getsockopt_peeloff_common+0x56b/0x770 net/sctp/socket.c:5732 sctp_getsockopt_peeloff_flags+0x13b/0x230 net/sctp/socket.c:5801 sctp_getsockopt+0x3ab/0xb60 net/sctp/socket.c:8151 do_sock_getsockopt+0x2b4/0x3d0 net/socket.c:2399 __sys_getsockopt net/socket.c:2428 [inline] __do_sys_getsockopt net/socket.c:2435 [inline] __se_sys_getsockopt net/socket.c:2432 [inline] __x64_sys_getsockopt+0x1a5/0x250 net/socket.c:2432 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xfa/0xf80 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f8f8c38f749 Code: ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 40 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 a8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007ffcfdade018 EFLAGS: 00000246 ORIG_RAX: 0000000000000037 RAX: ffffffffffffffda RBX: 00007f8f8c5e5fa0 RCX: 00007f8f8c38f749 RDX: 000000000000007a RSI: 0000000000000084 RDI: 0000000000000003 RBP: 00007f8f8c413f91 R08: 0000200000000040 R09: 0000000000000000 R10: 0000200000000340 R11: 0000000000000246 R12: 0000000000000000 R13: 00007f8f8c5e5fa0 R14: 00007f8f8c5e5fa0 R15: 0000000000000005 Fixes: 16942cf4d3e31 ("sctp: Use sk_clone() in sctp_accept().") Reported-by: syzbot+c59e6bb54e7620495725@syzkaller.appspotmail.com Closes: https://lore.kernel.org/netdev/6936d112.a70a0220.38f243.00a7.GAE@google.com/ Signed-off-by: Kuniyuki Iwashima --- net/sctp/socket.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index d808096f5ab17..2493a5b1fa3ca 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -4863,8 +4863,6 @@ static struct sock *sctp_clone_sock(struct sock *sk, newsp->pf->to_sk_daddr(&asoc->peer.primary_addr, newsk); newinet->inet_dport = htons(asoc->peer.port); - - newsp->pf->copy_ip_options(sk, newsk); atomic_set(&newinet->inet_id, get_random_u16()); inet_set_bit(MC_LOOP, newsk); @@ -4874,17 +4872,20 @@ static struct sock *sctp_clone_sock(struct sock *sk, #if IS_ENABLED(CONFIG_IPV6) if (sk->sk_family == AF_INET6) { - struct ipv6_pinfo *newnp = inet6_sk(newsk); + struct ipv6_pinfo *newnp; newinet->pinet6 = &((struct sctp6_sock *)newsk)->inet6; newinet->ipv6_fl_list = NULL; + newnp = inet6_sk(newsk); memcpy(newnp, inet6_sk(sk), sizeof(struct ipv6_pinfo)); newnp->ipv6_mc_list = NULL; newnp->ipv6_ac_list = NULL; } #endif + newsp->pf->copy_ip_options(sk, newsk); + newsp->do_auto_asconf = 0; skb_queue_head_init(&newsp->pd_lobby); -- 2.52.0.223.gf5cc29aaa4-goog