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

Stephen Smalley <[email protected]> Tue, 21 Jul 2026 12:58:05 -0400
Newsgroups org.kernel.vger.selinux
Message-ID <CAEjxPJ7pfTxcZ=DRO4WaW9J3Twrttc0LiK1RsEj_HMtUPDv00g@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.

Not sure if this change in behavior is desired - it seemingly
precludes .local from intentionally overriding an entry's context.
Defer to distro maintainers.

>
> 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
> @@ -104,9 +104,59 @@ void sort_spec_node(struct spec_node *node, struct spec_node *parent)
>  }
>
>  /*
> - * Warn about duplicate specifications.
> + * Report a duplicate in the log.
> + *
> + * If the duplicate is considered fatal (i.e., if the specifications of both
> + * entries do not match), return -1 and set errno to EINVAL.
> + */
> +static int report_dups(struct selabel_handle *rec, uint8_t inputno1,
> +                      uint8_t inputno2, const char *ctx_raw1,
> +                      const char *ctx_raw2, const char *match,
> +                      const char *file_kind)
> +{
> +       if (inputno1 >= rec->spec_files_len)
> +               inputno1 = 0;
> +       if (inputno2 >= rec->spec_files_len)
> +               inputno2 = 0;

Since you are intentionally passing in num_paths + 1 and num_paths + 2
for the homedirs and local files, this will incorrectly attribute any
duplicates to the wrong file. Not sure we want cross-file duplicate
checking anyway.