ape: fix more bugs, use /env and /proc instead of #e and #p, cleanup
remove envname length limitation in _envsetup() by using allocated buffer and use /env instead of #e use /proc and getpid() instead of #p and #c in readprocfdinit() fix buffer overflow in execlp(), check if name of failed exec starts with / . or is \0 make sure not to close our own filedescriptors for FD_CLOEXEC in execve(), fix wrong length check for flushing buffer to /env/_fdinfo. fix error handling cases. copy the enviroment before decoding \1 to \0 because the strings in environ[] array might not be writable. remove bogus close if we fail to open ppid file in getppid() and use /dev/ppid instead of #c/ppid
This commit is contained in:
parent
f3842de5fd
commit
eb9de925c6
5 changed files with 74 additions and 70 deletions
|
@ -21,7 +21,6 @@
|
||||||
char **environ;
|
char **environ;
|
||||||
int errno;
|
int errno;
|
||||||
unsigned long _clock;
|
unsigned long _clock;
|
||||||
static char name[NAME_MAX+5] = "#e";
|
|
||||||
static void fdsetup(char *, char *);
|
static void fdsetup(char *, char *);
|
||||||
static void sigsetup(char *, char *);
|
static void sigsetup(char *, char *);
|
||||||
|
|
||||||
|
@ -45,33 +44,32 @@ _envsetup(void)
|
||||||
nohandle = 0;
|
nohandle = 0;
|
||||||
fdinited = 0;
|
fdinited = 0;
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
dfd = _OPEN(name, 0);
|
dfd = _OPEN("/env", 0);
|
||||||
if(dfd < 0) {
|
if(dfd < 0) {
|
||||||
static char **emptyenvp = 0;
|
static char **emptyenvp = 0;
|
||||||
environ = emptyenvp;
|
environ = emptyenvp;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
name[2] = '/';
|
|
||||||
ps = p = malloc(Envhunk);
|
|
||||||
psize = Envhunk;
|
psize = Envhunk;
|
||||||
|
ps = p = malloc(psize);
|
||||||
nd = _dirreadall(dfd, &d9a);
|
nd = _dirreadall(dfd, &d9a);
|
||||||
_CLOSE(dfd);
|
_CLOSE(dfd);
|
||||||
for(j=0; j<nd; j++){
|
for(j=0; j<nd; j++){
|
||||||
d9 = &d9a[j];
|
d9 = &d9a[j];
|
||||||
n = strlen(d9->name);
|
n = strlen(d9->name);
|
||||||
if(n >= sizeof(name)-4)
|
|
||||||
continue;
|
|
||||||
m = d9->length;
|
m = d9->length;
|
||||||
i = p - ps;
|
i = p - ps;
|
||||||
if(i+n+1+m+1 > psize) {
|
if(i+n+5+m+1 > psize) {
|
||||||
psize += (n+m+2 < Envhunk)? Envhunk : n+m+2;
|
psize += (n+m+6 < Envhunk)? Envhunk : n+m+6;
|
||||||
ps = realloc(ps, psize);
|
ps = realloc(ps, psize);
|
||||||
p = ps + i;
|
p = ps + i;
|
||||||
}
|
}
|
||||||
|
strcpy(p, "/env/");
|
||||||
|
memcpy(p+5, d9->name, n+1);
|
||||||
|
f = _OPEN(p, 0);
|
||||||
|
memset(p, 0, n+6);
|
||||||
memcpy(p, d9->name, n);
|
memcpy(p, d9->name, n);
|
||||||
p[n] = '=';
|
p[n] = '=';
|
||||||
strcpy(name+3, d9->name);
|
|
||||||
f = _OPEN(name, O_RDONLY);
|
|
||||||
if(f < 0 || _READ(f, p+n+1, m) != m)
|
if(f < 0 || _READ(f, p+n+1, m) != m)
|
||||||
m = 0;
|
m = 0;
|
||||||
_CLOSE(f);
|
_CLOSE(f);
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
#include "sys9.h"
|
#include "sys9.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
@ -33,21 +34,12 @@ readprocfdinit(void)
|
||||||
/* construct info from /proc/$pid/fd */
|
/* construct info from /proc/$pid/fd */
|
||||||
char buf[8192];
|
char buf[8192];
|
||||||
Fdinfo *fi;
|
Fdinfo *fi;
|
||||||
int fd, pfd, pid, n, tot, m;
|
int fd, pfd, n, tot, m;
|
||||||
char *s, *nexts;
|
char *s, *nexts;
|
||||||
|
|
||||||
memset(buf, 0, sizeof buf);
|
memset(buf, 0, sizeof buf);
|
||||||
pfd = _OPEN("#c/pid", 0);
|
strcpy(buf, "/proc/");
|
||||||
if(pfd < 0)
|
_ultoa(buf+6, getpid());
|
||||||
return -1;
|
|
||||||
if(_PREAD(pfd, buf, 100, 0) < 0){
|
|
||||||
_CLOSE(pfd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
_CLOSE(pfd);
|
|
||||||
pid = strtoul(buf, 0, 10);
|
|
||||||
strcpy(buf, "#p/");
|
|
||||||
_ultoa(buf+3, pid);
|
|
||||||
strcat(buf, "/fd");
|
strcat(buf, "/fd");
|
||||||
pfd = _OPEN(buf, 0);
|
pfd = _OPEN(buf, 0);
|
||||||
if(pfd < 0)
|
if(pfd < 0)
|
||||||
|
@ -77,9 +69,7 @@ readprocfdinit(void)
|
||||||
fd = strtoul(s, &s, 10);
|
fd = strtoul(s, &s, 10);
|
||||||
if(errno != 0)
|
if(errno != 0)
|
||||||
return -1;
|
return -1;
|
||||||
if(fd >= OPEN_MAX)
|
if(fd < 0 || fd == pfd || fd >= OPEN_MAX)
|
||||||
continue;
|
|
||||||
if(fd == pfd)
|
|
||||||
continue;
|
continue;
|
||||||
fi = &_fdinfo[fd];
|
fi = &_fdinfo[fd];
|
||||||
fi->flags = FD_ISOPEN;
|
fi->flags = FD_ISOPEN;
|
||||||
|
@ -149,8 +139,6 @@ _fdinit(char *s, char *se)
|
||||||
usedproc = 0;
|
usedproc = 0;
|
||||||
if(readprocfdinit() == 0)
|
if(readprocfdinit() == 0)
|
||||||
usedproc = 1;
|
usedproc = 1;
|
||||||
else
|
|
||||||
_WRITE(2, "FAILED\n", 7);
|
|
||||||
if(s)
|
if(s)
|
||||||
sfdinit(usedproc, s, se);
|
sfdinit(usedproc, s, se);
|
||||||
if(!s && !usedproc)
|
if(!s && !usedproc)
|
||||||
|
|
|
@ -16,9 +16,11 @@ execlp(const char *name, const char *arg0, ...)
|
||||||
char buf[PATH_MAX];
|
char buf[PATH_MAX];
|
||||||
|
|
||||||
if((n=execve(name, &arg0, environ)) < 0){
|
if((n=execve(name, &arg0, environ)) < 0){
|
||||||
|
if(strchr("/.", name[0]) != 0 || strlen(name) >= sizeof(buf)-5)
|
||||||
|
return n;
|
||||||
strcpy(buf, "/bin/");
|
strcpy(buf, "/bin/");
|
||||||
strcpy(buf+5, name);
|
strcpy(buf+5, name);
|
||||||
n = execve(buf, &name+1, environ);
|
n = execve(buf, &arg0, environ);
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,7 @@ execve(const char *name, const char *argv[], const char *envp[])
|
||||||
char **e, *ss, *se;
|
char **e, *ss, *se;
|
||||||
Fdinfo *fi;
|
Fdinfo *fi;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
char nam[256+5];
|
char buf[1024];
|
||||||
char buf[1000];
|
|
||||||
|
|
||||||
_RFORK(RFCENVG);
|
_RFORK(RFCENVG);
|
||||||
/*
|
/*
|
||||||
|
@ -24,31 +23,40 @@ execve(const char *name, const char *argv[], const char *envp[])
|
||||||
* in $_fdinfo (for open fd's)
|
* in $_fdinfo (for open fd's)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
f = _CREATE("#e/_fdinfo", OWRITE, 0666);
|
f = _CREATE("/env/_fdinfo", OWRITE, 0666);
|
||||||
ss = buf;
|
ss = buf;
|
||||||
for(n = 0; n<OPEN_MAX; n++){
|
for(i = 0; i<OPEN_MAX; i++){
|
||||||
fi = &_fdinfo[n];
|
if(i == f)
|
||||||
|
continue;
|
||||||
|
fi = &_fdinfo[i];
|
||||||
flags = fi->flags;
|
flags = fi->flags;
|
||||||
if(flags&FD_CLOEXEC){
|
if(flags&FD_CLOEXEC){
|
||||||
_CLOSE(n);
|
_CLOSE(i);
|
||||||
fi->flags = 0;
|
fi->flags = 0;
|
||||||
fi->oflags = 0;
|
fi->oflags = 0;
|
||||||
}else if(flags&FD_ISOPEN){
|
}else if(flags&FD_ISOPEN){
|
||||||
ss = _ultoa(ss, n);
|
if(f < 0)
|
||||||
|
continue;
|
||||||
|
ss = _ultoa(ss, i);
|
||||||
*ss++ = ' ';
|
*ss++ = ' ';
|
||||||
ss = _ultoa(ss, flags);
|
ss = _ultoa(ss, flags);
|
||||||
*ss++ = ' ';
|
*ss++ = ' ';
|
||||||
ss = _ultoa(ss, fi->oflags);
|
ss = _ultoa(ss, fi->oflags);
|
||||||
*ss++ = '\n';
|
*ss++ = '\n';
|
||||||
if(ss-buf < sizeof(buf)-50){
|
n = ss-buf;
|
||||||
_WRITE(f, buf, ss-buf);
|
if(n > sizeof(buf)-50){
|
||||||
|
if(_WRITE(f, buf, n) != n)
|
||||||
|
break;
|
||||||
ss = buf;
|
ss = buf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(ss > buf)
|
if(f >= 0){
|
||||||
_WRITE(f, buf, ss-buf);
|
if(ss > buf)
|
||||||
_CLOSE(f);
|
_WRITE(f, buf, ss-buf);
|
||||||
|
_CLOSE(f);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To pass _sighdlr[] across exec, set $_sighdlr
|
* To pass _sighdlr[] across exec, set $_sighdlr
|
||||||
* to list of blank separated fd's that have
|
* to list of blank separated fd's that have
|
||||||
|
@ -57,43 +65,52 @@ execve(const char *name, const char *argv[], const char *envp[])
|
||||||
* are ignored, in case the current value of the
|
* are ignored, in case the current value of the
|
||||||
* variable ignored some.
|
* variable ignored some.
|
||||||
*/
|
*/
|
||||||
f = _CREATE("#e/_sighdlr", OWRITE, 0666);
|
f = _CREATE("/env/_sighdlr", OWRITE, 0666);
|
||||||
if(f >= 0){
|
if(f >= 0){
|
||||||
ss = buf;
|
ss = buf;
|
||||||
for(i = 0, n=0; i <=MAXSIG && ss < &buf[sizeof(buf)]-5; i++) {
|
for(i = 0; i <=MAXSIG; i++) {
|
||||||
if(_sighdlr[i] == SIG_IGN) {
|
if(_sighdlr[i] == SIG_IGN) {
|
||||||
ss = _ultoa(ss, i);
|
ss = _ultoa(ss, i);
|
||||||
*ss++ = ' ';
|
*ss++ = ' ';
|
||||||
|
n = ss-buf;
|
||||||
|
if(n > sizeof(buf)-20){
|
||||||
|
if(_WRITE(f, buf, n) != n)
|
||||||
|
break;
|
||||||
|
ss = buf;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_WRITE(f, buf, ss-buf);
|
if(ss > buf)
|
||||||
|
_WRITE(f, buf, ss-buf);
|
||||||
_CLOSE(f);
|
_CLOSE(f);
|
||||||
}
|
}
|
||||||
if(envp){
|
if(envp){
|
||||||
strcpy(nam, "#e/");
|
|
||||||
for(e = envp; (ss = *e); e++) {
|
for(e = envp; (ss = *e); e++) {
|
||||||
se = strchr(ss, '=');
|
se = strchr(ss, '=');
|
||||||
if(!se || ss==se)
|
if(!se || ss==se)
|
||||||
continue; /* what is name? value? */
|
continue; /* what is name? value? */
|
||||||
n = se-ss;
|
n = se-ss;
|
||||||
if(n >= sizeof(nam)-3)
|
if(n >= sizeof(buf)-5)
|
||||||
n = sizeof(nam)-3-1;
|
continue; /* name too long */
|
||||||
memcpy(nam+3, ss, n);
|
strcpy(buf, "/env/");
|
||||||
nam[3+n] = 0;
|
memcpy(buf+5, ss, n);
|
||||||
f = _CREATE(nam, OWRITE, 0666);
|
buf[5+n] = 0;
|
||||||
|
f = _CREATE(buf, OWRITE, 0666);
|
||||||
if(f < 0)
|
if(f < 0)
|
||||||
continue;
|
continue;
|
||||||
se++; /* past = */
|
ss = ++se; /* past = */
|
||||||
n = strlen(se);
|
se += strlen(ss);
|
||||||
/* temporarily decode nulls (see _envsetup()) */
|
while((n = (se - ss)) > 0){
|
||||||
for(i=0; i < n; i++)
|
if(n > sizeof(buf))
|
||||||
if(se[i] == 1)
|
n = sizeof(buf);
|
||||||
se[i] = 0;
|
/* decode nulls (see _envsetup()) */
|
||||||
_WRITE(f, se, n);
|
for(i=0; i<n; i++)
|
||||||
/* put nulls back */
|
if((buf[i] = ss[i]) == 1)
|
||||||
for(i=0; i < n; i++)
|
buf[i] = 0;
|
||||||
if(se[i] == 0)
|
if(_WRITE(f, buf, n) != n)
|
||||||
se[i] = 1;
|
break;
|
||||||
|
ss += n;
|
||||||
|
}
|
||||||
_CLOSE(f);
|
_CLOSE(f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,15 +9,14 @@
|
||||||
pid_t
|
pid_t
|
||||||
getppid(void)
|
getppid(void)
|
||||||
{
|
{
|
||||||
int n, f;
|
char b[20];
|
||||||
char ppidbuf[15];
|
int f;
|
||||||
|
|
||||||
f = open("#c/ppid", 0);
|
memset(b, 0, sizeof(b));
|
||||||
n = read(f, ppidbuf, sizeof ppidbuf);
|
f = open("/dev/ppid", 0);
|
||||||
if(n < 0)
|
if(f >= 0) {
|
||||||
errno = EINVAL;
|
read(f, b, sizeof(b));
|
||||||
else
|
close(f);
|
||||||
n = atoi(ppidbuf);
|
}
|
||||||
close(f);
|
return atol(b);
|
||||||
return n;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue