summaryrefslogtreecommitdiff
path: root/sys/src/ape
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-12-03 05:35:33 +0100
committercinap_lenrek <cinap_lenrek@gmx.de>2012-12-03 05:35:33 +0100
commiteb9de925c63990f6b19494698e4db1eb9682e46d (patch)
tree774c129eaad9c5e0e8922885f9d310c8d6863e22 /sys/src/ape
parentf3842de5fd405859f0a2de9a6f9fed0311c4629c (diff)
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
Diffstat (limited to 'sys/src/ape')
-rw-r--r--sys/src/ape/lib/ap/plan9/_envsetup.c18
-rw-r--r--sys/src/ape/lib/ap/plan9/_fdinfo.c22
-rw-r--r--sys/src/ape/lib/ap/plan9/execlp.c4
-rw-r--r--sys/src/ape/lib/ap/plan9/execve.c81
-rw-r--r--sys/src/ape/lib/ap/plan9/getppid.c19
5 files changed, 74 insertions, 70 deletions
diff --git a/sys/src/ape/lib/ap/plan9/_envsetup.c b/sys/src/ape/lib/ap/plan9/_envsetup.c
index c83d45008..6a4f4204e 100644
--- a/sys/src/ape/lib/ap/plan9/_envsetup.c
+++ b/sys/src/ape/lib/ap/plan9/_envsetup.c
@@ -21,7 +21,6 @@
char **environ;
int errno;
unsigned long _clock;
-static char name[NAME_MAX+5] = "#e";
static void fdsetup(char *, char *);
static void sigsetup(char *, char *);
@@ -45,33 +44,32 @@ _envsetup(void)
nohandle = 0;
fdinited = 0;
cnt = 0;
- dfd = _OPEN(name, 0);
+ dfd = _OPEN("/env", 0);
if(dfd < 0) {
static char **emptyenvp = 0;
environ = emptyenvp;
return;
}
- name[2] = '/';
- ps = p = malloc(Envhunk);
psize = Envhunk;
+ ps = p = malloc(psize);
nd = _dirreadall(dfd, &d9a);
_CLOSE(dfd);
for(j=0; j<nd; j++){
d9 = &d9a[j];
n = strlen(d9->name);
- if(n >= sizeof(name)-4)
- continue;
m = d9->length;
i = p - ps;
- if(i+n+1+m+1 > psize) {
- psize += (n+m+2 < Envhunk)? Envhunk : n+m+2;
+ if(i+n+5+m+1 > psize) {
+ psize += (n+m+6 < Envhunk)? Envhunk : n+m+6;
ps = realloc(ps, psize);
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);
p[n] = '=';
- strcpy(name+3, d9->name);
- f = _OPEN(name, O_RDONLY);
if(f < 0 || _READ(f, p+n+1, m) != m)
m = 0;
_CLOSE(f);
diff --git a/sys/src/ape/lib/ap/plan9/_fdinfo.c b/sys/src/ape/lib/ap/plan9/_fdinfo.c
index 85bbeca95..51d034898 100644
--- a/sys/src/ape/lib/ap/plan9/_fdinfo.c
+++ b/sys/src/ape/lib/ap/plan9/_fdinfo.c
@@ -2,6 +2,7 @@
#include "lib.h"
#include <sys/stat.h>
#include <stdlib.h>
+#include <unistd.h>
#include "sys9.h"
#include <string.h>
@@ -33,21 +34,12 @@ readprocfdinit(void)
/* construct info from /proc/$pid/fd */
char buf[8192];
Fdinfo *fi;
- int fd, pfd, pid, n, tot, m;
+ int fd, pfd, n, tot, m;
char *s, *nexts;
memset(buf, 0, sizeof buf);
- pfd = _OPEN("#c/pid", 0);
- if(pfd < 0)
- 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);
+ strcpy(buf, "/proc/");
+ _ultoa(buf+6, getpid());
strcat(buf, "/fd");
pfd = _OPEN(buf, 0);
if(pfd < 0)
@@ -77,9 +69,7 @@ readprocfdinit(void)
fd = strtoul(s, &s, 10);
if(errno != 0)
return -1;
- if(fd >= OPEN_MAX)
- continue;
- if(fd == pfd)
+ if(fd < 0 || fd == pfd || fd >= OPEN_MAX)
continue;
fi = &_fdinfo[fd];
fi->flags = FD_ISOPEN;
@@ -149,8 +139,6 @@ _fdinit(char *s, char *se)
usedproc = 0;
if(readprocfdinit() == 0)
usedproc = 1;
-else
-_WRITE(2, "FAILED\n", 7);
if(s)
sfdinit(usedproc, s, se);
if(!s && !usedproc)
diff --git a/sys/src/ape/lib/ap/plan9/execlp.c b/sys/src/ape/lib/ap/plan9/execlp.c
index ff5d71761..2bb8d3980 100644
--- a/sys/src/ape/lib/ap/plan9/execlp.c
+++ b/sys/src/ape/lib/ap/plan9/execlp.c
@@ -16,9 +16,11 @@ execlp(const char *name, const char *arg0, ...)
char buf[PATH_MAX];
if((n=execve(name, &arg0, environ)) < 0){
+ if(strchr("/.", name[0]) != 0 || strlen(name) >= sizeof(buf)-5)
+ return n;
strcpy(buf, "/bin/");
strcpy(buf+5, name);
- n = execve(buf, &name+1, environ);
+ n = execve(buf, &arg0, environ);
}
return n;
}
diff --git a/sys/src/ape/lib/ap/plan9/execve.c b/sys/src/ape/lib/ap/plan9/execve.c
index 1d5c3c2fe..e11ca1c21 100644
--- a/sys/src/ape/lib/ap/plan9/execve.c
+++ b/sys/src/ape/lib/ap/plan9/execve.c
@@ -14,8 +14,7 @@ execve(const char *name, const char *argv[], const char *envp[])
char **e, *ss, *se;
Fdinfo *fi;
unsigned long flags;
- char nam[256+5];
- char buf[1000];
+ char buf[1024];
_RFORK(RFCENVG);
/*
@@ -24,31 +23,40 @@ execve(const char *name, const char *argv[], const char *envp[])
* in $_fdinfo (for open fd's)
*/
- f = _CREATE("#e/_fdinfo", OWRITE, 0666);
+ f = _CREATE("/env/_fdinfo", OWRITE, 0666);
ss = buf;
- for(n = 0; n<OPEN_MAX; n++){
- fi = &_fdinfo[n];
+ for(i = 0; i<OPEN_MAX; i++){
+ if(i == f)
+ continue;
+ fi = &_fdinfo[i];
flags = fi->flags;
if(flags&FD_CLOEXEC){
- _CLOSE(n);
+ _CLOSE(i);
fi->flags = 0;
fi->oflags = 0;
}else if(flags&FD_ISOPEN){
- ss = _ultoa(ss, n);
+ if(f < 0)
+ continue;
+ ss = _ultoa(ss, i);
*ss++ = ' ';
ss = _ultoa(ss, flags);
*ss++ = ' ';
ss = _ultoa(ss, fi->oflags);
*ss++ = '\n';
- if(ss-buf < sizeof(buf)-50){
- _WRITE(f, buf, ss-buf);
+ n = ss-buf;
+ if(n > sizeof(buf)-50){
+ if(_WRITE(f, buf, n) != n)
+ break;
ss = buf;
}
}
}
- if(ss > buf)
- _WRITE(f, buf, ss-buf);
- _CLOSE(f);
+ if(f >= 0){
+ if(ss > buf)
+ _WRITE(f, buf, ss-buf);
+ _CLOSE(f);
+ }
+
/*
* To pass _sighdlr[] across exec, set $_sighdlr
* 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
* variable ignored some.
*/
- f = _CREATE("#e/_sighdlr", OWRITE, 0666);
+ f = _CREATE("/env/_sighdlr", OWRITE, 0666);
if(f >= 0){
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) {
ss = _ultoa(ss, i);
*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);
}
if(envp){
- strcpy(nam, "#e/");
for(e = envp; (ss = *e); e++) {
se = strchr(ss, '=');
if(!se || ss==se)
continue; /* what is name? value? */
n = se-ss;
- if(n >= sizeof(nam)-3)
- n = sizeof(nam)-3-1;
- memcpy(nam+3, ss, n);
- nam[3+n] = 0;
- f = _CREATE(nam, OWRITE, 0666);
+ if(n >= sizeof(buf)-5)
+ continue; /* name too long */
+ strcpy(buf, "/env/");
+ memcpy(buf+5, ss, n);
+ buf[5+n] = 0;
+ f = _CREATE(buf, OWRITE, 0666);
if(f < 0)
continue;
- se++; /* past = */
- n = strlen(se);
- /* temporarily decode nulls (see _envsetup()) */
- for(i=0; i < n; i++)
- if(se[i] == 1)
- se[i] = 0;
- _WRITE(f, se, n);
- /* put nulls back */
- for(i=0; i < n; i++)
- if(se[i] == 0)
- se[i] = 1;
+ ss = ++se; /* past = */
+ se += strlen(ss);
+ while((n = (se - ss)) > 0){
+ if(n > sizeof(buf))
+ n = sizeof(buf);
+ /* decode nulls (see _envsetup()) */
+ for(i=0; i<n; i++)
+ if((buf[i] = ss[i]) == 1)
+ buf[i] = 0;
+ if(_WRITE(f, buf, n) != n)
+ break;
+ ss += n;
+ }
_CLOSE(f);
}
}
diff --git a/sys/src/ape/lib/ap/plan9/getppid.c b/sys/src/ape/lib/ap/plan9/getppid.c
index 01759221b..6d40a3cc9 100644
--- a/sys/src/ape/lib/ap/plan9/getppid.c
+++ b/sys/src/ape/lib/ap/plan9/getppid.c
@@ -9,15 +9,14 @@
pid_t
getppid(void)
{
- int n, f;
- char ppidbuf[15];
+ char b[20];
+ int f;
- f = open("#c/ppid", 0);
- n = read(f, ppidbuf, sizeof ppidbuf);
- if(n < 0)
- errno = EINVAL;
- else
- n = atoi(ppidbuf);
- close(f);
- return n;
+ memset(b, 0, sizeof(b));
+ f = open("/dev/ppid", 0);
+ if(f >= 0) {
+ read(f, b, sizeof(b));
+ close(f);
+ }
+ return atol(b);
}