diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c index 4e53f06a98f4d862dbf2d753f6fa28e40afcab4b..1fef25d46f6a223f9acf4334103e224f830fed26 100644 --- a/libsepol/cil/src/cil_build_ast.c +++ b/libsepol/cil/src/cil_build_ast.c @@ -49,10 +49,11 @@ struct cil_args_build { struct cil_tree_node *ast; struct cil_db *db; - struct cil_tree_node *macro; - struct cil_tree_node *boolif; struct cil_tree_node *tunif; struct cil_tree_node *in; + struct cil_tree_node *macro; + struct cil_tree_node *optional; + struct cil_tree_node *boolif; }; int cil_fill_list(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **list) @@ -6093,28 +6094,17 @@ void cil_destroy_src_info(struct cil_src_info *info) int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args) { - struct cil_args_build *args = NULL; - struct cil_tree_node *ast_current = NULL; - struct cil_db *db = NULL; + struct cil_args_build *args = extra_args; + struct cil_db *db = args->db; + struct cil_tree_node *ast_current = args->ast; + struct cil_tree_node *tunif = args->tunif; + struct cil_tree_node *in = args->in; + struct cil_tree_node *macro = args->macro; + struct cil_tree_node *optional = args->optional; + struct cil_tree_node *boolif = args->boolif; struct cil_tree_node *ast_node = NULL; - struct cil_tree_node *macro = NULL; - struct cil_tree_node *boolif = NULL; - struct cil_tree_node *tunif = NULL; - struct cil_tree_node *in = NULL; int rc = SEPOL_ERR; - if (parse_current == NULL || finished == NULL || extra_args == NULL) { - goto exit; - } - - args = extra_args; - ast_current = args->ast; - db = args->db; - macro = args->macro; - boolif = args->boolif; - tunif = args->tunif; - in = args->in; - if (parse_current->parent->cl_head != parse_current) { /* ignore anything that isn't following a parenthesis */ rc = SEPOL_OK; @@ -6130,29 +6120,60 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f goto exit; } + if (tunif != NULL) { + if (parse_current->data == CIL_KEY_TUNABLE) { + rc = SEPOL_ERR; + cil_tree_log(parse_current, CIL_ERR, "Found tunable"); + cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n"); + goto exit; + } + } + + if (in != NULL) { + if (parse_current->data == CIL_KEY_IN) { + rc = SEPOL_ERR; + cil_tree_log(parse_current, CIL_ERR, "Found in-statement"); + cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n"); + goto exit; + } + } + if (macro != NULL) { - if (parse_current->data == CIL_KEY_MACRO || - parse_current->data == CIL_KEY_TUNABLE || + if (parse_current->data == CIL_KEY_TUNABLE || parse_current->data == CIL_KEY_IN || parse_current->data == CIL_KEY_BLOCK || parse_current->data == CIL_KEY_BLOCKINHERIT || - parse_current->data == CIL_KEY_BLOCKABSTRACT) { + parse_current->data == CIL_KEY_BLOCKABSTRACT || + parse_current->data == CIL_KEY_MACRO) { rc = SEPOL_ERR; cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in macros", (char *)parse_current->data); goto exit; } } + if (optional != NULL) { + if (parse_current->data == CIL_KEY_TUNABLE || + parse_current->data == CIL_KEY_IN || + parse_current->data == CIL_KEY_BLOCK || + parse_current->data == CIL_KEY_BLOCKABSTRACT || + parse_current->data == CIL_KEY_MACRO) { + rc = SEPOL_ERR; + cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in optionals", (char *)parse_current->data); + goto exit; + } + } + if (boolif != NULL) { - if (parse_current->data != CIL_KEY_CONDTRUE && + if (parse_current->data != CIL_KEY_TUNABLEIF && + parse_current->data != CIL_KEY_CALL && + parse_current->data != CIL_KEY_CONDTRUE && parse_current->data != CIL_KEY_CONDFALSE && - parse_current->data != CIL_KEY_AUDITALLOW && - parse_current->data != CIL_KEY_TUNABLEIF && parse_current->data != CIL_KEY_ALLOW && parse_current->data != CIL_KEY_DONTAUDIT && + parse_current->data != CIL_KEY_AUDITALLOW && parse_current->data != CIL_KEY_TYPETRANSITION && parse_current->data != CIL_KEY_TYPECHANGE && - parse_current->data != CIL_KEY_CALL) { + parse_current->data != CIL_KEY_TYPEMEMBER) { rc = SEPOL_ERR; cil_tree_log(parse_current, CIL_ERR, "Found %s", (char*)parse_current->data); if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { @@ -6166,24 +6187,6 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f } } - if (tunif != NULL) { - if (parse_current->data == CIL_KEY_TUNABLE) { - rc = SEPOL_ERR; - cil_tree_log(parse_current, CIL_ERR, "Found tunable"); - cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n"); - goto exit; - } - } - - if (in != NULL) { - if (parse_current->data == CIL_KEY_IN) { - rc = SEPOL_ERR; - cil_tree_log(parse_current, CIL_ERR, "Found in-statement"); - cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n"); - goto exit; - } - } - cil_tree_node_init(&ast_node); ast_node->parent = ast_current; @@ -6469,22 +6472,6 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f if (rc == SEPOL_OK) { if (ast_current->cl_head == NULL) { - if (ast_current->flavor == CIL_MACRO) { - args->macro = ast_current; - } - - if (ast_current->flavor == CIL_BOOLEANIF) { - args->boolif = ast_current; - } - - if (ast_current->flavor == CIL_TUNABLEIF) { - args->tunif = ast_current; - } - - if (ast_current->flavor == CIL_IN) { - args->in = ast_current; - } - ast_current->cl_head = ast_node; } else { ast_current->cl_tail->next = ast_node; @@ -6500,34 +6487,45 @@ exit: return rc; } -int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void *extra_args) +int __cil_build_ast_first_child_helper(__attribute__((unused)) struct cil_tree_node *parse_current, void *extra_args) { - int rc = SEPOL_ERR; - struct cil_tree_node *ast = NULL; - struct cil_args_build *args = NULL; + struct cil_args_build *args = extra_args; + struct cil_tree_node *ast = args->ast; - if (extra_args == NULL) { - goto exit; + if (ast->flavor == CIL_TUNABLEIF) { + args->tunif = ast; } - args = extra_args; - ast = args->ast; - - if (ast->flavor == CIL_ROOT) { - rc = SEPOL_OK; - goto exit; + if (ast->flavor == CIL_IN) { + args->in = ast; } - args->ast = ast->parent; - if (ast->flavor == CIL_MACRO) { - args->macro = NULL; + args->macro = ast; + } + + if (ast->flavor == CIL_OPTIONAL) { + args->optional = ast; } if (ast->flavor == CIL_BOOLEANIF) { - args->boolif = NULL; + args->boolif = ast; } + return SEPOL_OK; +} + +int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void *extra_args) +{ + struct cil_args_build *args = extra_args; + struct cil_tree_node *ast = args->ast; + + if (ast->flavor == CIL_ROOT) { + return SEPOL_OK; + } + + args->ast = ast->parent; + if (ast->flavor == CIL_TUNABLEIF) { args->tunif = NULL; } @@ -6536,6 +6534,27 @@ int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void args->in = NULL; } + if (ast->flavor == CIL_MACRO) { + args->macro = NULL; + } + + if (ast->flavor == CIL_OPTIONAL) { + struct cil_tree_node *n = ast->parent; + args->optional = NULL; + /* Optionals can be nested */ + while (n && n->flavor != CIL_ROOT) { + if (n->flavor == CIL_OPTIONAL) { + args->optional = n; + break; + } + n = n->parent; + } + } + + if (ast->flavor == CIL_BOOLEANIF) { + args->boolif = NULL; + } + // At this point we no longer have any need for parse_current or any of its // siblings; they have all been converted to the appropriate AST node. The // full parse tree will get deleted elsewhere, but in an attempt to @@ -6544,9 +6563,6 @@ int __cil_build_ast_last_child_helper(struct cil_tree_node *parse_current, void cil_tree_children_destroy(parse_current->parent); return SEPOL_OK; - -exit: - return rc; } int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct cil_tree_node *ast) @@ -6560,12 +6576,13 @@ int cil_build_ast(struct cil_db *db, struct cil_tree_node *parse_tree, struct ci extra_args.ast = ast; extra_args.db = db; - extra_args.macro = NULL; - extra_args.boolif = NULL; extra_args.tunif = NULL; extra_args.in = NULL; + extra_args.macro = NULL; + extra_args.optional = NULL; + extra_args.boolif = NULL; - rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, NULL, __cil_build_ast_last_child_helper, &extra_args); + rc = cil_tree_walk(parse_tree, __cil_build_ast_node_helper, __cil_build_ast_first_child_helper, __cil_build_ast_last_child_helper, &extra_args); if (rc != SEPOL_OK) { goto exit; } diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c index 3da1b9a64167862d11b3bb75eecdeb9b437921ab..89f91e568d0ee846efb4e188a56650745ad54f30 100644 --- a/libsepol/cil/src/cil_reset_ast.c +++ b/libsepol/cil/src/cil_reset_ast.c @@ -36,7 +36,7 @@ static void cil_reset_class(struct cil_class *class) static void cil_reset_perm(struct cil_perm *perm) { - cil_reset_classperms_list(perm->classperms); + cil_list_destroy(&perm->classperms, CIL_FALSE); } static inline void cil_reset_classperms(struct cil_classperms *cp) @@ -54,7 +54,7 @@ static void cil_reset_classpermission(struct cil_classpermission *cp) return; } - cil_reset_classperms_list(cp->classperms); + cil_list_destroy(&cp->classperms, CIL_FALSE); } static void cil_reset_classperms_set(struct cil_classperms_set *cp_set) diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c index 0e07856133e5d2865bd184b797a46efac5d6e674..b5edfc04fd45d41fe17b1e14c96349e1ad9f9c43 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 *boolif; + struct cil_tree_node *block; struct cil_tree_node *macro; - struct cil_tree_node *blockstack; + struct cil_tree_node *optional; + struct cil_tree_node *boolif; struct cil_list *sidorder_lists; struct cil_list *classorder_lists; struct cil_list *unordered_classorder_lists; @@ -3775,59 +3775,70 @@ exit: int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) { - int rc = SEPOL_ERR; + int rc = SEPOL_OK; struct cil_args_resolve *args = extra_args; 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; + struct cil_tree_node *block = args->block; struct cil_tree_node *macro = args->macro; + struct cil_tree_node *optional = args->optional; + struct cil_tree_node *boolif = args->boolif; if (node == NULL) { goto exit; } - if (optstack != 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)); + 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; goto exit; } } - if (blockstack != 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)); + if (macro != NULL) { + if (node->flavor == CIL_BLOCK || + node->flavor == CIL_BLOCKINHERIT || + node->flavor == CIL_BLOCKABSTRACT || + node->flavor == CIL_MACRO) { + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in macros", cil_node_to_string(node)); rc = SEPOL_ERR; goto exit; } } - if (macro != NULL) { - if (node->flavor == CIL_BLOCKINHERIT || + if (optional != NULL) { + if (node->flavor == CIL_TUNABLE || + node->flavor == CIL_IN || node->flavor == CIL_BLOCK || node->flavor == CIL_BLOCKABSTRACT || - node->flavor == CIL_MACRO) { - cil_tree_log(node, CIL_ERR, "%s statement is not allowed in macros", cil_node_to_string(node)); + node->flavor == CIL_MACRO) { + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in optionals", cil_node_to_string(node)); rc = SEPOL_ERR; goto exit; } } if (boolif != NULL) { - if (!(node->flavor == CIL_CONDBLOCK || - node->flavor == CIL_AVRULE || - node->flavor == CIL_TYPE_RULE || - node->flavor == CIL_CALL || - node->flavor == CIL_TUNABLEIF || - node->flavor == CIL_NAMETYPETRANSITION)) { + if (node->flavor != CIL_TUNABLEIF && + node->flavor != CIL_CALL && + node->flavor != CIL_CONDBLOCK && + node->flavor != CIL_AVRULE && + node->flavor != CIL_TYPE_RULE && + node->flavor != CIL_NAMETYPETRANSITION) { + rc = SEPOL_ERR; + } else if (node->flavor == CIL_AVRULE) { + struct cil_avrule *rule = node->data; + if (rule->rule_kind == CIL_AVRULE_NEVERALLOW) { + rc = SEPOL_ERR; + } + } + if (rc == SEPOL_ERR) { if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs (tunableif treated as a booleanif)", cil_node_to_string(node)); } else { cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs", cil_node_to_string(node)); } - rc = SEPOL_ERR; goto exit; } } @@ -3850,11 +3861,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)); @@ -3877,43 +3888,22 @@ 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; - } - } else if (parent->flavor == CIL_BOOLEANIF) { - args->boolif = parent; + if (parent->flavor == CIL_BLOCK) { + args->block = parent; } else if (parent->flavor == CIL_MACRO) { args->macro = parent; + } else if (parent->flavor == CIL_OPTIONAL) { + args->optional = parent; + } else if (parent->flavor == CIL_BOOLEANIF) { + args->boolif = parent; } return SEPOL_OK; @@ -3928,7 +3918,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; @@ -3936,33 +3925,34 @@ int __cil_resolve_ast_last_child_helper(struct cil_tree_node *current, void *ext parent = current->parent; - if (parent->flavor == CIL_MACRO) { + if (parent->flavor == CIL_BLOCK) { + 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; + } + } else 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; - } - free(blockstack); } return SEPOL_OK; @@ -3971,16 +3961,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; @@ -3995,16 +3975,16 @@ 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.boolif= NULL; + extra_args.block = NULL; extra_args.macro = NULL; + extra_args.optional = NULL; + extra_args.boolif= NULL; extra_args.sidorder_lists = NULL; extra_args.classorder_lists = NULL; extra_args.unordered_classorder_lists = NULL; 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); @@ -4108,17 +4088,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; } } @@ -4129,8 +4099,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); diff --git a/secilc/docs/cil_call_macro_statements.md b/secilc/docs/cil_call_macro_statements.md index 332eb28f4256c65f301de6f4477ece6f3f007211..352a9fb06efef38bd4ff377ef1ea25b9ac3f109e 100644 --- a/secilc/docs/cil_call_macro_statements.md +++ b/secilc/docs/cil_call_macro_statements.md @@ -58,6 +58,8 @@ When resolving macros the following places are checked in this order: - Items defined in the global namespace +[`tunable`](cil_conditional_statements.md#tunable), [`in`](cil_container_statements.md#in), [`block`](cil_container_statements.md#block), [`blockinherit`](cil_container_statements.md#blockinherit), [`blockabstract`](cil_container_statements.md#blockabstract), and other [`macro`](cil_call_macro_statements.md#macro) statements are not allowed in [`macro`](cil_call_macro_statements.md#macro) blocks. + **Statement definition:** ```secil diff --git a/secilc/docs/cil_conditional_statements.md b/secilc/docs/cil_conditional_statements.md index a55a9b6cccd6e3ee52bf05c8cd1ff81dda125f50..d0c8e2ce483290c281d3a154625288b67349118d 100644 --- a/secilc/docs/cil_conditional_statements.md +++ b/secilc/docs/cil_conditional_statements.md @@ -6,6 +6,8 @@ boolean Declares a run time boolean as true or false in the current namespace. The [`booleanif`](cil_conditional_statements.md#booleanif) statement contains the CIL code that will be in the binary policy file. +[`boolean`](cil_conditional_statements.md#boolean) are not allowed in [`booleanif`](cil_conditional_statements.md#booleanif) blocks. + **Statement definition:** ```secil @@ -126,6 +128,8 @@ Tunables are similar to booleans, however they are used to manage areas of CIL s Note that tunables can be treated as booleans by the CIL compiler command line parameter `-P` or `--preserve-tunables` flags. +Since [`tunableif`](cil_conditional_statements.md#tunableif) statements are resolved first, [`tunable`](cil_conditional_statements.md#tunable) statements are not allowed in [`in`](cil_container_statements.md#in), [`macro`](cil_call_macro_statements.md#macro), [`optional`](cil_container_statements.md#optional), and [`booleanif`](cil_conditional_statements.md#booleanif) blocks. To simplify processing, they are also not allowed in [`tunableif`](cil_conditional_statements.md#tunableif) blocks. + **Statement definition:** ```secil @@ -164,6 +168,8 @@ tunableif Compile time conditional statement that may or may not add CIL statements to be compiled. +If tunables are being treated as booleans (by using the CIL compiler command line parameter `-P` or `--preserve-tunables` flag), then only the statements allowed in a [`booleanif`](cil_conditional_statements.md#booleanif) block are allowed in a [`tunableif`](cil_conditional_statements.md#tunableif) block. Otherwise, [`tunable`](cil_conditional_statements.md#tunable) statements are not allowed in a [`tunableif`](cil_conditional_statements.md#tunableif) block. + **Statement definition:** ```secil diff --git a/secilc/docs/cil_container_statements.md b/secilc/docs/cil_container_statements.md index 76e9da51f0bc7d88764f050eb50782ac182f7dbd..7a7f67cc27c4bbdabf821919e096386bf480e8db 100644 --- a/secilc/docs/cil_container_statements.md +++ b/secilc/docs/cil_container_statements.md @@ -4,7 +4,11 @@ Container Statements block ----- -Start a new namespace where any CIL statement is valid. +Start a new namespace. + +Not allowed in [`macro`](cil_call_macro_statements.md#macro) and [`optional`](cil_container_statements.md#optional) blocks. + +[`sensitivity`](cil_mls_labeling_statements.md#sensitivity) and [`category`](cil_mls_labeling_statements.md#category) statements are not allowed in [`block`](cil_container_statements.md#block) blocks. **Statement definition:** @@ -47,6 +51,8 @@ blockabstract Declares the namespace as a 'template' and does not generate code until instantiated by another namespace that has a [`blockinherit`](cil_container_statements.md#blockinherit) statement. +Not allowed in [`macro`](cil_call_macro_statements.md#macro) and [`optional`](cil_container_statements.md#optional) blocks. + **Statement definition:** ```secil @@ -97,6 +103,8 @@ blockinherit Used to add common policy rules to the current namespace via a template that has been defined with the [`blockabstract`](cil_container_statements.md#blockabstract) statement. All [`blockinherit`](cil_container_statements.md#blockinherit) statements are resolved first and then the contents of the block are copied. This is so that inherited blocks will not be inherited. For a concrete example, please see the examples section. +Not allowed in [`macro`](cil_call_macro_statements.md#macro) blocks. + **Statement definition:** ```secil @@ -199,15 +207,11 @@ This example contains a template `client_server` that is instantiated in two blo optional -------- -Declare an [`optional`](cil_container_statements.md#optional) namespace. All CIL statements in the optional block must be satisfied before instantiation in the binary policy. [`tunableif`](cil_conditional_statements.md#tunableif) and [`macro`](cil_call_macro_statements.md#macro) statements are not allowed in optional containers. The same restrictions apply to CIL policy statements within [`optional`](cil_container_statements.md#optional)'s that apply to kernel policy statements, i.e. only the policy statements shown in the following table are valid: +Declare an [`optional`](cil_container_statements.md#optional) namespace. All CIL statements in the optional block must be satisfied before instantiation in the binary policy. -| | | | | -| ------------------- | -------------- | ------------------ | ------------------ | -| [`allow`](cil_access_vector_rules.md#allow) | [`allowx`](cil_access_vector_rules.md#allowx) | [`auditallow`](cil_access_vector_rules.md#auditallow) | [`auditallowx`](cil_access_vector_rules.md#auditallowx) | -| [`booleanif`](cil_conditional_statements.md#booleanif) | [`dontaudit`](cil_access_vector_rules.md#dontaudit) | [`dontauditx`](cil_access_vector_rules.md#dontauditx) | [`typepermissive`](cil_type_statements.md#typepermissive) | -| [`rangetransition`](cil_mls_labeling_statements.md#rangetransition) | [`role`](cil_role_statements.md#role) | [`roleallow`](cil_role_statements.md#roleallow) | [`roleattribute`](cil_role_statements.md#roleattribute) | -| [`roletransition`](cil_role_statements.md#roletransition) | [`type`](cil_type_statements.md#type) | [`typealias`](cil_type_statements.md#typealias) | [`typeattribute`](cil_type_statements.md#typeattribute) | -| [`typechange`](cil_type_statements.md#typechange) | [`typemember`](cil_type_statements.md#typemember) | [`typetransition`](cil_type_statements.md#typetransition) | | +Not allowed in [`booleanif`](cil_conditional_statements.md#booleanif) blocks. + +[`tunable`](cil_conditional_statements.md#tunable), [`in`](cil_container_statements.md#in), [`block`](cil_container_statements.md#block), [`blockabstract`](cil_container_statements.md#blockabstract), and [`macro`](cil_call_macro_statements.md#macro) statements are not allowed in [`optional`](cil_container_statements.md#optional) blocks. **Statement definition:** @@ -266,7 +270,11 @@ This example will instantiate the optional block `ext_gateway.move_file` into po in -- -Allows the insertion of CIL statements into a named container ([`block`](cil_container_statements.md#block), [`optional`](cil_container_statements.md#optional) or [`macro`](cil_call_macro_statements.md#macro)). This statement is not allowed in [`booleanif`](cil_conditional_statements.md#booleanif) or [`tunableif`](cil_conditional_statements.md#tunableif) statements. This only works for containers that aren't inherited using [`blockinherit`](cil_conditional_statements.md#blockinherit). +Allows the insertion of CIL statements into a named container ([`block`](cil_container_statements.md#block), [`optional`](cil_container_statements.md#optional) or [`macro`](cil_call_macro_statements.md#macro)). + +Not allowed in [`macro`](cil_call_macro_statements.md#macro), [`booleanif`](cil_conditional_statements.md#booleanif), and other [`in`](cil_container_statements.md#in) blocks. + +[`tunable`](cil_conditional_statements.md#tunable) and [`in`](cil_container_statements.md#in) statements are not allowed in [`in`](cil_container_statements.md#in) blocks. **Statement definition:**