struct nfs_mount_info *mount_info)
 {
        /* clone any lsm security options from the parent to the new sb */
-       security_sb_clone_mnt_opts(mount_info->cloned->sb, s);
        if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops)
                return -ESTALE;
-       return 0;
+       return security_sb_clone_mnt_opts(mount_info->cloned->sb, s);
 }
 EXPORT_SYMBOL_GPL(nfs_clone_sb_security);
 
 
                             struct path *new_path);
        int (*sb_set_mnt_opts) (struct super_block *sb,
                                struct security_mnt_opts *opts);
-       void (*sb_clone_mnt_opts) (const struct super_block *oldsb,
+       int (*sb_clone_mnt_opts) (const struct super_block *oldsb,
                                   struct super_block *newsb);
        int (*sb_parse_opts_str) (char *options, struct security_mnt_opts *opts);
 
 int security_sb_umount(struct vfsmount *mnt, int flags);
 int security_sb_pivotroot(struct path *old_path, struct path *new_path);
 int security_sb_set_mnt_opts(struct super_block *sb, struct security_mnt_opts *opts);
-void security_sb_clone_mnt_opts(const struct super_block *oldsb,
+int security_sb_clone_mnt_opts(const struct super_block *oldsb,
                                struct super_block *newsb);
 int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts);
 
        return 0;
 }
 
-static inline void security_sb_clone_mnt_opts(const struct super_block *oldsb,
+static inline int security_sb_clone_mnt_opts(const struct super_block *oldsb,
                                              struct super_block *newsb)
-{ }
+{
+       return 0;
+}
 
 static inline int security_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
 {
 
        return 0;
 }
 
-static void cap_sb_clone_mnt_opts(const struct super_block *oldsb,
+static int cap_sb_clone_mnt_opts(const struct super_block *oldsb,
                                  struct super_block *newsb)
 {
+       return 0;
 }
 
 static int cap_sb_parse_opts_str(char *options, struct security_mnt_opts *opts)
 
 }
 EXPORT_SYMBOL(security_sb_set_mnt_opts);
 
-void security_sb_clone_mnt_opts(const struct super_block *oldsb,
+int security_sb_clone_mnt_opts(const struct super_block *oldsb,
                                struct super_block *newsb)
 {
-       security_ops->sb_clone_mnt_opts(oldsb, newsb);
+       return security_ops->sb_clone_mnt_opts(oldsb, newsb);
 }
 EXPORT_SYMBOL(security_sb_clone_mnt_opts);
 
 
        goto out;
 }
 
-static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
+static int selinux_cmp_sb_context(const struct super_block *oldsb,
+                                   const struct super_block *newsb)
+{
+       struct superblock_security_struct *old = oldsb->s_security;
+       struct superblock_security_struct *new = newsb->s_security;
+       char oldflags = old->flags & SE_MNTMASK;
+       char newflags = new->flags & SE_MNTMASK;
+
+       if (oldflags != newflags)
+               goto mismatch;
+       if ((oldflags & FSCONTEXT_MNT) && old->sid != new->sid)
+               goto mismatch;
+       if ((oldflags & CONTEXT_MNT) && old->mntpoint_sid != new->mntpoint_sid)
+               goto mismatch;
+       if ((oldflags & DEFCONTEXT_MNT) && old->def_sid != new->def_sid)
+               goto mismatch;
+       if (oldflags & ROOTCONTEXT_MNT) {
+               struct inode_security_struct *oldroot = oldsb->s_root->d_inode->i_security;
+               struct inode_security_struct *newroot = newsb->s_root->d_inode->i_security;
+               if (oldroot->sid != newroot->sid)
+                       goto mismatch;
+       }
+       return 0;
+mismatch:
+       printk(KERN_WARNING "SELinux: mount invalid.  Same superblock, "
+                           "different security settings for (dev %s, "
+                           "type %s)\n", newsb->s_id, newsb->s_type->name);
+       return -EBUSY;
+}
+
+static int selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
                                        struct super_block *newsb)
 {
        const struct superblock_security_struct *oldsbsec = oldsb->s_security;
         * mount options.  thus we can safely deal with this superblock later
         */
        if (!ss_initialized)
-               return;
+               return 0;
 
        /* how can we clone if the old one wasn't set up?? */
        BUG_ON(!(oldsbsec->flags & SE_SBINITIALIZED));
 
-       /* if fs is reusing a sb, just let its options stand... */
+       /* if fs is reusing a sb, make sure that the contexts match */
        if (newsbsec->flags & SE_SBINITIALIZED)
-               return;
+               return selinux_cmp_sb_context(oldsb, newsb);
 
        mutex_lock(&newsbsec->lock);
 
 
        sb_finish_set_opts(newsb);
        mutex_unlock(&newsbsec->lock);
+       return 0;
 }
 
 static int selinux_parse_opts_str(char *options,