1 /* $NetBSD: sys_process.c,v 1.143.4.1 2009/02/06 01:54:09 snj 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_process.c,v 1.143.4.1 2009/02/06 01:54:09 snj Exp $");
122
123 #include "opt_coredump.h"
124 #include "opt_ptrace.h"
125 #include "opt_ktrace.h"
126
127 #include <sys/param.h>
128 #include <sys/systm.h>
129 #include <sys/proc.h>
130 #include <sys/errno.h>
131 #include <sys/ptrace.h>
132 #include <sys/uio.h>
133 #include <sys/user.h>
134 #include <sys/ras.h>
135 #include <sys/malloc.h>
136 #include <sys/kauth.h>
137 #include <sys/mount.h>
138 #include <sys/syscallargs.h>
139
140 #include <uvm/uvm_extern.h>
141
142 #include <machine/reg.h>
143
144 #ifdef PTRACE
145 /*
146 * Process debugging system call.
147 */
148 int
149 sys_ptrace(struct lwp *l, const struct sys_ptrace_args *uap, register_t *retval)
150 {
151 /* {
152 syscallarg(int) req;
153 syscallarg(pid_t) pid;
154 syscallarg(void *) addr;
155 syscallarg(int) data;
156 } */
157 struct proc *p = l->l_proc;
158 struct lwp *lt;
159 struct proc *t; /* target process */
160 struct uio uio;
161 struct iovec iov;
162 struct ptrace_io_desc piod;
163 struct ptrace_lwpinfo pl;
164 struct vmspace *vm;
165 int error, write, tmp, req, pheld;
166 int signo;
167 ksiginfo_t ksi;
168 #ifdef COREDUMP
169 char *path;
170 #endif
171
172 error = 0;
173 req = SCARG(uap, req);
174
175 /*
176 * If attaching or detaching, we need to get a write hold on the
177 * proclist lock so that we can re-parent the target process.
178 */
179 mutex_enter(proc_lock);
180
181 /* "A foolish consistency..." XXX */
182 if (req == PT_TRACE_ME) {
183 t = p;
184 mutex_enter(t->p_lock);
185 } else {
186 /* Find the process we're supposed to be operating on. */
187 if ((t = p_find(SCARG(uap, pid), PFIND_LOCKED)) == NULL) {
188 mutex_exit(proc_lock);
189 return (ESRCH);
190 }
191
192 /* XXX-elad */
193 mutex_enter(t->p_lock);
194 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
195 t, KAUTH_ARG(KAUTH_REQ_PROCESS_CANSEE_ENTRY), NULL, NULL);
196 if (error) {
197 mutex_exit(proc_lock);
198 mutex_exit(t->p_lock);
199 return (ESRCH);
200 }
201 }
202
203 /*
204 * Grab a reference on the process to prevent it from execing or
205 * exiting.
206 */
207 if (!rw_tryenter(&t->p_reflock, RW_READER)) {
208 mutex_exit(proc_lock);
209 mutex_exit(t->p_lock);
210 return EBUSY;
211 }
212
213 /* Make sure we can operate on it. */
214 switch (req) {
215 case PT_TRACE_ME:
216 /* Saying that you're being traced is always legal. */
217 break;
218
219 case PT_ATTACH:
220 /*
221 * You can't attach to a process if:
222 * (1) it's the process that's doing the attaching,
223 */
224 if (t->p_pid == p->p_pid) {
225 error = EINVAL;
226 break;
227 }
228
229 /*
230 * (2) it's a system process
231 */
232 if (t->p_flag & PK_SYSTEM) {
233 error = EPERM;
234 break;
235 }
236
237 /*
238 * (3) it's already being traced, or
239 */
240 if (ISSET(t->p_slflag, PSL_TRACED)) {
241 error = EBUSY;
242 break;
243 }
244
245 /*
246 * (4) the tracer is chrooted, and its root directory is
247 * not at or above the root directory of the tracee
248 */
249 mutex_exit(t->p_lock); /* XXXSMP */
250 tmp = proc_isunder(t, l);
251 mutex_enter(t->p_lock); /* XXXSMP */
252 if (!tmp) {
253 error = EPERM;
254 break;
255 }
256 break;
257
258 case PT_READ_I:
259 case PT_READ_D:
260 case PT_WRITE_I:
261 case PT_WRITE_D:
262 case PT_IO:
263 #ifdef PT_GETREGS
264 case PT_GETREGS:
265 #endif
266 #ifdef PT_SETREGS
267 case PT_SETREGS:
268 #endif
269 #ifdef PT_GETFPREGS
270 case PT_GETFPREGS:
271 #endif
272 #ifdef PT_SETFPREGS
273 case PT_SETFPREGS:
274 #endif
275 #ifdef __HAVE_PTRACE_MACHDEP
276 PTRACE_MACHDEP_REQUEST_CASES
277 #endif
278 /*
279 * You can't read/write the memory or registers of a process
280 * if the tracer is chrooted, and its root directory is not at
281 * or above the root directory of the tracee.
282 */
283 mutex_exit(t->p_lock); /* XXXSMP */
284 tmp = proc_isunder(t, l);
285 mutex_enter(t->p_lock); /* XXXSMP */
286 if (!tmp) {
287 error = EPERM;
288 break;
289 }
290 /*FALLTHROUGH*/
291
292 case PT_CONTINUE:
293 case PT_KILL:
294 case PT_DETACH:
295 case PT_LWPINFO:
296 case PT_SYSCALL:
297 #ifdef COREDUMP
298 case PT_DUMPCORE:
299 #endif
300 #ifdef PT_STEP
301 case PT_STEP:
302 #endif
303 /*
304 * You can't do what you want to the process if:
305 * (1) It's not being traced at all,
306 */
307 if (!ISSET(t->p_slflag, PSL_TRACED)) {
308 error = EPERM;
309 break;
310 }
311
312 /*
313 * (2) it's being traced by procfs (which has
314 * different signal delivery semantics),
315 */
316 if (ISSET(t->p_slflag, PSL_FSTRACE)) {
317 uprintf("file system traced\n");
318 error = EBUSY;
319 break;
320 }
321
322 /*
323 * (3) it's not being traced by _you_, or
324 */
325 if (t->p_pptr != p) {
326 uprintf("parent %d != %d\n", t->p_pptr->p_pid, p->p_pid);
327 error = EBUSY;
328 break;
329 }
330
331 /*
332 * (4) it's not currently stopped.
333 */
334 if (t->p_stat != SSTOP || !t->p_waited /* XXXSMP */) {
335 uprintf("stat %d flag %d\n", t->p_stat,
336 !t->p_waited);
337 error = EBUSY;
338 break;
339 }
340 break;
341
342 default: /* It was not a legal request. */
343 error = EINVAL;
344 break;
345 }
346
347 if (error == 0) {
348 error = kauth_authorize_process(l->l_cred,
349 KAUTH_PROCESS_PTRACE, t, KAUTH_ARG(req),
350 NULL, NULL);
351 }
352 if (error == 0) {
353 lt = lwp_find_first(t);
354 if (lt == NULL)
355 error = ESRCH;
356 }
357
358 if (error != 0) {
359 mutex_exit(proc_lock);
360 mutex_exit(t->p_lock);
361 rw_exit(&t->p_reflock);
362 return error;
363 }
364
365 /* Do single-step fixup if needed. */
366 FIX_SSTEP(t);
367 KASSERT(lt != NULL);
368 lwp_addref(lt);
369
370 /*
371 * Which locks do we need held? XXX Ugly.
372 */
373 switch (req) {
374 #ifdef PT_STEP
375 case PT_STEP:
376 #endif
377 case PT_CONTINUE:
378 case PT_DETACH:
379 case PT_KILL:
380 case PT_SYSCALL:
381 case PT_ATTACH:
382 case PT_TRACE_ME:
383 pheld = 1;
384 break;
385 default:
386 mutex_exit(proc_lock);
387 mutex_exit(t->p_lock);
388 pheld = 0;
389 break;
390 }
391
392 /* Now do the operation. */
393 write = 0;
394 *retval = 0;
395 tmp = 0;
396
397 switch (req) {
398 case PT_TRACE_ME:
399 /* Just set the trace flag. */
400 SET(t->p_slflag, PSL_TRACED);
401 t->p_opptr = t->p_pptr;
402 break;
403
404 case PT_WRITE_I: /* XXX no separate I and D spaces */
405 case PT_WRITE_D:
406 #if defined(__HAVE_RAS)
407 /*
408 * Can't write to a RAS
409 */
410 if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) {
411 error = EACCES;
412 break;
413 }
414 #endif
415 write = 1;
416 tmp = SCARG(uap, data);
417 /* FALLTHROUGH */
418
419 case PT_READ_I: /* XXX no separate I and D spaces */
420 case PT_READ_D:
421 /* write = 0 done above. */
422 iov.iov_base = (void *)&tmp;
423 iov.iov_len = sizeof(tmp);
424 uio.uio_iov = &iov;
425 uio.uio_iovcnt = 1;
426 uio.uio_offset = (off_t)(unsigned long)SCARG(uap, addr);
427 uio.uio_resid = sizeof(tmp);
428 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
429 UIO_SETUP_SYSSPACE(&uio);
430
431 error = process_domem(l, lt, &uio);
432 if (!write)
433 *retval = tmp;
434 break;
435
436 case PT_IO:
437 error = copyin(SCARG(uap, addr), &piod, sizeof(piod));
438 if (error)
439 break;
440 switch (piod.piod_op) {
441 case PIOD_READ_D:
442 case PIOD_READ_I:
443 uio.uio_rw = UIO_READ;
444 break;
445 case PIOD_WRITE_D:
446 case PIOD_WRITE_I:
447 /*
448 * Can't write to a RAS
449 */
450 if (ras_lookup(t, SCARG(uap, addr)) != (void *)-1) {
451 return (EACCES);
452 }
453 uio.uio_rw = UIO_WRITE;
454 break;
455 default:
456 error = EINVAL;
457 break;
458 }
459 if (error)
460 break;
461 error = proc_vmspace_getref(l->l_proc, &vm);
462 if (error)
463 break;
464 iov.iov_base = piod.piod_addr;
465 iov.iov_len = piod.piod_len;
466 uio.uio_iov = &iov;
467 uio.uio_iovcnt = 1;
468 uio.uio_offset = (off_t)(unsigned long)piod.piod_offs;
469 uio.uio_resid = piod.piod_len;
470 uio.uio_vmspace = vm;
471
472 error = process_domem(l, lt, &uio);
473 piod.piod_len -= uio.uio_resid;
474 (void) copyout(&piod, SCARG(uap, addr), sizeof(piod));
475 uvmspace_free(vm);
476 break;
477
478 #ifdef COREDUMP
479 case PT_DUMPCORE:
480 if ((path = SCARG(uap, addr)) != NULL) {
481 char *dst;
482 int len = SCARG(uap, data);
483 if (len < 0 || len >= MAXPATHLEN) {
484 error = EINVAL;
485 break;
486 }
487 dst = malloc(len + 1, M_TEMP, M_WAITOK);
488 if ((error = copyin(path, dst, len)) != 0) {
489 free(dst, M_TEMP);
490 break;
491 }
492 path = dst;
493 path[len] = '\0';
494 }
495 error = coredump(lt, path);
496 if (path)
497 free(path, M_TEMP);
498 break;
499 #endif
500
501 #ifdef PT_STEP
502 case PT_STEP:
503 /*
504 * From the 4.4BSD PRM:
505 * "Execution continues as in request PT_CONTINUE; however
506 * as soon as possible after execution of at least one
507 * instruction, execution stops again. [ ... ]"
508 */
509 #endif
510 case PT_CONTINUE:
511 case PT_SYSCALL:
512 case PT_DETACH:
513 if (req == PT_SYSCALL) {
514 if (!ISSET(t->p_slflag, PSL_SYSCALL)) {
515 SET(t->p_slflag, PSL_SYSCALL);
516 #ifdef __HAVE_SYSCALL_INTERN
517 (*t->p_emul->e_syscall_intern)(t);
518 #endif
519 }
520 } else {
521 if (ISSET(t->p_slflag, PSL_SYSCALL)) {
522 CLR(t->p_slflag, PSL_SYSCALL);
523 #ifdef __HAVE_SYSCALL_INTERN
524 (*t->p_emul->e_syscall_intern)(t);
525 #endif
526 }
527 }
528 p->p_trace_enabled = trace_is_enabled(p);
529
530 /*
531 * From the 4.4BSD PRM:
532 * "The data argument is taken as a signal number and the
533 * child's execution continues at location addr as if it
534 * incurred that signal. Normally the signal number will
535 * be either 0 to indicate that the signal that caused the
536 * stop should be ignored, or that value fetched out of
537 * the process's image indicating which signal caused
538 * the stop. If addr is (int *)1 then execution continues
539 * from where it stopped."
540 */
541
542 /* Check that the data is a valid signal number or zero. */
543 if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG) {
544 error = EINVAL;
545 break;
546 }
547
548 uvm_lwp_hold(lt);
549
550 /* If the address parameter is not (int *)1, set the pc. */
551 if ((int *)SCARG(uap, addr) != (int *)1)
552 if ((error = process_set_pc(lt, SCARG(uap, addr))) != 0) {
553 uvm_lwp_rele(lt);
554 break;
555 }
556
557 #ifdef PT_STEP
558 /*
559 * Arrange for a single-step, if that's requested and possible.
560 */
561 error = process_sstep(lt, req == PT_STEP);
562 if (error) {
563 uvm_lwp_rele(lt);
564 break;
565 }
566 #endif
567
568 uvm_lwp_rele(lt);
569
570 if (req == PT_DETACH) {
571 CLR(t->p_slflag, PSL_TRACED|PSL_FSTRACE|PSL_SYSCALL);
572
573 /* give process back to original parent or init */
574 if (t->p_opptr != t->p_pptr) {
575 struct proc *pp = t->p_opptr;
576 proc_reparent(t, pp ? pp : initproc);
577 }
578
579 /* not being traced any more */
580 t->p_opptr = NULL;
581 }
582
583 signo = SCARG(uap, data);
584 sendsig:
585 /* Finally, deliver the requested signal (or none). */
586 if (t->p_stat == SSTOP) {
587 /*
588 * Unstop the process. If it needs to take a
589 * signal, make all efforts to ensure that at
590 * an LWP runs to see it.
591 */
592 t->p_xstat = signo;
593 proc_unstop(t);
594 } else if (signo != 0) {
595 KSI_INIT_EMPTY(&ksi);
596 ksi.ksi_signo = signo;
597 kpsignal2(t, &ksi);
598 }
599 break;
600
601 case PT_KILL:
602 /* just send the process a KILL signal. */
603 signo = SIGKILL;
604 goto sendsig; /* in PT_CONTINUE, above. */
605
606 case PT_ATTACH:
607 /*
608 * Go ahead and set the trace flag.
609 * Save the old parent (it's reset in
610 * _DETACH, and also in kern_exit.c:wait4()
611 * Reparent the process so that the tracing
612 * proc gets to see all the action.
613 * Stop the target.
614 */
615 t->p_opptr = t->p_pptr;
616 if (t->p_pptr != p) {
617 struct proc *parent = t->p_pptr;
618
619 if (parent->p_lock < t->p_lock) {
620 if (!mutex_tryenter(parent->p_lock)) {
621 mutex_exit(t->p_lock);
622 mutex_enter(parent->p_lock);
623 }
624 } else if (parent->p_lock > t->p_lock) {
625 mutex_enter(parent->p_lock);
626 }
627 parent->p_slflag |= PSL_CHTRACED;
628 proc_reparent(t, p);
629 if (parent->p_lock != t->p_lock)
630 mutex_exit(parent->p_lock);
631 }
632 SET(t->p_slflag, PSL_TRACED);
633 signo = SIGSTOP;
634 goto sendsig;
635
636 case PT_LWPINFO:
637 if (SCARG(uap, data) != sizeof(pl)) {
638 error = EINVAL;
639 break;
640 }
641 error = copyin(SCARG(uap, addr), &pl, sizeof(pl));
642 if (error)
643 break;
644 tmp = pl.pl_lwpid;
645 lwp_delref(lt);
646 mutex_enter(t->p_lock);
647 if (tmp == 0)
648 lt = lwp_find_first(t);
649 else {
650 lt = lwp_find(t, tmp);
651 if (lt == NULL) {
652 mutex_exit(t->p_lock);
653 error = ESRCH;
654 break;
655 }
656 lt = LIST_NEXT(lt, l_sibling);
657 }
658 while (lt != NULL && !lwp_alive(lt))
659 lt = LIST_NEXT(lt, l_sibling);
660 pl.pl_lwpid = 0;
661 pl.pl_event = 0;
662 if (lt) {
663 lwp_addref(lt);
664 pl.pl_lwpid = lt->l_lid;
665 if (lt->l_lid == t->p_sigctx.ps_lwp)
666 pl.pl_event = PL_EVENT_SIGNAL;
667 }
668 mutex_exit(t->p_lock);
669
670 error = copyout(&pl, SCARG(uap, addr), sizeof(pl));
671 break;
672
673 #ifdef PT_SETREGS
674 case PT_SETREGS:
675 write = 1;
676 #endif
677 #ifdef PT_GETREGS
678 case PT_GETREGS:
679 /* write = 0 done above. */
680 #endif
681 #if defined(PT_SETREGS) || defined(PT_GETREGS)
682 tmp = SCARG(uap, data);
683 if (tmp != 0 && t->p_nlwps > 1) {
684 lwp_delref(lt);
685 mutex_enter(t->p_lock);
686 lt = lwp_find(t, tmp);
687 if (lt == NULL) {
688 mutex_exit(t->p_lock);
689 error = ESRCH;
690 break;
691 }
692 lwp_addref(lt);
693 mutex_exit(t->p_lock);
694 }
695 if (!process_validregs(lt))
696 error = EINVAL;
697 else {
698 error = proc_vmspace_getref(l->l_proc, &vm);
699 if (error)
700 break;
701 iov.iov_base = SCARG(uap, addr);
702 iov.iov_len = sizeof(struct reg);
703 uio.uio_iov = &iov;
704 uio.uio_iovcnt = 1;
705 uio.uio_offset = 0;
706 uio.uio_resid = sizeof(struct reg);
707 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
708 uio.uio_vmspace = vm;
709
710 error = process_doregs(l, lt, &uio);
711 uvmspace_free(vm);
712 }
713 break;
714 #endif
715
716 #ifdef PT_SETFPREGS
717 case PT_SETFPREGS:
718 write = 1;
719 #endif
720 #ifdef PT_GETFPREGS
721 case PT_GETFPREGS:
722 /* write = 0 done above. */
723 #endif
724 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
725 tmp = SCARG(uap, data);
726 if (tmp != 0 && t->p_nlwps > 1) {
727 lwp_delref(lt);
728 mutex_enter(t->p_lock);
729 lt = lwp_find(t, tmp);
730 if (lt == NULL) {
731 mutex_exit(t->p_lock);
732 error = ESRCH;
733 break;
734 }
735 lwp_addref(lt);
736 mutex_exit(t->p_lock);
737 }
738 if (!process_validfpregs(lt))
739 error = EINVAL;
740 else {
741 error = proc_vmspace_getref(l->l_proc, &vm);
742 if (error)
743 break;
744 iov.iov_base = SCARG(uap, addr);
745 iov.iov_len = sizeof(struct fpreg);
746 uio.uio_iov = &iov;
747 uio.uio_iovcnt = 1;
748 uio.uio_offset = 0;
749 uio.uio_resid = sizeof(struct fpreg);
750 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
751 uio.uio_vmspace = vm;
752
753 error = process_dofpregs(l, lt, &uio);
754 uvmspace_free(vm);
755 }
756 break;
757 #endif
758
759 #ifdef __HAVE_PTRACE_MACHDEP
760 PTRACE_MACHDEP_REQUEST_CASES
761 error = ptrace_machdep_dorequest(l, lt,
762 req, SCARG(uap, addr), SCARG(uap, data));
763 break;
764 #endif
765 }
766
767 if (pheld) {
768 mutex_exit(t->p_lock);
769 mutex_exit(proc_lock);
770 }
771 if (lt != NULL)
772 lwp_delref(lt);
773 rw_exit(&t->p_reflock);
774
775 return error;
776 }
777
778 int
779 process_doregs(struct lwp *curl /*tracer*/,
780 struct lwp *l /*traced*/,
781 struct uio *uio)
782 {
783 #if defined(PT_GETREGS) || defined(PT_SETREGS)
784 int error;
785 struct reg r;
786 char *kv;
787 int kl;
788
789 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
790 return EINVAL;
791
792 kl = sizeof(r);
793 kv = (char *)&r;
794
795 kv += uio->uio_offset;
796 kl -= uio->uio_offset;
797 if ((size_t)kl > uio->uio_resid)
798 kl = uio->uio_resid;
799
800 uvm_lwp_hold(l);
801
802 error = process_read_regs(l, &r);
803 if (error == 0)
804 error = uiomove(kv, kl, uio);
805 if (error == 0 && uio->uio_rw == UIO_WRITE) {
806 if (l->l_stat != LSSTOP)
807 error = EBUSY;
808 else
809 error = process_write_regs(l, &r);
810 }
811
812 uvm_lwp_rele(l);
813
814 uio->uio_offset = 0;
815 return (error);
816 #else
817 return (EINVAL);
818 #endif
819 }
820
821 int
822 process_validregs(struct lwp *l)
823 {
824
825 #if defined(PT_SETREGS) || defined(PT_GETREGS)
826 return ((l->l_flag & LW_SYSTEM) == 0);
827 #else
828 return (0);
829 #endif
830 }
831
832 int
833 process_dofpregs(struct lwp *curl /*tracer*/,
834 struct lwp *l /*traced*/,
835 struct uio *uio)
836 {
837 #if defined(PT_GETFPREGS) || defined(PT_SETFPREGS)
838 int error;
839 struct fpreg r;
840 char *kv;
841 int kl;
842
843 if (uio->uio_offset < 0 || uio->uio_offset > (off_t)sizeof(r))
844 return EINVAL;
845
846 kl = sizeof(r);
847 kv = (char *)&r;
848
849 kv += uio->uio_offset;
850 kl -= uio->uio_offset;
851 if ((size_t)kl > uio->uio_resid)
852 kl = uio->uio_resid;
853
854 uvm_lwp_hold(l);
855
856 error = process_read_fpregs(l, &r);
857 if (error == 0)
858 error = uiomove(kv, kl, uio);
859 if (error == 0 && uio->uio_rw == UIO_WRITE) {
860 if (l->l_stat != LSSTOP)
861 error = EBUSY;
862 else
863 error = process_write_fpregs(l, &r);
864 }
865
866 uvm_lwp_rele(l);
867
868 uio->uio_offset = 0;
869 return (error);
870 #else
871 return (EINVAL);
872 #endif
873 }
874
875 int
876 process_validfpregs(struct lwp *l)
877 {
878
879 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
880 return ((l->l_flag & LW_SYSTEM) == 0);
881 #else
882 return (0);
883 #endif
884 }
885 #endif /* PTRACE */
886
887 #if defined(KTRACE) || defined(PTRACE)
888 int
889 process_domem(struct lwp *curl /*tracer*/,
890 struct lwp *l /*traced*/,
891 struct uio *uio)
892 {
893 struct proc *p = l->l_proc; /* traced */
894 struct vmspace *vm;
895 int error;
896
897 size_t len;
898 #ifdef PMAP_NEED_PROCWR
899 vaddr_t addr;
900 #endif
901
902 error = 0;
903 len = uio->uio_resid;
904
905 if (len == 0)
906 return (0);
907
908 #ifdef PMAP_NEED_PROCWR
909 addr = uio->uio_offset;
910 #endif
911
912 vm = p->p_vmspace;
913
914 mutex_enter(&vm->vm_map.misc_lock);
915 if ((l->l_flag & LW_WEXIT) || vm->vm_refcnt < 1)
916 error = EFAULT;
917 if (error == 0)
918 p->p_vmspace->vm_refcnt++; /* XXX */
919 mutex_exit(&vm->vm_map.misc_lock);
920 if (error != 0)
921 return (error);
922 error = uvm_io(&vm->vm_map, uio);
923 uvmspace_free(vm);
924
925 #ifdef PMAP_NEED_PROCWR
926 if (error == 0 && uio->uio_rw == UIO_WRITE)
927 pmap_procwr(p, addr, len);
928 #endif
929 return (error);
930 }
931 #endif /* KTRACE || PTRACE */
932
933 #if defined(KTRACE) || defined(PTRACE)
934 void
935 process_stoptrace(void)
936 {
937 struct lwp *l = curlwp;
938 struct proc *p = l->l_proc, *pp;
939
940 mutex_enter(proc_lock);
941 mutex_enter(p->p_lock);
942 pp = p->p_pptr;
943 if (pp->p_pid == 1) {
944 CLR(p->p_slflag, PSL_SYSCALL); /* XXXSMP */
945 mutex_exit(p->p_lock);
946 mutex_exit(proc_lock);
947 return;
948 }
949
950 p->p_xstat = SIGTRAP;
951 proc_stop(p, 1, SIGSTOP);
952 mutex_exit(proc_lock);
953
954 /*
955 * Call issignal() once only, to have it take care of the
956 * pending stop. Signal processing will take place as usual
957 * from userret().
958 */
959 KERNEL_UNLOCK_ALL(l, &l->l_biglocks);
960 (void)issignal(l);
961 mutex_exit(p->p_lock);
962 KERNEL_LOCK(l->l_biglocks, l);
963 }
964 #endif /* KTRACE || PTRACE */
Cache object: 5b2b9829753f61a10643e604bfc43221
|