Re: [PATCH] libsepol: Check for invalid categories when expanding semantic levels

Stephen Smalley <[email protected]> Wed, 29 Jul 2026 12:28:29 -0400
Newsgroups org.kernel.vger.selinux
Message-ID <CAEjxPJ4H1z2EZWN2hp3E0ff7HMQZRvpgRfE8yNgFkdpeM4A2Bw@mail.gmail.com>
On Wed, Jul 29, 2026 at 11:43 AM James Carter <[email protected]> wrote:
>
> The function mls_semantic_level_expand() is used before the policy
> has been validated. A maliciously crafted policy might have gaps in
> the categories, so a check must be done to verify that the categories
> referred to actually exist.
>
> Signed-off-by: James Carter <[email protected]>

Acked-by: Stephen Smalley <[email protected]>

> ---
>  libsepol/src/expand.c | 27 ++++++++++++++++++---------
>  1 file changed, 18 insertions(+), 9 deletions(-)
>
> diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
> index 8d7fe519..35f26c23 100644
> --- a/libsepol/src/expand.c
> +++ b/libsepol/src/expand.c
> @@ -1128,18 +1128,27 @@ int mls_semantic_level_expand(mls_semantic_level_t *sl, mls_level_t *l,
>                 return -1;
>         }
>         for (cat = sl->cat; cat; cat = cat->next) {
> -               if (!cat->low || cat->low > cat->high ||
> -                   cat->high > p->p_cats.nprim) {
> -                       ERR(h, "Category range is not valid %s.%s",
> -                           (cat->low && cat->low <= p->p_cats.nprim) ?
> -                                   p->p_cat_val_to_name[cat->low - 1] :
> -                                   "Invalid",
> -                           (cat->high && cat->high <= p->p_cats.nprim) ?
> -                                   p->p_cat_val_to_name[cat->high - 1] :
> -                                   "Invalid");
> +               if (!cat->low || cat->low > p->p_cats.nprim ||
> +                   !p->p_cat_val_to_name[cat->low - 1]) {
> +                       ERR(h, "Low category is invalid");
> +                       return -1;
> +               }
> +               if (!cat->high || cat->high > p->p_cats.nprim ||
> +                   !p->p_cat_val_to_name[cat->high - 1]) {
> +                       ERR(h, "High category is invalid");
> +                       return -1;
> +               }
> +               if (cat->low > cat->high) {
> +                       ERR(h, "Category range \"%s.%s\" is not valid",
> +                           p->p_cat_val_to_name[cat->low - 1],
> +                           p->p_cat_val_to_name[cat->high - 1]);
>                         return -1;
>                 }
>                 for (i = cat->low - 1; i < cat->high; i++) {
> +                       if (!p->p_cat_val_to_name[i]) {
> +                               ERR(h, "Invalid category in range");
> +                               return -1;
> +                       }
>                         if (!ebitmap_get_bit(&levdatum->level->cat, i)) {
>                                 ERR(h,
>                                     "Category %s can not be associated with "
> --
> 2.55.0
>