]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
user-util: sysconf_ngroups_max
authorZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Thu, 21 May 2026 08:11:47 +0000 (10:11 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Thu, 2 Jul 2026 15:19:18 +0000 (17:19 +0200)
This hides the iffy interface of sysconf(_SC_NGROUPS_MAX) to simplify
the calllers.

src/basic/socket-util.c
src/basic/user-util.c
src/basic/user-util.h
src/core/exec-invoke.c
src/test/test-condition.c
src/test/test-socket-util.c

index 13537593cfe130905ba1fd9f3d5a88cf463d5d3a..1fc8e67204f58d9f1833c2fbc27b1321f1e37367 100644 (file)
@@ -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);
 
index 8d9474fe214bb653fad7aa32a2658db6ecbdb889..869fabdebd70faf027b14347232668b73febd8f7 100644 (file)
@@ -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;
index f45e5bddfd2253398a18f28256d00c0a988631b4..12fe6f5f8a096391f006b751a25668e20cbf9572 100644 (file)
@@ -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,
index 74602efc5282549484f2d5f6552628859953a8cd..0037890307411d2bf5c4dae5e5a88333eb2bc2d0 100644 (file)
@@ -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)
index 8674dab488b9176eb631211127b0abfbcac5a06c..a35d08ef63557f96b492f62f635e213d533ae988 100644 (file)
@@ -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);
index 038140d4c578c31f178af6a39539e24c73e208b4..4b14bd46960d1c4198ca00798128fece3af03719 100644 (file)
@@ -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);