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