You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
248 lines
8.5 KiB
248 lines
8.5 KiB
diff -up util-linux-2.23.2/sys-utils/Makemodule.am.kzak util-linux-2.23.2/sys-utils/Makemodule.am |
|
--- util-linux-2.23.2/sys-utils/Makemodule.am.kzak 2014-09-25 14:16:33.526384729 +0200 |
|
+++ util-linux-2.23.2/sys-utils/Makemodule.am 2014-09-25 14:15:34.861825005 +0200 |
|
@@ -290,6 +290,7 @@ usrbin_exec_PROGRAMS += unshare |
|
dist_man_MANS += sys-utils/unshare.1 |
|
unshare_SOURCES = sys-utils/unshare.c |
|
unshare_LDADD = $(LDADD) libcommon.la |
|
+unshare_CFLAGS = $(AM_CFLAGS) -I$(ul_libmount_incdir) |
|
endif |
|
|
|
if BUILD_NSENTER |
|
diff -up util-linux-2.23.2/sys-utils/unshare.1.kzak util-linux-2.23.2/sys-utils/unshare.1 |
|
--- util-linux-2.23.2/sys-utils/unshare.1.kzak 2014-09-25 14:14:30.194208005 +0200 |
|
+++ util-linux-2.23.2/sys-utils/unshare.1 2014-09-25 14:15:17.617660476 +0200 |
|
@@ -1,63 +1,82 @@ |
|
.\" Process this file with |
|
.\" groff -man -Tascii lscpu.1 |
|
.\" |
|
-.TH UNSHARE 1 "January 2013" "util-linux" "User Commands" |
|
+.TH UNSHARE 1 "July 2013" "util-linux" "User Commands" |
|
.SH NAME |
|
unshare \- run program with some namespaces unshared from parent |
|
.SH SYNOPSIS |
|
.B unshare |
|
.RI [ options ] |
|
-program |
|
+.I program |
|
.RI [ arguments ] |
|
.SH DESCRIPTION |
|
-Unshares specified namespaces from parent process and then executes specified |
|
-program. Unshareable namespaces are: |
|
+Unshares the indicated namespaces from the parent process and then executes |
|
+the specified program. The namespaces to be unshared are indicated via |
|
+options. Unshareable namespaces are: |
|
.TP |
|
.BR "mount namespace" |
|
-mounting and unmounting filesystems will not affect rest of the system |
|
+Mounting and unmounting filesystems will not affect the rest of the system |
|
(\fBCLONE_NEWNS\fP flag), except for filesystems which are explicitly marked as |
|
-shared (by mount --make-shared). See /proc/self/mountinfo for the shared flags. |
|
+shared (with \fBmount --make-shared\fP; see \fI/proc/self/mountinfo\fP for the |
|
+\fBshared\fP flags). |
|
+ |
|
+It's recommended to use \fBmount --make-rprivate\fP or \fBmount --make-rslave\fP |
|
+after \fBunshare --mount\fP to make sure that mountpoints in the new namespace |
|
+are really unshared from parental namespace. |
|
.TP |
|
.BR "UTS namespace" |
|
-setting hostname, domainname will not affect rest of the system |
|
-(\fBCLONE_NEWUTS\fP flag). |
|
+Setting hostname or domainname will not affect the rest of the system. |
|
+(\fBCLONE_NEWUTS\fP flag) |
|
.TP |
|
.BR "IPC namespace" |
|
-process will have independent namespace for System V message queues, semaphore |
|
-sets and shared memory segments (\fBCLONE_NEWIPC\fP flag). |
|
+The process will have an independent namespace for System V message queues, |
|
+semaphore sets and shared memory segments. (\fBCLONE_NEWIPC\fP flag) |
|
.TP |
|
.BR "network namespace" |
|
-process will have independent IPv4 and IPv6 stacks, IP routing tables, firewall |
|
-rules, the \fI/proc/net\fP and \fI/sys/class/net\fP directory trees, sockets |
|
-etc. (\fBCLONE_NEWNET\fP flag). |
|
+The process will have independent IPv4 and IPv6 stacks, IP routing tables, |
|
+firewall rules, the \fI/proc/net\fP and \fI/sys/class/net\fP directory trees, |
|
+sockets, etc. (\fBCLONE_NEWNET\fP flag) |
|
.TP |
|
.BR "pid namespace" |
|
-children will have a distinct set of pid to process mappings than their parent. |
|
-(\fBCLONE_NEWPID\fP flag). |
|
+Children will have a distinct set of PID to process mappings from their parent. |
|
+(\fBCLONE_NEWPID\fP flag) |
|
.PP |
|
-See the \fBclone\fR(2) for exact semantics of the flags. |
|
+See \fBclone\fR(2) for the exact semantics of the flags. |
|
.SH OPTIONS |
|
.TP |
|
.BR \-h , " \-\-help" |
|
-Print a help message, |
|
-.TP |
|
-.BR \-m , " \-\-mount" |
|
-Unshare the mount namespace, |
|
-.TP |
|
-.BR \-u , " \-\-uts" |
|
-Unshare the UTS namespace, |
|
+Display help text and exit. |
|
.TP |
|
.BR \-i , " \-\-ipc" |
|
-Unshare the IPC namespace, |
|
+Unshare the IPC namespace. |
|
+.TP |
|
+.BR \-m , " \-\-mount" |
|
+Unshare the mount namespace. |
|
.TP |
|
.BR \-n , " \-\-net" |
|
Unshare the network namespace. |
|
.TP |
|
.BR \-p , " \-\-pid" |
|
Unshare the pid namespace. |
|
+See also the \fB--fork\fP and \fB--mount-proc\fP options. |
|
+.TP |
|
+.BR \-u , " \-\-uts" |
|
+Unshare the UTS namespace. |
|
+.TP |
|
+.BR \-f , " \-\-fork" |
|
+Fork the specified \fIprogram\fR as a child process of \fBunshare\fR rather than |
|
+running it directly. This is useful when creating a new pid namespace. |
|
+.TP |
|
+.BR \-\-mount-proc "[=\fImountpoint\fP]" |
|
+Just before running the program, mount the proc filesystem at the \fImountpoint\fP |
|
+(default is /proc). This is useful when creating a new pid namespace. It also |
|
+implies creating a new mount namespace since the /proc mount would otherwise |
|
+mess up existing programs on the system. The new proc filesystem is explicitly |
|
+mounted as private (by MS_PRIVATE|MS_REC). |
|
.SH SEE ALSO |
|
.BR unshare (2), |
|
-.BR clone (2) |
|
+.BR clone (2), |
|
+.BR mount (8) |
|
.SH BUGS |
|
None known so far. |
|
.SH AUTHOR |
|
diff -up util-linux-2.23.2/sys-utils/unshare.c.kzak util-linux-2.23.2/sys-utils/unshare.c |
|
--- util-linux-2.23.2/sys-utils/unshare.c.kzak 2014-09-25 14:14:30.194208005 +0200 |
|
+++ util-linux-2.23.2/sys-utils/unshare.c 2014-09-25 14:15:34.861825005 +0200 |
|
@@ -24,12 +24,19 @@ |
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <unistd.h> |
|
+#include <sys/wait.h> |
|
+#include <sys/mount.h> |
|
+ |
|
+/* we only need some defines missing in sys/mount.h, no libmount linkage */ |
|
+#include <libmount.h> |
|
|
|
#include "nls.h" |
|
#include "c.h" |
|
-#include "closestream.h" |
|
#include "namespace.h" |
|
#include "exec_shell.h" |
|
+#include "xalloc.h" |
|
+#include "pathnames.h" |
|
+ |
|
|
|
static void usage(int status) |
|
{ |
|
@@ -40,11 +47,13 @@ static void usage(int status) |
|
_(" %s [options] <program> [args...]\n"), program_invocation_short_name); |
|
|
|
fputs(USAGE_OPTIONS, out); |
|
- fputs(_(" -m, --mount unshare mounts namespace\n"), out); |
|
- fputs(_(" -u, --uts unshare UTS namespace (hostname etc)\n"), out); |
|
- fputs(_(" -i, --ipc unshare System V IPC namespace\n"), out); |
|
- fputs(_(" -n, --net unshare network namespace\n"), out); |
|
- fputs(_(" -p, --pid unshare pid namespace\n"), out); |
|
+ fputs(_(" -m, --mount unshare mounts namespace\n"), out); |
|
+ fputs(_(" -u, --uts unshare UTS namespace (hostname etc)\n"), out); |
|
+ fputs(_(" -i, --ipc unshare System V IPC namespace\n"), out); |
|
+ fputs(_(" -n, --net unshare network namespace\n"), out); |
|
+ fputs(_(" -p, --pid unshare pid namespace\n"), out); |
|
+ fputs(_(" -f, --fork fork before launching <program>\n"), out); |
|
+ fputs(_(" --mount-proc[=<dir>] mount proc filesystem first (implies --mount)\n"), out); |
|
|
|
fputs(USAGE_SEPARATOR, out); |
|
fputs(USAGE_HELP, out); |
|
@@ -56,6 +65,9 @@ static void usage(int status) |
|
|
|
int main(int argc, char *argv[]) |
|
{ |
|
+ enum { |
|
+ OPT_MOUNTPROC = CHAR_MAX + 1 |
|
+ }; |
|
static const struct option longopts[] = { |
|
{ "help", no_argument, 0, 'h' }, |
|
{ "version", no_argument, 0, 'V'}, |
|
@@ -64,20 +76,24 @@ int main(int argc, char *argv[]) |
|
{ "ipc", no_argument, 0, 'i' }, |
|
{ "net", no_argument, 0, 'n' }, |
|
{ "pid", no_argument, 0, 'p' }, |
|
+ { "fork", no_argument, 0, 'f' }, |
|
+ { "mount-proc", optional_argument, 0, OPT_MOUNTPROC }, |
|
{ NULL, 0, 0, 0 } |
|
}; |
|
|
|
int unshare_flags = 0; |
|
+ int c, forkit = 0; |
|
+ const char *procmnt = NULL; |
|
|
|
- int c; |
|
- |
|
- setlocale(LC_MESSAGES, ""); |
|
+ setlocale(LC_ALL, ""); |
|
bindtextdomain(PACKAGE, LOCALEDIR); |
|
textdomain(PACKAGE); |
|
- atexit(close_stdout); |
|
|
|
- while ((c = getopt_long(argc, argv, "hVmuinp", longopts, NULL)) != -1) { |
|
+ while ((c = getopt_long(argc, argv, "+fhVmuinp", longopts, NULL)) != -1) { |
|
switch (c) { |
|
+ case 'f': |
|
+ forkit = 1; |
|
+ break; |
|
case 'h': |
|
usage(EXIT_SUCCESS); |
|
case 'V': |
|
@@ -98,6 +114,10 @@ int main(int argc, char *argv[]) |
|
case 'p': |
|
unshare_flags |= CLONE_NEWPID; |
|
break; |
|
+ case OPT_MOUNTPROC: |
|
+ unshare_flags |= CLONE_NEWNS; |
|
+ procmnt = optarg ? optarg : "/proc"; |
|
+ break; |
|
default: |
|
usage(EXIT_FAILURE); |
|
} |
|
@@ -106,6 +126,31 @@ int main(int argc, char *argv[]) |
|
if (-1 == unshare(unshare_flags)) |
|
err(EXIT_FAILURE, _("unshare failed")); |
|
|
|
+ if (forkit) { |
|
+ int status; |
|
+ pid_t pid = fork(); |
|
+ |
|
+ switch(pid) { |
|
+ case -1: |
|
+ err(EXIT_FAILURE, _("fork failed")); |
|
+ case 0: /* child */ |
|
+ break; |
|
+ default: /* parent */ |
|
+ if (waitpid(pid, &status, 0) == -1) |
|
+ err(EXIT_FAILURE, _("waitpid failed")); |
|
+ if (WIFEXITED(status)) |
|
+ return WEXITSTATUS(status); |
|
+ else if (WIFSIGNALED(status)) |
|
+ kill(getpid(), WTERMSIG(status)); |
|
+ err(EXIT_FAILURE, _("child exit failed")); |
|
+ } |
|
+ } |
|
+ |
|
+ if (procmnt && |
|
+ (mount("none", procmnt, NULL, MS_PRIVATE|MS_REC, NULL) != 0 || |
|
+ mount("proc", procmnt, "proc", MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL) != 0)) |
|
+ err(EXIT_FAILURE, _("mount %s failed"), procmnt); |
|
+ |
|
if (optind < argc) { |
|
execvp(argv[optind], argv + optind); |
|
err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
|
|
|