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