|
@@ -2719,9 +2719,20 @@ dput_out:
|
|
|
return retval;
|
|
|
}
|
|
|
|
|
|
+static struct ucounts *inc_mnt_namespaces(struct user_namespace *ns)
|
|
|
+{
|
|
|
+ return inc_ucount(ns, current_euid(), UCOUNT_MNT_NAMESPACES);
|
|
|
+}
|
|
|
+
|
|
|
+static void dec_mnt_namespaces(struct ucounts *ucounts)
|
|
|
+{
|
|
|
+ dec_ucount(ucounts, UCOUNT_MNT_NAMESPACES);
|
|
|
+}
|
|
|
+
|
|
|
static void free_mnt_ns(struct mnt_namespace *ns)
|
|
|
{
|
|
|
ns_free_inum(&ns->ns);
|
|
|
+ dec_mnt_namespaces(ns->ucounts);
|
|
|
put_user_ns(ns->user_ns);
|
|
|
kfree(ns);
|
|
|
}
|
|
@@ -2738,14 +2749,22 @@ static atomic64_t mnt_ns_seq = ATOMIC64_INIT(1);
|
|
|
static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns)
|
|
|
{
|
|
|
struct mnt_namespace *new_ns;
|
|
|
+ struct ucounts *ucounts;
|
|
|
int ret;
|
|
|
|
|
|
+ ucounts = inc_mnt_namespaces(user_ns);
|
|
|
+ if (!ucounts)
|
|
|
+ return ERR_PTR(-ENFILE);
|
|
|
+
|
|
|
new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
|
|
|
- if (!new_ns)
|
|
|
+ if (!new_ns) {
|
|
|
+ dec_mnt_namespaces(ucounts);
|
|
|
return ERR_PTR(-ENOMEM);
|
|
|
+ }
|
|
|
ret = ns_alloc_inum(&new_ns->ns);
|
|
|
if (ret) {
|
|
|
kfree(new_ns);
|
|
|
+ dec_mnt_namespaces(ucounts);
|
|
|
return ERR_PTR(ret);
|
|
|
}
|
|
|
new_ns->ns.ops = &mntns_operations;
|
|
@@ -2756,6 +2775,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns)
|
|
|
init_waitqueue_head(&new_ns->poll);
|
|
|
new_ns->event = 0;
|
|
|
new_ns->user_ns = get_user_ns(user_ns);
|
|
|
+ new_ns->ucounts = ucounts;
|
|
|
return new_ns;
|
|
|
}
|
|
|
|