9front - general discussion about 9front
 help / color / mirror / Atom feed
* [9front] auth/box: tweaks for #! lines
@ 2022-07-10 21:50 ori
  2022-07-10 22:32 ` ori
  0 siblings, 1 reply; 2+ messages in thread
From: ori @ 2022-07-10 21:50 UTC (permalink / raw)
  To: 9front

this makes 'auth/box -s' work better when dropping the
sandboxing in a #! line, allowing any number of command
line arguments, verifying that the current dir is in the
namespace, and using it if available -- and erroring if
it's not.

diff cd64b7129c81102c811b3df9a32ceb4004420f54 uncommitted
--- a//sys/src/cmd/auth/box.c
+++ b//sys/src/cmd/auth/box.c
@@ -2,7 +2,11 @@
 #include <libc.h>
 #include <auth.h>
 
-static int debug;
+static int	debug;
+static char	cwd[8192];
+static char	*parts[256];
+static int	mflags[nelem(parts)];
+static int	nparts;
 
 static void
 binderr(char *new, char *old, int flag)
@@ -32,20 +36,15 @@
 		fprint(2, "bind %s %s %s\n", dash, new, old);
 	}
 	if(bind(new, old, flag) < 0)
-		sysfatal("bind: %r");
+		sysfatal("bind %s: %r", new);
 }
 
 static void
 resolvenames(char **names, int nname)
 {
-	int i;
-	char buf[8192];
-	int fd;
+	int i, gotcwd;
 
-	fd = open(".", OREAD|OCEXEC);
-	if(fd < 0)
-		sysfatal("could not open .: %r");
-	fd2path(fd, buf, sizeof buf);
+	gotcwd = 0;
 	for(i = 0; i < nname; i++){
 		if(names[i] == nil)
 			continue;
@@ -55,10 +54,13 @@
 		case '/':
 			break;
 		default:
-			names[i] = cleanname(smprint("%s/%s", buf, names[i]));
-		}	
+			names[i] = cleanname(smprint("%s/%s", cwd, names[i]));
+		}
+		if(strcmp(names[i], cwd) == 0)
+			gotcwd = 1;	
 	}
-	close(fd);
+	if(!gotcwd && strcmp(cwd, "/") != 0)
+		sysfatal("working outside box: %s", cwd);
 }
 
 static void
@@ -133,16 +135,11 @@
 		sysfatal("/mnt/d mount setup: %r");
 }
 
-static char *parts[256];
-static int  mflags[nelem(parts)];
-static int  nparts;
-static char *rc[] = { "/bin/rc", nil , nil};
-
 static void
 push(char *path, int flag)
 {
 	if(nparts == nelem(parts))
-		sysfatal("component overflow");
+		sysfatal("too many bound paths");
 	parts[nparts] = path;
 	mflags[nparts++] = flag;
 }
@@ -157,16 +154,16 @@
 void
 main(int argc, char **argv)
 {
-	char devs[1024];
-	int dfd;
-	char *path;
+	char **argp, devs[128];
+	int i, narg, dfd;
 	char *a;
 	int sflag;
 
 	nparts = 0;
-	path = "/";
+	narg = 0;
 	memset(devs, 0, sizeof devs);
 	sflag = 0;
+	argp = argv;
 	ARGBEGIN{
 	case 'D':
 		debug++;
@@ -184,9 +181,6 @@
 	case 'e':
 		snprint(devs, sizeof devs, "%s%s", devs, EARGF(usage()));
 		break;
-	case '.':
-		path = EARGF(usage());
-		break;
 	case 's':
 		sflag = 1;
 		break;
@@ -198,6 +192,8 @@
 	if(argc == 0)
 		usage();
 
+	if(getwd(cwd, sizeof(cwd)) == nil)
+		sysfatal("getwd: %r");
 	if(sflag){
 		snprint(devs, sizeof devs, "%s%s", devs, "|d");
 		push("/srv", MREPL|MCREATE);
@@ -204,9 +200,7 @@
 		push("/env", MREPL|MCREATE);
 		push("/rc", MREPL);
 		push("/bin", MREPL);
-		push(argv[0], MREPL);
-		rc[1] = argv[0];
-		argv = rc;
+		argp[narg++] = "/bin/rc";
 	} else {
 		if(access(argv[0], AEXIST) == -1){
 			if((argv[0] = smprint("/bin/%s", argv[0])) == nil)
@@ -216,6 +210,9 @@
 		}
 		push(argv[0], MREPL);
 	}
+	for(i = 0; i < argc; i++)
+		argp[narg++] = argv[i];
+	argp[narg] = nil;
 
 	rfork(RFNAMEG|RFFDG);
 	skelfs();
@@ -225,7 +222,7 @@
 
 	resolvenames(parts, nparts);
 	sandbox(parts, mflags, nparts);
-	
+
 	if(debug)
 		fprint(2, "chdev %s\n", devs);
 
@@ -238,8 +235,8 @@
 	}
 	close(dfd);
 
-	if(chdir(path) < 0)
-		sysfatal("can not cd to %s", path);
-	exec(argv[0], argv);
+	if(chdir(cwd) < 0)
+		sysfatal("chdir %s: %r", cwd);
+	exec(argp[0], argp);
 	sysfatal("exec: %r");
 }


^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [9front] auth/box: tweaks for #! lines
  2022-07-10 21:50 [9front] auth/box: tweaks for #! lines ori
@ 2022-07-10 22:32 ` ori
  0 siblings, 0 replies; 2+ messages in thread
