summaryrefslogtreecommitdiffstats
path: root/fs/nfs/super.c
diff options
context:
space:
mode:
authorScott Mayhew <smayhew@redhat.com>2017-06-05 11:45:04 -0400
committerPaul Moore <paul@paul-moore.com>2017-06-09 16:17:47 -0400
commit0b4d3452b8b4a5309b4445b900e3cec022cca95a (patch)
tree3c758827bc8bab1cd36f9c551840cdae00636e97 /fs/nfs/super.c
parentb4958c892e02241b9bd121f3397b76225ff6f4a3 (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.c17
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);
2544int nfs_clone_sb_security(struct super_block *s, struct dentry *mntroot, 2544int 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}
2552EXPORT_SYMBOL_GPL(nfs_clone_sb_security); 2567EXPORT_SYMBOL_GPL(nfs_clone_sb_security);
2553 2568