1 /* $NetBSD: sys_ptrace_common.c,v 1.22 2017/05/03 15:53:31 kamil Exp $ */ 2 3 /*- 4 * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Andrew Doran. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /*- 33 * Copyright (c) 1982, 1986, 1989, 1993 34 * The Regents of the University of California. All rights reserved. 35 * (c) UNIX System Laboratories, Inc. 36 * All or some portions of this file are derived from material licensed 37 * to the University of California by American Telephone and Telegraph 38 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 39 * the permission of UNIX System Laboratories, Inc. 40 * 41 * This code is derived from software contributed to Berkeley by 42 * Jan-Simon Pendry. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. Neither the name of the University nor the names of its contributors 53 * may be used to endorse or promote products derived from this software 54 * without specific prior written permission. 55 * 56 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 57 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 58 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 59 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 60 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 61 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 62 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 63 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 64 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 65 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 66 * SUCH DAMAGE. 67 * 68 * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 69 */ 70 71 /*- 72 * Copyright (c) 1993 Jan-Simon Pendry. 73 * Copyright (c) 1994 Christopher G. Demetriou. All rights reserved. 74 * 75 * This code is derived from software contributed to Berkeley by 76 * Jan-Simon Pendry. 77 * 78 * Redistribution and use in source and binary forms, with or without 79 * modification, are permitted provided that the following conditions 80 * are met: 81 * 1. Redistributions of source code must retain the above copyright 82 * notice, this list of conditions and the following disclaimer. 83 * 2. Redistributions in binary form must reproduce the above copyright 84 * notice, this list of conditions and the following disclaimer in the 85 * documentation and/or other materials provided with the distribution. 86 * 3. All advertising materials mentioning features or use of this software 87 * must display the following acknowledgement: 88 * This product includes software developed by the University of 89 * California, Berkeley and its contributors. 90 * 4. Neither the name of the University nor the names of its contributors 91 * may be used to endorse or promote products derived from this software 92 * without specific prior written permission. 93 * 94 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 95 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 96 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 97 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 98 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 99 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 100 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 101 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 102 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 103 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 104 * SUCH DAMAGE. 105 * 106 * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 107 */ 108 109 /* 110 * References: 111 * (1) Bach's "The Design of the UNIX Operating System", 112 * (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution, 113 * (3) the "4.4BSD Programmer's Reference Manual" published 114 * by USENIX and O'Reilly & Associates. 115 * The 4.4BSD PRM does a reasonably good job of documenting what the various 116 * ptrace() requests should actually do, and its text is quoted several times 117 * in this file. 118 */ 119 120 #include <sys/cdefs.h> 121 __KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.22 2017/05/03 15:53:31 kamil Exp $"); 122 123 #ifdef _KERNEL_OPT 124 #include "opt_ptrace.h" 125 #include "opt_ktrace.h" 126 #include "opt_pax.h" 127 #endif 128 129 #include <sys/param.h> 130 #include <sys/systm.h> 131 #include <sys/proc.h> 132 #include <sys/errno.h> 133 #include <sys/exec.h> 134 #include <sys/pax.h> 135 #include <sys/ptrace.h> 136 #include <sys/uio.h> 137 #include <sys/ras.h> 138 #include <sys/kmem.h> 139 #include <sys/kauth.h> 140 #include <sys/mount.h> 141 #include <sys/syscallargs.h> 142 #include <sys/module.h> 143 #include <sys/condvar.h> 144 #include <sys/mutex.h> 145 146 #include <uvm/uvm_extern.h> 147 148 #include <machine/reg.h> 149 150 #ifdef PTRACE 151 152 # ifdef DEBUG 153 # define DPRINTF(a) uprintf a 154 # else 155 # define DPRINTF(a) 156 # endif 157 158 static kauth_listener_t ptrace_listener; 159 static int process_auxv_offset(struct proc *, struct uio *); 160 161 #if 0 162 static int ptrace_cbref; 163 static kmutex_t ptrace_mtx; 164 static kcondvar_t ptrace_cv; 165 #endif 166 167 static int 168 ptrace_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, 169 void *arg0, void *arg1, void *arg2, void *arg3) 170 { 171 struct proc *p; 172 int result; 173 174 result = KAUTH_RESULT_DEFER; 175 p = arg0; 176 177 #if 0 178 mutex_enter(&ptrace_mtx); 179 ptrace_cbref++; 180 mutex_exit(&ptrace_mtx); 181 #endif 182 if (action != KAUTH_PROCESS_PTRACE) 183 goto out; 184 185 switch ((u_long)arg1) { 186 case PT_TRACE_ME: 187 case PT_ATTACH: 188 case PT_WRITE_I: 189 case PT_WRITE_D: 190 case PT_READ_I: 191 case PT_READ_D: 192 case PT_IO: 193 #ifdef PT_GETREGS 194 case PT_GETREGS: 195 #endif 196 #ifdef PT_SETREGS 197 case PT_SETREGS: 198 #endif 199 #ifdef PT_GETFPREGS 200 case PT_GETFPREGS: 201 #endif 202 #ifdef PT_SETFPREGS 203 case PT_SETFPREGS: 204 #endif 205 #ifdef PT_GETDBREGS 206 case PT_GETDBREGS: 207 #endif 208 #ifdef PT_SETDBREGS 209 case PT_SETDBREGS: 210 #endif 211 case PT_SET_EVENT_MASK: 212 case PT_GET_EVENT_MASK: 213 case PT_GET_PROCESS_STATE: 214 case PT_SET_SIGINFO: 215 case PT_GET_SIGINFO: 216 case PT_SET_SIGMASK: 217 case PT_GET_SIGMASK: 218 #ifdef __HAVE_PTRACE_MACHDEP 219 PTRACE_MACHDEP_REQUEST_CASES 220 #endif 221 if (kauth_cred_getuid(cred) != kauth_cred_getuid(p->p_cred) || 222 ISSET(p->p_flag, PK_SUGID)) { 223 break; 224 } 225 226 result = KAUTH_RESULT_ALLOW; 227 228 break; 229 230 #ifdef PT_STEP 231 case PT_STEP: 232 case PT_SETSTEP: 233 case PT_CLEARSTEP: 234 #endif 235 case PT_CONTINUE: 236 case PT_KILL: 237 case PT_DETACH: 238 case PT_LWPINFO: 239 case PT_SYSCALL: 240 case PT_SYSCALLEMU: 241 case PT_DUMPCORE: 242 case PT_RESUME: 243 case PT_SUSPEND: 244 result = KAUTH_RESULT_ALLOW; 245 break; 246 247 default: 248 break; 249 } 250 251 out: 252 #if 0 253 mutex_enter(&ptrace_mtx); 254 if (--ptrace_cbref == 0) 255 cv_broadcast(&ptrace_cv); 256 mutex_exit(&ptrace_mtx); 257 #endif 258 259 return result; 260 } 261 262 int 263 ptrace_init(void) 264 { 265 266 #if 0 267 mutex_init(&ptrace_mtx, MUTEX_DEFAULT, IPL_NONE); 268 cv_init(&ptrace_cv, "ptracecb"); 269 ptrace_cbref = 0; 270 #endif 271 ptrace_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS, 272 ptrace_listener_cb, NULL); 273 return 0; 274 } 275 276 int 277 ptrace_fini(void) 278 { 279 280 kauth_unlisten_scope(ptrace_listener); 281 282 #if 0 283 /* Make sure no-one is executing our kauth listener */ 284 285 mutex_enter(&ptrace_mtx); 286 while (ptrace_cbref != 0) 287 cv_wait(&ptrace_cv, &ptrace_mtx); 288 mutex_exit(&ptrace_mtx); 289 mutex_destroy(&ptrace_mtx); 290 cv_destroy(&ptrace_cv); 291 #endif 292 293 return 0; 294 } 295 296 int 297 do_ptrace(struct ptrace_methods *ptm, struct lwp *l, int req, pid_t pid, 298 void *addr, int data, register_t *retval) 299 { 300 struct proc *p = l->l_proc; 301 struct lwp *lt; 302 struct lwp *lt2; 303 struct proc *t; /* target process */ 304 struct uio uio; 305 struct iovec iov; 306 struct ptrace_io_desc piod; 307 struct ptrace_event pe; 308 struct ptrace_state ps; 309 struct ptrace_lwpinfo pl; 310 struct ptrace_siginfo psi; 311 struct vmspace *vm; 312 int error, write, tmp, pheld; 313 int signo = 0; 314 int resume_all; 315 ksiginfo_t ksi; 316 char *path; 317 int len = 0; 318 error = 0; 319 320 /* 321 * If attaching or detaching, we need to get a write hold on the 322 * proclist lock so that we can re-parent the target process. 323 */ 324 mutex_enter(proc_lock); 325 326 /* "A foolish consistency..." XXX */ 327 if (req == PT_TRACE_ME) { 328 t = p; 329 mutex_enter(t->p_lock); 330 } else { 331 /* Find the process we're supposed to be operating on. */ 332 t = proc_find(pid); 333 if (t == NULL) { 334 mutex_exit(proc_lock); 335 return ESRCH; 336 } 337 338 /* XXX-elad */ 339 mutex_enter(t->p_lock); 340 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE, 341 t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL); 342 if (error) { 343 mutex_exit(proc_lock); 344 mutex_exit(t->p_lock); 345 return ESRCH; 346 } 347 } 348 349 /* 350 * Grab a reference on the process to prevent it from execing or 351 * exiting. 352 */ 353 if (!rw_tryenter(&t->p_reflock, RW_READER)) { 354 mutex_exit(proc_lock); 355 mutex_exit(t->p_lock); 356 return EBUSY; 357 } 358 359 /* Make sure we can operate on it. */ 360 switch (req) { 361 case PT_TRACE_ME: 362 /* Saying that you're being traced is always legal. */ 363 break; 364 365 case PT_ATTACH: 366 /* 367 * You can't attach to a process if: 368 * (1) it's the process that's doing the attaching, 369 */ 370 if (t->p_pid == p->p_pid) { 371 error = EINVAL; 372 break; 373 } 374 375 /* 376 * (2) it's a system process 377 */ 378 if (t->p_flag & PK_SYSTEM) { 379 error = EPERM; 380 break; 381 } 382 383 /* 384 * (3) it's already being traced, or 385 */ 386 if (ISSET(t->p_slflag, PSL_TRACED)) { 387 error = EBUSY; 388 break; 389 } 390 391 /* 392 * (4) the tracer is chrooted, and its root directory is 393 * not at or above the root directory of the tracee 394 */ 395 mutex_exit(t->p_lock); /* XXXSMP */ 396 tmp = proc_isunder(t, l); 397 mutex_enter(t->p_lock); /* XXXSMP */ 398 if (!tmp) { 399 error = EPERM; 400 break; 401 } 402 break; 403 404 case PT_READ_I: 405 case PT_READ_D: 406 case PT_WRITE_I: 407 case PT_WRITE_D: 408 case PT_IO: 409 case PT_SET_SIGINFO: 410 case PT_GET_SIGINFO: 411 case PT_SET_SIGMASK: 412 case PT_GET_SIGMASK: 413 #ifdef PT_GETREGS 414 case PT_GETREGS: 415 #endif 416 #ifdef PT_SETREGS 417 case PT_SETREGS: 418 #endif 419 #ifdef PT_GETFPREGS 420 case PT_GETFPREGS: 421 #endif 422 #ifdef PT_SETFPREGS 423 case PT_SETFPREGS: 424 #endif 425 #ifdef PT_GETDBREGS 426 case PT_GETDBREGS: 427 #endif 428 #ifdef PT_SETDBREGS 429 case PT_SETDBREGS: 430 #endif 431 #ifdef __HAVE_PTRACE_MACHDEP 432 PTRACE_MACHDEP_REQUEST_CASES 433 #endif 434 /* 435 * You can't read/write the memory or registers of a process 436 * if the tracer is chrooted, and its root directory is not at 437 * or above the root directory of the tracee. 438 */ 439 mutex_exit(t->p_lock); /* XXXSMP */ 440 tmp = proc_isunder(t, l); 441 mutex_enter(t->p_lock); /* XXXSMP */ 442 if (!tmp) { 443 error = EPERM; 444 break; 445 } 446 /*FALLTHROUGH*/ 447 448 case PT_CONTINUE: 449 case PT_KILL: 450 case PT_DETACH: 451 case PT_LWPINFO: 452 case PT_SYSCALL: 453 case PT_SYSCALLEMU: 454 case PT_DUMPCORE: 455 #ifdef PT_STEP 456 case PT_STEP: 457 case PT_SETSTEP: 458 case PT_CLEARSTEP: 459 #endif 460 case PT_SET_EVENT_MASK: 461 case PT_GET_EVENT_MASK: 462 case PT_GET_PROCESS_STATE: 463 case PT_RESUME: 464 case PT_SUSPEND: 465 /* 466 * You can't do what you want to the process if: 467 * (1) It's not being traced at all, 468 */ 469 if (!ISSET(t->p_slflag, PSL_TRACED)) { 470 error = EPERM; 471 break; 472 } 473 474 /* 475 * (2) it's being traced by procfs (which has 476 * different signal delivery semantics), 477 */ 478 if (ISSET(t->p_slflag, PSL_FSTRACE)) { 479 DPRINTF(("file system traced\n")); 480 error = EBUSY; 481 break; 482 } 483 484 /* 485 * (3) it's not being traced by _you_, or 486 */ 487 if (t->p_pptr != p) { 488 DPRINTF(("parent %d != %d\n", t->p_pptr->p_pid, 489 p->p_pid)); 490 error = EBUSY; 491 break; 492 } 493 494 /* 495 * (4) it's not currently stopped. 496 */ 497 if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) { 498 DPRINTF(("stat %d flag %d\n", t->p_stat, 499 !t->p_waited)); 500 error = EBUSY; 501 break; 502 } 503 break; 504 505 default: /* It was not a legal request. */ 506 error = EINVAL; 507 break; 508 } 509 510 if (error == 0) { 511 error = kauth_authorize_process(l->l_cred, 512 KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req), 513 NULL, NULL); 514 } 515 if (error == 0) { 516 lt = lwp_find_first(t); 517 if (lt == NULL) 518 error = ESRCH; 519 } 520 521 if (error != 0) { 522 mutex_exit(proc_lock); 523 mutex_exit(t->p_lock); 524 rw_exit(&t->p_reflock); 525 return error; 526 } 527 528 /* Do single-step fixup if needed. */ 529 FIX_SSTEP(t); 530 KASSERT(lt != NULL); 531 lwp_addref(lt); 532 533 /* 534 * Which locks do we need held? XXX Ugly. 535 */ 536 switch (req) { 537 #ifdef PT_STEP 538 case PT_STEP: 539 #endif 540 case PT_CONTINUE: 541 case PT_DETACH: 542 case PT_KILL: 543 case PT_SYSCALL: 544 case PT_SYSCALLEMU: 545 case PT_ATTACH: 546 case PT_TRACE_ME: 547 pheld = 1; 548 break; 549 default: 550 mutex_exit(proc_lock); 551 mutex_exit(t->p_lock); 552 pheld = 0; 553 break; 554 } 555 556 /* Now do the operation. */ 557 write = 0; 558 *retval = 0; 559 tmp = 0; 560 resume_all = 1; 561 562 switch (req) { 563 case PT_TRACE_ME: 564 /* Just set the trace flag. */ 565 SET(t->p_slflag, PSL_TRACED); 566 t->p_opptr = t->p_pptr; 567 break; 568 569 case PT_WRITE_I: /* XXX no separate I and D spaces */ 570 case PT_WRITE_D: 571 #if defined(__HAVE_RAS) 572 /* 573 * Can't write to a RAS 574 */ 575 if (ras_lookup(t, addr) != (void *)-1) { 576 error = EACCES; 577 break; 578 } 579 #endif 580 write = 1; 581 tmp = data; 582 /* FALLTHROUGH */ 583 584 case PT_READ_I: /* XXX no separate I and D spaces */ 585 case PT_READ_D: 586 /* write = 0 done above. */ 587 iov.iov_base = (void *)&tmp; 588 iov.iov_len = sizeof(tmp); 589 uio.uio_iov = &iov; 590 uio.uio_iovcnt = 1; 591 uio.uio_offset = (off_t)(unsigned long)addr; 592 uio.uio_resid = sizeof(tmp); 593 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 594 UIO_SETUP_SYSSPACE(&uio); 595 596 error = process_domem(l, lt, &uio); 597 if (!write) 598 *retval = tmp; 599 break; 600 601 case PT_IO: 602 error = ptm->ptm_copyinpiod(&piod, addr); 603 if (error) 604 break; 605 606 iov.iov_base = piod.piod_addr; 607 iov.iov_len = piod.piod_len; 608 uio.uio_iov = &iov; 609 uio.uio_iovcnt = 1; 610 uio.uio_offset = (off_t)(unsigned long)piod.piod_offs; 611 uio.uio_resid = piod.piod_len; 612 613 switch (piod.piod_op) { 614 case PIOD_READ_D: 615 case PIOD_READ_I: 616 uio.uio_rw = UIO_READ; 617 break; 618 case PIOD_WRITE_D: 619 case PIOD_WRITE_I: 620 /* 621 * Can't write to a RAS 622 */ 623 if (ras_lookup(t, addr) != (void *)-1) { 624 return EACCES; 625 } 626 uio.uio_rw = UIO_WRITE; 627 break; 628 case PIOD_READ_AUXV: 629 req = PT_READ_D; 630 uio.uio_rw = UIO_READ; 631 tmp = t->p_execsw->es_arglen; 632 if (uio.uio_offset > tmp) 633 return EIO; 634 if (uio.uio_resid > tmp - uio.uio_offset) 635 uio.uio_resid = tmp - uio.uio_offset; 636 piod.piod_len = iov.iov_len = uio.uio_resid; 637 error = process_auxv_offset(t, &uio); 638 break; 639 default: 640 error = EINVAL; 641 break; 642 } 643 if (error) 644 break; 645 error = proc_vmspace_getref(l->l_proc, &vm); 646 if (error) 647 break; 648 uio.uio_vmspace = vm; 649 650 error = process_domem(l, lt, &uio); 651 piod.piod_len -= uio.uio_resid; 652 (void) ptm->ptm_copyoutpiod(&piod, addr); 653 654 uvmspace_free(vm); 655 break; 656 657 case PT_DUMPCORE: 658 if ((path = addr) != NULL) { 659 char *dst; 660 len = data; 661 662 if (len < 0 || len >= MAXPATHLEN) { 663 error = EINVAL; 664 break; 665 } 666 dst = kmem_alloc(len + 1, KM_SLEEP); 667 if ((error = copyin(path, dst, len)) != 0) { 668 kmem_free(dst, len + 1); 669 break; 670 } 671 path = dst; 672 path[len] = '\0'; 673 } 674 error = (*coredump_vec)(lt, path); 675 if (path) 676 kmem_free(path, len + 1); 677 break; 678 679 #ifdef PT_STEP 680 case PT_STEP: 681 /* 682 * From the 4.4BSD PRM: 683 * "Execution continues as in request PT_CONTINUE; however 684 * as soon as possible after execution of at least one 685 * instruction, execution stops again. [ ... ]" 686 */ 687 #endif 688 case PT_CONTINUE: 689 case PT_SYSCALL: 690 case PT_DETACH: 691 if (req == PT_SYSCALL) { 692 if (!ISSET(t->p_slflag, PSL_SYSCALL)) { 693 SET(t->p_slflag, PSL_SYSCALL); 694 #ifdef __HAVE_SYSCALL_INTERN 695 (*t->p_emul->e_syscall_intern)(t); 696 #endif 697 } 698 } else { 699 if (ISSET(t->p_slflag, PSL_SYSCALL)) { 700 CLR(t->p_slflag, PSL_SYSCALL); 701 #ifdef __HAVE_SYSCALL_INTERN 702 (*t->p_emul->e_syscall_intern)(t); 703 #endif 704 } 705 } 706 t->p_trace_enabled = trace_is_enabled(t); 707 708 /* 709 * Pick up the LWPID, if supplied. There are two cases: 710 * data < 0 : step or continue single thread, lwp = -data 711 * data > 0 in PT_STEP : step this thread, continue others 712 * For operations other than PT_STEP, data > 0 means 713 * data is the signo to deliver to the process. 714 */ 715 tmp = data; 716 if (tmp >= 0) { 717 #ifdef PT_STEP 718 if (req == PT_STEP) 719 signo = 0; 720 else 721 #endif 722 { 723 signo = tmp; 724 tmp = 0; /* don't search for LWP */ 725 } 726 } else 727 tmp = -tmp; 728 729 if (tmp > 0) { 730 if (req == PT_DETACH) { 731 error = EINVAL; 732 break; 733 } 734 lwp_delref2 (lt); 735 lt = lwp_find(t, tmp); 736 if (lt == NULL) { 737 error = ESRCH; 738 break; 739 } 740 lwp_addref(lt); 741 resume_all = 0; 742 signo = 0; 743 } 744 745 /* 746 * From the 4.4BSD PRM: 747 * "The data argument is taken as a signal number and the 748 * child's execution continues at location addr as if it 749 * incurred that signal. Normally the signal number will 750 * be either 0 to indicate that the signal that caused the 751 * stop should be ignored, or that value fetched out of 752 * the process's image indicating which signal caused 753 * the stop. If addr is (int *)1 then execution continues 754 * from where it stopped." 755 */ 756 757 /* Check that the data is a valid signal number or zero. */ 758 if (signo < 0 || signo >= NSIG) { 759 error = EINVAL; 760 break; 761 } 762 763 /* Prevent process deadlock */ 764 if (resume_all) { 765 #ifdef PT_STEP 766 if (req == PT_STEP) { 767 if (lt->l_flag & LW_WSUSPEND) { 768 error = EDEADLK; 769 break; 770 } 771 } else 772 #endif 773 { 774 error = EDEADLK; 775 LIST_FOREACH(lt2, &t->p_lwps, l_sibling) { 776 if ((lt2->l_flag & LW_WSUSPEND) == 0) { 777 error = 0; 778 break; 779 } 780 } 781 if (error != 0) 782 break; 783 } 784 } else { 785 if (lt->l_flag & LW_WSUSPEND) { 786 error = EDEADLK; 787 break; 788 } 789 } 790 791 /* If the address parameter is not (int *)1, set the pc. */ 792 if ((int *)addr != (int *)1) { 793 error = process_set_pc(lt, addr); 794 if (error != 0) 795 break; 796 } 797 #ifdef PT_STEP 798 /* 799 * Arrange for a single-step, if that's requested and possible. 800 * More precisely, set the single step status as requested for 801 * the requested thread, and clear it for other threads. 802 */ 803 LIST_FOREACH(lt2, &t->p_lwps, l_sibling) { 804 if (ISSET(lt2->l_pflag, LP_SINGLESTEP)) { 805 lwp_lock(lt2); 806 process_sstep(lt2, 1); 807 lwp_unlock(lt2); 808 } else if (lt != lt2) { 809 lwp_lock(lt2); 810 process_sstep(lt2, 0); 811 lwp_unlock(lt2); 812 } 813 } 814 error = process_sstep(lt, 815 ISSET(lt->l_pflag, LP_SINGLESTEP) || req == PT_STEP); 816 if (error) 817 break; 818 #endif 819 if (req == PT_DETACH) { 820 CLR(t->p_slflag, PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL); 821 822 /* give process back to original parent or init */ 823 if (t->p_opptr != t->p_pptr) { 824 struct proc *pp = t->p_opptr; 825 proc_reparent(t, pp ? pp : initproc); 826 } 827 828 /* not being traced any more */ 829 t->p_opptr = NULL; 830 831 /* clear single step */ 832 LIST_FOREACH(lt2, &t->p_lwps, l_sibling) { 833 CLR(lt2->l_pflag, LP_SINGLESTEP); 834 } 835 CLR(lt->l_pflag, LP_SINGLESTEP); 836 } 837 sendsig: 838 t->p_fpid = 0; 839 t->p_vfpid = 0; 840 t->p_vfpid_done = 0; 841 t->p_lwp_created = 0; 842 t->p_lwp_exited = 0; 843 /* Finally, deliver the requested signal (or none). */ 844 if (t->p_stat == SSTOP) { 845 /* 846 * Unstop the process. If it needs to take a 847 * signal, make all efforts to ensure that at 848 * an LWP runs to see it. 849 */ 850 t->p_xsig = signo; 851 if (resume_all) 852 proc_unstop(t); 853 else 854 lwp_unstop(lt); 855 } else if (t->p_sigctx.ps_faked) { 856 if (signo != t->p_sigctx.ps_info._signo) { 857 error = EINVAL; 858 break; 859 } 860 t->p_sigctx.ps_faked = false; 861 KSI_INIT_EMPTY(&ksi); 862 ksi.ksi_info = t->p_sigctx.ps_info; 863 ksi.ksi_lid = t->p_sigctx.ps_lwp; 864 kpsignal2(t, &ksi); 865 } else if (signo != 0) { 866 KSI_INIT_EMPTY(&ksi); 867 ksi.ksi_signo = signo; 868 kpsignal2(t, &ksi); 869 } 870 break; 871 872 case PT_SYSCALLEMU: 873 if (!ISSET(t->p_slflag, PSL_SYSCALL) || t->p_stat != SSTOP) { 874 error = EINVAL; 875 break; 876 } 877 SET(t->p_slflag, PSL_SYSCALLEMU); 878 break; 879 880 #ifdef PT_STEP 881 case PT_SETSTEP: 882 write = 1; 883 884 case PT_CLEARSTEP: 885 /* write = 0 done above. */ 886 887 tmp = data; 888 if (tmp != 0 && t->p_nlwps > 1) { 889 lwp_delref(lt); 890 mutex_enter(t->p_lock); 891 lt = lwp_find(t, tmp); 892 if (lt == NULL) { 893 mutex_exit(t->p_lock); 894 error = ESRCH; 895 break; 896 } 897 lwp_addref(lt); 898 mutex_exit(t->p_lock); 899 } 900 901 if (ISSET(lt->l_flag, LW_SYSTEM)) 902 error = EINVAL; 903 else if (write) 904 SET(lt->l_pflag, LP_SINGLESTEP); 905 else 906 CLR(lt->l_pflag, LP_SINGLESTEP); 907 break; 908 #endif 909 910 case PT_KILL: 911 /* just send the process a KILL signal. */ 912 signo = SIGKILL; 913 goto sendsig; /* in PT_CONTINUE, above. */ 914 915 case PT_ATTACH: 916 /* 917 * Go ahead and set the trace flag. 918 * Save the old parent (it's reset in 919 * _DETACH, and also in kern_exit.c:wait4() 920 * Reparent the process so that the tracing 921 * proc gets to see all the action. 922 * Stop the target. 923 */ 924 proc_changeparent(t, p); 925 signo = SIGSTOP; 926 goto sendsig; 927 928 case PT_GET_EVENT_MASK: 929 if (data != sizeof(pe)) { 930 DPRINTF(("ptrace(%d): %d != %zu\n", req, 931 data, sizeof(pe))); 932 error = EINVAL; 933 break; 934 } 935 memset(&pe, 0, sizeof(pe)); 936 pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ? 937 PTRACE_FORK : 0; 938 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK) ? 939 PTRACE_VFORK : 0; 940 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK_DONE) ? 941 PTRACE_VFORK_DONE : 0; 942 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACELWP_CREATE) ? 943 PTRACE_LWP_CREATE : 0; 944 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACELWP_EXIT) ? 945 PTRACE_LWP_EXIT : 0; 946 error = copyout(&pe, addr, sizeof(pe)); 947 break; 948 949 case PT_SET_EVENT_MASK: 950 if (data != sizeof(pe)) { 951 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 952 sizeof(pe))); 953 error = EINVAL; 954 break; 955 } 956 if ((error = copyin(addr, &pe, sizeof(pe))) != 0) 957 return error; 958 if (pe.pe_set_event & PTRACE_FORK) 959 SET(t->p_slflag, PSL_TRACEFORK); 960 else 961 CLR(t->p_slflag, PSL_TRACEFORK); 962 #if notyet 963 if (pe.pe_set_event & PTRACE_VFORK) 964 SET(t->p_slflag, PSL_TRACEVFORK); 965 else 966 CLR(t->p_slflag, PSL_TRACEVFORK); 967 #else 968 if (pe.pe_set_event & PTRACE_VFORK) { 969 error = ENOTSUP; 970 break; 971 } 972 #endif 973 if (pe.pe_set_event & PTRACE_VFORK_DONE) 974 SET(t->p_slflag, PSL_TRACEVFORK_DONE); 975 else 976 CLR(t->p_slflag, PSL_TRACEVFORK_DONE); 977 if (pe.pe_set_event & PTRACE_LWP_CREATE) 978 SET(t->p_slflag, PSL_TRACELWP_CREATE); 979 else 980 CLR(t->p_slflag, PSL_TRACELWP_CREATE); 981 if (pe.pe_set_event & PTRACE_LWP_EXIT) 982 SET(t->p_slflag, PSL_TRACELWP_EXIT); 983 else 984 CLR(t->p_slflag, PSL_TRACELWP_EXIT); 985 break; 986 987 case PT_GET_PROCESS_STATE: 988 if (data != sizeof(ps)) { 989 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 990 sizeof(ps))); 991 error = EINVAL; 992 break; 993 } 994 memset(&ps, 0, sizeof(ps)); 995 if (t->p_fpid) { 996 ps.pe_report_event = PTRACE_FORK; 997 ps.pe_other_pid = t->p_fpid; 998 } else if (t->p_vfpid) { 999 ps.pe_report_event = PTRACE_VFORK; 1000 ps.pe_other_pid = t->p_vfpid; 1001 } else if (t->p_vfpid_done) { 1002 ps.pe_report_event = PTRACE_VFORK_DONE; 1003 ps.pe_other_pid = t->p_vfpid_done; 1004 } else if (t->p_lwp_created) { 1005 ps.pe_report_event = PTRACE_LWP_CREATE; 1006 ps.pe_lwp = t->p_lwp_created; 1007 } else if (t->p_lwp_exited) { 1008 ps.pe_report_event = PTRACE_LWP_EXIT; 1009 ps.pe_lwp = t->p_lwp_exited; 1010 } 1011 error = copyout(&ps, addr, sizeof(ps)); 1012 break; 1013 1014 case PT_LWPINFO: 1015 if (data != sizeof(pl)) { 1016 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 1017 sizeof(pl))); 1018 error = EINVAL; 1019 break; 1020 } 1021 error = copyin(addr, &pl, sizeof(pl)); 1022 if (error) 1023 break; 1024 tmp = pl.pl_lwpid; 1025 lwp_delref(lt); 1026 mutex_enter(t->p_lock); 1027 if (tmp == 0) 1028 lt = lwp_find_first(t); 1029 else { 1030 lt = lwp_find(t, tmp); 1031 if (lt == NULL) { 1032 mutex_exit(t->p_lock); 1033 error = ESRCH; 1034 break; 1035 } 1036 lt = LIST_NEXT(lt, l_sibling); 1037 } 1038 while (lt != NULL && !lwp_alive(lt)) 1039 lt = LIST_NEXT(lt, l_sibling); 1040 pl.pl_lwpid = 0; 1041 pl.pl_event = 0; 1042 if (lt) { 1043 lwp_addref(lt); 1044 pl.pl_lwpid = lt->l_lid; 1045 1046 if (lt->l_flag & LW_WSUSPEND) 1047 pl.pl_event = PL_EVENT_SUSPENDED; 1048 /* 1049 * If we match the lwp, or it was sent to every lwp, 1050 * we set PL_EVENT_SIGNAL. 1051 * XXX: ps_lwp == 0 means everyone and noone, so 1052 * check ps_signo too. 1053 */ 1054 else if (lt->l_lid == t->p_sigctx.ps_lwp 1055 || (t->p_sigctx.ps_lwp == 0 && 1056 t->p_sigctx.ps_info._signo)) 1057 pl.pl_event = PL_EVENT_SIGNAL; 1058 } 1059 mutex_exit(t->p_lock); 1060 1061 error = copyout(&pl, addr, sizeof(pl)); 1062 break; 1063 1064 case PT_SET_SIGINFO: 1065 if (data != sizeof(psi)) { 1066 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 1067 sizeof(psi))); 1068 error = EINVAL; 1069 break; 1070 } 1071 1072 error = copyin(addr, &psi, sizeof(psi)); 1073 if (error) 1074 break; 1075 1076 /* Check that the data is a valid signal number or zero. */ 1077 if (psi.psi_siginfo.si_signo < 0 || 1078 psi.psi_siginfo.si_signo >= NSIG) { 1079 error = EINVAL; 1080 break; 1081 } 1082 1083 tmp = psi.psi_lwpid; 1084 if (tmp != 0) 1085 lwp_delref(lt); 1086 1087 mutex_enter(t->p_lock); 1088 1089 if (tmp != 0) { 1090 lt = lwp_find(t, tmp); 1091 if (lt == NULL) { 1092 mutex_exit(t->p_lock); 1093 error = ESRCH; 1094 break; 1095 } 1096 lwp_addref(lt); 1097 } 1098 1099 t->p_sigctx.ps_faked = true; 1100 t->p_sigctx.ps_info = psi.psi_siginfo._info; 1101 t->p_sigctx.ps_lwp = psi.psi_lwpid; 1102 mutex_exit(t->p_lock); 1103 break; 1104 1105 case PT_GET_SIGINFO: 1106 if (data != sizeof(psi)) { 1107 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 1108 sizeof(psi))); 1109 error = EINVAL; 1110 break; 1111 } 1112 mutex_enter(t->p_lock); 1113 psi.psi_siginfo._info = t->p_sigctx.ps_info; 1114 psi.psi_lwpid = t->p_sigctx.ps_lwp; 1115 mutex_exit(t->p_lock); 1116 1117 error = copyout(&psi, addr, sizeof(psi)); 1118 if (error) 1119 break; 1120 1121 break; 1122 1123 case PT_SET_SIGMASK: 1124 write = 1; 1125 1126 case PT_GET_SIGMASK: 1127 /* write = 0 done above. */ 1128 1129 tmp = data; 1130 if (tmp != 0 && t->p_nlwps > 1) { 1131 lwp_delref(lt); 1132 mutex_enter(t->p_lock); 1133 lt = lwp_find(t, tmp); 1134 if (lt == NULL) { 1135 mutex_exit(t->p_lock); 1136 error = ESRCH; 1137 break; 1138 } 1139 lwp_addref(lt); 1140 mutex_exit(t->p_lock); 1141 } 1142 1143 if (lt->l_flag & LW_SYSTEM) 1144 error = EINVAL; 1145 else if (write == 1) { 1146 error = copyin(addr, <->l_sigmask, sizeof(sigset_t)); 1147 sigminusset(&sigcantmask, <->l_sigmask); 1148 } else 1149 error = copyout(<->l_sigmask, addr, sizeof(sigset_t)); 1150 1151 break; 1152 1153 case PT_RESUME: 1154 write = 1; 1155 1156 case PT_SUSPEND: 1157 /* write = 0 done above. */ 1158 1159 tmp = data; 1160 if (tmp != 0 && t->p_nlwps > 1) { 1161 lwp_delref(lt); 1162 mutex_enter(t->p_lock); 1163 lt = lwp_find(t, tmp); 1164 if (lt == NULL) { 1165 mutex_exit(t->p_lock); 1166 error = ESRCH; 1167 break; 1168 } 1169 lwp_addref(lt); 1170 mutex_exit(t->p_lock); 1171 } 1172 if (lt->l_flag & LW_SYSTEM) { 1173 error = EINVAL; 1174 } else { 1175 lwp_lock(lt); 1176 if (write == 0) 1177 lt->l_flag |= LW_WSUSPEND; 1178 else 1179 lt->l_flag &= ~LW_WSUSPEND; 1180 lwp_unlock(lt); 1181 } 1182 break; 1183 1184 #ifdef PT_SETREGS 1185 case PT_SETREGS: 1186 write = 1; 1187 #endif 1188 #ifdef PT_GETREGS 1189 case PT_GETREGS: 1190 /* write = 0 done above. */ 1191 #endif 1192 #if defined(PT_SETREGS) || defined(PT_GETREGS) 1193 tmp = data; 1194 if (tmp != 0 && t->p_nlwps > 1) { 1195 lwp_delref(lt); 1196 mutex_enter(t->p_lock); 1197 lt = lwp_find(t, tmp); 1198 if (lt == NULL) { 1199 mutex_exit(t->p_lock); 1200 error = ESRCH; 1201 break; 1202 } 1203 lwp_addref(lt); 1204 mutex_exit(t->p_lock); 1205 } 1206 if (!process_validregs(lt)) 1207 error = EINVAL; 1208 else { 1209 error = proc_vmspace_getref(p, &vm); 1210 if (error) 1211 break; 1212 iov.iov_base = addr; 1213 iov.iov_len = PROC_REGSZ(p); 1214 uio.uio_iov = &iov; 1215 uio.uio_iovcnt = 1; 1216 uio.uio_offset = 0; 1217 uio.uio_resid = iov.iov_len; 1218 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 1219 uio.uio_vmspace = vm; 1220 1221 error = ptm->ptm_doregs(l, lt, &uio); 1222 uvmspace_free(vm); 1223 } 1224 break; 1225 #endif 1226 1227 #ifdef PT_SETFPREGS 1228 case PT_SETFPREGS: 1229 write = 1; 1230 /*FALLTHROUGH*/ 1231 #endif 1232 #ifdef PT_GETFPREGS 1233 case PT_GETFPREGS: 1234 /* write = 0 done above. */ 1235 #endif 1236 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 1237 tmp = data; 1238 if (tmp != 0 && t->p_nlwps > 1) { 1239 lwp_delref(lt); 1240 mutex_enter(t->p_lock); 1241 lt = lwp_find(t, tmp); 1242 if (lt == NULL) { 1243 mutex_exit(t->p_lock); 1244 error = ESRCH; 1245 break; 1246 } 1247 lwp_addref(lt); 1248 mutex_exit(t->p_lock); 1249 } 1250 if (!process_validfpregs(lt)) 1251 error = EINVAL; 1252 else { 1253 error = proc_vmspace_getref(p, &vm); 1254 if (error) 1255 break; 1256 iov.iov_base = addr; 1257 iov.iov_len = PROC_FPREGSZ(p); 1258 uio.uio_iov = &iov; 1259 uio.uio_iovcnt = 1; 1260 uio.uio_offset = 0; 1261 uio.uio_resid = iov.iov_len; 1262 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 1263 uio.uio_vmspace = vm; 1264 1265 error = ptm->ptm_dofpregs(l, lt, &uio); 1266 uvmspace_free(vm); 1267 } 1268 break; 1269 #endif 1270 1271 #ifdef PT_SETDBREGS 1272 case PT_SETDBREGS: 1273 write = 1; 1274 /*FALLTHROUGH*/ 1275 #endif 1276 #ifdef PT_GETDBREGS 1277 case PT_GETDBREGS: 1278 /* write = 0 done above. */ 1279 #endif 1280 #if defined(PT_SETDBREGS) || defined(PT_GETDBREGS) 1281 tmp = data; 1282 if (tmp != 0 && t->p_nlwps > 1) { 1283 lwp_delref(lt); 1284 mutex_enter(t->p_lock); 1285 lt = lwp_find(t, tmp); 1286 if (lt == NULL) { 1287 mutex_exit(t->p_lock); 1288 error = ESRCH; 1289 break; 1290 } 1291 lwp_addref(lt); 1292 mutex_exit(t->p_lock); 1293 } 1294 if (!process_validdbregs(lt)) 1295 error = EINVAL; 1296 else { 1297 error = proc_vmspace_getref(p, &vm); 1298 if (error) 1299 break; 1300 iov.iov_base = addr; 1301 iov.iov_len = PROC_DBREGSZ(p); 1302 uio.uio_iov = &iov; 1303 uio.uio_iovcnt = 1; 1304 uio.uio_offset = 0; 1305 uio.uio_resid = iov.iov_len; 1306 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 1307 uio.uio_vmspace = vm; 1308 1309 error = ptm->ptm_dodbregs(l, lt, &uio); 1310 uvmspace_free(vm); 1311 } 1312 break; 1313 #endif 1314 1315 #ifdef __HAVE_PTRACE_MACHDEP 1316 PTRACE_MACHDEP_REQUEST_CASES 1317 error = ptrace_machdep_dorequest(l, lt, req, addr, data); 1318 break; 1319 #endif 1320 } 1321 1322 if (pheld) { 1323 mutex_exit(t->p_lock); 1324 mutex_exit(proc_lock); 1325 } 1326 if (lt != NULL) 1327 lwp_delref(lt); 1328 rw_exit(&t->p_reflock); 1329 1330 return error; 1331 } 1332 1333 int 1334 process_doregs(struct lwp *curl /*tracer*/, 1335 struct lwp *l /*traced*/, 1336 struct uio *uio) 1337 { 1338 #if defined(PT_GETREGS) || defined(PT_SETREGS) 1339 int error; 1340 struct reg r; 1341 char *kv; 1342 int kl; 1343 1344 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 1345 return EINVAL; 1346 1347 kl = sizeof(r); 1348 kv = (char *)&r; 1349 1350 kv += uio->uio_offset; 1351 kl -= uio->uio_offset; 1352 if ((size_t)kl > uio->uio_resid) 1353 kl = uio->uio_resid; 1354 1355 error = process_read_regs(l, &r); 1356 if (error == 0) 1357 error = uiomove(kv, kl, uio); 1358 if (error == 0 && uio->uio_rw == UIO_WRITE) { 1359 if (l->l_stat != LSSTOP) 1360 error = EBUSY; 1361 else 1362 error = process_write_regs(l, &r); 1363 } 1364 1365 uio->uio_offset = 0; 1366 return error; 1367 #else 1368 return EINVAL; 1369 #endif 1370 } 1371 1372 int 1373 process_validregs(struct lwp *l) 1374 { 1375 1376 #if defined(PT_SETREGS) || defined(PT_GETREGS) 1377 return (l->l_flag & LW_SYSTEM) == 0; 1378 #else 1379 return 0; 1380 #endif 1381 } 1382 1383 int 1384 process_dofpregs(struct lwp *curl /*tracer*/, 1385 struct lwp *l /*traced*/, 1386 struct uio *uio) 1387 { 1388 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) 1389 int error; 1390 struct fpreg r; 1391 char *kv; 1392 size_t kl; 1393 1394 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 1395 return EINVAL; 1396 1397 kl = sizeof(r); 1398 kv = (char *)&r; 1399 1400 kv += uio->uio_offset; 1401 kl -= uio->uio_offset; 1402 if (kl > uio->uio_resid) 1403 kl = uio->uio_resid; 1404 1405 error = process_read_fpregs(l, &r, &kl); 1406 if (error == 0) 1407 error = uiomove(kv, kl, uio); 1408 if (error == 0 && uio->uio_rw == UIO_WRITE) { 1409 if (l->l_stat != LSSTOP) 1410 error = EBUSY; 1411 else 1412 error = process_write_fpregs(l, &r, kl); 1413 } 1414 uio->uio_offset = 0; 1415 return error; 1416 #else 1417 return EINVAL; 1418 #endif 1419 } 1420 1421 int 1422 process_validfpregs(struct lwp *l) 1423 { 1424 1425 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 1426 return (l->l_flag & LW_SYSTEM) == 0; 1427 #else 1428 return 0; 1429 #endif 1430 } 1431 1432 int 1433 process_dodbregs(struct lwp *curl /*tracer*/, 1434 struct lwp *l /*traced*/, 1435 struct uio *uio) 1436 { 1437 #if defined(PT_GETDBREGS) || defined(PT_SETDBREGS) 1438 int error; 1439 struct dbreg r; 1440 char *kv; 1441 size_t kl; 1442 1443 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 1444 return EINVAL; 1445 1446 kl = sizeof(r); 1447 kv = (char *)&r; 1448 1449 kv += uio->uio_offset; 1450 kl -= uio->uio_offset; 1451 if (kl > uio->uio_resid) 1452 kl = uio->uio_resid; 1453 1454 error = process_read_dbregs(l, &r, &kl); 1455 if (error == 0) 1456 error = uiomove(kv, kl, uio); 1457 if (error == 0 && uio->uio_rw == UIO_WRITE) { 1458 if (l->l_stat != LSSTOP) 1459 error = EBUSY; 1460 else 1461 error = process_write_dbregs(l, &r, kl); 1462 } 1463 uio->uio_offset = 0; 1464 return error; 1465 #else 1466 return EINVAL; 1467 #endif 1468 } 1469 1470 int 1471 process_validdbregs(struct lwp *l) 1472 { 1473 1474 #if defined(PT_SETDBREGS) || defined(PT_GETDBREGS) 1475 return (l->l_flag & LW_SYSTEM) == 0; 1476 #else 1477 return 0; 1478 #endif 1479 } 1480 1481 static int 1482 process_auxv_offset(struct proc *p, struct uio *uio) 1483 { 1484 struct ps_strings pss; 1485 int error; 1486 off_t off = (off_t)p->p_psstrp; 1487 1488 if ((error = copyin_psstrings(p, &pss)) != 0) 1489 return error; 1490 1491 if (pss.ps_envstr == NULL) 1492 return EIO; 1493 1494 uio->uio_offset += (off_t)(vaddr_t)(pss.ps_envstr + pss.ps_nenvstr + 1); 1495 #ifdef __MACHINE_STACK_GROWS_UP 1496 if (uio->uio_offset < off) 1497 return EIO; 1498 #else 1499 if (uio->uio_offset > off) 1500 return EIO; 1501 if ((uio->uio_offset + uio->uio_resid) > off) 1502 uio->uio_resid = off - uio->uio_offset; 1503 #endif 1504 return 0; 1505 } 1506 #endif /* PTRACE */ 1507 1508 MODULE(MODULE_CLASS_EXEC, ptrace_common, ""); 1509 1510 static int 1511 ptrace_common_modcmd(modcmd_t cmd, void *arg) 1512 { 1513 int error; 1514 1515 switch (cmd) { 1516 case MODULE_CMD_INIT: 1517 error = ptrace_init(); 1518 break; 1519 case MODULE_CMD_FINI: 1520 error = ptrace_fini(); 1521 break; 1522 default: 1523 ptrace_hooks(); 1524 error = ENOTTY; 1525 break; 1526 } 1527 return error; 1528 } 1529