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