Commit 1089665e31a647a5f0ba2eabe8ac6232b384bed9 (Add attribute expansion options) adds an expandattribute rule to the policy.conf language which sets a type_datum flag. Currently the flag is used only when writing out CIL policy from a policy.conf. Make use of the flag when expanding policy to expand policy rules and remove all type associations for an attribute that has TYPE_FLAGS_EXPAND_ATTR_TRUE set. (The attribute will remain in the policy, but have no types associated with it.) Signed-off-by: James Carter <jwcart2@xxxxxxxxxxxxx> --- libsepol/src/expand.c | 72 ++++++++++++++++++++++++++++++--------------------- libsepol/src/link.c | 8 +++--- 2 files changed, 46 insertions(+), 34 deletions(-) diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c index 54bf781..74a650f 100644 --- a/libsepol/src/expand.c +++ b/libsepol/src/expand.c @@ -2360,6 +2360,20 @@ oom: return -1; } +static int remove_types_from_expanded(hashtab_key_t key + __attribute__ ((unused)), hashtab_datum_t datum, + void *ptr) +{ + type_datum_t *type = (type_datum_t *) datum; + + if (type->flavor == TYPE_ATTRIB && (type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE)) { + ebitmap_destroy(&type->types); + ebitmap_init(&type->types); + } + + return 0; +} + /* converts typeset using typemap and expands into ebitmap_t types using the attributes in the passed in policy. * this should not be called until after all the blocks have been processed and the attributes in target policy * are complete. */ @@ -2513,46 +2527,41 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, unsigned int i; ebitmap_t types, neg_types; ebitmap_node_t *tnode; + unsigned char expand = alwaysexpand || ebitmap_length(&set->negset) || set->flags; + type_datum_t *type; int rc =-1; ebitmap_init(&types); ebitmap_init(t); - if (alwaysexpand || ebitmap_length(&set->negset) || set->flags) { - /* First go through the types and OR all the attributes to types */ - ebitmap_for_each_bit(&set->types, tnode, i) { - if (ebitmap_node_get_bit(tnode, i)) { + /* First go through the types and OR all the attributes to types */ + ebitmap_for_each_bit(&set->types, tnode, i) { + if (!ebitmap_node_get_bit(tnode, i)) + continue; + + /* + * invalid policies might have more types set in the ebitmap than + * what's available in the type_val_to_struct mapping + */ + if (i >= p->p_types.nprim) + goto err_types; - /* - * invalid policies might have more types set in the ebitmap than - * what's available in the type_val_to_struct mapping - */ - if (i >= p->p_types.nprim) - goto err_types; + type = p->type_val_to_struct[i]; - if (!p->type_val_to_struct[i]) { - goto err_types; - } + if (!type) { + goto err_types; + } - if (p->type_val_to_struct[i]->flavor == - TYPE_ATTRIB) { - if (ebitmap_union - (&types, - &p->type_val_to_struct[i]-> - types)) { - goto err_types; - } - } else { - if (ebitmap_set_bit(&types, i, 1)) { - goto err_types; - } - } + if (type->flavor == TYPE_ATTRIB && + (expand || (type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE))) { + if (ebitmap_union(&types, &type->types)) { + goto err_types; + } + } else { + if (ebitmap_set_bit(&types, i, 1)) { + goto err_types; } } - } else { - /* No expansion of attributes, just copy the set as is. */ - if (ebitmap_cpy(&types, &set->types)) - goto err_types; } /* Now do the same thing for negset */ @@ -3160,6 +3169,9 @@ int expand_module(sepol_handle_t * handle, if (genfs_copy(&state)) goto cleanup; + if (hashtab_map(state.out->p_types.table, remove_types_from_expanded, &state)) + goto cleanup; + /* Build the type<->attribute maps and remove attributes. */ state.out->attr_type_map = malloc(state.out->p_types.nprim * sizeof(ebitmap_t)); diff --git a/libsepol/src/link.c b/libsepol/src/link.c index f211164..52770f4 100644 --- a/libsepol/src/link.c +++ b/libsepol/src/link.c @@ -467,8 +467,8 @@ static int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum, state->cur_mod_name, id); return -1; } - /* permissive should pass to the base type */ - base_type->flags |= (type->flags & TYPE_FLAGS_PERMISSIVE); + + base_type->flags |= type->flags; } else { if (state->verbose) INFO(state->handle, "copying type %s", id); @@ -890,7 +890,7 @@ static int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum, return -1; } - target_type->flags |= (type->flags & TYPE_FLAGS_PERMISSIVE); + target_type->flags |= type->flags; base_type = hashtab_search(state->base->p_types.table, id); if (base_type == NULL) { @@ -938,7 +938,7 @@ static int alias_copy_callback(hashtab_key_t key, hashtab_datum_t datum, base_type->flavor = TYPE_ALIAS; base_type->primary = target_type->s.value; - base_type->flags |= (target_type->flags & TYPE_FLAGS_PERMISSIVE); + base_type->flags |= target_type->flags; } /* the aliases map points from its value to its primary so when this module -- 2.9.3