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> Acked-by: Mike Frysinger <vapier@gentoo.or>
This commit is contained in:
parent
5088ec338f
commit
6728ca101e
|
@ -56,7 +56,7 @@ Unshare the mount namespace.
|
||||||
Unshare the network namespace.
|
Unshare the network namespace.
|
||||||
.TP
|
.TP
|
||||||
.BR \-p , " \-\-pid"
|
.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
|
.TP
|
||||||
.BR \-u , " \-\-uts"
|
.BR \-u , " \-\-uts"
|
||||||
Unshare the UTS namespace.
|
Unshare the UTS namespace.
|
||||||
|
@ -67,6 +67,12 @@ Unshare the user namespace.
|
||||||
.BR \-f , " \-\-fork"
|
.BR \-f , " \-\-fork"
|
||||||
Fork the specified process as a child of unshare rather than running it
|
Fork the specified process as a child of unshare rather than running it
|
||||||
directly. This is useful when creating a new pid namespace.
|
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
|
.SH SEE ALSO
|
||||||
.BR unshare (2),
|
.BR unshare (2),
|
||||||
.BR clone (2)
|
.BR clone (2)
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
|
||||||
#include "nls.h"
|
#include "nls.h"
|
||||||
#include "c.h"
|
#include "c.h"
|
||||||
|
@ -48,6 +49,7 @@ static void usage(int status)
|
||||||
fputs(_(" -p, --pid unshare pid namespace\n"), out);
|
fputs(_(" -p, --pid unshare pid namespace\n"), out);
|
||||||
fputs(_(" -U, --user unshare user namespace\n"), out);
|
fputs(_(" -U, --user unshare user namespace\n"), out);
|
||||||
fputs(_(" -f, --fork fork before launching <program>\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_SEPARATOR, out);
|
||||||
fputs(USAGE_HELP, out);
|
fputs(USAGE_HELP, out);
|
||||||
|
@ -59,6 +61,9 @@ static void usage(int status)
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
enum {
|
||||||
|
OPT_MOUNTPROC = CHAR_MAX + 1
|
||||||
|
};
|
||||||
static const struct option longopts[] = {
|
static const struct option longopts[] = {
|
||||||
{ "help", no_argument, 0, 'h' },
|
{ "help", no_argument, 0, 'h' },
|
||||||
{ "version", no_argument, 0, 'V'},
|
{ "version", no_argument, 0, 'V'},
|
||||||
|
@ -69,11 +74,13 @@ int main(int argc, char *argv[])
|
||||||
{ "pid", no_argument, 0, 'p' },
|
{ "pid", no_argument, 0, 'p' },
|
||||||
{ "user", no_argument, 0, 'U' },
|
{ "user", no_argument, 0, 'U' },
|
||||||
{ "fork", no_argument, 0, 'f' },
|
{ "fork", no_argument, 0, 'f' },
|
||||||
|
{ "mount-proc", optional_argument, 0, OPT_MOUNTPROC },
|
||||||
{ NULL, 0, 0, 0 }
|
{ NULL, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
int unshare_flags = 0;
|
int unshare_flags = 0;
|
||||||
int c, forkit = 0;
|
int c, forkit = 0;
|
||||||
|
const char *procmnt = NULL;
|
||||||
|
|
||||||
setlocale(LC_MESSAGES, "");
|
setlocale(LC_MESSAGES, "");
|
||||||
bindtextdomain(PACKAGE, LOCALEDIR);
|
bindtextdomain(PACKAGE, LOCALEDIR);
|
||||||
|
@ -108,6 +115,10 @@ int main(int argc, char *argv[])
|
||||||
case 'U':
|
case 'U':
|
||||||
unshare_flags |= CLONE_NEWUSER;
|
unshare_flags |= CLONE_NEWUSER;
|
||||||
break;
|
break;
|
||||||
|
case OPT_MOUNTPROC:
|
||||||
|
unshare_flags |= CLONE_NEWNS;
|
||||||
|
procmnt = optarg ? optarg : "/proc";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
usage(EXIT_FAILURE);
|
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) {
|
if (optind < argc) {
|
||||||
execvp(argv[optind], argv + optind);
|
execvp(argv[optind], argv + optind);
|
||||||
err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
|
err(EXIT_FAILURE, _("failed to execute %s"), argv[optind]);
|
||||||
|
|
Loading…
Reference in New Issue