Re: [PATCH v2] arm64: ptrace: don't warn on missing siginfo in a group-stop

From: Will Deacon

Date: Wed Nov 04 2026 - 09:09:02 EST


Hey Oleg,

On Fri, Oct 23, 2026 at 03:24:04PM +0200, Oleg Nesterov wrote:
> On 10/23, Zhao Gongyi wrote:
> >
> > --- a/arch/arm64/kernel/ptrace.c
> > +++ b/arch/arm64/kernel/ptrace.c
> > @@ -573,10 +573,6 @@ static void update_syscall_orig_x0_after_ptrace(struct task_struct *target)
> > if (regs->syscallno == NO_SYSCALL)
> > return;
> >
> > - /* We should only be called when target is in a ptrace stop */
> > - if (WARN_ON_ONCE(!info))
> > - return;
> > -
> > /*
> > * For compat tasks, orig_r0 is provided directly through GPR index
> > * 17.
> > @@ -588,7 +584,7 @@ static void update_syscall_orig_x0_after_ptrace(struct task_struct *target)
> > * Don't update orig_x0 for a syscall-exit-stop, as x0 now contains the
> > * return value of the system call.
> > */
> > - if ((info->si_code & ~0x80) == SIGTRAP &&
> > + if (info && (info->si_code & ~0x80) == SIGTRAP &&
> > target->ptrace_message == PTRACE_EVENTMSG_SYSCALL_EXIT) {
> > return;
>
> LGTM, but I don't understand this arm-specific code.

Welcome to the club :)

The original rationale is described in e057b9477232 ("arm64: syscall:
Ensure saved x0 is kept in-sync with tracer updates"), so hopefully that
helps to set the scene. The crux of the problem is that the x0 register
on arm64 is used both for the first argument of a system call but also
for the return value, which causes difficulties for things like syscall
restarting, syscall skipping and syscall reporting in /proc/<pid>/syscall.

We handle that by keeping the original argument value in a shadow variable,
orig_x0, in the pt_regs and using that to implement the problematic
mechanisms above, including the accessors used by seccomp in asm/syscall.h.

The bug was (a) that we only copied x0 into orig_x0 early on the syscall
path (el0_svc_common()), which meant that tracer updates to x0 would not
be visible to seccomp filters and (b) that we passed x0 to the syscall,
which meant that the unchecked value was used as the first argument.

My initial fix (in e057b9477232) tried to copy x0 back into orig_x0
after tracer updates on the syscall entry path, however this didn't work
with some of the more complicated seccomp interactions (involving BPF
programs and SECCOMP_RET_TRACE) and so commit 88b839ce497c ("arm64: ptrace:
Keep 'orig_x0' in-sync with x0 on syscall entry") took a different
approach of updating orig_x0 at a lower-level, whenever x0 is written
by ptrace *and* we're on the syscall entry path. The latter check is
really a "we're not on the syscall exit path" so that we can handle the
seccomp case.

So that's the mess we're in and I'm all ears if there's a cleaner way to
sort it out without breaking anything that relies on the fragile semantics
we already have.

Cheers,

Will