xref: /netbsd-src/sys/kern/sys_process.c (revision 001c68bd94f75ce9270b69227c4199fbf34ee396)
1 /*	$NetBSD: sys_process.c,v 1.83 2003/06/29 22:31:27 fvdl Exp $	*/
2 
3 /*-
4  * Copyright (c) 1993 Jan-Simon Pendry.
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  * This code is derived from software contributed to Berkeley by
15  * Jan-Simon Pendry.
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  * 1. Redistributions of source code must retain the above copyright
21  *    notice, this list of conditions and the following disclaimer.
22  * 2. Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the
24  *    documentation and/or other materials provided with the distribution.
25  * 3. All advertising materials mentioning features or use of this software
26  *    must display the following acknowledgement:
27  *	This product includes software developed by the University of
28  *	California, Berkeley and its contributors.
29  * 4. Neither the name of the University nor the names of its contributors
30  *    may be used to endorse or promote products derived from this software
31  *    without specific prior written permission.
32  *
33  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
34  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
35  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
36  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
37  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
39  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
40  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
41  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
42  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
43  * SUCH DAMAGE.
44  *
45  *	from: @(#)sys_process.c	8.1 (Berkeley) 6/10/93
46  */
47 
48 /*
49  * References:
50  *	(1) Bach's "The Design of the UNIX Operating System",
51  *	(2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution,
52  *	(3) the "4.4BSD Programmer's Reference Manual" published
53  *		by USENIX and O'Reilly & Associates.
54  * The 4.4BSD PRM does a reasonably good job of documenting what the various
55  * ptrace() requests should actually do, and its text is quoted several times
56  * in this file.
57  */
58 
59 #include <sys/cdefs.h>
60 __KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.83 2003/06/29 22:31:27 fvdl Exp $");
61 
62 #include <sys/param.h>
63 #include <sys/systm.h>
64 #include <sys/proc.h>
65 #include <sys/errno.h>
66 #include <sys/ptrace.h>
67 #include <sys/uio.h>
68 #include <sys/user.h>
69 #include <sys/ras.h>
70 
71 #include <sys/mount.h>
72 #include <sys/sa.h>
73 #include <sys/syscallargs.h>
74 
75 #include <uvm/uvm_extern.h>
76 
77 #include <machine/reg.h>
78 
79 /* Macros to clear/set/test flags. */
80 #define	SET(t, f)	(t) |= (f)
81 #define	CLR(t, f)	(t) &= ~(f)
82 #define	ISSET(t, f)	((t) & (f))
83 
84 /*
85  * Process debugging system call.
86  */
87 int
88 sys_ptrace(l, v, retval)
89 	struct lwp *l;
90 	void *v;
91 	register_t *retval;
92 {
93 	struct sys_ptrace_args /* {
94 		syscallarg(int) req;
95 		syscallarg(pid_t) pid;
96 		syscallarg(caddr_t) addr;
97 		syscallarg(int) data;
98 	} */ *uap = v;
99 	struct proc *p = l->l_proc;
100 	struct lwp *lt, *lr;
101 	struct proc *t;				/* target process */
102 	struct uio uio;
103 	struct iovec iov;
104 	struct ptrace_io_desc piod;
105 	struct ptrace_lwpinfo pl;
106 	int s, error, write, tmp, size;
107 
108 	/* "A foolish consistency..." XXX */
109 	if (SCARG(uap, req) == PT_TRACE_ME)
110 		t = p;
111 	else {
112 
113 		/* Find the process we're supposed to be operating on. */
114 		if ((t = pfind(SCARG(uap, pid))) == NULL)
115 			return (ESRCH);
116 	}
117 
118 	/* Can't trace a process that's currently exec'ing. */
119 	if ((t->p_flag & P_INEXEC) != 0)
120 		return EAGAIN;
121 
122 	/* Make sure we can operate on it. */
123 	switch (SCARG(uap, req)) {
124 	case  PT_TRACE_ME:
125 		/* Saying that you're being traced is always legal. */
126 		break;
127 
128 	case  PT_ATTACH:
129 	case  PT_DUMPCORE:
130 		/*
131 		 * You can't attach to a process if:
132 		 *	(1) it's the process that's doing the attaching,
133 		 */
134 		if (t->p_pid == p->p_pid)
135 			return (EINVAL);
136 
137 		/*
138 		 *  (2) it's a system process
139 		 */
140 		if (t->p_flag & P_SYSTEM)
141 			return (EPERM);
142 
143 		/*
144 		 *	(3) it's already being traced, or
145 		 */
146 		if (ISSET(t->p_flag, P_TRACED))
147 			return (EBUSY);
148 
149 		/*
150 		 *	(4) it's not owned by you, or is set-id on exec
151 		 *	    (unless you're root), or...
152 		 */
153 		if ((t->p_cred->p_ruid != p->p_cred->p_ruid ||
154 			ISSET(t->p_flag, P_SUGID)) &&
155 		    (error = suser(p->p_ucred, &p->p_acflag)) != 0)
156 			return (error);
157 
158 		/*
159 		 *	(5) ...it's init, which controls the security level
160 		 *	    of the entire system, and the system was not
161 		 *	    compiled with permanently insecure mode turned on
162 		 */
163 		if (t == initproc && securelevel > -1)
164 			return (EPERM);
165 
166 		/*
167 		 * (6) the tracer is chrooted, and its root directory is
168 		 * not at or above the root directory of the tracee
169 		 */
170 
171 		if (!proc_isunder(t, p))
172 			return EPERM;
173 		break;
174 
175 	case  PT_READ_I:
176 	case  PT_READ_D:
177 	case  PT_WRITE_I:
178 	case  PT_WRITE_D:
179 	case  PT_CONTINUE:
180 	case  PT_IO:
181 	case  PT_KILL:
182 	case  PT_DETACH:
183 	case  PT_LWPINFO:
184 #ifdef PT_STEP
185 	case  PT_STEP:
186 #endif
187 #ifdef PT_GETREGS
188 	case  PT_GETREGS:
189 #endif
190 #ifdef PT_SETREGS
191 	case  PT_SETREGS:
192 #endif
193 #ifdef PT_GETFPREGS
194 	case  PT_GETFPREGS:
195 #endif
196 #ifdef PT_SETFPREGS
197 	case  PT_SETFPREGS:
198 #endif
199 
200 #ifdef __HAVE_PTRACE_MACHDEP
201 	PTRACE_MACHDEP_REQUEST_CASES
202 #endif
203 
204 		/*
205 		 * You can't do what you want to the process if:
206 		 *	(1) It's not being traced at all,
207 		 */
208 		if (!ISSET(t->p_flag, P_TRACED))
209 			return (EPERM);
210 
211 		/*
212 		 *	(2) it's being traced by procfs (which has
213 		 *	    different signal delivery semantics),
214 		 */
215 		if (ISSET(t->p_flag, P_FSTRACE))
216 			return (EBUSY);
217 
218 		/*
219 		 *	(3) it's not being traced by _you_, or
220 		 */
221 		if (t->p_pptr != p)
222 			return (EBUSY);
223 
224 		/*
225 		 *	(4) it's not currently stopped.
226 		 */
227 		if (t->p_stat != SSTOP || !ISSET(t->p_flag, P_WAITED))
228 			return (EBUSY);
229 		break;
230 
231 	default:			/* It was not a legal request. */
232 		return (EINVAL);
233 	}
234 
235 	/* Do single-step fixup if needed. */
236 	FIX_SSTEP(t);
237 
238 	/*
239 	 * XXX NJWLWP
240 	 *
241 	 * The entire ptrace interface needs work to be useful to a
242 	 * process with multiple LWPs. For the moment, we'll kluge
243 	 * this; memory access will be fine, but register access will
244 	 * be weird.
245 	 */
246 
247 	lt = proc_representative_lwp(t);
248 
249 	/* Now do the operation. */
250 	write = 0;
251 	*retval = 0;
252 	tmp = 0;
253 
254 	switch (SCARG(uap, req)) {
255 	case  PT_TRACE_ME:
256 		/* Just set the trace flag. */
257 		SET(t->p_flag, P_TRACED);
258 		t->p_opptr = t->p_pptr;
259 		return (0);
260 
261 	case  PT_WRITE_I:		/* XXX no separate I and D spaces */
262 	case  PT_WRITE_D:
263 #if defined(__HAVE_RAS)
264 		/*
265 		 * Can't write to a RAS
266 		 */
267 		if ((t->p_nras != 0) &&
268 		    (ras_lookup(t, SCARG(uap, addr)) != (caddr_t)-1)) {
269 			return (EACCES);
270 		}
271 #endif
272 		write = 1;
273 		tmp = SCARG(uap, data);
274 	case  PT_READ_I:		/* XXX no separate I and D spaces */
275 	case  PT_READ_D:
276 		/* write = 0 done above. */
277 		iov.iov_base = (caddr_t)&tmp;
278 		iov.iov_len = sizeof(tmp);
279 		uio.uio_iov = &iov;
280 		uio.uio_iovcnt = 1;
281 		uio.uio_offset = (off_t)(long)SCARG(uap, addr);
282 		uio.uio_resid = sizeof(tmp);
283 		uio.uio_segflg = UIO_SYSSPACE;
284 		uio.uio_rw = write ? UIO_WRITE : UIO_READ;
285 		uio.uio_procp = p;
286 		error = process_domem(p, t, &uio);
287 		if (!write)
288 			*retval = tmp;
289 		return (error);
290 
291 	case  PT_IO:
292 		error = copyin(SCARG(uap, addr), &piod, sizeof(piod));
293 		if (error)
294 			return (error);
295 		iov.iov_base = piod.piod_addr;
296 		iov.iov_len = piod.piod_len;
297 		uio.uio_iov = &iov;
298 		uio.uio_iovcnt = 1;
299 		uio.uio_offset = (off_t)(long)piod.piod_offs;
300 		uio.uio_resid = piod.piod_len;
301 		uio.uio_segflg = UIO_USERSPACE;
302 		uio.uio_procp = p;
303 		switch (piod.piod_op) {
304 		case PIOD_READ_D:
305 		case PIOD_READ_I:
306 			uio.uio_rw = UIO_READ;
307 			break;
308 		case PIOD_WRITE_D:
309 		case PIOD_WRITE_I:
310 			uio.uio_rw = UIO_WRITE;
311 			break;
312 		default:
313 			return (EINVAL);
314 		}
315 		error = process_domem(p, t, &uio);
316 		piod.piod_len -= uio.uio_resid;
317 		(void) copyout(&piod, SCARG(uap, addr), sizeof(piod));
318 		return (error);
319 
320 	case  PT_DUMPCORE:
321 		return coredump(lt);
322 
323 #ifdef PT_STEP
324 	case  PT_STEP:
325 		/*
326 		 * From the 4.4BSD PRM:
327 		 * "Execution continues as in request PT_CONTINUE; however
328 		 * as soon as possible after execution of at least one
329 		 * instruction, execution stops again. [ ... ]"
330 		 */
331 #endif
332 	case  PT_CONTINUE:
333 	case  PT_DETACH:
334 		/*
335 		 * From the 4.4BSD PRM:
336 		 * "The data argument is taken as a signal number and the
337 		 * child's execution continues at location addr as if it
338 		 * incurred that signal.  Normally the signal number will
339 		 * be either 0 to indicate that the signal that caused the
340 		 * stop should be ignored, or that value fetched out of
341 		 * the process's image indicating which signal caused
342 		 * the stop.  If addr is (int *)1 then execution continues
343 		 * from where it stopped."
344 		 */
345 
346 		/* Check that the data is a valid signal number or zero. */
347 		if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG)
348 			return (EINVAL);
349 
350 		PHOLD(lt);
351 
352 		/* If the address parameter is not (int *)1, set the pc. */
353 		if ((int *)SCARG(uap, addr) != (int *)1)
354 			if ((error = process_set_pc(lt, SCARG(uap, addr))) != 0)
355 				goto relebad;
356 
357 #ifdef PT_STEP
358 		/*
359 		 * Arrange for a single-step, if that's requested and possible.
360 		 */
361 		error = process_sstep(lt, SCARG(uap, req) == PT_STEP);
362 		if (error)
363 			goto relebad;
364 #endif
365 
366 		PRELE(lt);
367 
368 		if (SCARG(uap, req) == PT_DETACH) {
369 			/* give process back to original parent or init */
370 			if (t->p_opptr != t->p_pptr) {
371 				struct proc *pp = t->p_opptr;
372 				proc_reparent(t, pp ? pp : initproc);
373 			}
374 
375 			/* not being traced any more */
376 			t->p_opptr = NULL;
377 			CLR(t->p_flag, P_TRACED|P_WAITED);
378 		}
379 
380 	sendsig:
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 			lr = proc_unstop(t);
386 			/*
387 			 * If the target needs to take a signal, there
388 			 * is no running LWP that will see it, and
389 			 * there is a LWP sleeping interruptably, then
390 			 * get it moving.
391 			 */
392 			if (lr && (t->p_xstat != 0))
393 			    setrunnable(lr);
394 			SCHED_UNLOCK(s);
395 		} else {
396 			if (SCARG(uap, data) != 0)
397 				psignal(t, SCARG(uap, data));
398 		}
399 		return (0);
400 
401 	relebad:
402 		PRELE(lt);
403 		return (error);
404 
405 	case  PT_KILL:
406 		/* just send the process a KILL signal. */
407 		SCARG(uap, data) = SIGKILL;
408 		goto sendsig;	/* in PT_CONTINUE, above. */
409 
410 	case  PT_ATTACH:
411 		/*
412 		 * Go ahead and set the trace flag.
413 		 * Save the old parent (it's reset in
414 		 *   _DETACH, and also in kern_exit.c:wait4()
415 		 * Reparent the process so that the tracing
416 		 *   proc gets to see all the action.
417 		 * Stop the target.
418 		 */
419 		SET(t->p_flag, P_TRACED);
420 		t->p_opptr = t->p_pptr;
421 		if (t->p_pptr != p) {
422 			t->p_pptr->p_flag |= P_CHTRACED;
423 			proc_reparent(t, p);
424 		}
425 		SCARG(uap, data) = SIGSTOP;
426 		goto sendsig;
427 
428 	case PT_LWPINFO:
429 		size = SCARG(uap, data);
430 		if (size < sizeof(lwpid_t))
431 			return (EINVAL);
432 		error = copyin(SCARG(uap, addr), &pl, sizeof(lwpid_t));
433 		if (error)
434 			return (error);
435 		tmp = pl.pl_lwpid;
436 		if (tmp == 0)
437 			lt = LIST_FIRST(&t->p_lwps);
438 		else {
439 			LIST_FOREACH(lt, &t->p_lwps, l_sibling)
440 			    if (lt->l_lid == tmp)
441 				    break;
442 			if (lt == NULL)
443 				return (ESRCH);
444 			lt = LIST_NEXT(lt, l_sibling);
445 		}
446 		pl.pl_lwpid = 0;
447 		pl.pl_event = 0;
448 		if (lt) {
449 			pl.pl_lwpid = lt->l_lid;
450 			if (lt->l_lid == t->p_sigctx.ps_lwp)
451 				pl.pl_event = PL_EVENT_SIGNAL;
452 		}
453 
454 		error = copyout(&pl, SCARG(uap, addr), SCARG(uap, data));
455 
456 		return (0);
457 
458 #ifdef PT_SETREGS
459 	case  PT_SETREGS:
460 		write = 1;
461 #endif
462 #ifdef PT_GETREGS
463 	case  PT_GETREGS:
464 		/* write = 0 done above. */
465 #endif
466 #if defined(PT_SETREGS) || defined(PT_GETREGS)
467 		tmp = SCARG(uap, data);
468 		if (tmp != 0 && t->p_nlwps > 1) {
469 			LIST_FOREACH(lt, &t->p_lwps, l_sibling)
470 			    if (lt->l_lid == tmp)
471 				    break;
472 			if (lt == NULL)
473 				return (ESRCH);
474 		}
475 		if (!process_validregs(t))
476 			return (EINVAL);
477 		else {
478 			iov.iov_base = SCARG(uap, addr);
479 			iov.iov_len = sizeof(struct reg);
480 			uio.uio_iov = &iov;
481 			uio.uio_iovcnt = 1;
482 			uio.uio_offset = 0;
483 			uio.uio_resid = sizeof(struct reg);
484 			uio.uio_segflg = UIO_USERSPACE;
485 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
486 			uio.uio_procp = p;
487 			return (process_doregs(p, lt, &uio));
488 		}
489 #endif
490 
491 #ifdef PT_SETFPREGS
492 	case  PT_SETFPREGS:
493 		write = 1;
494 #endif
495 #ifdef PT_GETFPREGS
496 	case  PT_GETFPREGS:
497 		/* write = 0 done above. */
498 #endif
499 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
500 		tmp = SCARG(uap, data);
501 		if (tmp != 0 && t->p_nlwps > 1) {
502 			LIST_FOREACH(lt, &t->p_lwps, l_sibling)
503 			    if (lt->l_lid == tmp)
504 				    break;
505 			if (lt == NULL)
506 				return (ESRCH);
507 		}
508 		if (!process_validfpregs(t))
509 			return (EINVAL);
510 		else {
511 			iov.iov_base = SCARG(uap, addr);
512 			iov.iov_len = sizeof(struct fpreg);
513 			uio.uio_iov = &iov;
514 			uio.uio_iovcnt = 1;
515 			uio.uio_offset = 0;
516 			uio.uio_resid = sizeof(struct fpreg);
517 			uio.uio_segflg = UIO_USERSPACE;
518 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
519 			uio.uio_procp = p;
520 			return (process_dofpregs(p, lt, &uio));
521 		}
522 #endif
523 
524 #ifdef __HAVE_PTRACE_MACHDEP
525 	PTRACE_MACHDEP_REQUEST_CASES
526 		return (ptrace_machdep_dorequest(p, lt,
527 		    SCARG(uap, req), SCARG(uap, addr),
528 		    SCARG(uap, data)));
529 #endif
530 	}
531 
532 #ifdef DIAGNOSTIC
533 	panic("ptrace: impossible");
534 #endif
535 	return 0;
536 }
537 
538 int
539 process_doregs(curp, l, uio)
540 	struct proc *curp;		/* tracer */
541 	struct lwp *l;			/* traced */
542 	struct uio *uio;
543 {
544 #if defined(PT_GETREGS) || defined(PT_SETREGS)
545 	int error;
546 	struct reg r;
547 	char *kv;
548 	int kl;
549 
550 	if ((error = process_checkioperm(curp, l->l_proc)) != 0)
551 		return error;
552 
553 	kl = sizeof(r);
554 	kv = (char *) &r;
555 
556 	kv += uio->uio_offset;
557 	kl -= uio->uio_offset;
558 	if (kl < 0)
559 		return (EINVAL);
560 	if ((size_t) kl > uio->uio_resid)
561 		kl = uio->uio_resid;
562 
563 	PHOLD(l);
564 
565 	error = process_read_regs(l, &r);
566 	if (error == 0)
567 		error = uiomove(kv, kl, uio);
568 	if (error == 0 && uio->uio_rw == UIO_WRITE) {
569 		if (l->l_stat != LSSTOP)
570 			error = EBUSY;
571 		else
572 			error = process_write_regs(l, &r);
573 	}
574 
575 	PRELE(l);
576 
577 	uio->uio_offset = 0;
578 	return (error);
579 #else
580 	return (EINVAL);
581 #endif
582 }
583 
584 int
585 process_validregs(p)
586 	struct proc *p;
587 {
588 
589 #if defined(PT_SETREGS) || defined(PT_GETREGS)
590 	return ((p->p_flag & P_SYSTEM) == 0);
591 #else
592 	return (0);
593 #endif
594 }
595 
596 int
597 process_dofpregs(curp, l, uio)
598 	struct proc *curp;		/* tracer */
599 	struct lwp *l;			/* traced */
600 	struct uio *uio;
601 {
602 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS)
603 	int error;
604 	struct fpreg r;
605 	char *kv;
606 	int kl;
607 
608 	if ((error = process_checkioperm(curp, l->l_proc)) != 0)
609 		return (error);
610 
611 	kl = sizeof(r);
612 	kv = (char *) &r;
613 
614 	kv += uio->uio_offset;
615 	kl -= uio->uio_offset;
616 	if (kl < 0)
617 		return (EINVAL);
618 	if ((size_t) kl > uio->uio_resid)
619 		kl = uio->uio_resid;
620 
621 	PHOLD(l);
622 
623 	error = process_read_fpregs(l, &r);
624 	if (error == 0)
625 		error = uiomove(kv, kl, uio);
626 	if (error == 0 && uio->uio_rw == UIO_WRITE) {
627 		if (l->l_stat != LSSTOP)
628 			error = EBUSY;
629 		else
630 			error = process_write_fpregs(l, &r);
631 	}
632 
633 	PRELE(l);
634 
635 	uio->uio_offset = 0;
636 	return (error);
637 #else
638 	return (EINVAL);
639 #endif
640 }
641 
642 int
643 process_validfpregs(p)
644 	struct proc *p;
645 {
646 
647 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
648 	return ((p->p_flag & P_SYSTEM) == 0);
649 #else
650 	return (0);
651 #endif
652 }
653 
654 int
655 process_domem(curp, p, uio)
656 	struct proc *curp;		/* tracer */
657 	struct proc *p;			/* traced */
658 	struct uio *uio;
659 {
660 	int error;
661 
662 	size_t len;
663 #ifdef PMAP_NEED_PROCWR
664 	vaddr_t	addr;
665 #endif
666 
667 	len = uio->uio_resid;
668 
669 	if (len == 0)
670 		return (0);
671 
672 #ifdef PMAP_NEED_PROCWR
673 	addr = uio->uio_offset;
674 #endif
675 
676 	if ((error = process_checkioperm(curp, p)) != 0)
677 		return (error);
678 
679 	/* XXXCDC: how should locking work here? */
680 	if ((p->p_flag & P_WEXIT) || (p->p_vmspace->vm_refcnt < 1))
681 		return(EFAULT);
682 	p->p_vmspace->vm_refcnt++;  /* XXX */
683 	error = uvm_io(&p->p_vmspace->vm_map, uio);
684 	uvmspace_free(p->p_vmspace);
685 
686 #ifdef PMAP_NEED_PROCWR
687 	if (uio->uio_rw == UIO_WRITE)
688 		pmap_procwr(p, addr, len);
689 #endif
690 	return (error);
691 }
692 
693 /*
694  * Ensure that a process has permission to perform I/O on another.
695  * Arguments:
696  *	p	The process wishing to do the I/O (the tracer).
697  *	t	The process who's memory/registers will be read/written.
698  */
699 int
700 process_checkioperm(p, t)
701 	struct proc *p, *t;
702 {
703 	int error;
704 
705 	/*
706 	 * You cannot attach to a processes mem/regs if:
707 	 *
708 	 *	(1) It is currently exec'ing
709 	 */
710 	if (ISSET(t->p_flag, P_INEXEC))
711 		return (EAGAIN);
712 
713 	/*
714 	 *	(2) it's not owned by you, or is set-id on exec
715 	 *	    (unless you're root), or...
716 	 */
717 	if ((t->p_cred->p_ruid != p->p_cred->p_ruid ||
718 		ISSET(t->p_flag, P_SUGID)) &&
719 	    (error = suser(p->p_ucred, &p->p_acflag)) != 0)
720 		return (error);
721 
722 	/*
723 	 *	(3) ...it's init, which controls the security level
724 	 *	    of the entire system, and the system was not
725 	 *	    compiled with permanetly insecure mode turned on.
726 	 */
727 	if (t == initproc && securelevel > -1)
728 		return (EPERM);
729 
730 	/*
731 	 *	(4) the tracer is chrooted, and its root directory is
732 	 * 	    not at or above the root directory of the tracee
733 	 */
734 	if (!proc_isunder(t, p))
735 		return (EPERM);
736 
737 	return (0);
738 }
739