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