diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c index 7d46fd59..c9738da1 100644 --- a/libsepol/cil/src/cil_resolve_ast.c +++ b/libsepol/cil/src/cil_resolve_ast.c @@ -55,6 +55,7 @@ struct cil_args_resolve { struct cil_tree_node *optstack; struct cil_tree_node *boolif; struct cil_tree_node *macro; + struct cil_tree_node *blockstack; struct cil_list *sidorder_lists; struct cil_list *classorder_lists; struct cil_list *catorder_lists; @@ -3248,6 +3249,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, __attribute__((unu enum cil_pass pass = args->pass; struct cil_tree_node *optstack = args->optstack; struct cil_tree_node *boolif = args->boolif; + struct cil_tree_node *blockstack = args->blockstack; if (node == NULL) { goto exit; @@ -3262,6 +3264,14 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, __attribute__((unu } } + if (blockstack != NULL) { + if (node->flavor == CIL_CAT || node->flavor == CIL_SENS) { + cil_log(CIL_ERR, "%s statement is not allowed in blocks (%s:%d)\n", cil_node_to_string(node), node->path, node->line); + rc = SEPOL_ERR; + goto exit; + } + } + if (boolif != NULL) { if (!(node->flavor == CIL_CONDBLOCK || node->flavor == CIL_AVRULE || @@ -3318,6 +3328,8 @@ int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *ex struct cil_tree_node *callstack = NULL; struct cil_tree_node *optstack = NULL; struct cil_tree_node *parent = NULL; + struct cil_tree_node *blockstack = NULL; + struct cil_tree_node *new = NULL; if (current == NULL || extra_args == NULL) { goto exit; @@ -3326,10 +3338,10 @@ int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *ex callstack = args->callstack; optstack = args->optstack; parent = current->parent; + blockstack = args->blockstack; - if (parent->flavor == CIL_CALL || parent->flavor == CIL_OPTIONAL) { + if (parent->flavor == CIL_CALL || parent->flavor == CIL_OPTIONAL || parent->flavor == CIL_BLOCK) { /* push this node onto a stack */ - struct cil_tree_node *new; cil_tree_node_init(&new); new->data = parent->data; @@ -3358,6 +3370,12 @@ int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *ex new->cl_head = optstack; } args->optstack = new; + } else if (parent->flavor == CIL_BLOCK) { + if (blockstack != NULL) { + blockstack->parent = new; + new->cl_head = blockstack; + } + args->blockstack = new; } } else if (parent->flavor == CIL_BOOLEANIF) { args->boolif = parent; @@ -3377,6 +3395,7 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext int rc = SEPOL_ERR; struct cil_args_resolve *args = extra_args; struct cil_tree_node *parent = NULL; + struct cil_tree_node *blockstack = NULL; if (current == NULL || extra_args == NULL) { goto exit; @@ -3411,6 +3430,14 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext free(optstack); } else if (parent->flavor == CIL_BOOLEANIF) { args->boolif = NULL; + } else if (parent->flavor == CIL_BLOCK) { + /* pop off the stack */ + blockstack = args->blockstack; + args->blockstack = blockstack->cl_head; + if (blockstack->cl_head) { + blockstack->cl_head->parent = NULL; + } + free(blockstack); } return SEPOL_OK; @@ -3442,6 +3469,7 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current) extra_args.catorder_lists = NULL; extra_args.sensitivityorder_lists = NULL; extra_args.in_list = NULL; + extra_args.blockstack = NULL; cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM); cil_list_init(&extra_args.classorder_lists, CIL_LIST_ITEM); @@ -3536,6 +3564,12 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current) free(curr); extra_args.optstack = next; } + while (extra_args.blockstack!= NULL) { + struct cil_tree_node *curr = extra_args.blockstack; + struct cil_tree_node *next = curr->cl_head; + free(curr); + extra_args.blockstack= next; + } } rc = __cil_verify_initsids(db->sidorder);