X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/29a063464ebd4960b9510abcce8a232f9e620069..f4c13170101fd0eb5e60b14d3d74b3b34cba690c:/usr/src/sys/kern/kern_proc.c diff --git a/usr/src/sys/kern/kern_proc.c b/usr/src/sys/kern/kern_proc.c index dd800deb69..920b9f77dc 100644 --- a/usr/src/sys/kern/kern_proc.c +++ b/usr/src/sys/kern/kern_proc.c @@ -1,4 +1,4 @@ -/* kern_proc.c 3.22 %G% */ +/* kern_proc.c 4.8 %G% */ #include "../h/param.h" #include "../h/systm.h" @@ -42,20 +42,126 @@ exece() register struct buf *bp; register struct execa *uap; int na, ne, ucp, ap, c; + int indir, uid, gid; + char *sharg; struct inode *ip; swblk_t bno; + char cfname[DIRSIZ]; + char cfarg[SHSIZE]; if ((ip = namei(uchar, 0)) == NULL) return; + bno = 0; bp = 0; + indir = 0; + uid = u.u_uid; + gid = u.u_gid; + + if (ip->i_mode & ISUID) + uid = ip->i_uid; + if (ip->i_mode & ISGID) + gid = ip->i_gid; + + again: if(access(ip, IEXEC)) goto bad; + if((u.u_procp->p_flag&STRC) && access(ip, IREAD)) + goto bad; if((ip->i_mode & IFMT) != IFREG || (ip->i_mode & (IEXEC|(IEXEC>>3)|(IEXEC>>6))) == 0) { u.u_error = EACCES; goto bad; } + + /* + * Read in first few bytes of file for segment sizes, ux_mag: + * 407 = plain executable + * 410 = RO text + * 413 = demand paged RO text + * Also an ASCII line beginning with #! is + * the file name of a ``shell'' and arguments may be prepended + * to the argument list if given here. + * + * SHELL NAMES ARE LIMITED IN LENGTH. + * + * ONLY ONE ARGUMENT MAY BE PASSED TO THE SHELL FROM + * THE ASCII LINE. + */ + u.u_base = (caddr_t)&u.u_exdata; + u.u_count = sizeof(u.u_exdata); + u.u_offset = 0; + u.u_segflg = 1; + readi(ip); + u.u_segflg = 0; + if(u.u_error) + goto bad; + if (u.u_count > sizeof(u.u_exdata) - sizeof(u.u_exdata.Ux_A) + && u.u_exdata.ux_shell[0] != '#') { + u.u_error = ENOEXEC; + goto bad; + } + switch (u.u_exdata.ux_mag) { + + case 0407: + u.u_exdata.ux_dsize += u.u_exdata.ux_tsize; + u.u_exdata.ux_tsize = 0; + break; + + case 0413: + case 0410: + if (u.u_exdata.ux_tsize == 0) { + u.u_error = ENOEXEC; + goto bad; + } + break; + + default: + if (u.u_exdata.ux_shell[0] != '#' || + u.u_exdata.ux_shell[1] != '!' || + indir) { + u.u_error = ENOEXEC; + goto bad; + } + cp = &u.u_exdata.ux_shell[2]; /* skip "#!" */ + while (cp < &u.u_exdata.ux_shell[SHSIZE]) { + if (*cp == '\t') + *cp = ' '; + else if (*cp == '\n') { + *cp = '\0'; + break; + } + cp++; + } + if (*cp != '\0') { + u.u_error = ENOEXEC; + goto bad; + } + cp = &u.u_exdata.ux_shell[2]; + while (*cp == ' ') + cp++; + u.u_dirp = cp; + while (*cp && *cp != ' ') + cp++; + sharg = NULL; + if (*cp) { + *cp++ = '\0'; + while (*cp == ' ') + cp++; + if (*cp) { + bcopy((caddr_t)cp, (caddr_t)cfarg, SHSIZE); + sharg = cfarg; + } + } + bcopy((caddr_t)u.u_dbuf, (caddr_t)cfname, DIRSIZ); + indir = 1; + iput(ip); + ip = namei(schar, 0); + if (ip == NULL) + return; + goto again; + } + /* * Collect arguments on "file" in swap space. */ @@ -63,15 +169,20 @@ exece() ne = 0; nc = 0; uap = (struct execa *)u.u_ap; - if ((bno = malloc(argmap, ctod(clrnd((int) btoc(NCARGS))))) == 0) { + if ((bno = rmalloc(argmap, ctod(clrnd((int) btoc(NCARGS))))) == 0) { swkill(u.u_procp, "exece"); goto bad; } if (bno % CLSIZE) - panic("execa malloc"); + panic("execa rmalloc"); if (uap->argp) for (;;) { ap = NULL; - if (uap->argp) { + if (na == 1 && indir) { + if (sharg == NULL) + ap = (int)uap->fname; + } else if (na == 2 && indir && sharg != NULL) + ap = (int)uap->fname; + else if (uap->argp) { ap = fuword((caddr_t)uap->argp); uap->argp++; } @@ -90,7 +201,9 @@ exece() do { if (nc >= NCARGS-1) u.u_error = E2BIG; - if ((c = fubyte((caddr_t)ap++)) < 0) + if (indir && na == 2 && sharg != NULL) + c = *sharg++ & 0377; + else if ((c = fubyte((caddr_t)ap++)) < 0) u.u_error = EFAULT; if (u.u_error) { if (bp) @@ -113,7 +226,9 @@ exece() bdwrite(bp); bp = 0; nc = (nc + NBPW-1) & ~(NBPW-1); - getxfile(ip, nc); + if (indir) + bcopy((caddr_t)cfname, (caddr_t)u.u_dbuf, DIRSIZ); + getxfile(ip, nc + (na+4)*NBPW, uid, gid); if (u.u_error) { badarg: for (c = 0; c < nc; c += BSIZE) @@ -165,67 +280,28 @@ bad: if (bp) brelse(bp); if (bno) - mfree(argmap, ctod(clrnd((int) btoc(NCARGS))), bno); + rmfree(argmap, ctod(clrnd((int) btoc(NCARGS))), bno); iput(ip); } /* * Read in and set up memory for executed file. */ -getxfile(ip, nargc) +getxfile(ip, nargc, uid, gid) register struct inode *ip; { register size_t ts, ds, ss; - int pagi = 0; - - /* - * read in first few bytes - * of file for segment - * sizes: - * ux_mag = 407/410/413 - * 407 is plain executable - * 410 is RO text - * 413 is demand paged RO text - */ + int pagi; - u.u_base = (caddr_t)&u.u_exdata; - u.u_count = sizeof(u.u_exdata); - u.u_offset = 0; - u.u_segflg = 1; - readi(ip); - u.u_segflg = 0; - if(u.u_error) - goto bad; - if (u.u_count!=0) { - u.u_error = ENOEXEC; - goto bad; - } - switch (u.u_exdata.ux_mag) { - - case 0407: - u.u_exdata.ux_dsize += u.u_exdata.ux_tsize; - u.u_exdata.ux_tsize = 0; - break; - - case 0413: + if (u.u_exdata.ux_mag == 0413) pagi = SPAGI; - /* fall into ... */ - - case 0410: - if (u.u_exdata.ux_tsize == 0) { - u.u_error = ENOEXEC; - goto bad; - } - break; + else + pagi = 0; - default: - u.u_error = ENOEXEC; - goto bad; - } if(u.u_exdata.ux_tsize!=0 && (ip->i_flag&ITEXT)==0 && ip->i_count!=1) { register struct file *fp; - for (fp = file; fp < &file[NFILE]; fp++) + for (fp = file; fp < fileNFILE; fp++) if (fp->f_inode == ip && (fp->f_flag&FWRITE)) { u.u_error = ETXTBSY; goto bad; @@ -295,13 +371,14 @@ register struct inode *ip; * set SUID/SGID protections, if no tracing */ if ((u.u_procp->p_flag&STRC)==0) { - if(ip->i_mode&ISUID) - if(u.u_uid != 0) { - u.u_uid = ip->i_uid; - u.u_procp->p_uid = ip->i_uid; - } - if(ip->i_mode&ISGID) - u.u_gid = ip->i_gid; +#ifndef MELB + if(u.u_uid != 0) +#endif + { + u.u_uid = uid; + u.u_procp->p_uid = uid; + } + u.u_gid = gid; } else psignal(u.u_procp, SIGTRAP); u.u_tsize = ts; @@ -318,6 +395,9 @@ setregs() { register int (**rp)(); register i; +#ifdef UCBIPC + register struct port *pt; +#endif UCBIPC long sigmask; for(rp = &u.u_signal[0], sigmask = 1L; rp < &u.u_signal[NSIG]; @@ -354,8 +434,21 @@ setregs() u.u_ar0[PC] = u.u_exdata.ux_entloc + 2; /* skip over entry mask */ for(i=0; ipt_count == 0) + ptclose(pt); + u.u_pofile[i] &= ~ISPORT; + u.u_oport[i] = NULL; + } else { + closef(u.u_ofile[i]); + u.u_ofile[i] = NULL; + } +#endif UCBIPC u.u_pofile[i] &= ~EXCLOSE; } } @@ -392,6 +485,9 @@ exit(rv) register int i; register struct proc *p, *q; register struct file *f; +#ifdef UCBIPC + register struct port *pt; +#endif UCBIPC register int x; #ifdef PGINPROF @@ -411,7 +507,8 @@ exit(rv) else p->p_siga1 = 0; (void) spl0(); - p->p_aveflt = 0; + p->p_cpticks = 0; + p->p_pctcpu = 0; for(i=0; ip_flag &= ~SVFDONE; } for(i=0; ipt_count == 0) + ptclose(pt); + u.u_oport[i] = NULL; + } else { + f = u.u_ofile[i]; + u.u_ofile[i] = NULL; + closef(f); + } +#endif UCBIPC } plock(u.u_cdir); iput(u.u_cdir); @@ -445,8 +555,8 @@ exit(rv) vrelu(u.u_procp, 0); multprog--; /* spl7(); /* clock will get mad because of overlaying */ - noproc = 1; p->p_stat = SZOMB; + noproc = 1; i = PIDHASH(p->p_pid); x = p - proc; if (pidhash[i] == x) @@ -459,11 +569,13 @@ exit(rv) } panic("exit"); } + if (p->p_pid == 1) + panic("init died"); done: ((struct xproc *)p)->xp_xstat = rv; /* overlay */ ((struct xproc *)p)->xp_vm = u.u_vm; /* overlay */ vmsadd(&((struct xproc *)p)->xp_vm, &u.u_cvm); - for(q = &proc[0]; q < &proc[NPROC]; q++) + for(q = proc; q < procNPROC; q++) if(q->p_pptr == p) { q->p_pptr = &proc[1]; q->p_ppid = 1; @@ -488,7 +600,7 @@ done: * tty signals, clear TSTP/TTIN/TTOU if pending, * and set SDETACH bit on procs. */ - spgrp(q, -1); + (void) spgrp(q, -1); } wakeup((caddr_t)p->p_pptr); psignal(p->p_pptr, SIGCHLD); @@ -527,7 +639,7 @@ wait1(options, vp) f = 0; loop: - for(p = &proc[0]; p < &proc[NPROC]; p++) + for(p = proc; p < procNPROC; p++) if(p->p_pptr == u.u_procp) { f++; if(p->p_stat == SZOMB) { @@ -597,7 +709,7 @@ fork1(isvfork) a = 0; p2 = NULL; - for(p1 = &proc[0]; p1 < &proc[NPROC]; p1++) { + for(p1 = proc; p1 < procNPROC; p1++) { if (p1->p_stat==NULL && p2==NULL) p2 = p1; else { @@ -611,7 +723,7 @@ fork1(isvfork) * not su and too many procs owned; or * not su and would take last slot. */ - if (p2==NULL || (u.u_uid!=0 && (p2==&proc[NPROC-1] || a>MAXUPRC))) { + if (p2==NULL || (u.u_uid!=0 && (p2==procNPROC-1 || a>MAXUPRC))) { u.u_error = EAGAIN; if (!isvfork) { (void) vsexpand(0, &u.u_cdmap, 1);