1 /*- 2 * Copyright (c) 1982, 1986, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. 9 * 10 * %sccs.include.proprietary.c% 11 * 12 * @(#)kern_exec.c 8.10 (Berkeley) 05/14/95 13 */ 14 15 #include <sys/param.h> 16 #include <sys/systm.h> 17 #include <sys/filedesc.h> 18 #include <sys/kernel.h> 19 #include <sys/proc.h> 20 #include <sys/mount.h> 21 #include <sys/malloc.h> 22 #include <sys/namei.h> 23 #include <sys/vnode.h> 24 #include <sys/file.h> 25 #include <sys/acct.h> 26 #include <sys/exec.h> 27 #include <sys/ktrace.h> 28 #include <sys/resourcevar.h> 29 #include <sys/syscallargs.h> 30 31 #include <machine/cpu.h> 32 #include <machine/reg.h> 33 34 #include <sys/mman.h> 35 #include <vm/vm.h> 36 #include <vm/vm_param.h> 37 #include <vm/vm_map.h> 38 #include <vm/vm_kern.h> 39 #include <vm/vm_pager.h> 40 41 #include <sys/signalvar.h> 42 43 #ifdef HPUXCOMPAT 44 #include <sys/user.h> /* for pcb */ 45 #include <hp/hpux/hpux_exec.h> 46 #endif 47 48 #ifdef COPY_SIGCODE 49 extern char sigcode[], esigcode[]; 50 #define szsigcode (esigcode - sigcode) 51 #else 52 #define szsigcode 0 53 #endif 54 55 /* 56 * exec system call 57 */ 58 execve(p, uap, retval) 59 register struct proc *p; 60 register struct execve_args /* { 61 syscallarg(char *) path; 62 syscallarg(char **) argp; 63 syscallarg(char **) envp; 64 } */ *uap; 65 register_t *retval; 66 { 67 register struct ucred *cred = p->p_ucred; 68 register struct filedesc *fdp = p->p_fd; 69 int na, ne, ucp, ap, cc, ssize; 70 register char *cp; 71 register int nc; 72 unsigned len; 73 int indir, uid, gid; 74 char *sharg; 75 struct vnode *vp; 76 int resid, error, paged = 0; 77 vm_offset_t execargs = 0; 78 struct vattr vattr; 79 char cfarg[MAXINTERP]; 80 union { 81 char ex_shell[MAXINTERP]; /* #! and interpreter name */ 82 struct exec ex_exec; 83 #ifdef HPUXCOMPAT 84 struct hpux_exec ex_hexec; 85 #endif 86 } exdata; 87 #ifdef HPUXCOMPAT 88 struct hpux_exec hhead; 89 #endif 90 struct nameidata nd; 91 struct ps_strings ps; 92 93 NDINIT(&nd, LOOKUP, FOLLOW | SAVENAME, UIO_USERSPACE, 94 SCARG(uap, path), p); 95 if (error = namei(&nd)) 96 return (error); 97 vp = nd.ni_vp; 98 VOP_LEASE(vp, p, cred, LEASE_READ); 99 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 100 indir = 0; 101 uid = cred->cr_uid; 102 gid = cred->cr_gid; 103 if (error = VOP_GETATTR(vp, &vattr, cred, p)) 104 goto bad; 105 if (vp->v_mount->mnt_flag & MNT_NOEXEC) { 106 error = EACCES; 107 goto bad; 108 } 109 if ((vp->v_mount->mnt_flag & MNT_NOSUID) == 0) { 110 if (vattr.va_mode & VSUID) 111 uid = vattr.va_uid; 112 if (vattr.va_mode & VSGID) 113 gid = vattr.va_gid; 114 } 115 116 again: 117 if (error = VOP_ACCESS(vp, VEXEC, cred, p)) 118 goto bad; 119 if ((p->p_flag & P_TRACED) && (error = VOP_ACCESS(vp, VREAD, cred, p))) 120 goto bad; 121 if (vp->v_type != VREG || 122 (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) { 123 error = EACCES; 124 goto bad; 125 } 126 127 /* 128 * Read in first few bytes of file for segment sizes, magic number: 129 * OMAGIC = plain executable 130 * NMAGIC = RO text 131 * ZMAGIC = demand paged RO text 132 * Also an ASCII line beginning with #! is 133 * the file name of a ``shell'' and arguments may be prepended 134 * to the argument list if given here. 135 * 136 * SHELL NAMES ARE LIMITED IN LENGTH. 137 * 138 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM 139 * THE ASCII LINE. 140 */ 141 exdata.ex_shell[0] = '\0'; /* for zero length files */ 142 error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata), 143 (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), cred, &resid, 144 (struct proc *)0); 145 if (error) 146 goto bad; 147 #ifndef lint 148 if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) && 149 exdata.ex_shell[0] != '#') { 150 error = ENOEXEC; 151 goto bad; 152 } 153 #endif 154 #if defined(hp300) || defined(luna68k) 155 switch ((int)exdata.ex_exec.a_mid) { 156 157 /* 158 * An ancient hp200 or hp300 binary, shouldn't happen anymore. 159 * Mark as invalid. 160 */ 161 case MID_ZERO: 162 exdata.ex_exec.a_magic = 0; 163 break; 164 165 /* 166 * HP200 series has a smaller page size so we cannot 167 * demand-load or even write protect text, so we just 168 * treat as OMAGIC. 169 */ 170 case MID_HP200: 171 exdata.ex_exec.a_magic = OMAGIC; 172 break; 173 174 case MID_HP300: 175 break; 176 177 #ifdef HPUXCOMPAT 178 case MID_HPUX: 179 /* 180 * Save a.out header. This is eventually saved in the pcb, 181 * but we cannot do that yet in case the exec fails before 182 * the image is overlayed. 183 */ 184 bcopy((caddr_t)&exdata.ex_hexec, 185 (caddr_t)&hhead, sizeof hhead); 186 /* 187 * Shuffle important fields to their BSD locations. 188 * Note that the order in which this is done is important. 189 */ 190 exdata.ex_exec.a_text = exdata.ex_hexec.ha_text; 191 exdata.ex_exec.a_data = exdata.ex_hexec.ha_data; 192 exdata.ex_exec.a_bss = exdata.ex_hexec.ha_bss; 193 exdata.ex_exec.a_entry = exdata.ex_hexec.ha_entry; 194 /* 195 * For ZMAGIC files, make sizes consistant with those 196 * generated by BSD ld. 197 */ 198 if (exdata.ex_exec.a_magic == ZMAGIC) { 199 exdata.ex_exec.a_text = 200 ctob(btoc(exdata.ex_exec.a_text)); 201 nc = exdata.ex_exec.a_data + exdata.ex_exec.a_bss; 202 exdata.ex_exec.a_data = 203 ctob(btoc(exdata.ex_exec.a_data)); 204 nc -= (int)exdata.ex_exec.a_data; 205 exdata.ex_exec.a_bss = (nc < 0) ? 0 : nc; 206 } 207 break; 208 #endif 209 } 210 #endif 211 switch ((int)exdata.ex_exec.a_magic) { 212 213 case OMAGIC: 214 #ifdef COFF 215 if (exdata.ex_exec.ex_fhdr.magic != COFF_MAGIC) { 216 error = ENOEXEC; 217 goto bad; 218 } 219 #endif 220 #ifdef sparc 221 if (exdata.ex_exec.a_mid != MID_SUN_SPARC) { 222 error = ENOEXEC; 223 goto bad; 224 } 225 #endif 226 exdata.ex_exec.a_data += exdata.ex_exec.a_text; 227 exdata.ex_exec.a_text = 0; 228 break; 229 230 case ZMAGIC: 231 paged = 1; 232 /* FALLTHROUGH */ 233 234 case NMAGIC: 235 #ifdef COFF 236 if (exdata.ex_exec.ex_fhdr.magic != COFF_MAGIC) { 237 error = ENOEXEC; 238 goto bad; 239 } 240 #endif 241 #ifdef sparc 242 if (exdata.ex_exec.a_mid != MID_SUN_SPARC) { 243 error = ENOEXEC; 244 goto bad; 245 } 246 #endif 247 if (exdata.ex_exec.a_text == 0) { 248 error = ENOEXEC; 249 goto bad; 250 } 251 break; 252 253 default: 254 if (exdata.ex_shell[0] != '#' || 255 exdata.ex_shell[1] != '!' || 256 indir) { 257 error = ENOEXEC; 258 goto bad; 259 } 260 for (cp = &exdata.ex_shell[2];; ++cp) { 261 if (cp >= &exdata.ex_shell[MAXINTERP]) { 262 error = ENOEXEC; 263 goto bad; 264 } 265 if (*cp == '\n') { 266 *cp = '\0'; 267 break; 268 } 269 if (*cp == '\t') 270 *cp = ' '; 271 } 272 cp = &exdata.ex_shell[2]; 273 while (*cp == ' ') 274 cp++; 275 nd.ni_dirp = cp; 276 while (*cp && *cp != ' ') 277 cp++; 278 cfarg[0] = '\0'; 279 if (*cp) { 280 *cp++ = '\0'; 281 while (*cp == ' ') 282 cp++; 283 if (*cp) 284 bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP); 285 } 286 indir = 1; 287 vput(vp); 288 nd.ni_segflg = UIO_SYSSPACE; 289 if (error = namei(&nd)) 290 return (error); 291 vp = nd.ni_vp; 292 VOP_LEASE(vp, p, cred, LEASE_READ); 293 vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); 294 if (error = VOP_GETATTR(vp, &vattr, cred, p)) 295 goto bad; 296 uid = cred->cr_uid; /* shell scripts can't be setuid */ 297 gid = cred->cr_gid; 298 goto again; 299 } 300 301 /* 302 * Collect arguments on "file" in swap space. 303 */ 304 na = 0; 305 ne = 0; 306 nc = 0; 307 cc = NCARGS; 308 execargs = kmem_alloc_wait(exec_map, NCARGS); 309 #ifdef DIAGNOSTIC 310 if (execargs == (vm_offset_t)0) 311 panic("execve: kmem_alloc_wait"); 312 #endif 313 cp = (char *) execargs; 314 /* 315 * Copy arguments into file in argdev area. 316 */ 317 if (SCARG(uap, argp)) for (;;) { 318 ap = NULL; 319 sharg = NULL; 320 if (indir && na == 0) { 321 sharg = nd.ni_cnd.cn_nameptr; 322 ap = (int)sharg; 323 SCARG(uap, argp)++; /* ignore argv[0] */ 324 } else if (indir && (na == 1 && cfarg[0])) { 325 sharg = cfarg; 326 ap = (int)sharg; 327 } else if (indir && (na == 1 || na == 2 && cfarg[0])) 328 ap = (int)SCARG(uap, path); 329 else if (SCARG(uap, argp)) { 330 ap = fuword((caddr_t)SCARG(uap, argp)); 331 SCARG(uap, argp)++; 332 } 333 if (ap == NULL && SCARG(uap, envp)) { 334 SCARG(uap, argp) = NULL; 335 if ((ap = fuword((caddr_t)SCARG(uap, envp))) != NULL) 336 SCARG(uap, envp)++, ne++; 337 } 338 if (ap == NULL) 339 break; 340 na++; 341 if (ap == -1) { 342 error = EFAULT; 343 goto bad; 344 } 345 do { 346 if (nc >= NCARGS-1) { 347 error = E2BIG; 348 break; 349 } 350 if (sharg) { 351 error = copystr(sharg, cp, (unsigned)cc, &len); 352 sharg += len; 353 } else { 354 error = copyinstr((caddr_t)ap, cp, (unsigned)cc, 355 &len); 356 ap += len; 357 } 358 cp += len; 359 nc += len; 360 cc -= len; 361 } while (error == ENAMETOOLONG); 362 if (error) 363 goto bad; 364 } 365 366 /* 367 * XXX the following is excessively bogus 368 * 369 * Compute initial process stack size and location of argc 370 * and character strings. `nc' is currently just the number 371 * of characters of arg and env strings. 372 * 373 * nc = size of ps_strings structure + 374 * size of signal code + 375 * 4 bytes of NULL pointer + 376 * nc, 377 * rounded to nearest integer; 378 * ucp = USRSTACK - nc; [user characters pointer] 379 * apsize = padding (if any) + 380 * 4 bytes of NULL pointer + 381 * ne 4-byte pointers to env strings + 382 * 4 bytes of NULL pointer + 383 * (na-ne) 4-byte pointers to arg strings + 384 * 4 bytes of argc; 385 * (this is the same as nc + (na+3)*4) 386 * ap = ucp - apsize; [user address of argc] 387 * ssize = ssize + nc + machine-dependent space; 388 */ 389 nc = (sizeof(ps) + szsigcode + 4 + nc + NBPW-1) & ~(NBPW - 1); 390 #if defined(sparc) || defined(mips) 391 ucp = USRSTACK; 392 ssize = ALIGN(nc + (na + 3) * NBPW); 393 ap = ucp - ssize; 394 ucp -= nc; 395 #ifdef sparc 396 ssize += sizeof(struct rwindow); 397 #endif 398 #else 399 ssize = (na + 3) * NBPW; 400 ucp = USRSTACK - nc; 401 ap = ucp - ssize; 402 ssize += nc; 403 #endif 404 error = getxfile(p, vp, &exdata.ex_exec, paged, ssize, uid, gid); 405 if (error) 406 goto bad; 407 408 /* take a reference to the new text vnode (for procfs) */ 409 if (p->p_textvp) 410 vrele(p->p_textvp); 411 VREF(vp); 412 p->p_textvp = vp; 413 414 vput(vp); 415 vp = NULL; 416 417 #ifdef HPUXCOMPAT 418 /* 419 * We are now committed to the exec so we can save the exec 420 * header in the pcb where we can dump it if necessary in core() 421 */ 422 if (p->p_md.md_flags & MDP_HPUX) 423 bcopy((caddr_t)&hhead, 424 (caddr_t)p->p_addr->u_md.md_exec, sizeof hhead); 425 #endif 426 427 /* 428 * Copy back arglist. 429 */ 430 cpu_setstack(p, ap); 431 (void) suword((caddr_t)ap, na-ne); 432 nc = 0; 433 cp = (char *) execargs; 434 cc = NCARGS; 435 ps.ps_argvstr = (char *)ucp; /* first argv string */ 436 ps.ps_nargvstr = na - ne; /* argc */ 437 for (;;) { 438 ap += NBPW; 439 if (na == ne) { 440 (void) suword((caddr_t)ap, 0); 441 ap += NBPW; 442 ps.ps_envstr = (char *)ucp; 443 ps.ps_nenvstr = ne; 444 } 445 if (--na < 0) 446 break; 447 (void) suword((caddr_t)ap, ucp); 448 do { 449 error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc, 450 &len); 451 ucp += len; 452 cp += len; 453 nc += len; 454 cc -= len; 455 } while (error == ENAMETOOLONG); 456 if (error == EFAULT) 457 panic("exec: EFAULT"); 458 } 459 (void) suword((caddr_t)ap, 0); 460 (void) copyout((caddr_t)&ps, (caddr_t)PS_STRINGS, sizeof(ps)); 461 462 execsigs(p); 463 464 for (nc = fdp->fd_lastfile; nc >= 0; --nc) { 465 if (fdp->fd_ofileflags[nc] & UF_EXCLOSE) { 466 (void) closef(fdp->fd_ofiles[nc], p); 467 fdp->fd_ofiles[nc] = NULL; 468 fdp->fd_ofileflags[nc] = 0; 469 if (nc < fdp->fd_freefile) 470 fdp->fd_freefile = nc; 471 } 472 fdp->fd_ofileflags[nc] &= ~UF_MAPPED; 473 } 474 /* 475 * Adjust fd_lastfile to account for descriptors closed above. 476 * Don't decrement fd_lastfile past 0, as it's unsigned. 477 */ 478 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 479 fdp->fd_lastfile--; 480 setregs(p, exdata.ex_exec.a_entry, retval); 481 #ifdef COPY_SIGCODE 482 /* 483 * Install sigcode at top of user stack. 484 */ 485 copyout((caddr_t)sigcode, (caddr_t)PS_STRINGS - szsigcode, szsigcode); 486 #endif 487 /* 488 * Remember file name for accounting. 489 */ 490 p->p_acflag &= ~AFORK; 491 if (nd.ni_cnd.cn_namelen > MAXCOMLEN) 492 nd.ni_cnd.cn_namelen = MAXCOMLEN; 493 bcopy((caddr_t)nd.ni_cnd.cn_nameptr, (caddr_t)p->p_comm, 494 (unsigned)nd.ni_cnd.cn_namelen); 495 p->p_comm[nd.ni_cnd.cn_namelen] = '\0'; 496 cpu_exec(p); 497 bad: 498 FREE(nd.ni_cnd.cn_pnbuf, M_NAMEI); 499 if (execargs) 500 kmem_free_wakeup(exec_map, execargs, NCARGS); 501 if (vp) 502 vput(vp); 503 return (error); 504 } 505 506 /* 507 * Read in and set up memory for executed file. 508 */ 509 getxfile(p, vp, ep, paged, ssize, uid, gid) 510 register struct proc *p; 511 register struct vnode *vp; 512 register struct exec *ep; 513 int paged, ssize, uid, gid; 514 { 515 register struct ucred *cred = p->p_ucred; 516 register struct vmspace *vm = p->p_vmspace; 517 vm_offset_t addr; 518 vm_size_t xts, size; 519 segsz_t ds; 520 off_t toff; 521 int error = 0; 522 523 #ifdef HPUXCOMPAT 524 if (ep->a_mid == MID_HPUX) 525 toff = paged ? CLBYTES : sizeof(struct hpux_exec); 526 else 527 #endif 528 #ifdef COFF 529 toff = N_TXTOFF(*ep); 530 #else 531 #ifdef sparc 532 if (ep->a_mid == MID_SUN_SPARC) 533 toff = paged ? 0 : sizeof(struct exec); 534 else 535 #endif 536 if (paged) 537 #ifdef mips 538 toff = 0; 539 #else 540 toff = CLBYTES; 541 #endif 542 else 543 toff = sizeof (struct exec); 544 #endif 545 if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 && 546 vp->v_writecount != 0) 547 return (ETXTBSY); 548 549 /* 550 * Compute text and data sizes and make sure not too large. 551 * Text size is rounded to an ``ld page''; data+bss is left 552 * in machine pages. Check data and bss separately as they 553 * may overflow when summed together. (XXX not done yet) 554 */ 555 xts = roundup(ep->a_text, __LDPGSZ); 556 ds = clrnd(btoc(ep->a_data + ep->a_bss)); 557 558 /* 559 * If we're sharing the address space, allocate a new space 560 * and release our reference to the old one. Otherwise, 561 * empty out the existing vmspace. 562 */ 563 #ifdef sparc 564 kill_user_windows(p); /* before addrs go away */ 565 #endif 566 if (vm->vm_refcnt > 1) { 567 p->p_vmspace = vmspace_alloc(VM_MIN_ADDRESS, 568 VM_MAXUSER_ADDRESS, 1); 569 vmspace_free(vm); 570 vm = p->p_vmspace; 571 } else { 572 #ifdef SYSVSHM 573 if (vm->vm_shm) 574 shmexit(p); 575 #endif 576 (void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS, 577 VM_MAXUSER_ADDRESS); 578 } 579 /* 580 * If parent is waiting for us to exec or exit, 581 * P_PPWAIT will be set; clear it and wakeup parent. 582 */ 583 if (p->p_flag & P_PPWAIT) { 584 p->p_flag &= ~P_PPWAIT; 585 wakeup((caddr_t) p->p_pptr); 586 } 587 #if defined(HP380) || defined(LUNA2) 588 /* default to copyback caching on 68040 */ 589 if (mmutype == MMU_68040) 590 p->p_md.md_flags |= (MDP_CCBDATA|MDP_CCBSTACK); 591 #endif 592 #ifdef HPUXCOMPAT 593 p->p_md.md_flags &= ~(MDP_HPUX|MDP_HPUXMMAP); 594 /* note that we are an HP-UX binary */ 595 if (ep->a_mid == MID_HPUX) 596 p->p_md.md_flags |= MDP_HPUX; 597 /* deal with miscellaneous attributes */ 598 if (ep->a_trsize & HPUXM_VALID) { 599 if (ep->a_trsize & HPUXM_DATAWT) 600 p->p_md.md_flags &= ~MDP_CCBDATA; 601 if (ep->a_trsize & HPUXM_STKWT) 602 p->p_md.md_flags &= ~MDP_CCBSTACK; 603 } 604 #endif 605 #ifdef ULTRIXCOMPAT 606 /* 607 * Always start out as an ULTRIX process. 608 * A system call in crt0.o will change us to BSD system calls later. 609 */ 610 p->p_md.md_flags |= MDP_ULTRIX; 611 #endif 612 p->p_flag |= P_EXEC; 613 #ifndef COFF 614 addr = VM_MIN_ADDRESS; 615 if (vm_allocate(&vm->vm_map, &addr, xts + ctob(ds), FALSE)) { 616 uprintf("Cannot allocate text+data space\n"); 617 error = ENOMEM; /* XXX */ 618 goto badmap; 619 } 620 vm->vm_taddr = (caddr_t)VM_MIN_ADDRESS; 621 vm->vm_daddr = (caddr_t)(VM_MIN_ADDRESS + xts); 622 #else /* COFF */ 623 addr = (vm_offset_t)ep->ex_aout.codeStart; 624 vm->vm_taddr = (caddr_t)addr; 625 if (vm_allocate(&vm->vm_map, &addr, xts, FALSE)) { 626 uprintf("Cannot allocate text space\n"); 627 error = ENOMEM; /* XXX */ 628 goto badmap; 629 } 630 addr = (vm_offset_t)ep->ex_aout.heapStart; 631 vm->vm_daddr = (caddr_t)addr; 632 if (vm_allocate(&vm->vm_map, &addr, round_page(ctob(ds)), FALSE)) { 633 uprintf("Cannot allocate data space\n"); 634 error = ENOMEM; /* XXX */ 635 goto badmap; 636 } 637 #endif /* COFF */ 638 size = round_page(MAXSSIZ); /* XXX */ 639 #ifdef i386 640 addr = trunc_page(USRSTACK - size) - NBPG; /* XXX */ 641 #else 642 addr = trunc_page(USRSTACK - size); 643 #endif 644 if (vm_allocate(&vm->vm_map, &addr, size, FALSE)) { 645 uprintf("Cannot allocate stack space\n"); 646 error = ENOMEM; /* XXX */ 647 goto badmap; 648 } 649 size -= round_page(p->p_rlimit[RLIMIT_STACK].rlim_cur); 650 if (vm_map_protect(&vm->vm_map, addr, addr+size, VM_PROT_NONE, FALSE)) { 651 uprintf("Cannot protect stack space\n"); 652 error = ENOMEM; 653 goto badmap; 654 } 655 vm->vm_maxsaddr = (caddr_t)addr; 656 657 if (paged == 0) { 658 /* 659 * Read in data segment. 660 */ 661 (void) vn_rdwr(UIO_READ, vp, vm->vm_daddr, (int) ep->a_data, 662 (off_t)(toff + ep->a_text), UIO_USERSPACE, 663 (IO_UNIT|IO_NODELOCKED), cred, (int *)0, p); 664 /* 665 * Read in text segment if necessary (0410), 666 * and read-protect it. 667 */ 668 if (ep->a_text > 0) { 669 error = vn_rdwr(UIO_READ, vp, vm->vm_taddr, 670 (int)ep->a_text, toff, UIO_USERSPACE, 671 (IO_UNIT|IO_NODELOCKED), cred, (int *)0, p); 672 (void) vm_map_protect(&vm->vm_map, 673 (vm_offset_t)vm->vm_taddr, 674 (vm_offset_t)vm->vm_taddr + trunc_page(ep->a_text), 675 VM_PROT_READ|VM_PROT_EXECUTE, FALSE); 676 } 677 } else { 678 /* 679 * Allocate a region backed by the exec'ed vnode. 680 */ 681 #ifndef COFF 682 addr = VM_MIN_ADDRESS; 683 size = round_page(xts + ep->a_data); 684 error = vm_mmap(&vm->vm_map, &addr, size, 685 VM_PROT_ALL, VM_PROT_ALL, 686 MAP_COPY|MAP_FIXED, 687 (caddr_t)vp, (vm_offset_t)toff); 688 (void) vm_map_protect(&vm->vm_map, addr, addr + xts, 689 VM_PROT_READ|VM_PROT_EXECUTE, FALSE); 690 #else /* COFF */ 691 addr = (vm_offset_t)vm->vm_taddr; 692 size = xts; 693 error = vm_mmap(&vm->vm_map, &addr, size, 694 VM_PROT_READ|VM_PROT_EXECUTE, VM_PROT_ALL, 695 MAP_COPY|MAP_FIXED, 696 (caddr_t)vp, (vm_offset_t)toff); 697 toff += size; 698 addr = (vm_offset_t)vm->vm_daddr; 699 size = round_page(ep->a_data); 700 error = vm_mmap(&vm->vm_map, &addr, size, 701 VM_PROT_ALL, VM_PROT_ALL, 702 MAP_COPY|MAP_FIXED, 703 (caddr_t)vp, (vm_offset_t)toff); 704 #endif /* COFF */ 705 vp->v_flag |= VTEXT; 706 } 707 if (error) { 708 badmap: 709 killproc(p, "VM allocation in exec"); 710 p->p_flag |= P_NOSWAP; 711 return(error); 712 } 713 714 /* 715 * set SUID/SGID protections, if no tracing 716 */ 717 p->p_flag &= ~P_SUGID; 718 if ((p->p_flag & P_TRACED) == 0) { 719 if (uid != cred->cr_uid || gid != cred->cr_gid) { 720 p->p_ucred = cred = crcopy(cred); 721 #ifdef KTRACE 722 /* 723 * If process is being ktraced, turn off - unless 724 * root set it. 725 */ 726 if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) { 727 vrele(p->p_tracep); 728 p->p_tracep = NULL; 729 p->p_traceflag = 0; 730 } 731 #endif 732 cred->cr_uid = uid; 733 cred->cr_gid = gid; 734 p->p_flag |= P_SUGID; 735 } 736 } else 737 psignal(p, SIGTRAP); 738 p->p_cred->p_svuid = cred->cr_uid; 739 p->p_cred->p_svgid = cred->cr_gid; 740 vm->vm_tsize = btoc(xts); 741 vm->vm_dsize = ds; 742 vm->vm_ssize = btoc(ssize); 743 if (p->p_flag & P_PROFIL) 744 stopprofclock(p); 745 #if defined(tahoe) 746 /* move this when tahoe cpu_exec is created */ 747 p->p_addr->u_pcb.pcb_savacc.faddr = (float *)NULL; 748 #endif 749 return (0); 750 } 751