mirror of https://github.com/torvalds/linux.git
syzbot reported a lockdep splat regarding unix_gc_lock and
unix_state_lock().
One is called from recvmsg() for a connected socket, and another
is called from GC for TCP_LISTEN socket.
So, the splat is false-positive.
Let's add a dedicated lock class for the latter to suppress the splat.
Note that this change is not necessary for net-next.git as the issue
is only applied to the old GC impl.
[0]:
WARNING: possible circular locking dependency detected
6.9.0-rc5-syzkaller-00007-g4d2008430ce8 #0 Not tainted
-----------------------------------------------------
kworker/u8:1/11 is trying to acquire lock:
ffff88807cea4e70 (&u->lock){+.+.}-{2:2}, at: spin_lock include/linux/spinlock.h:351 [inline]
ffff88807cea4e70 (&u->lock){+.+.}-{2:2}, at: __unix_gc+0x40e/0xf70 net/unix/garbage.c:302
but task is already holding lock:
ffffffff8f6ab638 (unix_gc_lock){+.+.}-{2:2}, at: spin_lock include/linux/spinlock.h:351 [inline]
ffffffff8f6ab638 (unix_gc_lock){+.+.}-{2:2}, at: __unix_gc+0x117/0xf70 net/unix/garbage.c:261
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (unix_gc_lock){+.+.}-{2:2}:
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5754
__raw_spin_lock include/linux/spinlock_api_smp.h:133 [inline]
_raw_spin_lock+0x2e/0x40 kernel/locking/spinlock.c:154
spin_lock include/linux/spinlock.h:351 [inline]
unix_notinflight+0x13d/0x390 net/unix/garbage.c:140
unix_detach_fds net/unix/af_unix.c:1819 [inline]
unix_destruct_scm+0x221/0x350 net/unix/af_unix.c:1876
skb_release_head_state+0x100/0x250 net/core/skbuff.c:1188
skb_release_all net/core/skbuff.c:1200 [inline]
__kfree_skb net/core/skbuff.c:1216 [inline]
kfree_skb_reason+0x16d/0x3b0 net/core/skbuff.c:1252
kfree_skb include/linux/skbuff.h:1262 [inline]
manage_oob net/unix/af_unix.c:2672 [inline]
unix_stream_read_generic+0x1125/0x2700 net/unix/af_unix.c:2749
unix_stream_splice_read+0x239/0x320 net/unix/af_unix.c:2981
do_splice_read fs/splice.c:985 [inline]
splice_file_to_pipe+0x299/0x500 fs/splice.c:1295
do_splice+0xf2d/0x1880 fs/splice.c:1379
__do_splice fs/splice.c:1436 [inline]
__do_sys_splice fs/splice.c:1652 [inline]
__se_sys_splice+0x331/0x4a0 fs/splice.c:1634
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0xf5/0x240 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x77/0x7f
-> #0 (&u->lock){+.+.}-{2:2}:
check_prev_add kernel/locking/lockdep.c:3134 [inline]
check_prevs_add kernel/locking/lockdep.c:3253 [inline]
validate_chain+0x18cb/0x58e0 kernel/locking/lockdep.c:3869
__lock_acquire+0x1346/0x1fd0 kernel/locking/lockdep.c:5137
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5754
__raw_spin_lock include/linux/spinlock_api_smp.h:133 [inline]
_raw_spin_lock+0x2e/0x40 kernel/locking/spinlock.c:154
spin_lock include/linux/spinlock.h:351 [inline]
__unix_gc+0x40e/0xf70 net/unix/garbage.c:302
process_one_work kernel/workqueue.c:3254 [inline]
process_scheduled_works+0xa10/0x17c0 kernel/workqueue.c:3335
worker_thread+0x86d/0xd70 kernel/workqueue.c:3416
kthread+0x2f0/0x390 kernel/kthread.c:388
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
other info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
lock(unix_gc_lock);
lock(&u->lock);
lock(unix_gc_lock);
lock(&u->lock);
*** DEADLOCK ***
3 locks held by kworker/u8:1/11:
#0: ffff888015089148 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_one_work kernel/workqueue.c:3229 [inline]
#0: ffff888015089148 ((wq_completion)events_unbound){+.+.}-{0:0}, at: process_scheduled_works+0x8e0/0x17c0 kernel/workqueue.c:3335
#1: ffffc90000107d00 (unix_gc_work){+.+.}-{0:0}, at: process_one_work kernel/workqueue.c:3230 [inline]
#1: ffffc90000107d00 (unix_gc_work){+.+.}-{0:0}, at: process_scheduled_works+0x91b/0x17c0 kernel/workqueue.c:3335
#2: ffffffff8f6ab638 (unix_gc_lock){+.+.}-{2:2}, at: spin_lock include/linux/spinlock.h:351 [inline]
#2: ffffffff8f6ab638 (unix_gc_lock){+.+.}-{2:2}, at: __unix_gc+0x117/0xf70 net/unix/garbage.c:261
stack backtrace:
CPU: 0 PID: 11 Comm: kworker/u8:1 Not tainted 6.9.0-rc5-syzkaller-00007-g4d2008430ce8 #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 03/27/2024
Workqueue: events_unbound __unix_gc
Call Trace:
<TASK>
__dump_stack lib/dump_stack.c:88 [inline]
dump_stack_lvl+0x241/0x360 lib/dump_stack.c:114
check_noncircular+0x36a/0x4a0 kernel/locking/lockdep.c:2187
check_prev_add kernel/locking/lockdep.c:3134 [inline]
check_prevs_add kernel/locking/lockdep.c:3253 [inline]
validate_chain+0x18cb/0x58e0 kernel/locking/lockdep.c:3869
__lock_acquire+0x1346/0x1fd0 kernel/locking/lockdep.c:5137
lock_acquire+0x1ed/0x550 kernel/locking/lockdep.c:5754
__raw_spin_lock include/linux/spinlock_api_smp.h:133 [inline]
_raw_spin_lock+0x2e/0x40 kernel/locking/spinlock.c:154
spin_lock include/linux/spinlock.h:351 [inline]
__unix_gc+0x40e/0xf70 net/unix/garbage.c:302
process_one_work kernel/workqueue.c:3254 [inline]
process_scheduled_works+0xa10/0x17c0 kernel/workqueue.c:3335
worker_thread+0x86d/0xd70 kernel/workqueue.c:3416
kthread+0x2f0/0x390 kernel/kthread.c:388
ret_from_fork+0x4b/0x80 arch/x86/kernel/process.c:147
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:244
</TASK>
Fixes:
|
||
|---|---|---|
| .. | ||
| 9p | ||
| bluetooth | ||
| caif | ||
| iucv | ||
| mana | ||
| netfilter | ||
| netns | ||
| nfc | ||
| page_pool | ||
| phonet | ||
| sctp | ||
| tc_act | ||
| 6lowpan.h | ||
| Space.h | ||
| act_api.h | ||
| addrconf.h | ||
| af_ieee802154.h | ||
| af_rxrpc.h | ||
| af_unix.h | ||
| af_vsock.h | ||
| ah.h | ||
| amt.h | ||
| arp.h | ||
| atmclip.h | ||
| ax25.h | ||
| ax88796.h | ||
| bareudp.h | ||
| bond_3ad.h | ||
| bond_alb.h | ||
| bond_options.h | ||
| bonding.h | ||
| bpf_sk_storage.h | ||
| busy_poll.h | ||
| calipso.h | ||
| cfg80211-wext.h | ||
| cfg80211.h | ||
| cfg802154.h | ||
| checksum.h | ||
| cipso_ipv4.h | ||
| cls_cgroup.h | ||
| codel.h | ||
| codel_impl.h | ||
| codel_qdisc.h | ||
| compat.h | ||
| datalink.h | ||
| dcbevent.h | ||
| dcbnl.h | ||
| devlink.h | ||
| dropreason-core.h | ||
| dropreason.h | ||
| dsa.h | ||
| dsa_stubs.h | ||
| dsfield.h | ||
| dst.h | ||
| dst_cache.h | ||
| dst_metadata.h | ||
| dst_ops.h | ||
| eee.h | ||
| erspan.h | ||
| esp.h | ||
| espintcp.h | ||
| ethoc.h | ||
| failover.h | ||
| fib_notifier.h | ||
| fib_rules.h | ||
| firewire.h | ||
| flow.h | ||
| flow_dissector.h | ||
| flow_offload.h | ||
| fou.h | ||
| fq.h | ||
| fq_impl.h | ||
| garp.h | ||
| gen_stats.h | ||
| genetlink.h | ||
| geneve.h | ||
| gre.h | ||
| gro.h | ||
| gro_cells.h | ||
| gso.h | ||
| gtp.h | ||
| gue.h | ||
| handshake.h | ||
| hotdata.h | ||
| hwbm.h | ||
| icmp.h | ||
| ieee80211_radiotap.h | ||
| ieee802154_netdev.h | ||
| if_inet6.h | ||
| ife.h | ||
| inet6_connection_sock.h | ||
| inet6_hashtables.h | ||
| inet_common.h | ||
| inet_connection_sock.h | ||
| inet_dscp.h | ||
| inet_ecn.h | ||
| inet_frag.h | ||
| inet_hashtables.h | ||
| inet_sock.h | ||
| inet_timewait_sock.h | ||
| inetpeer.h | ||
| ioam6.h | ||
| ip.h | ||
| ip6_checksum.h | ||
| ip6_fib.h | ||
| ip6_route.h | ||
| ip6_tunnel.h | ||
| ip_fib.h | ||
| ip_tunnels.h | ||
| ip_vs.h | ||
| ipcomp.h | ||
| ipconfig.h | ||
| ipv6.h | ||
| ipv6_frag.h | ||
| ipv6_stubs.h | ||
| iw_handler.h | ||
| kcm.h | ||
| l3mdev.h | ||
| lag.h | ||
| lapb.h | ||
| lib80211.h | ||
| llc.h | ||
| llc_c_ac.h | ||
| llc_c_ev.h | ||
| llc_c_st.h | ||
| llc_conn.h | ||
| llc_if.h | ||
| llc_pdu.h | ||
| llc_s_ac.h | ||
| llc_s_ev.h | ||
| llc_s_st.h | ||
| llc_sap.h | ||
| lwtunnel.h | ||
| mac80211.h | ||
| mac802154.h | ||
| macsec.h | ||
| mctp.h | ||
| mctpdevice.h | ||
| mip6.h | ||
| mld.h | ||
| mpls.h | ||
| mpls_iptunnel.h | ||
| mptcp.h | ||
| mrp.h | ||
| ncsi.h | ||
| ndisc.h | ||
| neighbour.h | ||
| net_debug.h | ||
| net_failover.h | ||
| net_namespace.h | ||
| net_ratelimit.h | ||
| net_trackers.h | ||
| netdev_queues.h | ||
| netdev_rx_queue.h | ||
| netevent.h | ||
| netkit.h | ||
| netlabel.h | ||
| netlink.h | ||
| netmem.h | ||
| netprio_cgroup.h | ||
| netrom.h | ||
| nexthop.h | ||
| nl802154.h | ||
| nsh.h | ||
| p8022.h | ||
| pie.h | ||
| ping.h | ||
| pkt_cls.h | ||
| pkt_sched.h | ||
| pptp.h | ||
| protocol.h | ||
| psample.h | ||
| psnap.h | ||
| raw.h | ||
| rawv6.h | ||
| red.h | ||
| regulatory.h | ||
| request_sock.h | ||
| rose.h | ||
| route.h | ||
| rpl.h | ||
| rps.h | ||
| rsi_91x.h | ||
| rtnetlink.h | ||
| rtnh.h | ||
| sch_generic.h | ||
| scm.h | ||
| secure_seq.h | ||
| seg6.h | ||
| seg6_hmac.h | ||
| seg6_local.h | ||
| selftests.h | ||
| slhc_vj.h | ||
| smc.h | ||
| snmp.h | ||
| sock.h | ||
| sock_reuseport.h | ||
| stp.h | ||
| strparser.h | ||
| switchdev.h | ||
| tc_wrapper.h | ||
| tcp.h | ||
| tcp_ao.h | ||
| tcp_states.h | ||
| tcx.h | ||
| timewait_sock.h | ||
| tipc.h | ||
| tls.h | ||
| tls_prot.h | ||
| tls_toe.h | ||
| transp_v6.h | ||
| tso.h | ||
| tun_proto.h | ||
| udp.h | ||
| udp_tunnel.h | ||
| udplite.h | ||
| vsock_addr.h | ||
| vxlan.h | ||
| wext.h | ||
| x25.h | ||
| x25device.h | ||
| xdp.h | ||
| xdp_priv.h | ||
| xdp_sock.h | ||
| xdp_sock_drv.h | ||
| xfrm.h | ||
| xsk_buff_pool.h | ||