X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=security%2Fselinux%2Fss%2Fmls.c;h=feaf0a5b828fc19cb80c1af3c48df232d20c0bfe;hb=cec03afcb62fbbb0eaf943f6349ade61b89d7d40;hp=4a8bab2f3c712445f020fbe3a42a8aa4f172442c;hpb=e7b3ca08549caccf5d6e1cf066780bf4f0ae77a7;p=linux-2.6-omap-h63xx.git diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 4a8bab2f3c7..feaf0a5b828 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c @@ -34,7 +34,9 @@ */ int mls_compute_context_len(struct context * context) { - int i, l, len, range; + int i, l, len, head, prev; + char *nm; + struct ebitmap *e; struct ebitmap_node *node; if (!selinux_mls_enabled) @@ -42,31 +44,33 @@ int mls_compute_context_len(struct context * context) len = 1; /* for the beginning ":" */ for (l = 0; l < 2; l++) { - range = 0; - len += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); - - ebitmap_for_each_bit(&context->range.level[l].cat, node, i) { - if (ebitmap_node_get_bit(node, i)) { - if (range) { - range++; - continue; - } + int index_sens = context->range.level[l].sens; + len += strlen(policydb.p_sens_val_to_name[index_sens - 1]); - len += strlen(policydb.p_cat_val_to_name[i]) + 1; - range++; - } else { - if (range > 1) - len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1; - range = 0; + /* categories */ + head = -2; + prev = -2; + e = &context->range.level[l].cat; + ebitmap_for_each_positive_bit(e, node, i) { + if (i - prev > 1) { + /* one or more negative bits are skipped */ + if (head != prev) { + nm = policydb.p_cat_val_to_name[prev]; + len += strlen(nm) + 1; + } + nm = policydb.p_cat_val_to_name[i]; + len += strlen(nm) + 1; + head = i; } + prev = i; + } + if (prev != head) { + nm = policydb.p_cat_val_to_name[prev]; + len += strlen(nm) + 1; } - /* Handle case where last category is the end of range */ - if (range > 1) - len += strlen(policydb.p_cat_val_to_name[i - 1]) + 1; - if (l == 0) { if (mls_level_eq(&context->range.level[0], - &context->range.level[1])) + &context->range.level[1])) break; else len++; @@ -84,8 +88,9 @@ int mls_compute_context_len(struct context * context) void mls_sid_to_context(struct context *context, char **scontext) { - char *scontextp; - int i, l, range, wrote_sep; + char *scontextp, *nm; + int i, l, head, prev; + struct ebitmap *e; struct ebitmap_node *node; if (!selinux_mls_enabled) @@ -97,61 +102,54 @@ void mls_sid_to_context(struct context *context, scontextp++; for (l = 0; l < 2; l++) { - range = 0; - wrote_sep = 0; strcpy(scontextp, policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); - scontextp += strlen(policydb.p_sens_val_to_name[context->range.level[l].sens - 1]); + scontextp += strlen(scontextp); /* categories */ - ebitmap_for_each_bit(&context->range.level[l].cat, node, i) { - if (ebitmap_node_get_bit(node, i)) { - if (range) { - range++; - continue; - } - - if (!wrote_sep) { - *scontextp++ = ':'; - wrote_sep = 1; - } else - *scontextp++ = ','; - strcpy(scontextp, policydb.p_cat_val_to_name[i]); - scontextp += strlen(policydb.p_cat_val_to_name[i]); - range++; - } else { - if (range > 1) { - if (range > 2) + head = -2; + prev = -2; + e = &context->range.level[l].cat; + ebitmap_for_each_positive_bit(e, node, i) { + if (i - prev > 1) { + /* one or more negative bits are skipped */ + if (prev != head) { + if (prev - head > 1) *scontextp++ = '.'; else *scontextp++ = ','; - - strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]); - scontextp += strlen(policydb.p_cat_val_to_name[i - 1]); + nm = policydb.p_cat_val_to_name[prev]; + strcpy(scontextp, nm); + scontextp += strlen(nm); } - range = 0; + if (prev < 0) + *scontextp++ = ':'; + else + *scontextp++ = ','; + nm = policydb.p_cat_val_to_name[i]; + strcpy(scontextp, nm); + scontextp += strlen(nm); + head = i; } + prev = i; } - /* Handle case where last category is the end of range */ - if (range > 1) { - if (range > 2) + if (prev != head) { + if (prev - head > 1) *scontextp++ = '.'; else *scontextp++ = ','; - - strcpy(scontextp, policydb.p_cat_val_to_name[i - 1]); - scontextp += strlen(policydb.p_cat_val_to_name[i - 1]); + nm = policydb.p_cat_val_to_name[prev]; + strcpy(scontextp, nm); + scontextp += strlen(nm); } if (l == 0) { if (mls_level_eq(&context->range.level[0], &context->range.level[1])) break; - else { - *scontextp = '-'; - scontextp++; - } + else + *scontextp++ = '-'; } } @@ -159,51 +157,55 @@ void mls_sid_to_context(struct context *context, return; } +int mls_level_isvalid(struct policydb *p, struct mls_level *l) +{ + struct level_datum *levdatum; + struct ebitmap_node *node; + int i; + + if (!l->sens || l->sens > p->p_levels.nprim) + return 0; + levdatum = hashtab_search(p->p_levels.table, + p->p_sens_val_to_name[l->sens - 1]); + if (!levdatum) + return 0; + + ebitmap_for_each_positive_bit(&l->cat, node, i) { + if (i > p->p_cats.nprim) + return 0; + if (!ebitmap_get_bit(&levdatum->level->cat, i)) { + /* + * Category may not be associated with + * sensitivity. + */ + return 0; + } + } + + return 1; +} + +int mls_range_isvalid(struct policydb *p, struct mls_range *r) +{ + return (mls_level_isvalid(p, &r->level[0]) && + mls_level_isvalid(p, &r->level[1]) && + mls_level_dom(&r->level[1], &r->level[0])); +} + /* * Return 1 if the MLS fields in the security context * structure `c' are valid. Return 0 otherwise. */ int mls_context_isvalid(struct policydb *p, struct context *c) { - struct level_datum *levdatum; struct user_datum *usrdatum; - struct ebitmap_node *node; - int i, l; if (!selinux_mls_enabled) return 1; - /* - * MLS range validity checks: high must dominate low, low level must - * be valid (category set <-> sensitivity check), and high level must - * be valid (category set <-> sensitivity check) - */ - if (!mls_level_dom(&c->range.level[1], &c->range.level[0])) - /* High does not dominate low. */ + if (!mls_range_isvalid(p, &c->range)) return 0; - for (l = 0; l < 2; l++) { - if (!c->range.level[l].sens || c->range.level[l].sens > p->p_levels.nprim) - return 0; - levdatum = hashtab_search(p->p_levels.table, - p->p_sens_val_to_name[c->range.level[l].sens - 1]); - if (!levdatum) - return 0; - - ebitmap_for_each_bit(&c->range.level[l].cat, node, i) { - if (ebitmap_node_get_bit(node, i)) { - if (i > p->p_cats.nprim) - return 0; - if (!ebitmap_get_bit(&levdatum->level->cat, i)) - /* - * Category may not be associated with - * sensitivity in low level. - */ - return 0; - } - } - } - if (c->role == OBJECT_R_VAL) return 1; @@ -485,18 +487,16 @@ int mls_convert_context(struct policydb *oldp, c->range.level[l].sens = levdatum->level->sens; ebitmap_init(&bitmap); - ebitmap_for_each_bit(&c->range.level[l].cat, node, i) { - if (ebitmap_node_get_bit(node, i)) { - int rc; - - catdatum = hashtab_search(newp->p_cats.table, - oldp->p_cat_val_to_name[i]); - if (!catdatum) - return -EINVAL; - rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); - if (rc) - return rc; - } + ebitmap_for_each_positive_bit(&c->range.level[l].cat, node, i) { + int rc; + + catdatum = hashtab_search(newp->p_cats.table, + oldp->p_cat_val_to_name[i]); + if (!catdatum) + return -EINVAL; + rc = ebitmap_set_bit(&bitmap, catdatum->value - 1, 1); + if (rc) + return rc; } ebitmap_destroy(&c->range.level[l].cat); c->range.level[l].cat = bitmap; @@ -537,15 +537,8 @@ int mls_compute_sid(struct context *scontext, /* Use the process effective MLS attributes. */ return mls_context_cpy_low(newcontext, scontext); case AVTAB_MEMBER: - /* Only polyinstantiate the MLS attributes if - the type is being polyinstantiated */ - if (newcontext->type != tcontext->type) { - /* Use the process effective MLS attributes. */ - return mls_context_cpy_low(newcontext, scontext); - } else { - /* Use the related object MLS attributes. */ - return mls_context_cpy(newcontext, tcontext); - } + /* Use the process effective MLS attributes. */ + return mls_context_cpy_low(newcontext, scontext); default: return -EINVAL; } @@ -569,7 +562,7 @@ void mls_export_netlbl_lvl(struct context *context, if (!selinux_mls_enabled) return; - secattr->mls_lvl = context->range.level[0].sens - 1; + secattr->attr.mls.lvl = context->range.level[0].sens - 1; secattr->flags |= NETLBL_SECATTR_MLS_LVL; } @@ -589,7 +582,7 @@ void mls_import_netlbl_lvl(struct context *context, if (!selinux_mls_enabled) return; - context->range.level[0].sens = secattr->mls_lvl + 1; + context->range.level[0].sens = secattr->attr.mls.lvl + 1; context->range.level[1].sens = context->range.level[0].sens; } @@ -612,8 +605,8 @@ int mls_export_netlbl_cat(struct context *context, return 0; rc = ebitmap_netlbl_export(&context->range.level[0].cat, - &secattr->mls_cat); - if (rc == 0 && secattr->mls_cat != NULL) + &secattr->attr.mls.cat); + if (rc == 0 && secattr->attr.mls.cat != NULL) secattr->flags |= NETLBL_SECATTR_MLS_CAT; return rc; @@ -640,7 +633,7 @@ int mls_import_netlbl_cat(struct context *context, return 0; rc = ebitmap_netlbl_import(&context->range.level[0].cat, - secattr->mls_cat); + secattr->attr.mls.cat); if (rc != 0) goto import_netlbl_cat_failure;