Skip to content

Keepalived fails to resolve script group names when group have large numbers of members. #2605

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
awalls-cx18 opened this issue Apr 21, 2025 · 3 comments

Comments

@awalls-cx18
Copy link

Describe the bug
Keepalived fails to resolve script group names when group have large numbers of members.
The call to getgrnam_r() in lib/notify.c returns with errno ERANGE, indicating the provided buffer is not large enough.

To Reproduce
Have a group foogroup in /etc/group with many members, so that the list of all the names exceeds ~1024 bytes, the glibc default for sysconf(_SC_GETGR_R_SIZE_MAX) on many systems. (This is just a glibc hard coded suggested default for the buffersize for the getgrnam_r() call).

In the keepalived.conf file global_defs section set script_user baruser foogroup. That will be enough for keepalived to emit Unable to resolve default script group name ... message, griping about the group name, even though it exists in the /etc/group file.

Expected behavior
keepalived allows setting script group to a group with a large number of member without error.

Keepalived version

Keepalived v2.1.5 (07/13,2020)

Distro (please complete the following information):

  • Name: CentOS 7.6, AlmaLinux 8.8
  • Architecture: x86_64

Did keepalived coredump?
No.

Additional context
The proper way to deal with getgrnam_r() returning with an errno of ERANGE is to resize/reallocate the buffer to a larger buffer and try the call to getgrnam_r() again.

See this blog post:
https://tomlee.co/2012/10/problems-with-large-linux-unix-groups-and-getgrgid_r-getgrnam_r/

@pqarmitage
Copy link
Collaborator

pqarmitage commented Apr 22, 2025

@awalls-cx18 I don't particularly like the code at https://tomlee.co/2012/10/problems-with-large-linux-unix-groups-and-getgrgid_r-getgrnam_r/. The first example doesn't even compile, since there is an extraneous break;, and in the second example if ((size + realsize) < size || (size + realsize) > max_size) - for the overflow to occur would mean that >2Gb would have been allocated.

I think a reasonable assumption is that the size of the list of usernames returned as members of the group cannot exceed the size of the /etc/group file itself. Would you be happy with the following patch?

quentin@samson:~/keepalived/github.pqa$ git diff
diff --git a/lib/notify.c b/lib/notify.c
index e761bcd0..9803da41 100644
--- a/lib/notify.c
+++ b/lib/notify.c
@@ -939,6 +939,7 @@ static void
 set_pwnam_buf_len(void)
 {
        long buf_len;
+       struct stat statbuf;
 
        /* Get buffer length needed for getpwnam_r/getgrnam_r */
        if ((buf_len = sysconf(_SC_GETPW_R_SIZE_MAX)) == -1)
@@ -948,6 +949,12 @@ set_pwnam_buf_len(void)
        if ((buf_len = sysconf(_SC_GETGR_R_SIZE_MAX)) != -1 &&
            (size_t)buf_len > getpwnam_buf_len)
                getpwnam_buf_len = (size_t)buf_len;
+
+       /* In case there is an excessive number of members of the group, which
+        * could cause the default buffer size to overflow, a reasonable upper
+        * bound for the buffer size is the size of the group file itself. */
+       if (!stat("/etc/group", &statbuf) && (unsigned long)statbuf.st_size > getpwnam_buf_len)
+               getpwnam_buf_len = statbuf.st_size;
 }
 
 static bool

This has the advantage of avoiding a loop repeatedly calling getgrnam_r().

@pqarmitage
Copy link
Collaborator

Commit d9c5f4b should resolve this.

@awalls-cx18
Copy link
Author

The solution looks fine to me. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants