1139804Simp/*- 21945Sdg * Copyright (c) 1994, Sean Eric Fagan 31945Sdg * All rights reserved. 41541Srgrimes * 51541Srgrimes * Redistribution and use in source and binary forms, with or without 61541Srgrimes * modification, are permitted provided that the following conditions 71541Srgrimes * are met: 81541Srgrimes * 1. Redistributions of source code must retain the above copyright 91541Srgrimes * notice, this list of conditions and the following disclaimer. 101541Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111541Srgrimes * notice, this list of conditions and the following disclaimer in the 121541Srgrimes * documentation and/or other materials provided with the distribution. 131541Srgrimes * 3. All advertising materials mentioning features or use of this software 141541Srgrimes * must display the following acknowledgement: 151945Sdg * This product includes software developed by Sean Eric Fagan. 161945Sdg * 4. The name of the author may not be used to endorse or promote products 171945Sdg * derived from this software without specific prior written permission. 181541Srgrimes * 191945Sdg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 201541Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 211541Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 221945Sdg * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 231541Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 241541Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 251541Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 261541Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 271541Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 281541Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 291541Srgrimes * SUCH DAMAGE. 301541Srgrimes */ 311541Srgrimes 32116182Sobrien#include <sys/cdefs.h> 33116182Sobrien__FBSDID("$FreeBSD: stable/10/sys/kern/sys_process.c 328379 2018-01-24 21:48:39Z jhb $"); 34116182Sobrien 35147692Speter#include "opt_compat.h" 36147692Speter 371541Srgrimes#include <sys/param.h> 382112Swollman#include <sys/systm.h> 3976166Smarkm#include <sys/lock.h> 4076166Smarkm#include <sys/mutex.h> 41102946Siedowse#include <sys/syscallsubr.h> 42189282Skib#include <sys/sysent.h> 4312221Sbde#include <sys/sysproto.h> 44255708Sjhb#include <sys/priv.h> 451541Srgrimes#include <sys/proc.h> 461945Sdg#include <sys/vnode.h> 471945Sdg#include <sys/ptrace.h> 48248084Sattilio#include <sys/rwlock.h> 4974927Sjhb#include <sys/sx.h> 50132089Sdavidxu#include <sys/malloc.h> 51138129Sdas#include <sys/signalvar.h> 521541Srgrimes 531945Sdg#include <machine/reg.h> 5476166Smarkm 55155634Swsalamon#include <security/audit/audit.h> 56155634Swsalamon 571945Sdg#include <vm/vm.h> 5812662Sdg#include <vm/pmap.h> 5984637Sdes#include <vm/vm_extern.h> 6012662Sdg#include <vm/vm_map.h> 6184637Sdes#include <vm/vm_kern.h> 6284637Sdes#include <vm/vm_object.h> 631945Sdg#include <vm/vm_page.h> 64194766Skib#include <vm/vm_param.h> 651945Sdg 66205014Snwhitehorn#ifdef COMPAT_FREEBSD32 67147692Speter#include <sys/procfs.h> 68209688Skib#include <compat/freebsd32/freebsd32_signal.h> 69147692Speter 70147692Speterstruct ptrace_io_desc32 { 71147692Speter int piod_op; 72209390Sed uint32_t piod_offs; 73209390Sed uint32_t piod_addr; 74209390Sed uint32_t piod_len; 75147692Speter}; 76203708Smarcel 77203708Smarcelstruct ptrace_vm_entry32 { 78203783Smarcel int pve_entry; 79203783Smarcel int pve_timestamp; 80203708Smarcel uint32_t pve_start; 81203708Smarcel uint32_t pve_end; 82203708Smarcel uint32_t pve_offset; 83203708Smarcel u_int pve_prot; 84203708Smarcel u_int pve_pathlen; 85203783Smarcel int32_t pve_fileid; 86203783Smarcel u_int pve_fsid; 87203708Smarcel uint32_t pve_path; 88203708Smarcel}; 89203708Smarcel 90209688Skibstruct ptrace_lwpinfo32 { 91209688Skib lwpid_t pl_lwpid; /* LWP described. */ 92209688Skib int pl_event; /* Event that stopped the LWP. */ 93209688Skib int pl_flags; /* LWP flags. */ 94209688Skib sigset_t pl_sigmask; /* LWP signal mask */ 95209688Skib sigset_t pl_siglist; /* LWP pending signal */ 96209688Skib struct siginfo32 pl_siginfo; /* siginfo for signal */ 97215679Sattilio char pl_tdname[MAXCOMLEN + 1]; /* LWP name. */ 98290464Sjhb pid_t pl_child_pid; /* New child pid */ 99289780Sjhb u_int pl_syscall_code; 100289780Sjhb u_int pl_syscall_narg; 101209688Skib}; 102209688Skib 103147692Speter#endif 104147692Speter 10591006Sbde/* 10691006Sbde * Functions implemented using PROC_ACTION(): 10791006Sbde * 10891006Sbde * proc_read_regs(proc, regs) 10991006Sbde * Get the current user-visible register set from the process 11091006Sbde * and copy it into the regs structure (<machine/reg.h>). 11191006Sbde * The process is stopped at the time read_regs is called. 11291006Sbde * 11391006Sbde * proc_write_regs(proc, regs) 11491006Sbde * Update the current register set from the passed in regs 11591006Sbde * structure. Take care to avoid clobbering special CPU 11691006Sbde * registers or privileged bits in the PSL. 11791006Sbde * Depending on the architecture this may have fix-up work to do, 11891006Sbde * especially if the IAR or PCW are modified. 11991006Sbde * The process is stopped at the time write_regs is called. 12091006Sbde * 12191006Sbde * proc_read_fpregs, proc_write_fpregs 12291006Sbde * deal with the floating point register set, otherwise as above. 12391006Sbde * 12491006Sbde * proc_read_dbregs, proc_write_dbregs 12591006Sbde * deal with the processor debug register set, otherwise as above. 12691006Sbde * 12791006Sbde * proc_sstep(proc) 12891006Sbde * Arrange for the process to trap after executing a single instruction. 12991006Sbde */ 13091006Sbde 13191006Sbde#define PROC_ACTION(action) do { \ 13285297Sdes int error; \ 13385297Sdes \ 134113868Sjhb PROC_LOCK_ASSERT(td->td_proc, MA_OWNED); \ 135172207Sjeff if ((td->td_proc->p_flag & P_INMEM) == 0) \ 13691006Sbde error = EIO; \ 13791006Sbde else \ 13891006Sbde error = (action); \ 13985297Sdes return (error); \ 14091006Sbde} while(0) 141112389Sdes 14291006Sbdeint 14391006Sbdeproc_read_regs(struct thread *td, struct reg *regs) 14491006Sbde{ 14591006Sbde 14691006Sbde PROC_ACTION(fill_regs(td, regs)); 14785297Sdes} 14885297Sdes 14991006Sbdeint 15091006Sbdeproc_write_regs(struct thread *td, struct reg *regs) 15191006Sbde{ 15285297Sdes 15391006Sbde PROC_ACTION(set_regs(td, regs)); 15491006Sbde} 15591006Sbde 15684637Sdesint 15791006Sbdeproc_read_dbregs(struct thread *td, struct dbreg *dbregs) 15891006Sbde{ 15991006Sbde 16091006Sbde PROC_ACTION(fill_dbregs(td, dbregs)); 16191006Sbde} 16291006Sbde 16391006Sbdeint 16491006Sbdeproc_write_dbregs(struct thread *td, struct dbreg *dbregs) 16591006Sbde{ 16691006Sbde 16791006Sbde PROC_ACTION(set_dbregs(td, dbregs)); 16891006Sbde} 16991006Sbde 17091006Sbde/* 17191006Sbde * Ptrace doesn't support fpregs at all, and there are no security holes 17291006Sbde * or translations for fpregs, so we can just copy them. 17391006Sbde */ 17491006Sbdeint 17591006Sbdeproc_read_fpregs(struct thread *td, struct fpreg *fpregs) 17691006Sbde{ 17791006Sbde 17891006Sbde PROC_ACTION(fill_fpregs(td, fpregs)); 17991006Sbde} 18091006Sbde 18191006Sbdeint 18291006Sbdeproc_write_fpregs(struct thread *td, struct fpreg *fpregs) 18391006Sbde{ 18491006Sbde 18591006Sbde PROC_ACTION(set_fpregs(td, fpregs)); 18691006Sbde} 18791006Sbde 188205014Snwhitehorn#ifdef COMPAT_FREEBSD32 189147692Speter/* For 32 bit binaries, we need to expose the 32 bit regs layouts. */ 19091006Sbdeint 191147692Speterproc_read_regs32(struct thread *td, struct reg32 *regs32) 192147692Speter{ 193147692Speter 194147692Speter PROC_ACTION(fill_regs32(td, regs32)); 195147692Speter} 196147692Speter 197147692Speterint 198147692Speterproc_write_regs32(struct thread *td, struct reg32 *regs32) 199147692Speter{ 200147692Speter 201147692Speter PROC_ACTION(set_regs32(td, regs32)); 202147692Speter} 203147692Speter 204147692Speterint 205147692Speterproc_read_dbregs32(struct thread *td, struct dbreg32 *dbregs32) 206147692Speter{ 207147692Speter 208147692Speter PROC_ACTION(fill_dbregs32(td, dbregs32)); 209147692Speter} 210147692Speter 211147692Speterint 212147692Speterproc_write_dbregs32(struct thread *td, struct dbreg32 *dbregs32) 213147692Speter{ 214147692Speter 215147692Speter PROC_ACTION(set_dbregs32(td, dbregs32)); 216147692Speter} 217147692Speter 218147692Speterint 219147692Speterproc_read_fpregs32(struct thread *td, struct fpreg32 *fpregs32) 220147692Speter{ 221147692Speter 222147692Speter PROC_ACTION(fill_fpregs32(td, fpregs32)); 223147692Speter} 224147692Speter 225147692Speterint 226147692Speterproc_write_fpregs32(struct thread *td, struct fpreg32 *fpregs32) 227147692Speter{ 228147692Speter 229147692Speter PROC_ACTION(set_fpregs32(td, fpregs32)); 230147692Speter} 231147692Speter#endif 232147692Speter 233147692Speterint 23485297Sdesproc_sstep(struct thread *td) 23585297Sdes{ 23685297Sdes 23791006Sbde PROC_ACTION(ptrace_single_step(td)); 23885297Sdes} 23985297Sdes 24085297Sdesint 24184637Sdesproc_rwmem(struct proc *p, struct uio *uio) 24284483Sdes{ 24384637Sdes vm_map_t map; 244199819Salc vm_offset_t pageno; /* page number */ 24584637Sdes vm_prot_t reqprot; 246216604Salc int error, fault_flags, page_offset, writing; 2471945Sdg 24884637Sdes /* 249155922Sjhb * Assert that someone has locked this vmspace. (Should be 250155922Sjhb * curthread but we can't assert that.) This keeps the process 251155922Sjhb * from exiting out from under us until this operation completes. 25284637Sdes */ 253155922Sjhb KASSERT(p->p_lock >= 1, ("%s: process %p (pid %d) not held", __func__, 254155922Sjhb p, p->p_pid)); 255132684Salc 25684637Sdes /* 25784637Sdes * The map we want... 25884637Sdes */ 259155922Sjhb map = &p->p_vmspace->vm_map; 2601945Sdg 261216604Salc /* 262216604Salc * If we are writing, then we request vm_fault() to create a private 263216604Salc * copy of each page. Since these copies will not be writeable by the 264216604Salc * process, we must explicity request that they be dirtied. 265216604Salc */ 26684637Sdes writing = uio->uio_rw == UIO_WRITE; 267199819Salc reqprot = writing ? VM_PROT_COPY | VM_PROT_READ : VM_PROT_READ; 268216604Salc fault_flags = writing ? VM_FAULT_DIRTY : VM_FAULT_NORMAL; 2698876Srgrimes 27084637Sdes /* 27184637Sdes * Only map in one page at a time. We don't have to, but it 27284637Sdes * makes things easier. This way is trivial - right? 27384637Sdes */ 27484637Sdes do { 27584637Sdes vm_offset_t uva; 27684637Sdes u_int len; 27784637Sdes vm_page_t m; 2788876Srgrimes 27984637Sdes uva = (vm_offset_t)uio->uio_offset; 2801945Sdg 28184637Sdes /* 28284637Sdes * Get the page number of this segment. 28384637Sdes */ 28484637Sdes pageno = trunc_page(uva); 28584637Sdes page_offset = uva - pageno; 2861945Sdg 28784637Sdes /* 28884637Sdes * How many bytes to copy 28984637Sdes */ 29084637Sdes len = min(PAGE_SIZE - page_offset, uio->uio_resid); 29184637Sdes 29284637Sdes /* 293253953Sattilio * Fault and hold the page on behalf of the process. 29484637Sdes */ 295253953Sattilio error = vm_fault_hold(map, pageno, reqprot, fault_flags, &m); 296216604Salc if (error != KERN_SUCCESS) { 297194766Skib if (error == KERN_RESOURCE_SHORTAGE) 298194766Skib error = ENOMEM; 299194766Skib else 300194766Skib error = EFAULT; 30184637Sdes break; 3021945Sdg } 3031945Sdg 30484637Sdes /* 30584637Sdes * Now do the i/o move. 30684637Sdes */ 307127386Salc error = uiomove_fromphys(&m, page_offset, len, uio); 3081945Sdg 309198341Smarcel /* Make the I-cache coherent for breakpoints. */ 310216604Salc if (writing && error == 0) { 311216604Salc vm_map_lock_read(map); 312216604Salc if (vm_map_check_protection(map, pageno, pageno + 313216604Salc PAGE_SIZE, VM_PROT_EXECUTE)) 314216604Salc vm_sync_icache(map, uva, len); 315216604Salc vm_map_unlock_read(map); 316216604Salc } 317198341Smarcel 31884637Sdes /* 319118697Salc * Release the page. 32084637Sdes */ 321253953Sattilio vm_page_lock(m); 322253953Sattilio vm_page_unhold(m); 323253953Sattilio vm_page_unlock(m); 3241945Sdg 32584637Sdes } while (error == 0 && uio->uio_resid > 0); 3261945Sdg 32784637Sdes return (error); 3281945Sdg} 3291945Sdg 330203696Smarcelstatic int 331203696Smarcelptrace_vm_entry(struct thread *td, struct proc *p, struct ptrace_vm_entry *pve) 332203696Smarcel{ 333203783Smarcel struct vattr vattr; 334203696Smarcel vm_map_t map; 335203696Smarcel vm_map_entry_t entry; 336203696Smarcel vm_object_t obj, tobj, lobj; 337203783Smarcel struct vmspace *vm; 338203696Smarcel struct vnode *vp; 339203696Smarcel char *freepath, *fullpath; 340203696Smarcel u_int pathlen; 341241896Skib int error, index; 342203696Smarcel 343203783Smarcel error = 0; 344203783Smarcel obj = NULL; 345203783Smarcel 346203783Smarcel vm = vmspace_acquire_ref(p); 347203783Smarcel map = &vm->vm_map; 348203783Smarcel vm_map_lock_read(map); 349203783Smarcel 350203783Smarcel do { 351203783Smarcel entry = map->header.next; 352203783Smarcel index = 0; 353203783Smarcel while (index < pve->pve_entry && entry != &map->header) { 354203696Smarcel entry = entry->next; 355203783Smarcel index++; 356203783Smarcel } 357203783Smarcel if (index != pve->pve_entry) { 358203783Smarcel error = EINVAL; 359203783Smarcel break; 360203783Smarcel } 361203783Smarcel while (entry != &map->header && 362203783Smarcel (entry->eflags & MAP_ENTRY_IS_SUB_MAP) != 0) { 363203783Smarcel entry = entry->next; 364203783Smarcel index++; 365203783Smarcel } 366203783Smarcel if (entry == &map->header) { 367203783Smarcel error = ENOENT; 368203783Smarcel break; 369203783Smarcel } 370203696Smarcel 371203783Smarcel /* We got an entry. */ 372203783Smarcel pve->pve_entry = index + 1; 373203783Smarcel pve->pve_timestamp = map->timestamp; 374203783Smarcel pve->pve_start = entry->start; 375203783Smarcel pve->pve_end = entry->end - 1; 376203783Smarcel pve->pve_offset = entry->offset; 377203783Smarcel pve->pve_prot = entry->protection; 378203696Smarcel 379203783Smarcel /* Backing object's path needed? */ 380203783Smarcel if (pve->pve_pathlen == 0) 381203783Smarcel break; 382203696Smarcel 383203783Smarcel pathlen = pve->pve_pathlen; 384203783Smarcel pve->pve_pathlen = 0; 385203696Smarcel 386203783Smarcel obj = entry->object.vm_object; 387203783Smarcel if (obj != NULL) 388249277Sattilio VM_OBJECT_RLOCK(obj); 389203783Smarcel } while (0); 390203696Smarcel 391203783Smarcel vm_map_unlock_read(map); 392203783Smarcel 393203788Smarcel pve->pve_fsid = VNOVAL; 394203788Smarcel pve->pve_fileid = VNOVAL; 395203788Smarcel 396203783Smarcel if (error == 0 && obj != NULL) { 397203783Smarcel lobj = obj; 398203783Smarcel for (tobj = obj; tobj != NULL; tobj = tobj->backing_object) { 399203783Smarcel if (tobj != obj) 400249277Sattilio VM_OBJECT_RLOCK(tobj); 401203783Smarcel if (lobj != obj) 402249277Sattilio VM_OBJECT_RUNLOCK(lobj); 403203783Smarcel lobj = tobj; 404203783Smarcel pve->pve_offset += tobj->backing_object_offset; 405203783Smarcel } 406288499Svangyzen vp = vm_object_vnode(lobj); 407203696Smarcel if (vp != NULL) 408203696Smarcel vref(vp); 409203696Smarcel if (lobj != obj) 410249277Sattilio VM_OBJECT_RUNLOCK(lobj); 411249277Sattilio VM_OBJECT_RUNLOCK(obj); 412203696Smarcel 413203783Smarcel if (vp != NULL) { 414203783Smarcel freepath = NULL; 415203783Smarcel fullpath = NULL; 416203783Smarcel vn_fullpath(td, vp, &fullpath, &freepath); 417203783Smarcel vn_lock(vp, LK_SHARED | LK_RETRY); 418203783Smarcel if (VOP_GETATTR(vp, &vattr, td->td_ucred) == 0) { 419203783Smarcel pve->pve_fileid = vattr.va_fileid; 420203783Smarcel pve->pve_fsid = vattr.va_fsid; 421203783Smarcel } 422203783Smarcel vput(vp); 423203696Smarcel 424203783Smarcel if (fullpath != NULL) { 425203783Smarcel pve->pve_pathlen = strlen(fullpath) + 1; 426203783Smarcel if (pve->pve_pathlen <= pathlen) { 427203783Smarcel error = copyout(fullpath, pve->pve_path, 428203783Smarcel pve->pve_pathlen); 429203783Smarcel } else 430203783Smarcel error = ENAMETOOLONG; 431203783Smarcel } 432203783Smarcel if (freepath != NULL) 433203783Smarcel free(freepath, M_TEMP); 434203783Smarcel } 435203783Smarcel } 436303198Skib vmspace_free(vm); 437284343Sjhb if (error == 0) 438284343Sjhb CTR3(KTR_PTRACE, "PT_VM_ENTRY: pid %d, entry %d, start %p", 439284343Sjhb p->p_pid, pve->pve_entry, pve->pve_start); 440203696Smarcel 441203783Smarcel return (error); 442203783Smarcel} 443203783Smarcel 444205014Snwhitehorn#ifdef COMPAT_FREEBSD32 445290324Skibstatic int 446203783Smarcelptrace_vm_entry32(struct thread *td, struct proc *p, 447203783Smarcel struct ptrace_vm_entry32 *pve32) 448203783Smarcel{ 449203783Smarcel struct ptrace_vm_entry pve; 450203783Smarcel int error; 451203783Smarcel 452203783Smarcel pve.pve_entry = pve32->pve_entry; 453203783Smarcel pve.pve_pathlen = pve32->pve_pathlen; 454203783Smarcel pve.pve_path = (void *)(uintptr_t)pve32->pve_path; 455203783Smarcel 456203783Smarcel error = ptrace_vm_entry(td, p, &pve); 457203783Smarcel if (error == 0) { 458203783Smarcel pve32->pve_entry = pve.pve_entry; 459203783Smarcel pve32->pve_timestamp = pve.pve_timestamp; 460203783Smarcel pve32->pve_start = pve.pve_start; 461203783Smarcel pve32->pve_end = pve.pve_end; 462203783Smarcel pve32->pve_offset = pve.pve_offset; 463203783Smarcel pve32->pve_prot = pve.pve_prot; 464203783Smarcel pve32->pve_fileid = pve.pve_fileid; 465203783Smarcel pve32->pve_fsid = pve.pve_fsid; 466203696Smarcel } 467203783Smarcel 468203783Smarcel pve32->pve_pathlen = pve.pve_pathlen; 469203696Smarcel return (error); 470203696Smarcel} 471209688Skib 472209688Skibstatic void 473209688Skibptrace_lwpinfo_to32(const struct ptrace_lwpinfo *pl, 474209688Skib struct ptrace_lwpinfo32 *pl32) 475209688Skib{ 476209688Skib 477325643Skib bzero(pl32, sizeof(*pl32)); 478209688Skib pl32->pl_lwpid = pl->pl_lwpid; 479209688Skib pl32->pl_event = pl->pl_event; 480209688Skib pl32->pl_flags = pl->pl_flags; 481209688Skib pl32->pl_sigmask = pl->pl_sigmask; 482209688Skib pl32->pl_siglist = pl->pl_siglist; 483209688Skib siginfo_to_siginfo32(&pl->pl_siginfo, &pl32->pl_siginfo); 484215679Sattilio strcpy(pl32->pl_tdname, pl->pl_tdname); 485217819Skib pl32->pl_child_pid = pl->pl_child_pid; 486289780Sjhb pl32->pl_syscall_code = pl->pl_syscall_code; 487289780Sjhb pl32->pl_syscall_narg = pl->pl_syscall_narg; 488209688Skib} 489205014Snwhitehorn#endif /* COMPAT_FREEBSD32 */ 490203696Smarcel 4911541Srgrimes/* 4921541Srgrimes * Process debugging system call. 4931541Srgrimes */ 49412221Sbde#ifndef _SYS_SYSPROTO_H_ 4951541Srgrimesstruct ptrace_args { 4961541Srgrimes int req; 4971541Srgrimes pid_t pid; 4981541Srgrimes caddr_t addr; 4991541Srgrimes int data; 5001541Srgrimes}; 50112221Sbde#endif 5021945Sdg 503205014Snwhitehorn#ifdef COMPAT_FREEBSD32 504114028Sjhb/* 505147692Speter * This CPP subterfuge is to try and reduce the number of ifdefs in 506147692Speter * the body of the code. 507147692Speter * COPYIN(uap->addr, &r.reg, sizeof r.reg); 508147692Speter * becomes either: 509147692Speter * copyin(uap->addr, &r.reg, sizeof r.reg); 510147692Speter * or 511147692Speter * copyin(uap->addr, &r.reg32, sizeof r.reg32); 512147692Speter * .. except this is done at runtime. 513147692Speter */ 514147692Speter#define COPYIN(u, k, s) wrap32 ? \ 515147692Speter copyin(u, k ## 32, s ## 32) : \ 516147692Speter copyin(u, k, s) 517147692Speter#define COPYOUT(k, u, s) wrap32 ? \ 518147692Speter copyout(k ## 32, u, s ## 32) : \ 519147692Speter copyout(k, u, s) 520147692Speter#else 521147692Speter#define COPYIN(u, k, s) copyin(u, k, s) 522147692Speter#define COPYOUT(k, u, s) copyout(k, u, s) 523147692Speter#endif 5241549Srgrimesint 525225617Skmacysys_ptrace(struct thread *td, struct ptrace_args *uap) 5261541Srgrimes{ 52791007Sbde /* 52891007Sbde * XXX this obfuscation is to reduce stack usage, but the register 52991007Sbde * structs may be too large to put on the stack anyway. 53091007Sbde */ 53184637Sdes union { 53292395Sdes struct ptrace_io_desc piod; 533132016Smarcel struct ptrace_lwpinfo pl; 534203696Smarcel struct ptrace_vm_entry pve; 53591007Sbde struct dbreg dbreg; 53691007Sbde struct fpreg fpreg; 53791007Sbde struct reg reg; 538205014Snwhitehorn#ifdef COMPAT_FREEBSD32 539147692Speter struct dbreg32 dbreg32; 540147692Speter struct fpreg32 fpreg32; 541147692Speter struct reg32 reg32; 542147692Speter struct ptrace_io_desc32 piod32; 543209688Skib struct ptrace_lwpinfo32 pl32; 544203708Smarcel struct ptrace_vm_entry32 pve32; 545147692Speter#endif 546304188Sjhb int ptevents; 54784637Sdes } r; 548102946Siedowse void *addr; 549102946Siedowse int error = 0; 550205014Snwhitehorn#ifdef COMPAT_FREEBSD32 551147692Speter int wrap32 = 0; 552102946Siedowse 553189282Skib if (SV_CURPROC_FLAG(SV_ILP32)) 554147692Speter wrap32 = 1; 555147692Speter#endif 556195104Srwatson AUDIT_ARG_PID(uap->pid); 557195104Srwatson AUDIT_ARG_CMD(uap->req); 558195104Srwatson AUDIT_ARG_VALUE(uap->data); 559102946Siedowse addr = &r; 560102946Siedowse switch (uap->req) { 561304188Sjhb case PT_GET_EVENT_MASK: 562102946Siedowse case PT_GETREGS: 563102946Siedowse case PT_GETFPREGS: 564102946Siedowse case PT_GETDBREGS: 565132016Smarcel case PT_LWPINFO: 566102946Siedowse break; 567102946Siedowse case PT_SETREGS: 568147692Speter error = COPYIN(uap->addr, &r.reg, sizeof r.reg); 569102946Siedowse break; 570102946Siedowse case PT_SETFPREGS: 571147692Speter error = COPYIN(uap->addr, &r.fpreg, sizeof r.fpreg); 572102946Siedowse break; 573102946Siedowse case PT_SETDBREGS: 574147692Speter error = COPYIN(uap->addr, &r.dbreg, sizeof r.dbreg); 575102946Siedowse break; 576304188Sjhb case PT_SET_EVENT_MASK: 577304188Sjhb if (uap->data != sizeof(r.ptevents)) 578304188Sjhb error = EINVAL; 579304188Sjhb else 580304188Sjhb error = copyin(uap->addr, &r.ptevents, uap->data); 581304188Sjhb break; 582102946Siedowse case PT_IO: 583147692Speter error = COPYIN(uap->addr, &r.piod, sizeof r.piod); 584102946Siedowse break; 585203696Smarcel case PT_VM_ENTRY: 586203696Smarcel error = COPYIN(uap->addr, &r.pve, sizeof r.pve); 587203696Smarcel break; 588102946Siedowse default: 589102946Siedowse addr = uap->addr; 590118932Smarcel break; 591102946Siedowse } 592102946Siedowse if (error) 593102946Siedowse return (error); 594102946Siedowse 595102946Siedowse error = kern_ptrace(td, uap->req, uap->pid, addr, uap->data); 596102946Siedowse if (error) 597102946Siedowse return (error); 598102946Siedowse 599102946Siedowse switch (uap->req) { 600203696Smarcel case PT_VM_ENTRY: 601203696Smarcel error = COPYOUT(&r.pve, uap->addr, sizeof r.pve); 602203696Smarcel break; 603102946Siedowse case PT_IO: 604147692Speter error = COPYOUT(&r.piod, uap->addr, sizeof r.piod); 605102946Siedowse break; 606102946Siedowse case PT_GETREGS: 607147692Speter error = COPYOUT(&r.reg, uap->addr, sizeof r.reg); 608102946Siedowse break; 609102946Siedowse case PT_GETFPREGS: 610147692Speter error = COPYOUT(&r.fpreg, uap->addr, sizeof r.fpreg); 611102946Siedowse break; 612102946Siedowse case PT_GETDBREGS: 613147692Speter error = COPYOUT(&r.dbreg, uap->addr, sizeof r.dbreg); 614102946Siedowse break; 615304188Sjhb case PT_GET_EVENT_MASK: 616304188Sjhb /* NB: The size in uap->data is validated in kern_ptrace(). */ 617304188Sjhb error = copyout(&r.ptevents, uap->addr, uap->data); 618304188Sjhb break; 619132016Smarcel case PT_LWPINFO: 620304188Sjhb /* NB: The size in uap->data is validated in kern_ptrace(). */ 621132016Smarcel error = copyout(&r.pl, uap->addr, uap->data); 622132016Smarcel break; 623102946Siedowse } 624102946Siedowse 625102946Siedowse return (error); 626102946Siedowse} 627147692Speter#undef COPYIN 628147692Speter#undef COPYOUT 629102946Siedowse 630205014Snwhitehorn#ifdef COMPAT_FREEBSD32 631147692Speter/* 632147692Speter * PROC_READ(regs, td2, addr); 633147692Speter * becomes either: 634147692Speter * proc_read_regs(td2, addr); 635147692Speter * or 636147692Speter * proc_read_regs32(td2, addr); 637147692Speter * .. except this is done at runtime. There is an additional 638147692Speter * complication in that PROC_WRITE disallows 32 bit consumers 639147692Speter * from writing to 64 bit address space targets. 640147692Speter */ 641147692Speter#define PROC_READ(w, t, a) wrap32 ? \ 642147692Speter proc_read_ ## w ## 32(t, a) : \ 643147692Speter proc_read_ ## w (t, a) 644147692Speter#define PROC_WRITE(w, t, a) wrap32 ? \ 645147692Speter (safe ? proc_write_ ## w ## 32(t, a) : EINVAL ) : \ 646147692Speter proc_write_ ## w (t, a) 647147692Speter#else 648147692Speter#define PROC_READ(w, t, a) proc_read_ ## w (t, a) 649147692Speter#define PROC_WRITE(w, t, a) proc_write_ ## w (t, a) 650147692Speter#endif 651147692Speter 652304190Skibvoid 653304613Smarkjproc_set_traced(struct proc *p, bool stop) 654304190Skib{ 655304190Skib 656304190Skib PROC_LOCK_ASSERT(p, MA_OWNED); 657304190Skib p->p_flag |= P_TRACED; 658304613Smarkj if (stop) 659304613Smarkj p->p_flag2 |= P2_PTRACE_FSTP; 660304190Skib p->p_ptevents = PTRACE_DEFAULT; 661304190Skib p->p_oppid = p->p_pptr->p_pid; 662304190Skib} 663304190Skib 664102946Siedowseint 665102946Siedowsekern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) 666102946Siedowse{ 667102946Siedowse struct iovec iov; 668102946Siedowse struct uio uio; 66994665Salfred struct proc *curp, *p, *pp; 670238287Sdavidxu struct thread *td2 = NULL, *td3; 671147692Speter struct ptrace_io_desc *piod = NULL; 672132016Smarcel struct ptrace_lwpinfo *pl; 673132089Sdavidxu int error, write, tmp, num; 67494556Sjhb int proctree_locked = 0; 675132089Sdavidxu lwpid_t tid = 0, *buf; 676205014Snwhitehorn#ifdef COMPAT_FREEBSD32 677147692Speter int wrap32 = 0, safe = 0; 678147692Speter struct ptrace_io_desc32 *piod32 = NULL; 679209688Skib struct ptrace_lwpinfo32 *pl32 = NULL; 680209688Skib struct ptrace_lwpinfo plr; 681147692Speter#endif 6821541Srgrimes 68394665Salfred curp = td->td_proc; 68494665Salfred 685102946Siedowse /* Lock proctree before locking the process. */ 686102946Siedowse switch (req) { 68794556Sjhb case PT_TRACE_ME: 68894556Sjhb case PT_ATTACH: 68994556Sjhb case PT_STEP: 69094556Sjhb case PT_CONTINUE: 691120937Srobert case PT_TO_SCE: 692120937Srobert case PT_TO_SCX: 693143820Sdas case PT_SYSCALL: 694217819Skib case PT_FOLLOW_FORK: 695304017Sjhb case PT_LWP_EVENTS: 696304188Sjhb case PT_GET_EVENT_MASK: 697304188Sjhb case PT_SET_EVENT_MASK: 69894556Sjhb case PT_DETACH: 69994556Sjhb sx_xlock(&proctree_lock); 70094556Sjhb proctree_locked = 1; 70194556Sjhb break; 70294556Sjhb default: 70395165Smarcel break; 70494556Sjhb } 705112389Sdes 70648430Speter write = 0; 707102946Siedowse if (req == PT_TRACE_ME) { 70894556Sjhb p = td->td_proc; 70975893Sjhb PROC_LOCK(p); 71075893Sjhb } else { 711131450Sdavidxu if (pid <= PID_MAX) { 712131450Sdavidxu if ((p = pfind(pid)) == NULL) { 713131450Sdavidxu if (proctree_locked) 714131450Sdavidxu sx_xunlock(&proctree_lock); 715131450Sdavidxu return (ESRCH); 716131450Sdavidxu } 717131450Sdavidxu } else { 718213642Sdavidxu td2 = tdfind(pid, -1); 719213642Sdavidxu if (td2 == NULL) { 720131450Sdavidxu if (proctree_locked) 721131450Sdavidxu sx_xunlock(&proctree_lock); 722131450Sdavidxu return (ESRCH); 723131450Sdavidxu } 724213642Sdavidxu p = td2->td_proc; 725131450Sdavidxu tid = pid; 726131450Sdavidxu pid = p->p_pid; 72794556Sjhb } 7281945Sdg } 729195104Srwatson AUDIT_ARG_PROCESS(p); 730155922Sjhb 731155922Sjhb if ((p->p_flag & P_WEXIT) != 0) { 732155922Sjhb error = ESRCH; 733155922Sjhb goto fail; 734155922Sjhb } 735100418Srwatson if ((error = p_cansee(td, p)) != 0) 73694556Sjhb goto fail; 73784637Sdes 73896886Sjhb if ((error = p_candebug(td, p)) != 0) 73994556Sjhb goto fail; 74094556Sjhb 74113607Speter /* 74291007Sbde * System processes can't be debugged. 74384637Sdes */ 74484637Sdes if ((p->p_flag & P_SYSTEM) != 0) { 74594556Sjhb error = EINVAL; 74694556Sjhb goto fail; 74784637Sdes } 748112389Sdes 749131450Sdavidxu if (tid == 0) { 750153697Sdavidxu if ((p->p_flag & P_STOPPED_TRACE) != 0) { 751153697Sdavidxu KASSERT(p->p_xthread != NULL, ("NULL p_xthread")); 752153697Sdavidxu td2 = p->p_xthread; 753153697Sdavidxu } else { 754153697Sdavidxu td2 = FIRST_THREAD_IN_PROC(p); 755153697Sdavidxu } 756131450Sdavidxu tid = td2->td_tid; 757131450Sdavidxu } 758131450Sdavidxu 759205014Snwhitehorn#ifdef COMPAT_FREEBSD32 76084637Sdes /* 761147692Speter * Test if we're a 32 bit client and what the target is. 762147692Speter * Set the wrap controls accordingly. 763147692Speter */ 764189282Skib if (SV_CURPROC_FLAG(SV_ILP32)) { 765217896Sdchagin if (SV_PROC_FLAG(td2->td_proc, SV_ILP32)) 766147692Speter safe = 1; 767147692Speter wrap32 = 1; 768147692Speter } 769147692Speter#endif 770147692Speter /* 77113607Speter * Permissions check 77213607Speter */ 773102946Siedowse switch (req) { 77413607Speter case PT_TRACE_ME: 775290324Skib /* 776290324Skib * Always legal, when there is a parent process which 777290324Skib * could trace us. Otherwise, reject. 778290324Skib */ 779290324Skib if ((p->p_flag & P_TRACED) != 0) { 780290324Skib error = EBUSY; 781290324Skib goto fail; 782290324Skib } 783290324Skib if (p->p_pptr == initproc) { 784290324Skib error = EPERM; 785290324Skib goto fail; 786290324Skib } 78713607Speter break; 7881945Sdg 78913607Speter case PT_ATTACH: 79013607Speter /* Self */ 791290323Skib if (p == td->td_proc) { 79294556Sjhb error = EINVAL; 79394556Sjhb goto fail; 79475893Sjhb } 79513607Speter 79613607Speter /* Already traced */ 79773917Sjhb if (p->p_flag & P_TRACED) { 79894556Sjhb error = EBUSY; 79994556Sjhb goto fail; 80073917Sjhb } 80113607Speter 80294665Salfred /* Can't trace an ancestor if you're being traced. */ 80394665Salfred if (curp->p_flag & P_TRACED) { 80494665Salfred for (pp = curp->p_pptr; pp != NULL; pp = pp->p_pptr) { 80594665Salfred if (pp == p) { 80694665Salfred error = EINVAL; 80794665Salfred goto fail; 80894665Salfred } 80994665Salfred } 81094665Salfred } 81194665Salfred 81294665Salfred 81313607Speter /* OK */ 81413607Speter break; 81513607Speter 816132089Sdavidxu case PT_CLEARSTEP: 817132089Sdavidxu /* Allow thread to clear single step for itself */ 818132089Sdavidxu if (td->td_tid == tid) 819132089Sdavidxu break; 820132089Sdavidxu 821132089Sdavidxu /* FALLTHROUGH */ 822118932Smarcel default: 82313607Speter /* not being traced... */ 82473917Sjhb if ((p->p_flag & P_TRACED) == 0) { 82594556Sjhb error = EPERM; 82694556Sjhb goto fail; 82773917Sjhb } 82813607Speter 82913607Speter /* not being traced by YOU */ 83094556Sjhb if (p->p_pptr != td->td_proc) { 83194556Sjhb error = EBUSY; 83294556Sjhb goto fail; 83370317Sjake } 83413607Speter 83513607Speter /* not currently stopped */ 836153697Sdavidxu if ((p->p_flag & (P_STOPPED_SIG | P_STOPPED_TRACE)) == 0 || 837153697Sdavidxu p->p_suspcount != p->p_numthreads || 838132089Sdavidxu (p->p_flag & P_WAITED) == 0) { 83994556Sjhb error = EBUSY; 84094556Sjhb goto fail; 84169506Sjhb } 84213607Speter 843153697Sdavidxu if ((p->p_flag & P_STOPPED_TRACE) == 0) { 844153697Sdavidxu static int count = 0; 845153697Sdavidxu if (count++ == 0) 846153697Sdavidxu printf("P_STOPPED_TRACE not set.\n"); 847153697Sdavidxu } 848153697Sdavidxu 84913607Speter /* OK */ 85013607Speter break; 8511945Sdg } 85213607Speter 853155922Sjhb /* Keep this process around until we finish this request. */ 854155922Sjhb _PHOLD(p); 855155922Sjhb 85613607Speter#ifdef FIX_SSTEP 85713607Speter /* 85813607Speter * Single step fixup ala procfs 85913607Speter */ 860155922Sjhb FIX_SSTEP(td2); 8611945Sdg#endif 86213607Speter 8631541Srgrimes /* 86413607Speter * Actually do the requests 8651541Srgrimes */ 8661945Sdg 86783366Sjulian td->td_retval[0] = 0; 86813607Speter 869102946Siedowse switch (req) { 87013607Speter case PT_TRACE_ME: 87113607Speter /* set my trace flag and "owner" so it can read/write me */ 872304613Smarkj proc_set_traced(p, false); 873246484Skib if (p->p_flag & P_PPWAIT) 874246484Skib p->p_flag |= P_PPTRACE; 875284343Sjhb CTR1(KTR_PTRACE, "PT_TRACE_ME: pid %d", p->p_pid); 876155922Sjhb break; 8771945Sdg 87813607Speter case PT_ATTACH: 87913607Speter /* security check done above */ 880223212Sobrien /* 881223212Sobrien * It would be nice if the tracing relationship was separate 882223212Sobrien * from the parent relationship but that would require 883223212Sobrien * another set of links in the proc struct or for "wait" 884223212Sobrien * to scan the entire proc table. To make life easier, 885223212Sobrien * we just re-parent the process we're trying to trace. 886223212Sobrien * The old parent is remembered so we can put things back 887223212Sobrien * on a "detach". 888223212Sobrien */ 889304613Smarkj proc_set_traced(p, true); 890223088Sobrien if (p->p_pptr != td->td_proc) { 89194556Sjhb proc_reparent(p, td->td_proc); 892223088Sobrien } 893102946Siedowse data = SIGSTOP; 894284343Sjhb CTR2(KTR_PTRACE, "PT_ATTACH: pid %d, oppid %d", p->p_pid, 895284343Sjhb p->p_oppid); 89613607Speter goto sendsig; /* in PT_CONTINUE below */ 89713607Speter 898132089Sdavidxu case PT_CLEARSTEP: 899284343Sjhb CTR2(KTR_PTRACE, "PT_CLEARSTEP: tid %d (pid %d)", td2->td_tid, 900284343Sjhb p->p_pid); 901132089Sdavidxu error = ptrace_clear_single_step(td2); 902155922Sjhb break; 903132089Sdavidxu 904132089Sdavidxu case PT_SETSTEP: 905284343Sjhb CTR2(KTR_PTRACE, "PT_SETSTEP: tid %d (pid %d)", td2->td_tid, 906284343Sjhb p->p_pid); 907132089Sdavidxu error = ptrace_single_step(td2); 908155922Sjhb break; 909132089Sdavidxu 910132089Sdavidxu case PT_SUSPEND: 911284343Sjhb CTR2(KTR_PTRACE, "PT_SUSPEND: tid %d (pid %d)", td2->td_tid, 912284343Sjhb p->p_pid); 913183911Sdavidxu td2->td_dbgflags |= TDB_SUSPEND; 914170307Sjeff thread_lock(td2); 915183911Sdavidxu td2->td_flags |= TDF_NEEDSUSPCHK; 916170307Sjeff thread_unlock(td2); 917155922Sjhb break; 918132089Sdavidxu 919132089Sdavidxu case PT_RESUME: 920284343Sjhb CTR2(KTR_PTRACE, "PT_RESUME: tid %d (pid %d)", td2->td_tid, 921284343Sjhb p->p_pid); 922183911Sdavidxu td2->td_dbgflags &= ~TDB_SUSPEND; 923155922Sjhb break; 924132089Sdavidxu 925217819Skib case PT_FOLLOW_FORK: 926284343Sjhb CTR3(KTR_PTRACE, "PT_FOLLOW_FORK: pid %d %s -> %s", p->p_pid, 927304188Sjhb p->p_ptevents & PTRACE_FORK ? "enabled" : "disabled", 928284343Sjhb data ? "enabled" : "disabled"); 929217819Skib if (data) 930304188Sjhb p->p_ptevents |= PTRACE_FORK; 931217819Skib else 932304188Sjhb p->p_ptevents &= ~PTRACE_FORK; 933217819Skib break; 934217819Skib 935304017Sjhb case PT_LWP_EVENTS: 936304017Sjhb CTR3(KTR_PTRACE, "PT_LWP_EVENTS: pid %d %s -> %s", p->p_pid, 937304188Sjhb p->p_ptevents & PTRACE_LWP ? "enabled" : "disabled", 938304017Sjhb data ? "enabled" : "disabled"); 939304017Sjhb if (data) 940304188Sjhb p->p_ptevents |= PTRACE_LWP; 941304017Sjhb else 942304188Sjhb p->p_ptevents &= ~PTRACE_LWP; 943304017Sjhb break; 944304017Sjhb 945304188Sjhb case PT_GET_EVENT_MASK: 946304188Sjhb if (data != sizeof(p->p_ptevents)) { 947304188Sjhb error = EINVAL; 948304188Sjhb break; 949304188Sjhb } 950304188Sjhb CTR2(KTR_PTRACE, "PT_GET_EVENT_MASK: pid %d mask %#x", p->p_pid, 951304188Sjhb p->p_ptevents); 952304188Sjhb *(int *)addr = p->p_ptevents; 953304188Sjhb break; 954304188Sjhb 955304188Sjhb case PT_SET_EVENT_MASK: 956304188Sjhb if (data != sizeof(p->p_ptevents)) { 957304188Sjhb error = EINVAL; 958304188Sjhb break; 959304188Sjhb } 960304188Sjhb tmp = *(int *)addr; 961304188Sjhb if ((tmp & ~(PTRACE_EXEC | PTRACE_SCE | PTRACE_SCX | 962304499Sjhb PTRACE_FORK | PTRACE_LWP | PTRACE_VFORK)) != 0) { 963304188Sjhb error = EINVAL; 964304188Sjhb break; 965304188Sjhb } 966304188Sjhb CTR3(KTR_PTRACE, "PT_SET_EVENT_MASK: pid %d mask %#x -> %#x", 967304188Sjhb p->p_pid, p->p_ptevents, tmp); 968304188Sjhb p->p_ptevents = tmp; 969304188Sjhb break; 970304188Sjhb 97113607Speter case PT_STEP: 97213607Speter case PT_CONTINUE: 973120937Srobert case PT_TO_SCE: 974120937Srobert case PT_TO_SCX: 975143820Sdas case PT_SYSCALL: 9761945Sdg case PT_DETACH: 977118749Snectar /* Zero means do not send any signal */ 978118749Snectar if (data < 0 || data > _SIG_MAXSIG) { 97994556Sjhb error = EINVAL; 980155922Sjhb break; 98194556Sjhb } 98213607Speter 983120937Srobert switch (req) { 984120937Srobert case PT_STEP: 985324215Sjhb CTR3(KTR_PTRACE, "PT_STEP: tid %d (pid %d), sig = %d", 986324215Sjhb td2->td_tid, p->p_pid, data); 98790391Speter error = ptrace_single_step(td2); 988155922Sjhb if (error) 989155922Sjhb goto out; 990120937Srobert break; 991208555Sjhb case PT_CONTINUE: 992120937Srobert case PT_TO_SCE: 993120937Srobert case PT_TO_SCX: 994120937Srobert case PT_SYSCALL: 995208555Sjhb if (addr != (void *)1) { 996208555Sjhb error = ptrace_set_pc(td2, 997208555Sjhb (u_long)(uintfptr_t)addr); 998208555Sjhb if (error) 999208555Sjhb goto out; 1000208555Sjhb } 1001208555Sjhb switch (req) { 1002208555Sjhb case PT_TO_SCE: 1003304188Sjhb p->p_ptevents |= PTRACE_SCE; 1004290456Sjhb CTR4(KTR_PTRACE, 1005304188Sjhb "PT_TO_SCE: pid %d, events = %#x, PC = %#lx, sig = %d", 1006304188Sjhb p->p_pid, p->p_ptevents, 1007290456Sjhb (u_long)(uintfptr_t)addr, data); 1008208555Sjhb break; 1009208555Sjhb case PT_TO_SCX: 1010304188Sjhb p->p_ptevents |= PTRACE_SCX; 1011290456Sjhb CTR4(KTR_PTRACE, 1012304188Sjhb "PT_TO_SCX: pid %d, events = %#x, PC = %#lx, sig = %d", 1013304188Sjhb p->p_pid, p->p_ptevents, 1014290456Sjhb (u_long)(uintfptr_t)addr, data); 1015208555Sjhb break; 1016208555Sjhb case PT_SYSCALL: 1017304188Sjhb p->p_ptevents |= PTRACE_SYSCALL; 1018290456Sjhb CTR4(KTR_PTRACE, 1019304188Sjhb "PT_SYSCALL: pid %d, events = %#x, PC = %#lx, sig = %d", 1020304188Sjhb p->p_pid, p->p_ptevents, 1021290456Sjhb (u_long)(uintfptr_t)addr, data); 1022208555Sjhb break; 1023284343Sjhb case PT_CONTINUE: 1024290456Sjhb CTR3(KTR_PTRACE, 1025290456Sjhb "PT_CONTINUE: pid %d, PC = %#lx, sig = %d", 1026290456Sjhb p->p_pid, (u_long)(uintfptr_t)addr, data); 1027284343Sjhb break; 1028208555Sjhb } 1029120937Srobert break; 1030208555Sjhb case PT_DETACH: 1031287604Sjhb /* 1032287604Sjhb * Reset the process parent. 1033287604Sjhb * 1034287604Sjhb * NB: This clears P_TRACED before reparenting 1035287604Sjhb * a detached process back to its original 1036287604Sjhb * parent. Otherwise the debugee will be set 1037287604Sjhb * as an orphan of the debugger. 1038287604Sjhb */ 1039304188Sjhb p->p_flag &= ~(P_TRACED | P_WAITED); 104013607Speter if (p->p_oppid != p->p_pptr->p_pid) { 1041152214Sdavidxu PROC_LOCK(p->p_pptr); 1042152214Sdavidxu sigqueue_take(p->p_ksi); 1043152214Sdavidxu PROC_UNLOCK(p->p_pptr); 1044152214Sdavidxu 1045270264Skib pp = proc_realparent(p); 104676274Sjhb proc_reparent(p, pp); 1047125993Struckman if (pp == initproc) 1048125993Struckman p->p_sigparent = SIGCHLD; 1049290456Sjhb CTR3(KTR_PTRACE, 1050290456Sjhb "PT_DETACH: pid %d reparented to pid %d, sig %d", 1051290456Sjhb p->p_pid, pp->p_pid, data); 1052284343Sjhb } else 1053290456Sjhb CTR2(KTR_PTRACE, "PT_DETACH: pid %d, sig %d", 1054290456Sjhb p->p_pid, data); 1055223088Sobrien p->p_oppid = 0; 1056304188Sjhb p->p_ptevents = 0; 1057304190Skib FOREACH_THREAD_IN_PROC(p, td3) { 1058304190Skib if ((td3->td_dbgflags & TDB_FSTP) != 0) { 1059304190Skib sigqueue_delete(&td3->td_sigqueue, 1060304190Skib SIGSTOP); 1061304190Skib } 1062304190Skib td3->td_dbgflags &= ~(TDB_XSIG | TDB_FSTP); 1063304190Skib } 1064304190Skib if ((p->p_flag2 & P2_PTRACE_FSTP) != 0) { 1065304190Skib sigqueue_delete(&p->p_sigqueue, SIGSTOP); 1066304190Skib p->p_flag2 &= ~P2_PTRACE_FSTP; 1067304190Skib } 106873917Sjhb 106913607Speter /* should we send SIGCHLD? */ 1070152214Sdavidxu /* childproc_continued(p); */ 1071208555Sjhb break; 107213607Speter } 107313607Speter 107413607Speter sendsig: 1075328379Sjhb /* 1076328379Sjhb * Clear the pending event for the thread that just 1077328379Sjhb * reported its event (p_xthread). This may not be 1078328379Sjhb * the thread passed to PT_CONTINUE, PT_STEP, etc. if 1079328379Sjhb * the debugger is resuming a different thread. 1080328379Sjhb */ 1081328379Sjhb td2 = p->p_xthread; 1082155922Sjhb if (proctree_locked) { 108394556Sjhb sx_xunlock(&proctree_lock); 1084155922Sjhb proctree_locked = 0; 1085155922Sjhb } 1086153697Sdavidxu p->p_xstat = data; 1087153697Sdavidxu p->p_xthread = NULL; 1088153697Sdavidxu if ((p->p_flag & (P_STOPPED_SIG | P_STOPPED_TRACE)) != 0) { 1089172485Sjeff /* deliver or queue signal */ 1090183911Sdavidxu td2->td_dbgflags &= ~TDB_XSIG; 1091172485Sjeff td2->td_xsig = data; 1092172485Sjeff 1093315949Sbadger /* 1094315949Sbadger * P_WKILLED is insurance that a PT_KILL/SIGKILL always 1095315949Sbadger * works immediately, even if another thread is 1096315949Sbadger * unsuspended first and attempts to handle a different 1097315949Sbadger * signal or if the POSIX.1b style signal queue cannot 1098315949Sbadger * accommodate any new signals. 1099315949Sbadger */ 1100315949Sbadger if (data == SIGKILL) 1101315949Sbadger p->p_flag |= P_WKILLED; 1102315949Sbadger 1103132089Sdavidxu if (req == PT_DETACH) { 1104238287Sdavidxu FOREACH_THREAD_IN_PROC(p, td3) 1105304190Skib td3->td_dbgflags &= ~TDB_SUSPEND; 1106132089Sdavidxu } 1107132089Sdavidxu /* 1108132089Sdavidxu * unsuspend all threads, to not let a thread run, 1109132089Sdavidxu * you should use PT_SUSPEND to suspend it before 1110132089Sdavidxu * continuing process. 1111132089Sdavidxu */ 1112184667Sdavidxu PROC_SLOCK(p); 1113153697Sdavidxu p->p_flag &= ~(P_STOPPED_TRACE|P_STOPPED_SIG|P_WAITED); 1114103216Sjulian thread_unsuspend(p); 1115184667Sdavidxu PROC_SUNLOCK(p); 1116238287Sdavidxu if (req == PT_ATTACH) 1117238287Sdavidxu kern_psignal(p, data); 1118172485Sjeff } else { 1119172485Sjeff if (data) 1120225617Skmacy kern_psignal(p, data); 1121153697Sdavidxu } 1122155922Sjhb break; 11231945Sdg 11241945Sdg case PT_WRITE_I: 11251945Sdg case PT_WRITE_D: 1126202882Skib td2->td_dbgflags |= TDB_USERWR; 112713607Speter write = 1; 1128102412Scharnier /* FALLTHROUGH */ 112913607Speter case PT_READ_I: 113013607Speter case PT_READ_D: 113194556Sjhb PROC_UNLOCK(p); 113299880Stmm tmp = 0; 113313607Speter /* write = 0 set above */ 1134102946Siedowse iov.iov_base = write ? (caddr_t)&data : (caddr_t)&tmp; 113513607Speter iov.iov_len = sizeof(int); 113613607Speter uio.uio_iov = &iov; 113713607Speter uio.uio_iovcnt = 1; 1138102946Siedowse uio.uio_offset = (off_t)(uintptr_t)addr; 113913607Speter uio.uio_resid = sizeof(int); 114091007Sbde uio.uio_segflg = UIO_SYSSPACE; /* i.e.: the uap */ 114113607Speter uio.uio_rw = write ? UIO_WRITE : UIO_READ; 114283366Sjulian uio.uio_td = td; 114384637Sdes error = proc_rwmem(p, &uio); 114414925Speter if (uio.uio_resid != 0) { 114514925Speter /* 114684637Sdes * XXX proc_rwmem() doesn't currently return ENOSPC, 114714925Speter * so I think write() can bogusly return 0. 114814925Speter * XXX what happens for short writes? We don't want 114914925Speter * to write partial data. 115084637Sdes * XXX proc_rwmem() returns EPERM for other invalid 115114925Speter * addresses. Convert this to EINVAL. Does this 115214925Speter * clobber returns of EPERM for other reasons? 115314925Speter */ 115414925Speter if (error == 0 || error == ENOSPC || error == EPERM) 115514925Speter error = EINVAL; /* EOF */ 115614925Speter } 115799880Stmm if (!write) 115899880Stmm td->td_retval[0] = tmp; 1159284343Sjhb if (error == 0) { 1160284343Sjhb if (write) 1161284343Sjhb CTR3(KTR_PTRACE, "PT_WRITE: pid %d: %p <= %#x", 1162284343Sjhb p->p_pid, addr, data); 1163284343Sjhb else 1164284343Sjhb CTR3(KTR_PTRACE, "PT_READ: pid %d: %p >= %#x", 1165284343Sjhb p->p_pid, addr, tmp); 1166284343Sjhb } 1167155922Sjhb PROC_LOCK(p); 1168155922Sjhb break; 11691945Sdg 117092395Sdes case PT_IO: 1171205014Snwhitehorn#ifdef COMPAT_FREEBSD32 1172147692Speter if (wrap32) { 1173147692Speter piod32 = addr; 1174147692Speter iov.iov_base = (void *)(uintptr_t)piod32->piod_addr; 1175147692Speter iov.iov_len = piod32->piod_len; 1176147692Speter uio.uio_offset = (off_t)(uintptr_t)piod32->piod_offs; 1177147692Speter uio.uio_resid = piod32->piod_len; 1178147692Speter } else 1179147692Speter#endif 1180147692Speter { 1181147692Speter piod = addr; 1182147692Speter iov.iov_base = piod->piod_addr; 1183147692Speter iov.iov_len = piod->piod_len; 1184147692Speter uio.uio_offset = (off_t)(uintptr_t)piod->piod_offs; 1185147692Speter uio.uio_resid = piod->piod_len; 1186147692Speter } 118792395Sdes uio.uio_iov = &iov; 118892395Sdes uio.uio_iovcnt = 1; 118992395Sdes uio.uio_segflg = UIO_USERSPACE; 119092395Sdes uio.uio_td = td; 1191205014Snwhitehorn#ifdef COMPAT_FREEBSD32 1192147692Speter tmp = wrap32 ? piod32->piod_op : piod->piod_op; 1193147692Speter#else 1194147692Speter tmp = piod->piod_op; 1195147692Speter#endif 1196147692Speter switch (tmp) { 119792395Sdes case PIOD_READ_D: 119892395Sdes case PIOD_READ_I: 1199284343Sjhb CTR3(KTR_PTRACE, "PT_IO: pid %d: READ (%p, %#x)", 1200284343Sjhb p->p_pid, (uintptr_t)uio.uio_offset, uio.uio_resid); 120192395Sdes uio.uio_rw = UIO_READ; 120292395Sdes break; 120392395Sdes case PIOD_WRITE_D: 120492395Sdes case PIOD_WRITE_I: 1205284343Sjhb CTR3(KTR_PTRACE, "PT_IO: pid %d: WRITE (%p, %#x)", 1206284343Sjhb p->p_pid, (uintptr_t)uio.uio_offset, uio.uio_resid); 1207202882Skib td2->td_dbgflags |= TDB_USERWR; 120892395Sdes uio.uio_rw = UIO_WRITE; 120992395Sdes break; 121092395Sdes default: 1211155922Sjhb error = EINVAL; 1212155922Sjhb goto out; 121392395Sdes } 1214155922Sjhb PROC_UNLOCK(p); 121592395Sdes error = proc_rwmem(p, &uio); 1216205014Snwhitehorn#ifdef COMPAT_FREEBSD32 1217147692Speter if (wrap32) 1218147692Speter piod32->piod_len -= uio.uio_resid; 1219147692Speter else 1220147692Speter#endif 1221147692Speter piod->piod_len -= uio.uio_resid; 1222155922Sjhb PROC_LOCK(p); 1223155922Sjhb break; 122492395Sdes 12251945Sdg case PT_KILL: 1226284343Sjhb CTR1(KTR_PTRACE, "PT_KILL: pid %d", p->p_pid); 1227102946Siedowse data = SIGKILL; 122813607Speter goto sendsig; /* in PT_CONTINUE above */ 122913607Speter 123013607Speter case PT_SETREGS: 1231284343Sjhb CTR2(KTR_PTRACE, "PT_SETREGS: tid %d (pid %d)", td2->td_tid, 1232284343Sjhb p->p_pid); 1233202882Skib td2->td_dbgflags |= TDB_USERWR; 1234147692Speter error = PROC_WRITE(regs, td2, addr); 1235155922Sjhb break; 123684637Sdes 12371945Sdg case PT_GETREGS: 1238284343Sjhb CTR2(KTR_PTRACE, "PT_GETREGS: tid %d (pid %d)", td2->td_tid, 1239284343Sjhb p->p_pid); 1240147692Speter error = PROC_READ(regs, td2, addr); 1241155922Sjhb break; 124213607Speter 124313607Speter case PT_SETFPREGS: 1244284343Sjhb CTR2(KTR_PTRACE, "PT_SETFPREGS: tid %d (pid %d)", td2->td_tid, 1245284343Sjhb p->p_pid); 1246202882Skib td2->td_dbgflags |= TDB_USERWR; 1247147692Speter error = PROC_WRITE(fpregs, td2, addr); 1248155922Sjhb break; 124984637Sdes 125013607Speter case PT_GETFPREGS: 1251284343Sjhb CTR2(KTR_PTRACE, "PT_GETFPREGS: tid %d (pid %d)", td2->td_tid, 1252284343Sjhb p->p_pid); 1253147692Speter error = PROC_READ(fpregs, td2, addr); 1254155922Sjhb break; 125513607Speter 125648691Sjlemon case PT_SETDBREGS: 1257284343Sjhb CTR2(KTR_PTRACE, "PT_SETDBREGS: tid %d (pid %d)", td2->td_tid, 1258284343Sjhb p->p_pid); 1259202882Skib td2->td_dbgflags |= TDB_USERWR; 1260147692Speter error = PROC_WRITE(dbregs, td2, addr); 1261155922Sjhb break; 126292369Sdes 126348691Sjlemon case PT_GETDBREGS: 1264284343Sjhb CTR2(KTR_PTRACE, "PT_GETDBREGS: tid %d (pid %d)", td2->td_tid, 1265284343Sjhb p->p_pid); 1266147692Speter error = PROC_READ(dbregs, td2, addr); 1267155922Sjhb break; 126848691Sjlemon 1269132016Smarcel case PT_LWPINFO: 1270209688Skib if (data <= 0 || 1271209688Skib#ifdef COMPAT_FREEBSD32 1272209688Skib (!wrap32 && data > sizeof(*pl)) || 1273209688Skib (wrap32 && data > sizeof(*pl32))) { 1274209688Skib#else 1275209688Skib data > sizeof(*pl)) { 1276209688Skib#endif 1277155922Sjhb error = EINVAL; 1278155922Sjhb break; 1279155922Sjhb } 1280209688Skib#ifdef COMPAT_FREEBSD32 1281209688Skib if (wrap32) { 1282209688Skib pl = &plr; 1283209688Skib pl32 = addr; 1284209688Skib } else 1285209688Skib#endif 1286132016Smarcel pl = addr; 1287325643Skib bzero(pl, sizeof(*pl)); 1288153697Sdavidxu pl->pl_lwpid = td2->td_tid; 1289239135Skib pl->pl_event = PL_EVENT_NONE; 1290209688Skib pl->pl_flags = 0; 1291209688Skib if (td2->td_dbgflags & TDB_XSIG) { 1292132089Sdavidxu pl->pl_event = PL_EVENT_SIGNAL; 1293209688Skib if (td2->td_dbgksi.ksi_signo != 0 && 1294209688Skib#ifdef COMPAT_FREEBSD32 1295209688Skib ((!wrap32 && data >= offsetof(struct ptrace_lwpinfo, 1296209688Skib pl_siginfo) + sizeof(pl->pl_siginfo)) || 1297209688Skib (wrap32 && data >= offsetof(struct ptrace_lwpinfo32, 1298209688Skib pl_siginfo) + sizeof(struct siginfo32))) 1299209688Skib#else 1300209688Skib data >= offsetof(struct ptrace_lwpinfo, pl_siginfo) 1301209688Skib + sizeof(pl->pl_siginfo) 1302209688Skib#endif 1303209688Skib ){ 1304209688Skib pl->pl_flags |= PL_FLAG_SI; 1305209688Skib pl->pl_siginfo = td2->td_dbgksi.ksi_info; 1306209688Skib } 1307209688Skib } 1308208453Skib if (td2->td_dbgflags & TDB_SCE) 1309208453Skib pl->pl_flags |= PL_FLAG_SCE; 1310208453Skib else if (td2->td_dbgflags & TDB_SCX) 1311208453Skib pl->pl_flags |= PL_FLAG_SCX; 1312208453Skib if (td2->td_dbgflags & TDB_EXEC) 1313208453Skib pl->pl_flags |= PL_FLAG_EXEC; 1314217819Skib if (td2->td_dbgflags & TDB_FORK) { 1315217819Skib pl->pl_flags |= PL_FLAG_FORKED; 1316217819Skib pl->pl_child_pid = td2->td_dbg_forked; 1317304499Sjhb if (td2->td_dbgflags & TDB_VFORK) 1318304499Sjhb pl->pl_flags |= PL_FLAG_VFORKED; 1319304499Sjhb } else if ((td2->td_dbgflags & (TDB_SCX | TDB_VFORK)) == 1320304499Sjhb TDB_VFORK) 1321304499Sjhb pl->pl_flags |= PL_FLAG_VFORK_DONE; 1322231320Skib if (td2->td_dbgflags & TDB_CHILD) 1323231320Skib pl->pl_flags |= PL_FLAG_CHILD; 1324304017Sjhb if (td2->td_dbgflags & TDB_BORN) 1325304017Sjhb pl->pl_flags |= PL_FLAG_BORN; 1326304017Sjhb if (td2->td_dbgflags & TDB_EXIT) 1327304017Sjhb pl->pl_flags |= PL_FLAG_EXITED; 1328155381Sdavidxu pl->pl_sigmask = td2->td_sigmask; 1329155381Sdavidxu pl->pl_siglist = td2->td_siglist; 1330215679Sattilio strcpy(pl->pl_tdname, td2->td_name); 1331289780Sjhb if ((td2->td_dbgflags & (TDB_SCE | TDB_SCX)) != 0) { 1332289780Sjhb pl->pl_syscall_code = td2->td_dbg_sc_code; 1333289780Sjhb pl->pl_syscall_narg = td2->td_dbg_sc_narg; 1334289780Sjhb } else { 1335289780Sjhb pl->pl_syscall_code = 0; 1336289780Sjhb pl->pl_syscall_narg = 0; 1337289780Sjhb } 1338209688Skib#ifdef COMPAT_FREEBSD32 1339209688Skib if (wrap32) 1340209688Skib ptrace_lwpinfo_to32(pl, pl32); 1341209688Skib#endif 1342290456Sjhb CTR6(KTR_PTRACE, 1343290456Sjhb "PT_LWPINFO: tid %d (pid %d) event %d flags %#x child pid %d syscall %d", 1344284343Sjhb td2->td_tid, p->p_pid, pl->pl_event, pl->pl_flags, 1345290456Sjhb pl->pl_child_pid, pl->pl_syscall_code); 1346155922Sjhb break; 1347132016Smarcel 1348132089Sdavidxu case PT_GETNUMLWPS: 1349284343Sjhb CTR2(KTR_PTRACE, "PT_GETNUMLWPS: pid %d: %d threads", p->p_pid, 1350284343Sjhb p->p_numthreads); 1351132089Sdavidxu td->td_retval[0] = p->p_numthreads; 1352155922Sjhb break; 1353132089Sdavidxu 1354132089Sdavidxu case PT_GETLWPLIST: 1355284343Sjhb CTR3(KTR_PTRACE, "PT_GETLWPLIST: pid %d: data %d, actual %d", 1356284343Sjhb p->p_pid, data, p->p_numthreads); 1357132089Sdavidxu if (data <= 0) { 1358155922Sjhb error = EINVAL; 1359155922Sjhb break; 1360132089Sdavidxu } 1361132089Sdavidxu num = imin(p->p_numthreads, data); 1362132089Sdavidxu PROC_UNLOCK(p); 1363132089Sdavidxu buf = malloc(num * sizeof(lwpid_t), M_TEMP, M_WAITOK); 1364132089Sdavidxu tmp = 0; 1365132089Sdavidxu PROC_LOCK(p); 1366132089Sdavidxu FOREACH_THREAD_IN_PROC(p, td2) { 1367132089Sdavidxu if (tmp >= num) 1368132089Sdavidxu break; 1369132089Sdavidxu buf[tmp++] = td2->td_tid; 1370132089Sdavidxu } 1371132089Sdavidxu PROC_UNLOCK(p); 1372132089Sdavidxu error = copyout(buf, addr, tmp * sizeof(lwpid_t)); 1373132089Sdavidxu free(buf, M_TEMP); 1374132089Sdavidxu if (!error) 1375163345Strhodes td->td_retval[0] = tmp; 1376155922Sjhb PROC_LOCK(p); 1377155922Sjhb break; 1378132089Sdavidxu 1379203696Smarcel case PT_VM_TIMESTAMP: 1380284343Sjhb CTR2(KTR_PTRACE, "PT_VM_TIMESTAMP: pid %d: timestamp %d", 1381284343Sjhb p->p_pid, p->p_vmspace->vm_map.timestamp); 1382203696Smarcel td->td_retval[0] = p->p_vmspace->vm_map.timestamp; 1383203696Smarcel break; 1384203696Smarcel 1385203696Smarcel case PT_VM_ENTRY: 1386203783Smarcel PROC_UNLOCK(p); 1387205014Snwhitehorn#ifdef COMPAT_FREEBSD32 1388203783Smarcel if (wrap32) 1389203783Smarcel error = ptrace_vm_entry32(td, p, addr); 1390203783Smarcel else 1391203708Smarcel#endif 1392203696Smarcel error = ptrace_vm_entry(td, p, addr); 1393203696Smarcel PROC_LOCK(p); 1394203696Smarcel break; 1395203696Smarcel 13961945Sdg default: 1397118932Smarcel#ifdef __HAVE_PTRACE_MACHDEP 1398118932Smarcel if (req >= PT_FIRSTMACH) { 1399127034Sjhb PROC_UNLOCK(p); 1400118932Smarcel error = cpu_ptrace(td2, req, addr, data); 1401155922Sjhb PROC_LOCK(p); 1402155922Sjhb } else 1403118932Smarcel#endif 1404155922Sjhb /* Unknown request. */ 1405155922Sjhb error = EINVAL; 14061945Sdg break; 14071945Sdg } 14081945Sdg 1409155922Sjhbout: 1410155922Sjhb /* Drop our hold on this process now that the request has completed. */ 1411155922Sjhb _PRELE(p); 141294556Sjhbfail: 141394556Sjhb PROC_UNLOCK(p); 141494556Sjhb if (proctree_locked) 141594556Sjhb sx_xunlock(&proctree_lock); 141694556Sjhb return (error); 14171541Srgrimes} 1418147692Speter#undef PROC_READ 1419147692Speter#undef PROC_WRITE 14201541Srgrimes 142131564Ssef/* 142284637Sdes * Stop a process because of a debugging event; 142331564Ssef * stay stopped until p->p_step is cleared 142431564Ssef * (cleared by PIOCCONT in procfs). 142531564Ssef */ 142631564Ssefvoid 142784637Sdesstopevent(struct proc *p, unsigned int event, unsigned int val) 142871567Sjhb{ 142971567Sjhb 1430113635Sjhb PROC_LOCK_ASSERT(p, MA_OWNED); 143131564Ssef p->p_step = 1; 1432284343Sjhb CTR3(KTR_PTRACE, "stopevent: pid %d event %u val %u", p->p_pid, event, 1433284343Sjhb val); 143431564Ssef do { 143531564Ssef p->p_xstat = val; 1436132089Sdavidxu p->p_xthread = NULL; 143731564Ssef p->p_stype = event; /* Which event caused the stop? */ 143831564Ssef wakeup(&p->p_stype); /* Wake up any PIOCWAIT'ing procs */ 143971567Sjhb msleep(&p->p_step, &p->p_mtx, PWAIT, "stopevent", 0); 144031564Ssef } while (p->p_step); 144131564Ssef} 1442