1 /* $NetBSD: sys_ptrace_common.c,v 1.23 2017/08/28 00:46:07 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.23 2017/08/28 00:46:07 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 not being traced by _you_, or 476 */ 477 if (t->p_pptr != p) { 478 DPRINTF(("parent %d != %d\n", t->p_pptr->p_pid, 479 p->p_pid)); 480 error = EBUSY; 481 break; 482 } 483 484 /* 485 * (3) it's not currently stopped. 486 */ 487 if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) { 488 DPRINTF(("stat %d flag %d\n", t->p_stat, 489 !t->p_waited)); 490 error = EBUSY; 491 break; 492 } 493 break; 494 495 default: /* It was not a legal request. */ 496 error = EINVAL; 497 break; 498 } 499 500 if (error == 0) { 501 error = kauth_authorize_process(l->l_cred, 502 KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req), 503 NULL, NULL); 504 } 505 if (error == 0) { 506 lt = lwp_find_first(t); 507 if (lt == NULL) 508 error = ESRCH; 509 } 510 511 if (error != 0) { 512 mutex_exit(proc_lock); 513 mutex_exit(t->p_lock); 514 rw_exit(&t->p_reflock); 515 return error; 516 } 517 518 /* Do single-step fixup if needed. */ 519 FIX_SSTEP(t); 520 KASSERT(lt != NULL); 521 lwp_addref(lt); 522 523 /* 524 * Which locks do we need held? XXX Ugly. 525 */ 526 switch (req) { 527 #ifdef PT_STEP 528 case PT_STEP: 529 #endif 530 case PT_CONTINUE: 531 case PT_DETACH: 532 case PT_KILL: 533 case PT_SYSCALL: 534 case PT_SYSCALLEMU: 535 case PT_ATTACH: 536 case PT_TRACE_ME: 537 pheld = 1; 538 break; 539 default: 540 mutex_exit(proc_lock); 541 mutex_exit(t->p_lock); 542 pheld = 0; 543 break; 544 } 545 546 /* Now do the operation. */ 547 write = 0; 548 *retval = 0; 549 tmp = 0; 550 resume_all = 1; 551 552 switch (req) { 553 case PT_TRACE_ME: 554 /* Just set the trace flag. */ 555 SET(t->p_slflag, PSL_TRACED); 556 t->p_opptr = t->p_pptr; 557 break; 558 559 case PT_WRITE_I: /* XXX no separate I and D spaces */ 560 case PT_WRITE_D: 561 #if defined(__HAVE_RAS) 562 /* 563 * Can't write to a RAS 564 */ 565 if (ras_lookup(t, addr) != (void *)-1) { 566 error = EACCES; 567 break; 568 } 569 #endif 570 write = 1; 571 tmp = data; 572 /* FALLTHROUGH */ 573 574 case PT_READ_I: /* XXX no separate I and D spaces */ 575 case PT_READ_D: 576 /* write = 0 done above. */ 577 iov.iov_base = (void *)&tmp; 578 iov.iov_len = sizeof(tmp); 579 uio.uio_iov = &iov; 580 uio.uio_iovcnt = 1; 581 uio.uio_offset = (off_t)(unsigned long)addr; 582 uio.uio_resid = sizeof(tmp); 583 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 584 UIO_SETUP_SYSSPACE(&uio); 585 586 error = process_domem(l, lt, &uio); 587 if (!write) 588 *retval = tmp; 589 break; 590 591 case PT_IO: 592 error = ptm->ptm_copyinpiod(&piod, addr); 593 if (error) 594 break; 595 596 iov.iov_base = piod.piod_addr; 597 iov.iov_len = piod.piod_len; 598 uio.uio_iov = &iov; 599 uio.uio_iovcnt = 1; 600 uio.uio_offset = (off_t)(unsigned long)piod.piod_offs; 601 uio.uio_resid = piod.piod_len; 602 603 switch (piod.piod_op) { 604 case PIOD_READ_D: 605 case PIOD_READ_I: 606 uio.uio_rw = UIO_READ; 607 break; 608 case PIOD_WRITE_D: 609 case PIOD_WRITE_I: 610 /* 611 * Can't write to a RAS 612 */ 613 if (ras_lookup(t, addr) != (void *)-1) { 614 return EACCES; 615 } 616 uio.uio_rw = UIO_WRITE; 617 break; 618 case PIOD_READ_AUXV: 619 req = PT_READ_D; 620 uio.uio_rw = UIO_READ; 621 tmp = t->p_execsw->es_arglen; 622 if (uio.uio_offset > tmp) 623 return EIO; 624 if (uio.uio_resid > tmp - uio.uio_offset) 625 uio.uio_resid = tmp - uio.uio_offset; 626 piod.piod_len = iov.iov_len = uio.uio_resid; 627 error = process_auxv_offset(t, &uio); 628 break; 629 default: 630 error = EINVAL; 631 break; 632 } 633 if (error) 634 break; 635 error = proc_vmspace_getref(l->l_proc, &vm); 636 if (error) 637 break; 638 uio.uio_vmspace = vm; 639 640 error = process_domem(l, lt, &uio); 641 piod.piod_len -= uio.uio_resid; 642 (void) ptm->ptm_copyoutpiod(&piod, addr); 643 644 uvmspace_free(vm); 645 break; 646 647 case PT_DUMPCORE: 648 if ((path = addr) != NULL) { 649 char *dst; 650 len = data; 651 652 if (len < 0 || len >= MAXPATHLEN) { 653 error = EINVAL; 654 break; 655 } 656 dst = kmem_alloc(len + 1, KM_SLEEP); 657 if ((error = copyin(path, dst, len)) != 0) { 658 kmem_free(dst, len + 1); 659 break; 660 } 661 path = dst; 662 path[len] = '\0'; 663 } 664 error = (*coredump_vec)(lt, path); 665 if (path) 666 kmem_free(path, len + 1); 667 break; 668 669 #ifdef PT_STEP 670 case PT_STEP: 671 /* 672 * From the 4.4BSD PRM: 673 * "Execution continues as in request PT_CONTINUE; however 674 * as soon as possible after execution of at least one 675 * instruction, execution stops again. [ ... ]" 676 */ 677 #endif 678 case PT_CONTINUE: 679 case PT_SYSCALL: 680 case PT_DETACH: 681 if (req == PT_SYSCALL) { 682 if (!ISSET(t->p_slflag, PSL_SYSCALL)) { 683 SET(t->p_slflag, PSL_SYSCALL); 684 #ifdef __HAVE_SYSCALL_INTERN 685 (*t->p_emul->e_syscall_intern)(t); 686 #endif 687 } 688 } else { 689 if (ISSET(t->p_slflag, PSL_SYSCALL)) { 690 CLR(t->p_slflag, PSL_SYSCALL); 691 #ifdef __HAVE_SYSCALL_INTERN 692 (*t->p_emul->e_syscall_intern)(t); 693 #endif 694 } 695 } 696 t->p_trace_enabled = trace_is_enabled(t); 697 698 /* 699 * Pick up the LWPID, if supplied. There are two cases: 700 * data < 0 : step or continue single thread, lwp = -data 701 * data > 0 in PT_STEP : step this thread, continue others 702 * For operations other than PT_STEP, data > 0 means 703 * data is the signo to deliver to the process. 704 */ 705 tmp = data; 706 if (tmp >= 0) { 707 #ifdef PT_STEP 708 if (req == PT_STEP) 709 signo = 0; 710 else 711 #endif 712 { 713 signo = tmp; 714 tmp = 0; /* don't search for LWP */ 715 } 716 } else 717 tmp = -tmp; 718 719 if (tmp > 0) { 720 if (req == PT_DETACH) { 721 error = EINVAL; 722 break; 723 } 724 lwp_delref2 (lt); 725 lt = lwp_find(t, tmp); 726 if (lt == NULL) { 727 error = ESRCH; 728 break; 729 } 730 lwp_addref(lt); 731 resume_all = 0; 732 signo = 0; 733 } 734 735 /* 736 * From the 4.4BSD PRM: 737 * "The data argument is taken as a signal number and the 738 * child's execution continues at location addr as if it 739 * incurred that signal. Normally the signal number will 740 * be either 0 to indicate that the signal that caused the 741 * stop should be ignored, or that value fetched out of 742 * the process's image indicating which signal caused 743 * the stop. If addr is (int *)1 then execution continues 744 * from where it stopped." 745 */ 746 747 /* Check that the data is a valid signal number or zero. */ 748 if (signo < 0 || signo >= NSIG) { 749 error = EINVAL; 750 break; 751 } 752 753 /* Prevent process deadlock */ 754 if (resume_all) { 755 #ifdef PT_STEP 756 if (req == PT_STEP) { 757 if (lt->l_flag & LW_WSUSPEND) { 758 error = EDEADLK; 759 break; 760 } 761 } else 762 #endif 763 { 764 error = EDEADLK; 765 LIST_FOREACH(lt2, &t->p_lwps, l_sibling) { 766 if ((lt2->l_flag & LW_WSUSPEND) == 0) { 767 error = 0; 768 break; 769 } 770 } 771 if (error != 0) 772 break; 773 } 774 } else { 775 if (lt->l_flag & LW_WSUSPEND) { 776 error = EDEADLK; 777 break; 778 } 779 } 780 781 /* If the address parameter is not (int *)1, set the pc. */ 782 if ((int *)addr != (int *)1) { 783 error = process_set_pc(lt, addr); 784 if (error != 0) 785 break; 786 } 787 #ifdef PT_STEP 788 /* 789 * Arrange for a single-step, if that's requested and possible. 790 * More precisely, set the single step status as requested for 791 * the requested thread, and clear it for other threads. 792 */ 793 LIST_FOREACH(lt2, &t->p_lwps, l_sibling) { 794 if (ISSET(lt2->l_pflag, LP_SINGLESTEP)) { 795 lwp_lock(lt2); 796 process_sstep(lt2, 1); 797 lwp_unlock(lt2); 798 } else if (lt != lt2) { 799 lwp_lock(lt2); 800 process_sstep(lt2, 0); 801 lwp_unlock(lt2); 802 } 803 } 804 error = process_sstep(lt, 805 ISSET(lt->l_pflag, LP_SINGLESTEP) || req == PT_STEP); 806 if (error) 807 break; 808 #endif 809 if (req == PT_DETACH) { 810 CLR(t->p_slflag, PSL_TRACED|PSL_SYSCALL); 811 812 /* give process back to original parent or init */ 813 if (t->p_opptr != t->p_pptr) { 814 struct proc *pp = t->p_opptr; 815 proc_reparent(t, pp ? pp : initproc); 816 } 817 818 /* not being traced any more */ 819 t->p_opptr = NULL; 820 821 /* clear single step */ 822 LIST_FOREACH(lt2, &t->p_lwps, l_sibling) { 823 CLR(lt2->l_pflag, LP_SINGLESTEP); 824 } 825 CLR(lt->l_pflag, LP_SINGLESTEP); 826 } 827 sendsig: 828 t->p_fpid = 0; 829 t->p_vfpid = 0; 830 t->p_vfpid_done = 0; 831 t->p_lwp_created = 0; 832 t->p_lwp_exited = 0; 833 /* Finally, deliver the requested signal (or none). */ 834 if (t->p_stat == SSTOP) { 835 /* 836 * Unstop the process. If it needs to take a 837 * signal, make all efforts to ensure that at 838 * an LWP runs to see it. 839 */ 840 t->p_xsig = signo; 841 if (resume_all) 842 proc_unstop(t); 843 else 844 lwp_unstop(lt); 845 } else if (t->p_sigctx.ps_faked) { 846 if (signo != t->p_sigctx.ps_info._signo) { 847 error = EINVAL; 848 break; 849 } 850 t->p_sigctx.ps_faked = false; 851 KSI_INIT_EMPTY(&ksi); 852 ksi.ksi_info = t->p_sigctx.ps_info; 853 ksi.ksi_lid = t->p_sigctx.ps_lwp; 854 kpsignal2(t, &ksi); 855 } else if (signo != 0) { 856 KSI_INIT_EMPTY(&ksi); 857 ksi.ksi_signo = signo; 858 kpsignal2(t, &ksi); 859 } 860 break; 861 862 case PT_SYSCALLEMU: 863 if (!ISSET(t->p_slflag, PSL_SYSCALL) || t->p_stat != SSTOP) { 864 error = EINVAL; 865 break; 866 } 867 SET(t->p_slflag, PSL_SYSCALLEMU); 868 break; 869 870 #ifdef PT_STEP 871 case PT_SETSTEP: 872 write = 1; 873 874 case PT_CLEARSTEP: 875 /* write = 0 done above. */ 876 877 tmp = data; 878 if (tmp != 0 && t->p_nlwps > 1) { 879 lwp_delref(lt); 880 mutex_enter(t->p_lock); 881 lt = lwp_find(t, tmp); 882 if (lt == NULL) { 883 mutex_exit(t->p_lock); 884 error = ESRCH; 885 break; 886 } 887 lwp_addref(lt); 888 mutex_exit(t->p_lock); 889 } 890 891 if (ISSET(lt->l_flag, LW_SYSTEM)) 892 error = EINVAL; 893 else if (write) 894 SET(lt->l_pflag, LP_SINGLESTEP); 895 else 896 CLR(lt->l_pflag, LP_SINGLESTEP); 897 break; 898 #endif 899 900 case PT_KILL: 901 /* just send the process a KILL signal. */ 902 signo = SIGKILL; 903 goto sendsig; /* in PT_CONTINUE, above. */ 904 905 case PT_ATTACH: 906 /* 907 * Go ahead and set the trace flag. 908 * Save the old parent (it's reset in 909 * _DETACH, and also in kern_exit.c:wait4() 910 * Reparent the process so that the tracing 911 * proc gets to see all the action. 912 * Stop the target. 913 */ 914 proc_changeparent(t, p); 915 signo = SIGSTOP; 916 goto sendsig; 917 918 case PT_GET_EVENT_MASK: 919 if (data != sizeof(pe)) { 920 DPRINTF(("ptrace(%d): %d != %zu\n", req, 921 data, sizeof(pe))); 922 error = EINVAL; 923 break; 924 } 925 memset(&pe, 0, sizeof(pe)); 926 pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ? 927 PTRACE_FORK : 0; 928 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK) ? 929 PTRACE_VFORK : 0; 930 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK_DONE) ? 931 PTRACE_VFORK_DONE : 0; 932 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACELWP_CREATE) ? 933 PTRACE_LWP_CREATE : 0; 934 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACELWP_EXIT) ? 935 PTRACE_LWP_EXIT : 0; 936 error = copyout(&pe, addr, sizeof(pe)); 937 break; 938 939 case PT_SET_EVENT_MASK: 940 if (data != sizeof(pe)) { 941 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 942 sizeof(pe))); 943 error = EINVAL; 944 break; 945 } 946 if ((error = copyin(addr, &pe, sizeof(pe))) != 0) 947 return error; 948 if (pe.pe_set_event & PTRACE_FORK) 949 SET(t->p_slflag, PSL_TRACEFORK); 950 else 951 CLR(t->p_slflag, PSL_TRACEFORK); 952 #if notyet 953 if (pe.pe_set_event & PTRACE_VFORK) 954 SET(t->p_slflag, PSL_TRACEVFORK); 955 else 956 CLR(t->p_slflag, PSL_TRACEVFORK); 957 #else 958 if (pe.pe_set_event & PTRACE_VFORK) { 959 error = ENOTSUP; 960 break; 961 } 962 #endif 963 if (pe.pe_set_event & PTRACE_VFORK_DONE) 964 SET(t->p_slflag, PSL_TRACEVFORK_DONE); 965 else 966 CLR(t->p_slflag, PSL_TRACEVFORK_DONE); 967 if (pe.pe_set_event & PTRACE_LWP_CREATE) 968 SET(t->p_slflag, PSL_TRACELWP_CREATE); 969 else 970 CLR(t->p_slflag, PSL_TRACELWP_CREATE); 971 if (pe.pe_set_event & PTRACE_LWP_EXIT) 972 SET(t->p_slflag, PSL_TRACELWP_EXIT); 973 else 974 CLR(t->p_slflag, PSL_TRACELWP_EXIT); 975 break; 976 977 case PT_GET_PROCESS_STATE: 978 if (data != sizeof(ps)) { 979 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 980 sizeof(ps))); 981 error = EINVAL; 982 break; 983 } 984 memset(&ps, 0, sizeof(ps)); 985 if (t->p_fpid) { 986 ps.pe_report_event = PTRACE_FORK; 987 ps.pe_other_pid = t->p_fpid; 988 } else if (t->p_vfpid) { 989 ps.pe_report_event = PTRACE_VFORK; 990 ps.pe_other_pid = t->p_vfpid; 991 } else if (t->p_vfpid_done) { 992 ps.pe_report_event = PTRACE_VFORK_DONE; 993 ps.pe_other_pid = t->p_vfpid_done; 994 } else if (t->p_lwp_created) { 995 ps.pe_report_event = PTRACE_LWP_CREATE; 996 ps.pe_lwp = t->p_lwp_created; 997 } else if (t->p_lwp_exited) { 998 ps.pe_report_event = PTRACE_LWP_EXIT; 999 ps.pe_lwp = t->p_lwp_exited; 1000 } 1001 error = copyout(&ps, addr, sizeof(ps)); 1002 break; 1003 1004 case PT_LWPINFO: 1005 if (data != sizeof(pl)) { 1006 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 1007 sizeof(pl))); 1008 error = EINVAL; 1009 break; 1010 } 1011 error = copyin(addr, &pl, sizeof(pl)); 1012 if (error) 1013 break; 1014 tmp = pl.pl_lwpid; 1015 lwp_delref(lt); 1016 mutex_enter(t->p_lock); 1017 if (tmp == 0) 1018 lt = lwp_find_first(t); 1019 else { 1020 lt = lwp_find(t, tmp); 1021 if (lt == NULL) { 1022 mutex_exit(t->p_lock); 1023 error = ESRCH; 1024 break; 1025 } 1026 lt = LIST_NEXT(lt, l_sibling); 1027 } 1028 while (lt != NULL && !lwp_alive(lt)) 1029 lt = LIST_NEXT(lt, l_sibling); 1030 pl.pl_lwpid = 0; 1031 pl.pl_event = 0; 1032 if (lt) { 1033 lwp_addref(lt); 1034 pl.pl_lwpid = lt->l_lid; 1035 1036 if (lt->l_flag & LW_WSUSPEND) 1037 pl.pl_event = PL_EVENT_SUSPENDED; 1038 /* 1039 * If we match the lwp, or it was sent to every lwp, 1040 * we set PL_EVENT_SIGNAL. 1041 * XXX: ps_lwp == 0 means everyone and noone, so 1042 * check ps_signo too. 1043 */ 1044 else if (lt->l_lid == t->p_sigctx.ps_lwp 1045 || (t->p_sigctx.ps_lwp == 0 && 1046 t->p_sigctx.ps_info._signo)) 1047 pl.pl_event = PL_EVENT_SIGNAL; 1048 } 1049 mutex_exit(t->p_lock); 1050 1051 error = copyout(&pl, addr, sizeof(pl)); 1052 break; 1053 1054 case PT_SET_SIGINFO: 1055 if (data != sizeof(psi)) { 1056 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 1057 sizeof(psi))); 1058 error = EINVAL; 1059 break; 1060 } 1061 1062 error = copyin(addr, &psi, sizeof(psi)); 1063 if (error) 1064 break; 1065 1066 /* Check that the data is a valid signal number or zero. */ 1067 if (psi.psi_siginfo.si_signo < 0 || 1068 psi.psi_siginfo.si_signo >= NSIG) { 1069 error = EINVAL; 1070 break; 1071 } 1072 1073 tmp = psi.psi_lwpid; 1074 if (tmp != 0) 1075 lwp_delref(lt); 1076 1077 mutex_enter(t->p_lock); 1078 1079 if (tmp != 0) { 1080 lt = lwp_find(t, tmp); 1081 if (lt == NULL) { 1082 mutex_exit(t->p_lock); 1083 error = ESRCH; 1084 break; 1085 } 1086 lwp_addref(lt); 1087 } 1088 1089 t->p_sigctx.ps_faked = true; 1090 t->p_sigctx.ps_info = psi.psi_siginfo._info; 1091 t->p_sigctx.ps_lwp = psi.psi_lwpid; 1092 mutex_exit(t->p_lock); 1093 break; 1094 1095 case PT_GET_SIGINFO: 1096 if (data != sizeof(psi)) { 1097 DPRINTF(("ptrace(%d): %d != %zu\n", req, data, 1098 sizeof(psi))); 1099 error = EINVAL; 1100 break; 1101 } 1102 mutex_enter(t->p_lock); 1103 psi.psi_siginfo._info = t->p_sigctx.ps_info; 1104 psi.psi_lwpid = t->p_sigctx.ps_lwp; 1105 mutex_exit(t->p_lock); 1106 1107 error = copyout(&psi, addr, sizeof(psi)); 1108 if (error) 1109 break; 1110 1111 break; 1112 1113 case PT_SET_SIGMASK: 1114 write = 1; 1115 1116 case PT_GET_SIGMASK: 1117 /* write = 0 done above. */ 1118 1119 tmp = data; 1120 if (tmp != 0 && t->p_nlwps > 1) { 1121 lwp_delref(lt); 1122 mutex_enter(t->p_lock); 1123 lt = lwp_find(t, tmp); 1124 if (lt == NULL) { 1125 mutex_exit(t->p_lock); 1126 error = ESRCH; 1127 break; 1128 } 1129 lwp_addref(lt); 1130 mutex_exit(t->p_lock); 1131 } 1132 1133 if (lt->l_flag & LW_SYSTEM) 1134 error = EINVAL; 1135 else if (write == 1) { 1136 error = copyin(addr, <->l_sigmask, sizeof(sigset_t)); 1137 sigminusset(&sigcantmask, <->l_sigmask); 1138 } else 1139 error = copyout(<->l_sigmask, addr, sizeof(sigset_t)); 1140 1141 break; 1142 1143 case PT_RESUME: 1144 write = 1; 1145 1146 case PT_SUSPEND: 1147 /* write = 0 done above. */ 1148 1149 tmp = data; 1150 if (tmp != 0 && t->p_nlwps > 1) { 1151 lwp_delref(lt); 1152 mutex_enter(t->p_lock); 1153 lt = lwp_find(t, tmp); 1154 if (lt == NULL) { 1155 mutex_exit(t->p_lock); 1156 error = ESRCH; 1157 break; 1158 } 1159 lwp_addref(lt); 1160 mutex_exit(t->p_lock); 1161 } 1162 if (lt->l_flag & LW_SYSTEM) { 1163 error = EINVAL; 1164 } else { 1165 lwp_lock(lt); 1166 if (write == 0) 1167 lt->l_flag |= LW_WSUSPEND; 1168 else 1169 lt->l_flag &= ~LW_WSUSPEND; 1170 lwp_unlock(lt); 1171 } 1172 break; 1173 1174 #ifdef PT_SETREGS 1175 case PT_SETREGS: 1176 write = 1; 1177 #endif 1178 #ifdef PT_GETREGS 1179 case PT_GETREGS: 1180 /* write = 0 done above. */ 1181 #endif 1182 #if defined(PT_SETREGS) || defined(PT_GETREGS) 1183 tmp = data; 1184 if (tmp != 0 && t->p_nlwps > 1) { 1185 lwp_delref(lt); 1186 mutex_enter(t->p_lock); 1187 lt = lwp_find(t, tmp); 1188 if (lt == NULL) { 1189 mutex_exit(t->p_lock); 1190 error = ESRCH; 1191 break; 1192 } 1193 lwp_addref(lt); 1194 mutex_exit(t->p_lock); 1195 } 1196 if (!process_validregs(lt)) 1197 error = EINVAL; 1198 else { 1199 error = proc_vmspace_getref(p, &vm); 1200 if (error) 1201 break; 1202 iov.iov_base = addr; 1203 iov.iov_len = PROC_REGSZ(p); 1204 uio.uio_iov = &iov; 1205 uio.uio_iovcnt = 1; 1206 uio.uio_offset = 0; 1207 uio.uio_resid = iov.iov_len; 1208 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 1209 uio.uio_vmspace = vm; 1210 1211 error = ptm->ptm_doregs(l, lt, &uio); 1212 uvmspace_free(vm); 1213 } 1214 break; 1215 #endif 1216 1217 #ifdef PT_SETFPREGS 1218 case PT_SETFPREGS: 1219 write = 1; 1220 /*FALLTHROUGH*/ 1221 #endif 1222 #ifdef PT_GETFPREGS 1223 case PT_GETFPREGS: 1224 /* write = 0 done above. */ 1225 #endif 1226 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 1227 tmp = data; 1228 if (tmp != 0 && t->p_nlwps > 1) { 1229 lwp_delref(lt); 1230 mutex_enter(t->p_lock); 1231 lt = lwp_find(t, tmp); 1232 if (lt == NULL) { 1233 mutex_exit(t->p_lock); 1234 error = ESRCH; 1235 break; 1236 } 1237 lwp_addref(lt); 1238 mutex_exit(t->p_lock); 1239 } 1240 if (!process_validfpregs(lt)) 1241 error = EINVAL; 1242 else { 1243 error = proc_vmspace_getref(p, &vm); 1244 if (error) 1245 break; 1246 iov.iov_base = addr; 1247 iov.iov_len = PROC_FPREGSZ(p); 1248 uio.uio_iov = &iov; 1249 uio.uio_iovcnt = 1; 1250 uio.uio_offset = 0; 1251 uio.uio_resid = iov.iov_len; 1252 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 1253 uio.uio_vmspace = vm; 1254 1255 error = ptm->ptm_dofpregs(l, lt, &uio); 1256 uvmspace_free(vm); 1257 } 1258 break; 1259 #endif 1260 1261 #ifdef PT_SETDBREGS 1262 case PT_SETDBREGS: 1263 write = 1; 1264 /*FALLTHROUGH*/ 1265 #endif 1266 #ifdef PT_GETDBREGS 1267 case PT_GETDBREGS: 1268 /* write = 0 done above. */ 1269 #endif 1270 #if defined(PT_SETDBREGS) || defined(PT_GETDBREGS) 1271 tmp = data; 1272 if (tmp != 0 && t->p_nlwps > 1) { 1273 lwp_delref(lt); 1274 mutex_enter(t->p_lock); 1275 lt = lwp_find(t, tmp); 1276 if (lt == NULL) { 1277 mutex_exit(t->p_lock); 1278 error = ESRCH; 1279 break; 1280 } 1281 lwp_addref(lt); 1282 mutex_exit(t->p_lock); 1283 } 1284 if (!process_validdbregs(lt)) 1285 error = EINVAL; 1286 else { 1287 error = proc_vmspace_getref(p, &vm); 1288 if (error) 1289 break; 1290 iov.iov_base = addr; 1291 iov.iov_len = PROC_DBREGSZ(p); 1292 uio.uio_iov = &iov; 1293 uio.uio_iovcnt = 1; 1294 uio.uio_offset = 0; 1295 uio.uio_resid = iov.iov_len; 1296 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 1297 uio.uio_vmspace = vm; 1298 1299 error = ptm->ptm_dodbregs(l, lt, &uio); 1300 uvmspace_free(vm); 1301 } 1302 break; 1303 #endif 1304 1305 #ifdef __HAVE_PTRACE_MACHDEP 1306 PTRACE_MACHDEP_REQUEST_CASES 1307 error = ptrace_machdep_dorequest(l, lt, req, addr, data); 1308 break; 1309 #endif 1310 } 1311 1312 if (pheld) { 1313 mutex_exit(t->p_lock); 1314 mutex_exit(proc_lock); 1315 } 1316 if (lt != NULL) 1317 lwp_delref(lt); 1318 rw_exit(&t->p_reflock); 1319 1320 return error; 1321 } 1322 1323 int 1324 process_doregs(struct lwp *curl /*tracer*/, 1325 struct lwp *l /*traced*/, 1326 struct uio *uio) 1327 { 1328 #if defined(PT_GETREGS) || defined(PT_SETREGS) 1329 int error; 1330 struct reg r; 1331 char *kv; 1332 int kl; 1333 1334 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 1335 return EINVAL; 1336 1337 kl = sizeof(r); 1338 kv = (char *)&r; 1339 1340 kv += uio->uio_offset; 1341 kl -= uio->uio_offset; 1342 if ((size_t)kl > uio->uio_resid) 1343 kl = uio->uio_resid; 1344 1345 error = process_read_regs(l, &r); 1346 if (error == 0) 1347 error = uiomove(kv, kl, uio); 1348 if (error == 0 && uio->uio_rw == UIO_WRITE) { 1349 if (l->l_stat != LSSTOP) 1350 error = EBUSY; 1351 else 1352 error = process_write_regs(l, &r); 1353 } 1354 1355 uio->uio_offset = 0; 1356 return error; 1357 #else 1358 return EINVAL; 1359 #endif 1360 } 1361 1362 int 1363 process_validregs(struct lwp *l) 1364 { 1365 1366 #if defined(PT_SETREGS) || defined(PT_GETREGS) 1367 return (l->l_flag & LW_SYSTEM) == 0; 1368 #else 1369 return 0; 1370 #endif 1371 } 1372 1373 int 1374 process_dofpregs(struct lwp *curl /*tracer*/, 1375 struct lwp *l /*traced*/, 1376 struct uio *uio) 1377 { 1378 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS) 1379 int error; 1380 struct fpreg r; 1381 char *kv; 1382 size_t kl; 1383 1384 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 1385 return EINVAL; 1386 1387 kl = sizeof(r); 1388 kv = (char *)&r; 1389 1390 kv += uio->uio_offset; 1391 kl -= uio->uio_offset; 1392 if (kl > uio->uio_resid) 1393 kl = uio->uio_resid; 1394 1395 error = process_read_fpregs(l, &r, &kl); 1396 if (error == 0) 1397 error = uiomove(kv, kl, uio); 1398 if (error == 0 && uio->uio_rw == UIO_WRITE) { 1399 if (l->l_stat != LSSTOP) 1400 error = EBUSY; 1401 else 1402 error = process_write_fpregs(l, &r, kl); 1403 } 1404 uio->uio_offset = 0; 1405 return error; 1406 #else 1407 return EINVAL; 1408 #endif 1409 } 1410 1411 int 1412 process_validfpregs(struct lwp *l) 1413 { 1414 1415 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 1416 return (l->l_flag & LW_SYSTEM) == 0; 1417 #else 1418 return 0; 1419 #endif 1420 } 1421 1422 int 1423 process_dodbregs(struct lwp *curl /*tracer*/, 1424 struct lwp *l /*traced*/, 1425 struct uio *uio) 1426 { 1427 #if defined(PT_GETDBREGS) || defined(PT_SETDBREGS) 1428 int error; 1429 struct dbreg r; 1430 char *kv; 1431 size_t kl; 1432 1433 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r)) 1434 return EINVAL; 1435 1436 kl = sizeof(r); 1437 kv = (char *)&r; 1438 1439 kv += uio->uio_offset; 1440 kl -= uio->uio_offset; 1441 if (kl > uio->uio_resid) 1442 kl = uio->uio_resid; 1443 1444 error = process_read_dbregs(l, &r, &kl); 1445 if (error == 0) 1446 error = uiomove(kv, kl, uio); 1447 if (error == 0 && uio->uio_rw == UIO_WRITE) { 1448 if (l->l_stat != LSSTOP) 1449 error = EBUSY; 1450 else 1451 error = process_write_dbregs(l, &r, kl); 1452 } 1453 uio->uio_offset = 0; 1454 return error; 1455 #else 1456 return EINVAL; 1457 #endif 1458 } 1459 1460 int 1461 process_validdbregs(struct lwp *l) 1462 { 1463 1464 #if defined(PT_SETDBREGS) || defined(PT_GETDBREGS) 1465 return (l->l_flag & LW_SYSTEM) == 0; 1466 #else 1467 return 0; 1468 #endif 1469 } 1470 1471 static int 1472 process_auxv_offset(struct proc *p, struct uio *uio) 1473 { 1474 struct ps_strings pss; 1475 int error; 1476 off_t off = (off_t)p->p_psstrp; 1477 1478 if ((error = copyin_psstrings(p, &pss)) != 0) 1479 return error; 1480 1481 if (pss.ps_envstr == NULL) 1482 return EIO; 1483 1484 uio->uio_offset += (off_t)(vaddr_t)(pss.ps_envstr + pss.ps_nenvstr + 1); 1485 #ifdef __MACHINE_STACK_GROWS_UP 1486 if (uio->uio_offset < off) 1487 return EIO; 1488 #else 1489 if (uio->uio_offset > off) 1490 return EIO; 1491 if ((uio->uio_offset + uio->uio_resid) > off) 1492 uio->uio_resid = off - uio->uio_offset; 1493 #endif 1494 return 0; 1495 } 1496 #endif /* PTRACE */ 1497 1498 MODULE(MODULE_CLASS_EXEC, ptrace_common, ""); 1499 1500 static int 1501 ptrace_common_modcmd(modcmd_t cmd, void *arg) 1502 { 1503 int error; 1504 1505 switch (cmd) { 1506 case MODULE_CMD_INIT: 1507 error = ptrace_init(); 1508 break; 1509 case MODULE_CMD_FINI: 1510 error = ptrace_fini(); 1511 break; 1512 default: 1513 ptrace_hooks(); 1514 error = ENOTTY; 1515 break; 1516 } 1517 return error; 1518 } 1519