[PATCH] ARM: ptrace: Implement PTRACE_SYSEMU

Kyle Huey me at kylehuey.com
Tue Jul 21 03:04:45 PDT 2015


Implement PTRACE_SYSEMU support on ARM. Currently this ptrace call is
supported only on x86. This copies the x86 semantics for invoking ptrace hooks
(the syscall entry hook is invoked, the exit hook is not). This patch also
defines PTRACE_SYSEMU_SINGLESTEP because kernel/ptrace.c expects it to be
present if PTRACE_SYSEMU is present. Attempting to use PTRACE_SYSEMU_SINGLESTEP
will fail at runtime on ARM with EIO since there is no single stepping on ARM.

Signed-off-by: Kyle Huey <khuey at kylehuey.com>
---
 arch/arm/include/asm/thread_info.h |  8 ++++++--
 arch/arm/include/uapi/asm/ptrace.h | 32 +++++++++++++++++---------------
 arch/arm/kernel/ptrace.c           |  9 +++++++--
 3 files changed, 30 insertions(+), 19 deletions(-)

diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index bd32ede..0e3ee19 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -137,7 +137,8 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
 /*
  * thread information flags:
  *  TIF_SYSCALL_TRACE	- syscall trace active
- *  TIF_SYSCAL_AUDIT	- syscall auditing active
+ *  TIF_SYSCALL_AUDIT	- syscall auditing active
+ *  TIF_SYSCALL_EMU	- syscall emulation active
  *  TIF_SIGPENDING	- signal pending
  *  TIF_NEED_RESCHED	- rescheduling necessary
  *  TIF_NOTIFY_RESUME	- callback before returning to user
@@ -153,6 +154,7 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
 #define TIF_SYSCALL_TRACEPOINT	10
 #define TIF_SECCOMP		11	/* seccomp syscall filtering active */
 #define TIF_NOHZ		12	/* in adaptive nohz mode */
+#define TIF_SYSCALL_EMU		13
 #define TIF_USING_IWMMXT	17
 #define TIF_MEMDIE		18	/* is terminating due to OOM killer */
 #define TIF_RESTORE_SIGMASK	20
@@ -165,11 +167,13 @@ extern int vfp_restore_user_hwstate(struct user_vfp __user *,
 #define _TIF_SYSCALL_AUDIT	(1 << TIF_SYSCALL_AUDIT)
 #define _TIF_SYSCALL_TRACEPOINT	(1 << TIF_SYSCALL_TRACEPOINT)
 #define _TIF_SECCOMP		(1 << TIF_SECCOMP)
+#define _TIF_SYSCALL_EMU	(1 << TIF_SYSCALL_EMU)
 #define _TIF_USING_IWMMXT	(1 << TIF_USING_IWMMXT)
 
 /* Checks for any syscall work in entry-common.S */
 #define _TIF_SYSCALL_WORK (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \
-			   _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP)
+			   _TIF_SYSCALL_TRACEPOINT | _TIF_SECCOMP | \
+			   _TIF_SYSCALL_EMU)
 
 /*
  * Change these and you break ASM code in entry-common.S
diff --git a/arch/arm/include/uapi/asm/ptrace.h b/arch/arm/include/uapi/asm/ptrace.h
index 5af0ed1..2c5e4d7 100644
--- a/arch/arm/include/uapi/asm/ptrace.h
+++ b/arch/arm/include/uapi/asm/ptrace.h
@@ -12,25 +12,27 @@
 
 #include <asm/hwcap.h>
 
-#define PTRACE_GETREGS		12
-#define PTRACE_SETREGS		13
-#define PTRACE_GETFPREGS	14
-#define PTRACE_SETFPREGS	15
+#define PTRACE_GETREGS			12
+#define PTRACE_SETREGS			13
+#define PTRACE_GETFPREGS		14
+#define PTRACE_SETFPREGS		15
 /* PTRACE_ATTACH is 16 */
 /* PTRACE_DETACH is 17 */
-#define PTRACE_GETWMMXREGS	18
-#define PTRACE_SETWMMXREGS	19
+#define PTRACE_GETWMMXREGS		18
+#define PTRACE_SETWMMXREGS		19
 /* 20 is unused */
-#define PTRACE_OLDSETOPTIONS	21
-#define PTRACE_GET_THREAD_AREA	22
-#define PTRACE_SET_SYSCALL	23
+#define PTRACE_OLDSETOPTIONS		21
+#define PTRACE_GET_THREAD_AREA		22
+#define PTRACE_SET_SYSCALL		23
 /* PTRACE_SYSCALL is 24 */
-#define PTRACE_GETCRUNCHREGS	25
-#define PTRACE_SETCRUNCHREGS	26
-#define PTRACE_GETVFPREGS	27
-#define PTRACE_SETVFPREGS	28
-#define PTRACE_GETHBPREGS	29
-#define PTRACE_SETHBPREGS	30
+#define PTRACE_GETCRUNCHREGS		25
+#define PTRACE_SETCRUNCHREGS		26
+#define PTRACE_GETVFPREGS		27
+#define PTRACE_SETVFPREGS		28
+#define PTRACE_GETHBPREGS		29
+#define PTRACE_SETHBPREGS		30
+#define PTRACE_SYSEMU			31
+#define PTRACE_SYSEMU_SINGLESTEP	32
 
 /*
  * PSR bits
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index ef9119f..c84058c 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -930,6 +930,8 @@ static void tracehook_report_syscall(struct pt_regs *regs,
 
 asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
 {
+	int ret = 0;
+
 	current_thread_info()->syscall = scno;
 
 	/* Do the secure computing check first; failures should be fast. */
@@ -941,7 +943,10 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
 	secure_computing_strict(scno);
 #endif
 
-	if (test_thread_flag(TIF_SYSCALL_TRACE))
+	if (test_thread_flag(TIF_SYSCALL_EMU))
+		ret = -1;
+
+	if (ret || test_thread_flag(TIF_SYSCALL_TRACE))
 		tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
 
 	scno = current_thread_info()->syscall;
@@ -952,7 +957,7 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
 	audit_syscall_entry(scno, regs->ARM_r0, regs->ARM_r1, regs->ARM_r2,
 			    regs->ARM_r3);
 
-	return scno;
+	return ret ?: scno;
 }
 
 asmlinkage void syscall_trace_exit(struct pt_regs *regs)
-- 
1.9.1




More information about the linux-arm-kernel mailing list