comparison toys/other/nsenter.c @ 1701:83c14a9cd0fe draft

Patch from Isaac Dunham to add -r, fixed up so it doesn't try to include two flag contexts simultaneously.
author Rob Landley <rob@landley.net>
date Wed, 18 Feb 2015 15:19:15 -0600
parents cbb1aca81eca
children 5892daac85ab
comparison
equal deleted inserted replaced
1700:3b62d24bfa27 1701:83c14a9cd0fe
11 * No Standard 11 * No Standard
12 * 12 *
13 13
14 // Note: flags go in same order (right to left) for shared subset 14 // Note: flags go in same order (right to left) for shared subset
15 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)) 15 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))
16 USE_UNSHARE(NEWTOY(unshare, "<1^imnpuU", TOYFLAG_USR|TOYFLAG_BIN)) 16 USE_UNSHARE(NEWTOY(unshare, "<1^rimnpuU", TOYFLAG_USR|TOYFLAG_BIN))
17 17
18 config UNSHARE 18 config UNSHARE
19 bool "unshare" 19 bool "unshare"
20 default y 20 default y
21 depends on TOYBOX_CONTAINER 21 depends on TOYBOX_CONTAINER
22 help 22 help
23 usage: unshare [-imnpuU] COMMAND... 23 usage: unshare [-imnpuUr] COMMAND...
24 24
25 Create new namespace(s) for this process and its children, so some 25 Create new container namespace(s) for this process and its children, so
26 attribute is not shared with the parent process. This is part of 26 some attribute is not shared with the parent process.
27 Linux Containers. Each process can have its own:
28 27
29 -i SysV IPC (message queues, semaphores, shared memory) 28 -i SysV IPC (message queues, semaphores, shared memory)
30 -m Mount/unmount tree 29 -m Mount/unmount tree
31 -n Network address, sockets, routing, iptables 30 -n Network address, sockets, routing, iptables
32 -p Process IDs and init 31 -p Process IDs and init
32 -r Become root (map current euid/egid to 0/0, implies -U)
33 -u Host and domain names 33 -u Host and domain names
34 -U UIDs, GIDs, capabilities 34 -U UIDs, GIDs, capabilities
35
36 A namespace allows a set of processes to have a different view of the
37 system than other sets of processes.
35 38
36 config NSENTER 39 config NSENTER
37 bool "nsenter" 40 bool "nsenter"
38 default n 41 default n
39 help 42 help
40 usage: nsenter [-t pid] [-F] [-i] [-m] [-n] [-p] [-u] [-U] COMMAND... 43 usage: nsenter [-t pid] [-F] [-i] [-m] [-n] [-p] [-u] [-U] COMMAND...
41 44
42 Run COMMAND in a different set of namespaces. 45 Run COMMAND in an existing (set of) namespace(s).
43 46
44 -t PID to take namespaces from (--target) 47 -t PID to take namespaces from (--target)
45 -F don't fork, even if -p is used (--no-fork) 48 -F don't fork, even if -p is used (--no-fork)
46 49
47 The namespaces to switch are: 50 The namespaces to switch are:
66 GLOBALS( 69 GLOBALS(
67 char *nsnames[6]; 70 char *nsnames[6];
68 long targetpid; 71 long targetpid;
69 ) 72 )
70 73
74 // Code that must run in unshare's flag context
75 #define CLEANUP_nsenter
76 #define FOR_unshare
77 #include <generated/flags.h>
78
79 static void write_ugid_map(char *map, unsigned eugid)
80 {
81 int bytes = sprintf(toybuf, "0 %u 1", eugid), fd = xopen(map, O_WRONLY);
82
83 xwrite(fd, toybuf, bytes);
84 xclose(fd);
85 }
86
87
88 static int handle_r(int test)
89 {
90 int fd;
91
92 if (!CFG_UNSHARE || !(toys.optflags & FLAG_r) || *toys.which->name!='u')
93 return 0;
94 if (!test) return 1;
95
96 if (toys.optflags & FLAG_r) {
97 if ((fd = open("/proc/self/setgroups", O_WRONLY)) >= 0) {
98 xwrite(fd, "deny", 4);
99 close(fd);
100 }
101
102 write_ugid_map("/proc/self/uid_map", geteuid());
103 write_ugid_map("/proc/self/gid_map", getegid());
104 }
105
106 return 0;
107 }
108
109 // Shift back to the context GLOBALS lives in (I.E. matching the filename).
110 #define CLEANUP_unshare
111 #define FOR_nsenter
112 #include <generated/flags.h>
113
71 void unshare_main(void) 114 void unshare_main(void)
72 { 115 {
73 unsigned flags[]={CLONE_NEWUSER, CLONE_NEWUTS, CLONE_NEWPID, CLONE_NEWNET, 116 unsigned flags[]={CLONE_NEWUSER, CLONE_NEWUTS, CLONE_NEWPID, CLONE_NEWNET,
74 CLONE_NEWNS, CLONE_NEWIPC}, f = 0; 117 CLONE_NEWNS, CLONE_NEWIPC}, f = 0;
75 int i, fd; 118 int i, fd;
76 119
120 // unshare -U does not imply -r, so we cannot use [+rU]
121 if (handle_r(0)) toys.optflags |= FLAG_U;
122
77 // Create new namespace(s)? 123 // Create new namespace(s)?
78 if (CFG_UNSHARE && toys.which->name[0]) { 124 if (CFG_UNSHARE && *toys.which->name=='u') {
79 for (i = 0; i<ARRAY_LEN(flags); i++) 125 for (i = 0; i<ARRAY_LEN(flags); i++)
80 if (toys.optflags & (1<<i)) f |= flags[i]; 126 if (toys.optflags & (1<<i)) f |= flags[i];
81 127
82 if (unshare(f)) perror_exit(0); 128 if (unshare(f)) perror_exit(0);
129 handle_r(1);
83 130
84 // Bind to existing namespace(s)? 131 // Bind to existing namespace(s)?
85 } else if (CFG_NSENTER) { 132 } else if (CFG_NSENTER) {
86 char *nsnames = "user\0uts\0pid\0net\0mnt\0ipc"; 133 char *nsnames = "user\0uts\0pid\0net\0mnt\0ipc";
87 134
112 } 159 }
113 } 160 }
114 161
115 xexec(toys.optargs); 162 xexec(toys.optargs);
116 } 163 }
164
165 void nsenter_main(void)
166 {
167 unshare_main();
168 }