code: plan9front

Download patch

ref: c3474e39d6613d5000dcd7bb08de81e96904db53
parent: 79e9c9534592bc4948f4a0299f413d7cfa45479c
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Dec 4 12:48:56 EST 2022

kernel: free exec temporary stack segment under seglock

On error, we must free the temporary stack segment
while holding up->seglock.

--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -321,11 +321,6 @@
 		/* Disaster after commit */
 		if(up->seg[SSEG] == nil)
 			pexit(up->errstr, 1);
-		s = up->seg[ESEG];
-		if(s != nil){
-			putseg(s);
-			up->seg[ESEG] = nil;
-		}
 		nexterror();
 	}
 	align = BY2PG-1;
@@ -451,6 +446,11 @@
 	 */
 	qlock(&up->seglock);
 	if(waserror()){
+		s = up->seg[ESEG];
+		if(s != nil){
+			up->seg[ESEG] = nil;
+			putseg(s);
+		}
 		qunlock(&up->seglock);
 		nexterror();
 	}
@@ -524,15 +524,18 @@
 	 * Special segments are maintained across exec
 	 */
 	for(i = SSEG; i <= BSEG; i++) {
-		putseg(up->seg[i]);
-		/* prevent a second free if we have an error */
-		up->seg[i] = nil;
+		s = up->seg[i];
+		if(s != nil) {
+			/* prevent a second free if we have an error */
+			up->seg[i] = nil;
+			putseg(s);
+		}
 	}
 	for(i = ESEG+1; i < NSEG; i++) {
 		s = up->seg[i];
 		if(s != nil && (s->type&SG_CEXEC) != 0) {
-			putseg(s);
 			up->seg[i] = nil;
+			putseg(s);
 		}
 	}