From c86914667a4ad1debea0cb0cab44df3f10b36dbf Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sat, 20 Sep 2025 00:00:14 +0200 Subject: [PATCH 1/2] core/exec-invoke: gracefully handle lack of privilege for initgroups() in user mode Otherwise specifying User=SELF also fails because we got no privilege to call setgroups(). Fixes #39038 --- src/core/exec-invoke.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index aaa9a0e8bd..b930b1037d 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -902,8 +902,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; } From 7400e375786ab45c2c350b7eb6e1209ab54df802 Mon Sep 17 00:00:00 2001 From: Mike Yuan Date: Sat, 25 Oct 2025 21:26:54 +0200 Subject: [PATCH 2/2] TEST-74-AUX-UTILS.run: add test case for #39038 --- test/units/TEST-74-AUX-UTILS.run.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/units/TEST-74-AUX-UTILS.run.sh b/test/units/TEST-74-AUX-UTILS.run.sh index c7ca8ce615..64eb7257e7 100755 --- a/test/units/TEST-74-AUX-UTILS.run.sh +++ b/test/units/TEST-74-AUX-UTILS.run.sh @@ -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