Patch "net: rose: fix timer races against user threads" 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 timer races against user threads

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-timer-races-against-user-threads.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 a8893cfbe73fda6d9eceb84d651818ef14df8e8a
Author: Eric Dumazet <edumazet@xxxxxxxxxx>
Date:   Wed Jan 22 18:02:44 2025 +0000

    net: rose: fix timer races against user threads
    
    [ Upstream commit 5de7665e0a0746b5ad7943554b34db8f8614a196 ]
    
    Rose timers only acquire the socket spinlock, without
    checking if the socket is owned by one user thread.
    
    Add a check and rearm the timers if needed.
    
    BUG: KASAN: slab-use-after-free in rose_timer_expiry+0x31d/0x360 net/rose/rose_timer.c:174
    Read of size 2 at addr ffff88802f09b82a by task swapper/0/0
    
    CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 6.13.0-rc5-syzkaller-00172-gd1bf27c4e176 #0
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024
    Call Trace:
     <IRQ>
      __dump_stack lib/dump_stack.c:94 [inline]
      dump_stack_lvl+0x241/0x360 lib/dump_stack.c:120
      print_address_description mm/kasan/report.c:378 [inline]
      print_report+0x169/0x550 mm/kasan/report.c:489
      kasan_report+0x143/0x180 mm/kasan/report.c:602
      rose_timer_expiry+0x31d/0x360 net/rose/rose_timer.c:174
      call_timer_fn+0x187/0x650 kernel/time/timer.c:1793
      expire_timers kernel/time/timer.c:1844 [inline]
      __run_timers kernel/time/timer.c:2418 [inline]
      __run_timer_base+0x66a/0x8e0 kernel/time/timer.c:2430
      run_timer_base kernel/time/timer.c:2439 [inline]
      run_timer_softirq+0xb7/0x170 kernel/time/timer.c:2449
      handle_softirqs+0x2d4/0x9b0 kernel/softirq.c:561
      __do_softirq kernel/softirq.c:595 [inline]
      invoke_softirq kernel/softirq.c:435 [inline]
      __irq_exit_rcu+0xf7/0x220 kernel/softirq.c:662
      irq_exit_rcu+0x9/0x30 kernel/softirq.c:678
      instr_sysvec_apic_timer_interrupt arch/x86/kernel/apic/apic.c:1049 [inline]
      sysvec_apic_timer_interrupt+0xa6/0xc0 arch/x86/kernel/apic/apic.c:1049
     </IRQ>
    
    Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
    Reported-by: syzbot <syzkaller@xxxxxxxxxxxxxxxx>
    Signed-off-by: Eric Dumazet <edumazet@xxxxxxxxxx>
    Link: https://patch.msgid.link/20250122180244.1861468-1-edumazet@xxxxxxxxxx
    Signed-off-by: Jakub Kicinski <kuba@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/net/rose/rose_timer.c b/net/rose/rose_timer.c
index f06ddbed3fed6..1525773e94aa1 100644
--- a/net/rose/rose_timer.c
+++ b/net/rose/rose_timer.c
@@ -122,6 +122,10 @@ static void rose_heartbeat_expiry(struct timer_list *t)
 	struct rose_sock *rose = rose_sk(sk);
 
 	bh_lock_sock(sk);
+	if (sock_owned_by_user(sk)) {
+		sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ/20);
+		goto out;
+	}
 	switch (rose->state) {
 	case ROSE_STATE_0:
 		/* Magic here: If we listen() and a new link dies before it
@@ -152,6 +156,7 @@ static void rose_heartbeat_expiry(struct timer_list *t)
 	}
 
 	rose_start_heartbeat(sk);
+out:
 	bh_unlock_sock(sk);
 	sock_put(sk);
 }
@@ -162,6 +167,10 @@ static void rose_timer_expiry(struct timer_list *t)
 	struct sock *sk = &rose->sock;
 
 	bh_lock_sock(sk);
+	if (sock_owned_by_user(sk)) {
+		sk_reset_timer(sk, &rose->timer, jiffies + HZ/20);
+		goto out;
+	}
 	switch (rose->state) {
 	case ROSE_STATE_1:	/* T1 */
 	case ROSE_STATE_4:	/* T2 */
@@ -182,6 +191,7 @@ static void rose_timer_expiry(struct timer_list *t)
 		}
 		break;
 	}
+out:
 	bh_unlock_sock(sk);
 	sock_put(sk);
 }
@@ -192,6 +202,10 @@ static void rose_idletimer_expiry(struct timer_list *t)
 	struct sock *sk = &rose->sock;
 
 	bh_lock_sock(sk);
+	if (sock_owned_by_user(sk)) {
+		sk_reset_timer(sk, &rose->idletimer, jiffies + HZ/20);
+		goto out;
+	}
 	rose_clear_queues(sk);
 
 	rose_write_internal(sk, ROSE_CLEAR_REQUEST);
@@ -207,6 +221,7 @@ static void rose_idletimer_expiry(struct timer_list *t)
 		sk->sk_state_change(sk);
 		sock_set_flag(sk, SOCK_DEAD);
 	}
+out:
 	bh_unlock_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