summaryrefslogtreecommitdiff
path: root/sys/src/ape/lib/ap/plan9/execve.c
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/lib/ap/plan9/execve.c
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/lib/ap/plan9/execve.c')
-rw-r--r--sys/src/ape/lib/ap/plan9/execve.c81
1 files changed, 49 insertions, 32 deletions
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);
}
}