public inbox for util-linux@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH/RFC] unshare: add --fork/--mount-proc options for pid namespaces
@ 2013-06-28  0:04 Mike Frysinger
  2013-07-01 11:40 ` Karel Zak
  0 siblings, 1 reply; 6+ messages in thread
From: Mike Frysinger @ 2013-06-28  0:04 UTC (permalink / raw)
  To: util-linux; +Cc: ebiederm, mtk.manpages

The ability of unshare to launch a new pid namespace is a bit limited.
The first process in the namespace is expected to be the "init" for it.
When it's not, you get bad behavior.

For example, trying to launch a shell in a new pid namespace fails very
quickly:
	$ sudo unshare -p dash
	# uname -r
	3.8.3
	# uname -m
	dash: 2: Cannot fork
	# ls -ld /
	dash: 3: Cannot fork
	# echo $$
	1324

For this to work smoothly, we need an init process to actively watch over
things.  But forcing people to re-use an existing init or write their own
mini init is a bit overkill.  So let's add a --fork option to unshare to
do this common bit of book keeping.  Now we can do:
	$ sudo unshare -p --fork dash
	# uname -r
	3.8.3
	# uname -m
	x86_64
	# ls -ld /
	drwxr-xr-x 22 root root 4096 May  4 14:01 /
	# echo $$
	1

When it comes to pid namespaces, it's also useful for /proc to reflect
the current namespace.  Again, this is easy to pull off, but annoying
to force everyone to do it themselves.  So let's add a --mount-proc to
do the magic for us.  The downside is that this also implies creating
a mount namespace as mounting the new pid namespace /proc over top the
system one will quickly break all other processes on the system.
	$ sudo unshare --fork -p dash --mount-proc
	# ps uaxOT
	USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
	root         1  0.0  0.0   4328   632 pts/15   S    19:51   0:00 dash
	root         2  0.0  0.0  22592  1148 pts/15   R+   19:51   0:00 ps uaxOT

Thanks to Michael Kerrisk for his namespace articles on lwn.net

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
---
 sys-utils/unshare.1 | 10 ++++++++++
 sys-utils/unshare.c | 41 +++++++++++++++++++++++++++++++++++++----
 2 files changed, 47 insertions(+), 4 deletions(-)

diff --git a/sys-utils/unshare.1 b/sys-utils/unshare.1
index bd0f13e..5e2c27c 100644
--- a/sys-utils/unshare.1
+++ b/sys-utils/unshare.1
@@ -63,6 +63,16 @@ Unshare the UTS namespace.
 .TP
 .BR \-U , " \-\-user"
 Unshare the user namespace.
+.TP
+.BR \-\-fork
+Fork the specified process as a child of unshare rather than running it
+directly.  This is useful when creating a new pid namespace.
+.TP
+.BR \-\-mount\-proc
+Just before running the program, mount the proc filesystem at /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.
 .SH SEE ALSO
 .BR unshare (2),
 .BR clone (2)
diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c
index 8cc9c46..bc25d76 100644
--- a/sys-utils/unshare.c
+++ b/sys-utils/unshare.c
@@ -21,9 +21,12 @@
 #include <errno.h>
 #include <getopt.h>
 #include <sched.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <sys/mount.h>
+#include <sys/wait.h>
 
 #include "nls.h"
 #include "c.h"
@@ -46,6 +49,8 @@ static void usage(int status)
 	fputs(_(" -n, --net         unshare network namespace\n"), out);
 	fputs(_(" -p, --pid         unshare pid namespace\n"), out);
 	fputs(_(" -U, --user        unshare user namespace\n"), out);
+	fputs(_("     --fork        fork before launching <program>\n"), out);
+	fputs(_("     --mount-proc  mount /proc first (implies --mount)\n"), out);
 
 	fputs(USAGE_SEPARATOR, out);
 	fputs(USAGE_HELP, out);
@@ -66,12 +71,17 @@ int main(int argc, char *argv[])
 		{ "net", no_argument, 0, 'n' },
 		{ "pid", no_argument, 0, 'p' },
 		{ "user", no_argument, 0, 'U' },
+		{ "fork", no_argument, 0, 1 },
+		{ "mount-proc", no_argument, 0, 2 },
 		{ NULL, 0, 0, 0 }
 	};
 
 	int unshare_flags = 0;
 
 	int c;
+	pid_t pid;
+	bool forkit = false;
+	bool mount_proc = false;
 
 	setlocale(LC_MESSAGES, "");
 	bindtextdomain(PACKAGE, LOCALEDIR);
@@ -85,6 +95,9 @@ int main(int argc, char *argv[])
 		case 'V':
 			printf(UTIL_LINUX_VERSION);
 			return EXIT_SUCCESS;
+		case 2: /* --mount-proc */
+			mount_proc = true;
+			/* fall through */
 		case 'm':
 			unshare_flags |= CLONE_NEWNS;
 			break;
@@ -103,6 +116,9 @@ int main(int argc, char *argv[])
 		case 'U':
 			unshare_flags |= CLONE_NEWUSER;
 			break;
+		case 1: /* --fork */
+			forkit = true;
+			break;
 		default:
 			usage(EXIT_FAILURE);
 		}
@@ -111,9 +127,26 @@ int main(int argc, char *argv[])
 	if (-1 == unshare(unshare_flags))
 		err(EXIT_FAILURE, _("unshare failed"));
 
-	if (optind < argc) {
-		execvp(argv[optind], argv + optind);
-		err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
+	pid = forkit ? fork() : 1;
+	if (pid == 0) {
+		/* child */
+		if (mount_proc && mount("proc", "/proc", "proc", 0, NULL))
+			err(EXIT_FAILURE, _("mount(/proc) failed"));
+		if (optind < argc) {
+			execvp(argv[optind], argv + optind);
+			err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
+		}
+		exec_shell();
+	} else {
+		/* parent */
+		int status;
+		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));
+		/* still here !? */
+		err(EXIT_FAILURE, _("child exit failed"));
 	}
-	exec_shell();
 }
-- 
1.8.2.1


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH/RFC] unshare: add --fork/--mount-proc options for pid namespaces
  2013-06-28  0:04 [PATCH/RFC] unshare: add --fork/--mount-proc options for pid namespaces Mike Frysinger
@ 2013-07-01 11:40 ` Karel Zak
  2013-07-01 14:47   ` Mike Frysinger
  0 siblings, 1 reply; 6+ messages in thread
From: Karel Zak @ 2013-07-01 11:40 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: util-linux, ebiederm, mtk.manpages

On Thu, Jun 27, 2013 at 08:04:58PM -0400, Mike Frysinger wrote:
> When it comes to pid namespaces, it's also useful for /proc to reflect
> the current namespace.  Again, this is easy to pull off, but annoying
> to force everyone to do it themselves.  So let's add a --mount-proc to
> do the magic for us.  

 This is not so easy. For example on Fedora 18 the default is "shared":

 # grep /proc /proc/self/mountinfo
 14 33 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:5 - proc proc rw
 
 it means that unshare( CLONE_NEWNS ) has no expected effect and the
 following mount(/proc) has horrible impact for all system. You have
 to use (for example):

    mount --make-rprivate /proc
    unshare --fork --mount-proc --pid

 The --fork option makes sense, but I have doubts about --mount-proc.

 It would be better to keep unshare(1) simple and stupid rather than
 expect that we can setup usable container by the util.

 It's easy to call "mount proc /proc -t proc" after "unshare --pid
 --mount --fork".

> -	if (optind < argc) {
> -		execvp(argv[optind], argv + optind);
> -		err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
> +	pid = forkit ? fork() : 1;
^^^^^^^^^^^^^^^^^^^^^^^^^^
> +	if (pid == 0) {
> +		/* child */
> +		if (mount_proc && mount("proc", "/proc", "proc", 0, NULL))
> +			err(EXIT_FAILURE, _("mount(/proc) failed"));
> +		if (optind < argc) {
> +			execvp(argv[optind], argv + optind);
> +			err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
> +		}
> +		exec_shell();
> +	} else {
> +		/* parent */
> +		int status;
> +		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));
> +		/* still here !? */
> +		err(EXIT_FAILURE, _("child exit failed"));
>  	}
> -	exec_shell();
>  }

 I guess it's bug that exec_shell() only when forkit is set and
 waitpid() is called always.

 See the patch below. 

    Karel



>From 535b754f0003b60b9d7c0358cc4366fae169dd19 Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
Date: Thu, 27 Jun 2013 20:04:58 -0400
Subject: [PATCH] unshare: add --fork options for pid namespaces

The ability of unshare to launch a new pid namespace is a bit limited.
The first process in the namespace is expected to be the "init" for it.
When it's not, you get bad behavior.

For example, trying to launch a shell in a new pid namespace fails very
quickly:
	$ sudo unshare -p dash
	# uname -r
	3.8.3
	# uname -m
	dash: 2: Cannot fork
	# ls -ld /
	dash: 3: Cannot fork
	# echo $$
	1324

For this to work smoothly, we need an init process to actively watch over
things.  But forcing people to re-use an existing init or write their own
mini init is a bit overkill.  So let's add a --fork option to unshare to
do this common bit of book keeping.  Now we can do:
	$ sudo unshare -p --fork dash
	# uname -r
	3.8.3
	# uname -m
	x86_64
	# ls -ld /
	drwxr-xr-x 22 root root 4096 May  4 14:01 /
	# echo $$
	1

Thanks to Michael Kerrisk for his namespace articles on lwn.net

[kzak@redhat.com: - fix "forkif logic, remove --mount-proc]

Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Karel Zak <kzak@redhat.com>
---
 sys-utils/unshare.1 |  6 +++++-
 sys-utils/unshare.c | 31 ++++++++++++++++++++++++++++---
 2 files changed, 33 insertions(+), 4 deletions(-)

diff --git a/sys-utils/unshare.1 b/sys-utils/unshare.1
index bd0f13e..c387ceb 100644
--- a/sys-utils/unshare.1
+++ b/sys-utils/unshare.1
@@ -56,13 +56,17 @@ Unshare the mount namespace.
 Unshare the network namespace.
 .TP
 .BR \-p , " \-\-pid"
-Unshare the pid namespace.
+Unshare the pid namespace. See also \fB--fork\fP option.
 .TP
 .BR \-u , " \-\-uts"
 Unshare the UTS namespace.
 .TP
 .BR \-U , " \-\-user"
 Unshare the user namespace.
+.TP
+.BR \-f , " \-\-fork"
+Fork the specified process as a child of unshare rather than running it
+directly.  This is useful when creating a new pid namespace.
 .SH SEE ALSO
 .BR unshare (2),
 .BR clone (2)
diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c
index 8cc9c46..a889eee 100644
--- a/sys-utils/unshare.c
+++ b/sys-utils/unshare.c
@@ -24,6 +24,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
+#include <sys/wait.h>
 
 #include "nls.h"
 #include "c.h"
@@ -46,6 +47,7 @@ static void usage(int status)
 	fputs(_(" -n, --net         unshare network namespace\n"), out);
 	fputs(_(" -p, --pid         unshare pid namespace\n"), out);
 	fputs(_(" -U, --user        unshare user namespace\n"), out);
+	fputs(_(" -f, --fork        fork before launching <program>\n"), out);
 
 	fputs(USAGE_SEPARATOR, out);
 	fputs(USAGE_HELP, out);
@@ -66,20 +68,23 @@ int main(int argc, char *argv[])
 		{ "net", no_argument, 0, 'n' },
 		{ "pid", no_argument, 0, 'p' },
 		{ "user", no_argument, 0, 'U' },
+		{ "fork", no_argument, 0, 'f' },
 		{ NULL, 0, 0, 0 }
 	};
 
 	int unshare_flags = 0;
-
-	int c;
+	int c, forkit = 0;
 
 	setlocale(LC_MESSAGES, "");
 	bindtextdomain(PACKAGE, LOCALEDIR);
 	textdomain(PACKAGE);
 	atexit(close_stdout);
 
-	while ((c = getopt_long(argc, argv, "hVmuinpU", longopts, NULL)) != -1) {
+	while ((c = getopt_long(argc, argv, "fhVmuinpU", longopts, NULL)) != -1) {
 		switch (c) {
+		case 'f':
+			forkit = 1;
+			break;
 		case 'h':
 			usage(EXIT_SUCCESS);
 		case 'V':
@@ -111,6 +116,26 @@ 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 (optind < argc) {
 		execvp(argv[optind], argv + optind);
 		err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH/RFC] unshare: add --fork/--mount-proc options for pid namespaces
  2013-07-01 11:40 ` Karel Zak
