Re: [PATCH v3 1/2] libselinux: support multiple spec_files
Stephen Smalley <[email protected]> Mon, 27 Jul 2026 09:30:00 -0400
| Newsgroups | org.kernel.vger.selinux |
|---|---|
| Message-ID | <CAEjxPJ5vH0qm8_RduSnOX2EU_2fz-zAoCPNLsETdXf5X+NUOfA@mail.gmail.com> |
On Sun, Jul 26, 2026 at 9:39 PM Thiébaud Weksteen <[email protected]> wrote: > > Update the existing backends to potentially allocate multiple > spec_files. This commit simply adds a level of indirection but does not > change any current behaviour. It will facilitate the gradual migration > of backends to multiple context files. > > In selabel_fini(), compat_validate() is updated to use the first > spec_file only, for legacy validation error reporting. selabel_open() is > already performing context validation if requested against individual > file paths (see insert_spec). > > Signed-off-by: Thiébaud Weksteen <[email protected]> You can keep Acked-by/Reviewed-by/Tested-by when the patch is unchanged. Acked-by: Stephen Smalley <[email protected]> > --- > No changes since v2 > > libselinux/src/label.c | 10 ++++++++-- > libselinux/src/label_db.c | 11 +++++++++-- > libselinux/src/label_file.c | 8 ++++++-- > libselinux/src/label_internal.h | 5 +++-- > libselinux/src/label_media.c | 8 +++++++- > libselinux/src/label_x.c | 8 +++++++- > 6 files changed, 40 insertions(+), 10 deletions(-) > > diff --git a/libselinux/src/label.c b/libselinux/src/label.c > index 991b9769..4a97d3bc 100644 > --- a/libselinux/src/label.c > +++ b/libselinux/src/label.c > @@ -162,7 +162,7 @@ static int selabel_fini(const struct selabel_handle *rec, > char *ctx_trans; > int rc; > > - if (compat_validate(rec, lr, rec->spec_file, lr->lineno)) > + if (compat_validate(rec, lr, rec->spec_files[0], lr->lineno)) > return -1; > > if (!translating) > @@ -398,11 +398,17 @@ int selabel_digest(struct selabel_handle *rec, unsigned char **digest, > > void selabel_close(struct selabel_handle *rec) > { > + size_t i; > + > if (rec->digest) > selabel_digest_fini(rec->digest); > if (rec->func_close) > rec->func_close(rec); > - free(rec->spec_file); > + if (rec->spec_files) { > + for (i = 0; i < rec->spec_files_len; i++) > + free(rec->spec_files[i]); > + free(rec->spec_files); > + } > free(rec); > } > > diff --git a/libselinux/src/label_db.c b/libselinux/src/label_db.c > index bafa9328..53731470 100644 > --- a/libselinux/src/label_db.c > +++ b/libselinux/src/label_db.c > @@ -302,12 +302,19 @@ static catalog_t *db_init(const struct selinux_opt *opts, unsigned nopts, > errno = EINVAL; > return NULL; > } > - rec->spec_file = strdup(path); > - if (!rec->spec_file) { > + rec->spec_files = calloc(1, sizeof(*rec->spec_files)); > + if (!rec->spec_files) { > free(catalog); > fclose(filp); > return NULL; > } > + rec->spec_files[0] = strdup(path); > + if (!rec->spec_files[0]) { > + free(catalog); > + fclose(filp); > + return NULL; > + } > + rec->spec_files_len = 1; > > /* > * Parse for each lines > diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c > index 0c0499eb..d91e1462 100644 > --- a/libselinux/src/label_file.c > +++ b/libselinux/src/label_file.c > @@ -1549,9 +1549,13 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, > goto finish; > } > > - rec->spec_file = strdup(path); > - if (!rec->spec_file) > + rec->spec_files = calloc(1, sizeof(*rec->spec_files)); > + if (!rec->spec_files) > goto finish; > + rec->spec_files[0] = strdup(path); > + if (!rec->spec_files[0]) > + goto finish; > + rec->spec_files_len = 1; > > /* > * The do detailed validation of the input and fill the spec array > diff --git a/libselinux/src/label_internal.h b/libselinux/src/label_internal.h > index 4ff39d96..d54053df 100644 > --- a/libselinux/src/label_internal.h > +++ b/libselinux/src/label_internal.h > @@ -96,10 +96,11 @@ struct selabel_handle { > void *data; > > /* > - * The main spec file used. Note for file contexts the local and/or > + * The spec files used. Note for file contexts the local and/or > * homedirs could also have been used to resolve a context. > */ > - char *spec_file; > + size_t spec_files_len; > + char **spec_files; > > /* ptr to SHA1 hash information if SELABEL_OPT_DIGEST set */ > struct selabel_digest *digest; > diff --git a/libselinux/src/label_media.c b/libselinux/src/label_media.c > index 957fcfd3..f315abc3 100644 > --- a/libselinux/src/label_media.c > +++ b/libselinux/src/label_media.c > @@ -109,7 +109,13 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, > errno = EINVAL; > goto finish; > } > - rec->spec_file = strdup(path); > + rec->spec_files = calloc(1, sizeof(*rec->spec_files)); > + if (!rec->spec_files) > + goto finish; > + rec->spec_files[0] = strdup(path); > + if (!rec->spec_files[0]) > + goto finish; > + rec->spec_files_len = 1; > > /* > * Perform two passes over the specification file. > diff --git a/libselinux/src/label_x.c b/libselinux/src/label_x.c > index 0c525bfc..b528a019 100644 > --- a/libselinux/src/label_x.c > +++ b/libselinux/src/label_x.c > @@ -139,7 +139,13 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts, > errno = EINVAL; > goto finish; > } > - rec->spec_file = strdup(path); > + rec->spec_files = calloc(1, sizeof(*rec->spec_files)); > + if (!rec->spec_files) > + goto finish; > + rec->spec_files[0] = strdup(path); > + if (!rec->spec_files[0]) > + goto finish; > + rec->spec_files_len = 1; > > /* > * Perform two passes over the specification file. > -- > 2.55.0.229.g6434b31f56-goog >