|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ ! 26: /*- ! 27: * Copyright (c) 1982, 1986, 1989, 1993 ! 28: * The Regents of the University of California. All rights reserved. ! 29: * (c) UNIX System Laboratories, Inc. ! 30: * All or some portions of this file are derived from material licensed ! 31: * to the University of California by American Telephone and Telegraph ! 32: * Co. or Unix System Laboratories, Inc. and are reproduced herein with ! 33: * the permission of UNIX System Laboratories, Inc. ! 34: * ! 35: * Redistribution and use in source and binary forms, with or without ! 36: * modification, are permitted provided that the following conditions ! 37: * are met: ! 38: * 1. Redistributions of source code must retain the above copyright ! 39: * notice, this list of conditions and the following disclaimer. ! 40: * 2. Redistributions in binary form must reproduce the above copyright ! 41: * notice, this list of conditions and the following disclaimer in the ! 42: * documentation and/or other materials provided with the distribution. ! 43: * 3. All advertising materials mentioning features or use of this software ! 44: * must display the following acknowledgement: ! 45: * This product includes software developed by the University of ! 46: * California, Berkeley and its contributors. ! 47: * 4. Neither the name of the University nor the names of its contributors ! 48: * may be used to endorse or promote products derived from this software ! 49: * without specific prior written permission. ! 50: * ! 51: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ! 52: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ! 53: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ! 54: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE ! 55: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ! 56: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ! 57: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ! 58: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ! 59: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ! 60: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ! 61: * SUCH DAMAGE. ! 62: * ! 63: * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93 ! 64: */ ! 65: /* ! 66: * HISTORY ! 67: * ! 68: * 10-Jun-97 Umesh Vaishampayan ([email protected]) ! 69: * Ported to PPC. Cleaned up the architecture specific code. ! 70: */ ! 71: ! 72: #import <machine/reg.h> ! 73: #import <machine/psl.h> ! 74: ! 75: #include <sys/param.h> ! 76: #include <sys/systm.h> ! 77: #include <sys/proc.h> ! 78: #include <sys/errno.h> ! 79: #include <sys/ptrace.h> ! 80: #include <sys/uio.h> ! 81: #include <sys/user.h> ! 82: #include <sys/sysctl.h> ! 83: ! 84: #include <sys/mount.h> ! 85: ! 86: #import <kern/task.h> ! 87: #import <kern/thread.h> ! 88: #import <kern/sched_prim.h> ! 89: ! 90: #import <vm/vm_map.h> ! 91: #import <mach/vm_param.h> ! 92: #import <mach/vm_prot.h> ! 93: #import <vm/vm_kern.h> ! 94: #if defined(ppc) ! 95: #include <machdep/ppc/proc_reg.h> ! 96: #endif /* ppc */ ! 97: /* Macros to clear/set/test flags. */ ! 98: #define SET(t, f) (t) |= (f) ! 99: #define CLR(t, f) (t) &= ~(f) ! 100: #define ISSET(t, f) ((t) & (f)) ! 101: ! 102: /* ! 103: * sys-trace system call. ! 104: */ ! 105: struct ptrace_args { ! 106: int req; ! 107: pid_t pid; ! 108: caddr_t addr; ! 109: int data; ! 110: }; ! 111: int ! 112: ptrace(p, uap, retval) ! 113: struct proc *p; ! 114: struct ptrace_args *uap; ! 115: register_t *retval; ! 116: { ! 117: struct proc *t = current_proc(); /* target process */ ! 118: vm_map_t victim_map; ! 119: vm_offset_t start_addr, end_addr, ! 120: kern_addr, offset; ! 121: vm_size_t size; ! 122: boolean_t change_protection; ! 123: task_t task; ! 124: thread_t thread; ! 125: int *locr0; ! 126: int error = 0; ! 127: ! 128: /* ! 129: * Intercept and deal with "please trace me" request. ! 130: */ ! 131: if (uap->req == PT_TRACE_ME) { ! 132: SET(p->p_flag, P_TRACED); ! 133: /* Non-attached case, our tracer is our parent. */ ! 134: t->p_oppid = t->p_pptr->p_pid; ! 135: return(0); ! 136: } ! 137: ! 138: /* ! 139: * Locate victim, and make sure it is traceable. ! 140: */ ! 141: if ((t = pfind(uap->pid)) == NULL) ! 142: return (ESRCH); ! 143: ! 144: task = t->task; ! 145: if (uap->req == PT_ATTACH) { ! 146: ! 147: /* ! 148: * You can't attach to a process if: ! 149: * (1) it's the process that's doing the attaching, ! 150: */ ! 151: if (t->p_pid == p->p_pid) ! 152: return (EINVAL); ! 153: ! 154: /* ! 155: * (2) it's already being traced, or ! 156: */ ! 157: if (ISSET(t->p_flag, P_TRACED)) ! 158: return (EBUSY); ! 159: ! 160: /* ! 161: * (3) it's not owned by you, or is set-id on exec ! 162: * (unless you're root). ! 163: */ ! 164: if ((t->p_cred->p_ruid != p->p_cred->p_ruid || ! 165: ISSET(t->p_flag, P_SUGID)) && ! 166: (error = suser(p->p_ucred, &p->p_acflag)) != 0) ! 167: return (error); ! 168: ! 169: SET(t->p_flag, P_TRACED); ! 170: t->p_oppid = t->p_pptr->p_pid; ! 171: if (t->p_pptr != p) ! 172: proc_reparent(t, p); ! 173: t->p_xstat = 0; /* XXX ? */ ! 174: /* Halt it dead in its tracks. */ ! 175: psignal(t, SIGSTOP); ! 176: return(0); ! 177: } ! 178: ! 179: /* ! 180: * You can't do what you want to the process if: ! 181: * (1) It's not being traced at all, ! 182: */ ! 183: if (!ISSET(t->p_flag, P_TRACED)) ! 184: return (EPERM); ! 185: ! 186: /* ! 187: * (2) it's not being traced by _you_, or ! 188: */ ! 189: if (t->p_pptr != p) ! 190: return (EBUSY); ! 191: ! 192: /* ! 193: * (3) it's not currently stopped. ! 194: */ ! 195: if (task->user_stop_count == 0 || t->p_stat != SSTOP) ! 196: return (EBUSY); ! 197: ! 198: /* ! 199: * Mach version of ptrace executes request directly here, ! 200: * thus simplifying the interaction of ptrace and signals. ! 201: */ ! 202: switch (uap->req) { ! 203: ! 204: case PT_DETACH: ! 205: if (t->p_oppid != t->p_pptr->p_pid) { ! 206: struct proc *pp; ! 207: ! 208: pp = pfind(t->p_oppid); ! 209: proc_reparent(t, pp ? pp : initproc); ! 210: } ! 211: ! 212: t->p_oppid = 0; ! 213: CLR(t->p_flag, P_TRACED); ! 214: goto resume; ! 215: ! 216: case PT_KILL: ! 217: /* ! 218: * Tell child process to kill itself after it ! 219: * is resumed by adding NSIG to p_cursig. [see issig] ! 220: */ ! 221: psignal(t, SIGKILL); ! 222: goto resume; ! 223: ! 224: case PT_STEP: /* single step the child */ ! 225: case PT_CONTINUE: /* continue the child */ ! 226: thread = (thread_t) queue_first(&task->thread_list); ! 227: locr0 = thread->_uthread->uu_ar0; ! 228: if ((int)uap->addr != 1) { ! 229: #if defined(i386) ! 230: locr0[PC] = (int)uap->addr; ! 231: #elif defined(ppc) ! 232: #define ALIGNED(addr,size) (((unsigned)(addr)&((size)-1))==0) ! 233: if (!ALIGNED((int)uap->addr, sizeof(int))) ! 234: return (ERESTART); ! 235: ! 236: #if defined(ppc) ! 237: thread->pcb->ss.srr0 = (int)uap->addr; ! 238: #endif /* ppc */ ! 239: #undef ALIGNED ! 240: #else ! 241: #error architecture not implemented! ! 242: #endif ! 243: } /* (int)uap->addr != 1 */ ! 244: ! 245: if ((unsigned)uap->data < 0 || (unsigned)uap->data >= NSIG) ! 246: goto errorLabel; ! 247: ! 248: if (uap->data != 0) ! 249: psignal(t, uap->data); ! 250: ! 251: ! 252: if (uap->req == PT_STEP) { ! 253: #if defined(i386) ! 254: locr0[PS] |= PSL_T; ! 255: #elif defined(ppc) ! 256: thread->pcb->ss.srr1 |= MASK(MSR_SE); ! 257: #else ! 258: #error architecture not implemented! ! 259: #endif ! 260: } /* uap->req == PT_STEP */ ! 261: else { /* PT_CONTINUE - clear trace bit if set */ ! 262: #if defined(i386) ! 263: locr0[PS] &= ~PSL_T; ! 264: #elif defined(ppc) ! 265: thread->pcb->ss.srr1 &= ~MASK(MSR_SE); ! 266: #endif ! 267: } ! 268: ! 269: resume: ! 270: t->p_stat = SRUN; ! 271: t->p_xstat = uap->data; ! 272: task_resume(task); ! 273: break; ! 274: ! 275: default: ! 276: errorLabel: ! 277: return(EINVAL); ! 278: } ! 279: return(0); ! 280: } ! 281:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.