[PATCH 1/2] libselinux: support multiple spec_files

"Thiébaud Weksteen" <[email protected]>
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]>
---
 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..59a291e8 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(path));
+	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..eb2e66da 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(path));
+	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..35f3cc16 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(path));
+	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..33a64a6a 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(path));
+	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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.