aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm64/kernel/ptrace.c')
-rw-r--r--arch/arm64/kernel/ptrace.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
index 8a4ae8e73213..d882b833dbdb 100644
--- a/arch/arm64/kernel/ptrace.c
+++ b/arch/arm64/kernel/ptrace.c
@@ -27,6 +27,7 @@
27#include <linux/smp.h> 27#include <linux/smp.h>
28#include <linux/ptrace.h> 28#include <linux/ptrace.h>
29#include <linux/user.h> 29#include <linux/user.h>
30#include <linux/seccomp.h>
30#include <linux/security.h> 31#include <linux/security.h>
31#include <linux/init.h> 32#include <linux/init.h>
32#include <linux/signal.h> 33#include <linux/signal.h>
@@ -551,6 +552,32 @@ static int tls_set(struct task_struct *target, const struct user_regset *regset,
551 return ret; 552 return ret;
552} 553}
553 554
555static int system_call_get(struct task_struct *target,
556 const struct user_regset *regset,
557 unsigned int pos, unsigned int count,
558 void *kbuf, void __user *ubuf)
559{
560 int syscallno = task_pt_regs(target)->syscallno;
561
562 return user_regset_copyout(&pos, &count, &kbuf, &ubuf,
563 &syscallno, 0, -1);
564}
565
566static int system_call_set(struct task_struct *target,
567 const struct user_regset *regset,
568 unsigned int pos, unsigned int count,
569 const void *kbuf, const void __user *ubuf)
570{
571 int syscallno, ret;
572
573 ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &syscallno, 0, -1);
574 if (ret)
575 return ret;
576
577 task_pt_regs(target)->syscallno = syscallno;
578 return ret;
579}
580
554enum aarch64_regset { 581enum aarch64_regset {
555 REGSET_GPR, 582 REGSET_GPR,
556 REGSET_FPR, 583 REGSET_FPR,
@@ -559,6 +586,7 @@ enum aarch64_regset {
559 REGSET_HW_BREAK, 586 REGSET_HW_BREAK,
560 REGSET_HW_WATCH, 587 REGSET_HW_WATCH,
561#endif 588#endif
589 REGSET_SYSTEM_CALL,
562}; 590};
563 591
564static const struct user_regset aarch64_regsets[] = { 592static const struct user_regset aarch64_regsets[] = {
@@ -608,6 +636,14 @@ static const struct user_regset aarch64_regsets[] = {
608 .set = hw_break_set, 636 .set = hw_break_set,
609 }, 637 },
610#endif 638#endif
639 [REGSET_SYSTEM_CALL] = {
640 .core_note_type = NT_ARM_SYSTEM_CALL,
641 .n = 1,
642 .size = sizeof(int),
643 .align = sizeof(int),
644 .get = system_call_get,
645 .set = system_call_set,
646 },
611}; 647};
612 648
613static const struct user_regset_view user_aarch64_view = { 649static const struct user_regset_view user_aarch64_view = {
@@ -1114,6 +1150,10 @@ static void tracehook_report_syscall(struct pt_regs *regs,
1114 1150
1115asmlinkage int syscall_trace_enter(struct pt_regs *regs) 1151asmlinkage int syscall_trace_enter(struct pt_regs *regs)
1116{ 1152{
1153 /* Do the secure computing check first; failures should be fast. */
1154 if (secure_computing() == -1)
1155 return -1;
1156
1117 if (test_thread_flag(TIF_SYSCALL_TRACE)) 1157 if (test_thread_flag(TIF_SYSCALL_TRACE))
1118 tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER); 1158 tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
1119 1159