aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 64627f883bf2..877e4277f496 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2867,25 +2867,38 @@ bool current_chrooted(void)
2867 return chrooted; 2867 return chrooted;
2868} 2868}
2869 2869
2870void update_mnt_policy(struct user_namespace *userns) 2870bool fs_fully_visible(struct file_system_type *type)
2871{ 2871{
2872 struct mnt_namespace *ns = current->nsproxy->mnt_ns; 2872 struct mnt_namespace *ns = current->nsproxy->mnt_ns;
2873 struct mount *mnt; 2873 struct mount *mnt;
2874 bool visible = false;
2874 2875
2875 down_read(&namespace_sem); 2876 if (unlikely(!ns))
2877 return false;
2878
2879 namespace_lock();
2876 list_for_each_entry(mnt, &ns->list, mnt_list) { 2880 list_for_each_entry(mnt, &ns->list, mnt_list) {
2877 switch (mnt->mnt.mnt_sb->s_magic) { 2881 struct mount *child;
2878 case SYSFS_MAGIC: 2882 if (mnt->mnt.mnt_sb->s_type != type)
2879 userns->may_mount_sysfs = true; 2883 continue;
2880 break; 2884
2881 case PROC_SUPER_MAGIC: 2885 /* This mount is not fully visible if there are any child mounts
2882 userns->may_mount_proc = true; 2886 * that cover anything except for empty directories.
2883 break; 2887 */
2888 list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
2889 struct inode *inode = child->mnt_mountpoint->d_inode;
2890 if (!S_ISDIR(inode->i_mode))
2891 goto next;
2892 if (inode->i_nlink != 2)
2893 goto next;
2884 } 2894 }
2885 if (userns->may_mount_sysfs && userns->may_mount_proc) 2895 visible = true;
2886 break; 2896 goto found;
2897 next: ;
2887 } 2898 }
2888 up_read(&namespace_sem); 2899found:
2900 namespace_unlock();
2901 return visible;
2889} 2902}
2890 2903
2891static void *mntns_get(struct task_struct *task) 2904static void *mntns_get(struct task_struct *task)