xref: /netbsd-src/sys/kern/sys_process.c (revision 8b0f9554ff8762542c4defc4f70e1eb76fb508fa)
1 /*	$NetBSD: sys_process.c,v 1.131 2007/11/07 00:23:24 ad Exp $	*/
2 
3 /*-
4  * Copyright (c) 1982, 1986, 1989, 1993
5  *	The Regents of the University of California.  All rights reserved.
6  * (c) UNIX System Laboratories, Inc.
7  * All or some portions of this file are derived from material licensed
8  * to the University of California by American Telephone and Telegraph
9  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10  * the permission of UNIX System Laboratories, Inc.
11  *
12  * This code is derived from software contributed to Berkeley by
13  * Jan-Simon Pendry.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  * 3. Neither the name of the University nor the names of its contributors
24  *    may be used to endorse or promote products derived from this software
25  *    without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  *
39  *	from: @(#)sys_process.c	8.1 (Berkeley) 6/10/93
40  */
41 
42 /*-
43  * Copyright (c) 1993 Jan-Simon Pendry.
44  * Copyright (c) 1994 Christopher G. Demetriou.  All rights reserved.
45  *
46  * This code is derived from software contributed to Berkeley by
47  * Jan-Simon Pendry.
48  *
49  * Redistribution and use in source and binary forms, with or without
50  * modification, are permitted provided that the following conditions
51  * are met:
52  * 1. Redistributions of source code must retain the above copyright
53  *    notice, this list of conditions and the following disclaimer.
54  * 2. Redistributions in binary form must reproduce the above copyright
55  *    notice, this list of conditions and the following disclaimer in the
56  *    documentation and/or other materials provided with the distribution.
57  * 3. All advertising materials mentioning features or use of this software
58  *    must display the following acknowledgement:
59  *	This product includes software developed by the University of
60  *	California, Berkeley and its contributors.
61  * 4. Neither the name of the University nor the names of its contributors
62  *    may be used to endorse or promote products derived from this software
63  *    without specific prior written permission.
64  *
65  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
66  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
67  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
68  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
69  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
70  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
71  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
72  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
73  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
74  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
75  * SUCH DAMAGE.
76  *
77  *	from: @(#)sys_process.c	8.1 (Berkeley) 6/10/93
78  */
79 
80 /*
81  * References:
82  *	(1) Bach's "The Design of the UNIX Operating System",
83  *	(2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution,
84  *	(3) the "4.4BSD Programmer's Reference Manual" published
85  *		by USENIX and O'Reilly & Associates.
86  * The 4.4BSD PRM does a reasonably good job of documenting what the various
87  * ptrace() requests should actually do, and its text is quoted several times
88  * in this file.
89  */
90 
91 #include <sys/cdefs.h>
92 __KERNEL_RCSID(0, "$NetBSD: sys_process.c,v 1.131 2007/11/07 00:23:24 ad Exp $");
93 
94 #include "opt_coredump.h"
95 #include "opt_ptrace.h"
96 #include "opt_ktrace.h"
97 
98 #include <sys/param.h>
99 #include <sys/systm.h>
100 #include <sys/proc.h>
101 #include <sys/errno.h>
102 #include <sys/ptrace.h>
103 #include <sys/uio.h>
104 #include <sys/user.h>
105 #include <sys/ras.h>
106 #include <sys/malloc.h>
107 #include <sys/kauth.h>
108 #include <sys/mount.h>
109 #include <sys/syscallargs.h>
110 
111 #include <uvm/uvm_extern.h>
112 
113 #include <machine/reg.h>
114 
115 #ifdef PTRACE
116 /*
117  * Process debugging system call.
118  */
119 int
120 sys_ptrace(struct lwp *l, void *v, register_t *retval)
121 {
122 	struct sys_ptrace_args /* {
123 		syscallarg(int) req;
124 		syscallarg(pid_t) pid;
125 		syscallarg(void *) addr;
126 		syscallarg(int) data;
127 	} */ *uap = v;
128 	struct proc *p = l->l_proc;
129 	struct lwp *lt;
130 	struct proc *t;				/* target process */
131 	struct uio uio;
132 	struct iovec iov;
133 	struct ptrace_io_desc piod;
134 	struct ptrace_lwpinfo pl;
135 	struct vmspace *vm;
136 	int error, write, tmp, req, pheld;
137 	ksiginfo_t ksi;
138 #ifdef COREDUMP
139 	char *path;
140 #endif
141 
142 	error = 0;
143 	req = SCARG(uap, req);
144 
145 	/*
146 	 * If attaching or detaching, we need to get a write hold on the
147 	 * proclist lock so that we can re-parent the target process.
148 	 */
149 	mutex_enter(&proclist_lock);
150 
151 	/* "A foolish consistency..." XXX */
152 	if (req == PT_TRACE_ME) {
153 		t = p;
154 		mutex_enter(&t->p_mutex);
155 	} else {
156 		/* Find the process we're supposed to be operating on. */
157 		if ((t = p_find(SCARG(uap, pid), PFIND_LOCKED)) == NULL) {
158 			mutex_exit(&proclist_lock);
159 			return (ESRCH);
160 		}
161 
162 		/* XXX elad - this should be in pfind(). */
163 		mutex_enter(&t->p_mutex);
164 		error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
165 		    t, NULL, NULL, NULL);
166 		if (error) {
167 			mutex_exit(&proclist_lock);
168 			mutex_exit(&t->p_mutex);
169 			return (ESRCH);
170 		}
171 	}
172 
173 	/*
174 	 * Grab a reference on the process to prevent it from execing or
175 	 * exiting.
176 	 */
177 	if (!rw_tryenter(&t->p_reflock, RW_READER)) {
178 		mutex_exit(&proclist_lock);
179 		mutex_exit(&t->p_mutex);
180 		return EBUSY;
181 	}
182 
183 	/* Make sure we can operate on it. */
184 	switch (req) {
185 	case  PT_TRACE_ME:
186 		/* Saying that you're being traced is always legal. */
187 		break;
188 
189 	case  PT_ATTACH:
190 		/*
191 		 * You can't attach to a process if:
192 		 *	(1) it's the process that's doing the attaching,
193 		 */
194 		if (t->p_pid == p->p_pid) {
195 			error = EINVAL;
196 			break;
197 		}
198 
199 		/*
200 		 *  (2) it's a system process
201 		 */
202 		if (t->p_flag & PK_SYSTEM) {
203 			error = EPERM;
204 			break;
205 		}
206 
207 		/*
208 		 *	(3) it's already being traced, or
209 		 */
210 		if (ISSET(t->p_slflag, PSL_TRACED)) {
211 			error = EBUSY;
212 			break;
213 		}
214 
215 		/*
216 		 * 	(4) the tracer is chrooted, and its root directory is
217 		 * 	    not at or above the root directory of the tracee
218 		 */
219 		mutex_exit(&t->p_mutex);	/* XXXSMP */
220 		tmp = proc_isunder(t, l);
221 		mutex_enter(&t->p_mutex);	/* XXXSMP */
222 		if (!tmp) {
223 			error = EPERM;
224 			break;
225 		}
226 		break;
227 
228 	case  PT_READ_I:
229 	case  PT_READ_D:
230 	case  PT_WRITE_I:
231 	case  PT_WRITE_D:
232 	case  PT_IO:
233 #ifdef PT_GETREGS
234 	case  PT_GETREGS:
235 #endif
236 #ifdef PT_SETREGS
237 	case  PT_SETREGS:
238 #endif
239 #ifdef PT_GETFPREGS
240 	case  PT_GETFPREGS:
241 #endif
242 #ifdef PT_SETFPREGS
243 	case  PT_SETFPREGS:
244 #endif
245 #ifdef __HAVE_PTRACE_MACHDEP
246 	PTRACE_MACHDEP_REQUEST_CASES
247 #endif
248 		/*
249 		 * You can't read/write the memory or registers of a process
250 		 * if the tracer is chrooted, and its root directory is not at
251 		 * or above the root directory of the tracee.
252 		 */
253 		mutex_exit(&t->p_mutex);	/* XXXSMP */
254 		tmp = proc_isunder(t, l);
255 		mutex_enter(&t->p_mutex);	/* XXXSMP */
256 		if (!tmp) {
257 			error = EPERM;
258 			break;
259 		}
260 		/*FALLTHROUGH*/
261 
262 	case  PT_CONTINUE:
263 	case  PT_KILL:
264 	case  PT_DETACH:
265 	case  PT_LWPINFO:
266 	case  PT_SYSCALL:
267 #ifdef COREDUMP
268 	case  PT_DUMPCORE:
269 #endif
270 #ifdef PT_STEP
271 	case  PT_STEP:
272 #endif
273 		/*
274 		 * You can't do what you want to the process if:
275 		 *	(1) It's not being traced at all,
276 		 */
277 		if (!ISSET(t->p_slflag, PSL_TRACED)) {
278 			error = EPERM;
279 			break;
280 		}
281 
282 		/*
283 		 *	(2) it's being traced by procfs (which has
284 		 *	    different signal delivery semantics),
285 		 */
286 		if (ISSET(t->p_slflag, PSL_FSTRACE)) {
287 			uprintf("file system traced\n");
288 			error = EBUSY;
289 			break;
290 		}
291 
292 		/*
293 		 *	(3) it's not being traced by _you_, or
294 		 */
295 		if (t->p_pptr != p) {
296 			uprintf("parent %d != %d\n", t->p_pptr->p_pid, p->p_pid);
297 			error = EBUSY;
298 			break;
299 		}
300 
301 		/*
302 		 *	(4) it's not currently stopped.
303 		 */
304 		if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) {
305 			uprintf("stat %d flag %d\n", t->p_stat,
306 			    !t->p_waited);
307 			error = EBUSY;
308 			break;
309 		}
310 		break;
311 
312 	default:			/* It was not a legal request. */
313 		error = EINVAL;
314 		break;
315 	}
316 
317 	if (error == 0)
318 		error = kauth_authorize_process(l->l_cred,
319 		    KAUTH_PROCESS_CANPTRACE, t, KAUTH_ARG(req),
320 		    NULL, NULL);
321 
322 	if (error != 0) {
323 		mutex_exit(&proclist_lock);
324 		mutex_exit(&t->p_mutex);
325 		rw_exit(&t->p_reflock);
326 		return error;
327 	}
328 
329 	/*
330 	 * Which locks do we need held? XXX Ugly.
331 	 */
332 	switch (req) {
333 #ifdef PT_STEP
334 	case PT_STEP:
335 #endif
336 	case PT_CONTINUE:
337 	case PT_DETACH:
338 	case PT_KILL:
339 	case PT_SYSCALL:
340 	case PT_ATTACH:
341 		pheld = 1;
342 		break;
343 	default:
344 		mutex_exit(&proclist_lock);
345 		mutex_exit(&t->p_mutex);
346 		pheld = 0;
347 		break;
348 	}
349 
350 
351 	/* Do single-step fixup if needed. */
352 	FIX_SSTEP(t);
353 
354 	/*
355 	 * XXX NJWLWP
356 	 *
357 	 * The entire ptrace interface needs work to be useful to a
358 	 * process with multiple LWPs. For the moment, we'll kluge
359 	 * this; memory access will be fine, but register access will
360 	 * be weird.
361 	 */
362 	mutex_enter(&t->p_smutex);
363 	lt = proc_representative_lwp(t, NULL, 1);
364 	lwp_addref(lt);
365 	mutex_exit(&t->p_smutex);
366 
367 	/* Now do the operation. */
368 	write = 0;
369 	*retval = 0;
370 	tmp = 0;
371 
372 	switch (req) {
373 	case  PT_TRACE_ME:
374 		/* Just set the trace flag. */
375 		mutex_enter(&t->p_smutex);
376 		SET(t->p_slflag, PSL_TRACED);
377 		mutex_exit(&t->p_smutex);
378 		t->p_opptr = t->p_pptr;
379 		break;
380 
381 	case  PT_WRITE_I:		/* XXX no separate I and D spaces */
382 	case  PT_WRITE_D:
383 #if defined(__HAVE_RAS)
384 		/*
385 		 * Can't write to a RAS
386 		 */
387 		if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) {
388 			error = EACCES;
389 			break;
390 		}
391 #endif
392 		write = 1;
393 		tmp = SCARG(uap, data);
394 		/* FALLTHROUGH */
395 
396 	case  PT_READ_I:		/* XXX no separate I and D spaces */
397 	case  PT_READ_D:
398 		/* write = 0 done above. */
399 		iov.iov_base = (void *)&tmp;
400 		iov.iov_len = sizeof(tmp);
401 		uio.uio_iov = &iov;
402 		uio.uio_iovcnt = 1;
403 		uio.uio_offset = (off_t)(unsigned long)SCARG(uap, addr);
404 		uio.uio_resid = sizeof(tmp);
405 		uio.uio_rw = write ? UIO_WRITE : UIO_READ;
406 		UIO_SETUP_SYSSPACE(&uio);
407 
408 		error = process_domem(l, lt, &uio);
409 		if (!write)
410 			*retval = tmp;
411 		break;
412 
413 	case  PT_IO:
414 		error = copyin(SCARG(uap, addr), &piod, sizeof(piod));
415 		if (error)
416 			break;
417 		switch (piod.piod_op) {
418 		case PIOD_READ_D:
419 		case PIOD_READ_I:
420 			uio.uio_rw = UIO_READ;
421 			break;
422 		case PIOD_WRITE_D:
423 		case PIOD_WRITE_I:
424 			/*
425 			 * Can't write to a RAS
426 			 */
427 			if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) {
428 				return (EACCES);
429 			}
430 			uio.uio_rw = UIO_WRITE;
431 			break;
432 		default:
433 			error = EINVAL;
434 			break;
435 		}
436 		if (error)
437 			break;
438 		error = proc_vmspace_getref(l->l_proc, &vm);
439 		if (error)
440 			break;
441 		iov.iov_base = piod.piod_addr;
442 		iov.iov_len = piod.piod_len;
443 		uio.uio_iov = &iov;
444 		uio.uio_iovcnt = 1;
445 		uio.uio_offset = (off_t)(unsigned long)piod.piod_offs;
446 		uio.uio_resid = piod.piod_len;
447 		uio.uio_vmspace = vm;
448 
449 		error = process_domem(l, lt, &uio);
450 		piod.piod_len -= uio.uio_resid;
451 		(void) copyout(&piod, SCARG(uap, addr), sizeof(piod));
452 		uvmspace_free(vm);
453 		break;
454 
455 #ifdef COREDUMP
456 	case  PT_DUMPCORE:
457 		if ((path = SCARG(uap, addr)) != NULL) {
458 			char *dst;
459 			int len = SCARG(uap, data);
460 			if (len < 0 || len >= MAXPATHLEN) {
461 				error = EINVAL;
462 				break;
463 			}
464 			dst = malloc(len + 1, M_TEMP, M_WAITOK);
465 			if ((error = copyin(path, dst, len)) != 0) {
466 				free(dst, M_TEMP);
467 				break;
468 			}
469 			path = dst;
470 			path[len] = '\0';
471 		}
472 		error = coredump(lt, path);
473 		if (path)
474 			free(path, M_TEMP);
475 		break;
476 #endif
477 
478 #ifdef PT_STEP
479 	case  PT_STEP:
480 		/*
481 		 * From the 4.4BSD PRM:
482 		 * "Execution continues as in request PT_CONTINUE; however
483 		 * as soon as possible after execution of at least one
484 		 * instruction, execution stops again. [ ... ]"
485 		 */
486 #endif
487 	case  PT_CONTINUE:
488 	case  PT_SYSCALL:
489 	case  PT_DETACH:
490 		mutex_enter(&t->p_smutex);
491 		if (req == PT_SYSCALL) {
492 			if (!ISSET(t->p_slflag, PSL_SYSCALL)) {
493 				SET(t->p_slflag, PSL_SYSCALL);
494 #ifdef __HAVE_SYSCALL_INTERN
495 				(*t->p_emul->e_syscall_intern)(t);
496 #endif
497 			}
498 		} else {
499 			if (ISSET(t->p_slflag, PSL_SYSCALL)) {
500 				CLR(t->p_slflag, PSL_SYSCALL);
501 #ifdef __HAVE_SYSCALL_INTERN
502 				(*t->p_emul->e_syscall_intern)(t);
503 #endif
504 			}
505 		}
506 		mutex_exit(&t->p_smutex);
507 
508 		/*
509 		 * From the 4.4BSD PRM:
510 		 * "The data argument is taken as a signal number and the
511 		 * child's execution continues at location addr as if it
512 		 * incurred that signal.  Normally the signal number will
513 		 * be either 0 to indicate that the signal that caused the
514 		 * stop should be ignored, or that value fetched out of
515 		 * the process's image indicating which signal caused
516 		 * the stop.  If addr is (int *)1 then execution continues
517 		 * from where it stopped."
518 		 */
519 
520 		/* Check that the data is a valid signal number or zero. */
521 		if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG) {
522 			error = EINVAL;
523 			break;
524 		}
525 
526 		uvm_lwp_hold(lt);
527 
528 		/* If the address parameter is not (int *)1, set the pc. */
529 		if ((int *)SCARG(uap, addr) != (int *)1)
530 			if ((error = process_set_pc(lt, SCARG(uap, addr))) != 0) {
531 				uvm_lwp_rele(lt);
532 				break;
533 			}
534 
535 #ifdef PT_STEP
536 		/*
537 		 * Arrange for a single-step, if that's requested and possible.
538 		 */
539 		error = process_sstep(lt, req == PT_STEP);
540 		if (error) {
541 			uvm_lwp_rele(lt);
542 			break;
543 		}
544 #endif
545 
546 		uvm_lwp_rele(lt);
547 
548 		if (req == PT_DETACH) {
549 			mutex_enter(&t->p_smutex);
550 			CLR(t->p_slflag, PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL);
551 			mutex_exit(&t->p_smutex);
552 
553 			/* give process back to original parent or init */
554 			if (t->p_opptr != t->p_pptr) {
555 				struct proc *pp = t->p_opptr;
556 				proc_reparent(t, pp ? pp : initproc);
557 			}
558 
559 			/* not being traced any more */
560 			t->p_opptr = NULL;
561 		}
562 
563 	sendsig:
564 		/* Finally, deliver the requested signal (or none). */
565 		mutex_enter(&proclist_mutex);
566 		mutex_enter(&t->p_smutex);
567 		if (t->p_stat == SSTOP) {
568 			/*
569 			 * Unstop the process.  If it needs to take a
570 			 * signal, make all efforts to ensure that at
571 			 * an LWP runs to see it.
572 			 */
573 			t->p_xstat = SCARG(uap, data);
574 			proc_unstop(t);
575 		} else if (SCARG(uap, data) != 0) {
576 			KSI_INIT_EMPTY(&ksi);
577 			ksi.ksi_signo = SCARG(uap, data);
578 			kpsignal2(t, &ksi);
579 		}
580 		mutex_exit(&t->p_smutex);
581 		mutex_exit(&proclist_mutex);
582 		break;
583 
584 	case  PT_KILL:
585 		/* just send the process a KILL signal. */
586 		SCARG(uap, data) = SIGKILL;
587 		goto sendsig;	/* in PT_CONTINUE, above. */
588 
589 	case  PT_ATTACH:
590 		/*
591 		 * Go ahead and set the trace flag.
592 		 * Save the old parent (it's reset in
593 		 *   _DETACH, and also in kern_exit.c:wait4()
594 		 * Reparent the process so that the tracing
595 		 *   proc gets to see all the action.
596 		 * Stop the target.
597 		 */
598 		t->p_opptr = t->p_pptr;
599 		if (t->p_pptr != p) {
600 			mutex_enter(&t->p_pptr->p_smutex);
601 			t->p_pptr->p_slflag |= PSL_CHTRACED;
602 			mutex_exit(&t->p_pptr->p_smutex);
603 			proc_reparent(t, p);
604 		}
605 		mutex_enter(&t->p_smutex);
606 		SET(t->p_slflag, PSL_TRACED);
607 		mutex_exit(&t->p_smutex);
608 		SCARG(uap, data) = SIGSTOP;
609 		goto sendsig;
610 
611 	case PT_LWPINFO:
612 		if (SCARG(uap, data) != sizeof(pl)) {
613 			error = EINVAL;
614 			break;
615 		}
616 		error = copyin(SCARG(uap, addr), &pl, sizeof(pl));
617 		if (error)
618 			break;
619 		tmp = pl.pl_lwpid;
620 		lwp_delref(lt);
621 		mutex_enter(&t->p_smutex);
622 		if (tmp == 0)
623 			lt = LIST_FIRST(&t->p_lwps);
624 		else {
625 			lt = lwp_find(p, tmp);
626 			if (lt == NULL) {
627 				mutex_exit(&t->p_smutex);
628 				error = ESRCH;
629 				break;
630 			}
631 			lt = LIST_NEXT(lt, l_sibling);
632 		}
633 		while (lt != NULL && lt->l_stat == LSZOMB)
634 			lt = LIST_NEXT(lt, l_sibling);
635 		pl.pl_lwpid = 0;
636 		pl.pl_event = 0;
637 		if (lt) {
638 			lwp_addref(lt);
639 			pl.pl_lwpid = lt->l_lid;
640 			if (lt->l_lid == t->p_sigctx.ps_lwp)
641 				pl.pl_event = PL_EVENT_SIGNAL;
642 		}
643 		mutex_exit(&t->p_smutex);
644 
645 		error = copyout(&pl, SCARG(uap, addr), sizeof(pl));
646 		break;
647 
648 #ifdef PT_SETREGS
649 	case  PT_SETREGS:
650 		write = 1;
651 #endif
652 #ifdef PT_GETREGS
653 	case  PT_GETREGS:
654 		/* write = 0 done above. */
655 #endif
656 #if defined(PT_SETREGS) || defined(PT_GETREGS)
657 		tmp = SCARG(uap, data);
658 		if (tmp != 0 && t->p_nlwps > 1) {
659 			lwp_delref(lt);
660 			mutex_enter(&t->p_smutex);
661 			lt = lwp_find(t, tmp);
662 			if (lt == NULL) {
663 				mutex_exit(&t->p_smutex);
664 				error = ESRCH;
665 				break;
666 			}
667 			lwp_addref(lt);
668 			mutex_exit(&t->p_smutex);
669 		}
670 		if (!process_validregs(lt))
671 			error = EINVAL;
672 		else {
673 			error = proc_vmspace_getref(l->l_proc, &vm);
674 			if (error)
675 				break;
676 			iov.iov_base = SCARG(uap, addr);
677 			iov.iov_len = sizeof(struct reg);
678 			uio.uio_iov = &iov;
679 			uio.uio_iovcnt = 1;
680 			uio.uio_offset = 0;
681 			uio.uio_resid = sizeof(struct reg);
682 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
683 			uio.uio_vmspace = vm;
684 
685 			error = process_doregs(l, lt, &uio);
686 			uvmspace_free(vm);
687 		}
688 		break;
689 #endif
690 
691 #ifdef PT_SETFPREGS
692 	case  PT_SETFPREGS:
693 		write = 1;
694 #endif
695 #ifdef PT_GETFPREGS
696 	case  PT_GETFPREGS:
697 		/* write = 0 done above. */
698 #endif
699 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
700 		tmp = SCARG(uap, data);
701 		if (tmp != 0 && t->p_nlwps > 1) {
702 			lwp_delref(lt);
703 			mutex_enter(&t->p_smutex);
704 			lt = lwp_find(t, tmp);
705 			if (lt == NULL) {
706 				mutex_exit(&t->p_smutex);
707 				error = ESRCH;
708 				break;
709 			}
710 			lwp_addref(lt);
711 			mutex_exit(&t->p_smutex);
712 		}
713 		if (!process_validfpregs(lt))
714 			error = EINVAL;
715 		else {
716 			error = proc_vmspace_getref(l->l_proc, &vm);
717 			if (error)
718 				break;
719 			iov.iov_base = SCARG(uap, addr);
720 			iov.iov_len = sizeof(struct fpreg);
721 			uio.uio_iov = &iov;
722 			uio.uio_iovcnt = 1;
723 			uio.uio_offset = 0;
724 			uio.uio_resid = sizeof(struct fpreg);
725 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
726 			uio.uio_vmspace = vm;
727 
728 			error = process_dofpregs(l, lt, &uio);
729 			uvmspace_free(vm);
730 		}
731 		break;
732 #endif
733 
734 #ifdef __HAVE_PTRACE_MACHDEP
735 	PTRACE_MACHDEP_REQUEST_CASES
736 		error = ptrace_machdep_dorequest(l, lt,
737 		    req, SCARG(uap, addr), SCARG(uap, data));
738 		break;
739 #endif
740 	}
741 
742 	if (lt != NULL)
743 		lwp_delref(lt);
744 	if (pheld) {
745 		mutex_exit(&t->p_mutex);
746 		mutex_exit(&proclist_lock);
747 	}
748 	rw_exit(&t->p_reflock);
749 
750 	return error;
751 }
752 
753 int
754 process_doregs(struct lwp *curl /*tracer*/,
755     struct lwp *l /*traced*/,
756     struct uio *uio)
757 {
758 #if defined(PT_GETREGS) || defined(PT_SETREGS)
759 	int error;
760 	struct reg r;
761 	char *kv;
762 	int kl;
763 
764 	if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
765 		return EINVAL;
766 
767 	kl = sizeof(r);
768 	kv = (char *)&r;
769 
770 	kv += uio->uio_offset;
771 	kl -= uio->uio_offset;
772 	if ((size_t)kl > uio->uio_resid)
773 		kl = uio->uio_resid;
774 
775 	uvm_lwp_hold(l);
776 
777 	error = process_read_regs(l, &r);
778 	if (error == 0)
779 		error = uiomove(kv, kl, uio);
780 	if (error == 0 && uio->uio_rw == UIO_WRITE) {
781 		if (l->l_stat != LSSTOP)
782 			error = EBUSY;
783 		else
784 			error = process_write_regs(l, &r);
785 	}
786 
787 	uvm_lwp_rele(l);
788 
789 	uio->uio_offset = 0;
790 	return (error);
791 #else
792 	return (EINVAL);
793 #endif
794 }
795 
796 int
797 process_validregs(struct lwp *l)
798 {
799 
800 #if defined(PT_SETREGS) || defined(PT_GETREGS)
801 	return ((l->l_flag & LW_SYSTEM) == 0);
802 #else
803 	return (0);
804 #endif
805 }
806 
807 int
808 process_dofpregs(struct lwp *curl /*tracer*/,
809     struct lwp *l /*traced*/,
810     struct uio *uio)
811 {
812 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS)
813 	int error;
814 	struct fpreg r;
815 	char *kv;
816 	int kl;
817 
818 	if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
819 		return EINVAL;
820 
821 	kl = sizeof(r);
822 	kv = (char *)&r;
823 
824 	kv += uio->uio_offset;
825 	kl -= uio->uio_offset;
826 	if ((size_t)kl > uio->uio_resid)
827 		kl = uio->uio_resid;
828 
829 	uvm_lwp_hold(l);
830 
831 	error = process_read_fpregs(l, &r);
832 	if (error == 0)
833 		error = uiomove(kv, kl, uio);
834 	if (error == 0 && uio->uio_rw == UIO_WRITE) {
835 		if (l->l_stat != LSSTOP)
836 			error = EBUSY;
837 		else
838 			error = process_write_fpregs(l, &r);
839 	}
840 
841 	uvm_lwp_rele(l);
842 
843 	uio->uio_offset = 0;
844 	return (error);
845 #else
846 	return (EINVAL);
847 #endif
848 }
849 
850 int
851 process_validfpregs(struct lwp *l)
852 {
853 
854 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
855 	return ((l->l_flag & LW_SYSTEM) == 0);
856 #else
857 	return (0);
858 #endif
859 }
860 #endif /* PTRACE */
861 
862 #if defined(KTRACE) || defined(PTRACE) || defined(SYSTRACE)
863 int
864 process_domem(struct lwp *curl /*tracer*/,
865     struct lwp *l /*traced*/,
866     struct uio *uio)
867 {
868 	struct proc *p = l->l_proc;	/* traced */
869 	struct vmspace *vm;
870 	int error;
871 
872 	size_t len;
873 #ifdef PMAP_NEED_PROCWR
874 	vaddr_t	addr;
875 #endif
876 
877 	error = 0;
878 	len = uio->uio_resid;
879 
880 	if (len == 0)
881 		return (0);
882 
883 #ifdef PMAP_NEED_PROCWR
884 	addr = uio->uio_offset;
885 #endif
886 
887 	vm = p->p_vmspace;
888 
889 	mutex_enter(&vm->vm_map.misc_lock);
890 	if ((l->l_flag & LW_WEXIT) || vm->vm_refcnt < 1)
891 		error = EFAULT;
892 	if (error == 0)
893 		p->p_vmspace->vm_refcnt++;  /* XXX */
894 	mutex_exit(&vm->vm_map.misc_lock);
895 	if (error != 0)
896 		return (error);
897 	error = uvm_io(&vm->vm_map, uio);
898 	uvmspace_free(vm);
899 
900 #ifdef PMAP_NEED_PROCWR
901 	if (error == 0 && uio->uio_rw == UIO_WRITE)
902 		pmap_procwr(p, addr, len);
903 #endif
904 	return (error);
905 }
906 #endif /* KTRACE || PTRACE || SYSTRACE */
907 
908 #if defined(KTRACE) || defined(PTRACE)
909 void
910 process_stoptrace(struct lwp *l)
911 {
912 	struct proc *p = l->l_proc, *pp;
913 
914 	/* XXXSMP proc_stop -> child_psignal -> kpsignal2 -> pool_get */
915 	KERNEL_LOCK(1, l);
916 
917 	mutex_enter(&proclist_mutex);
918 	mutex_enter(&p->p_smutex);
919 	pp = p->p_pptr;
920 	if (pp->p_pid == 1) {
921 		CLR(p->p_slflag, PSL_SYSCALL);	/* XXXSMP */
922 		mutex_exit(&p->p_smutex);
923 		mutex_exit(&proclist_mutex);
924 		KERNEL_UNLOCK_ONE(l);
925 		return;
926 	}
927 
928 	p->p_xstat = SIGTRAP;
929 	proc_stop(p, 1, SIGSTOP);
930 	KERNEL_UNLOCK_ALL(l, &l->l_biglocks);
931 	mutex_exit(&proclist_mutex);
932 
933 	/*
934 	 * Call issignal() once only, to have it take care of the
935 	 * pending stop.  Signal processing will take place as usual
936 	 * from userret().
937 	 */
938 	(void)issignal(l);
939 	mutex_exit(&p->p_smutex);
940 	KERNEL_LOCK(l->l_biglocks - 1, l);
941 }
942 #endif	/* KTRACE || PTRACE */
943