summaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2019-05-12 15:42:48 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2019-05-25 17:59:56 -0400
commit0ce0cf12fc4c6a089717ff613d76457052cf4303 (patch)
treefd9ab4b39fc4c8236d06dede5f03c013d1186777 /fs/super.c
parentfeb8ae43a7b33148028829b1b1691b28c874c952 (diff)
consolidate the capability checks in sget_{fc,userns}()
... into a common helper - mount_capable(type, userns) Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c32
1 files changed, 14 insertions, 18 deletions
diff --git a/fs/super.c b/fs/super.c
index 9c371a04e1b6..3ba91d70c2a8 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -476,6 +476,14 @@ void generic_shutdown_super(struct super_block *sb)
476 476
477EXPORT_SYMBOL(generic_shutdown_super); 477EXPORT_SYMBOL(generic_shutdown_super);
478 478
479bool mount_capable(struct file_system_type *type, struct user_namespace *userns)
480{
481 if (!(type->fs_flags & FS_USERNS_MOUNT))
482 return capable(CAP_SYS_ADMIN);
483 else
484 return ns_capable(userns, CAP_SYS_ADMIN);
485}
486
479/** 487/**
480 * sget_fc - Find or create a superblock 488 * sget_fc - Find or create a superblock
481 * @fc: Filesystem context. 489 * @fc: Filesystem context.
@@ -505,16 +513,8 @@ struct super_block *sget_fc(struct fs_context *fc,
505 513
506 if (!(fc->sb_flags & SB_KERNMOUNT) && 514 if (!(fc->sb_flags & SB_KERNMOUNT) &&
507 fc->purpose != FS_CONTEXT_FOR_SUBMOUNT) { 515 fc->purpose != FS_CONTEXT_FOR_SUBMOUNT) {
508 /* Don't allow mounting unless the caller has CAP_SYS_ADMIN 516 if (!mount_capable(fc->fs_type, user_ns))
509 * over the namespace. 517 return ERR_PTR(-EPERM);
510 */
511 if (!(fc->fs_type->fs_flags & FS_USERNS_MOUNT)) {
512 if (!capable(CAP_SYS_ADMIN))
513 return ERR_PTR(-EPERM);
514 } else {
515 if (!ns_capable(fc->user_ns, CAP_SYS_ADMIN))
516 return ERR_PTR(-EPERM);
517 }
518 } 518 }
519 519
520retry: 520retry:
@@ -583,14 +583,10 @@ struct super_block *sget_userns(struct file_system_type *type,
583 struct super_block *old; 583 struct super_block *old;
584 int err; 584 int err;
585 585
586 /* Ensure the requestor has permissions over the target filesystem */ 586 if (!(flags & (SB_KERNMOUNT|SB_SUBMOUNT))) {
587 if (!(flags & (SB_KERNMOUNT|SB_SUBMOUNT)) && !ns_capable(user_ns, CAP_SYS_ADMIN)) 587 if (!mount_capable(type, user_ns))
588 return ERR_PTR(-EPERM); 588 return ERR_PTR(-EPERM);
589 589 }
590 if (!(flags & (SB_KERNMOUNT|SB_SUBMOUNT)) &&
591 !(type->fs_flags & FS_USERNS_MOUNT) &&
592 !capable(CAP_SYS_ADMIN))
593 return ERR_PTR(-EPERM);
594retry: 590retry:
595 spin_lock(&sb_lock); 591 spin_lock(&sb_lock);
596 if (test) { 592 if (test) {