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