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