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