libsepol/cil: Do not resolve names to declarations in abstract blocks

Since abstract blocks will not appear in the final policy, do not
resolve names to a declaration inside one.

When resolving blockabstract rules, they must be collected in a list
and processed at the end of the pass because if a parent block is
marked as abstract, then a blockabstract rule for a sub-block will
fail to resolve.

Found by oss-fuzz (#42981)

Signed-off-by: James Carter <jwcart2@gmail.com>
This commit is contained in:
James Carter 2022-01-05 16:06:28 -05:00
parent 6d783e5bb3
commit f0823bbbb5

View File

@ -65,6 +65,7 @@ struct cil_args_resolve {
struct cil_list *sensitivityorder_lists;
struct cil_list *in_list_before;
struct cil_list *in_list_after;
struct cil_list *abstract_blocks;
};
static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key, struct cil_tree_node *ast_node)
@ -2397,6 +2398,7 @@ int cil_resolve_blockabstract(struct cil_tree_node *current, void *extra_args)
struct cil_blockabstract *abstract = current->data;
struct cil_symtab_datum *block_datum = NULL;
struct cil_tree_node *block_node = NULL;
struct cil_args_resolve *args = extra_args;
int rc = SEPOL_ERR;
rc = cil_resolve_name(current, abstract->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum);
@ -2411,7 +2413,7 @@ int cil_resolve_blockabstract(struct cil_tree_node *current, void *extra_args)
goto exit;
}
cil_mark_subtree_abstract(block_node);
cil_list_append(args->abstract_blocks, CIL_NODE, block_node);
return SEPOL_OK;
@ -4097,6 +4099,7 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
extra_args.sensitivityorder_lists = NULL;
extra_args.in_list_before = NULL;
extra_args.in_list_after = NULL;
extra_args.abstract_blocks = NULL;
cil_list_init(&extra_args.to_destroy, CIL_NODE);
cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM);
@ -4106,6 +4109,7 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
cil_list_init(&extra_args.sensitivityorder_lists, CIL_LIST_ITEM);
cil_list_init(&extra_args.in_list_before, CIL_IN);
cil_list_init(&extra_args.in_list_after, CIL_IN);
cil_list_init(&extra_args.abstract_blocks, CIL_NODE);
for (pass = CIL_PASS_TIF; pass < CIL_PASS_NUM; pass++) {
extra_args.pass = pass;
@ -4129,6 +4133,13 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
cil_list_destroy(&extra_args.in_list_after, CIL_FALSE);
}
if (pass == CIL_PASS_BLKABS) {
struct cil_list_item *item;
cil_list_for_each(item, extra_args.abstract_blocks) {
cil_mark_subtree_abstract(item->data);
}
}
if (pass == CIL_PASS_BLKIN_LINK) {
rc = cil_check_for_bad_inheritance(current);
if (rc != SEPOL_OK) {
@ -4247,6 +4258,7 @@ exit:
cil_list_destroy(&extra_args.to_destroy, CIL_FALSE);
cil_list_destroy(&extra_args.in_list_before, CIL_FALSE);
cil_list_destroy(&extra_args.in_list_after, CIL_FALSE);
cil_list_destroy(&extra_args.abstract_blocks, CIL_FALSE);
return rc;
}
@ -4268,9 +4280,13 @@ static int __cil_resolve_name_with_parents(struct cil_tree_node *node, char *nam
case CIL_ROOT:
goto exit;
break;
case CIL_BLOCK:
symtab = &((struct cil_block*)node->data)->symtab[sym_index];
rc = cil_symtab_get_datum(symtab, name, datum);
case CIL_BLOCK: {
struct cil_block *block = node->data;
if (!block->is_abstract) {
symtab = &block->symtab[sym_index];
rc = cil_symtab_get_datum(symtab, name, datum);
}
}
break;
case CIL_BLOCKINHERIT: {
struct cil_blockinherit *inherit = node->data;