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.8 (Berkeley) 10/18/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] != '#' || 136 exdata.ex_shell[1] != '!' || 137 indir) { 138 u.u_error = ENOEXEC; 139 goto bad; 140 } 141 for (cp = &exdata.ex_shell[2];; ++cp) { 142 if (cp >= &exdata.ex_shell[MAXINTERP]) { 143 u.u_error = ENOEXEC; 144 goto bad; 145 } 146 if (*cp == '\n') { 147 *cp = '\0'; 148 break; 149 } 150 if (*cp == '\t') 151 *cp = ' '; 152 } 153 cp = &exdata.ex_shell[2]; 154 while (*cp == ' ') 155 cp++; 156 ndp->ni_dirp = cp; 157 while (*cp && *cp != ' ') 158 cp++; 159 cfarg[0] = '\0'; 160 if (*cp) { 161 *cp++ = '\0'; 162 while (*cp == ' ') 163 cp++; 164 if (*cp) 165 bcopy((caddr_t)cp, (caddr_t)cfarg, MAXINTERP); 166 } 167 indir = 1; 168 iput(ip); 169 ndp->ni_nameiop = LOOKUP | FOLLOW; 170 ndp->ni_segflg = UIO_SYSSPACE; 171 ip = namei(ndp); 172 if (ip == NULL) 173 return; 174 bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)cfname, 175 MAXCOMLEN); 176 cfname[MAXCOMLEN] = '\0'; 177 uid = u.u_uid; /* shell scripts can't be setuid */ 178 gid = u.u_gid; 179 goto again; 180 } 181 182 /* 183 * Collect arguments on "file" in swap space. 184 */ 185 na = 0; 186 ne = 0; 187 nc = 0; 188 cc = 0; 189 uap = (struct execa *)u.u_ap; 190 bno = rmalloc(argmap, (long)ctod(clrnd((int)btoc(NCARGS)))); 191 if (bno == 0) { 192 swkill(u.u_procp, "exec: no swap space"); 193 goto bad; 194 } 195 if (bno % CLSIZE) 196 panic("execa rmalloc"); 197 /* 198 * Copy arguments into file in argdev area. 199 */ 200 if (uap->argp) for (;;) { 201 ap = NULL; 202 sharg = NULL; 203 if (indir && na == 0) { 204 sharg = cfname; 205 ap = (int)sharg; 206 uap->argp++; /* ignore argv[0] */ 207 } else if (indir && (na == 1 && cfarg[0])) { 208 sharg = cfarg; 209 ap = (int)sharg; 210 } else if (indir && (na == 1 || na == 2 && cfarg[0])) 211 ap = (int)uap->fname; 212 else if (uap->argp) { 213 ap = fuword((caddr_t)uap->argp); 214 uap->argp++; 215 } 216 if (ap == NULL && uap->envp) { 217 uap->argp = NULL; 218 if ((ap = fuword((caddr_t)uap->envp)) != NULL) 219 uap->envp++, ne++; 220 } 221 if (ap == NULL) 222 break; 223 na++; 224 if (ap == -1) { 225 u.u_error = EFAULT; 226 break; 227 } 228 do { 229 if (cc <= 0) { 230 /* 231 * We depend on NCARGS being a multiple of 232 * CLBYTES. This way we need only check 233 * overflow before each buffer allocation. 234 */ 235 if (nc >= NCARGS-1) { 236 error = E2BIG; 237 break; 238 } 239 if (bp) 240 bdwrite(bp); 241 cc = CLBYTES; 242 bp = getblk(argdev, bno + ctod(nc/NBPG), cc); 243 cp = bp->b_un.b_addr; 244 } 245 if (sharg) { 246 error = copystr(sharg, cp, (unsigned)cc, &len); 247 sharg += len; 248 } else { 249 error = copyinstr((caddr_t)ap, cp, (unsigned)cc, 250 &len); 251 ap += len; 252 } 253 cp += len; 254 nc += len; 255 cc -= len; 256 } while (error == ENOENT); 257 if (error) { 258 u.u_error = error; 259 if (bp) 260 brelse(bp); 261 bp = 0; 262 goto badarg; 263 } 264 } 265 if (bp) 266 bdwrite(bp); 267 bp = 0; 268 nc = (nc + NBPW-1) & ~(NBPW-1); 269 getxfile(ip, &exdata.ex_exec, nc + (na+4)*NBPW, uid, gid); 270 if (u.u_error) { 271 badarg: 272 for (cc = 0; cc < nc; cc += CLSIZE*NBPG) { 273 bp = baddr(argdev, bno + ctod(cc/NBPG), CLSIZE*NBPG); 274 if (bp) { 275 bp->b_flags |= B_AGE; /* throw away */ 276 bp->b_flags &= ~B_DELWRI; /* cancel io */ 277 brelse(bp); 278 bp = 0; 279 } 280 } 281 goto bad; 282 } 283 iput(ip); 284 ip = NULL; 285 286 /* 287 * Copy back arglist. 288 */ 289 ucp = USRSTACK - nc - NBPW; 290 ap = ucp - na*NBPW - 3*NBPW; 291 u.u_ar0[SP] = ap; 292 (void) suword((caddr_t)ap, na-ne); 293 nc = 0; 294 cc = 0; 295 for (;;) { 296 ap += NBPW; 297 if (na == ne) { 298 (void) suword((caddr_t)ap, 0); 299 ap += NBPW; 300 } 301 if (--na < 0) 302 break; 303 (void) suword((caddr_t)ap, ucp); 304 do { 305 if (cc <= 0) { 306 if (bp) 307 brelse(bp); 308 cc = CLBYTES; 309 bp = bread(argdev, bno + ctod(nc / NBPG), cc); 310 bp->b_flags |= B_AGE; /* throw away */ 311 bp->b_flags &= ~B_DELWRI; /* cancel io */ 312 cp = bp->b_un.b_addr; 313 } 314 error = copyoutstr(cp, (caddr_t)ucp, (unsigned)cc, 315 &len); 316 ucp += len; 317 cp += len; 318 nc += len; 319 cc -= len; 320 } while (error == ENOENT); 321 if (error == EFAULT) 322 panic("exec: EFAULT"); 323 } 324 (void) suword((caddr_t)ap, 0); 325 326 /* 327 * Reset caught signals. Held signals 328 * remain held through p_sigmask. 329 */ 330 while (u.u_procp->p_sigcatch) { 331 nc = ffs((long)u.u_procp->p_sigcatch); 332 u.u_procp->p_sigcatch &= ~sigmask(nc); 333 u.u_signal[nc] = SIG_DFL; 334 } 335 /* 336 * Reset stack state to the user stack. 337 * Clear set of signals caught on the signal stack. 338 */ 339 u.u_onstack = 0; 340 u.u_sigsp = 0; 341 u.u_sigonstack = 0; 342 343 for (nc = u.u_lastfile; nc >= 0; --nc) { 344 if (u.u_pofile[nc] & UF_EXCLOSE) { 345 closef(u.u_ofile[nc]); 346 u.u_ofile[nc] = NULL; 347 u.u_pofile[nc] = 0; 348 } 349 u.u_pofile[nc] &= ~UF_MAPPED; 350 } 351 while (u.u_lastfile >= 0 && u.u_ofile[u.u_lastfile] == NULL) 352 u.u_lastfile--; 353 setregs(exdata.ex_exec.a_entry); 354 /* 355 * Remember file name for accounting. 356 */ 357 u.u_acflag &= ~AFORK; 358 if (indir) 359 bcopy((caddr_t)cfname, (caddr_t)u.u_comm, MAXCOMLEN); 360 else { 361 if (ndp->ni_dent.d_namlen > MAXCOMLEN) 362 ndp->ni_dent.d_namlen = MAXCOMLEN; 363 bcopy((caddr_t)ndp->ni_dent.d_name, (caddr_t)u.u_comm, 364 (unsigned)(ndp->ni_dent.d_namlen + 1)); 365 } 366 bad: 367 if (bp) 368 brelse(bp); 369 if (bno) 370 rmfree(argmap, (long)ctod(clrnd((int) btoc(NCARGS))), bno); 371 if (ip) 372 iput(ip); 373 } 374 375 /* 376 * Read in and set up memory for executed file. 377 */ 378 getxfile(ip, ep, nargc, uid, gid) 379 register struct inode *ip; 380 register struct exec *ep; 381 int nargc, uid, gid; 382 { 383 size_t ts, ds, ids, uds, ss; 384 int pagi; 385 386 if (ep->a_magic == 0413) 387 pagi = SPAGI; 388 else 389 pagi = 0; 390 if (ip->i_text && (ip->i_text->x_flag & XTRC)) { 391 u.u_error = ETXTBSY; 392 goto bad; 393 } 394 if (ep->a_text != 0 && (ip->i_flag&ITEXT) == 0 && 395 ip->i_count != 1) { 396 register struct file *fp; 397 398 for (fp = file; fp < fileNFILE; fp++) { 399 if (fp->f_type == DTYPE_INODE && 400 fp->f_count > 0 && 401 (struct inode *)fp->f_data == ip && 402 (fp->f_flag&FWRITE)) { 403 u.u_error = ETXTBSY; 404 goto bad; 405 } 406 } 407 } 408 409 /* 410 * Compute text and data sizes and make sure not too large. 411 * NB - Check data and bss separately as they may overflow 412 * when summed together. 413 */ 414 ts = clrnd(btoc(ep->a_text)); 415 ids = clrnd(btoc(ep->a_data)); 416 uds = clrnd(btoc(ep->a_bss)); 417 ds = clrnd(btoc(ep->a_data + ep->a_bss)); 418 ss = clrnd(SSIZE + btoc(nargc)); 419 if (chksize((unsigned)ts, (unsigned)ids, (unsigned)uds, (unsigned)ss)) 420 goto bad; 421 422 /* 423 * Make sure enough space to start process. 424 */ 425 u.u_cdmap = zdmap; 426 u.u_csmap = zdmap; 427 if (swpexpand(ds, ss, &u.u_cdmap, &u.u_csmap) == NULL) 428 goto bad; 429 430 /* 431 * At this point, committed to the new image! 432 * Release virtual memory resources of old process, and 433 * initialize the virtual memory of the new process. 434 * If we resulted from vfork(), instead wakeup our 435 * parent who will set SVFDONE when he has taken back 436 * our resources. 437 */ 438 if ((u.u_procp->p_flag & SVFORK) == 0) 439 vrelvm(); 440 else { 441 u.u_procp->p_flag &= ~SVFORK; 442 u.u_procp->p_flag |= SKEEP; 443 wakeup((caddr_t)u.u_procp); 444 while ((u.u_procp->p_flag & SVFDONE) == 0) 445 sleep((caddr_t)u.u_procp, PZERO - 1); 446 u.u_procp->p_flag &= ~(SVFDONE|SKEEP); 447 } 448 u.u_procp->p_flag &= ~(SPAGI|SSEQL|SUANOM|SOUSIG); 449 u.u_procp->p_flag |= pagi | SEXEC; 450 u.u_dmap = u.u_cdmap; 451 u.u_smap = u.u_csmap; 452 vgetvm(ts, ds, ss); 453 454 if (pagi == 0) 455 u.u_error = 456 rdwri(UIO_READ, ip, 457 (char *)ctob(dptov(u.u_procp, 0)), 458 (int)ep->a_data, 459 (off_t)(sizeof (struct exec) + ep->a_text), 460 0, (int *)0); 461 xalloc(ip, ep, pagi); 462 #if defined(tahoe) 463 /* 464 * Define new keys. 465 */ 466 if (u.u_procp->p_textp == 0) { /* use existing code key if shared */ 467 ckeyrelease(u.u_procp->p_ckey); 468 u.u_procp->p_ckey = getcodekey(); 469 } 470 mtpr(CCK, u.u_procp->p_ckey); 471 dkeyrelease(u.u_procp->p_dkey); 472 u.u_procp->p_dkey = getdatakey(); 473 mtpr(DCK, u.u_procp->p_dkey); 474 #endif 475 if (pagi && u.u_procp->p_textp) 476 vinifod((struct fpte *)dptopte(u.u_procp, 0), 477 PG_FTEXT, u.u_procp->p_textp->x_iptr, 478 (long)(1 + ts/CLSIZE), (size_t)btoc(ep->a_data)); 479 480 #if defined(vax) || defined(tahoe) 481 /* THIS SHOULD BE DONE AT A LOWER LEVEL, IF AT ALL */ 482 mtpr(TBIA, 0); 483 #endif 484 485 if (u.u_error) 486 swkill(u.u_procp, "exec: I/O error mapping pages"); 487 /* 488 * set SUID/SGID protections, if no tracing 489 */ 490 if ((u.u_procp->p_flag&STRC)==0) { 491 u.u_uid = uid; 492 u.u_procp->p_uid = uid; 493 u.u_gid = gid; 494 } else 495 psignal(u.u_procp, SIGTRAP); 496 u.u_tsize = ts; 497 u.u_dsize = ds; 498 u.u_ssize = ss; 499 u.u_prof.pr_scale = 0; 500 #if defined(tahoe) 501 u.u_pcb.pcb_savacc.faddr = (float *)NULL; 502 #endif 503 bad: 504 return; 505 } 506