[PATCH v17 12/15] arm64: ptrace: Make return type of arm64_syscall_trace_enter() bool
From: Jinjie Ruan <hidden>
Date: 2026-07-21 08:19:33
Also in:
linux-mm, lkml
Subsystem:
arm64 port (aarch64 architecture), ptrace support, the rest · Maintainers:
Catalin Marinas, Will Deacon, Oleg Nesterov, Linus Torvalds
In preparation for migrating arm64 to the generic entry infrastructure, decouple the decision to execute the syscall from the syscall number itself. The ptrace and seccomp now returns a boolean flag rather than overloading NO_SYSCALL (-1). Changes: - arm64_syscall_trace_enter() returns bool: - false: abort syscall execution - true: proceed, with syscall number reread from regs - If we decide to execute the syscall, reread the syscall number and check if it is NO_SYSCALL again. Because when a tracer sets the syscall number to -1 and provides a custom return value in x0, this avoids calling invoke_syscall() which would overwrite the custom value with -ENOSYS by sys_ni_syscall(). Behavioral impact (unchanged): - User-issued syscall(-1): unchanged, returns -ENOSYS. - Tracer skip with custom x0: unchanged, returns custom x0 - Tracer skip without setting x0: unchanged, returns original argument (garbage) - Normal syscalls and seccomp rejects: unaffected No functional changes. Cc: Mark Rutland <mark.rutland@arm.com> Cc: Will Deacon <will@kernel.org> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Ada Couprie Diaz <redacted> Signed-off-by: Jinjie Ruan <redacted> --- arch/arm64/include/asm/syscall.h | 2 +- arch/arm64/kernel/ptrace.c | 8 ++++---- arch/arm64/kernel/syscall.c | 6 +++++- 3 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 7cc872fde019..f19d4a8824ba 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h@@ -121,7 +121,7 @@ static inline int syscall_get_arch(struct task_struct *task) return AUDIT_ARCH_AARCH64; } -int arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags); +bool arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags); void arm64_syscall_exit_work(struct pt_regs *regs, unsigned long flags); static __always_inline void arm64_syscall_exit_to_user_mode_work(struct pt_regs *regs)
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 10ead67b4eaf..b2b28dcb2826 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c@@ -2468,14 +2468,14 @@ static inline void syscall_enter_audit(struct pt_regs *regs) } #endif -int arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags) +bool arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags) { int ret; if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) { ret = report_syscall_entry(regs); if (ret || (flags & _TIF_SYSCALL_EMU)) - return NO_SYSCALL; + return false; /* ptrace might have changed thread flags */ flags = read_thread_flags();
@@ -2484,7 +2484,7 @@ int arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags) /* Do the secure computing after ptrace; failures should be fast. */ if (unlikely(flags & _TIF_SECCOMP)) { if (!__seccomp_permit_syscall()) - return NO_SYSCALL; + return false; } if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
@@ -2493,7 +2493,7 @@ int arm64_syscall_trace_enter(struct pt_regs *regs, unsigned long flags) if (unlikely(audit_context())) syscall_enter_audit(regs); - return syscall_get_nr(current, regs); + return true; } static inline bool report_single_step(unsigned long flags)
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c
index 3488afd45d20..72c6e8b7ab21 100644
--- a/arch/arm64/kernel/syscall.c
+++ b/arch/arm64/kernel/syscall.c@@ -108,7 +108,11 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, */ if (scno == NO_SYSCALL) syscall_set_return_value(current, regs, -ENOSYS, 0); - scno = arm64_syscall_trace_enter(regs, read_thread_flags()); + if (!arm64_syscall_trace_enter(regs, read_thread_flags())) + goto trace_exit; + + /* Reread the syscall number as it might have been modified */ + scno = syscall_get_nr(current, regs); if (scno == NO_SYSCALL) goto trace_exit; }
--
2.34.1