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 * $FreeBSD: src/sys/kern/sys_process.c,v 1.51.2.6 2003/01/08 03:06:45 kan Exp $ 32 * $DragonFly: src/sys/kern/sys_process.c,v 1.30 2007/02/19 01:14:23 corecode Exp $ 33 */ 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/sysproto.h> 38 #include <sys/proc.h> 39 #include <sys/priv.h> 40 #include <sys/vnode.h> 41 #include <sys/ptrace.h> 42 #include <sys/reg.h> 43 #include <sys/lock.h> 44 45 #include <vm/vm.h> 46 #include <vm/pmap.h> 47 #include <vm/vm_map.h> 48 #include <vm/vm_page.h> 49 50 #include <sys/user.h> 51 #include <vfs/procfs/procfs.h> 52 53 #include <sys/thread2.h> 54 #include <sys/mplock2.h> 55 #include <sys/spinlock2.h> 56 57 /* use the equivalent procfs code */ 58 #if 0 59 static int 60 pread (struct proc *procp, unsigned int addr, unsigned int *retval) { 61 int rv; 62 vm_map_t map, tmap; 63 vm_object_t object; 64 vm_offset_t kva = 0; 65 int page_offset; /* offset into page */ 66 vm_offset_t pageno; /* page number */ 67 vm_map_entry_t out_entry; 68 vm_prot_t out_prot; 69 boolean_t wired; 70 vm_pindex_t pindex; 71 72 /* Map page into kernel space */ 73 74 map = &procp->p_vmspace->vm_map; 75 76 page_offset = addr - trunc_page(addr); 77 pageno = trunc_page(addr); 78 79 tmap = map; 80 rv = vm_map_lookup (&tmap, pageno, VM_PROT_READ, &out_entry, 81 &object, &pindex, &out_prot, &wired); 82 83 if (rv != KERN_SUCCESS) 84 return EINVAL; 85 86 vm_map_lookup_done (tmap, out_entry, 0); 87 88 /* Find space in kernel_map for the page we're interested in */ 89 rv = vm_map_find (&kernel_map, object, IDX_TO_OFF(pindex), 90 &kva, 91 PAGE_SIZE, PAGE_SIZE, 92 0, VM_MAPTYPE_NORMAL, 93 VM_PROT_ALL, VM_PROT_ALL, 94 0); 95 96 if (!rv) { 97 vm_object_reference (object); 98 99 rv = vm_map_wire (&kernel_map, kva, kva + PAGE_SIZE, 0); 100 if (!rv) { 101 *retval = 0; 102 bcopy ((caddr_t)kva + page_offset, 103 retval, sizeof *retval); 104 } 105 vm_map_remove (&kernel_map, kva, kva + PAGE_SIZE); 106 } 107 108 return rv; 109 } 110 111 static int 112 pwrite (struct proc *procp, unsigned int addr, unsigned int datum) { 113 int rv; 114 vm_map_t map, tmap; 115 vm_object_t object; 116 vm_offset_t kva = 0; 117 int page_offset; /* offset into page */ 118 vm_offset_t pageno; /* page number */ 119 vm_map_entry_t out_entry; 120 vm_prot_t out_prot; 121 boolean_t wired; 122 vm_pindex_t pindex; 123 boolean_t fix_prot = 0; 124 125 /* Map page into kernel space */ 126 127 map = &procp->p_vmspace->vm_map; 128 129 page_offset = addr - trunc_page(addr); 130 pageno = trunc_page(addr); 131 132 /* 133 * Check the permissions for the area we're interested in. 134 */ 135 136 if (vm_map_check_protection (map, pageno, pageno + PAGE_SIZE, 137 VM_PROT_WRITE, FALSE) == FALSE) { 138 /* 139 * If the page was not writable, we make it so. 140 * XXX It is possible a page may *not* be read/executable, 141 * if a process changes that! 142 */ 143 fix_prot = 1; 144 /* The page isn't writable, so let's try making it so... */ 145 if ((rv = vm_map_protect (map, pageno, pageno + PAGE_SIZE, 146 VM_PROT_ALL, 0)) != KERN_SUCCESS) 147 return EFAULT; /* I guess... */ 148 } 149 150 /* 151 * Now we need to get the page. out_entry, out_prot, wired, and 152 * single_use aren't used. One would think the vm code would be 153 * a *bit* nicer... We use tmap because vm_map_lookup() can 154 * change the map argument. 155 */ 156 157 tmap = map; 158 rv = vm_map_lookup (&tmap, pageno, VM_PROT_WRITE, &out_entry, 159 &object, &pindex, &out_prot, &wired); 160 if (rv != KERN_SUCCESS) { 161 return EINVAL; 162 } 163 164 /* 165 * Okay, we've got the page. Let's release tmap. 166 */ 167 168 vm_map_lookup_done (tmap, out_entry, 0); 169 170 /* 171 * Fault the page in... 172 */ 173 174 rv = vm_fault(map, pageno, VM_PROT_WRITE|VM_PROT_READ, FALSE); 175 if (rv != KERN_SUCCESS) 176 return EFAULT; 177 178 /* Find space in kernel_map for the page we're interested in */ 179 rv = vm_map_find (&kernel_map, object, IDX_TO_OFF(pindex), 180 &kva, 181 PAGE_SIZE, PAGE_SIZE, 182 0, VM_MAPTYPE_NORMAL, 183 VM_PROT_ALL, VM_PROT_ALL, 184 0); 185 if (!rv) { 186 vm_object_reference (object); 187 188 rv = vm_map_wire (&kernel_map, kva, kva + PAGE_SIZE, 0); 189 if (!rv) { 190 bcopy (&datum, (caddr_t)kva + page_offset, sizeof datum); 191 } 192 vm_map_remove (&kernel_map, kva, kva + PAGE_SIZE); 193 } 194 195 if (fix_prot) 196 vm_map_protect (map, pageno, pageno + PAGE_SIZE, 197 VM_PROT_READ|VM_PROT_EXECUTE, 0); 198 return rv; 199 } 200 #endif 201 202 /* 203 * Process debugging system call. 204 * 205 * MPALMOSTSAFE 206 */ 207 int 208 sys_ptrace(struct ptrace_args *uap) 209 { 210 struct proc *p = curproc; 211 212 /* 213 * XXX this obfuscation is to reduce stack usage, but the register 214 * structs may be too large to put on the stack anyway. 215 */ 216 union { 217 struct ptrace_io_desc piod; 218 struct dbreg dbreg; 219 struct fpreg fpreg; 220 struct reg reg; 221 } r; 222 void *addr; 223 int error = 0; 224 225 addr = &r; 226 switch (uap->req) { 227 case PT_GETREGS: 228 case PT_GETFPREGS: 229 #ifdef PT_GETDBREGS 230 case PT_GETDBREGS: 231 #endif 232 break; 233 case PT_SETREGS: 234 error = copyin(uap->addr, &r.reg, sizeof r.reg); 235 break; 236 case PT_SETFPREGS: 237 error = copyin(uap->addr, &r.fpreg, sizeof r.fpreg); 238 break; 239 #ifdef PT_SETDBREGS 240 case PT_SETDBREGS: 241 error = copyin(uap->addr, &r.dbreg, sizeof r.dbreg); 242 break; 243 #endif 244 case PT_IO: 245 error = copyin(uap->addr, &r.piod, sizeof r.piod); 246 break; 247 default: 248 addr = uap->addr; 249 } 250 if (error) 251 return (error); 252 253 get_mplock(); 254 error = kern_ptrace(p, uap->req, uap->pid, addr, uap->data, 255 &uap->sysmsg_result); 256 rel_mplock(); 257 if (error) 258 return (error); 259 260 switch (uap->req) { 261 case PT_IO: 262 (void)copyout(&r.piod, uap->addr, sizeof r.piod); 263 break; 264 case PT_GETREGS: 265 error = copyout(&r.reg, uap->addr, sizeof r.reg); 266 break; 267 case PT_GETFPREGS: 268 error = copyout(&r.fpreg, uap->addr, sizeof r.fpreg); 269 break; 270 #ifdef PT_GETDBREGS 271 case PT_GETDBREGS: 272 error = copyout(&r.dbreg, uap->addr, sizeof r.dbreg); 273 break; 274 #endif 275 } 276 277 return (error); 278 } 279 280 int 281 kern_ptrace(struct proc *curp, int req, pid_t pid, void *addr, int data, int *res) 282 { 283 struct proc *p, *pp; 284 struct lwp *lp; 285 struct iovec iov; 286 struct uio uio; 287 struct ptrace_io_desc *piod; 288 int error = 0; 289 int write, tmp; 290 291 write = 0; 292 if (req == PT_TRACE_ME) { 293 p = curp; 294 } else { 295 if ((p = pfind(pid)) == NULL) 296 return ESRCH; 297 } 298 if (!PRISON_CHECK(curp->p_ucred, p->p_ucred)) 299 return (ESRCH); 300 301 /* Can't trace a process that's currently exec'ing. */ 302 if ((p->p_flag & P_INEXEC) != 0) 303 return EAGAIN; 304 305 /* 306 * Permissions check 307 */ 308 switch (req) { 309 case PT_TRACE_ME: 310 /* Always legal. */ 311 break; 312 313 case PT_ATTACH: 314 /* Self */ 315 if (p->p_pid == curp->p_pid) 316 return EINVAL; 317 318 /* Already traced */ 319 if (p->p_flag & P_TRACED) 320 return EBUSY; 321 322 if (curp->p_flag & P_TRACED) 323 for (pp = curp->p_pptr; pp != NULL; pp = pp->p_pptr) 324 if (pp == p) 325 return (EINVAL); 326 327 /* not owned by you, has done setuid (unless you're root) */ 328 if ((p->p_ucred->cr_ruid != curp->p_ucred->cr_ruid) || 329 (p->p_flag & P_SUGID)) { 330 if ((error = priv_check_cred(curp->p_ucred, PRIV_ROOT, 0)) != 0) 331 return error; 332 } 333 334 /* can't trace init when securelevel > 0 */ 335 if (securelevel > 0 && p->p_pid == 1) 336 return EPERM; 337 338 /* OK */ 339 break; 340 341 case PT_READ_I: 342 case PT_READ_D: 343 case PT_WRITE_I: 344 case PT_WRITE_D: 345 case PT_IO: 346 case PT_CONTINUE: 347 case PT_KILL: 348 case PT_STEP: 349 case PT_DETACH: 350 #ifdef PT_GETREGS 351 case PT_GETREGS: 352 #endif 353 #ifdef PT_SETREGS 354 case PT_SETREGS: 355 #endif 356 #ifdef PT_GETFPREGS 357 case PT_GETFPREGS: 358 #endif 359 #ifdef PT_SETFPREGS 360 case PT_SETFPREGS: 361 #endif 362 #ifdef PT_GETDBREGS 363 case PT_GETDBREGS: 364 #endif 365 #ifdef PT_SETDBREGS 366 case PT_SETDBREGS: 367 #endif 368 /* not being traced... */ 369 if ((p->p_flag & P_TRACED) == 0) 370 return EPERM; 371 372 /* not being traced by YOU */ 373 if (p->p_pptr != curp) 374 return EBUSY; 375 376 /* not currently stopped */ 377 if (p->p_stat != SSTOP || 378 (p->p_flag & P_WAITED) == 0) { 379 return EBUSY; 380 } 381 382 /* OK */ 383 break; 384 385 default: 386 return EINVAL; 387 } 388 389 /* XXX lwp */ 390 lp = FIRST_LWP_IN_PROC(p); 391 #ifdef FIX_SSTEP 392 /* 393 * Single step fixup ala procfs 394 */ 395 FIX_SSTEP(lp); 396 #endif 397 398 /* 399 * Actually do the requests 400 */ 401 402 *res = 0; 403 404 switch (req) { 405 case PT_TRACE_ME: 406 /* set my trace flag and "owner" so it can read/write me */ 407 p->p_flag |= P_TRACED; 408 p->p_oppid = p->p_pptr->p_pid; 409 return 0; 410 411 case PT_ATTACH: 412 /* security check done above */ 413 p->p_flag |= P_TRACED; 414 p->p_oppid = p->p_pptr->p_pid; 415 if (p->p_pptr != curp) 416 proc_reparent(p, curp); 417 data = SIGSTOP; 418 goto sendsig; /* in PT_CONTINUE below */ 419 420 case PT_STEP: 421 case PT_CONTINUE: 422 case PT_DETACH: 423 /* Zero means do not send any signal */ 424 if (data < 0 || data > _SIG_MAXSIG) 425 return EINVAL; 426 427 LWPHOLD(lp); 428 429 if (req == PT_STEP) { 430 if ((error = ptrace_single_step (lp))) { 431 LWPRELE(lp); 432 return error; 433 } 434 } 435 436 if (addr != (void *)1) { 437 if ((error = ptrace_set_pc (lp, 438 (u_long)(uintfptr_t)addr))) { 439 LWPRELE(lp); 440 return error; 441 } 442 } 443 LWPRELE(lp); 444 445 if (req == PT_DETACH) { 446 /* reset process parent */ 447 if (p->p_oppid != p->p_pptr->p_pid) { 448 struct proc *pp; 449 450 pp = pfind(p->p_oppid); 451 proc_reparent(p, pp ? pp : initproc); 452 } 453 454 p->p_flag &= ~(P_TRACED | P_WAITED); 455 p->p_oppid = 0; 456 457 /* should we send SIGCHLD? */ 458 } 459 460 sendsig: 461 /* 462 * Deliver or queue signal. If the process is stopped 463 * force it to be SACTIVE again. 464 */ 465 crit_enter(); 466 if (p->p_stat == SSTOP) { 467 p->p_xstat = data; 468 lp->lwp_flag |= LWP_BREAKTSLEEP; 469 proc_unstop(p); 470 } else if (data) { 471 ksignal(p, data); 472 } 473 crit_exit(); 474 return 0; 475 476 case PT_WRITE_I: 477 case PT_WRITE_D: 478 write = 1; 479 /* fallthrough */ 480 case PT_READ_I: 481 case PT_READ_D: 482 /* 483 * NOTE! uio_offset represents the offset in the target 484 * process. The iov is in the current process (the guy 485 * making the ptrace call) so uio_td must be the current 486 * process (though for a SYSSPACE transfer it doesn't 487 * really matter). 488 */ 489 tmp = 0; 490 /* write = 0 set above */ 491 iov.iov_base = write ? (caddr_t)&data : (caddr_t)&tmp; 492 iov.iov_len = sizeof(int); 493 uio.uio_iov = &iov; 494 uio.uio_iovcnt = 1; 495 uio.uio_offset = (off_t)(uintptr_t)addr; 496 uio.uio_resid = sizeof(int); 497 uio.uio_segflg = UIO_SYSSPACE; 498 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 499 uio.uio_td = curthread; 500 error = procfs_domem(curp, lp, NULL, &uio); 501 if (uio.uio_resid != 0) { 502 /* 503 * XXX procfs_domem() doesn't currently return ENOSPC, 504 * so I think write() can bogusly return 0. 505 * XXX what happens for short writes? We don't want 506 * to write partial data. 507 * XXX procfs_domem() returns EPERM for other invalid 508 * addresses. Convert this to EINVAL. Does this 509 * clobber returns of EPERM for other reasons? 510 */ 511 if (error == 0 || error == ENOSPC || error == EPERM) 512 error = EINVAL; /* EOF */ 513 } 514 if (!write) 515 *res = tmp; 516 return (error); 517 518 case PT_IO: 519 /* 520 * NOTE! uio_offset represents the offset in the target 521 * process. The iov is in the current process (the guy 522 * making the ptrace call) so uio_td must be the current 523 * process. 524 */ 525 piod = addr; 526 iov.iov_base = piod->piod_addr; 527 iov.iov_len = piod->piod_len; 528 uio.uio_iov = &iov; 529 uio.uio_iovcnt = 1; 530 uio.uio_offset = (off_t)(uintptr_t)piod->piod_offs; 531 uio.uio_resid = piod->piod_len; 532 uio.uio_segflg = UIO_USERSPACE; 533 uio.uio_td = curthread; 534 switch (piod->piod_op) { 535 case PIOD_READ_D: 536 case PIOD_READ_I: 537 uio.uio_rw = UIO_READ; 538 break; 539 case PIOD_WRITE_D: 540 case PIOD_WRITE_I: 541 uio.uio_rw = UIO_WRITE; 542 break; 543 default: 544 return (EINVAL); 545 } 546 error = procfs_domem(curp, lp, NULL, &uio); 547 piod->piod_len -= uio.uio_resid; 548 return (error); 549 550 case PT_KILL: 551 data = SIGKILL; 552 goto sendsig; /* in PT_CONTINUE above */ 553 554 #ifdef PT_SETREGS 555 case PT_SETREGS: 556 write = 1; 557 /* fallthrough */ 558 #endif /* PT_SETREGS */ 559 #ifdef PT_GETREGS 560 case PT_GETREGS: 561 /* write = 0 above */ 562 #endif /* PT_SETREGS */ 563 #if defined(PT_SETREGS) || defined(PT_GETREGS) 564 if (!procfs_validregs(lp)) /* no P_SYSTEM procs please */ 565 return EINVAL; 566 else { 567 iov.iov_base = addr; 568 iov.iov_len = sizeof(struct reg); 569 uio.uio_iov = &iov; 570 uio.uio_iovcnt = 1; 571 uio.uio_offset = 0; 572 uio.uio_resid = sizeof(struct reg); 573 uio.uio_segflg = UIO_SYSSPACE; 574 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 575 uio.uio_td = curthread; 576 return (procfs_doregs(curp, lp, NULL, &uio)); 577 } 578 #endif /* defined(PT_SETREGS) || defined(PT_GETREGS) */ 579 580 #ifdef PT_SETFPREGS 581 case PT_SETFPREGS: 582 write = 1; 583 /* fallthrough */ 584 #endif /* PT_SETFPREGS */ 585 #ifdef PT_GETFPREGS 586 case PT_GETFPREGS: 587 /* write = 0 above */ 588 #endif /* PT_SETFPREGS */ 589 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 590 if (!procfs_validfpregs(lp)) /* no P_SYSTEM procs please */ 591 return EINVAL; 592 else { 593 iov.iov_base = addr; 594 iov.iov_len = sizeof(struct fpreg); 595 uio.uio_iov = &iov; 596 uio.uio_iovcnt = 1; 597 uio.uio_offset = 0; 598 uio.uio_resid = sizeof(struct fpreg); 599 uio.uio_segflg = UIO_SYSSPACE; 600 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 601 uio.uio_td = curthread; 602 return (procfs_dofpregs(curp, lp, NULL, &uio)); 603 } 604 #endif /* defined(PT_SETFPREGS) || defined(PT_GETFPREGS) */ 605 606 #ifdef PT_SETDBREGS 607 case PT_SETDBREGS: 608 write = 1; 609 /* fallthrough */ 610 #endif /* PT_SETDBREGS */ 611 #ifdef PT_GETDBREGS 612 case PT_GETDBREGS: 613 /* write = 0 above */ 614 #endif /* PT_SETDBREGS */ 615 #if defined(PT_SETDBREGS) || defined(PT_GETDBREGS) 616 if (!procfs_validdbregs(lp)) /* no P_SYSTEM procs please */ 617 return EINVAL; 618 else { 619 iov.iov_base = addr; 620 iov.iov_len = sizeof(struct dbreg); 621 uio.uio_iov = &iov; 622 uio.uio_iovcnt = 1; 623 uio.uio_offset = 0; 624 uio.uio_resid = sizeof(struct dbreg); 625 uio.uio_segflg = UIO_SYSSPACE; 626 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 627 uio.uio_td = curthread; 628 return (procfs_dodbregs(curp, lp, NULL, &uio)); 629 } 630 #endif /* defined(PT_SETDBREGS) || defined(PT_GETDBREGS) */ 631 632 default: 633 break; 634 } 635 636 return 0; 637 } 638 639 int 640 trace_req(struct proc *p) 641 { 642 return 1; 643 } 644 645 /* 646 * stopevent() 647 * 648 * Stop a process because of a procfs event. Stay stopped until p->p_step 649 * is cleared (cleared by PIOCCONT in procfs). 650 * 651 * MPSAFE 652 */ 653 void 654 stopevent(struct proc *p, unsigned int event, unsigned int val) 655 { 656 /* 657 * Set event info. Recheck p_stops in case we are 658 * racing a close() on procfs. 659 */ 660 spin_lock_wr(&p->p_spin); 661 if ((p->p_stops & event) == 0) { 662 spin_unlock_wr(&p->p_spin); 663 return; 664 } 665 p->p_xstat = val; 666 p->p_stype = event; 667 p->p_step = 1; 668 tsleep_interlock(&p->p_step, 0); 669 spin_unlock_wr(&p->p_spin); 670 671 /* 672 * Wakeup any PIOCWAITing procs and wait for p_step to 673 * be cleared. 674 */ 675 for (;;) { 676 wakeup(&p->p_stype); 677 tsleep(&p->p_step, PINTERLOCKED, "stopevent", 0); 678 spin_lock_wr(&p->p_spin); 679 if (p->p_step == 0) { 680 spin_unlock_wr(&p->p_spin); 681 break; 682 } 683 tsleep_interlock(&p->p_step, 0); 684 spin_unlock_wr(&p->p_spin); 685 } 686 } 687 688