ref: 1c021658107239bf4213d2d0f9b4cfc1fa13daf0
parent: 46832f04fa6f2ccd7a85d1a640bf5408e82b2571
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Aug 6 09:20:41 EDT 2015
kernel: have to validate argv[] again when copying to the new stack we have to validaddr() and vmemchr() all argv[] elements a second time when we copy to the new stack to deal with the fact that another process can come in and modify the memory of the process doing the exec. so the argv[] strings could have changed and increased in length. we just make sure the data being copied will fit into the new stack and error when we would overflow. also make sure to free the ESEG in case the copy pass errors.
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -295,8 +295,13 @@
free(elem);
free(args);
/* Disaster after commit */
- if(!up->seg[SSEG])
+ if(up->seg[SSEG] == nil)
pexit(up->errstr, 1);
+ s = up->seg[ESEG];
+ if(s != nil){+ putseg(s);
+ up->seg[ESEG] = nil;
+ }
nexterror();
}
align = BY2PG;
@@ -438,7 +443,6 @@
argv = (char**)(tstk - ssize);
charp = (char*)(tstk - nbytes);
- a = charp;
if(indir)
argp = progarg;
else
@@ -450,12 +454,22 @@
argp = argp0;
}
*argv++ = charp + (USTKTOP-tstk);
- n = strlen(*argp) + 1;
- memmove(charp, *argp++, n);
+ a = *argp++;
+ if(indir)
+ e = strchr(a, 0);
+ else {+ validaddr((uintptr)a, 1, 0);
+ e = vmemchr(a, 0, (char*)tstk - charp);
+ if(e == nil)
+ error(Ebadarg);
+ }
+ n = (e - a) + 1;
+ memmove(charp, a, n);
charp += n;
}
/* copy args; easiest from new process's stack */
+ a = (char*)(tstk - nbytes);
n = charp - a;
if(n > 128) /* don't waste too much space on huge arg lists */
n = 128;
--
⑨