[Buildroot] [git commit] package/libsemanage: fix build issue due to basename()

Julien Olivain ju.o at free.fr
Sun Sep 14 21:45:50 UTC 2025


commit: https://git.buildroot.net/buildroot/commit/?id=79031b79c273c9346487592ee1638bdd48ba7749
branch: https://git.buildroot.net/buildroot/commit/?id=refs/heads/master

The build of libsemanage on musl configurations fails with:

direct_api.c: In function 'semanage_direct_install_file':
direct_api.c:1746:20: error: implicit declaration of function 'basename' [-Wimplicit-function-declaration]
 1746 |         filename = basename(path);
      |                    ^~~~~~~~

This fails to build even with a GCC 14.x toolchain, even with
libsemanage 3.7, which is the version we have in our LTS branch.

Let's backport an upstream patch fixing this issue.

Fixes:

  https://autobuild.buildroot.net/results/913852e35c925888ced37e15be3731b9d3963019/

Signed-off-by: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
Signed-off-by: Julien Olivain <ju.o at free.fr>
---
 ...-create-semanage_basename-to-ensure-posix.patch | 172 +++++++++++++++++++++
 1 file changed, 172 insertions(+)

diff --git a/package/libsemanage/0001-libsemanage-create-semanage_basename-to-ensure-posix.patch b/package/libsemanage/0001-libsemanage-create-semanage_basename-to-ensure-posix.patch
new file mode 100644
index 0000000000..10a81241a1
--- /dev/null
+++ b/package/libsemanage/0001-libsemanage-create-semanage_basename-to-ensure-posix.patch
@@ -0,0 +1,172 @@
+From 795f8381fd64abf692b26d01369561fc68be230c Mon Sep 17 00:00:00 2001
+From: Rahul Sandhu <nvraxn at gmail.com>
+Date: Fri, 21 Feb 2025 09:39:10 +0000
+Subject: [PATCH] libsemanage: create semanage_basename to ensure posix
+ compliance
+
+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 at gmail.com>
+Acked-by: James Carter <jwcart2 at gmail.com>
+Upstream: a339594da6f027aed5d66ec6798a3d732df235e4
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
+---
+ src/conf-parse.y       | 13 ++++++++++---
+ src/direct_api.c       |  1 +
+ src/utilities.c        |  9 +++++++++
+ src/utilities.h        | 13 +++++++++++++
+ tests/test_utilities.c | 26 ++++++++++++++++++++++++++
+ 5 files changed, 59 insertions(+), 3 deletions(-)
+
+diff --git a/src/conf-parse.y b/src/conf-parse.y
+index 6cb8a598..d3ca5f1f 100644
+--- a/src/conf-parse.y
++++ b/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/src/direct_api.c b/src/direct_api.c
+index 99cba7f7..ce12ccaf 100644
+--- a/src/direct_api.c
++++ b/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/src/utilities.c b/src/utilities.c
+index 70b5b677..004ffb62 100644
+--- a/src/utilities.c
++++ b/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/src/utilities.h b/src/utilities.h
+index c2d484a7..7481077a 100644
+--- a/src/utilities.h
++++ b/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/tests/test_utilities.c b/tests/test_utilities.c
+index bbd5af30..70a76fe7 100644
+--- a/tests/test_utilities.c
++++ b/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.51.0
+


More information about the buildroot mailing list