*
* Licensed under GPLv2 or later, see file LICENSE in this source tree.
*/
-
//config:config UNSHARE
-//config: bool "unshare"
+//config: bool "unshare (9.2 kb)"
//config: default y
-//config: depends on LONG_OPTS && !NOMMU
+//config: depends on !NOMMU
//config: select PLATFORM_LINUX
+//config: select LONG_OPTS
//config: help
-//config: Run program with some namespaces unshared from parent.
+//config: Run program with some namespaces unshared from parent.
-// depends on LONG_OPTS: it is awkward to exclude code which handles --propagation
+// needs LONG_OPTS: it is awkward to exclude code which handles --propagation
// and --setgroups based on LONG_OPTS, so instead applet requires LONG_OPTS.
// depends on !NOMMU: we need fork()
//usage:#define unshare_trivial_usage
//usage: "[OPTIONS] [PROG [ARGS]]"
//usage:#define unshare_full_usage "\n"
-//usage: "\n -m, --mount[=FILE] Unshare mount namespace"
-//usage: "\n -u, --uts[=FILE] Unshare UTS namespace (hostname etc.)"
-//usage: "\n -i, --ipc[=FILE] Unshare System V IPC namespace"
-//usage: "\n -n, --net[=FILE] Unshare network namespace"
-//usage: "\n -p, --pid[=FILE] Unshare PID namespace"
-//usage: "\n -U, --user[=FILE} Unshare user namespace"
-//usage: "\n -f, --fork Fork before execing PROG"
-//usage: "\n -r, --map-root-user Map current user to root (implies -u)"
+//usage: "\n -m,--mount[=FILE] Unshare mount namespace"
+//usage: "\n -u,--uts[=FILE] Unshare UTS namespace (hostname etc.)"
+//usage: "\n -i,--ipc[=FILE] Unshare System V IPC namespace"
+//usage: "\n -n,--net[=FILE] Unshare network namespace"
+//usage: "\n -p,--pid[=FILE] Unshare PID namespace"
+//usage: "\n -U,--user[=FILE] Unshare user namespace"
+//usage: "\n -f,--fork Fork before execing PROG"
+//usage: "\n -r,--map-root-user Map current user to root (implies -U)"
//usage: "\n --mount-proc[=DIR] Mount /proc filesystem first (implies -m)"
//usage: "\n --propagation slave|shared|private|unchanged"
//usage: "\n Modify mount propagation in mount namespace"
#include "libbb.h"
static void mount_or_die(const char *source, const char *target,
- const char *fstype, unsigned long mountflags)
+ const char *fstype, unsigned long mountflags)
{
if (mount(source, target, fstype, mountflags, NULL)) {
bb_perror_msg_and_die("can't mount %s on %s (flags:0x%lx)",
OPT_mount = 1 << 0,
OPT_uts = 1 << 1,
OPT_ipc = 1 << 2,
- OPT_network = 1 << 3,
+ OPT_net = 1 << 3,
OPT_pid = 1 << 4,
OPT_user = 1 << 5, /* OPT_user, NS_USR_POS, and ns_list[] index must match! */
OPT_fork = 1 << 6,
* we are forced to use "fake" letters for them.
* '+': stop at first non-option.
*/
-static const char opt_str[] = "+muinpU""fr""\xfd::""\xfe:""\xff:";
+#define OPT_STR "+muinpU""fr""\xfd::""\xfe:""\xff:"
static const char unshare_longopts[] ALIGN1 =
"mount\0" Optional_argument "\xf0"
"uts\0" Optional_argument "\xf1"
"ipc\0" Optional_argument "\xf2"
- "network\0" Optional_argument "\xf3"
+ "net\0" Optional_argument "\xf3"
"pid\0" Optional_argument "\xf4"
"user\0" Optional_argument "\xf5"
"fork\0" No_argument "f"
prop_str = PRIVATE_STR;
setgrp_str = NULL;
- opt_complementary =
+ opts = getopt32long(argv, "^" OPT_STR "\0"
"\xf0""m" /* long opts (via their "fake chars") imply short opts */
":\xf1""u"
":\xf2""i"
":\xf3""n"
":\xf4""p"
":\xf5""U"
- ":ru" /* --map-root-user or -r implies -u */
+ ":rU" /* --map-root-user or -r implies -U */
":\xfd""m" /* --mount-proc implies -m */
- ;
- applet_long_options = unshare_longopts;
- opts = getopt32(argv, opt_str,
- &proc_mnt_target, &prop_str, &setgrp_str,
- &ns_ctx_list[NS_MNT_POS].path,
- &ns_ctx_list[NS_UTS_POS].path,
- &ns_ctx_list[NS_IPC_POS].path,
- &ns_ctx_list[NS_NET_POS].path,
- &ns_ctx_list[NS_PID_POS].path,
- &ns_ctx_list[NS_USR_POS].path
+ , unshare_longopts,
+ &proc_mnt_target, &prop_str, &setgrp_str,
+ &ns_ctx_list[NS_MNT_POS].path,
+ &ns_ctx_list[NS_UTS_POS].path,
+ &ns_ctx_list[NS_IPC_POS].path,
+ &ns_ctx_list[NS_NET_POS].path,
+ &ns_ctx_list[NS_PID_POS].path,
+ &ns_ctx_list[NS_USR_POS].path
);
argv += optind;
//bb_error_msg("opts:0x%x", opts);
}
if (opts & OPT_map_root) {
- char uidmap_buf[sizeof("%u 0 1") + sizeof(int)*3];
+ char uidmap_buf[sizeof("0 %u 1") + sizeof(int)*3];
/*
* Since Linux 3.19 unprivileged writing of /proc/self/gid_map
* in that user namespace.
*/
xopen_xwrite_close(PATH_PROC_SETGROUPS, "deny");
- sprintf(uidmap_buf, "%u 0 1", (unsigned)reuid);
+ sprintf(uidmap_buf, "0 %u 1", (unsigned)reuid);
xopen_xwrite_close(PATH_PROC_UIDMAP, uidmap_buf);
- sprintf(uidmap_buf, "%u 0 1", (unsigned)regid);
+ sprintf(uidmap_buf, "0 %u 1", (unsigned)regid);
xopen_xwrite_close(PATH_PROC_GIDMAP, uidmap_buf);
} else
if (setgrp_str) {