libsepol/cil: fix blockinherit copying segfault and add macro restrictions
When we copy a blockinherit statement, we perform actions that assume the blockinherit statement was already resolved. However, this isn't the case if the statement was copied from a tunableif or an in-statement, since those are resolve before blockinherits and blocks. So when copying a blockinherit that hasn't been resolved, ignore the code that associates blocks with the blockinherit; that will all be handled when the copied blockinherit is actually resolved later. Additionally, restrict block, blockabstract, and blockinherit statements from appearing in macros. These statements are all resolved before macros due to ordering issues, so they must not appear inside macros. Note that in addition to doing the checks in build_ast, they are also done in resolve_ast. This is because an in-statement could copy a block statement into a macro, which we would not know about until after the in-statement was resolved. Signed-off-by: Steve Lawrence <slawrence@tresys.com> Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
This commit is contained in:
parent
b724a08eb9
commit
b6e519e542
|
@ -5750,27 +5750,14 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f
|
|||
}
|
||||
|
||||
if (macro != NULL) {
|
||||
if (parse_current->data == CIL_KEY_MACRO) {
|
||||
if (parse_current->data == CIL_KEY_MACRO ||
|
||||
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) {
|
||||
rc = SEPOL_ERR;
|
||||
cil_log(CIL_ERR, "Found macro at line %d of %s\n",
|
||||
parse_current->line, parse_current->path);
|
||||
cil_log(CIL_ERR, "Macros cannot be defined within macro statement\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (parse_current->data == CIL_KEY_TUNABLE) {
|
||||
rc = SEPOL_ERR;
|
||||
cil_log(CIL_ERR, "Found tunable at line %d of %s\n",
|
||||
parse_current->line, parse_current->path);
|
||||
cil_log(CIL_ERR, "Tunables cannot be defined within macro statement\n");
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (parse_current->data == CIL_KEY_IN) {
|
||||
rc = SEPOL_ERR;
|
||||
cil_log(CIL_ERR, "Found in at line %d of %s\n",
|
||||
parse_current->line, parse_current->path);
|
||||
cil_log(CIL_ERR, "in-statements cannot be defined within macro statement\n");
|
||||
cil_log(CIL_ERR, "%s is not allowed in macros (%s:%d)\n", (char *)parse_current->data, parse_current->path, parse_current->line);
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1972,7 +1972,14 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
|
|||
|
||||
if (new->flavor == CIL_BLOCKINHERIT) {
|
||||
blockinherit = new->data;
|
||||
cil_list_append(blockinherit->block->bi_nodes, CIL_NODE, new);
|
||||
// if a blockinherit statement is copied before blockinherit are
|
||||
// resolved (like in an in-statement), the block will not have been
|
||||
// resolved yet, so there's nothing to append yet. This is fine,
|
||||
// the copied blockinherit statement will be handled later, as if
|
||||
// it wasn't in an in-statement
|
||||
if (blockinherit->block != NULL) {
|
||||
cil_list_append(blockinherit->block->bi_nodes, CIL_NODE, new);
|
||||
}
|
||||
}
|
||||
|
||||
if (parent->cl_head == NULL) {
|
||||
|
|
|
@ -3318,6 +3318,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, __attribute__((unu
|
|||
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 *macro = args->macro;
|
||||
|
||||
if (node == NULL) {
|
||||
goto exit;
|
||||
|
@ -3340,6 +3341,17 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, __attribute__((unu
|
|||
}
|
||||
}
|
||||
|
||||
if (macro != NULL) {
|
||||
if (node->flavor == CIL_BLOCKINHERIT ||
|
||||
node->flavor == CIL_BLOCK ||
|
||||
node->flavor == CIL_BLOCKABSTRACT ||
|
||||
node->flavor == CIL_MACRO) {
|
||||
cil_log(CIL_ERR, "%s statement is not allowed in macros (%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 ||
|
||||
|
|
Loading…
Reference in New Issue