From: Bogdan-Cristian Tătăroiu <b.tataroiu@xxxxxxxxx> sysconf(_SC_GETPW_R_SIZE_MAX) and sysconf(_SC_GETGR_R_SIZE_MAX) return -1 on musl, which causes either segmentation faults or ENOMEM errors. Replace all usages of sysconf with dedicated methods that guard against a result of -1. --- support/nfsidmap/gums.c | 4 ++-- support/nfsidmap/libnfsidmap.c | 4 ++-- support/nfsidmap/nfsidmap_common.c | 16 ++++++++++++++++ support/nfsidmap/nfsidmap_private.h | 2 ++ support/nfsidmap/nss.c | 8 ++++---- support/nfsidmap/regex.c | 9 +++++---- support/nfsidmap/static.c | 5 +++-- 7 files changed, 34 insertions(+), 14 deletions(-) diff --git a/support/nfsidmap/gums.c b/support/nfsidmap/gums.c index 1d6eb318..e94a4c50 100644 --- a/support/nfsidmap/gums.c +++ b/support/nfsidmap/gums.c @@ -475,7 +475,7 @@ static int translate_to_uid(char *local_uid, uid_t *uid, uid_t *gid) int ret = -1; struct passwd *pw = NULL; struct pwbuf *buf = NULL; - size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); + size_t buflen = get_pwnam_buflen(); buf = malloc(sizeof(*buf) + buflen); if (buf == NULL) @@ -501,7 +501,7 @@ static int translate_to_gid(char *local_gid, uid_t *gid) struct group *gr = NULL; struct group grbuf; char *buf = NULL; - size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX); + size_t buflen = get_grnam_buflen(); int ret = -1; do { diff --git a/support/nfsidmap/libnfsidmap.c b/support/nfsidmap/libnfsidmap.c index f8c36480..e1475879 100644 --- a/support/nfsidmap/libnfsidmap.c +++ b/support/nfsidmap/libnfsidmap.c @@ -457,7 +457,7 @@ int nfs4_init_name_mapping(char *conffile) nobody_user = conf_get_str("Mapping", "Nobody-User"); if (nobody_user) { - size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); + size_t buflen = get_pwnam_buflen(); struct passwd *buf; struct passwd *pw = NULL; int err; @@ -478,7 +478,7 @@ int nfs4_init_name_mapping(char *conffile) nobody_group = conf_get_str("Mapping", "Nobody-Group"); if (nobody_group) { - size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX); + size_t buflen = get_grnam_buflen(); struct group *buf; struct group *gr = NULL; int err; diff --git a/support/nfsidmap/nfsidmap_common.c b/support/nfsidmap/nfsidmap_common.c index 4d2cb14f..1d5b542b 100644 --- a/support/nfsidmap/nfsidmap_common.c +++ b/support/nfsidmap/nfsidmap_common.c @@ -116,3 +116,19 @@ int get_reformat_group(void) return reformat_group; } + +size_t get_pwnam_buflen(void) +{ + long buflen = sysconf(_SC_GETPW_R_SIZE_MAX); + if (buflen == -1) + buflen = 16384; + return (size_t)buflen; +} + +size_t get_grnam_buflen(void) +{ + long buflen = sysconf(_SC_GETGR_R_SIZE_MAX); + if (buflen == -1) + buflen = 16384; + return (size_t)buflen; +} diff --git a/support/nfsidmap/nfsidmap_private.h b/support/nfsidmap/nfsidmap_private.h index a5cb6dda..234ca9d4 100644 --- a/support/nfsidmap/nfsidmap_private.h +++ b/support/nfsidmap/nfsidmap_private.h @@ -40,6 +40,8 @@ struct conf_list *get_local_realms(void); void free_local_realms(void); int get_nostrip(void); int get_reformat_group(void); +size_t get_pwnam_buflen(void); +size_t get_grnam_buflen(void); typedef enum { IDTYPE_USER = 1, diff --git a/support/nfsidmap/nss.c b/support/nfsidmap/nss.c index 0f43076e..3fc045dc 100644 --- a/support/nfsidmap/nss.c +++ b/support/nfsidmap/nss.c @@ -91,7 +91,7 @@ static int nss_uid_to_name(uid_t uid, char *domain, char *name, size_t len) struct passwd *pw = NULL; struct passwd pwbuf; char *buf; - size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); + size_t buflen = get_pwnam_buflen(); int err = -ENOMEM; buf = malloc(buflen); @@ -119,7 +119,7 @@ static int nss_gid_to_name(gid_t gid, char *domain, char *name, size_t len) struct group *gr = NULL; struct group grbuf; char *buf; - size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX); + size_t buflen = get_grnam_buflen(); int err; if (domain == NULL) @@ -192,7 +192,7 @@ static struct passwd *nss_getpwnam(const char *name, const char *domain, { struct passwd *pw; struct pwbuf *buf; - size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); + size_t buflen = get_pwnam_buflen(); char *localname; int err = ENOMEM; @@ -301,7 +301,7 @@ static int _nss_name_to_gid(char *name, gid_t *gid, int dostrip) struct group *gr = NULL; struct group grbuf; char *buf, *domain; - size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX); + size_t buflen = get_grnam_buflen(); int err = -EINVAL; char *localname = NULL; char *ref_name = NULL; diff --git a/support/nfsidmap/regex.c b/support/nfsidmap/regex.c index 8424179f..ea094b95 100644 --- a/support/nfsidmap/regex.c +++ b/support/nfsidmap/regex.c @@ -46,6 +46,7 @@ #include "nfsidmap.h" #include "nfsidmap_plugin.h" +#include "nfsidmap_private.h" #define CONFIG_GET_STRING nfsidmap_config_get extern const char *nfsidmap_config_get(const char *, const char *); @@ -95,7 +96,7 @@ static struct passwd *regex_getpwnam(const char *name, const char *UNUSED(domain { struct passwd *pw; struct pwbuf *buf; - size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); + size_t buflen = get_pwnam_buflen(); char *localname; size_t namelen; int err; @@ -175,7 +176,7 @@ static struct group *regex_getgrnam(const char *name, const char *UNUSED(domain) { struct group *gr; struct grbuf *buf; - size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX); + size_t buflen = get_grnam_buflen(); char *localgroup; char *groupname; size_t namelen; @@ -366,7 +367,7 @@ static int regex_uid_to_name(uid_t uid, char *domain, char *name, size_t len) struct passwd *pw = NULL; struct passwd pwbuf; char *buf; - size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); + size_t buflen = get_pwnam_buflen(); int err = -ENOMEM; buf = malloc(buflen); @@ -392,7 +393,7 @@ static int regex_gid_to_name(gid_t gid, char *UNUSED(domain), char *name, size_t struct group grbuf; char *buf; const char *name_prefix; - size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX); + size_t buflen = get_grnam_buflen(); int err; char * groupname = NULL; diff --git a/support/nfsidmap/static.c b/support/nfsidmap/static.c index 8ac4a398..395cac06 100644 --- a/support/nfsidmap/static.c +++ b/support/nfsidmap/static.c @@ -44,6 +44,7 @@ #include "conffile.h" #include "nfsidmap.h" #include "nfsidmap_plugin.h" +#include "nfsidmap_private.h" /* * Static Translation Methods @@ -98,7 +99,7 @@ static struct passwd *static_getpwnam(const char *name, { struct passwd *pw; struct pwbuf *buf; - size_t buflen = sysconf(_SC_GETPW_R_SIZE_MAX); + size_t buflen = get_pwnam_buflen(); char *localname; int err; @@ -149,7 +150,7 @@ static struct group *static_getgrnam(const char *name, { struct group *gr; struct grbuf *buf; - size_t buflen = sysconf(_SC_GETGR_R_SIZE_MAX); + size_t buflen = get_grnam_buflen(); char *localgroup; int err; -- 2.45.2