Re: [PATCH 2/2] libselinux: support multiple contexts for the file backend

Stephen Smalley <[email protected]> Tue, 21 Jul 2026 12:31:38 -0400
Newsgroups org.kernel.vger.selinux
Message-ID <CAEjxPJ67CPCWK+qmvOgwfxfaT0KVoNSRnaUzWLoHxrm9P4X54Q@mail.gmail.com>
On Mon, Jul 20, 2026 at 10:11 PM Thiébaud Weksteen <[email protected]> wrote:
>
> Update the file labeling backend to support specifying multiple
> SELABEL_OPT_PATH options in selabel_open().
>
> All provided paths are stored in rec->spec_files and processed during
> initialization. Derived files, such as substitutions (.subs, .subs_dist)
> and auxiliary contexts (.homedirs, .local), continue to be based on the
> first path (or default selinux_file_context_path()) when enabled.
>
> Duplicate checking logic is refactored into a helper function
> report_dups(). A duplicate with the same specification result is not
> fatal anymore, but a warning is still logged.
>
> Additionally, duplicate validation is moved after all files (including
> .homedirs and .local) are loaded and sorted. For single file context setups,
> the only difference in behavior is that duplicate validation now extends to
> fc.homedirs and fc.local.
>
> A similar multiple files setup has been used in Android for 9+ years.
>
> Signed-off-by: Thiébaud Weksteen <[email protected]>
> ---
>  libselinux/src/label_file.c | 216 ++++++++++++++++++++++--------------
>  1 file changed, 132 insertions(+), 84 deletions(-)
>
> diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c
> index eb2e66da..902c9a25 100644
> --- a/libselinux/src/label_file.c
> +++ b/libselinux/src/label_file.c
> @@ -168,28 +204,11 @@ static int nodups_spec_node(const struct spec_node *node, const char *path)
>                                     node1->file_kind != node2->file_kind)
>                                         continue;
>
> -                               rc = -1;
> -                               errno = EINVAL;
> -                               if (strcmp(node1->lr.ctx_raw,
> -                                          node2->lr.ctx_raw) != 0) {
> -                                       COMPAT_LOG(
> -                                               SELINUX_ERROR,
> -                                               "%s: Multiple different specifications for %s %s  (%s and %s).\n",
> -                                               path,
> -                                               file_kind_to_string(
> -                                                       node1->file_kind),
> -                                               node1->regex_str,
> -                                               node1->lr.ctx_raw,
> -                                               node2->lr.ctx_raw);
> -                               } else {
> -                                       COMPAT_LOG(
> -                                               SELINUX_ERROR,
> -                                               "%s: Multiple same specifications for %s %s.\n",
> -                                               path,
> -                                               file_kind_to_string(
> -                                                       node1->file_kind),
> -                                               node1->regex_str);
> -                               }
> +                               rc = report_dups(
> +                                       rec, node1->inputno, node2->inputno,
> +                                       node1->lr.ctx_raw, node2->lr.ctx_raw,
> +                                       node1->regex_str,
> +                                       file_kind_to_string(node1->file_kind));

This will clobber prior errors; need to preserve those.

>                         }
>                 }
>         }
>