Add ability to enter a cgroup namespace

The cgroup namespacing feature was recently added to the linux kernel.
Allow jailed processes to be placed in to a new cgroup namespace.  This
avoids leaking host info into the jailed process and allows for the
jailed process to use cgroups as it would if it was running outside of
any namespaces.  Android needs this so its cgroup setting CTS tests can
pass and it can distribute its cpu shares between background and
foreground apps.

CQ-DEPEND=CL:356201
BUG=b/29259708
TEST=minijail0 -m '0 1000 100' -M '0 1000 100' -N /bin/bash
  check that the cgroup namespace is different
  check that a newly mounted cgroup FS is rooted at the parent's cgroup

Change-Id: I3aead23ec8273eae90184337c040054becf4f12b
Signed-off-by: Dylan Reid <dgreid@chromium.org>
diff --git a/libminijail.c b/libminijail.c
index 2c57d4d..3a51942 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -88,6 +88,11 @@
 # define SECCOMP_SOFTFAIL 0
 #endif
 
+/* New cgroup namespace might not be in linux-headers yet. */
+#ifndef CLONE_NEWCGROUP
+# define CLONE_NEWCGROUP 0x02000000
+#endif
+
 #define MAX_CGROUPS 10 /* 10 different controllers supported by Linux. */
 
 struct mountpoint {
@@ -117,6 +122,7 @@
 		int ipc:1;
 		int net:1;
 		int enter_net:1;
+		int ns_cgroups:1;
 		int userns:1;
 		int seccomp:1;
 		int remount_proc_ro:1;
@@ -452,6 +458,11 @@
 	j->flags.enter_net = 1;
 }
 
+void API minijail_namespace_cgroups(struct minijail *j)
+{
+	j->flags.ns_cgroups = 1;
+}
+
 void API minijail_remount_proc_readonly(struct minijail *j)
 {
 	j->flags.vfs = 1;
@@ -1455,6 +1466,9 @@
 		pdie("unshare(net)");
 	}
 
+	if (j->flags.ns_cgroups && unshare(CLONE_NEWCGROUP))
+		pdie("unshare(cgroups)");
+
 	if (j->flags.chroot && enter_chroot(j))
 		pdie("chroot");