Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 29b1deb2 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Revert "selinux: consider filesystem subtype in policies"

This reverts commit 102aefdd.

Tom London reports that it causes sync() to hang on Fedora rawhide:

  https://bugzilla.redhat.com/show_bug.cgi?id=1033965



and Josh Boyer bisected it down to this commit.  Reverting the commit in
the rawhide kernel fixes the problem.

Eric Paris root-caused it to incorrect subtype matching in that commit
breaking fuse, and has a tentative patch, but by now we're better off
retrying this in 3.14 rather than playing with it any more.

Reported-by: default avatarTom London <selinux@gmail.com>
Bisected-by: default avatarJosh Boyer <jwboyer@fedoraproject.org>
Acked-by: default avatarEric Paris <eparis@redhat.com>
Cc: James Morris <jmorris@namei.org>
Cc: Anand Avati <avati@redhat.com>
Cc: Paul Moore <paul@paul-moore.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 0925f2cd
Loading
Loading
Loading
Loading
+18 −22
Original line number Diff line number Diff line
@@ -95,10 +95,6 @@
#include "audit.h"
#include "avc_ss.h"

#define SB_TYPE_FMT "%s%s%s"
#define SB_SUBTYPE(sb) (sb->s_subtype && sb->s_subtype[0])
#define SB_TYPE_ARGS(sb) sb->s_type->name, SB_SUBTYPE(sb) ? "." : "", SB_SUBTYPE(sb) ? sb->s_subtype : ""

extern struct security_operations *security_ops;

/* SECMARK reference count */
@@ -413,8 +409,8 @@ static int sb_finish_set_opts(struct super_block *sb)
		   the first boot of the SELinux kernel before we have
		   assigned xattr values to the filesystem. */
		if (!root_inode->i_op->getxattr) {
			printk(KERN_WARNING "SELinux: (dev %s, type "SB_TYPE_FMT") has no "
			       "xattr support\n", sb->s_id, SB_TYPE_ARGS(sb));
			printk(KERN_WARNING "SELinux: (dev %s, type %s) has no "
			       "xattr support\n", sb->s_id, sb->s_type->name);
			rc = -EOPNOTSUPP;
			goto out;
		}
