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