shithub: riscv

Download patch

ref: 281729551fd7351b410f788d267c9041ae1ef15f
parent: b09cd6786047e4572f98a7703992fe96e4312da7
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Thu Aug 6 07:51:23 EDT 2015

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.

--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -270,7 +270,7 @@
 	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 @@
 		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 @@
 			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;