diff -Nru util-linux-2.27.1/debian/changelog util-linux-2.27.1/debian/changelog --- util-linux-2.27.1/debian/changelog 2016-02-15 07:48:50.000000000 -0800 +++ util-linux-2.27.1/debian/changelog 2016-03-02 17:23:38.000000000 -0800 @@ -1,3 +1,10 @@ +util-linux (2.27.1-3ubuntu2) xenial; urgency=medium + + * debian/patches/unshare-cgns.patch: implement unshare and nsenter for + cgroup namespaces (LP: #1552372) + + -- Serge Hallyn Wed, 02 Mar 2016 17:23:09 -0800 + util-linux (2.27.1-3ubuntu1) xenial; urgency=medium * Merge from Debian unstable. Remaining changes: diff -Nru util-linux-2.27.1/debian/patches/series util-linux-2.27.1/debian/patches/series --- util-linux-2.27.1/debian/patches/series 2016-02-15 07:47:19.000000000 -0800 +++ util-linux-2.27.1/debian/patches/series 2016-03-02 17:11:03.000000000 -0800 @@ -5,3 +5,4 @@ Mark-setarch-testcase-as-known-fail.patch sulogin-fallback-static-sh.patch sulogin-lockedpwd.patch +unshare-cgns.patch diff -Nru util-linux-2.27.1/debian/patches/unshare-cgns.patch util-linux-2.27.1/debian/patches/unshare-cgns.patch --- util-linux-2.27.1/debian/patches/unshare-cgns.patch 1969-12-31 16:00:00.000000000 -0800 +++ util-linux-2.27.1/debian/patches/unshare-cgns.patch 2016-03-02 17:22:59.000000000 -0800 @@ -0,0 +1,215 @@ +Index: util-linux-2.27.1/include/namespace.h +=================================================================== +--- util-linux-2.27.1.orig/include/namespace.h ++++ util-linux-2.27.1/include/namespace.h +@@ -7,6 +7,9 @@ + # ifndef CLONE_NEWNS + # define CLONE_NEWNS 0x00020000 + # endif ++# ifndef CLONE_NEWCGROUP ++# define CLONE_NEWCGROUP 0x02000000 ++# endif + # ifndef CLONE_NEWUTS + # define CLONE_NEWUTS 0x04000000 + # endif +Index: util-linux-2.27.1/sys-utils/nsenter.1 +=================================================================== +--- util-linux-2.27.1.orig/sys-utils/nsenter.1 ++++ util-linux-2.27.1/sys-utils/nsenter.1 +@@ -54,6 +54,12 @@ The process will have a distinct set of + .RB ( CLONE_\:NEWUSER + flag) + .TP ++.B cgroup namespace ++The process will have a virtualized view of \fI/proc\:/self\:/cgroup\fP, and new ++cgroup mounts will be rooted at the namespace cgroup root. ++.RB ( CLONE_\:NEWCGROUP ++flag) ++.TP + See \fBclone\fP(2) for the exact semantics of the flags. + .TP + If \fIprogram\fP is not given, then ``${SHELL}'' is run (default: /bin\:/sh). +@@ -87,6 +93,9 @@ the PID namespace + /proc/\fIpid\fR/ns/user + the user namespace + .TP ++/proc/\fIpid\fR/ns/cgroup ++the cgroup namespace ++.TP + /proc/\fIpid\fR/root + the root directory + .TP +@@ -125,6 +134,11 @@ Enter the user namespace. If no file is + the target process. If file is specified, enter the user namespace specified by + file. See also the \fB\-\-setuid\fR and \fB\-\-setgid\fR options. + .TP ++\fB\-C\fR, \fB\-\-cgroup\fR[=\fIfile\fR] ++Enter the cgroup namespace. If no file is specified, enter the cgroup namespace of ++the target process. If file is specified, enter the cgroup namespace specified by ++file. ++.TP + \fB\-G\fR, \fB\-\-setgid\fR \fIgid\fR + Set the group ID which will be used in the entered namespace and drop + supplementary groups. +Index: util-linux-2.27.1/sys-utils/nsenter.c +=================================================================== +--- util-linux-2.27.1.orig/sys-utils/nsenter.c ++++ util-linux-2.27.1/sys-utils/nsenter.c +@@ -52,12 +52,13 @@ static struct namespace_file { + * first. This gives an unprivileged user the potential to + * enter the other namespaces. + */ +- { .nstype = CLONE_NEWUSER, .name = "ns/user", .fd = -1 }, +- { .nstype = CLONE_NEWIPC, .name = "ns/ipc", .fd = -1 }, +- { .nstype = CLONE_NEWUTS, .name = "ns/uts", .fd = -1 }, +- { .nstype = CLONE_NEWNET, .name = "ns/net", .fd = -1 }, +- { .nstype = CLONE_NEWPID, .name = "ns/pid", .fd = -1 }, +- { .nstype = CLONE_NEWNS, .name = "ns/mnt", .fd = -1 }, ++ { .nstype = CLONE_NEWUSER, .name = "ns/user", .fd = -1 }, ++ { .nstype = CLONE_NEWCGROUP,.name = "ns/cgroup", .fd = -1 }, ++ { .nstype = CLONE_NEWIPC, .name = "ns/ipc", .fd = -1 }, ++ { .nstype = CLONE_NEWUTS, .name = "ns/uts", .fd = -1 }, ++ { .nstype = CLONE_NEWNET, .name = "ns/net", .fd = -1 }, ++ { .nstype = CLONE_NEWPID, .name = "ns/pid", .fd = -1 }, ++ { .nstype = CLONE_NEWNS, .name = "ns/mnt", .fd = -1 }, + { .nstype = 0, .name = NULL, .fd = -1 } + }; + +@@ -79,6 +80,7 @@ static void usage(int status) + fputs(_(" -i, --ipc[=] enter System V IPC namespace\n"), out); + fputs(_(" -n, --net[=] enter network namespace\n"), out); + fputs(_(" -p, --pid[=] enter pid namespace\n"), out); ++ fputs(_(" -C, --cgroup[=] enter cgroup namespace\n"), out); + fputs(_(" -U, --user[=] enter user namespace\n"), out); + fputs(_(" -S, --setuid set uid in entered namespace\n"), out); + fputs(_(" -G, --setgid set gid in entered namespace\n"), out); +@@ -186,6 +188,7 @@ int main(int argc, char *argv[]) + { "net", optional_argument, NULL, 'n' }, + { "pid", optional_argument, NULL, 'p' }, + { "user", optional_argument, NULL, 'U' }, ++ { "cgroup", optional_argument, NULL, 'C' }, + { "setuid", required_argument, NULL, 'S' }, + { "setgid", required_argument, NULL, 'G' }, + { "root", optional_argument, NULL, 'r' }, +@@ -214,7 +217,7 @@ int main(int argc, char *argv[]) + atexit(close_stdout); + + while ((c = +- getopt_long(argc, argv, "+hVt:m::u::i::n::p::U::S:G:r::w::FZ", ++ getopt_long(argc, argv, "+hVt:m::u::i::n::p::C::U::S:G:r::w::FZ", + longopts, NULL)) != -1) { + switch (c) { + case 'h': +@@ -256,6 +259,12 @@ int main(int argc, char *argv[]) + else + namespaces |= CLONE_NEWPID; + break; ++ case 'C': ++ if (optarg) ++ open_namespace_fd(CLONE_NEWCGROUP, optarg); ++ else ++ namespaces |= CLONE_NEWCGROUP; ++ break; + case 'U': + if (optarg) + open_namespace_fd(CLONE_NEWUSER, optarg); +Index: util-linux-2.27.1/sys-utils/unshare.1 +=================================================================== +--- util-linux-2.27.1.orig/sys-utils/unshare.1 ++++ util-linux-2.27.1/sys-utils/unshare.1 +@@ -49,6 +49,11 @@ sockets, etc. (\fBCLONE_NEWNET\fP flag) + Children will have a distinct set of PID to process mappings from their parent. + (\fBCLONE_NEWPID\fP flag) + .TP ++.BR "cgroup namespace" ++The process will have a virtualized view of \fI/proc\:/self\:/cgroup\fP, and new ++cgroup mounts will be rooted at the namespace cgroup root. ++(\fBCLONE_NEWCGROUP\fP flag) ++.TP + .BR "user namespace" + The process will have a distinct set of UIDs, GIDs and capabilities. + (\fBCLONE_NEWUSER\fP flag) +@@ -80,6 +85,10 @@ by bind mount. + Unshare the user namespace. If \fIfile\fP is specified then persistent namespace is created + by bind mount. + .TP ++.BR \-C , " \-\-cgroup"[=\fIfile\fP] ++Unshare the cgroup namespace. If \fIfile\fP is specified then persistent namespace is created ++by bind mount. ++.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. +Index: util-linux-2.27.1/sys-utils/unshare.c +=================================================================== +--- util-linux-2.27.1.orig/sys-utils/unshare.c ++++ util-linux-2.27.1/sys-utils/unshare.c +@@ -50,12 +50,13 @@ static struct namespace_file { + const char *name; /* ns/ */ + const char *target; /* user specified target for bind mount */ + } namespace_files[] = { +- { .type = CLONE_NEWUSER, .name = "ns/user" }, +- { .type = CLONE_NEWIPC, .name = "ns/ipc" }, +- { .type = CLONE_NEWUTS, .name = "ns/uts" }, +- { .type = CLONE_NEWNET, .name = "ns/net" }, +- { .type = CLONE_NEWPID, .name = "ns/pid" }, +- { .type = CLONE_NEWNS, .name = "ns/mnt" }, ++ { .type = CLONE_NEWUSER, .name = "ns/user" }, ++ { .type = CLONE_NEWCGROUP,.name = "ns/cgroup" }, ++ { .type = CLONE_NEWIPC, .name = "ns/ipc" }, ++ { .type = CLONE_NEWUTS, .name = "ns/uts" }, ++ { .type = CLONE_NEWNET, .name = "ns/net" }, ++ { .type = CLONE_NEWPID, .name = "ns/pid" }, ++ { .type = CLONE_NEWNS, .name = "ns/mnt" }, + { .name = NULL } + }; + +@@ -242,6 +243,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(_(" -C, --cgroup[=] unshare cgroup namespace\n"), out); + fputs(_(" -f, --fork fork before launching \n"), out); + fputs(_(" --mount-proc[=] mount proc filesystem first (implies --mount)\n"), out); + fputs(_(" -r, --map-root-user map current user to root (implies --user)\n"), out); +@@ -268,12 +270,13 @@ int main(int argc, char *argv[]) + { "help", no_argument, 0, 'h' }, + { "version", no_argument, 0, 'V'}, + +- { "mount", optional_argument, 0, 'm' }, +- { "uts", optional_argument, 0, 'u' }, +- { "ipc", optional_argument, 0, 'i' }, +- { "net", optional_argument, 0, 'n' }, +- { "pid", optional_argument, 0, 'p' }, +- { "user", optional_argument, 0, 'U' }, ++ { "mount", optional_argument, 0, 'm' }, ++ { "uts", optional_argument, 0, 'u' }, ++ { "ipc", optional_argument, 0, 'i' }, ++ { "net", optional_argument, 0, 'n' }, ++ { "pid", optional_argument, 0, 'p' }, ++ { "user", optional_argument, 0, 'U' }, ++ { "cgroup", optional_argument, 0, 'C' }, + + { "fork", no_argument, 0, 'f' }, + { "mount-proc", optional_argument, 0, OPT_MOUNTPROC }, +@@ -298,7 +301,7 @@ int main(int argc, char *argv[]) + textdomain(PACKAGE); + atexit(close_stdout); + +- while ((c = getopt_long(argc, argv, "+fhVmuinpUr", longopts, NULL)) != -1) { ++ while ((c = getopt_long(argc, argv, "+fhVmuinpCUr", longopts, NULL)) != -1) { + switch (c) { + case 'f': + forkit = 1; +@@ -338,6 +341,11 @@ int main(int argc, char *argv[]) + if (optarg) + set_ns_target(CLONE_NEWUSER, optarg); + break; ++ case 'C': ++ unshare_flags |= CLONE_NEWCGROUP; ++ if (optarg) ++ set_ns_target(CLONE_NEWCGROUP, optarg); ++ break; + case OPT_MOUNTPROC: + unshare_flags |= CLONE_NEWNS; + procmnt = optarg ? optarg : "/proc";