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