All of lore.kernel.org
 help / color / mirror / Atom feed
From: James Carter <jwcart2@gmail.com>
To: selinux@vger.kernel.org
Cc: cgzones@googlemail.com, takayas@chromium.org,
	James Carter <jwcart2@gmail.com>
Subject: [PATCH 4/9] Revert "libselinux: use vector instead of linked list for substitutions"
Date: Wed, 11 Dec 2024 11:14:01 -0500	[thread overview]
Message-ID: <20241211161417.126236-4-jwcart2@gmail.com> (raw)
In-Reply-To: <20241211161417.126236-1-jwcart2@gmail.com>

This reverts commit 4d436e4bf80284ac3b645bad022a9757dbc2dd36.

Needed to revert commit 92306daf5219e73f6e8bc9fc7699399457999bcd
"libselinux: rework selabel_file(5) database", which broke Android
file_context matching.

Signed-off-by: James Carter <jwcart2@gmail.com>
---
 libselinux/src/label_file.c | 129 +++++++++++++++++-------------------
 libselinux/src/label_file.h |  20 ++----
 2 files changed, 66 insertions(+), 83 deletions(-)

diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c
index b7ff8c09..be1ee11a 100644
--- a/libselinux/src/label_file.c
+++ b/libselinux/src/label_file.c
@@ -1188,27 +1188,28 @@ static int process_file(const char *path, const char *suffix,
 	return -1;
 }
 
