From 500a52218dc71386ed2771b5889d4890cec3228f Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Wed, 19 Nov 2025 19:20:54 +0100 Subject: [PATCH] *-daemon: always call setgroups, defaulting to count = 0 services started by init don't get any supplementary groups, but anything started from a shell would inherit the groups, causing inconsistent behaviour we can either clear all groups, or always initalize root's groups. since other init systems does not initialize anything, including us at boot, let's just always clear them unconditionally --- src/start-stop-daemon/start-stop-daemon.c | 15 +++++++++------ src/supervise-daemon/supervise-daemon.c | 16 ++++++++++------ 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/start-stop-daemon/start-stop-daemon.c b/src/start-stop-daemon/start-stop-daemon.c index fdcd90326..54d743552 100644 --- a/src/start-stop-daemon/start-stop-daemon.c +++ b/src/start-stop-daemon/start-stop-daemon.c @@ -892,7 +892,7 @@ int main(int argc, char **argv) /* Child process - lets go! */ if (pid == 0) { gid_t group_buf[32], *group_list = group_buf; - int group_count = ARRAY_SIZE(group_buf); + int group_count = 0; pid_t mypid = getpid(); close(pipefd[0]); /* Close the read end of the pipe. */ umask(numask); @@ -950,10 +950,13 @@ int main(int argc, char **argv) applet, pam_strerror(pamh, pamr)); } #endif - if (changeuser && getgrouplist(changeuser, gid, group_list, &group_count) < 0) { - group_list = xmalloc(group_count * sizeof(*group_list)); - if (getgrouplist(changeuser, gid, group_list, &group_count) < 0) - eerrorx("%s: getgrouplist(%s, %"PRIuMAX")", applet, changeuser, (uintmax_t)gid); + if (changeuser) { + group_count = ARRAY_SIZE(group_buf); + if (getgrouplist(changeuser, gid, group_list, &group_count) < 0) { + group_list = xmalloc(group_count * sizeof(*group_list)); + if (getgrouplist(changeuser, gid, group_list, &group_count) < 0) + eerrorx("%s: getgrouplist(%s, %"PRIuMAX")", applet, changeuser, (uintmax_t)gid); + } } /* Close any fd's to the passwd database */ @@ -980,7 +983,7 @@ int main(int argc, char **argv) if (gid && setgid(gid)) eerrorx("%s: unable to set groupid to %"PRIuMAX, applet, (uintmax_t)gid); - if (changeuser && setgroups(group_count, group_list)) + if (setgroups(group_count, group_list)) eerrorx("%s: setgroups() failed", applet); if (group_list != group_buf) free(group_list); diff --git a/src/supervise-daemon/supervise-daemon.c b/src/supervise-daemon/supervise-daemon.c index a1e870830..f1235f3bb 100644 --- a/src/supervise-daemon/supervise-daemon.c +++ b/src/supervise-daemon/supervise-daemon.c @@ -384,7 +384,7 @@ RC_NORETURN static void child_process(char *exec, char **argv) char start_time_string[20]; FILE *fp; gid_t group_buf[32], *group_list = group_buf; - int group_count = ARRAY_SIZE(group_buf); + int group_count = 0; #ifdef HAVE_PAM pam_handle_t *pamh = NULL; @@ -445,10 +445,14 @@ RC_NORETURN static void child_process(char *exec, char **argv) } #endif - if (changeuser && getgrouplist(changeuser, gid, group_list, &group_count) < 0) { - group_list = xmalloc(group_count * sizeof(*group_list)); - if (getgrouplist(changeuser, gid, group_list, &group_count) < 0) - eerrorx("%s: getgrouplist(%s, %"PRIuMAX")", applet, changeuser, (uintmax_t)gid); + if (changeuser) { + /* getgrouplist is a stupid api. */ + group_count = ARRAY_SIZE(group_buf); + if (getgrouplist(changeuser, gid, group_list, &group_count) < 0) { + group_list = xmalloc(group_count * sizeof(*group_list)); + if (getgrouplist(changeuser, gid, group_list, &group_count) < 0) + eerrorx("%s: getgrouplist(%s, %"PRIuMAX")", applet, changeuser, (uintmax_t)gid); + } } /* Close any fd's to the passwd database */ @@ -462,7 +466,7 @@ RC_NORETURN static void child_process(char *exec, char **argv) if (gid && setgid(gid)) eerrorx("%s: unable to set groupid to %"PRIuMAX, applet, (uintmax_t)gid); - if (changeuser && setgroups(group_count, group_list) < 0) + if (setgroups(group_count, group_list) < 0) eerrorx("%s: setgroups() failed", applet); if (group_list != group_buf) free(group_list);