diff --git a/fs/fs_context.c b/fs/fs_context.c index d75ba0eb8c5bcfc4c2974f332c0183eb9d15581a..bc5a5f5f1853a32c3c4dbbbd66ec07c892a5c474 100644 --- a/fs/fs_context.c +++ b/fs/fs_context.c @@ -663,7 +663,7 @@ static int legacy_get_tree(struct fs_context *fc) struct dentry *root; if (!(fc->sb_flags & (SB_KERNMOUNT|SB_SUBMOUNT))) { - if (!mount_capable(fc->fs_type, fc->user_ns)) + if (!mount_capable(fc)) return -EPERM; } diff --git a/fs/internal.h b/fs/internal.h index 65db901420afbe04ee3b04f472e9b29308e95ab2..b089a489da1f122bf14d2335c93f2e8d1be8fb54 100644 --- a/fs/internal.h +++ b/fs/internal.h @@ -114,7 +114,7 @@ extern struct file *alloc_empty_file_noaccount(int, const struct cred *); extern int reconfigure_super(struct fs_context *); extern bool trylock_super(struct super_block *sb); extern struct super_block *user_get_super(dev_t); -extern bool mount_capable(struct file_system_type *, struct user_namespace *); +extern bool mount_capable(struct fs_context *); /* * open.c diff --git a/fs/super.c b/fs/super.c index bdb03255c7ea988e2f1b53996812bf5869f8bd2f..d1e2f46bad7e9faeffd69483ee39fdbd81f47ab6 100644 --- a/fs/super.c +++ b/fs/super.c @@ -476,12 +476,15 @@ void generic_shutdown_super(struct super_block *sb) EXPORT_SYMBOL(generic_shutdown_super); -bool mount_capable(struct file_system_type *type, struct user_namespace *userns) +bool mount_capable(struct fs_context *fc) { - if (!(type->fs_flags & FS_USERNS_MOUNT)) + struct user_namespace *user_ns = fc->global ? &init_user_ns + : fc->user_ns; + + if (!(fc->fs_type->fs_flags & FS_USERNS_MOUNT)) return capable(CAP_SYS_ADMIN); else - return ns_capable(userns, CAP_SYS_ADMIN); + return ns_capable(user_ns, CAP_SYS_ADMIN); } /** @@ -513,7 +516,7 @@ struct super_block *sget_fc(struct fs_context *fc, if (!(fc->sb_flags & SB_KERNMOUNT) && fc->purpose != FS_CONTEXT_FOR_SUBMOUNT) { - if (!mount_capable(fc->fs_type, user_ns)) + if (!mount_capable(fc)) return ERR_PTR(-EPERM); }