diff -r -u libsepol-3.2_orig/cil/src/cil_build_ast.c libsepol-3.2/cil/src/cil_build_ast.c --- libsepol-3.2_orig/cil/src/cil_build_ast.c 2021-07-21 15:15:01.875585374 +0200 +++ libsepol-3.2/cil/src/cil_build_ast.c 2021-07-21 15:15:10.655704516 +0200 @@ -50,6 +50,7 @@ struct cil_tree_node *ast; struct cil_db *db; struct cil_tree_node *macro; + struct cil_tree_node *optional; struct cil_tree_node *boolif; struct cil_tree_node *tunif; struct cil_tree_node *in; @@ -6098,6 +6099,7 @@ struct cil_db *db = NULL; struct cil_tree_node *ast_node = NULL; struct cil_tree_node *macro = NULL; + struct cil_tree_node *optional = NULL; struct cil_tree_node *boolif = NULL; struct cil_tree_node *tunif = NULL; struct cil_tree_node *in = NULL; @@ -6143,6 +6145,18 @@ } } + 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 && parse_current->data != CIL_KEY_CONDFALSE && @@ -6524,6 +6538,19 @@ 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; } @@ -6561,6 +6588,7 @@ extra_args.ast = ast; extra_args.db = db; extra_args.macro = NULL; + extra_args.optional = NULL; extra_args.boolif = NULL; extra_args.tunif = NULL; extra_args.in = NULL; diff -r -u libsepol-3.2_orig/cil/src/cil_resolve_ast.c libsepol-3.2/cil/src/cil_resolve_ast.c --- libsepol-3.2_orig/cil/src/cil_resolve_ast.c 2021-07-21 15:15:01.879585428 +0200 +++ libsepol-3.2/cil/src/cil_resolve_ast.c 2021-07-21 15:15:15.559771063 +0200 @@ -3788,8 +3788,11 @@ } if (optstack != NULL) { - if (node->flavor == CIL_TUNABLE || node->flavor == CIL_MACRO) { - /* tuanbles and macros are not allowed in optionals*/ + 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 optionals", cil_node_to_string(node)); rc = SEPOL_ERR; goto exit;