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

Commit d5e4d81d authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull SELinux updates from Paul Moore:
 "Three SELinux patches for v4.20, all fall under the bug-fix or
  behave-better category, which is good. All three have pretty good
  descriptions too, which is even better"

* tag 'selinux-pr-20181022' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: Add __GFP_NOWARN to allocation at str_read()
  selinux: refactor mls_context_to_sid() and make it stricter
  selinux: fix mounting of cgroup2 under older policies
parents ba9f6f89 4458bba0
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -1508,6 +1508,11 @@ static int selinux_genfs_get_sid(struct dentry *dentry,
		}
		rc = security_genfs_sid(&selinux_state, sb->s_type->name,
					path, tclass, sid);
		if (rc == -ENOENT) {
			/* No match in policy, mark as unlabeled. */
			*sid = SECINITSID_UNLABELED;
			rc = 0;
		}
	}
	free_page((unsigned long)buffer);
	return rc;
+77 −101
Original line number Diff line number Diff line
@@ -218,9 +218,7 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
/*
 * Set the MLS fields in the security context structure
 * `context' based on the string representation in
 * the string `*scontext'.  Update `*scontext' to
 * point to the end of the string representation of
 * the MLS fields.
 * the string `scontext'.
 *
 * This function modifies the string in place, inserting
 * NULL characters to terminate the MLS fields.
@@ -235,22 +233,21 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
 */
