From: Luca Boccassi Date: Thu, 31 Aug 2023 19:58:22 +0000 (+0100) Subject: core: ensure execute/spawn functions can work without Unit object X-Git-Tag: v255-rc1~250^2~14 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b646fc324a83c9831fd3e3d356007ef3dfa3594c;p=thirdparty%2Fsystemd.git core: ensure execute/spawn functions can work without Unit object When switching to serialization later, the Unit object will not be serialized, move parameters around instead --- diff --git a/src/core/bpf-lsm.c b/src/core/bpf-lsm.c index 300486597b3..216fc341c18 100644 --- a/src/core/bpf-lsm.c +++ b/src/core/bpf-lsm.c @@ -154,20 +154,14 @@ int lsm_bpf_setup(Manager *m) { return 0; } -int lsm_bpf_unit_restrict_filesystems(Unit *u, const Set *filesystems, int outer_map_fd, bool allow_list) { - _cleanup_close_ int outer_map_fd_cleanup = -EBADF; +int lsm_bpf_restrict_filesystems(const Set *filesystems, uint64_t cgroup_id, int outer_map_fd, bool allow_list) { uint32_t dummy_value = 1, zero = 0; const char *fs; const statfs_f_type_t *magic; int r; assert(filesystems); - assert(u); - assert(outer_map_fd >= 0 || u->manager); - - if (u->manager && !u->manager->restrict_fs) /* Might be called in sd-executor with no manager object */ - return log_unit_error_errno(u, SYNTHETIC_ERRNO(EINVAL), - "bpf-lsm: BPF LSM object is not installed, has setup failed?"); + assert(outer_map_fd >= 0); int inner_map_fd = compat_bpf_map_create( BPF_MAP_TYPE_HASH, @@ -177,41 +171,35 @@ int lsm_bpf_unit_restrict_filesystems(Unit *u, const Set *filesystems, int outer 128U, /* Should be enough for all filesystem types */ NULL); if (inner_map_fd < 0) - return log_unit_error_errno(u, errno, "bpf-lsm: Failed to create inner BPF map: %m"); - - if (outer_map_fd < 0) { - outer_map_fd_cleanup = outer_map_fd = sym_bpf_map__fd(u->manager->restrict_fs->maps.cgroup_hash); - if (outer_map_fd < 0) - return log_unit_error_errno(u, errno, "bpf-lsm: Failed to get BPF map fd: %m"); - } + return log_error_errno(errno, "bpf-lsm: Failed to create inner BPF map: %m"); - if (sym_bpf_map_update_elem(outer_map_fd, &u->cgroup_id, &inner_map_fd, BPF_ANY) != 0) - return log_unit_error_errno(u, errno, "bpf-lsm: Error populating BPF map: %m"); + if (sym_bpf_map_update_elem(outer_map_fd, &cgroup_id, &inner_map_fd, BPF_ANY) != 0) + return log_error_errno(errno, "bpf-lsm: Error populating BPF map: %m"); uint32_t allow = allow_list; /* Use key 0 to store whether this is an allow list or a deny list */ if (sym_bpf_map_update_elem(inner_map_fd, &zero, &allow, BPF_ANY) != 0) - return log_unit_error_errno(u, errno, "bpf-lsm: Error initializing map: %m"); + return log_error_errno(errno, "bpf-lsm: Error initializing map: %m"); SET_FOREACH(fs, filesystems) { r = fs_type_from_string(fs, &magic); if (r < 0) { - log_unit_warning(u, "bpf-lsm: Invalid filesystem name '%s', ignoring.", fs); + log_warning("bpf-lsm: Invalid filesystem name '%s', ignoring.", fs); continue; } - log_unit_debug(u, "bpf-lsm: Restricting filesystem access to '%s'", fs); + log_debug("bpf-lsm: Restricting filesystem access to '%s'", fs); for (int i = 0; i < FILESYSTEM_MAGIC_MAX; i++) { if (magic[i] == 0) break; if (sym_bpf_map_update_elem(inner_map_fd, &magic[i], &dummy_value, BPF_ANY) != 0) { - r = log_unit_error_errno(u, errno, "bpf-lsm: Failed to update BPF map: %m"); + r = log_error_errno(errno, "bpf-lsm: Failed to update BPF map: %m"); - if (sym_bpf_map_delete_elem(outer_map_fd, &u->cgroup_id) != 0) - log_unit_debug_errno(u, errno, "bpf-lsm: Failed to delete cgroup entry from BPF map: %m"); + if (sym_bpf_map_delete_elem(outer_map_fd, &cgroup_id) != 0) + log_debug_errno(errno, "bpf-lsm: Failed to delete cgroup entry from BPF map: %m"); return r; } @@ -267,8 +255,8 @@ int lsm_bpf_setup(Manager *m) { return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "bpf-lsm: Failed to set up LSM BPF: %m"); } -int lsm_bpf_unit_restrict_filesystems(Unit *u, const Set *filesystems, int outer_map_fd, const bool allow_list) { - return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), "bpf-lsm: Failed to restrict filesystems using LSM BPF: %m"); +int lsm_bpf_restrict_filesystems(const Set *filesystems, uint64_t cgroup_id, int outer_map_fd, const bool allow_list) { + return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "bpf-lsm: Failed to restrict filesystems using LSM BPF: %m"); } int lsm_bpf_cleanup(const Unit *u) { diff --git a/src/core/bpf-lsm.h b/src/core/bpf-lsm.h index 5eb03ae7fb4..a6eda193fe0 100644 --- a/src/core/bpf-lsm.h +++ b/src/core/bpf-lsm.h @@ -16,7 +16,7 @@ typedef struct restrict_fs_bpf restrict_fs_bpf; bool lsm_bpf_supported(bool initialize); int lsm_bpf_setup(Manager *m); -int lsm_bpf_unit_restrict_filesystems(Unit *u, const Set *filesystems, int outer_map_fd, bool allow_list); +int lsm_bpf_restrict_filesystems(const Set *filesystems, uint64_t cgroup_id, int outer_map_fd, bool allow_list); int lsm_bpf_cleanup(const Unit *u); int lsm_bpf_map_restrict_fs_fd(Unit *u); void lsm_bpf_destroy(struct restrict_fs_bpf *prog); diff --git a/src/core/execute.c b/src/core/execute.c index e305e7b8be6..c13024b1f8d 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -353,7 +353,6 @@ static int connect_journal_socket( } static int connect_logger_as( - const Unit *unit, const ExecContext *context, const ExecParameters *params, ExecOutput output, @@ -393,7 +392,7 @@ static int connect_logger_as( "%i\n" "%i\n", context->syslog_identifier ?: ident, - params->flags & EXEC_PASS_LOG_UNIT ? unit->id : "", + params->flags & EXEC_PASS_LOG_UNIT ? params->unit_id : "", context->syslog_priority, !!context->syslog_level_prefix, false, @@ -619,7 +618,6 @@ static bool can_inherit_stderr_from_stdout( } static int setup_output( - const Unit *unit, const ExecContext *context, const ExecParameters *params, int fileno, @@ -635,7 +633,6 @@ static int setup_output( ExecInput i; int r; - assert(unit); assert(context); assert(params); assert(ident); @@ -714,9 +711,12 @@ static int setup_output( case EXEC_OUTPUT_KMSG_AND_CONSOLE: case EXEC_OUTPUT_JOURNAL: case EXEC_OUTPUT_JOURNAL_AND_CONSOLE: - r = connect_logger_as(unit, context, params, o, ident, fileno, uid, gid); + r = connect_logger_as(context, params, o, ident, fileno, uid, gid); if (r < 0) { - log_unit_warning_errno(unit, r, "Failed to connect %s to the journal socket, ignoring: %m", + log_exec_warning_errno(context, + params, + r, + "Failed to connect %s to the journal socket, ignoring: %m", fileno == STDOUT_FILENO ? "stdout" : "stderr"); r = open_null_as(O_WRONLY, fileno); } else { @@ -852,18 +852,19 @@ static int setup_confirm_stdio( return 0; } -static void write_confirm_error_fd(int err, int fd, const Unit *u) { +static void write_confirm_error_fd(int err, int fd, const char *unit_id) { assert(err < 0); + assert(unit_id); if (err == -ETIMEDOUT) - dprintf(fd, "Confirmation question timed out for %s, assuming positive response.\n", u->id); + dprintf(fd, "Confirmation question timed out for %s, assuming positive response.\n", unit_id); else { errno = -err; - dprintf(fd, "Couldn't ask confirmation for %s: %m, assuming positive response.\n", u->id); + dprintf(fd, "Couldn't ask confirmation for %s: %m, assuming positive response.\n", unit_id); } } -static void write_confirm_error(int err, const char *vc, const Unit *u) { +static void write_confirm_error(int err, const char *vc, const char *unit_id) { _cleanup_close_ int fd = -EBADF; assert(vc); @@ -872,7 +873,7 @@ static void write_confirm_error(int err, const char *vc, const Unit *u) { if (fd < 0) return; - write_confirm_error_fd(err, fd, u); + write_confirm_error_fd(err, fd, unit_id); } static int restore_confirm_stdio(int *saved_stdin, int *saved_stdout) { @@ -903,20 +904,27 @@ enum { CONFIRM_EXECUTE = 1, }; -static int ask_for_confirmation(const ExecContext *context, const char *vc, Unit *u, const char *cmdline) { +static bool confirm_spawn_disabled(void) { + return access("/run/systemd/confirm_spawn_disabled", F_OK) >= 0; +} + +static int ask_for_confirmation(const ExecContext *context, const ExecParameters *params, const char *cmdline) { int saved_stdout = -1, saved_stdin = -1, r; _cleanup_free_ char *e = NULL; char c; + assert(context); + assert(params); + /* For any internal errors, assume a positive response. */ - r = setup_confirm_stdio(context, vc, &saved_stdin, &saved_stdout); + r = setup_confirm_stdio(context, params->confirm_spawn, &saved_stdin, &saved_stdout); if (r < 0) { - write_confirm_error(r, vc, u); + write_confirm_error(r, params->confirm_spawn, params->unit_id); return CONFIRM_EXECUTE; } /* confirm_spawn might have been disabled while we were sleeping. */ - if (manager_is_confirm_spawn_disabled(u->manager)) { + if (!params->confirm_spawn || confirm_spawn_disabled()) { r = 1; goto restore_stdio; } @@ -931,7 +939,7 @@ static int ask_for_confirmation(const ExecContext *context, const char *vc, Unit for (;;) { r = ask_char(&c, "yfshiDjcn", "Execute %s? [y, f, s – h for help] ", e); if (r < 0) { - write_confirm_error_fd(r, STDOUT_FILENO, u); + write_confirm_error_fd(r, STDOUT_FILENO, params->unit_id); r = CONFIRM_EXECUTE; goto restore_stdio; } @@ -943,7 +951,10 @@ static int ask_for_confirmation(const ExecContext *context, const char *vc, Unit r = 1; break; case 'D': - unit_dump(u, stdout, " "); + printf(" Unit: %s\n", + params->unit_id); + exec_context_dump(context, stdout, " "); + exec_params_dump(params, stdout, " "); continue; /* ask again */ case 'f': printf("Failing execution.\n"); @@ -960,13 +971,16 @@ static int ask_for_confirmation(const ExecContext *context, const char *vc, Unit " y - yes, execute the command\n"); continue; /* ask again */ case 'i': - printf(" Description: %s\n" - " Unit: %s\n" + printf(" Unit: %s\n" " Command: %s\n", - u->id, u->description, cmdline); + params->unit_id, cmdline); continue; /* ask again */ case 'j': - manager_dump_jobs(u->manager, stdout, /* patterns= */ NULL, " "); + if (sigqueue(getppid(), + SIGRTMIN+18, + (const union sigval) { .sival_int = MANAGER_SIGNAL_COMMAND_DUMP_JOBS }) < 0) + return -errno; + continue; /* ask again */ case 'n': /* 'n' was removed in favor of 'f'. */ @@ -1505,26 +1519,26 @@ static bool context_has_no_new_privileges(const ExecContext *c) { #if HAVE_SECCOMP -static bool skip_seccomp_unavailable(const Unit* u, const char* msg) { +static bool skip_seccomp_unavailable(const ExecContext *c, const ExecParameters *p, const char* msg) { if (is_seccomp_available()) return false; - log_unit_debug(u, "SECCOMP features not detected in the kernel, skipping %s", msg); + log_exec_debug(c, p, "SECCOMP features not detected in the kernel, skipping %s", msg); return true; } -static int apply_syscall_filter(const Unit* u, const ExecContext *c, bool needs_ambient_hack) { +static int apply_syscall_filter(const ExecContext *c, const ExecParameters *p, bool needs_ambient_hack) { uint32_t negative_action, default_action, action; int r; - assert(u); assert(c); + assert(p); if (!context_has_syscall_filters(c)) return 0; - if (skip_seccomp_unavailable(u, "SystemCallFilter=")) + if (skip_seccomp_unavailable(c, p, "SystemCallFilter=")) return 0; negative_action = c->syscall_errno == SECCOMP_ERROR_NUMBER_KILL ? scmp_act_kill_process() : SCMP_ACT_ERRNO(c->syscall_errno); @@ -1546,19 +1560,19 @@ static int apply_syscall_filter(const Unit* u, const ExecContext *c, bool needs_ return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_filter, action, false); } -static int apply_syscall_log(const Unit* u, const ExecContext *c) { +static int apply_syscall_log(const ExecContext *c, const ExecParameters *p) { #ifdef SCMP_ACT_LOG uint32_t default_action, action; #endif - assert(u); assert(c); + assert(p); if (!context_has_syscall_logs(c)) return 0; #ifdef SCMP_ACT_LOG - if (skip_seccomp_unavailable(u, "SystemCallLog=")) + if (skip_seccomp_unavailable(c, p, "SystemCallLog=")) return 0; if (c->syscall_log_allow_list) { @@ -1574,42 +1588,42 @@ static int apply_syscall_log(const Unit* u, const ExecContext *c) { return seccomp_load_syscall_filter_set_raw(default_action, c->syscall_log, action, false); #else /* old libseccomp */ - log_unit_debug(u, "SECCOMP feature SCMP_ACT_LOG not available, skipping SystemCallLog="); + log_exec_debug(c, p, "SECCOMP feature SCMP_ACT_LOG not available, skipping SystemCallLog="); return 0; #endif } -static int apply_syscall_archs(const Unit *u, const ExecContext *c) { - assert(u); +static int apply_syscall_archs(const ExecContext *c, const ExecParameters *p) { assert(c); + assert(p); if (set_isempty(c->syscall_archs)) return 0; - if (skip_seccomp_unavailable(u, "SystemCallArchitectures=")) + if (skip_seccomp_unavailable(c, p, "SystemCallArchitectures=")) return 0; return seccomp_restrict_archs(c->syscall_archs); } -static int apply_address_families(const Unit* u, const ExecContext *c) { - assert(u); +static int apply_address_families(const ExecContext *c, const ExecParameters *p) { assert(c); + assert(p); if (!context_has_address_families(c)) return 0; - if (skip_seccomp_unavailable(u, "RestrictAddressFamilies=")) + if (skip_seccomp_unavailable(c, p, "RestrictAddressFamilies=")) return 0; return seccomp_restrict_address_families(c->address_families, c->address_families_allow_list); } -static int apply_memory_deny_write_execute(const Unit* u, const ExecContext *c) { +static int apply_memory_deny_write_execute(const ExecContext *c, const ExecParameters *p) { int r; - assert(u); assert(c); + assert(p); if (!c->memory_deny_write_execute) return 0; @@ -1617,49 +1631,52 @@ static int apply_memory_deny_write_execute(const Unit* u, const ExecContext *c) /* use prctl() if kernel supports it (6.3) */ r = prctl(PR_SET_MDWE, PR_MDWE_REFUSE_EXEC_GAIN, 0, 0, 0); if (r == 0) { - log_unit_debug(u, "Enabled MemoryDenyWriteExecute= with PR_SET_MDWE"); + log_exec_debug(c, p, "Enabled MemoryDenyWriteExecute= with PR_SET_MDWE"); return 0; } if (r < 0 && errno != EINVAL) - return log_unit_debug_errno(u, errno, "Failed to enable MemoryDenyWriteExecute= with PR_SET_MDWE: %m"); + return log_exec_debug_errno(c, + p, + errno, + "Failed to enable MemoryDenyWriteExecute= with PR_SET_MDWE: %m"); /* else use seccomp */ - log_unit_debug(u, "Kernel doesn't support PR_SET_MDWE: falling back to seccomp"); + log_exec_debug(c, p, "Kernel doesn't support PR_SET_MDWE: falling back to seccomp"); - if (skip_seccomp_unavailable(u, "MemoryDenyWriteExecute=")) + if (skip_seccomp_unavailable(c, p, "MemoryDenyWriteExecute=")) return 0; return seccomp_memory_deny_write_execute(); } -static int apply_restrict_realtime(const Unit* u, const ExecContext *c) { - assert(u); +static int apply_restrict_realtime(const ExecContext *c, const ExecParameters *p) { assert(c); + assert(p); if (!c->restrict_realtime) return 0; - if (skip_seccomp_unavailable(u, "RestrictRealtime=")) + if (skip_seccomp_unavailable(c, p, "RestrictRealtime=")) return 0; return seccomp_restrict_realtime(); } -static int apply_restrict_suid_sgid(const Unit* u, const ExecContext *c) { - assert(u); +static int apply_restrict_suid_sgid(const ExecContext *c, const ExecParameters *p) { assert(c); + assert(p); if (!c->restrict_suid_sgid) return 0; - if (skip_seccomp_unavailable(u, "RestrictSUIDSGID=")) + if (skip_seccomp_unavailable(c, p, "RestrictSUIDSGID=")) return 0; return seccomp_restrict_suid_sgid(); } -static int apply_protect_sysctl(const Unit *u, const ExecContext *c) { - assert(u); +static int apply_protect_sysctl(const ExecContext *c, const ExecParameters *p) { assert(c); + assert(p); /* Turn off the legacy sysctl() system call. Many distributions turn this off while building the kernel, but * let's protect even those systems where this is left on in the kernel. */ @@ -1667,92 +1684,92 @@ static int apply_protect_sysctl(const Unit *u, const ExecContext *c) { if (!c->protect_kernel_tunables) return 0; - if (skip_seccomp_unavailable(u, "ProtectKernelTunables=")) + if (skip_seccomp_unavailable(c, p, "ProtectKernelTunables=")) return 0; return seccomp_protect_sysctl(); } -static int apply_protect_kernel_modules(const Unit *u, const ExecContext *c) { - assert(u); +static int apply_protect_kernel_modules(const ExecContext *c, const ExecParameters *p) { assert(c); + assert(p); /* Turn off module syscalls on ProtectKernelModules=yes */ if (!c->protect_kernel_modules) return 0; - if (skip_seccomp_unavailable(u, "ProtectKernelModules=")) + if (skip_seccomp_unavailable(c, p, "ProtectKernelModules=")) return 0; return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_MODULE, SCMP_ACT_ERRNO(EPERM), false); } -static int apply_protect_kernel_logs(const Unit *u, const ExecContext *c) { - assert(u); +static int apply_protect_kernel_logs(const ExecContext *c, const ExecParameters *p) { assert(c); + assert(p); if (!c->protect_kernel_logs) return 0; - if (skip_seccomp_unavailable(u, "ProtectKernelLogs=")) + if (skip_seccomp_unavailable(c, p, "ProtectKernelLogs=")) return 0; return seccomp_protect_syslog(); } -static int apply_protect_clock(const Unit *u, const ExecContext *c) { - assert(u); +static int apply_protect_clock(const ExecContext *c, const ExecParameters *p) { assert(c); + assert(p); if (!c->protect_clock) return 0; - if (skip_seccomp_unavailable(u, "ProtectClock=")) + if (skip_seccomp_unavailable(c, p, "ProtectClock=")) return 0; return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_CLOCK, SCMP_ACT_ERRNO(EPERM), false); } -static int apply_private_devices(const Unit *u, const ExecContext *c) { - assert(u); +static int apply_private_devices(const ExecContext *c, const ExecParameters *p) { assert(c); + assert(p); /* If PrivateDevices= is set, also turn off iopl and all @raw-io syscalls. */ if (!c->private_devices) return 0; - if (skip_seccomp_unavailable(u, "PrivateDevices=")) + if (skip_seccomp_unavailable(c, p, "PrivateDevices=")) return 0; return seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO, SCMP_ACT_ERRNO(EPERM), false); } -static int apply_restrict_namespaces(const Unit *u, const ExecContext *c) { - assert(u); +static int apply_restrict_namespaces(const ExecContext *c, const ExecParameters *p) { assert(c); + assert(p); if (!exec_context_restrict_namespaces_set(c)) return 0; - if (skip_seccomp_unavailable(u, "RestrictNamespaces=")) + if (skip_seccomp_unavailable(c, p, "RestrictNamespaces=")) return 0; return seccomp_restrict_namespaces(c->restrict_namespaces); } -static int apply_lock_personality(const Unit* u, const ExecContext *c) { +static int apply_lock_personality(const ExecContext *c, const ExecParameters *p) { unsigned long personality; int r; - assert(u); assert(c); + assert(p); if (!c->lock_personality) return 0; - if (skip_seccomp_unavailable(u, "LockPersonality=")) + if (skip_seccomp_unavailable(c, p, "LockPersonality=")) return 0; personality = c->personality; @@ -1771,8 +1788,7 @@ static int apply_lock_personality(const Unit* u, const ExecContext *c) { #endif #if HAVE_LIBBPF -static int apply_restrict_filesystems(Unit *u, const ExecContext *c, const ExecParameters *p) { - assert(u); +static int apply_restrict_filesystems(const ExecContext *c, const ExecParameters *p) { assert(c); assert(p); @@ -1781,17 +1797,17 @@ static int apply_restrict_filesystems(Unit *u, const ExecContext *c, const ExecP if (p->bpf_outer_map_fd < 0) { /* LSM BPF is unsupported or lsm_bpf_setup failed */ - log_unit_debug(u, "LSM BPF not supported, skipping RestrictFileSystems="); + log_exec_debug(c, p, "LSM BPF not supported, skipping RestrictFileSystems="); return 0; } - return lsm_bpf_unit_restrict_filesystems(u, c->restrict_filesystems, p->bpf_outer_map_fd, c->restrict_filesystems_allow_list); + return lsm_bpf_restrict_filesystems(c->restrict_filesystems, p->cgroup_id, p->bpf_outer_map_fd, c->restrict_filesystems_allow_list); } #endif -static int apply_protect_hostname(const Unit *u, const ExecContext *c, int *ret_exit_status) { - assert(u); +static int apply_protect_hostname(const ExecContext *c, const ExecParameters *p, int *ret_exit_status) { assert(c); + assert(p); if (!c->protect_hostname) return 0; @@ -1800,24 +1816,33 @@ static int apply_protect_hostname(const Unit *u, const ExecContext *c, int *ret_ if (unshare(CLONE_NEWUTS) < 0) { if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) { *ret_exit_status = EXIT_NAMESPACE; - return log_unit_error_errno(u, errno, "Failed to set up UTS namespacing: %m"); + return log_exec_error_errno(c, + p, + errno, + "Failed to set up UTS namespacing: %m"); } - log_unit_warning(u, "ProtectHostname=yes is configured, but UTS namespace setup is prohibited (container manager?), ignoring namespace setup."); + log_exec_warning(c, + p, + "ProtectHostname=yes is configured, but UTS namespace setup is " + "prohibited (container manager?), ignoring namespace setup."); } } else - log_unit_warning(u, "ProtectHostname=yes is configured, but the kernel does not support UTS namespaces, ignoring namespace setup."); + log_exec_warning(c, + p, + "ProtectHostname=yes is configured, but the kernel does not " + "support UTS namespaces, ignoring namespace setup."); #if HAVE_SECCOMP int r; - if (skip_seccomp_unavailable(u, "ProtectHostname=")) + if (skip_seccomp_unavailable(c, p, "ProtectHostname=")) return 0; r = seccomp_protect_hostname(); if (r < 0) { *ret_exit_status = EXIT_SECCOMP; - return log_unit_error_errno(u, r, "Failed to apply hostname restrictions: %m"); + return log_exec_error_errno(c, p, r, "Failed to apply hostname restrictions: %m"); } #endif @@ -1855,7 +1880,6 @@ static void do_idle_pipe_dance(int idle_pipe[static 4]) { static const char *exec_directory_env_name_to_string(ExecDirectoryType t); static int build_environment( - const Unit *u, const ExecContext *c, const ExecParameters *p, const CGroupContext *cgroup_context, @@ -1874,7 +1898,6 @@ static int build_environment( char *x; int r; - assert(u); assert(c); assert(p); assert(ret); @@ -1932,7 +1955,10 @@ static int build_environment( if (!c->user && !c->dynamic_user && p->runtime_scope == RUNTIME_SCOPE_SYSTEM) { r = get_fixed_user("root", &username, NULL, NULL, &home, &shell); if (r < 0) - return log_unit_error_errno(u, r, "Failed to determine user credentials for root: %m"); + return log_exec_debug_errno(c, + p, + r, + "Failed to determine user credentials for root: %m"); } bool set_user_login_env = c->set_login_environment >= 0 ? c->set_login_environment : (c->user || c->dynamic_user); @@ -1969,8 +1995,11 @@ static int build_environment( our_env[n_env++] = x; } - if (!sd_id128_is_null(u->invocation_id)) { - if (asprintf(&x, "INVOCATION_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(u->invocation_id)) < 0) + if (!sd_id128_is_null(p->invocation_id)) { + assert(p->invocation_id_string); + + x = strjoin("INVOCATION_ID=", p->invocation_id_string); + if (!x) return -ENOMEM; our_env[n_env++] = x; @@ -1997,7 +2026,11 @@ static int build_environment( r = proc_cmdline_get_key(key, 0, &cmdline); if (r < 0) - log_debug_errno(r, "Failed to read %s from kernel cmdline, ignoring: %m", key); + log_exec_debug_errno(c, + p, + r, + "Failed to read %s from kernel cmdline, ignoring: %m", + key); else if (r > 0) term = cmdline; } @@ -2059,7 +2092,7 @@ static int build_environment( } _cleanup_free_ char *creds_dir = NULL; - r = exec_context_get_credential_directory(c, p, u->id, &creds_dir); + r = exec_context_get_credential_directory(c, p, p->unit_id, &creds_dir); if (r < 0) return r; if (r > 0) { @@ -2435,7 +2468,6 @@ static int create_many_symlinks(const char *root, const char *source, char **sym } static int setup_exec_directory( - Unit *u, const ExecContext *context, const ExecParameters *params, uid_t uid, @@ -2527,13 +2559,13 @@ static int setup_exec_directory( if (r < 0) goto fail; - log_unit_notice(u, "Unit state directory %s missing but matching configuration directory %s exists, assuming update from systemd 253 or older, creating compatibility symlink.", p, q); + log_exec_notice(context, params, "Unit state directory %s missing but matching configuration directory %s exists, assuming update from systemd 253 or older, creating compatibility symlink.", p, q); continue; } else if (r != -ENOENT) - log_unit_warning_errno(u, r, "Unable to detect whether unit configuration directory '%s' exists, assuming not: %m", q); + log_exec_warning_errno(context, params, r, "Unable to detect whether unit configuration directory '%s' exists, assuming not: %m", q); } else if (r < 0) - log_unit_warning_errno(u, r, "Unable to detect whether unit state directory '%s' is missing, assuming it is: %m", p); + log_exec_warning_errno(context, params, r, "Unable to detect whether unit state directory '%s' is missing, assuming it is: %m", p); } if (exec_directory_is_private(context, type)) { @@ -2590,7 +2622,9 @@ static int setup_exec_directory( * it over. Most likely the service has been upgraded from one that didn't use * DynamicUser=1, to one that does. */ - log_unit_info(u, "Found pre-existing public %s= directory %s, migrating to %s.\n" + log_exec_info(context, + params, + "Found pre-existing public %s= directory %s, migrating to %s.\n" "Apparently, service previously had DynamicUser= turned off, and has now turned it on.", exec_directory_type_to_string(type), p, pp); @@ -2658,7 +2692,9 @@ static int setup_exec_directory( /* Hmm, apparently DynamicUser= was once turned on for this service, * but is no longer. Let's move the directory back up. */ - log_unit_info(u, "Found pre-existing private %s= directory %s, migrating to %s.\n" + log_exec_info(context, + params, + "Found pre-existing private %s= directory %s, migrating to %s.\n" "Apparently, service previously had DynamicUser= turned on, and has now turned it off.", exec_directory_type_to_string(type), q, p); @@ -2690,7 +2726,9 @@ static int setup_exec_directory( /* Still complain if the access mode doesn't match */ if (((st.st_mode ^ context->directories[type].mode) & 07777) != 0) - log_unit_warning(u, "%s \'%s\' already exists but the mode is different. " + log_exec_warning(context, + params, + "%s \'%s\' already exists but the mode is different. " "(File system: %o %sMode: %o)", exec_directory_type_to_string(type), context->directories[type].items[i].path, st.st_mode & 07777, exec_directory_type_to_string(type), context->directories[type].mode & 07777); @@ -3125,7 +3163,6 @@ static int verity_settings_prepare( } static int apply_mount_namespace( - const Unit *u, ExecCommandFlags command_flags, const ExecContext *context, const ExecParameters *params, @@ -3205,16 +3242,18 @@ static int apply_mount_namespace( return r; if (context->mount_propagation_flag == MS_SHARED) - log_unit_debug(u, "shared mount propagation hidden by other fs namespacing unit settings: ignoring"); + log_exec_debug(context, + params, + "shared mount propagation hidden by other fs namespacing unit settings: ignoring"); if (FLAGS_SET(params->flags, EXEC_WRITE_CREDENTIALS)) { - r = exec_context_get_credential_directory(context, params, u->id, &creds_path); + r = exec_context_get_credential_directory(context, params, params->unit_id, &creds_path); if (r < 0) return r; } if (params->runtime_scope == RUNTIME_SCOPE_SYSTEM) { - propagate_dir = path_join("/run/systemd/propagate/", u->id); + propagate_dir = path_join("/run/systemd/propagate/", params->unit_id); if (!propagate_dir) return -ENOMEM; @@ -3343,7 +3382,8 @@ static int apply_mount_namespace( root_dir, root_image, bind_mounts, n_bind_mounts)) - return log_unit_debug_errno(u, + return log_exec_debug_errno(context, + params, SYNTHETIC_ERRNO(EOPNOTSUPP), "Failed to set up namespace, and refusing to continue since " "the selected namespacing options alter mount environment non-trivially.\n" @@ -3354,7 +3394,7 @@ static int apply_mount_namespace( yes_no(root_image), yes_no(context->dynamic_user)); - log_unit_debug(u, "Failed to set up namespace, assuming containerized execution and ignoring."); + log_exec_debug(context, params, "Failed to set up namespace, assuming containerized execution and ignoring."); return 0; } @@ -3419,7 +3459,6 @@ static int apply_root_directory( } static int setup_keyring( - const Unit *u, const ExecContext *context, const ExecParameters *p, uid_t uid, gid_t gid) { @@ -3429,7 +3468,6 @@ static int setup_keyring( uid_t saved_uid; gid_t saved_gid; - assert(u); assert(context); assert(p); @@ -3453,12 +3491,18 @@ static int setup_keyring( if (gid_is_valid(gid) && gid != saved_gid) { if (setregid(gid, -1) < 0) - return log_unit_error_errno(u, errno, "Failed to change GID for user keyring: %m"); + return log_exec_error_errno(context, + p, + errno, + "Failed to change GID for user keyring: %m"); } if (uid_is_valid(uid) && uid != saved_uid) { if (setreuid(uid, -1) < 0) { - r = log_unit_error_errno(u, errno, "Failed to change UID for user keyring: %m"); + r = log_exec_error_errno(context, + p, + errno, + "Failed to change UID for user keyring: %m"); goto out; } } @@ -3466,13 +3510,25 @@ static int setup_keyring( keyring = keyctl(KEYCTL_JOIN_SESSION_KEYRING, 0, 0, 0, 0); if (keyring == -1) { if (errno == ENOSYS) - log_unit_debug_errno(u, errno, "Kernel keyring not supported, ignoring."); + log_exec_debug_errno(context, + p, + errno, + "Kernel keyring not supported, ignoring."); else if (ERRNO_IS_PRIVILEGE(errno)) - log_unit_debug_errno(u, errno, "Kernel keyring access prohibited, ignoring."); + log_exec_debug_errno(context, + p, + errno, + "Kernel keyring access prohibited, ignoring."); else if (errno == EDQUOT) - log_unit_debug_errno(u, errno, "Out of kernel keyrings to allocate, ignoring."); + log_exec_debug_errno(context, + p, + errno, + "Out of kernel keyrings to allocate, ignoring."); else - r = log_unit_error_errno(u, errno, "Setting up kernel keyring failed: %m"); + r = log_exec_error_errno(context, + p, + errno, + "Setting up kernel keyring failed: %m"); goto out; } @@ -3483,7 +3539,10 @@ static int setup_keyring( if (keyctl(KEYCTL_LINK, KEY_SPEC_USER_KEYRING, KEY_SPEC_SESSION_KEYRING, 0, 0) < 0) { - r = log_unit_error_errno(u, errno, "Failed to link user keyring into session keyring: %m"); + r = log_exec_error_errno(context, + p, + errno, + "Failed to link user keyring into session keyring: %m"); goto out; } } @@ -3491,28 +3550,44 @@ static int setup_keyring( /* Restore uid/gid back */ if (uid_is_valid(uid) && uid != saved_uid) { if (setreuid(saved_uid, -1) < 0) { - r = log_unit_error_errno(u, errno, "Failed to change UID back for user keyring: %m"); + r = log_exec_error_errno(context, + p, + errno, + "Failed to change UID back for user keyring: %m"); goto out; } } if (gid_is_valid(gid) && gid != saved_gid) { if (setregid(saved_gid, -1) < 0) - return log_unit_error_errno(u, errno, "Failed to change GID back for user keyring: %m"); + return log_exec_error_errno(context, + p, + errno, + "Failed to change GID back for user keyring: %m"); } /* Populate they keyring with the invocation ID by default, as original saved_uid. */ - if (!sd_id128_is_null(u->invocation_id)) { + if (!sd_id128_is_null(p->invocation_id)) { key_serial_t key; - key = add_key("user", "invocation_id", &u->invocation_id, sizeof(u->invocation_id), KEY_SPEC_SESSION_KEYRING); + key = add_key("user", + "invocation_id", + &p->invocation_id, + sizeof(p->invocation_id), + KEY_SPEC_SESSION_KEYRING); if (key == -1) - log_unit_debug_errno(u, errno, "Failed to add invocation ID to keyring, ignoring: %m"); + log_exec_debug_errno(context, + p, + errno, + "Failed to add invocation ID to keyring, ignoring: %m"); else { if (keyctl(KEYCTL_SETPERM, key, KEY_POS_VIEW|KEY_POS_READ|KEY_POS_SEARCH| KEY_USR_VIEW|KEY_USR_READ|KEY_USR_SEARCH, 0, 0) < 0) - r = log_unit_error_errno(u, errno, "Failed to restrict invocation ID permission: %m"); + r = log_exec_error_errno(context, + p, + errno, + "Failed to restrict invocation ID permission: %m"); } } @@ -3586,12 +3661,12 @@ static int close_remaining_fds( } static int send_user_lookup( - Unit *unit, + const char *unit_id, int user_lookup_fd, uid_t uid, gid_t gid) { - assert(unit); + assert(unit_id); /* Send the resolved UID/GID to PID 1 after we learnt it. We send a single datagram, containing the UID/GID * data as well as the unit name. Note that we suppress sending this if no user/group to resolve was @@ -3607,7 +3682,7 @@ static int send_user_lookup( (struct iovec[]) { IOVEC_MAKE(&uid, sizeof(uid)), IOVEC_MAKE(&gid, sizeof(gid)), - IOVEC_MAKE_STRING(unit->id) }, 3) < 0) + IOVEC_MAKE_STRING(unit_id) }, 3) < 0) return -errno; return 0; @@ -3775,7 +3850,7 @@ static int add_shifted_fd(int *fds, size_t fds_size, size_t *n_fds, int fd, int return 1; } -static int connect_unix_harder(Unit *u, const OpenFile *of, int ofd) { +static int connect_unix_harder(const ExecContext *c, const ExecParameters *p, const OpenFile *of, int ofd) { union sockaddr_union addr = { .un.sun_family = AF_UNIX, }; @@ -3783,13 +3858,14 @@ static int connect_unix_harder(Unit *u, const OpenFile *of, int ofd) { static const int socket_types[] = { SOCK_DGRAM, SOCK_STREAM, SOCK_SEQPACKET }; int r; - assert(u); + assert(c); + assert(p); assert(of); assert(ofd >= 0); r = sockaddr_un_set_path(&addr.un, FORMAT_PROC_FD_PATH(ofd)); if (r < 0) - return log_unit_error_errno(u, r, "Failed to set sockaddr for %s: %m", of->path); + return log_exec_error_errno(c, p, r, "Failed to set sockaddr for %s: %m", of->path); sa_len = r; @@ -3798,44 +3874,56 @@ static int connect_unix_harder(Unit *u, const OpenFile *of, int ofd) { fd = socket(AF_UNIX, socket_types[i] | SOCK_CLOEXEC, 0); if (fd < 0) - return log_unit_error_errno(u, errno, "Failed to create socket for %s: %m", of->path); + return log_exec_error_errno(c, + p, + errno, + "Failed to create socket for %s: %m", + of->path); r = RET_NERRNO(connect(fd, &addr.sa, sa_len)); if (r == -EPROTOTYPE) continue; if (r < 0) - return log_unit_error_errno(u, r, "Failed to connect socket for %s: %m", of->path); + return log_exec_error_errno(c, + p, + r, + "Failed to connect socket for %s: %m", + of->path); return TAKE_FD(fd); } - return log_unit_error_errno(u, SYNTHETIC_ERRNO(EPROTOTYPE), "Failed to connect socket for \"%s\".", of->path); + return log_exec_error_errno(c, + p, + SYNTHETIC_ERRNO(EPROTOTYPE), "Failed to connect socket for \"%s\".", + of->path); } -static int get_open_file_fd(Unit *u, const OpenFile *of) { +static int get_open_file_fd(const ExecContext *c, const ExecParameters *p, const OpenFile *of) { struct stat st; _cleanup_close_ int fd = -EBADF, ofd = -EBADF; - assert(u); + assert(c); + assert(p); assert(of); ofd = open(of->path, O_PATH | O_CLOEXEC); if (ofd < 0) - return log_unit_error_errno(u, errno, "Could not open \"%s\": %m", of->path); + return log_exec_error_errno(c, p, errno, "Could not open \"%s\": %m", of->path); if (fstat(ofd, &st) < 0) - return log_unit_error_errno(u, errno, "Failed to stat %s: %m", of->path); + return log_exec_error_errno(c, p, errno, "Failed to stat %s: %m", of->path); if (S_ISSOCK(st.st_mode)) { - fd = connect_unix_harder(u, of, ofd); + fd = connect_unix_harder(c, p, of, ofd); if (fd < 0) return fd; if (FLAGS_SET(of->flags, OPENFILE_READ_ONLY) && shutdown(fd, SHUT_WR) < 0) - return log_unit_error_errno(u, errno, "Failed to shutdown send for socket %s: %m", + return log_exec_error_errno(c, p, errno, "Failed to shutdown send for socket %s: %m", of->path); - log_unit_debug(u, "socket %s opened (fd=%d)", of->path, fd); + log_exec_debug(c, p, "socket %s opened (fd=%d)", of->path, fd); } else { int flags = FLAGS_SET(of->flags, OPENFILE_READ_ONLY) ? O_RDONLY : O_RDWR; if (FLAGS_SET(of->flags, OPENFILE_APPEND)) @@ -3845,34 +3933,35 @@ static int get_open_file_fd(Unit *u, const OpenFile *of) { fd = fd_reopen(ofd, flags | O_CLOEXEC); if (fd < 0) - return log_unit_error_errno(u, fd, "Failed to open file %s: %m", of->path); + return log_exec_error_errno(c, p, fd, "Failed to open file %s: %m", of->path); - log_unit_debug(u, "file %s opened (fd=%d)", of->path, fd); + log_exec_debug(c, p, "file %s opened (fd=%d)", of->path, fd); } return TAKE_FD(fd); } static int collect_open_file_fds( - Unit *u, - OpenFile* open_files, + const ExecContext *c, + const ExecParameters *p, int **fds, char ***fdnames, size_t *n_fds) { int r; - assert(u); + assert(c); + assert(p); assert(fds); assert(fdnames); assert(n_fds); - LIST_FOREACH(open_files, of, open_files) { + LIST_FOREACH(open_files, of, p->open_files) { _cleanup_close_ int fd = -EBADF; - fd = get_open_file_fd(u, of); + fd = get_open_file_fd(c, p, of); if (fd < 0) { if (FLAGS_SET(of->flags, OPENFILE_GRACEFUL)) { - log_unit_debug_errno(u, fd, "Failed to get OpenFile= file descriptor for %s, ignoring: %m", of->path); + log_exec_debug_errno(c, p, fd, "Failed to get OpenFile= file descriptor for %s, ignoring: %m", of->path); continue; } @@ -3894,8 +3983,15 @@ static int collect_open_file_fds( return 0; } -static void log_command_line(Unit *unit, const char *msg, const char *executable, char **argv) { - assert(unit); +static void log_command_line( + const ExecContext *context, + const ExecParameters *params, + const char *msg, + const char *executable, + char **argv) { + + assert(context); + assert(params); assert(msg); assert(executable); @@ -3904,10 +4000,10 @@ static void log_command_line(Unit *unit, const char *msg, const char *executable _cleanup_free_ char *cmdline = quote_command_line(argv, SHELL_ESCAPE_EMPTY); - log_unit_struct(unit, LOG_DEBUG, + log_exec_struct(context, params, LOG_DEBUG, "EXECUTABLE=%s", executable, - LOG_UNIT_MESSAGE(unit, "%s: %s", msg, strnull(cmdline)), - LOG_UNIT_INVOCATION_ID(unit)); + LOG_EXEC_MESSAGE(params, "%s: %s", msg, strnull(cmdline)), + LOG_EXEC_INVOCATION_ID(params)); } static bool exec_context_need_unprivileged_private_users( @@ -3951,11 +4047,22 @@ static bool exec_context_need_unprivileged_private_users( !strv_isempty(context->no_exec_paths); } +static bool exec_context_shall_confirm_spawn(const ExecContext *context) { + assert(context); + + if (confirm_spawn_disabled()) + return false; + + /* For some reasons units remaining in the same process group + * as PID 1 fail to acquire the console even if it's not used + * by any process. So skip the confirmation question for them. */ + return !context->same_pgrp; +} + static int exec_context_load_environment(const Unit *unit, const ExecContext *c, char ***l); static int exec_context_named_iofds(const ExecContext *c, const ExecParameters *p, int named_iofds[static 3]); static int exec_child( - Unit *unit, const ExecCommand *command, const ExecContext *context, ExecParameters *params, @@ -4001,7 +4108,6 @@ static int exec_child( int socket_fd = -EBADF, named_iofds[3] = { -EBADF, -EBADF, -EBADF }, *params_fds = NULL; size_t n_storage_fds = 0, n_socket_fds = 0; - assert(unit); assert(command); assert(context); assert(params); @@ -4016,10 +4122,10 @@ static int exec_child( context->std_error == EXEC_OUTPUT_SOCKET) { if (params->n_socket_fds > 1) - return log_unit_error_errno(unit, SYNTHETIC_ERRNO(EINVAL), "Got more than one socket."); + return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(EINVAL), "Got more than one socket."); if (params->n_socket_fds == 0) - return log_unit_error_errno(unit, SYNTHETIC_ERRNO(EINVAL), "Got no socket."); + return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(EINVAL), "Got no socket."); socket_fd = params->fds[0]; } else { @@ -4031,7 +4137,7 @@ static int exec_child( r = exec_context_named_iofds(context, params, named_iofds); if (r < 0) - return log_unit_error_errno(unit, r, "Failed to load a named file descriptor: %m"); + return log_exec_error_errno(context, params, r, "Failed to load a named file descriptor: %m"); rename_process_from_path(command->path); @@ -4047,7 +4153,7 @@ static int exec_child( r = reset_signal_mask(); if (r < 0) { *exit_status = EXIT_SIGNAL_MASK; - return log_unit_error_errno(unit, r, "Failed to set process signal mask: %m"); + return log_exec_error_errno(context, params, r, "Failed to set process signal mask: %m"); } if (params->idle_pipe) @@ -4079,10 +4185,10 @@ static int exec_child( return log_oom(); } - r = collect_open_file_fds(unit, params->open_files, &fds, &fdnames, &n_fds); + r = collect_open_file_fds(context, params, &fds, &fdnames, &n_fds); if (r < 0) { *exit_status = EXIT_FDS; - return log_unit_error_errno(unit, r, "Failed to get OpenFile= file descriptors: %m"); + return log_exec_error_errno(context, params, r, "Failed to get OpenFile= file descriptors: %m"); } int keep_fds[n_fds + 3]; @@ -4092,7 +4198,7 @@ static int exec_child( r = add_shifted_fd(keep_fds, ELEMENTSOF(keep_fds), &n_keep_fds, params->exec_fd, &exec_fd); if (r < 0) { *exit_status = EXIT_FDS; - return log_unit_error_errno(unit, r, "Failed to shift fd and set FD_CLOEXEC: %m"); + return log_exec_error_errno(context, params, r, "Failed to shift fd and set FD_CLOEXEC: %m"); } #if HAVE_LIBBPF @@ -4100,7 +4206,7 @@ static int exec_child( r = add_shifted_fd(keep_fds, ELEMENTSOF(keep_fds), &n_keep_fds, params->bpf_outer_map_fd, (int *)¶ms->bpf_outer_map_fd); if (r < 0) { *exit_status = EXIT_FDS; - return log_unit_error_errno(unit, r, "Failed to shift fd and set FD_CLOEXEC: %m"); + return log_exec_error_errno(context, params, r, "Failed to shift fd and set FD_CLOEXEC: %m"); } } #endif @@ -4108,18 +4214,18 @@ static int exec_child( r = close_remaining_fds(params, runtime, socket_fd, keep_fds, n_keep_fds); if (r < 0) { *exit_status = EXIT_FDS; - return log_unit_error_errno(unit, r, "Failed to close unwanted file descriptors: %m"); + return log_exec_error_errno(context, params, r, "Failed to close unwanted file descriptors: %m"); } if (!context->same_pgrp && setsid() < 0) { *exit_status = EXIT_SETSID; - return log_unit_error_errno(unit, errno, "Failed to create new process session: %m"); + return log_exec_error_errno(context, params, errno, "Failed to create new process session: %m"); } exec_context_tty_reset(context, params); - if (params->shall_confirm_spawn && unit_shall_confirm_spawn(unit)) { + if (params->shall_confirm_spawn && exec_context_shall_confirm_spawn(context)) { _cleanup_free_ char *cmdline = NULL; cmdline = quote_command_line(command->argv, SHELL_ESCAPE_EMPTY); @@ -4128,7 +4234,7 @@ static int exec_child( return log_oom(); } - r = ask_for_confirmation(context, params->confirm_spawn, unit, cmdline); + r = ask_for_confirmation(context, params, cmdline); if (r != CONFIRM_EXECUTE) { if (r == CONFIRM_PRETEND_SUCCESS) { *exit_status = EXIT_SUCCESS; @@ -4136,7 +4242,7 @@ static int exec_child( } *exit_status = EXIT_CONFIRM; - return log_unit_error_errno(unit, SYNTHETIC_ERRNO(ECANCELED), + return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(ECANCELED), "Execution cancelled by the user"); } } @@ -4146,10 +4252,10 @@ static int exec_child( * that these env vars do not survive the execve(), which means they really only apply to the PAM and NSS * invocations themselves. Also note that while we'll only invoke NSS modules involved in user management they * might internally call into other NSS modules that are involved in hostname resolution, we never know. */ - if (setenv("SYSTEMD_ACTIVATION_UNIT", unit->id, true) != 0 || + if (setenv("SYSTEMD_ACTIVATION_UNIT", params->unit_id, true) != 0 || setenv("SYSTEMD_ACTIVATION_SCOPE", runtime_scope_to_string(params->runtime_scope), true) != 0) { *exit_status = EXIT_MEMORY; - return log_unit_error_errno(unit, errno, "Failed to update environment: %m"); + return log_exec_error_errno(context, params, errno, "Failed to update environment: %m"); } if (context->dynamic_user && runtime && runtime->dynamic_creds) { @@ -4159,7 +4265,7 @@ static int exec_child( * checks, if DynamicUser=1 is used, as we shouldn't create a feedback loop with ourselves here. */ if (putenv((char*) "SYSTEMD_NSS_DYNAMIC_BYPASS=1") != 0) { *exit_status = EXIT_USER; - return log_unit_error_errno(unit, errno, "Failed to update environment: %m"); + return log_exec_error_errno(context, params, errno, "Failed to update environment: %m"); } r = compile_suggested_paths(context, params, &suggested_paths); @@ -4172,19 +4278,19 @@ static int exec_child( if (r < 0) { *exit_status = EXIT_USER; if (r == -EILSEQ) - return log_unit_error_errno(unit, SYNTHETIC_ERRNO(EOPNOTSUPP), + return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(EOPNOTSUPP), "Failed to update dynamic user credentials: User or group with specified name already exists."); - return log_unit_error_errno(unit, r, "Failed to update dynamic user credentials: %m"); + return log_exec_error_errno(context, params, r, "Failed to update dynamic user credentials: %m"); } if (!uid_is_valid(uid)) { *exit_status = EXIT_USER; - return log_unit_error_errno(unit, SYNTHETIC_ERRNO(ESRCH), "UID validation failed for \""UID_FMT"\"", uid); + return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(ESRCH), "UID validation failed for \""UID_FMT"\"", uid); } if (!gid_is_valid(gid)) { *exit_status = EXIT_USER; - return log_unit_error_errno(unit, SYNTHETIC_ERRNO(ESRCH), "GID validation failed for \""GID_FMT"\"", gid); + return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(ESRCH), "GID validation failed for \""GID_FMT"\"", gid); } if (runtime->dynamic_creds->user) @@ -4195,7 +4301,7 @@ static int exec_child( r = get_fixed_user(context->user, &username, &uid, &gid, &home, &shell); if (r < 0) { *exit_status = EXIT_USER; - return log_unit_error_errno(unit, r, "Failed to determine user credentials: %m"); + return log_exec_error_errno(context, params, r, "Failed to determine user credentials: %m"); } } @@ -4203,7 +4309,7 @@ static int exec_child( r = get_fixed_group(context->group, &groupname, &gid); if (r < 0) { *exit_status = EXIT_GROUP; - return log_unit_error_errno(unit, r, "Failed to determine group credentials: %m"); + return log_exec_error_errno(context, params, r, "Failed to determine group credentials: %m"); } } } @@ -4213,13 +4319,13 @@ static int exec_child( &supplementary_gids, &ngids); if (r < 0) { *exit_status = EXIT_GROUP; - return log_unit_error_errno(unit, r, "Failed to determine supplementary groups: %m"); + return log_exec_error_errno(context, params, r, "Failed to determine supplementary groups: %m"); } - r = send_user_lookup(unit, params->user_lookup_fd, uid, gid); + r = send_user_lookup(params->unit_id, params->user_lookup_fd, uid, gid); if (r < 0) { *exit_status = EXIT_USER; - return log_unit_error_errno(unit, r, "Failed to send user credentials to PID1: %m"); + return log_exec_error_errno(context, params, r, "Failed to send user credentials to PID1: %m"); } params->user_lookup_fd = safe_close(params->user_lookup_fd); @@ -4227,7 +4333,7 @@ static int exec_child( r = acquire_home(context, uid, &home, &home_buffer); if (r < 0) { *exit_status = EXIT_CHDIR; - return log_unit_error_errno(unit, r, "Failed to determine $HOME for user: %m"); + return log_exec_error_errno(context, params, r, "Failed to determine $HOME for user: %m"); } /* If a socket is connected to STDIN/STDOUT/STDERR, we must drop O_NONBLOCK */ @@ -4242,19 +4348,19 @@ static int exec_child( r = exec_parameters_get_cgroup_path(params, cgroup_context, &p); if (r < 0) { *exit_status = EXIT_CGROUP; - return log_unit_error_errno(unit, r, "Failed to acquire cgroup path: %m"); + return log_exec_error_errno(context, params, r, "Failed to acquire cgroup path: %m"); } r = cg_attach_everywhere(params->cgroup_supported, p, 0, NULL, NULL); if (r == -EUCLEAN) { *exit_status = EXIT_CGROUP; - return log_unit_error_errno(unit, r, "Failed to attach process to cgroup %s " + return log_exec_error_errno(context, params, r, "Failed to attach process to cgroup %s " "because the cgroup or one of its parents or " "siblings is in the threaded mode: %m", p); } if (r < 0) { *exit_status = EXIT_CGROUP; - return log_unit_error_errno(unit, r, "Failed to attach to cgroup %s: %m", p); + return log_exec_error_errno(context, params, r, "Failed to attach to cgroup %s: %m", p); } } @@ -4262,7 +4368,7 @@ static int exec_child( r = open_shareable_ns_path(runtime->shared->netns_storage_socket, context->network_namespace_path, CLONE_NEWNET); if (r < 0) { *exit_status = EXIT_NETWORK; - return log_unit_error_errno(unit, r, "Failed to open network namespace path %s: %m", context->network_namespace_path); + return log_exec_error_errno(context, params, r, "Failed to open network namespace path %s: %m", context->network_namespace_path); } } @@ -4270,26 +4376,26 @@ static int exec_child( r = open_shareable_ns_path(runtime->shared->ipcns_storage_socket, context->ipc_namespace_path, CLONE_NEWIPC); if (r < 0) { *exit_status = EXIT_NAMESPACE; - return log_unit_error_errno(unit, r, "Failed to open IPC namespace path %s: %m", context->ipc_namespace_path); + return log_exec_error_errno(context, params, r, "Failed to open IPC namespace path %s: %m", context->ipc_namespace_path); } } r = setup_input(context, params, socket_fd, named_iofds); if (r < 0) { *exit_status = EXIT_STDIN; - return log_unit_error_errno(unit, r, "Failed to set up standard input: %m"); + return log_exec_error_errno(context, params, r, "Failed to set up standard input: %m"); } - r = setup_output(unit, context, params, STDOUT_FILENO, socket_fd, named_iofds, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino); + r = setup_output(context, params, STDOUT_FILENO, socket_fd, named_iofds, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino); if (r < 0) { *exit_status = EXIT_STDOUT; - return log_unit_error_errno(unit, r, "Failed to set up standard output: %m"); + return log_exec_error_errno(context, params, r, "Failed to set up standard output: %m"); } - r = setup_output(unit, context, params, STDERR_FILENO, socket_fd, named_iofds, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino); + r = setup_output(context, params, STDERR_FILENO, socket_fd, named_iofds, basename(command->path), uid, gid, &journal_stream_dev, &journal_stream_ino); if (r < 0) { *exit_status = EXIT_STDERR; - return log_unit_error_errno(unit, r, "Failed to set up standard error output: %m"); + return log_exec_error_errno(context, params, r, "Failed to set up standard error output: %m"); } if (context->oom_score_adjust_set) { @@ -4297,21 +4403,21 @@ static int exec_child( * namespaces prohibit write access to this file, and we shouldn't trip up over that. */ r = set_oom_score_adjust(context->oom_score_adjust); if (ERRNO_IS_NEG_PRIVILEGE(r)) - log_unit_debug_errno(unit, r, + log_exec_debug_errno(context, params, r, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m"); else if (r < 0) { *exit_status = EXIT_OOM_ADJUST; - return log_unit_error_errno(unit, r, "Failed to adjust OOM setting: %m"); + return log_exec_error_errno(context, params, r, "Failed to adjust OOM setting: %m"); } } if (context->coredump_filter_set) { r = set_coredump_filter(context->coredump_filter); if (ERRNO_IS_NEG_PRIVILEGE(r)) - log_unit_debug_errno(unit, r, "Failed to adjust coredump_filter, ignoring: %m"); + log_exec_debug_errno(context, params, r, "Failed to adjust coredump_filter, ignoring: %m"); else if (r < 0) { *exit_status = EXIT_LIMITS; - return log_unit_error_errno(unit, r, "Failed to adjust coredump_filter: %m"); + return log_exec_error_errno(context, params, r, "Failed to adjust coredump_filter: %m"); } } @@ -4319,7 +4425,7 @@ static int exec_child( r = setpriority_closest(context->nice); if (r < 0) { *exit_status = EXIT_NICE; - return log_unit_error_errno(unit, r, "Failed to set up process scheduling priority (nice level): %m"); + return log_exec_error_errno(context, params, r, "Failed to set up process scheduling priority (nice level): %m"); } } @@ -4335,7 +4441,7 @@ static int exec_child( ¶m); if (r < 0) { *exit_status = EXIT_SETSCHEDULER; - return log_unit_error_errno(unit, errno, "Failed to set up CPU scheduling: %m"); + return log_exec_error_errno(context, params, errno, "Failed to set up CPU scheduling: %m"); } } @@ -4347,7 +4453,7 @@ static int exec_child( r = exec_context_cpu_affinity_from_numa(context, &converted_cpu_set); if (r < 0) { *exit_status = EXIT_CPUAFFINITY; - return log_unit_error_errno(unit, r, "Failed to derive CPU affinity mask from NUMA mask: %m"); + return log_exec_error_errno(context, params, r, "Failed to derive CPU affinity mask from NUMA mask: %m"); } cpu_set = &converted_cpu_set; @@ -4356,37 +4462,37 @@ static int exec_child( if (sched_setaffinity(0, cpu_set->allocated, cpu_set->set) < 0) { *exit_status = EXIT_CPUAFFINITY; - return log_unit_error_errno(unit, errno, "Failed to set up CPU affinity: %m"); + return log_exec_error_errno(context, params, errno, "Failed to set up CPU affinity: %m"); } } if (mpol_is_valid(numa_policy_get_type(&context->numa_policy))) { r = apply_numa_policy(&context->numa_policy); if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) - log_unit_debug_errno(unit, r, "NUMA support not available, ignoring."); + log_exec_debug_errno(context, params, r, "NUMA support not available, ignoring."); else if (r < 0) { *exit_status = EXIT_NUMA_POLICY; - return log_unit_error_errno(unit, r, "Failed to set NUMA memory policy: %m"); + return log_exec_error_errno(context, params, r, "Failed to set NUMA memory policy: %m"); } } if (context->ioprio_set) if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) { *exit_status = EXIT_IOPRIO; - return log_unit_error_errno(unit, errno, "Failed to set up IO scheduling priority: %m"); + return log_exec_error_errno(context, params, errno, "Failed to set up IO scheduling priority: %m"); } if (context->timer_slack_nsec != NSEC_INFINITY) if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) { *exit_status = EXIT_TIMERSLACK; - return log_unit_error_errno(unit, errno, "Failed to set up timer slack: %m"); + return log_exec_error_errno(context, params, errno, "Failed to set up timer slack: %m"); } if (context->personality != PERSONALITY_INVALID) { r = safe_personality(context->personality); if (r < 0) { *exit_status = EXIT_PERSONALITY; - return log_unit_error_errno(unit, r, "Failed to set up execution domain (personality): %m"); + return log_exec_error_errno(context, params, r, "Failed to set up execution domain (personality): %m"); } } @@ -4406,7 +4512,7 @@ static int exec_child( r = chown_terminal(STDIN_FILENO, uid); if (r < 0) { *exit_status = EXIT_STDIN; - return log_unit_error_errno(unit, r, "Failed to change ownership of terminal: %m"); + return log_exec_error_errno(context, params, r, "Failed to change ownership of terminal: %m"); } } @@ -4422,19 +4528,19 @@ static int exec_child( r = cg_set_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, uid, gid); if (r < 0) { *exit_status = EXIT_CGROUP; - return log_unit_error_errno(unit, r, "Failed to adjust control group access: %m"); + return log_exec_error_errno(context, params, r, "Failed to adjust control group access: %m"); } r = exec_parameters_get_cgroup_path(params, cgroup_context, &p); if (r < 0) { *exit_status = EXIT_CGROUP; - return log_unit_error_errno(unit, r, "Failed to acquire cgroup path: %m"); + return log_exec_error_errno(context, params, r, "Failed to acquire cgroup path: %m"); } if (r > 0) { r = cg_set_access_recursive(SYSTEMD_CGROUP_CONTROLLER, p, uid, gid); if (r < 0) { *exit_status = EXIT_CGROUP; - return log_unit_error_errno(unit, r, "Failed to adjust control subgroup access: %m"); + return log_exec_error_errno(context, params, r, "Failed to adjust control subgroup access: %m"); } } } @@ -4449,7 +4555,7 @@ static int exec_child( r = chmod_and_chown(memory_pressure_path, 0644, uid, gid); if (r < 0) { - log_unit_full_errno(unit, r == -ENOENT || ERRNO_IS_PRIVILEGE(r) ? LOG_DEBUG : LOG_WARNING, r, + log_exec_full_errno(context, params, r == -ENOENT || ERRNO_IS_PRIVILEGE(r) ? LOG_DEBUG : LOG_WARNING, r, "Failed to adjust ownership of '%s', ignoring: %m", memory_pressure_path); memory_pressure_path = mfree(memory_pressure_path); } @@ -4466,21 +4572,20 @@ static int exec_child( needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime); for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) { - r = setup_exec_directory(unit, context, params, uid, gid, dt, needs_mount_namespace, exit_status); + r = setup_exec_directory(context, params, uid, gid, dt, needs_mount_namespace, exit_status); if (r < 0) - return log_unit_error_errno(unit, r, "Failed to set up special execution directory in %s: %m", params->prefix[dt]); + return log_exec_error_errno(context, params, r, "Failed to set up special execution directory in %s: %m", params->prefix[dt]); } if (FLAGS_SET(params->flags, EXEC_WRITE_CREDENTIALS)) { - r = exec_setup_credentials(context, params, unit->id, uid, gid); + r = exec_setup_credentials(context, params, params->unit_id, uid, gid); if (r < 0) { *exit_status = EXIT_CREDENTIALS; - return log_unit_error_errno(unit, r, "Failed to set up credentials: %m"); + return log_exec_error_errno(context, params, r, "Failed to set up credentials: %m"); } } r = build_environment( - unit, context, params, cgroup_context, @@ -4537,10 +4642,10 @@ static int exec_child( (void) umask(context->umask); - r = setup_keyring(unit, context, params, uid, gid); + r = setup_keyring(context, params, uid, gid); if (r < 0) { *exit_status = EXIT_KEYRING; - return log_unit_error_errno(unit, r, "Failed to set up kernel keyring: %m"); + return log_exec_error_errno(context, params, r, "Failed to set up kernel keyring: %m"); } /* We need sandboxing if the caller asked us to apply it and the command isn't explicitly excepted @@ -4586,7 +4691,7 @@ static int exec_child( r = setrlimit_closest_all((const struct rlimit* const *) context->rlimit, &which_failed); if (r < 0) { *exit_status = EXIT_LIMITS; - return log_unit_error_errno(unit, r, "Failed to adjust resource limit RLIMIT_%s: %m", rlimit_to_string(which_failed)); + return log_exec_error_errno(context, params, r, "Failed to adjust resource limit RLIMIT_%s: %m", rlimit_to_string(which_failed)); } } @@ -4598,7 +4703,7 @@ static int exec_child( r = setup_pam(context->pam_name, username, uid, gid, context->tty_path, &accum_env, fds, n_fds); if (r < 0) { *exit_status = EXIT_PAM; - return log_unit_error_errno(unit, r, "Failed to set up PAM session: %m"); + return log_exec_error_errno(context, params, r, "Failed to set up PAM session: %m"); } if (ambient_capabilities_supported()) { @@ -4609,7 +4714,7 @@ static int exec_child( r = capability_get_ambient(&ambient_after_pam); if (r < 0) { *exit_status = EXIT_CAPABILITIES; - return log_unit_error_errno(unit, r, "Failed to query ambient caps: %m"); + return log_exec_error_errno(context, params, r, "Failed to query ambient caps: %m"); } capability_ambient_set |= ambient_after_pam; @@ -4618,7 +4723,7 @@ static int exec_child( ngids_after_pam = getgroups_alloc(&gids_after_pam); if (ngids_after_pam < 0) { *exit_status = EXIT_MEMORY; - return log_unit_error_errno(unit, ngids_after_pam, "Failed to obtain groups after setting up PAM: %m"); + return log_exec_error_errno(context, params, ngids_after_pam, "Failed to obtain groups after setting up PAM: %m"); } } @@ -4632,10 +4737,10 @@ static int exec_child( * the actual requested operations fail (or silently continue). */ if (r < 0 && context->private_users) { *exit_status = EXIT_USER; - return log_unit_error_errno(unit, r, "Failed to set up user namespacing for unprivileged user: %m"); + return log_exec_error_errno(context, params, r, "Failed to set up user namespacing for unprivileged user: %m"); } if (r < 0) - log_unit_info_errno(unit, r, "Failed to set up user namespacing for unprivileged user, ignoring: %m"); + log_exec_info_errno(context, params, r, "Failed to set up user namespacing for unprivileged user, ignoring: %m"); else userns_set_up = true; } @@ -4649,18 +4754,18 @@ static int exec_child( if (ns_type_supported(NAMESPACE_NET) && have_effective_cap(CAP_NET_ADMIN) > 0) { r = setup_shareable_ns(runtime->shared->netns_storage_socket, CLONE_NEWNET); if (ERRNO_IS_NEG_PRIVILEGE(r)) - log_unit_notice_errno(unit, r, + log_exec_notice_errno(context, params, r, "PrivateNetwork=yes is configured, but network namespace setup not permitted, proceeding without: %m"); else if (r < 0) { *exit_status = EXIT_NETWORK; - return log_unit_error_errno(unit, r, "Failed to set up network namespacing: %m"); + return log_exec_error_errno(context, params, r, "Failed to set up network namespacing: %m"); } } else if (context->network_namespace_path) { *exit_status = EXIT_NETWORK; - return log_unit_error_errno(unit, SYNTHETIC_ERRNO(EOPNOTSUPP), + return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(EOPNOTSUPP), "NetworkNamespacePath= is not supported, refusing."); } else - log_unit_notice(unit, "PrivateNetwork=yes is configured, but the kernel does not support or we lack privileges for network namespace, proceeding without."); + log_exec_notice(context, params, "PrivateNetwork=yes is configured, but the kernel does not support or we lack privileges for network namespace, proceeding without."); } if (exec_needs_ipc_namespace(context) && runtime && runtime->shared && runtime->shared->ipcns_storage_socket[0] >= 0) { @@ -4668,33 +4773,33 @@ static int exec_child( if (ns_type_supported(NAMESPACE_IPC)) { r = setup_shareable_ns(runtime->shared->ipcns_storage_socket, CLONE_NEWIPC); if (r == -EPERM) - log_unit_warning_errno(unit, r, + log_exec_warning_errno(context, params, r, "PrivateIPC=yes is configured, but IPC namespace setup failed, ignoring: %m"); else if (r < 0) { *exit_status = EXIT_NAMESPACE; - return log_unit_error_errno(unit, r, "Failed to set up IPC namespacing: %m"); + return log_exec_error_errno(context, params, r, "Failed to set up IPC namespacing: %m"); } } else if (context->ipc_namespace_path) { *exit_status = EXIT_NAMESPACE; - return log_unit_error_errno(unit, SYNTHETIC_ERRNO(EOPNOTSUPP), + return log_exec_error_errno(context, params, SYNTHETIC_ERRNO(EOPNOTSUPP), "IPCNamespacePath= is not supported, refusing."); } else - log_unit_warning(unit, "PrivateIPC=yes is configured, but the kernel does not support IPC namespaces, ignoring."); + log_exec_warning(context, params, "PrivateIPC=yes is configured, but the kernel does not support IPC namespaces, ignoring."); } if (needs_mount_namespace) { _cleanup_free_ char *error_path = NULL; - r = apply_mount_namespace(unit, command->flags, context, params, runtime, memory_pressure_path, &error_path); + r = apply_mount_namespace(command->flags, context, params, runtime, memory_pressure_path, &error_path); if (r < 0) { *exit_status = EXIT_NAMESPACE; - return log_unit_error_errno(unit, r, "Failed to set up mount namespacing%s%s: %m", + return log_exec_error_errno(context, params, r, "Failed to set up mount namespacing%s%s: %m", error_path ? ": " : "", strempty(error_path)); } } if (needs_sandboxing) { - r = apply_protect_hostname(unit, context, exit_status); + r = apply_protect_hostname(context, params, exit_status); if (r < 0) return r; } @@ -4702,10 +4807,13 @@ static int exec_child( if (context->memory_ksm >= 0) if (prctl(PR_SET_MEMORY_MERGE, context->memory_ksm) < 0) { if (ERRNO_IS_NOT_SUPPORTED(errno)) - log_unit_debug_errno(unit, errno, "KSM support not available, ignoring."); + log_exec_debug_errno(context, + params, + errno, + "KSM support not available, ignoring."); else { *exit_status = EXIT_KSM; - return log_unit_error_errno(unit, errno, "Failed to set KSM: %m"); + return log_exec_error_errno(context, params, errno, "Failed to set KSM: %m"); } } @@ -4723,7 +4831,7 @@ static int exec_child( &gids_to_enforce); if (ngids_to_enforce < 0) { *exit_status = EXIT_MEMORY; - return log_unit_error_errno(unit, + return log_exec_error_errno(context, params, ngids_to_enforce, "Failed to merge group lists. Group membership might be incorrect: %m"); } @@ -4731,7 +4839,7 @@ static int exec_child( r = enforce_groups(gid, gids_to_enforce, ngids_to_enforce); if (r < 0) { *exit_status = EXIT_GROUP; - return log_unit_error_errno(unit, r, "Changing group credentials failed: %m"); + return log_exec_error_errno(context, params, r, "Changing group credentials failed: %m"); } } @@ -4745,7 +4853,7 @@ static int exec_child( r = setup_private_users(saved_uid, saved_gid, uid, gid); if (r < 0) { *exit_status = EXIT_USER; - return log_unit_error_errno(unit, r, "Failed to set up user namespacing: %m"); + return log_exec_error_errno(context, params, r, "Failed to set up user namespacing: %m"); } } @@ -4757,10 +4865,11 @@ static int exec_child( r = find_executable_full(command->path, /* root= */ NULL, context->exec_search_path, false, &executable, &executable_fd); if (r < 0) { if (r != -ENOMEM && (command->flags & EXEC_COMMAND_IGNORE_FAILURE)) { - log_unit_struct_errno(unit, LOG_INFO, r, + log_exec_struct_errno(context, params, LOG_INFO, r, "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR, - LOG_UNIT_INVOCATION_ID(unit), - LOG_UNIT_MESSAGE(unit, "Executable %s missing, skipping: %m", + LOG_EXEC_INVOCATION_ID(params), + LOG_EXEC_MESSAGE(params, + "Executable %s missing, skipping: %m", command->path), "EXECUTABLE=%s", command->path); *exit_status = EXIT_SUCCESS; @@ -4768,10 +4877,11 @@ static int exec_child( } *exit_status = EXIT_EXEC; - return log_unit_struct_errno(unit, LOG_INFO, r, + return log_exec_struct_errno(context, params, LOG_INFO, r, "MESSAGE_ID=" SD_MESSAGE_SPAWN_FAILED_STR, - LOG_UNIT_INVOCATION_ID(unit), - LOG_UNIT_MESSAGE(unit, "Failed to locate executable %s: %m", + LOG_EXEC_INVOCATION_ID(params), + LOG_EXEC_MESSAGE(params, + "Failed to locate executable %s: %m", command->path), "EXECUTABLE=%s", command->path); } @@ -4779,7 +4889,7 @@ static int exec_child( r = add_shifted_fd(keep_fds, ELEMENTSOF(keep_fds), &n_keep_fds, executable_fd, &executable_fd); if (r < 0) { *exit_status = EXIT_FDS; - return log_unit_error_errno(unit, r, "Failed to shift fd and set FD_CLOEXEC: %m"); + return log_exec_error_errno(context, params, r, "Failed to shift fd and set FD_CLOEXEC: %m"); } #if HAVE_SELINUX @@ -4798,9 +4908,15 @@ static int exec_child( if (r < 0) { if (!context->selinux_context_ignore) { *exit_status = EXIT_SELINUX_CONTEXT; - return log_unit_error_errno(unit, r, "Failed to determine SELinux context: %m"); + return log_exec_error_errno(context, + params, + r, + "Failed to determine SELinux context: %m"); } - log_unit_debug_errno(unit, r, "Failed to determine SELinux context, ignoring: %m"); + log_exec_debug_errno(context, + params, + r, + "Failed to determine SELinux context, ignoring: %m"); } } } @@ -4818,7 +4934,7 @@ static int exec_child( r = flags_fds(fds, n_socket_fds, n_fds, context->non_blocking); if (r < 0) { *exit_status = EXIT_FDS; - return log_unit_error_errno(unit, r, "Failed to adjust passed file descriptors: %m"); + return log_exec_error_errno(context, params, r, "Failed to adjust passed file descriptors: %m"); } /* At this point, the fds we want to pass to the program are all ready and set up, with O_CLOEXEC turned off @@ -4837,7 +4953,7 @@ static int exec_child( if (context->restrict_realtime && !context->rlimit[RLIMIT_RTPRIO]) { if (setrlimit(RLIMIT_RTPRIO, &RLIMIT_MAKE_CONST(0)) < 0) { *exit_status = EXIT_LIMITS; - return log_unit_error_errno(unit, errno, "Failed to adjust RLIMIT_RTPRIO resource limit: %m"); + return log_exec_error_errno(context, params, errno, "Failed to adjust RLIMIT_RTPRIO resource limit: %m"); } } @@ -4848,7 +4964,7 @@ static int exec_child( r = setup_smack(params, context, executable_fd); if (r < 0 && !context->smack_process_label_ignore) { *exit_status = EXIT_SMACK_PROCESS_LABEL; - return log_unit_error_errno(unit, r, "Failed to set SMACK process label: %m"); + return log_exec_error_errno(context, params, r, "Failed to set SMACK process label: %m"); } } #endif @@ -4866,7 +4982,7 @@ static int exec_child( r = capability_bounding_set_drop(bset, /* right_now= */ false); if (r < 0) { *exit_status = EXIT_CAPABILITIES; - return log_unit_error_errno(unit, r, "Failed to drop capabilities: %m"); + return log_exec_error_errno(context, params, r, "Failed to drop capabilities: %m"); } } @@ -4885,7 +5001,7 @@ static int exec_child( r = capability_ambient_set_apply(capability_ambient_set, /* also_inherit= */ true); if (r < 0) { *exit_status = EXIT_CAPABILITIES; - return log_unit_error_errno(unit, r, "Failed to apply ambient capabilities (before UID change): %m"); + return log_exec_error_errno(context, params, r, "Failed to apply ambient capabilities (before UID change): %m"); } } } @@ -4893,14 +5009,14 @@ static int exec_child( /* chroot to root directory first, before we lose the ability to chroot */ r = apply_root_directory(context, params, runtime, needs_mount_namespace, exit_status); if (r < 0) - return log_unit_error_errno(unit, r, "Chrooting to the requested root directory failed: %m"); + return log_exec_error_errno(context, params, r, "Chrooting to the requested root directory failed: %m"); if (needs_setuid) { if (uid_is_valid(uid)) { r = enforce_user(context, uid, capability_ambient_set); if (r < 0) { *exit_status = EXIT_USER; - return log_unit_error_errno(unit, r, "Failed to change UID to " UID_FMT ": %m", uid); + return log_exec_error_errno(context, params, r, "Failed to change UID to " UID_FMT ": %m", uid); } if (!needs_ambient_hack && capability_ambient_set != 0) { @@ -4909,7 +5025,7 @@ static int exec_child( r = capability_ambient_set_apply(capability_ambient_set, /* also_inherit= */ false); if (r < 0) { *exit_status = EXIT_CAPABILITIES; - return log_unit_error_errno(unit, r, "Failed to apply ambient capabilities (after UID change): %m"); + return log_exec_error_errno(context, params, r, "Failed to apply ambient capabilities (after UID change): %m"); } } } @@ -4919,7 +5035,7 @@ static int exec_child( * this service might have the correct privilege to change to the working directory */ r = apply_working_directory(context, params, runtime, home, exit_status); if (r < 0) - return log_unit_error_errno(unit, r, "Changing to the requested working directory failed: %m"); + return log_exec_error_errno(context, params, r, "Changing to the requested working directory failed: %m"); if (needs_sandboxing) { /* Apply other MAC contexts late, but before seccomp syscall filtering, as those should really be last to @@ -4936,9 +5052,13 @@ static int exec_child( if (r < 0) { if (!context->selinux_context_ignore) { *exit_status = EXIT_SELINUX_CONTEXT; - return log_unit_error_errno(unit, r, "Failed to change SELinux context to %s: %m", exec_context); + return log_exec_error_errno(context, params, r, "Failed to change SELinux context to %s: %m", exec_context); } - log_unit_debug_errno(unit, r, "Failed to change SELinux context to %s, ignoring: %m", exec_context); + log_exec_debug_errno(context, + params, + r, + "Failed to change SELinux context to %s, ignoring: %m", + exec_context); } } } @@ -4949,7 +5069,11 @@ static int exec_child( r = aa_change_onexec(context->apparmor_profile); if (r < 0 && !context->apparmor_profile_ignore) { *exit_status = EXIT_APPARMOR_PROFILE; - return log_unit_error_errno(unit, errno, "Failed to prepare AppArmor profile change to %s: %m", context->apparmor_profile); + return log_exec_error_errno(context, + params, + errno, + "Failed to prepare AppArmor profile change to %s: %m", + context->apparmor_profile); } } #endif @@ -4972,113 +5096,113 @@ static int exec_child( r = capability_gain_cap_setpcap(/* return_caps= */ NULL); if (r < 0) { *exit_status = EXIT_CAPABILITIES; - return log_unit_error_errno(unit, r, "Failed to gain CAP_SETPCAP for setting secure bits"); + return log_exec_error_errno(context, params, r, "Failed to gain CAP_SETPCAP for setting secure bits"); } if (prctl(PR_SET_SECUREBITS, secure_bits) < 0) { *exit_status = EXIT_SECUREBITS; - return log_unit_error_errno(unit, errno, "Failed to set process secure bits: %m"); + return log_exec_error_errno(context, params, errno, "Failed to set process secure bits: %m"); } } if (context_has_no_new_privileges(context)) if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) { *exit_status = EXIT_NO_NEW_PRIVILEGES; - return log_unit_error_errno(unit, errno, "Failed to disable new privileges: %m"); + return log_exec_error_errno(context, params, errno, "Failed to disable new privileges: %m"); } #if HAVE_SECCOMP - r = apply_address_families(unit, context); + r = apply_address_families(context, params); if (r < 0) { *exit_status = EXIT_ADDRESS_FAMILIES; - return log_unit_error_errno(unit, r, "Failed to restrict address families: %m"); + return log_exec_error_errno(context, params, r, "Failed to restrict address families: %m"); } - r = apply_memory_deny_write_execute(unit, context); + r = apply_memory_deny_write_execute(context, params); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to disable writing to executable memory: %m"); + return log_exec_error_errno(context, params, r, "Failed to disable writing to executable memory: %m"); } - r = apply_restrict_realtime(unit, context); + r = apply_restrict_realtime(context, params); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to apply realtime restrictions: %m"); + return log_exec_error_errno(context, params, r, "Failed to apply realtime restrictions: %m"); } - r = apply_restrict_suid_sgid(unit, context); + r = apply_restrict_suid_sgid(context, params); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to apply SUID/SGID restrictions: %m"); + return log_exec_error_errno(context, params, r, "Failed to apply SUID/SGID restrictions: %m"); } - r = apply_restrict_namespaces(unit, context); + r = apply_restrict_namespaces(context, params); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to apply namespace restrictions: %m"); + return log_exec_error_errno(context, params, r, "Failed to apply namespace restrictions: %m"); } - r = apply_protect_sysctl(unit, context); + r = apply_protect_sysctl(context, params); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to apply sysctl restrictions: %m"); + return log_exec_error_errno(context, params, r, "Failed to apply sysctl restrictions: %m"); } - r = apply_protect_kernel_modules(unit, context); + r = apply_protect_kernel_modules(context, params); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to apply module loading restrictions: %m"); + return log_exec_error_errno(context, params, r, "Failed to apply module loading restrictions: %m"); } - r = apply_protect_kernel_logs(unit, context); + r = apply_protect_kernel_logs(context, params); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to apply kernel log restrictions: %m"); + return log_exec_error_errno(context, params, r, "Failed to apply kernel log restrictions: %m"); } - r = apply_protect_clock(unit, context); + r = apply_protect_clock(context, params); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to apply clock restrictions: %m"); + return log_exec_error_errno(context, params, r, "Failed to apply clock restrictions: %m"); } - r = apply_private_devices(unit, context); + r = apply_private_devices(context, params); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to set up private devices: %m"); + return log_exec_error_errno(context, params, r, "Failed to set up private devices: %m"); } - r = apply_syscall_archs(unit, context); + r = apply_syscall_archs(context, params); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to apply syscall architecture restrictions: %m"); + return log_exec_error_errno(context, params, r, "Failed to apply syscall architecture restrictions: %m"); } - r = apply_lock_personality(unit, context); + r = apply_lock_personality(context, params); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to lock personalities: %m"); + return log_exec_error_errno(context, params, r, "Failed to lock personalities: %m"); } - r = apply_syscall_log(unit, context); + r = apply_syscall_log(context, params); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to apply system call log filters: %m"); + return log_exec_error_errno(context, params, r, "Failed to apply system call log filters: %m"); } /* This really should remain the last step before the execve(), to make sure our own code is unaffected * by the filter as little as possible. */ - r = apply_syscall_filter(unit, context, needs_ambient_hack); + r = apply_syscall_filter(context, params, needs_ambient_hack); if (r < 0) { *exit_status = EXIT_SECCOMP; - return log_unit_error_errno(unit, r, "Failed to apply system call filters: %m"); + return log_exec_error_errno(context, params, r, "Failed to apply system call filters: %m"); } #endif #if HAVE_LIBBPF - r = apply_restrict_filesystems(unit, context, params); + r = apply_restrict_filesystems(context, params); if (r < 0) { *exit_status = EXIT_BPF; - return log_unit_error_errno(unit, r, "Failed to restrict filesystems: %m"); + return log_exec_error_errno(context, params, r, "Failed to restrict filesystems: %m"); } #endif @@ -5102,23 +5226,32 @@ static int exec_child( r = replace_env_argv(command->argv, accum_env, &replaced_argv, &unset_variables, &bad_variables); if (r < 0) { *exit_status = EXIT_MEMORY; - return log_unit_error_errno(unit, r, "Failed to replace environment variables: %m"); + return log_exec_error_errno(context, + params, + r, + "Failed to replace environment variables: %m"); } final_argv = replaced_argv; if (!strv_isempty(unset_variables)) { _cleanup_free_ char *ju = strv_join(unset_variables, ", "); - log_unit_warning(unit, "Referenced but unset environment variable evaluates to an empty string: %s", strna(ju)); + log_exec_warning(context, + params, + "Referenced but unset environment variable evaluates to an empty string: %s", + strna(ju)); } if (!strv_isempty(bad_variables)) { _cleanup_free_ char *jb = strv_join(bad_variables, ", "); - log_unit_warning(unit, "Invalid environment variable name evaluates to an empty string: %s", strna(jb));; + log_exec_warning(context, + params, + "Invalid environment variable name evaluates to an empty string: %s", + strna(jb)); } } else final_argv = command->argv; - log_command_line(unit, "Executing", executable, final_argv); + log_command_line(context, params, "Executing", executable, final_argv); if (exec_fd >= 0) { uint8_t hot = 1; @@ -5128,7 +5261,7 @@ static int exec_child( if (write(exec_fd, &hot, sizeof(hot)) < 0) { *exit_status = EXIT_EXEC; - return log_unit_error_errno(unit, errno, "Failed to enable exec_fd: %m"); + return log_exec_error_errno(context, params, errno, "Failed to enable exec_fd: %m"); } } @@ -5142,12 +5275,12 @@ static int exec_child( if (write(exec_fd, &hot, sizeof(hot)) < 0) { *exit_status = EXIT_EXEC; - return log_unit_error_errno(unit, errno, "Failed to disable exec_fd: %m"); + return log_exec_error_errno(context, params, errno, "Failed to disable exec_fd: %m"); } } *exit_status = EXIT_EXEC; - return log_unit_error_errno(unit, r, "Failed to execute %s: %m", executable); + return log_exec_error_errno(context, params, r, "Failed to execute %s: %m", executable); } @@ -5170,6 +5303,7 @@ int exec_spawn(Unit *unit, assert(ret); assert(params); assert(params->fds || (params->n_socket_fds + params->n_storage_fds <= 0)); + assert(!params->files_env); /* We fill this field, ensure it comes NULL-initialized to us */ LOG_CONTEXT_PUSH_UNIT(unit); @@ -5183,7 +5317,7 @@ int exec_spawn(Unit *unit, /* We won't know the real executable path until we create the mount namespace in the child, but we want to log from the parent, so we use the possibly inaccurate path here. */ - log_command_line(unit, "About to execute", command->path, command->argv); + log_command_line(context, params, "About to execute", command->path, command->argv); if (params->cgroup_path) { r = exec_parameters_get_cgroup_path(params, cgroup_context, &subcgroup_path); @@ -5206,8 +5340,7 @@ int exec_spawn(Unit *unit, if (pid == 0) { int exit_status; - r = exec_child(unit, - command, + r = exec_child(command, context, params, runtime, @@ -7092,8 +7225,11 @@ void exec_params_clear(ExecParameters *p) { p->files_env = strv_free(p->files_env); p->fds = mfree(p->fds); p->exec_fd = safe_close(p->exec_fd); - p->user_lookup_fd = safe_close(p->user_lookup_fd); + p->user_lookup_fd = -EBADF; p->bpf_outer_map_fd = -EBADF; + p->unit_id = mfree(p->unit_id); + p->invocation_id = SD_ID128_NULL; + p->invocation_id_string[0] = '\0'; } void exec_directory_done(ExecDirectory *d) { diff --git a/src/core/execute.h b/src/core/execute.h index 52940332f75..6f7d0686e83 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -421,6 +421,7 @@ struct ExecParameters { CGroupMask cgroup_supported; const char *cgroup_path; + uint64_t cgroup_id; char **prefix; const char *received_credentials_directory; @@ -449,8 +450,24 @@ struct ExecParameters { char **files_env; int user_lookup_fd; int bpf_outer_map_fd; + + /* Used for logging in the executor functions */ + char *unit_id; + sd_id128_t invocation_id; + char invocation_id_string[SD_ID128_STRING_MAX]; }; +#define EXEC_PARAMETERS_INIT(_flags) \ + (ExecParameters) { \ + .flags = (_flags), \ + .stdin_fd = -EBADF, \ + .stdout_fd = -EBADF, \ + .stderr_fd = -EBADF, \ + .exec_fd = -EBADF, \ + .bpf_outer_map_fd = -EBADF, \ + .user_lookup_fd = -EBADF, \ + }; + #include "unit.h" #include "dynamic-user.h" @@ -551,3 +568,103 @@ ExecDirectoryType exec_resource_type_from_string(const char *s) _pure_; bool exec_needs_mount_namespace(const ExecContext *context, const ExecParameters *params, const ExecRuntime *runtime); bool exec_needs_network_namespace(const ExecContext *context); + +/* These logging macros do the same logging as those in unit.h, but using ExecContext and ExecParameters + * instead of the unit object, so that it can be used in the sd-executor context (where the unit object is + * not available). */ + +#define LOG_EXEC_ID_FIELD(ep) \ + ((ep)->runtime_scope == RUNTIME_SCOPE_USER ? "USER_UNIT=" : "UNIT=") +#define LOG_EXEC_ID_FIELD_FORMAT(ep) \ + ((ep)->runtime_scope == RUNTIME_SCOPE_USER ? "USER_UNIT=%s" : "UNIT=%s") +#define LOG_EXEC_INVOCATION_ID_FIELD(ep) \ + ((ep)->runtime_scope == RUNTIME_SCOPE_USER ? "USER_INVOCATION_ID=" : "INVOCATION_ID=") +#define LOG_EXEC_INVOCATION_ID_FIELD_FORMAT(ep) \ + ((ep)->runtime_scope == RUNTIME_SCOPE_USER ? "USER_INVOCATION_ID=%s" : "INVOCATION_ID=%s") + +#define log_exec_full_errno_zerook(ec, ep, level, error, ...) \ + ({ \ + const ExecContext *_c = (ec); \ + const ExecParameters *_p = (ep); \ + const int _l = (level); \ + bool _do_log = !(log_get_max_level() < LOG_PRI(_l) || \ + !(_c->log_level_max < 0 || \ + _c->log_level_max >= LOG_PRI(_l))); \ + LOG_CONTEXT_PUSH_IOV(_c->log_extra_fields, \ + _c->n_log_extra_fields); \ + !_do_log ? -ERRNO_VALUE(error) : \ + log_object_internal(_l, error, PROJECT_FILE, \ + __LINE__, __func__, \ + LOG_EXEC_ID_FIELD(_p), \ + _p->unit_id, \ + LOG_EXEC_INVOCATION_ID_FIELD(_p), \ + _p->invocation_id_string, ##__VA_ARGS__); \ + }) + +#define log_exec_full_errno(ec, ep, level, error, ...) \ + ({ \ + int _error = (error); \ + ASSERT_NON_ZERO(_error); \ + log_exec_full_errno_zerook(ec, ep, level, _error, ##__VA_ARGS__); \ + }) + +#define log_exec_full(ec, ep, level, ...) (void) log_exec_full_errno_zerook(ec, ep, level, 0, __VA_ARGS__) + +#define log_exec_debug(ec, ep, ...) log_exec_full(ec, ep, LOG_DEBUG, __VA_ARGS__) +#define log_exec_info(ec, ep, ...) log_exec_full(ec, ep, LOG_INFO, __VA_ARGS__) +#define log_exec_notice(ec, ep, ...) log_exec_full(ec, ep, LOG_NOTICE, __VA_ARGS__) +#define log_exec_warning(ec, ep, ...) log_exec_full(ec, ep, LOG_WARNING, __VA_ARGS__) +#define log_exec_error(ec, ep, ...) log_exec_full(ec, ep, LOG_ERR, __VA_ARGS__) + +#define log_exec_debug_errno(ec, ep, error, ...) log_exec_full_errno(ec, ep, LOG_DEBUG, error, __VA_ARGS__) +#define log_exec_info_errno(ec, ep, error, ...) log_exec_full_errno(ec, ep, LOG_INFO, error, __VA_ARGS__) +#define log_exec_notice_errno(ec, ep, error, ...) log_exec_full_errno(ec, ep, LOG_NOTICE, error, __VA_ARGS__) +#define log_exec_warning_errno(ec, ep, error, ...) log_exec_full_errno(ec, ep, LOG_WARNING, error, __VA_ARGS__) +#define log_exec_error_errno(ec, ep, error, ...) log_exec_full_errno(ec, ep, LOG_ERR, error, __VA_ARGS__) + +#define log_exec_struct_errno(ec, ep, level, error, ...) \ + ({ \ + const ExecContext *_c = (ec); \ + const ExecParameters *_p = (ep); \ + const int _l = (level); \ + bool _do_log = !(_c->log_level_max < 0 || \ + _c->log_level_max >= LOG_PRI(_l)); \ + LOG_CONTEXT_PUSH_IOV(_c->log_extra_fields, \ + _c->n_log_extra_fields); \ + _do_log ? \ + log_struct_errno(_l, error, __VA_ARGS__, LOG_EXEC_ID_FIELD_FORMAT(_p), _p->unit_id) : \ + -ERRNO_VALUE(error); \ + }) + +#define log_exec_struct(ec, ep, level, ...) log_exec_struct_errno(ec, ep, level, 0, __VA_ARGS__) + +#define log_exec_struct_iovec_errno(ec, ep, level, error, iovec, n_iovec) \ + ({ \ + const ExecContext *_c = (ec); \ + const ExecParameters *_p = (ep); \ + const int _l = (level); \ + bool _do_log = !(_c->log_level_max < 0 || \ + _c->log_level_max >= LOG_PRI(_l)); \ + LOG_CONTEXT_PUSH_IOV(_c->log_extra_fields, \ + _c->n_log_extra_fields); \ + _do_log ? \ + log_struct_iovec_errno(_l, error, iovec, n_iovec) : \ + -ERRNO_VALUE(error); \ + }) + +#define log_exec_struct_iovec(ec, ep, level, iovec, n_iovec) log_exec_struct_iovec_errno(ec, ep, level, 0, iovec, n_iovec) + +/* Like LOG_MESSAGE(), but with the unit name prefixed. */ +#define LOG_EXEC_MESSAGE(ep, fmt, ...) LOG_MESSAGE("%s: " fmt, (ep)->unit_id, ##__VA_ARGS__) +#define LOG_EXEC_ID(ep) LOG_EXEC_ID_FIELD_FORMAT(ep), (ep)->unit_id +#define LOG_EXEC_INVOCATION_ID(ep) LOG_EXEC_INVOCATION_ID_FIELD_FORMAT(ep), (ep)->invocation_id_string + +#define _LOG_CONTEXT_PUSH_EXEC(ec, ep, p, c) \ + const ExecContext *c = (ec); \ + const ExecParameters *p = (ep); \ + LOG_CONTEXT_PUSH_KEY_VALUE(LOG_EXEC_ID_FIELD(p), p->unit_id); \ + LOG_CONTEXT_PUSH_KEY_VALUE(LOG_EXEC_INVOCATION_ID_FIELD(p), p->invocation_id_string); \ + LOG_CONTEXT_PUSH_IOV(c->log_extra_fields, c->n_log_extra_fields) + +#define LOG_CONTEXT_PUSH_EXEC(ec, ep) \ + _LOG_CONTEXT_PUSH_EXEC(ec, ep, UNIQ_T(p, UNIQ), UNIQ_T(c, UNIQ)) diff --git a/src/core/manager.c b/src/core/manager.c index 9af6fd4184b..6042bda2394 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -144,6 +144,15 @@ static usec_t manager_watch_jobs_next_time(Manager *m) { return usec_add(now(CLOCK_MONOTONIC), timeout); } +static bool manager_is_confirm_spawn_disabled(Manager *m) { + assert(m); + + if (!m->confirm_spawn) + return true; + + return access("/run/systemd/confirm_spawn_disabled", F_OK) >= 0; +} + static void manager_watch_jobs_in_progress(Manager *m) { usec_t next; int r; @@ -4430,13 +4439,6 @@ void manager_disable_confirm_spawn(void) { (void) touch("/run/systemd/confirm_spawn_disabled"); } -bool manager_is_confirm_spawn_disabled(Manager *m) { - if (!m->confirm_spawn) - return true; - - return access("/run/systemd/confirm_spawn_disabled", F_OK) >= 0; -} - static bool manager_should_show_status(Manager *m, StatusType type) { assert(m); diff --git a/src/core/manager.h b/src/core/manager.h index 4fa54bb3c1a..4595b1b6863 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -616,7 +616,6 @@ const char *manager_state_to_string(ManagerState m) _const_; ManagerState manager_state_from_string(const char *s) _pure_; const char *manager_get_confirm_spawn(Manager *m); -bool manager_is_confirm_spawn_disabled(Manager *m); void manager_disable_confirm_spawn(void); const char *manager_timestamp_to_string(ManagerTimestamp m) _const_; diff --git a/src/core/mount.c b/src/core/mount.c index 06a3b8a8c3c..fe04b3d74c9 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -889,15 +889,8 @@ static void mount_dump(Unit *u, FILE *f, const char *prefix) { static int mount_spawn(Mount *m, ExecCommand *c, PidRef *ret_pid) { - _cleanup_(exec_params_clear) ExecParameters exec_params = { - .flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN, - .stdin_fd = -EBADF, - .stdout_fd = -EBADF, - .stderr_fd = -EBADF, - .exec_fd = -EBADF, - .bpf_outer_map_fd = -EBADF, - .user_lookup_fd = -EBADF, - }; + _cleanup_(exec_params_clear) ExecParameters exec_params = EXEC_PARAMETERS_INIT( + EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN); _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; pid_t pid; int r; diff --git a/src/core/service.c b/src/core/service.c index 802b1728de4..b4bd343bc94 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1602,15 +1602,7 @@ static int service_spawn_internal( ExecFlags flags, PidRef *ret_pid) { - _cleanup_(exec_params_clear) ExecParameters exec_params = { - .flags = flags, - .stdin_fd = -EBADF, - .stdout_fd = -EBADF, - .stderr_fd = -EBADF, - .exec_fd = -EBADF, - .bpf_outer_map_fd = -EBADF, - .user_lookup_fd = -EBADF, - }; + _cleanup_(exec_params_clear) ExecParameters exec_params = EXEC_PARAMETERS_INIT(flags); _cleanup_(sd_event_source_unrefp) sd_event_source *exec_fd_source = NULL; _cleanup_strv_free_ char **final_env = NULL, **our_env = NULL; _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; diff --git a/src/core/socket.c b/src/core/socket.c index 16faa256e2c..dff4bc42d79 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -1913,15 +1913,8 @@ static int socket_coldplug(Unit *u) { static int socket_spawn(Socket *s, ExecCommand *c, PidRef *ret_pid) { - _cleanup_(exec_params_clear) ExecParameters exec_params = { - .flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN, - .stdin_fd = -EBADF, - .stdout_fd = -EBADF, - .stderr_fd = -EBADF, - .exec_fd = -EBADF, - .bpf_outer_map_fd = -EBADF, - .user_lookup_fd = -EBADF, - }; + _cleanup_(exec_params_clear) ExecParameters exec_params = EXEC_PARAMETERS_INIT( + EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN); _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; pid_t pid; int r; diff --git a/src/core/swap.c b/src/core/swap.c index 73db3fcb967..d0bce8c44bd 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -632,15 +632,8 @@ static void swap_dump(Unit *u, FILE *f, const char *prefix) { static int swap_spawn(Swap *s, ExecCommand *c, PidRef *ret_pid) { - _cleanup_(exec_params_clear) ExecParameters exec_params = { - .flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN, - .stdin_fd = -EBADF, - .stdout_fd = -EBADF, - .stderr_fd = -EBADF, - .exec_fd = -EBADF, - .bpf_outer_map_fd = -EBADF, - .user_lookup_fd = -EBADF, - }; + _cleanup_(exec_params_clear) ExecParameters exec_params = EXEC_PARAMETERS_INIT( + EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN); _cleanup_(pidref_done) PidRef pidref = PIDREF_NULL; pid_t pid; int r; diff --git a/src/core/unit.c b/src/core/unit.c index b028f8fda08..cd4282a26b7 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1854,18 +1854,6 @@ int unit_test_start_limit(Unit *u) { return -ECANCELED; } -bool unit_shall_confirm_spawn(Unit *u) { - assert(u); - - if (manager_is_confirm_spawn_disabled(u->manager)) - return false; - - /* For some reasons units remaining in the same process group - * as PID 1 fail to acquire the console even if it's not used - * by any process. So skip the confirmation question for them. */ - return !unit_get_exec_context(u)->same_pgrp; -} - static bool unit_verify_deps(Unit *u) { Unit *other; @@ -5405,9 +5393,14 @@ int unit_set_exec_params(Unit *u, ExecParameters *p) { p->bpf_outer_map_fd = fd; } - p->user_lookup_fd = fcntl(u->manager->user_lookup_fds[1], F_DUPFD_CLOEXEC, 3); - if (p->user_lookup_fd < 0) - return -errno; + p->user_lookup_fd = u->manager->user_lookup_fds[1]; + + p->cgroup_id = u->cgroup_id; + p->invocation_id = u->invocation_id; + sd_id128_to_string(p->invocation_id, p->invocation_id_string); + p->unit_id = strdup(u->id); + if (!p->unit_id) + return -ENOMEM; return 0; } diff --git a/src/core/unit.h b/src/core/unit.h index 434981755af..b5d7eb5f261 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -1024,8 +1024,6 @@ void unit_notify_user_lookup(Unit *u, uid_t uid, gid_t gid); int unit_set_invocation_id(Unit *u, sd_id128_t id); int unit_acquire_invocation_id(Unit *u); -bool unit_shall_confirm_spawn(Unit *u); - int unit_set_exec_params(Unit *s, ExecParameters *p); int unit_fork_helper_process(Unit *u, const char *name, PidRef *ret);