mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-23 08:35:19 -05:00
nfs: update has_sec_mnt_opts after cloning lsm options from parent
After calling security_sb_clone_mnt_opts() in nfs_get_root(), it's
necessary to copy the value of has_sec_mnt_opts from the cloned
super_block's nfs_server. Otherwise, calls to nfs_compare_super()
using this super_block may not return the correct result, leading to
mount failures.
For example, mounting an nfs server with the following in /etc/exports:
/export *(rw,insecure,crossmnt,no_root_squash,security_label)
and having /export/scratch on a separate block device.
mount -o v4.2,context=system_u:object_r:root_t:s0 server:/export/test /mnt/test
mount -o v4.2,context=system_u:object_r:swapfile_t:s0 server:/export/scratch /mnt/scratch
The second mount would fail with "mount.nfs: /mnt/scratch is busy or
already mounted or sharecache fail" and "SELinux: mount invalid. Same
superblock, different security settings for..." would appear in the
syslog.
Also while we're in there, replace several instances of "NFS_SB(s)"
with "server", which was already declared at the top of the
nfs_get_root().
Fixes: ec1ade6a04
("nfs: account for selinux security context when deciding to share superblock")
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
This commit is contained in:
parent
a9601ac5e9
commit
eae00c5d6e
1 changed files with 8 additions and 4 deletions
|
@ -67,7 +67,7 @@ static int nfs_superblock_set_dummy_root(struct super_block *sb, struct inode *i
|
|||
int nfs_get_root(struct super_block *s, struct fs_context *fc)
|
||||
{
|
||||
struct nfs_fs_context *ctx = nfs_fc2context(fc);
|
||||
struct nfs_server *server = NFS_SB(s);
|
||||
struct nfs_server *server = NFS_SB(s), *clone_server;
|
||||
struct nfs_fsinfo fsinfo;
|
||||
struct dentry *root;
|
||||
struct inode *inode;
|
||||
|
@ -127,7 +127,7 @@ int nfs_get_root(struct super_block *s, struct fs_context *fc)
|
|||
}
|
||||
spin_unlock(&root->d_lock);
|
||||
fc->root = root;
|
||||
if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL)
|
||||
if (server->caps & NFS_CAP_SECURITY_LABEL)
|
||||
kflags |= SECURITY_LSM_NATIVE_LABELS;
|
||||
if (ctx->clone_data.sb) {
|
||||
if (d_inode(fc->root)->i_fop != &nfs_dir_operations) {
|
||||
|
@ -137,15 +137,19 @@ int nfs_get_root(struct super_block *s, struct fs_context *fc)
|
|||
/* clone lsm security options from the parent to the new sb */
|
||||
error = security_sb_clone_mnt_opts(ctx->clone_data.sb,
|
||||
s, kflags, &kflags_out);
|
||||
if (error)
|
||||
goto error_splat_root;
|
||||
clone_server = NFS_SB(ctx->clone_data.sb);
|
||||
server->has_sec_mnt_opts = clone_server->has_sec_mnt_opts;
|
||||
} else {
|
||||
error = security_sb_set_mnt_opts(s, fc->security,
|
||||
kflags, &kflags_out);
|
||||
}
|
||||
if (error)
|
||||
goto error_splat_root;
|
||||
if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL &&
|
||||
if (server->caps & NFS_CAP_SECURITY_LABEL &&
|
||||
!(kflags_out & SECURITY_LSM_NATIVE_LABELS))
|
||||
NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL;
|
||||
server->caps &= ~NFS_CAP_SECURITY_LABEL;
|
||||
|
||||
nfs_setsecurity(inode, fsinfo.fattr, fsinfo.fattr->label);
|
||||
error = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue