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