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 *sensitivityorder_lists;
struct cil_list *in_list_before; struct cil_list *in_list_before;
struct cil_list *in_list_after; 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) 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_blockabstract *abstract = current->data;
struct cil_symtab_datum *block_datum = NULL; struct cil_symtab_datum *block_datum = NULL;
struct cil_tree_node *block_node = NULL; struct cil_tree_node *block_node = NULL;
struct cil_args_resolve *args = extra_args;
int rc = SEPOL_ERR; int rc = SEPOL_ERR;
rc = cil_resolve_name(current, abstract->block_str, CIL_SYM_BLOCKS, extra_args, &block_datum); 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; goto exit;
} }
cil_mark_subtree_abstract(block_node); cil_list_append(args->abstract_blocks, CIL_NODE, block_node);
return SEPOL_OK; 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.sensitivityorder_lists = NULL;
extra_args.in_list_before = NULL; extra_args.in_list_before = NULL;
extra_args.in_list_after = 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.to_destroy, CIL_NODE);
cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM); 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.sensitivityorder_lists, CIL_LIST_ITEM);
cil_list_init(&extra_args.in_list_before, CIL_IN); 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.in_list_after, CIL_IN);
cil_list_init(&extra_args.abstract_blocks, CIL_NODE);
for (pass = CIL_PASS_TIF; pass < CIL_PASS_NUM; pass++) { for (pass = CIL_PASS_TIF; pass < CIL_PASS_NUM; pass++) {
extra_args.pass = 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); 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) { if (pass == CIL_PASS_BLKIN_LINK) {
rc = cil_check_for_bad_inheritance(current); rc = cil_check_for_bad_inheritance(current);
if (rc != SEPOL_OK) { if (rc != SEPOL_OK) {
@ -4247,6 +4258,7 @@ exit:
cil_list_destroy(&extra_args.to_destroy, CIL_FALSE); 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_before, CIL_FALSE);
cil_list_destroy(&extra_args.in_list_after, CIL_FALSE); cil_list_destroy(&extra_args.in_list_after, CIL_FALSE);
cil_list_destroy(&extra_args.abstract_blocks, CIL_FALSE);
return rc; return rc;
} }
@ -4268,9 +4280,13 @@ static int __cil_resolve_name_with_parents(struct cil_tree_node *node, char *nam
case CIL_ROOT: case CIL_ROOT:
goto exit; goto exit;
break; break;
case CIL_BLOCK: case CIL_BLOCK: {
symtab = &((struct cil_block*)node->data)->symtab[sym_index]; struct cil_block *block = node->data;
rc = cil_symtab_get_datum(symtab, name, datum); if (!block->is_abstract) {
symtab = &block->symtab[sym_index];
rc = cil_symtab_get_datum(symtab, name, datum);
}
}
break; break;
case CIL_BLOCKINHERIT: { case CIL_BLOCKINHERIT: {
struct cil_blockinherit *inherit = node->data; struct cil_blockinherit *inherit = node->data;