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 /*-
    2  * Copyright (c) 1994, Sean Eric Fagan
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  * 1. Redistributions of source code must retain the above copyright
    9  *    notice, this list of conditions and the following disclaimer.
   10  * 2. Redistributions in binary form must reproduce the above copyright
   11  *    notice, this list of conditions and the following disclaimer in the
   12  *    documentation and/or other materials provided with the distribution.
   13  * 3. All advertising materials mentioning features or use of this software
   14  *    must display the following acknowledgement:
   15  *      This product includes software developed by Sean Eric Fagan.
   16  * 4. The name of the author may not be used to endorse or promote products
   17  *    derived from this software without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  */
   31 
   32 #include <sys/cdefs.h>
   33 __FBSDID("$FreeBSD: releng/8.1/sys/kern/sys_process.c 208718 2010-06-01 19:38:46Z jhb $");
   34 
   35 #include "opt_compat.h"
   36 
   37 #include <sys/param.h>
   38 #include <sys/systm.h>
   39 #include <sys/lock.h>
   40 #include <sys/mutex.h>
   41 #include <sys/syscallsubr.h>
   42 #include <sys/sysent.h>
   43 #include <sys/sysproto.h>
   44 #include <sys/proc.h>
   45 #include <sys/vnode.h>
   46 #include <sys/ptrace.h>
   47 #include <sys/sx.h>
   48 #include <sys/malloc.h>
   49 #include <sys/signalvar.h>
   50 
   51 #include <machine/reg.h>
   52 
   53 #include <security/audit/audit.h>
   54 
   55 #include <vm/vm.h>
   56 #include <vm/pmap.h>
   57 #include <vm/vm_extern.h>
   58 #include <vm/vm_map.h>
   59 #include <vm/vm_kern.h>
   60 #include <vm/vm_object.h>
   61 #include <vm/vm_page.h>
   62 #include <vm/vm_param.h>
   63 
   64 #ifdef COMPAT_FREEBSD32
   65 #include <sys/procfs.h>
   66 
   67 struct ptrace_io_desc32 {
   68         int             piod_op;
   69         u_int32_t       piod_offs;
   70         u_int32_t       piod_addr;
   71         u_int32_t       piod_len;
   72 };
   73 
   74 struct ptrace_vm_entry32 {
   75         int             pve_entry;
   76         int             pve_timestamp;
   77         uint32_t        pve_start;
   78         uint32_t        pve_end;
   79         uint32_t        pve_offset;
   80         u_int           pve_prot;
   81         u_int           pve_pathlen;
   82         int32_t         pve_fileid;
   83         u_int           pve_fsid;
   84         uint32_t        pve_path;
   85 };
   86 
   87 #endif
   88 
   89 /*
   90  * Functions implemented using PROC_ACTION():
   91  *
   92  * proc_read_regs(proc, regs)
   93  *      Get the current user-visible register set from the process
   94  *      and copy it into the regs structure (<machine/reg.h>).
   95  *      The process is stopped at the time read_regs is called.
   96  *
   97  * proc_write_regs(proc, regs)
   98  *      Update the current register set from the passed in regs
   99  *      structure.  Take care to avoid clobbering special CPU
  100  *      registers or privileged bits in the PSL.
  101  *      Depending on the architecture this may have fix-up work to do,
  102  *      especially if the IAR or PCW are modified.
  103  *      The process is stopped at the time write_regs is called.
  104  *
  105  * proc_read_fpregs, proc_write_fpregs
  106  *      deal with the floating point register set, otherwise as above.
  107  *
  108  * proc_read_dbregs, proc_write_dbregs
  109  *      deal with the processor debug register set, otherwise as above.
  110  *
  111  * proc_sstep(proc)
  112  *      Arrange for the process to trap after executing a single instruction.
  113  */
  114 
  115 #define PROC_ACTION(action) do {                                        \
  116         int error;                                                      \
  117                                                                         \
  118         PROC_LOCK_ASSERT(td->td_proc, MA_OWNED);                        \
  119         if ((td->td_proc->p_flag & P_INMEM) == 0)                       \
  120                 error = EIO;                                            \
  121         else                                                            \
  122                 error = (action);                                       \
  123         return (error);                                                 \
  124 } while(0)
  125 
  126 int
  127 proc_read_regs(struct thread *td, struct reg *regs)
  128 {
  129 
  130         PROC_ACTION(fill_regs(td, regs));
  131 }
  132 
  133 int
  134 proc_write_regs(struct thread *td, struct reg *regs)
  135 {
  136 
  137         PROC_ACTION(set_regs(td, regs));
  138 }
  139 
  140 int
  141 proc_read_dbregs(struct thread *td, struct dbreg *dbregs)
  142 {
  143 
  144         PROC_ACTION(fill_dbregs(td, dbregs));
  145 }
  146 
  147 int
  148 proc_write_dbregs(struct thread *td, struct dbreg *dbregs)
  149 {
  150 
  151         PROC_ACTION(set_dbregs(td, dbregs));
  152 }
  153 
  154 /*
  155  * Ptrace doesn't support fpregs at all, and there are no security holes
  156  * or translations for fpregs, so we can just copy them.
  157  */
  158 int
  159 proc_read_fpregs(struct thread *td, struct fpreg *fpregs)
  160 {
  161 
  162         PROC_ACTION(fill_fpregs(td, fpregs));
  163 }
  164 
  165 int
  166 proc_write_fpregs(struct thread *td, struct fpreg *fpregs)
  167 {
  168 
  169         PROC_ACTION(set_fpregs(td, fpregs));
  170 }
  171 
  172 #ifdef COMPAT_FREEBSD32
  173 /* For 32 bit binaries, we need to expose the 32 bit regs layouts. */
  174 int
  175 proc_read_regs32(struct thread *td, struct reg32 *regs32)
  176 {
  177 
  178         PROC_ACTION(fill_regs32(td, regs32));
  179 }
  180 
  181 int
  182 proc_write_regs32(struct thread *td, struct reg32 *regs32)
  183 {
  184 
  185         PROC_ACTION(set_regs32(td, regs32));
  186 }
  187 
  188 int
  189 proc_read_dbregs32(struct thread *td, struct dbreg32 *dbregs32)
  190 {
  191 
  192         PROC_ACTION(fill_dbregs32(td, dbregs32));
  193 }
  194 
  195 int
  196 proc_write_dbregs32(struct thread *td, struct dbreg32 *dbregs32)
  197 {
  198 
  199         PROC_ACTION(set_dbregs32(td, dbregs32));
  200 }
  201 
  202 int
  203 proc_read_fpregs32(struct thread *td, struct fpreg32 *fpregs32)
  204 {
  205 
  206         PROC_ACTION(fill_fpregs32(td, fpregs32));
  207 }
  208 
  209 int
  210 proc_write_fpregs32(struct thread *td, struct fpreg32 *fpregs32)
  211 {
  212 
  213         PROC_ACTION(set_fpregs32(td, fpregs32));
  214 }
  215 #endif
  216 
  217 int
  218 proc_sstep(struct thread *td)
  219 {
  220 
  221         PROC_ACTION(ptrace_single_step(td));
  222 }
  223 
  224 int
  225 proc_rwmem(struct proc *p, struct uio *uio)
  226 {
  227         vm_map_t map;
  228         vm_object_t backing_object, object = NULL;
  229         vm_offset_t pageno = 0;         /* page number */
  230         vm_prot_t reqprot;
  231         int error, fault_flags, writing;
  232 
  233         /*
  234          * Assert that someone has locked this vmspace.  (Should be
  235          * curthread but we can't assert that.)  This keeps the process
  236          * from exiting out from under us until this operation completes.
  237          */
  238         KASSERT(p->p_lock >= 1, ("%s: process %p (pid %d) not held", __func__,
  239             p, p->p_pid));
  240 
  241         /*
  242          * The map we want...
  243          */
  244         map = &p->p_vmspace->vm_map;
  245 
  246         writing = uio->uio_rw == UIO_WRITE;
  247         reqprot = writing ? (VM_PROT_WRITE | VM_PROT_OVERRIDE_WRITE) :
  248             VM_PROT_READ;
  249         fault_flags = writing ? VM_FAULT_DIRTY : VM_FAULT_NORMAL; 
  250 
  251         /*
  252          * Only map in one page at a time.  We don't have to, but it
  253          * makes things easier.  This way is trivial - right?
  254          */
  255         do {
  256                 vm_map_t tmap;
  257                 vm_offset_t uva;
  258                 int page_offset;                /* offset into page */
  259                 vm_map_entry_t out_entry;
  260                 vm_prot_t out_prot;
  261                 boolean_t wired;
  262                 vm_pindex_t pindex;
  263                 u_int len;
  264                 vm_page_t m;
  265 
  266                 object = NULL;
  267 
  268                 uva = (vm_offset_t)uio->uio_offset;
  269 
  270                 /*
  271                  * Get the page number of this segment.
  272                  */
  273                 pageno = trunc_page(uva);
  274                 page_offset = uva - pageno;
  275 
  276                 /*
  277                  * How many bytes to copy
  278                  */
  279                 len = min(PAGE_SIZE - page_offset, uio->uio_resid);
  280 
  281                 /*
  282                  * Fault the page on behalf of the process
  283                  */
  284                 error = vm_fault(map, pageno, reqprot, fault_flags);
  285                 if (error) {
  286                         if (error == KERN_RESOURCE_SHORTAGE)
  287                                 error = ENOMEM;
  288                         else
  289                                 error = EFAULT;
  290                         break;
  291                 }
  292 
  293                 /*
  294                  * Now we need to get the page.  out_entry, out_prot, wired,
  295                  * and single_use aren't used.  One would think the vm code
  296                  * would be a *bit* nicer...  We use tmap because
  297                  * vm_map_lookup() can change the map argument.
  298                  */
  299                 tmap = map;
  300                 error = vm_map_lookup(&tmap, pageno, reqprot, &out_entry,
  301                     &object, &pindex, &out_prot, &wired);
  302                 if (error) {
  303                         error = EFAULT;
  304                         break;
  305                 }
  306                 VM_OBJECT_LOCK(object);
  307                 while ((m = vm_page_lookup(object, pindex)) == NULL &&
  308                     !writing &&
  309                     (backing_object = object->backing_object) != NULL) {
  310                         /*
  311                          * Allow fallback to backing objects if we are reading.
  312                          */
  313                         VM_OBJECT_LOCK(backing_object);
  314                         pindex += OFF_TO_IDX(object->backing_object_offset);
  315                         VM_OBJECT_UNLOCK(object);
  316                         object = backing_object;
  317                 }
  318                 VM_OBJECT_UNLOCK(object);
  319                 if (m == NULL) {
  320                         vm_map_lookup_done(tmap, out_entry);
  321                         error = EFAULT;
  322                         break;
  323                 }
  324 
  325                 /*
  326                  * Hold the page in memory.
  327                  */
  328                 vm_page_lock_queues();
  329                 vm_page_hold(m);
  330                 vm_page_unlock_queues();
  331 
  332                 /*
  333                  * We're done with tmap now.
  334                  */
  335                 vm_map_lookup_done(tmap, out_entry);
  336 
  337                 /*
  338                  * Now do the i/o move.
  339                  */
  340                 error = uiomove_fromphys(&m, page_offset, len, uio);
  341 
  342                 /* Make the I-cache coherent for breakpoints. */
  343                 if (!error && writing && (out_prot & VM_PROT_EXECUTE))
  344                         vm_sync_icache(map, uva, len);
  345 
  346                 /*
  347                  * Release the page.
  348                  */
  349                 vm_page_lock_queues();
  350                 vm_page_unhold(m);
  351                 vm_page_unlock_queues();
  352 
  353         } while (error == 0 && uio->uio_resid > 0);
  354 
  355         return (error);
  356 }
  357 
  358 static int
  359 ptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve)
  360 {
  361         struct vattr vattr;
  362         vm_map_t map;
  363         vm_map_entry_t entry;
  364         vm_object_t obj, tobj, lobj;
  365         struct vmspace *vm;
  366         struct vnode *vp;
  367         char *freepath, *fullpath;
  368         u_int pathlen;
  369         int error, index, vfslocked;
  370 
  371         error = 0;
  372         obj = NULL;
  373 
  374         vm = vmspace_acquire_ref(p);
  375         map = &vm->vm_map;
  376         vm_map_lock_read(map);
  377 
  378         do {
  379                 entry = map->header.next;
  380                 index = 0;
  381                 while (index < pve->pve_entry && entry != &map->header) {
  382                         entry = entry->next;
  383                         index++;
  384                 }
  385                 if (index != pve->pve_entry) {
  386                         error = EINVAL;
  387                         break;
  388                 }
  389                 while (entry != &map->header &&
  390                     (entry->eflags & MAP_ENTRY_IS_SUB_MAP) != 0) {
  391                         entry = entry->next;
  392                         index++;
  393                 }
  394                 if (entry == &map->header) {
  395                         error = ENOENT;
  396                         break;
  397                 }
  398 
  399                 /* We got an entry. */
  400                 pve->pve_entry = index + 1;
  401                 pve->pve_timestamp = map->timestamp;
  402                 pve->pve_start = entry->start;
  403                 pve->pve_end = entry->end - 1;
  404                 pve->pve_offset = entry->offset;
  405                 pve->pve_prot = entry->protection;
  406 
  407                 /* Backing object's path needed? */
  408                 if (pve->pve_pathlen == 0)
  409                         break;
  410 
  411                 pathlen = pve->pve_pathlen;
  412                 pve->pve_pathlen = 0;
  413 
  414                 obj = entry->object.vm_object;
  415                 if (obj != NULL)
  416                         VM_OBJECT_LOCK(obj);
  417         } while (0);
  418 
  419         vm_map_unlock_read(map);
  420         vmspace_free(vm);
  421 
  422         pve->pve_fsid = VNOVAL;
  423         pve->pve_fileid = VNOVAL;
  424 
  425         if (error == 0 && obj != NULL) {
  426                 lobj = obj;
  427                 for (tobj = obj; tobj != NULL; tobj = tobj->backing_object) {
  428                         if (tobj != obj)
  429                                 VM_OBJECT_LOCK(tobj);
  430                         if (lobj != obj)
  431                                 VM_OBJECT_UNLOCK(lobj);
  432                         lobj = tobj;
  433                         pve->pve_offset += tobj->backing_object_offset;
  434                 }
  435                 vp = (lobj->type == OBJT_VNODE) ? lobj->handle : NULL;
  436                 if (vp != NULL)
  437                         vref(vp);
  438                 if (lobj != obj)
  439                         VM_OBJECT_UNLOCK(lobj);
  440                 VM_OBJECT_UNLOCK(obj);
  441 
  442                 if (vp != NULL) {
  443                         freepath = NULL;
  444                         fullpath = NULL;
  445                         vn_fullpath(td, vp, &fullpath, &freepath);
  446                         vfslocked = VFS_LOCK_GIANT(vp->v_mount);
  447                         vn_lock(vp, LK_SHARED | LK_RETRY);
  448                         if (VOP_GETATTR(vp, &vattr, td->td_ucred) == 0) {
  449                                 pve->pve_fileid = vattr.va_fileid;
  450                                 pve->pve_fsid = vattr.va_fsid;
  451                         }
  452                         vput(vp);
  453                         VFS_UNLOCK_GIANT(vfslocked);
  454 
  455                         if (fullpath != NULL) {
  456                                 pve->pve_pathlen = strlen(fullpath) + 1;
  457                                 if (pve->pve_pathlen <= pathlen) {
  458                                         error = copyout(fullpath, pve->pve_path,
  459                                             pve->pve_pathlen);
  460                                 } else
  461                                         error = ENAMETOOLONG;
  462                         }
  463                         if (freepath != NULL)
  464                                 free(freepath, M_TEMP);
  465                 }
  466         }
  467 
  468         return (error);
  469 }
  470 
  471 #ifdef COMPAT_FREEBSD32
  472 static int      
  473 ptrace_vm_entry32(struct thread *td, struct proc *p,
  474     struct ptrace_vm_entry32 *pve32)
  475 {
  476         struct ptrace_vm_entry pve;
  477         int error;
  478 
  479         pve.pve_entry = pve32->pve_entry;
  480         pve.pve_pathlen = pve32->pve_pathlen;
  481         pve.pve_path = (void *)(uintptr_t)pve32->pve_path;
  482 
  483         error = ptrace_vm_entry(td, p, &pve);
  484         if (error == 0) {
  485                 pve32->pve_entry = pve.pve_entry;
  486                 pve32->pve_timestamp = pve.pve_timestamp;
  487                 pve32->pve_start = pve.pve_start;
  488                 pve32->pve_end = pve.pve_end;
  489                 pve32->pve_offset = pve.pve_offset;
  490                 pve32->pve_prot = pve.pve_prot;
  491                 pve32->pve_fileid = pve.pve_fileid;
  492                 pve32->pve_fsid = pve.pve_fsid;
  493         }
  494 
  495         pve32->pve_pathlen = pve.pve_pathlen;
  496         return (error);
  497 }
  498 #endif /* COMPAT_FREEBSD32 */
  499 
  500 /*
  501  * Process debugging system call.
  502  */
  503 #ifndef _SYS_SYSPROTO_H_
  504 struct ptrace_args {
  505         int     req;
  506         pid_t   pid;
  507         caddr_t addr;
  508         int     data;
  509 };
  510 #endif
  511 
  512 #ifdef COMPAT_FREEBSD32
  513 /*
  514  * This CPP subterfuge is to try and reduce the number of ifdefs in
  515  * the body of the code.
  516  *   COPYIN(uap->addr, &r.reg, sizeof r.reg);
  517  * becomes either:
  518  *   copyin(uap->addr, &r.reg, sizeof r.reg);
  519  * or
  520  *   copyin(uap->addr, &r.reg32, sizeof r.reg32);
  521  * .. except this is done at runtime.
  522  */
  523 #define COPYIN(u, k, s)         wrap32 ? \
  524         copyin(u, k ## 32, s ## 32) : \
  525         copyin(u, k, s)
  526 #define COPYOUT(k, u, s)        wrap32 ? \
  527         copyout(k ## 32, u, s ## 32) : \
  528         copyout(k, u, s)
  529 #else
  530 #define COPYIN(u, k, s)         copyin(u, k, s)
  531 #define COPYOUT(k, u, s)        copyout(k, u, s)
  532 #endif
  533 int
  534 ptrace(struct thread *td, struct ptrace_args *uap)
  535 {
  536         /*
  537          * XXX this obfuscation is to reduce stack usage, but the register
  538          * structs may be too large to put on the stack anyway.
  539          */
  540         union {
  541                 struct ptrace_io_desc piod;
  542                 struct ptrace_lwpinfo pl;
  543                 struct ptrace_vm_entry pve;
  544                 struct dbreg dbreg;
  545                 struct fpreg fpreg;
  546                 struct reg reg;
  547 #ifdef COMPAT_FREEBSD32
  548                 struct dbreg32 dbreg32;
  549                 struct fpreg32 fpreg32;
  550                 struct reg32 reg32;
  551                 struct ptrace_io_desc32 piod32;
  552                 struct ptrace_vm_entry32 pve32;
  553 #endif
  554         } r;
  555         void *addr;
  556         int error = 0;
  557 #ifdef COMPAT_FREEBSD32
  558         int wrap32 = 0;
  559 
  560         if (SV_CURPROC_FLAG(SV_ILP32))
  561                 wrap32 = 1;
  562 #endif
  563         AUDIT_ARG_PID(uap->pid);
  564         AUDIT_ARG_CMD(uap->req);
  565         AUDIT_ARG_VALUE(uap->data);
  566         addr = &r;
  567         switch (uap->req) {
  568         case PT_GETREGS:
  569         case PT_GETFPREGS:
  570         case PT_GETDBREGS:
  571         case PT_LWPINFO:
  572                 break;
  573         case PT_SETREGS:
  574                 error = COPYIN(uap->addr, &r.reg, sizeof r.reg);
  575                 break;
  576         case PT_SETFPREGS:
  577                 error = COPYIN(uap->addr, &r.fpreg, sizeof r.fpreg);
  578                 break;
  579         case PT_SETDBREGS:
  580                 error = COPYIN(uap->addr, &r.dbreg, sizeof r.dbreg);
  581                 break;
  582         case PT_IO:
  583                 error = COPYIN(uap->addr, &r.piod, sizeof r.piod);
  584                 break;
  585         case PT_VM_ENTRY:
  586                 error = COPYIN(uap->addr, &r.pve, sizeof r.pve);
  587                 break;
  588         default:
  589                 addr = uap->addr;
  590                 break;
  591         }
  592         if (error)
  593                 return (error);
  594 
  595         error = kern_ptrace(td, uap->req, uap->pid, addr, uap->data);
  596         if (error)
  597                 return (error);
  598 
  599         switch (uap->req) {
  600         case PT_VM_ENTRY:
  601                 error = COPYOUT(&r.pve, uap->addr, sizeof r.pve);
  602                 break;
  603         case PT_IO:
  604                 error = COPYOUT(&r.piod, uap->addr, sizeof r.piod);
  605                 break;
  606         case PT_GETREGS:
  607                 error = COPYOUT(&r.reg, uap->addr, sizeof r.reg);
  608                 break;
  609         case PT_GETFPREGS:
  610                 error = COPYOUT(&r.fpreg, uap->addr, sizeof r.fpreg);
  611                 break;
  612         case PT_GETDBREGS:
  613                 error = COPYOUT(&r.dbreg, uap->addr, sizeof r.dbreg);
  614                 break;
  615         case PT_LWPINFO:
  616                 error = copyout(&r.pl, uap->addr, uap->data);
  617                 break;
  618         }
  619 
  620         return (error);
  621 }
  622 #undef COPYIN
  623 #undef COPYOUT
  624 
  625 #ifdef COMPAT_FREEBSD32
  626 /*
  627  *   PROC_READ(regs, td2, addr);
  628  * becomes either:
  629  *   proc_read_regs(td2, addr);
  630  * or
  631  *   proc_read_regs32(td2, addr);
  632  * .. except this is done at runtime.  There is an additional
  633  * complication in that PROC_WRITE disallows 32 bit consumers
  634  * from writing to 64 bit address space targets.
  635  */
  636 #define PROC_READ(w, t, a)      wrap32 ? \
  637         proc_read_ ## w ## 32(t, a) : \
  638         proc_read_ ## w (t, a)
  639 #define PROC_WRITE(w, t, a)     wrap32 ? \
  640         (safe ? proc_write_ ## w ## 32(t, a) : EINVAL ) : \
  641         proc_write_ ## w (t, a)
  642 #else
  643 #define PROC_READ(w, t, a)      proc_read_ ## w (t, a)
  644 #define PROC_WRITE(w, t, a)     proc_write_ ## w (t, a)
  645 #endif
  646 
  647 int
  648 kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data)
  649 {
  650         struct iovec iov;
  651         struct uio uio;
  652         struct proc *curp, *p, *pp;
  653         struct thread *td2 = NULL;
  654         struct ptrace_io_desc *piod = NULL;
  655         struct ptrace_lwpinfo *pl;
  656         int error, write, tmp, num;
  657         int proctree_locked = 0;
  658         lwpid_t tid = 0, *buf;
  659 #ifdef COMPAT_FREEBSD32
  660         int wrap32 = 0, safe = 0;
  661         struct ptrace_io_desc32 *piod32 = NULL;
  662 #endif
  663 
  664         curp = td->td_proc;
  665 
  666         /* Lock proctree before locking the process. */
  667         switch (req) {
  668         case PT_TRACE_ME:
  669         case PT_ATTACH:
  670         case PT_STEP:
  671         case PT_CONTINUE:
  672         case PT_TO_SCE:
  673         case PT_TO_SCX:
  674         case PT_SYSCALL:
  675         case PT_DETACH:
  676                 sx_xlock(&proctree_lock);
  677                 proctree_locked = 1;
  678                 break;
  679         default:
  680                 break;
  681         }
  682 
  683         write = 0;
  684         if (req == PT_TRACE_ME) {
  685                 p = td->td_proc;
  686                 PROC_LOCK(p);
  687         } else {
  688                 if (pid <= PID_MAX) {
  689                         if ((p = pfind(pid)) == NULL) {
  690                                 if (proctree_locked)
  691                                         sx_xunlock(&proctree_lock);
  692                                 return (ESRCH);
  693                         }
  694                 } else {
  695                         /* this is slow, should be optimized */
  696                         sx_slock(&allproc_lock);
  697                         FOREACH_PROC_IN_SYSTEM(p) {
  698                                 PROC_LOCK(p);
  699                                 FOREACH_THREAD_IN_PROC(p, td2) {
  700                                         if (td2->td_tid == pid)
  701                                                 break;
  702                                 }
  703                                 if (td2 != NULL)
  704                                         break; /* proc lock held */
  705                                 PROC_UNLOCK(p);
  706                         }
  707                         sx_sunlock(&allproc_lock);
  708                         if (p == NULL) {
  709                                 if (proctree_locked)
  710                                         sx_xunlock(&proctree_lock);
  711                                 return (ESRCH);
  712                         }
  713                         tid = pid;
  714                         pid = p->p_pid;
  715                 }
  716         }
  717         AUDIT_ARG_PROCESS(p);
  718 
  719         if ((p->p_flag & P_WEXIT) != 0) {
  720                 error = ESRCH;
  721                 goto fail;
  722         }
  723         if ((error = p_cansee(td, p)) != 0)
  724                 goto fail;
  725 
  726         if ((error = p_candebug(td, p)) != 0)
  727                 goto fail;
  728 
  729         /*
  730          * System processes can't be debugged.
  731          */
  732         if ((p->p_flag & P_SYSTEM) != 0) {
  733                 error = EINVAL;
  734                 goto fail;
  735         }
  736 
  737         if (tid == 0) {
  738                 if ((p->p_flag & P_STOPPED_TRACE) != 0) {
  739                         KASSERT(p->p_xthread != NULL, ("NULL p_xthread"));
  740                         td2 = p->p_xthread;
  741                 } else {
  742                         td2 = FIRST_THREAD_IN_PROC(p);
  743                 }
  744                 tid = td2->td_tid;
  745         }
  746 
  747 #ifdef COMPAT_FREEBSD32
  748         /*
  749          * Test if we're a 32 bit client and what the target is.
  750          * Set the wrap controls accordingly.
  751          */
  752         if (SV_CURPROC_FLAG(SV_ILP32)) {
  753                 if (td2->td_proc->p_sysent->sv_flags & SV_ILP32)
  754                         safe = 1;
  755                 wrap32 = 1;
  756         }
  757 #endif
  758         /*
  759          * Permissions check
  760          */
  761         switch (req) {
  762         case PT_TRACE_ME:
  763                 /* Always legal. */
  764                 break;
  765 
  766         case PT_ATTACH:
  767                 /* Self */
  768                 if (p->p_pid == td->td_proc->p_pid) {
  769                         error = EINVAL;
  770                         goto fail;
  771                 }
  772 
  773                 /* Already traced */
  774                 if (p->p_flag & P_TRACED) {
  775                         error = EBUSY;
  776                         goto fail;
  777                 }
  778 
  779                 /* Can't trace an ancestor if you're being traced. */
  780                 if (curp->p_flag & P_TRACED) {
  781                         for (pp = curp->p_pptr; pp != NULL; pp = pp->p_pptr) {
  782                                 if (pp == p) {
  783                                         error = EINVAL;
  784                                         goto fail;
  785                                 }
  786                         }
  787                 }
  788 
  789 
  790                 /* OK */
  791                 break;
  792 
  793         case PT_CLEARSTEP:
  794                 /* Allow thread to clear single step for itself */
  795                 if (td->td_tid == tid)
  796                         break;
  797 
  798                 /* FALLTHROUGH */
  799         default:
  800                 /* not being traced... */
  801                 if ((p->p_flag & P_TRACED) == 0) {
  802                         error = EPERM;
  803                         goto fail;
  804                 }
  805 
  806                 /* not being traced by YOU */
  807                 if (p->p_pptr != td->td_proc) {
  808                         error = EBUSY;
  809                         goto fail;
  810                 }
  811 
  812                 /* not currently stopped */
  813                 if ((p->p_flag & (P_STOPPED_SIG | P_STOPPED_TRACE)) == 0 ||
  814                     p->p_suspcount != p->p_numthreads  ||
  815                     (p->p_flag & P_WAITED) == 0) {
  816                         error = EBUSY;
  817                         goto fail;
  818                 }
  819 
  820                 if ((p->p_flag & P_STOPPED_TRACE) == 0) {
  821                         static int count = 0;
  822                         if (count++ == 0)
  823                                 printf("P_STOPPED_TRACE not set.\n");
  824                 }
  825 
  826                 /* OK */
  827                 break;
  828         }
  829 
  830         /* Keep this process around until we finish this request. */
  831         _PHOLD(p);
  832 
  833 #ifdef FIX_SSTEP
  834         /*
  835          * Single step fixup ala procfs
  836          */
  837         FIX_SSTEP(td2);
  838 #endif
  839 
  840         /*
  841          * Actually do the requests
  842          */
  843 
  844         td->td_retval[0] = 0;
  845 
  846         switch (req) {
  847         case PT_TRACE_ME:
  848                 /* set my trace flag and "owner" so it can read/write me */
  849                 p->p_flag |= P_TRACED;
  850                 p->p_oppid = p->p_pptr->p_pid;
  851                 break;
  852 
  853         case PT_ATTACH:
  854                 /* security check done above */
  855                 p->p_flag |= P_TRACED;
  856                 p->p_oppid = p->p_pptr->p_pid;
  857                 if (p->p_pptr != td->td_proc)
  858                         proc_reparent(p, td->td_proc);
  859                 data = SIGSTOP;
  860                 goto sendsig;   /* in PT_CONTINUE below */
  861 
  862         case PT_CLEARSTEP:
  863                 error = ptrace_clear_single_step(td2);
  864                 break;
  865 
  866         case PT_SETSTEP:
  867                 error = ptrace_single_step(td2);
  868                 break;
  869 
  870         case PT_SUSPEND:
  871                 td2->td_dbgflags |= TDB_SUSPEND;
  872                 thread_lock(td2);
  873                 td2->td_flags |= TDF_NEEDSUSPCHK;
  874                 thread_unlock(td2);
  875                 break;
  876 
  877         case PT_RESUME:
  878                 td2->td_dbgflags &= ~TDB_SUSPEND;
  879                 break;
  880 
  881         case PT_STEP:
  882         case PT_CONTINUE:
  883         case PT_TO_SCE:
  884         case PT_TO_SCX:
  885         case PT_SYSCALL:
  886         case PT_DETACH:
  887                 /* Zero means do not send any signal */
  888                 if (data < 0 || data > _SIG_MAXSIG) {
  889                         error = EINVAL;
  890                         break;
  891                 }
  892 
  893                 switch (req) {
  894                 case PT_STEP:
  895                         error = ptrace_single_step(td2);
  896                         if (error)
  897                                 goto out;
  898                         break;
  899                 case PT_CONTINUE:
  900                 case PT_TO_SCE:
  901                 case PT_TO_SCX:
  902                 case PT_SYSCALL:
  903                         if (addr != (void *)1) {
  904                                 error = ptrace_set_pc(td2,
  905                                     (u_long)(uintfptr_t)addr);
  906                                 if (error)
  907                                         goto out;
  908                         }
  909                         switch (req) {
  910                         case PT_TO_SCE:
  911                                 p->p_stops |= S_PT_SCE;
  912                                 break;
  913                         case PT_TO_SCX:
  914                                 p->p_stops |= S_PT_SCX;
  915                                 break;
  916                         case PT_SYSCALL:
  917                                 p->p_stops |= S_PT_SCE | S_PT_SCX;
  918                                 break;
  919                         }
  920                         break;
  921                 case PT_DETACH:
  922                         /* reset process parent */
  923                         if (p->p_oppid != p->p_pptr->p_pid) {
  924                                 struct proc *pp;
  925 
  926                                 PROC_LOCK(p->p_pptr);
  927                                 sigqueue_take(p->p_ksi);
  928                                 PROC_UNLOCK(p->p_pptr);
  929 
  930                                 PROC_UNLOCK(p);
  931                                 pp = pfind(p->p_oppid);
  932                                 if (pp == NULL)
  933                                         pp = initproc;
  934                                 else
  935                                         PROC_UNLOCK(pp);
  936                                 PROC_LOCK(p);
  937                                 proc_reparent(p, pp);
  938                                 if (pp == initproc)
  939                                         p->p_sigparent = SIGCHLD;
  940                         }
  941                         p->p_flag &= ~(P_TRACED | P_WAITED);
  942                         p->p_oppid = 0;
  943 
  944                         /* should we send SIGCHLD? */
  945                         /* childproc_continued(p); */
  946                         break;
  947                 }
  948 
  949         sendsig:
  950                 if (proctree_locked) {
  951                         sx_xunlock(&proctree_lock);
  952                         proctree_locked = 0;
  953                 }
  954                 p->p_xstat = data;
  955                 p->p_xthread = NULL;
  956                 if ((p->p_flag & (P_STOPPED_SIG | P_STOPPED_TRACE)) != 0) {
  957                         /* deliver or queue signal */
  958                         td2->td_dbgflags &= ~TDB_XSIG;
  959                         td2->td_xsig = data;
  960 
  961                         if (req == PT_DETACH) {
  962                                 struct thread *td3;
  963                                 FOREACH_THREAD_IN_PROC(p, td3) {
  964                                         td3->td_dbgflags &= ~TDB_SUSPEND; 
  965                                 }
  966                         }
  967                         /*
  968                          * unsuspend all threads, to not let a thread run,
  969                          * you should use PT_SUSPEND to suspend it before
  970                          * continuing process.
  971                          */
  972                         PROC_SLOCK(p);
  973                         p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SIG|P_WAITED);
  974                         thread_unsuspend(p);
  975                         PROC_SUNLOCK(p);
  976                 } else {
  977                         if (data)
  978                                 psignal(p, data);
  979                 }
  980                 break;
  981 
  982         case PT_WRITE_I:
  983         case PT_WRITE_D:
  984                 td2->td_dbgflags |= TDB_USERWR;
  985                 write = 1;
  986                 /* FALLTHROUGH */
  987         case PT_READ_I:
  988         case PT_READ_D:
  989                 PROC_UNLOCK(p);
  990                 tmp = 0;
  991                 /* write = 0 set above */
  992                 iov.iov_base = write ? (caddr_t)&data : (caddr_t)&tmp;
  993                 iov.iov_len = sizeof(int);
  994                 uio.uio_iov = &iov;
  995                 uio.uio_iovcnt = 1;
  996                 uio.uio_offset = (off_t)(uintptr_t)addr;
  997                 uio.uio_resid = sizeof(int);
  998                 uio.uio_segflg = UIO_SYSSPACE;  /* i.e.: the uap */
  999                 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
 1000                 uio.uio_td = td;
 1001                 error = proc_rwmem(p, &uio);
 1002                 if (uio.uio_resid != 0) {
 1003                         /*
 1004                          * XXX proc_rwmem() doesn't currently return ENOSPC,
 1005                          * so I think write() can bogusly return 0.
 1006                          * XXX what happens for short writes?  We don't want
 1007                          * to write partial data.
 1008                          * XXX proc_rwmem() returns EPERM for other invalid
 1009                          * addresses.  Convert this to EINVAL.  Does this
 1010                          * clobber returns of EPERM for other reasons?
 1011                          */
 1012                         if (error == 0 || error == ENOSPC || error == EPERM)
 1013                                 error = EINVAL; /* EOF */
 1014                 }
 1015                 if (!write)
 1016                         td->td_retval[0] = tmp;
 1017                 PROC_LOCK(p);
 1018                 break;
 1019 
 1020         case PT_IO:
 1021 #ifdef COMPAT_FREEBSD32
 1022                 if (wrap32) {
 1023                         piod32 = addr;
 1024                         iov.iov_base = (void *)(uintptr_t)piod32->piod_addr;
 1025                         iov.iov_len = piod32->piod_len;
 1026                         uio.uio_offset = (off_t)(uintptr_t)piod32->piod_offs;
 1027                         uio.uio_resid = piod32->piod_len;
 1028                 } else
 1029 #endif
 1030                 {
 1031                         piod = addr;
 1032                         iov.iov_base = piod->piod_addr;
 1033                         iov.iov_len = piod->piod_len;
 1034                         uio.uio_offset = (off_t)(uintptr_t)piod->piod_offs;
 1035                         uio.uio_resid = piod->piod_len;
 1036                 }
 1037                 uio.uio_iov = &iov;
 1038                 uio.uio_iovcnt = 1;
 1039                 uio.uio_segflg = UIO_USERSPACE;
 1040                 uio.uio_td = td;
 1041 #ifdef COMPAT_FREEBSD32
 1042                 tmp = wrap32 ? piod32->piod_op : piod->piod_op;
 1043 #else
 1044                 tmp = piod->piod_op;
 1045 #endif
 1046                 switch (tmp) {
 1047                 case PIOD_READ_D:
 1048                 case PIOD_READ_I:
 1049                         uio.uio_rw = UIO_READ;
 1050                         break;
 1051                 case PIOD_WRITE_D:
 1052                 case PIOD_WRITE_I:
 1053                         td2->td_dbgflags |= TDB_USERWR;
 1054                         uio.uio_rw = UIO_WRITE;
 1055                         break;
 1056                 default:
 1057                         error = EINVAL;
 1058                         goto out;
 1059                 }
 1060                 PROC_UNLOCK(p);
 1061                 error = proc_rwmem(p, &uio);
 1062 #ifdef COMPAT_FREEBSD32
 1063                 if (wrap32)
 1064                         piod32->piod_len -= uio.uio_resid;
 1065                 else
 1066 #endif
 1067                         piod->piod_len -= uio.uio_resid;
 1068                 PROC_LOCK(p);
 1069                 break;
 1070 
 1071         case PT_KILL:
 1072                 data = SIGKILL;
 1073                 goto sendsig;   /* in PT_CONTINUE above */
 1074 
 1075         case PT_SETREGS:
 1076                 td2->td_dbgflags |= TDB_USERWR;
 1077                 error = PROC_WRITE(regs, td2, addr);
 1078                 break;
 1079 
 1080         case PT_GETREGS:
 1081                 error = PROC_READ(regs, td2, addr);
 1082                 break;
 1083 
 1084         case PT_SETFPREGS:
 1085                 td2->td_dbgflags |= TDB_USERWR;
 1086                 error = PROC_WRITE(fpregs, td2, addr);
 1087                 break;
 1088 
 1089         case PT_GETFPREGS:
 1090                 error = PROC_READ(fpregs, td2, addr);
 1091                 break;
 1092 
 1093         case PT_SETDBREGS:
 1094                 td2->td_dbgflags |= TDB_USERWR;
 1095                 error = PROC_WRITE(dbregs, td2, addr);
 1096                 break;
 1097 
 1098         case PT_GETDBREGS:
 1099                 error = PROC_READ(dbregs, td2, addr);
 1100                 break;
 1101 
 1102         case PT_LWPINFO:
 1103                 if (data <= 0 || data > sizeof(*pl)) {
 1104                         error = EINVAL;
 1105                         break;
 1106                 }
 1107                 pl = addr;
 1108                 pl->pl_lwpid = td2->td_tid;
 1109                 if (td2->td_dbgflags & TDB_XSIG)
 1110                         pl->pl_event = PL_EVENT_SIGNAL;
 1111                 else
 1112                         pl->pl_event = 0;
 1113                 pl->pl_flags = 0;
 1114                 pl->pl_sigmask = td2->td_sigmask;
 1115                 pl->pl_siglist = td2->td_siglist;
 1116                 break;
 1117 
 1118         case PT_GETNUMLWPS:
 1119                 td->td_retval[0] = p->p_numthreads;
 1120                 break;
 1121 
 1122         case PT_GETLWPLIST:
 1123                 if (data <= 0) {
 1124                         error = EINVAL;
 1125                         break;
 1126                 }
 1127                 num = imin(p->p_numthreads, data);
 1128                 PROC_UNLOCK(p);
 1129                 buf = malloc(num * sizeof(lwpid_t), M_TEMP, M_WAITOK);
 1130                 tmp = 0;
 1131                 PROC_LOCK(p);
 1132                 FOREACH_THREAD_IN_PROC(p, td2) {
 1133                         if (tmp >= num)
 1134                                 break;
 1135                         buf[tmp++] = td2->td_tid;
 1136                 }
 1137                 PROC_UNLOCK(p);
 1138                 error = copyout(buf, addr, tmp * sizeof(lwpid_t));
 1139                 free(buf, M_TEMP);
 1140                 if (!error)
 1141                         td->td_retval[0] = tmp;
 1142                 PROC_LOCK(p);
 1143                 break;
 1144 
 1145         case PT_VM_TIMESTAMP:
 1146                 td->td_retval[0] = p->p_vmspace->vm_map.timestamp;
 1147                 break;
 1148 
 1149         case PT_VM_ENTRY:
 1150                 PROC_UNLOCK(p);
 1151 #ifdef COMPAT_FREEBSD32
 1152                 if (wrap32)
 1153                         error = ptrace_vm_entry32(td, p, addr);
 1154                 else
 1155 #endif
 1156                 error = ptrace_vm_entry(td, p, addr);
 1157                 PROC_LOCK(p);
 1158                 break;
 1159 
 1160         default:
 1161 #ifdef __HAVE_PTRACE_MACHDEP
 1162                 if (req >= PT_FIRSTMACH) {
 1163                         PROC_UNLOCK(p);
 1164                         error = cpu_ptrace(td2, req, addr, data);
 1165                         PROC_LOCK(p);
 1166                 } else
 1167 #endif
 1168                         /* Unknown request. */
 1169                         error = EINVAL;
 1170                 break;
 1171         }
 1172 
 1173 out:
 1174         /* Drop our hold on this process now that the request has completed. */
 1175         _PRELE(p);
 1176 fail:
 1177         PROC_UNLOCK(p);
 1178         if (proctree_locked)
 1179                 sx_xunlock(&proctree_lock);
 1180         return (error);
 1181 }
 1182 #undef PROC_READ
 1183 #undef PROC_WRITE
 1184 
 1185 /*
 1186  * Stop a process because of a debugging event;
 1187  * stay stopped until p->p_step is cleared
 1188  * (cleared by PIOCCONT in procfs).
 1189  */
 1190 void
 1191 stopevent(struct proc *p, unsigned int event, unsigned int val)
 1192 {
 1193 
 1194         PROC_LOCK_ASSERT(p, MA_OWNED);
 1195         p->p_step = 1;
 1196         do {
 1197                 p->p_xstat = val;
 1198                 p->p_xthread = NULL;
 1199                 p->p_stype = event;     /* Which event caused the stop? */
 1200                 wakeup(&p->p_stype);    /* Wake up any PIOCWAIT'ing procs */
 1201                 msleep(&p->p_step, &p->p_mtx, PWAIT, "stopevent", 0);
 1202         } while (p->p_step);
 1203 }

Cache object: 737631a1091b64fd3d95a55a4a665018


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