Re: [PATCH 2/3] libsepol/cil: Copy and resolve macro calls in one pass

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

 



On Fri, May 7, 2021 at 1:37 PM James Carter <jwcart2@xxxxxxxxx> wrote:
>
> Lorenzo Ceragioli <lorenzo.ceragioli@xxxxxxxxxxxx> 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@xxxxxxxxx>
> ---
>  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
>



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

  Powered by Linux