From: Zbigniew Jędrzejewski-Szmek Date: Thu, 21 May 2026 08:11:47 +0000 (+0200) Subject: user-util: sysconf_ngroups_max X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=2c01b4895efe69a52c8eb2da2c15f4641064575e;p=thirdparty%2Fsystemd.git user-util: sysconf_ngroups_max This hides the iffy interface of sysconf(_SC_NGROUPS_MAX) to simplify the calllers. --- diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c index 13537593cfe..1fc8e67204f 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -39,6 +39,7 @@ #include "strv.h" #include "sysctl-util.h" #include "tmpfile-util.h" +#include "user-util.h" #include "xattr-util.h" #if ENABLE_IDN @@ -914,7 +915,7 @@ int getpeergroups(int fd, gid_t **ret) { assert(fd >= 0); assert(ret); - long ngroups_max = sysconf(_SC_NGROUPS_MAX); + int ngroups_max = sysconf_ngroups_max(); if (ngroups_max > 0) n = MAX(n, sizeof(gid_t) * (socklen_t) ngroups_max); diff --git a/src/basic/user-util.c b/src/basic/user-util.c index 8d9474fe214..869fabdebd7 100644 --- a/src/basic/user-util.c +++ b/src/basic/user-util.c @@ -1353,6 +1353,19 @@ int lookup_grent_in_files( return -ESRCH; } +int sysconf_ngroups_max(void) { + /* Query sysconf _SC_NGROUPS_MAX. Returns an int because the expected value is 64k + * and later on this is used as an int with various glibc consumers. */ + + errno = 0; + long ngroups_max = sysconf(_SC_NGROUPS_MAX); + if (ngroups_max <= 0) + return errno_or_else(EOPNOTSUPP); + if (ngroups_max > INT_MAX) + return -ERANGE; + return ngroups_max; +} + static size_t getgr_buffer_size(void) { long bufsize = sysconf(_SC_GETGR_R_SIZE_MAX); return bufsize <= 0 ? 4096U : (size_t) bufsize; diff --git a/src/basic/user-util.h b/src/basic/user-util.h index f45e5bddfd2..12fe6f5f8a0 100644 --- a/src/basic/user-util.h +++ b/src/basic/user-util.h @@ -173,6 +173,8 @@ static inline bool hashed_password_is_locked_or_invalid(const char *password) { */ #define PASSWORD_UNPROVISIONED "!unprovisioned" +int sysconf_ngroups_max(void); + int lookup_pwent_in_files( char * const *files, const char *name, diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 74602efc528..00378903074 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -917,14 +917,9 @@ static int get_supplementary_groups( return 0; } - /* - * If SupplementaryGroups= was passed then NGROUPS_MAX has to - * be positive, otherwise fail. - */ - errno = 0; - long ngroups_max = sysconf(_SC_NGROUPS_MAX); - if (ngroups_max <= 0) - return errno_or_else(EOPNOTSUPP); + int ngroups_max = sysconf_ngroups_max(); + if (ngroups_max < 0) + return ngroups_max; _cleanup_free_ gid_t *l_gids = new(gid_t, ngroups_max); if (!l_gids) diff --git a/src/test/test-condition.c b/src/test/test-condition.c index 8674dab488b..a35d08ef635 100644 --- a/src/test/test-condition.c +++ b/src/test/test-condition.c @@ -1038,7 +1038,7 @@ TEST(condition_test_group) { char gid[DECIMAL_STR_MAX(uint32_t)]; gid_t *gids, max_gid; int ngroups, r, i; - long ngroups_max; + int ngroups_max; xsprintf(gid, "%u", UINT32_C(0xFFFF)); ASSERT_NOT_NULL((condition = condition_new(CONDITION_GROUP, gid, false, false))); @@ -1054,7 +1054,7 @@ TEST(condition_test_group) { ASSERT_OK_POSITIVE(r); condition_free(condition); - ngroups_max = ASSERT_OK_ERRNO(sysconf(_SC_NGROUPS_MAX)); + ngroups_max = ASSERT_OK(sysconf_ngroups_max()); ASSERT_GT(ngroups_max, 0); gids = newa(gid_t, ngroups_max); diff --git a/src/test/test-socket-util.c b/src/test/test-socket-util.c index 038140d4c57..4b14bd46960 100644 --- a/src/test/test-socket-util.c +++ b/src/test/test-socket-util.c @@ -175,12 +175,10 @@ TEST(getpeercred_getpeergroups) { assert_se(fully_set_uid_gid(test_uid, test_gid, test_gids, n_test_gids) >= 0); } else { - long ngroups_max; - test_uid = getuid(); test_gid = getgid(); - ngroups_max = sysconf(_SC_NGROUPS_MAX); + int ngroups_max = sysconf_ngroups_max(); assert_se(ngroups_max > 0); test_gids = newa(gid_t, ngroups_max);