Patch "net/rose: fix races in rose_kill_by_device()" has been added to the 6.1-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    net/rose: fix races in rose_kill_by_device()

to the 6.1-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     net-rose-fix-races-in-rose_kill_by_device.patch
and it can be found in the queue-6.1 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit a10826494b4bcf12f6b5507e7a7d45aeab16fc16
Author: Eric Dumazet <edumazet@xxxxxxxxxx>
Date:   Thu Dec 14 15:27:47 2023 +0000

    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@xxxxxxxxxxxxxxxx>
    Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Cc: Bernard Pidoux <f6bvp@xxxxxxx>
    Signed-off-by: David S. Miller <davem@xxxxxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/rose/af_rose.c b/net/rose/af_rose.c
index 674937284b8d2..29b74a569e0b0 100644
--- a/net/rose/af_rose.c
+++ b/net/rose/af_rose.c
@@ -182,21 +182,47 @@ void rose_kill_by_neigh(struct rose_neigh *neigh)
  */
 static void rose_kill_by_device(struct net_device *dev)
 {
-	struct sock *s;
+	struct sock *sk, *array[16];
+	struct rose_sock *rose;
+	bool rescan;
+	int i, cnt;
 
+start:
+	rescan = false;
+	cnt = 0;
 	spin_lock_bh(&rose_list_lock);
-	sk_for_each(s, &rose_list) {
-		struct rose_sock *rose = rose_sk(s);
+	sk_for_each(sk, &rose_list) {
+		rose = rose_sk(sk);
+		if (rose->device == dev) {
+			if (cnt == ARRAY_SIZE(array)) {
+				rescan = true;
+				break;
+			}
+			sock_hold(sk);
+			array[cnt++] = sk;
+		}
+	}
+	spin_unlock_bh(&rose_list_lock);
 
+	for (i = 0; i < cnt; i++) {
+		sk = array[cnt];
+		rose = rose_sk(sk);
+		lock_sock(sk);
+		spin_lock_bh(&rose_list_lock);
 		if (rose->device == dev) {
-			rose_disconnect(s, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
+			rose_disconnect(sk, ENETUNREACH, ROSE_OUT_OF_ORDER, 0);
 			if (rose->neighbour)
 				rose->neighbour->use--;
 			netdev_put(rose->device, &rose->dev_tracker);
 			rose->device = NULL;
 		}
+		spin_unlock_bh(&rose_list_lock);
+		release_sock(sk);
+		sock_put(sk);
+		cond_resched();
 	}
-	spin_unlock_bh(&rose_list_lock);
+	if (rescan)
+		goto start;
 }
 
 /*
@@ -656,7 +682,10 @@ static int rose_release(struct socket *sock)
 		break;
 	}
 
+	spin_lock_bh(&rose_list_lock);
 	netdev_put(rose->device, &rose->dev_tracker);
+	rose->device = NULL;
+	spin_unlock_bh(&rose_list_lock);
 	sock->sk = NULL;
 	release_sock(sk);
 	sock_put(sk);




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux