All of lore.kernel.org
 help / color / mirror / Atom feed
From: Rahul Sandhu <nvraxn@gmail.com>
To: selinux@vger.kernel.org, nvraxn@gmail.com
Cc: bill.c.roberts@gmail.com
Subject: [PATCH v2] libsemanage: create semanage_basename to ensure posix compliance
Date: Fri, 21 Feb 2025 09:39:10 +0000	[thread overview]
Message-ID: <20250221093910.657484-1-nvraxn@gmail.com> (raw)
In-Reply-To: <D7Y03RIRQTEH.1SUBF6LGYYEM6@gmail.com>

Passing a const char * to basename(3) is a glibc-specific extension, so
create our own basename implementation. As it's a trivial 2 LOC, always
use our implementation of basename even if glibc is available to avoid
the complications of attaining the non-posix glibc implementation of
basename(3) as _GNU_SOURCE needs to be defined, but libgen.h also needs
to have not been included.

Also fix a missing check for selinux_policy_root(3). From the man page:
On failure, selinux_policy_root returns NULL.

As the glibc basename(3) (unlike posix basename(3)) does not support
having a nullptr passed to it, only pass the policy_root to basename(3)
if it is non-null.

Signed-off-by: Rahul Sandhu <nvraxn@gmail.com>
---
 libsemanage/src/conf-parse.y       | 13 ++++++++++---
 libsemanage/src/direct_api.c       |  1 +
 libsemanage/src/utilities.c        |  9 +++++++++
 libsemanage/src/utilities.h        | 13 +++++++++++++
 libsemanage/tests/test_utilities.c | 26 ++++++++++++++++++++++++++
 5 files changed, 59 insertions(+), 3 deletions(-)

