ref: eaa1949ba0cbc21b1951c4907fe52ead915a411a
parent: 6926080a2d7c8a5b61888c18fa88d70f3384409b
author: Jacob Moody <moody@posixcafe.org>
date: Fri May 27 22:27:59 EDT 2022
auth/newns: add chdev command
--- a/sys/man/6/namespace
+++ b/sys/man/6/namespace
@@ -59,6 +59,12 @@
.I new
is missing.
.TP
+.BR chdev \ [ -nr "] \fIdevmask
+.I Devmask
+defines a string of driver characters to restrict
+the current namespace to. Existing binds
+of drivers are left unaffected.
+.TP
.BR clear
Clear the name space with
.BR rfork(RFCNAMEG) .
@@ -80,4 +86,5 @@
.SH "SEE ALSO"
.IR bind (1),
.IR namespace (4),
-.IR init (8)
+.IR init (8),
+.IR chdev (1)
--- a/sys/src/libauth/newns.c
+++ b/sys/src/libauth/newns.c
@@ -14,8 +14,8 @@
static int setenv(char*, char*);
static char *expandarg(char*, char*);
static int splitargs(char*, char*[], char*, int);
-static int nsfile(char*, Biobuf *, AuthRpc *);
-static int nsop(char*, int, char*[], AuthRpc*);
+static int nsfile(char*, Biobuf *, AuthRpc *, int);
+static int nsop(char*, int, char*[], AuthRpc*, int);
static int catch(void*, char*);
int newnsdebug;
@@ -35,7 +35,7 @@
{
Biobuf *b;
char home[4*ANAMELEN];
- int afd, cdroot;
+ int afd, cdroot, dfd;
char *path;
AuthRpc *rpc;
@@ -51,8 +51,13 @@
}
/* rpc != nil iff afd >= 0 */
+ dfd = open("#c/drivers", OWRITE|OCEXEC);
+ if(dfd < 0 && newnsdebug)
+ fprint(2, "open #c/drivers: %r\n");
+
if(file == nil){
if(!newns){
+ close(dfd);
werrstr("no namespace file specified");
return freecloserpc(rpc);
}
@@ -60,6 +65,7 @@
}
b = Bopen(file, OREAD|OCEXEC);
if(b == nil){
+ close(dfd);
werrstr("can't open %s: %r", file);
return freecloserpc(rpc);
}
@@ -70,7 +76,8 @@
setenv("home", home);
}
- cdroot = nsfile(newns ? "newns" : "addns", b, rpc);
+ cdroot = nsfile(newns ? "newns" : "addns", b, rpc, dfd);
+ close(dfd);
Bterm(b);
freecloserpc(rpc);
@@ -87,7 +94,7 @@
}
static int
-nsfile(char *fn, Biobuf *b, AuthRpc *rpc)
+nsfile(char *fn, Biobuf *b, AuthRpc *rpc, int dfd)
{
int argc;
char *cmd, *argv[NARG+1], argbuf[MAXARG*NARG];
@@ -103,7 +110,7 @@
continue;
argc = splitargs(cmd, argv, argbuf, NARG);
if(argc)
- cdroot |= nsop(fn, argc, argv, rpc);
+ cdroot |= nsop(fn, argc, argv, rpc, dfd);
}
atnotify(catch, 0);
return cdroot;
@@ -143,10 +150,11 @@
}
static int
-nsop(char *fn, int argc, char *argv[], AuthRpc *rpc)
+nsop(char *fn, int argc, char *argv[], AuthRpc *rpc, int dfd)
{
char *argv0;
ulong flags;
+ char *devop;
int fd, i;
Biobuf *b;
int cdroot;
@@ -153,6 +161,7 @@
cdroot = 0;
flags = 0;
+ devop = "&";
argv0 = nil;
if(newnsdebug){
for (i = 0; i < argc; i++)
@@ -172,6 +181,12 @@
case 'C':
flags |= MCACHE;
break;
+ case 'r':
+ devop = "&~";
+ break;
+ case 'n':
+ devop = "~";
+ break;
}ARGEND
if(!(flags & (MAFTER|MBEFORE)))
@@ -181,7 +196,7 @@
b = Bopen(argv[0], OREAD|OCEXEC);
if(b == nil)
return 0;
- cdroot |= nsfile(fn, b, rpc);
+ cdroot |= nsfile(fn, b, rpc, dfd);
Bterm(b);
}else if(strcmp(argv0, "clear") == 0 && argc == 0){
rfork(RFCNAMEG);
@@ -212,6 +227,18 @@
}else if(strcmp(argv0, "cd") == 0 && argc == 1){
if(chdir(argv[0]) == 0 && *argv[0] == '/')
cdroot = 1;
+ }else if(strcmp(argv0, "chdev") == 0){
+ //We should not silently fail if we can not honor a chdev
+ //due to the parent namespace missing #c/drivers.
+ if(dfd <= 0)
+ sysfatal("chdev requested, but could not open #c/drivers");
+ if(argc == 0 && devop[0] == '~'){
+ if(fprint(dfd, "chdev ~") < 0 && newnsdebug)
+ fprint(2, "%s: chdev ~: %r\n", fn);
+ }else if(argc == 1){
+ if(fprint(dfd, "chdev %s %s", devop, argv[0]) < 0 && newnsdebug)
+ fprint(2, "%s: chdev %s %s: %r\n", fn, devop, argv[0]);
+ }
}
return cdroot;
}