-static void selabel_subs_fini(struct selabel_sub *subs, uint32_t num)
+static void selabel_subs_fini(struct selabel_sub *ptr)
 {
-	for (uint32_t i = 0; i < num; i++) {
-		free(subs[i].src);
-		free(subs[i].dst);
+	struct selabel_sub *next;
+
+	while (ptr) {
+		next = ptr->next;
+		free(ptr->src);
+		free(ptr->dst);
+		free(ptr);
+		ptr = next;
 	}
-
-	free(subs);
 }
 
-static char *selabel_apply_subs(const struct selabel_sub *subs, uint32_t num, const char *src)
+static char *selabel_sub(const struct selabel_sub *ptr, const char *src)
 {
-	char *dst;
-	uint32_t len;
-
-	for (uint32_t i = 0; i < num; i++) {
-		const struct selabel_sub *ptr = &subs[i];
+	char *dst = NULL;
+	unsigned int len;
 
+	while (ptr) {
 		if (strncmp(src, ptr->src, ptr->slen) == 0 ) {
 			if (src[ptr->slen] == '/' ||
-			    src[ptr->slen] == '\0') {
+			    src[ptr->slen] == 0) {
 				if ((src[ptr->slen] == '/') &&
 				    (strcmp(ptr->dst, "/") == 0))
 					len = ptr->slen + 1;
@@ -1219,38 +1220,34 @@ static char *selabel_apply_subs(const struct selabel_sub *subs, uint32_t num, co
 				return dst;
 			}
 		}
+		ptr = ptr->next;
 	}
-
 	return NULL;
 }
 
 #if !defined(BUILD_HOST) && !defined(ANDROID)
 static int selabel_subs_init(const char *path, struct selabel_digest *digest,
-			     struct selabel_sub **out_subs,
-			     uint32_t *out_num, uint32_t *out_alloc)
+			     struct selabel_sub **out_subs)
 {
 	char buf[1024];
-	FILE *cfg;
+	FILE *cfg = fopen(path, "re");
+	struct selabel_sub *list = NULL, *sub = NULL;
 	struct stat sb;
-	struct selabel_sub *tmp = NULL;
-	uint32_t tmp_num = 0, tmp_alloc = 0;
-	char *src_cpy = NULL, *dst_cpy = NULL;
-	int rc;
+	int status = -1;
 
 	*out_subs = NULL;
-	*out_num = 0;
-	*out_alloc = 0;
-
-	cfg = fopen(path, "re");
 	if (!cfg) {
 		/* If the file does not exist, it is not fatal */
 		return (errno == ENOENT) ? 0 : -1;
 	}
 
+	if (fstat(fileno(cfg), &sb) < 0)
+		goto out;
+
 	while (fgets_unlocked(buf, sizeof(buf) - 1, cfg)) {
-		char *ptr;
+		char *ptr = NULL;
 		char *src = buf;
-		char *dst;
+		char *dst = NULL;
 		size_t len;
 
 		while (*src && isspace((unsigned char)*src))
@@ -1278,68 +1275,62 @@ static int selabel_subs_init(const char *path, struct selabel_digest *digest,
 			goto err;
 		}
 
-		src_cpy = strdup(src);
-		if (!src_cpy)
+		sub = calloc(1, sizeof(*sub));
+		if (! sub)
 			goto err;
 
-		dst_cpy = strdup(dst);
-		if (!dst_cpy)
+		sub->src = strdup(src);
+		if (! sub->src)
 			goto err;
 
-		rc = GROW_ARRAY(tmp);
-		if (rc)
+		sub->dst = strdup(dst);
+		if (! sub->dst)
 			goto err;
 
-		tmp[tmp_num++] = (struct selabel_sub) {
-			.src = src_cpy,
-			.slen = len,
-			.dst = dst_cpy,
-		};
-		src_cpy = NULL;
-		dst_cpy = NULL;
+		sub->slen = len;
+		sub->next = list;
+		list = sub;
+		sub = NULL;
 	}
 
-	rc = fstat(fileno(cfg), &sb);
-	if (rc < 0)
-		goto err;
-
 	if (digest_add_specfile(digest, cfg, NULL, sb.st_size, path) < 0)
 		goto err;
 
-	*out_subs = tmp;
-	*out_num = tmp_num;
-	*out_alloc = tmp_alloc;
+	*out_subs = list;
+	status = 0;
 
+out:
 	fclose(cfg);
-
-	return 0;
-
+	return status;
 err:
-	free(dst_cpy);
-	free(src_cpy);
-	for (uint32_t i = 0; i < tmp_num; i++) {
-		free(tmp[i].src);
-		free(tmp[i].dst);
+	if (sub)
+		free(sub->src);
+	free(sub);
+	while (list) {
+		sub = list->next;
+		free(list->src);
+		free(list->dst);
+		free(list);
+		list = sub;
 	}
-	free(tmp);
-	fclose_errno_safe(cfg);
-	return -1;
+	goto out;
 }
 #endif
 
 static char *selabel_sub_key(const struct saved_data *data, const char *key)
 {
-	char *ptr, *dptr;
+	char *ptr = NULL;
+	char *dptr = NULL;
 
-	ptr = selabel_apply_subs(data->subs, data->subs_num, key);
+	ptr = selabel_sub(data->subs, key);
 	if (ptr) {
-		dptr = selabel_apply_subs(data->dist_subs, data->dist_subs_num, ptr);
+		dptr = selabel_sub(data->dist_subs, ptr);
 		if (dptr) {
 			free(ptr);
 			ptr = dptr;
 		}
 	} else {
-		ptr = selabel_apply_subs(data->dist_subs, data->dist_subs_num, key);
+		ptr = selabel_sub(data->dist_subs, key);
 	}
 
 	return ptr;
@@ -1384,25 +1375,23 @@ static int init(struct selabel_handle *rec, const struct selinux_opt *opts,
 	if (!path) {
 		status = selabel_subs_init(
 			selinux_file_context_subs_dist_path(),
-			rec->digest,
-			&data->dist_subs, &data->dist_subs_num, &data->dist_subs_alloc);
+			rec->digest, &data->dist_subs);
 		if (status)
 			goto finish;
 		status = selabel_subs_init(selinux_file_context_subs_path(),
-			rec->digest,
-			&data->subs, &data->subs_num, &data->subs_alloc);
+			rec->digest, &data->subs);
 		if (status)
 			goto finish;
 		path = selinux_file_context_path();
 	} else {
 		snprintf(subs_file, sizeof(subs_file), "%s.subs_dist", path);
 		status = selabel_subs_init(subs_file, rec->digest,
-					   &data->dist_subs, &data->dist_subs_num, &data->dist_subs_alloc);
+					   &data->dist_subs);
 		if (status)
 			goto finish;
 		snprintf(subs_file, sizeof(subs_file), "%s.subs", path);
 		status = selabel_subs_init(subs_file, rec->digest,
-					   &data->subs, &data->subs_num, &data->subs_alloc);
+					   &data->subs);
 		if (status)
 			goto finish;
 	}
@@ -1470,8 +1459,8 @@ static void closef(struct selabel_handle *rec)
 	if (!data)
 		return;
 
-	selabel_subs_fini(data->subs, data->subs_num);
-	selabel_subs_fini(data->dist_subs, data->dist_subs_num);
+	selabel_subs_fini(data->subs);
+	selabel_subs_fini(data->dist_subs);
 
 	free_spec_node(data->root);
 	free(data->root);
diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h
index d5dd2be1..b59db003 100644
--- a/libselinux/src/label_file.h
+++ b/libselinux/src/label_file.h
@@ -67,11 +67,11 @@ extern struct lookup_result *lookup_all(struct selabel_handle *rec, const char *
 extern enum selabel_cmp_result cmp(const struct selabel_handle *h1, const struct selabel_handle *h2);
 #endif  /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */
 
-/* A path substitution entry */
 struct selabel_sub {
-	char *src;				/* source path prefix */
-	char *dst;				/* substituted path prefix */
-	uint32_t slen;				/* length of source path prefix */
+	char *src;
+	unsigned int slen;
+	char *dst;
+	struct selabel_sub *next;
 };
 
 /* A regular expression file security context specification */
@@ -159,17 +159,9 @@ struct saved_data {
 
 	struct mmap_area *mmap_areas;
 
-	/*
-	 * Array of distribution substitutions
-	 */
+	/* substitution support */
 	struct selabel_sub *dist_subs;
-	uint32_t dist_subs_num, dist_subs_alloc;
-
-	/*
-	 * Array of local substitutions
-	 */
 	struct selabel_sub *subs;
-	uint32_t subs_num, subs_alloc;
 };
 
 void free_spec_node(struct spec_node *node);
@@ -795,6 +787,8 @@ static int insert_spec(const struct selabel_handle *rec, struct saved_data *data
 	return 0;
 }
 
+#undef GROW_ARRAY
+
 /* This will always check for buffer over-runs and either read the next entry
  * if buf != NULL or skip over the entry (as these areas are mapped in the
  * current buffer). */
-- 
2.47.1


  parent reply	other threads:[~2024-12-11 16:14 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-12-11 16:13 [PATCH 1/9] Revert "libselinux/utils: drop reachable assert in sefcontext_compile" James Carter
2024-12-11 16:13 ` [PATCH 2/9] Revert "libselinux/utils: use correct error handling" James Carter
2024-12-11 16:14 ` [PATCH 3/9] Revert "libselinux: simplify string formatting" James Carter
2024-12-11 16:14 ` James Carter [this message]
2024-12-11 16:14 ` [PATCH 5/9] Revert "libselinux: avoid memory allocation in common file label lookup" James Carter
2024-12-11 16:14 ` [PATCH 6/9] Revert "libselinux: move functions out of header file" James Carter
2024-12-11 16:14 ` [PATCH 7/9] Revert "libselinux: support parallel selabel_lookup(3)" James Carter
2024-12-11 16:14 ` [PATCH 8/9] Revert "libselinux: add selabel_file(5) fuzzer" James Carter
2024-12-11 16:14 ` [PATCH 9/9] Revert "libselinux: rework selabel_file(5) database" James Carter
2024-12-11 16:25 ` [PATCH 1/9] Revert "libselinux/utils: drop reachable assert in sefcontext_compile" James Carter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241211161417.126236-4-jwcart2@gmail.com \
    --to=jwcart2@gmail.com \
    --cc=cgzones@googlemail.com \
    --cc=selinux@vger.kernel.org \
    --cc=takayas@chromium.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.