diff --git a/libsemanage/src/conf-parse.y b/libsemanage/src/conf-parse.y
index 6cb8a598..d3ca5f1f 100644
--- a/libsemanage/src/conf-parse.y
+++ b/libsemanage/src/conf-parse.y
@@ -21,6 +21,7 @@
 %{
 
 #include "semanage_conf.h"
+#include "utilities.h"
 
 #include <sepol/policydb.h>
 #include <selinux/selinux.h>
@@ -382,7 +383,10 @@ external_opt:   PROG_PATH '=' ARG  { PASSIGN(new_external->path, $3); }
 static int semanage_conf_init(semanage_conf_t * conf)
 {
 	conf->store_type = SEMANAGE_CON_DIRECT;
-	conf->store_path = strdup(basename(selinux_policy_root()));
+	const char *policy_root = selinux_policy_root();
+	if (policy_root != NULL) {
+		conf->store_path = strdup(semanage_basename(policy_root));
+	}
 	conf->ignoredirs = NULL;
 	conf->store_root_path = strdup("/var/lib/selinux");
 	conf->compiler_directory_path = strdup("/usr/libexec/selinux/hll");
@@ -544,8 +548,11 @@ static int parse_module_store(char *arg)
 	free(current_conf->store_path);
 	if (strcmp(arg, "direct") == 0) {
 		current_conf->store_type = SEMANAGE_CON_DIRECT;
-		current_conf->store_path =
-		    strdup(basename(selinux_policy_root()));
+		const char *policy_root = selinux_policy_root();
+		if (policy_root != NULL) {
+			current_conf->store_path =
+			    strdup(semanage_basename(policy_root));
+		}
 		current_conf->server_port = -1;
 	} else if (*arg == '/') {
 		current_conf->store_type = SEMANAGE_CON_POLSERV_LOCAL;
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index 99cba7f7..ce12ccaf 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -26,6 +26,7 @@
 
 #include <assert.h>
 #include <fcntl.h>
+#include <libgen.h>
 #include <stdio.h>
 #include <stdio_ext.h>
 #include <stdlib.h>
diff --git a/libsemanage/src/utilities.c b/libsemanage/src/utilities.c
index 70b5b677..004ffb62 100644
--- a/libsemanage/src/utilities.c
+++ b/libsemanage/src/utilities.c
@@ -349,3 +349,12 @@ int write_full(int fd, const void *buf, size_t len)
 
 	return 0;
 }
+
+#ifdef __GNUC__
+__attribute__((nonnull))
+#endif
+char *semanage_basename(const char *filename)
+{
+	char *p = strrchr(filename, '/');
+	return p ? p + 1 : (char *)filename;
+}
diff --git a/libsemanage/src/utilities.h b/libsemanage/src/utilities.h
index c2d484a7..7481077a 100644
--- a/libsemanage/src/utilities.h
+++ b/libsemanage/src/utilities.h
@@ -156,4 +156,17 @@ semanage_list_t *semanage_slurp_file_filter(FILE * file,
 
 int write_full(int fd, const void *buf, size_t len) WARN_UNUSED;
 
+/**
+ * Portable implementation of the glibc version of basename(3).
+ *
+ * @param filename  path to find basename of
+ *
+ * @return          basename of filename
+ */
+
+#ifdef __GNUC__
+__attribute__((nonnull))
+#endif
+char *semanage_basename(const char *filename);
+
 #endif
diff --git a/libsemanage/tests/test_utilities.c b/libsemanage/tests/test_utilities.c
index bbd5af30..70a76fe7 100644
--- a/libsemanage/tests/test_utilities.c
+++ b/libsemanage/tests/test_utilities.c
@@ -46,6 +46,7 @@ static void test_semanage_rtrim(void);
 static void test_semanage_str_replace(void);
 static void test_semanage_findval(void);
 static void test_slurp_file_filter(void);
+static void test_semanage_basename(void);
 
 static char fname[] = {
 	'T', 'E', 'S', 'T', '_', 'T', 'E', 'M', 'P', '_', 'X', 'X', 'X', 'X',
@@ -117,6 +118,10 @@ int semanage_utilities_add_tests(CU_pSuite suite)
 				test_slurp_file_filter)) {
 		goto err;
 	}
+	if (NULL == CU_add_test(suite, "semanage_basename",
+				test_semanage_basename)) {
+		goto err;
+	}
 	return 0;
       err:
 	CU_cleanup_registry();
@@ -346,3 +351,24 @@ static void test_slurp_file_filter(void)
 
 	semanage_list_destroy(&data);
 }
+
+static void test_semanage_basename(void)
+{
+	char *basename1 = semanage_basename("/foo/bar");
+	CU_ASSERT_STRING_EQUAL(basename1, "bar");
+
+	char *basename2 = semanage_basename("/foo/bar/");
+	CU_ASSERT_STRING_EQUAL(basename2, "");
+
+	char *basename3 = semanage_basename("/foo.bar");
+	CU_ASSERT_STRING_EQUAL(basename3, "foo.bar");
+
+	char *basename5 = semanage_basename(".");
+	CU_ASSERT_STRING_EQUAL(basename5, ".");
+
+	char *basename6 = semanage_basename("");
+	CU_ASSERT_STRING_EQUAL(basename6, "");
+
+	char *basename7 = semanage_basename("/");
+	CU_ASSERT_STRING_EQUAL(basename7, "");
+}
-- 
2.48.1


  reply	other threads:[~2025-02-21  9:39 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-02-20 21:12 [PATCH] libsemanage: define basename macro for non-glibc systems Rahul Sandhu
2025-02-21  0:16 ` William Roberts
2025-02-21  0:50   ` William Roberts
2025-02-21  5:52     ` Rahul Sandhu
2025-02-21  9:03       ` Rahul Sandhu
2025-02-21  9:39         ` Rahul Sandhu [this message]
2025-03-08 23:24           ` [PATCH v2] libsemanage: create semanage_basename to ensure posix compliance Rahul Sandhu
2025-03-19 19:29           ` James Carter
2025-04-07 18:06             ` 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=20250221093910.657484-1-nvraxn@gmail.com \
    --to=nvraxn@gmail.com \
    --cc=bill.c.roberts@gmail.com \
    --cc=selinux@vger.kernel.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.