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