All of lore.kernel.org
 help / color / mirror / Atom feed
From: James Carter <jwcart2@gmail.com>
To: SElinux list <selinux@vger.kernel.org>
Subject: Re: [PATCH 2/3] libsepol/cil: Copy and resolve macro calls in one pass
Date: Mon, 10 May 2021 09:55:38 -0400	[thread overview]
Message-ID: <CAP+JOzTjZrFpDhceF54Pv2WMPzQG4gYqdoxh1HZX9kECxgBr0A@mail.gmail.com> (raw)
In-Reply-To: <20210507173744.198858-2-jwcart2@gmail.com>

On Fri, May 7, 2021 at 1:37 PM James Carter <jwcart2@gmail.com> wrote:
>
> Lorenzo Ceragioli <lorenzo.ceragioli@phd.unipi.it> noted that the
> following policy:
>   (type a)
>   (block A
>     (macro m ((type x))
>       (type a)
>       (allow x x (file (read))))
>   )
>   (block B
>     (call A.m(a))
>   )
> results in the allow rule (allow B.a B.a (file(read))). This makes
> no sense because the "a" being passed as an argument has to be the
> global "a" and not the "a" defined in the macro.
>
> This behavior occurs because the call arguments are resolved AFTER
> the macro body has been copied and the declaration of "a" in the
> macro has been added to block B's namespace, so this is the "a"
> that the call argument resolves to, rather than the one in the
> global namespace.
>
> It turns out that calls can be copied and resolved in one pass.
>

It turns out that you can't.
If an optional is disabled, then the call arguments need to be
re-resolved because one might have resolved to a declaration in the
optional that was just disabled.

JIm

