1 /* $NetBSD: sys_process.c,v 1.144 2008/11/19 18:36:07 ad Exp $ */ 2 3 /*- 4 * Copyright (c) 2008 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /*- 30 * Copyright (c) 1982, 1986, 1989, 1993 31 * The Regents of the University of California. All rights reserved. 32 * (c) UNIX System Laboratories, Inc. 33 * All or some portions of this file are derived from material licensed 34 * to the University of California by American Telephone and Telegraph 35 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 36 * the permission of UNIX System Laboratories, Inc. 37 * 38 * This code is derived from software contributed to Berkeley by 39 * Jan-Simon Pendry. 40 * 41 * Redistribution and use in source and binary forms, with or without 42 * modification, are permitted provided that the following conditions 43 * are met: 44 * 1. Redistributions of source code must retain the above copyright 45 * notice, this list of conditions and the following disclaimer. 46 * 2. Redistributions in binary form must reproduce the above copyright 47 * notice, this list of conditions and the following disclaimer in the 48 * documentation and/or other materials provided with the distribution. 49 * 3. Neither the name of the University nor the names of its contributors 50 * may be used to endorse or promote products derived from this software 51 * without specific prior written permission. 52 * 53 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 54 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 55 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 56 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * SUCH DAMAGE. 64 * 65 * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 66 */ 67 68 /*- 69 * Copyright (c) 1993 Jan-Simon Pendry. 70 * Copyright (c) 1994 Christopher G. Demetriou. All rights reserved. 71 * 72 * This code is derived from software contributed to Berkeley by 73 * Jan-Simon Pendry. 74 * 75 * Redistribution and use in source and binary forms, with or without 76 * modification, are permitted provided that the following conditions 77 * are met: 78 * 1. Redistributions of source code must retain the above copyright 79 * notice, this list of conditions and the following disclaimer. 80 * 2. Redistributions in binary form must reproduce the above copyright 81 * notice, this list of conditions and the following disclaimer in the 82 * documentation and/or other materials provided with the distribution. 83 * 3. All advertising materials mentioning features or use of this software 84 * must display the following acknowledgement: 85 * This product includes software developed by the University of 86 * California, Berkeley and its contributors. 87 * 4. Neither the name of the University nor the names of its contributors 88 * may be used to endorse or promote products derived from this software 89 * without specific prior written permission. 90 * 91 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 92 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 94 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 97 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 98 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 99 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 100 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 101 * SUCH DAMAGE. 102 * 103 * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 104 */ 105 106 /* 107 * References: 108 * (1) Bach's "The Design of the UNIX Operating System", 109 * (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution, 110 * (3) the "4.4BSD Programmer's Reference Manual" published 111 * by USENIX and O'Reilly & Associates. 112 * The 4.4BSD PRM does a reasonably good job of documenting what the various 113 * ptrace() requests should actually do, and its text is quoted several times 114 * in this file. 115 */ 116 117 #include <sys/cdefs.h> 118 __KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.144 2008/11/19 18:36:07 ad Exp $"); 119 120 #include "opt_ptrace.h" 121 #include "opt_ktrace.h" 122 123 #include <sys/param.h> 124 #include <sys/systm.h> 125 #include <sys/proc.h> 126 #include <sys/errno.h> 127 #include <sys/ptrace.h> 128 #include <sys/uio.h> 129 #include <sys/user.h> 130 #include <sys/ras.h> 131 #include <sys/malloc.h> 132 #include <sys/kauth.h> 133 #include <sys/mount.h> 134 #include <sys/syscallargs.h> 135 136 #include <uvm/uvm_extern.h> 137 138 #include <machine/reg.h> 139 140 #ifdef PTRACE 141 /* 142 * Process debugging system call. 143 */ 144 int 145 sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval) 146 { 147 /* { 148 syscallarg(int) req; 149 syscallarg(pid_t) pid; 150 syscallarg(void *) addr; 151 syscallarg(int) data; 152 } */ 153 struct proc *p = l->l_proc; 154 struct lwp *lt; 155 struct proc *t; /* target process */ 156 struct uio uio; 157 struct iovec iov; 158 struct ptrace_io_desc piod; 159 struct ptrace_lwpinfo pl; 160 struct vmspace *vm; 161 int error, write, tmp, req, pheld; 162 int signo; 163 ksiginfo_t ksi; 164 char *path; 165 166 error = 0; 167 req = SCARG(uap, req); 168 169 /* 170 * If attaching or detaching, we need to get a write hold on the 171 * proclist lock so that we can re-parent the target process. 172 */ 173 mutex_enter(proc_lock); 174 175 /* "A foolish consistency..." XXX */ 176 if (req == PT_TRACE_ME) { 177 t = p; 178 mutex_enter(t->p_lock); 179 } else { 180 /* Find the process we're supposed to be operating on. */ 181 if ((t = p_find(SCARG(uap, pid), PFIND_LOCKED)) == NULL) { 182 mutex_exit(proc_lock); 183 return (ESRCH); 184 } 185 186 /* XXX-elad */ 187 mutex_enter(t->p_lock); 188 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE, 189 t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL); 190 if (error) { 191 mutex_exit(proc_lock); 192 mutex_exit(t->p_lock); 193 return (ESRCH); 194 } 195 } 196 197 /* 198 * Grab a reference on the process to prevent it from execing or 199 * exiting. 200 */ 201 if (!rw_tryenter(&t->p_reflock, RW_READER)) { 202 mutex_exit(proc_lock); 203 mutex_exit(t->p_lock); 204 return EBUSY; 205 } 206 207 /* Make sure we can operate on it. */ 208 switch (req) { 209 case PT_TRACE_ME: 210 /* Saying that you're being traced is always legal. */ 211 break; 212 213 case PT_ATTACH: 214 /* 215 * You can't attach to a process if: 216 * (1) it's the process that's doing the attaching, 217 */ 218 if (t->p_pid == p->p_pid) { 219 error = EINVAL; 220 break; 221 } 222 223 /* 224 * (2) it's a system process 225 */ 226 if (t->p_flag & PK_SYSTEM) { 227 error = EPERM; 228 break; 229 } 230 231 /* 232 * (3) it's already being traced, or 233 */ 234 if (ISSET(t->p_slflag, PSL_TRACED)) { 235 error = EBUSY; 236 break; 237 } 238 239 /* 240 * (4) the tracer is chrooted, and its root directory is 241 * not at or above the root directory of the tracee 242 */ 243 mutex_exit(t->p_lock); /* XXXSMP */ 244 tmp = proc_isunder(t, l); 245 mutex_enter(t->p_lock); /* XXXSMP */ 246 if (!tmp) { 247 error = EPERM; 248 break; 249 } 250 break; 251 252 case PT_READ_I: 253 case PT_READ_D: 254 case PT_WRITE_I: 255 case PT_WRITE_D: 256 case PT_IO: 257 #ifdef PT_GETREGS 258 case PT_GETREGS: 259 #endif 260 #ifdef PT_SETREGS 261 case PT_SETREGS: 262 #endif 263 #ifdef PT_GETFPREGS 264 case PT_GETFPREGS: 265 #endif 266 #ifdef PT_SETFPREGS 267 case PT_SETFPREGS: 268 #endif 269 #ifdef __HAVE_PTRACE_MACHDEP 270 PTRACE_MACHDEP_REQUEST_CASES 271 #endif 272 /* 273 * You can't read/write the memory or registers of a process 274 * if the tracer is chrooted, and its root directory is not at 275 * or above the root directory of the tracee. 276 */ 277 mutex_exit(t->p_lock); /* XXXSMP */ 278 tmp = proc_isunder(t, l); 279 mutex_enter(t->p_lock); /* XXXSMP */ 280 if (!tmp) { 281 error = EPERM; 282 break; 283 } 284 /*FALLTHROUGH*/ 285 286 case PT_CONTINUE: 287 case PT_KILL: 288 case PT_DETACH: 289 case PT_LWPINFO: 290 case PT_SYSCALL: 291 case PT_DUMPCORE: 292 #ifdef PT_STEP 293 case PT_STEP: 294 #endif 295 /* 296 * You can't do what you want to the process if: 297 * (1) It's not being traced at all, 298 */ 299 if (!ISSET(t->p_slflag, PSL_TRACED)) { 300 error = EPERM; 301 break; 302 } 303 304 /* 305 * (2) it's being traced by procfs (which has 306 * different signal delivery semantics), 307 */ 308 if (ISSET(t->p_slflag, PSL_FSTRACE)) { 309 uprintf("file system traced\n"); 310 error = EBUSY; 311 break; 312 } 313 314 /* 315 * (3) it's not being traced by _you_, or 316 */ 317 if (t->p_pptr != p) { 318 uprintf("parent %d != %d\n", t->p_pptr->p_pid, p->p_pid); 319 error = EBUSY; 320 break; 321 } 322 323 /* 324 * (4) it's not currently stopped. 325 */ 326 if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) { 327 uprintf("stat %d flag %d\n", t->p_stat, 328 !t->p_waited); 329 error = EBUSY; 330 break; 331 } 332 break; 333 334 default: /* It was not a legal request. */ 335 error = EINVAL; 336 break; 337 } 338 339 if (error == 0) 340 error = kauth_authorize_process(l->l_cred, 341 KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req), 342 NULL, NULL); 343 344 if (error != 0) { 345 mutex_exit(proc_lock); 346 mutex_exit(t->p_lock); 347 rw_exit(&t->p_reflock); 348 return error; 349 } 350 351 /* Do single-step fixup if needed. */ 352 FIX_SSTEP(t); 353 354 /* 355 * XXX NJWLWP 356 * 357 * The entire ptrace interface needs work to be useful to a 358 * process with multiple LWPs. For the moment, we'll kluge 359 * this; memory access will be fine, but register access will 360 * be weird. 361 */ 362 lt = LIST_FIRST(&t->p_lwps); 363 KASSERT(lt != NULL); 364 lwp_addref(lt); 365 366 /* 367 * Which locks do we need held? XXX Ugly. 368 */ 369 switch (req) { 370 #ifdef PT_STEP 371 case PT_STEP: 372 #endif 373 case PT_CONTINUE: 374 case PT_DETACH: 375 case PT_KILL: 376 case PT_SYSCALL: 377 case PT_ATTACH: 378 case PT_TRACE_ME: 379 pheld = 1; 380 break; 381 default: 382 mutex_exit(proc_lock); 383 mutex_exit(t->p_lock); 384 pheld = 0; 385 break; 386 } 387 388 /* Now do the operation. */ 389 write = 0; 390 *retval = 0; 391 tmp = 0; 392 393 switch (req) { 394 case PT_TRACE_ME: 395 /* Just set the trace flag. */ 396 SET(t->p_slflag, PSL_TRACED); 397 t->p_opptr = t->p_pptr; 398 break; 399 400 case PT_WRITE_I: /* XXX no separate I and D spaces */ 401 case PT_WRITE_D: 402 #if defined(__HAVE_RAS) 403 /* 404 * Can't write to a RAS 405 */ 406 if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) { 407 error = EACCES; 408 break; 409 } 410 #endif 411 write = 1; 412 tmp = SCARG(uap, data); 413 /* FALLTHROUGH */ 414 415 case PT_READ_I: /* XXX no separate I and D spaces */ 416 case PT_READ_D: 417 /* write = 0 done above. */ 418 iov.iov_base = (void *)&tmp; 419 iov.iov_len = sizeof(tmp); 420 uio.uio_iov = &iov; 421 uio.uio_iovcnt = 1; 422 uio.uio_offset = (off_t)(unsigned long)SCARG(uap, addr); 423 uio.uio_resid = sizeof(tmp); 424 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 425 UIO_SETUP_SYSSPACE(&uio); 426 427 error = process_domem(l, lt, &uio); 428 if (!write) 429 *retval = tmp; 430 break; 431 432 case PT_IO: 433 error = copyin(SCARG(uap, addr), &piod, sizeof(piod)); 434 if (error) 435 break; 436 switch (piod.piod_op) { 437 case PIOD_READ_D: 438 case PIOD_READ_I: 439 uio.uio_rw = UIO_READ; 440 break; 441 case PIOD_WRITE_D: 442 case PIOD_WRITE_I: 443 /* 444 * Can't write to a RAS 445 */ 446 if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) { 447 return (EACCES); 448 } 449 uio.uio_rw = UIO_WRITE; 450 break; 451 default: 452 error = EINVAL; 453 break; 454 } 455 if (error) 456 break; 457 error = proc_vmspace_getref(l->l_proc, &vm); 458 if (error) 459 break; 460 iov.iov_base = piod.piod_addr; 461 iov.iov_len = piod.piod_len; 462 uio.uio_iov = &iov; 463 uio.uio_iovcnt = 1; 464 uio.uio_offset = (off_t)(unsigned long)piod.piod_offs; 465 uio.uio_resid = piod.piod_len; 466 uio.uio_vmspace = vm; 467 468 error = process_domem(l, lt, &uio); 469 piod.piod_len -= uio.uio_resid; 470 (void) copyout(&piod, SCARG(uap, addr), sizeof(piod)); 471 uvmspace_free(vm); 472 break; 473 474 case PT_DUMPCORE: 475 if ((path = SCARG(uap, addr)) != NULL) { 476 char *dst; 477 int len = SCARG(uap, data); 478 if (len < 0 || len >= MAXPATHLEN) { 479 error = EINVAL; 480 break; 481 } 482 dst = malloc(len + 1, M_TEMP, M_WAITOK); 483 if ((error = copyin(path, dst, len)) != 0) { 484 free(dst, M_TEMP); 485 break; 486 } 487 path = dst; 488 path[len] = '\0'; 489 } 490 error = (*coredump_vec)(lt, path); 491 if (path) 492 free(path, M_TEMP); 493 break; 494 495 #ifdef PT_STEP 496 case PT_STEP: 497 /* 498 * From the 4.4BSD PRM: 499 * "Execution continues as in request PT_CONTINUE; however 500 * as soon as possible after execution of at least one 501 * instruction, execution stops again. [ ... ]" 502 */ 503 #endif 504 case PT_CONTINUE: 505 case PT_SYSCALL: 506 case PT_DETACH: 507 if (req == PT_SYSCALL) { 508 if (!ISSET(t->p_slflag, PSL_SYSCALL)) { 509 SET(t->p_slflag, PSL_SYSCALL); 510 #ifdef __HAVE_SYSCALL_INTERN 511 (*t->p_emul->e_syscall_intern)(t); 512 #endif 513 } 514 } else { 515 if (ISSET(t->p_slflag, PSL_SYSCALL)) { 516 CLR(t->p_slflag, PSL_SYSCALL); 517 #ifdef __HAVE_SYSCALL_INTERN 518 (*t->p_emul->e_syscall_intern)(t); 519 #endif 520 } 521 } 522 p->p_trace_enabled = trace_is_enabled(p); 523 524 /* 525 * From the 4.4BSD PRM: 526 * "The data argument is taken as a signal number and the 527 * child's execution continues at location addr as if it 528 * incurred that signal. Normally the signal number will 529 * be either 0 to indicate that the signal that caused the 530 * stop should be ignored, or that value fetched out of 531 * the process's image indicating which signal caused 532 * the stop. If addr is (int *)1 then execution continues 533 * from where it stopped." 534 */ 535 536 /* Check that the data is a valid signal number or zero. */ 537 if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG) { 538 error = EINVAL; 539 break; 540 } 541 542 uvm_lwp_hold(lt); 543 544 /* If the address parameter is not (int *)1, set the pc. */ 545 if ((int *)SCARG(uap, addr) != (int *)1) 546 if ((error = process_set_pc(lt, SCARG(uap, addr))) != 0) { 547 uvm_lwp_rele(lt); 548 break; 549 } 550 551 #ifdef PT_STEP 552 /* 553 * Arrange for a single-step, if that's requested and possible. 554 */ 555 error = process_sstep(lt, req == PT_STEP); 556 if (error) { 557 uvm_lwp_rele(lt); 558 break; 559 } 560 #endif 561 562 uvm_lwp_rele(lt); 563 564 if (req == PT_DETACH) { 565 CLR(t->p_slflag, PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL); 566 567 /* give process back to original parent or init */ 568 if (t->p_opptr != t->p_pptr) { 569 struct proc *pp = t->p_opptr; 570 proc_reparent(t, pp ? pp : initproc); 571 } 572 573 /* not being traced any more */ 574 t->p_opptr = NULL; 575 } 576 577 signo = SCARG(uap, data); 578 sendsig: 579 /* Finally, deliver the requested signal (or none). */ 580 if (t->p_stat == SSTOP) { 581 /* 582 * Unstop the process. If it needs to take a 583 * signal, make all efforts to ensure that at 584 * an LWP runs to see it. 585 */ 586 t->p_xstat = signo; 587 proc_unstop(t); 588 } else if (signo != 0) { 589 KSI_INIT_EMPTY(&ksi); 590 ksi.ksi_signo = signo; 591 kpsignal2(t, &ksi); 592 } 593 break; 594 595 case PT_KILL: 596 /* just send the process a KILL signal. */ 597 signo = SIGKILL; 598 goto sendsig; /* in PT_CONTINUE, above. */ 599 600 case PT_ATTACH: 601 /* 602 * Go ahead and set the trace flag. 603 * Save the old parent (it's reset in 604 * _DETACH, and also in kern_exit.c:wait4() 605 * Reparent the process so that the tracing 606 * proc gets to see all the action. 607 * Stop the target. 608 */ 609 t->p_opptr = t->p_pptr; 610 if (t->p_pptr != p) { 611 struct proc *parent = t->p_pptr; 612 613 if (parent->p_lock < t->p_lock) { 614 if (!mutex_tryenter(parent->p_lock)) { 615 mutex_exit(t->p_lock); 616 mutex_enter(parent->p_lock); 617 } 618 } else if (parent->p_lock > t->p_lock) { 619 mutex_enter(parent->p_lock); 620 } 621 parent->p_slflag |= PSL_CHTRACED; 622 proc_reparent(t, p); 623 if (parent->p_lock != t->p_lock) 624 mutex_exit(parent->p_lock); 625 } 626 SET(t->p_slflag, PSL_TRACED); 627 signo = SIGSTOP; 628 goto sendsig; 629 630 case PT_LWPINFO: 631 if (SCARG(uap, data) != sizeof(pl)) { 632 error = EINVAL; 633 break; 634 } 635 error = copyin(SCARG(uap, addr), &pl, sizeof(pl)); 636 if (error) 637 break; 638 tmp = pl.pl_lwpid; 639 lwp_delref(lt); 640 mutex_enter(t->p_lock); 641 if (tmp == 0) 642 lt = LIST_FIRST(&t->p_lwps); 643 else { 644 lt = lwp_find(t, tmp); 645 if (lt == NULL) { 646 mutex_exit(t->p_lock); 647 error = ESRCH; 648 break; 649 } 650 lt = LIST_NEXT(lt, l_sibling); 651 } 652 while (lt != NULL && lt->l_stat == LSZOMB) 653 lt = LIST_NEXT(lt, l_sibling); 654 pl.pl_lwpid = 0; 655 pl.pl_event = 0; 656 if (lt) { 657 lwp_addref(lt); 658 pl.pl_lwpid = lt->l_lid; 659 if (lt->l_lid == t->p_sigctx.ps_lwp) 660 pl.pl_event = PL_EVENT_SIGNAL; 661 } 662 mutex_exit(t->p_lock); 663 664 error = copyout(&pl, SCARG(uap, addr), sizeof(pl)); 665 break; 666 667 #ifdef PT_SETREGS 668 case PT_SETREGS: 669 write = 1; 670 #endif 671 #ifdef PT_GETREGS 672 case PT_GETREGS: 673 /* write = 0 done above. */ 674 #endif 675 #if defined(PT_SETREGS) || defined(PT_GETREGS) 676 tmp = SCARG(uap, data); 677 if (tmp != 0 && t->p_nlwps > 1) { 678 lwp_delref(lt); 679 mutex_enter(t->p_lock); 680 lt = lwp_find(t, tmp); 681 if (lt == NULL) { 682 mutex_exit(t->p_lock); 683 error = ESRCH; 684 break; 685 } 686 lwp_addref(lt); 687 mutex_exit(t->p_lock); 688 } 689 if (!process_validregs(lt)) 690 error = EINVAL; 691 else { 692 error = proc_vmspace_getref(l->l_proc, &vm); 693 if (error) 694 break; 695 iov.iov_base = SCARG(uap, addr); 696 iov.iov_len = sizeof(struct reg); 697 uio.uio_iov = &iov; 698 uio.uio_iovcnt = 1; 699 uio.uio_offset = 0; 700 uio.uio_resid = sizeof(struct reg); 701 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 702 uio.uio_vmspace = vm; 703 704 error = process_doregs(l, lt, &uio); 705 uvmspace_free(vm); 706 } 707 break; 708 #endif 709 710 #ifdef PT_SETFPREGS 711 case PT_SETFPREGS: 712 write = 1; 713 #endif 714 #ifdef PT_GETFPREGS 715 case PT_GETFPREGS: 716 /* write = 0 done above. */ 717 #endif 718 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 719 tmp = SCARG(uap, data); 720 if (tmp != 0 && t->p_nlwps > 1) { 721 lwp_delref(lt); 722 mutex_enter(t->p_lock); 723 lt = lwp_find(t, tmp); 724 if (lt == NULL) { 725 mutex_exit(t->p_lock); 726 error = ESRCH; 727 break; 728 } 729 lwp_addref(lt); 730 mutex_exit(t->p_lock); 731 } 732 if (!process_validfpregs(lt)) 733 error = EINVAL; 734 else { 735 error = proc_vmspace_getref(l->l_proc, &vm); 736 if (error) 737 break; 738 iov.iov_base = SCARG(uap, addr); 739 iov.iov_len = sizeof(struct fpreg); 740 uio.uio_iov = &iov; 741 uio.uio_iovcnt = 1; 742 uio.uio_offset = 0; 743 uio.uio_resid = sizeof(struct fpreg); 744 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 745 uio.uio_vmspace = vm; 746 747 error = process_dofpregs(l, lt, &uio); 748 uvmspace_free(vm); 749 } 750 break; 751 #endif 752 753 #ifdef __HAVE_PTRACE_MACHDEP 754 PTRACE_MACHDEP_REQUEST_CASES 755 error = ptrace_machdep_dorequest(l, lt, 756 req, SCARG(uap, addr), SCARG(uap, data)); 757 break; 758 #endif 759 } 760 761 if (pheld) { 762 mutex_exit(t->p_lock); 763 mutex_exit(proc_lock); 764 } 765 if (lt != NULL) 766 lwp_delref(lt); 767 rw_exit(&t->p_reflock); 768 769 return error; 770 } 771 772 int 773 process_doregs(struct lwp *curl /*tracer*/, 774 struct lwp *l /*traced*/, 775 struct uio *uio) 776 { 777 #if defined(PT_GETREGS) || defined(PT_SETREGS) 778 int error; 779 struct reg r; 780 char *kv; 781 int kl; 782 783 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 784 return EINVAL; 785 786 kl = sizeof(r); 787 kv = (char *)&r; 788 789 kv += uio->uio_offset; 790 kl -= uio->uio_offset; 791 if ((size_t)kl > uio->uio_resid) 792 kl = uio->uio_resid; 793 794 uvm_lwp_hold(l); 795 796 error = process_read_regs(l, &r); 797 if (error == 0) 798 error = uiomove(kv, kl, uio); 799 if (error == 0 && uio->uio_rw == UIO_WRITE) { 800 if (l->l_stat != LSSTOP) 801 error = EBUSY; 802 else 803 error = process_write_regs(l, &r); 804 } 805 806 uvm_lwp_rele(l); 807 808 uio->uio_offset = 0; 809 return (error); 810 #else 811 return (EINVAL); 812 #endif 813 } 814 815 int 816 process_validregs(struct lwp *l) 817 { 818 819 #if defined(PT_SETREGS) || defined(PT_GETREGS) 820 return ((l->l_flag & LW_SYSTEM) == 0); 821 #else 822 return (0); 823 #endif 824 } 825 826 int 827 process_dofpregs(struct lwp *curl /*tracer*/, 828 struct lwp *l /*traced*/, 829 struct uio *uio) 830 { 831 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) 832 int error; 833 struct fpreg r; 834 char *kv; 835 int kl; 836 837 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 838 return EINVAL; 839 840 kl = sizeof(r); 841 kv = (char *)&r; 842 843 kv += uio->uio_offset; 844 kl -= uio->uio_offset; 845 if ((size_t)kl > uio->uio_resid) 846 kl = uio->uio_resid; 847 848 uvm_lwp_hold(l); 849 850 error = process_read_fpregs(l, &r); 851 if (error == 0) 852 error = uiomove(kv, kl, uio); 853 if (error == 0 && uio->uio_rw == UIO_WRITE) { 854 if (l->l_stat != LSSTOP) 855 error = EBUSY; 856 else 857 error = process_write_fpregs(l, &r); 858 } 859 860 uvm_lwp_rele(l); 861 862 uio->uio_offset = 0; 863 return (error); 864 #else 865 return (EINVAL); 866 #endif 867 } 868 869 int 870 process_validfpregs(struct lwp *l) 871 { 872 873 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 874 return ((l->l_flag & LW_SYSTEM) == 0); 875 #else 876 return (0); 877 #endif 878 } 879 #endif /* PTRACE */ 880 881 #if defined(KTRACE) || defined(PTRACE) 882 int 883 process_domem(struct lwp *curl /*tracer*/, 884 struct lwp *l /*traced*/, 885 struct uio *uio) 886 { 887 struct proc *p = l->l_proc; /* traced */ 888 struct vmspace *vm; 889 int error; 890 891 size_t len; 892 #ifdef PMAP_NEED_PROCWR 893 vaddr_t addr; 894 #endif 895 896 error = 0; 897 len = uio->uio_resid; 898 899 if (len == 0) 900 return (0); 901 902 #ifdef PMAP_NEED_PROCWR 903 addr = uio->uio_offset; 904 #endif 905 906 vm = p->p_vmspace; 907 908 mutex_enter(&vm->vm_map.misc_lock); 909 if ((l->l_flag & LW_WEXIT) || vm->vm_refcnt < 1) 910 error = EFAULT; 911 if (error == 0) 912 p->p_vmspace->vm_refcnt++; /* XXX */ 913 mutex_exit(&vm->vm_map.misc_lock); 914 if (error != 0) 915 return (error); 916 error = uvm_io(&vm->vm_map, uio); 917 uvmspace_free(vm); 918 919 #ifdef PMAP_NEED_PROCWR 920 if (error == 0 && uio->uio_rw == UIO_WRITE) 921 pmap_procwr(p, addr, len); 922 #endif 923 return (error); 924 } 925 #endif /* KTRACE || PTRACE */ 926 927 #if defined(KTRACE) || defined(PTRACE) 928 void 929 process_stoptrace(void) 930 { 931 struct lwp *l = curlwp; 932 struct proc *p = l->l_proc, *pp; 933 934 mutex_enter(proc_lock); 935 mutex_enter(p->p_lock); 936 pp = p->p_pptr; 937 if (pp->p_pid == 1) { 938 CLR(p->p_slflag, PSL_SYSCALL); /* XXXSMP */ 939 mutex_exit(p->p_lock); 940 mutex_exit(proc_lock); 941 return; 942 } 943 944 p->p_xstat = SIGTRAP; 945 proc_stop(p, 1, SIGSTOP); 946 mutex_exit(proc_lock); 947 948 /* 949 * Call issignal() once only, to have it take care of the 950 * pending stop. Signal processing will take place as usual 951 * from userret(). 952 */ 953 KERNEL_UNLOCK_ALL(l, &l->l_biglocks); 954 (void)issignal(l); 955 mutex_exit(p->p_lock); 956 KERNEL_LOCK(l->l_biglocks, l); 957 } 958 #endif /* KTRACE || PTRACE */ 959