From: Yunseong Kim <ysk@kzalloc.com>
To: Dmitry Vyukov <dvyukov@google.com>,
Andrey Konovalov <andreyknvl@gmail.com>,
Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Thomas Gleixner <tglx@linutronix.de>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>,
Byungchul Park <byungchul@sk.com>,
max.byungchul.park@gmail.com, Yeoreum Yun <yeoreum.yun@arm.com>,
ppbuk5246@gmail.com, linux-usb@vger.kernel.org,
linux-rt-devel@lists.linux.dev, syzkaller@googlegroups.com,
linux-kernel@vger.kernel.org, stable@vger.kernel.org,
Yunseong Kim <ysk@kzalloc.com>
Subject: [PATCH v3 0/4] kcov, usb: Fix invalid context sleep in softirq path on PREEMPT_RT
Date: Sun, 3 Aug 2025 07:20:41 +0000 [thread overview]
Message-ID: <20250803072044.572733-2-ysk@kzalloc.com> (raw)
This patch series resolves a sleeping function called from invalid context
bug that occurs when fuzzing USB with syzkaller on a PREEMPT_RT kernel.
The regression was introduced by the interaction of two separate patches:
one that made kcov's internal locks sleep on PREEMPT_RT for better latency
(d5d2c51f1e5f), and another that wrapped a kcov call in the USB softirq
path with local_irq_save() to prevent re-entrancy (f85d39dd7ed8).
This combination resulted in an attempt to acquire a sleeping lock from
within an atomic context, causing a kernel BUG.
To resolve this, this series makes the kcov remote path fully compatible
with atomic contexts by converting all its internal locking primitives to
non-sleeping variants. This approach is more robust than conditional
compilation as it creates a single, unified codebase that works correctly
on both RT and non-RT kernels.
The series is structured as follows:
Patch 1 converts the global kcov locks (kcov->lock and kcov_remote_lock)
to use the non-sleeping raw_spinlock_t.
Patch 2 replace the PREEMPT_RT-specific per-CPU local_lock_t back to the
original local_irq_save/restore primitives, making the per-CPU protection
non-sleeping as well.
Patches 3 and 4 are preparatory refactoring. They move the memory
allocation for remote handles out of the locked sections in the
KCOV_REMOTE_ENABLE ioctl path, which is a prerequisite for safely
using raw_spinlock_t as it forbids sleeping functions like kmalloc
within its critical section.
With these changes, I have been able to run syzkaller fuzzing on a
PREEMPT_RT kernel for a full day with no issues reported.
Reproduction details in here.
Link: https://lore.kernel.org/all/20250725201400.1078395-2-ysk@kzalloc.com/t/#u
Signed-off-by: Yunseong Kim <ysk@kzalloc.com>
---
Changes from v2:
1. Updated kcov_remote_reset() to use raw_spin_lock_irqsave() /
raw_spin_unlock_irqrestore() instead of raw_spin_lock() /
raw_spin_unlock(), following the interrupt disabling pattern
used in the original function that guard kcov_remote_lock.
Changes from v1:
1. Dropped the #ifdef-based PREEMPT_RT branching.
2. Convert kcov->lock and kcov_remote_lock from spinlock_t to
raw_spinlock_t. This ensures they remain true, non-sleeping
spinlocks even on PREEMPT_RT kernels.
3. Remove the local_lock_t protection for kcov_percpu_data in
kcov_remote_start/stop(). Since local_lock_t can also sleep under
RT, and the required protection is against local interrupts when
accessing per-CPU data, it is replaced with explicit
local_irq_save/restore().
4. Refactor the KCOV_REMOTE_ENABLE path to move memory allocations
out of the critical section.
5. Modify the ioctl handling logic to utilize these pre-allocated
structures within the critical section. kcov_remote_add() is
modified to accept a pre-allocated structure instead of allocating
one internally. All necessary struct kcov_remote structures are now
pre-allocated individually in kcov_ioctl() using GFP_KERNEL
(allowing sleep) before acquiring the raw spinlocks.
Changes from v0:
1. On PREEMPT_RT, separated the handling of
kcov_remote_start_usb_softirq() and kcov_remote_stop_usb_softirq()
to allow sleeping when entering kcov_remote_start_usb() /
kcov_remote_stop().
Yunseong Kim (4):
kcov: Use raw_spinlock_t for kcov->lock and kcov_remote_lock
kcov: Replace per-CPU local_lock with local_irq_save/restore
kcov: Separate KCOV_REMOTE_ENABLE ioctl helper function
kcov: move remote handle allocation outside raw spinlock
kernel/kcov.c | 248 +++++++++++++++++++++++++++-----------------------
1 file changed, 134 insertions(+), 114 deletions(-)
base-commit: 186f3edfdd41f2ae87fc40a9ccba52a3bf930994
--
2.50.0
next reply other threads:[~2025-08-03 7:21 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-08-03 7:20 Yunseong Kim [this message]
2025-08-03 7:20 ` [PATCH 1/4] kcov: Use raw_spinlock_t for kcov->lock and kcov_remote_lock Yunseong Kim
2025-08-03 7:23 ` kernel test robot
2025-08-04 16:27 ` Steven Rostedt
2025-08-05 15:33 ` Yunseong Kim
2025-08-03 7:20 ` [PATCH 2/4] kcov: Replace per-CPU local_lock with local_irq_save/restore Yunseong Kim
2025-08-04 16:37 ` Steven Rostedt
2025-08-05 15:41 ` Yunseong Kim
2025-08-03 7:20 ` [PATCH 3/4] kcov: Separate KCOV_REMOTE_ENABLE ioctl helper function Yunseong Kim
2025-08-03 7:20 ` [PATCH 4/4] kcov: move remote handle allocation outside raw spinlock Yunseong Kim
2025-08-04 16:24 ` [PATCH v3 0/4] kcov, usb: Fix invalid context sleep in softirq path on PREEMPT_RT Steven Rostedt
2025-08-05 15:27 ` Yunseong Kim
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20250803072044.572733-2-ysk@kzalloc.com \
--to=ysk@kzalloc.com \
--cc=andreyknvl@gmail.com \
--cc=bigeasy@linutronix.de \
--cc=byungchul@sk.com \
--cc=dvyukov@google.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=linux-usb@vger.kernel.org \
--cc=max.byungchul.park@gmail.com \
--cc=penguin-kernel@i-love.sakura.ne.jp \
--cc=ppbuk5246@gmail.com \
--cc=stable@vger.kernel.org \
--cc=syzkaller@googlegroups.com \
--cc=tglx@linutronix.de \
--cc=yeoreum.yun@arm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox