Commit d5e4d81d authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'selinux-pr-20181022' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

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
...@@ -1508,6 +1508,11 @@ static int selinux_genfs_get_sid(struct dentry *dentry, ...@@ -1508,6 +1508,11 @@ static int selinux_genfs_get_sid(struct dentry *dentry,
} }
rc = security_genfs_sid(&selinux_state, sb->s_type->name, rc = security_genfs_sid(&selinux_state, sb->s_type->name,
path, tclass, sid); path, tclass, sid);
if (rc == -ENOENT) {
/* No match in policy, mark as unlabeled. */
*sid = SECINITSID_UNLABELED;
rc = 0;
}
} }
free_page((unsigned long)buffer); free_page((unsigned long)buffer);
return rc; return rc;
......
...@@ -218,9 +218,7 @@ int mls_context_isvalid(struct policydb *p, struct context *c) ...@@ -218,9 +218,7 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
/* /*
* Set the MLS fields in the security context structure * Set the MLS fields in the security context structure
* `context' based on the string representation in * `context' based on the string representation in
* the string `*scontext'. Update `*scontext' to * the string `scontext'.
* point to the end of the string representation of
* the MLS fields.
* *
* This function modifies the string in place, inserting * This function modifies the string in place, inserting
* NULL characters to terminate the MLS fields. * NULL characters to terminate the MLS fields.
...@@ -235,22 +233,21 @@ int mls_context_isvalid(struct policydb *p, struct context *c) ...@@ -235,22 +233,21 @@ int mls_context_isvalid(struct policydb *p, struct context *c)
*/ */
int mls_context_to_sid(struct policydb *pol, int mls_context_to_sid(struct policydb *pol,
char oldc, char oldc,
char **scontext, char *scontext,
struct context *context, struct context *context,
struct sidtab *s, struct sidtab *s,
u32 def_sid) u32 def_sid)
{ {
char *sensitivity, *cur_cat, *next_cat, *rngptr;
char delim;
char *scontextp, *p, *rngptr;
struct level_datum *levdatum; struct level_datum *levdatum;
struct cat_datum *catdatum, *rngdatum; struct cat_datum *catdatum, *rngdatum;
int l, rc = -EINVAL; int l, rc, i;
char *rangep[2];
if (!pol->mls_enabled) { if (!pol->mls_enabled) {
if (def_sid != SECSID_NULL && oldc) if ((def_sid != SECSID_NULL && oldc) || (*scontext) == '\0')
*scontext += strlen(*scontext) + 1; return 0;
return 0; return -EINVAL;
} }
/* /*
...@@ -261,113 +258,94 @@ int mls_context_to_sid(struct policydb *pol, ...@@ -261,113 +258,94 @@ int mls_context_to_sid(struct policydb *pol,
struct context *defcon; struct context *defcon;
if (def_sid == SECSID_NULL) if (def_sid == SECSID_NULL)
goto out; return -EINVAL;
defcon = sidtab_search(s, def_sid); defcon = sidtab_search(s, def_sid);
if (!defcon) if (!defcon)
goto out; return -EINVAL;
rc = mls_context_cpy(context, defcon); return mls_context_cpy(context, defcon);
goto out;
} }
/* Extract low sensitivity. */ /*
scontextp = p = *scontext; * If we're dealing with a range, figure out where the two parts
while (*p && *p != ':' && *p != '-') * of the range begin.
p++; */
rangep[0] = scontext;
delim = *p; rangep[1] = strchr(scontext, '-');
if (delim != '\0') if (rangep[1]) {
*p++ = '\0'; rangep[1][0] = '\0';
rangep[1]++;
}
/* For each part of the range: */
for (l = 0; l < 2; l++) { for (l = 0; l < 2; l++) {
levdatum = hashtab_search(pol->p_levels.table, scontextp); /* Split sensitivity and category set. */
if (!levdatum) { sensitivity = rangep[l];
rc = -EINVAL; if (sensitivity == NULL)
goto out; 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; context->range.level[l].sens = levdatum->level->sens;
if (delim == ':') { /* Extract category set. */
/* Extract category set. */ while (next_cat != NULL) {
while (1) { cur_cat = next_cat;
scontextp = p; next_cat = strchr(next_cat, ',');
while (*p && *p != ',' && *p != '-') if (next_cat != NULL)
p++; *(next_cat++) = '\0';
delim = *p;
if (delim != '\0') /* Separate into range if exists */
*p++ = '\0'; rngptr = strchr(cur_cat, '.');
if (rngptr != NULL) {
/* Separate into range if exists */ /* Remove '.' */
rngptr = strchr(scontextp, '.'); *rngptr++ = '\0';
if (rngptr != NULL) { }
/* Remove '.' */
*rngptr++ = '\0';
}
catdatum = hashtab_search(pol->p_cats.table, catdatum = hashtab_search(pol->p_cats.table, cur_cat);
scontextp); if (!catdatum)
if (!catdatum) { return -EINVAL;
rc = -EINVAL;
goto out;
}
rc = ebitmap_set_bit(&context->range.level[l].cat, rc = ebitmap_set_bit(&context->range.level[l].cat,
catdatum->value - 1, 1); catdatum->value - 1, 1);
if (rc) if (rc)
goto out; return rc;
/* If range, set all categories in range */ /* If range, set all categories in range */
if (rngptr) { if (rngptr == NULL)
int i; continue;
rngdatum = hashtab_search(pol->p_cats.table, rngptr); rngdatum = hashtab_search(pol->p_cats.table, rngptr);
if (!rngdatum) { if (!rngdatum)
rc = -EINVAL; return -EINVAL;
goto out;
} if (catdatum->value >= rngdatum->value)
return -EINVAL;
if (catdatum->value >= rngdatum->value) {
rc = -EINVAL;
goto out;
}
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 != ',') for (i = catdatum->value; i < rngdatum->value; i++) {
break; rc = ebitmap_set_bit(&context->range.level[l].cat, i, 1);
if (rc)
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; context->range.level[1].sens = context->range.level[0].sens;
rc = ebitmap_cpy(&context->range.level[1].cat, rc = ebitmap_cpy(&context->range.level[1].cat,
&context->range.level[0].cat); &context->range.level[0].cat);
if (rc) if (rc)
goto out; return rc;
} }
*scontext = ++p;
rc = 0; return 0;
out:
return rc;
} }
/* /*
...@@ -379,21 +357,19 @@ int mls_context_to_sid(struct policydb *pol, ...@@ -379,21 +357,19 @@ int mls_context_to_sid(struct policydb *pol,
int mls_from_string(struct policydb *p, char *str, struct context *context, int mls_from_string(struct policydb *p, char *str, struct context *context,
gfp_t gfp_mask) gfp_t gfp_mask)
{ {
char *tmpstr, *freestr; char *tmpstr;
int rc; int rc;
if (!p->mls_enabled) if (!p->mls_enabled)
return -EINVAL; return -EINVAL;
/* we need freestr because mls_context_to_sid will change tmpstr = kstrdup(str, gfp_mask);
the value of tmpstr */
tmpstr = freestr = kstrdup(str, gfp_mask);
if (!tmpstr) { if (!tmpstr) {
rc = -ENOMEM; rc = -ENOMEM;
} else { } else {
rc = mls_context_to_sid(p, ':', &tmpstr, context, rc = mls_context_to_sid(p, ':', tmpstr, context,
NULL, SECSID_NULL); NULL, SECSID_NULL);
kfree(freestr); kfree(tmpstr);
} }
return rc; return rc;
......
...@@ -34,7 +34,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l); ...@@ -34,7 +34,7 @@ int mls_level_isvalid(struct policydb *p, struct mls_level *l);
int mls_context_to_sid(struct policydb *p, int mls_context_to_sid(struct policydb *p,
char oldc, char oldc,
char **scontext, char *scontext,
struct context *context, struct context *context,
struct sidtab *s, struct sidtab *s,
u32 def_sid); u32 def_sid);
......
...@@ -1101,7 +1101,7 @@ static int str_read(char **strp, gfp_t flags, void *fp, u32 len) ...@@ -1101,7 +1101,7 @@ static int str_read(char **strp, gfp_t flags, void *fp, u32 len)
if ((len == 0) || (len == (u32)-1)) if ((len == 0) || (len == (u32)-1))
return -EINVAL; return -EINVAL;
str = kmalloc(len + 1, flags); str = kmalloc(len + 1, flags | __GFP_NOWARN);
if (!str) if (!str)
return -ENOMEM; return -ENOMEM;
......
...@@ -1365,7 +1365,6 @@ int security_sid_to_context_force(struct selinux_state *state, u32 sid, ...@@ -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, static int string_to_context_struct(struct policydb *pol,
struct sidtab *sidtabp, struct sidtab *sidtabp,
char *scontext, char *scontext,
u32 scontext_len,
struct context *ctx, struct context *ctx,
u32 def_sid) u32 def_sid)
{ {
...@@ -1426,15 +1425,12 @@ static int string_to_context_struct(struct policydb *pol, ...@@ -1426,15 +1425,12 @@ static int string_to_context_struct(struct policydb *pol,
ctx->type = typdatum->value; 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) if (rc)
goto out; goto out;
rc = -EINVAL;
if ((p - scontext) < scontext_len)
goto out;
/* Check the validity of the new context. */ /* Check the validity of the new context. */
rc = -EINVAL;
if (!policydb_context_isvalid(pol, ctx)) if (!policydb_context_isvalid(pol, ctx))
goto out; goto out;
rc = 0; rc = 0;
...@@ -1489,7 +1485,7 @@ static int security_context_to_sid_core(struct selinux_state *state, ...@@ -1489,7 +1485,7 @@ static int security_context_to_sid_core(struct selinux_state *state,
policydb = &state->ss->policydb; policydb = &state->ss->policydb;
sidtab = &state->ss->sidtab; sidtab = &state->ss->sidtab;
rc = string_to_context_struct(policydb, sidtab, scontext2, rc = string_to_context_struct(policydb, sidtab, scontext2,
scontext_len, &context, def_sid); &context, def_sid);
if (rc == -EINVAL && force) { if (rc == -EINVAL && force) {
context.str = str; context.str = str;
context.len = strlen(str) + 1; context.len = strlen(str) + 1;
...@@ -1958,7 +1954,7 @@ static int convert_context(u32 key, ...@@ -1958,7 +1954,7 @@ static int convert_context(u32 key,
goto out; goto out;
rc = string_to_context_struct(args->newp, NULL, s, rc = string_to_context_struct(args->newp, NULL, s,
c->len, &ctx, SECSID_NULL); &ctx, SECSID_NULL);
kfree(s); kfree(s);
if (!rc) { if (!rc) {
pr_info("SELinux: Context %s became valid (mapped).\n", pr_info("SELinux: Context %s became valid (mapped).\n",
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment