1 /* $NetBSD: sys_process.c,v 1.95 2005/02/26 21:34:55 perry 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.95 2005/02/26 21:34:55 perry 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 #include <sys/malloc.h> 103 104 #include <sys/mount.h> 105 #include <sys/sa.h> 106 #include <sys/syscallargs.h> 107 108 #include <uvm/uvm_extern.h> 109 110 #include <machine/reg.h> 111 112 /* Macros to clear/set/test flags. */ 113 #define SET(t, f) (t) |= (f) 114 #define CLR(t, f) (t) &= ~(f) 115 #define ISSET(t, f) ((t) & (f)) 116 117 /* 118 * Process debugging system call. 119 */ 120 int 121 sys_ptrace(l, v, retval) 122 struct lwp *l; 123 void *v; 124 register_t *retval; 125 { 126 struct sys_ptrace_args /* { 127 syscallarg(int) req; 128 syscallarg(pid_t) pid; 129 syscallarg(caddr_t) addr; 130 syscallarg(int) data; 131 } */ *uap = v; 132 struct proc *p = l->l_proc; 133 struct lwp *lt, *lr; 134 struct proc *t; /* target process */ 135 struct uio uio; 136 struct iovec iov; 137 struct ptrace_io_desc piod; 138 struct ptrace_lwpinfo pl; 139 int s, error, write, tmp, size; 140 char *path; 141 142 /* "A foolish consistency..." XXX */ 143 if (SCARG(uap, req) == PT_TRACE_ME) 144 t = p; 145 else { 146 147 /* Find the process we're supposed to be operating on. */ 148 if ((t = pfind(SCARG(uap, pid))) == NULL) 149 return (ESRCH); 150 } 151 152 /* Can't trace a process that's currently exec'ing. */ 153 if ((t->p_flag & P_INEXEC) != 0) 154 return EAGAIN; 155 156 /* Make sure we can operate on it. */ 157 switch (SCARG(uap, req)) { 158 case PT_TRACE_ME: 159 /* Saying that you're being traced is always legal. */ 160 break; 161 162 case PT_ATTACH: 163 case PT_DUMPCORE: 164 /* 165 * You can't attach to a process if: 166 * (1) it's the process that's doing the attaching, 167 */ 168 if (t->p_pid == p->p_pid) 169 return (EINVAL); 170 171 /* 172 * (2) it's a system process 173 */ 174 if (t->p_flag & P_SYSTEM) 175 return (EPERM); 176 177 /* 178 * (3) it's already being traced, or 179 */ 180 if (ISSET(t->p_flag, P_TRACED)) 181 return (EBUSY); 182 183 /* 184 * (4) it's not owned by you, or is set-id on exec 185 * (unless you're root), or... 186 */ 187 if ((t->p_cred->p_ruid != p->p_cred->p_ruid || 188 ISSET(t->p_flag, P_SUGID)) && 189 (error = suser(p->p_ucred, &p->p_acflag)) != 0) 190 return (error); 191 192 /* 193 * (5) ...it's init, which controls the security level 194 * of the entire system, and the system was not 195 * compiled with permanently insecure mode turned on 196 */ 197 if (t == initproc && securelevel > -1) 198 return (EPERM); 199 200 /* 201 * (6) the tracer is chrooted, and its root directory is 202 * not at or above the root directory of the tracee 203 */ 204 205 if (!proc_isunder(t, p)) 206 return EPERM; 207 break; 208 209 case PT_READ_I: 210 case PT_READ_D: 211 case PT_WRITE_I: 212 case PT_WRITE_D: 213 case PT_CONTINUE: 214 case PT_IO: 215 case PT_KILL: 216 case PT_DETACH: 217 case PT_LWPINFO: 218 #ifdef PT_STEP 219 case PT_STEP: 220 #endif 221 #ifdef PT_GETREGS 222 case PT_GETREGS: 223 #endif 224 #ifdef PT_SETREGS 225 case PT_SETREGS: 226 #endif 227 #ifdef PT_GETFPREGS 228 case PT_GETFPREGS: 229 #endif 230 #ifdef PT_SETFPREGS 231 case PT_SETFPREGS: 232 #endif 233 234 #ifdef __HAVE_PTRACE_MACHDEP 235 PTRACE_MACHDEP_REQUEST_CASES 236 #endif 237 238 /* 239 * You can't do what you want to the process if: 240 * (1) It's not being traced at all, 241 */ 242 if (!ISSET(t->p_flag, P_TRACED)) 243 return (EPERM); 244 245 /* 246 * (2) it's being traced by procfs (which has 247 * different signal delivery semantics), 248 */ 249 if (ISSET(t->p_flag, P_FSTRACE)) 250 return (EBUSY); 251 252 /* 253 * (3) it's not being traced by _you_, or 254 */ 255 if (t->p_pptr != p) 256 return (EBUSY); 257 258 /* 259 * (4) it's not currently stopped. 260 */ 261 if (t->p_stat != SSTOP || !ISSET(t->p_flag, P_WAITED)) 262 return (EBUSY); 263 break; 264 265 default: /* It was not a legal request. */ 266 return (EINVAL); 267 } 268 269 /* Do single-step fixup if needed. */ 270 FIX_SSTEP(t); 271 272 /* 273 * XXX NJWLWP 274 * 275 * The entire ptrace interface needs work to be useful to a 276 * process with multiple LWPs. For the moment, we'll kluge 277 * this; memory access will be fine, but register access will 278 * be weird. 279 */ 280 281 lt = proc_representative_lwp(t); 282 283 /* Now do the operation. */ 284 write = 0; 285 *retval = 0; 286 tmp = 0; 287 288 switch (SCARG(uap, req)) { 289 case PT_TRACE_ME: 290 /* Just set the trace flag. */ 291 SET(t->p_flag, P_TRACED); 292 t->p_opptr = t->p_pptr; 293 return (0); 294 295 case PT_WRITE_I: /* XXX no separate I and D spaces */ 296 case PT_WRITE_D: 297 #if defined(__HAVE_RAS) 298 /* 299 * Can't write to a RAS 300 */ 301 if (!LIST_EMPTY(&t->p_raslist) && 302 (ras_lookup(t, SCARG(uap, addr)) != (caddr_t)-1)) { 303 return (EACCES); 304 } 305 #endif 306 write = 1; 307 tmp = SCARG(uap, data); 308 case PT_READ_I: /* XXX no separate I and D spaces */ 309 case PT_READ_D: 310 /* write = 0 done above. */ 311 iov.iov_base = (caddr_t)&tmp; 312 iov.iov_len = sizeof(tmp); 313 uio.uio_iov = &iov; 314 uio.uio_iovcnt = 1; 315 uio.uio_offset = (off_t)(unsigned long)SCARG(uap, addr); 316 uio.uio_resid = sizeof(tmp); 317 uio.uio_segflg = UIO_SYSSPACE; 318 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 319 uio.uio_procp = NULL; 320 error = process_domem(p, t, &uio); 321 if (!write) 322 *retval = tmp; 323 return (error); 324 325 case PT_IO: 326 error = copyin(SCARG(uap, addr), &piod, sizeof(piod)); 327 if (error) 328 return (error); 329 iov.iov_base = piod.piod_addr; 330 iov.iov_len = piod.piod_len; 331 uio.uio_iov = &iov; 332 uio.uio_iovcnt = 1; 333 uio.uio_offset = (off_t)(unsigned long)piod.piod_offs; 334 uio.uio_resid = piod.piod_len; 335 uio.uio_segflg = UIO_USERSPACE; 336 uio.uio_procp = p; 337 switch (piod.piod_op) { 338 case PIOD_READ_D: 339 case PIOD_READ_I: 340 uio.uio_rw = UIO_READ; 341 break; 342 case PIOD_WRITE_D: 343 case PIOD_WRITE_I: 344 uio.uio_rw = UIO_WRITE; 345 break; 346 default: 347 return (EINVAL); 348 } 349 error = process_domem(p, t, &uio); 350 piod.piod_len -= uio.uio_resid; 351 (void) copyout(&piod, SCARG(uap, addr), sizeof(piod)); 352 return (error); 353 354 case PT_DUMPCORE: 355 if ((path = SCARG(uap, addr)) != NULL) { 356 char *dst; 357 int len = SCARG(uap, data); 358 if (len >= MAXPATHLEN) 359 return EINVAL; 360 dst = malloc(len + 1, M_TEMP, M_WAITOK); 361 if ((error = copyin(path, dst, len)) != 0) { 362 free(dst, M_TEMP); 363 return error; 364 } 365 path = dst; 366 path[len] = '\0'; 367 } 368 error = coredump(lt, path); 369 if (path) 370 free(path, M_TEMP); 371 return error; 372 373 #ifdef PT_STEP 374 case PT_STEP: 375 /* 376 * From the 4.4BSD PRM: 377 * "Execution continues as in request PT_CONTINUE; however 378 * as soon as possible after execution of at least one 379 * instruction, execution stops again. [ ... ]" 380 */ 381 #endif 382 case PT_CONTINUE: 383 case PT_DETACH: 384 /* 385 * From the 4.4BSD PRM: 386 * "The data argument is taken as a signal number and the 387 * child's execution continues at location addr as if it 388 * incurred that signal. Normally the signal number will 389 * be either 0 to indicate that the signal that caused the 390 * stop should be ignored, or that value fetched out of 391 * the process's image indicating which signal caused 392 * the stop. If addr is (int *)1 then execution continues 393 * from where it stopped." 394 */ 395 396 /* Check that the data is a valid signal number or zero. */ 397 if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG) 398 return (EINVAL); 399 400 PHOLD(lt); 401 402 /* If the address parameter is not (int *)1, set the pc. */ 403 if ((int *)SCARG(uap, addr) != (int *)1) 404 if ((error = process_set_pc(lt, SCARG(uap, addr))) != 0) 405 goto relebad; 406 407 #ifdef PT_STEP 408 /* 409 * Arrange for a single-step, if that's requested and possible. 410 */ 411 error = process_sstep(lt, SCARG(uap, req) == PT_STEP); 412 if (error) 413 goto relebad; 414 #endif 415 416 PRELE(lt); 417 418 if (SCARG(uap, req) == PT_DETACH) { 419 /* give process back to original parent or init */ 420 s = proclist_lock_write(); 421 if (t->p_opptr != t->p_pptr) { 422 struct proc *pp = t->p_opptr; 423 proc_reparent(t, pp ? pp : initproc); 424 } 425 426 /* not being traced any more */ 427 t->p_opptr = NULL; 428 proclist_unlock_write(s); 429 CLR(t->p_flag, P_TRACED|P_WAITED); 430 } 431 432 sendsig: 433 /* Finally, deliver the requested signal (or none). */ 434 if (t->p_stat == SSTOP) { 435 t->p_xstat = SCARG(uap, data); 436 SCHED_LOCK(s); 437 lr = proc_unstop(t); 438 /* 439 * If the target needs to take a signal, there 440 * is no running LWP that will see it, and 441 * there is a LWP sleeping interruptably, then 442 * get it moving. 443 */ 444 if (lr && (t->p_xstat != 0)) 445 setrunnable(lr); 446 SCHED_UNLOCK(s); 447 } else { 448 if (SCARG(uap, data) != 0) 449 psignal(t, SCARG(uap, data)); 450 } 451 return (0); 452 453 relebad: 454 PRELE(lt); 455 return (error); 456 457 case PT_KILL: 458 /* just send the process a KILL signal. */ 459 SCARG(uap, data) = SIGKILL; 460 goto sendsig; /* in PT_CONTINUE, above. */ 461 462 case PT_ATTACH: 463 /* 464 * Go ahead and set the trace flag. 465 * Save the old parent (it's reset in 466 * _DETACH, and also in kern_exit.c:wait4() 467 * Reparent the process so that the tracing 468 * proc gets to see all the action. 469 * Stop the target. 470 */ 471 SET(t->p_flag, P_TRACED); 472 s = proclist_lock_write(); 473 t->p_opptr = t->p_pptr; 474 if (t->p_pptr != p) { 475 t->p_pptr->p_flag |= P_CHTRACED; 476 proc_reparent(t, p); 477 } 478 proclist_unlock_write(s); 479 SCARG(uap, data) = SIGSTOP; 480 goto sendsig; 481 482 case PT_LWPINFO: 483 size = SCARG(uap, data); 484 if (size < sizeof(lwpid_t)) 485 return (EINVAL); 486 error = copyin(SCARG(uap, addr), &pl, sizeof(lwpid_t)); 487 if (error) 488 return (error); 489 tmp = pl.pl_lwpid; 490 if (tmp == 0) 491 lt = LIST_FIRST(&t->p_lwps); 492 else { 493 LIST_FOREACH(lt, &t->p_lwps, l_sibling) 494 if (lt->l_lid == tmp) 495 break; 496 if (lt == NULL) 497 return (ESRCH); 498 lt = LIST_NEXT(lt, l_sibling); 499 } 500 pl.pl_lwpid = 0; 501 pl.pl_event = 0; 502 if (lt) { 503 pl.pl_lwpid = lt->l_lid; 504 if (lt->l_lid == t->p_sigctx.ps_lwp) 505 pl.pl_event = PL_EVENT_SIGNAL; 506 } 507 508 error = copyout(&pl, SCARG(uap, addr), SCARG(uap, data)); 509 510 return (0); 511 512 #ifdef PT_SETREGS 513 case PT_SETREGS: 514 write = 1; 515 #endif 516 #ifdef PT_GETREGS 517 case PT_GETREGS: 518 /* write = 0 done above. */ 519 #endif 520 #if defined(PT_SETREGS) || defined(PT_GETREGS) 521 tmp = SCARG(uap, data); 522 if (tmp != 0 && t->p_nlwps > 1) { 523 LIST_FOREACH(lt, &t->p_lwps, l_sibling) 524 if (lt->l_lid == tmp) 525 break; 526 if (lt == NULL) 527 return (ESRCH); 528 } 529 if (!process_validregs(t)) 530 return (EINVAL); 531 else { 532 iov.iov_base = SCARG(uap, addr); 533 iov.iov_len = sizeof(struct reg); 534 uio.uio_iov = &iov; 535 uio.uio_iovcnt = 1; 536 uio.uio_offset = 0; 537 uio.uio_resid = sizeof(struct reg); 538 uio.uio_segflg = UIO_USERSPACE; 539 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 540 uio.uio_procp = p; 541 return (process_doregs(p, lt, &uio)); 542 } 543 #endif 544 545 #ifdef PT_SETFPREGS 546 case PT_SETFPREGS: 547 write = 1; 548 #endif 549 #ifdef PT_GETFPREGS 550 case PT_GETFPREGS: 551 /* write = 0 done above. */ 552 #endif 553 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 554 tmp = SCARG(uap, data); 555 if (tmp != 0 && t->p_nlwps > 1) { 556 LIST_FOREACH(lt, &t->p_lwps, l_sibling) 557 if (lt->l_lid == tmp) 558 break; 559 if (lt == NULL) 560 return (ESRCH); 561 } 562 if (!process_validfpregs(t)) 563 return (EINVAL); 564 else { 565 iov.iov_base = SCARG(uap, addr); 566 iov.iov_len = sizeof(struct fpreg); 567 uio.uio_iov = &iov; 568 uio.uio_iovcnt = 1; 569 uio.uio_offset = 0; 570 uio.uio_resid = sizeof(struct fpreg); 571 uio.uio_segflg = UIO_USERSPACE; 572 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 573 uio.uio_procp = p; 574 return (process_dofpregs(p, lt, &uio)); 575 } 576 #endif 577 578 #ifdef __HAVE_PTRACE_MACHDEP 579 PTRACE_MACHDEP_REQUEST_CASES 580 return (ptrace_machdep_dorequest(p, lt, 581 SCARG(uap, req), SCARG(uap, addr), 582 SCARG(uap, data))); 583 #endif 584 } 585 586 #ifdef DIAGNOSTIC 587 panic("ptrace: impossible"); 588 #endif 589 return 0; 590 } 591 592 int 593 process_doregs(curp, l, uio) 594 struct proc *curp; /* tracer */ 595 struct lwp *l; /* traced */ 596 struct uio *uio; 597 { 598 #if defined(PT_GETREGS) || defined(PT_SETREGS) 599 int error; 600 struct reg r; 601 char *kv; 602 int kl; 603 604 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 605 return EINVAL; 606 607 if ((error = process_checkioperm(curp, l->l_proc)) != 0) 608 return error; 609 610 kl = sizeof(r); 611 kv = (char *)&r; 612 613 kv += uio->uio_offset; 614 kl -= uio->uio_offset; 615 if ((size_t)kl > uio->uio_resid) 616 kl = uio->uio_resid; 617 618 PHOLD(l); 619 620 error = process_read_regs(l, &r); 621 if (error == 0) 622 error = uiomove(kv, kl, uio); 623 if (error == 0 && uio->uio_rw == UIO_WRITE) { 624 if (l->l_stat != LSSTOP) 625 error = EBUSY; 626 else 627 error = process_write_regs(l, &r); 628 } 629 630 PRELE(l); 631 632 uio->uio_offset = 0; 633 return (error); 634 #else 635 return (EINVAL); 636 #endif 637 } 638 639 int 640 process_validregs(p) 641 struct proc *p; 642 { 643 644 #if defined(PT_SETREGS) || defined(PT_GETREGS) 645 return ((p->p_flag & P_SYSTEM) == 0); 646 #else 647 return (0); 648 #endif 649 } 650 651 int 652 process_dofpregs(curp, l, uio) 653 struct proc *curp; /* tracer */ 654 struct lwp *l; /* traced */ 655 struct uio *uio; 656 { 657 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) 658 int error; 659 struct fpreg r; 660 char *kv; 661 int kl; 662 663 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 664 return EINVAL; 665 666 if ((error = process_checkioperm(curp, l->l_proc)) != 0) 667 return (error); 668 669 kl = sizeof(r); 670 kv = (char *)&r; 671 672 kv += uio->uio_offset; 673 kl -= uio->uio_offset; 674 if ((size_t)kl > uio->uio_resid) 675 kl = uio->uio_resid; 676 677 PHOLD(l); 678 679 error = process_read_fpregs(l, &r); 680 if (error == 0) 681 error = uiomove(kv, kl, uio); 682 if (error == 0 && uio->uio_rw == UIO_WRITE) { 683 if (l->l_stat != LSSTOP) 684 error = EBUSY; 685 else 686 error = process_write_fpregs(l, &r); 687 } 688 689 PRELE(l); 690 691 uio->uio_offset = 0; 692 return (error); 693 #else 694 return (EINVAL); 695 #endif 696 } 697 698 int 699 process_validfpregs(p) 700 struct proc *p; 701 { 702 703 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 704 return ((p->p_flag & P_SYSTEM) == 0); 705 #else 706 return (0); 707 #endif 708 } 709 710 int 711 process_domem(curp, p, uio) 712 struct proc *curp; /* tracer */ 713 struct proc *p; /* traced */ 714 struct uio *uio; 715 { 716 struct vmspace *vm; 717 int error; 718 719 size_t len; 720 #ifdef PMAP_NEED_PROCWR 721 vaddr_t addr; 722 #endif 723 724 len = uio->uio_resid; 725 726 if (len == 0) 727 return (0); 728 729 #ifdef PMAP_NEED_PROCWR 730 addr = uio->uio_offset; 731 #endif 732 733 if ((error = process_checkioperm(curp, p)) != 0) 734 return (error); 735 736 vm = p->p_vmspace; 737 738 simple_lock(&vm->vm_map.ref_lock); 739 if ((p->p_flag & P_WEXIT) || vm->vm_refcnt < 1) 740 error = EFAULT; 741 if (error == 0) 742 p->p_vmspace->vm_refcnt++; /* XXX */ 743 simple_unlock(&vm->vm_map.ref_lock); 744 if (error != 0) 745 return (error); 746 error = uvm_io(&vm->vm_map, uio); 747 uvmspace_free(vm); 748 749 #ifdef PMAP_NEED_PROCWR 750 if (error == 0 && uio->uio_rw == UIO_WRITE) 751 pmap_procwr(p, addr, len); 752 #endif 753 return (error); 754 } 755 756 /* 757 * Ensure that a process has permission to perform I/O on another. 758 * Arguments: 759 * p The process wishing to do the I/O (the tracer). 760 * t The process who's memory/registers will be read/written. 761 */ 762 int 763 process_checkioperm(p, t) 764 struct proc *p, *t; 765 { 766 int error; 767 768 /* 769 * You cannot attach to a processes mem/regs if: 770 * 771 * (1) It is currently exec'ing 772 */ 773 if (ISSET(t->p_flag, P_INEXEC)) 774 return (EAGAIN); 775 776 /* 777 * (2) it's not owned by you, or is set-id on exec 778 * (unless you're root), or... 779 */ 780 if ((t->p_cred->p_ruid != p->p_cred->p_ruid || 781 ISSET(t->p_flag, P_SUGID)) && 782 (error = suser(p->p_ucred, &p->p_acflag)) != 0) 783 return (error); 784 785 /* 786 * (3) ...it's init, which controls the security level 787 * of the entire system, and the system was not 788 * compiled with permanetly insecure mode turned on. 789 */ 790 if (t == initproc && securelevel > -1) 791 return (EPERM); 792 793 /* 794 * (4) the tracer is chrooted, and its root directory is 795 * not at or above the root directory of the tracee 796 */ 797 if (!proc_isunder(t, p)) 798 return (EPERM); 799 800 return (0); 801 } 802