From 795f8381fd64abf692b26d01369561fc68be230c Mon Sep 17 00:00:00 2001 From: Rahul Sandhu 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 Acked-by: James Carter Upstream: a339594da6f027aed5d66ec6798a3d732df235e4 Signed-off-by: Thomas Petazzoni [thomas: backport to v3.7] Signed-off-by: Thomas Perale --- src/conf-parse.y | 13 ++++++++++--- src/direct_api.c | 1 + src/utilities.c | 9 +++++++++ src/utilities.h | 13 +++++++++++++ 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 #include @@ -350,7 +351,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"); @@ -505,8 +509,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 #include +#include #include #include #include diff --git a/src/utilities.c b/src/utilities.c index 70b5b677..004ffb62 100644 --- a/src/utilities.c +++ b/src/utilities.c @@ -328,3 +328,12 @@ semanage_list_t *semanage_slurp_file_filter(FILE * file, return head.next; } + +#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 @@ -144,4 +144,18 @@ void semanage_keep_until_space(char *data); semanage_list_t *semanage_slurp_file_filter(FILE * file, int (*pred) (const char *)) 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 -- 2.51.0