libsepol: Expand attributes with TYPE_FLAGS_EXPAND_ATTR_TRUE set

Commit 1089665e31 (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@tycho.nsa.gov>
This commit is contained in:
James Carter 2017-05-09 12:22:20 -04:00
parent 738db6077b
commit f9ae34a404
2 changed files with 43 additions and 41 deletions

View file

@ -2352,6 +2352,7 @@ static int type_attr_map(hashtab_key_t key
value = type->s.value; value = type->s.value;
if (type->flavor == TYPE_ATTRIB) { if (type->flavor == TYPE_ATTRIB) {
if (!(type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE)) {
if (ebitmap_cpy(&p->attr_type_map[value - 1], &type->types)) { if (ebitmap_cpy(&p->attr_type_map[value - 1], &type->types)) {
goto oom; goto oom;
} }
@ -2362,6 +2363,12 @@ static int type_attr_map(hashtab_key_t key
goto oom; goto oom;
} }
} }
} else {
/* Attribute is being expanded, so remove */
if (ebitmap_set_bit(&p->type_attr_map[value - 1], value - 1, 0)) {
goto oom;
}
}
} else { } else {
if (ebitmap_set_bit(&p->attr_type_map[value - 1], value - 1, 1)) { if (ebitmap_set_bit(&p->attr_type_map[value - 1], value - 1, 1)) {
goto oom; goto oom;
@ -2528,15 +2535,17 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p,
unsigned int i; unsigned int i;
ebitmap_t types, neg_types; ebitmap_t types, neg_types;
ebitmap_node_t *tnode; ebitmap_node_t *tnode;
unsigned char expand = alwaysexpand || ebitmap_length(&set->negset) || set->flags;
type_datum_t *type;
int rc =-1; int rc =-1;
ebitmap_init(&types); ebitmap_init(&types);
ebitmap_init(t); ebitmap_init(t);
if (alwaysexpand || ebitmap_length(&set->negset) || set->flags) {
/* First go through the types and OR all the attributes to types */ /* First go through the types and OR all the attributes to types */
ebitmap_for_each_bit(&set->types, tnode, i) { ebitmap_for_each_bit(&set->types, tnode, i) {
if (ebitmap_node_get_bit(tnode, i)) { if (!ebitmap_node_get_bit(tnode, i))
continue;
/* /*
* invalid policies might have more types set in the ebitmap than * invalid policies might have more types set in the ebitmap than
@ -2545,16 +2554,15 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p,
if (i >= p->p_types.nprim) if (i >= p->p_types.nprim)
goto err_types; goto err_types;
if (!p->type_val_to_struct[i]) { type = p->type_val_to_struct[i];
if (!type) {
goto err_types; goto err_types;
} }
if (p->type_val_to_struct[i]->flavor == if (type->flavor == TYPE_ATTRIB &&
TYPE_ATTRIB) { (expand || (type->flags & TYPE_FLAGS_EXPAND_ATTR_TRUE))) {
if (ebitmap_union if (ebitmap_union(&types, &type->types)) {
(&types,
&p->type_val_to_struct[i]->
types)) {
goto err_types; goto err_types;
} }
} else { } else {
@ -2563,12 +2571,6 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p,
} }
} }
} }
}
} 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 */ /* Now do the same thing for negset */
ebitmap_init(&neg_types); ebitmap_init(&neg_types);

View file

@ -467,8 +467,8 @@ static int type_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
state->cur_mod_name, id); state->cur_mod_name, id);
return -1; return -1;
} }
/* permissive should pass to the base type */
base_type->flags |= (type->flags & TYPE_FLAGS_PERMISSIVE); base_type->flags |= type->flags;
} else { } else {
if (state->verbose) if (state->verbose)
INFO(state->handle, "copying type %s", id); 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; 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); base_type = hashtab_search(state->base->p_types.table, id);
if (base_type == NULL) { 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->flavor = TYPE_ALIAS;
base_type->primary = target_type->s.value; 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 /* the aliases map points from its value to its primary so when this module