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