CIL was not correctly determining the depth of constraint expressions which prevented it from giving an error when the max depth was exceeded. This allowed invalid policy binaries with constraint expressions exceeding the max depth to be created. Correctly calculate the depth of constraint expressions when building the AST and give an error when the max depth is exceeded. Reported-by: Jonathan Hettwer <j2468h@xxxxxxxxx> Signed-off-by: James Carter <jwcart2@xxxxxxxxx> --- libsepol/cil/src/cil_build_ast.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c index 60ecaaff..29a3d060 100644 --- a/libsepol/cil/src/cil_build_ast.c +++ b/libsepol/cil/src/cil_build_ast.c @@ -2738,7 +2738,7 @@ exit: return SEPOL_ERR; } -static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr, int *depth) +static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr, int depth) { int rc = SEPOL_ERR; enum cil_flavor op; @@ -2750,8 +2750,9 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl goto exit; } - if (*depth > CEXPR_MAXDEPTH) { - cil_log(CIL_ERR, "Max depth of %d exceeded for constraint expression\n", CEXPR_MAXDEPTH); + if (depth >= CEXPR_MAXDEPTH) { + /* Error occurs when depth == CEXPR_MAXDEPTH */ + cil_log(CIL_ERR, "Max depth of %d exceeded for constraint expression\n", CEXPR_MAXDEPTH-1); rc = SEPOL_ERR; goto exit; } @@ -2769,14 +2770,13 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl case CIL_CONS_DOM: case CIL_CONS_DOMBY: case CIL_CONS_INCOMP: - (*depth)++; rc = __cil_fill_constraint_leaf_expr(current, flavor, op, expr); if (rc != SEPOL_OK) { goto exit; } break; case CIL_NOT: - rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr, depth); + rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr, depth+1); if (rc != SEPOL_OK) { goto exit; } @@ -2785,11 +2785,11 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl cil_list_append(*expr, CIL_LIST, lexpr); break; default: - rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr, depth); + rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr, depth+1); if (rc != SEPOL_OK) { goto exit; } - rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr, depth); + rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr, depth+1); if (rc != SEPOL_OK) { cil_list_destroy(&lexpr, CIL_TRUE); goto exit; @@ -2801,8 +2801,6 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl break; } - (*depth)--; - return SEPOL_OK; exit: @@ -2812,13 +2810,12 @@ exit: int cil_gen_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr) { int rc = SEPOL_ERR; - int depth = 0; if (current->cl_head == NULL) { goto exit; } - rc = __cil_fill_constraint_expr(current->cl_head, flavor, expr, &depth); + rc = __cil_fill_constraint_expr(current->cl_head, flavor, expr, 0); if (rc != SEPOL_OK) { goto exit; } -- 2.25.4