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