| 602 | } |
| 603 | |
| 604 | int |
| 605 | kern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data) |
| 606 | { |
| 607 | struct iovec iov; |
| 608 | struct uio uio; |
| 609 | struct proc *curp, *p, *pp; |
| 610 | struct thread *td2 = NULL, *td3; |
| 611 | struct ptrace_io_desc *piod = NULL; |
| 612 | struct ptrace_lwpinfo *pl; |
| 613 | struct ptrace_sc_ret *psr; |
| 614 | int error, num, tmp; |
| 615 | int proctree_locked = 0; |
| 616 | lwpid_t tid = 0, *buf; |
| 617 | #ifdef COMPAT_FREEBSD32 |
| 618 | int wrap32 = 0, safe = 0; |
| 619 | #endif |
| 620 | |
| 621 | curp = td->td_proc; |
| 622 | |
| 623 | /* Lock proctree before locking the process. */ |
| 624 | switch (req) { |
| 625 | case PT_TRACE_ME: |
| 626 | case PT_ATTACH: |
| 627 | case PT_STEP: |
| 628 | case PT_CONTINUE: |
| 629 | case PT_TO_SCE: |
| 630 | case PT_TO_SCX: |
| 631 | case PT_SYSCALL: |
| 632 | case PT_FOLLOW_FORK: |
| 633 | case PT_LWP_EVENTS: |
| 634 | case PT_GET_EVENT_MASK: |
| 635 | case PT_SET_EVENT_MASK: |
| 636 | case PT_DETACH: |
| 637 | case PT_GET_SC_ARGS: |
| 638 | sx_xlock(&proctree_lock); |
| 639 | proctree_locked = 1; |
| 640 | break; |
| 641 | default: |
| 642 | break; |
| 643 | } |
| 644 | |
| 645 | if (req == PT_TRACE_ME) { |
| 646 | p = td->td_proc; |
| 647 | PROC_LOCK(p); |
| 648 | } else { |
| 649 | if (pid <= PID_MAX) { |
| 650 | if ((p = pfind(pid)) == NULL) { |
| 651 | if (proctree_locked) |
| 652 | sx_xunlock(&proctree_lock); |
| 653 | return (ESRCH); |
| 654 | } |
| 655 | } else { |
| 656 | td2 = tdfind(pid, -1); |
| 657 | if (td2 == NULL) { |
| 658 | if (proctree_locked) |
| 659 | sx_xunlock(&proctree_lock); |
| 660 | return (ESRCH); |
| 661 | } |
no test coverage detected