int mls_context_to_sid(struct policydb *pol,
		       char oldc,
		       char **scontext,
		       char *scontext,
		       struct context *context,
		       struct sidtab *s,
		       u32 def_sid)
{

	char delim;
	char *scontextp, *p, *rngptr;
	char *sensitivity, *cur_cat, *next_cat, *rngptr;
	struct level_datum *levdatum;
	struct cat_datum *catdatum, *rngdatum;
	int l, rc = -EINVAL;
	int l, rc, i;
	char *rangep[2];

	if (!pol->mls_enabled) {
		if (def_sid != SECSID_NULL && oldc)
			*scontext += strlen(*scontext) + 1;
		if ((def_sid != SECSID_NULL && oldc) || (*scontext) == '\0')
			return 0;
		return -EINVAL;
	}

	/*
@@ -261,115 +258,96 @@ int mls_context_to_sid(struct policydb *pol,
		struct context *defcon;

		if (def_sid == SECSID_NULL)
			goto out;
			return -EINVAL;

		defcon = sidtab_search(s, def_sid);
		if (!defcon)
			goto out;
			return -EINVAL;

		rc = mls_context_cpy(context, defcon);
		goto out;
		return mls_context_cpy(context, defcon);
	}

	/* Extract low sensitivity. */
	scontextp = p = *scontext;
	while (*p && *p != ':' && *p != '-')
		p++;

	delim = *p;
	if (delim != '\0')
		*p++ = '\0';
	/*
	 * If we're dealing with a range, figure out where the two parts
	 * of the range begin.
	 */
	rangep[0] = scontext;
	rangep[1] = strchr(scontext, '-');
	if (rangep[1]) {
		rangep[1][0] = '\0';
		rangep[1]++;
	}

	/* For each part of the range: */
	for (l = 0; l < 2; l++) {
		levdatum = hashtab_search(pol->p_levels.table, scontextp);
		if (!levdatum) {
			rc = -EINVAL;
			goto out;
		}
		/* Split sensitivity and category set. */
		sensitivity = rangep[l];
		if (sensitivity == NULL)
			break;
		next_cat = strchr(sensitivity, ':');
		if (next_cat)
			*(next_cat++) = '\0';

		/* Parse sensitivity. */
		levdatum = hashtab_search(pol->p_levels.table, sensitivity);
		if (!levdatum)
			return -EINVAL;
		context->range.level[l].sens = levdatum->level->sens;

		if (delim == ':') {
		/* Extract category set. */
			while (1) {
				scontextp = p;
				while (*p && *p != ',' && *p != '-')
					p++;
				delim = *p;
				if (delim != '\0')
					*p++ = '\0';
		while (next_cat != NULL) {
			cur_cat = next_cat;
			next_cat = strchr(next_cat, ',');
			if (next_cat != NULL)
				*(next_cat++) = '\0';

			/* Separate into range if exists */
				rngptr = strchr(scontextp, '.');
			rngptr = strchr(cur_cat, '.');
			if (rngptr != NULL) {
				/* Remove '.' */
				*rngptr++ = '\0';
			}

				catdatum = hashtab_search(pol->p_cats.table,
							  scontextp);
				if (!catdatum) {
					rc = -EINVAL;
					goto out;
				}
			catdatum = hashtab_search(pol->p_cats.table, cur_cat);
			if (!catdatum)
				return -EINVAL;

			rc = ebitmap_set_bit(&context->range.level[l].cat,
					     catdatum->value - 1, 1);
			if (rc)
					goto out;
				return rc;

			/* If range, set all categories in range */
				if (rngptr) {
					int i;
			if (rngptr == NULL)
				continue;

			rngdatum = hashtab_search(pol->p_cats.table, rngptr);
					if (!rngdatum) {
						rc = -EINVAL;
						goto out;
					}
			if (!rngdatum)
				return -EINVAL;

					if (catdatum->value >= rngdatum->value) {
						rc = -EINVAL;
						goto out;
					}
			if (catdatum->value >= rngdatum->value)
				return -EINVAL;

			for (i = catdatum->value; i < rngdatum->value; i++) {
				rc = ebitmap_set_bit(&context->range.level[l].cat, i, 1);
				if (rc)
							goto out;
					}
				}

				if (delim != ',')
					break;
					return rc;
			}
		}
		if (delim == '-') {
			/* Extract high sensitivity. */
			scontextp = p;
			while (*p && *p != ':')
				p++;

			delim = *p;
			if (delim != '\0')
				*p++ = '\0';
		} else
			break;
	}

	if (l == 0) {
	/* If we didn't see a '-', the range start is also the range end. */
	if (rangep[1] == NULL) {
		context->range.level[1].sens = context->range.level[0].sens;
		rc = ebitmap_cpy(&context->range.level[1].cat,
				 &context->range.level[0].cat);
		if (rc)
			goto out;
	}
	*scontext = ++p;
	rc = 0;
out:
			return rc;
	}

	return 0;
}

/*
 * Set the MLS fields in the security context structure
 * `context' based on the string representation in
@@ -379,21 +357,19 @@ int mls_context_to_sid(struct policydb *pol,
int mls_from_string(struct policydb *p, char *str, struct context *context,
		    gfp_t gfp_mask)
{
	char *tmpstr, *freestr;
	char *tmpstr;
	int rc;

	if (!p->mls_enabled)
		return -EINVAL;

	/* we need freestr because mls_context_to_sid will change
	   the value of tmpstr */
	tmpstr = freestr = kstrdup(str, gfp_mask);
	tmpstr = kstrdup(str, gfp_mask);
	if (!tmpstr) {
		rc = -ENOMEM;
	} else {
		rc = mls_context_to_sid(p, ':', &tmpstr, context,
		rc = mls_context_to_sid(p, ':', tmpstr, context,
					NULL, SECSID_NULL);
		kfree(freestr);
		kfree(tmpstr);
	}

	return rc;
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l);

int mls_context_to_sid(struct policydb *p,
		       char oldc,
		       char **scontext,
		       char *scontext,
		       struct context *context,
		       struct sidtab *s,
		       u32 def_sid);
+1 −1
Original line number Diff line number Diff line
@@ -1101,7 +1101,7 @@ static int str_read(char **strp, gfp_t flags, void *fp, u32 len)
	if ((len == 0) || (len == (u32)-1))
		return -EINVAL;

	str = kmalloc(len + 1, flags);
	str = kmalloc(len + 1, flags | __GFP_NOWARN);
	if (!str)
		return -ENOMEM;

+4 −8
Original line number Diff line number Diff line
@@ -1365,7 +1365,6 @@ int security_sid_to_context_force(struct selinux_state *state, u32 sid,
static int string_to_context_struct(struct policydb *pol,
				    struct sidtab *sidtabp,
				    char *scontext,
				    u32 scontext_len,
				    struct context *ctx,
				    u32 def_sid)
{
@@ -1426,15 +1425,12 @@ static int string_to_context_struct(struct policydb *pol,

	ctx->type = typdatum->value;

	rc = mls_context_to_sid(pol, oldc, &p, ctx, sidtabp, def_sid);
	rc = mls_context_to_sid(pol, oldc, p, ctx, sidtabp, def_sid);
	if (rc)
		goto out;

	rc = -EINVAL;
	if ((p - scontext) < scontext_len)
		goto out;

	/* Check the validity of the new context. */
	rc = -EINVAL;
	if (!policydb_context_isvalid(pol, ctx))
		goto out;
	rc = 0;
@@ -1489,7 +1485,7 @@ static int security_context_to_sid_core(struct selinux_state *state,
	policydb = &state->ss->policydb;
	sidtab = &state->ss->sidtab;
	rc = string_to_context_struct(policydb, sidtab, scontext2,
				      scontext_len, &context, def_sid);
				      &context, def_sid);
	if (rc == -EINVAL && force) {
		context.str = str;
		context.len = strlen(str) + 1;
@@ -1958,7 +1954,7 @@ static int convert_context(u32 key,
			goto out;

		rc = string_to_context_struct(args->newp, NULL, s,
					      c->len, &ctx, SECSID_NULL);
					      &ctx, SECSID_NULL);
		kfree(s);
		if (!rc) {
			pr_info("SELinux:  Context %s became valid (mapped).\n",