From: Jiayuan Chen <jiayuan.chen@linux.dev>
To: linux-rt-devel@lists.linux.dev
Cc: Jiayuan Chen <jiayuan.chen@linux.dev>,
Sebastian Andrzej Siewior <bigeasy@linutronix.de>,
Steven Rostedt <rostedt@goodmis.org>,
Clark Williams <clrkwllms@kernel.org>,
"Peter Zijlstra (Intel)" <peterz@infradead.org>,
linux-kernel@vger.kernel.org
Subject: [PATCH v2] irq_work: Fix use-after-free in irq_work_single on PREEMPT_RT
Date: Mon, 30 Mar 2026 15:32:29 +0800 [thread overview]
Message-ID: <20260330073234.303732-1-jiayuan.chen@linux.dev> (raw)
On PREEMPT_RT, non-HARD irq_work runs in per-CPU kthreads via
run_irq_workd(), so irq_work_sync() uses rcuwait to wait for
BUSY==0.
After irq_work_single() clears BUSY via atomic_cmpxchg(), it still
dereferences @work for irq_work_is_hard() and rcuwait_wake_up().
An irq_work_sync() caller on another CPU that enters after BUSY is
cleared can observe BUSY==0 immediately, return, and free the work
before those accesses complete — causing a use-after-free.
Fix this by wrapping run_irq_workd() in guard(rcu)() so that the
entire irq_work_single() execution is within an RCU read-side
critical section. Then add synchronize_rcu() in irq_work_sync()
after rcuwait_wait_event() to ensure the caller waits for the RCU
grace period before returning, preventing premature frees.
Fixes: 810979682ccc ("irq_work: Allow irq_work_sync() to sleep if irq_work() no IRQ support.")
Suggested-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Suggested-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
---
kernel/irq_work.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/kernel/irq_work.c b/kernel/irq_work.c
index 73f7e1fd4ab4..bf411656c316 100644
--- a/kernel/irq_work.c
+++ b/kernel/irq_work.c
@@ -292,6 +292,12 @@ void irq_work_sync(struct irq_work *work)
!arch_irq_work_has_interrupt()) {
rcuwait_wait_event(&work->irqwait, !irq_work_is_busy(work),
TASK_UNINTERRUPTIBLE);
+ /*
+ * Ensure irq_work_single() does not access @work
+ * after removing IRQ_WORK_BUSY. It is always
+ * accessed within a RCU-read section.
+ */
+ synchronize_rcu();
return;
}
@@ -302,6 +308,7 @@ EXPORT_SYMBOL_GPL(irq_work_sync);
static void run_irq_workd(unsigned int cpu)
{
+ guard(rcu)();
irq_work_run_list(this_cpu_ptr(&lazy_list));
}
--
2.43.0
next reply other threads:[~2026-03-30 7:32 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-30 7:32 Jiayuan Chen [this message]
2026-04-02 6:50 ` [PATCH v2] irq_work: Fix use-after-free in irq_work_single on PREEMPT_RT Sebastian Andrzej Siewior
2026-06-05 10:31 ` Xi Ruoyao
2026-06-05 10:45 ` Sebastian Andrzej Siewior
2026-06-05 17:26 ` Xi Ruoyao
2026-05-11 14:31 ` [tip: irq/urgent] irq_work: Fix use-after-free in irq_work_single() " tip-bot2 for Jiayuan Chen
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=20260330073234.303732-1-jiayuan.chen@linux.dev \
--to=jiayuan.chen@linux.dev \
--cc=bigeasy@linutronix.de \
--cc=clrkwllms@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rt-devel@lists.linux.dev \
--cc=peterz@infradead.org \
--cc=rostedt@goodmis.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.