Skip to content

Commit 59ee987

Browse files
committed
arm64: ptrace: Add a comment describing our syscall entry/exit trap ABI
Our tracehook logic for syscall entry/exit raises a SIGTRAP back to the tracer following a ptrace request such as PTRACE_SYSCALL. As part of this procedure, we clobber the reported value of one of the tracee's general purpose registers (x7 for native tasks, r12 for compat) to indicate whether the stop occurred on syscall entry or exit. This is a slightly unfortunate ABI, as it prevents the tracer from accessing the real register value and is at odds with other similar stops such as seccomp traps. Since we're stuck with this ABI, expand the comment in our tracehook logic to acknowledge the issue and describe the behaviour in more detail. Cc: Mark Rutland <[email protected]> Cc: Luis Machado <[email protected]> Reported-by: Keno Fischer <[email protected]> Signed-off-by: Will Deacon <[email protected]>
1 parent 1595668 commit 59ee987

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

arch/arm64/kernel/ptrace.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1811,8 +1811,20 @@ static void tracehook_report_syscall(struct pt_regs *regs,
18111811
unsigned long saved_reg;
18121812

18131813
/*
1814-
* A scratch register (ip(r12) on AArch32, x7 on AArch64) is
1815-
* used to denote syscall entry/exit:
1814+
* We have some ABI weirdness here in the way that we handle syscall
1815+
* exit stops because we indicate whether or not the stop has been
1816+
* signalled from syscall entry or syscall exit by clobbering a general
1817+
* purpose register (ip/r12 for AArch32, x7 for AArch64) in the tracee
1818+
* and restoring its old value after the stop. This means that:
1819+
*
1820+
* - Any writes by the tracer to this register during the stop are
1821+
* ignored/discarded.
1822+
*
1823+
* - The actual value of the register is not available during the stop,
1824+
* so the tracer cannot save it and restore it later.
1825+
*
1826+
* - Syscall stops behave differently to seccomp and pseudo-step traps
1827+
* (the latter do not nobble any registers).
18161828
*/
18171829
regno = (is_compat_task() ? 12 : 7);
18181830
saved_reg = regs->regs[regno];

0 commit comments

Comments
 (0)