selinux/stable-4.20 PR 20181022
-----BEGIN PGP SIGNATURE----- iQJIBAABCAAyFiEES0KozwfymdVUl37v6iDy2pc3iXMFAlvOZkAUHHBhdWxAcGF1 bC1tb29yZS5jb20ACgkQ6iDy2pc3iXPekw/7BrlSGnobeKz9KuYWKykNfe3bVInx 3/6pS4zo7ODum4DdHbWdoeuhYpDVdXgvMM015Ug6A5YqSpioEH9eB2iY8E86A2Rm X2oGbawuZXNrYYbxDy9w9vZC+JlG/kcB4o9gKb4Kk06/8t//2wqAPquaWFckvkVi bExrrdmzZ7VYfgcx3LwN7tWzwF8qgdhgPYSofH+fvrrGMhwJW1sSc/GNtYD5cP5W 6ZhIDiZFAGBGDjKYaE8nrI4+6ECLJ2ThImau6SdG2LcrNNIXaMMR+TK2ka+4x0oa x6vl8Ij5vx2Q0j4XOIy7J1OglpoOZA5Bv5VtgTL7ORkQVyQA0orKtjBEzM/rt0OK DC9CiyAh7eVZmi4oQYn6ZV36Uc7TBefgJ2TlaUIlwX2AO5ucAPdicIOkX3+0QwGr s0guB4QUbkTK8TUlyZ9w9kN+OKJNJlOZuIFyFI54cjYjNKGU4kT6gm/zQDIkqFf1 Sl29YNtN4iv6nB0rM8hXHvFvLC5UQPDyxIomP8fB8D9Aynxmgg720EC2GlnKlFec 0EnHuiP5ZHJEUcAh5eW97KGPNAg6ASsoQwe3ZUI5zDnDUniBSx58v9rQVMo7aJFG 0tkgrJN2S1hydu8TpvM1gE+uZhqOAEOVPxAdOAlDwufn0uBio5n5H3SQ0QusQQ5l IUtYoWNkMcUvQpg= =Q8ZM -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
d5e4d81da4
@ -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)
|
|||||||
/*
|
/*
|
||||||
* 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)
|
|||||||
*/
|
*/
|
||||||
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,
|
|||||||
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')
|
|
||||||
*p++ = '\0';
|
|
||||||
|
|
||||||
/* Separate into range if exists */
|
/* Separate into range if exists */
|
||||||
rngptr = strchr(scontextp, '.');
|
rngptr = strchr(cur_cat, '.');
|
||||||
if (rngptr != NULL) {
|
if (rngptr != NULL) {
|
||||||
/* Remove '.' */
|
/* Remove '.' */
|
||||||
*rngptr++ = '\0';
|
*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)
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
/* If range, set all categories in range */
|
||||||
|
if (rngptr == NULL)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
rngdatum = hashtab_search(pol->p_cats.table, rngptr);
|
||||||
|
if (!rngdatum)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
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)
|
if (rc)
|
||||||
goto out;
|
return rc;
|
||||||
|
|
||||||
/* If range, set all categories in range */
|
|
||||||
if (rngptr) {
|
|
||||||
int i;
|
|
||||||
|
|
||||||
rngdatum = hashtab_search(pol->p_cats.table, rngptr);
|
|
||||||
if (!rngdatum) {
|
|
||||||
rc = -EINVAL;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 != ',')
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
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 @@ out:
|
|||||||
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);
|
|||||||
|
|
||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
|
|
||||||
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,
|
|||||||
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,
|
|||||||
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",
|
||||||
|
Loading…
Reference in New Issue
Block a user