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-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*      $OpenBSD: sys_process.c,v 1.43 2008/10/31 17:29:51 deraadt Exp $        */
    2 /*      $NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $     */
    3 
    4 /*-
    5  * Copyright (c) 1994 Christopher G. Demetriou.  All rights reserved.
    6  * Copyright (c) 1982, 1986, 1989, 1993
    7  *      The Regents of the University of California.  All rights reserved.
    8  * (c) UNIX System Laboratories, Inc.
    9  * All or some portions of this file are derived from material licensed
   10  * to the University of California by American Telephone and Telegraph
   11  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
   12  * the permission of UNIX System Laboratories, Inc.
   13  *
   14  * Redistribution and use in source and binary forms, with or without
   15  * modification, are permitted provided that the following conditions
   16  * are met:
   17  * 1. Redistributions of source code must retain the above copyright
   18  *    notice, this list of conditions and the following disclaimer.
   19  * 2. Redistributions in binary form must reproduce the above copyright
   20  *    notice, this list of conditions and the following disclaimer in the
   21  *    documentation and/or other materials provided with the distribution.
   22  * 3. Neither the name of the University nor the names of its contributors
   23  *    may be used to endorse or promote products derived from this software
   24  *    without specific prior written permission.
   25  *
   26  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   27  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   28  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   29  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   30  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   31  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   32  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   36  * SUCH DAMAGE.
   37  *
   38  *      from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93
   39  */
   40 
   41 /*
   42  * References:
   43  *      (1) Bach's "The Design of the UNIX Operating System",
   44  *      (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution,
   45  *      (3) the "4.4BSD Programmer's Reference Manual" published
   46  *              by USENIX and O'Reilly & Associates.
   47  * The 4.4BSD PRM does a reasonably good job of documenting what the various
   48  * ptrace() requests should actually do, and its text is quoted several times
   49  * in this file.
   50  */
   51 
   52 #include <sys/param.h>
   53 #include <sys/systm.h>
   54 #include <sys/exec.h>
   55 #include <sys/proc.h>
   56 #include <sys/signalvar.h>
   57 #include <sys/errno.h>
   58 #include <sys/malloc.h>
   59 #include <sys/ptrace.h>
   60 #include <sys/uio.h>
   61 #include <sys/user.h>
   62 #include <sys/sched.h>
   63 
   64 #include <sys/mount.h>
   65 #include <sys/syscallargs.h>
   66 
   67 #include <uvm/uvm_extern.h>
   68 
   69 #include <machine/reg.h>
   70 
   71 int     process_auxv_offset(struct proc *, struct proc *, struct uio *);
   72 
   73 #ifdef PTRACE
   74 /*
   75  * Process debugging system call.
   76  */
   77 int
   78 sys_ptrace(struct proc *p, void *v, register_t *retval)
   79 {
   80         struct sys_ptrace_args /* {
   81                 syscallarg(int) req;
   82                 syscallarg(pid_t) pid;
   83                 syscallarg(caddr_t) addr;
   84                 syscallarg(int) data;
   85         } */ *uap = v;
   86         struct proc *t;                         /* target process */
   87         struct uio uio;
   88         struct iovec iov;
   89         struct ptrace_io_desc piod;
   90         struct ptrace_event pe;
   91         struct reg *regs;
   92 #if defined (PT_SETFPREGS) || defined (PT_GETFPREGS)
   93         struct fpreg *fpregs;
   94 #endif
   95 #if defined (PT_SETXMMREGS) || defined (PT_GETXMMREGS)
   96         struct xmmregs *xmmregs;
   97 #endif
   98 #ifdef PT_WCOOKIE
   99         register_t wcookie;
  100 #endif
  101         int error, write;
  102         int temp;
  103         int req;
  104         int s;
  105 
  106         /* "A foolish consistency..." XXX */
  107         if (SCARG(uap, req) == PT_TRACE_ME)
  108                 t = p;
  109         else {
  110 
  111                 /* Find the process we're supposed to be operating on. */
  112                 if ((t = pfind(SCARG(uap, pid))) == NULL)
  113                         return (ESRCH);
  114         }
  115 
  116         if ((t->p_flag & P_INEXEC) != 0)
  117                 return (EAGAIN);
  118 
  119         /* Make sure we can operate on it. */
  120         switch (SCARG(uap, req)) {
  121         case  PT_TRACE_ME:
  122                 /* Saying that you're being traced is always legal. */
  123                 break;
  124 
  125         case  PT_ATTACH:
  126                 /*
  127                  * You can't attach to a process if:
  128                  *      (1) it's the process that's doing the attaching,
  129                  */
  130                 if (t->p_pid == p->p_pid)
  131                         return (EINVAL);
  132 
  133                 /*
  134                  *      (2) it's a system process
  135                  */
  136                 if (ISSET(t->p_flag, P_SYSTEM))
  137                         return (EPERM);
  138 
  139                 /*
  140                  *      (3) it's already being traced, or
  141                  */
  142                 if (ISSET(t->p_flag, P_TRACED))
  143                         return (EBUSY);
  144 
  145                 /*
  146                  *      (4) it's not owned by you, or the last exec
  147                  *          gave us setuid/setgid privs (unless
  148                  *          you're root), or...
  149                  * 
  150                  *      [Note: once P_SUGID or P_SUGIDEXEC gets set in
  151                  *      execve(), they stay set until the process does
  152                  *      another execve().  Hence this prevents a setuid
  153                  *      process which revokes its special privileges using
  154                  *      setuid() from being traced.  This is good security.]
  155                  */
  156                 if ((t->p_cred->p_ruid != p->p_cred->p_ruid ||
  157                     ISSET(t->p_flag, P_SUGIDEXEC) ||
  158                     ISSET(t->p_flag, P_SUGID)) &&
  159                     (error = suser(p, 0)) != 0)
  160                         return (error);
  161 
  162                 /*
  163                  *      (5) ...it's init, which controls the security level
  164                  *          of the entire system, and the system was not
  165                  *          compiled with permanently insecure mode turned
  166                  *          on.
  167                  */
  168                 if ((t->p_pid == 1) && (securelevel > -1))
  169                         return (EPERM);
  170                 break;
  171 
  172         case  PT_READ_I:
  173         case  PT_READ_D:
  174         case  PT_WRITE_I:
  175         case  PT_WRITE_D:
  176         case  PT_IO:
  177         case  PT_CONTINUE:
  178         case  PT_KILL:
  179         case  PT_DETACH:
  180 #ifdef PT_STEP
  181         case  PT_STEP:
  182 #endif
  183         case  PT_SET_EVENT_MASK:
  184         case  PT_GET_EVENT_MASK:
  185         case  PT_GET_PROCESS_STATE:
  186         case  PT_GETREGS:
  187         case  PT_SETREGS:
  188 #ifdef PT_GETFPREGS
  189         case  PT_GETFPREGS:
  190 #endif
  191 #ifdef PT_SETFPREGS
  192         case  PT_SETFPREGS:
  193 #endif
  194 #ifdef PT_GETXMMREGS
  195         case  PT_GETXMMREGS:
  196 #endif
  197 #ifdef PT_SETXMMREGS
  198         case  PT_SETXMMREGS:
  199 #endif
  200 #ifdef PT_WCOOKIE
  201         case  PT_WCOOKIE:
  202 #endif
  203                 /*
  204                  * You can't do what you want to the process if:
  205                  *      (1) It's not being traced at all,
  206                  */
  207                 if (!ISSET(t->p_flag, P_TRACED))
  208                         return (EPERM);
  209 
  210                 /*
  211                  *      (2) it's not being traced by _you_, or
  212                  */
  213                 if (t->p_pptr != p)
  214                         return (EBUSY);
  215 
  216                 /*
  217                  *      (3) it's not currently stopped.
  218                  */
  219                 if (t->p_stat != SSTOP || !ISSET(t->p_flag, P_WAITED))
  220                         return (EBUSY);
  221                 break;
  222 
  223         default:                        /* It was not a legal request. */
  224                 return (EINVAL);
  225         }
  226 
  227         /* Do single-step fixup if needed. */
  228         FIX_SSTEP(t);
  229 
  230         /* Now do the operation. */
  231         write = 0;
  232         *retval = 0;
  233 
  234         switch (SCARG(uap, req)) {
  235         case  PT_TRACE_ME:
  236                 /* Just set the trace flag. */
  237                 atomic_setbits_int(&t->p_flag, P_TRACED);
  238                 t->p_oppid = t->p_pptr->p_pid;
  239                 if (t->p_ptstat == NULL)
  240                         t->p_ptstat = malloc(sizeof(*t->p_ptstat),
  241                             M_SUBPROC, M_WAITOK);
  242                 bzero(t->p_ptstat, sizeof(*t->p_ptstat));
  243                 return (0);
  244 
  245         case  PT_WRITE_I:               /* XXX no separate I and D spaces */
  246         case  PT_WRITE_D:
  247                 write = 1;
  248                 temp = SCARG(uap, data);
  249         case  PT_READ_I:                /* XXX no separate I and D spaces */
  250         case  PT_READ_D:
  251                 /* write = 0 done above. */
  252                 iov.iov_base = (caddr_t)&temp;
  253                 iov.iov_len = sizeof(int);
  254                 uio.uio_iov = &iov;
  255                 uio.uio_iovcnt = 1;
  256                 uio.uio_offset = (off_t)(long)SCARG(uap, addr);
  257                 uio.uio_resid = sizeof(int);
  258                 uio.uio_segflg = UIO_SYSSPACE;
  259                 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
  260                 uio.uio_procp = p;
  261                 error = process_domem(p, t, &uio, write ? PT_WRITE_I :
  262                                 PT_READ_I);
  263                 if (write == 0)
  264                         *retval = temp;
  265                 return (error);
  266         case  PT_IO:
  267                 error = copyin(SCARG(uap, addr), &piod, sizeof(piod));
  268                 if (error)
  269                         return (error);
  270                 iov.iov_base = piod.piod_addr;
  271                 iov.iov_len = piod.piod_len;
  272                 uio.uio_iov = &iov;
  273                 uio.uio_iovcnt = 1;
  274                 uio.uio_offset = (off_t)(long)piod.piod_offs;
  275                 uio.uio_resid = piod.piod_len;
  276                 uio.uio_segflg = UIO_USERSPACE;
  277                 uio.uio_procp = p;
  278                 switch (piod.piod_op) {
  279                 case PIOD_READ_I:
  280                         req = PT_READ_I;
  281                         uio.uio_rw = UIO_READ;
  282                         break;
  283                 case PIOD_READ_D:
  284                         req = PT_READ_D;
  285                         uio.uio_rw = UIO_READ;
  286                         break;
  287                 case PIOD_WRITE_I:
  288                         req = PT_WRITE_I;
  289                         uio.uio_rw = UIO_WRITE;
  290                         break;
  291                 case PIOD_WRITE_D:
  292                         req = PT_WRITE_D;
  293                         uio.uio_rw = UIO_WRITE;
  294                         break;
  295                 case PIOD_READ_AUXV:
  296                         req = PT_READ_D;
  297                         uio.uio_rw = UIO_READ;
  298                         temp = t->p_emul->e_arglen * sizeof(char *);
  299                         if (uio.uio_offset > temp)
  300                                 return (EIO);
  301                         if (uio.uio_resid > temp - uio.uio_offset)
  302                                 uio.uio_resid = temp - uio.uio_offset;
  303                         piod.piod_len = iov.iov_len = uio.uio_resid;
  304                         error = process_auxv_offset(p, t, &uio);
  305                         if (error)
  306                                 return (error);
  307                         break;
  308                 default:
  309                         return (EINVAL);
  310                 }
  311                 error = process_domem(p, t, &uio, req);
  312                 piod.piod_len -= uio.uio_resid;
  313                 (void) copyout(&piod, SCARG(uap, addr), sizeof(piod));
  314                 return (error);
  315 #ifdef PT_STEP
  316         case  PT_STEP:
  317                 /*
  318                  * From the 4.4BSD PRM:
  319                  * "Execution continues as in request PT_CONTINUE; however
  320                  * as soon as possible after execution of at least one
  321                  * instruction, execution stops again. [ ... ]"
  322                  */
  323 #endif
  324         case  PT_CONTINUE:
  325                 /*
  326                  * From the 4.4BSD PRM:
  327                  * "The data argument is taken as a signal number and the
  328                  * child's execution continues at location addr as if it
  329                  * incurred that signal.  Normally the signal number will
  330                  * be either 0 to indicate that the signal that caused the
  331                  * stop should be ignored, or that value fetched out of
  332                  * the process's image indicating which signal caused
  333                  * the stop.  If addr is (int *)1 then execution continues
  334                  * from where it stopped."
  335                  */
  336 
  337                 /* Check that the data is a valid signal number or zero. */
  338                 if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG)
  339                         return (EINVAL);
  340 
  341                 /* If the address parameter is not (int *)1, set the pc. */
  342                 if ((int *)SCARG(uap, addr) != (int *)1)
  343                         if ((error = process_set_pc(t, SCARG(uap, addr))) != 0)
  344                                 goto relebad;
  345 
  346 #ifdef PT_STEP
  347                 /*
  348                  * Arrange for a single-step, if that's requested and possible.
  349                  */
  350                 error = process_sstep(t, SCARG(uap, req) == PT_STEP);
  351                 if (error)
  352                         goto relebad;
  353 #endif
  354                 goto sendsig;
  355 
  356         case  PT_DETACH:
  357                 /*
  358                  * From the 4.4BSD PRM:
  359                  * "The data argument is taken as a signal number and the
  360                  * child's execution continues at location addr as if it
  361                  * incurred that signal.  Normally the signal number will
  362                  * be either 0 to indicate that the signal that caused the
  363                  * stop should be ignored, or that value fetched out of
  364                  * the process's image indicating which signal caused
  365                  * the stop.  If addr is (int *)1 then execution continues
  366                  * from where it stopped."
  367                  */
  368 
  369                 /* Check that the data is a valid signal number or zero. */
  370                 if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG)
  371                         return (EINVAL);
  372 
  373 #ifdef PT_STEP
  374                 /*
  375                  * Arrange for a single-step, if that's requested and possible.
  376                  */
  377                 error = process_sstep(t, SCARG(uap, req) == PT_STEP);
  378                 if (error)
  379                         goto relebad;
  380 #endif
  381 
  382                 /* give process back to original parent or init */
  383                 if (t->p_oppid != t->p_pptr->p_pid) {
  384                         struct proc *pp;
  385 
  386                         pp = pfind(t->p_oppid);
  387                         proc_reparent(t, pp ? pp : initproc);
  388                 }
  389 
  390                 /* not being traced any more */
  391                 t->p_oppid = 0;
  392                 atomic_clearbits_int(&t->p_flag, P_TRACED|P_WAITED);
  393 
  394         sendsig:
  395                 bzero(t->p_ptstat, sizeof(*t->p_ptstat));
  396 
  397                 /* Finally, deliver the requested signal (or none). */
  398                 if (t->p_stat == SSTOP) {
  399                         t->p_xstat = SCARG(uap, data);
  400                         SCHED_LOCK(s);
  401                         setrunnable(t);
  402                         SCHED_UNLOCK(s);
  403                 } else {
  404                         if (SCARG(uap, data) != 0)
  405                                 psignal(t, SCARG(uap, data));
  406                 }
  407                 return (0);
  408 
  409         relebad:
  410                 return (error);
  411 
  412         case  PT_KILL:
  413                 /* just send the process a KILL signal. */
  414                 SCARG(uap, data) = SIGKILL;
  415                 goto sendsig;   /* in PT_CONTINUE, above. */
  416 
  417         case  PT_ATTACH:
  418                 /*
  419                  * As done in procfs:
  420                  * Go ahead and set the trace flag.
  421                  * Save the old parent (it's reset in
  422                  *   _DETACH, and also in kern_exit.c:wait4()
  423                  * Reparent the process so that the tracing
  424                  *   proc gets to see all the action.
  425                  * Stop the target.
  426                  */
  427                 atomic_setbits_int(&t->p_flag, P_TRACED);
  428                 t->p_oppid = t->p_pptr->p_pid;
  429                 if (t->p_pptr != p)
  430                         proc_reparent(t, p);
  431                 if (t->p_ptstat == NULL)
  432                         t->p_ptstat = malloc(sizeof(*t->p_ptstat),
  433                             M_SUBPROC, M_WAITOK);
  434                 SCARG(uap, data) = SIGSTOP;
  435                 goto sendsig;
  436 
  437         case  PT_GET_EVENT_MASK:
  438                 if (SCARG(uap, data) != sizeof(pe))
  439                         return (EINVAL);
  440                 bzero(&pe, sizeof(pe));
  441                 pe.pe_set_event = t->p_ptmask;
  442                 return (copyout(&pe, SCARG(uap, addr), sizeof(pe)));
  443         case  PT_SET_EVENT_MASK:
  444                 if (SCARG(uap, data) != sizeof(pe))
  445                         return (EINVAL);
  446                 if ((error = copyin(SCARG(uap, addr), &pe, sizeof(pe))))
  447                         return (error);
  448                 t->p_ptmask = pe.pe_set_event;
  449                 return (0);
  450 
  451         case  PT_GET_PROCESS_STATE:
  452                 if (SCARG(uap, data) != sizeof(*t->p_ptstat))
  453                         return (EINVAL);
  454                 return (copyout(t->p_ptstat, SCARG(uap, addr),
  455                     sizeof(*t->p_ptstat)));
  456 
  457         case  PT_SETREGS:
  458                 KASSERT((p->p_flag & P_SYSTEM) == 0);
  459                 if ((error = process_checkioperm(p, t)) != 0)
  460                         return (error);
  461 
  462                 regs = malloc(sizeof(*regs), M_TEMP, M_WAITOK);
  463                 error = copyin(SCARG(uap, addr), regs, sizeof(*regs));
  464                 if (error == 0) {
  465                         error = process_write_regs(t, regs);
  466                 }
  467                 free(regs, M_TEMP);
  468                 return (error);
  469         case  PT_GETREGS:
  470                 KASSERT((p->p_flag & P_SYSTEM) == 0);
  471                 if ((error = process_checkioperm(p, t)) != 0)
  472                         return (error);
  473 
  474                 regs = malloc(sizeof(*regs), M_TEMP, M_WAITOK);
  475                 error = process_read_regs(t, regs);
  476                 if (error == 0)
  477                         error = copyout(regs,
  478                             SCARG(uap, addr), sizeof (*regs));
  479                 free(regs, M_TEMP);
  480                 return (error);
  481 #ifdef PT_SETFPREGS
  482         case  PT_SETFPREGS:
  483                 KASSERT((p->p_flag & P_SYSTEM) == 0);
  484                 if ((error = process_checkioperm(p, t)) != 0)
  485                         return (error);
  486 
  487                 fpregs = malloc(sizeof(*fpregs), M_TEMP, M_WAITOK);
  488                 error = copyin(SCARG(uap, addr), fpregs, sizeof(*fpregs));
  489                 if (error == 0) {
  490                         error = process_write_fpregs(t, fpregs);
  491                 }
  492                 free(fpregs, M_TEMP);
  493                 return (error);
  494 #endif
  495 #ifdef PT_GETFPREGS
  496         case  PT_GETFPREGS:
  497                 KASSERT((p->p_flag & P_SYSTEM) == 0);
  498                 if ((error = process_checkioperm(p, t)) != 0)
  499                         return (error);
  500 
  501                 fpregs = malloc(sizeof(*fpregs), M_TEMP, M_WAITOK);
  502                 error = process_read_fpregs(t, fpregs);
  503                 if (error == 0)
  504                         error = copyout(fpregs,
  505                             SCARG(uap, addr), sizeof(*fpregs));
  506                 free(fpregs, M_TEMP);
  507                 return (error);
  508 #endif
  509 #ifdef PT_SETXMMREGS
  510         case  PT_SETXMMREGS:
  511                 KASSERT((p->p_flag & P_SYSTEM) == 0);
  512                 if ((error = process_checkioperm(p, t)) != 0)
  513                         return (error);
  514 
  515                 xmmregs = malloc(sizeof(*xmmregs), M_TEMP, M_WAITOK);
  516                 error = copyin(SCARG(uap, addr), xmmregs, sizeof(*xmmregs));
  517                 if (error == 0) {
  518                         error = process_write_xmmregs(t, xmmregs);
  519                 }
  520                 free(xmmregs, M_TEMP);
  521                 return (error);
  522 #endif
  523 #ifdef PT_GETXMMREGS
  524         case  PT_GETXMMREGS:
  525                 KASSERT((p->p_flag & P_SYSTEM) == 0);
  526                 if ((error = process_checkioperm(p, t)) != 0)
  527                         return (error);
  528 
  529                 xmmregs = malloc(sizeof(*xmmregs), M_TEMP, M_WAITOK);
  530                 error = process_read_xmmregs(t, xmmregs);
  531                 if (error == 0)
  532                         error = copyout(xmmregs,
  533                             SCARG(uap, addr), sizeof(*xmmregs));
  534                 free(xmmregs, M_TEMP);
  535                 return (error);
  536 #endif
  537 #ifdef PT_WCOOKIE
  538         case  PT_WCOOKIE:
  539                 wcookie = process_get_wcookie (t);
  540                 return (copyout(&wcookie, SCARG(uap, addr),
  541                     sizeof (register_t)));
  542 #endif
  543         }
  544 
  545 #ifdef DIAGNOSTIC
  546         panic("ptrace: impossible");
  547 #endif
  548         return 0;
  549 }
  550 #endif  /* PTRACE */
  551 
  552 /*
  553  * Check if a process is allowed to fiddle with the memory of another.
  554  *
  555  * p = tracer
  556  * t = tracee
  557  *
  558  * 1.  You can't attach to a process not owned by you or one that has raised
  559  *     its privileges.
  560  * 1a. ...unless you are root.
  561  *
  562  * 2.  init is always off-limits because it can control the securelevel.
  563  * 2a. ...unless securelevel is permanently set to insecure.
  564  *
  565  * 3.  Processes that are in the process of doing an exec() are always
  566  *     off-limits because of the can of worms they are. Just wait a
  567  *     second.
  568  */
  569 int
  570 process_checkioperm(struct proc *p, struct proc *t)
  571 {
  572         int error;
  573 
  574         if ((t->p_cred->p_ruid != p->p_cred->p_ruid ||
  575             ISSET(t->p_flag, P_SUGIDEXEC) ||
  576             ISSET(t->p_flag, P_SUGID)) &&
  577             (error = suser(p, 0)) != 0)
  578                 return (error);
  579 
  580         if ((t->p_pid == 1) && (securelevel > -1))
  581                 return (EPERM);
  582 
  583         if (t->p_flag & P_INEXEC)
  584                 return (EAGAIN);
  585 
  586         return (0);
  587 }
  588 
  589 int
  590 process_domem(struct proc *curp, struct proc *p, struct uio *uio, int req)
  591 {
  592         struct vmspace *vm;
  593         int error;
  594         vaddr_t addr;
  595         vsize_t len;
  596 
  597         len = uio->uio_resid;
  598         if (len == 0)
  599                 return (0);
  600 
  601         if ((error = process_checkioperm(curp, p)) != 0)
  602                 return (error);
  603 
  604         /* XXXCDC: how should locking work here? */
  605         if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) 
  606                 return(EFAULT);
  607         addr = uio->uio_offset;
  608 
  609         vm = p->p_vmspace;
  610         vm->vm_refcnt++;
  611 
  612         error = uvm_io(&vm->vm_map, uio,
  613             (req == PT_WRITE_I) ? UVM_IO_FIXPROT : 0);
  614 
  615         uvmspace_free(vm);
  616 
  617         if (error == 0 && req == PT_WRITE_I)
  618                 pmap_proc_iflush(p, addr, len);
  619 
  620         return (error);
  621 }
  622 
  623 #ifdef PTRACE
  624 int
  625 process_auxv_offset(struct proc *curp, struct proc *p, struct uio *uiop)
  626 {
  627         struct ps_strings pss;
  628         struct iovec iov;
  629         struct uio uio;
  630         int error;
  631 
  632         iov.iov_base = &pss;
  633         iov.iov_len = sizeof(pss);
  634         uio.uio_iov = &iov;
  635         uio.uio_iovcnt = 1;     
  636         uio.uio_offset = (off_t)PS_STRINGS;
  637         uio.uio_resid = sizeof(pss);
  638         uio.uio_segflg = UIO_SYSSPACE;
  639         uio.uio_rw = UIO_READ;
  640         uio.uio_procp = curp;
  641 
  642         if ((error = uvm_io(&p->p_vmspace->vm_map, &uio, 0)) != 0)
  643                 return (error);
  644 
  645         if (pss.ps_envstr == NULL)
  646                 return (EIO);
  647 
  648         uiop->uio_offset += (off_t)(long)(pss.ps_envstr + pss.ps_nenvstr + 1);
  649 #ifdef MACHINE_STACK_GROWS_UP
  650         if (uiop->uio_offset < (off_t)PS_STRINGS)
  651                 return (EIO);
  652 #else
  653         if (uiop->uio_offset > (off_t)PS_STRINGS)
  654                 return (EIO);
  655         if ((uiop->uio_offset + uiop->uio_resid) > (off_t)PS_STRINGS)
  656                 uiop->uio_resid = (off_t)PS_STRINGS - uiop->uio_offset;
  657 #endif
  658 
  659         return (0);
  660 }
  661 #endif

Cache object: 19599501808276658b5d055ac0a7371d


[ 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.