The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/kern/sys_process.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: sys_process.c,v 1.143.4.1 2009/02/06 01:54:09 snj Exp $        */
    2 
    3 /*-
    4  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
    5  * All rights reserved.
    6  *
    7  * This code is derived from software contributed to The NetBSD Foundation
    8  * by Andrew Doran.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
   20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
   23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
   24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
   25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
   27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
   28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
   29  * POSSIBILITY OF SUCH DAMAGE.
   30  */
   31 
   32 /*-
   33  * Copyright (c) 1982, 1986, 1989, 1993
   34  *      The Regents of the University of California.  All rights reserved.
   35  * (c) UNIX System Laboratories, Inc.
   36  * All or some portions of this file are derived from material licensed
   37  * to the University of California by American Telephone and Telegraph
   38  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   39  * the permission of UNIX System Laboratories, Inc.
   40  *
   41  * This code is derived from software contributed to Berkeley by
   42  * Jan-Simon Pendry.
   43  *
   44  * Redistribution and use in source and binary forms, with or without
   45  * modification, are permitted provided that the following conditions
   46  * are met:
   47  * 1. Redistributions of source code must retain the above copyright
   48  *    notice, this list of conditions and the following disclaimer.
   49  * 2. Redistributions in binary form must reproduce the above copyright
   50  *    notice, this list of conditions and the following disclaimer in the
   51  *    documentation and/or other materials provided with the distribution.
   52  * 3. Neither the name of the University nor the names of its contributors
   53  *    may be used to endorse or promote products derived from this software
   54  *    without specific prior written permission.
   55  *
   56  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   57  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   58  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   59  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   60  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   61  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   62  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   63  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   64  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   65  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   66  * SUCH DAMAGE.
   67  *
   68  *      from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93
   69  */
   70 
   71 /*-
   72  * Copyright (c) 1993 Jan-Simon Pendry.
   73  * Copyright (c) 1994 Christopher G. Demetriou.  All rights reserved.
   74  *
   75  * This code is derived from software contributed to Berkeley by
   76  * Jan-Simon Pendry.
   77  *
   78  * Redistribution and use in source and binary forms, with or without
   79  * modification, are permitted provided that the following conditions
   80  * are met:
   81  * 1. Redistributions of source code must retain the above copyright
   82  *    notice, this list of conditions and the following disclaimer.
   83  * 2. Redistributions in binary form must reproduce the above copyright
   84  *    notice, this list of conditions and the following disclaimer in the
   85  *    documentation and/or other materials provided with the distribution.
   86  * 3. All advertising materials mentioning features or use of this software
   87  *    must display the following acknowledgement:
   88  *      This product includes software developed by the University of
   89  *      California, Berkeley and its contributors.
   90  * 4. Neither the name of the University nor the names of its contributors
   91  *    may be used to endorse or promote products derived from this software
   92  *    without specific prior written permission.
   93  *
   94  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   95  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   96  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   97  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   98  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   99  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  100  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  101  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  102  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  103  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  104  * SUCH DAMAGE.
  105  *
  106  *      from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93
  107  */
  108 
  109 /*
  110  * References:
  111  *      (1) Bach's "The Design of the UNIX Operating System",
  112  *      (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution,
  113  *      (3) the "4.4BSD Programmer's Reference Manual" published
  114  *              by USENIX and O'Reilly & Associates.
  115  * The 4.4BSD PRM does a reasonably good job of documenting what the various
  116  * ptrace() requests should actually do, and its text is quoted several times
  117  * in this file.
  118  */
  119 
  120 #include <sys/cdefs.h>
  121 __KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.143.4.1 2009/02/06 01:54:09 snj Exp $");
  122 
  123 #include "opt_coredump.h"
  124 #include "opt_ptrace.h"
  125 #include "opt_ktrace.h"
  126 
  127 #include <sys/param.h>
  128 #include <sys/systm.h>
  129 #include <sys/proc.h>
  130 #include <sys/errno.h>
  131 #include <sys/ptrace.h>
  132 #include <sys/uio.h>
  133 #include <sys/user.h>
  134 #include <sys/ras.h>
  135 #include <sys/malloc.h>
  136 #include <sys/kauth.h>
  137 #include <sys/mount.h>
  138 #include <sys/syscallargs.h>
  139 
  140 #include <uvm/uvm_extern.h>
  141 
  142 #include <machine/reg.h>
  143 
  144 #ifdef PTRACE
  145 /*
  146  * Process debugging system call.
  147  */
  148 int
  149 sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
  150 {
  151         /* {
  152                 syscallarg(int) req;
  153                 syscallarg(pid_t) pid;
  154                 syscallarg(void *) addr;
  155                 syscallarg(int) data;
  156         } */
  157         struct proc *p = l->l_proc;
  158         struct lwp *lt;
  159         struct proc *t;                         /* target process */
  160         struct uio uio;
  161         struct iovec iov;
  162         struct ptrace_io_desc piod;
  163         struct ptrace_lwpinfo pl;
  164         struct vmspace *vm;
  165         int error, write, tmp, req, pheld;
  166         int signo;
  167         ksiginfo_t ksi;
  168 #ifdef COREDUMP
  169         char *path;
  170 #endif
  171 
  172         error = 0;
  173         req = SCARG(uap, req);
  174 
  175         /*
  176          * If attaching or detaching, we need to get a write hold on the
  177          * proclist lock so that we can re-parent the target process.
  178          */
  179         mutex_enter(proc_lock);
  180 
  181         /* "A foolish consistency..." XXX */
  182         if (req == PT_TRACE_ME) {
  183                 t = p;
  184                 mutex_enter(t->p_lock);
  185         } else {
  186                 /* Find the process we're supposed to be operating on. */
  187                 if ((t = p_find(SCARG(uap, pid), PFIND_LOCKED)) == NULL) {
  188                         mutex_exit(proc_lock);
  189                         return (ESRCH);
  190                 }
  191 
  192                 /* XXX-elad */
  193                 mutex_enter(t->p_lock);
  194                 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
  195                     t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
  196                 if (error) {
  197                         mutex_exit(proc_lock);
  198                         mutex_exit(t->p_lock);
  199                         return (ESRCH);
  200                 }
  201         }
  202 
  203         /*
  204          * Grab a reference on the process to prevent it from execing or
  205          * exiting.
  206          */
  207         if (!rw_tryenter(&t->p_reflock, RW_READER)) {
  208                 mutex_exit(proc_lock);
  209                 mutex_exit(t->p_lock);
  210                 return EBUSY;
  211         }
  212 
  213         /* Make sure we can operate on it. */
  214         switch (req) {
  215         case  PT_TRACE_ME:
  216                 /* Saying that you're being traced is always legal. */
  217                 break;
  218 
  219         case  PT_ATTACH:
  220                 /*
  221                  * You can't attach to a process if:
  222                  *      (1) it's the process that's doing the attaching,
  223                  */
  224                 if (t->p_pid == p->p_pid) {
  225                         error = EINVAL;
  226                         break;
  227                 }
  228 
  229                 /*
  230                  *  (2) it's a system process
  231                  */
  232                 if (t->p_flag & PK_SYSTEM) {
  233                         error = EPERM;
  234                         break;
  235                 }
  236 
  237                 /*
  238                  *      (3) it's already being traced, or
  239                  */
  240                 if (ISSET(t->p_slflag, PSL_TRACED)) {
  241                         error = EBUSY;
  242                         break;
  243                 }
  244 
  245                 /*
  246                  *      (4) the tracer is chrooted, and its root directory is
  247                  *          not at or above the root directory of the tracee
  248                  */
  249                 mutex_exit(t->p_lock);  /* XXXSMP */
  250                 tmp = proc_isunder(t, l);
  251                 mutex_enter(t->p_lock); /* XXXSMP */
  252                 if (!tmp) {
  253                         error = EPERM;
  254                         break;
  255                 }
  256                 break;
  257 
  258         case  PT_READ_I:
  259         case  PT_READ_D:
  260         case  PT_WRITE_I:
  261         case  PT_WRITE_D:
  262         case  PT_IO:
  263 #ifdef PT_GETREGS
  264         case  PT_GETREGS:
  265 #endif
  266 #ifdef PT_SETREGS
  267         case  PT_SETREGS:
  268 #endif
  269 #ifdef PT_GETFPREGS
  270         case  PT_GETFPREGS:
  271 #endif
  272 #ifdef PT_SETFPREGS
  273         case  PT_SETFPREGS:
  274 #endif
  275 #ifdef __HAVE_PTRACE_MACHDEP
  276         PTRACE_MACHDEP_REQUEST_CASES
  277 #endif
  278                 /*
  279                  * You can't read/write the memory or registers of a process
  280                  * if the tracer is chrooted, and its root directory is not at
  281                  * or above the root directory of the tracee.
  282                  */
  283                 mutex_exit(t->p_lock);  /* XXXSMP */
  284                 tmp = proc_isunder(t, l);
  285                 mutex_enter(t->p_lock); /* XXXSMP */
  286                 if (!tmp) {
  287                         error = EPERM;
  288                         break;
  289                 }
  290                 /*FALLTHROUGH*/
  291 
  292         case  PT_CONTINUE:
  293         case  PT_KILL:
  294         case  PT_DETACH:
  295         case  PT_LWPINFO:
  296         case  PT_SYSCALL:
  297 #ifdef COREDUMP
  298         case  PT_DUMPCORE:
  299 #endif
  300 #ifdef PT_STEP
  301         case  PT_STEP:
  302 #endif
  303                 /*
  304                  * You can't do what you want to the process if:
  305                  *      (1) It's not being traced at all,
  306                  */
  307                 if (!ISSET(t->p_slflag, PSL_TRACED)) {
  308                         error = EPERM;
  309                         break;
  310                 }
  311 
  312                 /*
  313                  *      (2) it's being traced by procfs (which has
  314                  *          different signal delivery semantics),
  315                  */
  316                 if (ISSET(t->p_slflag, PSL_FSTRACE)) {
  317                         uprintf("file system traced\n");
  318                         error = EBUSY;
  319                         break;
  320                 }
  321 
  322                 /*
  323                  *      (3) it's not being traced by _you_, or
  324                  */
  325                 if (t->p_pptr != p) {
  326                         uprintf("parent %d != %d\n", t->p_pptr->p_pid, p->p_pid);
  327                         error = EBUSY;
  328                         break;
  329                 }
  330 
  331                 /*
  332                  *      (4) it's not currently stopped.
  333                  */
  334                 if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) {
  335                         uprintf("stat %d flag %d\n", t->p_stat,
  336                             !t->p_waited);
  337                         error = EBUSY;
  338                         break;
  339                 }
  340                 break;
  341 
  342         default:                        /* It was not a legal request. */
  343                 error = EINVAL;
  344                 break;
  345         }
  346 
  347         if (error == 0) {
  348                 error = kauth_authorize_process(l->l_cred,
  349                     KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req),
  350                     NULL, NULL);
  351         }
  352         if (error == 0) {
  353                 lt = lwp_find_first(t);
  354                 if (lt == NULL)
  355                         error = ESRCH;
  356         }
  357 
  358         if (error != 0) {
  359                 mutex_exit(proc_lock);
  360                 mutex_exit(t->p_lock);
  361                 rw_exit(&t->p_reflock);
  362                 return error;
  363         }
  364 
  365         /* Do single-step fixup if needed. */
  366         FIX_SSTEP(t);
  367         KASSERT(lt != NULL);
  368         lwp_addref(lt);
  369 
  370         /*
  371          * Which locks do we need held? XXX Ugly.
  372          */
  373         switch (req) {
  374 #ifdef PT_STEP
  375         case PT_STEP:
  376 #endif
  377         case PT_CONTINUE:
  378         case PT_DETACH:
  379         case PT_KILL:
  380         case PT_SYSCALL:
  381         case PT_ATTACH:
  382         case PT_TRACE_ME:
  383                 pheld = 1;
  384                 break;
  385         default:
  386                 mutex_exit(proc_lock);
  387                 mutex_exit(t->p_lock);
  388                 pheld = 0;
  389                 break;
  390         }
  391 
  392         /* Now do the operation. */
  393         write = 0;
  394         *retval = 0;
  395         tmp = 0;
  396 
  397         switch (req) {
  398         case  PT_TRACE_ME:
  399                 /* Just set the trace flag. */
  400                 SET(t->p_slflag, PSL_TRACED);
  401                 t->p_opptr = t->p_pptr;
  402                 break;
  403 
  404         case  PT_WRITE_I:               /* XXX no separate I and D spaces */
  405         case  PT_WRITE_D:
  406 #if defined(__HAVE_RAS)
  407                 /*
  408                  * Can't write to a RAS
  409                  */
  410                 if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) {
  411                         error = EACCES;
  412                         break;
  413                 }
  414 #endif
  415                 write = 1;
  416                 tmp = SCARG(uap, data);
  417                 /* FALLTHROUGH */
  418 
  419         case  PT_READ_I:                /* XXX no separate I and D spaces */
  420         case  PT_READ_D:
  421                 /* write = 0 done above. */
  422                 iov.iov_base = (void *)&tmp;
  423                 iov.iov_len = sizeof(tmp);
  424                 uio.uio_iov = &iov;
  425                 uio.uio_iovcnt = 1;
  426                 uio.uio_offset = (off_t)(unsigned long)SCARG(uap, addr);
  427                 uio.uio_resid = sizeof(tmp);
  428                 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
  429                 UIO_SETUP_SYSSPACE(&uio);
  430 
  431                 error = process_domem(l, lt, &uio);
  432                 if (!write)
  433                         *retval = tmp;
  434                 break;
  435 
  436         case  PT_IO:
  437                 error = copyin(SCARG(uap, addr), &piod, sizeof(piod));
  438                 if (error)
  439                         break;
  440                 switch (piod.piod_op) {
  441                 case PIOD_READ_D:
  442                 case PIOD_READ_I:
  443                         uio.uio_rw = UIO_READ;
  444                         break;
  445                 case PIOD_WRITE_D:
  446                 case PIOD_WRITE_I:
  447                         /*
  448                          * Can't write to a RAS
  449                          */
  450                         if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) {
  451                                 return (EACCES);
  452                         }
  453                         uio.uio_rw = UIO_WRITE;
  454                         break;
  455                 default:
  456                         error = EINVAL;
  457                         break;
  458                 }
  459                 if (error)
  460                         break;
  461                 error = proc_vmspace_getref(l->l_proc, &vm);
  462                 if (error)
  463                         break;
  464                 iov.iov_base = piod.piod_addr;
  465                 iov.iov_len = piod.piod_len;
  466                 uio.uio_iov = &iov;
  467                 uio.uio_iovcnt = 1;
  468                 uio.uio_offset = (off_t)(unsigned long)piod.piod_offs;
  469                 uio.uio_resid = piod.piod_len;
  470                 uio.uio_vmspace = vm;
  471 
  472                 error = process_domem(l, lt, &uio);
  473                 piod.piod_len -= uio.uio_resid;
  474                 (void) copyout(&piod, SCARG(uap, addr), sizeof(piod));
  475                 uvmspace_free(vm);
  476                 break;
  477 
  478 #ifdef COREDUMP
  479         case  PT_DUMPCORE:
  480                 if ((path = SCARG(uap, addr)) != NULL) {
  481                         char *dst;
  482                         int len = SCARG(uap, data);
  483                         if (len < 0 || len >= MAXPATHLEN) {
  484                                 error = EINVAL;
  485                                 break;
  486                         }
  487                         dst = malloc(len + 1, M_TEMP, M_WAITOK);
  488                         if ((error = copyin(path, dst, len)) != 0) {
  489                                 free(dst, M_TEMP);
  490                                 break;
  491                         }
  492                         path = dst;
  493                         path[len] = '\0';
  494                 }
  495                 error = coredump(lt, path);
  496                 if (path)
  497                         free(path, M_TEMP);
  498                 break;
  499 #endif
  500 
  501 #ifdef PT_STEP
  502         case  PT_STEP:
  503                 /*
  504                  * From the 4.4BSD PRM:
  505                  * "Execution continues as in request PT_CONTINUE; however
  506                  * as soon as possible after execution of at least one
  507                  * instruction, execution stops again. [ ... ]"
  508                  */
  509 #endif
  510         case  PT_CONTINUE:
  511         case  PT_SYSCALL:
  512         case  PT_DETACH:
  513                 if (req == PT_SYSCALL) {
  514                         if (!ISSET(t->p_slflag, PSL_SYSCALL)) {
  515                                 SET(t->p_slflag, PSL_SYSCALL);
  516 #ifdef __HAVE_SYSCALL_INTERN
  517                                 (*t->p_emul->e_syscall_intern)(t);
  518 #endif
  519                         }
  520                 } else {
  521                         if (ISSET(t->p_slflag, PSL_SYSCALL)) {
  522                                 CLR(t->p_slflag, PSL_SYSCALL);
  523 #ifdef __HAVE_SYSCALL_INTERN
  524                                 (*t->p_emul->e_syscall_intern)(t);
  525 #endif
  526                         }
  527                 }
  528                 p->p_trace_enabled = trace_is_enabled(p);
  529 
  530                 /*
  531                  * From the 4.4BSD PRM:
  532                  * "The data argument is taken as a signal number and the
  533                  * child's execution continues at location addr as if it
  534                  * incurred that signal.  Normally the signal number will
  535                  * be either 0 to indicate that the signal that caused the
  536                  * stop should be ignored, or that value fetched out of
  537                  * the process's image indicating which signal caused
  538                  * the stop.  If addr is (int *)1 then execution continues
  539                  * from where it stopped."
  540                  */
  541 
  542                 /* Check that the data is a valid signal number or zero. */
  543                 if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG) {
  544                         error = EINVAL;
  545                         break;
  546                 }
  547 
  548                 uvm_lwp_hold(lt);
  549 
  550                 /* If the address parameter is not (int *)1, set the pc. */
  551                 if ((int *)SCARG(uap, addr) != (int *)1)
  552                         if ((error = process_set_pc(lt, SCARG(uap, addr))) != 0) {
  553                                 uvm_lwp_rele(lt);
  554                                 break;
  555                         }
  556 
  557 #ifdef PT_STEP
  558                 /*
  559                  * Arrange for a single-step, if that's requested and possible.
  560                  */
  561                 error = process_sstep(lt, req == PT_STEP);
  562                 if (error) {
  563                         uvm_lwp_rele(lt);
  564                         break;
  565                 }
  566 #endif
  567 
  568                 uvm_lwp_rele(lt);
  569 
  570                 if (req == PT_DETACH) {
  571                         CLR(t->p_slflag, PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL);
  572 
  573                         /* give process back to original parent or init */
  574                         if (t->p_opptr != t->p_pptr) {
  575                                 struct proc *pp = t->p_opptr;
  576                                 proc_reparent(t, pp ? pp : initproc);
  577                         }
  578 
  579                         /* not being traced any more */
  580                         t->p_opptr = NULL;
  581                 }
  582 
  583                 signo = SCARG(uap, data);
  584         sendsig:
  585                 /* Finally, deliver the requested signal (or none). */
  586                 if (t->p_stat == SSTOP) {
  587                         /*
  588                          * Unstop the process.  If it needs to take a
  589                          * signal, make all efforts to ensure that at
  590                          * an LWP runs to see it.
  591                          */
  592                         t->p_xstat = signo;
  593                         proc_unstop(t);
  594                 } else if (signo != 0) {
  595                         KSI_INIT_EMPTY(&ksi);
  596                         ksi.ksi_signo = signo;
  597                         kpsignal2(t, &ksi);
  598                 }
  599                 break;
  600 
  601         case  PT_KILL:
  602                 /* just send the process a KILL signal. */
  603                 signo = SIGKILL;
  604                 goto sendsig;   /* in PT_CONTINUE, above. */
  605 
  606         case  PT_ATTACH:
  607                 /*
  608                  * Go ahead and set the trace flag.
  609                  * Save the old parent (it's reset in
  610                  *   _DETACH, and also in kern_exit.c:wait4()
  611                  * Reparent the process so that the tracing
  612                  *   proc gets to see all the action.
  613                  * Stop the target.
  614                  */
  615                 t->p_opptr = t->p_pptr;
  616                 if (t->p_pptr != p) {
  617                         struct proc *parent = t->p_pptr;
  618 
  619                         if (parent->p_lock < t->p_lock) {
  620                                 if (!mutex_tryenter(parent->p_lock)) {
  621                                         mutex_exit(t->p_lock);
  622                                         mutex_enter(parent->p_lock);
  623                                 }
  624                         } else if (parent->p_lock > t->p_lock) {
  625                                 mutex_enter(parent->p_lock);
  626                         }
  627                         parent->p_slflag |= PSL_CHTRACED;
  628                         proc_reparent(t, p);
  629                         if (parent->p_lock != t->p_lock)
  630                                 mutex_exit(parent->p_lock);
  631                 }
  632                 SET(t->p_slflag, PSL_TRACED);
  633                 signo = SIGSTOP;
  634                 goto sendsig;
  635 
  636         case PT_LWPINFO:
  637                 if (SCARG(uap, data) != sizeof(pl)) {
  638                         error = EINVAL;
  639                         break;
  640                 }
  641                 error = copyin(SCARG(uap, addr), &pl, sizeof(pl));
  642                 if (error)
  643                         break;
  644                 tmp = pl.pl_lwpid;
  645                 lwp_delref(lt);
  646                 mutex_enter(t->p_lock);
  647                 if (tmp == 0)
  648                         lt = lwp_find_first(t);
  649                 else {
  650                         lt = lwp_find(t, tmp);
  651                         if (lt == NULL) {
  652                                 mutex_exit(t->p_lock);
  653                                 error = ESRCH;
  654                                 break;
  655                         }
  656                         lt = LIST_NEXT(lt, l_sibling);
  657                 }
  658                 while (lt != NULL && !lwp_alive(lt))
  659                         lt = LIST_NEXT(lt, l_sibling);
  660                 pl.pl_lwpid = 0;
  661                 pl.pl_event = 0;
  662                 if (lt) {
  663                         lwp_addref(lt);
  664                         pl.pl_lwpid = lt->l_lid;
  665                         if (lt->l_lid == t->p_sigctx.ps_lwp)
  666                                 pl.pl_event = PL_EVENT_SIGNAL;
  667                 }
  668                 mutex_exit(t->p_lock);
  669 
  670                 error = copyout(&pl, SCARG(uap, addr), sizeof(pl));
  671                 break;
  672 
  673 #ifdef PT_SETREGS
  674         case  PT_SETREGS:
  675                 write = 1;
  676 #endif
  677 #ifdef PT_GETREGS
  678         case  PT_GETREGS:
  679                 /* write = 0 done above. */
  680 #endif
  681 #if defined(PT_SETREGS) || defined(PT_GETREGS)
  682                 tmp = SCARG(uap, data);
  683                 if (tmp != 0 && t->p_nlwps > 1) {
  684                         lwp_delref(lt);
  685                         mutex_enter(t->p_lock);
  686                         lt = lwp_find(t, tmp);
  687                         if (lt == NULL) {
  688                                 mutex_exit(t->p_lock);
  689                                 error = ESRCH;
  690                                 break;
  691                         }
  692                         lwp_addref(lt);
  693                         mutex_exit(t->p_lock);
  694                 }
  695                 if (!process_validregs(lt))
  696                         error = EINVAL;
  697                 else {
  698                         error = proc_vmspace_getref(l->l_proc, &vm);
  699                         if (error)
  700                                 break;
  701                         iov.iov_base = SCARG(uap, addr);
  702                         iov.iov_len = sizeof(struct reg);
  703                         uio.uio_iov = &iov;
  704                         uio.uio_iovcnt = 1;
  705                         uio.uio_offset = 0;
  706                         uio.uio_resid = sizeof(struct reg);
  707                         uio.uio_rw = write ? UIO_WRITE : UIO_READ;
  708                         uio.uio_vmspace = vm;
  709 
  710                         error = process_doregs(l, lt, &uio);
  711                         uvmspace_free(vm);
  712                 }
  713                 break;
  714 #endif
  715 
  716 #ifdef PT_SETFPREGS
  717         case  PT_SETFPREGS:
  718                 write = 1;
  719 #endif
  720 #ifdef PT_GETFPREGS
  721         case  PT_GETFPREGS:
  722                 /* write = 0 done above. */
  723 #endif
  724 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
  725                 tmp = SCARG(uap, data);
  726                 if (tmp != 0 && t->p_nlwps > 1) {
  727                         lwp_delref(lt);
  728                         mutex_enter(t->p_lock);
  729                         lt = lwp_find(t, tmp);
  730                         if (lt == NULL) {
  731                                 mutex_exit(t->p_lock);
  732                                 error = ESRCH;
  733                                 break;
  734                         }
  735                         lwp_addref(lt);
  736                         mutex_exit(t->p_lock);
  737                 }
  738                 if (!process_validfpregs(lt))
  739                         error = EINVAL;
  740                 else {
  741                         error = proc_vmspace_getref(l->l_proc, &vm);
  742                         if (error)
  743                                 break;
  744                         iov.iov_base = SCARG(uap, addr);
  745                         iov.iov_len = sizeof(struct fpreg);
  746                         uio.uio_iov = &iov;
  747                         uio.uio_iovcnt = 1;
  748                         uio.uio_offset = 0;
  749                         uio.uio_resid = sizeof(struct fpreg);
  750                         uio.uio_rw = write ? UIO_WRITE : UIO_READ;
  751                         uio.uio_vmspace = vm;
  752 
  753                         error = process_dofpregs(l, lt, &uio);
  754                         uvmspace_free(vm);
  755                 }
  756                 break;
  757 #endif
  758 
  759 #ifdef __HAVE_PTRACE_MACHDEP
  760         PTRACE_MACHDEP_REQUEST_CASES
  761                 error = ptrace_machdep_dorequest(l, lt,
  762                     req, SCARG(uap, addr), SCARG(uap, data));
  763                 break;
  764 #endif
  765         }
  766 
  767         if (pheld) {
  768                 mutex_exit(t->p_lock);
  769                 mutex_exit(proc_lock);
  770         }
  771         if (lt != NULL)
  772                 lwp_delref(lt);
  773         rw_exit(&t->p_reflock);
  774 
  775         return error;
  776 }
  777 
  778 int
  779 process_doregs(struct lwp *curl /*tracer*/,
  780     struct lwp *l /*traced*/,
  781     struct uio *uio)
  782 {
  783 #if defined(PT_GETREGS) || defined(PT_SETREGS)
  784         int error;
  785         struct reg r;
  786         char *kv;
  787         int kl;
  788 
  789         if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
  790                 return EINVAL;
  791 
  792         kl = sizeof(r);
  793         kv = (char *)&r;
  794 
  795         kv += uio->uio_offset;
  796         kl -= uio->uio_offset;
  797         if ((size_t)kl > uio->uio_resid)
  798                 kl = uio->uio_resid;
  799 
  800         uvm_lwp_hold(l);
  801 
  802         error = process_read_regs(l, &r);
  803         if (error == 0)
  804                 error = uiomove(kv, kl, uio);
  805         if (error == 0 && uio->uio_rw == UIO_WRITE) {
  806                 if (l->l_stat != LSSTOP)
  807                         error = EBUSY;
  808                 else
  809                         error = process_write_regs(l, &r);
  810         }
  811 
  812         uvm_lwp_rele(l);
  813 
  814         uio->uio_offset = 0;
  815         return (error);
  816 #else
  817         return (EINVAL);
  818 #endif
  819 }
  820 
  821 int
  822 process_validregs(struct lwp *l)
  823 {
  824 
  825 #if defined(PT_SETREGS) || defined(PT_GETREGS)
  826         return ((l->l_flag & LW_SYSTEM) == 0);
  827 #else
  828         return (0);
  829 #endif
  830 }
  831 
  832 int
  833 process_dofpregs(struct lwp *curl /*tracer*/,
  834     struct lwp *l /*traced*/,
  835     struct uio *uio)
  836 {
  837 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS)
  838         int error;
  839         struct fpreg r;
  840         char *kv;
  841         int kl;
  842 
  843         if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
  844                 return EINVAL;
  845 
  846         kl = sizeof(r);
  847         kv = (char *)&r;
  848 
  849         kv += uio->uio_offset;
  850         kl -= uio->uio_offset;
  851         if ((size_t)kl > uio->uio_resid)
  852                 kl = uio->uio_resid;
  853 
  854         uvm_lwp_hold(l);
  855 
  856         error = process_read_fpregs(l, &r);
  857         if (error == 0)
  858                 error = uiomove(kv, kl, uio);
  859         if (error == 0 && uio->uio_rw == UIO_WRITE) {
  860                 if (l->l_stat != LSSTOP)
  861                         error = EBUSY;
  862                 else
  863                         error = process_write_fpregs(l, &r);
  864         }
  865 
  866         uvm_lwp_rele(l);
  867 
  868         uio->uio_offset = 0;
  869         return (error);
  870 #else
  871         return (EINVAL);
  872 #endif
  873 }
  874 
  875 int
  876 process_validfpregs(struct lwp *l)
  877 {
  878 
  879 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
  880         return ((l->l_flag & LW_SYSTEM) == 0);
  881 #else
  882         return (0);
  883 #endif
  884 }
  885 #endif /* PTRACE */
  886 
  887 #if defined(KTRACE) || defined(PTRACE)
  888 int
  889 process_domem(struct lwp *curl /*tracer*/,
  890     struct lwp *l /*traced*/,
  891     struct uio *uio)
  892 {
  893         struct proc *p = l->l_proc;     /* traced */
  894         struct vmspace *vm;
  895         int error;
  896 
  897         size_t len;
  898 #ifdef PMAP_NEED_PROCWR
  899         vaddr_t addr;
  900 #endif
  901 
  902         error = 0;
  903         len = uio->uio_resid;
  904 
  905         if (len == 0)
  906                 return (0);
  907 
  908 #ifdef PMAP_NEED_PROCWR
  909         addr = uio->uio_offset;
  910 #endif
  911 
  912         vm = p->p_vmspace;
  913 
  914         mutex_enter(&vm->vm_map.misc_lock);
  915         if ((l->l_flag & LW_WEXIT) || vm->vm_refcnt < 1)
  916                 error = EFAULT;
  917         if (error == 0)
  918                 p->p_vmspace->vm_refcnt++;  /* XXX */
  919         mutex_exit(&vm->vm_map.misc_lock);
  920         if (error != 0)
  921                 return (error);
  922         error = uvm_io(&vm->vm_map, uio);
  923         uvmspace_free(vm);
  924 
  925 #ifdef PMAP_NEED_PROCWR
  926         if (error == 0 && uio->uio_rw == UIO_WRITE)
  927                 pmap_procwr(p, addr, len);
  928 #endif
  929         return (error);
  930 }
  931 #endif /* KTRACE || PTRACE */
  932 
  933 #if defined(KTRACE) || defined(PTRACE)
  934 void
  935 process_stoptrace(void)
  936 {
  937         struct lwp *l = curlwp;
  938         struct proc *p = l->l_proc, *pp;
  939 
  940         mutex_enter(proc_lock);
  941         mutex_enter(p->p_lock);
  942         pp = p->p_pptr;
  943         if (pp->p_pid == 1) {
  944                 CLR(p->p_slflag, PSL_SYSCALL);  /* XXXSMP */
  945                 mutex_exit(p->p_lock);
  946                 mutex_exit(proc_lock);
  947                 return;
  948         }
  949 
  950         p->p_xstat = SIGTRAP;
  951         proc_stop(p, 1, SIGSTOP);
  952         mutex_exit(proc_lock);
  953 
  954         /*
  955          * Call issignal() once only, to have it take care of the
  956          * pending stop.  Signal processing will take place as usual
  957          * from userret().
  958          */
  959         KERNEL_UNLOCK_ALL(l, &l->l_biglocks);
  960         (void)issignal(l);
  961         mutex_exit(p->p_lock);
  962         KERNEL_LOCK(l->l_biglocks, l);
  963 }
  964 #endif  /* KTRACE || PTRACE */

Cache object: 5b2b9829753f61a10643e604bfc43221


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.