Re: [PATCH] libsepol/cil: Give error for more than one true or false block

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

 



On Thu, Oct 15, 2020 at 10:44 PM James Carter <jwcart2@xxxxxxxxx> wrote:
> Both tunableif and booleanif use conditional blocks (either true or
> false). No ordering is imposed, so a false block can be first (or even
> the only) block. Checks are made to ensure that the first and second
> (if it exists) blocks are either true or false, but no checks are made
> to ensure that there is only one true and/or one false block. If there
> are more than one true or false block, only the first will be used and
> the other will be ignored.
>
> Create a function, cil_verify_conditional_blocks(), that gives an error
> along with a message if more than one true or false block is specified
> and call that function when building tunableif and booleanif blocks in
> the AST.
>
> Signed-off-by: James Carter <jwcart2@xxxxxxxxx>
> ---
>  libsepol/cil/src/cil_build_ast.c | 44 +++++---------------------------
>  libsepol/cil/src/cil_verify.c    | 35 +++++++++++++++++++++++++
>  libsepol/cil/src/cil_verify.h    |  1 +
>  3 files changed, 42 insertions(+), 38 deletions(-)
>
> diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
> index 3aabb05e..a8955834 100644
> --- a/libsepol/cil/src/cil_build_ast.c
> +++ b/libsepol/cil/src/cil_build_ast.c
> @@ -2821,7 +2821,6 @@ int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struc
>         int syntax_len = sizeof(syntax)/sizeof(*syntax);
>         struct cil_booleanif *bif = NULL;
>         struct cil_tree_node *next = NULL;
> -       struct cil_tree_node *cond = NULL;
>         int rc = SEPOL_ERR;
>
>         if (db == NULL || parse_current == NULL || ast_node == NULL) {
> @@ -2841,27 +2840,12 @@ int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struc
>                 goto exit;
>         }
>
> -       cond = parse_current->next->next;
> -
> -       /* Destroying expr tree after stack is created*/
> -       if (cond->cl_head->data != CIL_KEY_CONDTRUE &&
> -               cond->cl_head->data != CIL_KEY_CONDFALSE) {
> -               rc = SEPOL_ERR;
> -               cil_log(CIL_ERR, "Conditional neither true nor false\n");
> +       rc = cil_verify_conditional_blocks(parse_current->next->next);
> +       if (rc != SEPOL_OK) {
>                 goto exit;
>         }
>
> -       if (cond->next != NULL) {
> -               cond = cond->next;
> -               if (cond->cl_head->data != CIL_KEY_CONDTRUE &&
> -                       cond->cl_head->data != CIL_KEY_CONDFALSE) {
> -                       rc = SEPOL_ERR;
> -                       cil_log(CIL_ERR, "Conditional neither true nor false\n");
> -                       goto exit;
> -               }
> -       }
> -
> -
> +       /* Destroying expr tree */
>         next = parse_current->next->next;
>         cil_tree_subtree_destroy(parse_current->next);
>         parse_current->next = next;
> @@ -2905,7 +2889,6 @@ int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct
>         int syntax_len = sizeof(syntax)/sizeof(*syntax);
>         struct cil_tunableif *tif = NULL;
>         struct cil_tree_node *next = NULL;
> -       struct cil_tree_node *cond = NULL;
>         int rc = SEPOL_ERR;
>
>         if (db == NULL || parse_current == NULL || ast_node == NULL) {
> @@ -2924,27 +2907,12 @@ int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct
>                 goto exit;
>         }
>
> -       cond = parse_current->next->next;
> -
> -       if (cond->cl_head->data != CIL_KEY_CONDTRUE &&
> -               cond->cl_head->data != CIL_KEY_CONDFALSE) {
> -               rc = SEPOL_ERR;
> -               cil_log(CIL_ERR, "Conditional neither true nor false\n");
> +       rc = cil_verify_conditional_blocks(parse_current->next->next);
> +       if (rc != SEPOL_OK) {
>                 goto exit;
>         }
>
> -       if (cond->next != NULL) {
> -               cond = cond->next;
> -
> -               if (cond->cl_head->data != CIL_KEY_CONDTRUE &&
> -                       cond->cl_head->data != CIL_KEY_CONDFALSE) {
> -                       rc = SEPOL_ERR;
> -                       cil_log(CIL_ERR, "Conditional neither true nor false\n");
> -                       goto exit;
> -               }
> -       }
> -
> -       /* Destroying expr tree after stack is created*/
> +       /* Destroying expr tree */
>         next = parse_current->next->next;
>         cil_tree_subtree_destroy(parse_current->next);
>         parse_current->next = next;
> diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
> index c73bbeee..7b3d2a8b 100644
> --- a/libsepol/cil/src/cil_verify.c
> +++ b/libsepol/cil/src/cil_verify.c
> @@ -324,6 +324,41 @@ exit:
>         return SEPOL_ERR;
>  }
>
> +int cil_verify_conditional_blocks(struct cil_tree_node *current)
> +{
> +       int found_true = CIL_FALSE;
> +       int found_false = CIL_FALSE;
> +
> +       if (current->cl_head->data == CIL_KEY_CONDTRUE) {
> +               found_true = CIL_TRUE;
> +       } else if (current->cl_head->data == CIL_KEY_CONDFALSE) {
> +               found_false = CIL_TRUE;
> +       } else {
> +               cil_tree_log(current,CIL_ERR,"Expected true or false block in conditional");

Please put a space after each comma in the argument list (same in the
other cil_tree_log() calls in this function).

> +               return SEPOL_ERR;
> +       }
> +
> +       current = current->next;
> +       if (current != NULL) {
> +               if (current->cl_head->data == CIL_KEY_CONDTRUE) {
> +                       if (found_true) {
> +                               cil_tree_log(current,CIL_ERR,"More than one true block in conditional");
> +                               return SEPOL_ERR;
> +                       }
> +               } else if (current->cl_head->data == CIL_KEY_CONDFALSE) {
> +                       if (found_false) {
> +                               cil_tree_log(current,CIL_ERR,"More than one false block in conditional");
> +                               return SEPOL_ERR;
> +                       }
> +               } else {
> +                       cil_tree_log(current,CIL_ERR,"Expected true or false block in conditional");
> +                       return SEPOL_ERR;
> +               }

Perhaps this is checked somewhere else or I'm missing something, but
shouldn't this function also fail if there are more than two blocks
(i.e. current->next != NULL here)? Not that it would cause any damage
(I guess the extra blocks would be just ignored), but IMHO it's better
to be strict about it.

> +       }
> +
> +       return SEPOL_OK;
> +}
> +
>  int cil_verify_no_self_reference(struct cil_symtab_datum *datum, struct cil_list *datum_list)
>  {
>         struct cil_list_item *i;
> diff --git a/libsepol/cil/src/cil_verify.h b/libsepol/cil/src/cil_verify.h
> index bda1565f..905761b0 100644
> --- a/libsepol/cil/src/cil_verify.h
> +++ b/libsepol/cil/src/cil_verify.h
> @@ -61,6 +61,7 @@ int __cil_verify_syntax(struct cil_tree_node *parse_current, enum cil_syntax s[]
>  int cil_verify_expr_syntax(struct cil_tree_node *current, enum cil_flavor op, enum cil_flavor expr_flavor);
>  int cil_verify_constraint_leaf_expr_syntax(enum cil_flavor l_flavor, enum cil_flavor r_flavor, enum cil_flavor op, enum cil_flavor expr_flavor);
>  int cil_verify_constraint_expr_syntax(struct cil_tree_node *current, enum cil_flavor op);
> +int cil_verify_conditional_blocks(struct cil_tree_node *current);
>  int cil_verify_no_self_reference(struct cil_symtab_datum *datum, struct cil_list *datum_list);
>  int __cil_verify_ranges(struct cil_list *list);
>  int __cil_verify_ordered_node_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args);
> --
> 2.25.4
>

-- 
Ondrej Mosnacek
Software Engineer, Platform Security - SELinux kernel
Red Hat, Inc.




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

  Powered by Linux