sys_ptrace_common.c revision 1.35.2.4 1 /* $NetBSD: sys_ptrace_common.c,v 1.35.2.4 2018/06/25 07:26:04 pgoyette 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.35.2.4 2018/06/25 07:26:04 pgoyette Exp $");
122
123 #ifdef _KERNEL_OPT
124 #include "opt_ptrace.h"
125 #include "opt_ktrace.h"
126 #include "opt_pax.h"
127 #include "opt_compat_netbsd32.h"
128 #endif
129
130 #if defined(__HAVE_COMPAT_NETBSD32) && !defined(COMPAT_NETBSD32) \
131 && !defined(_RUMPKERNEL)
132 #define COMPAT_NETBSD32
133 #endif
134
135 #include <sys/param.h>
136 #include <sys/systm.h>
137 #include <sys/proc.h>
138 #include <sys/errno.h>
139 #include <sys/exec.h>
140 #include <sys/pax.h>
141 #include <sys/ptrace.h>
142 #include <sys/uio.h>
143 #include <sys/ras.h>
144 #include <sys/kmem.h>
145 #include <sys/kauth.h>
146 #include <sys/mount.h>
147 #include <sys/syscallargs.h>
148 #include <sys/module.h>
149 #include <sys/condvar.h>
150 #include <sys/mutex.h>
151
152 #include <uvm/uvm_extern.h>
153
154 #include <machine/reg.h>
155
156 #ifdef PTRACE
157 # ifdef PTRACE_DEBUG
158 # define DPRINTF(a) uprintf a
159 # else
160 # define DPRINTF(a)
161 # endif
162
163 static kauth_listener_t ptrace_listener;
164 static int process_auxv_offset(struct proc *, struct uio *);
165
166 #if 0
167 static int ptrace_cbref;
168 static kmutex_t ptrace_mtx;
169 static kcondvar_t ptrace_cv;
170 #endif
171
172 #ifdef PT_GETREGS
173 # define case_PT_GETREGS case PT_GETREGS:
174 #else
175 # define case_PT_GETREGS
176 #endif
177
178 #ifdef PT_SETREGS
179 # define case_PT_SETREGS case PT_SETREGS:
180 #else
181 # define case_PT_SETREGS
182 #endif
183
184 #ifdef PT_GETFPREGS
185 # define case_PT_GETFPREGS case PT_GETFPREGS:
186 #else
187 # define case_PT_GETFPREGS
188 #endif
189
190 #ifdef PT_SETFPREGS
191 # define case_PT_SETFPREGS case PT_SETFPREGS:
192 #else
193 # define case_PT_SETFPREGS
194 #endif
195
196 #ifdef PT_GETDBREGS
197 # define case_PT_GETDBREGS case PT_GETDBREGS:
198 #else
199 # define case_PT_GETDBREGS
200 #endif
201
202 #ifdef PT_SETDBREGS
203 # define case_PT_SETDBREGS case PT_SETDBREGS:
204 #else
205 # define case_PT_SETDBREGS
206 #endif
207
208 #if defined(PT_SETREGS) || defined(PT_GETREGS) || \
209 defined(PT_SETFPREGS) || defined(PT_GETFOREGS) || \
210 defined(PT_SETDBREGS) || defined(PT_GETDBREGS)
211 # define PT_REGISTERS
212 #endif
213
214 static int
215 ptrace_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
216 void *arg0, void *arg1, void *arg2, void *arg3)
217 {
218 struct proc *p;
219 int result;
220 #ifdef PT_SETDBREGS
221 extern int user_set_dbregs;
222 #endif
223
224 result = KAUTH_RESULT_DEFER;
225 p = arg0;
226
227 #if 0
228 mutex_enter(&ptrace_mtx);
229 ptrace_cbref++;
230 mutex_exit(&ptrace_mtx);
231 #endif
232 if (action != KAUTH_PROCESS_PTRACE)
233 goto out;
234
235 switch ((u_long)arg1) {
236 #ifdef PT_SETDBREGS
237 case_PT_SETDBREGS
238 if (kauth_cred_getuid(cred) != 0 && user_set_dbregs == 0) {
239 result = KAUTH_RESULT_DENY;
240 break;
241 }
242 #endif
243 case PT_TRACE_ME:
244 case PT_ATTACH:
245 case PT_WRITE_I:
246 case PT_WRITE_D:
247 case PT_READ_I:
248 case PT_READ_D:
249 case PT_IO:
250 case_PT_GETREGS
251 case_PT_SETREGS
252 case_PT_GETFPREGS
253 case_PT_SETFPREGS
254 case_PT_GETDBREGS
255 case PT_SET_EVENT_MASK:
256 case PT_GET_EVENT_MASK:
257 case PT_GET_PROCESS_STATE:
258 case PT_SET_SIGINFO:
259 case PT_GET_SIGINFO:
260 #ifdef __HAVE_PTRACE_MACHDEP
261 PTRACE_MACHDEP_REQUEST_CASES
262 #endif
263 if (kauth_cred_getuid(cred) != kauth_cred_getuid(p->p_cred) ||
264 ISSET(p->p_flag, PK_SUGID)) {
265 break;
266 }
267
268 result = KAUTH_RESULT_ALLOW;
269
270 break;
271
272 #ifdef PT_STEP
273 case PT_STEP:
274 case PT_SETSTEP:
275 case PT_CLEARSTEP:
276 #endif
277 case PT_CONTINUE:
278 case PT_KILL:
279 case PT_DETACH:
280 case PT_LWPINFO:
281 case PT_SYSCALL:
282 case PT_SYSCALLEMU:
283 case PT_DUMPCORE:
284 case PT_RESUME:
285 case PT_SUSPEND:
286 result = KAUTH_RESULT_ALLOW;
287 break;
288
289 default:
290 break;
291 }
292
293 out:
294 #if 0
295 mutex_enter(&ptrace_mtx);
296 if (--ptrace_cbref == 0)
297 cv_broadcast(&ptrace_cv);
298 mutex_exit(&ptrace_mtx);
299 #endif
300
301 return result;
302 }
303
304 int
305 ptrace_init(void)
306 {
307
308 #if 0
309 mutex_init(&ptrace_mtx, MUTEX_DEFAULT, IPL_NONE);
310 cv_init(&ptrace_cv, "ptracecb");
311 ptrace_cbref = 0;
312 #endif
313 ptrace_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
314 ptrace_listener_cb, NULL);
315 return 0;
316 }
317
318 int
319 ptrace_fini(void)
320 {
321
322 kauth_unlisten_scope(ptrace_listener);
323
324 #if 0
325 /* Make sure no-one is executing our kauth listener */
326
327 mutex_enter(&ptrace_mtx);
328 while (ptrace_cbref != 0)
329 cv_wait(&ptrace_cv, &ptrace_mtx);
330 mutex_exit(&ptrace_mtx);
331 mutex_destroy(&ptrace_mtx);
332 cv_destroy(&ptrace_cv);
333 #endif
334
335 return 0;
336 }
337
338 static struct proc *
339 ptrace_find(struct lwp *l, int req, pid_t pid)
340 {
341 struct proc *t;
342
343 /* "A foolish consistency..." XXX */
344 if (req == PT_TRACE_ME) {
345 t = l->l_proc;
346 mutex_enter(t->p_lock);
347 return t;
348 }
349
350 /* Find the process we're supposed to be operating on. */
351 t = proc_find(pid);
352 if (t == NULL)
353 return NULL;
354
355 /* XXX-elad */
356 mutex_enter(t->p_lock);
357 int error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
358 t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
359 if (error) {
360 mutex_exit(t->p_lock);
361 return NULL;
362 }
363 return t;
364 }
365
366 static int
367 ptrace_allowed(struct lwp *l, int req, struct proc *t, struct proc *p)
368 {
369 /*
370 * Grab a reference on the process to prevent it from execing or
371 * exiting.
372 */
373 if (!rw_tryenter(&t->p_reflock, RW_READER))
374 return EBUSY;
375
376 /* Make sure we can operate on it. */
377 switch (req) {
378 case PT_TRACE_ME:
379 /*
380 * You can't say to the parent of a process to start tracing if:
381 * (1) the parent is initproc,
382 */
383 if (p->p_pptr == initproc)
384 return EPERM;
385
386 /*
387 * (2) the process is initproc, or
388 */
389 if (p == initproc)
390 return EPERM;
391
392 /*
393 * (3) the child is already traced.
394 */
395 if (ISSET(p->p_slflag, PSL_TRACED))
396 return EBUSY;
397
398 return 0;
399
400 case PT_ATTACH:
401 /*
402 * You can't attach to a process if:
403 * (1) it's the process that's doing the attaching,
404 */
405 if (t == p)
406 return EINVAL;
407
408 /*
409 * (2) it's a system process,
410 */
411 if (t->p_flag & PK_SYSTEM)
412 return EPERM;
413
414 /*
415 * (3) the tracer is initproc,
416 */
417 if (p == initproc)
418 return EPERM;
419
420 /*
421 * (4) it's already being traced,
422 */
423 if (ISSET(t->p_slflag, PSL_TRACED))
424 return EBUSY;
425
426 /*
427 * (5) it's a vfork(2)ed parent of the current process, or
428 */
429 if (ISSET(p->p_lflag, PL_PPWAIT) && p->p_pptr == t)
430 return EPERM;
431
432 /*
433 * (6) the tracer is chrooted, and its root directory is
434 * not at or above the root directory of the tracee
435 */
436 mutex_exit(t->p_lock); /* XXXSMP */
437 int tmp = proc_isunder(t, l);
438 mutex_enter(t->p_lock); /* XXXSMP */
439 if (!tmp)
440 return EPERM;
441 return 0;
442
443 case PT_READ_I:
444 case PT_READ_D:
445 case PT_WRITE_I:
446 case PT_WRITE_D:
447 case PT_IO:
448 case PT_SET_SIGINFO:
449 case PT_GET_SIGINFO:
450 case_PT_GETREGS
451 case_PT_SETREGS
452 case_PT_GETFPREGS
453 case_PT_SETFPREGS
454 case_PT_GETDBREGS
455 case_PT_SETDBREGS
456 #ifdef __HAVE_PTRACE_MACHDEP
457 PTRACE_MACHDEP_REQUEST_CASES
458 #endif
459 /*
460 * You can't read/write the memory or registers of a process
461 * if the tracer is chrooted, and its root directory is not at
462 * or above the root directory of the tracee.
463 */
464 mutex_exit(t->p_lock); /* XXXSMP */
465 tmp = proc_isunder(t, l);
466 mutex_enter(t->p_lock); /* XXXSMP */
467 if (!tmp)
468 return EPERM;
469 /*FALLTHROUGH*/
470
471 case PT_CONTINUE:
472 case PT_KILL:
473 case PT_DETACH:
474 case PT_LWPINFO:
475 case PT_SYSCALL:
476 case PT_SYSCALLEMU:
477 case PT_DUMPCORE:
478 #ifdef PT_STEP
479 case PT_STEP:
480 case PT_SETSTEP:
481 case PT_CLEARSTEP:
482 #endif
483 case PT_SET_EVENT_MASK:
484 case PT_GET_EVENT_MASK:
485 case PT_GET_PROCESS_STATE:
486 case PT_RESUME:
487 case PT_SUSPEND:
488 /*
489 * You can't do what you want to the process if:
490 * (1) It's not being traced at all,
491 */
492 if (!ISSET(t->p_slflag, PSL_TRACED))
493 return EPERM;
494
495 /*
496 * (2) it's not being traced by _you_, or
497 */
498 if (t->p_pptr != p) {
499 DPRINTF(("parent %d != %d\n", t->p_pptr->p_pid,
500 p->p_pid));
501 return EBUSY;
502 }
503
504 /*
505 * (3) it's not currently stopped.
506 */
507 if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) {
508 DPRINTF(("stat %d flag %d\n", t->p_stat,
509 !t->p_waited));
510 return EBUSY;
511 }
512 return 0;
513
514 default: /* It was not a legal request. */
515 return EINVAL;
516 }
517 }
518
519 static int
520 ptrace_needs_hold(int req)
521 {
522 switch (req) {
523 #ifdef PT_STEP
524 case PT_STEP:
525 #endif
526 case PT_CONTINUE:
527 case PT_DETACH:
528 case PT_KILL:
529 case PT_SYSCALL:
530 case PT_SYSCALLEMU:
531 case PT_ATTACH:
532 case PT_TRACE_ME:
533 case PT_GET_SIGINFO:
534 case PT_SET_SIGINFO:
535 return 1;
536 default:
537 return 0;
538 }
539 }
540
541 static int
542 ptrace_update_lwp(struct proc *t, struct lwp **lt, lwpid_t lid)
543 {
544 if (lid == 0 || lid == (*lt)->l_lid || t->p_nlwps == 1)
545 return 0;
546
547 lwp_delref(*lt);
548
549 mutex_enter(t->p_lock);
550 *lt = lwp_find(t, lid);
551 if (*lt == NULL) {
552 mutex_exit(t->p_lock);
553 return ESRCH;
554 }
555
556 if ((*lt)->l_flag & LW_SYSTEM) {
557 *lt = NULL;
558 return EINVAL;
559 }
560
561 lwp_addref(*lt);
562 mutex_exit(t->p_lock);
563
564 return 0;
565 }
566
567 static int
568 ptrace_get_siginfo(struct proc *t, struct ptrace_methods *ptm, void *addr,
569 size_t data)
570 {
571 struct ptrace_siginfo psi;
572
573 psi.psi_siginfo._info = t->p_sigctx.ps_info;
574 psi.psi_lwpid = t->p_sigctx.ps_lwp;
575 DPRINTF(("%s: lwp=%d signal=%d\n", __func__, psi.psi_lwpid,
576 psi.psi_siginfo.si_signo));
577
578 return ptm->ptm_copyout_siginfo(&psi, addr, data);
579 }
580
581 static int
582 ptrace_set_siginfo(struct proc *t, struct lwp **lt, struct ptrace_methods *ptm,
583 void *addr, size_t data)
584 {
585 struct ptrace_siginfo psi;
586
587 int error = ptm->ptm_copyin_siginfo(&psi, addr, data);
588 if (error)
589 return error;
590
591 /* Check that the data is a valid signal number or zero. */
592 if (psi.psi_siginfo.si_signo < 0 || psi.psi_siginfo.si_signo >= NSIG)
593 return EINVAL;
594
595 if ((error = ptrace_update_lwp(t, lt, psi.psi_lwpid)) != 0)
596 return error;
597
598 t->p_sigctx.ps_faked = true;
599 t->p_sigctx.ps_info = psi.psi_siginfo._info;
600 t->p_sigctx.ps_lwp = psi.psi_lwpid;
601 DPRINTF(("%s: lwp=%d signal=%d\n", __func__, psi.psi_lwpid,
602 psi.psi_siginfo.si_signo));
603 return 0;
604 }
605
606 static int
607 ptrace_get_event_mask(struct proc *t, void *addr, size_t data)
608 {
609 struct ptrace_event pe;
610
611 if (data != sizeof(pe)) {
612 DPRINTF(("%s: %zu != %zu\n", __func__, data, sizeof(pe)));
613 return EINVAL;
614 }
615 memset(&pe, 0, sizeof(pe));
616 pe.pe_set_event = ISSET(t->p_slflag, PSL_TRACEFORK) ?
617 PTRACE_FORK : 0;
618 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK) ?
619 PTRACE_VFORK : 0;
620 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACEVFORK_DONE) ?
621 PTRACE_VFORK_DONE : 0;
622 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACELWP_CREATE) ?
623 PTRACE_LWP_CREATE : 0;
624 pe.pe_set_event |= ISSET(t->p_slflag, PSL_TRACELWP_EXIT) ?
625 PTRACE_LWP_EXIT : 0;
626 DPRINTF(("%s: lwp=%d event=%#x\n", __func__,
627 t->p_sigctx.ps_lwp, pe.pe_set_event));
628 return copyout(&pe, addr, sizeof(pe));
629 }
630
631 static int
632 ptrace_set_event_mask(struct proc *t, void *addr, size_t data)
633 {
634 struct ptrace_event pe;
635 int error;
636
637 if (data != sizeof(pe)) {
638 DPRINTF(("%s: %zu != %zu\n", __func__, data, sizeof(pe)));
639 return EINVAL;
640 }
641 if ((error = copyin(addr, &pe, sizeof(pe))) != 0)
642 return error;
643
644 DPRINTF(("%s: lwp=%d event=%#x\n", __func__,
645 t->p_sigctx.ps_lwp, pe.pe_set_event));
646 if (pe.pe_set_event & PTRACE_FORK)
647 SET(t->p_slflag, PSL_TRACEFORK);
648 else
649 CLR(t->p_slflag, PSL_TRACEFORK);
650
651 if (pe.pe_set_event & PTRACE_VFORK)
652 SET(t->p_slflag, PSL_TRACEVFORK);
653 else
654 CLR(t->p_slflag, PSL_TRACEVFORK);
655
656 if (pe.pe_set_event & PTRACE_VFORK_DONE)
657 SET(t->p_slflag, PSL_TRACEVFORK_DONE);
658 else
659 CLR(t->p_slflag, PSL_TRACEVFORK_DONE);
660
661 if (pe.pe_set_event & PTRACE_LWP_CREATE)
662 SET(t->p_slflag, PSL_TRACELWP_CREATE);
663 else
664 CLR(t->p_slflag, PSL_TRACELWP_CREATE);
665
666 if (pe.pe_set_event & PTRACE_LWP_EXIT)
667 SET(t->p_slflag, PSL_TRACELWP_EXIT);
668 else
669 CLR(t->p_slflag, PSL_TRACELWP_EXIT);
670 return 0;
671 }
672
673 static int
674 ptrace_get_process_state(struct proc *t, void *addr, size_t data)
675 {
676 struct ptrace_state ps;
677
678 if (data != sizeof(ps)) {
679 DPRINTF(("%s: %zu != %zu\n", __func__, data, sizeof(ps)));
680 return EINVAL;
681 }
682 memset(&ps, 0, sizeof(ps));
683
684 if (t->p_fpid) {
685 ps.pe_report_event = PTRACE_FORK;
686 ps.pe_other_pid = t->p_fpid;
687 } else if (t->p_vfpid) {
688 ps.pe_report_event = PTRACE_VFORK;
689 ps.pe_other_pid = t->p_vfpid;
690 } else if (t->p_vfpid_done) {
691 ps.pe_report_event = PTRACE_VFORK_DONE;
692 ps.pe_other_pid = t->p_vfpid_done;
693 } else if (t->p_lwp_created) {
694 ps.pe_report_event = PTRACE_LWP_CREATE;
695 ps.pe_lwp = t->p_lwp_created;
696 } else if (t->p_lwp_exited) {
697 ps.pe_report_event = PTRACE_LWP_EXIT;
698 ps.pe_lwp = t->p_lwp_exited;
699 }
700 DPRINTF(("%s: lwp=%d event=%#x pid=%d lwp=%d\n", __func__,
701 t->p_sigctx.ps_lwp, ps.pe_report_event,
702 ps.pe_other_pid, ps.pe_lwp));
703 return copyout(&ps, addr, sizeof(ps));
704 }
705
706 static int
707 ptrace_lwpinfo(struct proc *t, struct lwp **lt, void *addr, size_t data)
708 {
709 struct ptrace_lwpinfo pl;
710
711 if (data != sizeof(pl)) {
712 DPRINTF(("%s: %zu != %zu\n", __func__, data, sizeof(pl)));
713 return EINVAL;
714 }
715 int error = copyin(addr, &pl, sizeof(pl));
716 if (error)
717 return error;
718
719 lwpid_t tmp = pl.pl_lwpid;
720 lwp_delref(*lt);
721 mutex_enter(t->p_lock);
722 if (tmp == 0)
723 *lt = lwp_find_first(t);
724 else {
725 *lt = lwp_find(t, tmp);
726 if (*lt == NULL) {
727 mutex_exit(t->p_lock);
728 return ESRCH;
729 }
730 *lt = LIST_NEXT(*lt, l_sibling);
731 }
732
733 while (*lt != NULL && !lwp_alive(*lt))
734 *lt = LIST_NEXT(*lt, l_sibling);
735
736 pl.pl_lwpid = 0;
737 pl.pl_event = 0;
738 if (*lt) {
739 lwp_addref(*lt);
740 pl.pl_lwpid = (*lt)->l_lid;
741
742 if ((*lt)->l_flag & LW_WSUSPEND)
743 pl.pl_event = PL_EVENT_SUSPENDED;
744 /*
745 * If we match the lwp, or it was sent to every lwp,
746 * we set PL_EVENT_SIGNAL.
747 * XXX: ps_lwp == 0 means everyone and noone, so
748 * check ps_signo too.
749 */
750 else if ((*lt)->l_lid == t->p_sigctx.ps_lwp
751 || (t->p_sigctx.ps_lwp == 0 &&
752 t->p_sigctx.ps_info._signo)) {
753 DPRINTF(("%s: lwp=%d siglwp=%d signo %d\n", __func__,
754 pl.pl_lwpid, t->p_sigctx.ps_lwp,
755 t->p_sigctx.ps_info._signo));
756 pl.pl_event = PL_EVENT_SIGNAL;
757 }
758 }
759 mutex_exit(t->p_lock);
760 DPRINTF(("%s: lwp=%d event=%#x\n", __func__,
761 pl.pl_lwpid, pl.pl_event));
762
763 return copyout(&pl, addr, sizeof(pl));
764 }
765
766 static int
767 ptrace_startstop(struct proc *t, struct lwp **lt, int rq, void *addr,
768 size_t data)
769 {
770 int error;
771
772 if ((error = ptrace_update_lwp(t, lt, data)) != 0)
773 return error;
774
775 DPRINTF(("%s: lwp=%d request=%d\n", __func__, (*lt)->l_lid, rq));
776 lwp_lock(*lt);
777 if (rq == PT_SUSPEND)
778 (*lt)->l_flag |= LW_WSUSPEND;
779 else
780 (*lt)->l_flag &= ~LW_WSUSPEND;
781 lwp_unlock(*lt);
782 return 0;
783 }
784
785 #ifdef PT_REGISTERS
786 static int
787 ptrace_uio_dir(int req)
788 {
789 switch (req) {
790 case_PT_GETREGS
791 case_PT_GETFPREGS
792 case_PT_GETDBREGS
793 return UIO_READ;
794 case_PT_SETREGS
795 case_PT_SETFPREGS
796 case_PT_SETDBREGS
797 return UIO_WRITE;
798 default:
799 return -1;
800 }
801 }
802
803 static int
804 ptrace_regs(struct lwp *l, struct lwp **lt, int rq, struct ptrace_methods *ptm,
805 void *addr, size_t data)
806 {
807 int error;
808 struct proc *t = (*lt)->l_proc;
809 struct vmspace *vm;
810
811 if ((error = ptrace_update_lwp(t, lt, data)) != 0)
812 return error;
813
814 int dir = ptrace_uio_dir(rq);
815 size_t size;
816 int (*func)(struct lwp *, struct lwp *, struct uio *);
817
818 DPRINTF(("%s: lwp=%d request=%d\n", __func__, l->l_lid, rq));
819
820 switch (rq) {
821 #if defined(PT_SETREGS) || defined(PT_GETREGS)
822 case_PT_GETREGS
823 case_PT_SETREGS
824 if (!process_validregs(*lt))
825 return EINVAL;
826 size = PROC_REGSZ(t);
827 func = ptm->ptm_doregs;
828 break;
829 #endif
830 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
831 case_PT_GETFPREGS
832 case_PT_SETFPREGS
833 if (!process_validfpregs(*lt))
834 return EINVAL;
835 size = PROC_FPREGSZ(t);
836 func = ptm->ptm_dofpregs;
837 break;
838 #endif
839 #if defined(PT_SETDBREGS) || defined(PT_GETDBREGS)
840 case_PT_GETDBREGS
841 case_PT_SETDBREGS
842 if (!process_validdbregs(*lt))
843 return EINVAL;
844 size = PROC_DBREGSZ(t);
845 func = ptm->ptm_dodbregs;
846 break;
847 #endif
848 default:
849 return EINVAL;
850 }
851
852 error = proc_vmspace_getref(l->l_proc, &vm);
853 if (error)
854 return error;
855
856 struct uio uio;
857 struct iovec iov;
858
859 iov.iov_base = addr;
860 iov.iov_len = size;
861 uio.uio_iov = &iov;
862 uio.uio_iovcnt = 1;
863 uio.uio_offset = 0;
864 uio.uio_resid = iov.iov_len;
865 uio.uio_rw = dir;
866 uio.uio_vmspace = vm;
867
868 error = (*func)(l, *lt, &uio);
869 uvmspace_free(vm);
870 return error;
871 }
872 #endif
873
874 static int
875 ptrace_sendsig(struct proc *t, struct lwp *lt, int signo, int resume_all)
876 {
877 ksiginfo_t ksi;
878
879 t->p_fpid = 0;
880 t->p_vfpid = 0;
881 t->p_vfpid_done = 0;
882 t->p_lwp_created = 0;
883 t->p_lwp_exited = 0;
884
885 /* Finally, deliver the requested signal (or none). */
886 if (t->p_stat == SSTOP) {
887 /*
888 * Unstop the process. If it needs to take a
889 * signal, make all efforts to ensure that at
890 * an LWP runs to see it.
891 */
892 t->p_xsig = signo;
893
894 /*
895 * signo > 0 check prevents a potential panic, as
896 * sigismember(&...,0) is invalid check and signo
897 * can be equal to 0 as a special case of no-signal.
898 */
899 if (signo > 0 && sigismember(&stopsigmask, signo)) {
900 t->p_waited = 0;
901 child_psignal(t, 0);
902 } else if (resume_all)
903 proc_unstop(t);
904 else
905 lwp_unstop(lt);
906 return 0;
907 }
908
909 KSI_INIT_EMPTY(&ksi);
910 if (t->p_sigctx.ps_faked) {
911 if (signo != t->p_sigctx.ps_info._signo)
912 return EINVAL;
913 t->p_sigctx.ps_faked = false;
914 ksi.ksi_info = t->p_sigctx.ps_info;
915 ksi.ksi_lid = t->p_sigctx.ps_lwp;
916 } else if (signo == 0) {
917 return 0;
918 } else {
919 ksi.ksi_signo = signo;
920 }
921 DPRINTF(("%s: pid=%d.%d signal=%d resume_all=%d\n", __func__, t->p_pid,
922 t->p_sigctx.ps_lwp, signo, resume_all));
923
924 kpsignal2(t, &ksi);
925 return 0;
926 }
927
928 static int
929 ptrace_dumpcore(struct lwp *lt, char *path, size_t len)
930 {
931 int error;
932 if (path != NULL) {
933
934 if (len >= MAXPATHLEN)
935 return EINVAL;
936
937 char *src = path;
938 path = kmem_alloc(len + 1, KM_SLEEP);
939 error = copyin(src, path, len);
940 if (error)
941 goto out;
942 path[len] = '\0';
943 }
944 DPRINTF(("%s: lwp=%d\n", __func__, lt->l_lid));
945 error = (*coredump_vec)(lt, path);
946 out:
947 if (path)
948 kmem_free(path, len + 1);
949 return error;
950 }
951
952 static int
953 ptrace_doio(struct lwp *l, struct proc *t, struct lwp *lt,
954 struct ptrace_io_desc *piod, void *addr, bool sysspace)
955 {
956 struct uio uio;
957 struct iovec iov;
958 int error, tmp;
959
960 error = 0;
961 iov.iov_base = piod->piod_addr;
962 iov.iov_len = piod->piod_len;
963 uio.uio_iov = &iov;
964 uio.uio_iovcnt = 1;
965 uio.uio_offset = (off_t)(unsigned long)piod->piod_offs;
966 uio.uio_resid = piod->piod_len;
967
968 DPRINTF(("%s: lwp=%d request=%d\n", __func__, l->l_lid, piod->piod_op));
969
970 switch (piod->piod_op) {
971 case PIOD_READ_D:
972 case PIOD_READ_I:
973 uio.uio_rw = UIO_READ;
974 break;
975 case PIOD_WRITE_D:
976 case PIOD_WRITE_I:
977 /*
978 * Can't write to a RAS
979 */
980 if (ras_lookup(t, addr) != (void *)-1) {
981 return EACCES;
982 }
983 uio.uio_rw = UIO_WRITE;
984 break;
985 case PIOD_READ_AUXV:
986 uio.uio_rw = UIO_READ;
987 tmp = t->p_execsw->es_arglen;
988 if (uio.uio_offset > tmp)
989 return EIO;
990 if (uio.uio_resid > tmp - uio.uio_offset)
991 uio.uio_resid = tmp - uio.uio_offset;
992 piod->piod_len = iov.iov_len = uio.uio_resid;
993 error = process_auxv_offset(t, &uio);
994 break;
995 default:
996 error = EINVAL;
997 break;
998 }
999
1000 if (error)
1001 return error;
1002
1003 if (sysspace) {
1004 uio.uio_vmspace = vmspace_kernel();
1005 } else {
1006 error = proc_vmspace_getref(l->l_proc, &uio.uio_vmspace);
1007 if (error)
1008 return error;
1009 }
1010
1011 error = process_domem(l, lt, &uio);
1012 if (!sysspace)
1013 uvmspace_free(uio.uio_vmspace);
1014 if (error)
1015 return error;
1016 piod->piod_len -= uio.uio_resid;
1017 return 0;
1018 }
1019
1020 int
1021 do_ptrace(struct ptrace_methods *ptm, struct lwp *l, int req, pid_t pid,
1022 void *addr, int data, register_t *retval)
1023 {
1024 struct proc *p = l->l_proc;
1025 struct lwp *lt = NULL;
1026 struct lwp *lt2;
1027 struct proc *t; /* target process */
1028 struct ptrace_io_desc piod;
1029 int error, write, tmp, pheld;
1030 int signo = 0;
1031 int resume_all;
1032 error = 0;
1033
1034 /*
1035 * If attaching or detaching, we need to get a write hold on the
1036 * proclist lock so that we can re-parent the target process.
1037 */
1038 mutex_enter(proc_lock);
1039
1040 t = ptrace_find(l, req, pid);
1041 if (t == NULL) {
1042 mutex_exit(proc_lock);
1043 return ESRCH;
1044 }
1045
1046 pheld = 1;
1047 if ((error = ptrace_allowed(l, req, t, p)) != 0)
1048 goto out;
1049
1050 if ((error = kauth_authorize_process(l->l_cred,
1051 KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req), NULL, NULL)) != 0)
1052 goto out;
1053
1054 if ((lt = lwp_find_first(t)) == NULL) {
1055 error = ESRCH;
1056 goto out;
1057 }
1058
1059 /* Do single-step fixup if needed. */
1060 FIX_SSTEP(t);
1061 KASSERT(lt != NULL);
1062 lwp_addref(lt);
1063
1064 /*
1065 * Which locks do we need held? XXX Ugly.
1066 */
1067 if ((pheld = ptrace_needs_hold(req)) == 0) {
1068 mutex_exit(t->p_lock);
1069 mutex_exit(proc_lock);
1070 }
1071
1072 /* Now do the operation. */
1073 write = 0;
1074 *retval = 0;
1075 tmp = 0;
1076 resume_all = 1;
1077
1078 switch (req) {
1079 case PT_TRACE_ME:
1080 /* Just set the trace flag. */
1081 SET(t->p_slflag, PSL_TRACED);
1082 t->p_opptr = t->p_pptr;
1083 break;
1084
1085 /*
1086 * The I and D separate address space has been inherited from PDP-11.
1087 * The 16-bit UNIX started with a single address space per program,
1088 * but was extended to two 16-bit (2 x 64kb) address spaces.
1089 *
1090 * We no longer maintain this feature in maintained architectures, but
1091 * we keep the API for backward compatiblity. Currently the I and D
1092 * operations are exactly the same and not distinguished in debuggers.
1093 */
1094 case PT_WRITE_I:
1095 case PT_WRITE_D:
1096 write = 1;
1097 tmp = data;
1098 /* FALLTHROUGH */
1099 case PT_READ_I:
1100 case PT_READ_D:
1101 piod.piod_addr = &tmp;
1102 piod.piod_len = sizeof(tmp);
1103 piod.piod_offs = addr;
1104 piod.piod_op = write ? PIOD_WRITE_D : PIOD_READ_D;
1105 if ((error = ptrace_doio(l, t, lt, &piod, addr, true)) != 0)
1106 break;
1107 if (!write)
1108 *retval = tmp;
1109 break;
1110
1111 case PT_IO:
1112 if ((error = ptm->ptm_copyin_piod(&piod, addr, data)) != 0)
1113 break;
1114 if ((error = ptrace_doio(l, t, lt, &piod, addr, false)) != 0)
1115 break;
1116 error = ptm->ptm_copyout_piod(&piod, addr, data);
1117 break;
1118
1119 case PT_DUMPCORE:
1120 error = ptrace_dumpcore(lt, addr, data);
1121 break;
1122
1123 #ifdef PT_STEP
1124 case PT_STEP:
1125 /*
1126 * From the 4.4BSD PRM:
1127 * "Execution continues as in request PT_CONTINUE; however
1128 * as soon as possible after execution of at least one
1129 * instruction, execution stops again. [ ... ]"
1130 */
1131 #endif
1132 case PT_CONTINUE:
1133 case PT_SYSCALL:
1134 case PT_DETACH:
1135 if (req == PT_SYSCALL) {
1136 if (!ISSET(t->p_slflag, PSL_SYSCALL)) {
1137 SET(t->p_slflag, PSL_SYSCALL);
1138 #ifdef __HAVE_SYSCALL_INTERN
1139 (*t->p_emul->e_syscall_intern)(t);
1140 #endif
1141 }
1142 } else {
1143 if (ISSET(t->p_slflag, PSL_SYSCALL)) {
1144 CLR(t->p_slflag, PSL_SYSCALL);
1145 #ifdef __HAVE_SYSCALL_INTERN
1146 (*t->p_emul->e_syscall_intern)(t);
1147 #endif
1148 }
1149 }
1150 t->p_trace_enabled = trace_is_enabled(t);
1151
1152 /*
1153 * Pick up the LWPID, if supplied. There are two cases:
1154 * data < 0 : step or continue single thread, lwp = -data
1155 * data > 0 in PT_STEP : step this thread, continue others
1156 * For operations other than PT_STEP, data > 0 means
1157 * data is the signo to deliver to the process.
1158 */
1159 tmp = data;
1160 if (tmp >= 0) {
1161 #ifdef PT_STEP
1162 if (req == PT_STEP)
1163 signo = 0;
1164 else
1165 #endif
1166 {
1167 signo = tmp;
1168 tmp = 0; /* don't search for LWP */
1169 }
1170 } else
1171 tmp = -tmp;
1172
1173 if (tmp > 0) {
1174 if (req == PT_DETACH) {
1175 error = EINVAL;
1176 break;
1177 }
1178 lwp_delref2 (lt);
1179 lt = lwp_find(t, tmp);
1180 if (lt == NULL) {
1181 error = ESRCH;
1182 break;
1183 }
1184 lwp_addref(lt);
1185 resume_all = 0;
1186 signo = 0;
1187 }
1188
1189 /*
1190 * From the 4.4BSD PRM:
1191 * "The data argument is taken as a signal number and the
1192 * child's execution continues at location addr as if it
1193 * incurred that signal. Normally the signal number will
1194 * be either 0 to indicate that the signal that caused the
1195 * stop should be ignored, or that value fetched out of
1196 * the process's image indicating which signal caused
1197 * the stop. If addr is (int *)1 then execution continues
1198 * from where it stopped."
1199 */
1200
1201 /* Check that the data is a valid signal number or zero. */
1202 if (signo < 0 || signo >= NSIG) {
1203 error = EINVAL;
1204 break;
1205 }
1206
1207 /* Prevent process deadlock */
1208 if (resume_all) {
1209 #ifdef PT_STEP
1210 if (req == PT_STEP) {
1211 if (lt->l_flag & LW_WSUSPEND) {
1212 error = EDEADLK;
1213 break;
1214 }
1215 } else
1216 #endif
1217 {
1218 error = EDEADLK;
1219 LIST_FOREACH(lt2, &t->p_lwps, l_sibling) {
1220 if ((lt2->l_flag & LW_WSUSPEND) == 0) {
1221 error = 0;
1222 break;
1223 }
1224 }
1225 if (error != 0)
1226 break;
1227 }
1228 } else {
1229 if (lt->l_flag & LW_WSUSPEND) {
1230 error = EDEADLK;
1231 break;
1232 }
1233 }
1234
1235 /* If the address parameter is not (int *)1, set the pc. */
1236 if ((int *)addr != (int *)1) {
1237 error = process_set_pc(lt, addr);
1238 if (error != 0)
1239 break;
1240 }
1241 #ifdef PT_STEP
1242 /*
1243 * Arrange for a single-step, if that's requested and possible.
1244 * More precisely, set the single step status as requested for
1245 * the requested thread, and clear it for other threads.
1246 */
1247 LIST_FOREACH(lt2, &t->p_lwps, l_sibling) {
1248 if (ISSET(lt2->l_pflag, LP_SINGLESTEP)) {
1249 lwp_lock(lt2);
1250 process_sstep(lt2, 1);
1251 lwp_unlock(lt2);
1252 } else if (lt != lt2) {
1253 lwp_lock(lt2);
1254 process_sstep(lt2, 0);
1255 lwp_unlock(lt2);
1256 }
1257 }
1258 error = process_sstep(lt,
1259 ISSET(lt->l_pflag, LP_SINGLESTEP) || req == PT_STEP);
1260 if (error)
1261 break;
1262 #endif
1263 if (req == PT_DETACH) {
1264 CLR(t->p_slflag, PSL_TRACED|PSL_SYSCALL);
1265
1266 /* give process back to original parent or init */
1267 if (t->p_opptr != t->p_pptr) {
1268 struct proc *pp = t->p_opptr;
1269 proc_reparent(t, pp ? pp : initproc);
1270 }
1271
1272 /* not being traced any more */
1273 t->p_opptr = NULL;
1274
1275 /* clear single step */
1276 LIST_FOREACH(lt2, &t->p_lwps, l_sibling) {
1277 CLR(lt2->l_pflag, LP_SINGLESTEP);
1278 }
1279 CLR(lt->l_pflag, LP_SINGLESTEP);
1280 }
1281 sendsig:
1282 error = ptrace_sendsig(t, lt, signo, resume_all);
1283 break;
1284
1285 case PT_SYSCALLEMU:
1286 if (!ISSET(t->p_slflag, PSL_SYSCALL) || t->p_stat != SSTOP) {
1287 error = EINVAL;
1288 break;
1289 }
1290 SET(t->p_slflag, PSL_SYSCALLEMU);
1291 break;
1292
1293 #ifdef PT_STEP
1294 case PT_SETSTEP:
1295 write = 1;
1296
1297 case PT_CLEARSTEP:
1298 /* write = 0 done above. */
1299 if ((error = ptrace_update_lwp(t, <, data)) != 0)
1300 break;
1301
1302 if (write)
1303 SET(lt->l_pflag, LP_SINGLESTEP);
1304 else
1305 CLR(lt->l_pflag, LP_SINGLESTEP);
1306 break;
1307 #endif
1308
1309 case PT_KILL:
1310 /* just send the process a KILL signal. */
1311 signo = SIGKILL;
1312 goto sendsig; /* in PT_CONTINUE, above. */
1313
1314 case PT_ATTACH:
1315 /*
1316 * Go ahead and set the trace flag.
1317 * Save the old parent (it's reset in
1318 * _DETACH, and also in kern_exit.c:wait4()
1319 * Reparent the process so that the tracing
1320 * proc gets to see all the action.
1321 * Stop the target.
1322 */
1323 proc_changeparent(t, p);
1324 signo = SIGSTOP;
1325 goto sendsig;
1326
1327 case PT_GET_EVENT_MASK:
1328 error = ptrace_get_event_mask(t, addr, data);
1329 break;
1330
1331 case PT_SET_EVENT_MASK:
1332 error = ptrace_set_event_mask(t, addr, data);
1333 break;
1334
1335 case PT_GET_PROCESS_STATE:
1336 error = ptrace_get_process_state(t, addr, data);
1337 break;
1338
1339 case PT_LWPINFO:
1340 error = ptrace_lwpinfo(t, <, addr, data);
1341 break;
1342
1343 case PT_SET_SIGINFO:
1344 error = ptrace_set_siginfo(t, <, ptm, addr, data);
1345 break;
1346
1347 case PT_GET_SIGINFO:
1348 error = ptrace_get_siginfo(t, ptm, addr, data);
1349 break;
1350
1351 case PT_RESUME:
1352 case PT_SUSPEND:
1353 error = ptrace_startstop(t, <, req, addr, data);
1354 break;
1355
1356 #ifdef PT_REGISTERS
1357 case_PT_SETREGS
1358 case_PT_GETREGS
1359 case_PT_SETFPREGS
1360 case_PT_GETFPREGS
1361 case_PT_SETDBREGS
1362 case_PT_GETDBREGS
1363 error = ptrace_regs(l, <, req, ptm, addr, data);
1364 break;
1365 #endif
1366
1367 #ifdef __HAVE_PTRACE_MACHDEP
1368 PTRACE_MACHDEP_REQUEST_CASES
1369 error = ptrace_machdep_dorequest(l, lt, req, addr, data);
1370 break;
1371 #endif
1372 }
1373
1374 out:
1375 if (pheld) {
1376 mutex_exit(t->p_lock);
1377 mutex_exit(proc_lock);
1378 }
1379 if (lt != NULL)
1380 lwp_delref(lt);
1381 rw_exit(&t->p_reflock);
1382
1383 return error;
1384 }
1385
1386 typedef int (*regrfunc_t)(struct lwp *, void *, size_t *);
1387 typedef int (*regwfunc_t)(struct lwp *, void *, size_t);
1388
1389 #ifdef PT_REGISTERS
1390 static int
1391 proc_regio(struct lwp *l, struct uio *uio, size_t ks, regrfunc_t r,
1392 regwfunc_t w)
1393 {
1394 char buf[1024];
1395 int error;
1396 char *kv;
1397 size_t kl;
1398
1399 if (ks > sizeof(buf))
1400 return E2BIG;
1401
1402 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)ks)
1403 return EINVAL;
1404
1405 kv = buf + uio->uio_offset;
1406 kl = ks - uio->uio_offset;
1407
1408 if (kl > uio->uio_resid)
1409 kl = uio->uio_resid;
1410
1411 error = (*r)(l, buf, &ks);
1412 if (error == 0)
1413 error = uiomove(kv, kl, uio);
1414 if (error == 0 && uio->uio_rw == UIO_WRITE) {
1415 if (l->l_stat != LSSTOP)
1416 error = EBUSY;
1417 else
1418 error = (*w)(l, buf, ks);
1419 }
1420
1421 uio->uio_offset = 0;
1422 return error;
1423 }
1424 #endif
1425
1426 int
1427 process_doregs(struct lwp *curl /*tracer*/,
1428 struct lwp *l /*traced*/,
1429 struct uio *uio)
1430 {
1431 #if defined(PT_GETREGS) || defined(PT_SETREGS)
1432 size_t s;
1433 regrfunc_t r;
1434 regwfunc_t w;
1435
1436 #ifdef COMPAT_NETBSD32
1437 const bool pk32 = (l->l_proc->p_flag & PK_32) != 0;
1438
1439 if (__predict_false(pk32)) {
1440 s = sizeof(process_reg32);
1441 r = (regrfunc_t)process_read_regs32;
1442 w = (regwfunc_t)process_write_regs32;
1443 } else
1444 #endif
1445 {
1446 s = sizeof(struct reg);
1447 r = (regrfunc_t)process_read_regs;
1448 w = (regwfunc_t)process_write_regs;
1449 }
1450 return proc_regio(l, uio, s, r, w);
1451 #else
1452 return EINVAL;
1453 #endif
1454 }
1455
1456 int
1457 process_validregs(struct lwp *l)
1458 {
1459
1460 #if defined(PT_SETREGS) || defined(PT_GETREGS)
1461 return (l->l_flag & LW_SYSTEM) == 0;
1462 #else
1463 return 0;
1464 #endif
1465 }
1466
1467 int
1468 process_dofpregs(struct lwp *curl /*tracer*/,
1469 struct lwp *l /*traced*/,
1470 struct uio *uio)
1471 {
1472 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS)
1473 size_t s;
1474 regrfunc_t r;
1475 regwfunc_t w;
1476
1477 #ifdef COMPAT_NETBSD32
1478 const bool pk32 = (l->l_proc->p_flag & PK_32) != 0;
1479
1480 if (__predict_false(pk32)) {
1481 s = sizeof(process_fpreg32);
1482 r = (regrfunc_t)process_read_fpregs32;
1483 w = (regwfunc_t)process_write_fpregs32;
1484 } else
1485 #endif
1486 {
1487 s = sizeof(struct fpreg);
1488 r = (regrfunc_t)process_read_fpregs;
1489 w = (regwfunc_t)process_write_fpregs;
1490 }
1491 return proc_regio(l, uio, s, r, w);
1492 #else
1493 return EINVAL;
1494 #endif
1495 }
1496
1497 int
1498 process_validfpregs(struct lwp *l)
1499 {
1500
1501 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
1502 return (l->l_flag & LW_SYSTEM) == 0;
1503 #else
1504 return 0;
1505 #endif
1506 }
1507
1508 int
1509 process_dodbregs(struct lwp *curl /*tracer*/,
1510 struct lwp *l /*traced*/,
1511 struct uio *uio)
1512 {
1513 #if defined(PT_GETDBREGS) || defined(PT_SETDBREGS)
1514 size_t s;
1515 regrfunc_t r;
1516 regwfunc_t w;
1517
1518 #ifdef COMPAT_NETBSD32
1519 const bool pk32 = (l->l_proc->p_flag & PK_32) != 0;
1520
1521 if (__predict_false(pk32)) {
1522 s = sizeof(process_dbreg32);
1523 r = (regrfunc_t)process_read_dbregs32;
1524 w = (regwfunc_t)process_write_dbregs32;
1525 } else
1526 #endif
1527 {
1528 s = sizeof(struct dbreg);
1529 r = (regrfunc_t)process_read_dbregs;
1530 w = (regwfunc_t)process_write_dbregs;
1531 }
1532 return proc_regio(l, uio, s, r, w);
1533 #else
1534 return EINVAL;
1535 #endif
1536 }
1537
1538 int
1539 process_validdbregs(struct lwp *l)
1540 {
1541
1542 #if defined(PT_SETDBREGS) || defined(PT_GETDBREGS)
1543 return (l->l_flag & LW_SYSTEM) == 0;
1544 #else
1545 return 0;
1546 #endif
1547 }
1548
1549 static int
1550 process_auxv_offset(struct proc *p, struct uio *uio)
1551 {
1552 struct ps_strings pss;
1553 int error;
1554 off_t off = (off_t)p->p_psstrp;
1555
1556 if ((error = copyin_psstrings(p, &pss)) != 0)
1557 return error;
1558
1559 if (pss.ps_envstr == NULL)
1560 return EIO;
1561
1562 uio->uio_offset += (off_t)(vaddr_t)(pss.ps_envstr + pss.ps_nenvstr + 1);
1563 #ifdef __MACHINE_STACK_GROWS_UP
1564 if (uio->uio_offset < off)
1565 return EIO;
1566 #else
1567 if (uio->uio_offset > off)
1568 return EIO;
1569 if ((uio->uio_offset + uio->uio_resid) > off)
1570 uio->uio_resid = off - uio->uio_offset;
1571 #endif
1572 return 0;
1573 }
1574 #endif /* PTRACE */
1575
1576 MODULE(MODULE_CLASS_EXEC, ptrace_common, "");
1577
1578 static int
1579 ptrace_common_modcmd(modcmd_t cmd, void *arg)
1580 {
1581 int error;
1582
1583 switch (cmd) {
1584 case MODULE_CMD_INIT:
1585 error = ptrace_init();
1586 break;
1587 case MODULE_CMD_FINI:
1588 error = ptrace_fini();
1589 break;
1590 default:
1591 ptrace_hooks();
1592 error = ENOTTY;
1593 break;
1594 }
1595 return error;
1596 }
1597