version 1.1, 1993/03/21 09:45:37
|
version 1.2, 1993/03/21 18:04:42
|
Line 50
|
Line 50
|
* Significant limitations and lack of compatiblity with POSIX are |
* Significant limitations and lack of compatiblity with POSIX are |
* present with this version, to make its basic operation more clear. |
* present with this version, to make its basic operation more clear. |
* |
* |
|
* PATCHES MAGIC LEVEL PATCH THAT GOT US HERE |
|
* -------------------- ----- ---------------------- |
|
* CURRENT PATCH LEVEL: 3 00069 |
|
* -------------------- ----- ---------------------- |
|
* |
|
* 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 |
|
* 12 Dec 92 Julians Elischer Place argc into user address space |
|
* correctly |
*/ |
*/ |
|
|
#include "param.h" |
#include "param.h" |
Line 93 execve(p, uap, retval)
|
Line 103 execve(p, uap, retval)
|
{ |
{ |
register struct nameidata *ndp; |
register struct nameidata *ndp; |
struct nameidata nd; |
struct nameidata nd; |
struct exec hdr; |
|
char **argbuf, **argbufp, *stringbuf, *stringbufp; |
char **argbuf, **argbufp, *stringbuf, *stringbufp; |
char **vectp, *ep; |
char **vectp, *ep; |
int needsenv, limitonargs, stringlen, addr, size, len, |
int needsenv, limitonargs, stringlen, addr, size, len, |
Line 101 execve(p, uap, retval)
|
Line 110 execve(p, uap, retval)
|
struct vattr attr; |
struct vattr attr; |
struct vmspace *vs; |
struct vmspace *vs; |
caddr_t newframe; |
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. |
* Step 1. Lookup filename to see if we have something to execute. |
*/ |
*/ |
ndp = &nd; |
ndp = &nd; |
ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW | SAVENAME; |
|
ndp->ni_segflg = UIO_USERSPACE; |
ndp->ni_segflg = UIO_USERSPACE; |
ndp->ni_dirp = uap->fname; |
ndp->ni_dirp = uap->fname; |
|
|
|
again: /* 05 Aug 92*/ |
|
ndp->ni_nameiop = LOOKUP | LOCKLEAF | FOLLOW | SAVENAME; |
|
|
/* is it there? */ |
/* is it there? */ |
if (rv = namei(ndp, p)) |
if (rv = namei(ndp, p)) |
return (rv); |
return (rv); |
Line 119 execve(p, uap, retval)
|
Line 136 execve(p, uap, retval)
|
if (rv) |
if (rv) |
goto exec_fail; |
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? */ |
/* is it executable, and a regular file? */ |
if ((attr.va_mode & VEXEC) == 0 || attr.va_type != VREG) { |
if ((ndp->ni_vp->v_mount->mnt_flag & MNT_NOEXEC) || /* 29 Jul 92*/ |
|
(VOP_ACCESS(ndp->ni_vp, VEXEC, p->p_ucred, p)) || |
|
((attr.va_mode & 0111) == 0) || |
|
(attr.va_type != VREG)) { |
rv = EACCES; |
rv = EACCES; |
goto exec_fail; |
goto exec_fail; |
} |
} |
Line 128 execve(p, uap, retval)
|
Line 153 execve(p, uap, retval)
|
/* |
/* |
* Step 2. Does the file contain a format we can |
* Step 2. Does the file contain a format we can |
* understand and execute |
* 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. |
*/ |
*/ |
rv = vn_rdwr(UIO_READ, ndp->ni_vp, (caddr_t)&hdr, sizeof(hdr), |
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); |
0, UIO_SYSSPACE, IO_NODELOCKED, p->p_ucred, &amt, p); |
|
|
/* big enough to hold a header? */ |
/* big enough to hold a header? */ |
if (rv) |
if (rv) |
goto exec_fail; |
goto exec_fail; |
|
|
/* ... that we recognize? */ |
/* ... that we recognize? */ |
rv = ENOEXEC; |
rv = ENOEXEC; |
if (hdr.a_magic != ZMAGIC) |
if (exdata.ex_hdr.a_magic != ZMAGIC) { |
goto exec_fail; |
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 */ |
/* sanity check "ain't not such thing as a sanity clause" -groucho */ |
rv = ENOMEM; |
rv = ENOMEM; |
if (/*hdr.a_text == 0 || */ hdr.a_text > MAXTSIZ |
if (/*exdata.ex_hdr.a_text == 0 || */ exdata.ex_hdr.a_text > MAXTSIZ || |
|| hdr.a_text % NBPG || hdr.a_text > attr.va_size) |
exdata.ex_hdr.a_text % NBPG || exdata.ex_hdr.a_text > attr.va_size) |
goto exec_fail; |
goto exec_fail; |
|
|
if (hdr.a_data == 0 || hdr.a_data > DFLDSIZ |
if (exdata.ex_hdr.a_data == 0 || exdata.ex_hdr.a_data > DFLDSIZ |
|| hdr.a_data > attr.va_size |
|| exdata.ex_hdr.a_data > attr.va_size |
|| hdr.a_data + hdr.a_text > attr.va_size) |
|| exdata.ex_hdr.a_data + exdata.ex_hdr.a_text > attr.va_size) |
goto exec_fail; |
goto exec_fail; |
|
|
if (hdr.a_bss > MAXDSIZ) |
if (exdata.ex_hdr.a_bss > MAXDSIZ) |
goto exec_fail; |
goto exec_fail; |
|
|
if (hdr.a_text + hdr.a_data + hdr.a_bss > MAXTSIZ + MAXDSIZ) |
if (exdata.ex_hdr.a_text + exdata.ex_hdr.a_data + exdata.ex_hdr.a_bss > MAXTSIZ + MAXDSIZ) |
goto exec_fail; |
goto exec_fail; |
|
|
if (hdr.a_data + hdr.a_bss > p->p_rlimit[RLIMIT_DATA].rlim_cur) |
if (exdata.ex_hdr.a_data + exdata.ex_hdr.a_bss > p->p_rlimit[RLIMIT_DATA].rlim_cur) |
goto exec_fail; |
goto exec_fail; |
|
|
if (hdr.a_entry > hdr.a_text + hdr.a_data) |
if (exdata.ex_hdr.a_entry > exdata.ex_hdr.a_text + exdata.ex_hdr.a_data) |
goto exec_fail; |
goto exec_fail; |
|
|
/* |
/* |
Line 202 execve(p, uap, retval)
|
Line 271 execve(p, uap, retval)
|
limitonargs = ARG_MAX; |
limitonargs = ARG_MAX; |
cnt = 0; |
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: |
do_env_as_well: |
if(vectp == 0) goto dont_bother; |
if(vectp == 0) goto dont_bother; |
|
|
Line 262 dont_bother:
|
Line 366 dont_bother:
|
*/ |
*/ |
|
|
/* stuff arg count on top of "new" stack */ |
/* stuff arg count on top of "new" stack */ |
argbuf[-1] = (char *)argc; |
/* argbuf[-1] = (char *)argc;*/ |
|
suword(argbuf-1,argc); |
|
|
/* |
/* |
* Step 4. Build the new processes image. |
* Step 4. Build the new processes image. |
Line 290 dont_bother:
|
Line 395 dont_bother:
|
addr = 0; |
addr = 0; |
|
|
/* screwball mode -- special case of 413 to save space for floppy */ |
/* screwball mode -- special case of 413 to save space for floppy */ |
if (hdr.a_text == 0) { |
if (exdata.ex_hdr.a_text == 0) { |
foff = tsize = 0; |
foff = tsize = 0; |
hdr.a_data += hdr.a_text; |
exdata.ex_hdr.a_data += exdata.ex_hdr.a_text; |
} else { |
} else { |
tsize = roundup(hdr.a_text, NBPG); |
tsize = roundup(exdata.ex_hdr.a_text, NBPG); |
foff = NBPG; |
foff = NBPG; |
} |
} |
|
|
/* treat text and data in terms of integral page size */ |
/* treat text and data in terms of integral page size */ |
dsize = roundup(hdr.a_data, NBPG); |
dsize = roundup(exdata.ex_hdr.a_data, NBPG); |
bsize = roundup(hdr.a_bss + dsize, NBPG); |
bsize = roundup(exdata.ex_hdr.a_bss + dsize, NBPG); |
bsize -= dsize; |
bsize -= dsize; |
|
|
/* map text & data in file, as being "paged in" on demand */ |
/* map text & data in file, as being "paged in" on demand */ |
Line 367 dont_bother:
|
Line 472 dont_bother:
|
|
|
/* setup initial register state */ |
/* setup initial register state */ |
p->p_regs[SP] = (unsigned) (argbuf - 1); |
p->p_regs[SP] = (unsigned) (argbuf - 1); |
setregs(p, hdr.a_entry); |
setregs(p, exdata.ex_hdr.a_entry); |
|
|
vput(ndp->ni_vp); |
vput(ndp->ni_vp); |
FREE(ndp->ni_pnbuf, M_NAMEI); |
FREE(ndp->ni_pnbuf, M_NAMEI); |