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.43 (Berkeley) 05/09/91 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 "seg.h" 20 #include "file.h" 21 #include "acct.h" 22 #include "exec.h" 23 #include "ktrace.h" 24 #include "resourcevar.h" 25 26 #include "machine/cpu.h" 27 #include "machine/reg.h" 28 29 #include "mman.h" 30 #include "vm/vm.h" 31 #include "vm/vm_param.h" 32 #include "vm/vm_map.h" 33 #include "vm/vm_kern.h" 34 #include "vm/vm_pager.h" 35 36 #include "signalvar.h" 37 #include "kinfo_proc.h" 38 39 #ifdef HPUXCOMPAT 40 #include "user.h" /* for pcb */ 41 #include "hp300/hpux/hpux_exec.h" 42 #endif 43 44 #ifdef COPY_SIGCODE 45 extern char sigcode[], esigcode[]; 46 #define szsigcode (esigcode - sigcode) 47 #else 48 #define szsigcode 0 49 #endif 50 51 /* 52 * exec system call 53 */ 54 /* ARGSUSED */ 55 execve(p, uap, retval) 56 register struct proc *p; 57 register struct args { 58 char *fname; 59 char **argp; 60 char **envp; 61 } *uap; 62 int *retval; 63 { 64 register struct ucred *cred = p->p_ucred; 65 register struct nameidata *ndp; 66 register struct filedesc *fdp = p->p_fd; 67 int na, ne, ucp, ap, cc; 68 register char *cp; 69 register int nc; 70 unsigned len; 71 int indir, uid, gid; 72 char *sharg; 73 struct vnode *vp; 74 int resid, error, paged = 0; 75 vm_offset_t execargs; 76 struct vattr vattr; 77 char cfname[MAXCOMLEN + 1]; 78 char cfarg[MAXINTERP]; 79 union { 80 char ex_shell[MAXINTERP]; /* #! and interpreter name */ 81 struct exec ex_exec; 82 #ifdef HPUXCOMPAT 83 struct hpux_exec ex_hexec; 84 #endif 85 } exdata; 86 #ifdef HPUXCOMPAT 87 struct hpux_exec hhead; 88 #endif 89 struct nameidata nd; 90 91 ndp = &nd; 92 start: 93 ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF; 94 ndp->ni_segflg = UIO_USERSPACE; 95 ndp->ni_dirp = uap->fname; 96 if (error = namei(ndp, p)) 97 return (error); 98 vp = ndp->ni_vp; 99 indir = 0; 100 uid = cred->cr_uid; 101 gid = cred->cr_gid; 102 if (error = VOP_GETATTR(vp, &vattr, cred, p)) 103 goto bad; 104 if (vp->v_mount->mnt_flag & MNT_NOEXEC) { 105 error = EACCES; 106 goto bad; 107 } 108 if ((vp->v_mount->mnt_flag & MNT_NOSUID) == 0) { 109 if (vattr.va_mode & VSUID) 110 uid = vattr.va_uid; 111 if (vattr.va_mode & VSGID) 112 gid = vattr.va_gid; 113 } 114 115 again: 116 if (error = VOP_ACCESS(vp, VEXEC, cred, p)) 117 goto bad; 118 if ((p->p_flag & STRC) && (error = VOP_ACCESS(vp, VREAD, cred, p))) 119 goto bad; 120 if (vp->v_type != VREG || 121 (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) { 122 error = EACCES; 123 goto bad; 124 } 125 126 /* 127 * Read in first few bytes of file for segment sizes, magic number: 128 * OMAGIC = plain executable 129 * NMAGIC = RO text 130 * ZMAGIC = demand paged RO text 131 * Also an ASCII line beginning with #! is 132 * the file name of a ``shell'' and arguments may be prepended 133 * to the argument list if given here. 134 * 135 * SHELL NAMES ARE LIMITED IN LENGTH. 136 * 137 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM 138 * THE ASCII LINE. 139 */ 140 exdata.ex_shell[0] = '\0'; /* for zero length files */ 141 error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata), 142 (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), cred, &resid, 143 (struct proc *)0); 144 if (error) 145 goto bad; 146 #ifndef lint 147 if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) && 148 exdata.ex_shell[0] != '#') { 149 error = ENOEXEC; 150 goto bad; 151 } 152 #endif 153 #if defined(hp300) 154 switch ((int)exdata.ex_exec.a_mid) { 155 156 /* 157 * An ancient hp200 or hp300 binary, shouldn't happen anymore. 158 * Mark as invalid. 159 */ 160 case MID_ZERO: 161 exdata.ex_exec.a_magic = 0; 162 break; 163 164 /* 165 * HP200 series has a smaller page size so we cannot 166 * demand-load or even write protect text, so we just 167 * treat as OMAGIC. 168 */ 169 case MID_HP200: 170 exdata.ex_exec.a_magic = OMAGIC; 171 break; 172 173 case MID_HP300: 174 break; 175 176 #ifdef HPUXCOMPAT 177 case MID_HPUX: 178 /* 179 * Save a.out header. This is eventually saved in the pcb, 180 * but we cannot do that yet in case the exec fails before 181 * the image is overlayed. 182 */ 183 bcopy((caddr_t)&exdata.ex_hexec, 184 (caddr_t)&hhead, sizeof hhead); 185 /* 186 * If version number is 0x2bad this is a native BSD 187 * binary created via the HPUX SGS. Should not be 188 * treated as an HPUX binary. 189 */ 190 if (exdata.ex_hexec.ha_version != BSDVNUM) 191 paged |= SHPUX; /* XXX */ 192 /* 193 * Shuffle important fields to their BSD locations. 194 * Note that the order in which this is done is important. 195 */ 196 exdata.ex_exec.a_text = exdata.ex_hexec.ha_text; 197 exdata.ex_exec.a_data = exdata.ex_hexec.ha_data; 198 exdata.ex_exec.a_bss = exdata.ex_hexec.ha_bss; 199 exdata.ex_exec.a_entry = exdata.ex_hexec.ha_entry; 200 /* 201 * For ZMAGIC files, make sizes consistant with those 202 * generated by BSD ld. 203 */ 204 if (exdata.ex_exec.a_magic == ZMAGIC) { 205 exdata.ex_exec.a_text = 206 ctob(btoc(exdata.ex_exec.a_text)); 207 nc = exdata.ex_exec.a_data + exdata.ex_exec.a_bss; 208 exdata.ex_exec.a_data = 209 ctob(btoc(exdata.ex_exec.a_data)); 210 nc -= (int)exdata.ex_exec.a_data; 211 exdata.ex_exec.a_bss = (nc < 0) ? 0 : nc; 212 } 213 break; 214 #endif 215 } 216 #endif 217 switch ((int)exdata.ex_exec.a_magic) { 218 219 case OMAGIC: 220 exdata.ex_exec.a_data += exdata.ex_exec.a_text; 221 exdata.ex_exec.a_text = 0; 222 break; 223 224 case ZMAGIC: 225 paged++; 226 /* FALLTHROUGH */ 227 case NMAGIC: 228 if (exdata.ex_exec.a_text == 0) { 229 error = ENOEXEC; 230 goto bad; 231 } 232 break; 233 234 default: 235 if (exdata.ex_shell[0] != '#' || 236 exdata.ex_shell[1] != '!' || 237 indir) { 238 error = ENOEXEC; 239 goto bad; 240 } 241 for (cp = &exdata.ex_shell[2];; ++cp) { 242 if (cp >= &exdata.ex_shell[MAXINTERP]) { 243 error = ENOEXEC; 244 goto bad; 245 } 246 if (*cp == '\n') { 247 *cp = '\0'; 248 break; 249 } 250 if (*cp == '\t') 251 *cp = ' '; 252 } 253 cp = &exdata.ex_shell[2]; 254 while (*cp == ' ') 255 cp++; 256 ndp->ni_dirp = cp; 257 while (*cp && *cp != ' ') 258 cp++; 259 cfarg[0] = '\0'; 260 if (*cp) { 261 *cp++ = '\0'; 262 while (*cp == ' ') 263 cp++; 264 if (*cp) 265 bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP); 266 } 267 indir = 1; 268 vput(vp); 269 ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF; 270 ndp->ni_segflg = UIO_SYSSPACE; 271 if (error = namei(ndp, p)) 272 return (error); 273 vp = ndp->ni_vp; 274 if (error = VOP_GETATTR(vp, &vattr, cred, p)) 275 goto bad; 276 bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname, 277 MAXCOMLEN); 278 cfname[MAXCOMLEN] = '\0'; 279 uid = cred->cr_uid; /* shell scripts can't be setuid */ 280 gid = cred->cr_gid; 281 goto again; 282 } 283 284 /* 285 * Collect arguments on "file" in swap space. 286 */ 287 na = 0; 288 ne = 0; 289 nc = 0; 290 cc = NCARGS; 291 execargs = kmem_alloc_wait(exec_map, NCARGS); 292 cp = (char *) execargs; 293 /* 294 * Copy arguments into file in argdev area. 295 */ 296 if (uap->argp) for (;;) { 297 ap = NULL; 298 sharg = NULL; 299 if (indir && na == 0) { 300 sharg = cfname; 301 ap = (int)sharg; 302 uap->argp++; /* ignore argv[0] */ 303 } else if (indir && (na == 1 && cfarg[0])) { 304 sharg = cfarg; 305 ap = (int)sharg; 306 } else if (indir && (na == 1 || na == 2 && cfarg[0])) 307 ap = (int)uap->fname; 308 else if (uap->argp) { 309 ap = fuword((caddr_t)uap->argp); 310 uap->argp++; 311 } 312 if (ap == NULL && uap->envp) { 313 uap->argp = NULL; 314 if ((ap = fuword((caddr_t)uap->envp)) != NULL) 315 uap->envp++, ne++; 316 } 317 if (ap == NULL) 318 break; 319 na++; 320 if (ap == -1) { 321 error = EFAULT; 322 goto bad; 323 } 324 do { 325 if (nc >= NCARGS-1) { 326 error = E2BIG; 327 break; 328 } 329 if (sharg) { 330 error = copystr(sharg, cp, (unsigned)cc, &len); 331 sharg += len; 332 } else { 333 error = copyinstr((caddr_t)ap, cp, (unsigned)cc, 334 &len); 335 ap += len; 336 } 337 cp += len; 338 nc += len; 339 cc -= len; 340 } while (error == ENAMETOOLONG); 341 if (error) 342 goto bad; 343 } 344 nc = (nc + NBPW-1) & ~(NBPW-1); 345 error = getxfile(p, vp, &exdata.ex_exec, paged, nc + (na+4)*NBPW, 346 uid, gid); 347 if (error) 348 goto bad; 349 vput(vp); 350 vp = NULL; 351 352 #ifdef HPUXCOMPAT 353 /* 354 * We are now committed to the exec so we can save the exec 355 * header in the pcb where we can dump it if necessary in core() 356 */ 357 if (p->p_addr->u_pcb.pcb_flags & PCB_HPUXBIN) 358 bcopy((caddr_t)&hhead, 359 (caddr_t)p->p_addr->u_pcb.pcb_exec, sizeof hhead); 360 #endif 361 362 /* 363 * Copy back arglist. 364 */ 365 ucp = USRSTACK - szsigcode - nc - NBPW; 366 ap = ucp - na*NBPW - 3*NBPW; 367 p->p_regs[SP] = ap; 368 (void) suword((caddr_t)ap, na-ne); 369 nc = 0; 370 cp = (char *) execargs; 371 cc = NCARGS; 372 for (;;) { 373 ap += NBPW; 374 if (na == ne) { 375 (void) suword((caddr_t)ap, 0); 376 ap += NBPW; 377 } 378 if (--na < 0) 379 break; 380 (void) suword((caddr_t)ap, ucp); 381 do { 382 error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc, 383 &len); 384 ucp += len; 385 cp += len; 386 nc += len; 387 cc -= len; 388 } while (error == ENAMETOOLONG); 389 if (error == EFAULT) 390 panic("exec: EFAULT"); 391 } 392 (void) suword((caddr_t)ap, 0); 393 394 execsigs(p); 395 396 for (nc = fdp->fd_lastfile; nc >= 0; --nc) { 397 if (fdp->fd_ofileflags[nc] & UF_EXCLOSE) { 398 (void) closef(fdp->fd_ofiles[nc], p); 399 fdp->fd_ofiles[nc] = NULL; 400 fdp->fd_ofileflags[nc] = 0; 401 if (nc < fdp->fd_freefile) 402 fdp->fd_freefile = nc; 403 } 404 fdp->fd_ofileflags[nc] &= ~UF_MAPPED; 405 } 406 /* 407 * Adjust fd_lastfile to account for descriptors closed above. 408 * Don't decrement fd_lastfile past 0, as it's unsigned. 409 */ 410 while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL) 411 fdp->fd_lastfile--; 412 setregs(p, exdata.ex_exec.a_entry, retval); 413 #ifdef COPY_SIGCODE 414 /* 415 * Install sigcode at top of user stack. 416 */ 417 copyout((caddr_t)sigcode, (caddr_t)(USRSTACK - szsigcode), szsigcode); 418 #endif 419 /* 420 * Remember file name for accounting. 421 */ 422 p->p_acflag &= ~AFORK; 423 if (indir) 424 bcopy((caddr_t)cfname, (caddr_t)p->p_comm, MAXCOMLEN); 425 else { 426 if (ndp->ni_dent.d_namlen > MAXCOMLEN) 427 ndp->ni_dent.d_namlen = MAXCOMLEN; 428 bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)p->p_comm, 429 (unsigned)(ndp->ni_dent.d_namlen + 1)); 430 } 431 cpu_exec(p); 432 bad: 433 if (execargs) 434 kmem_free_wakeup(exec_map, execargs, NCARGS); 435 if (vp) 436 vput(vp); 437 return (error); 438 } 439 440 /* 441 * Read in and set up memory for executed file. 442 */ 443 getxfile(p, vp, ep, paged, nargc, uid, gid) 444 register struct proc *p; 445 register struct vnode *vp; 446 register struct exec *ep; 447 int paged, nargc, uid, gid; 448 { 449 segsz_t ts, ds, ss; 450 register struct ucred *cred = p->p_ucred; 451 off_t toff; 452 int error = 0; 453 vm_offset_t addr; 454 vm_size_t size; 455 struct vmspace *vm = p->p_vmspace; 456 457 #ifdef HPUXCOMPAT 458 int hpux = (paged & SHPUX); 459 paged &= ~SHPUX; 460 if (ep->a_mid == MID_HPUX) { 461 if (paged) 462 toff = CLBYTES; 463 else 464 toff = sizeof (struct hpux_exec); 465 } else 466 #endif 467 if (paged) 468 toff = CLBYTES; 469 else 470 toff = sizeof (struct exec); 471 if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 && 472 vp->v_usecount != 1) { 473 register struct file *fp; 474 475 for (fp = file; fp < fileNFILE; fp++) { 476 if (fp->f_type == DTYPE_VNODE && 477 fp->f_count > 0 && 478 (struct vnode *)fp->f_data == vp && 479 (fp->f_flag & FWRITE)) { 480 return (ETXTBSY); 481 } 482 } 483 } 484 485 /* 486 * Compute text and data sizes and make sure not too large. 487 * NB - Check data and bss separately as they may overflow 488 * when summed together. 489 */ 490 ts = clrnd(btoc(ep->a_text)); 491 ds = clrnd(btoc(ep->a_data + ep->a_bss)); 492 ss = clrnd(SSIZE + btoc(nargc + szsigcode)); 493 494 /* 495 * If we're sharing the address space, allocate a new space 496 * and release our reference to the old one. Otherwise, 497 * empty out the existing vmspace. 498 */ 499 if (vm->vm_refcnt > 1) { 500 p->p_vmspace = vmspace_alloc(VM_MIN_ADDRESS, 501 VM_MAXUSER_ADDRESS, 1); 502 vmspace_free(vm); 503 vm = p->p_vmspace; 504 } else { 505 #ifdef SYSVSHM 506 if (vm->vm_shm) 507 shmexit(p); 508 #endif 509 (void) vm_map_remove(&vm->vm_map, VM_MIN_ADDRESS, 510 VM_MAXUSER_ADDRESS); 511 } 512 /* 513 * If parent is waiting for us to exec or exit, 514 * SPPWAIT will be set; clear it and wakeup parent. 515 */ 516 if (p->p_flag & SPPWAIT) { 517 p->p_flag &= ~SPPWAIT; 518 wakeup((caddr_t) p->p_pptr); 519 } 520 #ifdef HPUXCOMPAT 521 p->p_addr->u_pcb.pcb_flags &= ~(PCB_HPUXMMAP|PCB_HPUXBIN); 522 /* remember that we were loaded from an HPUX format file */ 523 if (ep->a_mid == MID_HPUX) 524 p->p_addr->u_pcb.pcb_flags |= PCB_HPUXBIN; 525 if (hpux) 526 p->p_flag |= SHPUX; 527 else 528 p->p_flag &= ~SHPUX; 529 #endif 530 p->p_flag |= SEXEC; 531 addr = VM_MIN_ADDRESS; 532 if (vm_allocate(&vm->vm_map, &addr, round_page(ctob(ts + ds)), FALSE)) { 533 uprintf("Cannot allocate text+data space\n"); 534 error = ENOMEM; /* XXX */ 535 goto badmap; 536 } 537 size = round_page(MAXSSIZ); /* XXX */ 538 addr = trunc_page(USRSTACK - size); 539 if (vm_allocate(&vm->vm_map, &addr, size, FALSE)) { 540 uprintf("Cannot allocate stack space\n"); 541 error = ENOMEM; /* XXX */ 542 goto badmap; 543 } 544 size -= round_page(p->p_rlimit[RLIMIT_STACK].rlim_cur); 545 if (vm_map_protect(&vm->vm_map, addr, addr+size, VM_PROT_NONE, FALSE)) { 546 uprintf("Cannot protect stack space\n"); 547 error = ENOMEM; 548 goto badmap; 549 } 550 vm->vm_maxsaddr = (caddr_t)addr; 551 vm->vm_taddr = (caddr_t)VM_MIN_ADDRESS; 552 vm->vm_daddr = (caddr_t)(VM_MIN_ADDRESS + ctob(ts)); 553 554 if (paged == 0) { 555 /* 556 * Read in data segment. 557 */ 558 (void) vn_rdwr(UIO_READ, vp, vm->vm_daddr, (int) ep->a_data, 559 (off_t)(toff + ep->a_text), UIO_USERSPACE, 560 (IO_UNIT|IO_NODELOCKED), cred, (int *)0, p); 561 /* 562 * Read in text segment if necessary (0410), 563 * and read-protect it. 564 */ 565 if (ep->a_text > 0) { 566 error = vn_rdwr(UIO_READ, vp, vm->vm_taddr, 567 (int)ep->a_text, toff, UIO_USERSPACE, 568 (IO_UNIT|IO_NODELOCKED), cred, (int *)0, p); 569 (void) vm_map_protect(&vm->vm_map, VM_MIN_ADDRESS, 570 VM_MIN_ADDRESS + trunc_page(ep->a_text), 571 VM_PROT_READ|VM_PROT_EXECUTE, FALSE); 572 } 573 } else { 574 /* 575 * Allocate a region backed by the exec'ed vnode. 576 */ 577 addr = VM_MIN_ADDRESS; 578 size = round_page(ep->a_text + ep->a_data); 579 error = vm_mmap(&vm->vm_map, &addr, size, VM_PROT_ALL, 580 MAP_FILE|MAP_COPY|MAP_FIXED, 581 (caddr_t)vp, (vm_offset_t)toff); 582 (void) vm_map_protect(&vm->vm_map, addr, 583 addr + trunc_page(ep->a_text), 584 VM_PROT_READ|VM_PROT_EXECUTE, FALSE); 585 vp->v_flag |= VTEXT; 586 } 587 badmap: 588 if (error) { 589 printf("pid %d: VM allocation failure\n", p->p_pid); 590 uprintf("sorry, pid %d was killed in exec: VM allocation\n", 591 p->p_pid); 592 psignal(p, SIGKILL); 593 p->p_flag |= SKEEP; 594 return(error); 595 } 596 597 /* 598 * set SUID/SGID protections, if no tracing 599 */ 600 if ((p->p_flag&STRC)==0) { 601 if (uid != cred->cr_uid || gid != cred->cr_gid) { 602 p->p_ucred = cred = crcopy(cred); 603 /* 604 * If process is being ktraced, turn off - unless 605 * root set it. 606 */ 607 if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) { 608 vrele(p->p_tracep); 609 p->p_tracep = NULL; 610 p->p_traceflag = 0; 611 } 612 } 613 cred->cr_uid = uid; 614 cred->cr_gid = gid; 615 } else 616 psignal(p, SIGTRAP); 617 p->p_cred->p_svuid = cred->cr_uid; 618 p->p_cred->p_svgid = cred->cr_gid; 619 vm->vm_tsize = ts; 620 vm->vm_dsize = ds; 621 vm->vm_ssize = ss; 622 p->p_stats->p_prof.pr_scale = 0; 623 #if defined(tahoe) 624 /* move this when tahoe cpu_exec is created */ 625 p->p_addr->u_pcb.pcb_savacc.faddr = (float *)NULL; 626 #endif 627 return (0); 628 } 629