mm, compaction: require only min watermarks for non-costly orders
[cascardo/linux.git] / kernel / user_namespace.c
index 58c67e5..86b7854 100644 (file)
@@ -31,6 +31,16 @@ static bool new_idmap_permitted(const struct file *file,
                                struct uid_gid_map *map);
 static void free_user_ns(struct work_struct *work);
 
+static struct ucounts *inc_user_namespaces(struct user_namespace *ns, kuid_t uid)
+{
+       return inc_ucount(ns, uid, UCOUNT_USER_NAMESPACES);
+}
+
+static void dec_user_namespaces(struct ucounts *ucounts)
+{
+       return dec_ucount(ucounts, UCOUNT_USER_NAMESPACES);
+}
+
 static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns)
 {
        /* Start with the same capabilities as init but useless for doing
@@ -64,9 +74,9 @@ int create_user_ns(struct cred *new)
        kuid_t owner = new->euid;
        kgid_t group = new->egid;
        struct ucounts *ucounts;
-       int ret;
+       int ret, i;
 
-       ret = -EUSERS;
+       ret = -ENOSPC;
        if (parent_ns->level > 32)
                goto fail;
 
@@ -110,7 +120,9 @@ int create_user_ns(struct cred *new)
        ns->owner = owner;
        ns->group = group;
        INIT_WORK(&ns->work, free_user_ns);
-       ns->max_user_namespaces = INT_MAX;
+       for (i = 0; i < UCOUNT_COUNTS; i++) {
+               ns->ucount_max[i] = INT_MAX;
+       }
        ns->ucounts = ucounts;
 
        /* Inherit USERNS_SETGROUPS_ALLOWED from our parent */
@@ -1038,12 +1050,37 @@ static int userns_install(struct nsproxy *nsproxy, struct ns_common *ns)
        return commit_creds(cred);
 }
 
+struct ns_common *ns_get_owner(struct ns_common *ns)
+{
+       struct user_namespace *my_user_ns = current_user_ns();
+       struct user_namespace *owner, *p;
+
+       /* See if the owner is in the current user namespace */
+       owner = p = ns->ops->owner(ns);
+       for (;;) {
+               if (!p)
+                       return ERR_PTR(-EPERM);
+               if (p == my_user_ns)
+                       break;
+               p = p->parent;
+       }
+
+       return &get_user_ns(owner)->ns;
+}
+
+static struct user_namespace *userns_owner(struct ns_common *ns)
+{
+       return to_user_ns(ns)->parent;
+}
+
 const struct proc_ns_operations userns_operations = {
        .name           = "user",
        .type           = CLONE_NEWUSER,
        .get            = userns_get,
        .put            = userns_put,
        .install        = userns_install,
+       .owner          = userns_owner,
+       .get_parent     = ns_get_owner,
 };
 
 static __init int user_namespaces_init(void)