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