173 lines
5.2 KiB
Diff
173 lines
5.2 KiB
Diff
|
From 734e4beb55cb53d3370201838caa4850b2a6d276 Mon Sep 17 00:00:00 2001
|
||
|
From: James Carter <jwcart2@gmail.com>
|
||
|
Date: Wed, 9 Sep 2020 16:57:02 -0400
|
||
|
Subject: [PATCH] libsepol/cil: Validate conditional expressions before adding
|
||
|
to binary policy
|
||
|
|
||
|
CIL was not correctly determining the depth of conditional expressions
|
||
|
which prevented it from giving an error when the max depth was exceeded.
|
||
|
This allowed invalid policy binaries to be created.
|
||
|
|
||
|
Validate the conditional expression using the same logic that is used
|
||
|
when evaluating a conditional expression. This includes checking the
|
||
|
depth of the expression.
|
||
|
|
||
|
Signed-off-by: James Carter <jwcart2@gmail.com>
|
||
|
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
|
||
|
---
|
||
|
libsepol/cil/src/cil_binary.c | 50 ++++++++++++++++++++++++++++++++
|
||
|
libsepol/cil/src/cil_build_ast.c | 26 +++++------------
|
||
|
2 files changed, 57 insertions(+), 19 deletions(-)
|
||
|
|
||
|
diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
|
||
|
index c8e41f09e53f..50cc7f757c62 100644
|
||
|
--- a/libsepol/cil/src/cil_binary.c
|
||
|
+++ b/libsepol/cil/src/cil_binary.c
|
||
|
@@ -2176,6 +2176,51 @@ static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_e
|
||
|
return SEPOL_OK;
|
||
|
}
|
||
|
|
||
|
+int __cil_validate_cond_expr(cond_expr_t *cond_expr)
|
||
|
+{
|
||
|
+ cond_expr_t *e;
|
||
|
+ int depth = -1;
|
||
|
+
|
||
|
+ for (e = cond_expr; e != NULL; e = e->next) {
|
||
|
+ switch (e->expr_type) {
|
||
|
+ case COND_BOOL:
|
||
|
+ if (depth == (COND_EXPR_MAXDEPTH - 1)) {
|
||
|
+ cil_log(CIL_ERR,"Conditional expression exceeded max allowable depth\n");
|
||
|
+ return SEPOL_ERR;
|
||
|
+ }
|
||
|
+ depth++;
|
||
|
+ break;
|
||
|
+ case COND_NOT:
|
||
|
+ if (depth < 0) {
|
||
|
+ cil_log(CIL_ERR,"Invalid conditional expression\n");
|
||
|
+ return SEPOL_ERR;
|
||
|
+ }
|
||
|
+ break;
|
||
|
+ case COND_OR:
|
||
|
+ case COND_AND:
|
||
|
+ case COND_XOR:
|
||
|
+ case COND_EQ:
|
||
|
+ case COND_NEQ:
|
||
|
+ if (depth < 1) {
|
||
|
+ cil_log(CIL_ERR,"Invalid conditional expression\n");
|
||
|
+ return SEPOL_ERR;
|
||
|
+ }
|
||
|
+ depth--;
|
||
|
+ break;
|
||
|
+ default:
|
||
|
+ cil_log(CIL_ERR,"Invalid conditional expression\n");
|
||
|
+ return SEPOL_ERR;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ if (depth != 0) {
|
||
|
+ cil_log(CIL_ERR,"Invalid conditional expression\n");
|
||
|
+ return SEPOL_ERR;
|
||
|
+ }
|
||
|
+
|
||
|
+ return SEPOL_OK;
|
||
|
+}
|
||
|
+
|
||
|
int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node)
|
||
|
{
|
||
|
int rc = SEPOL_ERR;
|
||
|
@@ -2204,6 +2249,11 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
+ rc = __cil_validate_cond_expr(tmp_cond->expr);
|
||
|
+ if (rc != SEPOL_OK) {
|
||
|
+ goto exit;
|
||
|
+ }
|
||
|
+
|
||
|
tmp_cond->true_list = &tmp_cl;
|
||
|
|
||
|
rc = cond_normalize_expr(pdb, tmp_cond);
|
||
|
diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
|
||
|
index 870c6923b4de..3aabb05ec534 100644
|
||
|
--- a/libsepol/cil/src/cil_build_ast.c
|
||
|
+++ b/libsepol/cil/src/cil_build_ast.c
|
||
|
@@ -2548,18 +2548,13 @@ static enum cil_flavor __cil_get_expr_operator_flavor(const char *op)
|
||
|
else return CIL_NONE;
|
||
|
}
|
||
|
|
||
|
-static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth);
|
||
|
+static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr);
|
||
|
|
||
|
-static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth)
|
||
|
+static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr)
|
||
|
{
|
||
|
int rc = SEPOL_ERR;
|
||
|
enum cil_flavor op;
|
||
|
|
||
|
- if (flavor == CIL_BOOL && *depth > COND_EXPR_MAXDEPTH) {
|
||
|
- cil_log(CIL_ERR, "Max depth of %d exceeded for boolean expression\n", COND_EXPR_MAXDEPTH);
|
||
|
- goto exit;
|
||
|
- }
|
||
|
-
|
||
|
op = __cil_get_expr_operator_flavor(current->data);
|
||
|
|
||
|
rc = cil_verify_expr_syntax(current, op, flavor);
|
||
|
@@ -2572,26 +2567,20 @@ static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor
|
||
|
current = current->next;
|
||
|
}
|
||
|
|
||
|
- if (op == CIL_NONE || op == CIL_ALL) {
|
||
|
- (*depth)++;
|
||
|
- }
|
||
|
-
|
||
|
for (;current != NULL; current = current->next) {
|
||
|
- rc = __cil_fill_expr(current, flavor, expr, depth);
|
||
|
+ rc = __cil_fill_expr(current, flavor, expr);
|
||
|
if (rc != SEPOL_OK) {
|
||
|
goto exit;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
- (*depth)--;
|
||
|
-
|
||
|
return SEPOL_OK;
|
||
|
|
||
|
exit:
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
-static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth)
|
||
|
+static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr)
|
||
|
{
|
||
|
int rc = SEPOL_ERR;
|
||
|
|
||
|
@@ -2605,7 +2594,7 @@ static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor
|
||
|
} else {
|
||
|
struct cil_list *sub_expr;
|
||
|
cil_list_init(&sub_expr, flavor);
|
||
|
- rc = __cil_fill_expr_helper(current->cl_head, flavor, sub_expr, depth);
|
||
|
+ rc = __cil_fill_expr_helper(current->cl_head, flavor, sub_expr);
|
||
|
if (rc != SEPOL_OK) {
|
||
|
cil_list_destroy(&sub_expr, CIL_TRUE);
|
||
|
goto exit;
|
||
|
@@ -2623,14 +2612,13 @@ exit:
|
||
|
int cil_gen_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr)
|
||
|
{
|
||
|
int rc = SEPOL_ERR;
|
||
|
- int depth = 0;
|
||
|
|
||
|
cil_list_init(expr, flavor);
|
||
|
|
||
|
if (current->cl_head == NULL) {
|
||
|
- rc = __cil_fill_expr(current, flavor, *expr, &depth);
|
||
|
+ rc = __cil_fill_expr(current, flavor, *expr);
|
||
|
} else {
|
||
|
- rc = __cil_fill_expr_helper(current->cl_head, flavor, *expr, &depth);
|
||
|
+ rc = __cil_fill_expr_helper(current->cl_head, flavor, *expr);
|
||
|
}
|
||
|
|
||
|
if (rc != SEPOL_OK) {
|
||
|
--
|
||
|
2.29.0.rc2
|
||
|
|