Re: [PATCH] libsepol/cil: Allow some duplicate macro and block declarations

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

 



On Wed, Aug 11, 2021 at 11:04 PM James Carter <jwcart2@xxxxxxxxx> wrote:
>
> The commit d155b410d4bbc90d28f361b966f0429598da8188 (libsepol/cil:
> Check for duplicate blocks, optionals, and macros) added checks when
> copying blocks, macros, and optionals so that a duplicate would cause
> an exit with an error. Unfortunately, some policies exist that depend
> on this behavior when using inheritance.
>
> The behavior is as follows.
>
> For macros only the first declared macro matters.
> ;
> (macro m ((type ARG1))
>   (allow ARG1 self (CLASS (PERM1)))
> )
> (block b
>   (macro m ((type ARG1))
>     (allow ARG1 self (CLASS (PERM2)))
>   )
> )
> (blockinherit b)
> (type t)
> (call m (t))
> ;
> For this policy segment, the macro m in block b will not be called.
> Only the original macro m will be.
>
> This behavior has been used to override macros that are going to
> be inherited. Only the inherited macros that have not already been
> declared in the destination namespace will be used.
>
> Blocks seem to work fine even though there are two of them
> ;
> (block b1
>   (blockinherit b2)
>   (block b
>     (type t1)
>     (allow t1 self (CLASS (PERM)))
>   )
> )
> (block b2
>   (block b
>     (type t2)
>     (allow t2 self (CLASS (PERM)))
>   )
> )
> (blockinherit b1)
> ;
> In this example, the blockinherit of b2 will cause there to be
> two block b's in block b1. Note that if both block b's tried to
> declare the same type, then that would be an error. The blockinherit
> of b1 will copy both block b's.
>
> This behavior has been used to allow the use of in-statements for
> a block that is being inherited. Since the in-statements are resolved
> before block inheritance, this only works if a block with the same
> name as the block to be inherited is declared in the namespace.
>
> To support the use of these two behaviors, allow duplicate blocks
> and macros when they occur as the result of block inheritance. In
> any other circumstances and error for a redeclaration will be given.
>
> Since the duplicate macro is not going to be used it is just skipped.
> The duplicate block will use the datum of the original block. In both
> cases a warning message will be produced (it will only be seen if
> "-v" is used when compiling the policy).
>
> Signed-off-by: James Carter <jwcart2@xxxxxxxxx>

Hello,
The patch looks good to me but a format string issue (see comment
below). If you fix this:

Acked-by: Nicolas Iooss <nicolas.iooss@xxxxxxx>

Thanks,
Nicolas

