1 /* $NetBSD: sys_process.c,v 1.139 2008/04/28 20:24:04 martin 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.139 2008/04/28 20:24:04 martin 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 if (t->p_pptr->p_lock < t->p_lock) { 618 if (!mutex_tryenter(t->p_pptr->p_lock)) { 619 mutex_exit(t->p_lock); 620 mutex_enter(t->p_pptr->p_lock); 621 } 622 } else if (t->p_pptr->p_lock > t->p_lock) { 623 mutex_enter(t->p_pptr->p_lock); 624 } 625 t->p_pptr->p_slflag |= PSL_CHTRACED; 626 proc_reparent(t, p); 627 if (t->p_pptr->p_lock != t->p_lock) 628 mutex_exit(t->p_pptr->p_lock); 629 } 630 SET(t->p_slflag, PSL_TRACED); 631 signo = SIGSTOP; 632 goto sendsig; 633 634 case PT_LWPINFO: 635 if (SCARG(uap, data) != sizeof(pl)) { 636 error = EINVAL; 637 break; 638 } 639 error = copyin(SCARG(uap, addr), &pl, sizeof(pl)); 640 if (error) 641 break; 642 tmp = pl.pl_lwpid; 643 lwp_delref(lt); 644 mutex_enter(t->p_lock); 645 if (tmp == 0) 646 lt = LIST_FIRST(&t->p_lwps); 647 else { 648 lt = lwp_find(p, tmp); 649 if (lt == NULL) { 650 mutex_exit(t->p_lock); 651 error = ESRCH; 652 break; 653 } 654 lt = LIST_NEXT(lt, l_sibling); 655 } 656 while (lt != NULL && lt->l_stat == LSZOMB) 657 lt = LIST_NEXT(lt, l_sibling); 658 pl.pl_lwpid = 0; 659 pl.pl_event = 0; 660 if (lt) { 661 lwp_addref(lt); 662 pl.pl_lwpid = lt->l_lid; 663 if (lt->l_lid == t->p_sigctx.ps_lwp) 664 pl.pl_event = PL_EVENT_SIGNAL; 665 } 666 mutex_exit(t->p_lock); 667 668 error = copyout(&pl, SCARG(uap, addr), sizeof(pl)); 669 break; 670 671 #ifdef PT_SETREGS 672 case PT_SETREGS: 673 write = 1; 674 #endif 675 #ifdef PT_GETREGS 676 case PT_GETREGS: 677 /* write = 0 done above. */ 678 #endif 679 #if defined(PT_SETREGS) || defined(PT_GETREGS) 680 tmp = SCARG(uap, data); 681 if (tmp != 0 && t->p_nlwps > 1) { 682 lwp_delref(lt); 683 mutex_enter(t->p_lock); 684 lt = lwp_find(t, tmp); 685 if (lt == NULL) { 686 mutex_exit(t->p_lock); 687 error = ESRCH; 688 break; 689 } 690 lwp_addref(lt); 691 mutex_exit(t->p_lock); 692 } 693 if (!process_validregs(lt)) 694 error = EINVAL; 695 else { 696 error = proc_vmspace_getref(l->l_proc, &vm); 697 if (error) 698 break; 699 iov.iov_base = SCARG(uap, addr); 700 iov.iov_len = sizeof(struct reg); 701 uio.uio_iov = &iov; 702 uio.uio_iovcnt = 1; 703 uio.uio_offset = 0; 704 uio.uio_resid = sizeof(struct reg); 705 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 706 uio.uio_vmspace = vm; 707 708 error = process_doregs(l, lt, &uio); 709 uvmspace_free(vm); 710 } 711 break; 712 #endif 713 714 #ifdef PT_SETFPREGS 715 case PT_SETFPREGS: 716 write = 1; 717 #endif 718 #ifdef PT_GETFPREGS 719 case PT_GETFPREGS: 720 /* write = 0 done above. */ 721 #endif 722 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 723 tmp = SCARG(uap, data); 724 if (tmp != 0 && t->p_nlwps > 1) { 725 lwp_delref(lt); 726 mutex_enter(t->p_lock); 727 lt = lwp_find(t, tmp); 728 if (lt == NULL) { 729 mutex_exit(t->p_lock); 730 error = ESRCH; 731 break; 732 } 733 lwp_addref(lt); 734 mutex_exit(t->p_lock); 735 } 736 if (!process_validfpregs(lt)) 737 error = EINVAL; 738 else { 739 error = proc_vmspace_getref(l->l_proc, &vm); 740 if (error) 741 break; 742 iov.iov_base = SCARG(uap, addr); 743 iov.iov_len = sizeof(struct fpreg); 744 uio.uio_iov = &iov; 745 uio.uio_iovcnt = 1; 746 uio.uio_offset = 0; 747 uio.uio_resid = sizeof(struct fpreg); 748 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 749 uio.uio_vmspace = vm; 750 751 error = process_dofpregs(l, lt, &uio); 752 uvmspace_free(vm); 753 } 754 break; 755 #endif 756 757 #ifdef __HAVE_PTRACE_MACHDEP 758 PTRACE_MACHDEP_REQUEST_CASES 759 error = ptrace_machdep_dorequest(l, lt, 760 req, SCARG(uap, addr), SCARG(uap, data)); 761 break; 762 #endif 763 } 764 765 if (pheld) { 766 mutex_exit(t->p_lock); 767 mutex_exit(proc_lock); 768 } 769 if (lt != NULL) 770 lwp_delref(lt); 771 rw_exit(&t->p_reflock); 772 773 return error; 774 } 775 776 int 777 process_doregs(struct lwp *curl /*tracer*/, 778 struct lwp *l /*traced*/, 779 struct uio *uio) 780 { 781 #if defined(PT_GETREGS) || defined(PT_SETREGS) 782 int error; 783 struct reg r; 784 char *kv; 785 int kl; 786 787 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 788 return EINVAL; 789 790 kl = sizeof(r); 791 kv = (char *)&r; 792 793 kv += uio->uio_offset; 794 kl -= uio->uio_offset; 795 if ((size_t)kl > uio->uio_resid) 796 kl = uio->uio_resid; 797 798 uvm_lwp_hold(l); 799 800 error = process_read_regs(l, &r); 801 if (error == 0) 802 error = uiomove(kv, kl, uio); 803 if (error == 0 && uio->uio_rw == UIO_WRITE) { 804 if (l->l_stat != LSSTOP) 805 error = EBUSY; 806 else 807 error = process_write_regs(l, &r); 808 } 809 810 uvm_lwp_rele(l); 811 812 uio->uio_offset = 0; 813 return (error); 814 #else 815 return (EINVAL); 816 #endif 817 } 818 819 int 820 process_validregs(struct lwp *l) 821 { 822 823 #if defined(PT_SETREGS) || defined(PT_GETREGS) 824 return ((l->l_flag & LW_SYSTEM) == 0); 825 #else 826 return (0); 827 #endif 828 } 829 830 int 831 process_dofpregs(struct lwp *curl /*tracer*/, 832 struct lwp *l /*traced*/, 833 struct uio *uio) 834 { 835 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) 836 int error; 837 struct fpreg r; 838 char *kv; 839 int kl; 840 841 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 842 return EINVAL; 843 844 kl = sizeof(r); 845 kv = (char *)&r; 846 847 kv += uio->uio_offset; 848 kl -= uio->uio_offset; 849 if ((size_t)kl > uio->uio_resid) 850 kl = uio->uio_resid; 851 852 uvm_lwp_hold(l); 853 854 error = process_read_fpregs(l, &r); 855 if (error == 0) 856 error = uiomove(kv, kl, uio); 857 if (error == 0 && uio->uio_rw == UIO_WRITE) { 858 if (l->l_stat != LSSTOP) 859 error = EBUSY; 860 else 861 error = process_write_fpregs(l, &r); 862 } 863 864 uvm_lwp_rele(l); 865 866 uio->uio_offset = 0; 867 return (error); 868 #else 869 return (EINVAL); 870 #endif 871 } 872 873 int 874 process_validfpregs(struct lwp *l) 875 { 876 877 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 878 return ((l->l_flag & LW_SYSTEM) == 0); 879 #else 880 return (0); 881 #endif 882 } 883 #endif /* PTRACE */ 884 885 #if defined(KTRACE) || defined(PTRACE) 886 int 887 process_domem(struct lwp *curl /*tracer*/, 888 struct lwp *l /*traced*/, 889 struct uio *uio) 890 { 891 struct proc *p = l->l_proc; /* traced */ 892 struct vmspace *vm; 893 int error; 894 895 size_t len; 896 #ifdef PMAP_NEED_PROCWR 897 vaddr_t addr; 898 #endif 899 900 error = 0; 901 len = uio->uio_resid; 902 903 if (len == 0) 904 return (0); 905 906 #ifdef PMAP_NEED_PROCWR 907 addr = uio->uio_offset; 908 #endif 909 910 vm = p->p_vmspace; 911 912 mutex_enter(&vm->vm_map.misc_lock); 913 if ((l->l_flag & LW_WEXIT) || vm->vm_refcnt < 1) 914 error = EFAULT; 915 if (error == 0) 916 p->p_vmspace->vm_refcnt++; /* XXX */ 917 mutex_exit(&vm->vm_map.misc_lock); 918 if (error != 0) 919 return (error); 920 error = uvm_io(&vm->vm_map, uio); 921 uvmspace_free(vm); 922 923 #ifdef PMAP_NEED_PROCWR 924 if (error == 0 && uio->uio_rw == UIO_WRITE) 925 pmap_procwr(p, addr, len); 926 #endif 927 return (error); 928 } 929 #endif /* KTRACE || PTRACE */ 930 931 #if defined(KTRACE) || defined(PTRACE) 932 void 933 process_stoptrace(void) 934 { 935 struct lwp *l = curlwp; 936 struct proc *p = l->l_proc, *pp; 937 938 mutex_enter(proc_lock); 939 mutex_enter(p->p_lock); 940 pp = p->p_pptr; 941 if (pp->p_pid == 1) { 942 CLR(p->p_slflag, PSL_SYSCALL); /* XXXSMP */ 943 mutex_exit(p->p_lock); 944 mutex_exit(proc_lock); 945 return; 946 } 947 948 p->p_xstat = SIGTRAP; 949 proc_stop(p, 1, SIGSTOP); 950 mutex_exit(proc_lock); 951 952 /* 953 * Call issignal() once only, to have it take care of the 954 * pending stop. Signal processing will take place as usual 955 * from userret(). 956 */ 957 KERNEL_UNLOCK_ALL(l, &l->l_biglocks); 958 (void)issignal(l); 959 mutex_exit(p->p_lock); 960 KERNEL_LOCK(l->l_biglocks - 1, l); 961 } 962 #endif /* KTRACE || PTRACE */ 963