1 /* $NetBSD: sys_process.c,v 1.141 2008/07/02 19:49:58 rmind 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.141 2008/07/02 19:49:58 rmind 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 = LIST_FIRST(&t->p_lwps); 368 KASSERT(lt != NULL); 369 lwp_addref(lt); 370 371 /* 372 * Which locks do we need held? XXX Ugly. 373 */ 374 switch (req) { 375 #ifdef PT_STEP 376 case PT_STEP: 377 #endif 378 case PT_CONTINUE: 379 case PT_DETACH: 380 case PT_KILL: 381 case PT_SYSCALL: 382 case PT_ATTACH: 383 case PT_TRACE_ME: 384 pheld = 1; 385 break; 386 default: 387 mutex_exit(proc_lock); 388 mutex_exit(t->p_lock); 389 pheld = 0; 390 break; 391 } 392 393 /* Now do the operation. */ 394 write = 0; 395 *retval = 0; 396 tmp = 0; 397 398 switch (req) { 399 case PT_TRACE_ME: 400 /* Just set the trace flag. */ 401 SET(t->p_slflag, PSL_TRACED); 402 t->p_opptr = t->p_pptr; 403 break; 404 405 case PT_WRITE_I: /* XXX no separate I and D spaces */ 406 case PT_WRITE_D: 407 #if defined(__HAVE_RAS) 408 /* 409 * Can't write to a RAS 410 */ 411 if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) { 412 error = EACCES; 413 break; 414 } 415 #endif 416 write = 1; 417 tmp = SCARG(uap, data); 418 /* FALLTHROUGH */ 419 420 case PT_READ_I: /* XXX no separate I and D spaces */ 421 case PT_READ_D: 422 /* write = 0 done above. */ 423 iov.iov_base = (void *)&tmp; 424 iov.iov_len = sizeof(tmp); 425 uio.uio_iov = &iov; 426 uio.uio_iovcnt = 1; 427 uio.uio_offset = (off_t)(unsigned long)SCARG(uap, addr); 428 uio.uio_resid = sizeof(tmp); 429 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 430 UIO_SETUP_SYSSPACE(&uio); 431 432 error = process_domem(l, lt, &uio); 433 if (!write) 434 *retval = tmp; 435 break; 436 437 case PT_IO: 438 error = copyin(SCARG(uap, addr), &piod, sizeof(piod)); 439 if (error) 440 break; 441 switch (piod.piod_op) { 442 case PIOD_READ_D: 443 case PIOD_READ_I: 444 uio.uio_rw = UIO_READ; 445 break; 446 case PIOD_WRITE_D: 447 case PIOD_WRITE_I: 448 /* 449 * Can't write to a RAS 450 */ 451 if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) { 452 return (EACCES); 453 } 454 uio.uio_rw = UIO_WRITE; 455 break; 456 default: 457 error = EINVAL; 458 break; 459 } 460 if (error) 461 break; 462 error = proc_vmspace_getref(l->l_proc, &vm); 463 if (error) 464 break; 465 iov.iov_base = piod.piod_addr; 466 iov.iov_len = piod.piod_len; 467 uio.uio_iov = &iov; 468 uio.uio_iovcnt = 1; 469 uio.uio_offset = (off_t)(unsigned long)piod.piod_offs; 470 uio.uio_resid = piod.piod_len; 471 uio.uio_vmspace = vm; 472 473 error = process_domem(l, lt, &uio); 474 piod.piod_len -= uio.uio_resid; 475 (void) copyout(&piod, SCARG(uap, addr), sizeof(piod)); 476 uvmspace_free(vm); 477 break; 478 479 #ifdef COREDUMP 480 case PT_DUMPCORE: 481 if ((path = SCARG(uap, addr)) != NULL) { 482 char *dst; 483 int len = SCARG(uap, data); 484 if (len < 0 || len >= MAXPATHLEN) { 485 error = EINVAL; 486 break; 487 } 488 dst = malloc(len + 1, M_TEMP, M_WAITOK); 489 if ((error = copyin(path, dst, len)) != 0) { 490 free(dst, M_TEMP); 491 break; 492 } 493 path = dst; 494 path[len] = '\0'; 495 } 496 error = coredump(lt, path); 497 if (path) 498 free(path, M_TEMP); 499 break; 500 #endif 501 502 #ifdef PT_STEP 503 case PT_STEP: 504 /* 505 * From the 4.4BSD PRM: 506 * "Execution continues as in request PT_CONTINUE; however 507 * as soon as possible after execution of at least one 508 * instruction, execution stops again. [ ... ]" 509 */ 510 #endif 511 case PT_CONTINUE: 512 case PT_SYSCALL: 513 case PT_DETACH: 514 if (req == PT_SYSCALL) { 515 if (!ISSET(t->p_slflag, PSL_SYSCALL)) { 516 SET(t->p_slflag, PSL_SYSCALL); 517 #ifdef __HAVE_SYSCALL_INTERN 518 (*t->p_emul->e_syscall_intern)(t); 519 #endif 520 } 521 } else { 522 if (ISSET(t->p_slflag, PSL_SYSCALL)) { 523 CLR(t->p_slflag, PSL_SYSCALL); 524 #ifdef __HAVE_SYSCALL_INTERN 525 (*t->p_emul->e_syscall_intern)(t); 526 #endif 527 } 528 } 529 p->p_trace_enabled = trace_is_enabled(p); 530 531 /* 532 * From the 4.4BSD PRM: 533 * "The data argument is taken as a signal number and the 534 * child's execution continues at location addr as if it 535 * incurred that signal. Normally the signal number will 536 * be either 0 to indicate that the signal that caused the 537 * stop should be ignored, or that value fetched out of 538 * the process's image indicating which signal caused 539 * the stop. If addr is (int *)1 then execution continues 540 * from where it stopped." 541 */ 542 543 /* Check that the data is a valid signal number or zero. */ 544 if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG) { 545 error = EINVAL; 546 break; 547 } 548 549 uvm_lwp_hold(lt); 550 551 /* If the address parameter is not (int *)1, set the pc. */ 552 if ((int *)SCARG(uap, addr) != (int *)1) 553 if ((error = process_set_pc(lt, SCARG(uap, addr))) != 0) { 554 uvm_lwp_rele(lt); 555 break; 556 } 557 558 #ifdef PT_STEP 559 /* 560 * Arrange for a single-step, if that's requested and possible. 561 */ 562 error = process_sstep(lt, req == PT_STEP); 563 if (error) { 564 uvm_lwp_rele(lt); 565 break; 566 } 567 #endif 568 569 uvm_lwp_rele(lt); 570 571 if (req == PT_DETACH) { 572 CLR(t->p_slflag, PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL); 573 574 /* give process back to original parent or init */ 575 if (t->p_opptr != t->p_pptr) { 576 struct proc *pp = t->p_opptr; 577 proc_reparent(t, pp ? pp : initproc); 578 } 579 580 /* not being traced any more */ 581 t->p_opptr = NULL; 582 } 583 584 signo = SCARG(uap, data); 585 sendsig: 586 /* Finally, deliver the requested signal (or none). */ 587 if (t->p_stat == SSTOP) { 588 /* 589 * Unstop the process. If it needs to take a 590 * signal, make all efforts to ensure that at 591 * an LWP runs to see it. 592 */ 593 t->p_xstat = signo; 594 proc_unstop(t); 595 } else if (signo != 0) { 596 KSI_INIT_EMPTY(&ksi); 597 ksi.ksi_signo = signo; 598 kpsignal2(t, &ksi); 599 } 600 break; 601 602 case PT_KILL: 603 /* just send the process a KILL signal. */ 604 signo = SIGKILL; 605 goto sendsig; /* in PT_CONTINUE, above. */ 606 607 case PT_ATTACH: 608 /* 609 * Go ahead and set the trace flag. 610 * Save the old parent (it's reset in 611 * _DETACH, and also in kern_exit.c:wait4() 612 * Reparent the process so that the tracing 613 * proc gets to see all the action. 614 * Stop the target. 615 */ 616 t->p_opptr = t->p_pptr; 617 if (t->p_pptr != p) { 618 struct proc *parent = t->p_pptr; 619 620 if (parent->p_lock < t->p_lock) { 621 if (!mutex_tryenter(parent->p_lock)) { 622 mutex_exit(t->p_lock); 623 mutex_enter(parent->p_lock); 624 } 625 } else if (parent->p_lock > t->p_lock) { 626 mutex_enter(parent->p_lock); 627 } 628 parent->p_slflag |= PSL_CHTRACED; 629 proc_reparent(t, p); 630 if (parent->p_lock != t->p_lock) 631 mutex_exit(parent->p_lock); 632 } 633 SET(t->p_slflag, PSL_TRACED); 634 signo = SIGSTOP; 635 goto sendsig; 636 637 case PT_LWPINFO: 638 if (SCARG(uap, data) != sizeof(pl)) { 639 error = EINVAL; 640 break; 641 } 642 error = copyin(SCARG(uap, addr), &pl, sizeof(pl)); 643 if (error) 644 break; 645 tmp = pl.pl_lwpid; 646 lwp_delref(lt); 647 mutex_enter(t->p_lock); 648 if (tmp == 0) 649 lt = LIST_FIRST(&t->p_lwps); 650 else { 651 lt = lwp_find(p, tmp); 652 if (lt == NULL) { 653 mutex_exit(t->p_lock); 654 error = ESRCH; 655 break; 656 } 657 lt = LIST_NEXT(lt, l_sibling); 658 } 659 while (lt != NULL && lt->l_stat == LSZOMB) 660 lt = LIST_NEXT(lt, l_sibling); 661 pl.pl_lwpid = 0; 662 pl.pl_event = 0; 663 if (lt) { 664 lwp_addref(lt); 665 pl.pl_lwpid = lt->l_lid; 666 if (lt->l_lid == t->p_sigctx.ps_lwp) 667 pl.pl_event = PL_EVENT_SIGNAL; 668 } 669 mutex_exit(t->p_lock); 670 671 error = copyout(&pl, SCARG(uap, addr), sizeof(pl)); 672 break; 673 674 #ifdef PT_SETREGS 675 case PT_SETREGS: 676 write = 1; 677 #endif 678 #ifdef PT_GETREGS 679 case PT_GETREGS: 680 /* write = 0 done above. */ 681 #endif 682 #if defined(PT_SETREGS) || defined(PT_GETREGS) 683 tmp = SCARG(uap, data); 684 if (tmp != 0 && t->p_nlwps > 1) { 685 lwp_delref(lt); 686 mutex_enter(t->p_lock); 687 lt = lwp_find(t, tmp); 688 if (lt == NULL) { 689 mutex_exit(t->p_lock); 690 error = ESRCH; 691 break; 692 } 693 lwp_addref(lt); 694 mutex_exit(t->p_lock); 695 } 696 if (!process_validregs(lt)) 697 error = EINVAL; 698 else { 699 error = proc_vmspace_getref(l->l_proc, &vm); 700 if (error) 701 break; 702 iov.iov_base = SCARG(uap, addr); 703 iov.iov_len = sizeof(struct reg); 704 uio.uio_iov = &iov; 705 uio.uio_iovcnt = 1; 706 uio.uio_offset = 0; 707 uio.uio_resid = sizeof(struct reg); 708 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 709 uio.uio_vmspace = vm; 710 711 error = process_doregs(l, lt, &uio); 712 uvmspace_free(vm); 713 } 714 break; 715 #endif 716 717 #ifdef PT_SETFPREGS 718 case PT_SETFPREGS: 719 write = 1; 720 #endif 721 #ifdef PT_GETFPREGS 722 case PT_GETFPREGS: 723 /* write = 0 done above. */ 724 #endif 725 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 726 tmp = SCARG(uap, data); 727 if (tmp != 0 && t->p_nlwps > 1) { 728 lwp_delref(lt); 729 mutex_enter(t->p_lock); 730 lt = lwp_find(t, tmp); 731 if (lt == NULL) { 732 mutex_exit(t->p_lock); 733 error = ESRCH; 734 break; 735 } 736 lwp_addref(lt); 737 mutex_exit(t->p_lock); 738 } 739 if (!process_validfpregs(lt)) 740 error = EINVAL; 741 else { 742 error = proc_vmspace_getref(l->l_proc, &vm); 743 if (error) 744 break; 745 iov.iov_base = SCARG(uap, addr); 746 iov.iov_len = sizeof(struct fpreg); 747 uio.uio_iov = &iov; 748 uio.uio_iovcnt = 1; 749 uio.uio_offset = 0; 750 uio.uio_resid = sizeof(struct fpreg); 751 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 752 uio.uio_vmspace = vm; 753 754 error = process_dofpregs(l, lt, &uio); 755 uvmspace_free(vm); 756 } 757 break; 758 #endif 759 760 #ifdef __HAVE_PTRACE_MACHDEP 761 PTRACE_MACHDEP_REQUEST_CASES 762 error = ptrace_machdep_dorequest(l, lt, 763 req, SCARG(uap, addr), SCARG(uap, data)); 764 break; 765 #endif 766 } 767 768 if (pheld) { 769 mutex_exit(t->p_lock); 770 mutex_exit(proc_lock); 771 } 772 if (lt != NULL) 773 lwp_delref(lt); 774 rw_exit(&t->p_reflock); 775 776 return error; 777 } 778 779 int 780 process_doregs(struct lwp *curl /*tracer*/, 781 struct lwp *l /*traced*/, 782 struct uio *uio) 783 { 784 #if defined(PT_GETREGS) || defined(PT_SETREGS) 785 int error; 786 struct reg r; 787 char *kv; 788 int kl; 789 790 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 791 return EINVAL; 792 793 kl = sizeof(r); 794 kv = (char *)&r; 795 796 kv += uio->uio_offset; 797 kl -= uio->uio_offset; 798 if ((size_t)kl > uio->uio_resid) 799 kl = uio->uio_resid; 800 801 uvm_lwp_hold(l); 802 803 error = process_read_regs(l, &r); 804 if (error == 0) 805 error = uiomove(kv, kl, uio); 806 if (error == 0 && uio->uio_rw == UIO_WRITE) { 807 if (l->l_stat != LSSTOP) 808 error = EBUSY; 809 else 810 error = process_write_regs(l, &r); 811 } 812 813 uvm_lwp_rele(l); 814 815 uio->uio_offset = 0; 816 return (error); 817 #else 818 return (EINVAL); 819 #endif 820 } 821 822 int 823 process_validregs(struct lwp *l) 824 { 825 826 #if defined(PT_SETREGS) || defined(PT_GETREGS) 827 return ((l->l_flag & LW_SYSTEM) == 0); 828 #else 829 return (0); 830 #endif 831 } 832 833 int 834 process_dofpregs(struct lwp *curl /*tracer*/, 835 struct lwp *l /*traced*/, 836 struct uio *uio) 837 { 838 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) 839 int error; 840 struct fpreg r; 841 char *kv; 842 int kl; 843 844 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 845 return EINVAL; 846 847 kl = sizeof(r); 848 kv = (char *)&r; 849 850 kv += uio->uio_offset; 851 kl -= uio->uio_offset; 852 if ((size_t)kl > uio->uio_resid) 853 kl = uio->uio_resid; 854 855 uvm_lwp_hold(l); 856 857 error = process_read_fpregs(l, &r); 858 if (error == 0) 859 error = uiomove(kv, kl, uio); 860 if (error == 0 && uio->uio_rw == UIO_WRITE) { 861 if (l->l_stat != LSSTOP) 862 error = EBUSY; 863 else 864 error = process_write_fpregs(l, &r); 865 } 866 867 uvm_lwp_rele(l); 868 869 uio->uio_offset = 0; 870 return (error); 871 #else 872 return (EINVAL); 873 #endif 874 } 875 876 int 877 process_validfpregs(struct lwp *l) 878 { 879 880 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 881 return ((l->l_flag & LW_SYSTEM) == 0); 882 #else 883 return (0); 884 #endif 885 } 886 #endif /* PTRACE */ 887 888 #if defined(KTRACE) || defined(PTRACE) 889 int 890 process_domem(struct lwp *curl /*tracer*/, 891 struct lwp *l /*traced*/, 892 struct uio *uio) 893 { 894 struct proc *p = l->l_proc; /* traced */ 895 struct vmspace *vm; 896 int error; 897 898 size_t len; 899 #ifdef PMAP_NEED_PROCWR 900 vaddr_t addr; 901 #endif 902 903 error = 0; 904 len = uio->uio_resid; 905 906 if (len == 0) 907 return (0); 908 909 #ifdef PMAP_NEED_PROCWR 910 addr = uio->uio_offset; 911 #endif 912 913 vm = p->p_vmspace; 914 915 mutex_enter(&vm->vm_map.misc_lock); 916 if ((l->l_flag & LW_WEXIT) || vm->vm_refcnt < 1) 917 error = EFAULT; 918 if (error == 0) 919 p->p_vmspace->vm_refcnt++; /* XXX */ 920 mutex_exit(&vm->vm_map.misc_lock); 921 if (error != 0) 922 return (error); 923 error = uvm_io(&vm->vm_map, uio); 924 uvmspace_free(vm); 925 926 #ifdef PMAP_NEED_PROCWR 927 if (error == 0 && uio->uio_rw == UIO_WRITE) 928 pmap_procwr(p, addr, len); 929 #endif 930 return (error); 931 } 932 #endif /* KTRACE || PTRACE */ 933 934 #if defined(KTRACE) || defined(PTRACE) 935 void 936 process_stoptrace(void) 937 { 938 struct lwp *l = curlwp; 939 struct proc *p = l->l_proc, *pp; 940 941 mutex_enter(proc_lock); 942 mutex_enter(p->p_lock); 943 pp = p->p_pptr; 944 if (pp->p_pid == 1) { 945 CLR(p->p_slflag, PSL_SYSCALL); /* XXXSMP */ 946 mutex_exit(p->p_lock); 947 mutex_exit(proc_lock); 948 return; 949 } 950 951 p->p_xstat = SIGTRAP; 952 proc_stop(p, 1, SIGSTOP); 953 mutex_exit(proc_lock); 954 955 /* 956 * Call issignal() once only, to have it take care of the 957 * pending stop. Signal processing will take place as usual 958 * from userret(). 959 */ 960 KERNEL_UNLOCK_ALL(l, &l->l_biglocks); 961 (void)issignal(l); 962 mutex_exit(p->p_lock); 963 KERNEL_LOCK(l->l_biglocks - 1, l); 964 } 965 #endif /* KTRACE || PTRACE */ 966