move mount_capable() calls to vfs_get_tree()
authorAl Viro <viro@zeniv.linux.org.uk>
Sun, 12 May 2019 22:16:04 +0000 (18:16 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 25 May 2019 22:00:01 +0000 (18:00 -0400)
sget_fc() is called only from ->get_tree() instances and
the only instance not calling it is legacy_get_tree(),
which calls mount_capable() directly.

In all sget_fc() callers the checks could be moved to the
very beginning of ->get_tree() - ->user_ns is not changed
in between.  So lifting the checks to the only caller of
->get_tree() is OK.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/fs_context.c
fs/super.c

index bc5a5f5..a47ccd5 100644 (file)
@@ -662,11 +662,6 @@ static int legacy_get_tree(struct fs_context *fc)
        struct super_block *sb;
        struct dentry *root;
 
-       if (!(fc->sb_flags & (SB_KERNMOUNT|SB_SUBMOUNT))) {
-               if (!mount_capable(fc))
-                       return -EPERM;
-       }
-
        root = fc->fs_type->mount(fc->fs_type, fc->sb_flags,
                                      fc->source, ctx->legacy_data);
        if (IS_ERR(root))
index d1e2f46..2c38541 100644 (file)
@@ -514,12 +514,6 @@ struct super_block *sget_fc(struct fs_context *fc,
        struct user_namespace *user_ns = fc->global ? &init_user_ns : fc->user_ns;
        int err;
 
-       if (!(fc->sb_flags & SB_KERNMOUNT) &&
-           fc->purpose != FS_CONTEXT_FOR_SUBMOUNT) {
-               if (!mount_capable(fc))
-                       return ERR_PTR(-EPERM);
-       }
-
 retry:
        spin_lock(&sb_lock);
        if (test) {
@@ -1421,6 +1415,12 @@ int vfs_get_tree(struct fs_context *fc)
        if (fc->root)
                return -EBUSY;
 
+       if (!(fc->sb_flags & SB_KERNMOUNT) &&
+           fc->purpose != FS_CONTEXT_FOR_SUBMOUNT) {
+               if (!mount_capable(fc))
+                       return -EPERM;
+       }
+
        /* Get the mountable root in fc->root, with a ref on the root and a ref
         * on the superblock.
         */