summaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
authorEric W. Biederman <ebiederm@xmission.com>2016-08-08 15:37:37 -0400
committerEric W. Biederman <ebiederm@xmission.com>2016-08-31 08:28:35 -0400
commit537f7ccb396804c6d0057b93ba8eb104ba44f851 (patch)
tree0fbb44ee9bb13aed8c9e3fedede97c07dcf2a4da /fs/namespace.c
parent703286608a220d53584cca5986aad5305eec75ed (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.c22
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
2722static struct ucounts *inc_mnt_namespaces(struct user_namespace *ns)
2723{
2724 return inc_ucount(ns, current_euid(), UCOUNT_MNT_NAMESPACES);
2725}
2726
2727static void dec_mnt_namespaces(struct ucounts *ucounts)
2728{
2729 dec_ucount(ucounts, UCOUNT_MNT_NAMESPACES);
2730}
2731
2722static void free_mnt_ns(struct mnt_namespace *ns) 2732static 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);
2738static struct mnt_namespace *alloc_mnt_ns(struct user_namespace *user_ns) 2749static 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