Re: [PATCH 2/3] libsepol: Support nlmsg extended permissions

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

 



On Wed, Aug 21, 2024 at 8:38 PM Thiébaud Weksteen <tweek@xxxxxxxxxx> wrote:
>
> Add support for AVTAB_XPERMS_NLMSG as extended permissions for netlink
> sockets. The behaviour is similar to the existing
> AVTAB_XPERMS_IOCTLFUNCTION.
>
> Signed-off-by: Thiébaud Weksteen <tweek@xxxxxxxxxx>

Acked-by: Stephen Smalley <stephen.smalley.work@xxxxxxxxx>

(side bar: would be nice to reduce the duplicated checking/handling of
"ioctl" and "nlmsg" throughout, but you didn't introduce it for ioctl
so not fair to require you to fix it)

> ---
>  checkpolicy/policy_define.c                | 64 +++++++++++++++--
>  checkpolicy/test/dismod.c                  |  2 +
>  libsepol/cil/src/cil.c                     |  2 +
>  libsepol/cil/src/cil_binary.c              | 84 ++++++++++++++++------
>  libsepol/cil/src/cil_build_ast.c           |  4 +-
>  libsepol/cil/src/cil_internal.h            |  2 +
>  libsepol/cil/src/cil_policy.c              |  2 +
>  libsepol/cil/src/cil_verify.c              |  3 +
>  libsepol/cil/src/cil_write_ast.c           | 16 ++++-
>  libsepol/include/sepol/policydb/avtab.h    |  1 +
>  libsepol/include/sepol/policydb/policydb.h |  1 +
>  libsepol/src/expand.c                      |  3 +
>  libsepol/src/kernel_to_cil.c               | 21 ++++--
>  libsepol/src/module_to_cil.c               | 20 ++++--
>  libsepol/src/policydb_validate.c           |  2 +
>  libsepol/src/util.c                        | 14 ++--
>  16 files changed, 200 insertions(+), 41 deletions(-)
>
> diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c
> index 4f6b2266..6b062657 100644
> --- a/checkpolicy/policy_define.c
> +++ b/checkpolicy/policy_define.c
> @@ -2342,8 +2342,8 @@ static int avrule_ioctl_completedriver(struct av_xperm_range_list *rangelist,
>         return 0;
>  }
>
> -static int avrule_ioctl_func(struct av_xperm_range_list *rangelist,
> -               av_extended_perms_t **extended_perms, unsigned int driver)
> +static int avrule_xperm_func(struct av_xperm_range_list *rangelist,
> +               av_extended_perms_t **extended_perms, unsigned int driver, uint8_t specified)
>  {
>         struct av_xperm_range_list *r;
>         av_extended_perms_t *xperms;
> @@ -2379,7 +2379,7 @@ static int avrule_ioctl_func(struct av_xperm_range_list *rangelist,
>                 high = IOC_FUNC(high);
>                 avrule_xperm_setrangebits(low, high, xperms);
>                 xperms->driver = driver;
> -               xperms->specified = AVRULE_XPERMS_IOCTLFUNCTION;
> +               xperms->specified = specified;
>                 r = r->next;
>         }
>
> @@ -2495,7 +2495,61 @@ static int define_te_avtab_ioctl(const avrule_t *avrule_template)
>          */
>         i = 0;
>         while (xperms_for_each_bit(&i, partial_driver)) {
> -               if (avrule_ioctl_func(rangelist, &xperms, i))
> +               if (avrule_xperm_func(rangelist, &xperms, i, AVRULE_XPERMS_IOCTLFUNCTION))
> +                       return -1;
> +
> +               if (xperms) {
> +                       avrule = (avrule_t *) calloc(1, sizeof(avrule_t));
> +                       if (!avrule) {
> +                               yyerror("out of memory");
> +                               return -1;
> +                       }
> +                       if (avrule_cpy(avrule, avrule_template))
> +                               return -1;
> +                       avrule->xperms = xperms;
> +                       append_avrule(avrule);
> +               }
> +       }
> +
> +done:
> +       if (partial_driver)
> +               free(partial_driver);
> +
> +       while (rangelist != NULL) {
> +               r = rangelist;
> +               rangelist = rangelist->next;
> +               free(r);
> +       }
> +
> +       return 0;
> +}
> +
> +static int define_te_avtab_netlink(const avrule_t *avrule_template)
> +{
> +       avrule_t *avrule;
> +       struct av_xperm_range_list *rangelist, *r;
> +       av_extended_perms_t *partial_driver, *xperms;
> +       unsigned int i;
> +
> +       /* organize ranges */
> +       if (avrule_xperm_ranges(&rangelist))
> +               return -1;
> +
> +       /* flag driver codes that are partially enabled */
> +       if (avrule_xperm_partialdriver(rangelist, NULL, &partial_driver))
> +               return -1;
> +
> +       if (!partial_driver || !avrule_xperms_used(partial_driver))
> +               goto done;
> +
> +       /*
> +        * create rule for each partially used driver codes
> +        * "partially used" meaning that the code number e.g. socket 0x89
> +        * has some permission bits set and others not set.
> +        */
> +       i = 0;
> +       while (xperms_for_each_bit(&i, partial_driver)) {
> +               if (avrule_xperm_func(rangelist, &xperms, i, AVRULE_XPERMS_NLMSG))
>                         return -1;
>
>                 if (xperms) {
> @@ -2546,6 +2600,8 @@ int define_te_avtab_extended_perms(int which)
>         id = queue_remove(id_queue);
>         if (strcmp(id,"ioctl") == 0) {
>                 rc = define_te_avtab_ioctl(avrule_template);
> +       } else if (strcmp(id,"nlmsg") == 0) {
> +               rc = define_te_avtab_netlink(avrule_template);
>         } else {
>                 yyerror2("only ioctl extended permissions are supported, found %s", id);
>                 rc = -1;
> diff --git a/checkpolicy/test/dismod.c b/checkpolicy/test/dismod.c
> index bd45c95e..4868190f 100644
> --- a/checkpolicy/test/dismod.c
> +++ b/checkpolicy/test/dismod.c
> @@ -353,6 +353,8 @@ static int display_avrule(avrule_t * avrule, policydb_t * policy,
>                         xperms.specified = AVTAB_XPERMS_IOCTLFUNCTION;
>                 else if (avrule->xperms->specified == AVRULE_XPERMS_IOCTLDRIVER)
>                         xperms.specified = AVTAB_XPERMS_IOCTLDRIVER;
> +               else if (avrule->xperms->specified == AVRULE_XPERMS_NLMSG)
> +                       xperms.specified = AVTAB_XPERMS_NLMSG;
>                 else {
>                         fprintf(fp, "     ERROR: no valid xperms specified\n");
>                         return -1;
> diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
> index 067e28a6..5521c7ea 100644
> --- a/libsepol/cil/src/cil.c
> +++ b/libsepol/cil/src/cil.c
> @@ -221,6 +221,7 @@ char *CIL_KEY_DONTAUDITX;
>  char *CIL_KEY_NEVERALLOWX;
>  char *CIL_KEY_PERMISSIONX;
>  char *CIL_KEY_IOCTL;
> +char *CIL_KEY_NLMSG;
>  char *CIL_KEY_UNORDERED;
>  char *CIL_KEY_SRC_INFO;
>  char *CIL_KEY_SRC_CIL;
> @@ -393,6 +394,7 @@ static void cil_init_keys(void)
>         CIL_KEY_NEVERALLOWX = cil_strpool_add("neverallowx");
>         CIL_KEY_PERMISSIONX = cil_strpool_add("permissionx");
>         CIL_KEY_IOCTL = cil_strpool_add("ioctl");
> +       CIL_KEY_NLMSG = cil_strpool_add("nlmsg");
>         CIL_KEY_UNORDERED = cil_strpool_add("unordered");
>         CIL_KEY_SRC_INFO = cil_strpool_add("<src_info>");
>         CIL_KEY_SRC_CIL = cil_strpool_add("cil");
> diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
> index c8144a5a..3dec1883 100644
> --- a/libsepol/cil/src/cil_binary.c
> +++ b/libsepol/cil/src/cil_binary.c
> @@ -66,6 +66,7 @@ struct cil_args_binary {
>         int pass;
>         hashtab_t role_trans_table;
>         hashtab_t avrulex_ioctl_table;
> +       hashtab_t avrulex_nlmsg_table;
>         void **type_value_to_cil;
>  };
>
> @@ -1671,11 +1672,22 @@ static void __avrule_xperm_setrangebits(uint16_t low, uint16_t high, struct avta
>         }
>  }
>
> +static char* __cil_xperm_kind_to_str(uint32_t xperm_kind)
> +{
> +       switch (xperm_kind) {
> +               case CIL_PERMX_KIND_IOCTL:
> +                       return CIL_KEY_IOCTL;
> +               case CIL_PERMX_KIND_NLMSG:
> +                       return CIL_KEY_NLMSG;
> +               default:
> +                       return (char *) "unknown";
> +       }
> +}
>
>  #define IOC_DRIV(x) (x >> 8)
>  #define IOC_FUNC(x) (x & 0xff)
>
> -static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil_list **xperms_list)
> +static int __cil_permx_bitmap_to_sepol_xperms_list(uint32_t kind, ebitmap_t *xperms, struct cil_list **xperms_list)
>  {
>         ebitmap_node_t *node;
>         unsigned int i;
> @@ -1705,7 +1717,7 @@ static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil
>                 high = i;
>                 start_new_range = 1;
>
> -               if (IOC_FUNC(low) == 0x00 && IOC_FUNC(high) == 0xff) {
> +               if (kind == CIL_PERMX_KIND_IOCTL && IOC_FUNC(low) == 0x00 && IOC_FUNC(high) == 0xff) {
>                         if (!complete) {
>                                 complete = cil_calloc(1, sizeof(*complete));
>                                 complete->driver = 0x0;
> @@ -1722,7 +1734,14 @@ static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil
>                         if (!partial) {
>                                 partial = cil_calloc(1, sizeof(*partial));
>                                 partial->driver = IOC_DRIV(low);
> -                               partial->specified = AVTAB_XPERMS_IOCTLFUNCTION;
> +                               switch (kind) {
> +                               case CIL_PERMX_KIND_IOCTL:
> +                                       partial->specified = AVTAB_XPERMS_IOCTLFUNCTION;
> +                                       break;
> +                               case CIL_PERMX_KIND_NLMSG:
> +                                       partial->specified = AVTAB_XPERMS_NLMSG;
> +                                       break;
> +                               }
>                         }
>
>                         __avrule_xperm_setrangebits(IOC_FUNC(low), IOC_FUNC(high), partial);
> @@ -1740,7 +1759,7 @@ static int __cil_permx_bitmap_to_sepol_xperms_list(ebitmap_t *xperms, struct cil
>         return SEPOL_OK;
>  }
>
> -static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args)
> +static int __cil_avrulex_xperm_to_policydb(hashtab_key_t k, hashtab_datum_t datum, uint32_t xperm_kind, void *args)
>  {
>         int rc = SEPOL_OK;
>         struct policydb *pdb;
> @@ -1750,6 +1769,7 @@ static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datu
>         struct cil_list_item *item;
>         class_datum_t *sepol_obj;
>         uint32_t data = 0;
> +       char *kind = NULL;
>
>         avtab_key = (avtab_key_t *)k;
>         pdb = args;
> @@ -1759,13 +1779,14 @@ static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datu
>         // setting the data for an extended avtab isn't really necessary because
>         // it is ignored by the kernel. However, neverallow checking requires that
>         // the data value be set, so set it for that to work.
> -       rc = __perm_str_to_datum(CIL_KEY_IOCTL, sepol_obj, &data);
> +       kind = __cil_xperm_kind_to_str(xperm_kind);
> +       rc = __perm_str_to_datum(kind, sepol_obj, &data);
>         if (rc != SEPOL_OK) {
>                 goto exit;
>         }
>         avtab_datum.data = data;
>
> -       rc = __cil_permx_bitmap_to_sepol_xperms_list(datum, &xperms_list);
> +       rc = __cil_permx_bitmap_to_sepol_xperms_list(xperm_kind, datum, &xperms_list);
>         if (rc != SEPOL_OK) {
>                 goto exit;
>         }
> @@ -1790,7 +1811,15 @@ exit:
>         return rc;
>  }
>
> -static int __cil_avrulex_ioctl_to_hashtable(hashtab_t h, uint16_t kind, uint32_t src, uint32_t tgt, uint32_t obj, ebitmap_t *xperms)
> +static int __cil_avrulex_ioctl_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args) {
> +       return __cil_avrulex_xperm_to_policydb(k, datum, CIL_PERMX_KIND_IOCTL, args);
> +}
> +
> +static int __cil_avrulex_nlmsg_to_policydb(hashtab_key_t k, hashtab_datum_t datum, void *args) {
> +       return __cil_avrulex_xperm_to_policydb(k, datum, CIL_PERMX_KIND_NLMSG, args);
> +}
> +
> +static int __cil_avrulex_xperm_to_hashtable(hashtab_t h, uint16_t kind, uint32_t src, uint32_t tgt, uint32_t obj, ebitmap_t *xperms)
>  {
>         uint16_t specified;
>         avtab_key_t *avtab_key;
> @@ -1870,7 +1899,11 @@ static int __cil_avrulex_to_hashtable_helper(policydb_t *pdb, uint16_t kind, str
>
>                 switch (permx->kind) {
>                 case  CIL_PERMX_KIND_IOCTL:
> -                       rc = __cil_avrulex_ioctl_to_hashtable(args->avrulex_ioctl_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms);
> +                       rc = __cil_avrulex_xperm_to_hashtable(args->avrulex_ioctl_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms);
> +                       if (rc != SEPOL_OK) goto exit;
> +                       break;
> +               case  CIL_PERMX_KIND_NLMSG:
> +                       rc = __cil_avrulex_xperm_to_hashtable(args->avrulex_nlmsg_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms);
>                         if (rc != SEPOL_OK) goto exit;
>                         break;
>                 default:
> @@ -2037,7 +2070,7 @@ exit:
>         return rc;
>  }
>
> -static int __cil_avrulex_ioctl_destroy(hashtab_key_t k, hashtab_datum_t datum, __attribute__((unused)) void *args)
> +static int __cil_avrulex_xperm_destroy(hashtab_key_t k, hashtab_datum_t datum, __attribute__((unused)) void *args)
>  {
>         free(k);
>         ebitmap_destroy(datum);
> @@ -4630,6 +4663,9 @@ static int __cil_permx_to_sepol_class_perms(policydb_t *pdb, struct cil_permissi
>                         case CIL_PERMX_KIND_IOCTL:
>                                 perm_str = CIL_KEY_IOCTL;
>                                 break;
> +                       case CIL_PERMX_KIND_NLMSG:
> +                               perm_str = CIL_KEY_NLMSG;
> +                               break;
>                         default:
>                                 rc = SEPOL_ERR;
>                                 goto exit;
> @@ -4769,17 +4805,10 @@ static void __cil_print_classperm(struct cil_list *cp_list)
>
>  static void __cil_print_permissionx(struct cil_permissionx *px)
>  {
> -       const char *kind_str = "";
> +       const char *kind_str = NULL;
>         char *expr_str;
>
> -       switch (px->kind) {
> -               case CIL_PERMX_KIND_IOCTL:
> -                       kind_str = CIL_KEY_IOCTL;
> -                       break;
> -               default:
> -                       kind_str = "unknown";
> -                       break;
> -       }
> +       kind_str = __cil_xperm_kind_to_str(px->kind);
>
>         __cil_expr_to_string(px->expr_str, CIL_PERMISSIONX, &expr_str);
>
> @@ -4928,7 +4957,7 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct
>                         goto exit;
>                 }
>
> -               rc = __cil_permx_bitmap_to_sepol_xperms_list(cil_rule->perms.x.permx->perms, &xperms);
> +               rc = __cil_permx_bitmap_to_sepol_xperms_list(cil_rule->perms.x.permx->kind, cil_rule->perms.x.permx->perms, &xperms);
>                 if (rc != SEPOL_OK) {
>                         goto exit;
>                 }
> @@ -5137,6 +5166,7 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
>         struct cil_list *neverallows = NULL;
>         hashtab_t role_trans_table = NULL;
>         hashtab_t avrulex_ioctl_table = NULL;
> +       hashtab_t avrulex_nlmsg_table = NULL;
>         void **type_value_to_cil = NULL;
>         struct cil_class **class_value_to_cil = NULL;
>         struct cil_perm ***perm_value_to_cil = NULL;
> @@ -5184,6 +5214,12 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
>                 goto exit;
>         }
>
> +       avrulex_nlmsg_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE);
> +       if (!avrulex_nlmsg_table) {
> +               cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n");
> +               goto exit;
> +       }
> +
>         cil_list_init(&neverallows, CIL_LIST_ITEM);
>
>         extra_args.db = db;
> @@ -5191,6 +5227,7 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
>         extra_args.neverallows = neverallows;
>         extra_args.role_trans_table = role_trans_table;
>         extra_args.avrulex_ioctl_table = avrulex_ioctl_table;
> +       extra_args.avrulex_nlmsg_table = avrulex_nlmsg_table;
>         extra_args.type_value_to_cil = type_value_to_cil;
>
>         for (i = 1; i <= 3; i++) {
> @@ -5216,6 +5253,11 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
>                                 cil_log(CIL_INFO, "Failure creating avrulex rules\n");
>                                 goto exit;
>                         }
> +                       rc = hashtab_map(avrulex_nlmsg_table, __cil_avrulex_nlmsg_to_policydb, pdb);
> +                       if (rc != SEPOL_OK) {
> +                               cil_log(CIL_INFO, "Failure creating avrulex rules\n");
> +                               goto exit;
> +                       }
>                 }
>         }
>
> @@ -5287,8 +5329,10 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p
>
>  exit:
>         hashtab_destroy(role_trans_table);
> -       hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_destroy, NULL);
> +       hashtab_map(avrulex_ioctl_table, __cil_avrulex_xperm_destroy, NULL);
>         hashtab_destroy(avrulex_ioctl_table);
> +       hashtab_map(avrulex_nlmsg_table, __cil_avrulex_xperm_destroy, NULL);
> +       hashtab_destroy(avrulex_nlmsg_table);
>         free(type_value_to_cil);
>         free(class_value_to_cil);
>         if (perm_value_to_cil != NULL) {
> diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
> index 56dac891..87178294 100644
> --- a/libsepol/cil/src/cil_build_ast.c
> +++ b/libsepol/cil/src/cil_build_ast.c
> @@ -2153,8 +2153,10 @@ static int cil_fill_permissionx(struct cil_tree_node *parse_current, struct cil_
>
>         if (parse_current->data == CIL_KEY_IOCTL) {
>                 permx->kind = CIL_PERMX_KIND_IOCTL;
> +       } else if (parse_current->data == CIL_KEY_NLMSG) {
> +               permx->kind = CIL_PERMX_KIND_NLMSG;
>         } else {
> -               cil_log(CIL_ERR, "Unknown permissionx kind, %s. Must be \"ioctl\"\n", (char *)parse_current->data);
> +               cil_log(CIL_ERR, "Unknown permissionx kind, %s. Must be \"ioctl\" or \"nlmsg\"\n", (char *)parse_current->data);
>                 rc = SEPOL_ERR;
>                 goto exit;
>         }
> diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
> index 47b67c89..959b31e3 100644
> --- a/libsepol/cil/src/cil_internal.h
> +++ b/libsepol/cil/src/cil_internal.h
> @@ -238,6 +238,7 @@ extern char *CIL_KEY_DONTAUDITX;
>  extern char *CIL_KEY_NEVERALLOWX;
>  extern char *CIL_KEY_PERMISSIONX;
>  extern char *CIL_KEY_IOCTL;
> +extern char *CIL_KEY_NLMSG;
>  extern char *CIL_KEY_UNORDERED;
>  extern char *CIL_KEY_SRC_INFO;
>  extern char *CIL_KEY_SRC_CIL;
> @@ -636,6 +637,7 @@ struct cil_avrule {
>  };
>
>  #define CIL_PERMX_KIND_IOCTL 1
> +#define CIL_PERMX_KIND_NLMSG 2
>  struct cil_permissionx {
>         struct cil_symtab_datum datum;
>         uint32_t kind;
> diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
> index e9a8f75d..c497c8ab 100644
> --- a/libsepol/cil/src/cil_policy.c
> +++ b/libsepol/cil/src/cil_policy.c
> @@ -1112,6 +1112,8 @@ static void cil_xperms_to_policy(FILE *out, struct cil_permissionx *permx)
>
>         if (permx->kind == CIL_PERMX_KIND_IOCTL) {
>                 kind = "ioctl";
> +       } else if (permx->kind == CIL_PERMX_KIND_NLMSG) {
> +               kind = "nlmsg";
>         } else {
>                 kind = "???";
>         }
> diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
> index 4ef2cbab..9621a247 100644
> --- a/libsepol/cil/src/cil_verify.c
> +++ b/libsepol/cil/src/cil_verify.c
> @@ -1513,6 +1513,9 @@ static int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tr
>                 case CIL_PERMX_KIND_IOCTL:
>                         kind_str = CIL_KEY_IOCTL;
>                         break;
> +               case CIL_PERMX_KIND_NLMSG:
> +                       kind_str = CIL_KEY_NLMSG;
> +                       break;
>                 default:
>                         cil_tree_log(node, CIL_ERR, "Invalid permissionx kind (%d)", permx->kind);
>                         rc = SEPOL_ERR;
> diff --git a/libsepol/cil/src/cil_write_ast.c b/libsepol/cil/src/cil_write_ast.c
> index 46bd84db..cd1b6e6c 100644
> --- a/libsepol/cil/src/cil_write_ast.c
> +++ b/libsepol/cil/src/cil_write_ast.c
> @@ -303,7 +303,13 @@ static void write_permx(FILE *out, struct cil_permissionx *permx)
>                 fprintf(out, "%s", datum_to_str(DATUM(permx)));
>         } else {
>                 fprintf(out, "(");
> -               fprintf(out, "%s ", permx->kind == CIL_PERMX_KIND_IOCTL ? "ioctl" : "<?KIND>");
> +               if (permx->kind == CIL_PERMX_KIND_IOCTL) {
> +                       fprintf(out, "ioctl ");
> +               } else if (permx->kind == CIL_PERMX_KIND_NLMSG) {
> +                       fprintf(out, "nlmsg ");
> +               } else {
> +                       fprintf(out, "<?KIND> ");
> +               }
>                 fprintf(out, "%s ", datum_or_str(DATUM(permx->obj), permx->obj_str));
>                 write_expr(out, permx->expr_str);
>                 fprintf(out, ")");
> @@ -825,7 +831,13 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
>         case CIL_PERMISSIONX: {
>                 struct cil_permissionx *permx = node->data;
>                 fprintf(out, "(permissionx %s (", datum_to_str(DATUM(permx)));
> -               fprintf(out, "%s ", permx->kind == CIL_PERMX_KIND_IOCTL ? "ioctl" : "<?KIND>");
> +               if (permx->kind == CIL_PERMX_KIND_IOCTL) {
> +                       fprintf(out, "ioctl ");
> +               } else if (permx->kind == CIL_PERMX_KIND_NLMSG) {
> +                       fprintf(out, "nlmsg ");
> +               } else {
> +                       fprintf(out, "<?KIND> ");
> +               }
>                 fprintf(out, "%s ", datum_or_str(DATUM(permx->obj), permx->obj_str));
>                 write_expr(out, permx->expr_str);
>                 fprintf(out, "))\n");
> diff --git a/libsepol/include/sepol/policydb/avtab.h b/libsepol/include/sepol/policydb/avtab.h
> index 2ab99c39..6e154cfe 100644
> --- a/libsepol/include/sepol/policydb/avtab.h
> +++ b/libsepol/include/sepol/policydb/avtab.h
> @@ -74,6 +74,7 @@ typedef struct avtab_extended_perms {
>
>  #define AVTAB_XPERMS_IOCTLFUNCTION     0x01
>  #define AVTAB_XPERMS_IOCTLDRIVER       0x02
> +#define AVTAB_XPERMS_NLMSG     0x03
>         /* extension of the avtab_key specified */
>         uint8_t specified;
>         uint8_t driver;
> diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
> index 856faeb7..104a7dc8 100644
> --- a/libsepol/include/sepol/policydb/policydb.h
> +++ b/libsepol/include/sepol/policydb/policydb.h
> @@ -259,6 +259,7 @@ typedef struct class_perm_node {
>  typedef struct av_extended_perms {
>  #define AVRULE_XPERMS_IOCTLFUNCTION    0x01
>  #define AVRULE_XPERMS_IOCTLDRIVER      0x02
> +#define AVRULE_XPERMS_NLMSG    0x03
>         uint8_t specified;
>         uint8_t driver;
>         /* 256 bits of permissions */
> diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
> index e63414b1..7032a83f 100644
> --- a/libsepol/src/expand.c
> +++ b/libsepol/src/expand.c
> @@ -1821,6 +1821,9 @@ static int allocate_xperms(sepol_handle_t * handle, avtab_datum_t * avdatump,
>         case AVRULE_XPERMS_IOCTLDRIVER:
>                 xperms->specified = AVTAB_XPERMS_IOCTLDRIVER;
>                 break;
> +       case AVRULE_XPERMS_NLMSG:
> +               xperms->specified = AVTAB_XPERMS_NLMSG;
> +               break;
>         default:
>                 return -1;
>         }
> diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c
> index f94cb245..7243b3c0 100644
> --- a/libsepol/src/kernel_to_cil.c
> +++ b/libsepol/src/kernel_to_cil.c
> @@ -1651,7 +1651,8 @@ static char *xperms_to_str(const avtab_extended_perms_t *xperms)
>         size_t remaining, size = 128;
>
>         if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
> -               && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) {
> +               && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
> +               && (xperms->specified != AVTAB_XPERMS_NLMSG)) {
>                 return NULL;
>         }
>
> @@ -1681,7 +1682,8 @@ retry:
>                         continue;
>                 }
>
> -               if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) {
> +               if ((xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION)
> +                || (xperms->specified == AVTAB_XPERMS_NLMSG)) {
>                         value = xperms->driver<<8 | bit;
>                         if (in_range) {
>                                 low_value = xperms->driver<<8 | low_bit;
> @@ -1690,7 +1692,7 @@ retry:
>                         } else {
>                                 len = snprintf(p, remaining, " 0x%hx", value);
>                         }
> -               } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) {
> +               } else if (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
>                         value = bit << 8;
>                         if (in_range) {
>                                 low_value = low_bit << 8;
> @@ -1728,7 +1730,7 @@ static char *avtab_node_to_str(struct policydb *pdb, avtab_key_t *key, avtab_dat
>         uint32_t data = datum->data;
>         type_datum_t *type;
>         const char *flavor, *tgt;
> -       char *src, *class, *perms, *new;
> +       char *src, *class, *perms, *new, *xperm;
>         char *rule = NULL;
>
>         switch (0xFFF & key->specified) {
> @@ -1795,9 +1797,16 @@ static char *avtab_node_to_str(struct policydb *pdb, avtab_key_t *key, avtab_dat
>                         ERR(NULL, "Failed to generate extended permission string");
>                         goto exit;
>                 }
> -
> +               if (datum->xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION || datum->xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
> +                       xperm = (char *) "ioctl";
> +               } else if (datum->xperms->specified == AVTAB_XPERMS_NLMSG) {
> +                       xperm = (char *) "nlmsg";
> +               } else {
> +                       ERR(NULL, "Unknown extended permssion");
> +                       goto exit;
> +               }
>                 rule = create_str("(%s %s %s (%s %s (%s)))",
> -                                 flavor, src, tgt, "ioctl", class, perms);
> +                                 flavor, src, tgt, xperm, class, perms);
>                 free(perms);
>         } else {
>                 new = pdb->p_type_val_to_name[data - 1];
> diff --git a/libsepol/src/module_to_cil.c b/libsepol/src/module_to_cil.c
> index 2dbf137e..79636897 100644
> --- a/libsepol/src/module_to_cil.c
> +++ b/libsepol/src/module_to_cil.c
> @@ -630,7 +630,8 @@ static int xperms_to_cil(const av_extended_perms_t *xperms)
>         int first = 1;
>
>         if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
> -               && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
> +               && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
> +               && (xperms->specified != AVTAB_XPERMS_NLMSG))
>                 return -1;
>
>         for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) {
> @@ -652,7 +653,8 @@ static int xperms_to_cil(const av_extended_perms_t *xperms)
>                 else
>                         first = 0;
>
> -               if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) {
> +               if ((xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION)
> +                || (xperms->specified == AVTAB_XPERMS_NLMSG)) {
>                         value = xperms->driver<<8 | bit;
>                         if (in_range) {
>                                 low_value = xperms->driver<<8 | low_bit;
> @@ -661,7 +663,7 @@ static int xperms_to_cil(const av_extended_perms_t *xperms)
>                         } else {
>                                 cil_printf("0x%hx", value);
>                         }
> -               } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) {
> +               } else if (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
>                         value = bit << 8;
>                         if (in_range) {
>                                 low_value = low_bit << 8;
> @@ -680,6 +682,7 @@ static int avrulex_to_cil(int indent, struct policydb *pdb, uint32_t type, const
>  {
>         int rc = -1;
>         const char *rule;
> +       const char *xperm;
>         const struct class_perm_node *classperm;
>
>         switch (type) {
> @@ -701,10 +704,19 @@ static int avrulex_to_cil(int indent, struct policydb *pdb, uint32_t type, const
>                 goto exit;
>         }
>
> +       if (xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION || xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
> +               xperm = "ioctl";
> +       } else if (xperms->specified == AVTAB_XPERMS_NLMSG) {
> +               xperm = "nlmsg";
> +       } else {
> +               ERR(NULL, "Unkown avrule xperms->specified: %i", xperms->specified);
> +               rc = -1;
> +               goto exit;
> +       }
>         for (classperm = classperms; classperm != NULL; classperm = classperm->next) {
>                 cil_indent(indent);
>                 cil_printf("(%s %s %s (%s %s (", rule, src, tgt,
> -                          "ioctl", pdb->p_class_val_to_name[classperm->tclass - 1]);
> +                          xperm, pdb->p_class_val_to_name[classperm->tclass - 1]);
>                 xperms_to_cil(xperms);
>                 cil_printf(")))\n");
>         }
> diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c
> index 121fd46c..5035313b 100644
> --- a/libsepol/src/policydb_validate.c
> +++ b/libsepol/src/policydb_validate.c
> @@ -921,6 +921,7 @@ static int validate_xperms(const avtab_extended_perms_t *xperms)
>         switch (xperms->specified) {
>         case AVTAB_XPERMS_IOCTLDRIVER:
>         case AVTAB_XPERMS_IOCTLFUNCTION:
> +       case AVTAB_XPERMS_NLMSG:
>                 break;
>         default:
>                 goto bad;
> @@ -1067,6 +1068,7 @@ static int validate_avrules(sepol_handle_t *handle, const avrule_t *avrule, int
>                         switch (avrule->xperms->specified) {
>                         case AVRULE_XPERMS_IOCTLFUNCTION:
>                         case AVRULE_XPERMS_IOCTLDRIVER:
> +                       case AVRULE_XPERMS_NLMSG:
>                                 break;
>                         default:
>                                 goto bad;
> diff --git a/libsepol/src/util.c b/libsepol/src/util.c
> index b1eb9b38..a4befbd9 100644
> --- a/libsepol/src/util.c
> +++ b/libsepol/src/util.c
> @@ -146,7 +146,8 @@ char *sepol_extended_perms_to_string(const avtab_extended_perms_t *xperms)
>         size_t remaining, size = 128;
>
>         if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION)
> -               && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER))
> +               && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)
> +               && (xperms->specified != AVTAB_XPERMS_NLMSG))
>                 return NULL;
>
>  retry:
> @@ -158,7 +159,12 @@ retry:
>         buffer = p;
>         remaining = size;
>
> -       len = snprintf(p, remaining, "ioctl { ");
> +       if ((xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION)
> +               || (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER)) {
> +               len = snprintf(p, remaining, "ioctl { ");
> +       } else {
> +               len = snprintf(p, remaining, "nlmsg { ");
> +       }
>         if (len < 0 || (size_t)len >= remaining)
>                 goto err;
>         p += len;
> @@ -179,7 +185,7 @@ retry:
>                         continue;
>                 }
>
> -               if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) {
> +               if (xperms->specified == AVTAB_XPERMS_IOCTLFUNCTION || xperms->specified == AVTAB_XPERMS_NLMSG) {
>                         value = xperms->driver<<8 | bit;
>                         if (in_range) {
>                                 low_value = xperms->driver<<8 | low_bit;
> @@ -187,7 +193,7 @@ retry:
>                         } else {
>                                 len = snprintf(p, remaining, "0x%hx ", value);
>                         }
> -               } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) {
> +               } else if (xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) {
>                         value = bit << 8;
>                         if (in_range) {
>                                 low_value = low_bit << 8;
> --
> 2.46.0.184.g6999bdac58-goog
>





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

  Powered by Linux