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 49 #include <sys/user.h> 50 #include <miscfs/procfs/procfs.h> 51 52 /* use the equivalent procfs code */ 53 #if 0 54 static int 55 pread (struct proc *procp, unsigned int addr, unsigned int *retval) { 56 int rv; 57 vm_map_t map, tmap; 58 vm_object_t object; 59 vm_offset_t kva = 0; 60 int page_offset; /* offset into page */ 61 vm_offset_t pageno; /* page number */ 62 vm_map_entry_t out_entry; 63 vm_prot_t out_prot; 64 boolean_t wired; 65 vm_pindex_t pindex; 66 67 /* Map page into kernel space */ 68 69 map = &procp->p_vmspace->vm_map; 70 71 page_offset = addr - trunc_page(addr); 72 pageno = trunc_page(addr); 73 74 tmap = map; 75 rv = vm_map_lookup (&tmap, pageno, VM_PROT_READ, &out_entry, 76 &object, &pindex, &out_prot, &wired); 77 78 if (rv != KERN_SUCCESS) 79 return EINVAL; 80 81 vm_map_lookup_done (tmap, out_entry); 82 83 /* Find space in kernel_map for the page we're interested in */ 84 rv = vm_map_find (kernel_map, object, IDX_TO_OFF(pindex), 85 &kva, PAGE_SIZE, 0, VM_PROT_ALL, VM_PROT_ALL, 0); 86 87 if (!rv) { 88 vm_object_reference (object); 89 90 rv = vm_map_pageable (kernel_map, kva, kva + PAGE_SIZE, 0); 91 if (!rv) { 92 *retval = 0; 93 bcopy ((caddr_t)kva + page_offset, 94 retval, sizeof *retval); 95 } 96 vm_map_remove (kernel_map, kva, kva + PAGE_SIZE); 97 } 98 99 return rv; 100 } 101 102 static int 103 pwrite (struct proc *procp, unsigned int addr, unsigned int datum) { 104 int rv; 105 vm_map_t map, tmap; 106 vm_object_t object; 107 vm_offset_t kva = 0; 108 int page_offset; /* offset into page */ 109 vm_offset_t pageno; /* page number */ 110 vm_map_entry_t out_entry; 111 vm_prot_t out_prot; 112 boolean_t wired; 113 vm_pindex_t pindex; 114 boolean_t fix_prot = 0; 115 116 /* Map page into kernel space */ 117 118 map = &procp->p_vmspace->vm_map; 119 120 page_offset = addr - trunc_page(addr); 121 pageno = trunc_page(addr); 122 123 /* 124 * Check the permissions for the area we're interested in. 125 */ 126 127 if (vm_map_check_protection (map, pageno, pageno + PAGE_SIZE, 128 VM_PROT_WRITE) == FALSE) { 129 /* 130 * If the page was not writable, we make it so. 131 * XXX It is possible a page may *not* be read/executable, 132 * if a process changes that! 133 */ 134 fix_prot = 1; 135 /* The page isn't writable, so let's try making it so... */ 136 if ((rv = vm_map_protect (map, pageno, pageno + PAGE_SIZE, 137 VM_PROT_ALL, 0)) != KERN_SUCCESS) 138 return EFAULT; /* I guess... */ 139 } 140 141 /* 142 * Now we need to get the page. out_entry, out_prot, wired, and 143 * single_use aren't used. One would think the vm code would be 144 * a *bit* nicer... We use tmap because vm_map_lookup() can 145 * change the map argument. 146 */ 147 148 tmap = map; 149 rv = vm_map_lookup (&tmap, pageno, VM_PROT_WRITE, &out_entry, 150 &object, &pindex, &out_prot, &wired); 151 if (rv != KERN_SUCCESS) { 152 return EINVAL; 153 } 154 155 /* 156 * Okay, we've got the page. Let's release tmap. 157 */ 158 159 vm_map_lookup_done (tmap, out_entry); 160 161 /* 162 * Fault the page in... 163 */ 164 165 rv = vm_fault(map, pageno, VM_PROT_WRITE|VM_PROT_READ, FALSE); 166 if (rv != KERN_SUCCESS) 167 return EFAULT; 168 169 /* Find space in kernel_map for the page we're interested in */ 170 rv = vm_map_find (kernel_map, object, IDX_TO_OFF(pindex), 171 &kva, PAGE_SIZE, 0, 172 VM_PROT_ALL, VM_PROT_ALL, 0); 173 if (!rv) { 174 vm_object_reference (object); 175 176 rv = vm_map_pageable (kernel_map, kva, kva + PAGE_SIZE, 0); 177 if (!rv) { 178 bcopy (&datum, (caddr_t)kva + page_offset, sizeof datum); 179 } 180 vm_map_remove (kernel_map, kva, kva + PAGE_SIZE); 181 } 182 183 if (fix_prot) 184 vm_map_protect (map, pageno, pageno + PAGE_SIZE, 185 VM_PROT_READ|VM_PROT_EXECUTE, 0); 186 return rv; 187 } 188 #endif 189 190 /* 191 * Process debugging system call. 192 */ 193 #ifndef _SYS_SYSPROTO_H_ 194 struct ptrace_args { 195 int req; 196 pid_t pid; 197 caddr_t addr; 198 int data; 199 }; 200 #endif 201 202 int 203 ptrace(curp, uap) 204 struct proc *curp; 205 struct ptrace_args *uap; 206 { 207 struct proc *p; 208 struct iovec iov; 209 struct uio uio; 210 int error = 0; 211 int write; 212 int s; 213 214 write = 0; 215 if (uap->req == PT_TRACE_ME) 216 p = curp; 217 else { 218 if ((p = pfind(uap->pid)) == NULL) 219 return ESRCH; 220 } 221 if (!PRISON_CHECK(curp, p)) 222 return (ESRCH); 223 224 /* 225 * Permissions check 226 */ 227 switch (uap->req) { 228 case PT_TRACE_ME: 229 /* Always legal. */ 230 break; 231 232 case PT_ATTACH: 233 /* Self */ 234 if (p->p_pid == curp->p_pid) 235 return EINVAL; 236 237 /* Already traced */ 238 if (p->p_flag & P_TRACED) 239 return EBUSY; 240 241 /* not owned by you, has done setuid (unless you're root) */ 242 if ((p->p_cred->p_ruid != curp->p_cred->p_ruid) || 243 (p->p_flag & P_SUGID)) { 244 if ((error = suser(curp)) != 0) 245 return error; 246 } 247 248 /* can't trace init when securelevel > 0 */ 249 if (securelevel > 0 && p->p_pid == 1) 250 return EPERM; 251 252 /* OK */ 253 break; 254 255 case PT_READ_I: 256 case PT_READ_D: 257 case PT_READ_U: 258 case PT_WRITE_I: 259 case PT_WRITE_D: 260 case PT_WRITE_U: 261 case PT_CONTINUE: 262 case PT_KILL: 263 case PT_STEP: 264 case PT_DETACH: 265 #ifdef PT_GETREGS 266 case PT_GETREGS: 267 #endif 268 #ifdef PT_SETREGS 269 case PT_SETREGS: 270 #endif 271 #ifdef PT_GETFPREGS 272 case PT_GETFPREGS: 273 #endif 274 #ifdef PT_SETFPREGS 275 case PT_SETFPREGS: 276 #endif 277 #ifdef PT_GETDBREGS 278 case PT_GETDBREGS: 279 #endif 280 #ifdef PT_SETDBREGS 281 case PT_SETDBREGS: 282 #endif 283 /* not being traced... */ 284 if ((p->p_flag & P_TRACED) == 0) 285 return EPERM; 286 287 /* not being traced by YOU */ 288 if (p->p_pptr != curp) 289 return EBUSY; 290 291 /* not currently stopped */ 292 if (p->p_stat != SSTOP || (p->p_flag & P_WAITED) == 0) 293 return EBUSY; 294 295 /* OK */ 296 break; 297 298 default: 299 return EINVAL; 300 } 301 302 #ifdef FIX_SSTEP 303 /* 304 * Single step fixup ala procfs 305 */ 306 FIX_SSTEP(p); 307 #endif 308 309 /* 310 * Actually do the requests 311 */ 312 313 curp->p_retval[0] = 0; 314 315 switch (uap->req) { 316 case PT_TRACE_ME: 317 /* set my trace flag and "owner" so it can read/write me */ 318 p->p_flag |= P_TRACED; 319 p->p_oppid = p->p_pptr->p_pid; 320 return 0; 321 322 case PT_ATTACH: 323 /* security check done above */ 324 p->p_flag |= P_TRACED; 325 p->p_oppid = p->p_pptr->p_pid; 326 if (p->p_pptr != curp) 327 proc_reparent(p, curp); 328 uap->data = SIGSTOP; 329 goto sendsig; /* in PT_CONTINUE below */ 330 331 case PT_STEP: 332 case PT_CONTINUE: 333 case PT_DETACH: 334 if ((unsigned)uap->data >= NSIG) 335 return EINVAL; 336 337 PHOLD(p); 338 339 if (uap->req == PT_STEP) { 340 if ((error = ptrace_single_step (p))) { 341 PRELE(p); 342 return error; 343 } 344 } 345 346 if (uap->addr != (caddr_t)1) { 347 fill_eproc (p, &p->p_addr->u_kproc.kp_eproc); 348 if ((error = ptrace_set_pc (p, 349 (u_long)(uintfptr_t)uap->addr))) { 350 PRELE(p); 351 return error; 352 } 353 } 354 PRELE(p); 355 356 if (uap->req == PT_DETACH) { 357 /* reset process parent */ 358 if (p->p_oppid != p->p_pptr->p_pid) { 359 struct proc *pp; 360 361 pp = pfind(p->p_oppid); 362 proc_reparent(p, pp ? pp : initproc); 363 } 364 365 p->p_flag &= ~(P_TRACED | P_WAITED); 366 p->p_oppid = 0; 367 368 /* should we send SIGCHLD? */ 369 370 } 371 372 sendsig: 373 /* deliver or queue signal */ 374 s = splhigh(); 375 if (p->p_stat == SSTOP) { 376 p->p_xstat = uap->data; 377 setrunnable(p); 378 } else if (uap->data) { 379 psignal(p, uap->data); 380 } 381 splx(s); 382 return 0; 383 384 case PT_WRITE_I: 385 case PT_WRITE_D: 386 write = 1; 387 /* fallthrough */ 388 case PT_READ_I: 389 case PT_READ_D: 390 /* write = 0 set above */ 391 iov.iov_base = write ? (caddr_t)&uap->data : (caddr_t)curp->p_retval; 392 iov.iov_len = sizeof(int); 393 uio.uio_iov = &iov; 394 uio.uio_iovcnt = 1; 395 uio.uio_offset = (off_t)(uintptr_t)uap->addr; 396 uio.uio_resid = sizeof(int); 397 uio.uio_segflg = UIO_SYSSPACE; /* ie: the uap */ 398 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 399 uio.uio_procp = p; 400 error = procfs_domem(curp, p, NULL, &uio); 401 if (uio.uio_resid != 0) { 402 /* 403 * XXX procfs_domem() doesn't currently return ENOSPC, 404 * so I think write() can bogusly return 0. 405 * XXX what happens for short writes? We don't want 406 * to write partial data. 407 * XXX procfs_domem() returns EPERM for other invalid 408 * addresses. Convert this to EINVAL. Does this 409 * clobber returns of EPERM for other reasons? 410 */ 411 if (error == 0 || error == ENOSPC || error == EPERM) 412 error = EINVAL; /* EOF */ 413 } 414 return (error); 415 416 case PT_READ_U: 417 if ((uintptr_t)uap->addr > UPAGES * PAGE_SIZE - sizeof(int)) { 418 return EFAULT; 419 } 420 if ((uintptr_t)uap->addr & (sizeof(int) - 1)) { 421 return EFAULT; 422 } 423 if (ptrace_read_u_check(p,(vm_offset_t) uap->addr, 424 sizeof(int)) && 425 !procfs_kmemaccess(curp)) { 426 return EFAULT; 427 } 428 error = 0; 429 PHOLD(p); /* user had damn well better be incore! */ 430 if (p->p_flag & P_INMEM) { 431 p->p_addr->u_kproc.kp_proc = *p; 432 fill_eproc (p, &p->p_addr->u_kproc.kp_eproc); 433 curp->p_retval[0] = *(int *) 434 ((uintptr_t)p->p_addr + (uintptr_t)uap->addr); 435 } else { 436 curp->p_retval[0] = 0; 437 error = EFAULT; 438 } 439 PRELE(p); 440 return error; 441 442 case PT_WRITE_U: 443 PHOLD(p); /* user had damn well better be incore! */ 444 if (p->p_flag & P_INMEM) { 445 p->p_addr->u_kproc.kp_proc = *p; 446 fill_eproc (p, &p->p_addr->u_kproc.kp_eproc); 447 error = ptrace_write_u(p, (vm_offset_t)uap->addr, uap->data); 448 } else { 449 error = EFAULT; 450 } 451 PRELE(p); 452 return error; 453 454 case PT_KILL: 455 uap->data = SIGKILL; 456 goto sendsig; /* in PT_CONTINUE above */ 457 458 #ifdef PT_SETREGS 459 case PT_SETREGS: 460 write = 1; 461 /* fallthrough */ 462 #endif /* PT_SETREGS */ 463 #ifdef PT_GETREGS 464 case PT_GETREGS: 465 /* write = 0 above */ 466 #endif /* PT_SETREGS */ 467 #if defined(PT_SETREGS) || defined(PT_GETREGS) 468 if (!procfs_validregs(p)) /* no P_SYSTEM procs please */ 469 return EINVAL; 470 else { 471 iov.iov_base = uap->addr; 472 iov.iov_len = sizeof(struct reg); 473 uio.uio_iov = &iov; 474 uio.uio_iovcnt = 1; 475 uio.uio_offset = 0; 476 uio.uio_resid = sizeof(struct reg); 477 uio.uio_segflg = UIO_USERSPACE; 478 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 479 uio.uio_procp = curp; 480 return (procfs_doregs(curp, p, NULL, &uio)); 481 } 482 #endif /* defined(PT_SETREGS) || defined(PT_GETREGS) */ 483 484 #ifdef PT_SETFPREGS 485 case PT_SETFPREGS: 486 write = 1; 487 /* fallthrough */ 488 #endif /* PT_SETFPREGS */ 489 #ifdef PT_GETFPREGS 490 case PT_GETFPREGS: 491 /* write = 0 above */ 492 #endif /* PT_SETFPREGS */ 493 #if defined(PT_SETFPREGS) || defined(PT_GETFPREGS) 494 if (!procfs_validfpregs(p)) /* no P_SYSTEM procs please */ 495 return EINVAL; 496 else { 497 iov.iov_base = uap->addr; 498 iov.iov_len = sizeof(struct fpreg); 499 uio.uio_iov = &iov; 500 uio.uio_iovcnt = 1; 501 uio.uio_offset = 0; 502 uio.uio_resid = sizeof(struct fpreg); 503 uio.uio_segflg = UIO_USERSPACE; 504 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 505 uio.uio_procp = curp; 506 return (procfs_dofpregs(curp, p, NULL, &uio)); 507 } 508 #endif /* defined(PT_SETFPREGS) || defined(PT_GETFPREGS) */ 509 510 #ifdef PT_SETDBREGS 511 case PT_SETDBREGS: 512 write = 1; 513 /* fallthrough */ 514 #endif /* PT_SETDBREGS */ 515 #ifdef PT_GETDBREGS 516 case PT_GETDBREGS: 517 /* write = 0 above */ 518 #endif /* PT_SETDBREGS */ 519 #if defined(PT_SETDBREGS) || defined(PT_GETDBREGS) 520 if (!procfs_validdbregs(p)) /* no P_SYSTEM procs please */ 521 return EINVAL; 522 else { 523 iov.iov_base = uap->addr; 524 iov.iov_len = sizeof(struct dbreg); 525 uio.uio_iov = &iov; 526 uio.uio_iovcnt = 1; 527 uio.uio_offset = 0; 528 uio.uio_resid = sizeof(struct dbreg); 529 uio.uio_segflg = UIO_USERSPACE; 530 uio.uio_rw = write ? UIO_WRITE : UIO_READ; 531 uio.uio_procp = curp; 532 return (procfs_dodbregs(curp, p, NULL, &uio)); 533 } 534 #endif /* defined(PT_SETDBREGS) || defined(PT_GETDBREGS) */ 535 536 default: 537 break; 538 } 539 540 return 0; 541 } 542 543 int 544 trace_req(p) 545 struct proc *p; 546 { 547 return 1; 548 } 549 550 /* 551 * stopevent() 552 * Stop a process because of a procfs event; 553 * stay stopped until p->p_step is cleared 554 * (cleared by PIOCCONT in procfs). 555 */ 556 557 void 558 stopevent(struct proc *p, unsigned int event, unsigned int val) { 559 p->p_step = 1; 560 561 do { 562 p->p_xstat = val; 563 p->p_stype = event; /* Which event caused the stop? */ 564 wakeup(&p->p_stype); /* Wake up any PIOCWAIT'ing procs */ 565 tsleep(&p->p_step, PWAIT, "stopevent", 0); 566 } while (p->p_step); 567 } 568