aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorEric W. Biederman2013-03-24 16:28:27 -0500
committerGreg Kroah-Hartman2013-04-05 11:26:02 -0500
commitcfc13c72f4642f811c159cceb921df69cd158725 (patch)
tree3aeebd2a9b1ab3ccc350a5810208779c7f8999e9 /fs
parent63795cc597539dff38550070dfd945dc08862eef (diff)
downloadkernel-omap-cfc13c72f4642f811c159cceb921df69cd158725.tar.gz
kernel-omap-cfc13c72f4642f811c159cceb921df69cd158725.tar.xz
kernel-omap-cfc13c72f4642f811c159cceb921df69cd158725.zip
userns: Restrict when proc and sysfs can be mounted
commit 87a8ebd637dafc255070f503909a053cf0d98d3f upstream. Only allow unprivileged mounts of proc and sysfs if they are already mounted when the user namespace is created. proc and sysfs are interesting because they have content that is per namespace, and so fresh mounts are needed when new namespaces are created while at the same time proc and sysfs have content that is shared between every instance. Respect the policy of who may see the shared content of proc and sysfs by only allowing new mounts if there was an existing mount at the time the user namespace was created. In practice there are only two interesting cases: proc and sysfs are mounted at their usual places, proc and sysfs are not mounted at all (some form of mount namespace jail). Acked-by: Serge Hallyn <serge.hallyn@canonical.com> Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/namespace.c21
-rw-r--r--fs/proc/root.c4
-rw-r--r--fs/sysfs/mount.c4
3 files changed, 29 insertions, 0 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 79460e17ac6c..5dd7709f9d02 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2789,6 +2789,27 @@ bool current_chrooted(void)
2789 return chrooted; 2789 return chrooted;
2790} 2790}
2791 2791
2792void update_mnt_policy(struct user_namespace *userns)
2793{
2794 struct mnt_namespace *ns = current->nsproxy->mnt_ns;
2795 struct mount *mnt;
2796
2797 down_read(&namespace_sem);
2798 list_for_each_entry(mnt, &ns->list, mnt_list) {
2799 switch (mnt->mnt.mnt_sb->s_magic) {
2800 case SYSFS_MAGIC:
2801 userns->may_mount_sysfs = true;
2802 break;
2803 case PROC_SUPER_MAGIC:
2804 userns->may_mount_proc = true;
2805 break;
2806 }
2807 if (userns->may_mount_sysfs && userns->may_mount_proc)
2808 break;
2809 }
2810 up_read(&namespace_sem);
2811}
2812
2792static void *mntns_get(struct task_struct *task) 2813static void *mntns_get(struct task_struct *task)
2793{ 2814{
2794 struct mnt_namespace *ns = NULL; 2815 struct mnt_namespace *ns = NULL;
diff --git a/fs/proc/root.c b/fs/proc/root.c
index c6e9fac26bac..9c7fab1d23f0 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -16,6 +16,7 @@
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/bitops.h> 18#include <linux/bitops.h>
19#include <linux/user_namespace.h>
19#include <linux/mount.h> 20#include <linux/mount.h>
20#include <linux/pid_namespace.h> 21#include <linux/pid_namespace.h>
21#include <linux/parser.h> 22#include <linux/parser.h>
@@ -108,6 +109,9 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
108 } else { 109 } else {
109 ns = task_active_pid_ns(current); 110 ns = task_active_pid_ns(current);
110 options = data; 111 options = data;
112
113 if (!current_user_ns()->may_mount_proc)
114 return ERR_PTR(-EPERM);
111 } 115 }
112 116
113 sb = sget(fs_type, proc_test_super, proc_set_super, flags, ns); 117 sb = sget(fs_type, proc_test_super, proc_set_super, flags, ns);
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index db940a9be045..fb328d1be42f 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -19,6 +19,7 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/magic.h> 20#include <linux/magic.h>
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/user_namespace.h>
22 23
23#include "sysfs.h" 24#include "sysfs.h"
24 25
@@ -111,6 +112,9 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type,
111 struct super_block *sb; 112 struct super_block *sb;
112 int error; 113 int error;
113 114
115 if (!(flags & MS_KERNMOUNT) && !current_user_ns()->may_mount_sysfs)
116 return ERR_PTR(-EPERM);
117
114 info = kzalloc(sizeof(*info), GFP_KERNEL); 118 info = kzalloc(sizeof(*info), GFP_KERNEL);
115 if (!info) 119 if (!info)
116 return ERR_PTR(-ENOMEM); 120 return ERR_PTR(-ENOMEM);