xref: /openbsd/sys/kern/sys_process.c (revision a6445c1d)
1 /*	$OpenBSD: sys_process.c,v 1.65 2014/09/08 01:47:06 guenther 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/exec.h>
55 #include <sys/proc.h>
56 #include <sys/signalvar.h>
57 #include <sys/errno.h>
58 #include <sys/malloc.h>
59 #include <sys/ptrace.h>
60 #include <sys/uio.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 int	process_auxv_offset(struct proc *, struct proc *, struct uio *);
71 
72 #ifdef PTRACE
73 /*
74  * Process debugging system call.
75  */
76 int
77 sys_ptrace(struct proc *p, void *v, register_t *retval)
78 {
79 	struct sys_ptrace_args /* {
80 		syscallarg(int) req;
81 		syscallarg(pid_t) pid;
82 		syscallarg(caddr_t) addr;
83 		syscallarg(int) data;
84 	} */ *uap = v;
85 	struct proc *t;				/* target thread */
86 	struct process *tr;			/* target process */
87 	struct uio uio;
88 	struct iovec iov;
89 	struct ptrace_io_desc piod;
90 	struct ptrace_event pe;
91 	struct ptrace_thread_state pts;
92 	struct reg *regs;
93 #if defined (PT_SETFPREGS) || defined (PT_GETFPREGS)
94 	struct fpreg *fpregs;
95 #endif
96 #if defined (PT_SETXMMREGS) || defined (PT_GETXMMREGS)
97 	struct xmmregs *xmmregs;
98 #endif
99 #ifdef PT_WCOOKIE
100 	register_t wcookie;
101 #endif
102 	int error, write;
103 	int temp;
104 	int req = SCARG(uap, req);
105 	int s;
106 
107 	/* "A foolish consistency..." XXX */
108 	switch (req) {
109 	case PT_TRACE_ME:
110 		t = p;
111 		break;
112 
113 	/* calls that only operate on the PID */
114 	case PT_READ_I:
115 	case PT_READ_D:
116 	case PT_WRITE_I:
117 	case PT_WRITE_D:
118 	case PT_KILL:
119 	case PT_ATTACH:
120 	case PT_IO:
121 	case PT_SET_EVENT_MASK:
122 	case PT_GET_EVENT_MASK:
123 	case PT_GET_PROCESS_STATE:
124 	case PT_GET_THREAD_FIRST:
125 	case PT_GET_THREAD_NEXT:
126 	default:
127 		/* Find the process we're supposed to be operating on. */
128 		if ((t = pfind(SCARG(uap, pid))) == NULL)
129 			return (ESRCH);
130 		if (t->p_flag & P_THREAD)
131 			return (ESRCH);
132 		break;
133 
134 	/* calls that accept a PID or a thread ID */
135 	case PT_CONTINUE:
136 	case PT_DETACH:
137 #ifdef PT_STEP
138 	case PT_STEP:
139 #endif
140 	case PT_GETREGS:
141 	case PT_SETREGS:
142 #ifdef PT_GETFPREGS
143 	case PT_GETFPREGS:
144 #endif
145 #ifdef PT_SETFPREGS
146 	case PT_SETFPREGS:
147 #endif
148 #ifdef PT_GETXMMREGS
149 	case PT_GETXMMREGS:
150 #endif
151 #ifdef PT_SETXMMREGS
152 	case PT_SETXMMREGS:
153 #endif
154 		if (SCARG(uap, pid) > THREAD_PID_OFFSET) {
155 			t = pfind(SCARG(uap, pid) - THREAD_PID_OFFSET);
156 			if (t == NULL)
157 				return (ESRCH);
158 		} else {
159 			if ((t = pfind(SCARG(uap, pid))) == NULL)
160 				return (ESRCH);
161 			if (t->p_flag & P_THREAD)
162 				return (ESRCH);
163 		}
164 		break;
165 	}
166 	tr = t->p_p;
167 
168 	if ((tr->ps_flags & PS_INEXEC) != 0)
169 		return (EAGAIN);
170 
171 	/* Make sure we can operate on it. */
172 	switch (req) {
173 	case  PT_TRACE_ME:
174 		/* Saying that you're being traced is always legal. */
175 		break;
176 
177 	case  PT_ATTACH:
178 		/*
179 		 * You can't attach to a process if:
180 		 *	(1) it's the process that's doing the attaching,
181 		 */
182 		if (tr == p->p_p)
183 			return (EINVAL);
184 
185 		/*
186 		 *	(2) it's a system process
187 		 */
188 		if (ISSET(tr->ps_flags, PS_SYSTEM))
189 			return (EPERM);
190 
191 		/*
192 		 *	(3) it's already being traced, or
193 		 */
194 		if (ISSET(tr->ps_flags, PS_TRACED))
195 			return (EBUSY);
196 
197 		/*
198 		 *	(4) it's not owned by you, or the last exec
199 		 *	    gave us setuid/setgid privs (unless
200 		 *	    you're root), or...
201 		 *
202 		 *      [Note: once PS_SUGID or PS_SUGIDEXEC gets set in
203 		 *	execve(), they stay set until the process does
204 		 *	another execve().  Hence this prevents a setuid
205 		 *	process which revokes its special privileges using
206 		 *	setuid() from being traced.  This is good security.]
207 		 */
208 		if ((tr->ps_ucred->cr_ruid != p->p_ucred->cr_ruid ||
209 		    ISSET(tr->ps_flags, PS_SUGIDEXEC | PS_SUGID)) &&
210 		    (error = suser(p, 0)) != 0)
211 			return (error);
212 
213 		/*
214 		 *	(5) ...it's init, which controls the security level
215 		 *	    of the entire system, and the system was not
216 		 *          compiled with permanently insecure mode turned
217 		 *	    on.
218 		 */
219 		if ((tr->ps_pid == 1) && (securelevel > -1))
220 			return (EPERM);
221 
222 		/*
223 		 *	(6) it's an ancestor of the current process and
224 		 *	    not init (because that would create a loop in
225 		 *	    the process graph).
226 		 */
227 		if (tr->ps_pid != 1 && inferior(p->p_p, tr))
228 			return (EINVAL);
229 		break;
230 
231 	case  PT_READ_I:
232 	case  PT_READ_D:
233 	case  PT_WRITE_I:
234 	case  PT_WRITE_D:
235 	case  PT_IO:
236 	case  PT_CONTINUE:
237 	case  PT_KILL:
238 	case  PT_DETACH:
239 #ifdef PT_STEP
240 	case  PT_STEP:
241 #endif
242 	case  PT_SET_EVENT_MASK:
243 	case  PT_GET_EVENT_MASK:
244 	case  PT_GET_PROCESS_STATE:
245 	case  PT_GETREGS:
246 	case  PT_SETREGS:
247 #ifdef PT_GETFPREGS
248 	case  PT_GETFPREGS:
249 #endif
250 #ifdef PT_SETFPREGS
251 	case  PT_SETFPREGS:
252 #endif
253 #ifdef PT_GETXMMREGS
254 	case  PT_GETXMMREGS:
255 #endif
256 #ifdef PT_SETXMMREGS
257 	case  PT_SETXMMREGS:
258 #endif
259 #ifdef PT_WCOOKIE
260 	case  PT_WCOOKIE:
261 #endif
262 		/*
263 		 * You can't do what you want to the process if:
264 		 *	(1) It's not being traced at all,
265 		 */
266 		if (!ISSET(tr->ps_flags, PS_TRACED))
267 			return (EPERM);
268 
269 		/*
270 		 *	(2) it's not being traced by _you_, or
271 		 */
272 		if (tr->ps_pptr != p->p_p)
273 			return (EBUSY);
274 
275 		/*
276 		 *	(3) it's not currently stopped.
277 		 */
278 		if (t->p_stat != SSTOP || !ISSET(tr->ps_flags, PS_WAITED))
279 			return (EBUSY);
280 		break;
281 
282 	case  PT_GET_THREAD_FIRST:
283 	case  PT_GET_THREAD_NEXT:
284 		/*
285 		 * You can't do what you want to the process if:
286 		 *	(1) It's not being traced at all,
287 		 */
288 		if (!ISSET(tr->ps_flags, PS_TRACED))
289 			return (EPERM);
290 
291 		/*
292 		 *	(2) it's not being traced by _you_, or
293 		 */
294 		if (tr->ps_pptr != p->p_p)
295 			return (EBUSY);
296 
297 		/*
298 		 * Do the work here because the request isn't actually
299 		 * associated with 't'
300 		 */
301 		if (SCARG(uap, data) != sizeof(pts))
302 			return (EINVAL);
303 
304 		if (req == PT_GET_THREAD_NEXT) {
305 			error = copyin(SCARG(uap, addr), &pts, sizeof(pts));
306 			if (error)
307 				return (error);
308 
309 			t = pfind(pts.pts_tid - THREAD_PID_OFFSET);
310 			if (t == NULL || ISSET(t->p_flag, P_WEXIT))
311 				return (ESRCH);
312 			if (t->p_p != tr)
313 				return (EINVAL);
314 			t = TAILQ_NEXT(t, p_thr_link);
315 		} else {
316 			t = TAILQ_FIRST(&tr->ps_threads);
317 		}
318 
319 		if (t == NULL)
320 			pts.pts_tid = -1;
321 		else
322 			pts.pts_tid = t->p_pid + THREAD_PID_OFFSET;
323 		return (copyout(&pts, SCARG(uap, addr), sizeof(pts)));
324 
325 	default:			/* It was not a legal request. */
326 		return (EINVAL);
327 	}
328 
329 	/* Do single-step fixup if needed. */
330 	FIX_SSTEP(t);
331 
332 	/* Now do the operation. */
333 	write = 0;
334 	*retval = 0;
335 
336 	switch (req) {
337 	case  PT_TRACE_ME:
338 		/* Just set the trace flag. */
339 		atomic_setbits_int(&tr->ps_flags, PS_TRACED);
340 		tr->ps_oppid = tr->ps_pptr->ps_pid;
341 		if (tr->ps_ptstat == NULL)
342 			tr->ps_ptstat = malloc(sizeof(*tr->ps_ptstat),
343 			    M_SUBPROC, M_WAITOK);
344 		memset(tr->ps_ptstat, 0, sizeof(*tr->ps_ptstat));
345 		return (0);
346 
347 	case  PT_WRITE_I:		/* XXX no separate I and D spaces */
348 	case  PT_WRITE_D:
349 		write = 1;
350 		temp = SCARG(uap, data);
351 	case  PT_READ_I:		/* XXX no separate I and D spaces */
352 	case  PT_READ_D:
353 		/* write = 0 done above. */
354 		iov.iov_base = (caddr_t)&temp;
355 		iov.iov_len = sizeof(int);
356 		uio.uio_iov = &iov;
357 		uio.uio_iovcnt = 1;
358 		uio.uio_offset = (off_t)(vaddr_t)SCARG(uap, addr);
359 		uio.uio_resid = sizeof(int);
360 		uio.uio_segflg = UIO_SYSSPACE;
361 		uio.uio_rw = write ? UIO_WRITE : UIO_READ;
362 		uio.uio_procp = p;
363 		error = process_domem(p, t, &uio, write ? PT_WRITE_I :
364 				PT_READ_I);
365 		if (write == 0)
366 			*retval = temp;
367 		return (error);
368 	case  PT_IO:
369 		error = copyin(SCARG(uap, addr), &piod, sizeof(piod));
370 		if (error)
371 			return (error);
372 		iov.iov_base = piod.piod_addr;
373 		iov.iov_len = piod.piod_len;
374 		uio.uio_iov = &iov;
375 		uio.uio_iovcnt = 1;
376 		uio.uio_offset = (off_t)(vaddr_t)piod.piod_offs;
377 		uio.uio_resid = piod.piod_len;
378 		uio.uio_segflg = UIO_USERSPACE;
379 		uio.uio_procp = p;
380 		switch (piod.piod_op) {
381 		case PIOD_READ_I:
382 			req = PT_READ_I;
383 			uio.uio_rw = UIO_READ;
384 			break;
385 		case PIOD_READ_D:
386 			req = PT_READ_D;
387 			uio.uio_rw = UIO_READ;
388 			break;
389 		case PIOD_WRITE_I:
390 			req = PT_WRITE_I;
391 			uio.uio_rw = UIO_WRITE;
392 			break;
393 		case PIOD_WRITE_D:
394 			req = PT_WRITE_D;
395 			uio.uio_rw = UIO_WRITE;
396 			break;
397 		case PIOD_READ_AUXV:
398 			req = PT_READ_D;
399 			uio.uio_rw = UIO_READ;
400 			temp = tr->ps_emul->e_arglen * sizeof(char *);
401 			if (uio.uio_offset > temp)
402 				return (EIO);
403 			if (uio.uio_resid > temp - uio.uio_offset)
404 				uio.uio_resid = temp - uio.uio_offset;
405 			piod.piod_len = iov.iov_len = uio.uio_resid;
406 			error = process_auxv_offset(p, t, &uio);
407 			if (error)
408 				return (error);
409 			break;
410 		default:
411 			return (EINVAL);
412 		}
413 		error = process_domem(p, t, &uio, req);
414 		piod.piod_len -= uio.uio_resid;
415 		(void) copyout(&piod, SCARG(uap, addr), sizeof(piod));
416 		return (error);
417 #ifdef PT_STEP
418 	case  PT_STEP:
419 		/*
420 		 * From the 4.4BSD PRM:
421 		 * "Execution continues as in request PT_CONTINUE; however
422 		 * as soon as possible after execution of at least one
423 		 * instruction, execution stops again. [ ... ]"
424 		 */
425 #endif
426 	case  PT_CONTINUE:
427 		/*
428 		 * From the 4.4BSD PRM:
429 		 * "The data argument is taken as a signal number and the
430 		 * child's execution continues at location addr as if it
431 		 * incurred that signal.  Normally the signal number will
432 		 * be either 0 to indicate that the signal that caused the
433 		 * stop should be ignored, or that value fetched out of
434 		 * the process's image indicating which signal caused
435 		 * the stop.  If addr is (int *)1 then execution continues
436 		 * from where it stopped."
437 		 */
438 
439 		if (SCARG(uap, pid) < THREAD_PID_OFFSET && tr->ps_single)
440 			t = tr->ps_single;
441 
442 		/* Check that the data is a valid signal number or zero. */
443 		if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG)
444 			return (EINVAL);
445 
446 		/* If the address parameter is not (int *)1, set the pc. */
447 		if ((int *)SCARG(uap, addr) != (int *)1)
448 			if ((error = process_set_pc(t, SCARG(uap, addr))) != 0)
449 				goto relebad;
450 
451 #ifdef PT_STEP
452 		/*
453 		 * Arrange for a single-step, if that's requested and possible.
454 		 */
455 		error = process_sstep(t, req == PT_STEP);
456 		if (error)
457 			goto relebad;
458 #endif
459 		goto sendsig;
460 
461 	case  PT_DETACH:
462 		/*
463 		 * From the 4.4BSD PRM:
464 		 * "The data argument is taken as a signal number and the
465 		 * child's execution continues at location addr as if it
466 		 * incurred that signal.  Normally the signal number will
467 		 * be either 0 to indicate that the signal that caused the
468 		 * stop should be ignored, or that value fetched out of
469 		 * the process's image indicating which signal caused
470 		 * the stop.  If addr is (int *)1 then execution continues
471 		 * from where it stopped."
472 		 */
473 
474 		if (SCARG(uap, pid) < THREAD_PID_OFFSET && tr->ps_single)
475 			t = tr->ps_single;
476 
477 		/* Check that the data is a valid signal number or zero. */
478 		if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG)
479 			return (EINVAL);
480 
481 #ifdef PT_STEP
482 		/*
483 		 * Arrange for a single-step, if that's requested and possible.
484 		 */
485 		error = process_sstep(t, req == PT_STEP);
486 		if (error)
487 			goto relebad;
488 #endif
489 
490 		/* give process back to original parent or init */
491 		if (tr->ps_oppid != tr->ps_pptr->ps_pid) {
492 			struct process *ppr;
493 
494 			ppr = prfind(tr->ps_oppid);
495 			proc_reparent(tr, ppr ? ppr : initprocess);
496 		}
497 
498 		/* not being traced any more */
499 		tr->ps_oppid = 0;
500 		atomic_clearbits_int(&tr->ps_flags, PS_TRACED|PS_WAITED);
501 
502 	sendsig:
503 		memset(tr->ps_ptstat, 0, sizeof(*tr->ps_ptstat));
504 
505 		/* Finally, deliver the requested signal (or none). */
506 		if (t->p_stat == SSTOP) {
507 			t->p_xstat = SCARG(uap, data);
508 			SCHED_LOCK(s);
509 			setrunnable(t);
510 			SCHED_UNLOCK(s);
511 		} else {
512 			if (SCARG(uap, data) != 0)
513 				psignal(t, SCARG(uap, data));
514 		}
515 
516 		return (0);
517 
518 	relebad:
519 		return (error);
520 
521 	case  PT_KILL:
522 		if (SCARG(uap, pid) < THREAD_PID_OFFSET && tr->ps_single)
523 			t = tr->ps_single;
524 
525 		/* just send the process a KILL signal. */
526 		SCARG(uap, data) = SIGKILL;
527 		goto sendsig;	/* in PT_CONTINUE, above. */
528 
529 	case  PT_ATTACH:
530 		/*
531 		 * As was done in procfs:
532 		 * Go ahead and set the trace flag.
533 		 * Save the old parent (it's reset in
534 		 *   _DETACH, and also in kern_exit.c:wait4()
535 		 * Reparent the process so that the tracing
536 		 *   proc gets to see all the action.
537 		 * Stop the target.
538 		 */
539 		atomic_setbits_int(&tr->ps_flags, PS_TRACED);
540 		tr->ps_oppid = tr->ps_pptr->ps_pid;
541 		if (tr->ps_pptr != p->p_p)
542 			proc_reparent(tr, p->p_p);
543 		if (tr->ps_ptstat == NULL)
544 			tr->ps_ptstat = malloc(sizeof(*tr->ps_ptstat),
545 			    M_SUBPROC, M_WAITOK);
546 		SCARG(uap, data) = SIGSTOP;
547 		goto sendsig;
548 
549 	case  PT_GET_EVENT_MASK:
550 		if (SCARG(uap, data) != sizeof(pe))
551 			return (EINVAL);
552 		memset(&pe, 0, sizeof(pe));
553 		pe.pe_set_event = tr->ps_ptmask;
554 		return (copyout(&pe, SCARG(uap, addr), sizeof(pe)));
555 	case  PT_SET_EVENT_MASK:
556 		if (SCARG(uap, data) != sizeof(pe))
557 			return (EINVAL);
558 		if ((error = copyin(SCARG(uap, addr), &pe, sizeof(pe))))
559 			return (error);
560 		tr->ps_ptmask = pe.pe_set_event;
561 		return (0);
562 
563 	case  PT_GET_PROCESS_STATE:
564 		if (SCARG(uap, data) != sizeof(*tr->ps_ptstat))
565 			return (EINVAL);
566 
567 		if (tr->ps_single)
568 			tr->ps_ptstat->pe_tid =
569 			    tr->ps_single->p_pid + THREAD_PID_OFFSET;
570 
571 		return (copyout(tr->ps_ptstat, SCARG(uap, addr),
572 		    sizeof(*tr->ps_ptstat)));
573 
574 	case  PT_SETREGS:
575 		KASSERT((p->p_flag & P_SYSTEM) == 0);
576 		if ((error = process_checkioperm(p, tr)) != 0)
577 			return (error);
578 
579 		regs = malloc(sizeof(*regs), M_TEMP, M_WAITOK);
580 		error = copyin(SCARG(uap, addr), regs, sizeof(*regs));
581 		if (error == 0) {
582 			error = process_write_regs(t, regs);
583 		}
584 		free(regs, M_TEMP, sizeof(*regs));
585 		return (error);
586 	case  PT_GETREGS:
587 		KASSERT((p->p_flag & P_SYSTEM) == 0);
588 		if ((error = process_checkioperm(p, tr)) != 0)
589 			return (error);
590 
591 		regs = malloc(sizeof(*regs), M_TEMP, M_WAITOK);
592 		error = process_read_regs(t, regs);
593 		if (error == 0)
594 			error = copyout(regs,
595 			    SCARG(uap, addr), sizeof (*regs));
596 		free(regs, M_TEMP, sizeof(*regs));
597 		return (error);
598 #ifdef PT_SETFPREGS
599 	case  PT_SETFPREGS:
600 		KASSERT((p->p_flag & P_SYSTEM) == 0);
601 		if ((error = process_checkioperm(p, tr)) != 0)
602 			return (error);
603 
604 		fpregs = malloc(sizeof(*fpregs), M_TEMP, M_WAITOK);
605 		error = copyin(SCARG(uap, addr), fpregs, sizeof(*fpregs));
606 		if (error == 0) {
607 			error = process_write_fpregs(t, fpregs);
608 		}
609 		free(fpregs, M_TEMP, sizeof(*fpregs));
610 		return (error);
611 #endif
612 #ifdef PT_GETFPREGS
613 	case  PT_GETFPREGS:
614 		KASSERT((p->p_flag & P_SYSTEM) == 0);
615 		if ((error = process_checkioperm(p, tr)) != 0)
616 			return (error);
617 
618 		fpregs = malloc(sizeof(*fpregs), M_TEMP, M_WAITOK);
619 		error = process_read_fpregs(t, fpregs);
620 		if (error == 0)
621 			error = copyout(fpregs,
622 			    SCARG(uap, addr), sizeof(*fpregs));
623 		free(fpregs, M_TEMP, sizeof(*fpregs));
624 		return (error);
625 #endif
626 #ifdef PT_SETXMMREGS
627 	case  PT_SETXMMREGS:
628 		KASSERT((p->p_flag & P_SYSTEM) == 0);
629 		if ((error = process_checkioperm(p, tr)) != 0)
630 			return (error);
631 
632 		xmmregs = malloc(sizeof(*xmmregs), M_TEMP, M_WAITOK);
633 		error = copyin(SCARG(uap, addr), xmmregs, sizeof(*xmmregs));
634 		if (error == 0) {
635 			error = process_write_xmmregs(t, xmmregs);
636 		}
637 		free(xmmregs, M_TEMP, sizeof(*xmmregs));
638 		return (error);
639 #endif
640 #ifdef PT_GETXMMREGS
641 	case  PT_GETXMMREGS:
642 		KASSERT((p->p_flag & P_SYSTEM) == 0);
643 		if ((error = process_checkioperm(p, tr)) != 0)
644 			return (error);
645 
646 		xmmregs = malloc(sizeof(*xmmregs), M_TEMP, M_WAITOK);
647 		error = process_read_xmmregs(t, xmmregs);
648 		if (error == 0)
649 			error = copyout(xmmregs,
650 			    SCARG(uap, addr), sizeof(*xmmregs));
651 		free(xmmregs, M_TEMP, sizeof(*xmmregs));
652 		return (error);
653 #endif
654 #ifdef PT_WCOOKIE
655 	case  PT_WCOOKIE:
656 		wcookie = process_get_wcookie (t);
657 		return (copyout(&wcookie, SCARG(uap, addr),
658 		    sizeof (register_t)));
659 #endif
660 	}
661 
662 #ifdef DIAGNOSTIC
663 	panic("ptrace: impossible");
664 #endif
665 	return 0;
666 }
667 #endif	/* PTRACE */
668 
669 /*
670  * Check if a process is allowed to fiddle with the memory of another.
671  *
672  * p = tracer
673  * tr = tracee
674  *
675  * 1.  You can't attach to a process not owned by you or one that has raised
676  *     its privileges.
677  * 1a. ...unless you are root.
678  *
679  * 2.  init is always off-limits because it can control the securelevel.
680  * 2a. ...unless securelevel is permanently set to insecure.
681  *
682  * 3.  Processes that are in the process of doing an exec() are always
683  *     off-limits because of the can of worms they are. Just wait a
684  *     second.
685  */
686 int
687 process_checkioperm(struct proc *p, struct process *tr)
688 {
689 	int error;
690 
691 	if ((tr->ps_ucred->cr_ruid != p->p_ucred->cr_ruid ||
692 	    ISSET(tr->ps_flags, PS_SUGIDEXEC | PS_SUGID)) &&
693 	    (error = suser(p, 0)) != 0)
694 		return (error);
695 
696 	if ((tr->ps_pid == 1) && (securelevel > -1))
697 		return (EPERM);
698 
699 	if (tr->ps_flags & PS_INEXEC)
700 		return (EAGAIN);
701 
702 	return (0);
703 }
704 
705 int
706 process_domem(struct proc *curp, struct proc *p, struct uio *uio, int req)
707 {
708 	struct vmspace *vm;
709 	int error;
710 	vaddr_t addr;
711 	vsize_t len;
712 
713 	len = uio->uio_resid;
714 	if (len == 0)
715 		return (0);
716 
717 	if ((error = process_checkioperm(curp, p->p_p)) != 0)
718 		return (error);
719 
720 	/* XXXCDC: how should locking work here? */
721 	if ((p->p_p->ps_flags & PS_EXITING) || (p->p_vmspace->vm_refcnt < 1))
722 		return(EFAULT);
723 	addr = uio->uio_offset;
724 
725 	vm = p->p_vmspace;
726 	vm->vm_refcnt++;
727 
728 	error = uvm_io(&vm->vm_map, uio,
729 	    (req == PT_WRITE_I) ? UVM_IO_FIXPROT : 0);
730 
731 	uvmspace_free(vm);
732 
733 	if (error == 0 && req == PT_WRITE_I)
734 		pmap_proc_iflush(p, addr, len);
735 
736 	return (error);
737 }
738 
739 #ifdef PTRACE
740 int
741 process_auxv_offset(struct proc *curp, struct proc *p, struct uio *uiop)
742 {
743 	struct ps_strings pss;
744 	struct iovec iov;
745 	struct uio uio;
746 	int error;
747 
748 	iov.iov_base = &pss;
749 	iov.iov_len = sizeof(pss);
750 	uio.uio_iov = &iov;
751 	uio.uio_iovcnt = 1;
752 	uio.uio_offset = (off_t)(vaddr_t)PS_STRINGS;
753 	uio.uio_resid = sizeof(pss);
754 	uio.uio_segflg = UIO_SYSSPACE;
755 	uio.uio_rw = UIO_READ;
756 	uio.uio_procp = curp;
757 
758 	if ((error = uvm_io(&p->p_vmspace->vm_map, &uio, 0)) != 0)
759 		return (error);
760 
761 	if (pss.ps_envstr == NULL)
762 		return (EIO);
763 
764 	uiop->uio_offset += (off_t)(vaddr_t)(pss.ps_envstr + pss.ps_nenvstr + 1);
765 #ifdef MACHINE_STACK_GROWS_UP
766 	if (uiop->uio_offset < (off_t)(vaddr_t)PS_STRINGS)
767 		return (EIO);
768 #else
769 	if (uiop->uio_offset > (off_t)(vaddr_t)PS_STRINGS)
770 		return (EIO);
771 	if ((uiop->uio_offset + uiop->uio_resid) > (off_t)(vaddr_t)PS_STRINGS)
772 		uiop->uio_resid = (off_t)(vaddr_t)PS_STRINGS - uiop->uio_offset;
773 #endif
774 
775 	return (0);
776 }
777 #endif
778