Linux Security Modules development
 help / color / mirror / Atom feed
* Re: [PATCH] xfrm: kill xfrm_dev_{state,policy}_flush_secctx_check()
From: Tetsuo Handa @ 2026-02-04 10:15 UTC (permalink / raw)
  To: Paul Moore, SELinux, linux-security-module
  Cc: Steffen Klassert, Herbert Xu, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Simon Horman, Network Development
In-Reply-To: <CAHC9VhRzRAR+hhn4TFADnHWpzjOxjmh0S_Hg_HktkPkKQ35ycg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 780 bytes --]

On 2026/02/04 7:40, Paul Moore wrote:
>         This is not an unusual request for such a proposed change, and
> is something that I would expect a LSM maintainer to do without much
> hesitation.  If you are unwilling to investigate this, can you explain
> why?

Because I'm not familiar with how XFRM works; I'm not a user of LSM XFRM hooks.

I can't judge whether the current code is COMPREHENSIVELY GATING;
I can't imagine what the state you call COMPREHENSIVELY GATING is.



P.S. For your investigation, I attach a new report that syzbot found today, and
I'll drop "xfrm: always fail xfrm_dev_{state,policy}_flush_secctx_check()"
because these three reports will be sufficient for people to understand that
we need to kill xfrm_dev_{state,policy}_flush_secctx_check() calls.

