linux/kernel/ptrace.c
<<
>>
Prefs
   1/*
   2 * linux/kernel/ptrace.c
   3 *
   4 * (C) Copyright 1999 Linus Torvalds
   5 *
   6 * Common interfaces for "ptrace()" which we do not want
   7 * to continually duplicate across every architecture.
   8 */
   9
  10#include <linux/capability.h>
  11#include <linux/module.h>
  12#include <linux/sched.h>
  13#include <linux/errno.h>
  14#include <linux/mm.h>
  15#include <linux/highmem.h>
  16#include <linux/pagemap.h>
  17#include <linux/smp_lock.h>
  18#include <linux/ptrace.h>
  19#include <linux/security.h>
  20#include <linux/signal.h>
  21#include <linux/audit.h>
  22#include <linux/pid_namespace.h>
  23#include <linux/syscalls.h>
  24#include <linux/uaccess.h>
  25
  26
  27/*
  28 * Initialize a new task whose father had been ptraced.
  29 *
  30 * Called from copy_process().
  31 */
  32void ptrace_fork(struct task_struct *child, unsigned long clone_flags)
  33{
  34        arch_ptrace_fork(child, clone_flags);
  35}
  36
  37/*
  38 * ptrace a task: make the debugger its new parent and
  39 * move it to the ptrace list.
  40 *
  41 * Must be called with the tasklist lock write-held.
  42 */
  43void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
  44{
  45        BUG_ON(!list_empty(&child->ptrace_entry));
  46        list_add(&child->ptrace_entry, &new_parent->ptraced);
  47        child->parent = new_parent;
  48}
  49
  50/*
  51 * Turn a tracing stop into a normal stop now, since with no tracer there
  52 * would be no way to wake it up with SIGCONT or SIGKILL.  If there was a
  53 * signal sent that would resume the child, but didn't because it was in
  54 * TASK_TRACED, resume it now.
  55 * Requires that irqs be disabled.
  56 */
  57static void ptrace_untrace(struct task_struct *child)
  58{
  59        spin_lock(&child->sighand->siglock);
  60        if (task_is_traced(child)) {
  61                /*
  62                 * If the group stop is completed or in progress,
  63                 * this thread was already counted as stopped.
  64                 */
  65                if (child->signal->flags & SIGNAL_STOP_STOPPED ||
  66                    child->signal->group_stop_count)
  67                        __set_task_state(child, TASK_STOPPED);
  68                else
  69                        signal_wake_up(child, 1);
  70        }
  71        spin_unlock(&child->sighand->siglock);
  72}
  73
  74/*
  75 * unptrace a task: move it back to its original parent and
  76 * remove it from the ptrace list.
  77 *
  78 * Must be called with the tasklist lock write-held.
  79 */
  80void __ptrace_unlink(struct task_struct *child)
  81{
  82        BUG_ON(!child->ptrace);
  83
  84        child->ptrace = 0;
  85        child->parent = child->real_parent;
  86        list_del_init(&child->ptrace_entry);
  87
  88        arch_ptrace_untrace(child);
  89        if (task_is_traced(child))
  90                ptrace_untrace(child);
  91}
  92
  93/*
  94 * Check that we have indeed attached to the thing..
  95 */
  96int ptrace_check_attach(struct task_struct *child, int kill)
  97{
  98        int ret = -ESRCH;
  99
 100        /*
 101         * We take the read lock around doing both checks to close a
 102         * possible race where someone else was tracing our child and
 103         * detached between these two checks.  After this locked check,
 104         * we are sure that this is our traced child and that can only
 105         * be changed by us so it's not changing right after this.
 106         */
 107        read_lock(&tasklist_lock);
 108        if ((child->ptrace & PT_PTRACED) && child->parent == current) {
 109                ret = 0;
 110                /*
 111                 * child->sighand can't be NULL, release_task()
 112                 * does ptrace_unlink() before __exit_signal().
 113                 */
 114                spin_lock_irq(&child->sighand->siglock);
 115                if (task_is_stopped(child))
 116                        child->state = TASK_TRACED;
 117                else if (!task_is_traced(child) && !kill)
 118                        ret = -ESRCH;
 119                spin_unlock_irq(&child->sighand->siglock);
 120        }
 121        read_unlock(&tasklist_lock);
 122
 123        if (!ret && !kill)
 124                ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH;
 125
 126        /* All systems go.. */
 127        return ret;
 128}
 129
 130int __ptrace_may_access(struct task_struct *task, unsigned int mode)
 131{
 132        const struct cred *cred = current_cred(), *tcred;
 133
 134        /* May we inspect the given task?
 135         * This check is used both for attaching with ptrace
 136         * and for allowing access to sensitive information in /proc.
 137         *
 138         * ptrace_attach denies several cases that /proc allows
 139         * because setting up the necessary parent/child relationship
 140         * or halting the specified task is impossible.
 141         */
 142        int dumpable = 0;
 143        /* Don't let security modules deny introspection */
 144        if (task == current)
 145                return 0;
 146        rcu_read_lock();
 147        tcred = __task_cred(task);
 148        if ((cred->uid != tcred->euid ||
 149             cred->uid != tcred->suid ||
 150             cred->uid != tcred->uid  ||
 151             cred->gid != tcred->egid ||
 152             cred->gid != tcred->sgid ||
 153             cred->gid != tcred->gid) &&
 154            !capable(CAP_SYS_PTRACE)) {
 155                rcu_read_unlock();
 156                return -EPERM;
 157        }
 158        rcu_read_unlock();
 159        smp_rmb();
 160        if (task->mm)
 161                dumpable = get_dumpable(task->mm);
 162        if (!dumpable && !capable(CAP_SYS_PTRACE))
 163                return -EPERM;
 164
 165        return security_ptrace_may_access(task, mode);
 166}
 167
 168bool ptrace_may_access(struct task_struct *task, unsigned int mode)
 169{
 170        int err;
 171        task_lock(task);
 172        err = __ptrace_may_access(task, mode);
 173        task_unlock(task);
 174        return !err;
 175}
 176
 177int ptrace_attach(struct task_struct *task)
 178{
 179        int retval;
 180        unsigned long flags;
 181
 182        audit_ptrace(task);
 183
 184        retval = -EPERM;
 185        if (same_thread_group(task, current))
 186                goto out;
 187
 188        /* Protect exec's credential calculations against our interference;
 189         * SUID, SGID and LSM creds get determined differently under ptrace.
 190         */
 191        retval = mutex_lock_interruptible(&task->cred_exec_mutex);
 192        if (retval  < 0)
 193                goto out;
 194
 195        retval = -EPERM;
 196repeat:
 197        /*
 198         * Nasty, nasty.
 199         *
 200         * We want to hold both the task-lock and the
 201         * tasklist_lock for writing at the same time.
 202         * But that's against the rules (tasklist_lock
 203         * is taken for reading by interrupts on other
 204         * cpu's that may have task_lock).
 205         */
 206        task_lock(task);
 207        if (!write_trylock_irqsave(&tasklist_lock, flags)) {
 208                task_unlock(task);
 209                do {
 210                        cpu_relax();
 211                } while (!write_can_lock(&tasklist_lock));
 212                goto repeat;
 213        }
 214
 215        if (!task->mm)
 216                goto bad;
 217        /* the same process cannot be attached many times */
 218        if (task->ptrace & PT_PTRACED)
 219                goto bad;
 220        retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
 221        if (retval)
 222                goto bad;
 223
 224        /* Go */
 225        task->ptrace |= PT_PTRACED;
 226        if (capable(CAP_SYS_PTRACE))
 227                task->ptrace |= PT_PTRACE_CAP;
 228
 229        __ptrace_link(task, current);
 230
 231        send_sig_info(SIGSTOP, SEND_SIG_FORCED, task);
 232bad:
 233        write_unlock_irqrestore(&tasklist_lock, flags);
 234        task_unlock(task);
 235        mutex_unlock(&task->cred_exec_mutex);
 236out:
 237        return retval;
 238}
 239
 240/*
 241 * Called with irqs disabled, returns true if childs should reap themselves.
 242 */
 243static int ignoring_children(struct sighand_struct *sigh)
 244{
 245        int ret;
 246        spin_lock(&sigh->siglock);
 247        ret = (sigh->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) ||
 248              (sigh->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT);
 249        spin_unlock(&sigh->siglock);
 250        return ret;
 251}
 252
 253/*
 254 * Called with tasklist_lock held for writing.
 255 * Unlink a traced task, and clean it up if it was a traced zombie.
 256 * Return true if it needs to be reaped with release_task().
 257 * (We can't call release_task() here because we already hold tasklist_lock.)
 258 *
 259 * If it's a zombie, our attachedness prevented normal parent notification
 260 * or self-reaping.  Do notification now if it would have happened earlier.
 261 * If it should reap itself, return true.
 262 *
 263 * If it's our own child, there is no notification to do.
 264 * But if our normal children self-reap, then this child
 265 * was prevented by ptrace and we must reap it now.
 266 */
 267static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p)
 268{
 269        __ptrace_unlink(p);
 270
 271        if (p->exit_state == EXIT_ZOMBIE) {
 272                if (!task_detached(p) && thread_group_empty(p)) {
 273                        if (!same_thread_group(p->real_parent, tracer))
 274                                do_notify_parent(p, p->exit_signal);
 275                        else if (ignoring_children(tracer->sighand))
 276                                p->exit_signal = -1;
 277                }
 278                if (task_detached(p)) {
 279                        /* Mark it as in the process of being reaped. */
 280                        p->exit_state = EXIT_DEAD;
 281                        return true;
 282                }
 283        }
 284
 285        return false;
 286}
 287
 288int ptrace_detach(struct task_struct *child, unsigned int data)
 289{
 290        bool dead = false;
 291
 292        if (!valid_signal(data))
 293                return -EIO;
 294
 295        /* Architecture-specific hardware disable .. */
 296        ptrace_disable(child);
 297        clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 298
 299        write_lock_irq(&tasklist_lock);
 300        /*
 301         * This child can be already killed. Make sure de_thread() or
 302         * our sub-thread doing do_wait() didn't do release_task() yet.
 303         */
 304        if (child->ptrace) {
 305                child->exit_code = data;
 306                dead = __ptrace_detach(current, child);
 307                if (!child->exit_state)
 308                        wake_up_process(child);
 309        }
 310        write_unlock_irq(&tasklist_lock);
 311
 312        if (unlikely(dead))
 313                release_task(child);
 314
 315        return 0;
 316}
 317
 318/*
 319 * Detach all tasks we were using ptrace on.
 320 */
 321void exit_ptrace(struct task_struct *tracer)
 322{
 323        struct task_struct *p, *n;
 324        LIST_HEAD(ptrace_dead);
 325
 326        write_lock_irq(&tasklist_lock);
 327        list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) {
 328                if (__ptrace_detach(tracer, p))
 329                        list_add(&p->ptrace_entry, &ptrace_dead);
 330        }
 331        write_unlock_irq(&tasklist_lock);
 332
 333        BUG_ON(!list_empty(&tracer->ptraced));
 334
 335        list_for_each_entry_safe(p, n, &ptrace_dead, ptrace_entry) {
 336                list_del_init(&p->ptrace_entry);
 337                release_task(p);
 338        }
 339}
 340
 341int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len)
 342{
 343        int copied = 0;
 344
 345        while (len > 0) {
 346                char buf[128];
 347                int this_len, retval;
 348
 349                this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
 350                retval = access_process_vm(tsk, src, buf, this_len, 0);
 351                if (!retval) {
 352                        if (copied)
 353                                break;
 354                        return -EIO;
 355                }
 356                if (copy_to_user(dst, buf, retval))
 357                        return -EFAULT;
 358                copied += retval;
 359                src += retval;
 360                dst += retval;
 361                len -= retval;
 362        }
 363        return copied;
 364}
 365
 366int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len)
 367{
 368        int copied = 0;
 369
 370        while (len > 0) {
 371                char buf[128];
 372                int this_len, retval;
 373
 374                this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
 375                if (copy_from_user(buf, src, this_len))
 376                        return -EFAULT;
 377                retval = access_process_vm(tsk, dst, buf, this_len, 1);
 378                if (!retval) {
 379                        if (copied)
 380                                break;
 381                        return -EIO;
 382                }
 383                copied += retval;
 384                src += retval;
 385                dst += retval;
 386                len -= retval;
 387        }
 388        return copied;
 389}
 390
 391static int ptrace_setoptions(struct task_struct *child, long data)
 392{
 393        child->ptrace &= ~PT_TRACE_MASK;
 394
 395        if (data & PTRACE_O_TRACESYSGOOD)
 396                child->ptrace |= PT_TRACESYSGOOD;
 397
 398        if (data & PTRACE_O_TRACEFORK)
 399                child->ptrace |= PT_TRACE_FORK;
 400
 401        if (data & PTRACE_O_TRACEVFORK)
 402                child->ptrace |= PT_TRACE_VFORK;
 403
 404        if (data & PTRACE_O_TRACECLONE)
 405                child->ptrace |= PT_TRACE_CLONE;
 406
 407        if (data & PTRACE_O_TRACEEXEC)
 408                child->ptrace |= PT_TRACE_EXEC;
 409
 410        if (data & PTRACE_O_TRACEVFORKDONE)
 411                child->ptrace |= PT_TRACE_VFORK_DONE;
 412
 413        if (data & PTRACE_O_TRACEEXIT)
 414                child->ptrace |= PT_TRACE_EXIT;
 415
 416        return (data & ~PTRACE_O_MASK) ? -EINVAL : 0;
 417}
 418
 419static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info)
 420{
 421        int error = -ESRCH;
 422
 423        read_lock(&tasklist_lock);
 424        if (likely(child->sighand != NULL)) {
 425                error = -EINVAL;
 426                spin_lock_irq(&child->sighand->siglock);
 427                if (likely(child->last_siginfo != NULL)) {
 428                        *info = *child->last_siginfo;
 429                        error = 0;
 430                }
 431                spin_unlock_irq(&child->sighand->siglock);
 432        }
 433        read_unlock(&tasklist_lock);
 434        return error;
 435}
 436
 437static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info)
 438{
 439        int error = -ESRCH;
 440
 441        read_lock(&tasklist_lock);
 442        if (likely(child->sighand != NULL)) {
 443                error = -EINVAL;
 444                spin_lock_irq(&child->sighand->siglock);
 445                if (likely(child->last_siginfo != NULL)) {
 446                        *child->last_siginfo = *info;
 447                        error = 0;
 448                }
 449                spin_unlock_irq(&child->sighand->siglock);
 450        }
 451        read_unlock(&tasklist_lock);
 452        return error;
 453}
 454
 455
 456#ifdef PTRACE_SINGLESTEP
 457#define is_singlestep(request)          ((request) == PTRACE_SINGLESTEP)
 458#else
 459#define is_singlestep(request)          0
 460#endif
 461
 462#ifdef PTRACE_SINGLEBLOCK
 463#define is_singleblock(request)         ((request) == PTRACE_SINGLEBLOCK)
 464#else
 465#define is_singleblock(request)         0
 466#endif
 467
 468#ifdef PTRACE_SYSEMU
 469#define is_sysemu_singlestep(request)   ((request) == PTRACE_SYSEMU_SINGLESTEP)
 470#else
 471#define is_sysemu_singlestep(request)   0
 472#endif
 473
 474static int ptrace_resume(struct task_struct *child, long request, long data)
 475{
 476        if (!valid_signal(data))
 477                return -EIO;
 478
 479        if (request == PTRACE_SYSCALL)
 480                set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 481        else
 482                clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
 483
 484#ifdef TIF_SYSCALL_EMU
 485        if (request == PTRACE_SYSEMU || request == PTRACE_SYSEMU_SINGLESTEP)
 486                set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
 487        else
 488                clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
 489#endif
 490
 491        if (is_singleblock(request)) {
 492                if (unlikely(!arch_has_block_step()))
 493                        return -EIO;
 494                user_enable_block_step(child);
 495        } else if (is_singlestep(request) || is_sysemu_singlestep(request)) {
 496                if (unlikely(!arch_has_single_step()))
 497                        return -EIO;
 498                user_enable_single_step(child);
 499        } else {
 500                user_disable_single_step(child);
 501        }
 502
 503        child->exit_code = data;
 504        wake_up_process(child);
 505
 506        return 0;
 507}
 508
 509int ptrace_request(struct task_struct *child, long request,
 510                   long addr, long data)
 511{
 512        int ret = -EIO;
 513        siginfo_t siginfo;
 514
 515        switch (request) {
 516        case PTRACE_PEEKTEXT:
 517        case PTRACE_PEEKDATA:
 518                return generic_ptrace_peekdata(child, addr, data);
 519        case PTRACE_POKETEXT:
 520        case PTRACE_POKEDATA:
 521                return generic_ptrace_pokedata(child, addr, data);
 522
 523#ifdef PTRACE_OLDSETOPTIONS
 524        case PTRACE_OLDSETOPTIONS:
 525#endif
 526        case PTRACE_SETOPTIONS:
 527                ret = ptrace_setoptions(child, data);
 528                break;
 529        case PTRACE_GETEVENTMSG:
 530                ret = put_user(child->ptrace_message, (unsigned long __user *) data);
 531                break;
 532
 533        case PTRACE_GETSIGINFO:
 534                ret = ptrace_getsiginfo(child, &siginfo);
 535                if (!ret)
 536                        ret = copy_siginfo_to_user((siginfo_t __user *) data,
 537                                                   &siginfo);
 538                break;
 539
 540        case PTRACE_SETSIGINFO:
 541                if (copy_from_user(&siginfo, (siginfo_t __user *) data,
 542                                   sizeof siginfo))
 543                        ret = -EFAULT;
 544                else
 545                        ret = ptrace_setsiginfo(child, &siginfo);
 546                break;
 547
 548        case PTRACE_DETACH:      /* detach a process that was attached. */
 549                ret = ptrace_detach(child, data);
 550                break;
 551
 552#ifdef PTRACE_SINGLESTEP
 553        case PTRACE_SINGLESTEP:
 554#endif
 555#ifdef PTRACE_SINGLEBLOCK
 556        case PTRACE_SINGLEBLOCK:
 557#endif
 558#ifdef PTRACE_SYSEMU
 559        case PTRACE_SYSEMU:
 560        case PTRACE_SYSEMU_SINGLESTEP:
 561#endif
 562        case PTRACE_SYSCALL:
 563        case PTRACE_CONT:
 564                return ptrace_resume(child, request, data);
 565
 566        case PTRACE_KILL:
 567                if (child->exit_state)  /* already dead */
 568                        return 0;
 569                return ptrace_resume(child, request, SIGKILL);
 570
 571        default:
 572                break;
 573        }
 574
 575        return ret;
 576}
 577
 578/**
 579 * ptrace_traceme  --  helper for PTRACE_TRACEME
 580 *
 581 * Performs checks and sets PT_PTRACED.
 582 * Should be used by all ptrace implementations for PTRACE_TRACEME.
 583 */
 584int ptrace_traceme(void)
 585{
 586        int ret = -EPERM;
 587
 588        /*
 589         * Are we already being traced?
 590         */
 591repeat:
 592        task_lock(current);
 593        if (!(current->ptrace & PT_PTRACED)) {
 594                /*
 595                 * See ptrace_attach() comments about the locking here.
 596                 */
 597                unsigned long flags;
 598                if (!write_trylock_irqsave(&tasklist_lock, flags)) {
 599                        task_unlock(current);
 600                        do {
 601                                cpu_relax();
 602                        } while (!write_can_lock(&tasklist_lock));
 603                        goto repeat;
 604                }
 605
 606                ret = security_ptrace_traceme(current->parent);
 607
 608                /*
 609                 * Check PF_EXITING to ensure ->real_parent has not passed
 610                 * exit_ptrace(). Otherwise we don't report the error but
 611                 * pretend ->real_parent untraces us right after return.
 612                 */
 613                if (!ret && !(current->real_parent->flags & PF_EXITING)) {
 614                        current->ptrace |= PT_PTRACED;
 615                        __ptrace_link(current, current->real_parent);
 616                }
 617
 618                write_unlock_irqrestore(&tasklist_lock, flags);
 619        }
 620        task_unlock(current);
 621        return ret;
 622}
 623
 624/**
 625 * ptrace_get_task_struct  --  grab a task struct reference for ptrace
 626 * @pid:       process id to grab a task_struct reference of
 627 *
 628 * This function is a helper for ptrace implementations.  It checks
 629 * permissions and then grabs a task struct for use of the actual
 630 * ptrace implementation.
 631 *
 632 * Returns the task_struct for @pid or an ERR_PTR() on failure.
 633 */
 634struct task_struct *ptrace_get_task_struct(pid_t pid)
 635{
 636        struct task_struct *child;
 637
 638        read_lock(&tasklist_lock);
 639        child = find_task_by_vpid(pid);
 640        if (child)
 641                get_task_struct(child);
 642
 643        read_unlock(&tasklist_lock);
 644        if (!child)
 645                return ERR_PTR(-ESRCH);
 646        return child;
 647}
 648
 649#ifndef arch_ptrace_attach
 650#define arch_ptrace_attach(child)       do { } while (0)
 651#endif
 652
 653SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data)
 654{
 655        struct task_struct *child;
 656        long ret;
 657
 658        /*
 659         * This lock_kernel fixes a subtle race with suid exec
 660         */
 661        lock_kernel();
 662        if (request == PTRACE_TRACEME) {
 663                ret = ptrace_traceme();
 664                if (!ret)
 665                        arch_ptrace_attach(current);
 666                goto out;
 667        }
 668
 669        child = ptrace_get_task_struct(pid);
 670        if (IS_ERR(child)) {
 671                ret = PTR_ERR(child);
 672                goto out;
 673        }
 674
 675        if (request == PTRACE_ATTACH) {
 676                ret = ptrace_attach(child);
 677                /*
 678                 * Some architectures need to do book-keeping after
 679                 * a ptrace attach.
 680                 */
 681                if (!ret)
 682                        arch_ptrace_attach(child);
 683                goto out_put_task_struct;
 684        }
 685
 686        ret = ptrace_check_attach(child, request == PTRACE_KILL);
 687        if (ret < 0)
 688                goto out_put_task_struct;
 689
 690        ret = arch_ptrace(child, request, addr, data);
 691
 692 out_put_task_struct:
 693        put_task_struct(child);
 694 out:
 695        unlock_kernel();
 696        return ret;
 697}
 698
 699int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data)
 700{
 701        unsigned long tmp;
 702        int copied;
 703
 704        copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0);
 705        if (copied != sizeof(tmp))
 706                return -EIO;
 707        return put_user(tmp, (unsigned long __user *)data);
 708}
 709
 710int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data)
 711{
 712        int copied;
 713
 714        copied = access_process_vm(tsk, addr, &data, sizeof(data), 1);
 715        return (copied == sizeof(data)) ? 0 : -EIO;
 716}
 717
 718#if defined CONFIG_COMPAT
 719#include <linux/compat.h>
 720
 721int compat_ptrace_request(struct task_struct *child, compat_long_t request,
 722                          compat_ulong_t addr, compat_ulong_t data)
 723{
 724        compat_ulong_t __user *datap = compat_ptr(data);
 725        compat_ulong_t word;
 726        siginfo_t siginfo;
 727        int ret;
 728
 729        switch (request) {
 730        case PTRACE_PEEKTEXT:
 731        case PTRACE_PEEKDATA:
 732                ret = access_process_vm(child, addr, &word, sizeof(word), 0);
 733                if (ret != sizeof(word))
 734                        ret = -EIO;
 735                else
 736                        ret = put_user(word, datap);
 737                break;
 738
 739        case PTRACE_POKETEXT:
 740        case PTRACE_POKEDATA:
 741                ret = access_process_vm(child, addr, &data, sizeof(data), 1);
 742                ret = (ret != sizeof(data) ? -EIO : 0);
 743                break;
 744
 745        case PTRACE_GETEVENTMSG:
 746                ret = put_user((compat_ulong_t) child->ptrace_message, datap);
 747                break;
 748
 749        case PTRACE_GETSIGINFO:
 750                ret = ptrace_getsiginfo(child, &siginfo);
 751                if (!ret)
 752                        ret = copy_siginfo_to_user32(
 753                                (struct compat_siginfo __user *) datap,
 754                                &siginfo);
 755                break;
 756
 757        case PTRACE_SETSIGINFO:
 758                memset(&siginfo, 0, sizeof siginfo);
 759                if (copy_siginfo_from_user32(
 760                            &siginfo, (struct compat_siginfo __user *) datap))
 761                        ret = -EFAULT;
 762                else
 763                        ret = ptrace_setsiginfo(child, &siginfo);
 764                break;
 765
 766        default:
 767                ret = ptrace_request(child, request, addr, data);
 768        }
 769
 770        return ret;
 771}
 772
 773asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
 774                                  compat_long_t addr, compat_long_t data)
 775{
 776        struct task_struct *child;
 777        long ret;
 778
 779        /*
 780         * This lock_kernel fixes a subtle race with suid exec
 781         */
 782        lock_kernel();
 783        if (request == PTRACE_TRACEME) {
 784                ret = ptrace_traceme();
 785                goto out;
 786        }
 787
 788        child = ptrace_get_task_struct(pid);
 789        if (IS_ERR(child)) {
 790                ret = PTR_ERR(child);
 791                goto out;
 792        }
 793
 794        if (request == PTRACE_ATTACH) {
 795                ret = ptrace_attach(child);
 796                /*
 797                 * Some architectures need to do book-keeping after
 798                 * a ptrace attach.
 799                 */
 800                if (!ret)
 801                        arch_ptrace_attach(child);
 802                goto out_put_task_struct;
 803        }
 804
 805        ret = ptrace_check_attach(child, request == PTRACE_KILL);
 806        if (!ret)
 807                ret = compat_arch_ptrace(child, request, addr, data);
 808
 809 out_put_task_struct:
 810        put_task_struct(child);
 811 out:
 812        unlock_kernel();
 813        return ret;
 814}
 815#endif  /* CONFIG_COMPAT */
 816