diff options
author | Scott Mayhew <smayhew@redhat.com> | 2017-06-05 11:45:04 -0400 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2017-06-09 16:17:47 -0400 |
commit | 0b4d3452b8b4a5309b4445b900e3cec022cca95a (patch) | |
tree | 3c758827bc8bab1cd36f9c551840cdae00636e97 /fs/nfs/super.c | |
parent | b4958c892e02241b9bd121f3397b76225ff6f4a3 (diff) |
security/selinux: allow security_sb_clone_mnt_opts to enable/disable native labeling behavior
When an NFSv4 client performs a mount operation, it first mounts the
NFSv4 root and then does path walk to the exported path and performs a
submount on that, cloning the security mount options from the root's
superblock to the submount's superblock in the process.
Unless the NFS server has an explicit fsid=0 export with the
"security_label" option, the NFSv4 root superblock will not have
SBLABEL_MNT set, and neither will the submount superblock after cloning
the security mount options. As a result, setxattr's of security labels
over NFSv4.2 will fail. In a similar fashion, NFSv4.2 mounts mounted
with the context= mount option will not show the correct labels because
the nfs_server->caps flags of the cloned superblock will still have
NFS_CAP_SECURITY_LABEL set.
Allowing the NFSv4 client to enable or disable SECURITY_LSM_NATIVE_LABELS
behavior will ensure that the SBLABEL_MNT flag has the correct value
when the client traverses from an exported path without the
"security_label" option to one with the "security_label" option and
vice versa. Similarly, checking to see if SECURITY_LSM_NATIVE_LABELS is
set upon return from security_sb_clone_mnt_opts() and clearing
NFS_CAP_SECURITY_LABEL if necessary will allow the correct labels to
be displayed for NFSv4.2 mounts mounted with the context= mount option.
Resolves: https://github.com/SELinuxProject/selinux-kernel/issues/35
Signed-off-by: Scott Mayhew <smayhew@redhat.com>
Reviewed-by: Stephen Smalley <sds@tycho.nsa.gov>
Tested-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'fs/nfs/super.c')
-rw-r--r-- | fs/nfs/super.c | 17 |
1 files changed, 16 insertions, 1 deletions
diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 2f3822a4a7d5..b8e073546507 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c | |||
@@ -2544,10 +2544,25 @@ EXPORT_SYMBOL_GPL(nfs_set_sb_security); | |||
2544 | int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, | 2544 | int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, |
2545 | struct nfs_mount_info *mount_info) | 2545 | struct nfs_mount_info *mount_info) |
2546 | { | 2546 | { |
2547 | int error; | ||
2548 | unsigned long kflags = 0, kflags_out = 0; | ||
2549 | |||
2547 | /* clone any lsm security options from the parent to the new sb */ | 2550 | /* clone any lsm security options from the parent to the new sb */ |
2548 | if (d_inode(mntroot)->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) | 2551 | if (d_inode(mntroot)->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops) |
2549 | return -ESTALE; | 2552 | return -ESTALE; |
2550 | return security_sb_clone_mnt_opts(mount_info->cloned->sb, s); | 2553 | |
2554 | if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL) | ||
2555 | kflags |= SECURITY_LSM_NATIVE_LABELS; | ||
2556 | |||
2557 | error = security_sb_clone_mnt_opts(mount_info->cloned->sb, s, kflags, | ||
2558 | &kflags_out); | ||
2559 | if (error) | ||
2560 | return error; | ||
2561 | |||
2562 | if (NFS_SB(s)->caps & NFS_CAP_SECURITY_LABEL && | ||
2563 | !(kflags_out & SECURITY_LSM_NATIVE_LABELS)) | ||
2564 | NFS_SB(s)->caps &= ~NFS_CAP_SECURITY_LABEL; | ||
2565 | return 0; | ||
2551 | } | 2566 | } |
2552 | EXPORT_SYMBOL_GPL(nfs_clone_sb_security); | 2567 | EXPORT_SYMBOL_GPL(nfs_clone_sb_security); |
2553 | 2568 | ||