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