* [PATCH] rseq: Out-of-line rseq_exit_user_update() for KMSAN
@ 2026-08-18 18:12 Ilya Leoshkevich
2026-08-18 18:32 ` sashiko-bot
0 siblings, 1 reply; 3+ messages in thread
From: Ilya Leoshkevich @ 2026-08-18 18:12 UTC (permalink / raw)
To: Mathieu Desnoyers, Peter Zijlstra, Paul E. McKenney, Boqun Feng,
Thomas Gleixner, Dmitry Vyukov, Alexander Potapenko
Cc: linux-kernel, Heiko Carstens, Vasily Gorbik, Alexander Gordeev,
Aleksei Nikiforov, linux-s390, Ilya Leoshkevich
KMSAN produces the following false positive on s390x:
[ 4.232136] Kernel panic - not syncing: kmsan.panic set ...
[ 4.232339] CPU: 7 UID: 0 PID: 1 Comm: virtme-init Tainted: G B N 7.2.0-rc6-virtme #27 PREEMPTLAZY
[ 4.232676] Tainted: [B]=BAD_PAGE, [N]=TEST
[ 4.232808] Hardware name: IBM 3931 A01 701 (KVM/Linux)
[ 4.232971] Call Trace:
[ 4.233065] [<000002dcfb993140>] vpanic+0xb50/0x1080
[ 4.239698] [<000002dcfb9925ec>] panic+0x22c/0x230
[ 4.239879] [<000002dcfcec5d32>] kmsan_report+0x322/0x330
[ 4.240081] [<000002dcfcec3592>] kmsan_internal_check_memory+0x222/0x280
[ 4.240304] [<000002dcffe3444e>] irqentry_exit+0x50e/0x8f0
[ 4.240522] [<000002dcffe33454>] __do_pgm_check+0x1b4/0x2b0
[ 4.240740] [<000002dcffe75304>] pgm_check_handler+0x114/0x160
The reason is that the following call chain inlined into the noinstr
irqentry_exit() function:
irqentry_exit()
irqentry_exit_to_user_mode()
irqentry_exit_to_user_mode_prepare()
__exit_to_user_mode_prepare()
exit_to_user_mode_loop()
rseq_exit_to_user_mode_restart()
__rseq_exit_to_user_mode_restart()
rseq_exit_user_update()
does not set KMSAN shadow on struct rseq_ids, which is then verified by
rseq_exit_user_update()
rseq_update_usr()
rseq_set_ids_get_csaddr()
unsafe_put_user()
regardless of presence of KMSAN instrumentation.
Fix by out-of-lining rseq_exit_user_update() and compiling the
out-of-lined version with KMSAN instrumentation.
This should affect other architectures as well, but whether one
actually sees it depends on the leftover shadow of struct rseq_ids
stack location: s390 is not special here.
Fixes: 05b44aef709c ("rseq: Implement fast path for exit to user")
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
---
include/linux/rseq_entry.h | 9 ++++++++-
kernel/rseq.c | 7 +++++++
2 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/include/linux/rseq_entry.h b/include/linux/rseq_entry.h
index ed9da6e41a2aa..a396050f771cc 100644
--- a/include/linux/rseq_entry.h
+++ b/include/linux/rseq_entry.h
@@ -595,7 +595,8 @@ static rseq_inline bool rseq_update_usr(struct task_struct *t, struct pt_regs *r
* tells the caller to loop back into exit_to_user_mode_loop(). The rseq
* slow path there will handle the failure.
*/
-static __always_inline bool rseq_exit_user_update(struct pt_regs *regs, struct task_struct *t)
+static __always_inline bool rseq_exit_user_update_inline(struct pt_regs *regs,
+ struct task_struct *t)
{
/*
* Page faults need to be disabled as this is called with
@@ -647,6 +648,12 @@ static __always_inline bool rseq_exit_user_update(struct pt_regs *regs, struct t
return false;
}
+#ifdef CONFIG_KMSAN
+bool rseq_exit_user_update(struct pt_regs *regs, struct task_struct *t);
+#else
+#define rseq_exit_user_update rseq_exit_user_update_inline
+#endif
+
static __always_inline bool __rseq_exit_to_user_mode_restart(struct pt_regs *regs)
{
struct task_struct *t = current;
diff --git a/kernel/rseq.c b/kernel/rseq.c
index e75e3a5e312c8..be759d7d266b5 100644
--- a/kernel/rseq.c
+++ b/kernel/rseq.c
@@ -329,6 +329,13 @@ void __rseq_handle_slowpath(struct pt_regs *regs)
rseq_slowpath_update_usr(regs);
}
+#if defined(CONFIG_KMSAN) && defined(CONFIG_GENERIC_ENTRY)
+bool rseq_exit_user_update(struct pt_regs *regs, struct task_struct *t)
+{
+ return rseq_exit_user_update_inline(regs, t);
+}
+#endif
+
void __rseq_signal_deliver(int sig, struct pt_regs *regs)
{
rseq_stat_inc(rseq_stats.signal);
--
2.55.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] rseq: Out-of-line rseq_exit_user_update() for KMSAN
2026-08-18 18:12 [PATCH] rseq: Out-of-line rseq_exit_user_update() for KMSAN Ilya Leoshkevich
@ 2026-08-18 18:32 ` sashiko-bot
2026-08-18 19:11 ` Ilya Leoshkevich
0 siblings, 1 reply; 3+ messages in thread
From: sashiko-bot @ 2026-08-18 18:32 UTC (permalink / raw)
To: Ilya Leoshkevich
Cc: Vasily Gorbik, Heiko Carstens, linux-s390, Christian Borntraeger,
Alexander Gordeev
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
Pre-existing issues:
- [High] KMSAN false positive in `__rseq_grant_slice_extension` due to missing out-of-line wrapper in `noinstr` context.
--
--- Patch [1]: [PATCH] rseq: Out-of-line rseq_exit_user_update() for KMSAN ---
commit 34d84b6249995289ac0487f7b7677244a859e66c
Author: Ilya Leoshkevich <iii@linux.ibm.com>
rseq: Out-of-line rseq_exit_user_update() for KMSAN
This patch fixes a KMSAN false positive on s390x caused by
rseq_exit_user_update() being inlined into a noinstr context, which leaves
KMSAN shadow memory uninitialized for stack variables. It resolves the
false positive by out-of-lining rseq_exit_user_update() and compiling it
with KMSAN instrumentation.
> diff --git a/include/linux/rseq_entry.h b/include/linux/rseq_entry.h
> index 31ce349ed42ce..defe1900e041a 100644
> --- a/include/linux/rseq_entry.h
> +++ b/include/linux/rseq_entry.h
> @@ -596,7 +596,8 @@ static rseq_inline bool rseq_update_usr(struct task_struct *t, struct pt_regs *r
> * tells the caller to loop back into exit_to_user_mode_loop(). The rseq
> * slow path there will handle the failure.
> */
> -static __always_inline bool rseq_exit_user_update(struct pt_regs *regs, struct task_struct *t)
> +static __always_inline bool rseq_exit_user_update_inline(struct pt_regs *regs,
> + struct task_struct *t)
> {
[Severity: High]
This isn't a regression introduced by this patch, but
__rseq_grant_slice_extension() appears to have the same KMSAN false
positive.
In include/linux/rseq_entry.h:__rseq_grant_slice_extension():
struct rseq_slice_ctrl usr_ctrl;
...
unsafe_get_user(usr_ctrl.all, &rseq->slice_ctrl.all, efault);
if (likely(!(usr_ctrl.request)))
return false;
/* Grant the slice extention */
usr_ctrl.request = 0;
usr_ctrl.granted = 1;
unsafe_put_user(usr_ctrl.all, &rseq->slice_ctrl.all, efault);
Because __rseq_grant_slice_extension() is unconditionally __always_inline,
it gets inlined into the noinstr function irqentry_exit(). The
unsafe_get_user() call reads into the local stack variable usr_ctrl, but
KMSAN's instrumentation is disabled here, leaving the shadow memory
uninitialized.
When unsafe_put_user() is called with usr_ctrl.all, it invokes
instrument_put_user() which explicitly calls kmsan_copy_to_user(). This
evaluates the shadow memory of usr_ctrl.all, sees it as uninitialized,
and produces a false positive.
Should __rseq_grant_slice_extension() also be out-of-lined similar to
how this patch handles rseq_exit_user_update() to prevent this?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260818181328.2963038-1-iii@linux.ibm.com?part=1
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] rseq: Out-of-line rseq_exit_user_update() for KMSAN
2026-08-18 18:32 ` sashiko-bot
@ 2026-08-18 19:11 ` Ilya Leoshkevich
0 siblings, 0 replies; 3+ messages in thread
From: Ilya Leoshkevich @ 2026-08-18 19:11 UTC (permalink / raw)
To: sashiko-reviews
Cc: Vasily Gorbik, Heiko Carstens, linux-s390, Christian Borntraeger,
Alexander Gordeev
On 8/18/26 20:32, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
>
> Pre-existing issues:
> - [High] KMSAN false positive in `__rseq_grant_slice_extension` due to missing out-of-line wrapper in `noinstr` context.
> --
>
> --- Patch [1]: [PATCH] rseq: Out-of-line rseq_exit_user_update() for KMSAN ---
> commit 34d84b6249995289ac0487f7b7677244a859e66c
> Author: Ilya Leoshkevich <iii@linux.ibm.com>
>
> rseq: Out-of-line rseq_exit_user_update() for KMSAN
>
> This patch fixes a KMSAN false positive on s390x caused by
> rseq_exit_user_update() being inlined into a noinstr context, which leaves
> KMSAN shadow memory uninitialized for stack variables. It resolves the
> false positive by out-of-lining rseq_exit_user_update() and compiling it
> with KMSAN instrumentation.
>
>> diff --git a/include/linux/rseq_entry.h b/include/linux/rseq_entry.h
>> index 31ce349ed42ce..defe1900e041a 100644
>> --- a/include/linux/rseq_entry.h
>> +++ b/include/linux/rseq_entry.h
>> @@ -596,7 +596,8 @@ static rseq_inline bool rseq_update_usr(struct task_struct *t, struct pt_regs *r
>> * tells the caller to loop back into exit_to_user_mode_loop(). The rseq
>> * slow path there will handle the failure.
>> */
>> -static __always_inline bool rseq_exit_user_update(struct pt_regs *regs, struct task_struct *t)
>> +static __always_inline bool rseq_exit_user_update_inline(struct pt_regs *regs,
>> + struct task_struct *t)
>> {
>
> [Severity: High]
> This isn't a regression introduced by this patch, but
> __rseq_grant_slice_extension() appears to have the same KMSAN false
> positive.
>
> In include/linux/rseq_entry.h:__rseq_grant_slice_extension():
>
> struct rseq_slice_ctrl usr_ctrl;
> ...
> unsafe_get_user(usr_ctrl.all, &rseq->slice_ctrl.all, efault);
> if (likely(!(usr_ctrl.request)))
> return false;
>
> /* Grant the slice extention */
> usr_ctrl.request = 0;
> usr_ctrl.granted = 1;
> unsafe_put_user(usr_ctrl.all, &rseq->slice_ctrl.all, efault);
>
> Because __rseq_grant_slice_extension() is unconditionally __always_inline,
> it gets inlined into the noinstr function irqentry_exit(). The
> unsafe_get_user() call reads into the local stack variable usr_ctrl, but
> KMSAN's instrumentation is disabled here, leaving the shadow memory
> uninitialized.
>
> When unsafe_put_user() is called with usr_ctrl.all, it invokes
> instrument_put_user() which explicitly calls kmsan_copy_to_user(). This
> evaluates the shadow memory of usr_ctrl.all, sees it as uninitialized,
> and produces a false positive.
>
> Should __rseq_grant_slice_extension() also be out-of-lined similar to
> how this patch handles rseq_exit_user_update() to prevent this?
Agreed, thanks.
I will wait for feedback for the out-of-lining approach, and if it's
favorable, I will post another patch for __rseq_grant_slice_extension().
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-08-18 19:11 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-18 18:12 [PATCH] rseq: Out-of-line rseq_exit_user_update() for KMSAN Ilya Leoshkevich
2026-08-18 18:32 ` sashiko-bot
2026-08-18 19:11 ` Ilya Leoshkevich
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.