diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2016-08-08 15:37:37 -0400 |
---|---|---|
committer | Eric W. Biederman <ebiederm@xmission.com> | 2016-08-31 08:28:35 -0400 |
commit | 537f7ccb396804c6d0057b93ba8eb104ba44f851 (patch) | |
tree | 0fbb44ee9bb13aed8c9e3fedede97c07dcf2a4da /fs/namespace.c | |
parent | 703286608a220d53584cca5986aad5305eec75ed (diff) |
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>
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index 7bb2cda3bfef..491b8f3e4c9a 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -2719,9 +2719,20 @@ dput_out: | |||
2719 | return retval; | 2719 | return retval; |
2720 | } | 2720 | } |
2721 | 2721 | ||
2722 | static struct ucounts *inc_mnt_namespaces(struct user_namespace *ns) | ||
2723 | { | ||
2724 | return inc_ucount(ns, current_euid(), UCOUNT_MNT_NAMESPACES); | ||
2725 | } | ||
2726 | |||
2727 | static void dec_mnt_namespaces(struct ucounts *ucounts) | ||
2728 | { | ||
2729 | dec_ucount(ucounts, UCOUNT_MNT_NAMESPACES); | ||
2730 | } | ||
2731 | |||
2722 | static void free_mnt_ns(struct mnt_namespace *ns) | 2732 | static void free_mnt_ns(struct mnt_namespace *ns) |
2723 | { | 2733 | { |
2724 | ns_free_inum(&ns->ns); | 2734 | ns_free_inum(&ns->ns); |
2735 | dec_mnt_namespaces(ns->ucounts); | ||
2725 | put_user_ns(ns->user_ns); | 2736 | put_user_ns(ns->user_ns); |
2726 | kfree(ns); | 2737 | kfree(ns); |
2727 | } | 2738 | } |
@@ -2738,14 +2749,22 @@ static atomic64_t mnt_ns_seq = ATOMIC64_INIT(1); | |||
2738 | static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) | 2749 | static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) |
2739 | { | 2750 | { |
2740 | struct mnt_namespace *new_ns; | 2751 | struct mnt_namespace *new_ns; |
2752 | struct ucounts *ucounts; | ||
2741 | int ret; | 2753 | int ret; |
2742 | 2754 | ||
2755 | ucounts = inc_mnt_namespaces(user_ns); | ||
2756 | if (!ucounts) | ||
2757 | return ERR_PTR(-ENFILE); | ||
2758 | |||
2743 | new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL); | 2759 | new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL); |
2744 | if (!new_ns) | 2760 | if (!new_ns) { |
2761 | dec_mnt_namespaces(ucounts); | ||
2745 | return ERR_PTR(-ENOMEM); | 2762 | return ERR_PTR(-ENOMEM); |
2763 | } | ||
2746 | ret = ns_alloc_inum(&new_ns->ns); | 2764 | ret = ns_alloc_inum(&new_ns->ns); |
2747 | if (ret) { | 2765 | if (ret) { |
2748 | kfree(new_ns); | 2766 | kfree(new_ns); |
2767 | dec_mnt_namespaces(ucounts); | ||
2749 | return ERR_PTR(ret); | 2768 | return ERR_PTR(ret); |
2750 | } | 2769 | } |
2751 | new_ns->ns.ops = &mntns_operations; | 2770 | new_ns->ns.ops = &mntns_operations; |
@@ -2756,6 +2775,7 @@ static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) | |||
2756 | init_waitqueue_head(&new_ns->poll); | 2775 | init_waitqueue_head(&new_ns->poll); |
2757 | new_ns->event = 0; | 2776 | new_ns->event = 0; |
2758 | new_ns->user_ns = get_user_ns(user_ns); | 2777 | new_ns->user_ns = get_user_ns(user_ns); |
2778 | new_ns->ucounts = ucounts; | ||
2759 | return new_ns; | 2779 | return new_ns; |
2760 | } | 2780 | } |
2761 | 2781 | ||