unshare: add -r option to map euid/egid to 0/0
This gives the user an easy way to run tools that need to think they are
root (but not actual root permissions), or to archive files as if they
belonged to root.
For example:
find . |unshare -r cpio -o -H newc |gzip -9c > ../initrd
Note: this bit will generate a bunch of warnings since FLAG_* get defined
twice (to the same values):
#define FOR_nsenter
#define FOR_unshare
However, I'm not certain how else to do this cleanly.
Thanks,
Isaac Dunham
diff --git a/toys/other/nsenter.c b/toys/other/nsenter.c
index 8f548bf..4e8e739 100644
--- a/toys/other/nsenter.c
+++ b/toys/other/nsenter.c
@@ -13,14 +13,14 @@
// Note: flags go in same order (right to left) for shared subset
USE_NSENTER(NEWTOY(nsenter, "<1F(no-fork)t#<1(target)i:(ipc);m:(mount);n:(net);p:(pid);u:(uts);U:(user);", TOYFLAG_USR|TOYFLAG_BIN))
-USE_UNSHARE(NEWTOY(unshare, "<1^imnpuU", TOYFLAG_USR|TOYFLAG_BIN))
+USE_UNSHARE(NEWTOY(unshare, "<1^rimnpuU", TOYFLAG_USR|TOYFLAG_BIN))
config UNSHARE
bool "unshare"
default y
depends on TOYBOX_CONTAINER
help
- usage: unshare [-imnpuU] COMMAND...
+ usage: unshare [-imnpuUr] COMMAND...
Create new namespace(s) for this process and its children, so some
attribute is not shared with the parent process. This is part of
@@ -33,6 +33,9 @@ config UNSHARE
-u Host and domain names
-U UIDs, GIDs, capabilities
+ Other options:
+ -r Map current euid/egid to 0/0 (implies -U)
+
config NSENTER
bool "nsenter"
default n
@@ -58,6 +61,7 @@ config NSENTER
*/
#define FOR_nsenter
+#define FOR_unshare
#include "toys.h"
#include <linux/sched.h>
int unshare(int flags);
@@ -68,12 +72,25 @@ GLOBALS(
long targetpid;
)
+void write_ugid_map(char *map, unsigned eugid)
+{
+ int bytes = sprintf(toybuf, "0 %u 1", eugid), fd = xopen(map, O_WRONLY);
+
+ xwrite(fd, toybuf, bytes);
+ xclose(fd);
+}
+
+
void unshare_main(void)
{
unsigned flags[]={CLONE_NEWUSER, CLONE_NEWUTS, CLONE_NEWPID, CLONE_NEWNET,
CLONE_NEWNS, CLONE_NEWIPC}, f = 0;
+ unsigned euid = geteuid(), egid = getegid();
int i, fd;
+ // unshare -U does not imply -r, so we cannot use [+rU]
+ if (toys.optflags & FLAG_r) toys.optflags |= FLAG_U;
+
// Create new namespace(s)?
if (CFG_UNSHARE && toys.which->name[0]) {
for (i = 0; i<ARRAY_LEN(flags); i++)
@@ -81,6 +98,15 @@ void unshare_main(void)
if (unshare(f)) perror_exit(0);
+ if (toys.optflags & FLAG_r) {
+ if ((fd = open("/proc/self/setgroups", O_WRONLY)) >= 0) {
+ xwrite(fd, "deny", 4);
+ close(fd);
+ }
+ write_ugid_map("/proc/self/uid_map", euid);
+ write_ugid_map("/proc/self/gid_map", egid);
+ }
+
// Bind to existing namespace(s)?
} else if (CFG_NSENTER) {
char *nsnames = "user\0uts\0pid\0net\0mnt\0ipc";
_______________________________________________
Toybox mailing list
[email protected]
http://lists.landley.net/listinfo.cgi/toybox-landley.net