[PATCH v2] arm64: ptrace: use live x0 for seccomp and audit after ptrace

Yiqi Sun sunyiqixm at gmail.com
Thu Jun 25 04:11:39 PDT 2026


On arm64, seccomp obtains syscall arguments via
syscall_get_arguments(), where arg0 is currently read from
regs->orig_x0. audit_syscall_entry() in syscall_trace_enter() also
takes arg0 from regs->orig_x0. However, the syscall wrapper consumes
live arguments from regs->regs[0..5].

A ptracer can modify x0 on syscall-enter stop before seccomp and audit
run, but cannot update orig_x0 through the native syscall-stop
interface. This can leave seccomp and audit checking stale arg0 while
the syscall executes with updated live x0.

Make both paths read arg0 from regs->regs[0], matching the actual
dispatch arguments and keeping seccomp and audit aligned after ptrace
updates.

Fixes: f27bb139c387 ("arm64: Miscellaneous library functions")
Signed-off-by: Yiqi Sun <sunyiqixm at gmail.com>
---
Changes in v2:
- Also switch the arm64 audit entry path to use live x0
- Clarify the orig_x0 synchronization comment in syscall_set_arguments()
---
 arch/arm64/include/asm/syscall.h | 7 +++----
 arch/arm64/kernel/ptrace.c       | 2 +-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/arch/arm64/include/asm/syscall.h b/arch/arm64/include/asm/syscall.h
index 5e4c7fc44f73..0a44db425522 100644
--- a/arch/arm64/include/asm/syscall.h
+++ b/arch/arm64/include/asm/syscall.h
@@ -81,7 +81,7 @@ static inline void syscall_get_arguments(struct task_struct *task,
 					 struct pt_regs *regs,
 					 unsigned long *args)
 {
-	args[0] = regs->orig_x0;
+	args[0] = regs->regs[0];
 	args[1] = regs->regs[1];
 	args[2] = regs->regs[2];
 	args[3] = regs->regs[3];
@@ -101,9 +101,8 @@ static inline void syscall_set_arguments(struct task_struct *task,
 	regs->regs[5] = args[5];
 
 	/*
-	 * Also copy the first argument into orig_x0
-	 * so that syscall_get_arguments() would return it
-	 * instead of the previous value.
+	 * Keep orig_x0 in sync so syscall_rollback() and compat
+	 * register views see the updated first argument.
 	 */
 	regs->orig_x0 = regs->regs[0];
 }
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 4d08598e2891..35dd86f9e87a 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -2426,7 +2426,7 @@ int syscall_trace_enter(struct pt_regs *regs)
 	if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
 		trace_sys_enter(regs, regs->syscallno);
 
-	audit_syscall_entry(regs->syscallno, regs->orig_x0, regs->regs[1],
+	audit_syscall_entry(regs->syscallno, regs->regs[0], regs->regs[1],
 			    regs->regs[2], regs->regs[3]);
 
 	return regs->syscallno;
-- 
2.34.1




More information about the linux-arm-kernel mailing list