diff options
author | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-09-18 01:07:06 +0200 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@gmx.de> | 2013-09-18 01:07:06 +0200 |
commit | 34cd9dc4c462ab01ce063a58a40f1317fcb13172 (patch) | |
tree | 9412be7121d64860b8169f8c4be2a998b628280f /sys/src/9/port/sysproc.c | |
parent | 8a7a6f778dec447480683186dcc43c7e406e7465 (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.c | 31 |
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; |