1 /* $NetBSD: sys_process.c,v 1.91 2004/06/22 02:06:55 christos 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.91 2004/06/22 02:06:55 christos 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 (!LIST_EMPTY(&t->p_raslist) && 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)(unsigned 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)(unsigned 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 s = proclist_lock_write(); 403 if (t->p_opptr != t->p_pptr) { 404 struct proc *pp = t->p_opptr; 405 proc_reparent(t, pp ? pp : initproc); 406 } 407 408 /* not being traced any more */ 409 t->p_opptr = NULL; 410 proclist_unlock_write(s); 411 CLR(t->p_flag, P_TRACED|P_WAITED); 412 } 413 414 sendsig: 415 /* Finally, deliver the requested signal (or none). */ 416 if (t->p_stat == SSTOP) { 417 t->p_xstat = SCARG(uap, data); 418 SCHED_LOCK(s); 419 lr = proc_unstop(t); 420 /* 421 * If the target needs to take a signal, there 422 * is no running LWP that will see it, and 423 * there is a LWP sleeping interruptably, then 424 * get it moving. 425 */ 426 if (lr && (t->p_xstat != 0)) 427 setrunnable(lr); 428 SCHED_UNLOCK(s); 429 } else { 430 if (SCARG(uap, data) != 0) 431 psignal(t, SCARG(uap, data)); 432 } 433 return (0); 434 435 relebad: 436 PRELE(lt); 437 return (error); 438 439 case PT_KILL: 440 /* just send the process a KILL signal. */ 441 SCARG(uap, data) = SIGKILL; 442 goto sendsig; /* in PT_CONTINUE, above. */ 443 444 case PT_ATTACH: 445 /* 446 * Go ahead and set the trace flag. 447 * Save the old parent (it's reset in 448 * _DETACH, and also in kern_exit.c:wait4() 449 * Reparent the process so that the tracing 450 * proc gets to see all the action. 451 * Stop the target. 452 */ 453 SET(t->p_flag, P_TRACED); 454 s = proclist_lock_write(); 455 t->p_opptr = t->p_pptr; 456 if (t->p_pptr != p) { 457 t->p_pptr->p_flag |= P_CHTRACED; 458 proc_reparent(t, p); 459 } 460 proclist_unlock_write(s); 461 SCARG(uap, data) = SIGSTOP; 462 goto sendsig; 463 464 case PT_LWPINFO: 465 size = SCARG(uap, data); 466 if (size < sizeof(lwpid_t)) 467 return (EINVAL); 468 error = copyin(SCARG(uap, addr), &pl, sizeof(lwpid_t)); 469 if (error) 470 return (error); 471 tmp = pl.pl_lwpid; 472 if (tmp == 0) 473 lt = LIST_FIRST(&t->p_lwps); 474 else { 475 LIST_FOREACH(lt, &t->p_lwps, l_sibling) 476 if (lt->l_lid == tmp) 477 break; 478 if (lt == NULL) 479 return (ESRCH); 480 lt = LIST_NEXT(lt, l_sibling); 481 } 482 pl.pl_lwpid = 0; 483 pl.pl_event = 0; 484 if (lt) { 485 pl.pl_lwpid = lt->l_lid; 486 if (lt->l_lid == t->p_sigctx.ps_lwp) 487 pl.pl_event = PL_EVENT_SIGNAL; 488 } 489 490 error = copyout(&pl, SCARG(uap, addr), SCARG(uap, data)); 491 492 return (0); 493 494 #ifdef PT_SETREGS 495 case PT_SETREGS: 496 write = 1; 497 #endif 498 #ifdef PT_GETREGS 499 case PT_GETREGS: 500 /* write = 0 done above. */ 501 #endif 502 #if defined(PT_SETREGS) || defined(PT_GETREGS) 503 tmp = SCARG(uap, data); 504 if (tmp != 0 && t->p_nlwps > 1) { 505 LIST_FOREACH(lt, &t->p_lwps, l_sibling) 506 if (lt->l_lid == tmp) 507 break; 508 if (lt == NULL) 509 return (ESRCH); 510 } 511 if (!process_validregs(t)) 512 return (EINVAL); 513 else { 514 iov.iov_base = SCARG(uap, addr); 515 iov.iov_len = sizeof(struct reg); 516 uio.uio_iov = &iov; 517 uio.uio_iovcnt = 1; 518 uio.uio_offset = 0; 519 uio.uio_resid = sizeof(struct reg); 520 uio.uio_segflg = UIO_USERSPACE; 521 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 522 uio.uio_procp = p; 523 return (process_doregs(p, lt, &uio)); 524 } 525 #endif 526 527 #ifdef PT_SETFPREGS 528 case PT_SETFPREGS: 529 write = 1; 530 #endif 531 #ifdef PT_GETFPREGS 532 case PT_GETFPREGS: 533 /* write = 0 done above. */ 534 #endif 535 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 536 tmp = SCARG(uap, data); 537 if (tmp != 0 && t->p_nlwps > 1) { 538 LIST_FOREACH(lt, &t->p_lwps, l_sibling) 539 if (lt->l_lid == tmp) 540 break; 541 if (lt == NULL) 542 return (ESRCH); 543 } 544 if (!process_validfpregs(t)) 545 return (EINVAL); 546 else { 547 iov.iov_base = SCARG(uap, addr); 548 iov.iov_len = sizeof(struct fpreg); 549 uio.uio_iov = &iov; 550 uio.uio_iovcnt = 1; 551 uio.uio_offset = 0; 552 uio.uio_resid = sizeof(struct fpreg); 553 uio.uio_segflg = UIO_USERSPACE; 554 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 555 uio.uio_procp = p; 556 return (process_dofpregs(p, lt, &uio)); 557 } 558 #endif 559 560 #ifdef __HAVE_PTRACE_MACHDEP 561 PTRACE_MACHDEP_REQUEST_CASES 562 return (ptrace_machdep_dorequest(p, lt, 563 SCARG(uap, req), SCARG(uap, addr), 564 SCARG(uap, data))); 565 #endif 566 } 567 568 #ifdef DIAGNOSTIC 569 panic("ptrace: impossible"); 570 #endif 571 return 0; 572 } 573 574 int 575 process_doregs(curp, l, uio) 576 struct proc *curp; /* tracer */ 577 struct lwp *l; /* traced */ 578 struct uio *uio; 579 { 580 #if defined(PT_GETREGS) || defined(PT_SETREGS) 581 int error; 582 struct reg r; 583 char *kv; 584 int kl; 585 586 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 587 return EINVAL; 588 589 if ((error = process_checkioperm(curp, l->l_proc)) != 0) 590 return error; 591 592 kl = sizeof(r); 593 kv = (char *)&r; 594 595 kv += uio->uio_offset; 596 kl -= uio->uio_offset; 597 if ((size_t)kl > uio->uio_resid) 598 kl = uio->uio_resid; 599 600 PHOLD(l); 601 602 error = process_read_regs(l, &r); 603 if (error == 0) 604 error = uiomove(kv, kl, uio); 605 if (error == 0 && uio->uio_rw == UIO_WRITE) { 606 if (l->l_stat != LSSTOP) 607 error = EBUSY; 608 else 609 error = process_write_regs(l, &r); 610 } 611 612 PRELE(l); 613 614 uio->uio_offset = 0; 615 return (error); 616 #else 617 return (EINVAL); 618 #endif 619 } 620 621 int 622 process_validregs(p) 623 struct proc *p; 624 { 625 626 #if defined(PT_SETREGS) || defined(PT_GETREGS) 627 return ((p->p_flag & P_SYSTEM) == 0); 628 #else 629 return (0); 630 #endif 631 } 632 633 int 634 process_dofpregs(curp, l, uio) 635 struct proc *curp; /* tracer */ 636 struct lwp *l; /* traced */ 637 struct uio *uio; 638 { 639 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) 640 int error; 641 struct fpreg r; 642 char *kv; 643 int kl; 644 645 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 646 return EINVAL; 647 648 if ((error = process_checkioperm(curp, l->l_proc)) != 0) 649 return (error); 650 651 kl = sizeof(r); 652 kv = (char *)&r; 653 654 kv += uio->uio_offset; 655 kl -= uio->uio_offset; 656 if ((size_t)kl > uio->uio_resid) 657 kl = uio->uio_resid; 658 659 PHOLD(l); 660 661 error = process_read_fpregs(l, &r); 662 if (error == 0) 663 error = uiomove(kv, kl, uio); 664 if (error == 0 && uio->uio_rw == UIO_WRITE) { 665 if (l->l_stat != LSSTOP) 666 error = EBUSY; 667 else 668 error = process_write_fpregs(l, &r); 669 } 670 671 PRELE(l); 672 673 uio->uio_offset = 0; 674 return (error); 675 #else 676 return (EINVAL); 677 #endif 678 } 679 680 int 681 process_validfpregs(p) 682 struct proc *p; 683 { 684 685 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 686 return ((p->p_flag & P_SYSTEM) == 0); 687 #else 688 return (0); 689 #endif 690 } 691 692 int 693 process_domem(curp, p, uio) 694 struct proc *curp; /* tracer */ 695 struct proc *p; /* traced */ 696 struct uio *uio; 697 { 698 struct vmspace *vm; 699 int error; 700 701 size_t len; 702 #ifdef PMAP_NEED_PROCWR 703 vaddr_t addr; 704 #endif 705 706 len = uio->uio_resid; 707 708 if (len == 0) 709 return (0); 710 711 #ifdef PMAP_NEED_PROCWR 712 addr = uio->uio_offset; 713 #endif 714 715 if ((error = process_checkioperm(curp, p)) != 0) 716 return (error); 717 718 vm = p->p_vmspace; 719 720 simple_lock(&vm->vm_map.ref_lock); 721 if ((p->p_flag & P_WEXIT) || vm->vm_refcnt < 1) 722 error = EFAULT; 723 if (error == 0) 724 p->p_vmspace->vm_refcnt++; /* XXX */ 725 simple_unlock(&vm->vm_map.ref_lock); 726 if (error != 0) 727 return (error); 728 error = uvm_io(&vm->vm_map, uio); 729 uvmspace_free(vm); 730 731 #ifdef PMAP_NEED_PROCWR 732 if (error == 0 && uio->uio_rw == UIO_WRITE) 733 pmap_procwr(p, addr, len); 734 #endif 735 return (error); 736 } 737 738 /* 739 * Ensure that a process has permission to perform I/O on another. 740 * Arguments: 741 * p The process wishing to do the I/O (the tracer). 742 * t The process who's memory/registers will be read/written. 743 */ 744 int 745 process_checkioperm(p, t) 746 struct proc *p, *t; 747 { 748 int error; 749 750 /* 751 * You cannot attach to a processes mem/regs if: 752 * 753 * (1) It is currently exec'ing 754 */ 755 if (ISSET(t->p_flag, P_INEXEC)) 756 return (EAGAIN); 757 758 /* 759 * (2) it's not owned by you, or is set-id on exec 760 * (unless you're root), or... 761 */ 762 if ((t->p_cred->p_ruid != p->p_cred->p_ruid || 763 ISSET(t->p_flag, P_SUGID)) && 764 (error = suser(p->p_ucred, &p->p_acflag)) != 0) 765 return (error); 766 767 /* 768 * (3) ...it's init, which controls the security level 769 * of the entire system, and the system was not 770 * compiled with permanetly insecure mode turned on. 771 */ 772 if (t == initproc && securelevel > -1) 773 return (EPERM); 774 775 /* 776 * (4) the tracer is chrooted, and its root directory is 777 * not at or above the root directory of the tracee 778 */ 779 if (!proc_isunder(t, p)) 780 return (EPERM); 781 782 return (0); 783 } 784