Re: [PATCH] rseq: Out-of-line rseq_exit_user_update() for KMSAN
Ilya Leoshkevich <[email protected]>
| Newsgroups | dev.linux.lists.sashiko-reviews,org.kernel.vger.linux-s390 |
|---|---|
| Message-ID | <[email protected]> |
On 8/18/26 20:32, [email protected] 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 <[email protected]> > > 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().