return chrooted;
 }
 
-void update_mnt_policy(struct user_namespace *userns)
+bool fs_fully_visible(struct file_system_type *type)
 {
        struct mnt_namespace *ns = current->nsproxy->mnt_ns;
        struct mount *mnt;
+       bool visible = false;
 
-       down_read(&namespace_sem);
+       if (unlikely(!ns))
+               return false;
+
+       namespace_lock();
        list_for_each_entry(mnt, &ns->list, mnt_list) {
-               switch (mnt->mnt.mnt_sb->s_magic) {
-               case SYSFS_MAGIC:
-                       userns->may_mount_sysfs = true;
-                       break;
-               case PROC_SUPER_MAGIC:
-                       userns->may_mount_proc = true;
-                       break;
+               struct mount *child;
+               if (mnt->mnt.mnt_sb->s_type != type)
+                       continue;
+
+               /* This mount is not fully visible if there are any child mounts
+                * that cover anything except for empty directories.
+                */
+               list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
+                       struct inode *inode = child->mnt_mountpoint->d_inode;
+                       if (!S_ISDIR(inode->i_mode))
+                               goto next;
+                       if (inode->i_nlink != 2)
+                               goto next;
                }
-               if (userns->may_mount_sysfs && userns->may_mount_proc)
-                       break;
+               visible = true;
+               goto found;
+       next:   ;
        }
-       up_read(&namespace_sem);
+found:
+       namespace_unlock();
+       return visible;
 }
 
 static void *mntns_get(struct task_struct *task)
 
                ns = task_active_pid_ns(current);
                options = data;
 
-               if (!current_user_ns()->may_mount_proc ||
-                   !ns_capable(ns->user_ns, CAP_SYS_ADMIN))
+               if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
+                       return ERR_PTR(-EPERM);
+
+               /* Does the mounter have privilege over the pid namespace? */
+               if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
                        return ERR_PTR(-EPERM);
        }
 
 
        struct super_block *sb;
        int error;
 
-       if (!(flags & MS_KERNMOUNT) && !current_user_ns()->may_mount_sysfs)
+       if (!(flags & MS_KERNMOUNT) && !capable(CAP_SYS_ADMIN) &&
+           !fs_fully_visible(fs_type))
                return ERR_PTR(-EPERM);
 
        info = kzalloc(sizeof(*info), GFP_KERNEL);
 
 extern int freeze_super(struct super_block *super);
 extern int thaw_super(struct super_block *super);
 extern bool our_mnt(struct vfsmount *mnt);
+extern bool fs_fully_visible(struct file_system_type *);
 
 extern int current_umask(void);
 
 
        kuid_t                  owner;
        kgid_t                  group;
        unsigned int            proc_inum;
-       bool                    may_mount_sysfs;
-       bool                    may_mount_proc;
 };
 
 extern struct user_namespace init_user_ns;
 
 #endif
 
-void update_mnt_policy(struct user_namespace *userns);
-
 #endif /* _LINUX_USER_H */
 
        .owner = GLOBAL_ROOT_UID,
        .group = GLOBAL_ROOT_GID,
        .proc_inum = PROC_USER_INIT_INO,
-       .may_mount_sysfs = true,
-       .may_mount_proc = true,
 };
 EXPORT_SYMBOL_GPL(init_user_ns);
 
 
 
        set_cred_user_ns(new, ns);
 
-       update_mnt_policy(ns);
-
        return 0;
 }