From 7a309d70bbd9a6acf3699af28b48280a24bcc0f7 Mon Sep 17 00:00:00 2001 From: "Todd C. Miller" Date: Sat, 26 Jun 2021 18:45:28 -0600 Subject: [PATCH] Don't assume that the number of groups returned by getgroups() is static. On systems where getgroups() returns results based on more than just the per-process group vector in the kernel it is possible for the number of groups to change in between invocations. Based on GitHub PR #106 from Pierre-Olivier Martel. --- src/sesh.c | 4 +++- src/sudo.c | 3 ++- src/sudo_edit.c | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/sesh.c b/src/sesh.c index b07aa9737..69756196a 100644 --- a/src/sesh.c +++ b/src/sesh.c @@ -408,8 +408,10 @@ sesh_sudoedit(int argc, char *argv[]) U_("unable to allocate memory")); debug_return_int(SESH_ERR_FAILURE); } - if (getgroups(run_cred.ngroups, run_cred.groups) < 0) { + run_cred.ngroups = getgroups(run_cred.ngroups, run_cred.groups); + if (run_cred.ngroups < 0) { sudo_warn("%s", U_("unable to get group list")); + free(run_cred.groups); debug_return_int(SESH_ERR_FAILURE); } } else { diff --git a/src/sudo.c b/src/sudo.c index 625f847c9..9a1fe0c21 100644 --- a/src/sudo.c +++ b/src/sudo.c @@ -443,7 +443,8 @@ get_user_groups(const char *user, struct sudo_cred *cred) cred->groups = reallocarray(NULL, cred->ngroups, sizeof(GETGROUPS_T)); if (cred->groups == NULL) goto done; - if (getgroups(cred->ngroups, cred->groups) < 0) { + cred->ngroups = getgroups(cred->ngroups, cred->groups); + if (cred->ngroups < 0) { sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_ERRNO, "%s: unable to get %d groups via getgroups()", __func__, cred->ngroups); diff --git a/src/sudo_edit.c b/src/sudo_edit.c index 15c75d8c4..af552749f 100644 --- a/src/sudo_edit.c +++ b/src/sudo_edit.c @@ -89,7 +89,8 @@ set_tmpdir(struct sudo_cred *user_cred) sudo_warnx(U_("%s: %s"), __func__, U_("unable to allocate memory")); debug_return_bool(false); } - if (getgroups(saved_cred.ngroups, saved_cred.groups) < 0) { + saved_cred.ngroups = getgroups(saved_cred.ngroups, saved_cred.groups); + if (saved_cred.ngroups < 0) { sudo_warn("%s", U_("unable to get group list")); free(saved_cred.groups); debug_return_bool(false);