core/exec-invoke: gracefully handle lack of privilege for initgroups() in user mode (#39039)

Fixes #39038
This commit is contained in:
Yu Watanabe
2025-11-05 02:53:05 +09:00
committed by GitHub
2 changed files with 15 additions and 2 deletions

View File

@@ -904,8 +904,16 @@ static int get_supplementary_groups(
bool keep_groups = false;
if (user && gid_is_valid(gid) && gid != 0) {
/* First step, initialize groups from /etc/groups */
if (initgroups(user, gid) < 0)
return -errno;
if (initgroups(user, gid) < 0) {
/* If our primary gid is already the one specified in Group= (i.e. we're running in
* user mode), gracefully handle the case where we have no privilege to re-initgroups().
*
* Note that group memberships of the current user might have been modified, but
* the change will only take effect after re-login. It's better to continue on with
* existing credentials rather than erroring out. */
if (!ERRNO_IS_PRIVILEGE(errno) || gid != getgid())
return -errno;
}
keep_groups = true;
}

View File

@@ -81,6 +81,11 @@ systemd-run --wait --pipe --user --machine=testuser@ \
systemd-run --wait --pipe --user --machine=testuser@ \
bash -xec '[[ "$PWD" == /home/testuser && -n "$INVOCATION_ID" ]]'
# https://github.com/systemd/systemd/issues/39038
systemd-run --wait --machine=testuser@ --user -p User=testuser true
systemd-run --wait --machine=testuser@ --user -p Group=testuser true
(! systemd-run --wait --machine=testuser@ --user -p Group=testuser -p SupplementaryGroups=root true)
# PrivateTmp=yes implies PrivateUsers=yes for user manager, so skip this if we
# don't have unprivileged user namespaces.
if [[ "$(sysctl -ne kernel.apparmor_restrict_unprivileged_userns)" -ne 1 ]]; then