diff options
Diffstat (limited to 'arch/xtensa/kernel/ptrace.c')
-rw-r--r-- | arch/xtensa/kernel/ptrace.c | 30 |
1 files changed, 19 insertions, 11 deletions
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c index b4c07bd890fe..bb3f4797d212 100644 --- a/arch/xtensa/kernel/ptrace.c +++ b/arch/xtensa/kernel/ptrace.c @@ -12,6 +12,7 @@ * Marc Gauthier<marc@tensilica.com> <marc@alumni.uwaterloo.ca> */ +#include <linux/audit.h> #include <linux/errno.h> #include <linux/hw_breakpoint.h> #include <linux/kernel.h> @@ -21,6 +22,7 @@ #include <linux/regset.h> #include <linux/sched.h> #include <linux/sched/task_stack.h> +#include <linux/seccomp.h> #include <linux/security.h> #include <linux/signal.h> #include <linux/smp.h> @@ -37,8 +39,7 @@ static int gpr_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { struct pt_regs *regs = task_pt_regs(target); struct user_pt_regs newregs = { @@ -51,6 +52,7 @@ static int gpr_get(struct task_struct *target, .threadptr = regs->threadptr, .windowbase = regs->windowbase, .windowstart = regs->windowstart, + .syscall = regs->syscall, }; memcpy(newregs.a, @@ -60,8 +62,7 @@ static int gpr_get(struct task_struct *target, regs->areg, (WSBITS - regs->windowbase) * 16); - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &newregs, 0, -1); + return membuf_write(&to, &newregs, sizeof(newregs)); } static int gpr_set(struct task_struct *target, @@ -90,6 +91,9 @@ static int gpr_set(struct task_struct *target, regs->sar = newregs.sar; regs->threadptr = newregs.threadptr; + if (newregs.syscall) + regs->syscall = newregs.syscall; + if (newregs.windowbase != regs->windowbase || newregs.windowstart != regs->windowstart) { u32 rotws, wmask; @@ -115,8 +119,7 @@ static int gpr_set(struct task_struct *target, static int tie_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { int ret; struct pt_regs *regs = task_pt_regs(target); @@ -141,8 +144,7 @@ static int tie_get(struct task_struct *target, newregs->cp6 = ti->xtregs_cp.cp6; newregs->cp7 = ti->xtregs_cp.cp7; #endif - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - newregs, 0, -1); + ret = membuf_write(&to, newregs, sizeof(*newregs)); kfree(newregs); return ret; } @@ -197,7 +199,7 @@ static const struct user_regset xtensa_regsets[] = { .n = sizeof(struct user_pt_regs) / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), - .get = gpr_get, + .regset_get = gpr_get, .set = gpr_set, }, [REGSET_TIE] = { @@ -205,7 +207,7 @@ static const struct user_regset xtensa_regsets[] = { .n = sizeof(elf_xtregs_t) / sizeof(u32), .size = sizeof(u32), .align = sizeof(u32), - .get = tie_get, + .regset_get = tie_get, .set = tie_set, }, }; @@ -554,7 +556,8 @@ int do_syscall_trace_enter(struct pt_regs *regs) return 0; } - if (regs->syscall == NO_SYSCALL) { + if (regs->syscall == NO_SYSCALL || + secure_computing() == -1) { do_syscall_trace_leave(regs); return 0; } @@ -562,6 +565,9 @@ int do_syscall_trace_enter(struct pt_regs *regs) if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) trace_sys_enter(regs, syscall_get_nr(current, regs)); + audit_syscall_entry(regs->syscall, regs->areg[6], + regs->areg[3], regs->areg[4], + regs->areg[5]); return 1; } @@ -569,6 +575,8 @@ void do_syscall_trace_leave(struct pt_regs *regs) { int step; + audit_syscall_exit(regs); + if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) trace_sys_exit(regs, regs_return_value(regs)); |