summaryrefslogtreecommitdiff
path: root/sys/src/9/port/sysproc.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2015-08-06 11:51:23 +0200
committercinap_lenrek <cinap_lenrek@felloff.net>2015-08-06 11:51:23 +0200
commit281729551fd7351b410f788d267c9041ae1ef15f (patch)
treefaef5257028a3c4bfac6b8d0c6e9cde3f646d49b /sys/src/9/port/sysproc.c
parentb09cd6786047e4572f98a7703992fe96e4312da7 (diff)
kernel: limit argv[] strings to the USTKSIZE to avoid overflow
argv[] strings get copied to the new processes stack segment, which has a maximum size of USTKSIZE, so limit the size of the strings to that and check early for overflow.
Diffstat (limited to 'sys/src/9/port/sysproc.c')
-rw-r--r--sys/src/9/port/sysproc.c11
1 files changed, 8 insertions, 3 deletions
diff --git a/sys/src/9/port/sysproc.c b/sys/src/9/port/sysproc.c
index 0a71a0c03..733ab381d 100644
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -270,7 +270,7 @@ sysexec(va_list list)
int i;
Chan *tc;
char **argv, **argp, **argp0;
- char *a, *charp, *args, *file, *file0;
+ char *a, *e, *charp, *args, *file, *file0;
char *progarg[sizeof(Exec)/2+1], *elem, progelem[64];
ulong magic, ssize, nargs, nbytes, n;
uintptr t, d, b, entry, bssend, text, data, bss, tstk, align;
@@ -390,7 +390,12 @@ sysexec(va_list list)
if(((uintptr)argp&(BY2PG-1)) < BY2WD)
validaddr((uintptr)argp, BY2WD, 0);
validaddr((uintptr)a, 1, 0);
- nbytes += ((char*)vmemchr(a, 0, ~0) - a) + 1;
+ e = vmemchr(a, 0, USTKSIZE);
+ if(e == nil)
+ error(Ebadarg);
+ nbytes += (e - a) + 1;
+ if(nbytes >= USTKSIZE)
+ error(Enovmem);
nargs++;
}
ssize = BY2WD*(nargs+1) + ((nbytes+(BY2WD-1)) & ~(BY2WD-1));
@@ -610,7 +615,7 @@ sysexits(va_list list)
status = inval;
else{
validaddr((uintptr)status, 1, 0);
- if(vmemchr(status, 0, ERRMAX) == 0){
+ if(vmemchr(status, 0, ERRMAX) == nil){
memmove(buf, status, ERRMAX);
buf[ERRMAX-1] = 0;
status = buf;