diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2019-05-12 15:42:48 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2019-05-25 17:59:56 -0400 |
commit | 0ce0cf12fc4c6a089717ff613d76457052cf4303 (patch) | |
tree | fd9ab4b39fc4c8236d06dede5f03c013d1186777 /fs/super.c | |
parent | feb8ae43a7b33148028829b1b1691b28c874c952 (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.c | 32 |
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 | ||
477 | EXPORT_SYMBOL(generic_shutdown_super); | 477 | EXPORT_SYMBOL(generic_shutdown_super); |
478 | 478 | ||
479 | bool 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 | ||
520 | retry: | 520 | retry: |
@@ -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); | ||
594 | retry: | 590 | retry: |
595 | spin_lock(&sb_lock); | 591 | spin_lock(&sb_lock); |
596 | if (test) { | 592 | if (test) { |