Hello, On Tue, Jul 07, 2026 at 09:06:48PM +0200, Thomas Gleixner wrote: > In preparation of converting the return value of > syscall_enter_from_user_mode[_work]() bool, rework trace_syscall_enter() to > > - update the syscall number via a pointer argument > > - Return True if the syscall number is != -1, False otherwise
This does not achieve the goal of the initial RFC: To detangle the return value of syscall_enter_from_user_mode from the syscall number. This still conflates them, making it impossible to tell if the syscall was rejected or syscall number was -1 to start with. Now also obfuscated by performing the check deeper inside the common code. > That aligns with ptrace_report_syscall_permit_enter() and > seccomp_permit_syscall(). > > The only difference is that this also returns False, when the syscall > number was already -1 to begin with, but there is not much which can be > done about that. As the architecture has to preset the return value to > -ENOSYS anyway, that results in the correct return value for such an > invalid syscall. That's not possible to do for architectures where the syscall number and the syscall return value are in the same register. You suggested that it is possible to not write the return value into an actual register but use an additional field for that, and have the exit code write the register. However, that's not what is documented, nor what is currently done. While this is an improvement in some respects the goal to have clear and intelligible API around the generic entry is not acheived. Thanks Michal > > Signed-off-by: Thomas Gleixner <[email protected]> > --- > include/linux/entry-common.h | 8 +++++--- > kernel/entry/syscall-common.c | 7 ++++--- > 2 files changed, 9 insertions(+), 6 deletions(-) > > --- a/include/linux/entry-common.h > +++ b/include/linux/entry-common.h > @@ -58,7 +58,7 @@ static __always_inline bool arch_ptrace_ > #endif > > bool syscall_user_dispatch(struct pt_regs *regs); > -long trace_syscall_enter(struct pt_regs *regs, long syscall); > +bool trace_syscall_enter(struct pt_regs *regs, long *syscall); > void trace_syscall_exit(struct pt_regs *regs, long ret); > > static inline void syscall_enter_audit(struct pt_regs *regs, long syscall) > @@ -108,8 +108,10 @@ static __always_inline long syscall_trac > /* Either of the above might have changed the syscall number */ > syscall = syscall_get_nr(current, regs); > > - if (unlikely(work & SYSCALL_WORK_SYSCALL_TRACEPOINT)) > - syscall = trace_syscall_enter(regs, syscall); > + if (unlikely(work & SYSCALL_WORK_SYSCALL_TRACEPOINT)) { > + if (!trace_syscall_enter(regs, &syscall)) > + return -1L; > + } > > syscall_enter_audit(regs, syscall); > > --- a/kernel/entry/syscall-common.c > +++ b/kernel/entry/syscall-common.c > @@ -7,14 +7,15 @@ > > /* Out of line to prevent tracepoint code duplication */ > > -long trace_syscall_enter(struct pt_regs *regs, long syscall) > +bool trace_syscall_enter(struct pt_regs *regs, long *syscall) > { > - trace_sys_enter(regs, syscall); > + trace_sys_enter(regs, *syscall); > /* > * Probes or BPF hooks in the tracepoint may have changed the > * system call number. Reread it. > */ > - return syscall_get_nr(current, regs); > + *syscall = syscall_get_nr(current, regs); > + return *syscall != -1L; > } > > void trace_syscall_exit(struct pt_regs *regs, long ret) >
