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