diff options
author | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-02-02 15:11:19 +0100 |
---|---|---|
committer | cinap_lenrek <cinap_lenrek@felloff.net> | 2014-02-02 15:11:19 +0100 |
commit | 0cdb32cc18b953fd22e86ba6fc6e24787f254576 (patch) | |
tree | 9a3e308313c80259285b0354c72c62f98d88d4e9 /sys/src/9/port/sysproc.c | |
parent | 269788514c9dae931ed6ac537786e56cabe44296 (diff) |
kernel: fix bogus free in sysexec.
we free the wrong pointer in the waserror() block.
Diffstat (limited to 'sys/src/9/port/sysproc.c')
-rw-r--r-- | sys/src/9/port/sysproc.c | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/sys/src/9/port/sysproc.c b/sys/src/9/port/sysproc.c index 8f2ee849c..05e590da0 100644 --- a/sys/src/9/port/sysproc.c +++ b/sys/src/9/port/sysproc.c @@ -251,8 +251,7 @@ sysexec(va_list list) Image *img; Tos *tos; - a = nil; - elem = nil; + args = elem = nil; file0 = va_arg(list, char*); validaddr((uintptr)file0, 1, 0); argp0 = va_arg(list, char**); @@ -260,7 +259,7 @@ sysexec(va_list list) if(waserror()){ free(file0); free(elem); - free(a); + free(args); /* Disaster after commit */ if(!up->seg[SSEG]) pexit(up->errstr, 1); @@ -396,7 +395,7 @@ sysexec(va_list list) argv = (char**)(tstk - ssize); charp = (char*)(tstk - nbytes); - args = charp; + a = charp; if(indir) argp = progarg; else @@ -414,18 +413,18 @@ sysexec(va_list list) } /* copy args; easiest from new process's stack */ - n = charp - args; + n = charp - a; if(n > 128) /* don't waste too much space on huge arg lists */ n = 128; - a = smalloc(n); - memmove(a, args, n); - if(n>0 && a[n-1]!='\0'){ + args = smalloc(n); + memmove(args, a, n); + if(n>0 && args[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(a+i, n-i)) + if(fullrune(args+i, n-i)) break; - a[i] = 0; + args[i] = 0; n = i+1; } @@ -505,7 +504,7 @@ sysexec(va_list list) free(up->text); up->text = elem; free(up->args); - up->args = a; + up->args = args; up->nargs = n; up->setargs = 0; |