diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c index fcec6e51d..d7cafaa4a 100644 --- a/checkpolicy/checkpolicy.c +++ b/checkpolicy/checkpolicy.c @@ -370,10 +370,9 @@ static int check_level(hashtab_key_t key, hashtab_datum_t datum, void *arg __att { level_datum_t *levdatum = (level_datum_t *) datum; - if (!levdatum->isalias && !levdatum->defined) { - fprintf(stderr, - "Error: sensitivity %s was not used in a level definition!\n", - key); + if (!levdatum->isalias && levdatum->notdefined) { + fprintf(stderr, "Error: sensitivity %s was not used in a level definition!\n", + key); return -1; } return 0; diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c index ddfd4ee35..614b77066 100644 --- a/checkpolicy/policy_define.c +++ b/checkpolicy/policy_define.c @@ -770,6 +770,7 @@ int define_sens(void) level_datum_init(datum); datum->isalias = FALSE; datum->level = level; + datum->notdefined = TRUE; ret = declare_symbol(SYM_LEVELS, id, datum, &value, &value); switch (ret) { @@ -809,6 +810,7 @@ int define_sens(void) level_datum_init(aliasdatum); aliasdatum->isalias = TRUE; aliasdatum->level = level; + aliasdatum->notdefined = TRUE; ret = declare_symbol(SYM_LEVELS, id, aliasdatum, NULL, &value); switch (ret) { @@ -1037,9 +1039,10 @@ static int clone_level(hashtab_key_t key __attribute__ ((unused)), hashtab_datum mls_level_t *level = (mls_level_t *) arg, *newlevel; if (levdatum->level == level) { - levdatum->defined = 1; - if (!levdatum->isalias) + if (!levdatum->isalias) { + levdatum->notdefined = FALSE; return 0; + } newlevel = (mls_level_t *) malloc(sizeof(mls_level_t)); if (!newlevel) return -1; @@ -1048,6 +1051,7 @@ static int clone_level(hashtab_key_t key __attribute__ ((unused)), hashtab_datum return -1; } levdatum->level = newlevel; + levdatum->notdefined = FALSE; } return 0; } @@ -1088,8 +1092,6 @@ int define_level(void) } free(id); - levdatum->defined = 1; - while ((id = queue_remove(id_queue))) { cat_datum_t *cdatum; uint32_t range_start, range_end, i; diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c index a8e3616a3..95bd18baa 100644 --- a/libsepol/cil/src/cil_binary.c +++ b/libsepol/cil/src/cil_binary.c @@ -907,7 +907,6 @@ static int cil_sensalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alia goto exit; } sepol_alias->level = mls_level; - sepol_alias->defined = 1; sepol_alias->isalias = 1; return SEPOL_OK; @@ -3163,8 +3162,6 @@ int cil_sepol_level_define(policydb_t *pdb, struct cil_sens *cil_sens) } } - sepol_level->defined = 1; - return SEPOL_OK; exit: diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h index 6682069ea..56d2cb01d 100644 --- a/libsepol/include/sepol/policydb/policydb.h +++ b/libsepol/include/sepol/policydb/policydb.h @@ -217,7 +217,7 @@ typedef struct user_datum { typedef struct level_datum { mls_level_t *level; /* sensitivity and associated categories */ unsigned char isalias; /* is this sensitivity an alias for another? */ - unsigned char defined; + unsigned char notdefined; /* Only set to non-zero in checkpolicy */ } level_datum_t; /* Category attributes */ diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c index f10a8a95a..0c23a7a22 100644 --- a/libsepol/src/policydb.c +++ b/libsepol/src/policydb.c @@ -1390,8 +1390,10 @@ static int sens_destroy(hashtab_key_t key, hashtab_datum_t datum, void *p if (key) free(key); levdatum = (level_datum_t *) datum; - mls_level_destroy(levdatum->level); - free(levdatum->level); + if (!levdatum->isalias || !levdatum->notdefined) { + mls_level_destroy(levdatum->level); + free(levdatum->level); + } level_datum_destroy(levdatum); free(levdatum); return 0; diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c index d86f885e4..6e46f4266 100644 --- a/libsepol/src/policydb_validate.c +++ b/libsepol/src/policydb_validate.c @@ -618,12 +618,37 @@ static int validate_mls_level(const mls_level_t *level, const validate_t *sens, return -1; } -static int validate_level_datum(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +static int validate_level_datum(sepol_handle_t *handle, const level_datum_t *level, validate_t flavors[], const policydb_t *p) { - level_datum_t *level = d; - validate_t *flavors = args; + if (level->notdefined != 0) + goto bad; + + if (validate_mls_level(level->level, &flavors[SYM_LEVELS], &flavors[SYM_CATS])) + goto bad; + + if (level->isalias) { + const mls_level_t *l1 = level->level; + const mls_level_t *l2; + const level_datum_t *actual = (level_datum_t *) hashtab_search(p->p_levels.table, p->p_sens_val_to_name[l1->sens - 1]); + if (!actual) + goto bad; + l2 = actual->level; + if (!ebitmap_cmp(&l1->cat, &l2->cat)) + goto bad; + } + + return 0; + + bad: + ERR(handle, "Invalid level datum"); + return -1; +} + +static int validate_level_datum_wrapper(__attribute__ ((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) +{ + map_arg_t *margs = args; - return validate_mls_level(level->level, &flavors[SYM_LEVELS], &flavors[SYM_CATS]); + return validate_level_datum(margs->handle, d, margs->flavors, margs->policy); } static int validate_mls_range(const mls_range_t *range, const validate_t *sens, const validate_t *cats) @@ -774,7 +799,7 @@ static int validate_datum_array_entries(sepol_handle_t *handle, const policydb_t if (hashtab_map(p->p_users.table, validate_user_datum_wrapper, &margs)) goto bad; - if (p->mls && hashtab_map(p->p_levels.table, validate_level_datum, flavors)) + if (p->mls && hashtab_map(p->p_levels.table, validate_level_datum_wrapper, &margs)) goto bad; if (hashtab_map(p->p_cats.table, validate_datum, &flavors[SYM_CATS]))