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