From: ori @ 2022-07-10 22:32 UTC (permalink / raw)
  To: 9front

Quoth ori@eigenstate.org:
> this makes 'auth/box -s' work better when dropping the
> sandboxing in a #! line, allowing any number of command
> line arguments, verifying that the current dir is in the
> namespace, and using it if available -- and erroring if
> it's not.

new revision: we now include an empty template for cwd
always, so that relative paths will work.

	auth/box $paths $cmd

will work exactly the same as

	$cmd

as long as $cmd only touches the paths handed to auth/box.

diff 845f8d12e4e417aaafaa6e62a80bf03856e7d906 uncommitted
--- a/sys/src/cmd/auth/box.c
+++ b/sys/src/cmd/auth/box.c
@@ -2,7 +2,11 @@
 #include <libc.h>
 #include <auth.h>
 
-static int debug;
+static int	debug;
+static char	cwd[8192];
+static char	*parts[256];
+static int	mflags[nelem(parts)];
+static int	nparts;
 
 static void
 binderr(char *new, char *old, int flag)
@@ -32,7 +36,7 @@
 		fprint(2, "bind %s %s %s\n", dash, new, old);
 	}
 	if(bind(new, old, flag) < 0)
-		sysfatal("bind: %r");
+		sysfatal("bind %s: %r", new);
 }
 
 static void
@@ -39,13 +43,7 @@
 resolvenames(char **names, int nname)
 {
 	int i;
-	char buf[8192];
-	int fd;
 
-	fd = open(".", OREAD|OCEXEC);
-	if(fd < 0)
-		sysfatal("could not open .: %r");
-	fd2path(fd, buf, sizeof buf);
 	for(i = 0; i < nname; i++){
 		if(names[i] == nil)
 			continue;
@@ -55,10 +53,9 @@
 		case '/':
 			break;
 		default:
-			names[i] = cleanname(smprint("%s/%s", buf, names[i]));
-		}	
+			names[i] = cleanname(smprint("%s/%s", cwd, names[i]));
+		}
 	}
-	close(fd);
 }
 
 static void
@@ -103,7 +100,8 @@
 			free(d);
 			binderr(skel, dir, MBEFORE);
 		}
-		binderr(names[j], targ, flags[j]);
+		if(flags[j] != -1)
+			binderr(names[j], targ, flags[j]);
 	}
 	binderr(newroot, "/", MREPL);
 }
@@ -133,16 +131,11 @@
 		sysfatal("/mnt/d mount setup: %r");
 }
 
-static char *parts[256];
-static int  mflags[nelem(parts)];
-static int  nparts;
-static char *rc[] = { "/bin/rc", nil , nil};
-
 static void
 push(char *path, int flag)
 {
 	if(nparts == nelem(parts))
-		sysfatal("component overflow");
+		sysfatal("too many bound paths");
 	parts[nparts] = path;
 	mflags[nparts++] = flag;
 }
@@ -157,16 +150,16 @@
 void
 main(int argc, char **argv)
 {
-	char devs[1024];
-	int dfd;
-	char *path;
+	char **argp, devs[128];
+	int i, narg, dfd;
 	char *a;
 	int sflag;
 
 	nparts = 0;
-	path = "/";
+	narg = 0;
 	memset(devs, 0, sizeof devs);
 	sflag = 0;
+	argp = argv;
 	ARGBEGIN{
 	case 'D':
 		debug++;
@@ -184,9 +177,6 @@
 	case 'e':
 		snprint(devs, sizeof devs, "%s%s", devs, EARGF(usage()));
 		break;
-	case '.':
-		path = EARGF(usage());
-		break;
 	case 's':
 		sflag = 1;
 		break;
@@ -198,6 +188,9 @@
 	if(argc == 0)
 		usage();
 
+	if(getwd(cwd, sizeof(cwd)) == nil)
+		sysfatal("getwd: %r");
+	push(cwd, -1);
 	if(sflag){
 		snprint(devs, sizeof devs, "%s%s", devs, "|d");
 		push("/srv", MREPL|MCREATE);
@@ -204,9 +197,7 @@
 		push("/env", MREPL|MCREATE);
 		push("/rc", MREPL);
 		push("/bin", MREPL);
-		push(argv[0], MREPL);
-		rc[1] = argv[0];
-		argv = rc;
+		argp[narg++] = "/bin/rc";
 	} else {
 		if(access(argv[0], AEXIST) == -1){
 			if((argv[0] = smprint("/bin/%s", argv[0])) == nil)
@@ -216,6 +207,9 @@
 		}
 		push(argv[0], MREPL);
 	}
+	for(i = 0; i < argc; i++)
+		argp[narg++] = argv[i];
+	argp[narg] = nil;
 
 	rfork(RFNAMEG|RFFDG);
 	skelfs();
@@ -225,7 +219,7 @@
 
 	resolvenames(parts, nparts);
 	sandbox(parts, mflags, nparts);
-	
+
 	if(debug)
 		fprint(2, "chdev %s\n", devs);
 
@@ -238,8 +232,8 @@
 	}
 	close(dfd);
 
-	if(chdir(path) < 0)
-		sysfatal("can not cd to %s", path);
-	exec(argv[0], argv);
+	if(chdir(cwd) < 0)
+		sysfatal("chdir %s: %r", cwd);
+	exec(argp[0], argp);
 	sysfatal("exec: %r");
 }


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-07-10 22:34 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-07-10 21:50 [9front] auth/box: tweaks for #! lines ori
2022-07-10 22:32 ` ori

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).