xref: /netbsd-src/sys/kern/sys_process.c (revision 5aefcfdc06931dd97e76246d2fe0302f7b3fe094)
1 /*	$NetBSD: sys_process.c,v 1.65 2000/09/24 07:31:28 erh Exp $	*/
2 
3 /*-
4  * Copyright (c) 1994 Christopher G. Demetriou.  All rights reserved.
5  * Copyright (c) 1982, 1986, 1989, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  * (c) UNIX System Laboratories, Inc.
8  * All or some portions of this file are derived from material licensed
9  * to the University of California by American Telephone and Telegraph
10  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
11  * the permission of UNIX System Laboratories, Inc.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. All advertising materials mentioning features or use of this software
22  *    must display the following acknowledgement:
23  *	This product includes software developed by the University of
24  *	California, Berkeley and its contributors.
25  * 4. Neither the name of the University nor the names of its contributors
26  *    may be used to endorse or promote products derived from this software
27  *    without specific prior written permission.
28  *
29  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
30  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
31  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
32  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
33  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
34  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
35  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
36  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
38  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
39  * SUCH DAMAGE.
40  *
41  *	from: @(#)sys_process.c	8.1 (Berkeley) 6/10/93
42  */
43 
44 /*
45  * References:
46  *	(1) Bach's "The Design of the UNIX Operating System",
47  *	(2) sys/miscfs/procfs from UCB's 4.4BSD-Lite distribution,
48  *	(3) the "4.4BSD Programmer's Reference Manual" published
49  *		by USENIX and O'Reilly & Associates.
50  * The 4.4BSD PRM does a reasonably good job of documenting what the various
51  * ptrace() requests should actually do, and its text is quoted several times
52  * in this file.
53  */
54 
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/proc.h>
58 #include <sys/errno.h>
59 #include <sys/ptrace.h>
60 #include <sys/uio.h>
61 #include <sys/user.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 
70 #include <miscfs/procfs/procfs.h>
71 
72 /* Macros to clear/set/test flags. */
73 #define	SET(t, f)	(t) |= (f)
74 #define	CLR(t, f)	(t) &= ~(f)
75 #define	ISSET(t, f)	((t) & (f))
76 
77 /*
78  * Process debugging system call.
79  */
80 int
81 sys_ptrace(p, v, retval)
82 	struct proc *p;
83 	void *v;
84 	register_t *retval;
85 {
86 	struct sys_ptrace_args /* {
87 		syscallarg(int) req;
88 		syscallarg(pid_t) pid;
89 		syscallarg(caddr_t) addr;
90 		syscallarg(int) data;
91 	} */ *uap = v;
92 	struct proc *t;				/* target process */
93 	struct uio uio;
94 	struct iovec iov;
95 	int s, error, write, tmp;
96 
97 	/* "A foolish consistency..." XXX */
98 	if (SCARG(uap, req) == PT_TRACE_ME)
99 		t = p;
100 	else {
101 
102 		/* Find the process we're supposed to be operating on. */
103 		if ((t = pfind(SCARG(uap, pid))) == NULL)
104 			return (ESRCH);
105 	}
106 
107 	/* Make sure we can operate on it. */
108 	switch (SCARG(uap, req)) {
109 	case  PT_TRACE_ME:
110 		/* Saying that you're being traced is always legal. */
111 		break;
112 
113 	case  PT_ATTACH:
114 		/*
115 		 * You can't attach to a process if:
116 		 *	(1) it's the process that's doing the attaching,
117 		 */
118 		if (t->p_pid == p->p_pid)
119 			return (EINVAL);
120 
121 		/*
122 		 *  (2) it's a system process
123 		 */
124 		if (t->p_flag & P_SYSTEM)
125 			return (EPERM);
126 
127 		/*
128 		 *	(3) it's already being traced, or
129 		 */
130 		if (ISSET(t->p_flag, P_TRACED))
131 			return (EBUSY);
132 
133 		/*
134 		 *	(4) it's not owned by you, or is set-id on exec
135 		 *	    (unless you're root), or...
136 		 */
137 		if ((t->p_cred->p_ruid != p->p_cred->p_ruid ||
138 			ISSET(t->p_flag, P_SUGID)) &&
139 		    (error = suser(p->p_ucred, &p->p_acflag)) != 0)
140 			return (error);
141 
142 		/*
143 		 *	(5) ...it's init, which controls the security level
144 		 *	    of the entire system, and the system was not
145 		 *	    compiled with permanently insecure mode turned on
146 		 */
147 		if (t == initproc && securelevel > -1)
148 			return (EPERM);
149 
150 		/*
151 		 * (6) the tracer is chrooted, and its root directory is
152 		 * not at or above the root directory of the tracee
153 		 */
154 
155 		if (!proc_isunder(t, p))
156 			return EPERM;
157 		break;
158 
159 	case  PT_READ_I:
160 	case  PT_READ_D:
161 	case  PT_WRITE_I:
162 	case  PT_WRITE_D:
163 	case  PT_CONTINUE:
164 	case  PT_KILL:
165 	case  PT_DETACH:
166 #ifdef PT_STEP
167 	case  PT_STEP:
168 #endif
169 #ifdef PT_GETREGS
170 	case  PT_GETREGS:
171 #endif
172 #ifdef PT_SETREGS
173 	case  PT_SETREGS:
174 #endif
175 #ifdef PT_GETFPREGS
176 	case  PT_GETFPREGS:
177 #endif
178 #ifdef PT_SETFPREGS
179 	case  PT_SETFPREGS:
180 #endif
181 		/*
182 		 * You can't do what you want to the process if:
183 		 *	(1) It's not being traced at all,
184 		 */
185 		if (!ISSET(t->p_flag, P_TRACED))
186 			return (EPERM);
187 
188 		/*
189 		 *	(2) it's being traced by procfs (which has
190 		 *	    different signal delivery semantics),
191 		 */
192 		if (ISSET(t->p_flag, P_FSTRACE))
193 			return (EBUSY);
194 
195 		/*
196 		 *	(3) it's not being traced by _you_, or
197 		 */
198 		if (t->p_pptr != p)
199 			return (EBUSY);
200 
201 		/*
202 		 *	(4) it's not currently stopped.
203 		 */
204 		if (t->p_stat != SSTOP || !ISSET(t->p_flag, P_WAITED))
205 			return (EBUSY);
206 		break;
207 
208 	default:			/* It was not a legal request. */
209 		return (EINVAL);
210 	}
211 
212 	/* Do single-step fixup if needed. */
213 	FIX_SSTEP(t);
214 
215 	/* Now do the operation. */
216 	write = 0;
217 	*retval = 0;
218 	tmp = 0;
219 
220 	switch (SCARG(uap, req)) {
221 	case  PT_TRACE_ME:
222 		/* Just set the trace flag. */
223 		SET(t->p_flag, P_TRACED);
224 		t->p_oppid = t->p_pptr->p_pid;
225 		return (0);
226 
227 	case  PT_WRITE_I:		/* XXX no seperate I and D spaces */
228 	case  PT_WRITE_D:
229 		write = 1;
230 		tmp = SCARG(uap, data);
231 	case  PT_READ_I:		/* XXX no seperate I and D spaces */
232 	case  PT_READ_D:
233 		/* write = 0 done above. */
234 		iov.iov_base = (caddr_t)&tmp;
235 		iov.iov_len = sizeof(tmp);
236 		uio.uio_iov = &iov;
237 		uio.uio_iovcnt = 1;
238 		uio.uio_offset = (off_t)(long)SCARG(uap, addr);
239 		uio.uio_resid = sizeof(tmp);
240 		uio.uio_segflg = UIO_SYSSPACE;
241 		uio.uio_rw = write ? UIO_WRITE : UIO_READ;
242 		uio.uio_procp = p;
243 		error = procfs_domem(p, t, NULL, &uio);
244 		if (!write)
245 			*retval = tmp;
246 		return (error);
247 
248 #ifdef PT_STEP
249 	case  PT_STEP:
250 		/*
251 		 * From the 4.4BSD PRM:
252 		 * "Execution continues as in request PT_CONTINUE; however
253 		 * as soon as possible after execution of at least one
254 		 * instruction, execution stops again. [ ... ]"
255 		 */
256 #endif
257 	case  PT_CONTINUE:
258 	case  PT_DETACH:
259 		/*
260 		 * From the 4.4BSD PRM:
261 		 * "The data argument is taken as a signal number and the
262 		 * child's execution continues at location addr as if it
263 		 * incurred that signal.  Normally the signal number will
264 		 * be either 0 to indicate that the signal that caused the
265 		 * stop should be ignored, or that value fetched out of
266 		 * the process's image indicating which signal caused
267 		 * the stop.  If addr is (int *)1 then execution continues
268 		 * from where it stopped."
269 		 */
270 
271 		/* Check that the data is a valid signal number or zero. */
272 		if (SCARG(uap, data) < 0 || SCARG(uap, data) >= NSIG)
273 			return (EINVAL);
274 
275 		PHOLD(t);
276 
277 #ifdef PT_STEP
278 		/*
279 		 * Arrange for a single-step, if that's requested and possible.
280 		 */
281 		error = process_sstep(t, SCARG(uap, req) == PT_STEP);
282 		if (error)
283 			goto relebad;
284 #endif
285 
286 		/* If the address paramter is not (int *)1, set the pc. */
287 		if ((int *)SCARG(uap, addr) != (int *)1)
288 			if ((error = process_set_pc(t, SCARG(uap, addr))) != 0)
289 				goto relebad;
290 
291 		PRELE(t);
292 
293 		if (SCARG(uap, req) == PT_DETACH) {
294 			/* give process back to original parent or init */
295 			if (t->p_oppid != t->p_pptr->p_pid) {
296 				struct proc *pp;
297 
298 				pp = pfind(t->p_oppid);
299 				proc_reparent(t, pp ? pp : initproc);
300 			}
301 
302 			/* not being traced any more */
303 			t->p_oppid = 0;
304 			CLR(t->p_flag, P_TRACED|P_WAITED);
305 		}
306 
307 	sendsig:
308 		/* Finally, deliver the requested signal (or none). */
309 		if (t->p_stat == SSTOP) {
310 			t->p_xstat = SCARG(uap, data);
311 			SCHED_LOCK(s);
312 			setrunnable(t);
313 			SCHED_UNLOCK(s);
314 		} else {
315 			if (SCARG(uap, data) != 0)
316 				psignal(t, SCARG(uap, data));
317 		}
318 		return (0);
319 
320 	relebad:
321 		PRELE(t);
322 		return (error);
323 
324 	case  PT_KILL:
325 		/* just send the process a KILL signal. */
326 		SCARG(uap, data) = SIGKILL;
327 		goto sendsig;	/* in PT_CONTINUE, above. */
328 
329 	case  PT_ATTACH:
330 		/*
331 		 * Go ahead and set the trace flag.
332 		 * Save the old parent (it's reset in
333 		 *   _DETACH, and also in kern_exit.c:wait4()
334 		 * Reparent the process so that the tracing
335 		 *   proc gets to see all the action.
336 		 * Stop the target.
337 		 */
338 		SET(t->p_flag, P_TRACED);
339 		t->p_oppid = t->p_pptr->p_pid;
340 		if (t->p_pptr != p)
341 			proc_reparent(t, p);
342 		SCARG(uap, data) = SIGSTOP;
343 		goto sendsig;
344 
345 #ifdef PT_SETREGS
346 	case  PT_SETREGS:
347 		write = 1;
348 #endif
349 #ifdef PT_GETREGS
350 	case  PT_GETREGS:
351 		/* write = 0 done above. */
352 #endif
353 #if defined(PT_SETREGS) || defined(PT_GETREGS)
354 		if (!procfs_validregs(t))
355 			return (EINVAL);
356 		else {
357 			iov.iov_base = SCARG(uap, addr);
358 			iov.iov_len = sizeof(struct reg);
359 			uio.uio_iov = &iov;
360 			uio.uio_iovcnt = 1;
361 			uio.uio_offset = 0;
362 			uio.uio_resid = sizeof(struct reg);
363 			uio.uio_segflg = UIO_USERSPACE;
364 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
365 			uio.uio_procp = p;
366 			return (procfs_doregs(p, t, NULL, &uio));
367 		}
368 #endif
369 
370 #ifdef PT_SETFPREGS
371 	case  PT_SETFPREGS:
372 		write = 1;
373 #endif
374 #ifdef PT_GETFPREGS
375 	case  PT_GETFPREGS:
376 		/* write = 0 done above. */
377 #endif
378 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
379 		if (!procfs_validfpregs(t))
380 			return (EINVAL);
381 		else {
382 			iov.iov_base = SCARG(uap, addr);
383 			iov.iov_len = sizeof(struct fpreg);
384 			uio.uio_iov = &iov;
385 			uio.uio_iovcnt = 1;
386 			uio.uio_offset = 0;
387 			uio.uio_resid = sizeof(struct fpreg);
388 			uio.uio_segflg = UIO_USERSPACE;
389 			uio.uio_rw = write ? UIO_WRITE : UIO_READ;
390 			uio.uio_procp = p;
391 			return (procfs_dofpregs(p, t, NULL, &uio));
392 		}
393 #endif
394 	}
395 
396 #ifdef DIAGNOSTIC
397 	panic("ptrace: impossible");
398 #endif
399 	return 0;
400 }
401 
402 int
403 trace_req(a1)
404 	struct proc *a1;
405 {
406 
407 	/* just return 1 to keep other parts of the system happy */
408 	return (1);
409 }
410