linux/net/rose
Eric Dumazet ffced26692 net/rose: fix races in rose_kill_by_device()
[ Upstream commit 64b8bc7d5f ]

syzbot found an interesting netdev refcounting issue in
net/rose/af_rose.c, thanks to CONFIG_NET_DEV_REFCNT_TRACKER=y [1]

Problem is that rose_kill_by_device() can change rose->device
while other threads do not expect the pointer to be changed.

We have to first collect sockets in a temporary array,
then perform the changes while holding the socket
lock and rose_list_lock spinlock (in this order)

Change rose_release() to also acquire rose_list_lock
before releasing the netdev refcount.

[1]

[ 1185.055088][ T7889] ref_tracker: reference already released.
[ 1185.061476][ T7889] ref_tracker: allocated in:
[ 1185.066081][ T7889]  rose_bind+0x4ab/0xd10
[ 1185.070446][ T7889]  __sys_bind+0x1ec/0x220
[ 1185.074818][ T7889]  __x64_sys_bind+0x72/0xb0
[ 1185.079356][ T7889]  do_syscall_64+0x40/0x110
[ 1185.083897][ T7889]  entry_SYSCALL_64_after_hwframe+0x63/0x6b
[ 1185.089835][ T7889] ref_tracker: freed in:
[ 1185.094088][ T7889]  rose_release+0x2f5/0x570
[ 1185.098629][ T7889]  __sock_release+0xae/0x260
[ 1185.103262][ T7889]  sock_close+0x1c/0x20
[ 1185.107453][ T7889]  __fput+0x270/0xbb0
[ 1185.111467][ T7889]  task_work_run+0x14d/0x240
[ 1185.116085][ T7889]  get_signal+0x106f/0x2790
[ 1185.120622][ T7889]  arch_do_signal_or_restart+0x90/0x7f0
[ 1185.126205][ T7889]  exit_to_user_mode_prepare+0x121/0x240
[ 1185.131846][ T7889]  syscall_exit_to_user_mode+0x1e/0x60
[ 1185.137293][ T7889]  do_syscall_64+0x4d/0x110
[ 1185.141783][ T7889]  entry_SYSCALL_64_after_hwframe+0x63/0x6b
[ 1185.148085][ T7889] ------------[ cut here ]------------

WARNING: CPU: 1 PID: 7889 at lib/ref_tracker.c:255 ref_tracker_free+0x61a/0x810 lib/ref_tracker.c:255
Modules linked in:
CPU: 1 PID: 7889 Comm: syz-executor.2 Not tainted 6.7.0-rc4-syzkaller-00162-g65c95f78917e #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 11/10/2023
RIP: 0010:ref_tracker_free+0x61a/0x810 lib/ref_tracker.c:255
Code: 00 44 8b 6b 18 31 ff 44 89 ee e8 21 62 f5 fc 45 85 ed 0f 85 a6 00 00 00 e8 a3 66 f5 fc 48 8b 34 24 48 89 ef e8 27 5f f1 05 90 <0f> 0b 90 bb ea ff ff ff e9 52 fd ff ff e8 84 66 f5 fc 4c 8d 6d 44
RSP: 0018:ffffc90004917850 EFLAGS: 00010202
RAX: 0000000000000201 RBX: ffff88802618f4c0 RCX: 0000000000000000
RDX: 0000000000000202 RSI: ffffffff8accb920 RDI: 0000000000000001
RBP: ffff8880269ea5b8 R08: 0000000000000001 R09: fffffbfff23e35f6
R10: ffffffff91f1afb7 R11: 0000000000000001 R12: 1ffff92000922f0c
R13: 0000000005a2039b R14: ffff88802618f4d8 R15: 00000000ffffffff
FS: 00007f0a720ef6c0(0000) GS:ffff8880b9900000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f43a819d988 CR3: 0000000076c64000 CR4: 00000000003506f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
netdev_tracker_free include/linux/netdevice.h:4127 [inline]
netdev_put include/linux/netdevice.h:4144 [inline]
netdev_put include/linux/netdevice.h:4140 [inline]
rose_kill_by_device net/rose/af_rose.c:195 [inline]
rose_device_event+0x25d/0x330 net/rose/af_rose.c:218
notifier_call_chain+0xb6/0x3b0 kernel/notifier.c:93
call_netdevice_notifiers_info+0xbe/0x130 net/core/dev.c:1967
call_netdevice_notifiers_extack net/core/dev.c:2005 [inline]
call_netdevice_notifiers net/core/dev.c:2019 [inline]
__dev_notify_flags+0x1f5/0x2e0 net/core/dev.c:8646
dev_change_flags+0x122/0x170 net/core/dev.c:8682
dev_ifsioc+0x9ad/0x1090 net/core/dev_ioctl.c:529
dev_ioctl+0x224/0x1090 net/core/dev_ioctl.c:786
sock_do_ioctl+0x198/0x270 net/socket.c:1234
sock_ioctl+0x22e/0x6b0 net/socket.c:1339
vfs_ioctl fs/ioctl.c:51 [inline]
__do_sys_ioctl fs/ioctl.c:871 [inline]
__se_sys_ioctl fs/ioctl.c:857 [inline]
__x64_sys_ioctl+0x18f/0x210 fs/ioctl.c:857
do_syscall_x64 arch/x86/entry/common.c:52 [inline]
do_syscall_64+0x40/0x110 arch/x86/entry/common.c:83
entry_SYSCALL_64_after_hwframe+0x63/0x6b
RIP: 0033:0x7f0a7147cba9
Code: 28 00 00 00 75 05 48 83 c4 28 c3 e8 e1 20 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 b0 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f0a720ef0c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f0a7159bf80 RCX: 00007f0a7147cba9
RDX: 0000000020000040 RSI: 0000000000008914 RDI: 0000000000000004
RBP: 00007f0a714c847a R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 000000000000000b R14: 00007f0a7159bf80 R15: 00007ffc8bb3a5f8
</TASK>

Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Bernard Pidoux <f6bvp@free.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
2024-01-01 12:42:31 +00:00
..
af_rose.c net/rose: fix races in rose_kill_by_device() 2024-01-01 12:42:31 +00:00
Makefile treewide: Add SPDX license identifier - Makefile/Kconfig 2019-05-21 10:50:46 +02:00
rose_dev.c rose: constify dev_addr passing 2021-10-13 09:40:45 -07:00
rose_in.c net: Don't include filter.h from net/sock.h 2021-12-29 08:48:14 -08:00
rose_link.c rose: Fix NULL pointer dereference in rose_send_frame() 2022-11-02 11:57:30 +00:00
rose_loopback.c rose: check NULL rose_loopback_neigh->loopback 2022-08-22 14:24:54 +01:00
rose_out.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
rose_route.c net: rose: fix netdev reference changes 2022-08-01 11:59:23 -07:00
rose_subr.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00
rose_timer.c net: rose: fix UAF bugs caused by timer handler 2022-06-30 11:07:30 +02:00
sysctl_net_rose.c treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 152 2019-05-30 11:26:32 -07:00