1 /*
2 * Copyright (c) 1994, Sean Eric Fagan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Sean Eric Fagan.
16 * 4. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 *
31 * $FreeBSD$
32 */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/sysproto.h>
37 #include <sys/proc.h>
38 #include <sys/vnode.h>
39 #include <sys/ptrace.h>
40
41 #include <machine/reg.h>
42 #include <vm/vm.h>
43 #include <vm/vm_prot.h>
44 #include <sys/lock.h>
45 #include <vm/pmap.h>
46 #include <vm/vm_map.h>
47 #include <vm/vm_page.h>
48 #include <vm/vm_extern.h>
49
50 #include <sys/user.h>
51 #include <miscfs/procfs/procfs.h>
52
53 /* use the equivalent procfs code */
54 #if 0
55 static int
56 pread (struct proc *procp, unsigned int addr, unsigned int *retval) {
57 int rv;
58 vm_map_t map, tmap;
59 vm_object_t object;
60 vm_offset_t kva = 0;
61 int page_offset; /* offset into page */
62 vm_offset_t pageno; /* page number */
63 vm_map_entry_t out_entry;
64 vm_prot_t out_prot;
65 boolean_t wired;
66 vm_pindex_t pindex;
67
68 /* Map page into kernel space */
69
70 map = &procp->p_vmspace->vm_map;
71
72 page_offset = addr - trunc_page(addr);
73 pageno = trunc_page(addr);
74
75 tmap = map;
76 rv = vm_map_lookup (&tmap, pageno, VM_PROT_READ, &out_entry,
77 &object, &pindex, &out_prot, &wired);
78
79 if (rv != KERN_SUCCESS)
80 return EINVAL;
81
82 vm_map_lookup_done (tmap, out_entry);
83
84 /* Find space in kernel_map for the page we're interested in */
85 rv = vm_map_find (kernel_map, object, IDX_TO_OFF(pindex),
86 &kva, PAGE_SIZE, 0, VM_PROT_ALL, VM_PROT_ALL, 0);
87
88 if (!rv) {
89 vm_object_reference (object);
90
91 rv = vm_map_pageable (kernel_map, kva, kva + PAGE_SIZE, 0);
92 if (!rv) {
93 *retval = 0;
94 bcopy ((caddr_t)kva + page_offset,
95 retval, sizeof *retval);
96 }
97 vm_map_remove (kernel_map, kva, kva + PAGE_SIZE);
98 }
99
100 return rv;
101 }
102
103 static int
104 pwrite (struct proc *procp, unsigned int addr, unsigned int datum) {
105 int rv;
106 vm_map_t map, tmap;
107 vm_object_t object;
108 vm_offset_t kva = 0;
109 int page_offset; /* offset into page */
110 vm_offset_t pageno; /* page number */
111 vm_map_entry_t out_entry;
112 vm_prot_t out_prot;
113 boolean_t wired;
114 vm_pindex_t pindex;
115 boolean_t fix_prot = 0;
116
117 /* Map page into kernel space */
118
119 map = &procp->p_vmspace->vm_map;
120
121 page_offset = addr - trunc_page(addr);
122 pageno = trunc_page(addr);
123
124 /*
125 * Check the permissions for the area we're interested in.
126 */
127
128 if (vm_map_check_protection (map, pageno, pageno + PAGE_SIZE,
129 VM_PROT_WRITE) == FALSE) {
130 /*
131 * If the page was not writable, we make it so.
132 * XXX It is possible a page may *not* be read/executable,
133 * if a process changes that!
134 */
135 fix_prot = 1;
136 /* The page isn't writable, so let's try making it so... */
137 if ((rv = vm_map_protect (map, pageno, pageno + PAGE_SIZE,
138 VM_PROT_ALL, 0)) != KERN_SUCCESS)
139 return EFAULT; /* I guess... */
140 }
141
142 /*
143 * Now we need to get the page. out_entry, out_prot, wired, and
144 * single_use aren't used. One would think the vm code would be
145 * a *bit* nicer... We use tmap because vm_map_lookup() can
146 * change the map argument.
147 */
148
149 tmap = map;
150 rv = vm_map_lookup (&tmap, pageno, VM_PROT_WRITE, &out_entry,
151 &object, &pindex, &out_prot, &wired);
152 if (rv != KERN_SUCCESS) {
153 return EINVAL;
154 }
155
156 /*
157 * Okay, we've got the page. Let's release tmap.
158 */
159
160 vm_map_lookup_done (tmap, out_entry);
161
162 /*
163 * Fault the page in...
164 */
165
166 rv = vm_fault(map, pageno, VM_PROT_WRITE|VM_PROT_READ, FALSE);
167 if (rv != KERN_SUCCESS)
168 return EFAULT;
169
170 /* Find space in kernel_map for the page we're interested in */
171 rv = vm_map_find (kernel_map, object, IDX_TO_OFF(pindex),
172 &kva, PAGE_SIZE, 0,
173 VM_PROT_ALL, VM_PROT_ALL, 0);
174 if (!rv) {
175 vm_object_reference (object);
176
177 rv = vm_map_pageable (kernel_map, kva, kva + PAGE_SIZE, 0);
178 if (!rv) {
179 bcopy (&datum, (caddr_t)kva + page_offset, sizeof datum);
180 }
181 vm_map_remove (kernel_map, kva, kva + PAGE_SIZE);
182 }
183
184 if (fix_prot)
185 vm_map_protect (map, pageno, pageno + PAGE_SIZE,
186 VM_PROT_READ|VM_PROT_EXECUTE, 0);
187 return rv;
188 }
189 #endif
190
191 /*
192 * Process debugging system call.
193 */
194 #ifndef _SYS_SYSPROTO_H_
195 struct ptrace_args {
196 int req;
197 pid_t pid;
198 caddr_t addr;
199 int data;
200 };
201 #endif
202
203 int
204 ptrace(curp, uap)
205 struct proc *curp;
206 struct ptrace_args *uap;
207 {
208 struct proc *p;
209 struct iovec iov;
210 struct uio uio;
211 int error = 0;
212 int write;
213 int s;
214
215 if (uap->req == PT_TRACE_ME)
216 p = curp;
217 else {
218 if ((p = pfind(uap->pid)) == NULL)
219 return ESRCH;
220 }
221
222 /*
223 * Permissions check
224 */
225 switch (uap->req) {
226 case PT_TRACE_ME:
227 /* Always legal. */
228 break;
229
230 case PT_ATTACH:
231 /* Self */
232 if (p->p_pid == curp->p_pid)
233 return EINVAL;
234
235 /* Already traced */
236 if (p->p_flag & P_TRACED)
237 return EBUSY;
238
239 /* not owned by you, has done setuid (unless you're root) */
240 if ((p->p_cred->p_ruid != curp->p_cred->p_ruid) ||
241 (p->p_flag & P_SUGID)) {
242 if (error = suser(curp->p_ucred, &curp->p_acflag))
243 return error;
244 }
245
246 /* can't trace init when securelevel > 0 */
247 if (securelevel > 0 && p->p_pid == 1)
248 return EPERM;
249
250 /* OK */
251 break;
252
253 case PT_READ_I:
254 case PT_READ_D:
255 case PT_READ_U:
256 case PT_WRITE_I:
257 case PT_WRITE_D:
258 case PT_WRITE_U:
259 case PT_CONTINUE:
260 case PT_KILL:
261 case PT_STEP:
262 case PT_DETACH:
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 /* not being traced... */
276 if ((p->p_flag & P_TRACED) == 0)
277 return EPERM;
278
279 /* not being traced by YOU */
280 if (p->p_pptr != curp)
281 return EBUSY;
282
283 /* not currently stopped */
284 if (p->p_stat != SSTOP || (p->p_flag & P_WAITED) == 0)
285 return EBUSY;
286
287 /* OK */
288 break;
289
290 default:
291 return EINVAL;
292 }
293
294 #ifdef FIX_SSTEP
295 /*
296 * Single step fixup ala procfs
297 */
298 FIX_SSTEP(p);
299 #endif
300
301 /*
302 * Actually do the requests
303 */
304
305 write = 0;
306 curp->p_retval[0] = 0;
307
308 switch (uap->req) {
309 case PT_TRACE_ME:
310 /* set my trace flag and "owner" so it can read/write me */
311 p->p_flag |= P_TRACED;
312 p->p_oppid = p->p_pptr->p_pid;
313 return 0;
314
315 case PT_ATTACH:
316 /* security check done above */
317 p->p_flag |= P_TRACED;
318 p->p_oppid = p->p_pptr->p_pid;
319 if (p->p_pptr != curp)
320 proc_reparent(p, curp);
321 uap->data = SIGSTOP;
322 goto sendsig; /* in PT_CONTINUE below */
323
324 case PT_STEP:
325 case PT_CONTINUE:
326 case PT_DETACH:
327 if ((unsigned)uap->data >= NSIG)
328 return EINVAL;
329
330 PHOLD(p);
331
332 if (uap->req == PT_STEP) {
333 if ((error = ptrace_single_step (p))) {
334 PRELE(p);
335 return error;
336 }
337 }
338
339 if (uap->addr != (caddr_t)1) {
340 fill_eproc (p, &p->p_addr->u_kproc.kp_eproc);
341 if ((error = ptrace_set_pc (p,
342 (u_long)(uintfptr_t)uap->addr))) {
343 PRELE(p);
344 return error;
345 }
346 }
347 PRELE(p);
348
349 if (uap->req == PT_DETACH) {
350 /* reset process parent */
351 if (p->p_oppid != p->p_pptr->p_pid) {
352 struct proc *pp;
353
354 pp = pfind(p->p_oppid);
355 proc_reparent(p, pp ? pp : initproc);
356 }
357
358 p->p_flag &= ~(P_TRACED | P_WAITED);
359 p->p_oppid = 0;
360
361 /* should we send SIGCHLD? */
362
363 }
364
365 sendsig:
366 /* deliver or queue signal */
367 s = splhigh();
368 if (p->p_stat == SSTOP) {
369 p->p_xstat = uap->data;
370 setrunnable(p);
371 } else if (uap->data) {
372 psignal(p, uap->data);
373 }
374 splx(s);
375 return 0;
376
377 case PT_WRITE_I:
378 case PT_WRITE_D:
379 write = 1;
380 /* fallthrough */
381 case PT_READ_I:
382 case PT_READ_D:
383 /* write = 0 set above */
384 iov.iov_base = write ? (caddr_t)&uap->data : (caddr_t)curp->p_retval;
385 iov.iov_len = sizeof(int);
386 uio.uio_iov = &iov;
387 uio.uio_iovcnt = 1;
388 uio.uio_offset = (off_t)(uintptr_t)uap->addr;
389 uio.uio_resid = sizeof(int);
390 uio.uio_segflg = UIO_SYSSPACE; /* ie: the uap */
391 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
392 uio.uio_procp = p;
393 error = procfs_domem(curp, p, NULL, &uio);
394 if (uio.uio_resid != 0) {
395 /*
396 * XXX procfs_domem() doesn't currently return ENOSPC,
397 * so I think write() can bogusly return 0.
398 * XXX what happens for short writes? We don't want
399 * to write partial data.
400 * XXX procfs_domem() returns EPERM for other invalid
401 * addresses. Convert this to EINVAL. Does this
402 * clobber returns of EPERM for other reasons?
403 */
404 if (error == 0 || error == ENOSPC || error == EPERM)
405 error = EINVAL; /* EOF */
406 }
407 return (error);
408
409 case PT_READ_U:
410 if ((uintptr_t)uap->addr > UPAGES * PAGE_SIZE - sizeof(int)) {
411 return EFAULT;
412 }
413 if ((uintptr_t)uap->addr & (sizeof(int) - 1)) {
414 return EFAULT;
415 }
416 if (ptrace_read_u_check(p,(vm_offset_t) uap->addr,
417 sizeof(long)) &&
418 !procfs_kmemaccess(curp)) {
419 return EFAULT;
420 }
421 error = 0;
422 PHOLD(p); /* user had damn well better be incore! */
423 if (p->p_flag & P_INMEM) {
424 p->p_addr->u_kproc.kp_proc = *p;
425 fill_eproc (p, &p->p_addr->u_kproc.kp_eproc);
426 curp->p_retval[0] = *(int *)
427 ((uintptr_t)p->p_addr + (uintptr_t)uap->addr);
428 } else {
429 curp->p_retval[0] = 0;
430 error = EFAULT;
431 }
432 PRELE(p);
433 return error;
434
435 case PT_WRITE_U:
436 PHOLD(p); /* user had damn well better be incore! */
437 if (p->p_flag & P_INMEM) {
438 p->p_addr->u_kproc.kp_proc = *p;
439 fill_eproc (p, &p->p_addr->u_kproc.kp_eproc);
440 error = ptrace_write_u(p, (vm_offset_t)uap->addr, uap->data);
441 } else {
442 error = EFAULT;
443 }
444 PRELE(p);
445 return error;
446
447 case PT_KILL:
448 uap->data = SIGKILL;
449 goto sendsig; /* in PT_CONTINUE above */
450
451 #ifdef PT_SETREGS
452 case PT_SETREGS:
453 write = 1;
454 /* fallthrough */
455 #endif /* PT_SETREGS */
456 #ifdef PT_GETREGS
457 case PT_GETREGS:
458 /* write = 0 above */
459 #endif /* PT_SETREGS */
460 #if defined(PT_SETREGS) || defined(PT_GETREGS)
461 if (!procfs_validregs(p)) /* no P_SYSTEM procs please */
462 return EINVAL;
463 else {
464 iov.iov_base = uap->addr;
465 iov.iov_len = sizeof(struct reg);
466 uio.uio_iov = &iov;
467 uio.uio_iovcnt = 1;
468 uio.uio_offset = 0;
469 uio.uio_resid = sizeof(struct reg);
470 uio.uio_segflg = UIO_USERSPACE;
471 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
472 uio.uio_procp = curp;
473 return (procfs_doregs(curp, p, NULL, &uio));
474 }
475 #endif /* defined(PT_SETREGS) || defined(PT_GETREGS) */
476
477 #ifdef PT_SETFPREGS
478 case PT_SETFPREGS:
479 write = 1;
480 /* fallthrough */
481 #endif /* PT_SETFPREGS */
482 #ifdef PT_GETFPREGS
483 case PT_GETFPREGS:
484 /* write = 0 above */
485 #endif /* PT_SETFPREGS */
486 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS)
487 if (!procfs_validfpregs(p)) /* no P_SYSTEM procs please */
488 return EINVAL;
489 else {
490 iov.iov_base = uap->addr;
491 iov.iov_len = sizeof(struct fpreg);
492 uio.uio_iov = &iov;
493 uio.uio_iovcnt = 1;
494 uio.uio_offset = 0;
495 uio.uio_resid = sizeof(struct fpreg);
496 uio.uio_segflg = UIO_USERSPACE;
497 uio.uio_rw = write ? UIO_WRITE : UIO_READ;
498 uio.uio_procp = curp;
499 return (procfs_dofpregs(curp, p, NULL, &uio));
500 }
501 #endif /* defined(PT_SETFPREGS) || defined(PT_GETFPREGS) */
502
503 default:
504 break;
505 }
506
507 return 0;
508 }
509
510 int
511 trace_req(p)
512 struct proc *p;
513 {
514 return 1;
515 }
516
517 /*
518 * stopevent()
519 * Stop a process because of a procfs event;
520 * stay stopped until p->p_step is cleared
521 * (cleared by PIOCCONT in procfs).
522 */
523
524 void
525 stopevent(struct proc *p, unsigned int event, unsigned int val) {
526 p->p_step = 1;
527
528 do {
529 p->p_xstat = val;
530 p->p_stype = event; /* Which event caused the stop? */
531 wakeup(&p->p_stype); /* Wake up any PIOCWAIT'ing procs */
532 tsleep(&p->p_step, PWAIT, "stopevent", 0);
533 } while (p->p_step);
534 }
Cache object: 6eebda3821a82e9315c6c318ba10bb2e
|