git: 9front

Download patch

ref: 8f68e89a895fb05b51429b02b4dd43ba65e3abfd
parent: 3ad7388b7424d20f343d12b4f2282fc6d3938e9e
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Oct 20 14:32:57 EDT 2025

lib9p: Fix srvrelease() stack descend into madness issue (thanks ori)

When using rfork based forker (srvforker()) for lib9p,
each srvrelease() call would spawn a new srvwork()
process on a deeper stack level. Eventually,
we run out of virtual address space for the stack
and the service will crash.

This solves the issue by adding a jmp_buf into Srv
and instead of passing srvwork directly to the forker,
we do a longjump back to the first invocation of srv().

This affects the following 9p servers using srvrelease():

audio/mixfs
auth/factotum
execfs
nusb/disk
webfs

--- a/sys/include/9p.h
+++ b/sys/include/9p.h
@@ -235,6 +235,7 @@
 	int	spid;	/* pid of srv() caller */
 	int	authok;	/* auth was done on this channel (for none) */
 
+	jmp_buf	srvtos;
 	void	(*forker)(void (*)(void*), void*, int);
 	void	(*free)(Srv*);
 };
--- a/sys/src/lib9p/srv.c
+++ b/sys/src/lib9p/srv.c
@@ -810,12 +810,21 @@
 	qlock(&srv->slock);
 }
 
+static void
+resetstack(void *arg)
+{
+	longjmp(arg, 1);
+}
+
 void
 srvrelease(Srv *srv)
 {
 	if(decref(&srv->sref) == 0){
 		incref(&srv->sref);
-		(*srv->forker)(srvwork, srv, 0);
+		if(srv->forker == srvforker)
+			srvforker(resetstack, srv->srvtos, 0);
+		else
+			(*srv->forker)(srvwork, srv, 0);
 	}
 	qunlock(&srv->slock);
 }
@@ -849,6 +858,7 @@
 		srv->forker = srvforker;
 
 	incref(&srv->sref);
+	setjmp(srv->srvtos);
 	srvwork(srv);
 }
 
--