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.11 (Berkeley) 07/03/89 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 /* 45 * exec system call, with and without environments. 46 */ 47 struct execa { 48 char *fname; 49 char **argp; 50 char **envp; 51 }; 52 53 execv() 54 { 55 ((struct execa *)u.u_ap)->envp = NULL; 56 execve(); 57 } 58 59 execve() 60 { 61 register nc; 62 register char *cp; 63 register struct buf *bp; 64 struct buf *tbp; 65 register struct execa *uap; 66 int na, ne, ucp, ap, cc; 67 unsigned len; 68 int indir, uid, gid; 69 char *sharg; 70 struct vnode *vp; 71 swblk_t bno; 72 struct vattr vattr; 73 char cfname[MAXCOMLEN + 1]; 74 char cfarg[MAXINTERP]; 75 union { 76 char ex_shell[MAXINTERP]; /* #! and interpreter name */ 77 struct exec ex_exec; 78 } exdata; 79 register struct nameidata *ndp = &u.u_nd; 80 int resid, error; 81 82 ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF; 83 ndp->ni_segflg = UIO_USERSPACE; 84 ndp->ni_dirp = ((struct execa *)u.u_ap)->fname; 85 if (u.u_error = namei(ndp)) { 86 return; 87 } 88 vp = ndp->ni_vp; 89 bno = 0; 90 bp = 0; 91 indir = 0; 92 uid = u.u_uid; 93 gid = u.u_gid; 94 if (u.u_error = VOP_GETATTR(vp, &vattr, u.u_cred)) 95 goto bad; 96 if (vp->v_mount->m_flag & M_NOEXEC) { 97 u.u_error = ENOEXEC; 98 goto bad; 99 } 100 if ((vp->v_mount->m_flag & M_NOSUID) == 0) { 101 if (vattr.va_mode & VSUID) 102 uid = vattr.va_uid; 103 if (vattr.va_mode & VSGID) 104 gid = vattr.va_gid; 105 } 106 107 again: 108 if (u.u_error = VOP_ACCESS(vp, VEXEC, u.u_cred)) 109 goto bad; 110 if ((u.u_procp->p_flag & STRC) && 111 (u.u_error = VOP_ACCESS(vp, VREAD, u.u_cred))) 112 goto bad; 113 if (vp->v_type != VREG || 114 (vattr.va_mode & (VEXEC|(VEXEC>>3)|(VEXEC>>6))) == 0) { 115 u.u_error = EACCES; 116 goto bad; 117 } 118 119 /* 120 * Read in first few bytes of file for segment sizes, magic number: 121 * OMAGIC = plain executable 122 * NMAGIC = RO text 123 * ZMAGIC = demand paged RO text 124 * Also an ASCII line beginning with #! is 125 * the file name of a ``shell'' and arguments may be prepended 126 * to the argument list if given here. 127 * 128 * SHELL NAMES ARE LIMITED IN LENGTH. 129 * 130 * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM 131 * THE ASCII LINE. 132 */ 133 exdata.ex_shell[0] = '\0'; /* for zero length files */ 134 u.u_error = vn_rdwr(UIO_READ, vp, (caddr_t)&exdata, sizeof (exdata), 135 (off_t)0, UIO_SYSSPACE, (IO_UNIT|IO_NODELOCKED), u.u_cred, &resid); 136 if (u.u_error) 137 goto bad; 138 #ifndef lint 139 if (resid > sizeof(exdata) - sizeof(exdata.ex_exec) && 140 exdata.ex_shell[0] != '#') { 141 u.u_error = ENOEXEC; 142 goto bad; 143 } 144 #endif 145 switch ((int)exdata.ex_exec.a_magic) { 146 147 case OMAGIC: 148 exdata.ex_exec.a_data += exdata.ex_exec.a_text; 149 exdata.ex_exec.a_text = 0; 150 break; 151 152 case ZMAGIC: 153 case NMAGIC: 154 if (exdata.ex_exec.a_text == 0) { 155 u.u_error = ENOEXEC; 156 goto bad; 157 } 158 break; 159 160 default: 161 if (exdata.ex_shell[0] != '#' || 162 exdata.ex_shell[1] != '!' || 163 indir) { 164 u.u_error = ENOEXEC; 165 goto bad; 166 } 167 for (cp = &exdata.ex_shell[2];; ++cp) { 168 if (cp >= &exdata.ex_shell[MAXINTERP]) { 169 u.u_error = ENOEXEC; 170 goto bad; 171 } 172 if (*cp == '\n') { 173 *cp = '\0'; 174 break; 175 } 176 if (*cp == '\t') 177 *cp = ' '; 178 } 179 cp = &exdata.ex_shell[2]; 180 while (*cp == ' ') 181 cp++; 182 ndp->ni_dirp = cp; 183 while (*cp && *cp != ' ') 184 cp++; 185 cfarg[0] = '\0'; 186 if (*cp) { 187 *cp++ = '\0'; 188 while (*cp == ' ') 189 cp++; 190 if (*cp) 191 bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP); 192 } 193 indir = 1; 194 vput(vp); 195 ndp->ni_nameiop = LOOKUP | FOLLOW | LOCKLEAF; 196 ndp->ni_segflg = UIO_SYSSPACE; 197 if (u.u_error = namei(ndp)) 198 return; 199 vp = ndp->ni_vp; 200 if (u.u_error = VOP_GETATTR(vp, &vattr, u.u_cred)) 201 goto bad; 202 bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname, 203 MAXCOMLEN); 204 cfname[MAXCOMLEN] = '\0'; 205 uid = u.u_uid; /* shell scripts can't be setuid */ 206 gid = u.u_gid; 207 goto again; 208 } 209 210 /* 211 * Collect arguments on "file" in swap space. 212 */ 213 na = 0; 214 ne = 0; 215 nc = 0; 216 cc = 0; 217 uap = (struct execa *)u.u_ap; 218 bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS)))); 219 if (bno == 0) { 220 swkill(u.u_procp, "exec: no swap space"); 221 goto bad; 222 } 223 if (bno % CLSIZE) 224 panic("execa rmalloc"); 225 /* 226 * Copy arguments into file in argdev area. 227 */ 228 if (uap->argp) for (;;) { 229 ap = NULL; 230 sharg = NULL; 231 if (indir && na == 0) { 232 sharg = cfname; 233 ap = (int)sharg; 234 uap->argp++; /* ignore argv[0] */ 235 } else if (indir && (na == 1 && cfarg[0])) { 236 sharg = cfarg; 237 ap = (int)sharg; 238 } else if (indir && (na == 1 || na == 2 && cfarg[0])) 239 ap = (int)uap->fname; 240 else if (uap->argp) { 241 ap = fuword((caddr_t)uap->argp); 242 uap->argp++; 243 } 244 if (ap == NULL && uap->envp) { 245 uap->argp = NULL; 246 if ((ap = fuword((caddr_t)uap->envp)) != NULL) 247 uap->envp++, ne++; 248 } 249 if (ap == NULL) 250 break; 251 na++; 252 if (ap == -1) { 253 u.u_error = EFAULT; 254 break; 255 } 256 do { 257 if (cc <= 0) { 258 /* 259 * We depend on NCARGS being a multiple of 260 * CLBYTES. This way we need only check 261 * overflow before each buffer allocation. 262 */ 263 if (nc >= NCARGS-1) { 264 error = E2BIG; 265 break; 266 } 267 if (bp) 268 bdwrite(bp); 269 cc = CLBYTES; 270 bp = getblk(argdev_vp, bno + ctod(nc/NBPG), cc); 271 cp = bp->b_un.b_addr; 272 } 273 if (sharg) { 274 error = copystr(sharg, cp, (unsigned)cc, &len); 275 sharg += len; 276 } else { 277 error = copyinstr((caddr_t)ap, cp, (unsigned)cc, 278 &len); 279 ap += len; 280 } 281 cp += len; 282 nc += len; 283 cc -= len; 284 } while (error == ENOENT); 285 if (error) { 286 u.u_error = error; 287 if (bp) 288 brelse(bp); 289 bp = 0; 290 goto badarg; 291 } 292 } 293 if (bp) 294 bdwrite(bp); 295 bp = 0; 296 nc = (nc + NBPW-1) & ~(NBPW-1); 297 getxfile(vp, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid, u.u_cred); 298 if (u.u_error) { 299 badarg: 300 for (cc = 0; cc < nc; cc += CLBYTES) { 301 u.u_error = baddr(argdev_vp, bno + ctod(cc/NBPG), 302 CLBYTES, &tbp); 303 bp = tbp; 304 if (bp) { 305 bp->b_flags |= B_AGE; /* throw away */ 306 bp->b_flags &= ~B_DELWRI; /* cancel io */ 307 brelse(bp); 308 bp = 0; 309 } 310 } 311 goto bad; 312 } 313 vput(vp); 314 vp = NULL; 315 316 /* 317 * Copy back arglist. 318 */ 319 ucp = USRSTACK - nc - NBPW; 320 ap = ucp - na*NBPW - 3*NBPW; 321 u.u_ar0[SP] = ap; 322 (void) suword((caddr_t)ap, na-ne); 323 nc = 0; 324 cc = 0; 325 for (;;) { 326 ap += NBPW; 327 if (na == ne) { 328 (void) suword((caddr_t)ap, 0); 329 ap += NBPW; 330 } 331 if (--na < 0) 332 break; 333 (void) suword((caddr_t)ap, ucp); 334 do { 335 if (cc <= 0) { 336 if (bp) 337 brelse(bp); 338 cc = CLBYTES; 339 error = bread(argdev_vp, 340 (daddr_t)(bno + ctod(nc / NBPG)), cc, &tbp); 341 bp = tbp; 342 bp->b_flags |= B_AGE; /* throw away */ 343 bp->b_flags &= ~B_DELWRI; /* cancel io */ 344 cp = bp->b_un.b_addr; 345 } 346 error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc, 347 &len); 348 ucp += len; 349 cp += len; 350 nc += len; 351 cc -= len; 352 } while (error == ENOENT); 353 if (error == EFAULT) 354 panic("exec: EFAULT"); 355 } 356 (void) suword((caddr_t)ap, 0); 357 358 /* 359 * Reset caught signals. Held signals 360 * remain held through p_sigmask. 361 */ 362 while (u.u_procp->p_sigcatch) { 363 nc = ffs((long)u.u_procp->p_sigcatch); 364 u.u_procp->p_sigcatch &= ~sigmask(nc); 365 u.u_signal[nc] = SIG_DFL; 366 } 367 /* 368 * Reset stack state to the user stack. 369 * Clear set of signals caught on the signal stack. 370 */ 371 u.u_onstack = 0; 372 u.u_sigsp = 0; 373 u.u_sigonstack = 0; 374 375 for (nc = u.u_lastfile; nc >= 0; --nc) { 376 if (u.u_pofile[nc] & UF_EXCLOSE) { 377 closef(u.u_ofile[nc]); 378 u.u_ofile[nc] = NULL; 379 u.u_pofile[nc] = 0; 380 } 381 u.u_pofile[nc] &= ~UF_MAPPED; 382 } 383 while (u.u_lastfile >= 0 && u.u_ofile[u.u_lastfile] == NULL) 384 u.u_lastfile--; 385 setregs(exdata.ex_exec.a_entry); 386 /* 387 * Remember file name for accounting. 388 */ 389 u.u_acflag &= ~AFORK; 390 if (indir) 391 bcopy((caddr_t)cfname, (caddr_t)u.u_comm, MAXCOMLEN); 392 else { 393 if (ndp->ni_dent.d_namlen > MAXCOMLEN) 394 ndp->ni_dent.d_namlen = MAXCOMLEN; 395 bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)u.u_comm, 396 (unsigned)(ndp->ni_dent.d_namlen + 1)); 397 } 398 bad: 399 if (bp) 400 brelse(bp); 401 if (bno) 402 rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno); 403 if (vp) 404 vput(vp); 405 } 406 407 /* 408 * Read in and set up memory for executed file. 409 */ 410 getxfile(vp, ep, nargc, uid, gid, cred) 411 register struct vnode *vp; 412 register struct exec *ep; 413 int nargc, uid, gid; 414 struct ucred *cred; 415 { 416 size_t ts, ds, ids, uds, ss; 417 int pagi; 418 419 if (ep->a_magic == ZMAGIC) 420 pagi = SPAGV; 421 else 422 pagi = 0; 423 if (vp->v_text && (vp->v_text->x_flag & XTRC)) { 424 u.u_error = ETXTBSY; 425 goto bad; 426 } 427 if (ep->a_text != 0 && (vp->v_flag & VTEXT) == 0 && 428 vp->v_count != 1) { 429 register struct file *fp; 430 431 for (fp = file; fp < fileNFILE; fp++) { 432 if (fp->f_type == DTYPE_VNODE && 433 fp->f_count > 0 && 434 (struct vnode *)fp->f_data == vp && 435 (fp->f_flag & FWRITE)) { 436 u.u_error = ETXTBSY; 437 goto bad; 438 } 439 } 440 } 441 442 /* 443 * Compute text and data sizes and make sure not too large. 444 * NB - Check data and bss separately as they may overflow 445 * when summed together. 446 */ 447 ts = clrnd(btoc(ep->a_text)); 448 ids = clrnd(btoc(ep->a_data)); 449 uds = clrnd(btoc(ep->a_bss)); 450 ds = clrnd(btoc(ep->a_data + ep->a_bss)); 451 ss = clrnd(SSIZE + btoc(nargc)); 452 if (chksize((unsigned)ts, (unsigned)ids, (unsigned)uds, (unsigned)ss)) 453 goto bad; 454 455 /* 456 * Make sure enough space to start process. 457 */ 458 u.u_cdmap = zdmap; 459 u.u_csmap = zdmap; 460 if (swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap) == NULL) 461 goto bad; 462 463 /* 464 * At this point, we are committed to the new image! 465 * Release virtual memory resources of old process, and 466 * initialize the virtual memory of the new process. 467 * If we resulted from vfork(), instead wakeup our 468 * parent who will set SVFDONE when he has taken back 469 * our resources. 470 */ 471 if ((u.u_procp->p_flag & SVFORK) == 0) 472 vrelvm(); 473 else { 474 u.u_procp->p_flag &= ~SVFORK; 475 u.u_procp->p_flag |= SKEEP; 476 wakeup((caddr_t)u.u_procp); 477 while ((u.u_procp->p_flag & SVFDONE) == 0) 478 sleep((caddr_t)u.u_procp, PZERO - 1); 479 u.u_procp->p_flag &= ~(SVFDONE|SKEEP); 480 } 481 u.u_procp->p_flag &= ~(SPAGV|SSEQL|SUANOM|SOUSIG); 482 u.u_procp->p_flag |= pagi | SEXEC; 483 u.u_dmap = u.u_cdmap; 484 u.u_smap = u.u_csmap; 485 vgetvm(ts, ds, ss); 486 487 if (pagi == 0) 488 u.u_error = vn_rdwr(UIO_READ, vp, 489 (char *)ctob(dptov(u.u_procp, 0)), 490 (int)ep->a_data, 491 (off_t)(sizeof (struct exec) + ep->a_text), 492 UIO_USERSPACE, (IO_UNIT|IO_NODELOCKED), cred, (int *)0); 493 xalloc(vp, ep, pagi, cred); 494 #if defined(tahoe) 495 /* 496 * Define new keys. 497 */ 498 if (u.u_procp->p_textp == 0) { /* use existing code key if shared */ 499 ckeyrelease(u.u_procp->p_ckey); 500 u.u_procp->p_ckey = getcodekey(); 501 } 502 mtpr(CCK, u.u_procp->p_ckey); 503 dkeyrelease(u.u_procp->p_dkey); 504 u.u_procp->p_dkey = getdatakey(); 505 mtpr(DCK, u.u_procp->p_dkey); 506 #endif 507 if (pagi && u.u_procp->p_textp) 508 vinifod((struct fpte *)dptopte(u.u_procp, 0), 509 PG_FTEXT, u.u_procp->p_textp->x_vptr, 510 (long)(1 + ts/CLSIZE), (size_t)btoc(ep->a_data)); 511 512 #if defined(vax) || defined(tahoe) 513 /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */ 514 mtpr(TBIA, 0); 515 #endif 516 517 if (u.u_error) 518 swkill(u.u_procp, "exec: I/O error mapping pages"); 519 /* 520 * set SUID/SGID protections, if no tracing 521 */ 522 if ((u.u_procp->p_flag&STRC)==0) { 523 if (uid != u.u_uid || gid != u.u_gid) 524 u.u_cred = crcopy(u.u_cred); 525 u.u_uid = uid; 526 u.u_procp->p_uid = uid; 527 u.u_gid = gid; 528 } else 529 psignal(u.u_procp, SIGTRAP); 530 u.u_tsize = ts; 531 u.u_dsize = ds; 532 u.u_ssize = ss; 533 u.u_prof.pr_scale = 0; 534 #if defined(tahoe) 535 u.u_pcb.pcb_savacc.faddr = (float *)NULL; 536 #endif 537 bad: 538 return; 539 } 540