net/rose: fix races in rose_kill_by_device()
[ Upstream commit
64b8bc7d5f1434c636a40bdcfcd42b278d1714be ]
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:
1da177e4c3f4 ("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>