cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ptrace.c (12565B)


      1/*
      2 *  PowerPC version
      3 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
      4 *
      5 *  Derived from "arch/m68k/kernel/ptrace.c"
      6 *  Copyright (C) 1994 by Hamish Macdonald
      7 *  Taken from linux/kernel/ptrace.c and modified for M680x0.
      8 *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds
      9 *
     10 * Modified by Cort Dougan (cort@hq.fsmlabs.com)
     11 * and Paul Mackerras (paulus@samba.org).
     12 *
     13 * This file is subject to the terms and conditions of the GNU General
     14 * Public License.  See the file README.legal in the main directory of
     15 * this archive for more details.
     16 */
     17
     18#include <linux/regset.h>
     19#include <linux/ptrace.h>
     20#include <linux/audit.h>
     21#include <linux/context_tracking.h>
     22#include <linux/syscalls.h>
     23
     24#include <asm/switch_to.h>
     25#include <asm/debug.h>
     26
     27#define CREATE_TRACE_POINTS
     28#include <trace/events/syscalls.h>
     29
     30#include "ptrace-decl.h"
     31
     32/*
     33 * Called by kernel/ptrace.c when detaching..
     34 *
     35 * Make sure single step bits etc are not set.
     36 */
     37void ptrace_disable(struct task_struct *child)
     38{
     39	/* make sure the single step bit is not set. */
     40	user_disable_single_step(child);
     41}
     42
     43long arch_ptrace(struct task_struct *child, long request,
     44		 unsigned long addr, unsigned long data)
     45{
     46	int ret = -EPERM;
     47	void __user *datavp = (void __user *) data;
     48	unsigned long __user *datalp = datavp;
     49
     50	switch (request) {
     51	/* read the word at location addr in the USER area. */
     52	case PTRACE_PEEKUSR: {
     53		unsigned long index, tmp;
     54
     55		ret = -EIO;
     56		/* convert to index and check */
     57		index = addr / sizeof(long);
     58		if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
     59			break;
     60
     61		if (index < PT_FPR0)
     62			ret = ptrace_get_reg(child, (int) index, &tmp);
     63		else
     64			ret = ptrace_get_fpr(child, index, &tmp);
     65
     66		if (ret)
     67			break;
     68		ret = put_user(tmp, datalp);
     69		break;
     70	}
     71
     72	/* write the word at location addr in the USER area */
     73	case PTRACE_POKEUSR: {
     74		unsigned long index;
     75
     76		ret = -EIO;
     77		/* convert to index and check */
     78		index = addr / sizeof(long);
     79		if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
     80			break;
     81
     82		if (index < PT_FPR0)
     83			ret = ptrace_put_reg(child, index, data);
     84		else
     85			ret = ptrace_put_fpr(child, index, data);
     86		break;
     87	}
     88
     89	case PPC_PTRACE_GETHWDBGINFO: {
     90		struct ppc_debug_info dbginfo;
     91
     92		ppc_gethwdinfo(&dbginfo);
     93
     94		if (copy_to_user(datavp, &dbginfo,
     95				 sizeof(struct ppc_debug_info)))
     96			return -EFAULT;
     97		return 0;
     98	}
     99
    100	case PPC_PTRACE_SETHWDEBUG: {
    101		struct ppc_hw_breakpoint bp_info;
    102
    103		if (copy_from_user(&bp_info, datavp,
    104				   sizeof(struct ppc_hw_breakpoint)))
    105			return -EFAULT;
    106		return ppc_set_hwdebug(child, &bp_info);
    107	}
    108
    109	case PPC_PTRACE_DELHWDEBUG: {
    110		ret = ppc_del_hwdebug(child, data);
    111		break;
    112	}
    113
    114	case PTRACE_GET_DEBUGREG:
    115		ret = ptrace_get_debugreg(child, addr, datalp);
    116		break;
    117
    118	case PTRACE_SET_DEBUGREG:
    119		ret = ptrace_set_debugreg(child, addr, data);
    120		break;
    121
    122#ifdef CONFIG_PPC64
    123	case PTRACE_GETREGS64:
    124#endif
    125	case PTRACE_GETREGS:	/* Get all pt_regs from the child. */
    126		return copy_regset_to_user(child, &user_ppc_native_view,
    127					   REGSET_GPR,
    128					   0, sizeof(struct user_pt_regs),
    129					   datavp);
    130
    131#ifdef CONFIG_PPC64
    132	case PTRACE_SETREGS64:
    133#endif
    134	case PTRACE_SETREGS:	/* Set all gp regs in the child. */
    135		return copy_regset_from_user(child, &user_ppc_native_view,
    136					     REGSET_GPR,
    137					     0, sizeof(struct user_pt_regs),
    138					     datavp);
    139
    140	case PTRACE_GETFPREGS: /* Get the child FPU state (FPR0...31 + FPSCR) */
    141		return copy_regset_to_user(child, &user_ppc_native_view,
    142					   REGSET_FPR,
    143					   0, sizeof(elf_fpregset_t),
    144					   datavp);
    145
    146	case PTRACE_SETFPREGS: /* Set the child FPU state (FPR0...31 + FPSCR) */
    147		return copy_regset_from_user(child, &user_ppc_native_view,
    148					     REGSET_FPR,
    149					     0, sizeof(elf_fpregset_t),
    150					     datavp);
    151
    152#ifdef CONFIG_ALTIVEC
    153	case PTRACE_GETVRREGS:
    154		return copy_regset_to_user(child, &user_ppc_native_view,
    155					   REGSET_VMX,
    156					   0, (33 * sizeof(vector128) +
    157					       sizeof(u32)),
    158					   datavp);
    159
    160	case PTRACE_SETVRREGS:
    161		return copy_regset_from_user(child, &user_ppc_native_view,
    162					     REGSET_VMX,
    163					     0, (33 * sizeof(vector128) +
    164						 sizeof(u32)),
    165					     datavp);
    166#endif
    167#ifdef CONFIG_VSX
    168	case PTRACE_GETVSRREGS:
    169		return copy_regset_to_user(child, &user_ppc_native_view,
    170					   REGSET_VSX,
    171					   0, 32 * sizeof(double),
    172					   datavp);
    173
    174	case PTRACE_SETVSRREGS:
    175		return copy_regset_from_user(child, &user_ppc_native_view,
    176					     REGSET_VSX,
    177					     0, 32 * sizeof(double),
    178					     datavp);
    179#endif
    180#ifdef CONFIG_SPE
    181	case PTRACE_GETEVRREGS:
    182		/* Get the child spe register state. */
    183		return copy_regset_to_user(child, &user_ppc_native_view,
    184					   REGSET_SPE, 0, 35 * sizeof(u32),
    185					   datavp);
    186
    187	case PTRACE_SETEVRREGS:
    188		/* Set the child spe register state. */
    189		return copy_regset_from_user(child, &user_ppc_native_view,
    190					     REGSET_SPE, 0, 35 * sizeof(u32),
    191					     datavp);
    192#endif
    193
    194	default:
    195		ret = ptrace_request(child, request, addr, data);
    196		break;
    197	}
    198	return ret;
    199}
    200
    201#ifdef CONFIG_SECCOMP
    202static int do_seccomp(struct pt_regs *regs)
    203{
    204	if (!test_thread_flag(TIF_SECCOMP))
    205		return 0;
    206
    207	/*
    208	 * The ABI we present to seccomp tracers is that r3 contains
    209	 * the syscall return value and orig_gpr3 contains the first
    210	 * syscall parameter. This is different to the ptrace ABI where
    211	 * both r3 and orig_gpr3 contain the first syscall parameter.
    212	 */
    213	regs->gpr[3] = -ENOSYS;
    214
    215	/*
    216	 * We use the __ version here because we have already checked
    217	 * TIF_SECCOMP. If this fails, there is nothing left to do, we
    218	 * have already loaded -ENOSYS into r3, or seccomp has put
    219	 * something else in r3 (via SECCOMP_RET_ERRNO/TRACE).
    220	 */
    221	if (__secure_computing(NULL))
    222		return -1;
    223
    224	/*
    225	 * The syscall was allowed by seccomp, restore the register
    226	 * state to what audit expects.
    227	 * Note that we use orig_gpr3, which means a seccomp tracer can
    228	 * modify the first syscall parameter (in orig_gpr3) and also
    229	 * allow the syscall to proceed.
    230	 */
    231	regs->gpr[3] = regs->orig_gpr3;
    232
    233	return 0;
    234}
    235#else
    236static inline int do_seccomp(struct pt_regs *regs) { return 0; }
    237#endif /* CONFIG_SECCOMP */
    238
    239/**
    240 * do_syscall_trace_enter() - Do syscall tracing on kernel entry.
    241 * @regs: the pt_regs of the task to trace (current)
    242 *
    243 * Performs various types of tracing on syscall entry. This includes seccomp,
    244 * ptrace, syscall tracepoints and audit.
    245 *
    246 * The pt_regs are potentially visible to userspace via ptrace, so their
    247 * contents is ABI.
    248 *
    249 * One or more of the tracers may modify the contents of pt_regs, in particular
    250 * to modify arguments or even the syscall number itself.
    251 *
    252 * It's also possible that a tracer can choose to reject the system call. In
    253 * that case this function will return an illegal syscall number, and will put
    254 * an appropriate return value in regs->r3.
    255 *
    256 * Return: the (possibly changed) syscall number.
    257 */
    258long do_syscall_trace_enter(struct pt_regs *regs)
    259{
    260	u32 flags;
    261
    262	flags = read_thread_flags() & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
    263
    264	if (flags) {
    265		int rc = ptrace_report_syscall_entry(regs);
    266
    267		if (unlikely(flags & _TIF_SYSCALL_EMU)) {
    268			/*
    269			 * A nonzero return code from
    270			 * ptrace_report_syscall_entry() tells us to prevent
    271			 * the syscall execution, but we are not going to
    272			 * execute it anyway.
    273			 *
    274			 * Returning -1 will skip the syscall execution. We want
    275			 * to avoid clobbering any registers, so we don't goto
    276			 * the skip label below.
    277			 */
    278			return -1;
    279		}
    280
    281		if (rc) {
    282			/*
    283			 * The tracer decided to abort the syscall. Note that
    284			 * the tracer may also just change regs->gpr[0] to an
    285			 * invalid syscall number, that is handled below on the
    286			 * exit path.
    287			 */
    288			goto skip;
    289		}
    290	}
    291
    292	/* Run seccomp after ptrace; allow it to set gpr[3]. */
    293	if (do_seccomp(regs))
    294		return -1;
    295
    296	/* Avoid trace and audit when syscall is invalid. */
    297	if (regs->gpr[0] >= NR_syscalls)
    298		goto skip;
    299
    300	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
    301		trace_sys_enter(regs, regs->gpr[0]);
    302
    303	if (!is_32bit_task())
    304		audit_syscall_entry(regs->gpr[0], regs->gpr[3], regs->gpr[4],
    305				    regs->gpr[5], regs->gpr[6]);
    306	else
    307		audit_syscall_entry(regs->gpr[0],
    308				    regs->gpr[3] & 0xffffffff,
    309				    regs->gpr[4] & 0xffffffff,
    310				    regs->gpr[5] & 0xffffffff,
    311				    regs->gpr[6] & 0xffffffff);
    312
    313	/* Return the possibly modified but valid syscall number */
    314	return regs->gpr[0];
    315
    316skip:
    317	/*
    318	 * If we are aborting explicitly, or if the syscall number is
    319	 * now invalid, set the return value to -ENOSYS.
    320	 */
    321	regs->gpr[3] = -ENOSYS;
    322	return -1;
    323}
    324
    325void do_syscall_trace_leave(struct pt_regs *regs)
    326{
    327	int step;
    328
    329	audit_syscall_exit(regs);
    330
    331	if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
    332		trace_sys_exit(regs, regs->result);
    333
    334	step = test_thread_flag(TIF_SINGLESTEP);
    335	if (step || test_thread_flag(TIF_SYSCALL_TRACE))
    336		ptrace_report_syscall_exit(regs, step);
    337}
    338
    339void __init pt_regs_check(void);
    340
    341/*
    342 * Dummy function, its purpose is to break the build if struct pt_regs and
    343 * struct user_pt_regs don't match.
    344 */
    345void __init pt_regs_check(void)
    346{
    347	BUILD_BUG_ON(offsetof(struct pt_regs, gpr) !=
    348		     offsetof(struct user_pt_regs, gpr));
    349	BUILD_BUG_ON(offsetof(struct pt_regs, nip) !=
    350		     offsetof(struct user_pt_regs, nip));
    351	BUILD_BUG_ON(offsetof(struct pt_regs, msr) !=
    352		     offsetof(struct user_pt_regs, msr));
    353	BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
    354		     offsetof(struct user_pt_regs, orig_gpr3));
    355	BUILD_BUG_ON(offsetof(struct pt_regs, ctr) !=
    356		     offsetof(struct user_pt_regs, ctr));
    357	BUILD_BUG_ON(offsetof(struct pt_regs, link) !=
    358		     offsetof(struct user_pt_regs, link));
    359	BUILD_BUG_ON(offsetof(struct pt_regs, xer) !=
    360		     offsetof(struct user_pt_regs, xer));
    361	BUILD_BUG_ON(offsetof(struct pt_regs, ccr) !=
    362		     offsetof(struct user_pt_regs, ccr));
    363#ifdef __powerpc64__
    364	BUILD_BUG_ON(offsetof(struct pt_regs, softe) !=
    365		     offsetof(struct user_pt_regs, softe));
    366#else
    367	BUILD_BUG_ON(offsetof(struct pt_regs, mq) !=
    368		     offsetof(struct user_pt_regs, mq));
    369#endif
    370	BUILD_BUG_ON(offsetof(struct pt_regs, trap) !=
    371		     offsetof(struct user_pt_regs, trap));
    372	BUILD_BUG_ON(offsetof(struct pt_regs, dar) !=
    373		     offsetof(struct user_pt_regs, dar));
    374	BUILD_BUG_ON(offsetof(struct pt_regs, dear) !=
    375		     offsetof(struct user_pt_regs, dar));
    376	BUILD_BUG_ON(offsetof(struct pt_regs, dsisr) !=
    377		     offsetof(struct user_pt_regs, dsisr));
    378	BUILD_BUG_ON(offsetof(struct pt_regs, esr) !=
    379		     offsetof(struct user_pt_regs, dsisr));
    380	BUILD_BUG_ON(offsetof(struct pt_regs, result) !=
    381		     offsetof(struct user_pt_regs, result));
    382
    383	BUILD_BUG_ON(sizeof(struct user_pt_regs) > sizeof(struct pt_regs));
    384
    385	// Now check that the pt_regs offsets match the uapi #defines
    386	#define CHECK_REG(_pt, _reg) \
    387		BUILD_BUG_ON(_pt != (offsetof(struct user_pt_regs, _reg) / \
    388				     sizeof(unsigned long)));
    389
    390	CHECK_REG(PT_R0,  gpr[0]);
    391	CHECK_REG(PT_R1,  gpr[1]);
    392	CHECK_REG(PT_R2,  gpr[2]);
    393	CHECK_REG(PT_R3,  gpr[3]);
    394	CHECK_REG(PT_R4,  gpr[4]);
    395	CHECK_REG(PT_R5,  gpr[5]);
    396	CHECK_REG(PT_R6,  gpr[6]);
    397	CHECK_REG(PT_R7,  gpr[7]);
    398	CHECK_REG(PT_R8,  gpr[8]);
    399	CHECK_REG(PT_R9,  gpr[9]);
    400	CHECK_REG(PT_R10, gpr[10]);
    401	CHECK_REG(PT_R11, gpr[11]);
    402	CHECK_REG(PT_R12, gpr[12]);
    403	CHECK_REG(PT_R13, gpr[13]);
    404	CHECK_REG(PT_R14, gpr[14]);
    405	CHECK_REG(PT_R15, gpr[15]);
    406	CHECK_REG(PT_R16, gpr[16]);
    407	CHECK_REG(PT_R17, gpr[17]);
    408	CHECK_REG(PT_R18, gpr[18]);
    409	CHECK_REG(PT_R19, gpr[19]);
    410	CHECK_REG(PT_R20, gpr[20]);
    411	CHECK_REG(PT_R21, gpr[21]);
    412	CHECK_REG(PT_R22, gpr[22]);
    413	CHECK_REG(PT_R23, gpr[23]);
    414	CHECK_REG(PT_R24, gpr[24]);
    415	CHECK_REG(PT_R25, gpr[25]);
    416	CHECK_REG(PT_R26, gpr[26]);
    417	CHECK_REG(PT_R27, gpr[27]);
    418	CHECK_REG(PT_R28, gpr[28]);
    419	CHECK_REG(PT_R29, gpr[29]);
    420	CHECK_REG(PT_R30, gpr[30]);
    421	CHECK_REG(PT_R31, gpr[31]);
    422	CHECK_REG(PT_NIP, nip);
    423	CHECK_REG(PT_MSR, msr);
    424	CHECK_REG(PT_ORIG_R3, orig_gpr3);
    425	CHECK_REG(PT_CTR, ctr);
    426	CHECK_REG(PT_LNK, link);
    427	CHECK_REG(PT_XER, xer);
    428	CHECK_REG(PT_CCR, ccr);
    429#ifdef CONFIG_PPC64
    430	CHECK_REG(PT_SOFTE, softe);
    431#else
    432	CHECK_REG(PT_MQ, mq);
    433#endif
    434	CHECK_REG(PT_TRAP, trap);
    435	CHECK_REG(PT_DAR, dar);
    436	CHECK_REG(PT_DSISR, dsisr);
    437	CHECK_REG(PT_RESULT, result);
    438	#undef CHECK_REG
    439
    440	BUILD_BUG_ON(PT_REGS_COUNT != sizeof(struct user_pt_regs) / sizeof(unsigned long));
    441
    442	/*
    443	 * PT_DSCR isn't a real reg, but it's important that it doesn't overlap the
    444	 * real registers.
    445	 */
    446	BUILD_BUG_ON(PT_DSCR < sizeof(struct user_pt_regs) / sizeof(unsigned long));
    447
    448	// ptrace_get/put_fpr() rely on PPC32 and VSX being incompatible
    449	BUILD_BUG_ON(IS_ENABLED(CONFIG_PPC32) && IS_ENABLED(CONFIG_VSX));
    450}