diff options
Diffstat (limited to 'arch/sh/kernel/ptrace_32.c')
| -rw-r--r-- | arch/sh/kernel/ptrace_32.c | 108 |
1 files changed, 30 insertions, 78 deletions
diff --git a/arch/sh/kernel/ptrace_32.c b/arch/sh/kernel/ptrace_32.c index 668c81631c08..06f765d71a29 100644 --- a/arch/sh/kernel/ptrace_32.c +++ b/arch/sh/kernel/ptrace_32.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0 /* * SuperH process tracing * @@ -5,13 +6,10 @@ * Copyright (C) 2002 - 2009 Paul Mundt * * Audit support by Yuichi Nakamura <ynakam@hitachisoft.jp> - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. */ #include <linux/kernel.h> #include <linux/sched.h> +#include <linux/sched/task_stack.h> #include <linux/mm.h> #include <linux/smp.h> #include <linux/errno.h> @@ -22,12 +20,10 @@ #include <linux/io.h> #include <linux/audit.h> #include <linux/seccomp.h> -#include <linux/tracehook.h> #include <linux/elf.h> #include <linux/regset.h> #include <linux/hw_breakpoint.h> -#include <asm/uaccess.h> -#include <asm/pgtable.h> +#include <linux/uaccess.h> #include <asm/processor.h> #include <asm/mmu_context.h> #include <asm/syscalls.h> @@ -137,26 +133,11 @@ void ptrace_disable(struct task_struct *child) static int genregs_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { const struct pt_regs *regs = task_pt_regs(target); - int ret; - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - regs->regs, - 0, 16 * sizeof(unsigned long)); - if (!ret) - /* PC, PR, SR, GBR, MACH, MACL, TRA */ - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, - ®s->pc, - offsetof(struct pt_regs, pc), - sizeof(struct pt_regs)); - if (!ret) - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - sizeof(struct pt_regs), -1); - - return ret; + return membuf_write(&to, regs, sizeof(struct pt_regs)); } static int genregs_set(struct task_struct *target, @@ -176,17 +157,16 @@ static int genregs_set(struct task_struct *target, offsetof(struct pt_regs, pc), sizeof(struct pt_regs)); if (!ret) - ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, - sizeof(struct pt_regs), -1); + user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + sizeof(struct pt_regs), -1); return ret; } #ifdef CONFIG_SH_FPU -int fpregs_get(struct task_struct *target, +static int fpregs_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; @@ -194,12 +174,8 @@ int fpregs_get(struct task_struct *target, if (ret) return ret; - if ((boot_cpu_data.flags & CPU_HAS_FPU)) - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.xstate->hardfpu, 0, -1); - - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, - &target->thread.xstate->softfpu, 0, -1); + return membuf_write(&to, target->thread.xstate, + sizeof(struct user_fpu_struct)); } static int fpregs_set(struct task_struct *target, @@ -233,20 +209,12 @@ static int fpregs_active(struct task_struct *target, #ifdef CONFIG_SH_DSP static int dspregs_get(struct task_struct *target, const struct user_regset *regset, - unsigned int pos, unsigned int count, - void *kbuf, void __user *ubuf) + struct membuf to) { const struct pt_dspregs *regs = (struct pt_dspregs *)&target->thread.dsp_status.dsp_regs; - int ret; - - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, regs, - 0, sizeof(struct pt_dspregs)); - if (!ret) - ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf, - sizeof(struct pt_dspregs), -1); - return ret; + return membuf_write(&to, regs, sizeof(struct pt_dspregs)); } static int dspregs_set(struct task_struct *target, @@ -261,8 +229,8 @@ static int dspregs_set(struct task_struct *target, ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, regs, 0, sizeof(struct pt_dspregs)); if (!ret) - ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, - sizeof(struct pt_dspregs), -1); + user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf, + sizeof(struct pt_dspregs), -1); return ret; } @@ -323,21 +291,21 @@ static const struct user_regset sh_regsets[] = { * PC, PR, SR, GBR, MACH, MACL, TRA */ [REGSET_GENERAL] = { - .core_note_type = NT_PRSTATUS, + USER_REGSET_NOTE_TYPE(PRSTATUS), .n = ELF_NGREG, .size = sizeof(long), .align = sizeof(long), - .get = genregs_get, + .regset_get = genregs_get, .set = genregs_set, }, #ifdef CONFIG_SH_FPU [REGSET_FPU] = { - .core_note_type = NT_PRFPREG, + USER_REGSET_NOTE_TYPE(PRFPREG), .n = sizeof(struct user_fpu_struct) / sizeof(long), .size = sizeof(long), .align = sizeof(long), - .get = fpregs_get, + .regset_get = fpregs_get, .set = fpregs_set, .active = fpregs_active, }, @@ -348,7 +316,7 @@ static const struct user_regset sh_regsets[] = { .n = sizeof(struct pt_dspregs) / sizeof(long), .size = sizeof(long), .align = sizeof(long), - .get = dspregs_get, + .regset_get = dspregs_get, .set = dspregs_set, .active = dspregs_active, }, @@ -484,40 +452,24 @@ long arch_ptrace(struct task_struct *child, long request, return ret; } -static inline int audit_arch(void) -{ - int arch = EM_SH; - -#ifdef CONFIG_CPU_LITTLE_ENDIAN - arch |= __AUDIT_ARCH_LE; -#endif - - return arch; -} - asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { - long ret = 0; - - secure_computing_strict(regs->regs[0]); - if (test_thread_flag(TIF_SYSCALL_TRACE) && - tracehook_report_syscall_entry(regs)) - /* - * Tracing decided this syscall should not happen. - * We'll return a bogus call number to get an ENOSYS - * error, but leave the original number in regs->regs[0]. - */ - ret = -1L; + ptrace_report_syscall_entry(regs)) { + regs->regs[0] = -ENOSYS; + return -1; + } + + if (secure_computing() == -1) + return -1; if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) trace_sys_enter(regs, regs->regs[0]); - audit_syscall_entry(audit_arch(), regs->regs[3], - regs->regs[4], regs->regs[5], + audit_syscall_entry(regs->regs[3], regs->regs[4], regs->regs[5], regs->regs[6], regs->regs[7]); - return ret ?: regs->regs[0]; + return 0; } asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) @@ -531,5 +483,5 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs) step = test_thread_flag(TIF_SINGLESTEP); if (step || test_thread_flag(TIF_SYSCALL_TRACE)) - tracehook_report_syscall_exit(regs, step); + ptrace_report_syscall_exit(regs, step); } |
