aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c39
1 files changed, 35 insertions, 4 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 7171a957b933..feb2f42c5a07 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -751,7 +751,37 @@ out_double_mount:
751 goto out; 751 goto out;
752} 752}
753 753
754static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb, 754static int selinux_cmp_sb_context(const struct super_block *oldsb,
755 const struct super_block *newsb)
756{
757 struct superblock_security_struct *old = oldsb->s_security;
758 struct superblock_security_struct *new = newsb->s_security;
759 char oldflags = old->flags & SE_MNTMASK;
760 char newflags = new->flags & SE_MNTMASK;
761
762 if (oldflags != newflags)
763 goto mismatch;
764 if ((oldflags & FSCONTEXT_MNT) && old->sid != new->sid)
765 goto mismatch;
766 if ((oldflags & CONTEXT_MNT) && old->mntpoint_sid != new->mntpoint_sid)
767 goto mismatch;
768 if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid)
769 goto mismatch;
770 if (oldflags & ROOTCONTEXT_MNT) {
771 struct inode_security_struct *oldroot = oldsb->s_root->d_inode->i_security;
772 struct inode_security_struct *newroot = newsb->s_root->d_inode->i_security;
773 if (oldroot->sid != newroot->sid)
774 goto mismatch;
775 }
776 return 0;
777mismatch:
778 printk(KERN_WARNING "SELinux: mount invalid. Same superblock, "
779 "different security settings for (dev %s, "
780 "type %s)\n", newsb->s_id, newsb->s_type->name);
781 return -EBUSY;
782}
783
784static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
755 struct super_block *newsb) 785 struct super_block *newsb)
756{ 786{
757 const struct superblock_security_struct *oldsbsec = oldsb->s_security; 787 const struct superblock_security_struct *oldsbsec = oldsb->s_security;
@@ -766,14 +796,14 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
766 * mount options. thus we can safely deal with this superblock later 796 * mount options. thus we can safely deal with this superblock later
767 */ 797 */
768 if (!ss_initialized) 798 if (!ss_initialized)
769 return; 799 return 0;
770 800
771 /* how can we clone if the old one wasn't set up?? */ 801 /* how can we clone if the old one wasn't set up?? */
772 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED)); 802 BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
773 803
774 /* if fs is reusing a sb, just let its options stand... */ 804 /* if fs is reusing a sb, make sure that the contexts match */
775 if (newsbsec->flags & SE_SBINITIALIZED) 805 if (newsbsec->flags & SE_SBINITIALIZED)
776 return; 806 return selinux_cmp_sb_context(oldsb, newsb);
777 807
778 mutex_lock(&newsbsec->lock); 808 mutex_lock(&newsbsec->lock);
779 809
@@ -806,6 +836,7 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
806 836
807 sb_finish_set_opts(newsb); 837 sb_finish_set_opts(newsb);
808 mutex_unlock(&newsbsec->lock); 838 mutex_unlock(&newsbsec->lock);
839 return 0;
809} 840}
810 841
811static int selinux_parse_opts_str(char *options, 842static int selinux_parse_opts_str(char *options,