Re: [PATCH] libsepol: Eliminate gaps in the policydb role arrays

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

 



On Fri, Feb 5, 2021 at 9:51 PM James Carter <jwcart2@xxxxxxxxx> wrote:
>
> Since the kernel binary policy does not include role attributes,
> they are expanded when creating the policy and there are gaps
> in the role values written to the policy. When this policy is
> read from a file and the policydb is created there will be gaps
> in the p_role_val_to_name and role_val_to_struct arrays.
>
> When expanding a policy into a new policydb, copy the roles first
> and then copy the role attributes. When writing a kernel binary
> policy, update the nprim of the role symtab by subtracting the number
> of role attributes. Now when that policy is read and its policydb is
> created there will be no gaps in the role arrays.
>
> Signed-off-by: James Carter <jwcart2@xxxxxxxxx>
> ---
>  libsepol/src/expand.c | 40 ++++++++++++++++++++++++++++++++--------
>  libsepol/src/write.c  |  6 ++++--
>  2 files changed, 36 insertions(+), 10 deletions(-)
>
> diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
> index eac7e450..ea1b115a 100644
> --- a/libsepol/src/expand.c
> +++ b/libsepol/src/expand.c
> @@ -789,19 +789,15 @@ static int role_fix_callback(hashtab_key_t key, hashtab_datum_t datum,
>         return 0;
>  }
>
> -static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
> -                             void *data)
> +static int role_copy_callback_helper(char *id, role_datum_t *role, expand_state_t *state, unsigned int copy_attr)
>  {
>         int ret;
> -       char *id, *new_id;
> -       role_datum_t *role;
> +       char *new_id;
>         role_datum_t *new_role;
> -       expand_state_t *state;
>         ebitmap_t tmp_union_types;
>
> -       id = key;
> -       role = (role_datum_t *) datum;
> -       state = (expand_state_t *) data;
> +       if ((!copy_attr && role->flavor == ROLE_ATTRIB) || (copy_attr && role->flavor != ROLE_ATTRIB))
> +               return 0;
>
>         if (strcmp(id, OBJECT_R) == 0) {
>                 /* object_r is always value 1 */
> @@ -878,6 +874,26 @@ static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
>         return 0;
>  }
>
> +static int role_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
> +                             void *data)
> +{
> +       char *id = key;
> +       role_datum_t *role = (role_datum_t *) datum;
> +       expand_state_t *state = (expand_state_t *) data;
> +
> +       return role_copy_callback_helper(id, role, state, 0);
> +}
> +
> +static int role_attr_copy_callback(hashtab_key_t key, hashtab_datum_t datum,
> +                             void *data)
> +{
> +       char *id = key;
> +       role_datum_t *role = (role_datum_t *) datum;
> +       expand_state_t *state = (expand_state_t *) data;
> +
> +       return role_copy_callback_helper(id, role, state, 1);
> +}
> +
>  int mls_semantic_level_expand(mls_semantic_level_t * sl, mls_level_t * l,
>                               policydb_t * p, sepol_handle_t * h)
>  {
> @@ -3014,6 +3030,9 @@ int expand_module(sepol_handle_t * handle,
>         /* copy roles */
>         if (hashtab_map(state.base->p_roles.table, role_copy_callback, &state))
>                 goto cleanup;
> +       /* copy role attrs */
> +       if (hashtab_map(state.base->p_roles.table, role_attr_copy_callback, &state))
> +               goto cleanup;
>         if (hashtab_map(state.base->p_roles.table,
>                         role_bounds_copy_callback, &state))
>                 goto cleanup;
> @@ -3074,6 +3093,11 @@ int expand_module(sepol_handle_t * handle,
>                     (decl->p_roles.table, role_copy_callback, &state))
>                         goto cleanup;
>
> +               /* copy role attrs */
> +               if (hashtab_map
> +                   (decl->p_roles.table, role_attr_copy_callback, &state))
> +                       goto cleanup;
> +
>                 /* copy users */
>                 if (hashtab_map
>                     (decl->p_users.table, user_copy_callback, &state))
> diff --git a/libsepol/src/write.c b/libsepol/src/write.c
> index 84bcaf3f..95a2c376 100644
> --- a/libsepol/src/write.c
> +++ b/libsepol/src/write.c
> @@ -2321,8 +2321,10 @@ int policydb_write(policydb_t * p, struct policy_file *fp)
>                 if ((i == SYM_ROLES) &&
>                     ((p->policy_type == POLICY_KERN) ||
>                      (p->policy_type != POLICY_KERN &&
> -                     p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB)))
> -                       (void)hashtab_map(p->symtab[i].table, role_attr_uncount, &buf[1]);
> +                         p->policyvers < MOD_POLICYDB_VERSION_ROLEATTRIB))) {
> +                       hashtab_map(p->symtab[i].table, role_attr_uncount, &buf[1]);
> +                       buf[0] -= p->symtab[i].table->nel - buf[1];

Hello,
Sorry for the delay, I was busy in the last few days.
While reviewing this patch, I stumbled upon this line which changes
buf[0]. At the beginning of the for where these lines are modified
there is:

    buf[0] = cpu_to_le32(p->symtab[i].nprim);

Does doing "buf[0] -= ..." works on Big Endian systems? It would be
more intuitive if the code was:

    buf[0] = p->symtab[i].nprim
    /* ... */
    if (...) {
        buf[0] -= p->symtab[i].table->nel - buf[1];
    }
    buf[0] = cpu_to_le32(buf[0]);
    buf[1] = cpu_to_le32(buf[1]);
    items = put_entry(buf, sizeof(uint32_t), 2, fp);

Thanks!
Nicolas




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

  Powered by Linux