public inbox for linux-usb@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] kcov, usb: Fix invalid context sleep in softirq path on PREEMPT_RT
@ 2025-07-25 20:14 Yunseong Kim
  2025-07-26  6:36 ` Greg Kroah-Hartman
  2025-08-08 16:33 ` Sebastian Andrzej Siewior
  0 siblings, 2 replies; 9+ messages in thread
From: Yunseong Kim @ 2025-07-25 20:14 UTC (permalink / raw)
  To: Dmitry Vyukov, Andrey Konovalov
  Cc: Byungchul Park, max.byungchul.park, Yeoreum Yun, Michelle Jin,
	linux-kernel, Yunseong Kim, Tetsuo Handa, Alan Stern,
	Greg Kroah-Hartman, Thomas Gleixner, Sebastian Andrzej Siewior,
	stable, kasan-dev, syzkaller, linux-usb, linux-rt-devel

When fuzzing USB with syzkaller on a PREEMPT_RT enabled kernel, following
bug is triggered in the ksoftirqd context.

| BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48
| in_atomic(): 0, irqs_disabled(): 1, non_block: 0, pid: 30, name: ksoftirqd/1
| preempt_count: 0, expected: 0
| RCU nest depth: 2, expected: 2
| CPU: 1 UID: 0 PID: 30 Comm: ksoftirqd/1 Tainted: G        W           6.16.0-rc1-rt1 #11 PREEMPT_RT
| Tainted: [W]=WARN
| Hardware name: QEMU KVM Virtual Machine, BIOS 2025.02-8 05/13/2025
| Call trace:
|  show_stack+0x2c/0x3c (C)
|  __dump_stack+0x30/0x40
|  dump_stack_lvl+0x148/0x1d8
|  dump_stack+0x1c/0x3c
|  __might_resched+0x2e4/0x52c
|  rt_spin_lock+0xa8/0x1bc
|  kcov_remote_start+0xb0/0x490
|  __usb_hcd_giveback_urb+0x2d0/0x5e8
|  usb_giveback_urb_bh+0x234/0x3c4
|  process_scheduled_works+0x678/0xd18
|  bh_worker+0x2f0/0x59c
|  workqueue_softirq_action+0x104/0x14c
|  tasklet_action+0x18/0x8c
|  handle_softirqs+0x208/0x63c
|  run_ksoftirqd+0x64/0x264
|  smpboot_thread_fn+0x4ac/0x908
|  kthread+0x5e8/0x734
|  ret_from_fork+0x10/0x20

To reproduce on PREEMPT_RT kernel:

 $ git remote add rt-devel git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git
 $ git fetch rt-devel
 $ git checkout -b v6.16-rc1-rt1 v6.16-rc1-rt1

I have attached the syzlang and the C source code converted by syz-prog2c:

Link: https://gist.github.com/kzall0c/9455aaa246f4aa1135353a51753adbbe

Then, run with a PREEMPT_RT config.

This issue was introduced by commit
f85d39dd7ed8 ("kcov, usb: disable interrupts in kcov_remote_start_usb_softirq").

However, this creates a conflict on PREEMPT_RT kernels. The local_irq_save()
call establishes an atomic context where sleeping is forbidden. Inside this
context, kcov_remote_start() is called, which on PREEMPT_RT uses sleeping
locks (spinlock_t and local_lock_t are mapped to rt_mutex). This results in
a sleeping function called from invalid context.

On PREEMPT_RT, interrupt handlers are threaded, so the re-entrancy scenario
is already safely handled by the existing local_lock_t and the global
kcov_remote_lock within kcov_remote_start(). Therefore, the outer
local_irq_save() is not necessary.

This preserves the intended re-entrancy protection for non-RT kernels while
resolving the locking violation on PREEMPT_RT kernels.

After making this modification and testing it, syzkaller fuzzing the
PREEMPT_RT kernel is now running without stopping on latest announced
Real-time Linux.

Link: https://lore.kernel.org/linux-rt-devel/20250610080307.LMm1hleC@linutronix.de/
Fixes: f85d39dd7ed8 ("kcov, usb: disable interrupts in kcov_remote_start_usb_softirq")
Cc: Andrey Konovalov <andreyknvl@gmail.com>
Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
Cc: Alan Stern <stern@rowland.harvard.edu>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Cc: Byungchul Park <byungchul@sk.com>
Cc: stable@vger.kernel.org
Cc: kasan-dev@googlegroups.com
Cc: syzkaller@googlegroups.com
Cc: linux-usb@vger.kernel.org
Cc: linux-rt-devel@lists.linux.dev
Signed-off-by: Yunseong Kim <ysk@kzalloc.com>
---
 include/linux/kcov.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/include/linux/kcov.h b/include/linux/kcov.h
index 75a2fb8b16c3..c5e1b2dd0bb7 100644
--- a/include/linux/kcov.h
+++ b/include/linux/kcov.h
@@ -85,7 +85,9 @@ static inline unsigned long kcov_remote_start_usb_softirq(u64 id)
 	unsigned long flags = 0;
 
 	if (in_serving_softirq()) {
+#ifndef CONFIG_PREEMPT_RT
 		local_irq_save(flags);
+#endif
 		kcov_remote_start_usb(id);
 	}
 
@@ -96,7 +98,9 @@ static inline void kcov_remote_stop_softirq(unsigned long flags)
 {
 	if (in_serving_softirq()) {
 		kcov_remote_stop();
+#ifndef CONFIG_PREEMPT_RT
 		local_irq_restore(flags);
+#endif
 	}
 }
 
-- 
2.50.0


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2025-08-11  8:31 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-25 20:14 [PATCH] kcov, usb: Fix invalid context sleep in softirq path on PREEMPT_RT Yunseong Kim
2025-07-26  6:36 ` Greg Kroah-Hartman
2025-07-26  7:44   ` Tetsuo Handa
2025-07-26  7:59     ` Greg Kroah-Hartman
2025-07-26 11:59       ` Thomas Gleixner
2025-08-01 22:06         ` Yunseong Kim
2025-08-08 16:33 ` Sebastian Andrzej Siewior
2025-08-08 17:35   ` Yunseong Kim
2025-08-11  8:31     ` Sebastian Andrzej Siewior

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