X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fcore%2Fexecute.c;h=e683fa5e16e63a3f84a60130cc8cebd9889f980b;hb=9fa95f8539a380e93f760956bc6982e57f5bf3af;hp=fff25c2b236b9c96dafe8232a507a126d7974502;hpb=4298d0b5128326621c8f537107c4c8b459490721;p=elogind.git diff --git a/src/core/execute.c b/src/core/execute.c index fff25c2b2..e683fa5e1 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -69,7 +69,6 @@ #include "ioprio.h" #include "securebits.h" #include "namespace.h" -#include "tcpwrap.h" #include "exit-status.h" #include "missing.h" #include "utmp-wtmp.h" @@ -82,6 +81,7 @@ #include "selinux-util.h" #include "errno-list.h" #include "af-list.h" +#include "mkdir.h" #include "apparmor-util.h" #ifdef HAVE_SECCOMP @@ -122,7 +122,7 @@ static int shift_fds(int fds[], unsigned n_fds) { if ((nfd = fcntl(fds[i], F_DUPFD, i+3)) < 0) return -errno; - close_nointr_nofail(fds[i]); + safe_close(fds[i]); fds[i] = nfd; /* Hmm, the fd we wanted isn't free? Then @@ -208,7 +208,7 @@ static int open_null_as(int flags, int nfd) { if (fd != nfd) { r = dup2(fd, nfd) < 0 ? -errno : nfd; - close_nointr_nofail(fd); + safe_close(fd); } else r = nfd; @@ -233,12 +233,12 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)); if (r < 0) { - close_nointr_nofail(fd); + safe_close(fd); return -errno; } if (shutdown(fd, SHUT_RD) < 0) { - close_nointr_nofail(fd); + safe_close(fd); return -errno; } @@ -262,7 +262,7 @@ static int connect_logger_as(const ExecContext *context, ExecOutput output, cons if (fd != nfd) { r = dup2(fd, nfd) < 0 ? -errno : nfd; - close_nointr_nofail(fd); + safe_close(fd); } else r = nfd; @@ -279,7 +279,7 @@ static int open_terminal_as(const char *path, mode_t mode, int nfd) { if (fd != nfd) { r = dup2(fd, nfd) < 0 ? -errno : nfd; - close_nointr_nofail(fd); + safe_close(fd); } else r = nfd; @@ -333,13 +333,13 @@ static int setup_input(const ExecContext *context, int socket_fd, bool apply_tty i == EXEC_INPUT_TTY_FAIL, i == EXEC_INPUT_TTY_FORCE, false, - (usec_t) -1); + USEC_INFINITY); if (fd < 0) return fd; if (fd != STDIN_FILENO) { r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO; - close_nointr_nofail(fd); + safe_close(fd); } else r = STDIN_FILENO; @@ -503,7 +503,7 @@ static int setup_confirm_stdio(int *_saved_stdin, } if (fd >= 2) - close_nointr_nofail(fd); + safe_close(fd); *_saved_stdin = saved_stdin; *_saved_stdout = saved_stdout; @@ -511,20 +511,15 @@ static int setup_confirm_stdio(int *_saved_stdin, return 0; fail: - if (saved_stdout >= 0) - close_nointr_nofail(saved_stdout); - - if (saved_stdin >= 0) - close_nointr_nofail(saved_stdin); - - if (fd >= 0) - close_nointr_nofail(fd); + safe_close(saved_stdout); + safe_close(saved_stdin); + safe_close(fd); return r; } _printf_(1, 2) static int write_confirm_message(const char *format, ...) { - int fd; + _cleanup_close_ int fd = -1; va_list ap; assert(format); @@ -537,8 +532,6 @@ _printf_(1, 2) static int write_confirm_message(const char *format, ...) { vdprintf(fd, format, ap); va_end(ap); - close_nointr_nofail(fd); - return 0; } @@ -560,18 +553,15 @@ static int restore_confirm_stdio(int *saved_stdin, if (dup2(*saved_stdout, STDOUT_FILENO) < 0) r = -errno; - if (*saved_stdin >= 0) - close_nointr_nofail(*saved_stdin); - - if (*saved_stdout >= 0) - close_nointr_nofail(*saved_stdout); + safe_close(*saved_stdin); + safe_close(*saved_stdout); return r; } static int ask_for_confirmation(char *response, char **argv) { int saved_stdout = -1, saved_stdin = -1, r; - char *line; + _cleanup_free_ char *line = NULL; r = setup_confirm_stdio(&saved_stdin, &saved_stdout); if (r < 0) @@ -581,8 +571,7 @@ static int ask_for_confirmation(char *response, char **argv) { if (!line) return -ENOMEM; - r = ask(response, "yns", "Execute %s? [Yes, No, Skip] ", line); - free(line); + r = ask_char(response, "yns", "Execute %s? [Yes, No, Skip] ", line); restore_confirm_stdio(&saved_stdin, &saved_stdout); @@ -1124,10 +1113,9 @@ finish: static void do_idle_pipe_dance(int idle_pipe[4]) { assert(idle_pipe); - if (idle_pipe[1] >= 0) - close_nointr_nofail(idle_pipe[1]); - if (idle_pipe[2] >= 0) - close_nointr_nofail(idle_pipe[2]); + + safe_close(idle_pipe[1]); + safe_close(idle_pipe[2]); if (idle_pipe[0] >= 0) { int r; @@ -1142,16 +1130,15 @@ static void do_idle_pipe_dance(int idle_pipe[4]) { fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT2_USEC); } - close_nointr_nofail(idle_pipe[0]); + safe_close(idle_pipe[0]); } - if (idle_pipe[3] >= 0) - close_nointr_nofail(idle_pipe[3]); + safe_close(idle_pipe[3]); } static int build_environment( - ExecContext *c, + const ExecContext *c, unsigned n_fds, usec_t watchdog_usec, const char *home, @@ -1185,7 +1172,7 @@ static int build_environment( return -ENOMEM; our_env[n_env++] = x; - if (asprintf(&x, "WATCHDOG_USEC=%llu", (unsigned long long) watchdog_usec) < 0) + if (asprintf(&x, "WATCHDOG_USEC="USEC_FMT, watchdog_usec) < 0) return -ENOMEM; our_env[n_env++] = x; } @@ -1237,66 +1224,56 @@ static int build_environment( } int exec_spawn(ExecCommand *command, - char **argv, - ExecContext *context, - int fds[], unsigned n_fds, - char **environment, - bool apply_permissions, - bool apply_chroot, - bool apply_tty_stdin, - bool confirm_spawn, - CGroupControllerMask cgroup_supported, - const char *cgroup_path, - const char *unit_id, - usec_t watchdog_usec, - int idle_pipe[4], + const ExecContext *context, + const ExecParameters *exec_params, ExecRuntime *runtime, pid_t *ret) { _cleanup_strv_free_ char **files_env = NULL; + int *fds = NULL; unsigned n_fds = 0; int socket_fd; - char *line; + char *line, **argv; pid_t pid; int r; assert(command); assert(context); assert(ret); - assert(fds || n_fds <= 0); + assert(exec_params); + assert(exec_params->fds || exec_params->n_fds <= 0); if (context->std_input == EXEC_INPUT_SOCKET || context->std_output == EXEC_OUTPUT_SOCKET || context->std_error == EXEC_OUTPUT_SOCKET) { - if (n_fds != 1) + if (exec_params->n_fds != 1) return -EINVAL; - socket_fd = fds[0]; - - fds = NULL; - n_fds = 0; - } else + socket_fd = exec_params->fds[0]; + } else { socket_fd = -1; + fds = exec_params->fds; + n_fds = exec_params->n_fds; + } r = exec_context_load_environment(context, &files_env); if (r < 0) { log_struct_unit(LOG_ERR, - unit_id, + exec_params->unit_id, "MESSAGE=Failed to load environment files: %s", strerror(-r), "ERRNO=%d", -r, NULL); return r; } - if (!argv) - argv = command->argv; + argv = exec_params->argv ?: command->argv; line = exec_command_line(argv); if (!line) return log_oom(); log_struct_unit(LOG_DEBUG, - unit_id, + exec_params->unit_id, "EXECUTABLE=%s", command->path, "MESSAGE=About to execute: %s", line, NULL); @@ -1313,7 +1290,6 @@ int exec_spawn(ExecCommand *command, int dont_close[n_fds + 3]; uid_t uid = (uid_t) -1; gid_t gid = (gid_t) -1; - sigset_t ss; int i, err; /* child */ @@ -1331,15 +1307,14 @@ int exec_spawn(ExecCommand *command, if (context->ignore_sigpipe) ignore_signals(SIGPIPE, -1); - assert_se(sigemptyset(&ss) == 0); - if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) { - err = -errno; + err = reset_signal_mask(); + if (err < 0) { r = EXIT_SIGNAL_MASK; goto fail_child; } - if (idle_pipe) - do_idle_pipe_dance(idle_pipe); + if (exec_params->idle_pipe) + do_idle_pipe_dance(exec_params->idle_pipe); /* Close sockets very early to make sure we don't * block init reexecution because it cannot bind its @@ -1372,26 +1347,9 @@ int exec_spawn(ExecCommand *command, goto fail_child; } - if (context->tcpwrap_name) { - if (socket_fd >= 0) - if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) { - err = -EACCES; - r = EXIT_TCPWRAP; - goto fail_child; - } - - for (i = 0; i < (int) n_fds; i++) { - if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) { - err = -EACCES; - r = EXIT_TCPWRAP; - goto fail_child; - } - } - } - exec_context_tty_reset(context); - if (confirm_spawn) { + if (exec_params->confirm_spawn) { char response; err = ask_for_confirmation(&response, argv); @@ -1416,26 +1374,26 @@ int exec_spawn(ExecCommand *command, if (socket_fd >= 0) fd_nonblock(socket_fd, false); - err = setup_input(context, socket_fd, apply_tty_stdin); + err = setup_input(context, socket_fd, exec_params->apply_tty_stdin); if (err < 0) { r = EXIT_STDIN; goto fail_child; } - err = setup_output(context, STDOUT_FILENO, socket_fd, basename(command->path), unit_id, apply_tty_stdin); + err = setup_output(context, STDOUT_FILENO, socket_fd, basename(command->path), exec_params->unit_id, exec_params->apply_tty_stdin); if (err < 0) { r = EXIT_STDOUT; goto fail_child; } - err = setup_output(context, STDERR_FILENO, socket_fd, basename(command->path), unit_id, apply_tty_stdin); + err = setup_output(context, STDERR_FILENO, socket_fd, basename(command->path), exec_params->unit_id, exec_params->apply_tty_stdin); if (err < 0) { r = EXIT_STDERR; goto fail_child; } - if (cgroup_path) { - err = cg_attach_everywhere(cgroup_supported, cgroup_path, 0); + if (exec_params->cgroup_path) { + err = cg_attach_everywhere(exec_params->cgroup_supported, exec_params->cgroup_path, 0); if (err < 0) { r = EXIT_CGROUP; goto fail_child; @@ -1493,7 +1451,7 @@ int exec_spawn(ExecCommand *command, goto fail_child; } - if (context->timer_slack_nsec != (nsec_t) -1) + if (context->timer_slack_nsec != NSEC_INFINITY) if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) { err = -errno; r = EXIT_TIMERSLACK; @@ -1528,15 +1486,15 @@ int exec_spawn(ExecCommand *command, } #ifdef HAVE_PAM - if (cgroup_path && context->user && context->pam_name) { - err = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, 0644, uid, gid); + if (exec_params->cgroup_path && context->user && context->pam_name) { + err = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, exec_params->cgroup_path, 0644, uid, gid); if (err < 0) { r = EXIT_CGROUP; goto fail_child; } - err = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, 0755, uid, gid); + err = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, exec_params->cgroup_path, 0755, uid, gid); if (err < 0) { r = EXIT_CGROUP; goto fail_child; @@ -1544,7 +1502,28 @@ int exec_spawn(ExecCommand *command, } #endif - if (apply_permissions) { + if (!strv_isempty(context->runtime_directory) && exec_params->runtime_prefix) { + char **rt; + + STRV_FOREACH(rt, context->runtime_directory) { + _cleanup_free_ char *p; + + p = strjoin(exec_params->runtime_prefix, "/", *rt, NULL); + if (!p) { + r = EXIT_RUNTIME_DIRECTORY; + err = -ENOMEM; + goto fail_child; + } + + err = mkdir_safe(p, context->runtime_directory_mode, uid, gid); + if (err < 0) { + r = EXIT_RUNTIME_DIRECTORY; + goto fail_child; + } + } + } + + if (exec_params->apply_permissions) { err = enforce_groups(context, username, gid); if (err < 0) { r = EXIT_GROUP; @@ -1555,7 +1534,7 @@ int exec_spawn(ExecCommand *command, umask(context->umask); #ifdef HAVE_PAM - if (apply_permissions && context->pam_name && username) { + if (exec_params->apply_permissions && context->pam_name && username) { err = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds); if (err < 0) { r = EXIT_PAM; @@ -1576,7 +1555,9 @@ int exec_spawn(ExecCommand *command, !strv_isempty(context->inaccessible_dirs) || context->mount_flags != 0 || (context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir)) || - context->private_devices) { + context->private_devices || + context->protect_system != PROTECT_SYSTEM_NO || + context->protect_home != PROTECT_HOME_NO) { char *tmp = NULL, *var = NULL; @@ -1600,15 +1581,16 @@ int exec_spawn(ExecCommand *command, tmp, var, context->private_devices, + context->protect_home, + context->protect_system, context->mount_flags); - if (err < 0) { r = EXIT_NAMESPACE; goto fail_child; } } - if (apply_chroot) { + if (exec_params->apply_chroot) { if (context->root_directory) if (chroot(context->root_directory) < 0) { err = -errno; @@ -1640,7 +1622,9 @@ int exec_spawn(ExecCommand *command, } /* We repeat the fd closing here, to make sure that - * nothing is leaked from the PAM modules */ + * nothing is leaked from the PAM modules. Note that + * we are more aggressive this time since socket_fd + * and the netns fds we don#t need anymore. */ err = close_all_fds(fds, n_fds); if (err >= 0) err = shift_fds(fds, n_fds); @@ -1651,9 +1635,9 @@ int exec_spawn(ExecCommand *command, goto fail_child; } - if (apply_permissions) { + if (exec_params->apply_permissions) { - for (i = 0; i < RLIMIT_NLIMITS; i++) { + for (i = 0; i < _RLIMIT_MAX; i++) { if (!context->rlimit[i]) continue; @@ -1706,7 +1690,8 @@ int exec_spawn(ExecCommand *command, } #ifdef HAVE_SECCOMP - if (context->address_families) { + if (context->address_families_whitelist || + !set_isempty(context->address_families)) { err = apply_address_families(context); if (err < 0) { r = EXIT_ADDRESS_FAMILIES; @@ -1714,7 +1699,9 @@ int exec_spawn(ExecCommand *command, } } - if (context->syscall_filter || context->syscall_archs) { + if (context->syscall_whitelist || + !set_isempty(context->syscall_filter) || + !set_isempty(context->syscall_archs)) { err = apply_seccomp(context); if (err < 0) { r = EXIT_SECCOMP; @@ -1744,14 +1731,14 @@ int exec_spawn(ExecCommand *command, #endif } - err = build_environment(context, n_fds, watchdog_usec, home, username, shell, &our_env); + err = build_environment(context, n_fds, exec_params->watchdog_usec, home, username, shell, &our_env); if (r < 0) { r = EXIT_MEMORY; goto fail_child; } final_env = strv_env_merge(5, - environment, + exec_params->environment, our_env, context->environment, files_env, @@ -1777,7 +1764,7 @@ int exec_spawn(ExecCommand *command, if (line) { log_open(); log_struct_unit(LOG_DEBUG, - unit_id, + exec_params->unit_id, "EXECUTABLE=%s", command->path, "MESSAGE=Executing: %s", line, NULL); @@ -1807,7 +1794,7 @@ int exec_spawn(ExecCommand *command, } log_struct_unit(LOG_DEBUG, - unit_id, + exec_params->unit_id, "MESSAGE=Forked %s as "PID_FMT, command->path, pid, NULL); @@ -1817,8 +1804,8 @@ int exec_spawn(ExecCommand *command, * outside of the cgroup) and in the parent (so that we can be * sure that when we kill the cgroup the process will be * killed too). */ - if (cgroup_path) - cg_attach(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, pid); + if (exec_params->cgroup_path) + cg_attach(SYSTEMD_CGROUP_CONTROLLER, exec_params->cgroup_path, pid); exec_status_start(&command->exec_status, pid); @@ -1835,8 +1822,9 @@ void exec_context_init(ExecContext *c) { c->syslog_priority = LOG_DAEMON|LOG_INFO; c->syslog_level_prefix = true; c->ignore_sigpipe = true; - c->timer_slack_nsec = (nsec_t) -1; + c->timer_slack_nsec = NSEC_INFINITY; c->personality = 0xffffffffUL; + c->runtime_directory_mode = 0755; } void exec_context_done(ExecContext *c) { @@ -1863,9 +1851,6 @@ void exec_context_done(ExecContext *c) { free(c->tty_path); c->tty_path = NULL; - free(c->tcpwrap_name); - c->tcpwrap_name = NULL; - free(c->syslog_identifier); c->syslog_identifier = NULL; @@ -1915,6 +1900,33 @@ void exec_context_done(ExecContext *c) { set_free(c->address_families); c->address_families = NULL; + + strv_free(c->runtime_directory); + c->runtime_directory = NULL; +} + +int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_prefix) { + char **i; + + assert(c); + + if (!runtime_prefix) + return 0; + + STRV_FOREACH(i, c->runtime_directory) { + _cleanup_free_ char *p; + + p = strjoin(runtime_prefix, "/", *i, NULL); + if (!p) + return -ENOMEM; + + /* We execute this synchronously, since we need to be + * sure this is gone when we start the service + * next. */ + rm_rf_dangerous(p, false, true, false); + } + + return 0; } void exec_command_done(ExecCommand *c) { @@ -2000,7 +2012,7 @@ int exec_context_load_environment(const ExecContext *c, char ***l) { return -EINVAL; } for (n = 0; n < count; n++) { - k = load_env_file(pglob.gl_pathv[n], NULL, &p); + k = load_env_file(NULL, pglob.gl_pathv[n], NULL, &p); if (k < 0) { if (ignore) continue; @@ -2034,8 +2046,8 @@ int exec_context_load_environment(const ExecContext *c, char ***l) { } static bool tty_may_match_dev_console(const char *tty) { - char *active = NULL, *console; - bool b; + _cleanup_free_ char *active = NULL; + char *console; if (startswith(tty, "/dev/")) tty += 5; @@ -2050,10 +2062,7 @@ static bool tty_may_match_dev_console(const char *tty) { return true; /* "tty0" means the active VC, so it may be the same sometimes */ - b = streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty)); - free(active); - - return b; + return streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty)); } bool exec_context_may_touch_console(ExecContext *ec) { @@ -2090,6 +2099,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { "%sPrivateTmp: %s\n" "%sPrivateNetwork: %s\n" "%sPrivateDevices: %s\n" + "%sProtectHome: %s\n" + "%sProtectSystem: %s\n" "%sIgnoreSIGPIPE: %s\n", prefix, c->umask, prefix, c->working_directory ? c->working_directory : "/", @@ -2098,6 +2109,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { prefix, yes_no(c->private_tmp), prefix, yes_no(c->private_network), prefix, yes_no(c->private_devices), + prefix, protect_home_to_string(c->protect_home), + prefix, protect_system_to_string(c->protect_system), prefix, yes_no(c->ignore_sigpipe)); STRV_FOREACH(e, c->environment) @@ -2106,11 +2119,6 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { STRV_FOREACH(e, c->environment_files) fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e); - if (c->tcpwrap_name) - fprintf(f, - "%sTCPWrapName: %s\n", - prefix, c->tcpwrap_name); - if (c->nice_set) fprintf(f, "%sNice: %i\n", @@ -2123,7 +2131,8 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { for (i = 0; i < RLIM_NLIMITS; i++) if (c->rlimit[i]) - fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max); + fprintf(f, "%s%s: "RLIM_FMT"\n", + prefix, rlimit_to_string(i), c->rlimit[i]->rlim_max); if (c->ioprio_set) { _cleanup_free_ char *class_str = NULL; @@ -2157,7 +2166,7 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) { fputs("\n", f); } - if (c->timer_slack_nsec != (nsec_t) -1) + if (c->timer_slack_nsec != NSEC_INFINITY) fprintf(f, "%sTimerSlackNSec: "NSEC_FMT "\n", prefix, c->timer_slack_nsec); fprintf(f, @@ -2378,12 +2387,11 @@ void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) { assert(s); assert(f); - if (!prefix) - prefix = ""; - if (s->pid <= 0) return; + prefix = strempty(prefix); + fprintf(f, "%sPID: "PID_FMT"\n", prefix, s->pid); @@ -2443,37 +2451,27 @@ char *exec_command_line(char **argv) { } void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) { - char *p2; + _cleanup_free_ char *cmd = NULL; const char *prefix2; - char *cmd; - assert(c); assert(f); - if (!prefix) - prefix = ""; - p2 = strappend(prefix, "\t"); - prefix2 = p2 ? p2 : prefix; + prefix = strempty(prefix); + prefix2 = strappenda(prefix, "\t"); cmd = exec_command_line(c->argv); - fprintf(f, "%sCommand Line: %s\n", prefix, cmd ? cmd : strerror(ENOMEM)); - free(cmd); - exec_status_dump(&c->exec_status, f, prefix2); - - free(p2); } void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) { assert(f); - if (!prefix) - prefix = ""; + prefix = strempty(prefix); LIST_FOREACH(command, c, c) exec_command_dump(c, f, prefix); @@ -2587,7 +2585,7 @@ ExecRuntime *exec_runtime_unref(ExecRuntime *r) { if (r->n_ref <= 0) { free(r->tmp_dir); free(r->var_tmp_dir); - close_pipe(r->netns_storage_socket); + safe_close_pair(r->netns_storage_socket); free(r); } @@ -2676,9 +2674,7 @@ int exec_runtime_deserialize_item(ExecRuntime **rt, Unit *u, const char *key, co if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd)) log_debug_unit(u->id, "Failed to parse netns socket value %s", value); else { - if ((*rt)->netns_storage_socket[0] >= 0) - close_nointr_nofail((*rt)->netns_storage_socket[0]); - + safe_close((*rt)->netns_storage_socket[0]); (*rt)->netns_storage_socket[0] = fdset_remove(fds, fd); } } else if (streq(key, "netns-socket-1")) { @@ -2691,9 +2687,7 @@ int exec_runtime_deserialize_item(ExecRuntime **rt, Unit *u, const char *key, co if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd)) log_debug_unit(u->id, "Failed to parse netns socket value %s", value); else { - if ((*rt)->netns_storage_socket[1] >= 0) - close_nointr_nofail((*rt)->netns_storage_socket[1]); - + safe_close((*rt)->netns_storage_socket[1]); (*rt)->netns_storage_socket[1] = fdset_remove(fds, fd); } } else @@ -2710,6 +2704,8 @@ static void *remove_tmpdir_thread(void *p) { } void exec_runtime_destroy(ExecRuntime *rt) { + int r; + if (!rt) return; @@ -2719,17 +2715,29 @@ void exec_runtime_destroy(ExecRuntime *rt) { if (rt->tmp_dir) { log_debug("Spawning thread to nuke %s", rt->tmp_dir); - asynchronous_job(remove_tmpdir_thread, rt->tmp_dir); + + r = asynchronous_job(remove_tmpdir_thread, rt->tmp_dir); + if (r < 0) { + log_warning("Failed to nuke %s: %s", rt->tmp_dir, strerror(-r)); + free(rt->tmp_dir); + } + rt->tmp_dir = NULL; } if (rt->var_tmp_dir) { log_debug("Spawning thread to nuke %s", rt->var_tmp_dir); - asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir); + + r = asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir); + if (r < 0) { + log_warning("Failed to nuke %s: %s", rt->var_tmp_dir, strerror(-r)); + free(rt->var_tmp_dir); + } + rt->var_tmp_dir = NULL; } - close_pipe(rt->netns_storage_socket); + safe_close_pair(rt->netns_storage_socket); } static const char* const exec_input_table[_EXEC_INPUT_MAX] = {