]> git.proxmox.com Git - mirror_lxc.git/commitdiff
namespace: always attach to user namespace first
authorChristian Brauner <christian.brauner@canonical.com>
Sun, 20 Nov 2016 05:20:07 +0000 (06:20 +0100)
committerChristian Brauner <christian.brauner@canonical.com>
Sun, 20 Nov 2016 05:26:03 +0000 (06:26 +0100)
Move the user namespace at the first position in the array so that we always
attach to it first when iterating over the struct and using setns() to switch
namespaces. This especially affects lxc_attach(): Suppose you cloned a new user
namespace and mount namespace as an unprivileged user on the host and want to
setns() to the mount namespace. This requires you to attach to the user
namespace first otherwise the kernel will fail this check:

    if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
        !ns_capable(current_user_ns(), CAP_SYS_CHROOT) ||
        !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
     return -EPERM;

in

    linux/fs/namespace.c:mntns_install().

Signed-off-by: Christian Brauner <christian.brauner@canonical.com>
src/lxc/namespace.c
src/lxc/namespace.h

index bb76f4c90364390353425f61fc92d485f3291d10..3a5b3bef6c5bde2e66ad76657cb129a5d8b50b84 100644 (file)
@@ -69,12 +69,28 @@ pid_t lxc_clone(int (*fn)(void *), void *arg, int flags)
        return ret;
 }
 
+/* Leave the user namespace at the first position in the array of structs so
+ * that we always attach to it first when iterating over the struct and using
+ * setns() to switch namespaces. This especially affects lxc_attach(): Suppose
+ * you cloned a new user namespace and mount namespace as an unprivileged user
+ * on the host and want to setns() to the mount namespace. This requires you to
+ * attach to the user namespace first otherwise the kernel will fail this check:
+ *
+ *        if (!ns_capable(mnt_ns->user_ns, CAP_SYS_ADMIN) ||
+ *            !ns_capable(current_user_ns(), CAP_SYS_CHROOT) ||
+ *            !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
+ *            return -EPERM;
+ *
+ *    in
+ *
+ *        linux/fs/namespace.c:mntns_install().
+ */
 const struct ns_info ns_info[LXC_NS_MAX] = {
+       [LXC_NS_USER] = {"user", CLONE_NEWUSER, "CLONE_NEWUSER"},
        [LXC_NS_MNT] = {"mnt", CLONE_NEWNS, "CLONE_NEWNS"},
        [LXC_NS_PID] = {"pid", CLONE_NEWPID, "CLONE_NEWPID"},
        [LXC_NS_UTS] = {"uts", CLONE_NEWUTS, "CLONE_NEWUTS"},
        [LXC_NS_IPC] = {"ipc", CLONE_NEWIPC, "CLONE_NEWIPC"},
-       [LXC_NS_USER] = {"user", CLONE_NEWUSER, "CLONE_NEWUSER"},
        [LXC_NS_NET] = {"net", CLONE_NEWNET, "CLONE_NEWNET"},
        [LXC_NS_CGROUP] = {"cgroup", CLONE_NEWCGROUP, "CLONE_NEWCGROUP"}
 };
index 57167f4d045300ad0e590d9d8e7700c9af910541..4916950c15d2a0e935cafd610f140ae2fcd7ed75 100644 (file)
 #endif
 
 enum {
+       LXC_NS_USER,
        LXC_NS_MNT,
        LXC_NS_PID,
        LXC_NS_UTS,
        LXC_NS_IPC,
-       LXC_NS_USER,
        LXC_NS_NET,
        LXC_NS_CGROUP,
        LXC_NS_MAX