shithub: riscv

Download patch

ref: 2acb02f29ba24f3fed9bb3b8b0e0d870181eef50
parent: b89fcf2fe32195d0900b1a04ca98a4cb3cc62bf1
author: cinap_lenrek <[email protected]>
date: Thu Aug 6 04:47:38 EDT 2015

kernel: reject empty argv (argv[0] == nil) in sysexec()

when executing a script, we did advance argp0 unconditionally
to replace argv[0] with the script name. this fails when
argv[] is empty, then we'd advance argp0 past the nil terminator.

the alternative would be to *not* advance if *argp0 == nil, but that
would require another validaddr() check for a case that is unlikely
to have been anticipated in most programs being invoked as
libc's ARGBEGIN macro assumes argv[0] being non-nil as it also
unconditionally advances the argv pointer.

to keep us sane, we now reject an empty argv[]. on entry, we
verify that argv[] is valid for at least two elements:
- the program name argv[0], has to be non-nil
- the first potential nil terminator in argv[1]

when argv[0] == nil, we throw Ebadarg "bad arg in system call"

--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -255,6 +255,10 @@
 	file0 = va_arg(list, char*);
 	validaddr((uintptr)file0, 1, 0);
 	argp0 = va_arg(list, char**);
+	evenaddr((uintptr)argp0);
+	validaddr((uintptr)argp0, 2*BY2WD, 0);
+	if(*argp0 == nil)
+		error(Ebadarg);
 	file0 = validnamedup(file0, 1);
 	if(waserror()){
 		free(file0);
@@ -351,9 +355,7 @@
 		}
 	}
 	argp = argp0;
-	evenaddr((uintptr)argp);
-	validaddr((uintptr)argp, BY2WD, 0);
-	while(*argp){
+	while(*argp != nil){
 		a = *argp++;
 		if(((uintptr)argp&(BY2PG-1)) < BY2WD)
 			validaddr((uintptr)argp, BY2WD, 0);