Subject: linux 3.14.22, patch-3.14.17-vs2.3.6.13.diff, and CONFIG_USER_NS
From: Corey Wright <undefined@pobox.com>
Date: Mon, 27 Oct 2014 04:31:05 -0500
Mon, 27 Oct 2014 04:31:05 -0500
the attached patch (in conjuction with [1] for linux 3.14.22, though possibly
still applicable to kernels < 3.14.19 without those additional patches)
allows linux 3.14 to compile and run with CONFIG_USER_NS, including
containers.

[1] http://archives.linux-vserver.org/201410/0050.html

WARNING:
1. this is not production quality and only made available for testing.
2. i don't know the security ramifications of running both vservers and
containers on a single host.
3. it is conceivable that containers can run inside of vservers with the
provided patch, but i haven't tested such nor do i know the security
ramifications.

NOTES:
1. vservers will not use user namespaces by default. [2]
2. vservers cannot use user namespaces without changes to util-vserver and
possibly more kernel changes. [3]
3. lxc should work. [4]

[2] in the attached patch CLONE_NEWUSER is commented out in
default_space_mask which prevents util-vserver from using user namespaces with
vservers.

[3] vspace needs to create uid and gid mappings for the new user namespace
between sys_clone() and execvp() calls otherwise all capabilities,
specifically CAP_CONTEXT, are removed from the executed vcontext because the
uid and gid are 65535.  see https://lwn.net/Articles/532593/, specifically
the section "Capabilities, execve(), and user ID 0".

[4] tested with lxc 1.0.6 on linux 3.14.22-vs2.3.6.13 with the attached
userns patch by creating a container ("SUITE=wheezy
MIRROR=http://http.us.debian.org/debian lxc-create -n test -t debian"),
starting the container ("lxc-start -n test -d"), and attaching to the console
("lxc-console -n test"), and stopping the container ("lxc-stop -n test")
though i was unable to log into the container ("unable to determine your tty
name"), but i believe that to be a configuration problem with the
installation inside the container.

FULL DISCLOSURE:
1. the last two hunks are not both necessary.  commenting out CLONE_NEWUSER
in default_space_mask is used to keep util-vserver from using user namespaces
for vservers.  changing "capable()" to "ns_capable()" is required to use
linux-vserver system calls within a user namespace (and is there currently
for testing as it's not that useful without the aforementioned changes to
util-vserver).  you really only need one or the other and the last hunk is
not that useful without changes to util-vserver (and more changes might be
necessary).

please test and provide feedback, especially if you have better suggestions to
simply test lxc/containers as i'm a newbie in that area.

corey
--
undefined@pobox.com


diff -urNpd linux-3.14.22-vs2.3.6.13~/include/linux/uidgid.h linux-3.14.22-vs2.3.6.13/include/linux/uidgid.h
--- linux-3.14.22-vs2.3.6.13~/include/linux/uidgid.h	2014-10-15 21:33:01.000000000 -0500
+++ linux-3.14.22-vs2.3.6.13/include/linux/uidgid.h	2014-10-15 21:36:39.000000000 -0500
@@ -130,7 +130,7 @@ static inline bool tag_valid(ktag_t tag)
 
 extern kuid_t make_kuid(struct user_namespace *from, uid_t uid);
 extern kgid_t make_kgid(struct user_namespace *from, gid_t gid);
-extern krag_t make_ktag(struct user_namespace *from, gid_t gid);
+extern ktag_t make_ktag(struct user_namespace *from, vtag_t tag);
 
 extern uid_t from_kuid(struct user_namespace *to, kuid_t uid);
 extern gid_t from_kgid(struct user_namespace *to, kgid_t gid);
--- linux-3.14.22-vs2.3.6.14~/kernel/user_namespace.c	2014-10-15 21:33:01.000000000
-0500
+++ linux-3.14.22-vs2.3.6.14/kernel/user_namespace.c	2014-10-25 15:20:12.000000000 -0500
@@ -352,6 +352,18 @@ gid_t from_kgid_munged(struct user_names
 }
 EXPORT_SYMBOL(from_kgid_munged);
 
+ktag_t make_ktag(struct user_namespace *from, vtag_t tag)
+{
+	return KTAGT_INIT(tag);
+}
+EXPORT_SYMBOL(make_ktag);
+
+vtag_t from_ktag(struct user_namespace *to, ktag_t tag)
+{
+	return __ktag_val(tag);
+}
+EXPORT_SYMBOL(from_ktag);
+
 /**
  *	make_kprojid - Map a user-namespace projid pair into a kprojid.
  *	@ns:  User namespace that the projid is in
diff -urpd linux-3.14.22-vs2.3.6.14~/kernel/vserver/space.c linux-3.14.22-vs2.3.6.14/kernel/vserver/space.c
--- linux-3.14.22-vs2.3.6.14~/kernel/vserver/space.c	2014-10-15 21:33:01.000000000 -0500
+++ linux-3.14.22-vs2.3.6.14/kernel/vserver/space.c	2014-10-27 01:36:37.000000000 -0500
@@ -88,7 +88,7 @@ static const struct vcmd_space_mask_v1 d
 		CLONE_NEWIPC |
 #endif
 #ifdef	CONFIG_USER_NS
-		CLONE_NEWUSER |
+//		CLONE_NEWUSER |
 #endif
 #ifdef	CONFIG_PID_NS
 //		CLONE_NEWPID |
diff -urpd linux-3.14.22-vs2.3.6.14~/kernel/vserver/switch.c linux-3.14.22-vs2.3.6.14/kernel/vserver/switch.c
--- linux-3.14.22-vs2.3.6.14~/kernel/vserver/switch.c	2014-10-15 21:33:01.000000000
-0500
+++ linux-3.14.22-vs2.3.6.14/kernel/vserver/switch.c	2014-10-27 01:18:15.000000000 -0500
@@ -435,19 +435,20 @@ long do_vserver(uint32_t cmd, uint32_t i
 		goto out;
 
 	state = 1;
-	if (!capable(CAP_CONTEXT))
+	if (!ns_capable(current_user_ns(), CAP_CONTEXT))
 		goto out;
 
 	state = 2;
 	/* moved here from the individual commands */
 	ret = -EPERM;
-	if ((perm > 1) && !capable(CAP_SYS_ADMIN))
+	if ((perm > 1) && !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
 		goto out;
 
 	state = 3;
 	/* vcmd involves resource management  */
 	ret = -EPERM;
-	if ((flags & VCF_ARES) && !capable(CAP_SYS_RESOURCE))
+	if ((flags & VCF_ARES) &&
+		!ns_capable(current_user_ns(), CAP_SYS_RESOURCE))
 		goto out;
 
 	state = 4;