X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=util-linux%2Funshare.c;h=875e3f86e3048336e9c8ca6dfdc50b034a6e4734;hb=5b2cc0aaee6985431d9bab1b49ceea7e1fa1d7af;hp=f1a9cdf194c43f4d66d15d55860b890c03272255;hpb=29b33b63d49be88200f794d832450a4c71e85a5e;p=oweals%2Fbusybox.git diff --git a/util-linux/unshare.c b/util-linux/unshare.c index f1a9cdf19..875e3f86e 100644 --- a/util-linux/unshare.c +++ b/util-linux/unshare.c @@ -6,16 +6,16 @@ * * Licensed under GPLv2 or later, see file LICENSE in this source tree. */ - //config:config UNSHARE //config: bool "unshare" //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. -// 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() @@ -26,21 +26,50 @@ //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" //usage: "\n --setgroups allow|deny Control the setgroups syscall in user namespaces" #include +#ifndef CLONE_NEWUTS +# define CLONE_NEWUTS 0x04000000 +#endif +#ifndef CLONE_NEWIPC +# define CLONE_NEWIPC 0x08000000 +#endif +#ifndef CLONE_NEWUSER +# define CLONE_NEWUSER 0x10000000 +#endif +#ifndef CLONE_NEWPID +# define CLONE_NEWPID 0x20000000 +#endif +#ifndef CLONE_NEWNET +# define CLONE_NEWNET 0x40000000 +#endif + #include +#ifndef MS_REC +# define MS_REC (1 << 14) +#endif +#ifndef MS_PRIVATE +# define MS_PRIVATE (1 << 18) +#endif +#ifndef MS_SLAVE +# define MS_SLAVE (1 << 19) +#endif +#ifndef MS_SHARED +# define MS_SHARED (1 << 20) +#endif + #include "libbb.h" static void mount_or_die(const char *source, const char *target, @@ -57,22 +86,6 @@ static void mount_or_die(const char *source, const char *target, } } -// TODO: move to libbb -static int wait_for_exitstatus(pid_t pid) -{ - int exit_status, n; - - n = safe_waitpid(pid, &exit_status, 0); - if (n < 0) - bb_perror_msg_and_die("waitpid"); - return exit_status; -} - -/* - * Longest possible path to a procfs file used in unshare. Must be able to - * contain the '/proc/' string, the '/ns/user' string which is the longest - * namespace name and a 32-bit integer representing the process ID. - */ #define PATH_PROC_SETGROUPS "/proc/self/setgroups" #define PATH_PROC_UIDMAP "/proc/self/uid_map" #define PATH_PROC_GIDMAP "/proc/self/gid_map" @@ -90,7 +103,7 @@ enum { 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, @@ -124,12 +137,12 @@ static const struct namespace_descr ns_list[] = { * we are forced to use "fake" letters for them. * '+': stop at first non-option. */ -static const char opt_str[] = "+muinpU""fr""\xfd::""\xfe:""\xff:"; +static const char opt_str[] ALIGN1 = "+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" @@ -297,7 +310,7 @@ int unshare_main(int argc UNUSED_PARAM, char **argv) if (fdp.wr >= 0) { close(fdp.wr); /* Release child */ - /*close(fdp.rd);*/ + close(fdp.rd); /* should close fd, to not confuse exec'ed PROG */ } if (need_mount) { @@ -323,14 +336,7 @@ int unshare_main(int argc UNUSED_PARAM, char **argv) * that'll become PID 1 in this new namespace. */ if (opts & OPT_fork) { - pid_t pid = xfork(); - if (pid > 0) { - /* Parent */ - int exit_status = wait_for_exitstatus(pid); - if (WIFSIGNALED(exit_status)) - kill_myself_with_sig(WTERMSIG(exit_status)); - return WEXITSTATUS(exit_status); - } + xvfork_parent_waits_and_exits(); /* Child continues */ } @@ -370,11 +376,5 @@ int unshare_main(int argc UNUSED_PARAM, char **argv) mount_or_die("proc", proc_mnt_target, "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV); } - if (argv[0]) { - BB_EXECVP_or_die(argv); - } - /* unshare from util-linux 2.27.1, despite not documenting it, - * runs a login shell (argv0="-sh") if no PROG is given - */ - run_shell(getenv("SHELL"), /*login:*/ 1, NULL, NULL); + exec_prog_or_SHELL(argv); }