git: 9front

Download patch

ref: 8b5e8084fc7b57e847f1f850374d110f84ba532b
parent: f28f9f58f7a733f91fca9145569b90f9bdaea27f
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Oct 31 19:23:27 EDT 2025

kernel: fix off-by-one in sysexec progargs

When terminating progargs[], it was possible that
we would set progargs[nelem(progargs)] = nil.

The variable after the progargs array is
volatile char *args, which is already nil,
and not used until later.

Fix the off-by-one, and inline the code for
shargs() directly as it makes it more easy to
see what is going on.

We now raise an error when there are more than
31 (nelem(progargs)-2) arguments passed.

--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -277,24 +277,6 @@
 	return pid;
 }
 
-static int
-shargs(char *s, int n, char **ap, int nap)
-{
-	char *p;
-	int i;
-
-	if(n <= 2 || s[0] != '#' || s[1] != '!')
-		return -1;
-	s += 2;
-	n -= 2;		/* skip #! */
-	if((p = memchr(s, '\n', n)) == nil)
-		return 0;
-	*p = 0;
-	i = tokenize(s, ap, nap-1);
-	ap[i] = nil;
-	return i;
-}
-
 ulong
 beswal(ulong l)
 {
@@ -412,9 +394,14 @@
 		 * Process #! /bin/sh args ...
 		 */
 		memmove(line, u.buf, n);
-		n = shargs(line, n, progarg, nelem(progarg));
-		if(n < 1)
+		if(n <= 2 || line[0] != '#' || line[1] != '!'
+		|| (a = memchr(line+2, '\n', n-2)) == nil)
 			error(Ebadexec);
+		*a = '\0';
+		n = tokenize(line+2, progarg, nelem(progarg)-1);
+		if(n < 1 || n >= nelem(progarg)-1)
+			error(Ebadexec);
+
 		/*
 		 * First arg becomes complete file name
 		 */
--