1 /* 2 * Copyright (c) 1982, 1986, 1989 Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 * 7 * @(#)kern_exec.c 7.32 (Berkeley) 10/19/90 8 */ 9 10 #include "param.h" 11 #include "systm.h" 12 #include "map.h" 13 #include "user.h" 14 #include "kernel.h" 15 #include "proc.h" 16 #include "mount.h" 17 #include "ucred.h" 18 #include "malloc.h" 19 #include "buf.h" 20 #include "vnode.h" 21 #include "seg.h" 22 #include "vm.h" 23 #include "text.h" 24 #include "file.h" 25 #include "uio.h" 26 #include "acct.h" 27 #include "exec.h" 28 #include "ktrace.h" 29 30 #include "machine/reg.h" 31 #include "machine/pte.h" 32 #include "machine/psl.h" 33 #include "machine/mtpr.h" 34 35 #ifdef HPUXCOMPAT 36 #include "../hpux/hpux_exec.h" 37 #endif 38 39 /* 40 * exec system call, with and without environments. 41 */ 42 execv(p, uap, retval) 43 struct proc *p; 44 struct args { 45 char *fname; 46 char **argp; 47 char **envp; 48 } *uap; 49 int *retval; 50 { 51 52 uap->envp = NULL; 53 return (execve(p, uap, retval)); 54 } 55 56 /* ARGSUSED */ 57 execve(p, uap, retval) 58 register struct proc *p; 59 register struct args { 60 char *fname; 61 char **argp; 62 char **envp; 63 } *uap; 64 int *retval; 65 { 66 register nc; 67 register char *cp; 68 register struct buf *bp; 69 struct buf *tbp; 70 int na, ne, ucp, ap, cc; 71 unsigned len; 72 int indir, uid, gid; 73 char *sharg; 74 struct vnode *vp; 75 swblk_t bno; 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 register struct ucred *cred = u.u_cred; 90 register struct nameidata *ndp = &u.u_nd; 91 int resid, error, flags = 0; 92 93 start: 94 ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF; 95 ndp->ni_segflg = UIO_USERSPACE; 96 ndp->ni_dirp = uap->fname; 97 if (error = namei(ndp)) 98 return (error); 99 vp = ndp->ni_vp; 100 bno = 0; 101 bp = 0; 102 indir = 0; 103 uid = cred->cr_uid; 104 gid = cred->cr_gid; 105 if (error = VOP_GETATTR(vp, &vattr, cred)) 106 goto bad; 107 if (vp->v_mount->mnt_flag & MNT_NOEXEC) { 108 error = EACCES; 109 goto bad; 110 } 111 if ((vp->v_mount->mnt_flag & MNT_NOSUID) == 0) { 112 if (vattr.va_mode & VSUID) 113 uid = vattr.va_uid; 114 if (vattr.va_mode & VSGID) 115 gid = vattr.va_gid; 116 } 117 118 again: 119 if (error = VOP_ACCESS(vp, VEXEC, cred)) 120 goto bad; 121 if ((p->p_flag & STRC) && (error = VOP_ACCESS(vp, VREAD, cred))) 122 goto bad; 123 if (vp->v_type != VREG || 124 (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) { 125 error = EACCES; 126 goto bad; 127 } 128 129 /* 130 * Read in first few bytes of file for segment sizes, magic number: 131 * OMAGIC = plain executable 132 * NMAGIC = RO text 133 * ZMAGIC = demand paged RO text 134 * Also an ASCII line beginning with #! is 135 * the file name of a ``shell'' and arguments may be prepended 136 * to the argument list if given here. 137 * 138 * SHELL NAMES ARE LIMITED IN LENGTH. 139 * 140 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM 141 * THE ASCII LINE. 142 */ 143 exdata.ex_shell[0] = '\0'; /* for zero length files */ 144 error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata), 145 (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), cred, &resid); 146 if (error) 147 goto bad; 148 #ifndef lint 149 if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) && 150 exdata.ex_shell[0] != '#') { 151 error = ENOEXEC; 152 goto bad; 153 } 154 #endif 155 #if defined(hp300) 156 switch ((int)exdata.ex_exec.a_mid) { 157 158 /* 159 * An ancient hp200 or hp300 binary, shouldn't happen anymore. 160 * Mark as invalid. 161 */ 162 case MID_ZERO: 163 exdata.ex_exec.a_magic = 0; 164 break; 165 166 /* 167 * HP200 series has a smaller page size so we cannot 168 * demand-load or even write protect text, so we just 169 * treat as OMAGIC. 170 */ 171 case MID_HP200: 172 exdata.ex_exec.a_magic = OMAGIC; 173 break; 174 175 case MID_HP300: 176 break; 177 178 #ifdef HPUXCOMPAT 179 case MID_HPUX: 180 /* 181 * Save a.out header. This is eventually saved in the pcb, 182 * but we cannot do that yet in case the exec fails before 183 * the image is overlayed. 184 */ 185 bcopy((caddr_t)&exdata.ex_hexec, 186 (caddr_t)&hhead, sizeof hhead); 187 /* 188 * If version number is 0x2bad this is a native BSD 189 * binary created via the HPUX SGS. Should not be 190 * treated as an HPUX binary. 191 */ 192 if (exdata.ex_hexec.ha_version != BSDVNUM) 193 flags |= SHPUX; 194 /* 195 * Shuffle important fields to their BSD locations. 196 * Note that the order in which this is done is important. 197 */ 198 exdata.ex_exec.a_text = exdata.ex_hexec.ha_text; 199 exdata.ex_exec.a_data = exdata.ex_hexec.ha_data; 200 exdata.ex_exec.a_bss = exdata.ex_hexec.ha_bss; 201 exdata.ex_exec.a_entry = exdata.ex_hexec.ha_entry; 202 /* 203 * For ZMAGIC files, make sizes consistant with those 204 * generated by BSD ld. 205 */ 206 if (exdata.ex_exec.a_magic == ZMAGIC) { 207 exdata.ex_exec.a_text = 208 ctob(btoc(exdata.ex_exec.a_text)); 209 nc = exdata.ex_exec.a_data + exdata.ex_exec.a_bss; 210 exdata.ex_exec.a_data = 211 ctob(btoc(exdata.ex_exec.a_data)); 212 nc -= (int)exdata.ex_exec.a_data; 213 exdata.ex_exec.a_bss = (nc < 0) ? 0 : nc; 214 } 215 break; 216 #endif 217 } 218 #endif 219 switch ((int)exdata.ex_exec.a_magic) { 220 221 case OMAGIC: 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 flags |= SPAGV; 228 case NMAGIC: 229 if (exdata.ex_exec.a_text == 0) { 230 error = ENOEXEC; 231 goto bad; 232 } 233 break; 234 235 default: 236 if (exdata.ex_shell[0] != '#' || 237 exdata.ex_shell[1] != '!' || 238 indir) { 239 error = ENOEXEC; 240 goto bad; 241 } 242 for (cp = &exdata.ex_shell[2];; ++cp) { 243 if (cp >= &exdata.ex_shell[MAXINTERP]) { 244 error = ENOEXEC; 245 goto bad; 246 } 247 if (*cp == '\n') { 248 *cp = '\0'; 249 break; 250 } 251 if (*cp == '\t') 252 *cp = ' '; 253 } 254 cp = &exdata.ex_shell[2]; 255 while (*cp == ' ') 256 cp++; 257 ndp->ni_dirp = cp; 258 while (*cp && *cp != ' ') 259 cp++; 260 cfarg[0] = '\0'; 261 if (*cp) { 262 *cp++ = '\0'; 263 while (*cp == ' ') 264 cp++; 265 if (*cp) 266 bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP); 267 } 268 indir = 1; 269 vput(vp); 270 ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF; 271 ndp->ni_segflg = UIO_SYSSPACE; 272 if (error = namei(ndp)) 273 return (error); 274 vp = ndp->ni_vp; 275 if (error = VOP_GETATTR(vp, &vattr, cred)) 276 goto bad; 277 bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname, 278 MAXCOMLEN); 279 cfname[MAXCOMLEN] = '\0'; 280 uid = cred->cr_uid; /* shell scripts can't be setuid */ 281 gid = cred->cr_gid; 282 goto again; 283 } 284 /* 285 * If the vnode has been modified since we last used it, 286 * then throw away all its pages and its text table entry. 287 */ 288 if (vp->v_text && vp->v_text->x_mtime != vattr.va_mtime.tv_sec) { 289 /* 290 * Try once to release, if it is still busy 291 * take more drastic action. 292 */ 293 xrele(vp); 294 if (vp->v_flag & VTEXT) { 295 vput(vp); 296 vgone(vp); 297 goto start; 298 } 299 } 300 301 /* 302 * Collect arguments on "file" in swap space. 303 */ 304 na = 0; 305 ne = 0; 306 nc = 0; 307 cc = 0; 308 bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS)))); 309 if (bno == 0) { 310 swkill(p, "exec: no swap space"); 311 goto bad; 312 } 313 if (bno % CLSIZE) 314 panic("execa rmalloc"); 315 #ifdef GENERIC 316 if (rootdev == dumpdev) 317 bno += 4096; 318 #endif 319 /* 320 * Copy arguments into file in argdev area. 321 */ 322 if (uap->argp) for (;;) { 323 ap = NULL; 324 sharg = NULL; 325 if (indir && na == 0) { 326 sharg = cfname; 327 ap = (int)sharg; 328 uap->argp++; /* ignore argv[0] */ 329 } else if (indir && (na == 1 && cfarg[0])) { 330 sharg = cfarg; 331 ap = (int)sharg; 332 } else if (indir && (na == 1 || na == 2 && cfarg[0])) 333 ap = (int)uap->fname; 334 else if (uap->argp) { 335 ap = fuword((caddr_t)uap->argp); 336 uap->argp++; 337 } 338 if (ap == NULL && uap->envp) { 339 uap->argp = NULL; 340 if ((ap = fuword((caddr_t)uap->envp)) != NULL) 341 uap->envp++, ne++; 342 } 343 if (ap == NULL) 344 break; 345 na++; 346 if (ap == -1) { 347 error = EFAULT; 348 if (bp) { 349 brelse(bp); 350 bp = 0; 351 } 352 goto badarg; 353 } 354 do { 355 if (cc <= 0) { 356 /* 357 * We depend on NCARGS being a multiple of 358 * CLBYTES. This way we need only check 359 * overflow before each buffer allocation. 360 */ 361 if (nc >= NCARGS-1) { 362 error = E2BIG; 363 break; 364 } 365 if (bp) 366 bdwrite(bp); 367 cc = CLBYTES; 368 bp = getblk(argdev_vp, bno + ctod(nc/NBPG), cc); 369 cp = bp->b_un.b_addr; 370 } 371 if (sharg) { 372 error = copystr(sharg, cp, (unsigned)cc, &len); 373 sharg += len; 374 } else { 375 error = copyinstr((caddr_t)ap, cp, (unsigned)cc, 376 &len); 377 ap += len; 378 } 379 cp += len; 380 nc += len; 381 cc -= len; 382 } while (error == ENAMETOOLONG); 383 if (error) { 384 if (bp) 385 brelse(bp); 386 bp = 0; 387 goto badarg; 388 } 389 } 390 if (bp) 391 bdwrite(bp); 392 bp = 0; 393 nc = (nc + NBPW-1) & ~(NBPW-1); 394 error = getxfile(p, vp, &exdata.ex_exec, flags, nc + (na+4)*NBPW, 395 uid, gid); 396 if (error) { 397 badarg: 398 for (cc = 0; cc < nc; cc += CLBYTES) { 399 (void) baddr(argdev_vp, bno + ctod(cc/NBPG), 400 CLBYTES, NOCRED, &tbp); 401 bp = tbp; 402 if (bp) { 403 bp->b_flags |= B_INVAL; /* throw away */ 404 brelse(bp); 405 bp = 0; 406 } 407 } 408 goto bad; 409 } 410 if (vp->v_text) 411 vp->v_text->x_mtime = vattr.va_mtime.tv_sec; 412 vput(vp); 413 vp = NULL; 414 415 #ifdef HPUXCOMPAT 416 /* 417 * We are now committed to the exec so we can save the exec 418 * header in the pcb where we can dump it if necessary in core() 419 */ 420 if (u.u_pcb.pcb_flags & PCB_HPUXBIN) 421 bcopy((caddr_t)&hhead, 422 (caddr_t)u.u_pcb.pcb_exec, sizeof hhead); 423 #endif 424 425 /* 426 * Copy back arglist. 427 */ 428 ucp = USRSTACK - nc - NBPW; 429 ap = ucp - na*NBPW - 3*NBPW; 430 u.u_ar0[SP] = ap; 431 (void) suword((caddr_t)ap, na-ne); 432 nc = 0; 433 cc = 0; 434 for (;;) { 435 ap += NBPW; 436 if (na == ne) { 437 (void) suword((caddr_t)ap, 0); 438 ap += NBPW; 439 } 440 if (--na < 0) 441 break; 442 (void) suword((caddr_t)ap, ucp); 443 do { 444 if (cc <= 0) { 445 if (bp) 446 brelse(bp); 447 cc = CLBYTES; 448 error = bread(argdev_vp, 449 (daddr_t)(bno + ctod(nc / NBPG)), cc, 450 NOCRED, &tbp); 451 bp = tbp; 452 bp->b_flags |= B_INVAL; /* throw away */ 453 cp = bp->b_un.b_addr; 454 } 455 error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc, 456 &len); 457 ucp += len; 458 cp += len; 459 nc += len; 460 cc -= len; 461 } while (error == ENAMETOOLONG); 462 if (error == EFAULT) 463 panic("exec: EFAULT"); 464 } 465 (void) suword((caddr_t)ap, 0); 466 467 execsigs(p); 468 469 for (nc = u.u_lastfile; nc >= 0; --nc) { 470 if (u.u_pofile[nc] & UF_EXCLOSE) { 471 (void) closef(u.u_ofile[nc]); 472 u.u_ofile[nc] = NULL; 473 u.u_pofile[nc] = 0; 474 } 475 u.u_pofile[nc] &= ~UF_MAPPED; 476 } 477 while (u.u_lastfile >= 0 && u.u_ofile[u.u_lastfile] == NULL) 478 u.u_lastfile--; 479 setregs(exdata.ex_exec.a_entry, retval); 480 /* 481 * Remember file name for accounting. 482 */ 483 u.u_acflag &= ~AFORK; 484 if (indir) 485 bcopy((caddr_t)cfname, (caddr_t)p->p_comm, MAXCOMLEN); 486 else { 487 if (ndp->ni_dent.d_namlen > MAXCOMLEN) 488 ndp->ni_dent.d_namlen = MAXCOMLEN; 489 bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)p->p_comm, 490 (unsigned)(ndp->ni_dent.d_namlen + 1)); 491 } 492 bad: 493 if (bp) 494 brelse(bp); 495 if (bno) 496 rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno); 497 if (vp) 498 vput(vp); 499 return (error); 500 } 501 502 /* 503 * Read in and set up memory for executed file. 504 */ 505 getxfile(p, vp, ep, flags, nargc, uid, gid) 506 register struct proc *p; 507 register struct vnode *vp; 508 register struct exec *ep; 509 int flags, nargc, uid, gid; 510 { 511 segsz_t ts, ds, ids, uds, ss; 512 register struct ucred *cred = u.u_cred; 513 off_t toff; 514 int error; 515 516 #ifdef HPUXCOMPAT 517 if (ep->a_mid == MID_HPUX) 518 toff = sizeof (struct hpux_exec); 519 else 520 #endif 521 toff = sizeof (struct exec); 522 if (vp->v_text && (vp->v_text->x_flag & XTRC)) 523 return (ETXTBSY); 524 if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 && 525 vp->v_usecount != 1) { 526 register struct file *fp; 527 528 for (fp = file; fp < fileNFILE; fp++) { 529 if (fp->f_type == DTYPE_VNODE && 530 fp->f_count > 0 && 531 (struct vnode *)fp->f_data == vp && 532 (fp->f_flag & FWRITE)) { 533 return (ETXTBSY); 534 } 535 } 536 } 537 538 /* 539 * Compute text and data sizes and make sure not too large. 540 * NB - Check data and bss separately as they may overflow 541 * when summed together. 542 */ 543 ts = clrnd(btoc(ep->a_text)); 544 ids = clrnd(btoc(ep->a_data)); 545 uds = clrnd(btoc(ep->a_bss)); 546 ds = clrnd(btoc(ep->a_data + ep->a_bss)); 547 ss = clrnd(SSIZE + btoc(nargc)); 548 if (error = 549 chksize((unsigned)ts, (unsigned)ids, (unsigned)uds, (unsigned)ss)) 550 return (error); 551 552 /* 553 * Make sure enough space to start process. 554 */ 555 u.u_cdmap = zdmap; 556 u.u_csmap = zdmap; 557 if (error = swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap)) 558 return (error); 559 560 /* 561 * At this point, we are committed to the new image! 562 * Release virtual memory resources of old process, and 563 * initialize the virtual memory of the new process. 564 * If we resulted from vfork(), instead wakeup our 565 * parent who will set SVFDONE when he has taken back 566 * our resources. 567 */ 568 if ((p->p_flag & SVFORK) == 0) { 569 #ifdef MAPMEM 570 if (u.u_mmap && (error = mmexec(p))) 571 return (error); 572 #endif 573 vrelvm(); 574 } else { 575 p->p_flag &= ~SVFORK; 576 p->p_flag |= SKEEP; 577 wakeup((caddr_t)p); 578 while ((p->p_flag & SVFDONE) == 0) 579 sleep((caddr_t)p, PZERO - 1); 580 p->p_flag &= ~(SVFDONE|SKEEP); 581 } 582 #ifdef hp300 583 u.u_pcb.pcb_flags &= ~(PCB_AST|PCB_HPUXMMAP|PCB_HPUXBIN); 584 #ifdef HPUXCOMPAT 585 /* remember that we were loaded from an HPUX format file */ 586 if (ep->a_mid == MID_HPUX) 587 u.u_pcb.pcb_flags |= PCB_HPUXBIN; 588 #endif 589 #endif 590 p->p_flag &= ~(SPAGV|SSEQL|SUANOM|SHPUX); 591 p->p_flag |= flags | SEXEC; 592 u.u_dmap = u.u_cdmap; 593 u.u_smap = u.u_csmap; 594 vgetvm(ts, ds, ss); 595 596 if ((flags & SPAGV) == 0) 597 (void) vn_rdwr(UIO_READ, vp, 598 (char *)ctob(dptov(p, 0)), 599 (int)ep->a_data, 600 (off_t)(toff + ep->a_text), 601 UIO_USERSPACE, (IO_UNIT|IO_NODELOCKED), cred, (int *)0); 602 xalloc(vp, ep, toff, cred); 603 #if defined(tahoe) 604 /* 605 * Define new keys. 606 */ 607 if (p->p_textp == 0) { /* use existing code key if shared */ 608 ckeyrelease(p->p_ckey); 609 p->p_ckey = getcodekey(); 610 } 611 mtpr(CCK, p->p_ckey); 612 dkeyrelease(p->p_dkey); 613 p->p_dkey = getdatakey(); 614 mtpr(DCK, p->p_dkey); 615 #endif 616 if ((flags & SPAGV) && p->p_textp) 617 vinifod(p, (struct fpte *)dptopte(p, 0), 618 PG_FTEXT, p->p_textp->x_vptr, 619 (long)(1 + ts/CLSIZE), (segsz_t)btoc(ep->a_data)); 620 621 #if defined(vax) || defined(tahoe) 622 /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */ 623 mtpr(TBIA, 0); 624 #endif 625 #ifdef hp300 626 TBIAU(); 627 #endif 628 #if defined(i386) 629 tlbflush(); 630 #endif 631 632 /* 633 * set SUID/SGID protections, if no tracing 634 */ 635 if ((p->p_flag&STRC)==0) { 636 if (uid != cred->cr_uid || gid != cred->cr_gid) { 637 u.u_cred = cred = crcopy(cred); 638 /* 639 * If process is being ktraced, turn off - unless 640 * root set it. 641 */ 642 if (p->p_tracep && !(p->p_traceflag & KTRFAC_ROOT)) { 643 vrele(p->p_tracep); 644 p->p_tracep = NULL; 645 p->p_traceflag = 0; 646 } 647 } 648 cred->cr_uid = uid; 649 cred->cr_gid = gid; 650 p->p_uid = uid; 651 } else 652 psignal(p, SIGTRAP); 653 p->p_svuid = p->p_uid; 654 p->p_svgid = cred->cr_gid; 655 u.u_tsize = ts; 656 u.u_dsize = ds; 657 u.u_ssize = ss; 658 u.u_prof.pr_scale = 0; 659 #if defined(tahoe) 660 u.u_pcb.pcb_savacc.faddr = (float *)NULL; 661 #endif 662 return (0); 663 } 664