@@ -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;
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> --- libsepol/cil/src/cil_resolve_ast.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-)