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