git: 9front

Download patch

ref: c9d4c3bd83310c8ea6cac3b6e7d989cdb19c9331
parent: 44374f9a1556a5e806a4fe73bbc6bc400888284f
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Tue Sep 17 21:07:06 EDT 2013

kernel: reset up->setargs on sysexec(), fix race with devproc

up->setargs wasnt reset in sysexec(). also, up->args should only
be exchanged/freed under up->debug qlock. otherwise double free
could happen.

--- a/sys/src/9/port/portdat.h
+++ b/sys/src/9/port/portdat.h
@@ -737,7 +737,7 @@
 	ulong	qpc;		/* pc calling last blocking qlock */
 	QLock	*eql;		/* interruptable eqlock */
 
-	int	setargs;
+	int	setargs;	/* process changed its args */
 
 	void	*ureg;		/* User registers for notes */
 	void	*dbgreg;	/* User registers for devproc */
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -252,19 +252,20 @@
 	ulong magic, text, entry, data, bss;
 	Tos *tos;
 
-	indir = 0;
+	a = nil;
 	elem = nil;
 	validaddr(arg[0], 1, 0);
 	file0 = validnamedup((char*)arg[0], 1);
 	if(waserror()){
 		free(file0);
-		if(elem != up->text)
-			free(elem);
+		free(elem);
+		free(a);
 		/* Disaster after commit */
 		if(!up->seg[SSEG])
 			pexit(up->errstr, 1);
 		nexterror();
 	}
+	indir = 0;
 	file = file0;
 	for(;;){
 		tc = namec(file, Aopen, OEXEC, 0);
@@ -405,28 +406,21 @@
 		charp += n;
 	}
 
-	free(up->text);
-	up->text = elem;
-
 	/* copy args; easiest from new process's stack */
 	n = charp - args;
 	if(n > 128)	/* don't waste too much space on huge arg lists */
 		n = 128;
-	a = up->args;
-	up->args = nil;
-	free(a);
-	up->args = smalloc(n);
-	memmove(up->args, args, n);
-	if(n>0 && up->args[n-1]!='\0'){
+	a = smalloc(n);
+	memmove(a, args, n);
+	if(n>0 && a[n-1]!='\0'){
 		/* make sure last arg is NUL-terminated */
 		/* put NUL at UTF-8 character boundary */
 		for(i=n-1; i>0; --i)
-			if(fullrune(up->args+i, n-i))
+			if(fullrune(a+i, n-i))
 				break;
-		up->args[i] = 0;
+		a[i] = 0;
 		n = i+1;
 	}
-	up->nargs = n;
 
 	/*
 	 * Committed.
@@ -501,6 +495,13 @@
 	free(file0);
 
 	qlock(&up->debug);
+	free(up->text);
+	up->text = elem;
+	free(up->args);
+	up->args = a;
+	up->nargs = n;
+	up->setargs = 0;
+
 	up->nnote = 0;
 	up->notify = 0;
 	up->notified = 0;
--