xref: /netbsd-src/sys/kern/sys_ptrace_common.c (revision 7e30e94394d0994ab9534f68a8f91665045c91ce)
1 /*	$NetBSD: sys_ptrace_common.c,v 1.18 2017/02/23 04:48:36 kamil Exp $	*/
2 
3 /*-
4  * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Andrew Doran.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*-
33  * Copyright (c) 1982, 1986, 1989, 1993
34  *	The Regents of the University of California.  All rights reserved.
35  * (c) UNIX System Laboratories, Inc.
36  * All or some portions of this file are derived from material licensed
37  * to the University of California by American Telephone and Telegraph
38  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
39  * the permission of UNIX System Laboratories, Inc.
40  *
41  * This code is derived from software contributed to Berkeley by
42  * Jan-Simon Pendry.
43  *
44  * Redistribution and use in source and binary forms, with or without
45  * modification, are permitted provided that the following conditions
46  * are met:
47  * 1. Redistributions of source code must retain the above copyright
48  *    notice, this list of conditions and the following disclaimer.
49  * 2. Redistributions in binary form must reproduce the above copyright
50  *    notice, this list of conditions and the following disclaimer in the
51  *    documentation and/or other materials provided with the distribution.
52  * 3. Neither the name of the University nor the names of its contributors
53  *    may be used to endorse or promote products derived from this software
54  *    without specific prior written permission.
55  *
56  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
57  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
58  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
59  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
60  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
61  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
62  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
63  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
64  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
65  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
66  * SUCH DAMAGE.
67  *
68  *	from: @(#)sys_process.c	8.1 (Berkeley) 6/10/93
69  */
70 
71 /*-
72  * Copyright (c) 1993 Jan-Simon Pendry.
73  * Copyright (c) 1994 Christopher G. Demetriou.  All rights reserved.
74  *
75  * This code is derived from software contributed to Berkeley by
76  * Jan-Simon Pendry.
77  *
78  * Redistribution and use in source and binary forms, with or without
79  * modification, are permitted provided that the following conditions
80  * are met:
81  * 1. Redistributions of source code must retain the above copyright
82  *    notice, this list of conditions and the following disclaimer.
83  * 2. Redistributions in binary form must reproduce the above copyright
84  *    notice, this list of conditions and the following disclaimer in the
85  *    documentation and/or other materials provided with the distribution.
86  * 3. All advertising materials mentioning features or use of this software
87  *    must display the following acknowledgement:
88  *	This product includes software developed by the University of
89  *	California, Berkeley and its contributors.
90  * 4. Neither the name of the University nor the names of its contributors
91  *    may be used to endorse or promote products derived from this software
92  *    without specific prior written permission.
93  *
94  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
95  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
96  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
97  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
98  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
99  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
100  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
101  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
102  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
103  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
104  * SUCH DAMAGE.
105  *
106  *	from: @(#)sys_process.c	8.1 (Berkeley) 6/10/93
107  */
108 
109 /*
110  * References:
111  *	(1) Bach's "The Design of the UNIX Operating System",
112  *	(2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution,
113  *	(3) the "4.4BSD Programmer's Reference Manual" published
114  *		by USENIX and O'Reilly & Associates.
115  * The 4.4BSD PRM does a reasonably good job of documenting what the various
116  * ptrace() requests should actually do, and its text is quoted several times
117  * in this file.
118  */
119 
120 #include <sys/cdefs.h>
121 __KERNEL_RCSID(0, "$NetBSD: sys_ptrace_common.c,v 1.18 2017/02/23 04:48:36 kamil Exp $");
122 
123 #ifdef _KERNEL_OPT
124 #include "opt_ptrace.h"
125 #include "opt_ktrace.h"
126 #include "opt_pax.h"
127 #endif
128 
129 #include <sys/param.h>
130 #include <sys/systm.h>
131 #include <sys/proc.h>
132 #include <sys/errno.h>
133 #include <sys/exec.h>
134 #include <sys/pax.h>
135 #include <sys/ptrace.h>
136 #include <sys/uio.h>
137 #include <sys/ras.h>
138 #include <sys/kmem.h>
139 #include <sys/kauth.h>
140 #include <sys/mount.h>
141 #include <sys/syscallargs.h>
142 #include <sys/module.h>
143 #include <sys/condvar.h>
144 #include <sys/mutex.h>
145 
146 #include <uvm/uvm_extern.h>
147 
148 #include <machine/reg.h>
149 
150 #ifdef PTRACE
151 
152 # ifdef DEBUG
153 #  define DPRINTF(a) uprintf a
154 # else
155 #  define DPRINTF(a)
156 # endif
157 
158 static kauth_listener_t ptrace_listener;
159 static int process_auxv_offset(struct proc *, struct uio *);
160 
161 #if 0
162 static int ptrace_cbref;
163 static kmutex_t ptrace_mtx;
164 static kcondvar_t ptrace_cv;
165 #endif
166 
167 static int
168 ptrace_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
169     void *arg0, void *arg1, void *arg2, void *arg3)
170 {
171 	struct proc *p;
172 	int result;
173 
174 	result = KAUTH_RESULT_DEFER;
175 	p = arg0;
176 
177 #if 0
178 	mutex_enter(&ptrace_mtx);
179 	ptrace_cbref++;
180 	mutex_exit(&ptrace_mtx);
181 #endif
182 	if (action != KAUTH_PROCESS_PTRACE)
183 		goto out;
184 
185 	switch ((u_long)arg1) {
186 	case PT_TRACE_ME:
187 	case PT_ATTACH:
188 	case PT_WRITE_I:
189 	case PT_WRITE_D:
190 	case PT_READ_I:
191 	case PT_READ_D:
192 	case PT_IO:
193 #ifdef PT_GETREGS
194 	case PT_GETREGS:
195 #endif
196 #ifdef PT_SETREGS
197 	case PT_SETREGS:
198 #endif
199 #ifdef PT_GETFPREGS
200 	case PT_GETFPREGS:
201 #endif
202 #ifdef PT_SETFPREGS
203 	case PT_SETFPREGS:
204 #endif
205 #ifdef PT_GETDBREGS
206 	case PT_GETDBREGS:
207 #endif
208 #ifdef PT_SETDBREGS
209 	case PT_SETDBREGS:
210 #endif
211 	case PT_SET_EVENT_MASK:
212 	case PT_GET_EVENT_MASK:
213 	case PT_GET_PROCESS_STATE:
214 	case PT_SET_SIGINFO:
215 	case PT_GET_SIGINFO:
216 	case PT_SET_SIGMASK:
217 	case PT_GET_SIGMASK:
218 #ifdef __HAVE_PTRACE_MACHDEP
219 	PTRACE_MACHDEP_REQUEST_CASES
220 #endif
221 		if (kauth_cred_getuid(cred) != kauth_cred_getuid(p->p_cred) ||
222 		    ISSET(p->p_flag, PK_SUGID)) {
223 			break;
224 		}
225 
226 		result = KAUTH_RESULT_ALLOW;
227 
228 	break;
229 
230 #ifdef PT_STEP
231 	case PT_STEP:
232 #endif
233 	case PT_CONTINUE:
234 	case PT_KILL:
235 	case PT_DETACH:
236 	case PT_LWPINFO:
237 	case PT_SYSCALL:
238 	case PT_SYSCALLEMU:
239 	case PT_DUMPCORE:
240 	case PT_RESUME:
241 	case PT_SUSPEND:
242 		result = KAUTH_RESULT_ALLOW;
243 		break;
244 
245 	default:
246 		break;
247 	}
248 
249  out:
250 #if 0
251 	mutex_enter(&ptrace_mtx);
252 	if (--ptrace_cbref == 0)
253 		cv_broadcast(&ptrace_cv);
254 	mutex_exit(&ptrace_mtx);
255 #endif
256 
257 	return result;
258 }
259 
260 int
261 ptrace_init(void)
262 {
263 
264 #if 0
265 	mutex_init(&ptrace_mtx, MUTEX_DEFAULT, IPL_NONE);
266 	cv_init(&ptrace_cv, "ptracecb");
267 	ptrace_cbref = 0;
268 #endif
269 	ptrace_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
270 	    ptrace_listener_cb, NULL);
271 	return 0;
272 }
273 
274 int
275 ptrace_fini(void)
276 {
277 
278 	kauth_unlisten_scope(ptrace_listener);
279 
280 #if 0
281 	/* Make sure no-one is executing our kauth listener */
282 
283 	mutex_enter(&ptrace_mtx);
284 	while (ptrace_cbref != 0)
285 		cv_wait(&ptrace_cv, &ptrace_mtx);
286 	mutex_exit(&ptrace_mtx);
287 	mutex_destroy(&ptrace_mtx);
288 	cv_destroy(&ptrace_cv);
289 #endif
290 
291 	return 0;
292 }
293 
294 int
295 do_ptrace(struct ptrace_methods *ptm, struct lwp *l, int req, pid_t pid,
296     void *addr, int data, register_t *retval)
297 {
298 	struct proc *p = l->l_proc;
299 	struct lwp *lt;
300 	struct lwp *lt2;
301 	struct proc *t;				/* target process */
302 	struct uio uio;
303 	struct iovec iov;
304 	struct ptrace_io_desc piod;
305 	struct ptrace_event pe;
306 	struct ptrace_state ps;
307 	struct ptrace_lwpinfo pl;
308 	struct ptrace_siginfo psi;
309 	struct vmspace *vm;
310 	int error, write, tmp, pheld;
311 	int signo = 0;
312 	int resume_all;
313 	ksiginfo_t ksi;
314 	char *path;
315 	int len = 0;
316 	error = 0;
317 
318 	/*
319 	 * If attaching or detaching, we need to get a write hold on the
320 	 * proclist lock so that we can re-parent the target process.
321 	 */
322 	mutex_enter(proc_lock);
323 
324 	/* "A foolish consistency..." XXX */
325 	if (req == PT_TRACE_ME) {
326 		t = p;
327 		mutex_enter(t->p_lock);
328 	} else {
329 		/* Find the process we're supposed to be operating on. */
330 		t = proc_find(pid);
331 		if (t == NULL) {
332 			mutex_exit(proc_lock);
333 			return ESRCH;
334 		}
335 
336 		/* XXX-elad */
337 		mutex_enter(t->p_lock);
338 		error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
339 		    t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
340 		if (error) {
341 			mutex_exit(proc_lock);
342 			mutex_exit(t->p_lock);
343 			return ESRCH;
344 		}
345 	}
346 
347 	/*
348 	 * Grab a reference on the process to prevent it from execing or
349 	 * exiting.
350 	 */
351 	if (!rw_tryenter(&t->p_reflock, RW_READER)) {
352 		mutex_exit(proc_lock);
353 		mutex_exit(t->p_lock);
354 		return EBUSY;
355 	}
356 
357 	/* Make sure we can operate on it. */
358 	switch (req) {
359 	case  PT_TRACE_ME:
360 		/* Saying that you're being traced is always legal. */
361 		break;
362 
363 	case  PT_ATTACH:
364 		/*
365 		 * You can't attach to a process if:
366 		 *	(1) it's the process that's doing the attaching,
367 		 */
368 		if (t->p_pid == p->p_pid) {
369 			error = EINVAL;
370 			break;
371 		}
372 
373 		/*
374 		 *  (2) it's a system process
375 		 */
376 		if (t->p_flag & PK_SYSTEM) {
377 			error = EPERM;
378 			break;
379 		}
380 
381 		/*
382 		 *	(3) it's already being traced, or
383 		 */
384 		if (ISSET(t->p_slflag, PSL_TRACED)) {
385 			error = EBUSY;
386 			break;
387 		}
388 
389 		/*
390 		 * 	(4) the tracer is chrooted, and its root directory is
391 		 * 	    not at or above the root directory of the tracee
392 		 */
393 		mutex_exit(t->p_lock);	/* XXXSMP */
394 		tmp = proc_isunder(t, l);
395 		mutex_enter(t->p_lock);	/* XXXSMP */
396 		if (!tmp) {
397 			error = EPERM;
398 			break;
399 		}
400 		break;
401 
402 	case  PT_READ_I:
403 	case  PT_READ_D:
404 	case  PT_WRITE_I:
405 	case  PT_WRITE_D:
406 	case  PT_IO:
407 	case  PT_SET_SIGINFO:
408 	case  PT_GET_SIGINFO:
409 	case  PT_SET_SIGMASK:
410 	case  PT_GET_SIGMASK:
411 #ifdef PT_GETREGS
412 	case  PT_GETREGS:
413 #endif
414 #ifdef PT_SETREGS
415 	case  PT_SETREGS:
416 #endif
417 #ifdef PT_GETFPREGS
418 	case  PT_GETFPREGS:
419 #endif
420 #ifdef PT_SETFPREGS
421 	case  PT_SETFPREGS:
422 #endif
423 #ifdef PT_GETDBREGS
424 	case  PT_GETDBREGS:
425 #endif
426 #ifdef PT_SETDBREGS
427 	case  PT_SETDBREGS:
428 #endif
429 #ifdef __HAVE_PTRACE_MACHDEP
430 	PTRACE_MACHDEP_REQUEST_CASES
431 #endif
432 		/*
433 		 * You can't read/write the memory or registers of a process
434 		 * if the tracer is chrooted, and its root directory is not at
435 		 * or above the root directory of the tracee.
436 		 */
437 		mutex_exit(t->p_lock);	/* XXXSMP */
438 		tmp = proc_isunder(t, l);
439 		mutex_enter(t->p_lock);	/* XXXSMP */
440 		if (!tmp) {
441 			error = EPERM;
442 			break;
443 		}
444 		/*FALLTHROUGH*/
445 
446 	case  PT_CONTINUE:
447 	case  PT_KILL:
448 	case  PT_DETACH:
449 	case  PT_LWPINFO:
450 	case  PT_SYSCALL:
451 	case  PT_SYSCALLEMU:
452 	case  PT_DUMPCORE:
453 #ifdef PT_STEP
454 	case  PT_STEP:
455 #endif
456 	case  PT_SET_EVENT_MASK:
457 	case  PT_GET_EVENT_MASK:
458 	case  PT_GET_PROCESS_STATE:
459 	case  PT_RESUME:
460 	case  PT_SUSPEND:
461 		/*
462 		 * You can't do what you want to the process if:
463 		 *	(1) It's not being traced at all,
464 		 */
465 		if (!ISSET(t->p_slflag, PSL_TRACED)) {
466 			error = EPERM;
467 			break;
468 		}
469 
470 		/*
471 		 *	(2) it's being traced by procfs (which has
472 		 *	    different signal delivery semantics),
473 		 */
474 		if (ISSET(t->p_slflag, PSL_FSTRACE)) {
475 			DPRINTF(("file system traced\n"));
476 			error = EBUSY;
477 			break;
478 		}
479 
480 		/*
481 		 *	(3) it's not being traced by _you_, or
482 		 */
483 		if (t->p_pptr != p) {
484 			DPRINTF(("parent %d != %d\n", t->p_pptr->p_pid,
485 			    p->p_pid));
486 			error = EBUSY;
487 			break;
488 		}
489 
490 		/*
491 		 *	(4) it's not currently stopped.
492 		 */
493 		if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) {
494 			DPRINTF(("stat %d flag %d\n", t->p_stat,
495 			    !t->p_waited));
496 			error = EBUSY;
497 			break;
498 		}
499 		break;
500 
501 	default:			/* It was not a legal request. */
502 		error = EINVAL;
503 		break;
504 	}
505 
506 	if (error == 0) {
507 		error = kauth_authorize_process(l->l_cred,
508 		    KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req),
509 		    NULL, NULL);
510 	}
511 	if (error == 0) {
512 		lt = lwp_find_first(t);
513 		if (lt == NULL)
514 			error = ESRCH;
515 	}
516 
517 	if (error != 0) {
518 		mutex_exit(proc_lock);
519 		mutex_exit(t->p_lock);
520 		rw_exit(&t->p_reflock);
521 		return error;
522 	}
523 
524 	/* Do single-step fixup if needed. */
525 	FIX_SSTEP(t);
526 	KASSERT(lt != NULL);
527 	lwp_addref(lt);
528 
529 	/*
530 	 * Which locks do we need held? XXX Ugly.
531 	 */
532 	switch (req) {
533 #ifdef PT_STEP
534 	case PT_STEP:
535 #endif
536 	case PT_CONTINUE:
537 	case PT_DETACH:
538 	case PT_KILL:
539 	case PT_SYSCALL:
540 	case PT_SYSCALLEMU:
541 	case PT_ATTACH:
542 	case PT_TRACE_ME:
543 		pheld = 1;
544 		break;
545 	default:
546 		mutex_exit(proc_lock);
547 		mutex_exit(t->p_lock);
548 		pheld = 0;
549 		break;
550 	}
551 
552 	/* Now do the operation. */
553 	write = 0;
554 	*retval = 0;
555 	tmp = 0;
556 	resume_all = 1;
557 
558 	switch (req) {
559 	case  PT_TRACE_ME:
560 		/* Just set the trace flag. */
561 		SET(t->p_slflag, PSL_TRACED);
562 		t->p_opptr = t->p_pptr;
563 		break;
564 
565 	case  PT_WRITE_I:		/* XXX no separate I and D spaces */
566 	case  PT_WRITE_D:
567 #if defined(__HAVE_RAS)
568 		/*
569 		 * Can't write to a RAS
570 		 */
571 		if (ras_lookup(t, addr) != (void *)-1) {
572 			error = EACCES;
573 			break;
574 		}
575 #endif
576 		write = 1;
577 		tmp = data;
578 		/* FALLTHROUGH */
579 
580 	case  PT_READ_I:		/* XXX no separate I and D spaces */
581 	case  PT_READ_D:
582 		/* write = 0 done above. */
583 		iov.iov_base = (void *)&tmp;
584 		iov.iov_len = sizeof(tmp);
585 		uio.uio_iov = &iov;
586 		uio.uio_iovcnt = 1;
587 		uio.uio_offset = (off_t)(unsigned long)addr;
588 		uio.uio_resid = sizeof(tmp);
589 		uio.uio_rw = write ? UIO_WRITE : UIO_READ;
590 		UIO_SETUP_SYSSPACE(&uio);
591 
592 		error = process_domem(l, lt, &uio);
593 		if (!write)
594 			*retval = tmp;
595 		break;
596 
597 	case  PT_IO:
598 		error = ptm->ptm_copyinpiod(&piod, addr);
599 		if (error)
600 			break;
601 
602 		iov.iov_base = piod.piod_addr;
603 		iov.iov_len = piod.piod_len;
604 		uio.uio_iov = &iov;
605 		uio.uio_iovcnt = 1;
606 		uio.uio_offset = (off_t)(unsigned long)piod.piod_offs;
607 		uio.uio_resid = piod.piod_len;
608 
609 		switch (piod.piod_op) {
610 		case PIOD_READ_D:
611 		case PIOD_READ_I:
612 			uio.uio_rw = UIO_READ;
613 			break;
614 		case PIOD_WRITE_D:
615 		case PIOD_WRITE_I:
616 			/*
617 			 * Can't write to a RAS
618 			 */
619 			if (ras_lookup(t, addr) != (void *)-1) {
620 				return EACCES;
621 			}
622 			uio.uio_rw = UIO_WRITE;
623 			break;
624 		case PIOD_READ_AUXV:
625 			req = PT_READ_D;
626 			uio.uio_rw = UIO_READ;
627 			tmp = t->p_execsw->es_arglen;
628 			if (uio.uio_offset > tmp)
629 				return EIO;
630 			if (uio.uio_resid > tmp - uio.uio_offset)
631 				uio.uio_resid = tmp - uio.uio_offset;
632 			piod.piod_len = iov.iov_len = uio.uio_resid;
633 			error = process_auxv_offset(t, &uio);
634 			break;
635 		default:
636 			error = EINVAL;
637 			break;
638 		}
639 		if (error)
640 			break;
641 		error = proc_vmspace_getref(l->l_proc, &vm);
642 		if (error)
643 			break;
644 		uio.uio_vmspace = vm;
645 
646 		error = process_domem(l, lt, &uio);
647 		piod.piod_len -= uio.uio_resid;
648 		(void) ptm->ptm_copyoutpiod(&piod, addr);
649 
650 		uvmspace_free(vm);
651 		break;
652 
653 	case  PT_DUMPCORE:
654 		if ((path = addr) != NULL) {
655 			char *dst;
656 			len = data;
657 
658 			if (len < 0 || len >= MAXPATHLEN) {
659 				error = EINVAL;
660 				break;
661 			}
662 			dst = kmem_alloc(len + 1, KM_SLEEP);
663 			if ((error = copyin(path, dst, len)) != 0) {
664 				kmem_free(dst, len + 1);
665 				break;
666 			}
667 			path = dst;
668 			path[len] = '\0';
669 		}
670 		error = (*coredump_vec)(lt, path);
671 		if (path)
672 			kmem_free(path, len + 1);
673 		break;
674 
675 #ifdef PT_STEP
676 	case  PT_STEP:
677 		/*
678 		 * From the 4.4BSD PRM:
679 		 * "Execution continues as in request PT_CONTINUE; however
680 		 * as soon as possible after execution of at least one
681 		 * instruction, execution stops again. [ ... ]"
682 		 */
683 #endif
684 	case  PT_CONTINUE:
685 	case  PT_SYSCALL:
686 	case  PT_DETACH:
687 		if (req == PT_SYSCALL) {
688 			if (!ISSET(t->p_slflag, PSL_SYSCALL)) {
689 				SET(t->p_slflag, PSL_SYSCALL);
690 #ifdef __HAVE_SYSCALL_INTERN
691 				(*t->p_emul->e_syscall_intern)(t);
692 #endif
693 			}
694 		} else {
695 			if (ISSET(t->p_slflag, PSL_SYSCALL)) {
696 				CLR(t->p_slflag, PSL_SYSCALL);
697 #ifdef __HAVE_SYSCALL_INTERN
698 				(*t->p_emul->e_syscall_intern)(t);
699 #endif
700 			}
701 		}
702 		t->p_trace_enabled = trace_is_enabled(t);
703 
704 		/*
705 		 * Pick up the LWPID, if supplied.  There are two cases:
706 		 * data < 0 : step or continue single thread, lwp = -data
707 		 * data > 0 in PT_STEP : step this thread, continue others
708 		 * For operations other than PT_STEP, data > 0 means
709 		 * data is the signo to deliver to the process.
710 		 */
711 		tmp = data;
712 		if (tmp >= 0) {
713 #ifdef PT_STEP
714 			if (req == PT_STEP)
715 				signo = 0;
716 			else
717 #endif
718 			{
719 				signo = tmp;
720 				tmp = 0;	/* don't search for LWP */
721 			}
722 		} else
723 			tmp = -tmp;
724 
725 		if (tmp > 0) {
726 			if (req == PT_DETACH) {
727 				error = EINVAL;
728 				break;
729 			}
730 			lwp_delref2 (lt);
731 			lt = lwp_find(t, tmp);
732 			if (lt == NULL) {
733 				error = ESRCH;
734 				break;
735 			}
736 			lwp_addref(lt);
737 			resume_all = 0;
738 			signo = 0;
739 		}
740 
741 		/*
742 		 * From the 4.4BSD PRM:
743 		 * "The data argument is taken as a signal number and the
744 		 * child's execution continues at location addr as if it
745 		 * incurred that signal.  Normally the signal number will
746 		 * be either 0 to indicate that the signal that caused the
747 		 * stop should be ignored, or that value fetched out of
748 		 * the process's image indicating which signal caused
749 		 * the stop.  If addr is (int *)1 then execution continues
750 		 * from where it stopped."
751 		 */
752 
753 		/* Check that the data is a valid signal number or zero. */
754 		if (signo < 0 || signo >= NSIG) {
755 			error = EINVAL;
756 			break;
757 		}
758 
759 		/* Prevent process deadlock */
760 		if (resume_all) {
761 #ifdef PT_STEP
762 			if (req == PT_STEP) {
763 				if (lt->l_flag & LW_WSUSPEND) {
764 					error = EDEADLK;
765 					break;
766 				}
767 			} else
768 #endif
769 			{
770 				error = EDEADLK;
771 				LIST_FOREACH(lt2, &t->p_lwps, l_sibling) {
772 					if ((lt2->l_flag & LW_WSUSPEND) == 0) {
773 						error = 0;
774 						break;
775 					}
776 				}
777 				if (error != 0)
778 					break;
779 			}
780 		} else {
781 			if (lt->l_flag & LW_WSUSPEND) {
782 				error = EDEADLK;
783 				break;
784 			}
785 		}
786 
787 		/* If the address parameter is not (int *)1, set the pc. */
788 		if ((int *)addr != (int *)1) {
789 			error = process_set_pc(lt, addr);
790 			if (error != 0)
791 				break;
792 		}
793 #ifdef PT_STEP
794 		/*
795 		 * Arrange for a single-step, if that's requested and possible.
796 		 * More precisely, set the single step status as requested for
797 		 * the requested thread, and clear it for other threads.
798 		 */
799 		LIST_FOREACH(lt2, &t->p_lwps, l_sibling) {
800 			if (lt != lt2) {
801 				lwp_lock(lt2);
802 				process_sstep(lt2, 0);
803 				lwp_unlock(lt2);
804 			}
805 		}
806 		error = process_sstep(lt, req == PT_STEP);
807 		if (error)
808 			break;
809 #endif
810 		if (req == PT_DETACH) {
811 			CLR(t->p_slflag, PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL);
812 
813 			/* give process back to original parent or init */
814 			if (t->p_opptr != t->p_pptr) {
815 				struct proc *pp = t->p_opptr;
816 				proc_reparent(t, pp ? pp : initproc);
817 			}
818 
819 			/* not being traced any more */
820 			t->p_opptr = NULL;
821 		}
822 	sendsig:
823 		t->p_fpid = 0;
824 		t->p_vfpid = 0;
825 		t->p_vfpid_done = 0;
826 		t->p_lwp_created = 0;
827 		t->p_lwp_exited = 0;
828 		/* Finally, deliver the requested signal (or none). */
829 		if (t->p_stat == SSTOP) {
830 			/*
831 			 * Unstop the process.  If it needs to take a
832 			 * signal, make all efforts to ensure that at
833 			 * an LWP runs to see it.
834 			 */
835 			t->p_xsig = signo;
836 			if (resume_all)
837 				proc_unstop(t);
838 			else
839 				lwp_unstop(lt);
840 		} else if (t->p_sigctx.ps_faked) {
841 			if (signo != t->p_sigctx.ps_info._signo) {
842 				error = EINVAL;
843 				break;
844 			}
845 			t->p_sigctx.ps_faked = false;
846 			KSI_INIT_EMPTY(&ksi);
847 			ksi.ksi_info = t->p_sigctx.ps_info;
848 			ksi.ksi_lid = t->p_sigctx.ps_lwp;
849 			kpsignal2(t, &ksi);
850 		} else if (signo != 0) {
851 			KSI_INIT_EMPTY(&ksi);
852 			ksi.ksi_signo = signo;
853 			kpsignal2(t, &ksi);
854 		}
855 		break;
856 
857 	case  PT_SYSCALLEMU:
858 		if (!ISSET(t->p_slflag, PSL_SYSCALL) || t->p_stat != SSTOP) {
859 			error = EINVAL;
860 			break;
861 		}
862 		SET(t->p_slflag, PSL_SYSCALLEMU);
863 		break;
864 
865 	case  PT_KILL:
866 		/* just send the process a KILL signal. */
867 		signo = SIGKILL;
868 		goto sendsig;	/* in PT_CONTINUE, above. */
869 
870 	case  PT_ATTACH:
871 		/*
872 		 * Go ahead and set the trace flag.
873 		 * Save the old parent (it's reset in
874 		 *   _DETACH, and also in kern_exit.c:wait4()
875 		 * Reparent the process so that the tracing
876 		 *   proc gets to see all the action.
877 		 * Stop the target.
878 		 */
879 		proc_changeparent(t, p);
880 		signo = SIGSTOP;
881 		goto sendsig;
882 
883 	case  PT_GET_EVENT_MASK:
884 		if (data != sizeof(pe)) {
885 			DPRINTF(("ptrace(%d): %d != %zu\n", req,
886 			    data, sizeof(pe)));
887 			error = EINVAL;
888 			break;
889 		}
890 		memset(&pe, 0, sizeof(pe));
891 		pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ?
892 		    PTRACE_FORK : 0;
893 		pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK) ?
894 		    PTRACE_VFORK : 0;
895 		pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK_DONE) ?
896 		    PTRACE_VFORK_DONE : 0;
897 		pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACELWP_CREATE) ?
898 		    PTRACE_LWP_CREATE : 0;
899 		pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACELWP_EXIT) ?
900 		    PTRACE_LWP_EXIT : 0;
901 		error = copyout(&pe, addr, sizeof(pe));
902 		break;
903 
904 	case  PT_SET_EVENT_MASK:
905 		if (data != sizeof(pe)) {
906 			DPRINTF(("ptrace(%d): %d != %zu\n", req, data,
907 			    sizeof(pe)));
908 			error = EINVAL;
909 			break;
910 		}
911 		if ((error = copyin(addr, &pe, sizeof(pe))) != 0)
912 			return error;
913 		if (pe.pe_set_event & PTRACE_FORK)
914 			SET(t->p_slflag, PSL_TRACEFORK);
915 		else
916 			CLR(t->p_slflag, PSL_TRACEFORK);
917 #if notyet
918 		if (pe.pe_set_event & PTRACE_VFORK)
919 			SET(t->p_slflag, PSL_TRACEVFORK);
920 		else
921 			CLR(t->p_slflag, PSL_TRACEVFORK);
922 #else
923 		if (pe.pe_set_event & PTRACE_VFORK) {
924 			error = ENOTSUP;
925 			break;
926 		}
927 #endif
928 		if (pe.pe_set_event & PTRACE_VFORK_DONE)
929 			SET(t->p_slflag, PSL_TRACEVFORK_DONE);
930 		else
931 			CLR(t->p_slflag, PSL_TRACEVFORK_DONE);
932 		if (pe.pe_set_event & PTRACE_LWP_CREATE)
933 			SET(t->p_slflag, PSL_TRACELWP_CREATE);
934 		else
935 			CLR(t->p_slflag, PSL_TRACELWP_CREATE);
936 		if (pe.pe_set_event & PTRACE_LWP_EXIT)
937 			SET(t->p_slflag, PSL_TRACELWP_EXIT);
938 		else
939 			CLR(t->p_slflag, PSL_TRACELWP_EXIT);
940 		break;
941 
942 	case  PT_GET_PROCESS_STATE:
943 		if (data != sizeof(ps)) {
944 			DPRINTF(("ptrace(%d): %d != %zu\n", req, data,
945 			    sizeof(ps)));
946 			error = EINVAL;
947 			break;
948 		}
949 		memset(&ps, 0, sizeof(ps));
950 		if (t->p_fpid) {
951 			ps.pe_report_event = PTRACE_FORK;
952 			ps.pe_other_pid = t->p_fpid;
953 		} else if (t->p_vfpid) {
954 			ps.pe_report_event = PTRACE_VFORK;
955 			ps.pe_other_pid = t->p_vfpid;
956 		} else if (t->p_vfpid_done) {
957 			ps.pe_report_event = PTRACE_VFORK_DONE;
958 			ps.pe_other_pid = t->p_vfpid_done;
959 		} else if (t->p_lwp_created) {
960 			ps.pe_report_event = PTRACE_LWP_CREATE;
961 			ps.pe_lwp = t->p_lwp_created;
962 		} else if (t->p_lwp_exited) {
963 			ps.pe_report_event = PTRACE_LWP_EXIT;
964 			ps.pe_lwp = t->p_lwp_exited;
965 		}
966 		error = copyout(&ps, addr, sizeof(ps));
967 		break;
968 
969 	case PT_LWPINFO:
970 		if (data != sizeof(pl)) {
971 			DPRINTF(("ptrace(%d): %d != %zu\n", req, data,
972 			    sizeof(pl)));
973 			error = EINVAL;
974 			break;
975 		}
976 		error = copyin(addr, &pl, sizeof(pl));
977 		if (error)
978 			break;
979 		tmp = pl.pl_lwpid;
980 		lwp_delref(lt);
981 		mutex_enter(t->p_lock);
982 		if (tmp == 0)
983 			lt = lwp_find_first(t);
984 		else {
985 			lt = lwp_find(t, tmp);
986 			if (lt == NULL) {
987 				mutex_exit(t->p_lock);
988 				error = ESRCH;
989 				break;
990 			}
991 			lt = LIST_NEXT(lt, l_sibling);
992 		}
993 		while (lt != NULL && !lwp_alive(lt))
994 			lt = LIST_NEXT(lt, l_sibling);
995 		pl.pl_lwpid = 0;
996 		pl.pl_event = 0;
997 		if (lt) {
998 			lwp_addref(lt);
999 			pl.pl_lwpid = lt->l_lid;
1000 
1001 			if (lt->l_flag & LW_WSUSPEND)
1002 				pl.pl_event = PL_EVENT_SUSPENDED;
1003 			/*
1004 			 * If we match the lwp, or it was sent to every lwp,
1005 			 * we set PL_EVENT_SIGNAL.
1006 			 * XXX: ps_lwp == 0 means everyone and noone, so
1007 			 * check ps_signo too.
1008 			 */
1009 			else if (lt->l_lid == t->p_sigctx.ps_lwp
1010 			         || (t->p_sigctx.ps_lwp == 0 &&
1011 			             t->p_sigctx.ps_info._signo))
1012 				pl.pl_event = PL_EVENT_SIGNAL;
1013 		}
1014 		mutex_exit(t->p_lock);
1015 
1016 		error = copyout(&pl, addr, sizeof(pl));
1017 		break;
1018 
1019 	case  PT_SET_SIGINFO:
1020 		if (data != sizeof(psi)) {
1021 			DPRINTF(("ptrace(%d): %d != %zu\n", req, data,
1022 			    sizeof(psi)));
1023 			error = EINVAL;
1024 			break;
1025 		}
1026 
1027 		error = copyin(addr, &psi, sizeof(psi));
1028 		if (error)
1029 			break;
1030 
1031 		/* Check that the data is a valid signal number or zero. */
1032 		if (psi.psi_siginfo.si_signo < 0 ||
1033 		    psi.psi_siginfo.si_signo >= NSIG) {
1034 			error = EINVAL;
1035 			break;
1036 		}
1037 
1038 		tmp = psi.psi_lwpid;
1039 		if (tmp != 0)
1040 			lwp_delref(lt);
1041 
1042 		mutex_enter(t->p_lock);
1043 
1044 		if (tmp != 0) {
1045 			lt = lwp_find(t, tmp);
1046 			if (lt == NULL) {
1047 				mutex_exit(t->p_lock);
1048 				error = ESRCH;
1049 				break;
1050 			}
1051 			lwp_addref(lt);
1052 		}
1053 
1054 		t->p_sigctx.ps_faked = true;
1055 		t->p_sigctx.ps_info = psi.psi_siginfo._info;
1056 		t->p_sigctx.ps_lwp = psi.psi_lwpid;
1057 		mutex_exit(t->p_lock);
1058 		break;
1059 
1060 	case  PT_GET_SIGINFO:
1061 		if (data != sizeof(psi)) {
1062 			DPRINTF(("ptrace(%d): %d != %zu\n", req, data,
1063 			    sizeof(psi)));
1064 			error = EINVAL;
1065 			break;
1066 		}
1067 		mutex_enter(t->p_lock);
1068 		psi.psi_siginfo._info = t->p_sigctx.ps_info;
1069 		psi.psi_lwpid = t->p_sigctx.ps_lwp;
1070 		mutex_exit(t->p_lock);
1071 
1072 		error = copyout(&psi, addr, sizeof(psi));
1073 		if (error)
1074 			break;
1075 
1076 		break;
1077 
1078 	case  PT_SET_SIGMASK:
1079 		write = 1;
1080 
1081 	case  PT_GET_SIGMASK:
1082 		/* write = 0 done above. */
1083 
1084 		tmp = data;
1085 		if (tmp != 0 && t->p_nlwps > 1) {
1086 			lwp_delref(lt);
1087 			mutex_enter(t->p_lock);
1088 			lt = lwp_find(t, tmp);
1089 			if (lt == NULL) {
1090 				mutex_exit(t->p_lock);
1091 				error = ESRCH;
1092 				break;
1093 			}
1094 			lwp_addref(lt);
1095 			mutex_exit(t->p_lock);
1096 		}
1097 
1098 		if (lt->l_flag & LW_SYSTEM)
1099 			error = EINVAL;
1100 		else if (write == 1) {
1101 			error = copyin(addr, &lt->l_sigmask, sizeof(sigset_t));
1102 			sigminusset(&sigcantmask, &lt->l_sigmask);
1103 		} else
1104 			error = copyout(&lt->l_sigmask, addr, sizeof(sigset_t));
1105 
1106 		break;
1107 
1108 	case  PT_RESUME:
1109 		write = 1;
1110 
1111 	case  PT_SUSPEND:
1112 		/* write = 0 done above. */
1113 
1114 		tmp = data;
1115 		if (tmp != 0 && t->p_nlwps > 1) {
1116 			lwp_delref(lt);
1117 			mutex_enter(t->p_lock);
1118 			lt = lwp_find(t, tmp);
1119 			if (lt == NULL) {
1120 				mutex_exit(t->p_lock);
1121 				error = ESRCH;
1122 				break;
1123 			}
1124 			lwp_addref(lt);
1125 			mutex_exit(t->p_lock);
1126 		}
1127 		if (lt->l_flag & LW_SYSTEM) {
1128 			error = EINVAL;
1129 		} else {
1130 			lwp_lock(lt);
1131 			if (write == 0)
1132 				lt->l_flag |= LW_WSUSPEND;
1133 			else
1134 				lt->l_flag &= ~LW_WSUSPEND;
1135 			lwp_unlock(lt);
1136 		}
1137 		break;
1138 
1139 #ifdef PT_SETREGS
1140 	case  PT_SETREGS:
1141 		write = 1;
1142 #endif
1143 #ifdef PT_GETREGS
1144 	case  PT_GETREGS:
1145 		/* write = 0 done above. */
1146 #endif
1147 #if defined(PT_SETREGS) || defined(PT_GETREGS)
1148 		tmp = data;
1149 		if (tmp != 0 && t->p_nlwps > 1) {
1150 			lwp_delref(lt);
1151 			mutex_enter(t->p_lock);
1152 			lt = lwp_find(t, tmp);
1153 			if (lt == NULL) {
1154 				mutex_exit(t->p_lock);
1155 				error = ESRCH;
1156 				break;
1157 			}
1158 			lwp_addref(lt);
1159 			mutex_exit(t->p_lock);
1160 		}
1161 		if (!process_validregs(lt))
1162 			error = EINVAL;
1163 		else {
1164 			error = proc_vmspace_getref(p, &vm);
1165 			if (error)
1166 				break;
1167 			iov.iov_base = addr;
1168 			iov.iov_len = PROC_REGSZ(p);
1169 			uio.uio_iov = &iov;
1170 			uio.uio_iovcnt = 1;
1171 			uio.uio_offset = 0;
1172 			uio.uio_resid = iov.iov_len;
1173 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
1174 			uio.uio_vmspace = vm;
1175 
1176 			error = ptm->ptm_doregs(l, lt, &uio);
1177 			uvmspace_free(vm);
1178 		}
1179 		break;
1180 #endif
1181 
1182 #ifdef PT_SETFPREGS
1183 	case  PT_SETFPREGS:
1184 		write = 1;
1185 		/*FALLTHROUGH*/
1186 #endif
1187 #ifdef PT_GETFPREGS
1188 	case  PT_GETFPREGS:
1189 		/* write = 0 done above. */
1190 #endif
1191 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
1192 		tmp = data;
1193 		if (tmp != 0 && t->p_nlwps > 1) {
1194 			lwp_delref(lt);
1195 			mutex_enter(t->p_lock);
1196 			lt = lwp_find(t, tmp);
1197 			if (lt == NULL) {
1198 				mutex_exit(t->p_lock);
1199 				error = ESRCH;
1200 				break;
1201 			}
1202 			lwp_addref(lt);
1203 			mutex_exit(t->p_lock);
1204 		}
1205 		if (!process_validfpregs(lt))
1206 			error = EINVAL;
1207 		else {
1208 			error = proc_vmspace_getref(p, &vm);
1209 			if (error)
1210 				break;
1211 			iov.iov_base = addr;
1212 			iov.iov_len = PROC_FPREGSZ(p);
1213 			uio.uio_iov = &iov;
1214 			uio.uio_iovcnt = 1;
1215 			uio.uio_offset = 0;
1216 			uio.uio_resid = iov.iov_len;
1217 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
1218 			uio.uio_vmspace = vm;
1219 
1220 			error = ptm->ptm_dofpregs(l, lt, &uio);
1221 			uvmspace_free(vm);
1222 		}
1223 		break;
1224 #endif
1225 
1226 #ifdef PT_SETDBREGS
1227 	case  PT_SETDBREGS:
1228 		write = 1;
1229 		/*FALLTHROUGH*/
1230 #endif
1231 #ifdef PT_GETDBREGS
1232 	case  PT_GETDBREGS:
1233 		/* write = 0 done above. */
1234 #endif
1235 #if defined(PT_SETDBREGS) || defined(PT_GETDBREGS)
1236 		tmp = data;
1237 		if (tmp != 0 && t->p_nlwps > 1) {
1238 			lwp_delref(lt);
1239 			mutex_enter(t->p_lock);
1240 			lt = lwp_find(t, tmp);
1241 			if (lt == NULL) {
1242 				mutex_exit(t->p_lock);
1243 				error = ESRCH;
1244 				break;
1245 			}
1246 			lwp_addref(lt);
1247 			mutex_exit(t->p_lock);
1248 		}
1249 		if (!process_validdbregs(lt))
1250 			error = EINVAL;
1251 		else {
1252 			error = proc_vmspace_getref(p, &vm);
1253 			if (error)
1254 				break;
1255 			iov.iov_base = addr;
1256 			iov.iov_len = PROC_DBREGSZ(p);
1257 			uio.uio_iov = &iov;
1258 			uio.uio_iovcnt = 1;
1259 			uio.uio_offset = 0;
1260 			uio.uio_resid = iov.iov_len;
1261 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
1262 			uio.uio_vmspace = vm;
1263 
1264 			error = ptm->ptm_dodbregs(l, lt, &uio);
1265 			uvmspace_free(vm);
1266 		}
1267 		break;
1268 #endif
1269 
1270 #ifdef __HAVE_PTRACE_MACHDEP
1271 	PTRACE_MACHDEP_REQUEST_CASES
1272 		error = ptrace_machdep_dorequest(l, lt, req, addr, data);
1273 		break;
1274 #endif
1275 	}
1276 
1277 	if (pheld) {
1278 		mutex_exit(t->p_lock);
1279 		mutex_exit(proc_lock);
1280 	}
1281 	if (lt != NULL)
1282 		lwp_delref(lt);
1283 	rw_exit(&t->p_reflock);
1284 
1285 	return error;
1286 }
1287 
1288 int
1289 process_doregs(struct lwp *curl /*tracer*/,
1290     struct lwp *l /*traced*/,
1291     struct uio *uio)
1292 {
1293 #if defined(PT_GETREGS) || defined(PT_SETREGS)
1294 	int error;
1295 	struct reg r;
1296 	char *kv;
1297 	int kl;
1298 
1299 	if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
1300 		return EINVAL;
1301 
1302 	kl = sizeof(r);
1303 	kv = (char *)&r;
1304 
1305 	kv += uio->uio_offset;
1306 	kl -= uio->uio_offset;
1307 	if ((size_t)kl > uio->uio_resid)
1308 		kl = uio->uio_resid;
1309 
1310 	error = process_read_regs(l, &r);
1311 	if (error == 0)
1312 		error = uiomove(kv, kl, uio);
1313 	if (error == 0 && uio->uio_rw == UIO_WRITE) {
1314 		if (l->l_stat != LSSTOP)
1315 			error = EBUSY;
1316 		else
1317 			error = process_write_regs(l, &r);
1318 	}
1319 
1320 	uio->uio_offset = 0;
1321 	return error;
1322 #else
1323 	return EINVAL;
1324 #endif
1325 }
1326 
1327 int
1328 process_validregs(struct lwp *l)
1329 {
1330 
1331 #if defined(PT_SETREGS) || defined(PT_GETREGS)
1332 	return (l->l_flag & LW_SYSTEM) == 0;
1333 #else
1334 	return 0;
1335 #endif
1336 }
1337 
1338 int
1339 process_dofpregs(struct lwp *curl /*tracer*/,
1340     struct lwp *l /*traced*/,
1341     struct uio *uio)
1342 {
1343 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS)
1344 	int error;
1345 	struct fpreg r;
1346 	char *kv;
1347 	size_t kl;
1348 
1349 	if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
1350 		return EINVAL;
1351 
1352 	kl = sizeof(r);
1353 	kv = (char *)&r;
1354 
1355 	kv += uio->uio_offset;
1356 	kl -= uio->uio_offset;
1357 	if (kl > uio->uio_resid)
1358 		kl = uio->uio_resid;
1359 
1360 	error = process_read_fpregs(l, &r, &kl);
1361 	if (error == 0)
1362 		error = uiomove(kv, kl, uio);
1363 	if (error == 0 && uio->uio_rw == UIO_WRITE) {
1364 		if (l->l_stat != LSSTOP)
1365 			error = EBUSY;
1366 		else
1367 			error = process_write_fpregs(l, &r, kl);
1368 	}
1369 	uio->uio_offset = 0;
1370 	return error;
1371 #else
1372 	return EINVAL;
1373 #endif
1374 }
1375 
1376 int
1377 process_validfpregs(struct lwp *l)
1378 {
1379 
1380 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
1381 	return (l->l_flag & LW_SYSTEM) == 0;
1382 #else
1383 	return 0;
1384 #endif
1385 }
1386 
1387 int
1388 process_dodbregs(struct lwp *curl /*tracer*/,
1389     struct lwp *l /*traced*/,
1390     struct uio *uio)
1391 {
1392 #if defined(PT_GETDBREGS) || defined(PT_SETDBREGS)
1393 	int error;
1394 	struct dbreg r;
1395 	char *kv;
1396 	size_t kl;
1397 
1398 	if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
1399 		return EINVAL;
1400 
1401 	kl = sizeof(r);
1402 	kv = (char *)&r;
1403 
1404 	kv += uio->uio_offset;
1405 	kl -= uio->uio_offset;
1406 	if (kl > uio->uio_resid)
1407 		kl = uio->uio_resid;
1408 
1409 	error = process_read_dbregs(l, &r, &kl);
1410 	if (error == 0)
1411 		error = uiomove(kv, kl, uio);
1412 	if (error == 0 && uio->uio_rw == UIO_WRITE) {
1413 		if (l->l_stat != LSSTOP)
1414 			error = EBUSY;
1415 		else
1416 			error = process_write_dbregs(l, &r, kl);
1417 	}
1418 	uio->uio_offset = 0;
1419 	return error;
1420 #else
1421 	return EINVAL;
1422 #endif
1423 }
1424 
1425 int
1426 process_validdbregs(struct lwp *l)
1427 {
1428 
1429 #if defined(PT_SETDBREGS) || defined(PT_GETDBREGS)
1430 	return (l->l_flag & LW_SYSTEM) == 0;
1431 #else
1432 	return 0;
1433 #endif
1434 }
1435 
1436 static int
1437 process_auxv_offset(struct proc *p, struct uio *uio)
1438 {
1439 	struct ps_strings pss;
1440 	int error;
1441 	off_t off = (off_t)p->p_psstrp;
1442 
1443 	if ((error = copyin_psstrings(p, &pss)) != 0)
1444 		return error;
1445 
1446 	if (pss.ps_envstr == NULL)
1447 		return EIO;
1448 
1449 	uio->uio_offset += (off_t)(vaddr_t)(pss.ps_envstr + pss.ps_nenvstr + 1);
1450 #ifdef __MACHINE_STACK_GROWS_UP
1451 	if (uio->uio_offset < off)
1452 		return EIO;
1453 #else
1454 	if (uio->uio_offset > off)
1455 		return EIO;
1456 	if ((uio->uio_offset + uio->uio_resid) > off)
1457 		uio->uio_resid = off - uio->uio_offset;
1458 #endif
1459 	return 0;
1460 }
1461 #endif /* PTRACE */
1462 
1463 MODULE(MODULE_CLASS_EXEC, ptrace_common, "");
1464 
1465 static int
1466 ptrace_common_modcmd(modcmd_t cmd, void *arg)
1467 {
1468         int error;
1469 
1470         switch (cmd) {
1471         case MODULE_CMD_INIT:
1472                 error = ptrace_init();
1473                 break;
1474         case MODULE_CMD_FINI:
1475                 error = ptrace_fini();
1476                 break;
1477         default:
1478 		ptrace_hooks();
1479                 error = ENOTTY;
1480                 break;
1481         }
1482         return error;
1483 }
1484