Re: [PATCH v2] libsepol/cil: Give an error when constraint expressions exceed max depth

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I just realized that I copied more than just the depth checking. I am
going to keep the extra checks, but I need more error messages and a
new function name.

Jim

On Wed, Sep 9, 2020 at 12:32 PM James Carter <jwcart2@xxxxxxxxx> wrote:
>
> 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.
>
> Check the depth of a constraint expression after converting it to the
> postfix form used in the binary policy 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_binary.c    | 42 ++++++++++++++++++++++++++++++++
>  libsepol/cil/src/cil_build_ast.c | 20 ++++-----------
>  2 files changed, 47 insertions(+), 15 deletions(-)
>
> diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
> index 77266858..3131a63e 100644
> --- a/libsepol/cil/src/cil_binary.c
> +++ b/libsepol/cil/src/cil_binary.c
> @@ -2713,6 +2713,42 @@ int __cil_constrain_expr_to_sepol_expr(policydb_t *pdb, const struct cil_db *db,
>         return SEPOL_OK;
>  }
>
> +int __cil_constrain_expr_check_depth(constraint_expr_t *sepol_expr)
> +{
> +       constraint_expr_t *e = sepol_expr;
> +       int depth = -1;
> +
> +       while (e) {
> +               switch (e->expr_type) {
> +               case CEXPR_NOT:
> +                       if (depth < 0)
> +                               return SEPOL_ERR;
> +                       break;
> +               case CEXPR_AND:
> +               case CEXPR_OR:
> +                       if (depth < 1)
> +                               return SEPOL_ERR;
> +                       depth--;
> +                       break;
> +               case CEXPR_ATTR:
> +                       if (depth == (CEXPR_MAXDEPTH - 1))
> +                               return SEPOL_ERR;
> +                       depth++;
> +                       break;
> +               case CEXPR_NAMES:
> +                       if (depth == (CEXPR_MAXDEPTH - 1))
> +                               return SEPOL_ERR;
> +                       depth++;
> +                       break;
> +               default:
> +                       return SEPOL_ERR;
> +               }
> +               e = e->next;
> +       }
> +
> +       return SEPOL_OK;
> +}
> +
>  int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *class, struct cil_list *perms, struct cil_list *expr)
>  {
>         int rc = SEPOL_ERR;
> @@ -2736,6 +2772,12 @@ int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, s
>                 goto exit;
>         }
>
> +       rc = __cil_constrain_expr_check_depth(sepol_expr);
> +       if (rc != SEPOL_OK) {
> +               cil_log(CIL_ERR,"Constraint expression exceeded max allowable depth\n");
> +               goto exit;
> +       }
> +
>         sepol_constrain->expr = sepol_expr;
>         sepol_constrain->next = sepol_class->constraints;
>         sepol_class->constraints = sepol_constrain;
> diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
> index 60ecaaff..870c6923 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 rc = SEPOL_ERR;
>         enum cil_flavor op;
> @@ -2750,12 +2750,6 @@ 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);
> -               rc = SEPOL_ERR;
> -               goto exit;
> -       }
> -
>         op = __cil_get_constraint_operator_flavor(current->data);
>
>         rc = cil_verify_constraint_expr_syntax(current, op);
> @@ -2769,14 +2763,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);
>                 if (rc != SEPOL_OK) {
>                         goto exit;
>                 }
> @@ -2785,11 +2778,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);
>                 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);
>                 if (rc != SEPOL_OK) {
>                         cil_list_destroy(&lexpr, CIL_TRUE);
>                         goto exit;
> @@ -2801,8 +2794,6 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl
>                 break;
>         }
>
> -       (*depth)--;
> -
>         return SEPOL_OK;
>  exit:
>
> @@ -2812,13 +2803,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);
>         if (rc != SEPOL_OK) {
>                 goto exit;
>         }
> --
> 2.25.4
>



[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux