summaryrefslogtreecommitdiffstats
path: root/fs/super.c
diff options
context:
space:
mode:
authorAl Viro <viro@zeniv.linux.org.uk>2018-12-20 15:04:50 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2019-01-30 17:44:26 -0500
commitc9ce29ed795fae86e594844857fad1b0d3be85f4 (patch)
tree3b5abef036dc37687ea0fb3d1913f9cb3d31f234 /fs/super.c
parent132e460848f4261b8a6b9c28fae52bf9e02b52fd (diff)
vfs_get_tree(): evict the call of security_sb_kern_mount()
Right now vfs_get_tree() calls security_sb_kern_mount() (i.e. mount MAC) unless it gets MS_KERNMOUNT or MS_SUBMOUNT in flags. Doing it that way is both clumsy and imprecise. Consider the callers' tree of vfs_get_tree(): vfs_get_tree() <- do_new_mount() <- vfs_kern_mount() <- simple_pin_fs() <- vfs_submount() <- kern_mount_data() <- init_mount_tree() <- btrfs_mount() <- vfs_get_tree() <- nfs_do_root_mount() <- nfs4_try_mount() <- nfs_fs_mount() <- vfs_get_tree() <- nfs4_referral_mount() do_new_mount() always does need MAC (we are guaranteed that neither MS_KERNMOUNT nor MS_SUBMOUNT will be passed there). simple_pin_fs(), vfs_submount() and kern_mount_data() pass explicit flags inhibiting that check. So does nfs4_referral_mount() (the flags there are ulimately coming from vfs_submount()). init_mount_tree() is called too early for anything LSM-related; it doesn't matter whether we attempt those checks, they'll do nothing. Finally, in case of btrfs_mount() and nfs_fs_mount(), doing MAC is pointless - either the caller will do it, or the flags are such that we wouldn't have done it either. In other words, the one and only case when we want that check done is when we are called from do_new_mount(), and there we want it unconditionally. So let's simply move it there. The superblock is still locked, so nobody is going to get access to it (via ustat(2), etc.) until we get a chance to apply the checks - we are free to move them to any point up to where we drop ->s_umount (in do_new_mount_fc()). Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/super.c')
-rw-r--r--fs/super.c15
1 files changed, 3 insertions, 12 deletions
diff --git a/fs/super.c b/fs/super.c
index b91b6df05b67..11e2a6cb3baf 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -1277,13 +1277,9 @@ int vfs_get_tree(struct fs_context *fc)
1277 sb->s_flags |= SB_BORN; 1277 sb->s_flags |= SB_BORN;
1278 1278
1279 error = security_sb_set_mnt_opts(sb, fc->security, 0, NULL); 1279 error = security_sb_set_mnt_opts(sb, fc->security, 0, NULL);
1280 if (error) 1280 if (unlikely(error)) {
1281 goto out_sb; 1281 fc_drop_locked(fc);
1282 1282 return error;
1283 if (!(fc->sb_flags & (MS_KERNMOUNT|MS_SUBMOUNT))) {
1284 error = security_sb_kern_mount(sb);
1285 if (error)
1286 goto out_sb;
1287 } 1283 }
1288 1284
1289 /* 1285 /*
@@ -1296,11 +1292,6 @@ int vfs_get_tree(struct fs_context *fc)
1296 "negative value (%lld)\n", fc->fs_type->name, sb->s_maxbytes); 1292 "negative value (%lld)\n", fc->fs_type->name, sb->s_maxbytes);
1297 1293
1298 return 0; 1294 return 0;
1299out_sb:
1300 dput(fc->root);
1301 fc->root = NULL;
1302 deactivate_locked_super(sb);
1303 return error;
1304} 1295}
1305EXPORT_SYMBOL(vfs_get_tree); 1296EXPORT_SYMBOL(vfs_get_tree);
1306 1297