1 /* $NetBSD: sys_process.c,v 1.84 2003/08/07 16:31:55 agc Exp $ */ 2 3 /*- 4 * Copyright (c) 1982, 1986, 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * (c) UNIX System Laboratories, Inc. 7 * All or some portions of this file are derived from material licensed 8 * to the University of California by American Telephone and Telegraph 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 10 * the permission of UNIX System Laboratories, Inc. 11 * 12 * This code is derived from software contributed to Berkeley by 13 * Jan-Simon Pendry. 14 * 15 * Redistribution and use in source and binary forms, with or without 16 * modification, are permitted provided that the following conditions 17 * are met: 18 * 1. Redistributions of source code must retain the above copyright 19 * notice, this list of conditions and the following disclaimer. 20 * 2. Redistributions in binary form must reproduce the above copyright 21 * notice, this list of conditions and the following disclaimer in the 22 * documentation and/or other materials provided with the distribution. 23 * 3. Neither the name of the University nor the names of its contributors 24 * may be used to endorse or promote products derived from this software 25 * without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 28 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 31 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 33 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 34 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 35 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 36 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 37 * SUCH DAMAGE. 38 * 39 * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 40 */ 41 42 /*- 43 * Copyright (c) 1993 Jan-Simon Pendry. 44 * Copyright (c) 1994 Christopher G. Demetriou. All rights reserved. 45 * 46 * This code is derived from software contributed to Berkeley by 47 * Jan-Simon Pendry. 48 * 49 * Redistribution and use in source and binary forms, with or without 50 * modification, are permitted provided that the following conditions 51 * are met: 52 * 1. Redistributions of source code must retain the above copyright 53 * notice, this list of conditions and the following disclaimer. 54 * 2. Redistributions in binary form must reproduce the above copyright 55 * notice, this list of conditions and the following disclaimer in the 56 * documentation and/or other materials provided with the distribution. 57 * 3. All advertising materials mentioning features or use of this software 58 * must display the following acknowledgement: 59 * This product includes software developed by the University of 60 * California, Berkeley and its contributors. 61 * 4. Neither the name of the University nor the names of its contributors 62 * may be used to endorse or promote products derived from this software 63 * without specific prior written permission. 64 * 65 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 66 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 67 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 68 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 69 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 70 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 71 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 72 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 73 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 74 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 75 * SUCH DAMAGE. 76 * 77 * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 78 */ 79 80 /* 81 * References: 82 * (1) Bach's "The Design of the UNIX Operating System", 83 * (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution, 84 * (3) the "4.4BSD Programmer's Reference Manual" published 85 * by USENIX and O'Reilly & Associates. 86 * The 4.4BSD PRM does a reasonably good job of documenting what the various 87 * ptrace() requests should actually do, and its text is quoted several times 88 * in this file. 89 */ 90 91 #include <sys/cdefs.h> 92 __KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.84 2003/08/07 16:31:55 agc Exp $"); 93 94 #include <sys/param.h> 95 #include <sys/systm.h> 96 #include <sys/proc.h> 97 #include <sys/errno.h> 98 #include <sys/ptrace.h> 99 #include <sys/uio.h> 100 #include <sys/user.h> 101 #include <sys/ras.h> 102 103 #include <sys/mount.h> 104 #include <sys/sa.h> 105 #include <sys/syscallargs.h> 106 107 #include <uvm/uvm_extern.h> 108 109 #include <machine/reg.h> 110 111 /* Macros to clear/set/test flags. */ 112 #define SET(t, f) (t) |= (f) 113 #define CLR(t, f) (t) &= ~(f) 114 #define ISSET(t, f) ((t) & (f)) 115 116 /* 117 * Process debugging system call. 118 */ 119 int 120 sys_ptrace(l, v, retval) 121 struct lwp *l; 122 void *v; 123 register_t *retval; 124 { 125 struct sys_ptrace_args /* { 126 syscallarg(int) req; 127 syscallarg(pid_t) pid; 128 syscallarg(caddr_t) addr; 129 syscallarg(int) data; 130 } */ *uap = v; 131 struct proc *p = l->l_proc; 132 struct lwp *lt, *lr; 133 struct proc *t; /* target process */ 134 struct uio uio; 135 struct iovec iov; 136 struct ptrace_io_desc piod; 137 struct ptrace_lwpinfo pl; 138 int s, error, write, tmp, size; 139 140 /* "A foolish consistency..." XXX */ 141 if (SCARG(uap, req) == PT_TRACE_ME) 142 t = p; 143 else { 144 145 /* Find the process we're supposed to be operating on. */ 146 if ((t = pfind(SCARG(uap, pid))) == NULL) 147 return (ESRCH); 148 } 149 150 /* Can't trace a process that's currently exec'ing. */ 151 if ((t->p_flag & P_INEXEC) != 0) 152 return EAGAIN; 153 154 /* Make sure we can operate on it. */ 155 switch (SCARG(uap, req)) { 156 case PT_TRACE_ME: 157 /* Saying that you're being traced is always legal. */ 158 break; 159 160 case PT_ATTACH: 161 case PT_DUMPCORE: 162 /* 163 * You can't attach to a process if: 164 * (1) it's the process that's doing the attaching, 165 */ 166 if (t->p_pid == p->p_pid) 167 return (EINVAL); 168 169 /* 170 * (2) it's a system process 171 */ 172 if (t->p_flag & P_SYSTEM) 173 return (EPERM); 174 175 /* 176 * (3) it's already being traced, or 177 */ 178 if (ISSET(t->p_flag, P_TRACED)) 179 return (EBUSY); 180 181 /* 182 * (4) it's not owned by you, or is set-id on exec 183 * (unless you're root), or... 184 */ 185 if ((t->p_cred->p_ruid != p->p_cred->p_ruid || 186 ISSET(t->p_flag, P_SUGID)) && 187 (error = suser(p->p_ucred, &p->p_acflag)) != 0) 188 return (error); 189 190 /* 191 * (5) ...it's init, which controls the security level 192 * of the entire system, and the system was not 193 * compiled with permanently insecure mode turned on 194 */ 195 if (t == initproc && securelevel > -1) 196 return (EPERM); 197 198 /* 199 * (6) the tracer is chrooted, and its root directory is 200 * not at or above the root directory of the tracee 201 */ 202 203 if (!proc_isunder(t, p)) 204 return EPERM; 205 break; 206 207 case PT_READ_I: 208 case PT_READ_D: 209 case PT_WRITE_I: 210 case PT_WRITE_D: 211 case PT_CONTINUE: 212 case PT_IO: 213 case PT_KILL: 214 case PT_DETACH: 215 case PT_LWPINFO: 216 #ifdef PT_STEP 217 case PT_STEP: 218 #endif 219 #ifdef PT_GETREGS 220 case PT_GETREGS: 221 #endif 222 #ifdef PT_SETREGS 223 case PT_SETREGS: 224 #endif 225 #ifdef PT_GETFPREGS 226 case PT_GETFPREGS: 227 #endif 228 #ifdef PT_SETFPREGS 229 case PT_SETFPREGS: 230 #endif 231 232 #ifdef __HAVE_PTRACE_MACHDEP 233 PTRACE_MACHDEP_REQUEST_CASES 234 #endif 235 236 /* 237 * You can't do what you want to the process if: 238 * (1) It's not being traced at all, 239 */ 240 if (!ISSET(t->p_flag, P_TRACED)) 241 return (EPERM); 242 243 /* 244 * (2) it's being traced by procfs (which has 245 * different signal delivery semantics), 246 */ 247 if (ISSET(t->p_flag, P_FSTRACE)) 248 return (EBUSY); 249 250 /* 251 * (3) it's not being traced by _you_, or 252 */ 253 if (t->p_pptr != p) 254 return (EBUSY); 255 256 /* 257 * (4) it's not currently stopped. 258 */ 259 if (t->p_stat != SSTOP || !ISSET(t->p_flag, P_WAITED)) 260 return (EBUSY); 261 break; 262 263 default: /* It was not a legal request. */ 264 return (EINVAL); 265 } 266 267 /* Do single-step fixup if needed. */ 268 FIX_SSTEP(t); 269 270 /* 271 * XXX NJWLWP 272 * 273 * The entire ptrace interface needs work to be useful to a 274 * process with multiple LWPs. For the moment, we'll kluge 275 * this; memory access will be fine, but register access will 276 * be weird. 277 */ 278 279 lt = proc_representative_lwp(t); 280 281 /* Now do the operation. */ 282 write = 0; 283 *retval = 0; 284 tmp = 0; 285 286 switch (SCARG(uap, req)) { 287 case PT_TRACE_ME: 288 /* Just set the trace flag. */ 289 SET(t->p_flag, P_TRACED); 290 t->p_opptr = t->p_pptr; 291 return (0); 292 293 case PT_WRITE_I: /* XXX no separate I and D spaces */ 294 case PT_WRITE_D: 295 #if defined(__HAVE_RAS) 296 /* 297 * Can't write to a RAS 298 */ 299 if ((t->p_nras != 0) && 300 (ras_lookup(t, SCARG(uap, addr)) != (caddr_t)-1)) { 301 return (EACCES); 302 } 303 #endif 304 write = 1; 305 tmp = SCARG(uap, data); 306 case PT_READ_I: /* XXX no separate I and D spaces */ 307 case PT_READ_D: 308 /* write = 0 done above. */ 309 iov.iov_base = (caddr_t)&tmp; 310 iov.iov_len = sizeof(tmp); 311 uio.uio_iov = &iov; 312 uio.uio_iovcnt = 1; 313 uio.uio_offset = (off_t)(long)SCARG(uap, addr); 314 uio.uio_resid = sizeof(tmp); 315 uio.uio_segflg = UIO_SYSSPACE; 316 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 317 uio.uio_procp = p; 318 error = process_domem(p, t, &uio); 319 if (!write) 320 *retval = tmp; 321 return (error); 322 323 case PT_IO: 324 error = copyin(SCARG(uap, addr), &piod, sizeof(piod)); 325 if (error) 326 return (error); 327 iov.iov_base = piod.piod_addr; 328 iov.iov_len = piod.piod_len; 329 uio.uio_iov = &iov; 330 uio.uio_iovcnt = 1; 331 uio.uio_offset = (off_t)(long)piod.piod_offs; 332 uio.uio_resid = piod.piod_len; 333 uio.uio_segflg = UIO_USERSPACE; 334 uio.uio_procp = p; 335 switch (piod.piod_op) { 336 case PIOD_READ_D: 337 case PIOD_READ_I: 338 uio.uio_rw = UIO_READ; 339 break; 340 case PIOD_WRITE_D: 341 case PIOD_WRITE_I: 342 uio.uio_rw = UIO_WRITE; 343 break; 344 default: 345 return (EINVAL); 346 } 347 error = process_domem(p, t, &uio); 348 piod.piod_len -= uio.uio_resid; 349 (void) copyout(&piod, SCARG(uap, addr), sizeof(piod)); 350 return (error); 351 352 case PT_DUMPCORE: 353 return coredump(lt); 354 355 #ifdef PT_STEP 356 case PT_STEP: 357 /* 358 * From the 4.4BSD PRM: 359 * "Execution continues as in request PT_CONTINUE; however 360 * as soon as possible after execution of at least one 361 * instruction, execution stops again. [ ... ]" 362 */ 363 #endif 364 case PT_CONTINUE: 365 case PT_DETACH: 366 /* 367 * From the 4.4BSD PRM: 368 * "The data argument is taken as a signal number and the 369 * child's execution continues at location addr as if it 370 * incurred that signal. Normally the signal number will 371 * be either 0 to indicate that the signal that caused the 372 * stop should be ignored, or that value fetched out of 373 * the process's image indicating which signal caused 374 * the stop. If addr is (int *)1 then execution continues 375 * from where it stopped." 376 */ 377 378 /* Check that the data is a valid signal number or zero. */ 379 if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG) 380 return (EINVAL); 381 382 PHOLD(lt); 383 384 /* If the address parameter is not (int *)1, set the pc. */ 385 if ((int *)SCARG(uap, addr) != (int *)1) 386 if ((error = process_set_pc(lt, SCARG(uap, addr))) != 0) 387 goto relebad; 388 389 #ifdef PT_STEP 390 /* 391 * Arrange for a single-step, if that's requested and possible. 392 */ 393 error = process_sstep(lt, SCARG(uap, req) == PT_STEP); 394 if (error) 395 goto relebad; 396 #endif 397 398 PRELE(lt); 399 400 if (SCARG(uap, req) == PT_DETACH) { 401 /* give process back to original parent or init */ 402 if (t->p_opptr != t->p_pptr) { 403 struct proc *pp = t->p_opptr; 404 proc_reparent(t, pp ? pp : initproc); 405 } 406 407 /* not being traced any more */ 408 t->p_opptr = NULL; 409 CLR(t->p_flag, P_TRACED|P_WAITED); 410 } 411 412 sendsig: 413 /* Finally, deliver the requested signal (or none). */ 414 if (t->p_stat == SSTOP) { 415 t->p_xstat = SCARG(uap, data); 416 SCHED_LOCK(s); 417 lr = proc_unstop(t); 418 /* 419 * If the target needs to take a signal, there 420 * is no running LWP that will see it, and 421 * there is a LWP sleeping interruptably, then 422 * get it moving. 423 */ 424 if (lr && (t->p_xstat != 0)) 425 setrunnable(lr); 426 SCHED_UNLOCK(s); 427 } else { 428 if (SCARG(uap, data) != 0) 429 psignal(t, SCARG(uap, data)); 430 } 431 return (0); 432 433 relebad: 434 PRELE(lt); 435 return (error); 436 437 case PT_KILL: 438 /* just send the process a KILL signal. */ 439 SCARG(uap, data) = SIGKILL; 440 goto sendsig; /* in PT_CONTINUE, above. */ 441 442 case PT_ATTACH: 443 /* 444 * Go ahead and set the trace flag. 445 * Save the old parent (it's reset in 446 * _DETACH, and also in kern_exit.c:wait4() 447 * Reparent the process so that the tracing 448 * proc gets to see all the action. 449 * Stop the target. 450 */ 451 SET(t->p_flag, P_TRACED); 452 t->p_opptr = t->p_pptr; 453 if (t->p_pptr != p) { 454 t->p_pptr->p_flag |= P_CHTRACED; 455 proc_reparent(t, p); 456 } 457 SCARG(uap, data) = SIGSTOP; 458 goto sendsig; 459 460 case PT_LWPINFO: 461 size = SCARG(uap, data); 462 if (size < sizeof(lwpid_t)) 463 return (EINVAL); 464 error = copyin(SCARG(uap, addr), &pl, sizeof(lwpid_t)); 465 if (error) 466 return (error); 467 tmp = pl.pl_lwpid; 468 if (tmp == 0) 469 lt = LIST_FIRST(&t->p_lwps); 470 else { 471 LIST_FOREACH(lt, &t->p_lwps, l_sibling) 472 if (lt->l_lid == tmp) 473 break; 474 if (lt == NULL) 475 return (ESRCH); 476 lt = LIST_NEXT(lt, l_sibling); 477 } 478 pl.pl_lwpid = 0; 479 pl.pl_event = 0; 480 if (lt) { 481 pl.pl_lwpid = lt->l_lid; 482 if (lt->l_lid == t->p_sigctx.ps_lwp) 483 pl.pl_event = PL_EVENT_SIGNAL; 484 } 485 486 error = copyout(&pl, SCARG(uap, addr), SCARG(uap, data)); 487 488 return (0); 489 490 #ifdef PT_SETREGS 491 case PT_SETREGS: 492 write = 1; 493 #endif 494 #ifdef PT_GETREGS 495 case PT_GETREGS: 496 /* write = 0 done above. */ 497 #endif 498 #if defined(PT_SETREGS) || defined(PT_GETREGS) 499 tmp = SCARG(uap, data); 500 if (tmp != 0 && t->p_nlwps > 1) { 501 LIST_FOREACH(lt, &t->p_lwps, l_sibling) 502 if (lt->l_lid == tmp) 503 break; 504 if (lt == NULL) 505 return (ESRCH); 506 } 507 if (!process_validregs(t)) 508 return (EINVAL); 509 else { 510 iov.iov_base = SCARG(uap, addr); 511 iov.iov_len = sizeof(struct reg); 512 uio.uio_iov = &iov; 513 uio.uio_iovcnt = 1; 514 uio.uio_offset = 0; 515 uio.uio_resid = sizeof(struct reg); 516 uio.uio_segflg = UIO_USERSPACE; 517 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 518 uio.uio_procp = p; 519 return (process_doregs(p, lt, &uio)); 520 } 521 #endif 522 523 #ifdef PT_SETFPREGS 524 case PT_SETFPREGS: 525 write = 1; 526 #endif 527 #ifdef PT_GETFPREGS 528 case PT_GETFPREGS: 529 /* write = 0 done above. */ 530 #endif 531 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 532 tmp = SCARG(uap, data); 533 if (tmp != 0 && t->p_nlwps > 1) { 534 LIST_FOREACH(lt, &t->p_lwps, l_sibling) 535 if (lt->l_lid == tmp) 536 break; 537 if (lt == NULL) 538 return (ESRCH); 539 } 540 if (!process_validfpregs(t)) 541 return (EINVAL); 542 else { 543 iov.iov_base = SCARG(uap, addr); 544 iov.iov_len = sizeof(struct fpreg); 545 uio.uio_iov = &iov; 546 uio.uio_iovcnt = 1; 547 uio.uio_offset = 0; 548 uio.uio_resid = sizeof(struct fpreg); 549 uio.uio_segflg = UIO_USERSPACE; 550 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 551 uio.uio_procp = p; 552 return (process_dofpregs(p, lt, &uio)); 553 } 554 #endif 555 556 #ifdef __HAVE_PTRACE_MACHDEP 557 PTRACE_MACHDEP_REQUEST_CASES 558 return (ptrace_machdep_dorequest(p, lt, 559 SCARG(uap, req), SCARG(uap, addr), 560 SCARG(uap, data))); 561 #endif 562 } 563 564 #ifdef DIAGNOSTIC 565 panic("ptrace: impossible"); 566 #endif 567 return 0; 568 } 569 570 int 571 process_doregs(curp, l, uio) 572 struct proc *curp; /* tracer */ 573 struct lwp *l; /* traced */ 574 struct uio *uio; 575 { 576 #if defined(PT_GETREGS) || defined(PT_SETREGS) 577 int error; 578 struct reg r; 579 char *kv; 580 int kl; 581 582 if ((error = process_checkioperm(curp, l->l_proc)) != 0) 583 return error; 584 585 kl = sizeof(r); 586 kv = (char *) &r; 587 588 kv += uio->uio_offset; 589 kl -= uio->uio_offset; 590 if (kl < 0) 591 return (EINVAL); 592 if ((size_t) kl > uio->uio_resid) 593 kl = uio->uio_resid; 594 595 PHOLD(l); 596 597 error = process_read_regs(l, &r); 598 if (error == 0) 599 error = uiomove(kv, kl, uio); 600 if (error == 0 && uio->uio_rw == UIO_WRITE) { 601 if (l->l_stat != LSSTOP) 602 error = EBUSY; 603 else 604 error = process_write_regs(l, &r); 605 } 606 607 PRELE(l); 608 609 uio->uio_offset = 0; 610 return (error); 611 #else 612 return (EINVAL); 613 #endif 614 } 615 616 int 617 process_validregs(p) 618 struct proc *p; 619 { 620 621 #if defined(PT_SETREGS) || defined(PT_GETREGS) 622 return ((p->p_flag & P_SYSTEM) == 0); 623 #else 624 return (0); 625 #endif 626 } 627 628 int 629 process_dofpregs(curp, l, uio) 630 struct proc *curp; /* tracer */ 631 struct lwp *l; /* traced */ 632 struct uio *uio; 633 { 634 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) 635 int error; 636 struct fpreg r; 637 char *kv; 638 int kl; 639 640 if ((error = process_checkioperm(curp, l->l_proc)) != 0) 641 return (error); 642 643 kl = sizeof(r); 644 kv = (char *) &r; 645 646 kv += uio->uio_offset; 647 kl -= uio->uio_offset; 648 if (kl < 0) 649 return (EINVAL); 650 if ((size_t) kl > uio->uio_resid) 651 kl = uio->uio_resid; 652 653 PHOLD(l); 654 655 error = process_read_fpregs(l, &r); 656 if (error == 0) 657 error = uiomove(kv, kl, uio); 658 if (error == 0 && uio->uio_rw == UIO_WRITE) { 659 if (l->l_stat != LSSTOP) 660 error = EBUSY; 661 else 662 error = process_write_fpregs(l, &r); 663 } 664 665 PRELE(l); 666 667 uio->uio_offset = 0; 668 return (error); 669 #else 670 return (EINVAL); 671 #endif 672 } 673 674 int 675 process_validfpregs(p) 676 struct proc *p; 677 { 678 679 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 680 return ((p->p_flag & P_SYSTEM) == 0); 681 #else 682 return (0); 683 #endif 684 } 685 686 int 687 process_domem(curp, p, uio) 688 struct proc *curp; /* tracer */ 689 struct proc *p; /* traced */ 690 struct uio *uio; 691 { 692 int error; 693 694 size_t len; 695 #ifdef PMAP_NEED_PROCWR 696 vaddr_t addr; 697 #endif 698 699 len = uio->uio_resid; 700 701 if (len == 0) 702 return (0); 703 704 #ifdef PMAP_NEED_PROCWR 705 addr = uio->uio_offset; 706 #endif 707 708 if ((error = process_checkioperm(curp, p)) != 0) 709 return (error); 710 711 /* XXXCDC: how should locking work here? */ 712 if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1)) 713 return(EFAULT); 714 p->p_vmspace->vm_refcnt++; /* XXX */ 715 error = uvm_io(&p->p_vmspace->vm_map, uio); 716 uvmspace_free(p->p_vmspace); 717 718 #ifdef PMAP_NEED_PROCWR 719 if (uio->uio_rw == UIO_WRITE) 720 pmap_procwr(p, addr, len); 721 #endif 722 return (error); 723 } 724 725 /* 726 * Ensure that a process has permission to perform I/O on another. 727 * Arguments: 728 * p The process wishing to do the I/O (the tracer). 729 * t The process who's memory/registers will be read/written. 730 */ 731 int 732 process_checkioperm(p, t) 733 struct proc *p, *t; 734 { 735 int error; 736 737 /* 738 * You cannot attach to a processes mem/regs if: 739 * 740 * (1) It is currently exec'ing 741 */ 742 if (ISSET(t->p_flag, P_INEXEC)) 743 return (EAGAIN); 744 745 /* 746 * (2) it's not owned by you, or is set-id on exec 747 * (unless you're root), or... 748 */ 749 if ((t->p_cred->p_ruid != p->p_cred->p_ruid || 750 ISSET(t->p_flag, P_SUGID)) && 751 (error = suser(p->p_ucred, &p->p_acflag)) != 0) 752 return (error); 753 754 /* 755 * (3) ...it's init, which controls the security level 756 * of the entire system, and the system was not 757 * compiled with permanetly insecure mode turned on. 758 */ 759 if (t == initproc && securelevel > -1) 760 return (EPERM); 761 762 /* 763 * (4) the tracer is chrooted, and its root directory is 764 * not at or above the root directory of the tracee 765 */ 766 if (!proc_isunder(t, p)) 767 return (EPERM); 768 769 return (0); 770 } 771