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