{
const char *name;
const struct level_datum *levdatum;
- struct ebitmap_node *node;
- u32 bit;
- int rc;
if (!l->sens || l->sens > p->p_levels.nprim)
return false;
return false;
/*
- * Validate that all bits set in l->cat are also be set in
- * levdatum->level->cat and no bit in l->cat is larger than
- * p->p_cats.nprim.
+ * l is valid iff every bit in l->cat is set in levdatum->level.cat
+ * and no bit in l->cat is larger than p->p_cats.nprim.
+ * policydb_index() has already verified that every bit set in
+ * levdatum->level.cat names a defined category, so containment is
+ * sufficient here.
*/
- rc = ebitmap_contains(&levdatum->level.cat, &l->cat,
- p->p_cats.nprim);
- if (!rc)
- return false;
-
- ebitmap_for_each_positive_bit(&levdatum->level.cat, node, bit) {
- if (!sym_name(p, SYM_CATS, bit))
- return false;
- }
-
- return true;
+ return ebitmap_contains(&levdatum->level.cat, &l->cat,
+ p->p_cats.nprim);
}
bool mls_range_isvalid(const struct policydb *p, const struct mls_range *r)
return 0;
}
+static int sens_cat_index_check(void *key, void *datum, void *datap)
+{
+ struct policydb *p = datap;
+ struct level_datum *levdatum = datum;
+ struct ebitmap_node *node;
+ u32 bit;
+
+ ebitmap_for_each_positive_bit(&levdatum->level.cat, node, bit) {
+ if (bit >= p->p_cats.nprim || !sym_name(p, SYM_CATS, bit)) {
+ pr_err("SELinux: sensitivity %s allows undefined category %u\n",
+ (const char *)key, bit + 1);
+ return -EINVAL;
+ }
+ }
+ return 0;
+}
+
/* clang-format off */
static int (*const index_f[SYM_NUM])(void *key, void *datum, void *datap) = {
common_index,
}
}
+ if (p->mls_enabled) {
+ rc = hashtab_map(&p->p_levels.table, sens_cat_index_check, p);
+ if (rc)
+ goto out;
+ }
+
rc = 0;
out:
return rc;