commit a9f3a74a29af ("entry: Provide generic syscall exit function") introduce generic syscall exit function and call rseq_syscall() before audit_syscall_exit() and arch_syscall_exit_tracehook().
And commit b74406f37737 ("arm: Add syscall detection for restartable sequences") add rseq support for arm32, which also call rseq_syscall() before audit_syscall_exit() and tracehook_report_syscall().
However, commit 409d5db49867c ("arm64: rseq: Implement backend rseq calls and select HAVE_RSEQ") implement arm64 rseq and call rseq_syscall() after audit_syscall_exit() and tracehook_report_syscall().
So compared to the generic entry and arm32 code, arm64 terminates the process a bit later if the syscall is issued within a restartable sequence.
But as commit b74406f37737 ("arm: Add syscall detection for restartable sequences") said, syscalls are not allowed inside restartable sequences, so should call rseq_syscall() at the very beginning of system call exiting path for CONFIG_DEBUG_RSEQ=y kernel. This could help us to detect whether there is a syscall issued inside restartable sequences.
It makes sense to raise SIGSEGV via rseq_syscall() before auditing and ptrace syscall exit, because this guarantees that the process is already in an error state with SIGSEGV pending when those later steps run. Although it makes no practical difference to signal delivery (signals are processed at the very end in arm64_exit_to_user_mode()), the ordering is more logical: detect and flag the error first, then proceed with the remaining work.
To make it more reasonable and in preparation for moving arm64 over to the generic entry code, move rseq_syscall() ahead before audit_syscall_exit().
Signed-off-by: Jinjie Ruan ruanjinjie@huawei.com --- arch/arm64/kernel/ptrace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c index 63ba6c961ecc..dfdd886dc0a9 100644 --- a/arch/arm64/kernel/ptrace.c +++ b/arch/arm64/kernel/ptrace.c @@ -2411,6 +2411,8 @@ int syscall_trace_enter(struct pt_regs *regs, long syscall, unsigned long flags)
void syscall_trace_exit(struct pt_regs *regs, unsigned long flags) { + rseq_syscall(regs); + audit_syscall_exit(regs);
if (flags & _TIF_SYSCALL_TRACEPOINT) @@ -2418,8 +2420,6 @@ void syscall_trace_exit(struct pt_regs *regs, unsigned long flags)
if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP)) report_syscall_exit(regs); - - rseq_syscall(regs); }
/*