> ---
>  libsepol/cil/src/cil_copy_ast.c | 69 ++++++++++++++++++++++++---------
>  1 file changed, 50 insertions(+), 19 deletions(-)
>
> diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c
> index 9c0231f2..67be2ec8 100644
> --- a/libsepol/cil/src/cil_copy_ast.c
> +++ b/libsepol/cil/src/cil_copy_ast.c
> @@ -43,6 +43,7 @@
>  #include "cil_verify.h"
>
>  struct cil_args_copy {
> +       struct cil_tree_node *orig_dest;
>         struct cil_tree_node *dest;
>         struct cil_db *db;
>  };
> @@ -101,17 +102,23 @@ int cil_copy_block(__attribute__((unused)) struct cil_db *db, void *data, void *
>         struct cil_block *orig = data;
>         char *key = orig->datum.name;
>         struct cil_symtab_datum *datum = NULL;
> -       struct cil_block *new;
>
>         cil_symtab_get_datum(symtab, key, &datum);
>         if (datum != NULL) {
> -               cil_tree_log(NODE(datum), CIL_ERR, "Re-declaration of %s %s", cil_node_to_string(NODE(datum)), key);
> -               return SEPOL_ERR;
> +               if (FLAVOR(datum) != CIL_BLOCK) {
> +                       cil_tree_log(NODE(orig), CIL_ERR, "Block %s being copied", key);
> +                       cil_tree_log(NODE(datum), CIL_ERR, "  Conflicts with %s already declared", cil_node_to_string(NODE(datum)));
> +                       return SEPOL_ERR;
> +               }
> +               cil_tree_log(NODE(orig), CIL_WARN, "Block %s being copied", key);
> +               cil_tree_log(NODE(datum), CIL_WARN, "  Previously declared", key);

Here there is an extra format argument "key", which needs to be removed.

> +               *copy = datum;
> +       } else {
> +               struct cil_block *new;
> +               cil_block_init(&new);
> +               *copy = new;
>         }
>
> -       cil_block_init(&new);
> -       *copy = new;
> -
>         return SEPOL_OK;
>  }
>
> @@ -1511,21 +1518,26 @@ int cil_copy_macro(__attribute__((unused)) struct cil_db *db, void *data, void *
>         struct cil_macro *orig = data;
>         char *key = orig->datum.name;
>         struct cil_symtab_datum *datum = NULL;
> -       struct cil_macro *new;
>
>         cil_symtab_get_datum(symtab, key, &datum);
>         if (datum != NULL) {
> -               cil_tree_log(NODE(datum), CIL_ERR, "Re-declaration of %s %s", cil_node_to_string(NODE(datum)), key);
> -               return SEPOL_ERR;
> -       }
> -
> -       cil_macro_init(&new);
> -       if (orig->params != NULL) {
> -               cil_copy_list(orig->params, &new->params);
> +               if (FLAVOR(datum) != CIL_MACRO) {
> +                       cil_tree_log(NODE(orig), CIL_ERR, "Macro %s being copied", key);
> +                       cil_tree_log(NODE(datum), CIL_ERR, "  Conflicts with %s already declared", cil_node_to_string(NODE(datum)));
> +                       return SEPOL_ERR;
> +               }
> +               cil_tree_log(NODE(orig), CIL_WARN, "Skipping macro %s", key);
> +               cil_tree_log(NODE(datum), CIL_WARN, "  Previously declared");
> +               *copy = NULL;
> +       } else {
> +               struct cil_macro *new;
> +               cil_macro_init(&new);
> +               if (orig->params != NULL) {
> +                       cil_copy_list(orig->params, &new->params);
> +               }
> +               *copy = new;
>         }
>
> -       *copy = new;
> -
>         return SEPOL_OK;
>  }
>
> @@ -1700,7 +1712,7 @@ int cil_copy_src_info(__attribute__((unused)) struct cil_db *db, void *data, voi
>         return SEPOL_OK;
>  }
>
> -int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) uint32_t *finished, void *extra_args)
> +int __cil_copy_node_helper(struct cil_tree_node *orig, uint32_t *finished, void *extra_args)
>  {
>         int rc = SEPOL_ERR;
>         struct cil_tree_node *parent = NULL;
> @@ -2005,6 +2017,16 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
>
>         rc = (*copy_func)(db, orig->data, &data, symtab);
>         if (rc == SEPOL_OK) {
> +               if (orig->flavor == CIL_MACRO && data == NULL) {
> +                       /* Skipping macro re-declaration */
> +                       if (args->orig_dest->flavor != CIL_BLOCKINHERIT) {
> +                               cil_log(CIL_ERR, "  Re-declaration of macro is only allowed when inheriting a block\n");
> +                               return SEPOL_ERR;
> +                       }
> +                       *finished = CIL_TREE_SKIP_HEAD;
> +                       return SEPOL_OK;
> +               }
> +
>                 cil_tree_node_init(&new);
>
>                 new->parent = parent;
> @@ -2013,7 +2035,15 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u
>                 new->flavor = orig->flavor;
>                 new->data = data;
>
> -               if (orig->flavor >= CIL_MIN_DECLARATIVE) {
> +               if (orig->flavor == CIL_BLOCK && DATUM(data)->nodes->head != NULL) {
> +                       /* Duplicate block */
> +                       if (args->orig_dest->flavor != CIL_BLOCKINHERIT) {
> +                               cil_log(CIL_ERR, "  Re-declaration of block is only allowed when inheriting a block\n");
> +                               rc = SEPOL_ERR;
> +                               goto exit;
> +                       }
> +                       cil_list_append(DATUM(new->data)->nodes, CIL_NODE, new);
> +               } else if (orig->flavor >= CIL_MIN_DECLARATIVE) {
>                         /* Check the flavor of data if was found in the destination symtab */
>                         if (DATUM(data)->nodes->head && FLAVOR(data) != orig->flavor) {
>                                 cil_tree_log(orig, CIL_ERR, "Incompatible flavor when trying to copy %s", DATUM(data)->name);
> @@ -2098,12 +2128,13 @@ int cil_copy_ast(struct cil_db *db, struct cil_tree_node *orig, struct cil_tree_
>         int rc = SEPOL_ERR;
>         struct cil_args_copy extra_args;
>
> +       extra_args.orig_dest = dest;
>         extra_args.dest = dest;
>         extra_args.db = db;
>
>         rc = cil_tree_walk(orig, __cil_copy_node_helper, NULL,  __cil_copy_last_child_helper, &extra_args);
>         if (rc != SEPOL_OK) {
> -               cil_log(CIL_INFO, "cil_tree_walk failed, rc: %d\n", rc);
> +               cil_tree_log(dest, CIL_ERR, "Failed to copy %s to %s", cil_node_to_string(orig), cil_node_to_string(dest));
>                 goto exit;
>         }
>
> --
> 2.31.1
>




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

  Powered by Linux