On Tue, May 15, 2018 at 07:19:39AM +0200, Dmitry Vyukov wrote: > On Mon, May 14, 2018 at 8:00 PM, Andrei Vagin <ava...@virtuozzo.com> wrote: > >> >> Hello, > >> >> > >> >> syzbot found the following crash on: > >> >> > >> >> HEAD commit: c1c07416cdd4 Merge tag 'kbuild-fixes-v4.17' of > >> >> git://git.k.. > >> >> git tree: upstream > >> >> console output: https://syzkaller.appspot.com/x/log.txt?x=12164c97800000 > >> >> kernel config: > >> >> https://syzkaller.appspot.com/x/.config?x=5a1dc06635c10d27 > >> >> dashboard link: > >> >> https://syzkaller.appspot.com/bug?extid=c1872be62e587eae9669 > >> >> compiler: gcc (GCC) 8.0.1 20180413 (experimental) > >> >> userspace arch: i386 > >> >> > >> >> Unfortunately, I don't have any reproducer for this crash yet. > >> >> > >> >> IMPORTANT: if you fix the bug, please add the following tag to the > >> >> commit: > >> >> Reported-by: syzbot+c1872be62e587eae9...@syzkaller.appspotmail.com > >> >> > >> >> > >> >> ====================================================== > >> >> WARNING: possible circular locking dependency detected > >> >> 4.17.0-rc3+ #59 Not tainted > >> >> ------------------------------------------------------ > >> >> syz-executor1/25282 is trying to acquire lock: > >> >> 000000004fddf743 (&(&u->lock)->rlock/1){+.+.}, at: sk_diag_dump_icons > >> >> net/unix/diag.c:82 [inline] > >> >> 000000004fddf743 (&(&u->lock)->rlock/1){+.+.}, at: > >> >> sk_diag_fill.isra.5+0xa43/0x10d0 net/unix/diag.c:144 > >> >> > >> >> but task is already holding lock: > >> >> 00000000b6895645 (rlock-AF_UNIX){+.+.}, at: spin_lock > >> >> include/linux/spinlock.h:310 [inline] > >> >> 00000000b6895645 (rlock-AF_UNIX){+.+.}, at: sk_diag_dump_icons > >> >> net/unix/diag.c:64 [inline] > >> >> 00000000b6895645 (rlock-AF_UNIX){+.+.}, at: > >> >> sk_diag_fill.isra.5+0x94e/0x10d0 > >> >> net/unix/diag.c:144 > >> >> > >> >> which lock already depends on the new lock. > >> > > >> > In the code, we have a comment which explains why it is safe to take > >> > this lock > >> > > >> > /* > >> > * The state lock is outer for the same sk's > >> > * queue lock. With the other's queue locked it's > >> > * OK to lock the state. > >> > */ > >> > unix_state_lock_nested(req); > >> > > >> > It is a question how to explain this to lockdep. > >> > >> Do I understand it correctly that (&u->lock)->rlock associated with > >> AF_UNIX is locked under rlock-AF_UNIX, and then rlock-AF_UNIX is > >> locked under (&u->lock)->rlock associated with AF_NETLINK? If so, I > >> think we need to split (&u->lock)->rlock by family too, so that we > >> have u->lock-AF_UNIX and u->lock-AF_NETLINK. > > > > I think here is another problem. lockdep woried about > > sk->sk_receive_queue vs unix_sk(s)->lock. > > > > sk_diag_dump_icons() takes sk->sk_receive_queue and then > > unix_sk(s)->lock. > > > > unix_dgram_sendmsg takes unix_sk(sk)->lock and then sk->sk_receive_queue. > > > > sk_diag_dump_icons() takes locks for two different sockets, but > > unix_dgram_sendmsg() takes locks for one socket. > > > > sk_diag_dump_icons > > if (sk->sk_state == TCP_LISTEN) { > > spin_lock(&sk->sk_receive_queue.lock); > > skb_queue_walk(&sk->sk_receive_queue, skb) { > > unix_state_lock_nested(req); > > spin_lock_nested(&unix_sk(s)->lock, > > > > > > unix_dgram_sendmsg > > unix_state_lock(other) > > spin_lock(&unix_sk(s)->lock) > > skb_queue_tail(&other->sk_receive_queue, skb); > > spin_lock_irqsave(&list->lock, flags); > > > Do you mean the following? > There is socket 1 with state lock (S1) and queue lock (Q2), and socket > 2 with state lock (S2) and queue lock (Q2). unix_dgram_sendmsg lock > S1->Q1. And sk_diag_dump_icons locks Q1->S2. > If yes, then this looks pretty much as deadlock. Consider that 2 > unix_dgram_sendmsg in 2 different threads lock S1 and S2 respectively. > Now 2 sk_diag_dump_icons in 2 different threads lock Q1 and Q2 > respectively. Now sk_diag_dump_icons want to lock S's, and > unix_dgram_sendmsg want to lock Q's. Nobody can proceed.
Q1 and S1 belongs to a listen socket, so they can't be taken from unix_dgram_sendmsg().