On Fri, Feb 21, 2025 at 4:41 AM Rahul Sandhu <nvraxn@xxxxxxxxx> wrote: > > 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@xxxxxxxxx> Acked-by: James Carter <jwcart2@xxxxxxxxx> > --- > 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 > >