summaryrefslogtreecommitdiff
path: root/sys/src/9/port/sysproc.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2013-09-18 01:07:06 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2013-09-18 01:07:06 +0200
commit34cd9dc4c462ab01ce063a58a40f1317fcb13172 (patch)
tree9412be7121d64860b8169f8c4be2a998b628280f /sys/src/9/port/sysproc.c
parent8a7a6f778dec447480683186dcc43c7e406e7465 (diff)
kernel: reset up->setargs on sysexec(), fix race with devproc
up->setargs wasnt reset in sysexec(). also, up->args should only be exchanged/freed under up->debug qlock. otherwise double free could happen.
Diffstat (limited to 'sys/src/9/port/sysproc.c')
-rw-r--r--sys/src/9/port/sysproc.c31
1 files changed, 16 insertions, 15 deletions
diff --git a/sys/src/9/port/sysproc.c b/sys/src/9/port/sysproc.c
index 8eed9814f..9f670a5a0 100644
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -252,19 +252,20 @@ sysexec(ulong *arg)
ulong magic, text, entry, data, bss;
Tos *tos;
- indir = 0;
+ a = nil;
elem = nil;
validaddr(arg[0], 1, 0);
file0 = validnamedup((char*)arg[0], 1);
if(waserror()){
free(file0);
- if(elem != up->text)
- free(elem);
+ free(elem);
+ free(a);
/* Disaster after commit */
if(!up->seg[SSEG])
pexit(up->errstr, 1);
nexterror();
}
+ indir = 0;
file = file0;
for(;;){
tc = namec(file, Aopen, OEXEC, 0);
@@ -405,28 +406,21 @@ sysexec(ulong *arg)
charp += n;
}
- free(up->text);
- up->text = elem;
-
/* copy args; easiest from new process's stack */
n = charp - args;
if(n > 128) /* don't waste too much space on huge arg lists */
n = 128;
- a = up->args;
- up->args = nil;
- free(a);
- up->args = smalloc(n);
- memmove(up->args, args, n);
- if(n>0 && up->args[n-1]!='\0'){
+ a = smalloc(n);
+ memmove(a, args, n);
+ if(n>0 && a[n-1]!='\0'){
/* make sure last arg is NUL-terminated */
/* put NUL at UTF-8 character boundary */
for(i=n-1; i>0; --i)
- if(fullrune(up->args+i, n-i))
+ if(fullrune(a+i, n-i))
break;
- up->args[i] = 0;
+ a[i] = 0;
n = i+1;
}
- up->nargs = n;
/*
* Committed.
@@ -501,6 +495,13 @@ sysexec(ulong *arg)
free(file0);
qlock(&up->debug);
+ free(up->text);
+ up->text = elem;
+ free(up->args);
+ up->args = a;
+ up->nargs = n;
+ up->setargs = 0;
+
up->nnote = 0;
up->notify = 0;
up->notified = 0;