code: plan9front

Download patch

ref: ceeb701a2b93d3f0b96a8b8f945ed5e46d2d0672
parent: 67672ffdc9a537ef852c0edd89a5d8cef7346d11
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Mon Dec 28 16:00:15 EST 2020

plumber: don't leak srvfd file descriptor into sub processes

Put OCEXEC flag on the srvfd so it wont be leaked
on sub-processes we spawn from plumb rules.

--- a/sys/src/cmd/plumb/fsys.c
+++ b/sys/src/cmd/plumb/fsys.c
@@ -99,7 +99,7 @@
 static int	ndir = NQID;
 
 static int		srvfd;
-static int		srvclosefd;			/* rock for end of pipe to close */
+static int		mntfd;
 static int		clockfd;
 static int		clock;
 static Fid		*fids[Nhash];
@@ -190,19 +190,34 @@
 	return atoi(buf);
 }
 
+/*
+ * Build pipe with OCEXEC set on second fd.
+ * Can't put it on both because we want to post one in /srv.
+ */
+static int
+cexecpipe(int *p0, int *p1)
+{
+	/* pipe the hard way to get close on exec */
+	if(bind("#|", "/mnt/temp", MREPL) == -1)
+		return -1;
+	*p0 = open("/mnt/temp/data", ORDWR);
+	*p1 = open("/mnt/temp/data1", ORDWR|OCEXEC);
+	unmount(nil, "/mnt/temp");
+	if(*p0<0 || *p1<0)
+		return -1;
+	return 0;
+}
+
 void
 startfsys(void)
 {
-	int p[2], fd;
+	int fd;
 
 	fmtinstall('F', fcallfmt);
 	clockfd = open("/dev/time", OREAD|OCEXEC);
 	clock = getclock();
-	if(pipe(p) < 0)
+	if(cexecpipe(&mntfd, &srvfd) < 0)
 		error("can't create pipe: %r");
-	/* 0 will be server end, 1 will be client end */
-	srvfd = p[0];
-	srvclosefd = p[1];
 	sprint(srvfile, "/srv/plumb.%s.%d", user, getpid());
 	if(putenv("plumbsrv", srvfile) < 0)
 		error("can't write $plumbsrv: %r");
@@ -209,16 +224,12 @@
 	fd = create(srvfile, OWRITE|OCEXEC|ORCLOSE, 0600);
 	if(fd < 0)
 		error("can't create /srv file: %r");
-	if(fprint(fd, "%d", p[1]) <= 0)
+	if(fprint(fd, "%d", mntfd) <= 0)
 		error("can't write /srv/file: %r");
-	/* leave fd open; ORCLOSE will take care of it */
-
 	procrfork(fsysproc, nil, Stack, RFFDG);
-
-	close(p[0]);
-	if(mount(p[1], -1, "/mnt/plumb", MREPL, "") == -1)
+	close(srvfd);
+	if(mount(mntfd, -1, "/mnt/plumb", MREPL, "") == -1)
 		error("can't mount /mnt/plumb: %r");
-	close(p[1]);
 }
 
 static void
@@ -229,8 +240,8 @@
 	Fid *f;
 	uchar *buf;
 
-	close(srvclosefd);
-	srvclosefd = -1;
+	close(mntfd);
+
 	t = nil;
 	for(;;){
 		buf = malloc(messagesize);	/* avoid memset of emalloc */