[PATCH v3 1/2] libselinux: support multiple spec_files
"ThiƩbaud Weksteen" <[email protected]> Mon, 27 Jul 2026 11:39:28 +1000
| Newsgroups | org.kernel.vger.selinux |
|---|---|
| Message-ID | <[email protected]> |
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]> --- 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