mntns: Add a limit on the number of mount namespaces.
v2: Fixed the very obvious lack of setting ucounts on struct mnt_ns reported by Andrei Vagin, and the kbuild test report. Reported-by: Andrei Vagin <avagin@openvz.org> Acked-by: Kees Cook <keescook@chromium.org> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
This commit is contained in:
parent
703286608a
commit
537f7ccb39
4 changed files with 24 additions and 1 deletions
|
@ -10,6 +10,7 @@ struct mnt_namespace {
|
||||||
struct mount * root;
|
struct mount * root;
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
struct user_namespace *user_ns;
|
struct user_namespace *user_ns;
|
||||||
|
struct ucounts *ucounts;
|
||||||
u64 seq; /* Sequence number to prevent loops */
|
u64 seq; /* Sequence number to prevent loops */
|
||||||
wait_queue_head_t poll;
|
wait_queue_head_t poll;
|
||||||
u64 event;
|
u64 event;
|
||||||
|
|
|
@ -2719,9 +2719,20 @@ long do_mount(const char *dev_name, const char __user *dir_name,
|
||||||
return retval;
|
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)
|
static void free_mnt_ns(struct mnt_namespace *ns)
|
||||||
{
|
{
|
||||||
ns_free_inum(&ns->ns);
|
ns_free_inum(&ns->ns);
|
||||||
|
dec_mnt_namespaces(ns->ucounts);
|
||||||
put_user_ns(ns->user_ns);
|
put_user_ns(ns->user_ns);
|
||||||
kfree(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)
|
static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns)
|
||||||
{
|
{
|
||||||
struct mnt_namespace *new_ns;
|
struct mnt_namespace *new_ns;
|
||||||
|
struct ucounts *ucounts;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
ucounts = inc_mnt_namespaces(user_ns);
|
||||||
|
if (!ucounts)
|
||||||
|
return ERR_PTR(-ENFILE);
|
||||||
|
|
||||||
new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
|
new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
|
||||||
if (!new_ns)
|
if (!new_ns) {
|
||||||
|
dec_mnt_namespaces(ucounts);
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
}
|
||||||
ret = ns_alloc_inum(&new_ns->ns);
|
ret = ns_alloc_inum(&new_ns->ns);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kfree(new_ns);
|
kfree(new_ns);
|
||||||
|
dec_mnt_namespaces(ucounts);
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
new_ns->ns.ops = &mntns_operations;
|
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);
|
init_waitqueue_head(&new_ns->poll);
|
||||||
new_ns->event = 0;
|
new_ns->event = 0;
|
||||||
new_ns->user_ns = get_user_ns(user_ns);
|
new_ns->user_ns = get_user_ns(user_ns);
|
||||||
|
new_ns->ucounts = ucounts;
|
||||||
return new_ns;
|
return new_ns;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,7 @@ enum ucount_type {
|
||||||
UCOUNT_UTS_NAMESPACES,
|
UCOUNT_UTS_NAMESPACES,
|
||||||
UCOUNT_IPC_NAMESPACES,
|
UCOUNT_IPC_NAMESPACES,
|
||||||
UCOUNT_NET_NAMESPACES,
|
UCOUNT_NET_NAMESPACES,
|
||||||
|
UCOUNT_MNT_NAMESPACES,
|
||||||
UCOUNT_CGROUP_NAMESPACES,
|
UCOUNT_CGROUP_NAMESPACES,
|
||||||
UCOUNT_COUNTS,
|
UCOUNT_COUNTS,
|
||||||
};
|
};
|
||||||
|
|
|
@ -72,6 +72,7 @@ static struct ctl_table user_table[] = {
|
||||||
UCOUNT_ENTRY("max_uts_namespaces"),
|
UCOUNT_ENTRY("max_uts_namespaces"),
|
||||||
UCOUNT_ENTRY("max_ipc_namespaces"),
|
UCOUNT_ENTRY("max_ipc_namespaces"),
|
||||||
UCOUNT_ENTRY("max_net_namespaces"),
|
UCOUNT_ENTRY("max_net_namespaces"),
|
||||||
|
UCOUNT_ENTRY("max_mnt_namespaces"),
|
||||||
UCOUNT_ENTRY("max_cgroup_namespaces"),
|
UCOUNT_ENTRY("max_cgroup_namespaces"),
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue