diff options
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 37 |
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 | ||
2870 | void update_mnt_policy(struct user_namespace *userns) | 2870 | bool 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); | 2899 | found: |
2900 | namespace_unlock(); | ||
2901 | return visible; | ||
2889 | } | 2902 | } |
2890 | 2903 | ||
2891 | static void *mntns_get(struct task_struct *task) | 2904 | static void *mntns_get(struct task_struct *task) |