LCOV - code coverage report
Current view: top level - kern - sys_process.c (source / functions) Hit Total Coverage
Test: 6.4 Lines: 0 311 0.0 %
Date: 2018-10-19 03:25:38 Functions: 0 9 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*      $OpenBSD: sys_process.c,v 1.80 2018/02/19 09:25:13 mpi 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/sched.h>
      62             : 
      63             : #include <sys/mount.h>
      64             : #include <sys/syscallargs.h>
      65             : 
      66             : #include <uvm/uvm_extern.h>
      67             : 
      68             : #include <machine/reg.h>
      69             : 
      70             : #ifdef PTRACE
      71             : 
      72             : static inline int       process_checktracestate(struct process *_curpr,
      73             :                             struct process *_tr, struct proc *_t);
      74             : static inline struct process *process_tprfind(pid_t _tpid, struct proc **_tp);
      75             : 
      76             : int     ptrace_ctrl(struct proc *, int, pid_t, caddr_t, int);
      77             : int     ptrace_ustate(struct proc *, int, pid_t, void *, int, register_t *);
      78             : int     ptrace_kstate(struct proc *, int, pid_t, void *);
      79             : int     process_auxv_offset(struct proc *, struct process *, struct uio *);
      80             : 
      81             : int     global_ptrace;  /* permit tracing of not children */
      82             : 
      83             : 
      84             : /*
      85             :  * Process debugging system call.
      86             :  */
      87             : int
      88           0 : sys_ptrace(struct proc *p, void *v, register_t *retval)
      89             : {
      90             :         struct sys_ptrace_args /* {
      91             :                 syscallarg(int) req;
      92             :                 syscallarg(pid_t) pid;
      93             :                 syscallarg(caddr_t) addr;
      94             :                 syscallarg(int) data;
      95           0 :         } */ *uap = v;
      96           0 :         int req = SCARG(uap, req);
      97           0 :         pid_t pid = SCARG(uap, pid);
      98           0 :         caddr_t uaddr = SCARG(uap, addr);       /* userspace */
      99             :         void *kaddr = NULL;                     /* kernelspace */
     100           0 :         int data = SCARG(uap, data);
     101           0 :         union {
     102             :                 struct ptrace_thread_state u_pts;
     103             :                 struct ptrace_io_desc u_piod;
     104             :                 struct ptrace_event u_pe;
     105             :                 struct ptrace_state u_ps;
     106             :                 register_t u_wcookie;
     107             :         } u;
     108             :         int size = 0;
     109             :         enum { NONE, IN, IN_ALLOC, OUT, OUT_ALLOC, IN_OUT } mode;
     110             :         int kstate = 0;
     111             :         int error;
     112             : 
     113           0 :         *retval = 0;
     114             : 
     115             :         /* Figure out what sort of copyin/out operations we'll do */
     116           0 :         switch (req) {
     117             :         case PT_TRACE_ME:
     118             :         case PT_CONTINUE:
     119             :         case PT_KILL:
     120             :         case PT_ATTACH:
     121             :         case PT_DETACH:
     122             : #ifdef PT_STEP
     123             :         case PT_STEP:
     124             : #endif
     125             :                 /* control operations do no copyin/out; dispatch directly */
     126           0 :                 return ptrace_ctrl(p, req, pid, uaddr, data);
     127             : 
     128             :         case PT_READ_I:
     129             :         case PT_READ_D:
     130             :         case PT_WRITE_I:
     131             :         case PT_WRITE_D:
     132             :                 mode = NONE;
     133           0 :                 break;
     134             :         case PT_IO:
     135             :                 mode = IN_OUT;
     136             :                 size = sizeof u.u_piod;
     137             :                 data = size;    /* suppress the data == size check */
     138           0 :                 break;
     139             :         case PT_GET_THREAD_FIRST:
     140             :                 mode = OUT;
     141             :                 size = sizeof u.u_pts;
     142             :                 kstate = 1;
     143           0 :                 break;
     144             :         case PT_GET_THREAD_NEXT:
     145             :                 mode = IN_OUT;
     146             :                 size = sizeof u.u_pts;
     147             :                 kstate = 1;
     148           0 :                 break;
     149             :         case PT_GET_EVENT_MASK:
     150             :                 mode = OUT;
     151             :                 size = sizeof u.u_pe;
     152             :                 kstate = 1;
     153           0 :                 break;
     154             :         case PT_SET_EVENT_MASK:
     155             :                 mode = IN;
     156             :                 size = sizeof u.u_pe;
     157             :                 kstate = 1;
     158           0 :                 break;
     159             :         case PT_GET_PROCESS_STATE:
     160             :                 mode = OUT;
     161             :                 size = sizeof u.u_ps;
     162             :                 kstate = 1;
     163           0 :                 break;
     164             :         case PT_GETREGS:
     165             :                 mode = OUT_ALLOC;
     166             :                 size = sizeof(struct reg);
     167           0 :                 break;
     168             :         case PT_SETREGS:
     169             :                 mode = IN_ALLOC;
     170             :                 size = sizeof(struct reg);
     171           0 :                 break;
     172             : #ifdef PT_GETFPREGS
     173             :         case PT_GETFPREGS:
     174             :                 mode = OUT_ALLOC;
     175             :                 size = sizeof(struct fpreg);
     176           0 :                 break;
     177             : #endif
     178             : #ifdef PT_SETFPREGS
     179             :         case PT_SETFPREGS:
     180             :                 mode = IN_ALLOC;
     181             :                 size = sizeof(struct fpreg);
     182           0 :                 break;
     183             : #endif
     184             : #ifdef PT_GETXMMREGS
     185             :         case PT_GETXMMREGS:
     186             :                 mode = OUT_ALLOC;
     187             :                 size = sizeof(struct xmmregs);
     188             :                 break;
     189             : #endif
     190             : #ifdef PT_SETXMMREGS
     191             :         case PT_SETXMMREGS:
     192             :                 mode = IN_ALLOC;
     193             :                 size = sizeof(struct xmmregs);
     194             :                 break;
     195             : #endif
     196             : #ifdef PT_WCOOKIE
     197             :         case PT_WCOOKIE:
     198             :                 mode = OUT;
     199             :                 size = sizeof u.u_wcookie;
     200             :                 data = size;    /* suppress the data == size check */
     201             :                 break;
     202             : #endif
     203             :         default:
     204           0 :                 return EINVAL;
     205             :         }
     206             : 
     207             : 
     208             :         /* Now do any copyin()s and allocations in a consistent manner */
     209           0 :         switch (mode) {
     210             :         case NONE:
     211             :                 kaddr = uaddr;
     212           0 :                 break;
     213             :         case IN:
     214             :         case IN_OUT:
     215             :         case OUT:
     216           0 :                 KASSERT(size <= sizeof u);
     217           0 :                 if (data != size)
     218           0 :                         return EINVAL;
     219           0 :                 if (mode == OUT)
     220           0 :                         memset(&u, 0, size);
     221             :                 else { /* IN or IN_OUT */
     222           0 :                         if ((error = copyin(uaddr, &u, size)))
     223           0 :                                 return error;
     224             :                 }
     225             :                 kaddr = &u;
     226           0 :                 break;
     227             :         case IN_ALLOC:
     228           0 :                 kaddr = malloc(size, M_TEMP, M_WAITOK);
     229           0 :                 if ((error = copyin(uaddr, kaddr, size))) {
     230           0 :                         free(kaddr, M_TEMP, size);
     231           0 :                         return error;
     232             :                 }
     233             :                 break;
     234             :         case OUT_ALLOC:
     235           0 :                 kaddr = malloc(size, M_TEMP, M_WAITOK | M_ZERO);
     236           0 :                 break;
     237             :         }
     238             : 
     239           0 :         if (kstate)
     240           0 :                 error = ptrace_kstate(p, req, pid, kaddr);
     241             :         else
     242           0 :                 error = ptrace_ustate(p, req, pid, kaddr, data, retval);
     243             : 
     244             :         /* Do any copyout()s and frees */
     245           0 :         if (error == 0) {
     246           0 :                 switch (mode) {
     247             :                 case NONE:
     248             :                 case IN:
     249             :                 case IN_ALLOC:
     250             :                         break;
     251             :                 case IN_OUT:
     252             :                 case OUT:
     253           0 :                         error = copyout(&u, uaddr, size);
     254           0 :                         if (req == PT_IO) {
     255             :                                 /* historically, errors here are ignored */
     256             :                                 error = 0;
     257             :                         }
     258           0 :                         break;
     259             :                 case OUT_ALLOC:
     260           0 :                         error = copyout(kaddr, uaddr, size);
     261           0 :                         break;
     262             :                 }
     263             :         }
     264             : 
     265           0 :         if (mode == IN_ALLOC || mode == OUT_ALLOC)
     266           0 :                 free(kaddr, M_TEMP, size);
     267           0 :         return error;
     268           0 : }
     269             : 
     270             : /*
     271             :  * ptrace control requests: attach, detach, continue, kill, single-step, etc
     272             :  */
     273             : int
     274           0 : ptrace_ctrl(struct proc *p, int req, pid_t pid, caddr_t addr, int data)
     275             : {
     276           0 :         struct proc *t;                         /* target thread */
     277             :         struct process *tr;                     /* target process */
     278             :         int error = 0;
     279             :         int s;
     280             : 
     281           0 :         switch (req) {
     282             :         case PT_TRACE_ME:
     283             :                 /* Just set the trace flag. */
     284           0 :                 tr = p->p_p;
     285           0 :                 atomic_setbits_int(&tr->ps_flags, PS_TRACED);
     286           0 :                 tr->ps_oppid = tr->ps_pptr->ps_pid;
     287           0 :                 if (tr->ps_ptstat == NULL)
     288           0 :                         tr->ps_ptstat = malloc(sizeof(*tr->ps_ptstat),
     289             :                             M_SUBPROC, M_WAITOK);
     290           0 :                 memset(tr->ps_ptstat, 0, sizeof(*tr->ps_ptstat));
     291           0 :                 return 0;
     292             : 
     293             :         /* calls that only operate on the PID */
     294             :         case PT_KILL:
     295             :         case PT_ATTACH:
     296             :         case PT_DETACH:
     297             :                 /* Find the process we're supposed to be operating on. */
     298           0 :                 if ((tr = prfind(pid)) == NULL) {
     299             :                         error = ESRCH;
     300           0 :                         goto fail;
     301             :                 }
     302           0 :                 t = TAILQ_FIRST(&tr->ps_threads);
     303           0 :                 break;
     304             : 
     305             :         /* calls that accept a PID or a thread ID */
     306             :         case PT_CONTINUE:
     307             : #ifdef PT_STEP
     308             :         case PT_STEP:
     309             : #endif
     310           0 :                 if ((tr = process_tprfind(pid, &t)) == NULL) {
     311             :                         error = ESRCH;
     312           0 :                         goto fail;
     313             :                 }
     314             :                 break;
     315             :         }
     316             : 
     317             :         /* Check permissions/state */
     318           0 :         if (req != PT_ATTACH) {
     319             :                 /* Check that the data is a valid signal number or zero. */
     320           0 :                 if (req != PT_KILL && (data < 0 || data >= NSIG)) {
     321             :                         error = EINVAL;
     322           0 :                         goto fail;
     323             :                 }
     324             : 
     325             :                 /* Most operations require the target to already be traced */
     326           0 :                 if ((error = process_checktracestate(p->p_p, tr, t)))
     327             :                         goto fail;
     328             : 
     329             :                 /* Do single-step fixup if needed. */
     330             :                 FIX_SSTEP(t);
     331             :         } else {
     332             :                 /*
     333             :                  * PT_ATTACH is the opposite; you can't attach to a process if:
     334             :                  *      (1) it's the process that's doing the attaching,
     335             :                  */
     336           0 :                 if (tr == p->p_p) {
     337             :                         error = EINVAL;
     338           0 :                         goto fail;
     339             :                 }
     340             : 
     341             :                 /*
     342             :                  *      (2) it's a system process
     343             :                  */
     344           0 :                 if (ISSET(tr->ps_flags, PS_SYSTEM)) {
     345             :                         error = EPERM;
     346           0 :                         goto fail;
     347             :                 }
     348             : 
     349             :                 /*
     350             :                  *      (3) it's already being traced, or
     351             :                  */
     352           0 :                 if (ISSET(tr->ps_flags, PS_TRACED)) {
     353             :                         error = EBUSY;
     354           0 :                         goto fail;
     355             :                 }
     356             : 
     357             :                 /*
     358             :                  *      (4) it's in the middle of execve(2)
     359             :                  */
     360           0 :                 if (ISSET(tr->ps_flags, PS_INEXEC)) {
     361             :                         error = EAGAIN;
     362           0 :                         goto fail;
     363             :                 }
     364             : 
     365             :                 /*
     366             :                  *      (5) it's not owned by you, or the last exec
     367             :                  *          gave us setuid/setgid privs (unless
     368             :                  *          you're root), or...
     369             :                  * 
     370             :                  *      [Note: once PS_SUGID or PS_SUGIDEXEC gets set in
     371             :                  *      execve(), they stay set until the process does
     372             :                  *      another execve().  Hence this prevents a setuid
     373             :                  *      process which revokes its special privileges using
     374             :                  *      setuid() from being traced.  This is good security.]
     375             :                  */
     376           0 :                 if ((tr->ps_ucred->cr_ruid != p->p_ucred->cr_ruid ||
     377           0 :                     ISSET(tr->ps_flags, PS_SUGIDEXEC | PS_SUGID)) &&
     378           0 :                     (error = suser(p)) != 0)
     379             :                         goto fail;
     380             : 
     381             :                 /*
     382             :                  *      (5.5) it's not a child of the tracing process.
     383             :                  */
     384           0 :                 if (global_ptrace == 0 && !inferior(tr, p->p_p) &&
     385           0 :                     (error = suser(p)) != 0)
     386             :                         goto fail;
     387             : 
     388             :                 /*
     389             :                  *      (6) ...it's init, which controls the security level
     390             :                  *          of the entire system, and the system was not
     391             :                  *          compiled with permanently insecure mode turned
     392             :                  *          on.
     393             :                  */
     394           0 :                 if ((tr->ps_pid == 1) && (securelevel > -1)) {
     395             :                         error = EPERM;
     396           0 :                         goto fail;
     397             :                 }
     398             : 
     399             :                 /*
     400             :                  *      (7) it's an ancestor of the current process and
     401             :                  *          not init (because that would create a loop in
     402             :                  *          the process graph).
     403             :                  */
     404           0 :                 if (tr->ps_pid != 1 && inferior(p->p_p, tr)) {
     405             :                         error = EINVAL;
     406           0 :                         goto fail;
     407             :                 }
     408             :         }
     409             : 
     410           0 :         switch (req) {
     411             : 
     412             : #ifdef PT_STEP
     413             :         case PT_STEP:
     414             :                 /*
     415             :                  * From the 4.4BSD PRM:
     416             :                  * "Execution continues as in request PT_CONTINUE; however
     417             :                  * as soon as possible after execution of at least one
     418             :                  * instruction, execution stops again. [ ... ]"
     419             :                  */
     420             : #endif
     421             :         case PT_CONTINUE:
     422             :                 /*
     423             :                  * From the 4.4BSD PRM:
     424             :                  * "The data argument is taken as a signal number and the
     425             :                  * child's execution continues at location addr as if it
     426             :                  * incurred that signal.  Normally the signal number will
     427             :                  * be either 0 to indicate that the signal that caused the
     428             :                  * stop should be ignored, or that value fetched out of
     429             :                  * the process's image indicating which signal caused
     430             :                  * the stop.  If addr is (int *)1 then execution continues
     431             :                  * from where it stopped."
     432             :                  */
     433             : 
     434           0 :                 if (pid < THREAD_PID_OFFSET && tr->ps_single)
     435           0 :                         t = tr->ps_single;
     436             : 
     437             :                 /* If the address parameter is not (int *)1, set the pc. */
     438           0 :                 if ((int *)addr != (int *)1)
     439           0 :                         if ((error = process_set_pc(t, addr)) != 0)
     440             :                                 goto fail;
     441             : 
     442             : #ifdef PT_STEP
     443             :                 /*
     444             :                  * Arrange for a single-step, if that's requested and possible.
     445             :                  */
     446           0 :                 error = process_sstep(t, req == PT_STEP);
     447           0 :                 if (error)
     448             :                         goto fail;
     449             : #endif
     450             :                 goto sendsig;
     451             : 
     452             :         case PT_DETACH:
     453             :                 /*
     454             :                  * From the 4.4BSD PRM:
     455             :                  * "The data argument is taken as a signal number and the
     456             :                  * child's execution continues at location addr as if it
     457             :                  * incurred that signal.  Normally the signal number will
     458             :                  * be either 0 to indicate that the signal that caused the
     459             :                  * stop should be ignored, or that value fetched out of
     460             :                  * the process's image indicating which signal caused
     461             :                  * the stop.  If addr is (int *)1 then execution continues
     462             :                  * from where it stopped."
     463             :                  */
     464             : 
     465           0 :                 if (pid < THREAD_PID_OFFSET && tr->ps_single)
     466           0 :                         t = tr->ps_single;
     467             : 
     468             : #ifdef PT_STEP
     469             :                 /*
     470             :                  * Stop single stepping.
     471             :                  */
     472           0 :                 error = process_sstep(t, 0);
     473           0 :                 if (error)
     474             :                         goto fail;
     475             : #endif
     476             : 
     477             :                 /* give process back to original parent or init */
     478           0 :                 if (tr->ps_oppid != tr->ps_pptr->ps_pid) {
     479             :                         struct process *ppr;
     480             : 
     481           0 :                         ppr = prfind(tr->ps_oppid);
     482           0 :                         proc_reparent(tr, ppr ? ppr : initprocess);
     483           0 :                 }
     484             : 
     485             :                 /* not being traced any more */
     486           0 :                 tr->ps_oppid = 0;
     487           0 :                 atomic_clearbits_int(&tr->ps_flags, PS_TRACED|PS_WAITED);
     488             : 
     489             :         sendsig:
     490           0 :                 memset(tr->ps_ptstat, 0, sizeof(*tr->ps_ptstat));
     491             : 
     492             :                 /* Finally, deliver the requested signal (or none). */
     493           0 :                 if (t->p_stat == SSTOP) {
     494           0 :                         t->p_xstat = data;
     495           0 :                         SCHED_LOCK(s);
     496           0 :                         setrunnable(t);
     497           0 :                         SCHED_UNLOCK(s);
     498           0 :                 } else {
     499           0 :                         if (data != 0)
     500           0 :                                 psignal(t, data);
     501             :                 }
     502             :                 break;
     503             : 
     504             :         case PT_KILL:
     505           0 :                 if (pid < THREAD_PID_OFFSET && tr->ps_single)
     506           0 :                         t = tr->ps_single;
     507             : 
     508             :                 /* just send the process a KILL signal. */
     509             :                 data = SIGKILL;
     510           0 :                 goto sendsig;   /* in PT_CONTINUE, above. */
     511             : 
     512             :         case PT_ATTACH:
     513             :                 /*
     514             :                  * As was done in procfs:
     515             :                  * Go ahead and set the trace flag.
     516             :                  * Save the old parent (it's reset in
     517             :                  *   _DETACH, and also in kern_exit.c:wait4()
     518             :                  * Reparent the process so that the tracing
     519             :                  *   proc gets to see all the action.
     520             :                  * Stop the target.
     521             :                  */
     522           0 :                 atomic_setbits_int(&tr->ps_flags, PS_TRACED);
     523           0 :                 tr->ps_oppid = tr->ps_pptr->ps_pid;
     524           0 :                 if (tr->ps_pptr != p->p_p)
     525           0 :                         proc_reparent(tr, p->p_p);
     526           0 :                 if (tr->ps_ptstat == NULL)
     527           0 :                         tr->ps_ptstat = malloc(sizeof(*tr->ps_ptstat),
     528             :                             M_SUBPROC, M_WAITOK);
     529             :                 data = SIGSTOP;
     530           0 :                 goto sendsig;
     531             :         default:
     532           0 :                 KASSERTMSG(0, "%s: unhandled request %d", __func__, req);
     533             :                 break;
     534             :         }
     535             : 
     536             : fail:
     537           0 :         return error;
     538           0 : }
     539             : 
     540             : /*
     541             :  * ptrace kernel-state requests: thread list, event mask, process state
     542             :  */
     543             : int
     544           0 : ptrace_kstate(struct proc *p, int req, pid_t pid, void *addr)
     545             : {
     546             :         struct process *tr;                     /* target process */
     547           0 :         struct ptrace_event *pe = addr;
     548             :         int error;
     549             : 
     550           0 :         KASSERT((p->p_flag & P_SYSTEM) == 0);
     551             : 
     552             :         /* Find the process we're supposed to be operating on. */
     553           0 :         if ((tr = prfind(pid)) == NULL)
     554           0 :                 return ESRCH;
     555             : 
     556           0 :         if ((error = process_checktracestate(p->p_p, tr, NULL)))
     557           0 :                 return error;
     558             : 
     559           0 :         switch (req) {
     560             :         case PT_GET_THREAD_FIRST:
     561             :         case PT_GET_THREAD_NEXT:
     562             :               {
     563           0 :                 struct ptrace_thread_state *pts = addr;
     564             :                 struct proc *t;
     565             : 
     566           0 :                 if (req == PT_GET_THREAD_NEXT) {
     567           0 :                         t = tfind(pts->pts_tid - THREAD_PID_OFFSET);
     568           0 :                         if (t == NULL || ISSET(t->p_flag, P_WEXIT))
     569           0 :                                 return ESRCH;
     570           0 :                         if (t->p_p != tr)
     571           0 :                                 return EINVAL;
     572           0 :                         t = TAILQ_NEXT(t, p_thr_link);
     573           0 :                 } else {
     574           0 :                         t = TAILQ_FIRST(&tr->ps_threads);
     575             :                 }
     576             : 
     577           0 :                 if (t == NULL)
     578           0 :                         pts->pts_tid = -1;
     579             :                 else
     580           0 :                         pts->pts_tid = t->p_tid + THREAD_PID_OFFSET;
     581           0 :                 return 0;
     582             :               }
     583             :         }
     584             : 
     585           0 :         switch (req) {
     586             :         case PT_GET_EVENT_MASK:
     587           0 :                 pe->pe_set_event = tr->ps_ptmask;
     588           0 :                 break;
     589             :         case PT_SET_EVENT_MASK:
     590           0 :                 tr->ps_ptmask = pe->pe_set_event;
     591           0 :                 break;
     592             :         case PT_GET_PROCESS_STATE:
     593           0 :                 if (tr->ps_single)
     594           0 :                         tr->ps_ptstat->pe_tid =
     595           0 :                             tr->ps_single->p_tid + THREAD_PID_OFFSET;
     596           0 :                 memcpy(addr, tr->ps_ptstat, sizeof *tr->ps_ptstat);
     597           0 :                 break;
     598             :         default:
     599           0 :                 KASSERTMSG(0, "%s: unhandled request %d", __func__, req);
     600             :                 break;
     601             :         }
     602             : 
     603           0 :         return 0;
     604           0 : }
     605             : 
     606             : /*
     607             :  * ptrace user-state requests: memory access, registers, stack cookie
     608             :  */
     609             : int
     610           0 : ptrace_ustate(struct proc *p, int req, pid_t pid, void *addr, int data,
     611             :     register_t *retval)
     612             : {
     613           0 :         struct proc *t;                         /* target thread */
     614             :         struct process *tr;                     /* target process */
     615           0 :         struct uio uio;
     616           0 :         struct iovec iov;
     617             :         int error, write;
     618           0 :         int temp = 0;
     619             : 
     620           0 :         KASSERT((p->p_flag & P_SYSTEM) == 0);
     621             : 
     622             :         /* Accept either PID or TID */
     623           0 :         if ((tr = process_tprfind(pid, &t)) == NULL)
     624           0 :                 return ESRCH;
     625             : 
     626           0 :         if ((error = process_checktracestate(p->p_p, tr, t)))
     627           0 :                 return error;
     628             : 
     629             :         FIX_SSTEP(t);
     630             : 
     631             :         /* Now do the operation. */
     632             :         write = 0;
     633             : 
     634           0 :         if ((error = process_checkioperm(p, tr)) != 0)
     635           0 :                 return error;
     636             : 
     637           0 :         switch (req) {
     638             :         case PT_WRITE_I:                /* XXX no separate I and D spaces */
     639             :         case PT_WRITE_D:
     640             :                 write = 1;
     641           0 :                 temp = data;
     642             :         case PT_READ_I:         /* XXX no separate I and D spaces */
     643             :         case PT_READ_D:
     644             :                 /* write = 0 done above. */
     645           0 :                 iov.iov_base = (caddr_t)&temp;
     646           0 :                 iov.iov_len = sizeof(int);
     647           0 :                 uio.uio_iov = &iov;
     648           0 :                 uio.uio_iovcnt = 1;
     649           0 :                 uio.uio_offset = (off_t)(vaddr_t)addr;
     650           0 :                 uio.uio_resid = sizeof(int);
     651           0 :                 uio.uio_segflg = UIO_SYSSPACE;
     652           0 :                 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
     653           0 :                 uio.uio_procp = p;
     654           0 :                 error = process_domem(p, tr, &uio, write ? PT_WRITE_I :
     655             :                                 PT_READ_I);
     656           0 :                 if (write == 0)
     657           0 :                         *retval = temp;
     658           0 :                 return error;
     659             : 
     660             :         case PT_IO:
     661             :               {
     662           0 :                 struct ptrace_io_desc *piod = addr;
     663             : 
     664           0 :                 iov.iov_base = piod->piod_addr;
     665           0 :                 iov.iov_len = piod->piod_len;
     666           0 :                 uio.uio_iov = &iov;
     667           0 :                 uio.uio_iovcnt = 1;
     668           0 :                 uio.uio_offset = (off_t)(vaddr_t)piod->piod_offs;
     669           0 :                 uio.uio_resid = piod->piod_len;
     670           0 :                 uio.uio_segflg = UIO_USERSPACE;
     671           0 :                 uio.uio_procp = p;
     672           0 :                 switch (piod->piod_op) {
     673             :                 case PIOD_READ_I:
     674             :                         req = PT_READ_I;
     675           0 :                         uio.uio_rw = UIO_READ;
     676           0 :                         break;
     677             :                 case PIOD_READ_D:
     678             :                         req = PT_READ_D;
     679           0 :                         uio.uio_rw = UIO_READ;
     680           0 :                         break;
     681             :                 case PIOD_WRITE_I:
     682             :                         req = PT_WRITE_I;
     683           0 :                         uio.uio_rw = UIO_WRITE;
     684           0 :                         break;
     685             :                 case PIOD_WRITE_D:
     686             :                         req = PT_WRITE_D;
     687           0 :                         uio.uio_rw = UIO_WRITE;
     688           0 :                         break;
     689             :                 case PIOD_READ_AUXV:
     690             :                         req = PT_READ_D;
     691           0 :                         uio.uio_rw = UIO_READ;
     692           0 :                         temp = tr->ps_emul->e_arglen * sizeof(char *);
     693           0 :                         if (uio.uio_offset > temp)
     694           0 :                                 return EIO;
     695           0 :                         if (uio.uio_resid > temp - uio.uio_offset)
     696           0 :                                 uio.uio_resid = temp - uio.uio_offset;
     697           0 :                         piod->piod_len = iov.iov_len = uio.uio_resid;
     698           0 :                         error = process_auxv_offset(p, tr, &uio);
     699           0 :                         if (error)
     700           0 :                                 return error;
     701             :                         break;
     702             :                 default:
     703           0 :                         return EINVAL;
     704             :                 }
     705           0 :                 error = process_domem(p, tr, &uio, req);
     706           0 :                 piod->piod_len -= uio.uio_resid;
     707           0 :                 return error;
     708             :               }
     709             : 
     710             :         case PT_SETREGS:
     711           0 :                 return process_write_regs(t, addr);
     712             :         case PT_GETREGS:
     713           0 :                 return process_read_regs(t, addr);
     714             : 
     715             : #ifdef PT_SETFPREGS
     716             :         case PT_SETFPREGS:
     717           0 :                 return process_write_fpregs(t, addr);
     718             : #endif
     719             : #ifdef PT_SETFPREGS
     720             :         case PT_GETFPREGS:
     721           0 :                 return process_read_fpregs(t, addr);
     722             : #endif
     723             : #ifdef PT_SETXMMREGS
     724             :         case PT_SETXMMREGS:
     725             :                 return process_write_xmmregs(t, addr);
     726             : #endif
     727             : #ifdef PT_SETXMMREGS
     728             :         case PT_GETXMMREGS:
     729             :                 return process_read_xmmregs(t, addr);
     730             : #endif
     731             : #ifdef PT_WCOOKIE
     732             :         case PT_WCOOKIE:
     733             :                 *(register_t *)addr = process_get_wcookie(t);
     734             :                 return 0;
     735             : #endif
     736             :         default:
     737           0 :                 KASSERTMSG(0, "%s: unhandled request %d", __func__, req);
     738             :                 break;
     739             :         }
     740             : 
     741             :         return 0;
     742           0 : }
     743             : 
     744             : 
     745             : /*
     746             :  * Helper for doing "it could be a PID or TID" lookup.  On failure
     747             :  * returns NULL; on success returns the selected process and sets *tp
     748             :  * to an appropriate thread in that process.
     749             :  */
     750             : static inline struct process *
     751           0 : process_tprfind(pid_t tpid, struct proc **tp)
     752             : {
     753           0 :         if (tpid > THREAD_PID_OFFSET) {
     754           0 :                 struct proc *t = tfind(tpid - THREAD_PID_OFFSET);
     755             : 
     756           0 :                 if (t == NULL)
     757           0 :                         return NULL;
     758           0 :                 *tp = t;
     759           0 :                 return t->p_p;
     760             :         } else {
     761           0 :                 struct process *tr = prfind(tpid);
     762             : 
     763           0 :                 if (tr == NULL)
     764           0 :                         return NULL;
     765           0 :                 *tp = TAILQ_FIRST(&tr->ps_threads);
     766           0 :                 return tr;
     767             :         }
     768           0 : }
     769             : 
     770             : 
     771             : /*
     772             :  * Check whether 'tr' is currently traced by 'curpr' and in a state
     773             :  * to be manipulated.  If 't' is supplied then it must be stopped and
     774             :  * waited for.
     775             :  */
     776             : static inline int
     777           0 : process_checktracestate(struct process *curpr, struct process *tr,
     778             :     struct proc *t)
     779             : {
     780             :         /*
     781             :          * You can't do what you want to the process if:
     782             :          *      (1) It's not being traced at all,
     783             :          */
     784           0 :         if (!ISSET(tr->ps_flags, PS_TRACED))
     785           0 :                 return EPERM;
     786             : 
     787             :         /*
     788             :          *      (2) it's not being traced by _you_, or
     789             :          */
     790           0 :         if (tr->ps_pptr != curpr)
     791           0 :                 return EBUSY;
     792             : 
     793             :         /*
     794             :          *      (3) it's in the middle of execve(2)
     795             :          */
     796           0 :         if (ISSET(tr->ps_flags, PS_INEXEC))
     797           0 :                 return EAGAIN;
     798             : 
     799             :         /*
     800             :          *      (4) if a thread was specified and it's not currently stopped.
     801             :          */
     802           0 :         if (t != NULL &&
     803           0 :             (t->p_stat != SSTOP || !ISSET(tr->ps_flags, PS_WAITED)))
     804           0 :                 return EBUSY;
     805             : 
     806           0 :         return 0;
     807           0 : }
     808             : 
     809             : 
     810             : /*
     811             :  * Check if a process is allowed to fiddle with the memory of another.
     812             :  *
     813             :  * p = tracer
     814             :  * tr = tracee
     815             :  *
     816             :  * 1.  You can't attach to a process not owned by you or one that has raised
     817             :  *     its privileges.
     818             :  * 1a. ...unless you are root.
     819             :  *
     820             :  * 2.  init is always off-limits because it can control the securelevel.
     821             :  * 2a. ...unless securelevel is permanently set to insecure.
     822             :  *
     823             :  * 3.  Processes that are in the process of doing an exec() are always
     824             :  *     off-limits because of the can of worms they are. Just wait a
     825             :  *     second.
     826             :  */
     827             : int
     828           0 : process_checkioperm(struct proc *p, struct process *tr)
     829             : {
     830             :         int error;
     831             : 
     832           0 :         if ((tr->ps_ucred->cr_ruid != p->p_ucred->cr_ruid ||
     833           0 :             ISSET(tr->ps_flags, PS_SUGIDEXEC | PS_SUGID)) &&
     834           0 :             (error = suser(p)) != 0)
     835           0 :                 return (error);
     836             : 
     837           0 :         if ((tr->ps_pid == 1) && (securelevel > -1))
     838           0 :                 return (EPERM);
     839             : 
     840           0 :         if (ISSET(tr->ps_flags, PS_INEXEC))
     841           0 :                 return (EAGAIN);
     842             : 
     843           0 :         return (0);
     844           0 : }
     845             : 
     846             : int
     847           0 : process_domem(struct proc *curp, struct process *tr, struct uio *uio, int req)
     848             : {
     849             :         struct vmspace *vm;
     850             :         int error;
     851             :         vaddr_t addr;
     852             :         vsize_t len;
     853             : 
     854           0 :         len = uio->uio_resid;
     855           0 :         if (len == 0)
     856           0 :                 return 0;
     857             : 
     858           0 :         if ((error = process_checkioperm(curp, tr)) != 0)
     859           0 :                 return error;
     860             : 
     861             :         /* XXXCDC: how should locking work here? */
     862           0 :         vm = tr->ps_vmspace;
     863           0 :         if ((tr->ps_flags & PS_EXITING) || (vm->vm_refcnt < 1))
     864           0 :                 return EFAULT;
     865           0 :         addr = uio->uio_offset;
     866             : 
     867           0 :         vm->vm_refcnt++;
     868             : 
     869           0 :         error = uvm_io(&vm->vm_map, uio,
     870           0 :             (uio->uio_rw == UIO_WRITE) ? UVM_IO_FIXPROT : 0);
     871             : 
     872           0 :         uvmspace_free(vm);
     873             : 
     874           0 :         if (error == 0 && req == PT_WRITE_I)
     875             :                 pmap_proc_iflush(tr, addr, len);
     876             : 
     877           0 :         return error;
     878           0 : }
     879             : 
     880             : int
     881           0 : process_auxv_offset(struct proc *curp, struct process *tr, struct uio *uiop)
     882             : {
     883             :         struct vmspace *vm;
     884           0 :         struct ps_strings pss;
     885           0 :         struct iovec iov;
     886           0 :         struct uio uio;
     887             :         int error;
     888             : 
     889           0 :         iov.iov_base = &pss;
     890           0 :         iov.iov_len = sizeof(pss);
     891           0 :         uio.uio_iov = &iov;
     892           0 :         uio.uio_iovcnt = 1;     
     893           0 :         uio.uio_offset = (off_t)tr->ps_strings;
     894           0 :         uio.uio_resid = sizeof(pss);
     895           0 :         uio.uio_segflg = UIO_SYSSPACE;
     896           0 :         uio.uio_rw = UIO_READ;
     897           0 :         uio.uio_procp = curp;
     898             : 
     899           0 :         vm = tr->ps_vmspace;
     900           0 :         if ((tr->ps_flags & PS_EXITING) || (vm->vm_refcnt < 1))
     901           0 :                 return EFAULT;
     902             : 
     903           0 :         vm->vm_refcnt++;
     904           0 :         error = uvm_io(&vm->vm_map, &uio, 0);
     905           0 :         uvmspace_free(vm);
     906             : 
     907           0 :         if (error != 0)
     908           0 :                 return error;
     909             : 
     910           0 :         if (pss.ps_envstr == NULL)
     911           0 :                 return EIO;
     912             : 
     913           0 :         uiop->uio_offset += (off_t)(vaddr_t)(pss.ps_envstr + pss.ps_nenvstr + 1);
     914             : #ifdef MACHINE_STACK_GROWS_UP
     915             :         if (uiop->uio_offset < (off_t)tr->ps_strings)
     916             :                 return EIO;
     917             : #else
     918           0 :         if (uiop->uio_offset > (off_t)tr->ps_strings)
     919           0 :                 return EIO;
     920           0 :         if ((uiop->uio_offset + uiop->uio_resid) > (off_t)tr->ps_strings)
     921           0 :                 uiop->uio_resid = (off_t)tr->ps_strings - uiop->uio_offset;
     922             : #endif
     923             : 
     924           0 :         return 0;
     925           0 : }
     926             : #endif

Generated by: LCOV version 1.13