* [PATCH] libsemanage: define basename macro for non-glibc systems @ 2025-02-20 21:12 Rahul Sandhu 2025-02-21 0:16 ` William Roberts 0 siblings, 1 reply; 9+ messages in thread From: Rahul Sandhu @ 2025-02-20 21:12 UTC (permalink / raw) To: selinux; +Cc: Rahul Sandhu Passing a const char *path to basename(3) is a glibc specific extension. Signed-off-by: Rahul Sandhu <nvraxn@gmail.com> --- libsemanage/src/conf-parse.y | 3 +++ libsemanage/src/direct_api.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/libsemanage/src/conf-parse.y b/libsemanage/src/conf-parse.y index 6cb8a598..97cc5438 100644 --- a/libsemanage/src/conf-parse.y +++ b/libsemanage/src/conf-parse.y @@ -50,6 +50,9 @@ static external_prog_t *new_external; static int parse_errors; #define PASSIGN(p1,p2) { free(p1); p1 = p2; } +#if !defined(__GLIBC__) +#define basename(src) (strrchr(src, '/') ? strrchr(src, '/') + 1 : src) +#endif %} diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c index 99cba7f7..4459a7d7 100644 --- a/libsemanage/src/direct_api.c +++ b/libsemanage/src/direct_api.c @@ -63,6 +63,9 @@ #define PIPE_READ 0 #define PIPE_WRITE 1 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +#if !defined(__GLIBC__) +#define basename(src) (strrchr(src, '/') ? strrchr(src, '/') + 1 : src) +#endif static void semanage_direct_destroy(semanage_handle_t * sh); static int semanage_direct_disconnect(semanage_handle_t * sh); -- 2.48.1 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH] libsemanage: define basename macro for non-glibc systems 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 0 siblings, 1 reply; 9+ messages in thread From: William Roberts @ 2025-02-21 0:16 UTC (permalink / raw) To: Rahul Sandhu; +Cc: selinux On Thu, Feb 20, 2025 at 3:13 PM Rahul Sandhu <nvraxn@gmail.com> wrote: > > Passing a const char *path to basename(3) is a glibc specific > extension. > > Signed-off-by: Rahul Sandhu <nvraxn@gmail.com> > --- > libsemanage/src/conf-parse.y | 3 +++ > libsemanage/src/direct_api.c | 3 +++ > 2 files changed, 6 insertions(+) > > diff --git a/libsemanage/src/conf-parse.y b/libsemanage/src/conf-parse.y > index 6cb8a598..97cc5438 100644 > --- a/libsemanage/src/conf-parse.y > +++ b/libsemanage/src/conf-parse.y > @@ -50,6 +50,9 @@ static external_prog_t *new_external; > static int parse_errors; > > #define PASSIGN(p1,p2) { free(p1); p1 = p2; } > +#if !defined(__GLIBC__) > +#define basename(src) (strrchr(src, '/') ? strrchr(src, '/') + 1 : src) > +#endif > > %} > > diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c > index 99cba7f7..4459a7d7 100644 > --- a/libsemanage/src/direct_api.c > +++ b/libsemanage/src/direct_api.c > @@ -63,6 +63,9 @@ > #define PIPE_READ 0 > #define PIPE_WRITE 1 > #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) > +#if !defined(__GLIBC__) > +#define basename(src) (strrchr(src, '/') ? strrchr(src, '/') + 1 : src) > +#endif > > static void semanage_direct_destroy(semanage_handle_t * sh); > static int semanage_direct_disconnect(semanage_handle_t * sh); > -- > 2.48.1 > What system are you on where you run libsemange without glibc, just curious? I am not opposed to adding an implementation for basename where the input can be read only for non-glibc, but this patch doesn't work: Per the man page, https://man7.org/linux/man-pages/man3/basename.3.html, basename("/") should return "/", this one return "\0" basename("/usr/"); should return "usr", this returns "\0". There are two ways you could approach this: 1. If you wanted to do an implementation, I would add it to utilities.c/h and call it something other than basename so we don't get any odd issues with it choosing the one from the headers over the macro. Perhaps libsemange_basename(). On glibc systems this would just call basename directly and on non-glibc systems do the implementation with your own logic. 2. Just copy the path into a modifiable buffer on non-glibc systems I would do both approaches. Create a utility routine that calls basename for glibc and for non-glibc just copies it to a modifiable buffer and then calls basename over rolling our own and the bugs associated with it, also add a unit test for this. This would keep the logic in one place and be dirt simple. Bill ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] libsemanage: define basename macro for non-glibc systems 2025-02-21 0:16 ` William Roberts @ 2025-02-21 0:50 ` William Roberts 2025-02-21 5:52 ` Rahul Sandhu 0 siblings, 1 reply; 9+ messages in thread From: William Roberts @ 2025-02-21 0:50 UTC (permalink / raw) To: Rahul Sandhu; +Cc: selinux On Thu, Feb 20, 2025 at 6:16 PM William Roberts <bill.c.roberts@gmail.com> wrote: > > On Thu, Feb 20, 2025 at 3:13 PM Rahul Sandhu <nvraxn@gmail.com> wrote: > > > > Passing a const char *path to basename(3) is a glibc specific > > extension. > > > > Signed-off-by: Rahul Sandhu <nvraxn@gmail.com> > > --- > > libsemanage/src/conf-parse.y | 3 +++ > > libsemanage/src/direct_api.c | 3 +++ > > 2 files changed, 6 insertions(+) > > > > diff --git a/libsemanage/src/conf-parse.y b/libsemanage/src/conf-parse.y > > index 6cb8a598..97cc5438 100644 > > --- a/libsemanage/src/conf-parse.y > > +++ b/libsemanage/src/conf-parse.y > > @@ -50,6 +50,9 @@ static external_prog_t *new_external; > > static int parse_errors; > > > > #define PASSIGN(p1,p2) { free(p1); p1 = p2; } > > +#if !defined(__GLIBC__) > > +#define basename(src) (strrchr(src, '/') ? strrchr(src, '/') + 1 : src) > > +#endif > > > > %} > > > > diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c > > index 99cba7f7..4459a7d7 100644 > > --- a/libsemanage/src/direct_api.c > > +++ b/libsemanage/src/direct_api.c > > @@ -63,6 +63,9 @@ > > #define PIPE_READ 0 > > #define PIPE_WRITE 1 > > #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) > > +#if !defined(__GLIBC__) > > +#define basename(src) (strrchr(src, '/') ? strrchr(src, '/') + 1 : src) > > +#endif > > > > static void semanage_direct_destroy(semanage_handle_t * sh); > > static int semanage_direct_disconnect(semanage_handle_t * sh); > > -- > > 2.48.1 > > > > What system are you on where you run libsemange without glibc, just curious? > > I am not opposed to adding an implementation for basename where the > input can be read only for non-glibc, but this patch doesn't work: > Per the man page, https://man7.org/linux/man-pages/man3/basename.3.html, > basename("/") should return "/", this one return "\0" > basename("/usr/"); should return "usr", this returns "\0". > > There are two ways you could approach this: > 1. If you wanted to do an implementation, I would add it to > utilities.c/h and call it something other than basename so we don't > get any odd issues with it choosing the one from the headers over the > macro. Perhaps libsemange_basename(). On glibc systems this would just > call basename directly and on non-glibc systems do the implementation > with your own logic. > 2. Just copy the path into a modifiable buffer on non-glibc systems > > I would do both approaches. Create a utility routine that calls > basename for glibc and for non-glibc just copies it to a modifiable > buffer and then calls basename over rolling our own and the bugs > associated with it, also add a unit test for this. This would keep the > logic in one place and be dirt simple. > Looking even more closely it's only the conf-parse.y usage where selinux_policy_root() returns a const char *, the usage in direct_api.c path is a char *, so we only need one spot changed and that can just be a simple copy to an intermediate buffer or am I missing something else here you're pointing out? > Bill ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] libsemanage: define basename macro for non-glibc systems 2025-02-21 0:50 ` William Roberts @ 2025-02-21 5:52 ` Rahul Sandhu 2025-02-21 9:03 ` Rahul Sandhu 0 siblings, 1 reply; 9+ messages in thread From: Rahul Sandhu @ 2025-02-21 5:52 UTC (permalink / raw) To: William Roberts; +Cc: selinux > What system are you on where you run libsemange without glibc, just curious? All Gentoo machines, Gentoo musl. :) > I am not opposed to adding an implementation for basename where the > input can be read only for non-glibc, but this patch doesn't work: > Per the man page, https://man7.org/linux/man-pages/man3/basename.3.html, > basename("/") should return "/", this one return "\0" > basename("/usr/"); should return "usr", this returns "\0". > There are two ways you could approach this: > 1. If you wanted to do an implementation, I would add it to > utilities.c/h and call it something other than basename so we don't > get any odd issues with it choosing the one from the headers over the > macro. Perhaps libsemange_basename(). On glibc systems this would just > call basename directly and on non-glibc systems do the implementation > with your own logic. > 2. Just copy the path into a modifiable buffer on non-glibc systems > > I would do both approaches. Create a utility routine that calls > basename for glibc and for non-glibc just copies it to a modifiable > buffer and then calls basename over rolling our own and the bugs > associated with it, also add a unit test for this. This would keep the > logic in one place and be dirt simple. FWIW, glibc's basename appears to be really trivial: char * __basename (const char *filename) { char *p = strrchr (filename, '/'); return p ? p + 1 : (char *) filename; } > selinux_policy_root() returns a const char *, > the usage in direct_api.c path is a char *, so we only need one spot > changed and that can just be a simple > copy to an intermediate buffer or am I missing something else here > you're pointing out? Oh good point, we're just missing a header (libgen.h). I suppose then it is just a simple copy to an intermediate buffer, I'll send an updated patch shortly. Thanks, Rahul ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] libsemanage: define basename macro for non-glibc systems 2025-02-21 5:52 ` Rahul Sandhu @ 2025-02-21 9:03 ` Rahul Sandhu 2025-02-21 9:39 ` [PATCH v2] libsemanage: create semanage_basename to ensure posix compliance Rahul Sandhu 0 siblings, 1 reply; 9+ messages in thread From: Rahul Sandhu @ 2025-02-21 9:03 UTC (permalink / raw) To: nvraxn; +Cc: bill.c.roberts, selinux In regards to this: > There are two ways you could approach this: > 1. If you wanted to do an implementation, I would add it to > utilities.c/h and call it something other than basename so we don't > get any odd issues with it choosing the one from the headers over the > macro. Perhaps libsemange_basename(). On glibc systems this would just > call basename directly and on non-glibc systems do the implementation > with your own logic. > 2. Just copy the path into a modifiable buffer on non-glibc systems > > I would do both approaches. Create a utility routine that calls > basename for glibc and for non-glibc just copies it to a modifiable > buffer and then calls basename over rolling our own and the bugs > associated with it, also add a unit test for this. This would keep the > logic in one place and be dirt simple. It appears that glibc's basename(3) has a different behaviour to the version of basename(3) defined in posix. From the man page: > The GNU version never modifies its argument, and returns the empty > string when path has a trailing slash, and in particular also when it > is "/". So I think it might be best to just define an semanage_basename based off the GNU behaviour as it is fairly trivial (being 2 LOC). I'll send a patch to do this shortly. Thanks, Rahul ^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2] libsemanage: create semanage_basename to ensure posix compliance 2025-02-21 9:03 ` Rahul Sandhu @ 2025-02-21 9:39 ` Rahul Sandhu 2025-03-08 23:24 ` Rahul Sandhu 2025-03-19 19:29 ` James Carter 0 siblings, 2 replies; 9+ messages in thread From: Rahul Sandhu @ 2025-02-21 9:39 UTC (permalink / raw) To: selinux, nvraxn; +Cc: bill.c.roberts 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 ^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2] libsemanage: create semanage_basename to ensure posix compliance 2025-02-21 9:39 ` [PATCH v2] libsemanage: create semanage_basename to ensure posix compliance Rahul Sandhu @ 2025-03-08 23:24 ` Rahul Sandhu 2025-03-19 19:29 ` James Carter 1 sibling, 0 replies; 9+ messages in thread From: Rahul Sandhu @ 2025-03-08 23:24 UTC (permalink / raw) To: Rahul Sandhu, selinux; +Cc: bill.c.roberts Ping Thanks, Rahul ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] libsemanage: create semanage_basename to ensure posix compliance 2025-02-21 9:39 ` [PATCH v2] libsemanage: create semanage_basename to ensure posix compliance Rahul Sandhu 2025-03-08 23:24 ` Rahul Sandhu @ 2025-03-19 19:29 ` James Carter 2025-04-07 18:06 ` James Carter 1 sibling, 1 reply; 9+ messages in thread From: James Carter @ 2025-03-19 19:29 UTC (permalink / raw) To: Rahul Sandhu; +Cc: selinux, bill.c.roberts On Fri, Feb 21, 2025 at 4:41 AM Rahul Sandhu <nvraxn@gmail.com> 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@gmail.com> Acked-by: James Carter <jwcart2@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 > > ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2] libsemanage: create semanage_basename to ensure posix compliance 2025-03-19 19:29 ` James Carter @ 2025-04-07 18:06 ` James Carter 0 siblings, 0 replies; 9+ messages in thread From: James Carter @ 2025-04-07 18:06 UTC (permalink / raw) To: Rahul Sandhu; +Cc: selinux, bill.c.roberts On Wed, Mar 19, 2025 at 3:29 PM James Carter <jwcart2@gmail.com> wrote: > > On Fri, Feb 21, 2025 at 4:41 AM Rahul Sandhu <nvraxn@gmail.com> 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@gmail.com> > > Acked-by: James Carter <jwcart2@gmail.com> > Merged. Thanks, Jim > > --- > > 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 > > > > ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2025-04-07 18:06 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 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 ` [PATCH v2] libsemanage: create semanage_basename to ensure posix compliance Rahul Sandhu 2025-03-08 23:24 ` Rahul Sandhu 2025-03-19 19:29 ` James Carter 2025-04-07 18:06 ` James Carter
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.