1 /* $NetBSD: darwin_ptrace.c,v 1.17 2008/04/28 20:23:41 martin Exp $ */
2
3 /*-
4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Emmanuel Dreyfus.
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 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: darwin_ptrace.c,v 1.17 2008/04/28 20:23:41 martin Exp $");
34
35 #include "opt_ptrace.h"
36
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/mount.h>
41 #include <sys/proc.h>
42 #include <sys/ptrace.h>
43
44 #include <sys/syscall.h>
45 #include <sys/syscallargs.h>
46
47 #include <compat/sys/signal.h>
48
49 #include <compat/mach/mach_types.h>
50 #include <compat/mach/mach_vm.h>
51
52 #include <compat/darwin/darwin_exec.h>
53 #include <compat/darwin/darwin_audit.h>
54 #include <compat/darwin/darwin_ptrace.h>
55 #include <compat/darwin/darwin_syscallargs.h>
56
57 #define ISSET(t, f) ((t) & (f))
58
59 int
60 darwin_sys_ptrace(struct lwp *l, const struct darwin_sys_ptrace_args *uap, register_t *retval)
61 {
62 #if defined(PTRACE) || defined(_LKM)
63 /* {
64 syscallarg(int) req;
65 syscallarg(pid_t) pid;
66 syscallarg(void *) addr;
67 syscallarg(int) data;
68 } */
69 int req = SCARG(uap, req);
70 struct proc *p = l->l_proc;
71 struct darwin_emuldata *ded = NULL;
72 struct proc *t; /* target process */
73 struct sys_ptrace_args bsd_ua;
74 int error;
75
76 #ifdef _LKM
77 #define sys_ptrace (*sysent[SYS_ptrace].sy_call)
78 if (sys_ptrace == sys_nosys)
79 return ENOSYS;
80 #endif
81
82 /* XXXAD locking */
83 SCARG(&bsd_ua, req) = SCARG(uap, req);
84 SCARG(&bsd_ua, pid) = SCARG(uap, pid);
85 SCARG(&bsd_ua, addr) = SCARG(uap, addr);
86 SCARG(&bsd_ua, data) = SCARG(uap, data);
87
88
89 ded = (struct darwin_emuldata *)p->p_emuldata;
90
91 switch (req) {
92 case DARWIN_PT_ATTACHEXC:
93 if ((t = pfind(SCARG(uap, pid))) == NULL)
94 return ESRCH;
95
96 if (t->p_emul != &emul_darwin)
97 return ESRCH;
98 ded = t->p_emuldata;
99
100 if (ded->ded_flags & DARWIN_DED_SIGEXC)
101 return EBUSY;
102
103 ded->ded_flags |= DARWIN_DED_SIGEXC;
104
105 SCARG(&bsd_ua, req) = PT_ATTACH;
106 if ((error = sys_ptrace(l, &bsd_ua, retval)) != 0)
107 ded->ded_flags &= ~DARWIN_DED_SIGEXC;
108
109 return error;
110 break;
111
112 case DARWIN_PT_SIGEXC:
113 if ((p->p_slflag & PSL_TRACED) == 0)
114 return EBUSY;
115
116 ded->ded_flags |= DARWIN_DED_SIGEXC;
117 break;
118
119 case DARWIN_PT_DETACH: {
120 int had_sigexc = 0;
121
122 if ((t = pfind(SCARG(uap, pid))) == NULL)
123 return (ESRCH);
124
125 if ((t->p_emul == &emul_darwin) &&
126 (t->p_slflag & PSL_TRACED) &&
127 (t->p_pptr == p)) {
128 ded = t->p_emuldata;
129 if (ded->ded_flags & DARWIN_DED_SIGEXC) {
130 had_sigexc = 1;
131 ded->ded_flags &= ~DARWIN_DED_SIGEXC;
132 }
133 }
134
135 /*
136 * If the process is not marked as stopped,
137 * sys_ptrace sanity checks will return EBUSY.
138 */
139 mutex_enter(proc_lock);
140 mutex_enter(t->p_lock);
141 proc_stop(t, 0, SIGSTOP);
142 mutex_exit(t->p_lock);
143 mutex_exit(proc_lock);
144
145 if ((error = sys_ptrace(l, &bsd_ua, retval)) != 0) {
146 mutex_enter(proc_lock);
147 mutex_enter(t->p_lock);
148 proc_unstop(t);
149 mutex_exit(t->p_lock);
150 mutex_exit(proc_lock);
151 if (had_sigexc)
152 ded->ded_flags |= DARWIN_DED_SIGEXC;
153 }
154
155 break;
156 }
157
158 case DARWIN_PT_THUPDATE: {
159 int signo = SCARG(uap, data);
160
161 if ((t = pfind(SCARG(uap, pid))) == NULL)
162 return ESRCH;
163
164 /* Checks from native ptrace */
165 if (!ISSET(t->p_slflag, PSL_TRACED))
166 return EPERM;
167
168 if (ISSET(t->p_slflag, PSL_FSTRACE))
169 return EBUSY;
170
171 if (t->p_pptr != p)
172 return EBUSY;
173
174 #if 0
175 if (t->p_stat != SSTOP || !ISSET(t->p_sflag, PS_WAITED))
176 return EBUSY;
177 #endif
178 if ((signo < 0) || (signo > NSIG))
179 return EINVAL;
180
181 t->p_xstat = signo;
182 if (signo != 0)
183 sigaddset(&p->p_sigpend.sp_set, signo);
184
185 break;
186 }
187
188 case DARWIN_PT_READ_U:
189 case DARWIN_PT_WRITE_U:
190 case DARWIN_PT_STEP:
191 case DARWIN_PT_FORCEQUOTA:
192 case DARWIN_PT_DENY_ATTACH:
193 printf("darwin_sys_ptrace: unimplemented command %d\n", req);
194 break;
195
196 /* The other ptrace commands are the same on NetBSD */
197 default:
198 return sys_ptrace(l, &bsd_ua, retval);
199 break;
200 }
201
202 return 0;
203 #else
204 return ENOSYS;
205 #endif /* PTRACE || _LKM */
206 }
207
208 int
209 darwin_sys_kdebug_trace(struct lwp *l, const struct darwin_sys_kdebug_trace_args *uap, register_t *retval)
210 {
211 /* {
212 syscallarg(int) debugid;
213 syscallarg(int) arg1;
214 syscallarg(int) arg2;
215 syscallarg(int) arg3;
216 syscallarg(int) arg4;
217 syscallarg(int) arg5;
218 } */
219 int args[4];
220 char *str;
221
222 args[0] = SCARG(uap, arg1);
223 args[1] = SCARG(uap, arg2);
224 args[2] = SCARG(uap, arg3);
225 args[3] = 0;
226 str = (char*)args;
227
228 #ifdef DEBUG_DARWIN
229 printf("darwin_sys_kdebug_trace(%x, (%x %x %x)/\"%s\", %x, %x)\n",
230 SCARG(uap, debugid), SCARG(uap, arg1), SCARG(uap, arg2),
231 SCARG(uap, arg3), str, SCARG(uap, arg4), SCARG(uap, arg5));
232 #endif
233 return 0;
234 }
Cache object: 77f7a45be4d59ce6b53709dbbafbdbfb
|