1
0
mirror of https://github.com/systemd/systemd synced 2025-11-06 10:24:44 +01:00

Compare commits

..

7 Commits

Author SHA1 Message Date
Chris Down
666cd35be4 core: Only apply unprivileged userns logic to user managers
Commit 38748596f078 ("core: Make DelegateNamespaces= work for user
managers with CAP_SYS_ADMIN") refactored the logic for when an
unprivileged process should create a new user namespace for sandboxing.

This refactor inadvertently removed a check (`params->runtime_scope !=
RUNTIME_SCOPE_USER`) that differentiated between system services and user
services.

This causes a regression in rootless containers where systemd runs
unprivileged. When starting a system service (like `dbus-broker`) that
uses sandboxing features (eg. with `PrivateTmp=yes`), systemd now
incorrectly creates a new, minimal `PRIVATE_USERS_SELF` namespace.

This new namespace only maps UID/GID 0. When dbus-broker attempts to
drop privileges to the `dbus` user (GID 81), the `setresgid(81, 81, 81)`
call fails because GID 81 is not mapped.

Restore the check to ensure that the special unprivileged sandboxing
logic is only applied to user services, as was the original intent.
System services in a rootless context will now correctly run in the
container's main user namespace, where all necessary UIDs/GIDs are
mapped.

Fixes: https://github.com/systemd/systemd/issues/39563
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2391343
2025-11-05 21:12:52 +08:00
Yu Watanabe
3a2c46dfbe
core/manager: small cleanups (#39562) 2025-11-05 21:17:54 +09:00
Mike Yuan
f873ac8727
core/manager: rearrange several struct fields 2025-11-05 10:40:22 +01:00
Mike Yuan
4fc9e19f7f
core/manager: drop unneeded "struct" 2025-11-05 10:40:21 +01:00
Mike Yuan
185af6ebd3
core/manager: kill unused default_unit_job_id field
While at it, make sure the "Queued ... job for default target"
message is always logged, i.e. also when we fall back to
start job instead of isolate.
2025-11-05 10:39:30 +01:00
Yu Watanabe
5468cd269f tpm2-setup: fix typo
Follow-up for 8a6e77f1a8088bb6c7877e256bcc1f1e71552819.
2025-11-05 18:18:49 +09:00
Yu Watanabe
f91fd8d5a1 tar-util: fix typo
Follow-up for 4ded7f7a434c59534f65a0f9d391c55961eb110d.
2025-11-05 18:17:23 +09:00
5 changed files with 15 additions and 12 deletions

View File

@ -4468,6 +4468,12 @@ static void log_command_line(
static bool exec_needs_cap_sys_admin(const ExecContext *context, const ExecParameters *params) { static bool exec_needs_cap_sys_admin(const ExecContext *context, const ExecParameters *params) {
assert(context); assert(context);
assert(params);
/* We only want to ever imply PrivateUsers= for user managers, as they're not expected to setuid() to
* other users, unlike the system manager which needs all users to be around. */
if (params->runtime_scope != RUNTIME_SCOPE_USER)
return false;
return context->private_users != PRIVATE_USERS_NO || return context->private_users != PRIVATE_USERS_NO ||
context->private_tmp != PRIVATE_TMP_NO || context->private_tmp != PRIVATE_TMP_NO ||

View File

@ -2639,12 +2639,10 @@ static int do_queue_default_job(
return log_struct_errno(LOG_EMERG, r, return log_struct_errno(LOG_EMERG, r,
LOG_MESSAGE("Failed to isolate default target: %s", bus_error_message(&error, r)), LOG_MESSAGE("Failed to isolate default target: %s", bus_error_message(&error, r)),
LOG_MESSAGE_ID(SD_MESSAGE_CORE_ISOLATE_TARGET_FAILED_STR)); LOG_MESSAGE_ID(SD_MESSAGE_CORE_ISOLATE_TARGET_FAILED_STR));
} else }
log_info("Queued %s job for default target %s.",
job_type_to_string(job->type),
unit_status_string(job->unit, NULL));
m->default_unit_job_id = job->id; log_info("Queued %s job for default target %s.",
job_type_to_string(job->type), unit_status_string(job->unit, NULL));
return 0; return 0;
} }

View File

@ -173,7 +173,7 @@ typedef struct Manager {
LIST_HEAD(Unit, load_queue); /* this is actually more a stack than a queue, but uh. */ LIST_HEAD(Unit, load_queue); /* this is actually more a stack than a queue, but uh. */
/* Jobs that need to be run */ /* Jobs that need to be run */
struct Prioq *run_queue; Prioq *run_queue;
/* Units and jobs that have not yet been announced via /* Units and jobs that have not yet been announced via
* D-Bus. When something about a job changes it is added here * D-Bus. When something about a job changes it is added here
@ -321,18 +321,15 @@ typedef struct Manager {
Hashmap *watch_bus; /* D-Bus names => Unit object n:1 */ Hashmap *watch_bus; /* D-Bus names => Unit object n:1 */
bool send_reloading_done;
uint32_t current_job_id; uint32_t current_job_id;
uint32_t default_unit_job_id;
/* Data specific to the Automount subsystem */ /* Data specific to the Automount subsystem */
int dev_autofs_fd; int dev_autofs_fd;
/* Data specific to the cgroup subsystem */ /* Data specific to the cgroup subsystem */
Hashmap *cgroup_unit; Hashmap *cgroup_unit;
CGroupMask cgroup_supported;
char *cgroup_root; char *cgroup_root;
CGroupMask cgroup_supported;
/* Notifications from cgroups, when the unified hierarchy is used is done via inotify. */ /* Notifications from cgroups, when the unified hierarchy is used is done via inotify. */
int cgroup_inotify_fd; int cgroup_inotify_fd;
@ -365,6 +362,8 @@ typedef struct Manager {
bool dispatching_load_queue; bool dispatching_load_queue;
int may_dispatch_stop_notify_queue; /* tristate */ int may_dispatch_stop_notify_queue; /* tristate */
bool send_reloading_done;
/* Have we already sent out the READY=1 notification? */ /* Have we already sent out the READY=1 notification? */
bool ready_sent; bool ready_sent;

View File

@ -529,7 +529,7 @@ static int archive_entry_read_acl(
r = acl_set_perm(p, ACL_EXECUTE, permset & ARCHIVE_ENTRY_ACL_EXECUTE); r = acl_set_perm(p, ACL_EXECUTE, permset & ARCHIVE_ENTRY_ACL_EXECUTE);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to set ACL entry excute bit: %m"); return log_error_errno(r, "Failed to set ACL entry execute bit: %m");
if (sym_acl_set_permset(e, p) < 0) if (sym_acl_set_permset(e, p) < 0)
return log_error_errno(errno, "Failed to set ACL entry permission set: %m"); return log_error_errno(errno, "Failed to set ACL entry permission set: %m");

View File

@ -467,7 +467,7 @@ static int setup_nvpcr(void) {
if (c.n_already > 0 && c.n_anchored == 0 && !arg_early) { if (c.n_already > 0 && c.n_anchored == 0 && !arg_early) {
/* If we didn't anchor anything right now, but we anchored something earlier, then it might /* If we didn't anchor anything right now, but we anchored something earlier, then it might
* have happened in the initrd, and thus the anchor ID was not commited to /var/ or the ESP * have happened in the initrd, and thus the anchor ID was not committed to /var/ or the ESP
* yet. Hence, let's explicitly do so now, to catch up. */ * yet. Hence, let's explicitly do so now, to catch up. */
r = tpm2_nvpcr_acquire_anchor_secret(/* ret= */ NULL, /* sync_secondary= */ true); r = tpm2_nvpcr_acquire_anchor_secret(/* ret= */ NULL, /* sync_secondary= */ true);