250 lines
8.3 KiB
Diff
250 lines
8.3 KiB
Diff
|
From 599c1422479ae9dd9501c43680bf4a1667e7c951 Mon Sep 17 00:00:00 2001
|
||
|
From: James Carter <jwcart2@gmail.com>
|
||
|
Date: Tue, 30 Mar 2021 13:39:15 -0400
|
||
|
Subject: [PATCH] libsepol/cil: Use AST to track blocks and optionals when
|
||
|
resolving
|
||
|
|
||
|
When resolving the AST, block and optional stacks are used to
|
||
|
determine if the current rule being resolved is in a block or
|
||
|
an optional. There is no need to do this since the parent node
|
||
|
pointers can be used when exiting a block or an optional to
|
||
|
determine if resolution is still within a block or an optional.
|
||
|
|
||
|
When entering either a block or an optional, update the appropriate
|
||
|
tree node pointer. When finished with the last child of a block or
|
||
|
optional, set the appropriate pointer to NULL. If a parent of the
|
||
|
same kind is found when the parent node pointers are followed back
|
||
|
to the root node, then set the pointer to that tree node.
|
||
|
|
||
|
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||
|
---
|
||
|
libsepol/cil/src/cil_resolve_ast.c | 107 +++++++++--------------------
|
||
|
1 file changed, 32 insertions(+), 75 deletions(-)
|
||
|
|
||
|
diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
|
||
|
index dab8b276..e0379782 100644
|
||
|
--- a/libsepol/cil/src/cil_resolve_ast.c
|
||
|
+++ b/libsepol/cil/src/cil_resolve_ast.c
|
||
|
@@ -52,10 +52,10 @@ struct cil_args_resolve {
|
||
|
enum cil_pass pass;
|
||
|
uint32_t *changed;
|
||
|
struct cil_list *disabled_optionals;
|
||
|
- struct cil_tree_node *optstack;
|
||
|
+ struct cil_tree_node *optional;
|
||
|
struct cil_tree_node *boolif;
|
||
|
struct cil_tree_node *macro;
|
||
|
- struct cil_tree_node *blockstack;
|
||
|
+ struct cil_tree_node *block;
|
||
|
struct cil_list *sidorder_lists;
|
||
|
struct cil_list *classorder_lists;
|
||
|
struct cil_list *unordered_classorder_lists;
|
||
|
@@ -3692,16 +3692,16 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
||
|
int rc = SEPOL_ERR;
|
||
|
struct cil_args_resolve *args = extra_args;
|
||
|
enum cil_pass pass = args->pass;
|
||
|
- struct cil_tree_node *optstack = args->optstack;
|
||
|
+ struct cil_tree_node *optional = args->optional;
|
||
|
struct cil_tree_node *boolif = args->boolif;
|
||
|
- struct cil_tree_node *blockstack = args->blockstack;
|
||
|
+ struct cil_tree_node *block = args->block;
|
||
|
struct cil_tree_node *macro = args->macro;
|
||
|
|
||
|
if (node == NULL) {
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
- if (optstack != NULL) {
|
||
|
+ if (optional != NULL) {
|
||
|
if (node->flavor == CIL_TUNABLE || node->flavor == CIL_MACRO) {
|
||
|
/* tuanbles and macros are not allowed in optionals*/
|
||
|
cil_tree_log(node, CIL_ERR, "%s statement is not allowed in optionals", cil_node_to_string(node));
|
||
|
@@ -3710,7 +3710,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- if (blockstack != NULL) {
|
||
|
+ if (block != NULL) {
|
||
|
if (node->flavor == CIL_CAT || node->flavor == CIL_SENS) {
|
||
|
cil_tree_log(node, CIL_ERR, "%s statement is not allowed in blocks", cil_node_to_string(node));
|
||
|
rc = SEPOL_ERR;
|
||
|
@@ -3764,11 +3764,11 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished
|
||
|
if (rc == SEPOL_ENOENT) {
|
||
|
enum cil_log_level lvl = CIL_ERR;
|
||
|
|
||
|
- if (optstack != NULL) {
|
||
|
+ if (optional != NULL) {
|
||
|
lvl = CIL_INFO;
|
||
|
|
||
|
- struct cil_optional *opt = (struct cil_optional *)optstack->data;
|
||
|
- struct cil_tree_node *opt_node = opt->datum.nodes->head->data;
|
||
|
+ struct cil_optional *opt = (struct cil_optional *)optional->data;
|
||
|
+ struct cil_tree_node *opt_node = NODE(opt);;
|
||
|
/* disable an optional if something failed to resolve */
|
||
|
opt->enabled = CIL_FALSE;
|
||
|
cil_tree_log(node, lvl, "Failed to resolve %s statement", cil_node_to_string(node));
|
||
|
@@ -3791,39 +3791,18 @@ int __cil_resolve_ast_first_child_helper(struct cil_tree_node *current, void *ex
|
||
|
{
|
||
|
int rc = SEPOL_ERR;
|
||
|
struct cil_args_resolve *args = extra_args;
|
||
|
- 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;
|
||
|
}
|
||
|
|
||
|
- optstack = args->optstack;
|
||
|
parent = current->parent;
|
||
|
- blockstack = args->blockstack;
|
||
|
|
||
|
- if (parent->flavor == CIL_OPTIONAL || parent->flavor == CIL_BLOCK) {
|
||
|
- /* push this node onto a stack */
|
||
|
- cil_tree_node_init(&new);
|
||
|
-
|
||
|
- new->data = parent->data;
|
||
|
- new->flavor = parent->flavor;
|
||
|
-
|
||
|
- if (parent->flavor == CIL_OPTIONAL) {
|
||
|
- if (optstack != NULL) {
|
||
|
- optstack->parent = new;
|
||
|
- 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;
|
||
|
- }
|
||
|
+ if (parent->flavor == CIL_BLOCK) {
|
||
|
+ args->block = parent;
|
||
|
+ } else if (parent->flavor == CIL_OPTIONAL) {
|
||
|
+ args->optional = parent;
|
||
|
} else if (parent->flavor == CIL_BOOLEANIF) {
|
||
|
args->boolif = parent;
|
||
|
} else if (parent->flavor == CIL_MACRO) {
|
||
|
@@ -3842,7 +3821,6 @@ 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;
|
||
|
@@ -3853,30 +3831,31 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext
|
||
|
if (parent->flavor == CIL_MACRO) {
|
||
|
args->macro = NULL;
|
||
|
} else if (parent->flavor == CIL_OPTIONAL) {
|
||
|
- struct cil_tree_node *optstack;
|
||
|
-
|
||
|
+ struct cil_tree_node *n = parent->parent;
|
||
|
if (((struct cil_optional *)parent->data)->enabled == CIL_FALSE) {
|
||
|
*(args->changed) = CIL_TRUE;
|
||
|
cil_list_append(args->disabled_optionals, CIL_NODE, parent);
|
||
|
}
|
||
|
-
|
||
|
- /* pop off the stack */
|
||
|
- optstack = args->optstack;
|
||
|
- args->optstack = optstack->cl_head;
|
||
|
- if (optstack->cl_head) {
|
||
|
- optstack->cl_head->parent = NULL;
|
||
|
+ args->optional = NULL;
|
||
|
+ while (n && n->flavor != CIL_ROOT) {
|
||
|
+ if (n->flavor == CIL_OPTIONAL) {
|
||
|
+ args->optional = n;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ n = n->parent;
|
||
|
}
|
||
|
- 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;
|
||
|
+ struct cil_tree_node *n = parent->parent;
|
||
|
+ args->block = NULL;
|
||
|
+ while (n && n->flavor != CIL_ROOT) {
|
||
|
+ if (n->flavor == CIL_BLOCK) {
|
||
|
+ args->block = n;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ n = n->parent;
|
||
|
}
|
||
|
- free(blockstack);
|
||
|
}
|
||
|
|
||
|
return SEPOL_OK;
|
||
|
@@ -3885,16 +3864,6 @@ exit:
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
-static void cil_destroy_tree_node_stack(struct cil_tree_node *curr)
|
||
|
-{
|
||
|
- struct cil_tree_node *next;
|
||
|
- while (curr != NULL) {
|
||
|
- next = curr->cl_head;
|
||
|
- free(curr);
|
||
|
- curr = next;
|
||
|
- }
|
||
|
-}
|
||
|
-
|
||
|
int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
||
|
{
|
||
|
int rc = SEPOL_ERR;
|
||
|
@@ -3909,7 +3878,8 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
||
|
extra_args.db = db;
|
||
|
extra_args.pass = pass;
|
||
|
extra_args.changed = &changed;
|
||
|
- extra_args.optstack = NULL;
|
||
|
+ extra_args.block = NULL;
|
||
|
+ extra_args.optional = NULL;
|
||
|
extra_args.boolif= NULL;
|
||
|
extra_args.macro = NULL;
|
||
|
extra_args.sidorder_lists = NULL;
|
||
|
@@ -3918,7 +3888,6 @@ 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.disabled_optionals, CIL_NODE);
|
||
|
cil_list_init(&extra_args.sidorder_lists, CIL_LIST_ITEM);
|
||
|
@@ -4022,17 +3991,7 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
||
|
}
|
||
|
cil_list_destroy(&extra_args.disabled_optionals, CIL_FALSE);
|
||
|
cil_list_init(&extra_args.disabled_optionals, CIL_NODE);
|
||
|
- }
|
||
|
-
|
||
|
- /* reset the arguments */
|
||
|
- changed = 0;
|
||
|
- while (extra_args.optstack != NULL) {
|
||
|
- cil_destroy_tree_node_stack(extra_args.optstack);
|
||
|
- extra_args.optstack = NULL;
|
||
|
- }
|
||
|
- while (extra_args.blockstack!= NULL) {
|
||
|
- cil_destroy_tree_node_stack(extra_args.blockstack);
|
||
|
- extra_args.blockstack = NULL;
|
||
|
+ changed = 0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@@ -4043,8 +4002,6 @@ int cil_resolve_ast(struct cil_db *db, struct cil_tree_node *current)
|
||
|
|
||
|
rc = SEPOL_OK;
|
||
|
exit:
|
||
|
- cil_destroy_tree_node_stack(extra_args.optstack);
|
||
|
- cil_destroy_tree_node_stack(extra_args.blockstack);
|
||
|
__cil_ordered_lists_destroy(&extra_args.sidorder_lists);
|
||
|
__cil_ordered_lists_destroy(&extra_args.classorder_lists);
|
||
|
__cil_ordered_lists_destroy(&extra_args.catorder_lists);
|
||
|
--
|
||
|
2.30.2
|
||
|
|