From 05e8f155d5cdbf6f997199a31651d43512605cf3 Mon Sep 17 00:00:00 2001 From: James Carter Date: Mon, 30 Aug 2021 14:23:12 -0400 Subject: [PATCH] libsepol/cil: Refactor the function __cil_build_ast_node_helper() Refactor the function __cil_build_ast_node_helper() by moving the check for illegal statements and the large if-then-else statement to determine which function to call to parse the policy statements to different functions. There is no need to keep walking the nodes of a policy statement that has already been completely parsed. This means that the remaining nodes of any policy statement that does not contain a list of policy statements can be skipped. This was done inconsistently before. The following policy statements now have all nodes after the first one skipped: blockinherit, blockabstract, classcommon, user, userattribute, userbounds, userprefix, type, typeattribute, typealias, typealiasactual, typebounds, typepermissive, role, userrole, roletype, roletransition, roleallow, roleattribute, rolebounds, bool, tunable, typetransition, typechange, typemember, sensitivity, sensitivityalias, senistivityaliasactual, category, categoryalias, categoryaliasactual, and ipaddr. The only policy statements that do contain a list of policy statements are: block, in, tunableif, booleanif, true (conditional block), false (conditional block), macro, optional, and src_info. Signed-off-by: James Carter --- libsepol/cil/src/cil_build_ast.c | 418 ++++++++++++++----------------- 1 file changed, 185 insertions(+), 233 deletions(-) diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c index a5afc267..521c3012 100644 --- a/libsepol/cil/src/cil_build_ast.c +++ b/libsepol/cil/src/cil_build_ast.c @@ -6108,77 +6108,47 @@ void cil_destroy_src_info(struct cil_src_info *info) free(info); } -int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args) +static int check_for_illegal_statement(struct cil_tree_node *parse_current, struct cil_args_build *args) { - 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; - int rc = SEPOL_ERR; - - if (parse_current->parent->cl_head != parse_current) { - /* ignore anything that isn't following a parenthesis */ - rc = SEPOL_OK; - goto exit; - } else if (parse_current->data == NULL) { - /* the only time parenthesis can immediately following parenthesis is if - * the parent is the root node */ - if (parse_current->parent->parent == NULL) { - rc = SEPOL_OK; - } else { - cil_tree_log(parse_current, CIL_ERR, "Keyword expected after open parenthesis"); - } - goto exit; - } - - if (tunif != NULL) { + if (args->tunif != NULL) { if (parse_current->data == CIL_KEY_TUNABLE) { - rc = SEPOL_ERR; cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in tunableif", (char *)parse_current->data); - goto exit; + return SEPOL_ERR; } } - if (in != NULL) { + if (args->in != NULL) { if (parse_current->data == CIL_KEY_TUNABLE || parse_current->data == CIL_KEY_IN) { - rc = SEPOL_ERR; cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in in-statement", (char *)parse_current->data); - goto exit; + return SEPOL_ERR; } } - if (macro != NULL) { + if (args->macro != 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_BLOCKINHERIT || 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 macro", (char *)parse_current->data); - goto exit; + return SEPOL_ERR; } } - if (optional != NULL) { + if (args->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 optional", (char *)parse_current->data); - goto exit; + return SEPOL_ERR; } } - if (boolif != NULL) { + if (args->boolif != NULL) { if (parse_current->data != CIL_KEY_TUNABLEIF && parse_current->data != CIL_KEY_CALL && parse_current->data != CIL_KEY_CONDTRUE && @@ -6189,314 +6159,304 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f parse_current->data != CIL_KEY_TYPETRANSITION && parse_current->data != CIL_KEY_TYPECHANGE && parse_current->data != CIL_KEY_TYPEMEMBER) { - rc = SEPOL_ERR; - if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { + if (((struct cil_booleanif*)args->boolif->data)->preserved_tunable) { cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in tunableif being treated as a booleanif", (char *)parse_current->data); } else { cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in booleanif", (char *)parse_current->data); } - goto exit; + return SEPOL_ERR; } } - cil_tree_node_init(&ast_node); + return SEPOL_OK; +} - ast_node->parent = ast_current; - ast_node->line = parse_current->line; - ast_node->hll_offset = parse_current->hll_offset; +static struct cil_tree_node * parse_statement(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_parent) +{ + struct cil_tree_node *new_ast_node = NULL; + int rc = SEPOL_ERR; + + cil_tree_node_init(&new_ast_node); + new_ast_node->parent = ast_parent; + new_ast_node->line = parse_current->line; + new_ast_node->hll_offset = parse_current->hll_offset; if (parse_current->data == CIL_KEY_BLOCK) { - rc = cil_gen_block(db, parse_current, ast_node, 0); + rc = cil_gen_block(db, parse_current, new_ast_node, 0); } else if (parse_current->data == CIL_KEY_BLOCKINHERIT) { - rc = cil_gen_blockinherit(db, parse_current, ast_node); + rc = cil_gen_blockinherit(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_BLOCKABSTRACT) { - rc = cil_gen_blockabstract(db, parse_current, ast_node); + rc = cil_gen_blockabstract(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_IN) { - rc = cil_gen_in(db, parse_current, ast_node); + rc = cil_gen_in(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_CLASS) { - rc = cil_gen_class(db, parse_current, ast_node); - // To avoid parsing list of perms again - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_class(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_CLASSORDER) { - rc = cil_gen_classorder(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_classorder(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_MAP_CLASS) { - rc = cil_gen_map_class(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_map_class(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_CLASSMAPPING) { - rc = cil_gen_classmapping(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_classmapping(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_CLASSPERMISSION) { - rc = cil_gen_classpermission(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_classpermission(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_CLASSPERMISSIONSET) { - rc = cil_gen_classpermissionset(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_classpermissionset(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_COMMON) { - rc = cil_gen_common(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_common(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_CLASSCOMMON) { - rc = cil_gen_classcommon(db, parse_current, ast_node); + rc = cil_gen_classcommon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_SID) { - rc = cil_gen_sid(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_sid(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_SIDCONTEXT) { - rc = cil_gen_sidcontext(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_sidcontext(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_SIDORDER) { - rc = cil_gen_sidorder(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_sidorder(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_USER) { - rc = cil_gen_user(db, parse_current, ast_node); + rc = cil_gen_user(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_USERATTRIBUTE) { - rc = cil_gen_userattribute(db, parse_current, ast_node); + rc = cil_gen_userattribute(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_USERATTRIBUTESET) { - rc = cil_gen_userattributeset(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_userattributeset(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_USERLEVEL) { - rc = cil_gen_userlevel(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_userlevel(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_USERRANGE) { - rc = cil_gen_userrange(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_userrange(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_USERBOUNDS) { - rc = cil_gen_bounds(db, parse_current, ast_node, CIL_USER); + rc = cil_gen_bounds(db, parse_current, new_ast_node, CIL_USER); } else if (parse_current->data == CIL_KEY_USERPREFIX) { - rc = cil_gen_userprefix(db, parse_current, ast_node); + rc = cil_gen_userprefix(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_SELINUXUSER) { - rc = cil_gen_selinuxuser(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_selinuxuser(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_SELINUXUSERDEFAULT) { - rc = cil_gen_selinuxuserdefault(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_selinuxuserdefault(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_TYPE) { - rc = cil_gen_type(db, parse_current, ast_node); + rc = cil_gen_type(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_TYPEATTRIBUTE) { - rc = cil_gen_typeattribute(db, parse_current, ast_node); + rc = cil_gen_typeattribute(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_TYPEATTRIBUTESET) { - rc = cil_gen_typeattributeset(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_typeattributeset(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_EXPANDTYPEATTRIBUTE) { - rc = cil_gen_expandtypeattribute(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_expandtypeattribute(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_TYPEALIAS) { - rc = cil_gen_alias(db, parse_current, ast_node, CIL_TYPEALIAS); + rc = cil_gen_alias(db, parse_current, new_ast_node, CIL_TYPEALIAS); } else if (parse_current->data == CIL_KEY_TYPEALIASACTUAL) { - rc = cil_gen_aliasactual(db, parse_current, ast_node, CIL_TYPEALIASACTUAL); + rc = cil_gen_aliasactual(db, parse_current, new_ast_node, CIL_TYPEALIASACTUAL); } else if (parse_current->data == CIL_KEY_TYPEBOUNDS) { - rc = cil_gen_bounds(db, parse_current, ast_node, CIL_TYPE); + rc = cil_gen_bounds(db, parse_current, new_ast_node, CIL_TYPE); } else if (parse_current->data == CIL_KEY_TYPEPERMISSIVE) { - rc = cil_gen_typepermissive(db, parse_current, ast_node); + rc = cil_gen_typepermissive(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_RANGETRANSITION) { - rc = cil_gen_rangetransition(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_rangetransition(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_ROLE) { - rc = cil_gen_role(db, parse_current, ast_node); + rc = cil_gen_role(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_USERROLE) { - rc = cil_gen_userrole(db, parse_current, ast_node); + rc = cil_gen_userrole(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_ROLETYPE) { - rc = cil_gen_roletype(db, parse_current, ast_node); + rc = cil_gen_roletype(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_ROLETRANSITION) { - rc = cil_gen_roletransition(parse_current, ast_node); + rc = cil_gen_roletransition(parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_ROLEALLOW) { - rc = cil_gen_roleallow(db, parse_current, ast_node); + rc = cil_gen_roleallow(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_ROLEATTRIBUTE) { - rc = cil_gen_roleattribute(db, parse_current, ast_node); + rc = cil_gen_roleattribute(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_ROLEATTRIBUTESET) { - rc = cil_gen_roleattributeset(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_roleattributeset(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_ROLEBOUNDS) { - rc = cil_gen_bounds(db, parse_current, ast_node, CIL_ROLE); + rc = cil_gen_bounds(db, parse_current, new_ast_node, CIL_ROLE); } else if (parse_current->data == CIL_KEY_BOOL) { - rc = cil_gen_bool(db, parse_current, ast_node, CIL_FALSE); + rc = cil_gen_bool(db, parse_current, new_ast_node, CIL_FALSE); } else if (parse_current->data == CIL_KEY_BOOLEANIF) { - rc = cil_gen_boolif(db, parse_current, ast_node, CIL_FALSE); + rc = cil_gen_boolif(db, parse_current, new_ast_node, CIL_FALSE); } else if(parse_current->data == CIL_KEY_TUNABLE) { if (db->preserve_tunables) { - rc = cil_gen_bool(db, parse_current, ast_node, CIL_TRUE); + rc = cil_gen_bool(db, parse_current, new_ast_node, CIL_TRUE); } else { - rc = cil_gen_tunable(db, parse_current, ast_node); + rc = cil_gen_tunable(db, parse_current, new_ast_node); } } else if (parse_current->data == CIL_KEY_TUNABLEIF) { if (db->preserve_tunables) { - rc = cil_gen_boolif(db, parse_current, ast_node, CIL_TRUE); + rc = cil_gen_boolif(db, parse_current, new_ast_node, CIL_TRUE); } else { - rc = cil_gen_tunif(db, parse_current, ast_node); + rc = cil_gen_tunif(db, parse_current, new_ast_node); } } else if (parse_current->data == CIL_KEY_CONDTRUE) { - rc = cil_gen_condblock(db, parse_current, ast_node, CIL_CONDTRUE); + rc = cil_gen_condblock(db, parse_current, new_ast_node, CIL_CONDTRUE); } else if (parse_current->data == CIL_KEY_CONDFALSE) { - rc = cil_gen_condblock(db, parse_current, ast_node, CIL_CONDFALSE); + rc = cil_gen_condblock(db, parse_current, new_ast_node, CIL_CONDFALSE); } else if (parse_current->data == CIL_KEY_ALLOW) { - rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_ALLOWED); - // So that the object and perms lists do not get parsed again - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_avrule(parse_current, new_ast_node, CIL_AVRULE_ALLOWED); } else if (parse_current->data == CIL_KEY_AUDITALLOW) { - rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_AUDITALLOW); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_avrule(parse_current, new_ast_node, CIL_AVRULE_AUDITALLOW); } else if (parse_current->data == CIL_KEY_DONTAUDIT) { - rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_DONTAUDIT); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_avrule(parse_current, new_ast_node, CIL_AVRULE_DONTAUDIT); } else if (parse_current->data == CIL_KEY_NEVERALLOW) { - rc = cil_gen_avrule(parse_current, ast_node, CIL_AVRULE_NEVERALLOW); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_avrule(parse_current, new_ast_node, CIL_AVRULE_NEVERALLOW); } else if (parse_current->data == CIL_KEY_ALLOWX) { - rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_ALLOWED); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_avrulex(parse_current, new_ast_node, CIL_AVRULE_ALLOWED); } else if (parse_current->data == CIL_KEY_AUDITALLOWX) { - rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_AUDITALLOW); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_avrulex(parse_current, new_ast_node, CIL_AVRULE_AUDITALLOW); } else if (parse_current->data == CIL_KEY_DONTAUDITX) { - rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_DONTAUDIT); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_avrulex(parse_current, new_ast_node, CIL_AVRULE_DONTAUDIT); } else if (parse_current->data == CIL_KEY_NEVERALLOWX) { - rc = cil_gen_avrulex(parse_current, ast_node, CIL_AVRULE_NEVERALLOW); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_avrulex(parse_current, new_ast_node, CIL_AVRULE_NEVERALLOW); } else if (parse_current->data == CIL_KEY_PERMISSIONX) { - rc = cil_gen_permissionx(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_permissionx(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_TYPETRANSITION) { - rc = cil_gen_typetransition(db, parse_current, ast_node); + rc = cil_gen_typetransition(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_TYPECHANGE) { - rc = cil_gen_type_rule(parse_current, ast_node, CIL_TYPE_CHANGE); + rc = cil_gen_type_rule(parse_current, new_ast_node, CIL_TYPE_CHANGE); } else if (parse_current->data == CIL_KEY_TYPEMEMBER) { - rc = cil_gen_type_rule(parse_current, ast_node, CIL_TYPE_MEMBER); + rc = cil_gen_type_rule(parse_current, new_ast_node, CIL_TYPE_MEMBER); } else if (parse_current->data == CIL_KEY_SENSITIVITY) { - rc = cil_gen_sensitivity(db, parse_current, ast_node); + rc = cil_gen_sensitivity(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_SENSALIAS) { - rc = cil_gen_alias(db, parse_current, ast_node, CIL_SENSALIAS); + rc = cil_gen_alias(db, parse_current, new_ast_node, CIL_SENSALIAS); } else if (parse_current->data == CIL_KEY_SENSALIASACTUAL) { - rc = cil_gen_aliasactual(db, parse_current, ast_node, CIL_SENSALIASACTUAL); + rc = cil_gen_aliasactual(db, parse_current, new_ast_node, CIL_SENSALIASACTUAL); } else if (parse_current->data == CIL_KEY_CATEGORY) { - rc = cil_gen_category(db, parse_current, ast_node); + rc = cil_gen_category(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_CATALIAS) { - rc = cil_gen_alias(db, parse_current, ast_node, CIL_CATALIAS); + rc = cil_gen_alias(db, parse_current, new_ast_node, CIL_CATALIAS); } else if (parse_current->data == CIL_KEY_CATALIASACTUAL) { - rc = cil_gen_aliasactual(db, parse_current, ast_node, CIL_CATALIASACTUAL); + rc = cil_gen_aliasactual(db, parse_current, new_ast_node, CIL_CATALIASACTUAL); } else if (parse_current->data == CIL_KEY_CATSET) { - rc = cil_gen_catset(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_catset(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_CATORDER) { - rc = cil_gen_catorder(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_catorder(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_SENSITIVITYORDER) { - rc = cil_gen_sensitivityorder(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_sensitivityorder(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_SENSCAT) { - rc = cil_gen_senscat(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_senscat(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_LEVEL) { - rc = cil_gen_level(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_level(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_LEVELRANGE) { - rc = cil_gen_levelrange(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_levelrange(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_CONSTRAIN) { - rc = cil_gen_constrain(db, parse_current, ast_node, CIL_CONSTRAIN); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_constrain(db, parse_current, new_ast_node, CIL_CONSTRAIN); } else if (parse_current->data == CIL_KEY_MLSCONSTRAIN) { - rc = cil_gen_constrain(db, parse_current, ast_node, CIL_MLSCONSTRAIN); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_constrain(db, parse_current, new_ast_node, CIL_MLSCONSTRAIN); } else if (parse_current->data == CIL_KEY_VALIDATETRANS) { - rc = cil_gen_validatetrans(db, parse_current, ast_node, CIL_VALIDATETRANS); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_validatetrans(db, parse_current, new_ast_node, CIL_VALIDATETRANS); } else if (parse_current->data == CIL_KEY_MLSVALIDATETRANS) { - rc = cil_gen_validatetrans(db, parse_current, ast_node, CIL_MLSVALIDATETRANS); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_validatetrans(db, parse_current, new_ast_node, CIL_MLSVALIDATETRANS); } else if (parse_current->data == CIL_KEY_CONTEXT) { - rc = cil_gen_context(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_context(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_FILECON) { - rc = cil_gen_filecon(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_filecon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_IBPKEYCON) { - rc = cil_gen_ibpkeycon(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_ibpkeycon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_IBENDPORTCON) { - rc = cil_gen_ibendportcon(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_ibendportcon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_PORTCON) { - rc = cil_gen_portcon(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_portcon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_NODECON) { - rc = cil_gen_nodecon(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_nodecon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_GENFSCON) { - rc = cil_gen_genfscon(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_genfscon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_NETIFCON) { - rc = cil_gen_netifcon(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_netifcon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_PIRQCON) { - rc = cil_gen_pirqcon(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_pirqcon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_IOMEMCON) { - rc = cil_gen_iomemcon(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_iomemcon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_IOPORTCON) { - rc = cil_gen_ioportcon(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_ioportcon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_PCIDEVICECON) { - rc = cil_gen_pcidevicecon(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_pcidevicecon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_DEVICETREECON) { - rc = cil_gen_devicetreecon(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_devicetreecon(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_FSUSE) { - rc = cil_gen_fsuse(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_fsuse(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_MACRO) { - rc = cil_gen_macro(db, parse_current, ast_node); + rc = cil_gen_macro(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_CALL) { - rc = cil_gen_call(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_call(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_POLICYCAP) { - rc = cil_gen_policycap(db, parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_policycap(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_OPTIONAL) { - rc = cil_gen_optional(db, parse_current, ast_node); + rc = cil_gen_optional(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_IPADDR) { - rc = cil_gen_ipaddr(db, parse_current, ast_node); + rc = cil_gen_ipaddr(db, parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_DEFAULTUSER) { - rc = cil_gen_default(parse_current, ast_node, CIL_DEFAULTUSER); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_default(parse_current, new_ast_node, CIL_DEFAULTUSER); } else if (parse_current->data == CIL_KEY_DEFAULTROLE) { - rc = cil_gen_default(parse_current, ast_node, CIL_DEFAULTROLE); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_default(parse_current, new_ast_node, CIL_DEFAULTROLE); } else if (parse_current->data == CIL_KEY_DEFAULTTYPE) { - rc = cil_gen_default(parse_current, ast_node, CIL_DEFAULTTYPE); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_default(parse_current, new_ast_node, CIL_DEFAULTTYPE); } else if (parse_current->data == CIL_KEY_DEFAULTRANGE) { - rc = cil_gen_defaultrange(parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_defaultrange(parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_HANDLEUNKNOWN) { - rc = cil_gen_handleunknown(parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_handleunknown(parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_MLS) { - rc = cil_gen_mls(parse_current, ast_node); - *finished = CIL_TREE_SKIP_NEXT; + rc = cil_gen_mls(parse_current, new_ast_node); } else if (parse_current->data == CIL_KEY_SRC_INFO) { - rc = cil_gen_src_info(parse_current, ast_node); + rc = cil_gen_src_info(parse_current, new_ast_node); } else { cil_log(CIL_ERR, "Error: Unknown keyword %s\n", (char *)parse_current->data); rc = SEPOL_ERR; } if (rc == SEPOL_OK) { - if (ast_current->cl_head == NULL) { - ast_current->cl_head = ast_node; + if (ast_parent->cl_head == NULL) { + ast_parent->cl_head = new_ast_node; } else { - ast_current->cl_tail->next = ast_node; + ast_parent->cl_tail->next = new_ast_node; } - ast_current->cl_tail = ast_node; - ast_current = ast_node; - args->ast = ast_current; + ast_parent->cl_tail = new_ast_node; } else { - cil_tree_node_destroy(&ast_node); + cil_tree_node_destroy(&new_ast_node); + new_ast_node = NULL; } -exit: - return rc; + return new_ast_node; +} + +int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args) +{ + struct cil_args_build *args = extra_args; + struct cil_tree_node *new_ast_node = NULL; + int rc = SEPOL_ERR; + + if (parse_current->parent->cl_head != parse_current) { + /* ignore anything that isn't following a parenthesis */ + return SEPOL_OK; + } else if (parse_current->data == NULL) { + /* the only time parenthesis can immediately following parenthesis is if + * the parent is the root node */ + if (parse_current->parent->parent == NULL) { + return SEPOL_OK; + } else { + cil_tree_log(parse_current, CIL_ERR, "Keyword expected after open parenthesis"); + return SEPOL_ERR; + } + } + + rc = check_for_illegal_statement(parse_current, args); + if (rc != SEPOL_OK) { + return SEPOL_ERR; + } + + new_ast_node = parse_statement(args->db, parse_current, args->ast); + if (!new_ast_node) { + return SEPOL_ERR; + } + + args->ast = new_ast_node; + + if (parse_current->data != CIL_KEY_BLOCK && + parse_current->data != CIL_KEY_IN && + parse_current->data != CIL_KEY_TUNABLEIF && + parse_current->data != CIL_KEY_BOOLEANIF && + parse_current->data != CIL_KEY_CONDTRUE && + parse_current->data != CIL_KEY_CONDFALSE && + parse_current->data != CIL_KEY_MACRO && + parse_current->data != CIL_KEY_OPTIONAL && + parse_current->data != CIL_KEY_SRC_INFO) { + /* Skip anything that does not contain a list of policy statements */ + *finished = CIL_TREE_SKIP_NEXT; + } + + return SEPOL_OK; } int __cil_build_ast_first_child_helper(__attribute__((unused)) struct cil_tree_node *parse_current, void *extra_args) @@ -6506,21 +6466,13 @@ int __cil_build_ast_first_child_helper(__attribute__((unused)) struct cil_tree_n if (ast->flavor == CIL_TUNABLEIF) { args->tunif = ast; - } - - if (ast->flavor == CIL_IN) { + } else if (ast->flavor == CIL_IN) { args->in = ast; - } - - if (ast->flavor == CIL_MACRO) { + } else if (ast->flavor == CIL_MACRO) { args->macro = ast; - } - - if (ast->flavor == CIL_OPTIONAL) { + } else if (ast->flavor == CIL_OPTIONAL) { args->optional = ast; - } - - if (ast->flavor == CIL_BOOLEANIF) { + } else if (ast->flavor == CIL_BOOLEANIF) { args->boolif = ast; }