@ 2013-07-01 14:47   ` Mike Frysinger
  2013-07-03 10:36     ` Karel Zak
  0 siblings, 1 reply; 6+ messages in thread
From: Mike Frysinger @ 2013-07-01 14:47 UTC (permalink / raw)
  To: Karel Zak; +Cc: util-linux, ebiederm, mtk.manpages

[-- Attachment #1: Type: Text/Plain, Size: 1839 bytes --]

On Monday 01 July 2013 07:40:08 Karel Zak wrote:
> On Thu, Jun 27, 2013 at 08:04:58PM -0400, Mike Frysinger wrote:
> > When it comes to pid namespaces, it's also useful for /proc to reflect
> > the current namespace.  Again, this is easy to pull off, but annoying
> > to force everyone to do it themselves.  So let's add a --mount-proc to
> > do the magic for us.
> 
>  This is not so easy. For example on Fedora 18 the default is "shared":
> 
>  # grep /proc /proc/self/mountinfo
>  14 33 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:5 - proc proc rw
> 
>  it means that unshare( CLONE_NEWNS ) has no expected effect and the
>  following mount(/proc) has horrible impact for all system. You have
>  to use (for example):
> 
>     mount --make-rprivate /proc
>     unshare --fork --mount-proc --pid

i'm not quite following here.  are you saying that Fedora 18 by default makes 
it hard to do pid namespaces ?  

>  The --fork option makes sense, but I have doubts about --mount-proc.
> 
>  It would be better to keep unshare(1) simple and stupid rather than
>  expect that we can setup usable container by the util.
> 
>  It's easy to call "mount proc /proc -t proc" after "unshare --pid
>  --mount --fork".

unless you're running on a system that has a shared /proc ? :)

> > -	if (optind < argc) {
> > -		execvp(argv[optind], argv + optind);
> > -		err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
> > +	pid = forkit ? fork() : 1;
> ^^^^^^^^^^^^^^^^^^^^^^^^^^
> 
>  I guess it's bug that exec_shell() only when forkit is set and
>  waitpid() is called always.

i fixed this locally already.  guess i sent out a stale version.  change the 
"1" to "0".

>  See the patch below.

sure, that gets us half way home :)

> +		switch(pid) {

needs a space before the (
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH/RFC] unshare: add --fork/--mount-proc options for pid namespaces
  2013-07-01 14:47   ` Mike Frysinger
@ 2013-07-03 10:36     ` Karel Zak
  2013-07-03 17:08       ` Mike Frysinger
  0 siblings, 1 reply; 6+ messages in thread
From: Karel Zak @ 2013-07-03 10:36 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: util-linux, ebiederm, mtk.manpages

On Mon, Jul 01, 2013 at 10:47:04AM -0400, Mike Frysinger wrote:
> On Monday 01 July 2013 07:40:08 Karel Zak wrote:
> > On Thu, Jun 27, 2013 at 08:04:58PM -0400, Mike Frysinger wrote:
> > > When it comes to pid namespaces, it's also useful for /proc to reflect
> > > the current namespace.  Again, this is easy to pull off, but annoying
> > > to force everyone to do it themselves.  So let's add a --mount-proc to
> > > do the magic for us.
> > 
> >  This is not so easy. For example on Fedora 18 the default is "shared":
> > 
> >  # grep /proc /proc/self/mountinfo
> >  14 33 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:5 - proc proc rw
> > 
> >  it means that unshare( CLONE_NEWNS ) has no expected effect and the
> >  following mount(/proc) has horrible impact for all system. You have
> >  to use (for example):
> > 
> >     mount --make-rprivate /proc
> >     unshare --fork --mount-proc --pid
> 
> i'm not quite following here.  are you saying that Fedora 18 by default makes 
> it hard to do pid namespaces ?  

 /proc does not have to be private. You have to call

    mount("none", "/proc", NULL, MS_PRIVATE|MS_REC, NULL);

 to be sure that unshare(CLONE_NEWNS) makes any effect. It's mistake
 to blindly call 

    unshare( CLONE_NEWNS );
    mount("proc, "/proc", "proc", 0, NULL);

 If we want to add --mount-proc to unshare(1) than the implementation has to 
 be robust. Your current patch is dangerous on systems where /proc is shared.

 It would be also nice to support optional argument to specify the
 mountpoint --mount-proc[=<mountpoint>].

 See the patch below -- works for me.

    Karel


>From 03719f39f83770af7dc1f6fca38c6c1deb98d84c Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Wed, 3 Jul 2013 12:28:16 +0200
Subject: [PATCH] unshare: add --mount-proc for pid namespaces

Based on patch from Mike Frysinger <vapier@gentoo.org>.

Mike Frysinger wrote:
 When it comes to pid namespaces, it's also useful for /proc to reflect
 the current namespace.  Again, this is easy to pull off, but annoying
 to force everyone to do it themselves.  So let's add a --mount-proc to
 do the magic for us.  The downside is that this also implies creating
 a mount namespace as mounting the new pid namespace /proc over top the
 system one will quickly break all other processes on the system.

Signed-off-by: Karel Zak <kzak@redhat.com>
---
 sys-utils/unshare.1 |  8 +++++++-
 sys-utils/unshare.c | 30 +++++++++++++++++++++++-------
 2 files changed, 30 insertions(+), 8 deletions(-)

diff --git a/sys-utils/unshare.1 b/sys-utils/unshare.1
index c387ceb..dfd4189 100644
--- a/sys-utils/unshare.1
+++ b/sys-utils/unshare.1
@@ -56,7 +56,7 @@ Unshare the mount namespace.
 Unshare the network namespace.
 .TP
 .BR \-p , " \-\-pid"
-Unshare the pid namespace. See also \fB--fork\fP option.
+Unshare the pid namespace. See also \fB--fork\fP and \fB--mount-proc\fP options.
 .TP
 .BR \-u , " \-\-uts"
 Unshare the UTS namespace.
@@ -67,6 +67,12 @@ Unshare the user namespace.
 .BR \-f , " \-\-fork"
 Fork the specified process as a child of unshare rather than running it
 directly.  This is useful when creating a new pid namespace.
+.TP
+.BR "\fB\-\-mount-proc\fR [=\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.
 .SH SEE ALSO
 .BR unshare (2),
 .BR clone (2)
diff --git a/sys-utils/unshare.c b/sys-utils/unshare.c
index a889eee..a64b776 100644
--- a/sys-utils/unshare.c
+++ b/sys-utils/unshare.c
@@ -25,6 +25,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <sys/wait.h>
+#include <sys/mount.h>
 
 #include "nls.h"
 #include "c.h"
@@ -41,13 +42,14 @@ 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(_(" -U, --user        unshare user namespace\n"), out);
-	fputs(_(" -f, --fork        fork before launching <program>\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(_(" -U, --user                unshare user 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);
@@ -59,6 +61,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'},
@@ -69,11 +74,13 @@ int main(int argc, char *argv[])
 		{ "pid", no_argument, 0, 'p' },
 		{ "user", no_argument, 0, 'U' },
 		{ "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;
 
 	setlocale(LC_MESSAGES, "");
 	bindtextdomain(PACKAGE, LOCALEDIR);
@@ -108,6 +115,10 @@ int main(int argc, char *argv[])
 		case 'U':
 			unshare_flags |= CLONE_NEWUSER;
 			break;
+		case OPT_MOUNTPROC:
+			unshare_flags |= CLONE_NEWNS;
+			procmnt = optarg ? optarg : "/proc";
+			break;
 		default:
 			usage(EXIT_FAILURE);
 		}
@@ -136,6 +147,11 @@ int main(int argc, char *argv[])
 		}
 	}
 
+	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]);
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH/RFC] unshare: add --fork/--mount-proc options for pid namespaces
  2013-07-03 10:36     ` Karel Zak
@ 2013-07-03 17:08       ` Mike Frysinger
  2013-07-09  9:08         ` Karel Zak
  0 siblings, 1 reply; 6+ messages in thread
From: Mike Frysinger @ 2013-07-03 17:08 UTC (permalink / raw)
  To: Karel Zak; +Cc: util-linux, ebiederm, mtk.manpages

[-- Attachment #1: Type: Text/Plain, Size: 2122 bytes --]

On Wednesday 03 July 2013 06:36:35 Karel Zak wrote:
> On Mon, Jul 01, 2013 at 10:47:04AM -0400, Mike Frysinger wrote:
> > On Monday 01 July 2013 07:40:08 Karel Zak wrote:
> > > On Thu, Jun 27, 2013 at 08:04:58PM -0400, Mike Frysinger wrote:
> > > > When it comes to pid namespaces, it's also useful for /proc to
> > > > reflect the current namespace.  Again, this is easy to pull off, but
> > > > annoying to force everyone to do it themselves.  So let's add a
> > > > --mount-proc to do the magic for us.
> > >  
> > >  This is not so easy. For example on Fedora 18 the default is "shared":
> > >  
> > >  # grep /proc /proc/self/mountinfo
> > >  14 33 0:3 / /proc rw,nosuid,nodev,noexec,relatime shared:5 - proc proc
> > >  rw
> > >  
> > >  it means that unshare( CLONE_NEWNS ) has no expected effect and the
> > >  following mount(/proc) has horrible impact for all system. You have
> > >  
> > >  to use (for example):
> > >     mount --make-rprivate /proc
> > >     unshare --fork --mount-proc --pid
> > 
> > i'm not quite following here.  are you saying that Fedora 18 by default
> > makes it hard to do pid namespaces ?
> 
>  /proc does not have to be private. You have to call
> 
>     mount("none", "/proc", NULL, MS_PRIVATE|MS_REC, NULL);
> 
>  to be sure that unshare(CLONE_NEWNS) makes any effect. It's mistake
>  to blindly call
> 
>     unshare( CLONE_NEWNS );
>     mount("proc, "/proc", "proc", 0, NULL);
> 
>  If we want to add --mount-proc to unshare(1) than the implementation has
> to be robust. Your current patch is dangerous on systems where /proc is
> shared.

well, it usually does more:
	unshare(...);
	fork();
	mount(...);

but if just adding MS_PRIVATE makes it work w/out needing to do 
unshare(NEWNS), that's even better.  i'm not familiar with that flag as it's 
not in the mount(2) man page (looks like it's listed as a TODO).

>  It would be also nice to support optional argument to specify the
>  mountpoint --mount-proc[=<mountpoint>].
> 
>  See the patch below -- works for me.

Acked-by: Mike Frysinger <vapier@gentoo.or>
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH/RFC] unshare: add --fork/--mount-proc options for pid namespaces
  2013-07-03 17:08       ` Mike Frysinger
@ 2013-07-09  9:08         ` Karel Zak
  0 siblings, 0 replies; 6+ messages in thread
From: Karel Zak @ 2013-07-09  9:08 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: util-linux, ebiederm, mtk.manpages

On Wed, Jul 03, 2013 at 01:08:30PM -0400, Mike Frysinger wrote:
> i'm not familiar with that flag as it's 
> not in the mount(2) man page (looks like it's listed as a TODO).

 the flag is used for mount --make-private, 

 http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/filesystems/sharedsubtree.txt

> Acked-by: Mike Frysinger <vapier@gentoo.or>

 Merged, thanks.

    Karel

-- 
 Karel Zak  <kzak@redhat.com>
 http://karelzak.blogspot.com

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-07-09  9:08 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-28  0:04 [PATCH/RFC] unshare: add --fork/--mount-proc options for pid namespaces Mike Frysinger
2013-07-01 11:40 ` Karel Zak
2013-07-01 14:47   ` Mike Frysinger
2013-07-03 10:36     ` Karel Zak
2013-07-03 17:08       ` Mike Frysinger
2013-07-09  9:08         ` Karel Zak

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox