*** /usr/src/sys.386bsd/kern/kern_execve.c.pl2 Thu Sep 17 23:12:46 1992 --- /usr/src/sys.386bsd/kern/kern_execve.c Thu Sep 17 23:41:02 1992 *************** *** 52,60 **** * * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE * -------------------- ----- ---------------------- ! * CURRENT PATCH LEVEL: 1 00024 * -------------------- ----- ---------------------- * * 29 Jul 92 Mark Tinguely Fixed execute permission enforcement * 15 Aug 92 Terry Lambert Fixed CMOS RAM size bug */ --- 52,61 ---- * * PATCHES MAGIC LEVEL PATCH THAT GOT US HERE * -------------------- ----- ---------------------- ! * CURRENT PATCH LEVEL: 2 00025 * -------------------- ----- ---------------------- * + * 05 Aug 92 Paul Kranenburg Fixed #! as a magic number * 29 Jul 92 Mark Tinguely Fixed execute permission enforcement * 15 Aug 92 Terry Lambert Fixed CMOS RAM size bug */ *************** *** 100,106 **** { register struct nameidata *ndp; struct nameidata nd; - struct exec hdr; char **argbuf, **argbufp, *stringbuf, *stringbufp; char **vectp, *ep; int needsenv, limitonargs, stringlen, addr, size, len, --- 101,106 ---- *************** *** 108,122 **** struct vattr attr; struct vmspace *vs; caddr_t newframe; /* * Step 1. Lookup filename to see if we have something to execute. */ ndp = &nd; - ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW | SAVENAME; ndp->ni_segflg = UIO_USERSPACE; ndp->ni_dirp = uap->fname; /* is it there? */ if (rv = namei(ndp, p)) return (rv); --- 108,130 ---- struct vattr attr; struct vmspace *vs; caddr_t newframe; + char shellname[MAXINTERP]; /* 05 Aug 92*/ + union { + char ex_shell[MAXINTERP]; /* #! and interpreter name */ + struct exec ex_hdr; + } exdata; + int indir = 0; /* * Step 1. Lookup filename to see if we have something to execute. */ ndp = &nd; ndp->ni_segflg = UIO_USERSPACE; ndp->ni_dirp = uap->fname; + again: /* 05 Aug 92*/ + ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW | SAVENAME; + /* is it there? */ if (rv = namei(ndp, p)) return (rv); *************** *** 126,131 **** --- 134,144 ---- if (rv) goto exec_fail; + if (ndp->ni_vp->v_mount->mnt_flag & MNT_NOEXEC) { /* no exec on fs ?*/ + rv = EACCES; + goto exec_fail; + } + /* is it executable, and a regular file? */ if ((ndp->ni_vp->v_mount->mnt_flag & MNT_NOEXEC) || /* 29 Jul 92*/ (VOP_ACCESS(ndp->ni_vp, VEXEC, p->p_ucred, p)) || *************** *** 138,177 **** /* * Step 2. Does the file contain a format we can * understand and execute */ ! rv = vn_rdwr(UIO_READ, ndp->ni_vp, (caddr_t)&hdr, sizeof(hdr), 0, UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &amt, p); /* big enough to hold a header? */ if (rv) goto exec_fail; ! /* ... that we recognize? */ rv = ENOEXEC; ! if (hdr.a_magic != ZMAGIC) ! goto exec_fail; /* sanity check "ain't not such thing as a sanity clause" -groucho */ rv = ENOMEM; ! if (/*hdr.a_text == 0 || */ hdr.a_text > MAXTSIZ ! || hdr.a_text % NBPG || hdr.a_text > attr.va_size) goto exec_fail; ! if (hdr.a_data == 0 || hdr.a_data > DFLDSIZ ! || hdr.a_data > attr.va_size ! || hdr.a_data + hdr.a_text > attr.va_size) goto exec_fail; ! if (hdr.a_bss > MAXDSIZ) goto exec_fail; ! if (hdr.a_text + hdr.a_data + hdr.a_bss > MAXTSIZ + MAXDSIZ) goto exec_fail; ! if (hdr.a_data + hdr.a_bss > p->p_rlimit[RLIMIT_DATA].rlim_cur) goto exec_fail; ! if (hdr.a_entry > hdr.a_text + hdr.a_data) goto exec_fail; /* --- 151,234 ---- /* * Step 2. Does the file contain a format we can * understand and execute + * + * XXX 05 Aug 92 + * Read in first few bytes of file for segment sizes, magic number: + * ZMAGIC = 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. */ ! exdata.ex_shell[0] = '\0'; /* for zero length files */ ! ! rv = vn_rdwr(UIO_READ, ndp->ni_vp, (caddr_t)&exdata, sizeof(exdata), 0, UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &amt, p); /* big enough to hold a header? */ if (rv) goto exec_fail; ! /* ... that we recognize? */ rv = ENOEXEC; ! if (exdata.ex_hdr.a_magic != ZMAGIC) { ! char *cp, *sp; ! ! if (exdata.ex_shell[0] != '#' || ! exdata.ex_shell[1] != '!' || indir) { ! rv = ENOEXEC; ! goto exec_fail; ! } ! for (cp = &exdata.ex_shell[2];; ++cp) { ! if (cp >= &exdata.ex_shell[MAXINTERP]) { ! rv = ENOEXEC; ! goto exec_fail; ! } ! if (*cp == '\n') { ! *cp = '\0'; ! break; ! } ! if (*cp == '\t') ! *cp = ' '; ! } ! cp = &exdata.ex_shell[2]; /* get shell interpreter name */ ! while (*cp == ' ') ! cp++; ! ! sp = shellname; ! while (*cp && *cp != ' ') ! *sp++ = *cp++; ! *sp = '\0'; ! ! indir = 1; /* indicate this is a script file */ ! vput(ndp->ni_vp); ! FREE(ndp->ni_pnbuf, M_NAMEI); ! ! ndp->ni_dirp = shellname; /* find shell interpreter */ ! ndp->ni_segflg = UIO_SYSSPACE; ! goto again; ! } /* sanity check "ain't not such thing as a sanity clause" -groucho */ rv = ENOMEM; ! if (/*exdata.ex_hdr.a_text == 0 || */ exdata.ex_hdr.a_text > MAXTSIZ || ! exdata.ex_hdr.a_text % NBPG || exdata.ex_hdr.a_text > attr.va_size) goto exec_fail; ! if (exdata.ex_hdr.a_data == 0 || exdata.ex_hdr.a_data > DFLDSIZ ! || exdata.ex_hdr.a_data > attr.va_size ! || exdata.ex_hdr.a_data + exdata.ex_hdr.a_text > attr.va_size) goto exec_fail; ! if (exdata.ex_hdr.a_bss > MAXDSIZ) goto exec_fail; ! if (exdata.ex_hdr.a_text + exdata.ex_hdr.a_data + exdata.ex_hdr.a_bss > MAXTSIZ + MAXDSIZ) goto exec_fail; ! if (exdata.ex_hdr.a_data + exdata.ex_hdr.a_bss > p->p_rlimit[RLIMIT_DATA].rlim_cur) goto exec_fail; ! if (exdata.ex_hdr.a_entry > exdata.ex_hdr.a_text + exdata.ex_hdr.a_data) goto exec_fail; /* *************** *** 212,217 **** --- 269,309 ---- limitonargs = ARG_MAX; cnt = 0; + /* first, do (shell name if any then) args */ + if (indir) { + ep = shellname; + twice: + if (ep) { + /* did we outgrow initial argbuf, if so, die */ + if (argbufp >= (char **)stringbuf) { + rv = E2BIG; + goto exec_dealloc; + } + + if (rv = copyoutstr(ep, stringbufp, + (u_int)limitonargs, (u_int *)&stringlen)) { + if (rv == ENAMETOOLONG) + rv = E2BIG; + goto exec_dealloc; + } + suword(argbufp++, (int)stringbufp); + cnt++; + stringbufp += stringlen; + limitonargs -= stringlen; + } + + if (indir) { + indir = 0; + /* orginal executable is 1st argument with scripts */ + ep = uap->fname; + goto twice; + } + /* terminate in case no more args to script */ + suword(argbufp, 0); + if (vectp = uap->argp) vectp++; /* manually doing the first + argument with scripts */ + } + do_env_as_well: if(vectp == 0) goto dont_bother; *************** *** 300,316 **** addr = 0; /* screwball mode -- special case of 413 to save space for floppy */ ! if (hdr.a_text == 0) { foff = tsize = 0; ! hdr.a_data += hdr.a_text; } else { ! tsize = roundup(hdr.a_text, NBPG); foff = NBPG; } /* treat text and data in terms of integral page size */ ! dsize = roundup(hdr.a_data, NBPG); ! bsize = roundup(hdr.a_bss + dsize, NBPG); bsize -= dsize; /* map text & data in file, as being "paged in" on demand */ --- 392,408 ---- addr = 0; /* screwball mode -- special case of 413 to save space for floppy */ ! if (exdata.ex_hdr.a_text == 0) { foff = tsize = 0; ! exdata.ex_hdr.a_data += exdata.ex_hdr.a_text; } else { ! tsize = roundup(exdata.ex_hdr.a_text, NBPG); foff = NBPG; } /* treat text and data in terms of integral page size */ ! dsize = roundup(exdata.ex_hdr.a_data, NBPG); ! bsize = roundup(exdata.ex_hdr.a_bss + dsize, NBPG); bsize -= dsize; /* map text & data in file, as being "paged in" on demand */ *************** *** 377,383 **** /* setup initial register state */ p->p_regs[SP] = (unsigned) (argbuf - 1); ! setregs(p, hdr.a_entry); vput(ndp->ni_vp); FREE(ndp->ni_pnbuf, M_NAMEI); --- 469,475 ---- /* setup initial register state */ p->p_regs[SP] = (unsigned) (argbuf - 1); ! setregs(p, exdata.ex_hdr.a_entry); vput(ndp->ni_vp); FREE(ndp->ni_pnbuf, M_NAMEI);