> Resolve the call arguments first and then copy the macro rules
> all in one pass.
>
> Signed-off-by: James Carter <jwcart2@gmail.com>
> ---
>  libsepol/cil/src/cil_resolve_ast.c | 620 +++++++++++++++--------------
>  1 file changed, 312 insertions(+), 308 deletions(-)
>
> diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
> index bbe86e22..740a9b5e 100644
> --- a/libsepol/cil/src/cil_resolve_ast.c
> +++ b/libsepol/cil/src/cil_resolve_ast.c
> @@ -2840,338 +2840,300 @@ exit:
>         return rc;
>  }
>
> -int cil_resolve_call1(struct cil_tree_node *current, void *extra_args)
> +static int cil_build_call_args(struct cil_tree_node *call_node, struct cil_call *call, struct cil_macro *macro, void *extra_args)
>  {
> -       struct cil_call *new_call = current->data;
>         struct cil_args_resolve *args = extra_args;
> -       struct cil_db *db = NULL;
> -       struct cil_tree_node *macro_node = NULL;
> -       struct cil_symtab_datum *macro_datum = NULL;
> +       struct cil_list_item *item;
> +       struct cil_args *arg = NULL;
> +       struct cil_tree_node *arg_node = NULL;
>         int rc = SEPOL_ERR;
>
> -       if (args != NULL) {
> -               db = args->db;
> +       if (macro->params == NULL) {
> +               if (call->args_tree == NULL) {
> +                       return SEPOL_OK;
> +               } else {
> +                       cil_tree_log(call_node, CIL_ERR, "Unexpected arguments");
> +                       return SEPOL_ERR;;
> +               }
>         }
> -
> -       rc = cil_resolve_name(current, new_call->macro_str, CIL_SYM_BLOCKS, extra_args, &macro_datum);
> -       if (rc != SEPOL_OK) {
> -               goto exit;
> +       if (call->args_tree == NULL) {
> +               cil_tree_log(call_node, CIL_ERR, "Missing arguments");
> +               return SEPOL_ERR;
>         }
>
> -       macro_node = NODE(macro_datum);
> +       arg_node = call->args_tree->root->cl_head;
>
> -       if (macro_node->flavor != CIL_MACRO) {
> -               cil_tree_log(current, CIL_ERR, "Failed to resolve %s to a macro", new_call->macro_str);
> -               rc = SEPOL_ERR;
> -               goto exit;
> -       }
> -       new_call->macro = (struct cil_macro*)macro_datum;
> +       cil_list_init(&call->args, CIL_LIST_ITEM);
>
> -       if (new_call->macro->params != NULL ) {
> -
> -               struct cil_list_item *item;
> -               struct cil_args *new_arg = NULL;
> -               struct cil_tree_node *pc = NULL;
> +       cil_list_for_each(item, macro->params) {
> +               enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor;
>
> -               if (new_call->args_tree == NULL) {
> -                       cil_tree_log(current, CIL_ERR, "Missing arguments");
> +               if (arg_node == NULL) {
> +                       cil_tree_log(call_node, CIL_ERR, "Missing arguments");
> +                       rc = SEPOL_ERR;
> +                       goto exit;
> +               }
> +               if (item->flavor != CIL_PARAM) {
>                         rc = SEPOL_ERR;
>                         goto exit;
>                 }
>
> -               pc = new_call->args_tree->root->cl_head;
> -
> -               cil_list_init(&new_call->args, CIL_LIST_ITEM);
> -
> -               cil_list_for_each(item, new_call->macro->params) {
> -                       enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor;
> +               cil_args_init(&arg);
>
> -                       if (pc == NULL) {
> -                               cil_tree_log(current, CIL_ERR, "Missing arguments");
> +               switch (flavor) {
> +               case CIL_NAME: {
> +                       struct cil_name *name;
> +                       if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
>                                 rc = SEPOL_ERR;
>                                 goto exit;
>                         }
> -                       if (item->flavor != CIL_PARAM) {
> +                       name = __cil_insert_name(args->db, arg_node->data, call_node);
> +                       if (name != NULL) {
> +                               arg->arg = (struct cil_symtab_datum *)name;
> +                       } else {
> +                               arg->arg_str = arg_node->data;
> +                       }
> +               }
> +                       break;
> +               case CIL_TYPE:
> +                       if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
>                                 rc = SEPOL_ERR;
>                                 goto exit;
>                         }
> -
> -                       cil_args_init(&new_arg);
> -
> -                       switch (flavor) {
> -                       case CIL_NAME: {
> -                               struct cil_name *name;
> -                               if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> -                                       goto exit;
> -                               }
> -                               name = __cil_insert_name(args->db, pc->data, current);
> -                               if (name != NULL) {
> -                                       new_arg->arg = (struct cil_symtab_datum *)name;
> -                               } else {
> -                                       new_arg->arg_str = pc->data;
> -                               }
> +                       arg->arg_str = arg_node->data;
> +                       break;
> +               case CIL_ROLE:
> +                       if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
> +                               rc = SEPOL_ERR;
> +                               goto exit;
>                         }
> -                               break;
> -                       case CIL_TYPE:
> -                               if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> -                                       goto exit;
> -                               }
> -                               new_arg->arg_str = pc->data;
> -                               break;
> -                       case CIL_ROLE:
> -                               if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> -                                       goto exit;
> -                               }
> -                               new_arg->arg_str = pc->data;
> -                               break;
> -                       case CIL_USER:
> -                               if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> -                                       goto exit;
> -                               }
> -                               new_arg->arg_str = pc->data;
> -                               break;
> -                       case CIL_SENS:
> -                               if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> -                                       goto exit;
> -                               }
> -                               new_arg->arg_str = pc->data;
> -                               break;
> -                       case CIL_CAT:
> -                               if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> -                                       goto exit;
> -                               }
> -                               new_arg->arg_str = pc->data;
> -                               break;
> -                       case CIL_BOOL:
> -                               if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> -                                       goto exit;
> -                               }
> -                               new_arg->arg_str = pc->data;
> -                               break;
> -                       case CIL_CATSET: {
> -                               if (pc->cl_head != NULL) {
> -                                       struct cil_catset *catset = NULL;
> -                                       struct cil_tree_node *cat_node = NULL;
> -                                       cil_catset_init(&catset);
> -                                       rc = cil_fill_cats(pc, &catset->cats);
> -                                       if (rc != SEPOL_OK) {
> -                                               cil_destroy_catset(catset);
> -                                               cil_destroy_args(new_arg);
> -                                               goto exit;
> -                                       }
> -                                       cil_tree_node_init(&cat_node);
> -                                       cat_node->flavor = CIL_CATSET;
> -                                       cat_node->data = catset;
> -                                       cil_list_append(((struct cil_symtab_datum*)catset)->nodes,
> -                                                                       CIL_LIST_ITEM, cat_node);
> -                                       new_arg->arg = (struct cil_symtab_datum*)catset;
> -                               } else if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> +                       arg->arg_str = arg_node->data;
> +                       break;
> +               case CIL_USER:
> +                       if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
> +                               rc = SEPOL_ERR;
> +                               goto exit;
> +                       }
> +                       arg->arg_str = arg_node->data;
> +                       break;
> +               case CIL_SENS:
> +                       if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
> +                               rc = SEPOL_ERR;
> +                               goto exit;
> +                       }
> +                       arg->arg_str = arg_node->data;
> +                       break;
> +               case CIL_CAT:
> +                       if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
> +                               rc = SEPOL_ERR;
> +                               goto exit;
> +                       }
> +                       arg->arg_str = arg_node->data;
> +                       break;
> +               case CIL_BOOL:
> +                       if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
> +                               rc = SEPOL_ERR;
> +                               goto exit;
> +                       }
> +                       arg->arg_str = arg_node->data;
> +                       break;
> +               case CIL_CATSET: {
> +                       if (arg_node->cl_head != NULL) {
> +                               struct cil_catset *catset = NULL;
> +                               struct cil_tree_node *cat_node = NULL;
> +                               cil_catset_init(&catset);
> +                               rc = cil_fill_cats(arg_node, &catset->cats);
> +                               if (rc != SEPOL_OK) {
> +                                       cil_destroy_catset(catset);
> +                                       cil_destroy_args(arg);
>                                         goto exit;
> -                               } else {
> -                                       new_arg->arg_str = pc->data;
>                                 }
> -
> -                               break;
> +                               cil_tree_node_init(&cat_node);
> +                               cat_node->flavor = CIL_CATSET;
> +                               cat_node->data = catset;
> +                               cil_list_append(((struct cil_symtab_datum*)catset)->nodes,
> +                                                               CIL_LIST_ITEM, cat_node);
> +                               arg->arg = (struct cil_symtab_datum*)catset;
> +                       } else if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
> +                               rc = SEPOL_ERR;
> +                               goto exit;
> +                       } else {
> +                               arg->arg_str = arg_node->data;
>                         }
> -                       case CIL_LEVEL: {
> -                               if (pc->cl_head != NULL) {
> -                                       struct cil_level *level = NULL;
> -                                       struct cil_tree_node *lvl_node = NULL;
> -                                       cil_level_init(&level);
> -
> -                                       rc = cil_fill_level(pc->cl_head, level);
> -                                       if (rc != SEPOL_OK) {
> -                                               cil_log(CIL_ERR, "Failed to create anonymous level, rc: %d\n", rc);
> -                                               cil_destroy_level(level);
> -                                               cil_destroy_args(new_arg);
> -                                               goto exit;
> -                                       }
> -                                       cil_tree_node_init(&lvl_node);
> -                                       lvl_node->flavor = CIL_LEVEL;
> -                                       lvl_node->data = level;
> -                                       cil_list_append(((struct cil_symtab_datum*)level)->nodes,
> -                                                                       CIL_LIST_ITEM, lvl_node);
> -                                       new_arg->arg = (struct cil_symtab_datum*)level;
> -                               } else if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> +
> +                       break;
> +               }
> +               case CIL_LEVEL: {
> +                       if (arg_node->cl_head != NULL) {
> +                               struct cil_level *level = NULL;
> +                               struct cil_tree_node *lvl_node = NULL;
> +                               cil_level_init(&level);
> +
> +                               rc = cil_fill_level(arg_node->cl_head, level);
> +                               if (rc != SEPOL_OK) {
> +                                       cil_log(CIL_ERR, "Failed to create anonymous level, rc: %d\n", rc);
> +                                       cil_destroy_level(level);
> +                                       cil_destroy_args(arg);
>                                         goto exit;
> -                               } else {
> -                                       new_arg->arg_str = pc->data;
>                                 }
> -
> -                               break;
> +                               cil_tree_node_init(&lvl_node);
> +                               lvl_node->flavor = CIL_LEVEL;
> +                               lvl_node->data = level;
> +                               cil_list_append(((struct cil_symtab_datum*)level)->nodes,
> +                                                               CIL_LIST_ITEM, lvl_node);
> +                               arg->arg = (struct cil_symtab_datum*)level;
> +                       } else if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
> +                               rc = SEPOL_ERR;
> +                               goto exit;
> +                       } else {
> +                               arg->arg_str = arg_node->data;
>                         }
> -                       case CIL_LEVELRANGE: {
> -                               if (pc->cl_head != NULL) {
> -                                       struct cil_levelrange *range = NULL;
> -                                       struct cil_tree_node *range_node = NULL;
> -                                       cil_levelrange_init(&range);
> -
> -                                       rc = cil_fill_levelrange(pc->cl_head, range);
> -                                       if (rc != SEPOL_OK) {
> -                                               cil_log(CIL_ERR, "Failed to create anonymous levelrange, rc: %d\n", rc);
> -                                               cil_destroy_levelrange(range);
> -                                               cil_destroy_args(new_arg);
> -                                               goto exit;
> -                                       }
> -                                       cil_tree_node_init(&range_node);
> -                                       range_node->flavor = CIL_LEVELRANGE;
> -                                       range_node->data = range;
> -                                       cil_list_append(((struct cil_symtab_datum*)range)->nodes,
> -                                                                       CIL_LIST_ITEM, range_node);
> -                                       new_arg->arg = (struct cil_symtab_datum*)range;
> -                               } else if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> +
> +                       break;
> +               }
> +               case CIL_LEVELRANGE: {
> +                       if (arg_node->cl_head != NULL) {
> +                               struct cil_levelrange *range = NULL;
> +                               struct cil_tree_node *range_node = NULL;
> +                               cil_levelrange_init(&range);
> +
> +                               rc = cil_fill_levelrange(arg_node->cl_head, range);
> +                               if (rc != SEPOL_OK) {
> +                                       cil_log(CIL_ERR, "Failed to create anonymous levelrange, rc: %d\n", rc);
> +                                       cil_destroy_levelrange(range);
> +                                       cil_destroy_args(arg);
>                                         goto exit;
> -                               } else {
> -                                       new_arg->arg_str = pc->data;
>                                 }
> -
> -                               break;
> +                               cil_tree_node_init(&range_node);
> +                               range_node->flavor = CIL_LEVELRANGE;
> +                               range_node->data = range;
> +                               cil_list_append(((struct cil_symtab_datum*)range)->nodes,
> +                                                               CIL_LIST_ITEM, range_node);
> +                               arg->arg = (struct cil_symtab_datum*)range;
> +                       } else if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
> +                               rc = SEPOL_ERR;
> +                               goto exit;
> +                       } else {
> +                               arg->arg_str = arg_node->data;
>                         }
> -                       case CIL_IPADDR: {
> -                               if (pc->cl_head != NULL) {
> -                                       struct cil_ipaddr *ipaddr = NULL;
> -                                       struct cil_tree_node *addr_node = NULL;
> -                                       cil_ipaddr_init(&ipaddr);
> -
> -                                       rc = cil_fill_ipaddr(pc->cl_head, ipaddr);
> -                                       if (rc != SEPOL_OK) {
> -                                               cil_log(CIL_ERR, "Failed to create anonymous ip address, rc: %d\n", rc);
> -                                               cil_destroy_ipaddr(ipaddr);
> -                                               cil_destroy_args(new_arg);
> -                                               goto exit;
> -                                       }
> -                                       cil_tree_node_init(&addr_node);
> -                                       addr_node->flavor = CIL_IPADDR;
> -                                       addr_node->data = ipaddr;
> -                                       cil_list_append(((struct cil_symtab_datum*)ipaddr)->nodes,
> -                                                                       CIL_LIST_ITEM, addr_node);
> -                                       new_arg->arg = (struct cil_symtab_datum*)ipaddr;
> -                               } else if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> +
> +                       break;
> +               }
> +               case CIL_IPADDR: {
> +                       if (arg_node->cl_head != NULL) {
> +                               struct cil_ipaddr *ipaddr = NULL;
> +                               struct cil_tree_node *addr_node = NULL;
> +                               cil_ipaddr_init(&ipaddr);
> +
> +                               rc = cil_fill_ipaddr(arg_node->cl_head, ipaddr);
> +                               if (rc != SEPOL_OK) {
> +                                       cil_log(CIL_ERR, "Failed to create anonymous ip address, rc: %d\n", rc);
> +                                       cil_destroy_ipaddr(ipaddr);
> +                                       cil_destroy_args(arg);
>                                         goto exit;
> -                               } else {
> -                                       new_arg->arg_str = pc->data;
>                                 }
> +                               cil_tree_node_init(&addr_node);
> +                               addr_node->flavor = CIL_IPADDR;
> +                               addr_node->data = ipaddr;
> +                               cil_list_append(((struct cil_symtab_datum*)ipaddr)->nodes,
> +                                                               CIL_LIST_ITEM, addr_node);
> +                               arg->arg = (struct cil_symtab_datum*)ipaddr;
> +                       } else if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
> +                               rc = SEPOL_ERR;
> +                               goto exit;
> +                       } else {
> +                               arg->arg_str = arg_node->data;
> +                       }
>
> -                               break;
> +                       break;
> +               }
> +               case CIL_CLASS:
> +                       if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
> +                               rc = SEPOL_ERR;
> +                               goto exit;
>                         }
> -                       case CIL_CLASS:
> -                               if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> -                                       goto exit;
> -                               }
> -                               new_arg->arg_str = pc->data;
> -                               break;
> -                       case CIL_MAP_CLASS:
> -                               if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> -                                       goto exit;
> -                               }
> -                               new_arg->arg_str = pc->data;
> -                               break;
> -                       case CIL_CLASSPERMISSION: {
> -                               if (pc->cl_head != NULL) {
> -                                       struct cil_classpermission *cp = NULL;
> -                                       struct cil_tree_node *cp_node = NULL;
> -
> -                                       cil_classpermission_init(&cp);
> -                                       rc = cil_fill_classperms_list(pc, &cp->classperms);
> -                                       if (rc != SEPOL_OK) {
> -                                               cil_log(CIL_ERR, "Failed to create anonymous classpermission\n");
> -                                               cil_destroy_classpermission(cp);
> -                                               cil_destroy_args(new_arg);
> -                                               goto exit;
> -                                       }
> -                                       cil_tree_node_init(&cp_node);
> -                                       cp_node->flavor = CIL_CLASSPERMISSION;
> -                                       cp_node->data = cp;
> -                                       cil_list_append(cp->datum.nodes, CIL_LIST_ITEM, cp_node);
> -                                       new_arg->arg = (struct cil_symtab_datum*)cp;
> -                               } else if (pc->data == NULL) {
> -                                       cil_tree_log(current, CIL_ERR, "Invalid macro parameter");
> -                                       cil_destroy_args(new_arg);
> -                                       rc = SEPOL_ERR;
> +                       arg->arg_str = arg_node->data;
> +                       break;
> +               case CIL_MAP_CLASS:
> +                       if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
> +                               rc = SEPOL_ERR;
> +                               goto exit;
> +                       }
> +                       arg->arg_str = arg_node->data;
> +                       break;
> +               case CIL_CLASSPERMISSION: {
> +                       if (arg_node->cl_head != NULL) {
> +                               struct cil_classpermission *cp = NULL;
> +                               struct cil_tree_node *cp_node = NULL;
> +
> +                               cil_classpermission_init(&cp);
> +                               rc = cil_fill_classperms_list(arg_node, &cp->classperms);
> +                               if (rc != SEPOL_OK) {
> +                                       cil_log(CIL_ERR, "Failed to create anonymous classpermission\n");
> +                                       cil_destroy_classpermission(cp);
> +                                       cil_destroy_args(arg);
>                                         goto exit;
> -                               } else {
> -                                       new_arg->arg_str = pc->data;
>                                 }
> -                               break;
> -                       }
> -                       default:
> -                               cil_log(CIL_ERR, "Unexpected flavor: %d\n",
> -                                               (((struct cil_param*)item->data)->flavor));
> -                               cil_destroy_args(new_arg);
> +                               cil_tree_node_init(&cp_node);
> +                               cp_node->flavor = CIL_CLASSPERMISSION;
> +                               cp_node->data = cp;
> +                               cil_list_append(cp->datum.nodes, CIL_LIST_ITEM, cp_node);
> +                               arg->arg = (struct cil_symtab_datum*)cp;
> +                       } else if (arg_node->data == NULL) {
> +                               cil_tree_log(call_node, CIL_ERR, "Invalid macro parameter");
> +                               cil_destroy_args(arg);
>                                 rc = SEPOL_ERR;
>                                 goto exit;
> +                       } else {
> +                               arg->arg_str = arg_node->data;
>                         }
> -                       new_arg->param_str = ((struct cil_param*)item->data)->str;
> -                       new_arg->flavor = flavor;
> -
> -                       cil_list_append(new_call->args, CIL_ARGS, new_arg);
> -
> -                       pc = pc->next;
> +                       break;
>                 }
> -
> -               if (pc != NULL) {
> -                       cil_tree_log(current, CIL_ERR, "Unexpected arguments");
> +               default:
> +                       cil_log(CIL_ERR, "Unexpected flavor: %d\n",
> +                                       (((struct cil_param*)item->data)->flavor));
> +                       cil_destroy_args(arg);
>                         rc = SEPOL_ERR;
>                         goto exit;
>                 }
> -       } else if (new_call->args_tree != NULL) {
> -               cil_tree_log(current, CIL_ERR, "Unexpected arguments");
> -               rc = SEPOL_ERR;
> -               goto exit;
> -       }
> +               arg->param_str = ((struct cil_param*)item->data)->str;
> +               arg->flavor = flavor;
>
> -       if (new_call->copied == 0) {
> -               new_call->copied = 1;
> +               cil_list_append(call->args, CIL_ARGS, arg);
>
> -               rc = cil_check_recursive_call(current, macro_node);
> -               if (rc != SEPOL_OK) {
> -                       goto exit;
> -               }
> +               arg_node = arg_node->next;
> +       }
>
> -               rc = cil_copy_ast(db, macro_node, current);
> -               if (rc != SEPOL_OK) {
> -                       cil_log(CIL_ERR, "Failed to copy macro, rc: %d\n", rc);
> -                       goto exit;
> -               }
> +       if (arg_node != NULL) {
> +               cil_tree_log(call_node, CIL_ERR, "Unexpected arguments");
> +               rc = SEPOL_ERR;
> +               goto exit;
>         }
>
>         return SEPOL_OK;
> @@ -3180,19 +3142,17 @@ exit:
>         return rc;
>  }
>
> -int cil_resolve_call2(struct cil_tree_node *current, void *extra_args)
> +static int cil_resolve_call_args(struct cil_tree_node *call_node, struct cil_call *call, void *extra_args)
>  {
> -       struct cil_call *new_call = current->data;
> -       int rc = SEPOL_ERR;
> -       enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
>         struct cil_list_item *item;
> +       enum cil_sym_index sym_index = CIL_SYM_UNKNOWN;
> +       int rc = SEPOL_ERR;
>
> -       if (new_call->args == NULL) {
> -               rc = SEPOL_OK;
> -               goto exit;
> +       if (call->args == NULL) {
> +               return SEPOL_OK;
>         }
>
> -       cil_list_for_each(item, new_call->args) {
> +       cil_list_for_each(item, call->args) {
>                 struct cil_args *arg = item->data;
>                 if (arg->arg == NULL && arg->arg_str == NULL) {
>                         cil_log(CIL_ERR, "Arguments not created correctly\n");
> @@ -3275,9 +3235,9 @@ int cil_resolve_call2(struct cil_tree_node *current, void *extra_args)
>                 }
>
>                 if (sym_index != CIL_SYM_UNKNOWN) {
> -                       rc = cil_resolve_name(current, arg->arg_str, sym_index, extra_args, &(arg->arg));
> +                       rc = cil_resolve_name(call_node, arg->arg_str, sym_index, extra_args, &(arg->arg));
>                         if (rc != SEPOL_OK) {
> -                               cil_tree_log(current, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str);
> +                               cil_tree_log(call_node, CIL_ERR, "Failed to resolve %s in call argument list", arg->arg_str);
>                                 goto exit;
>                         }
>                 }
> @@ -3289,6 +3249,61 @@ exit:
>         return rc;
>  }
>
> +int cil_resolve_call(struct cil_tree_node *current, void *extra_args)
> +{
> +       struct cil_call *call = current->data;
> +       struct cil_args_resolve *args = extra_args;
> +       struct cil_tree_node *macro_node = NULL;
> +       struct cil_symtab_datum *macro_datum = NULL;
> +       int rc = SEPOL_ERR;
> +
> +       if (call->copied) {
> +               return SEPOL_OK;
> +       }
> +
> +       rc = cil_resolve_name(current, call->macro_str, CIL_SYM_BLOCKS, extra_args, &macro_datum);
> +       if (rc != SEPOL_OK) {
> +               goto exit;
> +       }
> +
> +       macro_node = NODE(macro_datum);
> +
> +       if (macro_node->flavor != CIL_MACRO) {
> +               cil_tree_log(current, CIL_ERR, "Failed to resolve %s to a macro", call->macro_str);
> +               rc = SEPOL_ERR;
> +               goto exit;
> +       }
> +       call->macro = (struct cil_macro*)macro_datum;
> +
> +       rc = cil_build_call_args(current, call, call->macro, extra_args);
> +       if (rc != SEPOL_OK) {
> +               goto exit;
> +       }
> +
> +       rc = cil_resolve_call_args(current, call, extra_args);
> +       if (rc != SEPOL_OK) {
> +               goto exit;
> +       }
> +
> +       call->copied = 1;
> +
> +       rc = cil_check_recursive_call(current, macro_node);
> +       if (rc != SEPOL_OK) {
> +               goto exit;
> +       }
> +
> +       rc = cil_copy_ast(args->db, macro_node, current);
> +       if (rc != SEPOL_OK) {
> +               cil_log(CIL_ERR, "Failed to copy macro, rc: %d\n", rc);
> +               goto exit;
> +       }
> +
> +       return SEPOL_OK;
> +
> +exit:
> +       return rc;
> +}
> +
>  int cil_resolve_name_call_args(struct cil_call *call, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum)
>  {
>         struct cil_list_item *item;
> @@ -3604,18 +3619,8 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
>                 }
>                 break;
>         case CIL_PASS_MACRO:
> -               if (node->flavor == CIL_CALL && args->macro != NULL) {
> -                       rc = cil_resolve_call1(node, args);
> -               }
> -               break;
> -       case CIL_PASS_CALL1:
> -               if (node->flavor == CIL_CALL) {
> -                       rc = cil_resolve_call1(node, args);
> -               }
> -               break;
> -       case CIL_PASS_CALL2:
> -               if (node->flavor == CIL_CALL) {
> -                       rc = cil_resolve_call2(node, args);
> +               if (node->flavor == CIL_CALL && args->macro == NULL) {
> +                       rc = cil_resolve_call(node, args);
>                 }
>                 break;
>         case CIL_PASS_ALIAS1:
> @@ -4188,7 +4193,6 @@ exit:
>  static int __cil_resolve_name_with_root(struct cil_db *db, char *name, enum cil_sym_index sym_index, struct cil_symtab_datum **datum)
>  {
>         symtab_t *symtab = &((struct cil_root *)db->ast->root->data)->symtab[sym_index];
> -
>         return cil_symtab_get_datum(symtab, name, datum);
>  }
>
> --
> 2.26.3
>

  reply	other threads:[~2021-05-10 14:20 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-07 17:37 [PATCH 1/3] libsepol/cil: Make name resolution in macros work as documented James Carter
2021-05-07 17:37 ` [PATCH 2/3] libsepol/cil: Copy and resolve macro calls in one pass James Carter
2021-05-10 13:55   ` James Carter [this message]
2021-05-07 17:37 ` [PATCH 3/3] secilc/docs: Relocate and reword macro call name resolution order James Carter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CAP+JOzTjZrFpDhceF54Pv2WMPzQG4gYqdoxh1HZX9kECxgBr0A@mail.gmail.com \
    --to=jwcart2@gmail.com \
    --cc=selinux@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.