sys_process.c revision 1.54
1/*	$OpenBSD: sys_process.c,v 1.54 2012/04/12 12:09:05 kettenis Exp $	*/
2/*	$NetBSD: sys_process.c,v 1.55 1996/05/15 06:17:47 tls Exp $	*/
3
4/*-
5 * Copyright (c) 1994 Christopher G. Demetriou.  All rights reserved.
6 * Copyright (c) 1982, 1986, 1989, 1993
7 *	The Regents of the University of California.  All rights reserved.
8 * (c) UNIX System Laboratories, Inc.
9 * All or some portions of this file are derived from material licensed
10 * to the University of California by American Telephone and Telegraph
11 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
12 * the permission of UNIX System Laboratories, Inc.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions
16 * are met:
17 * 1. Redistributions of source code must retain the above copyright
18 *    notice, this list of conditions and the following disclaimer.
19 * 2. Redistributions in binary form must reproduce the above copyright
20 *    notice, this list of conditions and the following disclaimer in the
21 *    documentation and/or other materials provided with the distribution.
22 * 3. Neither the name of the University nor the names of its contributors
23 *    may be used to endorse or promote products derived from this software
24 *    without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 *	from: @(#)sys_process.c	8.1 (Berkeley) 6/10/93
39 */
40
41/*
42 * References:
43 *	(1) Bach's "The Design of the UNIX Operating System",
44 *	(2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution,
45 *	(3) the "4.4BSD Programmer's Reference Manual" published
46 *		by USENIX and O'Reilly & Associates.
47 * The 4.4BSD PRM does a reasonably good job of documenting what the various
48 * ptrace() requests should actually do, and its text is quoted several times
49 * in this file.
50 */
51
52#include <sys/param.h>
53#include <sys/systm.h>
54#include <sys/exec.h>
55#include <sys/proc.h>
56#include <sys/signalvar.h>
57#include <sys/errno.h>
58#include <sys/malloc.h>
59#include <sys/ptrace.h>
60#include <sys/uio.h>
61#include <sys/sched.h>
62
63#include <sys/mount.h>
64#include <sys/syscallargs.h>
65
66#include <uvm/uvm_extern.h>
67
68#include <machine/reg.h>
69
70int	process_auxv_offset(struct proc *, struct proc *, struct uio *);
71
72#ifdef PTRACE
73/*
74 * Process debugging system call.
75 */
76int
77sys_ptrace(struct proc *p, void *v, register_t *retval)
78{
79	struct sys_ptrace_args /* {
80		syscallarg(int) req;
81		syscallarg(pid_t) pid;
82		syscallarg(caddr_t) addr;
83		syscallarg(int) data;
84	} */ *uap = v;
85	struct proc *t;				/* target thread */
86	struct process *tr;			/* target process */
87	struct proc *q;
88	struct uio uio;
89	struct iovec iov;
90	struct ptrace_io_desc piod;
91	struct ptrace_event pe;
92	struct ptrace_thread_state pts;
93	struct reg *regs;
94#if defined (PT_SETFPREGS) || defined (PT_GETFPREGS)
95	struct fpreg *fpregs;
96#endif
97#if defined (PT_SETXMMREGS) || defined (PT_GETXMMREGS)
98	struct xmmregs *xmmregs;
99#endif
100#ifdef PT_WCOOKIE
101	register_t wcookie;
102#endif
103	int error, write;
104	int temp;
105	int req = SCARG(uap, req);
106	int s;
107
108	/* "A foolish consistency..." XXX */
109	switch (req) {
110	case PT_TRACE_ME:
111		t = p;
112		break;
113
114	/* calls that only operate on the PID */
115	case PT_READ_I:
116	case PT_READ_D:
117	case PT_WRITE_I:
118	case PT_WRITE_D:
119	case PT_KILL:
120	case PT_ATTACH:
121	case PT_IO:
122	case PT_SET_EVENT_MASK:
123	case PT_GET_EVENT_MASK:
124	case PT_GET_PROCESS_STATE:
125	case PT_GET_THREAD_FIRST:
126	case PT_GET_THREAD_NEXT:
127	default:
128		/* Find the process we're supposed to be operating on. */
129		if ((t = pfind(SCARG(uap, pid))) == NULL)
130			return (ESRCH);
131		if (t->p_flag & P_THREAD)
132			return (ESRCH);
133		break;
134
135	/* calls that accept a PID or a thread ID */
136	case PT_CONTINUE:
137	case PT_DETACH:
138#ifdef PT_STEP
139	case PT_STEP:
140#endif
141	case PT_GETREGS:
142	case PT_SETREGS:
143#ifdef PT_GETFPREGS
144	case PT_GETFPREGS:
145#endif
146#ifdef PT_SETFPREGS
147	case PT_SETFPREGS:
148#endif
149#ifdef PT_GETXMMREGS
150	case PT_GETXMMREGS:
151#endif
152#ifdef PT_SETXMMREGS
153	case PT_SETXMMREGS:
154#endif
155		if (SCARG(uap, pid) > THREAD_PID_OFFSET) {
156			t = pfind(SCARG(uap, pid) - THREAD_PID_OFFSET);
157			if (t == NULL)
158				return (ESRCH);
159		} else {
160			if ((t = pfind(SCARG(uap, pid))) == NULL)
161				return (ESRCH);
162			if (t->p_flag & P_THREAD)
163				return (ESRCH);
164		}
165		break;
166	}
167	tr = t->p_p;
168
169	if ((tr->ps_flags & PS_INEXEC) != 0)
170		return (EAGAIN);
171
172	/* Make sure we can operate on it. */
173	switch (req) {
174	case  PT_TRACE_ME:
175		/* Saying that you're being traced is always legal. */
176		break;
177
178	case  PT_ATTACH:
179		/*
180		 * You can't attach to a process if:
181		 *	(1) it's the process that's doing the attaching,
182		 */
183		if (tr == p->p_p)
184			return (EINVAL);
185
186		/*
187		 *	(2) it's a system process
188		 */
189		if (ISSET(t->p_flag, P_SYSTEM))
190			return (EPERM);
191
192		/*
193		 *	(3) it's already being traced, or
194		 */
195		if (ISSET(tr->ps_flags, PS_TRACED))
196			return (EBUSY);
197
198		/*
199		 *	(4) it's not owned by you, or the last exec
200		 *	    gave us setuid/setgid privs (unless
201		 *	    you're root), or...
202		 *
203		 *      [Note: once PS_SUGID or PS_SUGIDEXEC gets set in
204		 *	execve(), they stay set until the process does
205		 *	another execve().  Hence this prevents a setuid
206		 *	process which revokes its special privileges using
207		 *	setuid() from being traced.  This is good security.]
208		 */
209		if ((tr->ps_cred->p_ruid != p->p_cred->p_ruid ||
210		    ISSET(tr->ps_flags, PS_SUGIDEXEC | PS_SUGID)) &&
211		    (error = suser(p, 0)) != 0)
212			return (error);
213
214		/*
215		 *	(5) ...it's init, which controls the security level
216		 *	    of the entire system, and the system was not
217		 *          compiled with permanently insecure mode turned
218		 *	    on.
219		 */
220		if ((tr->ps_pid == 1) && (securelevel > -1))
221			return (EPERM);
222
223		/*
224		 *	(6) it's an ancestor of the current process and
225		 *	    not init (because that would create a loop in
226		 *	    the process graph).
227		 */
228		if (tr->ps_pid != 1 && inferior(p->p_p, tr))
229			return (EINVAL);
230		break;
231
232	case  PT_READ_I:
233	case  PT_READ_D:
234	case  PT_WRITE_I:
235	case  PT_WRITE_D:
236	case  PT_IO:
237	case  PT_CONTINUE:
238	case  PT_KILL:
239	case  PT_DETACH:
240#ifdef PT_STEP
241	case  PT_STEP:
242#endif
243	case  PT_SET_EVENT_MASK:
244	case  PT_GET_EVENT_MASK:
245	case  PT_GET_PROCESS_STATE:
246	case  PT_GETREGS:
247	case  PT_SETREGS:
248#ifdef PT_GETFPREGS
249	case  PT_GETFPREGS:
250#endif
251#ifdef PT_SETFPREGS
252	case  PT_SETFPREGS:
253#endif
254#ifdef PT_GETXMMREGS
255	case  PT_GETXMMREGS:
256#endif
257#ifdef PT_SETXMMREGS
258	case  PT_SETXMMREGS:
259#endif
260#ifdef PT_WCOOKIE
261	case  PT_WCOOKIE:
262#endif
263		/*
264		 * You can't do what you want to the process if:
265		 *	(1) It's not being traced at all,
266		 */
267		if (!ISSET(tr->ps_flags, PS_TRACED))
268			return (EPERM);
269
270		/*
271		 *	(2) it's not being traced by _you_, or
272		 */
273		if (tr->ps_pptr != p->p_p)
274			return (EBUSY);
275
276		/*
277		 *	(3) it's not currently stopped.
278		 */
279		if (t->p_stat != SSTOP || !ISSET(tr->ps_flags, PS_WAITED))
280			return (EBUSY);
281		break;
282
283	case  PT_GET_THREAD_FIRST:
284	case  PT_GET_THREAD_NEXT:
285		/*
286		 * You can't do what you want to the process if:
287		 *	(1) It's not being traced at all,
288		 */
289		if (!ISSET(tr->ps_flags, PS_TRACED))
290			return (EPERM);
291
292		/*
293		 *	(2) it's not being traced by _you_, or
294		 */
295		if (tr->ps_pptr != p->p_p)
296			return (EBUSY);
297
298		/*
299		 * Do the work here because the request isn't actually
300		 * associated with 't'
301		 */
302		if (SCARG(uap, data) != sizeof(pts))
303			return (EINVAL);
304
305		if (req == PT_GET_THREAD_NEXT) {
306			error = copyin(SCARG(uap, addr), &pts, sizeof(pts));
307			if (error)
308				return (error);
309
310			t = pfind(pts.pts_tid - THREAD_PID_OFFSET);
311			if (t == NULL)
312				return (ESRCH);
313			if (t->p_p != tr)
314				return (EINVAL);
315			t = TAILQ_NEXT(t, p_thr_link);
316		}
317
318		if (t == NULL)
319			pts.pts_tid = -1;
320		else
321			pts.pts_tid = t->p_pid + THREAD_PID_OFFSET;
322		return (copyout(&pts, SCARG(uap, addr), sizeof(pts)));
323
324	default:			/* It was not a legal request. */
325		return (EINVAL);
326	}
327
328	/* Do single-step fixup if needed. */
329	FIX_SSTEP(t);
330
331	/* Now do the operation. */
332	write = 0;
333	*retval = 0;
334
335	switch (req) {
336	case  PT_TRACE_ME:
337		/* Just set the trace flag. */
338		atomic_setbits_int(&tr->ps_flags, PS_TRACED);
339		tr->ps_oppid = tr->ps_pptr->ps_pid;
340		if (tr->ps_ptstat == NULL)
341			tr->ps_ptstat = malloc(sizeof(*tr->ps_ptstat),
342			    M_SUBPROC, M_WAITOK);
343		bzero(tr->ps_ptstat, sizeof(*tr->ps_ptstat));
344		return (0);
345
346	case  PT_WRITE_I:		/* XXX no separate I and D spaces */
347	case  PT_WRITE_D:
348		write = 1;
349		temp = SCARG(uap, data);
350	case  PT_READ_I:		/* XXX no separate I and D spaces */
351	case  PT_READ_D:
352		/* write = 0 done above. */
353		iov.iov_base = (caddr_t)&temp;
354		iov.iov_len = sizeof(int);
355		uio.uio_iov = &iov;
356		uio.uio_iovcnt = 1;
357		uio.uio_offset = (off_t)(vaddr_t)SCARG(uap, addr);
358		uio.uio_resid = sizeof(int);
359		uio.uio_segflg = UIO_SYSSPACE;
360		uio.uio_rw = write ? UIO_WRITE : UIO_READ;
361		uio.uio_procp = p;
362		error = process_domem(p, t, &uio, write ? PT_WRITE_I :
363				PT_READ_I);
364		if (write == 0)
365			*retval = temp;
366		return (error);
367	case  PT_IO:
368		error = copyin(SCARG(uap, addr), &piod, sizeof(piod));
369		if (error)
370			return (error);
371		iov.iov_base = piod.piod_addr;
372		iov.iov_len = piod.piod_len;
373		uio.uio_iov = &iov;
374		uio.uio_iovcnt = 1;
375		uio.uio_offset = (off_t)(vaddr_t)piod.piod_offs;
376		uio.uio_resid = piod.piod_len;
377		uio.uio_segflg = UIO_USERSPACE;
378		uio.uio_procp = p;
379		switch (piod.piod_op) {
380		case PIOD_READ_I:
381			req = PT_READ_I;
382			uio.uio_rw = UIO_READ;
383			break;
384		case PIOD_READ_D:
385			req = PT_READ_D;
386			uio.uio_rw = UIO_READ;
387			break;
388		case PIOD_WRITE_I:
389			req = PT_WRITE_I;
390			uio.uio_rw = UIO_WRITE;
391			break;
392		case PIOD_WRITE_D:
393			req = PT_WRITE_D;
394			uio.uio_rw = UIO_WRITE;
395			break;
396		case PIOD_READ_AUXV:
397			req = PT_READ_D;
398			uio.uio_rw = UIO_READ;
399			temp = t->p_emul->e_arglen * sizeof(char *);
400			if (uio.uio_offset > temp)
401				return (EIO);
402			if (uio.uio_resid > temp - uio.uio_offset)
403				uio.uio_resid = temp - uio.uio_offset;
404			piod.piod_len = iov.iov_len = uio.uio_resid;
405			error = process_auxv_offset(p, t, &uio);
406			if (error)
407				return (error);
408			break;
409		default:
410			return (EINVAL);
411		}
412		error = process_domem(p, t, &uio, req);
413		piod.piod_len -= uio.uio_resid;
414		(void) copyout(&piod, SCARG(uap, addr), sizeof(piod));
415		return (error);
416#ifdef PT_STEP
417	case  PT_STEP:
418		/*
419		 * From the 4.4BSD PRM:
420		 * "Execution continues as in request PT_CONTINUE; however
421		 * as soon as possible after execution of at least one
422		 * instruction, execution stops again. [ ... ]"
423		 */
424#endif
425	case  PT_CONTINUE:
426		/*
427		 * From the 4.4BSD PRM:
428		 * "The data argument is taken as a signal number and the
429		 * child's execution continues at location addr as if it
430		 * incurred that signal.  Normally the signal number will
431		 * be either 0 to indicate that the signal that caused the
432		 * stop should be ignored, or that value fetched out of
433		 * the process's image indicating which signal caused
434		 * the stop.  If addr is (int *)1 then execution continues
435		 * from where it stopped."
436		 */
437
438		/* Check that the data is a valid signal number or zero. */
439		if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG)
440			return (EINVAL);
441
442		/* If the address parameter is not (int *)1, set the pc. */
443		if ((int *)SCARG(uap, addr) != (int *)1)
444			if ((error = process_set_pc(t, SCARG(uap, addr))) != 0)
445				goto relebad;
446
447#ifdef PT_STEP
448		/*
449		 * Arrange for a single-step, if that's requested and possible.
450		 */
451		error = process_sstep(t, req == PT_STEP);
452		if (error)
453			goto relebad;
454#endif
455		goto sendsig;
456
457	case  PT_DETACH:
458		/*
459		 * From the 4.4BSD PRM:
460		 * "The data argument is taken as a signal number and the
461		 * child's execution continues at location addr as if it
462		 * incurred that signal.  Normally the signal number will
463		 * be either 0 to indicate that the signal that caused the
464		 * stop should be ignored, or that value fetched out of
465		 * the process's image indicating which signal caused
466		 * the stop.  If addr is (int *)1 then execution continues
467		 * from where it stopped."
468		 */
469
470		/* Check that the data is a valid signal number or zero. */
471		if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG)
472			return (EINVAL);
473
474#ifdef PT_STEP
475		/*
476		 * Arrange for a single-step, if that's requested and possible.
477		 */
478		error = process_sstep(t, req == PT_STEP);
479		if (error)
480			goto relebad;
481#endif
482
483		/* give process back to original parent or init */
484		if (tr->ps_oppid != tr->ps_pptr->ps_pid) {
485			struct process *ppr;
486
487			ppr = prfind(tr->ps_oppid);
488			proc_reparent(tr, ppr ? ppr : initproc->p_p);
489		}
490
491		/* not being traced any more */
492		tr->ps_oppid = 0;
493		atomic_clearbits_int(&tr->ps_flags, PS_TRACED|PS_WAITED);
494
495	sendsig:
496		bzero(tr->ps_ptstat, sizeof(*tr->ps_ptstat));
497
498		/* Finally, deliver the requested signal (or none). */
499		if (t->p_stat == SSTOP) {
500			t->p_xstat = SCARG(uap, data);
501			SCHED_LOCK(s);
502			setrunnable(t);
503			SCHED_UNLOCK(s);
504		} else {
505			if (SCARG(uap, data) != 0)
506				psignal(t, SCARG(uap, data));
507		}
508		SCHED_LOCK(s);
509		TAILQ_FOREACH(q, &tr->ps_threads, p_thr_link) {
510			if (q != t && q->p_stat == SSTOP) {
511				setrunnable(q);
512			}
513		}
514		SCHED_UNLOCK(s);
515		return (0);
516
517	relebad:
518		return (error);
519
520	case  PT_KILL:
521		/* just send the process a KILL signal. */
522		SCARG(uap, data) = SIGKILL;
523		goto sendsig;	/* in PT_CONTINUE, above. */
524
525	case  PT_ATTACH:
526		/*
527		 * As done in procfs:
528		 * Go ahead and set the trace flag.
529		 * Save the old parent (it's reset in
530		 *   _DETACH, and also in kern_exit.c:wait4()
531		 * Reparent the process so that the tracing
532		 *   proc gets to see all the action.
533		 * Stop the target.
534		 */
535		atomic_setbits_int(&tr->ps_flags, PS_TRACED);
536		tr->ps_oppid = tr->ps_pptr->ps_pid;
537		if (tr->ps_pptr != p->p_p)
538			proc_reparent(tr, p->p_p);
539		if (tr->ps_ptstat == NULL)
540			tr->ps_ptstat = malloc(sizeof(*tr->ps_ptstat),
541			    M_SUBPROC, M_WAITOK);
542		SCARG(uap, data) = SIGSTOP;
543		goto sendsig;
544
545	case  PT_GET_EVENT_MASK:
546		if (SCARG(uap, data) != sizeof(pe))
547			return (EINVAL);
548		bzero(&pe, sizeof(pe));
549		pe.pe_set_event = tr->ps_ptmask;
550		return (copyout(&pe, SCARG(uap, addr), sizeof(pe)));
551	case  PT_SET_EVENT_MASK:
552		if (SCARG(uap, data) != sizeof(pe))
553			return (EINVAL);
554		if ((error = copyin(SCARG(uap, addr), &pe, sizeof(pe))))
555			return (error);
556		tr->ps_ptmask = pe.pe_set_event;
557		return (0);
558
559	case  PT_GET_PROCESS_STATE:
560		if (SCARG(uap, data) != sizeof(*tr->ps_ptstat))
561			return (EINVAL);
562		return (copyout(tr->ps_ptstat, SCARG(uap, addr),
563		    sizeof(*tr->ps_ptstat)));
564
565	case  PT_SETREGS:
566		KASSERT((p->p_flag & P_SYSTEM) == 0);
567		if ((error = process_checkioperm(p, tr)) != 0)
568			return (error);
569
570		regs = malloc(sizeof(*regs), M_TEMP, M_WAITOK);
571		error = copyin(SCARG(uap, addr), regs, sizeof(*regs));
572		if (error == 0) {
573			error = process_write_regs(t, regs);
574		}
575		free(regs, M_TEMP);
576		return (error);
577	case  PT_GETREGS:
578		KASSERT((p->p_flag & P_SYSTEM) == 0);
579		if ((error = process_checkioperm(p, tr)) != 0)
580			return (error);
581
582		regs = malloc(sizeof(*regs), M_TEMP, M_WAITOK);
583		error = process_read_regs(t, regs);
584		if (error == 0)
585			error = copyout(regs,
586			    SCARG(uap, addr), sizeof (*regs));
587		free(regs, M_TEMP);
588		return (error);
589#ifdef PT_SETFPREGS
590	case  PT_SETFPREGS:
591		KASSERT((p->p_flag & P_SYSTEM) == 0);
592		if ((error = process_checkioperm(p, tr)) != 0)
593			return (error);
594
595		fpregs = malloc(sizeof(*fpregs), M_TEMP, M_WAITOK);
596		error = copyin(SCARG(uap, addr), fpregs, sizeof(*fpregs));
597		if (error == 0) {
598			error = process_write_fpregs(t, fpregs);
599		}
600		free(fpregs, M_TEMP);
601		return (error);
602#endif
603#ifdef PT_GETFPREGS
604	case  PT_GETFPREGS:
605		KASSERT((p->p_flag & P_SYSTEM) == 0);
606		if ((error = process_checkioperm(p, tr)) != 0)
607			return (error);
608
609		fpregs = malloc(sizeof(*fpregs), M_TEMP, M_WAITOK);
610		error = process_read_fpregs(t, fpregs);
611		if (error == 0)
612			error = copyout(fpregs,
613			    SCARG(uap, addr), sizeof(*fpregs));
614		free(fpregs, M_TEMP);
615		return (error);
616#endif
617#ifdef PT_SETXMMREGS
618	case  PT_SETXMMREGS:
619		KASSERT((p->p_flag & P_SYSTEM) == 0);
620		if ((error = process_checkioperm(p, tr)) != 0)
621			return (error);
622
623		xmmregs = malloc(sizeof(*xmmregs), M_TEMP, M_WAITOK);
624		error = copyin(SCARG(uap, addr), xmmregs, sizeof(*xmmregs));
625		if (error == 0) {
626			error = process_write_xmmregs(t, xmmregs);
627		}
628		free(xmmregs, M_TEMP);
629		return (error);
630#endif
631#ifdef PT_GETXMMREGS
632	case  PT_GETXMMREGS:
633		KASSERT((p->p_flag & P_SYSTEM) == 0);
634		if ((error = process_checkioperm(p, tr)) != 0)
635			return (error);
636
637		xmmregs = malloc(sizeof(*xmmregs), M_TEMP, M_WAITOK);
638		error = process_read_xmmregs(t, xmmregs);
639		if (error == 0)
640			error = copyout(xmmregs,
641			    SCARG(uap, addr), sizeof(*xmmregs));
642		free(xmmregs, M_TEMP);
643		return (error);
644#endif
645#ifdef PT_WCOOKIE
646	case  PT_WCOOKIE:
647		wcookie = process_get_wcookie (t);
648		return (copyout(&wcookie, SCARG(uap, addr),
649		    sizeof (register_t)));
650#endif
651	}
652
653#ifdef DIAGNOSTIC
654	panic("ptrace: impossible");
655#endif
656	return 0;
657}
658#endif	/* PTRACE */
659
660/*
661 * Check if a process is allowed to fiddle with the memory of another.
662 *
663 * p = tracer
664 * tr = tracee
665 *
666 * 1.  You can't attach to a process not owned by you or one that has raised
667 *     its privileges.
668 * 1a. ...unless you are root.
669 *
670 * 2.  init is always off-limits because it can control the securelevel.
671 * 2a. ...unless securelevel is permanently set to insecure.
672 *
673 * 3.  Processes that are in the process of doing an exec() are always
674 *     off-limits because of the can of worms they are. Just wait a
675 *     second.
676 */
677int
678process_checkioperm(struct proc *p, struct process *tr)
679{
680	int error;
681
682	if ((tr->ps_cred->p_ruid != p->p_cred->p_ruid ||
683	    ISSET(tr->ps_flags, PS_SUGIDEXEC | PS_SUGID)) &&
684	    (error = suser(p, 0)) != 0)
685		return (error);
686
687	if ((tr->ps_pid == 1) && (securelevel > -1))
688		return (EPERM);
689
690	if (tr->ps_flags & PS_INEXEC)
691		return (EAGAIN);
692
693	return (0);
694}
695
696int
697process_domem(struct proc *curp, struct proc *p, struct uio *uio, int req)
698{
699	struct vmspace *vm;
700	int error;
701	vaddr_t addr;
702	vsize_t len;
703
704	len = uio->uio_resid;
705	if (len == 0)
706		return (0);
707
708	if ((error = process_checkioperm(curp, p->p_p)) != 0)
709		return (error);
710
711	/* XXXCDC: how should locking work here? */
712	if ((p->p_p->ps_flags & PS_EXITING) || (p->p_vmspace->vm_refcnt < 1))
713		return(EFAULT);
714	addr = uio->uio_offset;
715
716	vm = p->p_vmspace;
717	vm->vm_refcnt++;
718
719	error = uvm_io(&vm->vm_map, uio,
720	    (req == PT_WRITE_I) ? UVM_IO_FIXPROT : 0);
721
722	uvmspace_free(vm);
723
724	if (error == 0 && req == PT_WRITE_I)
725		pmap_proc_iflush(p, addr, len);
726
727	return (error);
728}
729
730#ifdef PTRACE
731int
732process_auxv_offset(struct proc *curp, struct proc *p, struct uio *uiop)
733{
734	struct ps_strings pss;
735	struct iovec iov;
736	struct uio uio;
737	int error;
738
739	iov.iov_base = &pss;
740	iov.iov_len = sizeof(pss);
741	uio.uio_iov = &iov;
742	uio.uio_iovcnt = 1;
743	uio.uio_offset = (off_t)(vaddr_t)PS_STRINGS;
744	uio.uio_resid = sizeof(pss);
745	uio.uio_segflg = UIO_SYSSPACE;
746	uio.uio_rw = UIO_READ;
747	uio.uio_procp = curp;
748
749	if ((error = uvm_io(&p->p_vmspace->vm_map, &uio, 0)) != 0)
750		return (error);
751
752	if (pss.ps_envstr == NULL)
753		return (EIO);
754
755	uiop->uio_offset += (off_t)(vaddr_t)(pss.ps_envstr + pss.ps_nenvstr + 1);
756#ifdef MACHINE_STACK_GROWS_UP
757	if (uiop->uio_offset < (off_t)(vaddr_t)PS_STRINGS)
758		return (EIO);
759#else
760	if (uiop->uio_offset > (off_t)(vaddr_t)PS_STRINGS)
761		return (EIO);
762	if ((uiop->uio_offset + uiop->uio_resid) > (off_t)(vaddr_t)PS_STRINGS)
763		uiop->uio_resid = (off_t)(vaddr_t)PS_STRINGS - uiop->uio_offset;
764#endif
765
766	return (0);
767}
768#endif
769