@@ -422,22 +418,22 @@ static int sb_finish_set_opts(struct super_block *sb)
		if (rc < 0 && rc != -ENODATA) {
			if (rc == -EOPNOTSUPP)
				printk(KERN_WARNING "SELinux: (dev %s, type "
				       SB_TYPE_FMT") has no security xattr handler\n",
				       sb->s_id, SB_TYPE_ARGS(sb));
				       "%s) has no security xattr handler\n",
				       sb->s_id, sb->s_type->name);
			else
				printk(KERN_WARNING "SELinux: (dev %s, type "
				       SB_TYPE_FMT") getxattr errno %d\n", sb->s_id,
				       SB_TYPE_ARGS(sb), -rc);
				       "%s) getxattr errno %d\n", sb->s_id,
				       sb->s_type->name, -rc);
			goto out;
		}
	}

	if (sbsec->behavior > ARRAY_SIZE(labeling_behaviors))
		printk(KERN_ERR "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), unknown behavior\n",
		       sb->s_id, SB_TYPE_ARGS(sb));
		printk(KERN_ERR "SELinux: initialized (dev %s, type %s), unknown behavior\n",
		       sb->s_id, sb->s_type->name);
	else
		printk(KERN_DEBUG "SELinux: initialized (dev %s, type "SB_TYPE_FMT"), %s\n",
		       sb->s_id, SB_TYPE_ARGS(sb),
		printk(KERN_DEBUG "SELinux: initialized (dev %s, type %s), %s\n",
		       sb->s_id, sb->s_type->name,
		       labeling_behaviors[sbsec->behavior-1]);

	sbsec->flags |= SE_SBINITIALIZED;
@@ -600,6 +596,7 @@ static int selinux_set_mnt_opts(struct super_block *sb,
	const struct cred *cred = current_cred();
	int rc = 0, i;
	struct superblock_security_struct *sbsec = sb->s_security;
	const char *name = sb->s_type->name;
	struct inode *inode = sbsec->sb->s_root->d_inode;
	struct inode_security_struct *root_isec = inode->i_security;
	u32 fscontext_sid = 0, context_sid = 0, rootcontext_sid = 0;
@@ -658,8 +655,8 @@ static int selinux_set_mnt_opts(struct super_block *sb,
					     strlen(mount_options[i]), &sid);
		if (rc) {
			printk(KERN_WARNING "SELinux: security_context_to_sid"
			       "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
			       mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
			       "(%s) failed for (dev %s, type %s) errno=%d\n",
			       mount_options[i], sb->s_id, name, rc);
			goto out;
		}
		switch (flags[i]) {
@@ -806,8 +803,7 @@ out:
out_double_mount:
	rc = -EINVAL;
	printk(KERN_WARNING "SELinux: mount invalid.  Same superblock, different "
	       "security settings for (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
	       SB_TYPE_ARGS(sb));
	       "security settings for (dev %s, type %s)\n", sb->s_id, name);
	goto out;
}

@@ -2480,8 +2476,8 @@ static int selinux_sb_remount(struct super_block *sb, void *data)
		rc = security_context_to_sid(mount_options[i], len, &sid);
		if (rc) {
			printk(KERN_WARNING "SELinux: security_context_to_sid"
			       "(%s) failed for (dev %s, type "SB_TYPE_FMT") errno=%d\n",
			       mount_options[i], sb->s_id, SB_TYPE_ARGS(sb), rc);
			       "(%s) failed for (dev %s, type %s) errno=%d\n",
			       mount_options[i], sb->s_id, sb->s_type->name, rc);
			goto out_free_opts;
		}
		rc = -EINVAL;
@@ -2519,8 +2515,8 @@ out_free_secdata:
	return rc;
out_bad_option:
	printk(KERN_WARNING "SELinux: unable to change security options "
	       "during remount (dev %s, type "SB_TYPE_FMT")\n", sb->s_id,
	       SB_TYPE_ARGS(sb));
	       "during remount (dev %s, type=%s)\n", sb->s_id,
	       sb->s_type->name);
	goto out_free_opts;
}

+4 −38
Original line number Diff line number Diff line
@@ -2334,50 +2334,16 @@ int security_fs_use(struct super_block *sb)
	struct ocontext *c;
	struct superblock_security_struct *sbsec = sb->s_security;
	const char *fstype = sb->s_type->name;
	const char *subtype = (sb->s_subtype && sb->s_subtype[0]) ? sb->s_subtype : NULL;
	struct ocontext *base = NULL;

	read_lock(&policy_rwlock);

	for (c = policydb.ocontexts[OCON_FSUSE]; c; c = c->next) {
		char *sub;
		int baselen;

		baselen = strlen(fstype);

		/* if base does not match, this is not the one */
		if (strncmp(fstype, c->u.name, baselen))
			continue;

		/* if there is no subtype, this is the one! */
		if (!subtype)
			break;

		/* skip past the base in this entry */
		sub = c->u.name + baselen;

		/* entry is only a base. save it. keep looking for subtype */
		if (sub[0] == '\0') {
			base = c;
			continue;
		}

		/* entry is not followed by a subtype, so it is not a match */
		if (sub[0] != '.')
			continue;

		/* whew, we found a subtype of this fstype */
		sub++; /* move past '.' */

		/* exact match of fstype AND subtype */
		if (!strcmp(subtype, sub))
	c = policydb.ocontexts[OCON_FSUSE];
	while (c) {
		if (strcmp(fstype, c->u.name) == 0)
			break;
		c = c->next;
	}

	/* in case we had found an fstype match but no subtype match */
	if (!c)
		c = base;

	if (c) {
		sbsec->behavior = c->v.behavior;
		if (!c->sid[0]) {