Subject: [PATCH] arm: ptrace: fix syscall modification under PTRACE_O_TRACESECCOMP

From: [email-masked] (Will Deacon)
Date: Thu, 3 Jul 2014 17:32:00 +0100

On Thu, Jul 03, 2014 at 05:13:50PM +0100, Andy Lutomirski wrote:
> On Thu, Jul 3, 2014 at 9:11 AM, Will Deacon <[email-masked]> wrote:
> > On Thu, Jul 03, 2014 at 04:39:21PM +0100, Andy Lutomirski wrote:
> >> On Thu, Jul 3, 2014 at 3:24 AM, Will Deacon <[email-masked]> wrote:
> >> > On Thu, Jul 03, 2014 at 08:43:07AM +0100, AKASHI Takahiro wrote:
> >> >> So it seems to me that we can't change a system call by ptrace().
> >> >> Do I misunderstand anything?
> >> >
> >> > No, it looks like you have a point here. I don't think userspace has any
> >> > business with orig_x0, but changing syscallno is certainly useful. I can
> >> > think of two ways to fix this:
> >> >
> >> >   (1) Updating syscallno based on w8, but this ties us to the current ABI
> >> >       and could get messy if this register changes in the future.
> >> >
> >> >   (2) Adding a PTRACE_SET_SYSCALL request, like we have for arch/arm/,
> >> >       but that means adding arch-specific stuff to arch_ptrace (which
> >> >       currently goes straight to ptrace_request on arm64).
> >> >
> >> > It looks like x86 uses orig_ax, which I *think* means we would go with
> >> > (1) above if we followed their lead.
> >>
> >> w8 is a real register, right?  On x86, at least orig_ax isn't a real
> >> register, so it's quite unlikely to conflict with hardware stuff.
> >
> > Yeah, w8 is the hardware register which the Linux ABI uses for the system
> > call number. I was thinking We could allow the debugger/tracer to update
> > the syscall number by updating that register, or do you see an issue with
> > that? (other than tying us to the current ABI).
> 
> Not immediately, but I'm not super-familiar with ptrace.
> 
> Is w8 clobbered or otherwise changed by syscalls?  Using w8 for this
> has the odd effect that tracers can't force a return with a specific
> value of w8 without executing the corresponding syscall.  If that's a
> meaningful limitation, then presumably some other channel should be
> used.

Hmm, that's true. Currently w8 is preserved across a syscall by the kernel,
so it would be pretty bizarre for somebody to try and modify it but I guess
they could do it if they wanted to. However, they could just as easily
modify it on the syscall return path and have the same effect...

Furthermore, glibc unconditionally emits a mov into w8 prior to the svc
instruction, so from a user's perspective that register always contains
the system call number.

FWIW: the role of w8 in the PCS is `Indirect result location register', so
I'd expect it to be saved across the syscall anyway.

Will