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