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);
}
--
⑨