mirror of
https://github.com/systemd/systemd.git
synced 2026-08-12 22:17:19 +00:00
run: reset groups before scope uid switch
Reproducer:
sudo systemd-run --scope --uid=nobody /usr/bin/id
Before, the command ran as nobody but kept the caller supplementary
root group, for example groups=65534(nogroup),0(root). Scope mode
performs the uid/gid switch locally, so initialize the target user groups
before dropping privileges.
Follow-up for 4de33e7f32
This commit is contained in:
@@ -2517,6 +2517,17 @@ static int start_transient_service(sd_bus *bus) {
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int log_scope_group_setup_errno(int r, gid_t gid, const char *message) {
|
||||
assert(r < 0);
|
||||
assert(message);
|
||||
|
||||
if (!ERRNO_IS_PRIVILEGE(r) || gid != getgid())
|
||||
return log_error_errno(r, "%s: %m", message);
|
||||
|
||||
log_debug_errno(r, "%s, ignoring: %m", message);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int start_transient_scope(sd_bus *bus) {
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
_cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
|
||||
@@ -2623,26 +2634,22 @@ static int start_transient_scope(sd_bus *bus) {
|
||||
return log_error_errno(errno, "Failed to set nice level: %m");
|
||||
}
|
||||
|
||||
gid_t gid = GID_INVALID;
|
||||
if (arg_exec_group) {
|
||||
gid_t gid;
|
||||
|
||||
r = get_group_creds(arg_exec_group, /* flags= */ 0, /* ret_name= */ NULL, &gid);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to resolve group '%s': %s",
|
||||
arg_exec_group, STRERROR_GROUP(r));
|
||||
|
||||
if (setresgid(gid, gid, gid) < 0)
|
||||
return log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid);
|
||||
}
|
||||
|
||||
uid_t uid = UID_INVALID;
|
||||
if (arg_exec_user) {
|
||||
_cleanup_free_ char *user = NULL, *home = NULL, *shell = NULL;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
gid_t user_gid;
|
||||
|
||||
r = get_user_creds(arg_exec_user,
|
||||
USER_CREDS_CLEAN|USER_CREDS_SUPPRESS_PLACEHOLDER|USER_CREDS_PREFER_NSS,
|
||||
&user, &uid, &gid, &home, &shell);
|
||||
&user, &uid, &user_gid, &home, &shell);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to resolve user '%s': %s",
|
||||
arg_exec_user, STRERROR_USER(r));
|
||||
@@ -2669,14 +2676,33 @@ static int start_transient_scope(sd_bus *bus) {
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
if (!arg_exec_group &&
|
||||
setresgid(gid, gid, gid) < 0)
|
||||
return log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid);
|
||||
if (!gid_is_valid(gid))
|
||||
gid = user_gid;
|
||||
|
||||
if (setresuid(uid, uid, uid) < 0)
|
||||
return log_error_errno(errno, "Failed to change UID to " UID_FMT ": %m", uid);
|
||||
r = initgroups_wrapper(arg_exec_user, gid);
|
||||
if (r < 0) {
|
||||
r = log_scope_group_setup_errno(
|
||||
r,
|
||||
gid,
|
||||
strjoina("Failed to initialize supplementary groups for user '", arg_exec_user, "'"));
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
} else if (gid_is_valid(gid)) {
|
||||
r = maybe_setgroups(/* size= */ 0, /* list= */ NULL);
|
||||
if (r < 0) {
|
||||
r = log_scope_group_setup_errno(r, gid, "Failed to drop supplementary groups");
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (gid_is_valid(gid) && setresgid(gid, gid, gid) < 0)
|
||||
return log_error_errno(errno, "Failed to change GID to " GID_FMT ": %m", gid);
|
||||
|
||||
if (uid_is_valid(uid) && setresuid(uid, uid, uid) < 0)
|
||||
return log_error_errno(errno, "Failed to change UID to " UID_FMT ": %m", uid);
|
||||
|
||||
if (arg_working_directory && chdir(arg_working_directory) < 0)
|
||||
return log_error_errno(errno, "Failed to change directory to '%s': %m", arg_working_directory);
|
||||
|
||||
|
||||
@@ -111,6 +111,10 @@ systemd-run --scope --slice-inherit --slice=foo \
|
||||
bash -xec '[[ "$(</proc/self/cgroup)" =~ /system\.slice/system-foo\.slice/run-.+\.scope$ ]]'
|
||||
# We should inherit caller's environment
|
||||
systemd-run --scope bash -xec '[[ "$PARENT_FOO" == bar ]]'
|
||||
systemd-run --scope --uid=testuser \
|
||||
bash -xec '[[ " $(id -G) " != *" 0 "* ]]'
|
||||
systemd-run --scope --gid=testuser \
|
||||
bash -xec '[[ " $(id -G) " != *" 0 "* ]]'
|
||||
systemd-run --scope \
|
||||
--property=RuntimeMaxSec=10 \
|
||||
--property=RuntimeMaxSec=infinity \
|
||||
|
||||
Reference in New Issue
Block a user