[-- Attachment #2: report-0202-kernfs.txt --]
[-- Type: text/plain, Size: 90653 bytes --]

unregister_netdevice: waiting for netdevsim0 to become free. Usage count = 2
ref_tracker: netdev@ffff888028c4c630 has 1/1 users at
     xfrm_dev_state_add+0x6f4/0xc40 net/xfrm/xfrm_device.c:316
     xfrm_state_construct net/xfrm/xfrm_user.c:986 [inline]
     xfrm_add_sa+0x34ca/0x4230 net/xfrm/xfrm_user.c:1022
     xfrm_user_rcv_msg+0x746/0xb20 net/xfrm/xfrm_user.c:3507
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     xfrm_netlink_rcv+0x79/0x90 net/xfrm/xfrm_user.c:3529
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
     __sock_sendmsg net/socket.c:752 [inline]
     ____sys_sendmsg+0x589/0x8c0 net/socket.c:2610
     ___sys_sendmsg+0x2a5/0x360 net/socket.c:2664
     __sys_sendmsg net/socket.c:2696 [inline]
     __do_sys_sendmsg net/socket.c:2701 [inline]
     __se_sys_sendmsg net/socket.c:2699 [inline]
     __x64_sys_sendmsg+0x1bd/0x2a0 net/socket.c:2699
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f

infiniband: balance for netdevsim0@ib_gid_table_entry is 0
balance for netdevsim0@j1939_priv is 0
Call trace for netdevsim0[1] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     rx_queue_add_kobject net/core/net-sysfs.c:1257 [inline]
     net_rx_queue_update_kobjects+0x148/0x750 net/core/net-sysfs.c:1322
     register_queue_kobjects net/core/net-sysfs.c:2114 [inline]
     netdev_register_kobject+0x21f/0x310 net/core/net-sysfs.c:2362
     register_netdevice+0x12c0/0x1cf0 net/core/dev.c:11409
     nsim_init_netdevsim drivers/net/netdevsim/netdev.c:1064 [inline]
     nsim_create+0xb92/0x1100 drivers/net/netdevsim/netdev.c:1146
     __nsim_dev_port_add+0x72a/0xb50 drivers/net/netdevsim/dev.c:1494
     nsim_dev_port_add_all+0x37/0xf0 drivers/net/netdevsim/dev.c:1550
     nsim_drv_probe+0x905/0xc20 drivers/net/netdevsim/dev.c:1711
     call_driver_probe drivers/base/dd.c:-1 [inline]
     really_probe+0x267/0xaf0 drivers/base/dd.c:661
     __driver_probe_device+0x18c/0x320 drivers/base/dd.c:803
     driver_probe_device+0x4f/0x240 drivers/base/dd.c:833
     __device_attach_driver+0x2d4/0x4c0 drivers/base/dd.c:961
     bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500
     __device_attach+0x2c5/0x450 drivers/base/dd.c:1033
     device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1088
     bus_probe_device+0x12a/0x220 drivers/base/bus.c:574
     device_add+0x7b6/0xb70 drivers/base/core.c:3689
     nsim_bus_dev_new drivers/net/netdevsim/bus.c:471 [inline]
     new_device_store+0x37b/0x710 drivers/net/netdevsim/bus.c:191
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
Call trace for netdevsim0[2] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     netdev_queue_add_kobject net/core/net-sysfs.c:1994 [inline]
     netdev_queue_update_kobjects+0x170/0x6d0 net/core/net-sysfs.c:2056
     register_queue_kobjects net/core/net-sysfs.c:2119 [inline]
     netdev_register_kobject+0x258/0x310 net/core/net-sysfs.c:2362
     register_netdevice+0x12c0/0x1cf0 net/core/dev.c:11409
     nsim_init_netdevsim drivers/net/netdevsim/netdev.c:1064 [inline]
     nsim_create+0xb92/0x1100 drivers/net/netdevsim/netdev.c:1146
     __nsim_dev_port_add+0x72a/0xb50 drivers/net/netdevsim/dev.c:1494
     nsim_dev_port_add_all+0x37/0xf0 drivers/net/netdevsim/dev.c:1550
     nsim_drv_probe+0x905/0xc20 drivers/net/netdevsim/dev.c:1711
     call_driver_probe drivers/base/dd.c:-1 [inline]
     really_probe+0x267/0xaf0 drivers/base/dd.c:661
     __driver_probe_device+0x18c/0x320 drivers/base/dd.c:803
     driver_probe_device+0x4f/0x240 drivers/base/dd.c:833
     __device_attach_driver+0x2d4/0x4c0 drivers/base/dd.c:961
     bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500
     __device_attach+0x2c5/0x450 drivers/base/dd.c:1033
     device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1088
     bus_probe_device+0x12a/0x220 drivers/base/bus.c:574
     device_add+0x7b6/0xb70 drivers/base/core.c:3689
     nsim_bus_dev_new drivers/net/netdevsim/bus.c:471 [inline]
     new_device_store+0x37b/0x710 drivers/net/netdevsim/bus.c:191
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
Call trace for netdevsim0[3] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold+0x27/0xc0 include/linux/netdevice.h:4446
     register_netdevice+0x15cc/0x1cf0 net/core/dev.c:11433
     nsim_init_netdevsim drivers/net/netdevsim/netdev.c:1064 [inline]
     nsim_create+0xb92/0x1100 drivers/net/netdevsim/netdev.c:1146
     __nsim_dev_port_add+0x72a/0xb50 drivers/net/netdevsim/dev.c:1494
     nsim_dev_port_add_all+0x37/0xf0 drivers/net/netdevsim/dev.c:1550
     nsim_drv_probe+0x905/0xc20 drivers/net/netdevsim/dev.c:1711
     call_driver_probe drivers/base/dd.c:-1 [inline]
     really_probe+0x267/0xaf0 drivers/base/dd.c:661
     __driver_probe_device+0x18c/0x320 drivers/base/dd.c:803
     driver_probe_device+0x4f/0x240 drivers/base/dd.c:833
     __device_attach_driver+0x2d4/0x4c0 drivers/base/dd.c:961
     bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500
     __device_attach+0x2c5/0x450 drivers/base/dd.c:1033
     device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1088
     bus_probe_device+0x12a/0x220 drivers/base/bus.c:574
     device_add+0x7b6/0xb70 drivers/base/core.c:3689
     nsim_bus_dev_new drivers/net/netdevsim/bus.c:471 [inline]
     new_device_store+0x37b/0x710 drivers/net/netdevsim/bus.c:191
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
Call trace for netdevsim0[4] +3 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     netdevice_queue_work drivers/infiniband/core/roce_gid_mgmt.c:698 [inline]
     netdevice_event+0x4ea/0x8d0 drivers/infiniband/core/roce_gid_mgmt.c:849
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     register_netdevice+0x173a/0x1cf0 net/core/dev.c:11447
     nsim_init_netdevsim drivers/net/netdevsim/netdev.c:1064 [inline]
     nsim_create+0xb92/0x1100 drivers/net/netdevsim/netdev.c:1146
     __nsim_dev_port_add+0x72a/0xb50 drivers/net/netdevsim/dev.c:1494
     nsim_dev_port_add_all+0x37/0xf0 drivers/net/netdevsim/dev.c:1550
     nsim_drv_probe+0x905/0xc20 drivers/net/netdevsim/dev.c:1711
     call_driver_probe drivers/base/dd.c:-1 [inline]
     really_probe+0x267/0xaf0 drivers/base/dd.c:661
     __driver_probe_device+0x18c/0x320 drivers/base/dd.c:803
     driver_probe_device+0x4f/0x240 drivers/base/dd.c:833
     __device_attach_driver+0x2d4/0x4c0 drivers/base/dd.c:961
     bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500
     __device_attach+0x2c5/0x450 drivers/base/dd.c:1033
     device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1088
     bus_probe_device+0x12a/0x220 drivers/base/bus.c:574
     device_add+0x7b6/0xb70 drivers/base/core.c:3689
     nsim_bus_dev_new drivers/net/netdevsim/bus.c:471 [inline]
     new_device_store+0x37b/0x710 drivers/net/netdevsim/bus.c:191
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
Call trace for netdevsim0[5] +3 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     netdevice_queue_work drivers/infiniband/core/roce_gid_mgmt.c:699 [inline]
     netdevice_event+0x593/0x8d0 drivers/infiniband/core/roce_gid_mgmt.c:849
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     register_netdevice+0x173a/0x1cf0 net/core/dev.c:11447
     nsim_init_netdevsim drivers/net/netdevsim/netdev.c:1064 [inline]
     nsim_create+0xb92/0x1100 drivers/net/netdevsim/netdev.c:1146
     __nsim_dev_port_add+0x72a/0xb50 drivers/net/netdevsim/dev.c:1494
     nsim_dev_port_add_all+0x37/0xf0 drivers/net/netdevsim/dev.c:1550
     nsim_drv_probe+0x905/0xc20 drivers/net/netdevsim/dev.c:1711
     call_driver_probe drivers/base/dd.c:-1 [inline]
     really_probe+0x267/0xaf0 drivers/base/dd.c:661
     __driver_probe_device+0x18c/0x320 drivers/base/dd.c:803
     driver_probe_device+0x4f/0x240 drivers/base/dd.c:833
     __device_attach_driver+0x2d4/0x4c0 drivers/base/dd.c:961
     bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500
     __device_attach+0x2c5/0x450 drivers/base/dd.c:1033
     device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1088
     bus_probe_device+0x12a/0x220 drivers/base/bus.c:574
     device_add+0x7b6/0xb70 drivers/base/core.c:3689
     nsim_bus_dev_new drivers/net/netdevsim/bus.c:471 [inline]
     new_device_store+0x37b/0x710 drivers/net/netdevsim/bus.c:191
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
Call trace for netdevsim0[6] -10 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     dev_put include/linux/netdevice.h:4481 [inline]
     netdevice_event_work_handler+0x12c/0x260 drivers/infiniband/core/roce_gid_mgmt.c:675
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
Call trace for netdevsim0[7] -10 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     dev_put include/linux/netdevice.h:4481 [inline]
     netdevice_event_work_handler+0x1b2/0x260 drivers/infiniband/core/roce_gid_mgmt.c:676
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
Call trace for netdevsim0[8] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     neigh_parms_alloc+0x192/0x530 net/core/neighbour.c:1778
     inetdev_init+0x118/0x4f0 net/ipv4/devinet.c:280
     inetdev_event+0x30d/0x1610 net/ipv4/devinet.c:1590
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     register_netdevice+0x173a/0x1cf0 net/core/dev.c:11447
     nsim_init_netdevsim drivers/net/netdevsim/netdev.c:1064 [inline]
     nsim_create+0xb92/0x1100 drivers/net/netdevsim/netdev.c:1146
     __nsim_dev_port_add+0x72a/0xb50 drivers/net/netdevsim/dev.c:1494
     nsim_dev_port_add_all+0x37/0xf0 drivers/net/netdevsim/dev.c:1550
     nsim_drv_probe+0x905/0xc20 drivers/net/netdevsim/dev.c:1711
     call_driver_probe drivers/base/dd.c:-1 [inline]
     really_probe+0x267/0xaf0 drivers/base/dd.c:661
     __driver_probe_device+0x18c/0x320 drivers/base/dd.c:803
     driver_probe_device+0x4f/0x240 drivers/base/dd.c:833
     __device_attach_driver+0x2d4/0x4c0 drivers/base/dd.c:961
     bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500
     __device_attach+0x2c5/0x450 drivers/base/dd.c:1033
     device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1088
     bus_probe_device+0x12a/0x220 drivers/base/bus.c:574
     device_add+0x7b6/0xb70 drivers/base/core.c:3689
     nsim_bus_dev_new drivers/net/netdevsim/bus.c:471 [inline]
     new_device_store+0x37b/0x710 drivers/net/netdevsim/bus.c:191
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
Call trace for netdevsim0[9] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     inetdev_init+0x19f/0x4f0 net/ipv4/devinet.c:286
     inetdev_event+0x30d/0x1610 net/ipv4/devinet.c:1590
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     register_netdevice+0x173a/0x1cf0 net/core/dev.c:11447
     nsim_init_netdevsim drivers/net/netdevsim/netdev.c:1064 [inline]
     nsim_create+0xb92/0x1100 drivers/net/netdevsim/netdev.c:1146
     __nsim_dev_port_add+0x72a/0xb50 drivers/net/netdevsim/dev.c:1494
     nsim_dev_port_add_all+0x37/0xf0 drivers/net/netdevsim/dev.c:1550
     nsim_drv_probe+0x905/0xc20 drivers/net/netdevsim/dev.c:1711
     call_driver_probe drivers/base/dd.c:-1 [inline]
     really_probe+0x267/0xaf0 drivers/base/dd.c:661
     __driver_probe_device+0x18c/0x320 drivers/base/dd.c:803
     driver_probe_device+0x4f/0x240 drivers/base/dd.c:833
     __device_attach_driver+0x2d4/0x4c0 drivers/base/dd.c:961
     bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500
     __device_attach+0x2c5/0x450 drivers/base/dd.c:1033
     device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1088
     bus_probe_device+0x12a/0x220 drivers/base/bus.c:574
     device_add+0x7b6/0xb70 drivers/base/core.c:3689
     nsim_bus_dev_new drivers/net/netdevsim/bus.c:471 [inline]
     new_device_store+0x37b/0x710 drivers/net/netdevsim/bus.c:191
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
Call trace for netdevsim0[10] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     neigh_parms_alloc+0x192/0x530 net/core/neighbour.c:1778
     ipv6_add_dev+0x40d/0x13c0 net/ipv6/addrconf.c:403
     addrconf_notify+0x771/0x1050 net/ipv6/addrconf.c:3655
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     register_netdevice+0x173a/0x1cf0 net/core/dev.c:11447
     nsim_init_netdevsim drivers/net/netdevsim/netdev.c:1064 [inline]
     nsim_create+0xb92/0x1100 drivers/net/netdevsim/netdev.c:1146
     __nsim_dev_port_add+0x72a/0xb50 drivers/net/netdevsim/dev.c:1494
     nsim_dev_port_add_all+0x37/0xf0 drivers/net/netdevsim/dev.c:1550
     nsim_drv_probe+0x905/0xc20 drivers/net/netdevsim/dev.c:1711
     call_driver_probe drivers/base/dd.c:-1 [inline]
     really_probe+0x267/0xaf0 drivers/base/dd.c:661
     __driver_probe_device+0x18c/0x320 drivers/base/dd.c:803
     driver_probe_device+0x4f/0x240 drivers/base/dd.c:833
     __device_attach_driver+0x2d4/0x4c0 drivers/base/dd.c:961
     bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500
     __device_attach+0x2c5/0x450 drivers/base/dd.c:1033
     device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1088
     bus_probe_device+0x12a/0x220 drivers/base/bus.c:574
     device_add+0x7b6/0xb70 drivers/base/core.c:3689
     nsim_bus_dev_new drivers/net/netdevsim/bus.c:471 [inline]
     new_device_store+0x37b/0x710 drivers/net/netdevsim/bus.c:191
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
Call trace for netdevsim0[11] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     ipv6_add_dev+0x4ae/0x13c0 net/ipv6/addrconf.c:411
     addrconf_notify+0x771/0x1050 net/ipv6/addrconf.c:3655
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     register_netdevice+0x173a/0x1cf0 net/core/dev.c:11447
     nsim_init_netdevsim drivers/net/netdevsim/netdev.c:1064 [inline]
     nsim_create+0xb92/0x1100 drivers/net/netdevsim/netdev.c:1146
     __nsim_dev_port_add+0x72a/0xb50 drivers/net/netdevsim/dev.c:1494
     nsim_dev_port_add_all+0x37/0xf0 drivers/net/netdevsim/dev.c:1550
     nsim_drv_probe+0x905/0xc20 drivers/net/netdevsim/dev.c:1711
     call_driver_probe drivers/base/dd.c:-1 [inline]
     really_probe+0x267/0xaf0 drivers/base/dd.c:661
     __driver_probe_device+0x18c/0x320 drivers/base/dd.c:803
     driver_probe_device+0x4f/0x240 drivers/base/dd.c:833
     __device_attach_driver+0x2d4/0x4c0 drivers/base/dd.c:961
     bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500
     __device_attach+0x2c5/0x450 drivers/base/dd.c:1033
     device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1088
     bus_probe_device+0x12a/0x220 drivers/base/bus.c:574
     device_add+0x7b6/0xb70 drivers/base/core.c:3689
     nsim_bus_dev_new drivers/net/netdevsim/bus.c:471 [inline]
     new_device_store+0x37b/0x710 drivers/net/netdevsim/bus.c:191
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
Call trace for netdevsim0[12] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     batadv_hardif_add_interface net/batman-adv/hard-interface.c:878 [inline]
     batadv_hard_if_event+0xb47/0x1240 net/batman-adv/hard-interface.c:958
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     register_netdevice+0x173a/0x1cf0 net/core/dev.c:11447
     nsim_init_netdevsim drivers/net/netdevsim/netdev.c:1064 [inline]
     nsim_create+0xb92/0x1100 drivers/net/netdevsim/netdev.c:1146
     __nsim_dev_port_add+0x72a/0xb50 drivers/net/netdevsim/dev.c:1494
     nsim_dev_port_add_all+0x37/0xf0 drivers/net/netdevsim/dev.c:1550
     nsim_drv_probe+0x905/0xc20 drivers/net/netdevsim/dev.c:1711
     call_driver_probe drivers/base/dd.c:-1 [inline]
     really_probe+0x267/0xaf0 drivers/base/dd.c:661
     __driver_probe_device+0x18c/0x320 drivers/base/dd.c:803
     driver_probe_device+0x4f/0x240 drivers/base/dd.c:833
     __device_attach_driver+0x2d4/0x4c0 drivers/base/dd.c:961
     bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500
     __device_attach+0x2c5/0x450 drivers/base/dd.c:1033
     device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1088
     bus_probe_device+0x12a/0x220 drivers/base/bus.c:574
     device_add+0x7b6/0xb70 drivers/base/core.c:3689
     nsim_bus_dev_new drivers/net/netdevsim/bus.c:471 [inline]
     new_device_store+0x37b/0x710 drivers/net/netdevsim/bus.c:191
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
Call trace for netdevsim0[13] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     udp_tunnel_nic_register net/ipv4/udp_tunnel_nic.c:850 [inline]
     udp_tunnel_nic_netdevice_event+0xaea/0x17e0 net/ipv4/udp_tunnel_nic.c:931
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     register_netdevice+0x173a/0x1cf0 net/core/dev.c:11447
     nsim_init_netdevsim drivers/net/netdevsim/netdev.c:1064 [inline]
     nsim_create+0xb92/0x1100 drivers/net/netdevsim/netdev.c:1146
     __nsim_dev_port_add+0x72a/0xb50 drivers/net/netdevsim/dev.c:1494
     nsim_dev_port_add_all+0x37/0xf0 drivers/net/netdevsim/dev.c:1550
     nsim_drv_probe+0x905/0xc20 drivers/net/netdevsim/dev.c:1711
     call_driver_probe drivers/base/dd.c:-1 [inline]
     really_probe+0x267/0xaf0 drivers/base/dd.c:661
     __driver_probe_device+0x18c/0x320 drivers/base/dd.c:803
     driver_probe_device+0x4f/0x240 drivers/base/dd.c:833
     __device_attach_driver+0x2d4/0x4c0 drivers/base/dd.c:961
     bus_for_each_drv+0x258/0x2f0 drivers/base/bus.c:500
     __device_attach+0x2c5/0x450 drivers/base/dd.c:1033
     device_initial_probe+0xa1/0xd0 drivers/base/dd.c:1088
     bus_probe_device+0x12a/0x220 drivers/base/bus.c:574
     device_add+0x7b6/0xb70 drivers/base/core.c:3689
     nsim_bus_dev_new drivers/net/netdevsim/bus.c:471 [inline]
     new_device_store+0x37b/0x710 drivers/net/netdevsim/bus.c:191
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
Call trace for netdevsim0[14] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     qdisc_alloc+0x631/0x910 net/sched/sch_generic.c:985
     qdisc_create_dflt+0x8e/0x510 net/sched/sch_generic.c:1008
     attach_one_default_qdisc net/sched/sch_generic.c:1174 [inline]
     netdev_for_each_tx_queue include/linux/netdevice.h:2688 [inline]
     attach_default_qdiscs net/sched/sch_generic.c:1192 [inline]
     dev_activate+0x378/0x1150 net/sched/sch_generic.c:1251
     __dev_open+0x67a/0x830 net/core/dev.c:1704
     __dev_change_flags+0x1f7/0x690 net/core/dev.c:9749
     netif_change_flags+0x88/0x1a0 net/core/dev.c:9812
     do_setlink+0xf82/0x4590 net/core/rtnetlink.c:3158
     rtnl_changelink net/core/rtnetlink.c:3776 [inline]
     __rtnl_newlink net/core/rtnetlink.c:3935 [inline]
     rtnl_newlink+0x15a9/0x1be0 net/core/rtnetlink.c:4072
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[15] +3 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     netdevice_queue_work drivers/infiniband/core/roce_gid_mgmt.c:698 [inline]
     netdevice_event+0x4ea/0x8d0 drivers/infiniband/core/roce_gid_mgmt.c:849
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     __dev_notify_flags+0x1a9/0x310 net/core/dev.c:9788
     netif_change_flags+0xe8/0x1a0 net/core/dev.c:9817
     do_setlink+0xf82/0x4590 net/core/rtnetlink.c:3158
     rtnl_changelink net/core/rtnetlink.c:3776 [inline]
     __rtnl_newlink net/core/rtnetlink.c:3935 [inline]
     rtnl_newlink+0x15a9/0x1be0 net/core/rtnetlink.c:4072
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[16] +3 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     netdevice_queue_work drivers/infiniband/core/roce_gid_mgmt.c:699 [inline]
     netdevice_event+0x593/0x8d0 drivers/infiniband/core/roce_gid_mgmt.c:849
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     __dev_notify_flags+0x1a9/0x310 net/core/dev.c:9788
     netif_change_flags+0xe8/0x1a0 net/core/dev.c:9817
     do_setlink+0xf82/0x4590 net/core/rtnetlink.c:3158
     rtnl_changelink net/core/rtnetlink.c:3776 [inline]
     __rtnl_newlink net/core/rtnetlink.c:3935 [inline]
     rtnl_newlink+0x15a9/0x1be0 net/core/rtnetlink.c:4072
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[17] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     dev_get_by_index+0x1b3/0x2f0 net/core/dev.c:995
     netdev_get_by_index+0x25/0xb0 net/core/dev.c:1018
     fib6_nh_init+0x1f2/0x2010 net/ipv6/route.c:3598
     ip6_route_info_create_nh+0x16a/0xad0 net/ipv6/route.c:3898
     ip6_route_add+0x6e/0x1b0 net/ipv6/route.c:3950
     addrconf_add_mroute+0x2d1/0x370 net/ipv6/addrconf.c:2552
     addrconf_add_dev net/ipv6/addrconf.c:2570 [inline]
     addrconf_dev_config net/ipv6/addrconf.c:3484 [inline]
     addrconf_init_auto_addrs+0x4d7/0xa50 net/ipv6/addrconf.c:3572
     addrconf_notify+0xb1e/0x1050 net/ipv6/addrconf.c:3745
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     __dev_notify_flags+0x1a9/0x310 net/core/dev.c:9788
     netif_change_flags+0xe8/0x1a0 net/core/dev.c:9817
     do_setlink+0xf82/0x4590 net/core/rtnetlink.c:3158
     rtnl_changelink net/core/rtnetlink.c:3776 [inline]
     __rtnl_newlink net/core/rtnetlink.c:3935 [inline]
     rtnl_newlink+0x15a9/0x1be0 net/core/rtnetlink.c:4072
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[18] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     dev_get_by_index+0x1b3/0x2f0 net/core/dev.c:995
     netdev_get_by_index+0x25/0xb0 net/core/dev.c:1018
     fib6_nh_init+0x1f2/0x2010 net/ipv6/route.c:3598
     ip6_route_info_create_nh+0x16a/0xad0 net/ipv6/route.c:3898
     addrconf_f6i_alloc+0x3b7/0x630 net/ipv6/route.c:4690
     ipv6_add_addr+0x59c/0x1100 net/ipv6/addrconf.c:1126
     addrconf_add_linklocal+0x20c/0x460 net/ipv6/addrconf.c:3311
     addrconf_addr_gen+0x2f8/0x360 net/ipv6/addrconf.c:3447
     addrconf_notify+0xb1e/0x1050 net/ipv6/addrconf.c:3745
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     __dev_notify_flags+0x1a9/0x310 net/core/dev.c:9788
     netif_change_flags+0xe8/0x1a0 net/core/dev.c:9817
     do_setlink+0xf82/0x4590 net/core/rtnetlink.c:3158
     rtnl_changelink net/core/rtnetlink.c:3776 [inline]
     __rtnl_newlink net/core/rtnetlink.c:3935 [inline]
     rtnl_newlink+0x15a9/0x1be0 net/core/rtnetlink.c:4072
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[19] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     addr_event+0x302/0x480 drivers/infiniband/core/roce_gid_mgmt.c:897
     inet6addr_event+0x9f/0xd0 drivers/infiniband/core/roce_gid_mgmt.c:930
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     atomic_notifier_call_chain+0xda/0x180 kernel/notifier.c:223
     ipv6_add_addr+0xe08/0x1100 net/ipv6/addrconf.c:1186
     addrconf_add_linklocal+0x20c/0x460 net/ipv6/addrconf.c:3311
     addrconf_addr_gen+0x2f8/0x360 net/ipv6/addrconf.c:3447
     addrconf_notify+0xb1e/0x1050 net/ipv6/addrconf.c:3745
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     __dev_notify_flags+0x1a9/0x310 net/core/dev.c:9788
     netif_change_flags+0xe8/0x1a0 net/core/dev.c:9817
     do_setlink+0xf82/0x4590 net/core/rtnetlink.c:3158
     rtnl_changelink net/core/rtnetlink.c:3776 [inline]
     __rtnl_newlink net/core/rtnetlink.c:3935 [inline]
     rtnl_newlink+0x15a9/0x1be0 net/core/rtnetlink.c:4072
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[20] -6 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     dev_put include/linux/netdevice.h:4481 [inline]
     update_gid_event_work_handler+0x84/0xf0 drivers/infiniband/core/roce_gid_mgmt.c:861
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
Call trace for netdevsim0[21] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     dev_get_by_index+0x1b3/0x2f0 net/core/dev.c:995
     netdev_get_by_index+0x25/0xb0 net/core/dev.c:1018
     fib6_nh_init+0x1f2/0x2010 net/ipv6/route.c:3598
     ip6_route_info_create_nh+0x16a/0xad0 net/ipv6/route.c:3898
     ip6_route_add+0x6e/0x1b0 net/ipv6/route.c:3950
     addrconf_prefix_route+0x3a2/0x480 net/ipv6/addrconf.c:2488
     addrconf_add_linklocal+0x266/0x460 net/ipv6/addrconf.c:3313
     addrconf_addr_gen+0x2f8/0x360 net/ipv6/addrconf.c:3447
     addrconf_notify+0xb1e/0x1050 net/ipv6/addrconf.c:3745
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     __dev_notify_flags+0x1a9/0x310 net/core/dev.c:9788
     netif_change_flags+0xe8/0x1a0 net/core/dev.c:9817
     do_setlink+0xf82/0x4590 net/core/rtnetlink.c:3158
     rtnl_changelink net/core/rtnetlink.c:3776 [inline]
     __rtnl_newlink net/core/rtnetlink.c:3935 [inline]
     rtnl_newlink+0x15a9/0x1be0 net/core/rtnetlink.c:4072
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[22] +5 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dst_init+0x6f/0x490 net/core/dst.c:52
     dst_alloc+0x12a/0x170 net/core/dst.c:94
     ip6_dst_alloc net/ipv6/route.c:342 [inline]
     icmp6_dst_alloc+0x75/0x440 net/ipv6/route.c:3333
     mld_sendpack+0x6ba/0xe40 net/ipv6/mcast.c:1844
     mld_send_cr net/ipv6/mcast.c:2154 [inline]
     mld_ifc_work+0x835/0xe70 net/ipv6/mcast.c:2693
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
Call trace for netdevsim0[23] +2 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     ___neigh_create+0xc3d/0x2290 net/core/neighbour.c:664
     ip6_finish_output2+0x1038/0x1360 net/ipv6/ip6_output.c:128
     NF_HOOK_COND include/linux/netfilter.h:307 [inline]
     ip6_output+0x340/0x550 net/ipv6/ip6_output.c:247
     NF_HOOK+0xa2/0x3a0 include/linux/netfilter.h:318
     mld_sendpack+0x8b4/0xe40 net/ipv6/mcast.c:1855
     mld_send_cr net/ipv6/mcast.c:2154 [inline]
     mld_ifc_work+0x835/0xe70 net/ipv6/mcast.c:2693
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
Call trace for netdevsim0[24] -17 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     dst_destroy+0x117/0x360 net/core/dst.c:115
     rcu_do_batch kernel/rcu/tree.c:2617 [inline]
     rcu_core+0x7cd/0x1070 kernel/rcu/tree.c:2869
     handle_softirqs+0x22a/0x870 kernel/softirq.c:626
Call trace for netdevsim0[25] +2 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dst_init+0x6f/0x490 net/core/dst.c:52
     dst_alloc+0x12a/0x170 net/core/dst.c:94
     ip6_dst_alloc net/ipv6/route.c:342 [inline]
     icmp6_dst_alloc+0x75/0x440 net/ipv6/route.c:3333
     ndisc_send_skb+0x42d/0x14e0 net/ipv6/ndisc.c:491
     ndisc_send_ns+0xd7/0x160 net/ipv6/ndisc.c:670
     addrconf_dad_work+0xac4/0x14c0 net/ipv6/addrconf.c:4287
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
Call trace for netdevsim0[26] +2 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     ___neigh_create+0xc3d/0x2290 net/core/neighbour.c:664
     ip6_finish_output2+0x1038/0x1360 net/ipv6/ip6_output.c:128
     NF_HOOK_COND include/linux/netfilter.h:307 [inline]
     ip6_output+0x340/0x550 net/ipv6/ip6_output.c:247
     NF_HOOK include/linux/netfilter.h:318 [inline]
     ndisc_send_skb+0xbaa/0x14e0 net/ipv6/ndisc.c:512
     ndisc_send_ns+0xd7/0x160 net/ipv6/ndisc.c:670
     addrconf_dad_work+0xac4/0x14c0 net/ipv6/addrconf.c:4287
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
Call trace for netdevsim0[27] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     addr_event+0x302/0x480 drivers/infiniband/core/roce_gid_mgmt.c:897
     inetaddr_event+0xef/0x150 drivers/infiniband/core/roce_gid_mgmt.c:916
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     blocking_notifier_call_chain+0x6a/0x90 kernel/notifier.c:380
     __inet_insert_ifa+0x9e9/0xbc0 net/ipv4/devinet.c:566
     inet_rtm_newaddr+0x10d8/0x1ad0 net/ipv4/devinet.c:1001
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[28] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     dev_get_by_index+0x1b3/0x2f0 net/core/dev.c:995
     fib_create_info+0x2296/0x31f0 net/ipv4/fib_semantics.c:1493
     fib_table_insert+0xc8/0x1b50 net/ipv4/fib_trie.c:1212
     fib_magic+0x434/0x510 net/ipv4/fib_frontend.c:1134
     fib_add_ifaddr+0x144/0x5f0 net/ipv4/fib_frontend.c:1156
     fib_inetaddr_event+0x12e/0x190 net/ipv4/fib_frontend.c:1470
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     blocking_notifier_call_chain+0x6a/0x90 kernel/notifier.c:380
     __inet_insert_ifa+0x9e9/0xbc0 net/ipv4/devinet.c:566
     inet_rtm_newaddr+0x10d8/0x1ad0 net/ipv4/devinet.c:1001
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[29] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     fib_check_nh_nongw net/ipv4/fib_semantics.c:1263 [inline]
     fib_check_nh+0xd1e/0x1b60 net/ipv4/fib_semantics.c:1283
     fib_create_info+0x2085/0x31f0 net/ipv4/fib_semantics.c:1503
     fib_table_insert+0xc8/0x1b50 net/ipv4/fib_trie.c:1212
     fib_magic+0x434/0x510 net/ipv4/fib_frontend.c:1134
     fib_add_ifaddr+0x38d/0x5f0 net/ipv4/fib_frontend.c:1171
     fib_inetaddr_event+0x12e/0x190 net/ipv4/fib_frontend.c:1470
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     blocking_notifier_call_chain+0x6a/0x90 kernel/notifier.c:380
     __inet_insert_ifa+0x9e9/0xbc0 net/ipv4/devinet.c:566
     inet_rtm_newaddr+0x10d8/0x1ad0 net/ipv4/devinet.c:1001
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[30] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     fib_check_nh_nongw net/ipv4/fib_semantics.c:1263 [inline]
     fib_check_nh+0xd1e/0x1b60 net/ipv4/fib_semantics.c:1283
     fib_create_info+0x2085/0x31f0 net/ipv4/fib_semantics.c:1503
     fib_table_insert+0xc8/0x1b50 net/ipv4/fib_trie.c:1212
     fib_magic+0x434/0x510 net/ipv4/fib_frontend.c:1134
     fib_add_ifaddr+0x3fb/0x5f0 net/ipv4/fib_frontend.c:1178
     fib_inetaddr_event+0x12e/0x190 net/ipv4/fib_frontend.c:1470
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     blocking_notifier_call_chain+0x6a/0x90 kernel/notifier.c:380
     __inet_insert_ifa+0x9e9/0xbc0 net/ipv4/devinet.c:566
     inet_rtm_newaddr+0x10d8/0x1ad0 net/ipv4/devinet.c:1001
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[31] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     dev_get_by_index+0x1b3/0x2f0 net/core/dev.c:995
     netdev_get_by_index+0x25/0xb0 net/core/dev.c:1018
     fib6_nh_init+0x1f2/0x2010 net/ipv6/route.c:3598
     ip6_route_info_create_nh+0x16a/0xad0 net/ipv6/route.c:3898
     ip6_route_add+0x6e/0x1b0 net/ipv6/route.c:3950
     addrconf_add_mroute+0x2d1/0x370 net/ipv6/addrconf.c:2552
     addrconf_add_dev net/ipv6/addrconf.c:2570 [inline]
     inet6_addr_add+0x2dd/0xb20 net/ipv6/addrconf.c:3032
     inet6_rtm_newaddr+0xa17/0xe30 net/ipv6/addrconf.c:5064
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[32] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     dev_get_by_index+0x1b3/0x2f0 net/core/dev.c:995
     netdev_get_by_index+0x25/0xb0 net/core/dev.c:1018
     fib6_nh_init+0x1f2/0x2010 net/ipv6/route.c:3598
     ip6_route_info_create_nh+0x16a/0xad0 net/ipv6/route.c:3898
     addrconf_f6i_alloc+0x3b7/0x630 net/ipv6/route.c:4690
     ipv6_add_addr+0x59c/0x1100 net/ipv6/addrconf.c:1126
     inet6_addr_add+0x454/0xb20 net/ipv6/addrconf.c:3050
     inet6_rtm_newaddr+0xa17/0xe30 net/ipv6/addrconf.c:5064
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[33] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     addr_event+0x302/0x480 drivers/infiniband/core/roce_gid_mgmt.c:897
     inet6addr_event+0x9f/0xd0 drivers/infiniband/core/roce_gid_mgmt.c:930
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     atomic_notifier_call_chain+0xda/0x180 kernel/notifier.c:223
     ipv6_add_addr+0xe08/0x1100 net/ipv6/addrconf.c:1186
     inet6_addr_add+0x454/0xb20 net/ipv6/addrconf.c:3050
     inet6_rtm_newaddr+0xa17/0xe30 net/ipv6/addrconf.c:5064
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[34] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     dev_get_by_index+0x1b3/0x2f0 net/core/dev.c:995
     netdev_get_by_index+0x25/0xb0 net/core/dev.c:1018
     fib6_nh_init+0x1f2/0x2010 net/ipv6/route.c:3598
     ip6_route_info_create_nh+0x16a/0xad0 net/ipv6/route.c:3898
     ip6_route_add+0x6e/0x1b0 net/ipv6/route.c:3950
     addrconf_prefix_route+0x3a2/0x480 net/ipv6/addrconf.c:2488
     inet6_addr_add+0x508/0xb20 net/ipv6/addrconf.c:3053
     inet6_rtm_newaddr+0xa17/0xe30 net/ipv6/addrconf.c:5064
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[35] +3 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     netdevice_queue_work drivers/infiniband/core/roce_gid_mgmt.c:698 [inline]
     netdevice_event+0x4ea/0x8d0 drivers/infiniband/core/roce_gid_mgmt.c:849
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     netif_set_mac_address+0x39f/0x4e0 net/core/dev.c:9990
     do_setlink+0x9b1/0x4590 net/core/rtnetlink.c:3110
     rtnl_changelink net/core/rtnetlink.c:3776 [inline]
     __rtnl_newlink net/core/rtnetlink.c:3935 [inline]
     rtnl_newlink+0x15a9/0x1be0 net/core/rtnetlink.c:4072
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[36] +3 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     netdevice_queue_work drivers/infiniband/core/roce_gid_mgmt.c:699 [inline]
     netdevice_event+0x593/0x8d0 drivers/infiniband/core/roce_gid_mgmt.c:849
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     netif_set_mac_address+0x39f/0x4e0 net/core/dev.c:9990
     do_setlink+0x9b1/0x4590 net/core/rtnetlink.c:3110
     rtnl_changelink net/core/rtnetlink.c:3776 [inline]
     __rtnl_newlink net/core/rtnetlink.c:3935 [inline]
     rtnl_newlink+0x15a9/0x1be0 net/core/rtnetlink.c:4072
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[37] -2 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     neigh_destroy+0x35c/0x5d0 net/core/neighbour.c:940
     neigh_flush_dev net/core/neighbour.c:433 [inline]
     neigh_changeaddr+0xde/0x130 net/core/neighbour.c:457
     ndisc_netdev_event+0x18f/0x4d0 net/ipv6/ndisc.c:1862
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     netif_set_mac_address+0x39f/0x4e0 net/core/dev.c:9990
     do_setlink+0x9b1/0x4590 net/core/rtnetlink.c:3110
     rtnl_changelink net/core/rtnetlink.c:3776 [inline]
     __rtnl_newlink net/core/rtnetlink.c:3935 [inline]
     rtnl_newlink+0x15a9/0x1be0 net/core/rtnetlink.c:4072
     rtnetlink_rcv_msg+0x7d5/0xbe0 net/core/rtnetlink.c:6958
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
     __sock_sendmsg net/socket.c:752 [inline]
     __sys_sendto+0x3ff/0x590 net/socket.c:2221
     __do_sys_sendto net/socket.c:2228 [inline]
     __se_sys_sendto net/socket.c:2224 [inline]
     __x64_sys_sendto+0xde/0x100 net/socket.c:2224
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
Call trace for netdevsim0[38] -6 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     fib_nh_common_release+0x5c/0x430 net/ipv4/fib_semantics.c:204
     fib6_info_destroy_rcu+0xca/0x1c0 net/ipv6/ip6_fib.c:177
     rcu_do_batch kernel/rcu/tree.c:2617 [inline]
     rcu_core+0x7cd/0x1070 kernel/rcu/tree.c:2869
     handle_softirqs+0x22a/0x870 kernel/softirq.c:626
Call trace for netdevsim0[39] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dst_init+0x6f/0x490 net/core/dst.c:52
     dst_alloc+0x12a/0x170 net/core/dst.c:94
     ip6_dst_alloc net/ipv6/route.c:342 [inline]
     icmp6_dst_alloc+0x75/0x440 net/ipv6/route.c:3333
     mld_sendpack+0x6ba/0xe40 net/ipv6/mcast.c:1844
     ipv6_mc_dad_complete+0x88/0x540 net/ipv6/mcast.c:2279
     addrconf_dad_completed+0x8a7/0xe60 net/ipv6/addrconf.c:4345
     addrconf_dad_work+0xc5e/0x14c0 net/ipv6/addrconf.c:-1
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
Call trace for netdevsim0[40] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dst_init+0x6f/0x490 net/core/dst.c:52
     dst_alloc+0x12a/0x170 net/core/dst.c:94
     ip6_dst_alloc net/ipv6/route.c:342 [inline]
     icmp6_dst_alloc+0x75/0x440 net/ipv6/route.c:3333
     ndisc_send_skb+0x42d/0x14e0 net/ipv6/ndisc.c:491
     addrconf_dad_completed+0x909/0xe60 net/ipv6/addrconf.c:4365
     addrconf_dad_work+0xc5e/0x14c0 net/ipv6/addrconf.c:-1
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
Call trace for netdevsim0[41] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     ___neigh_create+0xc3d/0x2290 net/core/neighbour.c:664
     ip6_finish_output2+0x1038/0x1360 net/ipv6/ip6_output.c:128
     NF_HOOK_COND include/linux/netfilter.h:307 [inline]
     ip6_output+0x340/0x550 net/ipv6/ip6_output.c:247
     NF_HOOK include/linux/netfilter.h:318 [inline]
     ndisc_send_skb+0xbaa/0x14e0 net/ipv6/ndisc.c:512
     addrconf_dad_completed+0x909/0xe60 net/ipv6/addrconf.c:4365
     addrconf_dad_work+0xc5e/0x14c0 net/ipv6/addrconf.c:-1
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
Call trace for netdevsim0[42] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dst_init+0x6f/0x490 net/core/dst.c:52
     dst_alloc+0x12a/0x170 net/core/dst.c:94
     ip6_dst_alloc net/ipv6/route.c:342 [inline]
     icmp6_dst_alloc+0x75/0x440 net/ipv6/route.c:3333
     mld_sendpack+0x6ba/0xe40 net/ipv6/mcast.c:1844
     mld_dad_work+0x45/0x5b0 net/ipv6/mcast.c:2294
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
Call trace for netdevsim0[43] +7 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dst_init+0x6f/0x490 net/core/dst.c:52
     dst_alloc+0x12a/0x170 net/core/dst.c:94
     ip6_dst_alloc net/ipv6/route.c:342 [inline]
     icmp6_dst_alloc+0x75/0x440 net/ipv6/route.c:3333
     ndisc_send_skb+0x42d/0x14e0 net/ipv6/ndisc.c:491
     addrconf_rs_timer+0x395/0x6d0 net/ipv6/addrconf.c:4042
     call_timer_fn+0x192/0x640 kernel/time/timer.c:1748
     expire_timers kernel/time/timer.c:1799 [inline]
     __run_timers kernel/time/timer.c:2373 [inline]
     __run_timer_base+0x652/0x8b0 kernel/time/timer.c:2385
     run_timer_base kernel/time/timer.c:2394 [inline]
     run_timer_softirq+0xb7/0x170 kernel/time/timer.c:2404
     handle_softirqs+0x22a/0x870 kernel/softirq.c:626
Call trace for netdevsim0[44] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     dev_get_by_index+0x1b3/0x2f0 net/core/dev.c:995
     xfrm_dev_state_add+0x33a/0xc40 net/xfrm/xfrm_device.c:268
     xfrm_state_construct net/xfrm/xfrm_user.c:986 [inline]
     xfrm_add_sa+0x34ca/0x4230 net/xfrm/xfrm_user.c:1022
     xfrm_user_rcv_msg+0x746/0xb20 net/xfrm/xfrm_user.c:3507
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     xfrm_netlink_rcv+0x79/0x90 net/xfrm/xfrm_user.c:3529
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[45] -6 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     neigh_destroy+0x35c/0x5d0 net/core/neighbour.c:940
     neigh_periodic_work+0xb4f/0xe50 net/core/neighbour.c:1029
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
     process_scheduled_works kernel/workqueue.c:3362 [inline]
     worker_thread+0xb46/0x1140 kernel/workqueue.c:3443
     kthread+0x388/0x470 kernel/kthread.c:467
     ret_from_fork+0x51e/0xb90 arch/x86/kernel/process.c:158
     ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
Call trace for netdevsim0[46] +3 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     ___neigh_create+0xc3d/0x2290 net/core/neighbour.c:664
     ip6_finish_output2+0x1038/0x1360 net/ipv6/ip6_output.c:128
     NF_HOOK_COND include/linux/netfilter.h:307 [inline]
     ip6_output+0x340/0x550 net/ipv6/ip6_output.c:247
     NF_HOOK include/linux/netfilter.h:318 [inline]
     ndisc_send_skb+0xbaa/0x14e0 net/ipv6/ndisc.c:512
     addrconf_rs_timer+0x395/0x6d0 net/ipv6/addrconf.c:4042
     call_timer_fn+0x192/0x640 kernel/time/timer.c:1748
     expire_timers kernel/time/timer.c:1799 [inline]
     __run_timers kernel/time/timer.c:2373 [inline]
     __run_timer_base+0x652/0x8b0 kernel/time/timer.c:2385
     run_timer_base kernel/time/timer.c:2394 [inline]
     run_timer_softirq+0xb7/0x170 kernel/time/timer.c:2404
     handle_softirqs+0x22a/0x870 kernel/softirq.c:626
Call trace for netdevsim0[47] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     dev_get_by_name+0xdb/0x210 net/core/dev.c:909
     netdev_get_by_name+0x27/0xb0 net/core/dev.c:933
     ethnl_parse_header_dev_get+0x445/0x8b0 net/ethtool/netlink.c:194
     ethnl_default_parse net/ethtool/netlink.c:457 [inline]
     ethnl_default_set_doit+0x224/0xae0 net/ethtool/netlink.c:895
     genl_family_rcv_msg_doit+0x22a/0x330 net/netlink/genetlink.c:1115
     genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
     genl_rcv_msg+0x61c/0x7a0 net/netlink/genetlink.c:1210
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[48] -1 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     ethnl_parse_header_dev_put net/ethtool/netlink.h:274 [inline]
     ethnl_default_set_doit+0x92e/0xae0 net/ethtool/netlink.c:940
     genl_family_rcv_msg_doit+0x22a/0x330 net/netlink/genetlink.c:1115
     genl_family_rcv_msg net/netlink/genetlink.c:1195 [inline]
     genl_rcv_msg+0x61c/0x7a0 net/netlink/genetlink.c:1210
     netlink_rcv_skb+0x232/0x4b0 net/netlink/af_netlink.c:2550
     genl_rcv+0x28/0x40 net/netlink/genetlink.c:1219
     netlink_unicast_kernel net/netlink/af_netlink.c:1318 [inline]
     netlink_unicast+0x80f/0x9b0 net/netlink/af_netlink.c:1344
     netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1894
     sock_sendmsg_nosec+0x18f/0x1d0 net/socket.c:737
Call trace for netdevsim0[49] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     linkwatch_add_event net/core/link_watch.c:131 [inline]
     linkwatch_fire_event+0x166/0x220 net/core/link_watch.c:314
     nsim_stop+0x88/0x430 drivers/net/netdevsim/netdev.c:595
     __dev_close_many+0x368/0x6d0 net/core/dev.c:1768
     netif_close_many+0x225/0x420 net/core/dev.c:1793
     netif_close_many_and_unlock net/core/dev.c:12317 [inline]
     unregister_netdevice_many_notify+0x81f/0x2380 net/core/dev.c:12381
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
Call trace for netdevsim0[50] +2 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     addr_event+0x302/0x480 drivers/infiniband/core/roce_gid_mgmt.c:897
     inet6addr_event+0x9f/0xd0 drivers/infiniband/core/roce_gid_mgmt.c:930
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     atomic_notifier_call_chain+0xda/0x180 kernel/notifier.c:223
     addrconf_ifdown+0xeb3/0x1a40 net/ipv6/addrconf.c:3983
     addrconf_notify+0x1bc/0x1050 net/ipv6/addrconf.c:-1
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     netif_close_many+0x2ae/0x420 net/core/dev.c:1797
     netif_close_many_and_unlock net/core/dev.c:12317 [inline]
     unregister_netdevice_many_notify+0x81f/0x2380 net/core/dev.c:12381
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
Call trace for netdevsim0[51] -3 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     fib_nh_common_release+0x5c/0x430 net/ipv4/fib_semantics.c:204
     fib_nh_release net/ipv4/fib_semantics.c:218 [inline]
     free_fib_info_rcu+0xdf/0x310 net/ipv4/fib_semantics.c:230
     rcu_do_batch kernel/rcu/tree.c:2617 [inline]
     rcu_core+0x7cd/0x1070 kernel/rcu/tree.c:2869
     handle_softirqs+0x22a/0x870 kernel/softirq.c:626
Call trace for netdevsim0[52] -1 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     __qdisc_destroy+0x1c9/0x450 net/sched/sch_generic.c:1081
     qdisc_put net/sched/sch_generic.c:1105 [inline]
     dev_shutdown+0x34c/0x440 net/sched/sch_generic.c:1493
     unregister_netdevice_many_notify+0x11a9/0x2380 net/core/dev.c:12405
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
Call trace for netdevsim0[53] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     netdevice_queue_work drivers/infiniband/core/roce_gid_mgmt.c:698 [inline]
     netdevice_event+0x4ea/0x8d0 drivers/infiniband/core/roce_gid_mgmt.c:849
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     unregister_netdevice_many_notify+0x186a/0x2380 net/core/dev.c:12417
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
Call trace for netdevsim0[54] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     netdevice_queue_work drivers/infiniband/core/roce_gid_mgmt.c:699 [inline]
     netdevice_event+0x593/0x8d0 drivers/infiniband/core/roce_gid_mgmt.c:849
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     unregister_netdevice_many_notify+0x186a/0x2380 net/core/dev.c:12417
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
Call trace for netdevsim0[55] +1 at
     __dev_hold include/linux/netdevice.h:4403 [inline]
     netdev_hold include/linux/netdevice.h:4446 [inline]
     dev_hold include/linux/netdevice.h:4469 [inline]
     addr_event+0x302/0x480 drivers/infiniband/core/roce_gid_mgmt.c:897
     inetaddr_event+0xef/0x150 drivers/infiniband/core/roce_gid_mgmt.c:916
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     blocking_notifier_call_chain+0x6a/0x90 kernel/notifier.c:380
     __inet_del_ifa+0x840/0xfe0 net/ipv4/devinet.c:450
     inet_del_ifa net/ipv4/devinet.c:487 [inline]
     inetdev_destroy net/ipv4/devinet.c:328 [inline]
     inetdev_event+0x647/0x1610 net/ipv4/devinet.c:1655
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     unregister_netdevice_many_notify+0x186a/0x2380 net/core/dev.c:12417
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
Call trace for netdevsim0[56] -1 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     neigh_parms_release+0x170/0x200 net/core/neighbour.c:1817
     inetdev_destroy net/ipv4/devinet.c:335 [inline]
     inetdev_event+0x7f4/0x1610 net/ipv4/devinet.c:1655
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     unregister_netdevice_many_notify+0x186a/0x2380 net/core/dev.c:12417
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
Call trace for netdevsim0[57] -1 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     neigh_parms_release+0x170/0x200 net/core/neighbour.c:1817
     addrconf_ifdown+0x177b/0x1a40 net/ipv6/addrconf.c:4012
     addrconf_notify+0x1bc/0x1050 net/ipv6/addrconf.c:-1
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     unregister_netdevice_many_notify+0x186a/0x2380 net/core/dev.c:12417
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
Call trace for netdevsim0[58] -1 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     batadv_hardif_release net/batman-adv/hard-interface.c:55 [inline]
     kref_put include/linux/kref.h:65 [inline]
     batadv_hardif_put+0x8f/0x140 net/batman-adv/hard-interface.h:94
     batadv_hard_if_event+0x624/0x1240 net/batman-adv/hard-interface.c:1008
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     unregister_netdevice_many_notify+0x186a/0x2380 net/core/dev.c:12417
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
Call trace for netdevsim0[59] -1 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     in6_dev_finish_destroy+0xdd/0x1e0 net/ipv6/addrconf_core.c:273
     in6_dev_put include/net/addrconf.h:422 [inline]
     ip6_dst_ifdown+0xed/0x220 net/ipv6/route.c:384
     dst_dev_put+0xab/0x2d0 net/core/dst.c:151
     fib6_nh_release_dsts net/ipv6/route.c:3740 [inline]
     fib6_nh_release+0x36c/0x430 net/ipv6/route.c:3721
     fib6_info_destroy_rcu+0xca/0x1c0 net/ipv6/ip6_fib.c:177
     rcu_do_batch kernel/rcu/tree.c:2617 [inline]
     rcu_core+0x7cd/0x1070 kernel/rcu/tree.c:2869
     handle_softirqs+0x22a/0x870 kernel/softirq.c:626
Call trace for netdevsim0[60] -1 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     dev_put include/linux/netdevice.h:4481 [inline]
     udp_tunnel_nic_unregister net/ipv4/udp_tunnel_nic.c:913 [inline]
     udp_tunnel_nic_netdevice_event+0x1582/0x17e0 net/ipv4/udp_tunnel_nic.c:942
     notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
     call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
     call_netdevice_notifiers net/core/dev.c:2295 [inline]
     unregister_netdevice_many_notify+0x186a/0x2380 net/core/dev.c:12417
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
Call trace for netdevsim0[61] -1 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     rx_queue_release+0x126/0x1a0 net/core/net-sysfs.c:1181
     kobject_cleanup lib/kobject.c:689 [inline]
     kobject_release lib/kobject.c:720 [inline]
     kref_put include/linux/kref.h:65 [inline]
     kobject_put+0x228/0x560 lib/kobject.c:737
     net_rx_queue_update_kobjects+0x6a6/0x750 net/core/net-sysfs.c:1338
     remove_queue_kobjects net/core/net-sysfs.c:2169 [inline]
     netdev_unregister_kobject+0x113/0x450 net/core/net-sysfs.c:2325
     unregister_netdevice_many_notify+0x1e0e/0x2380 net/core/dev.c:12452
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
Call trace for netdevsim0[62] -1 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     netdev_queue_release+0x6a/0xd0 net/core/net-sysfs.c:1931
     kobject_cleanup lib/kobject.c:689 [inline]
     kobject_release lib/kobject.c:720 [inline]
     kref_put include/linux/kref.h:65 [inline]
     kobject_put+0x228/0x560 lib/kobject.c:737
     netdev_queue_update_kobjects+0x5e8/0x6d0 net/core/net-sysfs.c:2073
     remove_queue_kobjects net/core/net-sysfs.c:2170 [inline]
     netdev_unregister_kobject+0x11f/0x450 net/core/net-sysfs.c:2325
     unregister_netdevice_many_notify+0x1e0e/0x2380 net/core/dev.c:12452
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
Call trace for netdevsim0[63] -1 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     in_dev_finish_destroy+0xa7/0x1a0 net/ipv4/devinet.c:258
     in_dev_put include/linux/inetdevice.h:290 [inline]
     inet_rcu_free_ifa+0x72/0xb0 net/ipv4/devinet.c:228
     rcu_do_batch kernel/rcu/tree.c:2617 [inline]
     rcu_core+0x7cd/0x1070 kernel/rcu/tree.c:2869
     handle_softirqs+0x22a/0x870 kernel/softirq.c:626
Call trace for netdevsim0[64] -1 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     netdev_put include/linux/netdevice.h:4456 [inline]
     unregister_netdevice_many_notify+0x2068/0x2380 net/core/dev.c:12462
     unregister_netdevice_many net/core/dev.c:12480 [inline]
     unregister_netdevice_queue+0x31f/0x360 net/core/dev.c:12294
     unregister_netdevice include/linux/netdevice.h:3414 [inline]
     nsim_destroy+0x1e5/0x680 drivers/net/netdevsim/netdev.c:1183
     __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
     nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
     nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
     nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
     device_remove drivers/base/dd.c:571 [inline]
     __device_release_driver drivers/base/dd.c:1284 [inline]
     device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
     bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
     device_del+0x527/0x8f0 drivers/base/core.c:3878
     device_unregister+0x21/0xf0 drivers/base/core.c:3919
     nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
     del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
     kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
     new_sync_write fs/read_write.c:595 [inline]
     vfs_write+0x61d/0xb90 fs/read_write.c:688
     ksys_write+0x150/0x270 fs/read_write.c:740
     do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
     do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
     entry_SYSCALL_64_after_hwframe+0x77/0x7f
Call trace for netdevsim0[65] -1 at
     __dev_put include/linux/netdevice.h:4389 [inline]
     linkwatch_do_dev+0x89/0x180 net/core/link_watch.c:191
     __linkwatch_run_queue+0x572/0x7f0 net/core/link_watch.c:244
     linkwatch_event+0x4c/0x60 net/core/link_watch.c:304
     process_one_work+0x949/0x1650 kernel/workqueue.c:3279
balance as of netdevsim0[65] is 1
xfrm_dev_state_flush_secctx_check: LSM policy is rejecting this operation.
CPU: 0 UID: 0 PID: 18368 Comm: syz-executor Tainted: G             L      syzkaller #0 PREEMPT(full) 
Tainted: [L]=SOFTLOCKUP
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/24/2026
Call Trace:
 <TASK>
 dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
 xfrm_dev_state_flush_secctx_check net/xfrm/xfrm_state.c:900 [inline]
 xfrm_dev_state_flush+0x5fa/0x740 net/xfrm/xfrm_state.c:971
 xfrm_dev_unregister net/xfrm/xfrm_device.c:549 [inline]
 xfrm_dev_event+0x1bc/0x3f0 net/xfrm/xfrm_device.c:570
 notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
 call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
 call_netdevice_notifiers net/core/dev.c:2295 [inline]
 netdev_wait_allrefs_any net/core/dev.c:11589 [inline]
 netdev_run_todo+0x778/0x1130 net/core/dev.c:11710
 nsim_destroy+0x3ae/0x680 drivers/net/netdevsim/netdev.c:1190
 __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
 nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
 nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
 nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
 device_remove drivers/base/dd.c:571 [inline]
 __device_release_driver drivers/base/dd.c:1284 [inline]
 device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
 bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
 device_del+0x527/0x8f0 drivers/base/core.c:3878
 device_unregister+0x21/0xf0 drivers/base/core.c:3919
 nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
 del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
 kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
 new_sync_write fs/read_write.c:595 [inline]
 vfs_write+0x61d/0xb90 fs/read_write.c:688
 ksys_write+0x150/0x270 fs/read_write.c:740
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fd13375b78e
Code: 08 0f 85 a5 a8 ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 80 00 00 00 00 48 83 ec 08
RSP: 002b:00007ffc52b936a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000555567157500 RCX: 00007fd13375b78e
RDX: 0000000000000001 RSI: 00007ffc52b93730 RDI: 0000000000000005
RBP: 00007fd133808a88 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
R13: 00007ffc52b93730 R14: 00007fd134544620 R15: 0000000000000003
 </TASK>
xfrm_dev_state_flush_secctx_check: LSM policy is rejecting this operation.
CPU: 0 UID: 0 PID: 18368 Comm: syz-executor Tainted: G             L      syzkaller #0 PREEMPT(full) 
Tainted: [L]=SOFTLOCKUP
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/24/2026
Call Trace:
 <TASK>
 dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
 xfrm_dev_state_flush_secctx_check net/xfrm/xfrm_state.c:900 [inline]
 xfrm_dev_state_flush+0x5fa/0x740 net/xfrm/xfrm_state.c:971
 xfrm_dev_unregister net/xfrm/xfrm_device.c:549 [inline]
 xfrm_dev_event+0x1bc/0x3f0 net/xfrm/xfrm_device.c:570
 notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
 call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
 call_netdevice_notifiers net/core/dev.c:2295 [inline]
 netdev_wait_allrefs_any net/core/dev.c:11589 [inline]
 netdev_run_todo+0x778/0x1130 net/core/dev.c:11710
 nsim_destroy+0x3ae/0x680 drivers/net/netdevsim/netdev.c:1190
 __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
 nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
 nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
 nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
 device_remove drivers/base/dd.c:571 [inline]
 __device_release_driver drivers/base/dd.c:1284 [inline]
 device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
 bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
 device_del+0x527/0x8f0 drivers/base/core.c:3878
 device_unregister+0x21/0xf0 drivers/base/core.c:3919
 nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
 del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
 kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
 new_sync_write fs/read_write.c:595 [inline]
 vfs_write+0x61d/0xb90 fs/read_write.c:688
 ksys_write+0x150/0x270 fs/read_write.c:740
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fd13375b78e
Code: 08 0f 85 a5 a8 ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 80 00 00 00 00 48 83 ec 08
RSP: 002b:00007ffc52b936a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000555567157500 RCX: 00007fd13375b78e
RDX: 0000000000000001 RSI: 00007ffc52b93730 RDI: 0000000000000005
RBP: 00007fd133808a88 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
R13: 00007ffc52b93730 R14: 00007fd134544620 R15: 0000000000000003
 </TASK>
xfrm_dev_state_flush_secctx_check: LSM policy is rejecting this operation.
CPU: 0 UID: 0 PID: 18368 Comm: syz-executor Tainted: G             L      syzkaller #0 PREEMPT(full) 
Tainted: [L]=SOFTLOCKUP
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/24/2026
Call Trace:
 <TASK>
 dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120
 xfrm_dev_state_flush_secctx_check net/xfrm/xfrm_state.c:900 [inline]
 xfrm_dev_state_flush+0x5fa/0x740 net/xfrm/xfrm_state.c:971
 xfrm_dev_unregister net/xfrm/xfrm_device.c:549 [inline]
 xfrm_dev_event+0x1bc/0x3f0 net/xfrm/xfrm_device.c:570
 notifier_call_chain+0x1be/0x400 kernel/notifier.c:85
 call_netdevice_notifiers_extack net/core/dev.c:2281 [inline]
 call_netdevice_notifiers net/core/dev.c:2295 [inline]
 netdev_wait_allrefs_any net/core/dev.c:11589 [inline]
 netdev_run_todo+0x778/0x1130 net/core/dev.c:11710
 nsim_destroy+0x3ae/0x680 drivers/net/netdevsim/netdev.c:1190
 __nsim_dev_port_del+0x14d/0x1b0 drivers/net/netdevsim/dev.c:1529
 nsim_dev_port_del_all drivers/net/netdevsim/dev.c:1541 [inline]
 nsim_dev_reload_destroy+0x288/0x490 drivers/net/netdevsim/dev.c:1765
 nsim_drv_remove+0x58/0x170 drivers/net/netdevsim/dev.c:1780
 device_remove drivers/base/dd.c:571 [inline]
 __device_release_driver drivers/base/dd.c:1284 [inline]
 device_release_driver_internal+0x46f/0x860 drivers/base/dd.c:1307
 bus_remove_device+0x34d/0x440 drivers/base/bus.c:616
 device_del+0x527/0x8f0 drivers/base/core.c:3878
 device_unregister+0x21/0xf0 drivers/base/core.c:3919
 nsim_bus_dev_del drivers/net/netdevsim/bus.c:491 [inline]
 del_device_store+0x2b0/0x370 drivers/net/netdevsim/bus.c:244
 kernfs_fop_write_iter+0x3af/0x540 fs/kernfs/file.c:352
 new_sync_write fs/read_write.c:595 [inline]
 vfs_write+0x61d/0xb90 fs/read_write.c:688
 ksys_write+0x150/0x270 fs/read_write.c:740
 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
 do_syscall_64+0x14d/0xf80 arch/x86/entry/syscall_64.c:94
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fd13375b78e
Code: 08 0f 85 a5 a8 ff ff 49 89 fb 48 89 f0 48 89 d7 48 89 ce 4c 89 c2 4d 89 ca 4c 8b 44 24 08 4c 8b 4c 24 10 4c 89 5c 24 08 0f 05 <c3> 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 80 00 00 00 00 48 83 ec 08
RSP: 002b:00007ffc52b936a8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000555567157500 RCX: 00007fd13375b78e
RDX: 0000000000000001 RSI: 00007ffc52b93730 RDI: 0000000000000005
RBP: 00007fd133808a88 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001
R13: 00007ffc52b93730 R14: 00007fd134544620 R15: 0000000000000003
 </TASK>

^ permalink raw reply

* Re: [PATCH] man/man7/kernel_lockdown.7: remove Secure Boot untruth
From: Nicolas Bouchinet @ 2026-02-04  9:03 UTC (permalink / raw)
  To: Alyssa Ross
  Cc: Alejandro Colomar, Heinrich Schuchardt, David Howells,
	Xiu Jianfeng, linux-security-module, linux-man
In-Reply-To: <20260203195001.20131-1-hi@alyssa.is>

Hi,

On Tue, Feb 03, 2026 at 08:50:01PM +0100, Alyssa Ross wrote:
> This is true for Fedora, where this page was sourced from, but I don't
> believe it has ever been true for the mainline kernel, because Linus
> rejected it.
> 
I confirm this has never been merged upstream.
Idealy we really need to rewrite Lockdown documentation, it has changed
a lot since it was first introduced.

> Link: https://bbs.archlinux.org/viewtopic.php?pid=2088704#p2088704
> Link: https://lore.kernel.org/lkml/CA+55aFzYbpRAdma0PvqE+9ygySuKzNKByqOzzMufBoovXVnfPw@mail.gmail.com/
> Fixes: bb509e6fc ("kernel_lockdown.7: New page documenting the Kernel Lockdown feature")
> Signed-off-by: Alyssa Ross <hi@alyssa.is>
> ---
>  man/man7/kernel_lockdown.7 | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/man/man7/kernel_lockdown.7 b/man/man7/kernel_lockdown.7
> index 5090484ea..5986c8f01 100644
> --- a/man/man7/kernel_lockdown.7
> +++ b/man/man7/kernel_lockdown.7
> @@ -23,9 +23,6 @@ Lockdown: X: Y is restricted, see man kernel_lockdown.7
>  .in
>  .P
>  where X indicates the process name and Y indicates what is restricted.
> -.P
> -On an EFI-enabled x86 or arm64 machine, lockdown will be automatically enabled
> -if the system boots in EFI Secure Boot mode.
>  .\"
>  .SS Coverage
>  When lockdown is in effect, a number of features are disabled or have their
> -- 
> 2.52.0

Best regards,

Nicolas

^ permalink raw reply

* Re: [PATCH RESEND] apparmor: Replace deprecated strcpy with memcpy in gen_symlink_name
From: John Johansen @ 2026-02-04  8:22 UTC (permalink / raw)
  To: Thorsten Blum
  Cc: Paul Moore, James Morris, Serge E. Hallyn, apparmor,
	linux-security-module, linux-kernel
In-Reply-To: <3CA1F386-2217-405B-AB6E-85195AD09CA8@linux.dev>

On 2/1/26 04:42, Thorsten Blum wrote:
> Hi John,
> 
> On 27. Nov 2025, at 11:18, Thorsten Blum wrote:
>> On 27. Nov 2025, at 02:32, John Johansen wrote:
>>> hey Thorsten,
>>>
>>> sorry I have actually pulled these in, and tested them. I didn't send out
>>> the acks yet because I have another patch that I was waiting on a proper
>>> signed-off-by: on.
>>>
>>> I am going to have to pull that one so I can push. I'll add acks now but
>>> the push isn't going to happen for a few hours.
>>>
>>> Acked-by: John Johansen <john.johansen@canonical.com>
>>
>> Ah sorry for resending then, didn't know you looked at them already.
> 
> Did you ever push the commits? I can't find them anywhere.
> 
sorry I am having "fun" email issue atm

it should be in apparmor-next. I have been staging that through gitlab

https://gitlab.com/apparmor/apparmor-kernel
and
https://gitlab.com/jjohansen/apparmor-kernel

trying to get better CI integration with the userspace side. It was stuck
again and I had to manually kick it last week.


^ permalink raw reply

* Re: [PATCH net-next v2 0/4] net: uapi: Provide an UAPI definition of 'struct sockaddr'
From: Thomas Weißschuh @ 2026-02-04  5:51 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: Eric Dumazet, Kuniyuki Iwashima, Paolo Abeni, Willem de Bruijn,
	David S. Miller, Simon Horman, Shuah Khan, Matthieu Baerts,
	Mat Martineau, Geliang Tang, Mickaël Salaün,
	Günther Noack, Alexei Starovoitov, Daniel Borkmann,
	Jesper Dangaard Brouer, John Fastabend, Stanislav Fomichev,
	Andrii Nakryiko, Martin KaFai Lau, Eduard Zingerman, Song Liu,
	Yonghong Song, KP Singh, Hao Luo, Jiri Olsa, netdev, linux-kernel,
	linux-api, Arnd Bergmann, linux-kselftest, mptcp,
	linux-security-module, bpf, libc-alpha, Carlos O'Donell,
	Adhemerval Zanella, Rich Felker, klibc, Florian Weimer
In-Reply-To: <20260203144011.32d5b223@kernel.org>

On Tue, Feb 03, 2026 at 02:40:11PM -0800, Jakub Kicinski wrote:
> On Tue, 3 Feb 2026 12:42:22 +0100 Thomas Weißschuh wrote:
> > > FWIW the typelimits change broke compilation of ethtool, we'll see if
> > > anyone "outside kernel community itself" complains.  
> > 
> > Can you point me to that breakage? I was unable to find it.
> 
> Not reported on the ML, and it's kinda annoying to repro because 
> the uAPI header sync script isn't committed :/ You have to check 
> this out
> 
>  https://git.kernel.org/pub/scm/network/ethtool/ethtool.git/
> 
> and run a script like this to sync headers from the kernel (then build):
> 
> #!/bin/bash -e
> 
> sn="${0##*/}"
> export ARCH="x86_64"
> 
> if [ ! -d "$LINUX_GIT" ]; then
>     echo "${sn}: LINUX_GIT not set" >&2
>     exit 1
> fi
> 
> pushd "$LINUX_GIT"
> if [ -n "$1" ]; then
>     git checkout "$1"
> fi
> desc=$(git describe --exact-match 2>/dev/null \
>        || git show -s --abbrev=12 --pretty='commit %h')
> kobj=$(mktemp -d)

> make -j16 O="$kobj" allmodconfig
> make -j16 O="$kobj" prepare

These are not necessary.
The UAPI generation does not need a kernel configuration.

> make -j16 O="$kobj" INSTALL_HDR_PATH="${kobj}/hdr" headers_install
> popd
> 
> pushd uapi
> find . -type f -name '*.h' -exec cp -v "${kobj}/hdr/include/{}" {} \;

Here only those headers which already exist in ethtool's uapi/ directory
are copied. As linux/typelimits.h is new, it is now missing.
Honestly, if a user fiddles with the internals of the UAPI headers like
this, it is on them to update their code if the internal structure
changes. In your case a simple 'touch uapi/linux/typelimits.h'
before running the script will be enough. Also internal.h now requires
an explicit inclusion of <limits.h>, as that is not satisfied by the
UAPI anymore.

> popd
> rm -rf "$kobj"
> 
> git add uapi
> git commit -s -F - <<EOT
> update UAPI header copies
> 
> Update to kernel ${desc}.
> 
> EOT

^ permalink raw reply

* [PATCH 13/13] VFS: unexport lock_rename(), lock_rename_child(), unlock_rename()
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

These three function are now only used in namei.c, so they don't need to
be exported.

Signed-off-by: NeilBrown <neil@brown.name>
---
 Documentation/filesystems/porting.rst | 7 +++++++
 fs/namei.c                            | 9 +++------
 include/linux/namei.h                 | 3 ---
 3 files changed, 10 insertions(+), 9 deletions(-)

diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst
index ed86c95d9d01..5f7008172f14 100644
--- a/Documentation/filesystems/porting.rst
+++ b/Documentation/filesystems/porting.rst
@@ -1347,3 +1347,10 @@ implementation should set it to generic_setlease().
 
 lookup_one_qstr_excl() is no longer exported - use start_creating() or
 similar.
+---
+
+** mandatory**
+
+lock_rename(), lock_rename_child(), unlock_rename() are no
+longer available.  Use start_renaming() or similar.
+
diff --git a/fs/namei.c b/fs/namei.c
index 307b4d0866b8..0bc82bf90adc 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -3713,7 +3713,7 @@ static struct dentry *lock_two_directories(struct dentry *p1, struct dentry *p2)
 /*
  * p1 and p2 should be directories on the same fs.
  */
-struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
+static struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
 {
 	if (p1 == p2) {
 		inode_lock_nested(p1->d_inode, I_MUTEX_PARENT);
@@ -3723,12 +3723,11 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
 	mutex_lock(&p1->d_sb->s_vfs_rename_mutex);
 	return lock_two_directories(p1, p2);
 }
-EXPORT_SYMBOL(lock_rename);
 
 /*
  * c1 and p2 should be on the same fs.
  */
-struct dentry *lock_rename_child(struct dentry *c1, struct dentry *p2)
+static struct dentry *lock_rename_child(struct dentry *c1, struct dentry *p2)
 {
 	if (READ_ONCE(c1->d_parent) == p2) {
 		/*
@@ -3765,9 +3764,8 @@ struct dentry *lock_rename_child(struct dentry *c1, struct dentry *p2)
 	mutex_unlock(&c1->d_sb->s_vfs_rename_mutex);
 	return NULL;
 }
-EXPORT_SYMBOL(lock_rename_child);
 
-void unlock_rename(struct dentry *p1, struct dentry *p2)
+static void unlock_rename(struct dentry *p1, struct dentry *p2)
 {
 	inode_unlock(p1->d_inode);
 	if (p1 != p2) {
@@ -3775,7 +3773,6 @@ void unlock_rename(struct dentry *p1, struct dentry *p2)
 		mutex_unlock(&p1->d_sb->s_vfs_rename_mutex);
 	}
 }
-EXPORT_SYMBOL(unlock_rename);
 
 /**
  * __start_renaming - lookup and lock names for rename
diff --git a/include/linux/namei.h b/include/linux/namei.h
index c7a7288cdd25..2ad6dd9987b9 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -165,9 +165,6 @@ extern int follow_down_one(struct path *);
 extern int follow_down(struct path *path, unsigned int flags);
 extern int follow_up(struct path *);
 
-extern struct dentry *lock_rename(struct dentry *, struct dentry *);
-extern struct dentry *lock_rename_child(struct dentry *, struct dentry *);
-extern void unlock_rename(struct dentry *, struct dentry *);
 int start_renaming(struct renamedata *rd, int lookup_flags,
 		   struct qstr *old_last, struct qstr *new_last);
 int start_renaming_dentry(struct renamedata *rd, int lookup_flags,
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 12/13] ovl: remove ovl_lock_rename_workdir()
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

This function is unused.

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/overlayfs/overlayfs.h |  2 --
 fs/overlayfs/util.c      | 25 -------------------------
 2 files changed, 27 deletions(-)

diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 4fb4750a83e4..3eedc2684c23 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -569,8 +569,6 @@ bool ovl_is_inuse(struct dentry *dentry);
 bool ovl_need_index(struct dentry *dentry);
 int ovl_nlink_start(struct dentry *dentry);
 void ovl_nlink_end(struct dentry *dentry);
-int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *work,
-			    struct dentry *upperdir, struct dentry *upper);
 int ovl_check_metacopy_xattr(struct ovl_fs *ofs, const struct path *path,
 			     struct ovl_metacopy *data);
 int ovl_set_metacopy_xattr(struct ovl_fs *ofs, struct dentry *d,
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 94986d11a166..810c8752b4f7 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -1213,31 +1213,6 @@ void ovl_nlink_end(struct dentry *dentry)
 	ovl_inode_unlock(inode);
 }
 
-int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *work,
-			    struct dentry *upperdir, struct dentry *upper)
-{
-	struct dentry *trap;
-
-	/* Workdir should not be subdir of upperdir and vice versa */
-	trap = lock_rename(workdir, upperdir);
-	if (IS_ERR(trap))
-		goto err;
-	if (trap)
-		goto err_unlock;
-	if (work && (work->d_parent != workdir || d_unhashed(work)))
-		goto err_unlock;
-	if (upper && (upper->d_parent != upperdir || d_unhashed(upper)))
-		goto err_unlock;
-
-	return 0;
-
-err_unlock:
-	unlock_rename(workdir, upperdir);
-err:
-	pr_err("failed to lock workdir+upperdir\n");
-	return -EIO;
-}
-
 /*
  * err < 0, 0 if no metacopy xattr, metacopy data size if xattr found.
  * an empty xattr returns OVL_METACOPY_MIN_SIZE to distinguish from no xattr value.
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 11/13] ovl: use is_subdir() for testing if one thing is a subdir of another
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

Rather than using lock_rename(), use the more obvious is_subdir() for
ensuring that neither upper nor workdir contain the other.
Also be explicit in the comment that the two directories cannot be the
same.

As this is a point-it-time sanity check and does not provide any
on-going guarantees, the removal of locking does not introduce any
interesting races.

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/overlayfs/super.c | 15 +++++----------
 1 file changed, 5 insertions(+), 10 deletions(-)

diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index ba9146f22a2c..2fd3e0aee50e 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -451,18 +451,13 @@ static int ovl_lower_dir(const char *name, const struct path *path,
 	return 0;
 }
 
-/* Workdir should not be subdir of upperdir and vice versa */
+/*
+ * Workdir should not be subdir of upperdir and vice versa, and
+ * they should not be the same.
+ */
 static bool ovl_workdir_ok(struct dentry *workdir, struct dentry *upperdir)
 {
-	bool ok = false;
-
-	if (workdir != upperdir) {
-		struct dentry *trap = lock_rename(workdir, upperdir);
-		if (!IS_ERR(trap))
-			unlock_rename(workdir, upperdir);
-		ok = (trap == NULL);
-	}
-	return ok;
+	return !is_subdir(workdir, upperdir) && !is_subdir(upperdir, workdir);
 }
 
 static int ovl_setup_trap(struct super_block *sb, struct dentry *dir,
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 10/13] ovl: change ovl_create_real() to get a new lock when re-opening created file.
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

When ovl_create_real() is used to create a file on the upper filesystem
it needs to return the resulting dentry - positive and hashed.
It is usually the case the that dentry passed to the create function
(e.g.  vfs_create()) will be suitable but this is not guaranteed.  The
filesystem may unhash that dentry forcing a repeat lookup next time the
name is wanted.

So ovl_create_real() must be (and is) aware of this and prepared to
perform that lookup to get a hash positive dentry.

This is currently done under that same directory lock that provided
exclusion for the create.  Proposed changes to locking will make this
not possible - as the name, rather than the directory, will be locked.
The new APIs provided for lookup and locking do not and cannot support
this pattern.

The lock isn't needed.  ovl_create_real() can drop the lock and then get
a new lock for the lookup - then check that the lookup returned the
correct inode.  In a well-behaved configuration where the upper
filesystem is not being modified by a third party, this will always work
reliably, and if there are separate modification it will fail cleanly.

So change ovl_create_real() to drop the lock and call
ovl_start_creating_upper() to find the correct dentry.  Note that
start_creating doesn't fail if the name already exists.

This removes the only remaining use of ovl_lookup_upper, so it is
removed.

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/overlayfs/dir.c       | 24 ++++++++++++++++++------
 fs/overlayfs/overlayfs.h |  7 -------
 2 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
index ff3dbd1ca61f..ec08904d084d 100644
--- a/fs/overlayfs/dir.c
+++ b/fs/overlayfs/dir.c
@@ -219,21 +219,33 @@ struct dentry *ovl_create_real(struct ovl_fs *ofs, struct dentry *parent,
 		err = -EIO;
 	} else if (d_unhashed(newdentry)) {
 		struct dentry *d;
+		struct name_snapshot name;
 		/*
 		 * Some filesystems (i.e. casefolded) may return an unhashed
-		 * negative dentry from the ovl_lookup_upper() call before
+		 * negative dentry from the ovl_start_creating_upper() call before
 		 * ovl_create_real().
 		 * In that case, lookup again after making the newdentry
 		 * positive, so ovl_create_upper() always returns a hashed
 		 * positive dentry.
+		 * As we have to drop the lock before the lookup a race
+		 * could result in a lookup failure.  In that case we return
+		 * an error.
 		 */
-		d = ovl_lookup_upper(ofs, newdentry->d_name.name, parent,
-				     newdentry->d_name.len);
-		dput(newdentry);
-		if (IS_ERR_OR_NULL(d))
+		take_dentry_name_snapshot(&name, newdentry);
+		end_creating_keep(newdentry);
+		d = ovl_start_creating_upper(ofs, parent, &name.name);
+		release_dentry_name_snapshot(&name);
+
+		if (IS_ERR_OR_NULL(d)) {
 			err = d ? PTR_ERR(d) : -ENOENT;
-		else
+		} else if (d->d_inode != newdentry->d_inode) {
+			err = -EIO;
+			dput(newdentry);
+		} else {
+			dput(newdentry);
 			return d;
+		}
+		return ERR_PTR(err);
 	}
 out:
 	if (err) {
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 315882a360ce..4fb4750a83e4 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -406,13 +406,6 @@ static inline struct file *ovl_do_tmpfile(struct ovl_fs *ofs,
 	return file;
 }
 
-static inline struct dentry *ovl_lookup_upper(struct ovl_fs *ofs,
-					      const char *name,
-					      struct dentry *base, int len)
-{
-	return lookup_one(ovl_upper_mnt_idmap(ofs), &QSTR_LEN(name, len), base);
-}
-
 static inline struct dentry *ovl_lookup_upper_unlocked(struct ovl_fs *ofs,
 						       const char *name,
 						       struct dentry *base,
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 09/13] cachefiles: change cachefiles_bury_object to use start_renaming_dentry()
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

Rather then using lock_rename() and lookup_one() etc we can use
the new start_renaming_dentry().  This is part of centralising dir
locking and lookup so that locking rules can be changed.

Some error check are removed as not necessary.  Checks for rep being a
non-dir or IS_DEADDIR and the check that ->graveyard is still a
directory only provide slightly more informative errors and have been
dropped.

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/cachefiles/namei.c | 76 ++++++++-----------------------------------
 1 file changed, 14 insertions(+), 62 deletions(-)

diff --git a/fs/cachefiles/namei.c b/fs/cachefiles/namei.c
index e5ec90dccc27..3af42ec78411 100644
--- a/fs/cachefiles/namei.c
+++ b/fs/cachefiles/namei.c
@@ -270,7 +270,8 @@ int cachefiles_bury_object(struct cachefiles_cache *cache,
 			   struct dentry *rep,
 			   enum fscache_why_object_killed why)
 {
-	struct dentry *grave, *trap;
+	struct dentry *grave;
+	struct renamedata rd = {};
 	struct path path, path_to_graveyard;
 	char nbuffer[8 + 8 + 1];
 	int ret;
@@ -302,77 +303,36 @@ int cachefiles_bury_object(struct cachefiles_cache *cache,
 		(uint32_t) ktime_get_real_seconds(),
 		(uint32_t) atomic_inc_return(&cache->gravecounter));
 
-	/* do the multiway lock magic */
-	trap = lock_rename(cache->graveyard, dir);
-	if (IS_ERR(trap))
-		return PTR_ERR(trap);
-
-	/* do some checks before getting the grave dentry */
-	if (rep->d_parent != dir || IS_DEADDIR(d_inode(rep))) {
-		/* the entry was probably culled when we dropped the parent dir
-		 * lock */
-		unlock_rename(cache->graveyard, dir);
-		_leave(" = 0 [culled?]");
-		return 0;
-	}
-
-	if (!d_can_lookup(cache->graveyard)) {
-		unlock_rename(cache->graveyard, dir);
-		cachefiles_io_error(cache, "Graveyard no longer a directory");
-		return -EIO;
-	}
-
-	if (trap == rep) {
-		unlock_rename(cache->graveyard, dir);
-		cachefiles_io_error(cache, "May not make directory loop");
+	rd.mnt_idmap = &nop_mnt_idmap;
+	rd.old_parent = dir;
+	rd.new_parent = cache->graveyard;
+	rd.flags = 0;
+	ret = start_renaming_dentry(&rd, 0, rep, &QSTR(nbuffer));
+	if (ret) {
+		cachefiles_io_error(cache, "Cannot lock/lookup in graveyard");
 		return -EIO;
 	}
 
 	if (d_mountpoint(rep)) {
-		unlock_rename(cache->graveyard, dir);
+		end_renaming(&rd);
 		cachefiles_io_error(cache, "Mountpoint in cache");
 		return -EIO;
 	}
 
-	grave = lookup_one(&nop_mnt_idmap, &QSTR(nbuffer), cache->graveyard);
-	if (IS_ERR(grave)) {
-		unlock_rename(cache->graveyard, dir);
-		trace_cachefiles_vfs_error(object, d_inode(cache->graveyard),
-					   PTR_ERR(grave),
-					   cachefiles_trace_lookup_error);
-
-		if (PTR_ERR(grave) == -ENOMEM) {
-			_leave(" = -ENOMEM");
-			return -ENOMEM;
-		}
-
-		cachefiles_io_error(cache, "Lookup error %ld", PTR_ERR(grave));
-		return -EIO;
-	}
-
+	grave = rd.new_dentry;
 	if (d_is_positive(grave)) {
-		unlock_rename(cache->graveyard, dir);
-		dput(grave);
+		end_renaming(&rd);
 		grave = NULL;
 		cond_resched();
 		goto try_again;
 	}
 
 	if (d_mountpoint(grave)) {
-		unlock_rename(cache->graveyard, dir);
-		dput(grave);
+		end_renaming(&rd);
 		cachefiles_io_error(cache, "Mountpoint in graveyard");
 		return -EIO;
 	}
 
-	/* target should not be an ancestor of source */
-	if (trap == grave) {
-		unlock_rename(cache->graveyard, dir);
-		dput(grave);
-		cachefiles_io_error(cache, "May not make directory loop");
-		return -EIO;
-	}
-
 	/* attempt the rename */
 	path.mnt = cache->mnt;
 	path.dentry = dir;
@@ -382,13 +342,6 @@ int cachefiles_bury_object(struct cachefiles_cache *cache,
 	if (ret < 0) {
 		cachefiles_io_error(cache, "Rename security error %d", ret);
 	} else {
-		struct renamedata rd = {
-			.mnt_idmap	= &nop_mnt_idmap,
-			.old_parent	= dir,
-			.old_dentry	= rep,
-			.new_parent	= cache->graveyard,
-			.new_dentry	= grave,
-		};
 		trace_cachefiles_rename(object, d_inode(rep)->i_ino, why);
 		ret = cachefiles_inject_read_error();
 		if (ret == 0)
@@ -402,8 +355,7 @@ int cachefiles_bury_object(struct cachefiles_cache *cache,
 	}
 
 	__cachefiles_unmark_inode_in_use(object, d_inode(rep));
-	unlock_rename(cache->graveyard, dir);
-	dput(grave);
+	end_renaming(&rd);
 	_leave(" = 0");
 	return 0;
 }
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 08/13] ovl: Simplify ovl_lookup_real_one()
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

The primary purpose of this patch is to remove the locking from
ovl_lookup_real_one() as part of centralising all locking of directories
for name operations.

The locking here isn't needed.  By performing consistency tests after
the lookup we can be sure that the result of the lookup was valid at
least for a moment, which is all the original code promised.

lookup_noperm_unlocked() is used for the lookup and it will take the
lock if needed only where it is needed.

Also:
 - don't take a reference to real->d_parent.  The parent is
   only use for a pointer comparison, and no reference is needed for
   that.
 - Several "if" statements have a "goto" followed by "else" - the
   else isn't needed: the following statement can directly follow
   the "if" as a new statement
 - Use a consistent pattern of setting "err" before performing a test
   and possibly going to "fail".
 - remove the "out" label (now that we don't need to dput(parent) or
   unlock) and simply return from fail:.

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/overlayfs/export.c | 61 ++++++++++++++++++-------------------------
 1 file changed, 26 insertions(+), 35 deletions(-)

diff --git a/fs/overlayfs/export.c b/fs/overlayfs/export.c
index 83f80fdb1567..dcd28ffc4705 100644
--- a/fs/overlayfs/export.c
+++ b/fs/overlayfs/export.c
@@ -359,59 +359,50 @@ static struct dentry *ovl_lookup_real_one(struct dentry *connected,
 					  struct dentry *real,
 					  const struct ovl_layer *layer)
 {
-	struct inode *dir = d_inode(connected);
-	struct dentry *this, *parent = NULL;
+	struct dentry *this;
 	struct name_snapshot name;
 	int err;
 
 	/*
-	 * Lookup child overlay dentry by real name. The dir mutex protects us
-	 * from racing with overlay rename. If the overlay dentry that is above
-	 * real has already been moved to a parent that is not under the
-	 * connected overlay dir, we return -ECHILD and restart the lookup of
-	 * connected real path from the top.
+	 * @connected is a directory in the overlay and @real is an object
+	 * on @layer which is expected to be a child of @connected.
+	 * The goal is to return a dentry from the overlay which corresponds
+	 * to @real.  This is done by looking up the name from @real in
+	 * @connected and checking that the result meets expectations.
+	 *
+	 * Return %-ECHILD if the parent of @real no-longer corresponds to
+	 * @connected, and %-ESTALE if the dentry found by lookup doesn't
+	 * correspond to @real.
 	 */
-	inode_lock_nested(dir, I_MUTEX_PARENT);
-	err = -ECHILD;
-	parent = dget_parent(real);
-	if (ovl_dentry_real_at(connected, layer->idx) != parent)
-		goto fail;
 
-	/*
-	 * We also need to take a snapshot of real dentry name to protect us
-	 * from racing with underlying layer rename. In this case, we don't
-	 * care about returning ESTALE, only from dereferencing a free name
-	 * pointer because we hold no lock on the real dentry.
-	 */
 	take_dentry_name_snapshot(&name, real);
-	/*
-	 * No idmap handling here: it's an internal lookup.
-	 */
-	this = lookup_noperm(&name.name, connected);
+	this = lookup_noperm_unlocked(&name.name, connected);
 	release_dentry_name_snapshot(&name);
+
+	err = -ECHILD;
+	if (ovl_dentry_real_at(connected, layer->idx) != real->d_parent)
+		goto fail;
+
 	err = PTR_ERR(this);
-	if (IS_ERR(this)) {
+	if (IS_ERR(this))
 		goto fail;
-	} else if (!this || !this->d_inode) {
-		dput(this);
-		err = -ENOENT;
+
+	err = -ENOENT;
+	if (!this || !this->d_inode)
 		goto fail;
-	} else if (ovl_dentry_real_at(this, layer->idx) != real) {
-		dput(this);
-		err = -ESTALE;
+
+	err = -ESTALE;
+	if (ovl_dentry_real_at(this, layer->idx) != real)
 		goto fail;
-	}
 
-out:
-	dput(parent);
-	inode_unlock(dir);
 	return this;
 
 fail:
 	pr_warn_ratelimited("failed to lookup one by real (%pd2, layer=%d, connected=%pd2, err=%i)\n",
 			    real, layer->idx, connected, err);
-	this = ERR_PTR(err);
-	goto out;
+	if (!IS_ERR(this))
+		dput(this);
+	return ERR_PTR(err);
 }
 
 static struct dentry *ovl_lookup_real(struct super_block *sb,
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 07/13] VFS: make lookup_one_qstr_excl() static.
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

lookup_one_qstr_excl() is no longer used outside of namei.c, so
make it static.

Signed-off-by: NeilBrown <neil@brown.name>
---
 Documentation/filesystems/porting.rst | 7 +++++++
 fs/namei.c                            | 5 ++---
 include/linux/namei.h                 | 3 ---
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/Documentation/filesystems/porting.rst b/Documentation/filesystems/porting.rst
index ed3ac56e3c76..ed86c95d9d01 100644
--- a/Documentation/filesystems/porting.rst
+++ b/Documentation/filesystems/porting.rst
@@ -1340,3 +1340,10 @@ The ->setlease() file_operation must now be explicitly set in order to provide
 support for leases. When set to NULL, the kernel will now return -EINVAL to
 attempts to set a lease. Filesystems that wish to use the kernel-internal lease
 implementation should set it to generic_setlease().
+
+---
+
+**mandatory**
+
+lookup_one_qstr_excl() is no longer exported - use start_creating() or
+similar.
diff --git a/fs/namei.c b/fs/namei.c
index 40af78ddfb1b..307b4d0866b8 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1730,8 +1730,8 @@ static struct dentry *lookup_dcache(const struct qstr *name,
  * Will return -ENOENT if name isn't found and LOOKUP_CREATE wasn't passed.
  * Will return -EEXIST if name is found and LOOKUP_EXCL was passed.
  */
-struct dentry *lookup_one_qstr_excl(const struct qstr *name,
-				    struct dentry *base, unsigned int flags)
+static struct dentry *lookup_one_qstr_excl(const struct qstr *name,
+					   struct dentry *base, unsigned int flags)
 {
 	struct dentry *dentry;
 	struct dentry *old;
@@ -1768,7 +1768,6 @@ struct dentry *lookup_one_qstr_excl(const struct qstr *name,
 	}
 	return dentry;
 }
-EXPORT_SYMBOL(lookup_one_qstr_excl);
 
 /**
  * lookup_fast - do fast lockless (but racy) lookup of a dentry
diff --git a/include/linux/namei.h b/include/linux/namei.h
index 58600cf234bc..c7a7288cdd25 100644
--- a/include/linux/namei.h
+++ b/include/linux/namei.h
@@ -54,9 +54,6 @@ extern int path_pts(struct path *path);
 
 extern int user_path_at(int, const char __user *, unsigned, struct path *);
 
-struct dentry *lookup_one_qstr_excl(const struct qstr *name,
-				    struct dentry *base,
-				    unsigned int flags);
 extern int kern_path(const char *, unsigned, struct path *);
 struct dentry *kern_path_parent(const char *name, struct path *parent);
 
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 06/13] nfsd: switch purge_old() to use start_removing_noperm()
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

Rather than explicit locking, use the start_removing_noperm() and
end_removing() wrappers.
This was not done with other start_removing changes due to conflicting
in-flight patches.

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/nfsd/nfs4recover.c | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c
index 441dfbfe2d2b..52fbe723a3c8 100644
--- a/fs/nfsd/nfs4recover.c
+++ b/fs/nfsd/nfs4recover.c
@@ -351,16 +351,14 @@ purge_old(struct dentry *parent, char *cname, struct nfsd_net *nn)
 	if (nfs4_has_reclaimed_state(name, nn))
 		goto out_free;
 
-	inode_lock_nested(d_inode(parent), I_MUTEX_PARENT);
-	child = lookup_one(&nop_mnt_idmap, &QSTR(cname), parent);
+	child = start_removing_noperm(parent, &QSTR(cname));
 	if (!IS_ERR(child)) {
 		status = vfs_rmdir(&nop_mnt_idmap, d_inode(parent), child, NULL);
 		if (status)
 			printk("failed to remove client recovery directory %pd\n",
 			       child);
-		dput(child);
 	}
-	inode_unlock(d_inode(parent));
+	end_removing(child);
 
 out_free:
 	kfree(name.data);
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 05/13] selinux: Use simple_start_creating() / simple_done_creating()
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

Instead of explicitly locking the parent and performing a lookup in
selinux, use simple_start_creating(), and then use
simple_done_creating() to unlock.

This extends the region that the directory is locked for, and also
performs a lookup.
The lock extension is of no real consequence.
The lookup uses simple_lookup() and so always succeeds.  Thus when
d_make_persistent() is called the dentry will already be hashed.
d_make_persistent() handles this case.

Signed-off-by: NeilBrown <neil@brown.name>
---
 security/selinux/selinuxfs.c | 15 +++++++--------
 1 file changed, 7 insertions(+), 8 deletions(-)

diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index 896acad1f5f7..97e02cd5a9dc 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1930,15 +1930,16 @@ static const struct inode_operations swapover_dir_inode_operations = {
 static struct dentry *sel_make_swapover_dir(struct super_block *sb,
 						unsigned long *ino)
 {
-	struct dentry *dentry = d_alloc_name(sb->s_root, ".swapover");
+	struct dentry *dentry;
 	struct inode *inode;
 
-	if (!dentry)
+	inode = sel_make_inode(sb, S_IFDIR);
+	if (!inode)
 		return ERR_PTR(-ENOMEM);
 
-	inode = sel_make_inode(sb, S_IFDIR);
-	if (!inode) {
-		dput(dentry);
+	dentry = simple_start_creating(sb->s_root, ".swapover");
+	if (!dentry) {
+		iput(inode);
 		return ERR_PTR(-ENOMEM);
 	}
 
@@ -1946,11 +1947,9 @@ static struct dentry *sel_make_swapover_dir(struct super_block *sb,
 	inode->i_ino = ++(*ino);
 	/* directory inodes start off with i_nlink == 2 (for "." entry) */
 	inc_nlink(inode);
-	inode_lock(sb->s_root->d_inode);
 	d_make_persistent(dentry, inode);
 	inc_nlink(sb->s_root->d_inode);
-	inode_unlock(sb->s_root->d_inode);
-	dput(dentry);
+	simple_done_creating(dentry);
 	return dentry;	// borrowed
 }
 
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 04/13] Apparmor: Use simple_start_creating() / simple_done_creating()
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

Instead of explicitly locking the parent and performing a look up in
apparmor, use simple_start_creating(), and then simple_done_creating()
to unlock and drop the dentry.

This removes the need to check for an existing entry (as
simple_start_creating() acts like an exclusive create and can return
-EEXIST), simplifies error paths, and keeps dir locking code
centralised.

Signed-off-by: NeilBrown <neil@brown.name>
---
 security/apparmor/apparmorfs.c | 38 ++++++++--------------------------
 1 file changed, 9 insertions(+), 29 deletions(-)

diff --git a/security/apparmor/apparmorfs.c b/security/apparmor/apparmorfs.c
index 907bd2667e28..7f78c36e6e50 100644
--- a/security/apparmor/apparmorfs.c
+++ b/security/apparmor/apparmorfs.c
@@ -282,32 +282,19 @@ static struct dentry *aafs_create(const char *name, umode_t mode,
 
 	dir = d_inode(parent);
 
-	inode_lock(dir);
-	dentry = lookup_noperm(&QSTR(name), parent);
+	dentry = simple_start_creating(parent, name);
 	if (IS_ERR(dentry)) {
 		error = PTR_ERR(dentry);
-		goto fail_lock;
-	}
-
-	if (d_really_is_positive(dentry)) {
-		error = -EEXIST;
-		goto fail_dentry;
+		goto fail;
 	}
 
 	error = __aafs_setup_d_inode(dir, dentry, mode, data, link, fops, iops);
+	simple_done_creating(dentry);
 	if (error)
-		goto fail_dentry;
-	inode_unlock(dir);
-
-	return dentry;
-
-fail_dentry:
-	dput(dentry);
-
-fail_lock:
-	inode_unlock(dir);
+		goto fail;
+	return 0;
+fail:
 	simple_release_fs(&aafs_mnt, &aafs_count);
-
 	return ERR_PTR(error);
 }
 
@@ -2572,8 +2559,7 @@ static int aa_mk_null_file(struct dentry *parent)
 	if (error)
 		return error;
 
-	inode_lock(d_inode(parent));
-	dentry = lookup_noperm(&QSTR(NULL_FILE_NAME), parent);
+	dentry = simple_start_creating(parent, NULL_FILE_NAME);
 	if (IS_ERR(dentry)) {
 		error = PTR_ERR(dentry);
 		goto out;
@@ -2581,7 +2567,7 @@ static int aa_mk_null_file(struct dentry *parent)
 	inode = new_inode(parent->d_inode->i_sb);
 	if (!inode) {
 		error = -ENOMEM;
-		goto out1;
+		goto out;
 	}
 
 	inode->i_ino = get_next_ino();
@@ -2593,18 +2579,12 @@ static int aa_mk_null_file(struct dentry *parent)
 	aa_null.dentry = dget(dentry);
 	aa_null.mnt = mntget(mount);
 
-	error = 0;
-
-out1:
-	dput(dentry);
 out:
-	inode_unlock(d_inode(parent));
+	simple_done_creating(dentry);
 	simple_release_fs(&mount, &count);
 	return error;
 }
 
-
-
 static const char *policy_get_link(struct dentry *dentry,
 				   struct inode *inode,
 				   struct delayed_call *done)
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 03/13] libfs: change simple_done_creating() to use end_creating()
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

simple_done_creating() and end_creating() are identical.
So change the former to use the latter.  This further centralises
unlocking of directories.

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/libfs.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/libfs.c b/fs/libfs.c
index f1860dff86f2..db18b53fc189 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -2318,7 +2318,6 @@ EXPORT_SYMBOL(simple_start_creating);
 /* parent must have been held exclusive since simple_start_creating() */
 void simple_done_creating(struct dentry *child)
 {
-	inode_unlock(child->d_parent->d_inode);
-	dput(child);
+	end_creating(child);
 }
 EXPORT_SYMBOL(simple_done_creating);
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 02/13] VFS: move the start_dirop() kerndoc comment to before start_dirop()
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

This kerneldoc comment was always meant for start_dirop(), not for
__start_dirop() which is a static function and doesn't need
documentation.

It was in the wrong place and was then incorrectly renamed (instead of
moved) and useless "documentation" was added for "@state" was provided.

This patch reverts the name, removes the mention of @state, and moves
the comment to where it belongs.

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/namei.c | 27 +++++++++++++--------------
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/fs/namei.c b/fs/namei.c
index b28ecb699f32..40af78ddfb1b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2841,20 +2841,6 @@ static int filename_parentat(int dfd, struct filename *name,
 	return __filename_parentat(dfd, name, flags, parent, last, type, NULL);
 }
 
-/**
- * __start_dirop - begin a create or remove dirop, performing locking and lookup
- * @parent:       the dentry of the parent in which the operation will occur
- * @name:         a qstr holding the name within that parent
- * @lookup_flags: intent and other lookup flags.
- * @state:        task state bitmask
- *
- * The lookup is performed and necessary locks are taken so that, on success,
- * the returned dentry can be operated on safely.
- * The qstr must already have the hash value calculated.
- *
- * Returns: a locked dentry, or an error.
- *
- */
 static struct dentry *__start_dirop(struct dentry *parent, struct qstr *name,
 				    unsigned int lookup_flags,
 				    unsigned int state)
@@ -2876,6 +2862,19 @@ static struct dentry *__start_dirop(struct dentry *parent, struct qstr *name,
 	return dentry;
 }
 
+/**
+ * start_dirop - begin a create or remove dirop, performing locking and lookup
+ * @parent:       the dentry of the parent in which the operation will occur
+ * @name:         a qstr holding the name within that parent
+ * @lookup_flags: intent and other lookup flags.
+ *
+ * The lookup is performed and necessary locks are taken so that, on success,
+ * the returned dentry can be operated on safely.
+ * The qstr must already have the hash value calculated.
+ *
+ * Returns: a locked dentry, or an error.
+ *
+ */
 struct dentry *start_dirop(struct dentry *parent, struct qstr *name,
 			   unsigned int lookup_flags)
 {
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 01/13] fs/proc: Don't lock root inode when creating "self" and "thread-self"
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux
In-Reply-To: <20260204050726.177283-1-neilb@ownmail.net>

From: NeilBrown <neil@brown.name>

proc_setup_self() and proc_setup_thread_self() are only called from
proc_fill_super() which is before the filesystem is "live".  So there is
no need to lock the root directory when adding "self" and "thread-self".
This is clear from simple_fill_super() which provides similar
functionality for other filesystems and does not lock anything.

The locking is not harmful, except that it may be confusing to a reader.
As part of a an effort to centralise all locking for directories for
name-based operations (prior to changing some locking rules), it is
simplest to remove the locking here.

Signed-off-by: NeilBrown <neil@brown.name>
---
 fs/proc/self.c        | 3 ---
 fs/proc/thread_self.c | 3 ---
 2 files changed, 6 deletions(-)

diff --git a/fs/proc/self.c b/fs/proc/self.c
index 62d2c0cfe35c..56adf1c68f7a 100644
--- a/fs/proc/self.c
+++ b/fs/proc/self.c
@@ -35,11 +35,9 @@ unsigned self_inum __ro_after_init;
 
 int proc_setup_self(struct super_block *s)
 {
-	struct inode *root_inode = d_inode(s->s_root);
 	struct dentry *self;
 	int ret = -ENOMEM;
 
-	inode_lock(root_inode);
 	self = d_alloc_name(s->s_root, "self");
 	if (self) {
 		struct inode *inode = new_inode(s);
@@ -55,7 +53,6 @@ int proc_setup_self(struct super_block *s)
 		}
 		dput(self);
 	}
-	inode_unlock(root_inode);
 
 	if (ret)
 		pr_err("proc_fill_super: can't allocate /proc/self\n");
diff --git a/fs/proc/thread_self.c b/fs/proc/thread_self.c
index d6113dbe58e0..61ac62c3fd9f 100644
--- a/fs/proc/thread_self.c
+++ b/fs/proc/thread_self.c
@@ -35,11 +35,9 @@ unsigned thread_self_inum __ro_after_init;
 
 int proc_setup_thread_self(struct super_block *s)
 {
-	struct inode *root_inode = d_inode(s->s_root);
 	struct dentry *thread_self;
 	int ret = -ENOMEM;
 
-	inode_lock(root_inode);
 	thread_self = d_alloc_name(s->s_root, "thread-self");
 	if (thread_self) {
 		struct inode *inode = new_inode(s);
@@ -55,7 +53,6 @@ int proc_setup_thread_self(struct super_block *s)
 		}
 		dput(thread_self);
 	}
-	inode_unlock(root_inode);
 
 	if (ret)
 		pr_err("proc_fill_super: can't allocate /proc/thread-self\n");
-- 
2.50.0.107.gf914562f5916.dirty


^ permalink raw reply related

* [PATCH 00/13] Further centralising of directory locking for name ops.
From: NeilBrown @ 2026-02-04  4:57 UTC (permalink / raw)
  To: Christian Brauner, Alexander Viro, David Howells, Jan Kara,
	Chuck Lever, Jeff Layton, Miklos Szeredi, Amir Goldstein,
	John Johansen, Paul Moore, James Morris, Serge E. Hallyn,
	Stephen Smalley
  Cc: linux-kernel, netfs, linux-fsdevel, linux-nfs, linux-unionfs,
	apparmor, linux-security-module, selinux

I am working towards changing the locking rules for name-operations: locking
the name rather than the whole directory.

The current part of this process is centralising all the locking so that
it can be changed in one place.

Recently "start_creating", "start_removing", "start_renaming" and related
interaces were added which combine the locking and the lookup.  At that time
many callers were changed to use the new interfaces.  However there are still
an assortment of places out side of fs/namei.c where the directory is locked
explictly, whether with inode_lock() or lock_rename() or similar.  These were
missed in the first pass for an assortment of uninteresting reasons.

This series addresses the remaining places where explicit locking is
used, and changes them to use the new interfaces, or otherwise removes
the explicit locking.

The biggest changes are in overlayfs.  The other changes are quite
simple, though maybe the cachefiles changes is the least simple of those.

I'm running the --overlay tests in xfstests and nothing has popped yet.
I'll continue with this and run some NFS tests too.

Thanks for your review of these patches!

NeilBrown


 [PATCH 01/13] fs/proc: Don't lock root inode when creating "self" and
 [PATCH 02/13] VFS: move the start_dirop() kerndoc comment to before
 [PATCH 03/13] libfs: change simple_done_creating() to use
 [PATCH 04/13] Apparmor: Use simple_start_creating() /
 [PATCH 05/13] selinux: Use simple_start_creating() /
 [PATCH 06/13] nfsd: switch purge_old() to use start_removing_noperm()
 [PATCH 07/13] VFS: make lookup_one_qstr_excl() static.
 [PATCH 08/13] ovl: Simplify ovl_lookup_real_one()
 [PATCH 09/13] cachefiles: change cachefiles_bury_object to use
 [PATCH 10/13] ovl: change ovl_create_real() to get a new lock when
 [PATCH 11/13] ovl: use is_subdir() for testing if one thing is a
 [PATCH 12/13] ovl: remove ovl_lock_rename_workdir()
 [PATCH 13/13] VFS: unexport lock_rename(), lock_rename_child(),

^ permalink raw reply

* [GIT PULL] lsm/lsm-pr-20260203
From: Paul Moore @ 2026-02-04  4:10 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: linux-security-module, linux-kernel

Linus,

This is a bit early, but due to some personal scheduling I'd rather send
this to you now, and you always mention you prefer to get pull requests
early (perhaps not this early?) so here is hoping this is a win-win.

Here are the highlights for the LSM changes queued for the Linux v7.0
merge window:

- Unify the security_inode_listsecurity() calls in NFSv4

While looking at security_inode_listsecurity() with an eye towards
improving the interface, we realized that the NFSv4 code was making
multiple calls to the LSM hook that could be consolidated into one.  We
attempted to engage the NFS folks on this multiple times over several
months to get input, ACKs, etc. but never recieved any comments.  While
this commit does touch NFS code exclusively, it is directly related to
the LSM hook, so I've gone and merged the commit into the LSM tree.  It
has been in linux-next for almost a full month without any comments or
complaints from the NFS folks.

- Mark the LSM static branch keys as static

This helps resolve some sparse warnings.

- Add __rust_helper annotations to the LSM and cred wrapper functions.

- Remove the unsused set_security_override_from_ctx() function

- Minor fixes to some of the LSM kdoc comment blocks

Paul

--
The following changes since commit 8f0b4cce4481fb22653697cced8d0d04027cb1e8:

  Linux 6.19-rc1 (2025-12-14 16:05:07 +1200)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm.git
    tags/lsm-pr-20260203

for you to fetch changes up to 472711068fa950642b9b471aaebcc82e9930eb8c:

  lsm: make keys for static branch static (2026-01-06 20:57:55 -0500)

----------------------------------------------------------------
lsm/stable-7.0 PR 20260203
----------------------------------------------------------------

Alice Ryhl (2):
      rust: cred: add __rust_helper to helpers
      rust: security: add __rust_helper to helpers

Ben Dooks (1):
      lsm: make keys for static branch static

Casey Schaufler (1):
      cred: remove unused set_security_override_from_ctx()

Randy Dunlap (1):
      lsm: fix kernel-doc struct member names

Stephen Smalley (1):
      nfs: unify security_inode_listsecurity() calls

 fs/nfs/nfs4proc.c         |   38 +++-----------------------------------
 include/linux/cred.h      |    1 -
 include/linux/lsm_hooks.h |    4 ++--
 kernel/cred.c             |   23 -----------------------
 rust/helpers/cred.c       |    4 ++--
 rust/helpers/security.c   |   26 +++++++++++++++-----------
 security/security.c       |    2 +-
 7 files changed, 23 insertions(+), 75 deletions(-)

--
paul-moore.com

^ permalink raw reply

* [GIT PULL] selinux/selinux-pr-20260203
From: Paul Moore @ 2026-02-04  4:10 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: selinux, linux-security-module, linux-kernel

Linus,

This is a bit early, but due to some personal scheduling I'd rather send
this to you now, and you always mention you prefer to get pull requests
early (perhaps not this early?) so here is hoping this is a win-win.

Here are the highlights for the SELinux changes queued for the Linux v7.0
merge window:

- Add support for SELinux based access control of BPF tokens

We worked with the BPF devs to add the necessary LSM hooks when the BPF
token code was first introduced, but it took us a bit longer to add the
SELinux wiring and support.  In order to preserve existing token-unaware
SELinux policies, the new code is gated by the new "bpf_token_perms"
policy capability.

Additional details regarding the new permissions, and behaviors can be
found in the associated commit.

- Remove a BUG() from the SELinux capability code

We now perform a similar check during compile time so we can safely
remove the BUG() call.

Paul

--
The following changes since commit 8f0b4cce4481fb22653697cced8d0d04027cb1e8:

  Linux 6.19-rc1 (2025-12-14 16:05:07 +1200)

are available in the Git repository at:

  https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git
    tags/selinux-pr-20260203

for you to fetch changes up to ea64aa57d596c4cbe518ffd043c52ef64089708d:

  selinux: drop the BUG() in cred_has_capability()
    (2026-01-14 16:26:21 -0500)

----------------------------------------------------------------
selinux/stable-7.0 PR 20260203
----------------------------------------------------------------

Eric Suen (1):
      selinux: add support for BPF token access control

Paul Moore (3):
      selinux: move the selinux_blob_sizes struct
      selinux: fix a capabilities parsing typo in
         selinux_bpf_token_capable()
      selinux: drop the BUG() in cred_has_capability()

 security/selinux/hooks.c                   |  163 +++++++++++++++++----
 security/selinux/include/classmap.h        |    2 
 security/selinux/include/objsec.h          |    3 
 security/selinux/include/policycap.h       |    1 
 security/selinux/include/policycap_names.h |    1 
 security/selinux/include/security.h        |    6 
 6 files changed, 151 insertions(+), 25 deletions(-)

--
paul-moore.com

^ permalink raw reply

* [PATCH v3 6/6] selftests/landlock: Add pathname socket variants for more tests
From: Tingmao Wang @ 2026-02-03 23:12 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Tingmao Wang, Günther Noack, Demi Marie Obenour, Alyssa Ross,
	Jann Horn, Tahera Fahimi, Justin Suess, linux-security-module
In-Reply-To: <cover.1770160146.git.m@maowtm.org>

While this produces a lot of change, it does allow us to
"simultaneously" test both abstract and pathname UNIX sockets with
relatively little code duplication, since they are really similar.

Tests touched: scoped_vs_unscoped, outside_socket,
various_address_sockets, datagram_sockets, self_connect.

Signed-off-by: Tingmao Wang <m@maowtm.org>
---

Changes in v3:
- Comment update, format

 .../selftests/landlock/scoped_unix_test.c     | 617 ++++++++++++------
 1 file changed, 411 insertions(+), 206 deletions(-)

diff --git a/tools/testing/selftests/landlock/scoped_unix_test.c b/tools/testing/selftests/landlock/scoped_unix_test.c
index d117c85a2ca7..bc406c98f704 100644
--- a/tools/testing/selftests/landlock/scoped_unix_test.c
+++ b/tools/testing/selftests/landlock/scoped_unix_test.c
@@ -545,8 +545,12 @@ TEST_F(scoped_audit, connect_to_child)
 
 FIXTURE(scoped_vs_unscoped)
 {
-	struct service_fixture parent_stream_address, parent_dgram_address,
-		child_stream_address, child_dgram_address;
+	struct service_fixture parent_stream_address_abstract,
+		parent_dgram_address_abstract, child_stream_address_abstract,
+		child_dgram_address_abstract;
+	struct service_fixture parent_stream_address_pathname,
+		parent_dgram_address_pathname, child_stream_address_pathname,
+		child_dgram_address_pathname;
 };
 
 #include "scoped_multiple_domain_variants.h"
@@ -555,35 +559,79 @@ FIXTURE_SETUP(scoped_vs_unscoped)
 {
 	drop_caps(_metadata);
 
-	memset(&self->parent_stream_address, 0,
-	       sizeof(self->parent_stream_address));
-	set_unix_address(&self->parent_stream_address, 0, true);
-	memset(&self->parent_dgram_address, 0,
-	       sizeof(self->parent_dgram_address));
-	set_unix_address(&self->parent_dgram_address, 1, true);
-	memset(&self->child_stream_address, 0,
-	       sizeof(self->child_stream_address));
-	set_unix_address(&self->child_stream_address, 2, true);
-	memset(&self->child_dgram_address, 0,
-	       sizeof(self->child_dgram_address));
-	set_unix_address(&self->child_dgram_address, 3, true);
+	ASSERT_EQ(0, mkdir(PATHNAME_UNIX_SOCK_DIR, 0700));
+
+	/* Abstract addresses. */
+	memset(&self->parent_stream_address_abstract, 0,
+	       sizeof(self->parent_stream_address_abstract));
+	set_unix_address(&self->parent_stream_address_abstract, 0, true);
+	memset(&self->parent_dgram_address_abstract, 0,
+	       sizeof(self->parent_dgram_address_abstract));
+	set_unix_address(&self->parent_dgram_address_abstract, 1, true);
+	memset(&self->child_stream_address_abstract, 0,
+	       sizeof(self->child_stream_address_abstract));
+	set_unix_address(&self->child_stream_address_abstract, 2, true);
+	memset(&self->child_dgram_address_abstract, 0,
+	       sizeof(self->child_dgram_address_abstract));
+	set_unix_address(&self->child_dgram_address_abstract, 3, true);
+
+	/* Pathname addresses. */
+	memset(&self->parent_stream_address_pathname, 0,
+	       sizeof(self->parent_stream_address_pathname));
+	set_unix_address(&self->parent_stream_address_pathname, 4, false);
+	memset(&self->parent_dgram_address_pathname, 0,
+	       sizeof(self->parent_dgram_address_pathname));
+	set_unix_address(&self->parent_dgram_address_pathname, 5, false);
+	memset(&self->child_stream_address_pathname, 0,
+	       sizeof(self->child_stream_address_pathname));
+	set_unix_address(&self->child_stream_address_pathname, 6, false);
+	memset(&self->child_dgram_address_pathname, 0,
+	       sizeof(self->child_dgram_address_pathname));
+	set_unix_address(&self->child_dgram_address_pathname, 7, false);
 }
 
 FIXTURE_TEARDOWN(scoped_vs_unscoped)
 {
+	EXPECT_EQ(0, remove_path(self->parent_stream_address_pathname.unix_addr
+					 .sun_path));
+	EXPECT_EQ(0, remove_path(self->parent_dgram_address_pathname.unix_addr
+					 .sun_path));
+	EXPECT_EQ(0, remove_path(self->child_stream_address_pathname.unix_addr
+					 .sun_path));
+	EXPECT_EQ(0, remove_path(self->child_dgram_address_pathname.unix_addr
+					 .sun_path));
+	EXPECT_EQ(0, rmdir(PATHNAME_UNIX_SOCK_DIR));
 }
 
 /*
  * Test unix_stream_connect and unix_may_send for parent, child and
  * grand child processes when they can have scoped or non-scoped domains.
  */
-TEST_F(scoped_vs_unscoped, unix_scoping)
+static void test_scoped_vs_unscoped(struct __test_metadata *const _metadata,
+				    FIXTURE_DATA(scoped_vs_unscoped) * self,
+				    const FIXTURE_VARIANT(scoped_vs_unscoped) *
+					    variant,
+				    const bool abstract)
 {
 	pid_t child;
 	int status;
 	bool can_connect_to_parent, can_connect_to_child;
 	int pipe_parent[2];
 	int stream_server_parent, dgram_server_parent;
+	const __u16 scope = abstract ? LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET :
+				       LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET;
+	const struct service_fixture *parent_stream_address =
+		abstract ? &self->parent_stream_address_abstract :
+			   &self->parent_stream_address_pathname;
+	const struct service_fixture *parent_dgram_address =
+		abstract ? &self->parent_dgram_address_abstract :
+			   &self->parent_dgram_address_pathname;
+	const struct service_fixture *child_stream_address =
+		abstract ? &self->child_stream_address_abstract :
+			   &self->child_stream_address_pathname;
+	const struct service_fixture *child_dgram_address =
+		abstract ? &self->child_dgram_address_abstract :
+			   &self->child_dgram_address_pathname;
 
 	can_connect_to_child = (variant->domain_grand_child != SCOPE_SANDBOX);
 	can_connect_to_parent = (can_connect_to_child &&
@@ -594,8 +642,7 @@ TEST_F(scoped_vs_unscoped, unix_scoping)
 	if (variant->domain_all == OTHER_SANDBOX)
 		create_fs_domain(_metadata);
 	else if (variant->domain_all == SCOPE_SANDBOX)
-		create_scoped_domain(_metadata,
-				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+		create_scoped_domain(_metadata, scope);
 
 	child = fork();
 	ASSERT_LE(0, child);
@@ -609,8 +656,7 @@ TEST_F(scoped_vs_unscoped, unix_scoping)
 		if (variant->domain_children == OTHER_SANDBOX)
 			create_fs_domain(_metadata);
 		else if (variant->domain_children == SCOPE_SANDBOX)
-			create_scoped_domain(
-				_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+			create_scoped_domain(_metadata, scope);
 
 		grand_child = fork();
 		ASSERT_LE(0, grand_child);
@@ -625,9 +671,7 @@ TEST_F(scoped_vs_unscoped, unix_scoping)
 			if (variant->domain_grand_child == OTHER_SANDBOX)
 				create_fs_domain(_metadata);
 			else if (variant->domain_grand_child == SCOPE_SANDBOX)
-				create_scoped_domain(
-					_metadata,
-					LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+				create_scoped_domain(_metadata, scope);
 
 			stream_client = socket(AF_UNIX, SOCK_STREAM, 0);
 			ASSERT_LE(0, stream_client);
@@ -636,14 +680,12 @@ TEST_F(scoped_vs_unscoped, unix_scoping)
 
 			ASSERT_EQ(1, read(pipe_child[0], &buf, 1));
 			stream_err = connect(
-				stream_client,
-				&self->child_stream_address.unix_addr,
-				self->child_stream_address.unix_addr_len);
+				stream_client, &child_stream_address->unix_addr,
+				child_stream_address->unix_addr_len);
 			stream_errno = errno;
-			dgram_err = connect(
-				dgram_client,
-				&self->child_dgram_address.unix_addr,
-				self->child_dgram_address.unix_addr_len);
+			dgram_err = connect(dgram_client,
+					    &child_dgram_address->unix_addr,
+					    child_dgram_address->unix_addr_len);
 			dgram_errno = errno;
 			if (can_connect_to_child) {
 				EXPECT_EQ(0, stream_err);
@@ -661,15 +703,14 @@ TEST_F(scoped_vs_unscoped, unix_scoping)
 			/* Datagram sockets can "reconnect". */
 
 			ASSERT_EQ(1, read(pipe_parent[0], &buf, 1));
-			stream_err = connect(
-				stream_client,
-				&self->parent_stream_address.unix_addr,
-				self->parent_stream_address.unix_addr_len);
+			stream_err =
+				connect(stream_client,
+					&parent_stream_address->unix_addr,
+					parent_stream_address->unix_addr_len);
 			stream_errno = errno;
 			dgram_err = connect(
-				dgram_client,
-				&self->parent_dgram_address.unix_addr,
-				self->parent_dgram_address.unix_addr_len);
+				dgram_client, &parent_dgram_address->unix_addr,
+				parent_dgram_address->unix_addr_len);
 			dgram_errno = errno;
 			if (can_connect_to_parent) {
 				EXPECT_EQ(0, stream_err);
@@ -690,8 +731,7 @@ TEST_F(scoped_vs_unscoped, unix_scoping)
 		if (variant->domain_child == OTHER_SANDBOX)
 			create_fs_domain(_metadata);
 		else if (variant->domain_child == SCOPE_SANDBOX)
-			create_scoped_domain(
-				_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+			create_scoped_domain(_metadata, scope);
 
 		stream_server_child = socket(AF_UNIX, SOCK_STREAM, 0);
 		ASSERT_LE(0, stream_server_child);
@@ -699,11 +739,11 @@ TEST_F(scoped_vs_unscoped, unix_scoping)
 		ASSERT_LE(0, dgram_server_child);
 
 		ASSERT_EQ(0, bind(stream_server_child,
-				  &self->child_stream_address.unix_addr,
-				  self->child_stream_address.unix_addr_len));
+				  &child_stream_address->unix_addr,
+				  child_stream_address->unix_addr_len));
 		ASSERT_EQ(0, bind(dgram_server_child,
-				  &self->child_dgram_address.unix_addr,
-				  self->child_dgram_address.unix_addr_len));
+				  &child_dgram_address->unix_addr,
+				  child_dgram_address->unix_addr_len));
 		ASSERT_EQ(0, listen(stream_server_child, backlog));
 
 		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
@@ -717,19 +757,17 @@ TEST_F(scoped_vs_unscoped, unix_scoping)
 	if (variant->domain_parent == OTHER_SANDBOX)
 		create_fs_domain(_metadata);
 	else if (variant->domain_parent == SCOPE_SANDBOX)
-		create_scoped_domain(_metadata,
-				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+		create_scoped_domain(_metadata, scope);
 
 	stream_server_parent = socket(AF_UNIX, SOCK_STREAM, 0);
 	ASSERT_LE(0, stream_server_parent);
 	dgram_server_parent = socket(AF_UNIX, SOCK_DGRAM, 0);
 	ASSERT_LE(0, dgram_server_parent);
-	ASSERT_EQ(0, bind(stream_server_parent,
-			  &self->parent_stream_address.unix_addr,
-			  self->parent_stream_address.unix_addr_len));
-	ASSERT_EQ(0, bind(dgram_server_parent,
-			  &self->parent_dgram_address.unix_addr,
-			  self->parent_dgram_address.unix_addr_len));
+	ASSERT_EQ(0,
+		  bind(stream_server_parent, &parent_stream_address->unix_addr,
+		       parent_stream_address->unix_addr_len));
+	ASSERT_EQ(0, bind(dgram_server_parent, &parent_dgram_address->unix_addr,
+			  parent_dgram_address->unix_addr_len));
 
 	ASSERT_EQ(0, listen(stream_server_parent, backlog));
 
@@ -743,57 +781,121 @@ TEST_F(scoped_vs_unscoped, unix_scoping)
 		_metadata->exit_code = KSFT_FAIL;
 }
 
+TEST_F(scoped_vs_unscoped, unix_scoping_abstract)
+{
+	test_scoped_vs_unscoped(_metadata, self, variant, true);
+}
+
+TEST_F(scoped_vs_unscoped, unix_scoping_pathname)
+{
+	test_scoped_vs_unscoped(_metadata, self, variant, false);
+}
+
 FIXTURE(outside_socket)
 {
-	struct service_fixture address, transit_address;
+	struct service_fixture address_abstract, transit_address_abstract;
+	struct service_fixture address_pathname, transit_address_pathname;
 };
 
 FIXTURE_VARIANT(outside_socket)
 {
 	const bool child_socket;
 	const int type;
+	const bool abstract;
 };
 
 /* clang-format off */
-FIXTURE_VARIANT_ADD(outside_socket, allow_dgram_child) {
+FIXTURE_VARIANT_ADD(outside_socket, abstract_allow_dgram_child) {
 	/* clang-format on */
 	.child_socket = true,
 	.type = SOCK_DGRAM,
+	.abstract = true,
 };
 
 /* clang-format off */
-FIXTURE_VARIANT_ADD(outside_socket, deny_dgram_server) {
+FIXTURE_VARIANT_ADD(outside_socket, abstract_deny_dgram_server) {
 	/* clang-format on */
 	.child_socket = false,
 	.type = SOCK_DGRAM,
+	.abstract = true,
 };
 
 /* clang-format off */
-FIXTURE_VARIANT_ADD(outside_socket, allow_stream_child) {
+FIXTURE_VARIANT_ADD(outside_socket, abstract_allow_stream_child) {
 	/* clang-format on */
 	.child_socket = true,
 	.type = SOCK_STREAM,
+	.abstract = true,
 };
 
 /* clang-format off */
-FIXTURE_VARIANT_ADD(outside_socket, deny_stream_server) {
+FIXTURE_VARIANT_ADD(outside_socket, abstract_deny_stream_server) {
 	/* clang-format on */
 	.child_socket = false,
 	.type = SOCK_STREAM,
+	.abstract = true,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(outside_socket, pathname_allow_dgram_child) {
+	/* clang-format on */
+	.child_socket = true,
+	.type = SOCK_DGRAM,
+	.abstract = false,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(outside_socket, pathname_deny_dgram_server) {
+	/* clang-format on */
+	.child_socket = false,
+	.type = SOCK_DGRAM,
+	.abstract = false,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(outside_socket, pathname_allow_stream_child) {
+	/* clang-format on */
+	.child_socket = true,
+	.type = SOCK_STREAM,
+	.abstract = false,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(outside_socket, pathname_deny_stream_server) {
+	/* clang-format on */
+	.child_socket = false,
+	.type = SOCK_STREAM,
+	.abstract = false,
 };
 
 FIXTURE_SETUP(outside_socket)
 {
 	drop_caps(_metadata);
 
-	memset(&self->transit_address, 0, sizeof(self->transit_address));
-	set_unix_address(&self->transit_address, 0, true);
-	memset(&self->address, 0, sizeof(self->address));
-	set_unix_address(&self->address, 1, true);
+	ASSERT_EQ(0, mkdir(PATHNAME_UNIX_SOCK_DIR, 0700));
+
+	/* Abstract addresses. */
+	memset(&self->transit_address_abstract, 0,
+	       sizeof(self->transit_address_abstract));
+	set_unix_address(&self->transit_address_abstract, 0, true);
+	memset(&self->address_abstract, 0, sizeof(self->address_abstract));
+	set_unix_address(&self->address_abstract, 1, true);
+
+	/* Pathname addresses. */
+	memset(&self->transit_address_pathname, 0,
+	       sizeof(self->transit_address_pathname));
+	set_unix_address(&self->transit_address_pathname, 2, false);
+	memset(&self->address_pathname, 0, sizeof(self->address_pathname));
+	set_unix_address(&self->address_pathname, 3, false);
 }
 
 FIXTURE_TEARDOWN(outside_socket)
 {
+	EXPECT_EQ(
+		0,
+		remove_path(self->transit_address_pathname.unix_addr.sun_path));
+	EXPECT_EQ(0, remove_path(self->address_pathname.unix_addr.sun_path));
+	EXPECT_EQ(0, rmdir(PATHNAME_UNIX_SOCK_DIR));
 }
 
 /*
@@ -807,6 +909,15 @@ TEST_F(outside_socket, socket_with_different_domain)
 	int pipe_child[2], pipe_parent[2];
 	char buf_parent;
 	int server_socket;
+	const __u16 scope = variant->abstract ?
+				    LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET :
+				    LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET;
+	const struct service_fixture *transit_address =
+		variant->abstract ? &self->transit_address_abstract :
+				    &self->transit_address_pathname;
+	const struct service_fixture *address =
+		variant->abstract ? &self->address_abstract :
+				    &self->address_pathname;
 
 	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
 	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
@@ -821,8 +932,7 @@ TEST_F(outside_socket, socket_with_different_domain)
 		EXPECT_EQ(0, close(pipe_child[0]));
 
 		/* Client always has a domain. */
-		create_scoped_domain(_metadata,
-				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+		create_scoped_domain(_metadata, scope);
 
 		if (variant->child_socket) {
 			int data_socket, passed_socket, stream_server;
@@ -832,8 +942,8 @@ TEST_F(outside_socket, socket_with_different_domain)
 			stream_server = socket(AF_UNIX, SOCK_STREAM, 0);
 			ASSERT_LE(0, stream_server);
 			ASSERT_EQ(0, bind(stream_server,
-					  &self->transit_address.unix_addr,
-					  self->transit_address.unix_addr_len));
+					  &transit_address->unix_addr,
+					  transit_address->unix_addr_len));
 			ASSERT_EQ(0, listen(stream_server, backlog));
 			ASSERT_EQ(1, write(pipe_child[1], ".", 1));
 			data_socket = accept(stream_server, NULL, NULL);
@@ -848,8 +958,8 @@ TEST_F(outside_socket, socket_with_different_domain)
 
 		/* Waits for parent signal for connection. */
 		ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
-		err = connect(client_socket, &self->address.unix_addr,
-			      self->address.unix_addr_len);
+		err = connect(client_socket, &address->unix_addr,
+			      address->unix_addr_len);
 		if (variant->child_socket) {
 			EXPECT_EQ(0, err);
 		} else {
@@ -868,9 +978,8 @@ TEST_F(outside_socket, socket_with_different_domain)
 
 		ASSERT_LE(0, client_child);
 		ASSERT_EQ(1, read(pipe_child[0], &buf_parent, 1));
-		ASSERT_EQ(0, connect(client_child,
-				     &self->transit_address.unix_addr,
-				     self->transit_address.unix_addr_len));
+		ASSERT_EQ(0, connect(client_child, &transit_address->unix_addr,
+				     transit_address->unix_addr_len));
 		server_socket = recv_fd(client_child);
 		EXPECT_EQ(0, close(client_child));
 	} else {
@@ -879,10 +988,10 @@ TEST_F(outside_socket, socket_with_different_domain)
 	ASSERT_LE(0, server_socket);
 
 	/* Server always has a domain. */
-	create_scoped_domain(_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+	create_scoped_domain(_metadata, scope);
 
-	ASSERT_EQ(0, bind(server_socket, &self->address.unix_addr,
-			  self->address.unix_addr_len));
+	ASSERT_EQ(0, bind(server_socket, &address->unix_addr,
+			  address->unix_addr_len));
 	if (variant->type == SOCK_STREAM)
 		ASSERT_EQ(0, listen(server_socket, backlog));
 
@@ -897,52 +1006,90 @@ TEST_F(outside_socket, socket_with_different_domain)
 		_metadata->exit_code = KSFT_FAIL;
 }
 
-static const char stream_path[] = TMP_DIR "/stream.sock";
-static const char dgram_path[] = TMP_DIR "/dgram.sock";
-
 /* clang-format off */
-FIXTURE(various_address_sockets) {};
+FIXTURE(various_address_sockets) {
+	struct service_fixture stream_pathname_addr, dgram_pathname_addr;
+	struct service_fixture stream_abstract_addr, dgram_abstract_addr;
+};
 /* clang-format on */
 
-FIXTURE_VARIANT(various_address_sockets)
-{
-	const int domain;
+/*
+ * Test all 4 combinations of abstract and pathname socket scope bits,
+ * plus a case with no Landlock domain at all.
+ */
+/* clang-format off */
+FIXTURE_VARIANT(various_address_sockets) {
+	/* clang-format on */
+	const __u16 scope_bits;
+	const bool no_sandbox;
 };
 
 /* clang-format off */
-FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_scoped_domain) {
+FIXTURE_VARIANT_ADD(various_address_sockets, scope_abstract) {
 	/* clang-format on */
-	.domain = SCOPE_SANDBOX,
+	.scope_bits = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET,
 };
 
 /* clang-format off */
-FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_other_domain) {
+FIXTURE_VARIANT_ADD(various_address_sockets, scope_pathname) {
 	/* clang-format on */
-	.domain = OTHER_SANDBOX,
+	.scope_bits = LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET,
 };
 
 /* clang-format off */
-FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_no_domain) {
+FIXTURE_VARIANT_ADD(various_address_sockets, scope_both) {
 	/* clang-format on */
-	.domain = NO_SANDBOX,
+	.scope_bits = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
+		      LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(various_address_sockets, scope_none) {
+	/* clang-format on */
+	.scope_bits = 0,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(various_address_sockets, no_domain) {
+	/* clang-format on */
+	.no_sandbox = true,
 };
 
 FIXTURE_SETUP(various_address_sockets)
 {
 	drop_caps(_metadata);
 
-	umask(0077);
-	ASSERT_EQ(0, mkdir(TMP_DIR, 0700));
+	ASSERT_EQ(0, mkdir(PATHNAME_UNIX_SOCK_DIR, 0700));
+
+	memset(&self->stream_pathname_addr, 0,
+	       sizeof(self->stream_pathname_addr));
+	set_unix_address(&self->stream_pathname_addr, 0, false);
+	memset(&self->dgram_pathname_addr, 0,
+	       sizeof(self->dgram_pathname_addr));
+	set_unix_address(&self->dgram_pathname_addr, 1, false);
+
+	memset(&self->stream_abstract_addr, 0,
+	       sizeof(self->stream_abstract_addr));
+	set_unix_address(&self->stream_abstract_addr, 2, true);
+	memset(&self->dgram_abstract_addr, 0,
+	       sizeof(self->dgram_abstract_addr));
+	set_unix_address(&self->dgram_abstract_addr, 3, true);
 }
 
 FIXTURE_TEARDOWN(various_address_sockets)
 {
-	EXPECT_EQ(0, unlink(stream_path));
-	EXPECT_EQ(0, unlink(dgram_path));
-	EXPECT_EQ(0, rmdir(TMP_DIR));
+	EXPECT_EQ(0,
+		  remove_path(self->stream_pathname_addr.unix_addr.sun_path));
+	EXPECT_EQ(0, remove_path(self->dgram_pathname_addr.unix_addr.sun_path));
+	EXPECT_EQ(0, rmdir(PATHNAME_UNIX_SOCK_DIR));
 }
 
-TEST_F(various_address_sockets, scoped_pathname_sockets)
+/*
+ * Test interaction of various scope flags (controlled by variant->domain)
+ * with pathname and abstract sockets when connecting from a sandboxed
+ * child.
+ */
+TEST_F(various_address_sockets, scoped_sockets)
 {
 	pid_t child;
 	int status;
@@ -951,25 +1098,10 @@ TEST_F(various_address_sockets, scoped_pathname_sockets)
 	int unnamed_sockets[2];
 	int stream_pathname_socket, dgram_pathname_socket,
 		stream_abstract_socket, dgram_abstract_socket, data_socket;
-	struct service_fixture stream_abstract_addr, dgram_abstract_addr;
-	struct sockaddr_un stream_pathname_addr = {
-		.sun_family = AF_UNIX,
-	};
-	struct sockaddr_un dgram_pathname_addr = {
-		.sun_family = AF_UNIX,
-	};
-
-	/* Pathname address. */
-	snprintf(stream_pathname_addr.sun_path,
-		 sizeof(stream_pathname_addr.sun_path), "%s", stream_path);
-	snprintf(dgram_pathname_addr.sun_path,
-		 sizeof(dgram_pathname_addr.sun_path), "%s", dgram_path);
-
-	/* Abstract address. */
-	memset(&stream_abstract_addr, 0, sizeof(stream_abstract_addr));
-	set_unix_address(&stream_abstract_addr, 0, true);
-	memset(&dgram_abstract_addr, 0, sizeof(dgram_abstract_addr));
-	set_unix_address(&dgram_abstract_addr, 1, true);
+	bool pathname_restricted =
+		(variant->scope_bits & LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET);
+	bool abstract_restricted =
+		(variant->scope_bits & LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
 
 	/* Unnamed address for datagram socket. */
 	ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_DGRAM, 0, unnamed_sockets));
@@ -984,82 +1116,103 @@ TEST_F(various_address_sockets, scoped_pathname_sockets)
 		EXPECT_EQ(0, close(pipe_parent[1]));
 		EXPECT_EQ(0, close(unnamed_sockets[1]));
 
-		if (variant->domain == SCOPE_SANDBOX)
-			create_scoped_domain(
-				_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
-		else if (variant->domain == OTHER_SANDBOX)
+		/* Create domain based on variant. */
+		if (variant->scope_bits)
+			create_scoped_domain(_metadata, variant->scope_bits);
+		else if (!variant->no_sandbox)
 			create_fs_domain(_metadata);
 
 		/* Waits for parent to listen. */
 		ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
 		EXPECT_EQ(0, close(pipe_parent[0]));
 
-		/* Checks that we can send data through a datagram socket. */
+		/* Checks that we can send data through an unnamed socket. */
 		ASSERT_EQ(1, write(unnamed_sockets[0], "a", 1));
 		EXPECT_EQ(0, close(unnamed_sockets[0]));
 
 		/* Connects with pathname sockets. */
 		stream_pathname_socket = socket(AF_UNIX, SOCK_STREAM, 0);
 		ASSERT_LE(0, stream_pathname_socket);
-		ASSERT_EQ(0,
-			  connect(stream_pathname_socket, &stream_pathname_addr,
-				  sizeof(stream_pathname_addr)));
-		ASSERT_EQ(1, write(stream_pathname_socket, "b", 1));
+		err = connect(stream_pathname_socket,
+			      &self->stream_pathname_addr.unix_addr,
+			      self->stream_pathname_addr.unix_addr_len);
+		if (pathname_restricted) {
+			EXPECT_EQ(-1, err);
+			EXPECT_EQ(EPERM, errno);
+		} else {
+			EXPECT_EQ(0, err);
+			ASSERT_EQ(1, write(stream_pathname_socket, "b", 1));
+		}
 		EXPECT_EQ(0, close(stream_pathname_socket));
 
-		/* Sends without connection. */
+		/* Sends without connection (pathname). */
 		dgram_pathname_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 		ASSERT_LE(0, dgram_pathname_socket);
 		err = sendto(dgram_pathname_socket, "c", 1, 0,
-			     &dgram_pathname_addr, sizeof(dgram_pathname_addr));
-		EXPECT_EQ(1, err);
-
-		/* Sends with connection. */
-		ASSERT_EQ(0,
-			  connect(dgram_pathname_socket, &dgram_pathname_addr,
-				  sizeof(dgram_pathname_addr)));
-		ASSERT_EQ(1, write(dgram_pathname_socket, "d", 1));
+			     &self->dgram_pathname_addr.unix_addr,
+			     self->dgram_pathname_addr.unix_addr_len);
+		if (pathname_restricted) {
+			EXPECT_EQ(-1, err);
+			EXPECT_EQ(EPERM, errno);
+		} else {
+			EXPECT_EQ(1, err);
+		}
+
+		/* Sends with connection (pathname). */
+		err = connect(dgram_pathname_socket,
+			      &self->dgram_pathname_addr.unix_addr,
+			      self->dgram_pathname_addr.unix_addr_len);
+		if (pathname_restricted) {
+			EXPECT_EQ(-1, err);
+			EXPECT_EQ(EPERM, errno);
+		} else {
+			EXPECT_EQ(0, err);
+			ASSERT_EQ(1, write(dgram_pathname_socket, "d", 1));
+		}
+
 		EXPECT_EQ(0, close(dgram_pathname_socket));
 
 		/* Connects with abstract sockets. */
 		stream_abstract_socket = socket(AF_UNIX, SOCK_STREAM, 0);
 		ASSERT_LE(0, stream_abstract_socket);
 		err = connect(stream_abstract_socket,
-			      &stream_abstract_addr.unix_addr,
-			      stream_abstract_addr.unix_addr_len);
-		if (variant->domain == SCOPE_SANDBOX) {
+			      &self->stream_abstract_addr.unix_addr,
+			      self->stream_abstract_addr.unix_addr_len);
+		if (abstract_restricted) {
 			EXPECT_EQ(-1, err);
 			EXPECT_EQ(EPERM, errno);
 		} else {
 			EXPECT_EQ(0, err);
 			ASSERT_EQ(1, write(stream_abstract_socket, "e", 1));
 		}
+
 		EXPECT_EQ(0, close(stream_abstract_socket));
 
-		/* Sends without connection. */
+		/* Sends without connection (abstract). */
 		dgram_abstract_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 		ASSERT_LE(0, dgram_abstract_socket);
 		err = sendto(dgram_abstract_socket, "f", 1, 0,
-			     &dgram_abstract_addr.unix_addr,
-			     dgram_abstract_addr.unix_addr_len);
-		if (variant->domain == SCOPE_SANDBOX) {
+			     &self->dgram_abstract_addr.unix_addr,
+			     self->dgram_abstract_addr.unix_addr_len);
+		if (abstract_restricted) {
 			EXPECT_EQ(-1, err);
 			EXPECT_EQ(EPERM, errno);
 		} else {
 			EXPECT_EQ(1, err);
 		}
 
-		/* Sends with connection. */
+		/* Sends with connection (abstract). */
 		err = connect(dgram_abstract_socket,
-			      &dgram_abstract_addr.unix_addr,
-			      dgram_abstract_addr.unix_addr_len);
-		if (variant->domain == SCOPE_SANDBOX) {
+			      &self->dgram_abstract_addr.unix_addr,
+			      self->dgram_abstract_addr.unix_addr_len);
+		if (abstract_restricted) {
 			EXPECT_EQ(-1, err);
 			EXPECT_EQ(EPERM, errno);
 		} else {
 			EXPECT_EQ(0, err);
 			ASSERT_EQ(1, write(dgram_abstract_socket, "g", 1));
 		}
+
 		EXPECT_EQ(0, close(dgram_abstract_socket));
 
 		_exit(_metadata->exit_code);
@@ -1071,27 +1224,30 @@ TEST_F(various_address_sockets, scoped_pathname_sockets)
 	/* Sets up pathname servers. */
 	stream_pathname_socket = socket(AF_UNIX, SOCK_STREAM, 0);
 	ASSERT_LE(0, stream_pathname_socket);
-	ASSERT_EQ(0, bind(stream_pathname_socket, &stream_pathname_addr,
-			  sizeof(stream_pathname_addr)));
+	ASSERT_EQ(0, bind(stream_pathname_socket,
+			  &self->stream_pathname_addr.unix_addr,
+			  self->stream_pathname_addr.unix_addr_len));
 	ASSERT_EQ(0, listen(stream_pathname_socket, backlog));
 
 	dgram_pathname_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 	ASSERT_LE(0, dgram_pathname_socket);
-	ASSERT_EQ(0, bind(dgram_pathname_socket, &dgram_pathname_addr,
-			  sizeof(dgram_pathname_addr)));
+	ASSERT_EQ(0, bind(dgram_pathname_socket,
+			  &self->dgram_pathname_addr.unix_addr,
+			  self->dgram_pathname_addr.unix_addr_len));
 
 	/* Sets up abstract servers. */
 	stream_abstract_socket = socket(AF_UNIX, SOCK_STREAM, 0);
 	ASSERT_LE(0, stream_abstract_socket);
-	ASSERT_EQ(0,
-		  bind(stream_abstract_socket, &stream_abstract_addr.unix_addr,
-		       stream_abstract_addr.unix_addr_len));
+	ASSERT_EQ(0, bind(stream_abstract_socket,
+			  &self->stream_abstract_addr.unix_addr,
+			  self->stream_abstract_addr.unix_addr_len));
+	ASSERT_EQ(0, listen(stream_abstract_socket, backlog));
 
 	dgram_abstract_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 	ASSERT_LE(0, dgram_abstract_socket);
-	ASSERT_EQ(0, bind(dgram_abstract_socket, &dgram_abstract_addr.unix_addr,
-			  dgram_abstract_addr.unix_addr_len));
-	ASSERT_EQ(0, listen(stream_abstract_socket, backlog));
+	ASSERT_EQ(0, bind(dgram_abstract_socket,
+			  &self->dgram_abstract_addr.unix_addr,
+			  self->dgram_abstract_addr.unix_addr_len));
 
 	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
 	EXPECT_EQ(0, close(pipe_parent[1]));
@@ -1101,24 +1257,31 @@ TEST_F(various_address_sockets, scoped_pathname_sockets)
 	ASSERT_EQ('a', buf_parent);
 	EXPECT_LE(0, close(unnamed_sockets[1]));
 
-	/* Reads from pathname sockets. */
-	data_socket = accept(stream_pathname_socket, NULL, NULL);
-	ASSERT_LE(0, data_socket);
-	ASSERT_EQ(1, read(data_socket, &buf_parent, sizeof(buf_parent)));
-	ASSERT_EQ('b', buf_parent);
-	EXPECT_EQ(0, close(data_socket));
-	EXPECT_EQ(0, close(stream_pathname_socket));
+	if (!pathname_restricted) {
+		/*
+		 * Reads from pathname sockets if we expect child to be able to
+		 * send.
+		 */
+		data_socket = accept(stream_pathname_socket, NULL, NULL);
+		ASSERT_LE(0, data_socket);
+		ASSERT_EQ(1,
+			  read(data_socket, &buf_parent, sizeof(buf_parent)));
+		ASSERT_EQ('b', buf_parent);
+		EXPECT_EQ(0, close(data_socket));
 
-	ASSERT_EQ(1,
-		  read(dgram_pathname_socket, &buf_parent, sizeof(buf_parent)));
-	ASSERT_EQ('c', buf_parent);
-	ASSERT_EQ(1,
-		  read(dgram_pathname_socket, &buf_parent, sizeof(buf_parent)));
-	ASSERT_EQ('d', buf_parent);
-	EXPECT_EQ(0, close(dgram_pathname_socket));
+		ASSERT_EQ(1, read(dgram_pathname_socket, &buf_parent,
+				  sizeof(buf_parent)));
+		ASSERT_EQ('c', buf_parent);
+		ASSERT_EQ(1, read(dgram_pathname_socket, &buf_parent,
+				  sizeof(buf_parent)));
+		ASSERT_EQ('d', buf_parent);
+	}
 
-	if (variant->domain != SCOPE_SANDBOX) {
-		/* Reads from abstract sockets if allowed to send. */
+	if (!abstract_restricted) {
+		/*
+		 * Reads from abstract sockets if we expect child to be able to
+		 * send.
+		 */
 		data_socket = accept(stream_abstract_socket, NULL, NULL);
 		ASSERT_LE(0, data_socket);
 		ASSERT_EQ(1,
@@ -1134,30 +1297,76 @@ TEST_F(various_address_sockets, scoped_pathname_sockets)
 		ASSERT_EQ('g', buf_parent);
 	}
 
-	/* Waits for all abstract socket tests. */
+	/* Waits for child to complete, and only close the socket afterwards. */
 	ASSERT_EQ(child, waitpid(child, &status, 0));
 	EXPECT_EQ(0, close(stream_abstract_socket));
 	EXPECT_EQ(0, close(dgram_abstract_socket));
+	EXPECT_EQ(0, close(stream_pathname_socket));
+	EXPECT_EQ(0, close(dgram_pathname_socket));
 
 	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
 	    WEXITSTATUS(status) != EXIT_SUCCESS)
 		_metadata->exit_code = KSFT_FAIL;
 }
 
-TEST(datagram_sockets)
+/* Fixture for datagram_sockets and self_connect tests */
+FIXTURE(socket_type_test)
 {
 	struct service_fixture connected_addr, non_connected_addr;
+};
+
+FIXTURE_VARIANT(socket_type_test)
+{
+	const bool abstract;
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(socket_type_test, abstract) {
+	/* clang-format on */
+	.abstract = true,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(socket_type_test, pathname) {
+	/* clang-format on */
+	.abstract = false,
+};
+
+FIXTURE_SETUP(socket_type_test)
+{
+	drop_caps(_metadata);
+
+	if (!variant->abstract)
+		ASSERT_EQ(0, mkdir(PATHNAME_UNIX_SOCK_DIR, 0700));
+
+	memset(&self->connected_addr, 0, sizeof(self->connected_addr));
+	set_unix_address(&self->connected_addr, 0, variant->abstract);
+	memset(&self->non_connected_addr, 0, sizeof(self->non_connected_addr));
+	set_unix_address(&self->non_connected_addr, 1, variant->abstract);
+}
+
+FIXTURE_TEARDOWN(socket_type_test)
+{
+	if (!variant->abstract) {
+		EXPECT_EQ(0,
+			  remove_path(self->connected_addr.unix_addr.sun_path));
+		EXPECT_EQ(0,
+			  remove_path(
+				  self->non_connected_addr.unix_addr.sun_path));
+		EXPECT_EQ(0, rmdir(PATHNAME_UNIX_SOCK_DIR));
+	}
+}
+
+TEST_F(socket_type_test, datagram_sockets)
+{
 	int server_conn_socket, server_unconn_socket;
 	int pipe_parent[2], pipe_child[2];
 	int status;
 	char buf;
 	pid_t child;
-
-	drop_caps(_metadata);
-	memset(&connected_addr, 0, sizeof(connected_addr));
-	set_unix_address(&connected_addr, 0, true);
-	memset(&non_connected_addr, 0, sizeof(non_connected_addr));
-	set_unix_address(&non_connected_addr, 1, true);
+	const __u16 scope = variant->abstract ?
+				    LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET :
+				    LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET;
 
 	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
 	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
@@ -1177,9 +1386,9 @@ TEST(datagram_sockets)
 
 		/* Waits for parent to listen. */
 		ASSERT_EQ(1, read(pipe_parent[0], &buf, 1));
-		ASSERT_EQ(0,
-			  connect(client_conn_socket, &connected_addr.unix_addr,
-				  connected_addr.unix_addr_len));
+		ASSERT_EQ(0, connect(client_conn_socket,
+				     &self->connected_addr.unix_addr,
+				     self->connected_addr.unix_addr_len));
 
 		/*
 		 * Both connected and non-connected sockets can send data when
@@ -1187,13 +1396,12 @@ TEST(datagram_sockets)
 		 */
 		ASSERT_EQ(1, send(client_conn_socket, ".", 1, 0));
 		ASSERT_EQ(1, sendto(client_unconn_socket, ".", 1, 0,
-				    &non_connected_addr.unix_addr,
-				    non_connected_addr.unix_addr_len));
+				    &self->non_connected_addr.unix_addr,
+				    self->non_connected_addr.unix_addr_len));
 		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
 
 		/* Scopes the domain. */
-		create_scoped_domain(_metadata,
-				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+		create_scoped_domain(_metadata, scope);
 
 		/*
 		 * Connected socket sends data to the receiver, but the
@@ -1201,8 +1409,8 @@ TEST(datagram_sockets)
 		 */
 		ASSERT_EQ(1, send(client_conn_socket, ".", 1, 0));
 		ASSERT_EQ(-1, sendto(client_unconn_socket, ".", 1, 0,
-				     &non_connected_addr.unix_addr,
-				     non_connected_addr.unix_addr_len));
+				     &self->non_connected_addr.unix_addr,
+				     self->non_connected_addr.unix_addr_len));
 		ASSERT_EQ(EPERM, errno);
 		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
 
@@ -1219,10 +1427,11 @@ TEST(datagram_sockets)
 	ASSERT_LE(0, server_conn_socket);
 	ASSERT_LE(0, server_unconn_socket);
 
-	ASSERT_EQ(0, bind(server_conn_socket, &connected_addr.unix_addr,
-			  connected_addr.unix_addr_len));
-	ASSERT_EQ(0, bind(server_unconn_socket, &non_connected_addr.unix_addr,
-			  non_connected_addr.unix_addr_len));
+	ASSERT_EQ(0, bind(server_conn_socket, &self->connected_addr.unix_addr,
+			  self->connected_addr.unix_addr_len));
+	ASSERT_EQ(0, bind(server_unconn_socket,
+			  &self->non_connected_addr.unix_addr,
+			  self->non_connected_addr.unix_addr_len));
 	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
 
 	/* Waits for child to test. */
@@ -1247,52 +1456,48 @@ TEST(datagram_sockets)
 		_metadata->exit_code = KSFT_FAIL;
 }
 
-TEST(self_connect)
+TEST_F(socket_type_test, self_connect)
 {
-	struct service_fixture connected_addr, non_connected_addr;
 	int connected_socket, non_connected_socket, status;
 	pid_t child;
-
-	drop_caps(_metadata);
-	memset(&connected_addr, 0, sizeof(connected_addr));
-	set_unix_address(&connected_addr, 0, true);
-	memset(&non_connected_addr, 0, sizeof(non_connected_addr));
-	set_unix_address(&non_connected_addr, 1, true);
+	const __u16 scope = variant->abstract ?
+				    LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET :
+				    LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET;
 
 	connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 	non_connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 	ASSERT_LE(0, connected_socket);
 	ASSERT_LE(0, non_connected_socket);
 
-	ASSERT_EQ(0, bind(connected_socket, &connected_addr.unix_addr,
-			  connected_addr.unix_addr_len));
-	ASSERT_EQ(0, bind(non_connected_socket, &non_connected_addr.unix_addr,
-			  non_connected_addr.unix_addr_len));
+	ASSERT_EQ(0, bind(connected_socket, &self->connected_addr.unix_addr,
+			  self->connected_addr.unix_addr_len));
+	ASSERT_EQ(0, bind(non_connected_socket,
+			  &self->non_connected_addr.unix_addr,
+			  self->non_connected_addr.unix_addr_len));
 
 	child = fork();
 	ASSERT_LE(0, child);
 	if (child == 0) {
 		/* Child's domain is scoped. */
-		create_scoped_domain(_metadata,
-				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+		create_scoped_domain(_metadata, scope);
 
 		/*
 		 * The child inherits the sockets, and cannot connect or
 		 * send data to them.
 		 */
-		ASSERT_EQ(-1,
-			  connect(connected_socket, &connected_addr.unix_addr,
-				  connected_addr.unix_addr_len));
+		ASSERT_EQ(-1, connect(connected_socket,
+				      &self->connected_addr.unix_addr,
+				      self->connected_addr.unix_addr_len));
 		ASSERT_EQ(EPERM, errno);
 
 		ASSERT_EQ(-1, sendto(connected_socket, ".", 1, 0,
-				     &connected_addr.unix_addr,
-				     connected_addr.unix_addr_len));
+				     &self->connected_addr.unix_addr,
+				     self->connected_addr.unix_addr_len));
 		ASSERT_EQ(EPERM, errno);
 
 		ASSERT_EQ(-1, sendto(non_connected_socket, ".", 1, 0,
-				     &non_connected_addr.unix_addr,
-				     non_connected_addr.unix_addr_len));
+				     &self->non_connected_addr.unix_addr,
+				     self->non_connected_addr.unix_addr_len));
 		ASSERT_EQ(EPERM, errno);
 
 		EXPECT_EQ(0, close(connected_socket));
-- 
2.52.0

^ permalink raw reply related

* [PATCH v3 5/6] selftests/landlock: Repurpose scoped_abstract_unix_test.c for pathname sockets too
From: Tingmao Wang @ 2026-02-03 23:12 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Tingmao Wang, Günther Noack, Demi Marie Obenour, Alyssa Ross,
	Jann Horn, Tahera Fahimi, Justin Suess, linux-security-module
In-Reply-To: <cover.1770160146.git.m@maowtm.org>

Since there is very little difference between abstract and pathname
sockets in terms of testing of the scoped access checks (the only
difference is in which scope bit control which form of socket), it makes
sense to reuse the existing test for both type of sockets.  Therefore,
we rename scoped_abstract_unix_test.c to scoped_unix_test.c and extend
the scoped_domains test to test pathname (i.e. non-abstract) sockets
too.

Since we can't change the variant data of scoped_domains (as it is
defined in the shared .h file), we do this by extracting the actual test
code into a function, and call it from different test cases.

Also extend scoped_audit (this time we can use variants) to test both
abstract and pathname sockets.  For pathname sockets, audit_log_lsm_data
will produce path="..." (or hex if path contains control characters)
with absolute paths from the dentry, so we need to construct the escaped
regex for the real path like in fs_test.

Signed-off-by: Tingmao Wang <m@maowtm.org>
---

Changes in v3:
- Fix comment, style, formatting, and reflow the above message
- Update definition of log_match_remaining

 ...bstract_unix_test.c => scoped_unix_test.c} | 269 ++++++++++++++----
 1 file changed, 217 insertions(+), 52 deletions(-)
 rename tools/testing/selftests/landlock/{scoped_abstract_unix_test.c => scoped_unix_test.c} (80%)

diff --git a/tools/testing/selftests/landlock/scoped_abstract_unix_test.c b/tools/testing/selftests/landlock/scoped_unix_test.c
similarity index 80%
rename from tools/testing/selftests/landlock/scoped_abstract_unix_test.c
rename to tools/testing/selftests/landlock/scoped_unix_test.c
index 4a790e2d387d..d117c85a2ca7 100644
--- a/tools/testing/selftests/landlock/scoped_abstract_unix_test.c
+++ b/tools/testing/selftests/landlock/scoped_unix_test.c
@@ -1,6 +1,7 @@
 // SPDX-License-Identifier: GPL-2.0
 /*
- * Landlock tests - Abstract UNIX socket
+ * Landlock tests - Scoped access checks for UNIX socket (abstract and
+ * pathname)
  *
  * Copyright © 2024 Tahera Fahimi <fahimitahera@gmail.com>
  */
@@ -19,6 +20,7 @@
 #include <sys/un.h>
 #include <sys/wait.h>
 #include <unistd.h>
+#include <stdlib.h>
 
 #include "audit.h"
 #include "common.h"
@@ -47,7 +49,8 @@ static void create_fs_domain(struct __test_metadata *const _metadata)
 
 FIXTURE(scoped_domains)
 {
-	struct service_fixture stream_address, dgram_address;
+	struct service_fixture stream_address_abstract, dgram_address_abstract,
+		stream_address_pathname, dgram_address_pathname;
 };
 
 #include "scoped_base_variants.h"
@@ -56,27 +59,64 @@ FIXTURE_SETUP(scoped_domains)
 {
 	drop_caps(_metadata);
 
-	memset(&self->stream_address, 0, sizeof(self->stream_address));
-	memset(&self->dgram_address, 0, sizeof(self->dgram_address));
-	set_unix_address(&self->stream_address, 0, true);
-	set_unix_address(&self->dgram_address, 1, true);
+	ASSERT_EQ(0, mkdir(PATHNAME_UNIX_SOCK_DIR, 0700));
+
+	memset(&self->stream_address_abstract, 0,
+	       sizeof(self->stream_address_abstract));
+	memset(&self->dgram_address_abstract, 0,
+	       sizeof(self->dgram_address_abstract));
+	memset(&self->stream_address_pathname, 0,
+	       sizeof(self->stream_address_pathname));
+	memset(&self->dgram_address_pathname, 0,
+	       sizeof(self->dgram_address_pathname));
+	set_unix_address(&self->stream_address_abstract, 0, true);
+	set_unix_address(&self->dgram_address_abstract, 1, true);
+	set_unix_address(&self->stream_address_pathname, 0, false);
+	set_unix_address(&self->dgram_address_pathname, 1, false);
+}
+
+/* Remove @path if it exists */
+int remove_path(const char *path)
+{
+	if (unlink(path) == -1) {
+		if (errno != ENOENT)
+			return -errno;
+	}
+	return 0;
 }
 
 FIXTURE_TEARDOWN(scoped_domains)
 {
+	EXPECT_EQ(0, remove_path(
+			     self->stream_address_pathname.unix_addr.sun_path));
+	EXPECT_EQ(0,
+		  remove_path(self->dgram_address_pathname.unix_addr.sun_path));
+	EXPECT_EQ(0, rmdir(PATHNAME_UNIX_SOCK_DIR));
 }
 
 /*
  * Test unix_stream_connect() and unix_may_send() for a child connecting to its
  * parent, when they have scoped domain or no domain.
  */
-TEST_F(scoped_domains, connect_to_parent)
+static void test_connect_to_parent(struct __test_metadata *const _metadata,
+				   FIXTURE_DATA(scoped_domains) * self,
+				   const FIXTURE_VARIANT(scoped_domains) *
+					   variant,
+				   const bool abstract)
 {
 	pid_t child;
 	bool can_connect_to_parent;
 	int status;
 	int pipe_parent[2];
 	int stream_server, dgram_server;
+	const __u16 scope = abstract ? LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET :
+				       LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET;
+	const struct service_fixture *stream_address =
+		abstract ? &self->stream_address_abstract :
+			   &self->stream_address_pathname;
+	const struct service_fixture *dgram_address =
+		abstract ? &self->dgram_address_abstract :
+			   &self->dgram_address_pathname;
 
 	/*
 	 * can_connect_to_parent is true if a child process can connect to its
@@ -87,8 +127,7 @@ TEST_F(scoped_domains, connect_to_parent)
 
 	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
 	if (variant->domain_both) {
-		create_scoped_domain(_metadata,
-				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+		create_scoped_domain(_metadata, scope);
 		if (!__test_passed(_metadata))
 			return;
 	}
@@ -102,8 +141,7 @@ TEST_F(scoped_domains, connect_to_parent)
 
 		EXPECT_EQ(0, close(pipe_parent[1]));
 		if (variant->domain_child)
-			create_scoped_domain(
-				_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+			create_scoped_domain(_metadata, scope);
 
 		stream_client = socket(AF_UNIX, SOCK_STREAM, 0);
 		ASSERT_LE(0, stream_client);
@@ -113,8 +151,8 @@ TEST_F(scoped_domains, connect_to_parent)
 		/* Waits for the server. */
 		ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
 
-		err = connect(stream_client, &self->stream_address.unix_addr,
-			      self->stream_address.unix_addr_len);
+		err = connect(stream_client, &stream_address->unix_addr,
+			      stream_address->unix_addr_len);
 		if (can_connect_to_parent) {
 			EXPECT_EQ(0, err);
 		} else {
@@ -123,8 +161,8 @@ TEST_F(scoped_domains, connect_to_parent)
 		}
 		EXPECT_EQ(0, close(stream_client));
 
-		err = connect(dgram_client, &self->dgram_address.unix_addr,
-			      self->dgram_address.unix_addr_len);
+		err = connect(dgram_client, &dgram_address->unix_addr,
+			      dgram_address->unix_addr_len);
 		if (can_connect_to_parent) {
 			EXPECT_EQ(0, err);
 		} else {
@@ -137,17 +175,16 @@ TEST_F(scoped_domains, connect_to_parent)
 	}
 	EXPECT_EQ(0, close(pipe_parent[0]));
 	if (variant->domain_parent)
-		create_scoped_domain(_metadata,
-				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+		create_scoped_domain(_metadata, scope);
 
 	stream_server = socket(AF_UNIX, SOCK_STREAM, 0);
 	ASSERT_LE(0, stream_server);
 	dgram_server = socket(AF_UNIX, SOCK_DGRAM, 0);
 	ASSERT_LE(0, dgram_server);
-	ASSERT_EQ(0, bind(stream_server, &self->stream_address.unix_addr,
-			  self->stream_address.unix_addr_len));
-	ASSERT_EQ(0, bind(dgram_server, &self->dgram_address.unix_addr,
-			  self->dgram_address.unix_addr_len));
+	ASSERT_EQ(0, bind(stream_server, &stream_address->unix_addr,
+			  stream_address->unix_addr_len));
+	ASSERT_EQ(0, bind(dgram_server, &dgram_address->unix_addr,
+			  dgram_address->unix_addr_len));
 	ASSERT_EQ(0, listen(stream_server, backlog));
 
 	/* Signals to child that the parent is listening. */
@@ -166,7 +203,11 @@ TEST_F(scoped_domains, connect_to_parent)
  * Test unix_stream_connect() and unix_may_send() for a parent connecting to
  * its child, when they have scoped domain or no domain.
  */
-TEST_F(scoped_domains, connect_to_child)
+static void test_connect_to_child(struct __test_metadata *const _metadata,
+				  FIXTURE_DATA(scoped_domains) * self,
+				  const FIXTURE_VARIANT(scoped_domains) *
+					  variant,
+				  const bool abstract)
 {
 	pid_t child;
 	bool can_connect_to_child;
@@ -174,6 +215,14 @@ TEST_F(scoped_domains, connect_to_child)
 	int pipe_child[2], pipe_parent[2];
 	char buf;
 	int stream_client, dgram_client;
+	const __u16 scope = abstract ? LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET :
+				       LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET;
+	const struct service_fixture *stream_address =
+		abstract ? &self->stream_address_abstract :
+			   &self->stream_address_pathname;
+	const struct service_fixture *dgram_address =
+		abstract ? &self->dgram_address_abstract :
+			   &self->dgram_address_pathname;
 
 	/*
 	 * can_connect_to_child is true if a parent process can connect to its
@@ -185,8 +234,7 @@ TEST_F(scoped_domains, connect_to_child)
 	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
 	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
 	if (variant->domain_both) {
-		create_scoped_domain(_metadata,
-				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+		create_scoped_domain(_metadata, scope);
 		if (!__test_passed(_metadata))
 			return;
 	}
@@ -199,8 +247,7 @@ TEST_F(scoped_domains, connect_to_child)
 		EXPECT_EQ(0, close(pipe_parent[1]));
 		EXPECT_EQ(0, close(pipe_child[0]));
 		if (variant->domain_child)
-			create_scoped_domain(
-				_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+			create_scoped_domain(_metadata, scope);
 
 		/* Waits for the parent to be in a domain, if any. */
 		ASSERT_EQ(1, read(pipe_parent[0], &buf, 1));
@@ -209,11 +256,10 @@ TEST_F(scoped_domains, connect_to_child)
 		ASSERT_LE(0, stream_server);
 		dgram_server = socket(AF_UNIX, SOCK_DGRAM, 0);
 		ASSERT_LE(0, dgram_server);
-		ASSERT_EQ(0,
-			  bind(stream_server, &self->stream_address.unix_addr,
-			       self->stream_address.unix_addr_len));
-		ASSERT_EQ(0, bind(dgram_server, &self->dgram_address.unix_addr,
-				  self->dgram_address.unix_addr_len));
+		ASSERT_EQ(0, bind(stream_server, &stream_address->unix_addr,
+				  stream_address->unix_addr_len));
+		ASSERT_EQ(0, bind(dgram_server, &dgram_address->unix_addr,
+				  dgram_address->unix_addr_len));
 		ASSERT_EQ(0, listen(stream_server, backlog));
 
 		/* Signals to the parent that child is listening. */
@@ -230,8 +276,7 @@ TEST_F(scoped_domains, connect_to_child)
 	EXPECT_EQ(0, close(pipe_parent[0]));
 
 	if (variant->domain_parent)
-		create_scoped_domain(_metadata,
-				     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+		create_scoped_domain(_metadata, scope);
 
 	/* Signals that the parent is in a domain, if any. */
 	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
@@ -243,11 +288,11 @@ TEST_F(scoped_domains, connect_to_child)
 
 	/* Waits for the child to listen */
 	ASSERT_EQ(1, read(pipe_child[0], &buf, 1));
-	err_stream = connect(stream_client, &self->stream_address.unix_addr,
-			     self->stream_address.unix_addr_len);
+	err_stream = connect(stream_client, &stream_address->unix_addr,
+			     stream_address->unix_addr_len);
 	errno_stream = errno;
-	err_dgram = connect(dgram_client, &self->dgram_address.unix_addr,
-			    self->dgram_address.unix_addr_len);
+	err_dgram = connect(dgram_client, &dgram_address->unix_addr,
+			    dgram_address->unix_addr_len);
 	errno_dgram = errno;
 	if (can_connect_to_child) {
 		EXPECT_EQ(0, err_stream);
@@ -268,19 +313,79 @@ TEST_F(scoped_domains, connect_to_child)
 		_metadata->exit_code = KSFT_FAIL;
 }
 
+/*
+ * Test unix_stream_connect() and unix_may_send() for a child connecting to its
+ * parent, when they have scoped domain or no domain.
+ */
+TEST_F(scoped_domains, abstract_connect_to_parent)
+{
+	test_connect_to_parent(_metadata, self, variant, true);
+}
+
+/*
+ * Test unix_stream_connect() and unix_may_send() for a parent connecting to
+ * its child, when they have scoped domain or no domain.
+ */
+TEST_F(scoped_domains, abstract_connect_to_child)
+{
+	test_connect_to_child(_metadata, self, variant, true);
+}
+
+/*
+ * Test unix_stream_connect() and unix_may_send() for a child connecting to its
+ * parent with pathname sockets.
+ */
+TEST_F(scoped_domains, pathname_connect_to_parent)
+{
+	test_connect_to_parent(_metadata, self, variant, false);
+}
+
+/*
+ * Test unix_stream_connect() and unix_may_send() for a parent connecting to
+ * its child with pathname sockets.
+ */
+TEST_F(scoped_domains, pathname_connect_to_child)
+{
+	test_connect_to_child(_metadata, self, variant, false);
+}
+
 FIXTURE(scoped_audit)
 {
-	struct service_fixture dgram_address;
+	struct service_fixture dgram_address_abstract, dgram_address_pathname;
 	struct audit_filter audit_filter;
 	int audit_fd;
 };
 
+FIXTURE_VARIANT(scoped_audit)
+{
+	const bool abstract_socket;
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(scoped_audit, abstract_socket)
+{
+	/* clang-format on */
+	.abstract_socket = true,
+};
+
+/* clang-format off */
+FIXTURE_VARIANT_ADD(scoped_audit, pathname_socket)
+{
+	/* clang-format on */
+	.abstract_socket = false,
+};
+
 FIXTURE_SETUP(scoped_audit)
 {
 	disable_caps(_metadata);
 
-	memset(&self->dgram_address, 0, sizeof(self->dgram_address));
-	set_unix_address(&self->dgram_address, 1, true);
+	ASSERT_EQ(0, mkdir(PATHNAME_UNIX_SOCK_DIR, 0700));
+	memset(&self->dgram_address_abstract, 0,
+	       sizeof(self->dgram_address_abstract));
+	memset(&self->dgram_address_pathname, 0,
+	       sizeof(self->dgram_address_pathname));
+	set_unix_address(&self->dgram_address_abstract, 1, true);
+	set_unix_address(&self->dgram_address_pathname, 1, false);
 
 	set_cap(_metadata, CAP_AUDIT_CONTROL);
 	self->audit_fd = audit_init_with_exe_filter(&self->audit_filter);
@@ -291,6 +396,9 @@ FIXTURE_SETUP(scoped_audit)
 FIXTURE_TEARDOWN_PARENT(scoped_audit)
 {
 	EXPECT_EQ(0, audit_cleanup(-1, NULL));
+	EXPECT_EQ(0,
+		  remove_path(self->dgram_address_pathname.unix_addr.sun_path));
+	EXPECT_EQ(0, rmdir(PATHNAME_UNIX_SOCK_DIR));
 }
 
 /* python -c 'print(b"\0selftests-landlock-abstract-unix-".hex().upper())' */
@@ -308,6 +416,22 @@ TEST_F(scoped_audit, connect_to_child)
 	char buf;
 	int dgram_client;
 	struct audit_records records;
+	struct service_fixture *const dgram_address =
+		variant->abstract_socket ? &self->dgram_address_abstract :
+					   &self->dgram_address_pathname;
+	static const char abstract_log_regex[] = REGEX_LANDLOCK_PREFIX
+		" blockers=scope\\.abstract_unix_socket path=" ABSTRACT_SOCKET_PATH_PREFIX
+		"[0-9A-F]\\+$";
+	static const char pathname_log_template[] = REGEX_LANDLOCK_PREFIX
+		" blockers=scope\\.pathname_unix_socket path=\"%s\"$";
+	size_t log_match_remaining =
+		sizeof(abstract_log_regex) + PATH_MAX * 2 + 1;
+	char log_match[log_match_remaining];
+	char *log_match_cursor = log_match;
+
+	/* Make sure log_match_remaining calculation is correct */
+	static_assert(sizeof(pathname_log_template) <
+		      sizeof(abstract_log_regex));
 
 	/* Makes sure there is no superfluous logged records. */
 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
@@ -330,8 +454,8 @@ TEST_F(scoped_audit, connect_to_child)
 
 		dgram_server = socket(AF_UNIX, SOCK_DGRAM, 0);
 		ASSERT_LE(0, dgram_server);
-		ASSERT_EQ(0, bind(dgram_server, &self->dgram_address.unix_addr,
-				  self->dgram_address.unix_addr_len));
+		ASSERT_EQ(0, bind(dgram_server, &dgram_address->unix_addr,
+				  dgram_address->unix_addr_len));
 
 		/* Signals to the parent that child is listening. */
 		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
@@ -345,7 +469,9 @@ TEST_F(scoped_audit, connect_to_child)
 	EXPECT_EQ(0, close(pipe_child[1]));
 	EXPECT_EQ(0, close(pipe_parent[0]));
 
-	create_scoped_domain(_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+	create_scoped_domain(_metadata,
+			     LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
+				     LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET);
 
 	/* Signals that the parent is in a domain, if any. */
 	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
@@ -355,19 +481,58 @@ TEST_F(scoped_audit, connect_to_child)
 
 	/* Waits for the child to listen */
 	ASSERT_EQ(1, read(pipe_child[0], &buf, 1));
-	err_dgram = connect(dgram_client, &self->dgram_address.unix_addr,
-			    self->dgram_address.unix_addr_len);
+	err_dgram = connect(dgram_client, &dgram_address->unix_addr,
+			    dgram_address->unix_addr_len);
 	EXPECT_EQ(-1, err_dgram);
 	EXPECT_EQ(EPERM, errno);
 
-	EXPECT_EQ(
-		0,
-		audit_match_record(
-			self->audit_fd, AUDIT_LANDLOCK_ACCESS,
+	if (variant->abstract_socket) {
+		log_match_cursor = stpncpy(log_match, abstract_log_regex,
+					   log_match_remaining);
+		log_match_remaining =
+			sizeof(log_match) - (log_match_cursor - log_match);
+		ASSERT_NE(0, log_match_remaining);
+	} else {
+		/*
+		 * It is assumed that absolute_path does not contain control
+		 * characters nor spaces, see audit_string_contains_control().
+		 */
+		char *const absolute_path =
+			realpath(dgram_address->unix_addr.sun_path, NULL);
+
+		EXPECT_NE(NULL, absolute_path)
+		{
+			TH_LOG("realpath() failed: %s", strerror(errno));
+			return;
+		}
+
+		log_match_cursor = stpncpy(
+			log_match,
 			REGEX_LANDLOCK_PREFIX
-			" blockers=scope\\.abstract_unix_socket path=" ABSTRACT_SOCKET_PATH_PREFIX
-			"[0-9A-F]\\+$",
-			NULL));
+			" blockers=scope\\.pathname_unix_socket path=\"",
+			log_match_remaining);
+		log_match_remaining =
+			sizeof(log_match) - (log_match_cursor - log_match);
+		ASSERT_NE(0, log_match_remaining);
+		log_match_cursor = regex_escape(absolute_path, log_match_cursor,
+						log_match_remaining);
+		free(absolute_path);
+		if (log_match_cursor < 0) {
+			TH_LOG("regex_escape() failed (buffer too small)");
+			return;
+		}
+		log_match_remaining =
+			sizeof(log_match) - (log_match_cursor - log_match);
+		ASSERT_NE(0, log_match_remaining);
+		log_match_cursor =
+			stpncpy(log_match_cursor, "\"$", log_match_remaining);
+		log_match_remaining =
+			sizeof(log_match) - (log_match_cursor - log_match);
+		ASSERT_NE(0, log_match_remaining);
+	}
+
+	EXPECT_EQ(0, audit_match_record(self->audit_fd, AUDIT_LANDLOCK_ACCESS,
+					log_match, NULL));
 
 	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
 	EXPECT_EQ(0, close(dgram_client));
-- 
2.52.0

^ permalink raw reply related

* [PATCH v3 4/6] selftests/landlock: Support pathname socket path in set_unix_address
From: Tingmao Wang @ 2026-02-03 23:12 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Tingmao Wang, Günther Noack, Demi Marie Obenour, Alyssa Ross,
	Jann Horn, Tahera Fahimi, Justin Suess, linux-security-module
In-Reply-To: <cover.1770160146.git.m@maowtm.org>

To prepare for extending the socket tests to do non-abstract sockets too,
extend set_unix_address() to also be able to populate a non-abstract
socket path under TMP_DIR.  Also use snprintf for good measure.

This also changes existing callers to pass true for the abstract argument.

Signed-off-by: Tingmao Wang <m@maowtm.org>
---
 tools/testing/selftests/landlock/common.h     | 33 +++++++++++++++----
 tools/testing/selftests/landlock/net_test.c   |  2 +-
 .../landlock/scoped_abstract_unix_test.c      | 30 ++++++++---------
 .../selftests/landlock/scoped_signal_test.c   |  2 +-
 4 files changed, 44 insertions(+), 23 deletions(-)

diff --git a/tools/testing/selftests/landlock/common.h b/tools/testing/selftests/landlock/common.h
index 90551650299c..c55c11434e27 100644
--- a/tools/testing/selftests/landlock/common.h
+++ b/tools/testing/selftests/landlock/common.h
@@ -241,13 +241,34 @@ struct service_fixture {
 	};
 };
 
+#define PATHNAME_UNIX_SOCK_DIR TMP_DIR
+
+/**
+ * set_unix_address - Set up srv->unix_addr and srv->unix_addr_len.
+ * @srv: Service fixture containing the socket address to initialize
+ * @index: Index to include in socket names
+ * @abstract: If true, creates an abstract socket address (sun_path[0] ==
+ *     '\0') with the given name.  If false, creates a pathname socket
+ *     address with the given path.
+ */
 static void __maybe_unused set_unix_address(struct service_fixture *const srv,
-					    const unsigned short index)
+					    const unsigned short index,
+					    const bool abstract)
 {
 	srv->unix_addr.sun_family = AF_UNIX;
-	sprintf(srv->unix_addr.sun_path,
-		"_selftests-landlock-abstract-unix-tid%d-index%d", sys_gettid(),
-		index);
-	srv->unix_addr_len = SUN_LEN(&srv->unix_addr);
-	srv->unix_addr.sun_path[0] = '\0';
+	if (abstract) {
+		snprintf(srv->unix_addr.sun_path,
+			 sizeof(srv->unix_addr.sun_path),
+			 "_selftests-landlock-abstract-unix-tid%d-index%d",
+			 sys_gettid(), index);
+		srv->unix_addr_len = SUN_LEN(&srv->unix_addr);
+		srv->unix_addr.sun_path[0] = '\0';
+	} else {
+		snprintf(srv->unix_addr.sun_path,
+			 sizeof(srv->unix_addr.sun_path),
+			 PATHNAME_UNIX_SOCK_DIR
+			 "/pathname-unix-tid%d-index%d.sock",
+			 sys_gettid(), index);
+		srv->unix_addr_len = sizeof(srv->unix_addr);
+	}
 }
diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/selftests/landlock/net_test.c
index b34b139b3f89..fd3fe51ce92f 100644
--- a/tools/testing/selftests/landlock/net_test.c
+++ b/tools/testing/selftests/landlock/net_test.c
@@ -69,7 +69,7 @@ static int set_service(struct service_fixture *const srv,
 		return 0;
 
 	case AF_UNIX:
-		set_unix_address(srv, index);
+		set_unix_address(srv, index, true);
 		return 0;
 	}
 	return 1;
diff --git a/tools/testing/selftests/landlock/scoped_abstract_unix_test.c b/tools/testing/selftests/landlock/scoped_abstract_unix_test.c
index 72f97648d4a7..4a790e2d387d 100644
--- a/tools/testing/selftests/landlock/scoped_abstract_unix_test.c
+++ b/tools/testing/selftests/landlock/scoped_abstract_unix_test.c
@@ -58,8 +58,8 @@ FIXTURE_SETUP(scoped_domains)
 
 	memset(&self->stream_address, 0, sizeof(self->stream_address));
 	memset(&self->dgram_address, 0, sizeof(self->dgram_address));
-	set_unix_address(&self->stream_address, 0);
-	set_unix_address(&self->dgram_address, 1);
+	set_unix_address(&self->stream_address, 0, true);
+	set_unix_address(&self->dgram_address, 1, true);
 }
 
 FIXTURE_TEARDOWN(scoped_domains)
@@ -280,7 +280,7 @@ FIXTURE_SETUP(scoped_audit)
 	disable_caps(_metadata);
 
 	memset(&self->dgram_address, 0, sizeof(self->dgram_address));
-	set_unix_address(&self->dgram_address, 1);
+	set_unix_address(&self->dgram_address, 1, true);
 
 	set_cap(_metadata, CAP_AUDIT_CONTROL);
 	self->audit_fd = audit_init_with_exe_filter(&self->audit_filter);
@@ -392,16 +392,16 @@ FIXTURE_SETUP(scoped_vs_unscoped)
 
 	memset(&self->parent_stream_address, 0,
 	       sizeof(self->parent_stream_address));
-	set_unix_address(&self->parent_stream_address, 0);
+	set_unix_address(&self->parent_stream_address, 0, true);
 	memset(&self->parent_dgram_address, 0,
 	       sizeof(self->parent_dgram_address));
-	set_unix_address(&self->parent_dgram_address, 1);
+	set_unix_address(&self->parent_dgram_address, 1, true);
 	memset(&self->child_stream_address, 0,
 	       sizeof(self->child_stream_address));
-	set_unix_address(&self->child_stream_address, 2);
+	set_unix_address(&self->child_stream_address, 2, true);
 	memset(&self->child_dgram_address, 0,
 	       sizeof(self->child_dgram_address));
-	set_unix_address(&self->child_dgram_address, 3);
+	set_unix_address(&self->child_dgram_address, 3, true);
 }
 
 FIXTURE_TEARDOWN(scoped_vs_unscoped)
@@ -622,9 +622,9 @@ FIXTURE_SETUP(outside_socket)
 	drop_caps(_metadata);
 
 	memset(&self->transit_address, 0, sizeof(self->transit_address));
-	set_unix_address(&self->transit_address, 0);
+	set_unix_address(&self->transit_address, 0, true);
 	memset(&self->address, 0, sizeof(self->address));
-	set_unix_address(&self->address, 1);
+	set_unix_address(&self->address, 1, true);
 }
 
 FIXTURE_TEARDOWN(outside_socket)
@@ -802,9 +802,9 @@ TEST_F(various_address_sockets, scoped_pathname_sockets)
 
 	/* Abstract address. */
 	memset(&stream_abstract_addr, 0, sizeof(stream_abstract_addr));
-	set_unix_address(&stream_abstract_addr, 0);
+	set_unix_address(&stream_abstract_addr, 0, true);
 	memset(&dgram_abstract_addr, 0, sizeof(dgram_abstract_addr));
-	set_unix_address(&dgram_abstract_addr, 1);
+	set_unix_address(&dgram_abstract_addr, 1, true);
 
 	/* Unnamed address for datagram socket. */
 	ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_DGRAM, 0, unnamed_sockets));
@@ -990,9 +990,9 @@ TEST(datagram_sockets)
 
 	drop_caps(_metadata);
 	memset(&connected_addr, 0, sizeof(connected_addr));
-	set_unix_address(&connected_addr, 0);
+	set_unix_address(&connected_addr, 0, true);
 	memset(&non_connected_addr, 0, sizeof(non_connected_addr));
-	set_unix_address(&non_connected_addr, 1);
+	set_unix_address(&non_connected_addr, 1, true);
 
 	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
 	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
@@ -1090,9 +1090,9 @@ TEST(self_connect)
 
 	drop_caps(_metadata);
 	memset(&connected_addr, 0, sizeof(connected_addr));
-	set_unix_address(&connected_addr, 0);
+	set_unix_address(&connected_addr, 0, true);
 	memset(&non_connected_addr, 0, sizeof(non_connected_addr));
-	set_unix_address(&non_connected_addr, 1);
+	set_unix_address(&non_connected_addr, 1, true);
 
 	connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
 	non_connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0);
diff --git a/tools/testing/selftests/landlock/scoped_signal_test.c b/tools/testing/selftests/landlock/scoped_signal_test.c
index d8bf33417619..8d1e1dc89c43 100644
--- a/tools/testing/selftests/landlock/scoped_signal_test.c
+++ b/tools/testing/selftests/landlock/scoped_signal_test.c
@@ -463,7 +463,7 @@ TEST_F(fown, sigurg_socket)
 	pid_t child;
 
 	memset(&server_address, 0, sizeof(server_address));
-	set_unix_address(&server_address, 0);
+	set_unix_address(&server_address, 0, true);
 
 	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
 	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
-- 
2.52.0


^ permalink raw reply related

* [PATCH v3 3/6] samples/landlock: Support LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET
From: Tingmao Wang @ 2026-02-03 23:12 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Tingmao Wang, Günther Noack, Demi Marie Obenour, Alyssa Ross,
	Jann Horn, Tahera Fahimi, Justin Suess, linux-security-module
In-Reply-To: <cover.1770160146.git.m@maowtm.org>

Add support for this new scope bit to the sandboxer via LL_SCOPED=u

Signed-off-by: Tingmao Wang <m@maowtm.org>
---

Changes in v3:
- Add message

 samples/landlock/sandboxer.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c
index e7af02f98208..2de14e1c787d 100644
--- a/samples/landlock/sandboxer.c
+++ b/samples/landlock/sandboxer.c
@@ -234,14 +234,16 @@ static bool check_ruleset_scope(const char *const env_var,
 	bool error = false;
 	bool abstract_scoping = false;
 	bool signal_scoping = false;
+	bool named_scoping = false;
 
 	/* Scoping is not supported by Landlock ABI */
 	if (!(ruleset_attr->scoped &
-	      (LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | LANDLOCK_SCOPE_SIGNAL)))
+	      (LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | LANDLOCK_SCOPE_SIGNAL |
+	       LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET)))
 		goto out_unset;
 
 	env_type_scope = getenv(env_var);
-	/* Scoping is not supported by the user */
+	/* Scoping is not requested by the user */
 	if (!env_type_scope || strcmp("", env_type_scope) == 0)
 		goto out_unset;
 
@@ -254,6 +256,9 @@ static bool check_ruleset_scope(const char *const env_var,
 		} else if (strcmp("s", ipc_scoping_name) == 0 &&
 			   !signal_scoping) {
 			signal_scoping = true;
+		} else if (strcmp("u", ipc_scoping_name) == 0 &&
+			   !named_scoping) {
+			named_scoping = true;
 		} else {
 			fprintf(stderr, "Unknown or duplicate scope \"%s\"\n",
 				ipc_scoping_name);
@@ -270,6 +275,8 @@ static bool check_ruleset_scope(const char *const env_var,
 		ruleset_attr->scoped &= ~LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET;
 	if (!signal_scoping)
 		ruleset_attr->scoped &= ~LANDLOCK_SCOPE_SIGNAL;
+	if (!named_scoping)
+		ruleset_attr->scoped &= ~LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET;
 
 	unsetenv(env_var);
 	return error;
@@ -299,7 +306,7 @@ static bool check_ruleset_scope(const char *const env_var,
 
 /* clang-format on */
 
-#define LANDLOCK_ABI_LAST 7
+#define LANDLOCK_ABI_LAST 8
 
 #define XSTR(s) #s
 #define STR(s) XSTR(s)
@@ -325,6 +332,7 @@ static const char help[] =
 	"* " ENV_SCOPED_NAME ": actions denied on the outside of the landlock domain\n"
 	"  - \"a\" to restrict opening abstract unix sockets\n"
 	"  - \"s\" to restrict sending signals\n"
+	"  - \"u\" to restrict opening pathname (non-abstract) unix sockets\n"
 	"\n"
 	"A sandboxer should not log denied access requests to avoid spamming logs, "
 	"but to test audit we can set " ENV_FORCE_LOG_NAME "=1\n"
@@ -334,7 +342,7 @@ static const char help[] =
 	ENV_FS_RW_NAME "=\"/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp\" "
 	ENV_TCP_BIND_NAME "=\"9418\" "
 	ENV_TCP_CONNECT_NAME "=\"80:443\" "
-	ENV_SCOPED_NAME "=\"a:s\" "
+	ENV_SCOPED_NAME "=\"a:s:u\" "
 	"%1$s bash -i\n"
 	"\n"
 	"This sandboxer can use Landlock features up to ABI version "
@@ -356,7 +364,8 @@ int main(const int argc, char *const argv[], char *const *const envp)
 		.handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP |
 				      LANDLOCK_ACCESS_NET_CONNECT_TCP,
 		.scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
-			  LANDLOCK_SCOPE_SIGNAL,
+			  LANDLOCK_SCOPE_SIGNAL |
+			  LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET,
 	};
 	int supported_restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON;
 	int set_restrict_flags = 0;
@@ -436,6 +445,10 @@ int main(const int argc, char *const argv[], char *const *const envp)
 		/* Removes LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON for ABI < 7 */
 		supported_restrict_flags &=
 			~LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON;
+		__attribute__((fallthrough));
+	case 7:
+		/* Removes LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET for ABI < 8 */
+		ruleset_attr.scoped &= ~LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET;
 
 		/* Must be printed for any ABI < LANDLOCK_ABI_LAST. */
 		fprintf(stderr,
-- 
2.52.0

^ permalink raw reply related

* [PATCH v3 2/6] landlock: Implement LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET
From: Tingmao Wang @ 2026-02-03 23:12 UTC (permalink / raw)
  To: Mickaël Salaün
  Cc: Tingmao Wang, Günther Noack, Demi Marie Obenour, Alyssa Ross,
	Jann Horn, Tahera Fahimi, Justin Suess, linux-security-module
In-Reply-To: <cover.1770160146.git.m@maowtm.org>

Extend the existing abstract UNIX socket scoping to pathname sockets as
well.  Basically all of the logic is reused between the two types, just
that pathname sockets scoping are controlled by another bit, and has its
own audit request type (since the current one is named
"abstract_unix_socket").

Closes: https://github.com/landlock-lsm/linux/issues/51
Signed-off-by: Tingmao Wang <m@maowtm.org>
---

Changes in v3:
- missing dot in comment
- More accurate comment on check_socket_access
- Unix -> UNIX

Changes in v2:
- Factor out common code in hook_unix_stream_connect and
  hook_unix_may_send into check_socket_access(), and inline
  is_abstract_socket().

 security/landlock/audit.c |   4 ++
 security/landlock/audit.h |   1 +
 security/landlock/task.c  | 113 ++++++++++++++++++++++----------------
 3 files changed, 71 insertions(+), 47 deletions(-)

diff --git a/security/landlock/audit.c b/security/landlock/audit.c
index 650bd7f5cb6b..97f0f503a836 100644
--- a/security/landlock/audit.c
+++ b/security/landlock/audit.c
@@ -75,6 +75,10 @@ get_blocker(const enum landlock_request_type type,
 		WARN_ON_ONCE(access_bit != -1);
 		return "scope.abstract_unix_socket";
 
+	case LANDLOCK_REQUEST_SCOPE_PATHNAME_UNIX_SOCKET:
+		WARN_ON_ONCE(access_bit != -1);
+		return "scope.pathname_unix_socket";
+
 	case LANDLOCK_REQUEST_SCOPE_SIGNAL:
 		WARN_ON_ONCE(access_bit != -1);
 		return "scope.signal";
diff --git a/security/landlock/audit.h b/security/landlock/audit.h
index 104472060ef5..0e40fed17f21 100644
--- a/security/landlock/audit.h
+++ b/security/landlock/audit.h
@@ -21,6 +21,7 @@ enum landlock_request_type {
 	LANDLOCK_REQUEST_NET_ACCESS,
 	LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
 	LANDLOCK_REQUEST_SCOPE_SIGNAL,
+	LANDLOCK_REQUEST_SCOPE_PATHNAME_UNIX_SOCKET,
 };
 
 /*
diff --git a/security/landlock/task.c b/security/landlock/task.c
index 833bc0cfe5c9..973de1efc08a 100644
--- a/security/landlock/task.c
+++ b/security/landlock/task.c
@@ -232,35 +232,85 @@ static bool domain_is_scoped(const struct landlock_ruleset *const client,
 	return false;
 }
 
+/**
+ * sock_is_scoped - Check if socket connect or send should be restricted
+ *    based on scope controls.
+ *
+ * @other: The server socket.
+ * @domain: The client domain.
+ * @scope: The relevant scope bit to check (i.e. pathname or abstract).
+ *
+ * Returns: True if connect should be restricted, false otherwise.
+ */
 static bool sock_is_scoped(struct sock *const other,
-			   const struct landlock_ruleset *const domain)
+			   const struct landlock_ruleset *const domain,
+			   access_mask_t scope)
 {
 	const struct landlock_ruleset *dom_other;
 
 	/* The credentials will not change. */
 	lockdep_assert_held(&unix_sk(other)->lock);
 	dom_other = landlock_cred(other->sk_socket->file->f_cred)->domain;
-	return domain_is_scoped(domain, dom_other,
-				LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
+	return domain_is_scoped(domain, dom_other, scope);
 }
 
-static bool is_abstract_socket(struct sock *const sock)
+/*
+ * Allow us to quickly test if the current domain scopes any form of
+ * socket.
+ */
+static const struct access_masks unix_scope = {
+	.scope = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
+		 LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET,
+};
+
+/*
+ * UNIX sockets can have three types of addresses: pathname (a filesystem path),
+ * unnamed (not bound to an address), and abstract (sun_path[0] is '\0').
+ * Unnamed sockets include those created with socketpair() and unbound sockets.
+ * We do not restrict unnamed sockets since they cannot be used to reach a
+ * new peer.
+ */
+static int
+check_socket_access(struct sock *const other,
+		    const struct landlock_cred_security *const subject,
+		    const size_t handle_layer)
 {
-	struct unix_address *addr = unix_sk(sock)->addr;
+	const struct unix_address *addr = unix_sk(other)->addr;
+	access_mask_t scope;
+	enum landlock_request_type request_type;
 
+	/* Unnamed sockets are not restricted. */
 	if (!addr)
-		return false;
+		return 0;
 
+	/*
+	 * Abstract and pathname UNIX sockets have separate scope and audit
+	 * request type.
+	 */
 	if (addr->len >= offsetof(struct sockaddr_un, sun_path) + 1 &&
-	    addr->name->sun_path[0] == '\0')
-		return true;
+	    addr->name->sun_path[0] == '\0') {
+		scope = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET;
+		request_type = LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET;
+	} else {
+		scope = LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET;
+		request_type = LANDLOCK_REQUEST_SCOPE_PATHNAME_UNIX_SOCKET;
+	}
 
-	return false;
-}
+	if (!sock_is_scoped(other, subject->domain, scope))
+		return 0;
 
-static const struct access_masks unix_scope = {
-	.scope = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET,
-};
+	landlock_log_denial(subject, &(struct landlock_request) {
+		.type = request_type,
+		.audit = {
+			.type = LSM_AUDIT_DATA_NET,
+			.u.net = &(struct lsm_network_audit) {
+				.sk = other,
+			},
+		},
+		.layer_plus_one = handle_layer + 1,
+	});
+	return -EPERM;
+}
 
 static int hook_unix_stream_connect(struct sock *const sock,
 				    struct sock *const other,
@@ -275,23 +325,7 @@ static int hook_unix_stream_connect(struct sock *const sock,
 	if (!subject)
 		return 0;
 
-	if (!is_abstract_socket(other))
-		return 0;
-
-	if (!sock_is_scoped(other, subject->domain))
-		return 0;
-
-	landlock_log_denial(subject, &(struct landlock_request) {
-		.type = LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
-		.audit = {
-			.type = LSM_AUDIT_DATA_NET,
-			.u.net = &(struct lsm_network_audit) {
-				.sk = other,
-			},
-		},
-		.layer_plus_one = handle_layer + 1,
-	});
-	return -EPERM;
+	return check_socket_access(other, subject, handle_layer);
 }
 
 static int hook_unix_may_send(struct socket *const sock,
@@ -302,6 +336,7 @@ static int hook_unix_may_send(struct socket *const sock,
 		landlock_get_applicable_subject(current_cred(), unix_scope,
 						&handle_layer);
 
+	/* Quick return for non-landlocked tasks. */
 	if (!subject)
 		return 0;
 
@@ -312,23 +347,7 @@ static int hook_unix_may_send(struct socket *const sock,
 	if (unix_peer(sock->sk) == other->sk)
 		return 0;
 
-	if (!is_abstract_socket(other->sk))
-		return 0;
-
-	if (!sock_is_scoped(other->sk, subject->domain))
-		return 0;
-
-	landlock_log_denial(subject, &(struct landlock_request) {
-		.type = LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
-		.audit = {
-			.type = LSM_AUDIT_DATA_NET,
-			.u.net = &(struct lsm_network_audit) {
-				.sk = other->sk,
-			},
-		},
-		.layer_plus_one = handle_layer + 1,
-	});
-	return -EPERM;
+	return check_socket_access(other->sk, subject, handle_layer);
 }
 
 static const struct access_masks signal_scope = {
-- 
2.52.0

^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox