Skip to content

Commit

Permalink
unshare: Add support for the pid and user namespaces
Browse files Browse the repository at this point in the history
- Update the unshare application to support the pid and user namespaces.
- Update the man page for the new options
- Fix typo in the man page where UTS was spelled UTC.
- Remove the vestigal support for running a suid unshare.
  After unsharing a user namespace setuid(getuid()) won't work because
  no uid or gid mappings have been specified yet. So it is just easier not
  to have any support for running suid.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
  • Loading branch information
ebiederm authored and karelzak committed Jan 17, 2013
1 parent f8aa8e9 commit bc7f9b9
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 13 deletions.
19 changes: 15 additions & 4 deletions sys-utils/unshare.1
@@ -1,7 +1,7 @@
.\" Process this file with
.\" groff -man -Tascii lscpu.1
.\"
.TH UNSHARE 1 "October 2008" "util-linux" "User Commands"
.TH UNSHARE 1 "January 2013" "util-linux" "User Commands"
.SH NAME
unshare \- run program with some namespaces unshared from parent
.SH SYNOPSIS
Expand Down Expand Up @@ -31,6 +31,13 @@ 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).
.TP
.BR "user namespace"
process will have distinct set of uids, gids and capabilities. (\fBCLONE_NEWUSER\fP flag).
.TP
See the \fBclone\fR(2) for exact semantics of the flags.
.SH OPTIONS
.TP
Expand All @@ -41,16 +48,20 @@ Print a help message,
Unshare the mount namespace,
.TP
.BR \-u , " \-\-uts"
Unshare the UTC namespace,
Unshare the UTS namespace,
.TP
.BR \-i , " \-\-ipc"
Unshare the IPC namespace,
.TP
.BR \-n , " \-\-net"
Unshare the network namespace.
.TP
.BR \-p , " \-\-pid"
Unshare the pid namespace.
.TP
.BR \-U , " \-\-user"
Unshare the user namespace.
.SH NOTES
The unshare command drops potential privileges before executing the
target program. This allows to setuid unshare.
.SH SEE ALSO
.BR unshare (2),
.BR clone (2)
Expand Down
27 changes: 18 additions & 9 deletions sys-utils/unshare.c
Expand Up @@ -41,6 +41,12 @@
#ifndef CLONE_NEWNET
# define CLONE_NEWNET 0x40000000
#endif
#ifndef CLONE_NEWUSER
# define CLONE_NEWUSER 0x10000000
#endif
#ifndef CLONE_NEWPID
# define CLONE_NEWPID 0x20000000
#endif

#ifndef HAVE_UNSHARE
# include <sys/syscall.h>
Expand All @@ -63,7 +69,9 @@ static void usage(int status)
fputs(_(" -m, --mount unshare mounts namespace\n"
" -u, --uts unshare UTS namespace (hostname etc)\n"
" -i, --ipc unshare System V IPC namespace\n"
" -n, --net unshare network namespace\n"), out);
" -n, --net unshare network namespace\n"
" -p, --pid unshare pid namespace\n"
" -U, --user unshare user namespace\n"), out);

fputs(USAGE_SEPARATOR, out);
fputs(USAGE_HELP, out);
Expand All @@ -82,6 +90,8 @@ int main(int argc, char *argv[])
{ "uts", no_argument, 0, 'u' },
{ "ipc", no_argument, 0, 'i' },
{ "net", no_argument, 0, 'n' },
{ "pid", no_argument, 0, 'p' },
{ "user", no_argument, 0, 'U' },
{ NULL, 0, 0, 0 }
};

Expand All @@ -94,7 +104,7 @@ int main(int argc, char *argv[])
textdomain(PACKAGE);
atexit(close_stdout);

while((c = getopt_long(argc, argv, "hVmuin", longopts, NULL)) != -1) {
while((c = getopt_long(argc, argv, "hVmuinpU", longopts, NULL)) != -1) {
switch(c) {
case 'h':
usage(EXIT_SUCCESS);
Expand All @@ -113,6 +123,12 @@ int main(int argc, char *argv[])
case 'n':
unshare_flags |= CLONE_NEWNET;
break;
case 'p':
unshare_flags |= CLONE_NEWPID;
break;
case 'U':
unshare_flags |= CLONE_NEWUSER;
break;
default:
usage(EXIT_FAILURE);
}
Expand All @@ -124,13 +140,6 @@ int main(int argc, char *argv[])
if(-1 == unshare(unshare_flags))
err(EXIT_FAILURE, _("unshare failed"));

/* drop potential root euid/egid if we had been setuid'd */
if (setgid(getgid()) < 0)
err(EXIT_FAILURE, _("cannot set group id"));

if (setuid(getuid()) < 0)
err(EXIT_FAILURE, _("cannot set user id"));

execvp(argv[optind], argv + optind);

err(EXIT_FAILURE, _("exec %s failed"), argv[optind]);
Expand Down

0 comments on commit bc7f9b9

Please sign in to comment.