1 /* $OpenBSD: sys_process.c,v 1.30 2005/04/16 22:19:28 kettenis Exp $ */
2 /* $OpenBSD: sys_process.c,v 1.27 2004/02/08 00:04:21 deraadt Exp $ */
3 /* + 1.43.6.1 */
4 /* $NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $ */
5
6 /*-
7 * Copyright (c) 1994 Christopher G. Demetriou. All rights reserved.
8 * Copyright (c) 1982, 1986, 1989, 1993
9 * The Regents of the University of California. All rights reserved.
10 * (c) UNIX System Laboratories, Inc.
11 * All or some portions of this file are derived from material licensed
12 * to the University of California by American Telephone and Telegraph
13 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
14 * the permission of UNIX System Laboratories, Inc.
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 * 3. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * from: @(#)sys_process.c 8.1 (Berkeley) 6/10/93
41 */
42
43 /*
44 * References:
45 * (1) Bach's "The Design of the UNIX Operating System",
46 * (2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution,
47 * (3) the "4.4BSD Programmer's Reference Manual" published
48 * by USENIX and O'Reilly & Associates.
49 * The 4.4BSD PRM does a reasonably good job of documenting what the various
50 * ptrace() requests should actually do, and its text is quoted several times
51 * in this file.
52 */
53
54 #include <sys/param.h>
55 #include <sys/systm.h>
56 #include <sys/proc.h>
57 #include <sys/signalvar.h>
58 #include <sys/errno.h>
59 #include <sys/ptrace.h>
60 #include <sys/uio.h>
61 #include <sys/user.h>
62
63 #include <sys/mount.h>
64 #include <sys/syscallargs.h>
65
66 #include <uvm/uvm_extern.h>
67
68 #include <machine/reg.h>
69
70 #include <miscfs/procfs/procfs.h>
71
72 /*
73 * Process debugging system call.
74 */
75 int
sys_ptrace(p,v,retval)76 sys_ptrace(p, v, retval)
77 struct proc *p;
78 void *v;
79 register_t *retval;
80 {
81 struct sys_ptrace_args /* {
82 syscallarg(int) req;
83 syscallarg(pid_t) pid;
84 syscallarg(caddr_t) addr;
85 syscallarg(int) data;
86 } */ *uap = v;
87 struct proc *t; /* target process */
88 struct uio uio;
89 struct iovec iov;
90 struct ptrace_io_desc piod;
91 struct reg regs;
92 #if defined (PT_SETFPREGS) || defined (PT_GETFPREGS)
93 struct fpreg fpregs;
94 #endif
95 #if defined (PT_SETXMMREGS) || defined (PT_GETXMMREGS)
96 struct xmmregs xmmregs;
97 #endif
98 #ifdef PT_WCOOKIE
99 register_t wcookie;
100 #endif
101 int error, write;
102 int temp;
103
104 /* "A foolish consistency..." XXX */
105 if (SCARG(uap, req) == PT_TRACE_ME)
106 t = p;
107 else {
108
109 /* Find the process we're supposed to be operating on. */
110 if ((t = pfind(SCARG(uap, pid))) == NULL)
111 return (ESRCH);
112 }
113
114 if ((t->p_flag & P_INEXEC) != 0)
115 return (EAGAIN);
116
117 /* Make sure we can operate on it. */
118 switch (SCARG(uap, req)) {
119 case PT_TRACE_ME:
120 /* Saying that you're being traced is always legal. */
121 break;
122
123 case PT_ATTACH:
124 /*
125 * You can't attach to a process if:
126 * (1) it's the process that's doing the attaching,
127 */
128 if (t->p_pid == p->p_pid)
129 return (EINVAL);
130
131 /*
132 * (2) it's a system process
133 */
134 if (ISSET(t->p_flag, P_SYSTEM))
135 return (EPERM);
136
137 /*
138 * (3) it's already being traced, or
139 */
140 if (ISSET(t->p_flag, P_TRACED))
141 return (EBUSY);
142
143 /*
144 * (4) it's not owned by you, or the last exec
145 * gave us setuid/setgid privs (unless
146 * you're root), or...
147 *
148 * [Note: once P_SUGID or P_SUGIDEXEC gets set in
149 * execve(), they stay set until the process does
150 * another execve(). Hence this prevents a setuid
151 * process which revokes it's special privileges using
152 * setuid() from being traced. This is good security.]
153 */
154 if ((t->p_cred->p_ruid != p->p_cred->p_ruid ||
155 ISSET(t->p_flag, P_SUGIDEXEC) ||
156 ISSET(t->p_flag, P_SUGID)) &&
157 (error = suser(p, 0)) != 0)
158 return (error);
159
160 /*
161 * (5) ...it's init, which controls the security level
162 * of the entire system, and the system was not
163 * compiled with permanently insecure mode turned
164 * on.
165 */
166 if ((t->p_pid == 1) && (securelevel > -1))
167 return (EPERM);
168
169 /*
170 * (6) it's an ancestor of the current process and
171 * not init (because that would create a loop in
172 * the process graph).
173 */
174 if (t->p_pid != 1 && inferior(p, t))
175 return (EINVAL);
176 break;
177
178 case PT_READ_I:
179 case PT_READ_D:
180 case PT_WRITE_I:
181 case PT_WRITE_D:
182 case PT_IO:
183 case PT_CONTINUE:
184 case PT_KILL:
185 case PT_DETACH:
186 #ifdef PT_STEP
187 case PT_STEP:
188 #endif
189 case PT_GETREGS:
190 case PT_SETREGS:
191 #ifdef PT_GETFPREGS
192 case PT_GETFPREGS:
193 #endif
194 #ifdef PT_SETFPREGS
195 case PT_SETFPREGS:
196 #endif
197 #ifdef PT_GETXMMREGS
198 case PT_GETXMMREGS:
199 #endif
200 #ifdef PT_SETXMMREGS
201 case PT_SETXMMREGS:
202 #endif
203 #ifdef PT_WCOOKIE
204 case PT_WCOOKIE:
205 #endif
206 /*
207 * You can't do what you want to the process if:
208 * (1) It's not being traced at all,
209 */
210 if (!ISSET(t->p_flag, P_TRACED))
211 return (EPERM);
212
213 /*
214 * (2) it's not being traced by _you_, or
215 */
216 if (t->p_pptr != p)
217 return (EBUSY);
218
219 /*
220 * (3) it's not currently stopped.
221 */
222 if (t->p_stat != SSTOP || !ISSET(t->p_flag, P_WAITED))
223 return (EBUSY);
224 break;
225
226 default: /* It was not a legal request. */
227 return (EINVAL);
228 }
229
230 /* Do single-step fixup if needed. */
231 FIX_SSTEP(t);
232
233 /* Now do the operation. */
234 write = 0;
235 *retval = 0;
236
237 switch (SCARG(uap, req)) {
238 case PT_TRACE_ME:
239 /* Just set the trace flag. */
240 SET(t->p_flag, P_TRACED);
241 t->p_oppid = t->p_pptr->p_pid;
242 return (0);
243
244 case PT_WRITE_I: /* XXX no separate I and D spaces */
245 case PT_WRITE_D:
246 write = 1;
247 temp = SCARG(uap, data);
248 case PT_READ_I: /* XXX no separate I and D spaces */
249 case PT_READ_D:
250 /* write = 0 done above. */
251 iov.iov_base = (caddr_t)&temp;
252 iov.iov_len = sizeof(int);
253 uio.uio_iov = &iov;
254 uio.uio_iovcnt = 1;
255 uio.uio_offset = (off_t)(unsigned long)SCARG(uap, addr);
256 uio.uio_resid = sizeof(int);
257 uio.uio_segflg = UIO_SYSSPACE;
258 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
259 uio.uio_procp = p;
260 error = procfs_domem(p, t, NULL, &uio);
261 if (write == 0)
262 *retval = temp;
263 return (error);
264 case PT_IO:
265 error = copyin(SCARG(uap, addr), &piod, sizeof(piod));
266 if (error)
267 return (error);
268 iov.iov_base = piod.piod_addr;
269 iov.iov_len = piod.piod_len;
270 uio.uio_iov = &iov;
271 uio.uio_iovcnt = 1;
272 uio.uio_offset = (off_t)(unsigned long)piod.piod_offs;
273 uio.uio_resid = piod.piod_len;
274 uio.uio_segflg = UIO_USERSPACE;
275 uio.uio_procp = p;
276 switch (piod.piod_op) {
277 case PIOD_READ_D:
278 case PIOD_READ_I:
279 uio.uio_rw = UIO_READ;
280 break;
281 case PIOD_WRITE_D:
282 case PIOD_WRITE_I:
283 uio.uio_rw = UIO_WRITE;
284 break;
285 default:
286 return (EINVAL);
287 }
288 error = procfs_domem(p, t, NULL, &uio);
289 piod.piod_len -= uio.uio_resid;
290 (void) copyout(&piod, SCARG(uap, addr), sizeof(piod));
291 return (error);
292 #ifdef PT_STEP
293 case PT_STEP:
294 /*
295 * From the 4.4BSD PRM:
296 * "Execution continues as in request PT_CONTINUE; however
297 * as soon as possible after execution of at least one
298 * instruction, execution stops again. [ ... ]"
299 */
300 #endif
301 case PT_CONTINUE:
302 /*
303 * From the 4.4BSD PRM:
304 * "The data argument is taken as a signal number and the
305 * child's execution continues at location addr as if it
306 * incurred that signal. Normally the signal number will
307 * be either 0 to indicate that the signal that caused the
308 * stop should be ignored, or that value fetched out of
309 * the process's image indicating which signal caused
310 * the stop. If addr is (int *)1 then execution continues
311 * from where it stopped."
312 */
313
314 /* Check that the data is a valid signal number or zero. */
315 if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG)
316 return (EINVAL);
317
318 PHOLD(t);
319 /* If the address paramter is not (int *)1, set the pc. */
320 if ((int *)SCARG(uap, addr) != (int *)1)
321 if ((error = process_set_pc(t, SCARG(uap, addr))) != 0)
322 goto relebad;
323
324 #ifdef PT_STEP
325 /*
326 * Arrange for a single-step, if that's requested and possible.
327 */
328 error = process_sstep(t, SCARG(uap, req) == PT_STEP);
329 if (error)
330 goto relebad;
331 #endif
332 PRELE(t);
333 goto sendsig;
334
335 case PT_DETACH:
336 /*
337 * From the 4.4BSD PRM:
338 * "The data argument is taken as a signal number and the
339 * child's execution continues at location addr as if it
340 * incurred that signal. Normally the signal number will
341 * be either 0 to indicate that the signal that caused the
342 * stop should be ignored, or that value fetched out of
343 * the process's image indicating which signal caused
344 * the stop. If addr is (int *)1 then execution continues
345 * from where it stopped."
346 */
347
348 /* Check that the data is a valid signal number or zero. */
349 if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG)
350 return (EINVAL);
351
352 PHOLD(t);
353 #ifdef PT_STEP
354 /*
355 * Arrange for a single-step, if that's requested and possible.
356 */
357 error = process_sstep(t, SCARG(uap, req) == PT_STEP);
358 if (error)
359 goto relebad;
360 #endif
361 PRELE(t);
362
363 /* give process back to original parent or init */
364 if (t->p_oppid != t->p_pptr->p_pid) {
365 struct proc *pp;
366
367 pp = pfind(t->p_oppid);
368 proc_reparent(t, pp ? pp : initproc);
369 }
370
371 /* not being traced any more */
372 t->p_oppid = 0;
373 CLR(t->p_flag, P_TRACED|P_WAITED);
374
375 sendsig:
376 /* Finally, deliver the requested signal (or none). */
377 if (t->p_stat == SSTOP) {
378 t->p_xstat = SCARG(uap, data);
379 setrunnable(t);
380 } else {
381 if (SCARG(uap, data) != 0)
382 psignal(t, SCARG(uap, data));
383 }
384 return (0);
385
386 relebad:
387 PRELE(t);
388 return (error);
389
390 case PT_KILL:
391 /* just send the process a KILL signal. */
392 SCARG(uap, data) = SIGKILL;
393 goto sendsig; /* in PT_CONTINUE, above. */
394
395 case PT_ATTACH:
396 /*
397 * As done in procfs:
398 * Go ahead and set the trace flag.
399 * Save the old parent (it's reset in
400 * _DETACH, and also in kern_exit.c:wait4()
401 * Reparent the process so that the tracing
402 * proc gets to see all the action.
403 * Stop the target.
404 */
405 SET(t->p_flag, P_TRACED);
406 t->p_oppid = t->p_pptr->p_pid;
407 if (t->p_pptr != p)
408 proc_reparent(t, p);
409 SCARG(uap, data) = SIGSTOP;
410 goto sendsig;
411
412 case PT_SETREGS:
413 KASSERT((p->p_flag & P_SYSTEM) == 0);
414 if ((error = procfs_checkioperm(p, t)) != 0)
415 return (error);
416
417 error = copyin(SCARG(uap, addr), ®s, sizeof(regs));
418 if (error)
419 return (error);
420 PHOLD(p);
421 error = process_write_regs(t, ®s);
422 PRELE(p);
423 return (error);
424 case PT_GETREGS:
425 KASSERT((p->p_flag & P_SYSTEM) == 0);
426 if ((error = procfs_checkioperm(p, t)) != 0)
427 return (error);
428
429 PHOLD(p);
430 error = process_read_regs(t, ®s);
431 PRELE(p);
432 if (error)
433 return (error);
434 return (copyout(®s, SCARG(uap, addr), sizeof (regs)));
435 #ifdef PT_SETFPREGS
436 case PT_SETFPREGS:
437 KASSERT((p->p_flag & P_SYSTEM) == 0);
438 if ((error = procfs_checkioperm(p, t)) != 0)
439 return (error);
440
441 error = copyin(SCARG(uap, addr), &fpregs, sizeof(fpregs));
442 if (error)
443 return (error);
444 PHOLD(p);
445 error = process_write_fpregs(t, &fpregs);
446 PRELE(p);
447 return (error);
448 #endif
449 #ifdef PT_GETFPREGS
450 case PT_GETFPREGS:
451 KASSERT((p->p_flag & P_SYSTEM) == 0);
452 if ((error = procfs_checkioperm(p, t)) != 0)
453 return (error);
454
455 PHOLD(p);
456 error = process_read_fpregs(t, &fpregs);
457 PRELE(p);
458 if (error)
459 return (error);
460 return (copyout(&fpregs, SCARG(uap, addr), sizeof (fpregs)));
461 #endif
462 #ifdef PT_SETXMMREGS
463 case PT_SETXMMREGS:
464 KASSERT((p->p_flag & P_SYSTEM) == 0);
465 if ((error = procfs_checkioperm(p, t)) != 0)
466 return (error);
467
468 error = copyin(SCARG(uap, addr), &xmmregs, sizeof(xmmregs));
469 if (error)
470 return (error);
471 PHOLD(p);
472 error = process_write_xmmregs(t, &xmmregs);
473 PRELE(p);
474 return (error);
475 #endif
476 #ifdef PT_GETXMMREGS
477 case PT_GETXMMREGS:
478 KASSERT((p->p_flag & P_SYSTEM) == 0);
479 if ((error = procfs_checkioperm(p, t)) != 0)
480 return (error);
481
482 PHOLD(p);
483 error = process_read_xmmregs(t, &xmmregs);
484 PRELE(p);
485 if (error)
486 return (error);
487 return (copyout(&xmmregs, SCARG(uap, addr), sizeof (xmmregs)));
488 #endif
489 #ifdef PT_WCOOKIE
490 case PT_WCOOKIE:
491 wcookie = process_get_wcookie (t);
492 return (copyout(&wcookie, SCARG(uap, addr),
493 sizeof (register_t)));
494 #endif
495 }
496
497 #ifdef DIAGNOSTIC
498 panic("ptrace: impossible");
499 #endif
500 return 0;
501 }
502