1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
29 #include <sys/socket.h>
31 #include <sys/prctl.h>
32 #include <linux/sched.h>
33 #include <sys/types.h>
37 #include <sys/mount.h>
39 #include <linux/oom.h>
41 #include <linux/seccomp-bpf.h>
46 #include <security/pam_appl.h>
52 #include "capability.h"
55 #include "sd-messages.h"
57 #include "securebits.h"
58 #include "namespace.h"
60 #include "exit-status.h"
62 #include "utmp-wtmp.h"
64 #include "path-util.h"
65 #include "syscall-list.h"
71 #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
72 #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
74 /* This assumes there is a 'tty' group */
77 static int shift_fds(int fds[], unsigned n_fds) {
78 int start, restart_from;
83 /* Modifies the fds array! (sorts it) */
93 for (i = start; i < (int) n_fds; i++) {
96 /* Already at right index? */
100 if ((nfd = fcntl(fds[i], F_DUPFD, i+3)) < 0)
103 close_nointr_nofail(fds[i]);
106 /* Hmm, the fd we wanted isn't free? Then
107 * let's remember that and try again from here*/
108 if (nfd != i+3 && restart_from < 0)
112 if (restart_from < 0)
115 start = restart_from;
121 static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) {
130 /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
132 for (i = 0; i < n_fds; i++) {
134 if ((r = fd_nonblock(fds[i], nonblock)) < 0)
137 /* We unconditionally drop FD_CLOEXEC from the fds,
138 * since after all we want to pass these fds to our
141 if ((r = fd_cloexec(fds[i], false)) < 0)
148 _pure_ static const char *tty_path(const ExecContext *context) {
151 if (context->tty_path)
152 return context->tty_path;
154 return "/dev/console";
157 static void exec_context_tty_reset(const ExecContext *context) {
160 if (context->tty_vhangup)
161 terminal_vhangup(tty_path(context));
163 if (context->tty_reset)
164 reset_terminal(tty_path(context));
166 if (context->tty_vt_disallocate && context->tty_path)
167 vt_disallocate(context->tty_path);
170 static bool is_terminal_output(ExecOutput o) {
172 o == EXEC_OUTPUT_TTY ||
173 o == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
174 o == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
175 o == EXEC_OUTPUT_JOURNAL_AND_CONSOLE;
178 static int open_null_as(int flags, int nfd) {
183 fd = open("/dev/null", flags|O_NOCTTY);
188 r = dup2(fd, nfd) < 0 ? -errno : nfd;
189 close_nointr_nofail(fd);
196 static int connect_logger_as(const ExecContext *context, ExecOutput output, const char *ident, const char *unit_id, int nfd) {
198 union sockaddr_union sa = {
199 .un.sun_family = AF_UNIX,
200 .un.sun_path = "/run/systemd/journal/stdout",
204 assert(output < _EXEC_OUTPUT_MAX);
208 fd = socket(AF_UNIX, SOCK_STREAM, 0);
212 r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
214 close_nointr_nofail(fd);
218 if (shutdown(fd, SHUT_RD) < 0) {
219 close_nointr_nofail(fd);
231 context->syslog_identifier ? context->syslog_identifier : ident,
233 context->syslog_priority,
234 !!context->syslog_level_prefix,
235 output == EXEC_OUTPUT_SYSLOG || output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
236 output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE,
237 is_terminal_output(output));
240 r = dup2(fd, nfd) < 0 ? -errno : nfd;
241 close_nointr_nofail(fd);
247 static int open_terminal_as(const char *path, mode_t mode, int nfd) {
253 if ((fd = open_terminal(path, mode | O_NOCTTY)) < 0)
257 r = dup2(fd, nfd) < 0 ? -errno : nfd;
258 close_nointr_nofail(fd);
265 static bool is_terminal_input(ExecInput i) {
267 i == EXEC_INPUT_TTY ||
268 i == EXEC_INPUT_TTY_FORCE ||
269 i == EXEC_INPUT_TTY_FAIL;
272 static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) {
274 if (is_terminal_input(std_input) && !apply_tty_stdin)
275 return EXEC_INPUT_NULL;
277 if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0)
278 return EXEC_INPUT_NULL;
283 static int fixup_output(ExecOutput std_output, int socket_fd) {
285 if (std_output == EXEC_OUTPUT_SOCKET && socket_fd < 0)
286 return EXEC_OUTPUT_INHERIT;
291 static int setup_input(const ExecContext *context, int socket_fd, bool apply_tty_stdin) {
296 i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
300 case EXEC_INPUT_NULL:
301 return open_null_as(O_RDONLY, STDIN_FILENO);
304 case EXEC_INPUT_TTY_FORCE:
305 case EXEC_INPUT_TTY_FAIL: {
308 fd = acquire_terminal(tty_path(context),
309 i == EXEC_INPUT_TTY_FAIL,
310 i == EXEC_INPUT_TTY_FORCE,
316 if (fd != STDIN_FILENO) {
317 r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
318 close_nointr_nofail(fd);
325 case EXEC_INPUT_SOCKET:
326 return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
329 assert_not_reached("Unknown input type");
333 static int setup_output(const ExecContext *context, int fileno, int socket_fd, const char *ident, const char *unit_id, bool apply_tty_stdin) {
341 i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
342 o = fixup_output(context->std_output, socket_fd);
344 if (fileno == STDERR_FILENO) {
346 e = fixup_output(context->std_error, socket_fd);
348 /* This expects the input and output are already set up */
350 /* Don't change the stderr file descriptor if we inherit all
351 * the way and are not on a tty */
352 if (e == EXEC_OUTPUT_INHERIT &&
353 o == EXEC_OUTPUT_INHERIT &&
354 i == EXEC_INPUT_NULL &&
355 !is_terminal_input(context->std_input) &&
359 /* Duplicate from stdout if possible */
360 if (e == o || e == EXEC_OUTPUT_INHERIT)
361 return dup2(STDOUT_FILENO, fileno) < 0 ? -errno : fileno;
365 } else if (o == EXEC_OUTPUT_INHERIT) {
366 /* If input got downgraded, inherit the original value */
367 if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input))
368 return open_terminal_as(tty_path(context), O_WRONLY, fileno);
370 /* If the input is connected to anything that's not a /dev/null, inherit that... */
371 if (i != EXEC_INPUT_NULL)
372 return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
374 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
378 /* We need to open /dev/null here anew, to get the right access mode. */
379 return open_null_as(O_WRONLY, fileno);
384 case EXEC_OUTPUT_NULL:
385 return open_null_as(O_WRONLY, fileno);
387 case EXEC_OUTPUT_TTY:
388 if (is_terminal_input(i))
389 return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
391 /* We don't reset the terminal if this is just about output */
392 return open_terminal_as(tty_path(context), O_WRONLY, fileno);
394 case EXEC_OUTPUT_SYSLOG:
395 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE:
396 case EXEC_OUTPUT_KMSG:
397 case EXEC_OUTPUT_KMSG_AND_CONSOLE:
398 case EXEC_OUTPUT_JOURNAL:
399 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE:
400 r = connect_logger_as(context, o, ident, unit_id, fileno);
402 log_struct_unit(LOG_CRIT, unit_id,
403 "MESSAGE=Failed to connect std%s of %s to the journal socket: %s",
404 fileno == STDOUT_FILENO ? "out" : "err",
405 unit_id, strerror(-r),
408 r = open_null_as(O_WRONLY, fileno);
412 case EXEC_OUTPUT_SOCKET:
413 assert(socket_fd >= 0);
414 return dup2(socket_fd, fileno) < 0 ? -errno : fileno;
417 assert_not_reached("Unknown error type");
421 static int chown_terminal(int fd, uid_t uid) {
426 /* This might fail. What matters are the results. */
427 (void) fchown(fd, uid, -1);
428 (void) fchmod(fd, TTY_MODE);
430 if (fstat(fd, &st) < 0)
433 if (st.st_uid != uid || (st.st_mode & 0777) != TTY_MODE)
439 static int setup_confirm_stdio(int *_saved_stdin,
440 int *_saved_stdout) {
441 int fd = -1, saved_stdin, saved_stdout = -1, r;
443 assert(_saved_stdin);
444 assert(_saved_stdout);
446 saved_stdin = fcntl(STDIN_FILENO, F_DUPFD, 3);
450 saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD, 3);
451 if (saved_stdout < 0) {
456 fd = acquire_terminal(
461 DEFAULT_CONFIRM_USEC);
467 r = chown_terminal(fd, getuid());
471 if (dup2(fd, STDIN_FILENO) < 0) {
476 if (dup2(fd, STDOUT_FILENO) < 0) {
482 close_nointr_nofail(fd);
484 *_saved_stdin = saved_stdin;
485 *_saved_stdout = saved_stdout;
490 if (saved_stdout >= 0)
491 close_nointr_nofail(saved_stdout);
493 if (saved_stdin >= 0)
494 close_nointr_nofail(saved_stdin);
497 close_nointr_nofail(fd);
502 _printf_(1, 2) static int write_confirm_message(const char *format, ...) {
508 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
512 va_start(ap, format);
513 vdprintf(fd, format, ap);
516 close_nointr_nofail(fd);
521 static int restore_confirm_stdio(int *saved_stdin,
527 assert(saved_stdout);
531 if (*saved_stdin >= 0)
532 if (dup2(*saved_stdin, STDIN_FILENO) < 0)
535 if (*saved_stdout >= 0)
536 if (dup2(*saved_stdout, STDOUT_FILENO) < 0)
539 if (*saved_stdin >= 0)
540 close_nointr_nofail(*saved_stdin);
542 if (*saved_stdout >= 0)
543 close_nointr_nofail(*saved_stdout);
548 static int ask_for_confirmation(char *response, char **argv) {
549 int saved_stdout = -1, saved_stdin = -1, r;
552 r = setup_confirm_stdio(&saved_stdin, &saved_stdout);
556 line = exec_command_line(argv);
560 r = ask(response, "yns", "Execute %s? [Yes, No, Skip] ", line);
563 restore_confirm_stdio(&saved_stdin, &saved_stdout);
568 static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) {
569 bool keep_groups = false;
574 /* Lookup and set GID and supplementary group list. Here too
575 * we avoid NSS lookups for gid=0. */
577 if (context->group || username) {
579 if (context->group) {
580 const char *g = context->group;
582 if ((r = get_group_creds(&g, &gid)) < 0)
586 /* First step, initialize groups from /etc/groups */
587 if (username && gid != 0) {
588 if (initgroups(username, gid) < 0)
594 /* Second step, set our gids */
595 if (setresgid(gid, gid, gid) < 0)
599 if (context->supplementary_groups) {
604 /* Final step, initialize any manually set supplementary groups */
605 assert_se((ngroups_max = (int) sysconf(_SC_NGROUPS_MAX)) > 0);
607 if (!(gids = new(gid_t, ngroups_max)))
611 if ((k = getgroups(ngroups_max, gids)) < 0) {
618 STRV_FOREACH(i, context->supplementary_groups) {
621 if (k >= ngroups_max) {
627 r = get_group_creds(&g, gids+k);
636 if (setgroups(k, gids) < 0) {
647 static int enforce_user(const ExecContext *context, uid_t uid) {
651 /* Sets (but doesn't lookup) the uid and make sure we keep the
652 * capabilities while doing so. */
654 if (context->capabilities) {
656 static const cap_value_t bits[] = {
657 CAP_SETUID, /* Necessary so that we can run setresuid() below */
658 CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */
661 /* First step: If we need to keep capabilities but
662 * drop privileges we need to make sure we keep our
663 * caps, while we drop privileges. */
665 int sb = context->secure_bits | 1<<SECURE_KEEP_CAPS;
667 if (prctl(PR_GET_SECUREBITS) != sb)
668 if (prctl(PR_SET_SECUREBITS, sb) < 0)
672 /* Second step: set the capabilities. This will reduce
673 * the capabilities to the minimum we need. */
675 if (!(d = cap_dup(context->capabilities)))
678 if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 ||
679 cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0) {
685 if (cap_set_proc(d) < 0) {
694 /* Third step: actually set the uids */
695 if (setresuid(uid, uid, uid) < 0)
698 /* At this point we should have all necessary capabilities but
699 are otherwise a normal user. However, the caps might got
700 corrupted due to the setresuid() so we need clean them up
701 later. This is done outside of this call. */
708 static int null_conv(
710 const struct pam_message **msg,
711 struct pam_response **resp,
714 /* We don't support conversations */
719 static int setup_pam(
725 int fds[], unsigned n_fds) {
727 static const struct pam_conv conv = {
732 pam_handle_t *handle = NULL;
734 int pam_code = PAM_SUCCESS;
737 bool close_session = false;
738 pid_t pam_pid = 0, parent_pid;
745 /* We set up PAM in the parent process, then fork. The child
746 * will then stay around until killed via PR_GET_PDEATHSIG or
747 * systemd via the cgroup logic. It will then remove the PAM
748 * session again. The parent process will exec() the actual
749 * daemon. We do things this way to ensure that the main PID
750 * of the daemon is the one we initially fork()ed. */
752 if (log_get_max_level() < LOG_PRI(LOG_DEBUG))
755 pam_code = pam_start(name, user, &conv, &handle);
756 if (pam_code != PAM_SUCCESS) {
762 pam_code = pam_set_item(handle, PAM_TTY, tty);
763 if (pam_code != PAM_SUCCESS)
767 pam_code = pam_acct_mgmt(handle, flags);
768 if (pam_code != PAM_SUCCESS)
771 pam_code = pam_open_session(handle, flags);
772 if (pam_code != PAM_SUCCESS)
775 close_session = true;
777 e = pam_getenvlist(handle);
779 pam_code = PAM_BUF_ERR;
783 /* Block SIGTERM, so that we know that it won't get lost in
785 if (sigemptyset(&ss) < 0 ||
786 sigaddset(&ss, SIGTERM) < 0 ||
787 sigprocmask(SIG_BLOCK, &ss, &old_ss) < 0)
790 parent_pid = getpid();
800 /* The child's job is to reset the PAM session on
803 /* This string must fit in 10 chars (i.e. the length
804 * of "/sbin/init"), to look pretty in /bin/ps */
805 rename_process("(sd-pam)");
807 /* Make sure we don't keep open the passed fds in this
808 child. We assume that otherwise only those fds are
809 open here that have been opened by PAM. */
810 close_many(fds, n_fds);
812 /* Drop privileges - we don't need any to pam_close_session
813 * and this will make PR_SET_PDEATHSIG work in most cases.
814 * If this fails, ignore the error - but expect sd-pam threads
815 * to fail to exit normally */
816 if (setresuid(uid, uid, uid) < 0)
817 log_error("Error: Failed to setresuid() in sd-pam: %s", strerror(-r));
819 /* Wait until our parent died. This will only work if
820 * the above setresuid() succeeds, otherwise the kernel
821 * will not allow unprivileged parents kill their privileged
822 * children this way. We rely on the control groups kill logic
823 * to do the rest for us. */
824 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
827 /* Check if our parent process might already have
829 if (getppid() == parent_pid) {
831 if (sigwait(&ss, &sig) < 0) {
838 assert(sig == SIGTERM);
843 /* If our parent died we'll end the session */
844 if (getppid() != parent_pid) {
845 pam_code = pam_close_session(handle, flags);
846 if (pam_code != PAM_SUCCESS)
853 pam_end(handle, pam_code | flags);
857 /* If the child was forked off successfully it will do all the
858 * cleanups, so forget about the handle here. */
861 /* Unblock SIGTERM again in the parent */
862 if (sigprocmask(SIG_SETMASK, &old_ss, NULL) < 0)
865 /* We close the log explicitly here, since the PAM modules
866 * might have opened it, but we don't want this fd around. */
875 if (pam_code != PAM_SUCCESS) {
876 log_error("PAM failed: %s", pam_strerror(handle, pam_code));
877 err = -EPERM; /* PAM errors do not map to errno */
879 log_error("PAM failed: %m");
885 pam_code = pam_close_session(handle, flags);
887 pam_end(handle, pam_code | flags);
895 kill(pam_pid, SIGTERM);
896 kill(pam_pid, SIGCONT);
903 static void rename_process_from_path(const char *path) {
904 char process_name[11];
908 /* This resulting string must fit in 10 chars (i.e. the length
909 * of "/sbin/init") to look pretty in /bin/ps */
911 p = path_get_file_name(path);
913 rename_process("(...)");
919 /* The end of the process name is usually more
920 * interesting, since the first bit might just be
926 process_name[0] = '(';
927 memcpy(process_name+1, p, l);
928 process_name[1+l] = ')';
929 process_name[1+l+1] = 0;
931 rename_process(process_name);
934 static int apply_seccomp(uint32_t *syscall_filter) {
935 static const struct sock_filter header[] = {
936 VALIDATE_ARCHITECTURE,
939 static const struct sock_filter footer[] = {
945 struct sock_filter *f;
946 struct sock_fprog prog = {};
948 assert(syscall_filter);
950 /* First: count the syscalls to check for */
951 for (i = 0, n = 0; i < syscall_max(); i++)
952 if (syscall_filter[i >> 4] & (1 << (i & 31)))
955 /* Second: build the filter program from a header the syscall
956 * matches and the footer */
957 f = alloca(sizeof(struct sock_filter) * (ELEMENTSOF(header) + 2*n + ELEMENTSOF(footer)));
958 memcpy(f, header, sizeof(header));
960 for (i = 0, n = 0; i < syscall_max(); i++)
961 if (syscall_filter[i >> 4] & (1 << (i & 31))) {
962 struct sock_filter item[] = {
963 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, INDEX_TO_SYSCALL(i), 0, 1),
964 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
967 assert_cc(ELEMENTSOF(item) == 2);
969 f[ELEMENTSOF(header) + 2*n] = item[0];
970 f[ELEMENTSOF(header) + 2*n+1] = item[1];
975 memcpy(f + (ELEMENTSOF(header) + 2*n), footer, sizeof(footer));
977 /* Third: install the filter */
978 prog.len = ELEMENTSOF(header) + ELEMENTSOF(footer) + 2*n;
980 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0)
986 static void do_idle_pipe_dance(int idle_pipe[4]) {
989 if (idle_pipe[1] >= 0)
990 close_nointr_nofail(idle_pipe[1]);
991 if (idle_pipe[2] >= 0)
992 close_nointr_nofail(idle_pipe[2]);
994 if (idle_pipe[0] >= 0) {
997 r = fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
999 if (idle_pipe[3] >= 0 && r == 0 /* timeout */) {
1000 /* Signal systemd that we are bored and want to continue. */
1001 write(idle_pipe[3], "x", 1);
1003 /* Wait for systemd to react to the signal above. */
1004 fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT2_USEC);
1007 close_nointr_nofail(idle_pipe[0]);
1011 if (idle_pipe[3] >= 0)
1012 close_nointr_nofail(idle_pipe[3]);
1015 int exec_spawn(ExecCommand *command,
1017 ExecContext *context,
1018 int fds[], unsigned n_fds,
1020 bool apply_permissions,
1022 bool apply_tty_stdin,
1024 CGroupControllerMask cgroup_supported,
1025 const char *cgroup_path,
1026 const char *unit_id,
1028 ExecRuntime *runtime,
1031 _cleanup_strv_free_ char **files_env = NULL;
1040 assert(fds || n_fds <= 0);
1042 if (context->std_input == EXEC_INPUT_SOCKET ||
1043 context->std_output == EXEC_OUTPUT_SOCKET ||
1044 context->std_error == EXEC_OUTPUT_SOCKET) {
1056 r = exec_context_load_environment(context, &files_env);
1058 log_struct_unit(LOG_ERR,
1060 "MESSAGE=Failed to load environment files: %s", strerror(-r),
1067 argv = command->argv;
1069 line = exec_command_line(argv);
1073 log_struct_unit(LOG_DEBUG,
1075 "EXECUTABLE=%s", command->path,
1076 "MESSAGE=About to execute: %s", line,
1085 _cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
1086 const char *username = NULL, *home = NULL, *shell = NULL;
1087 unsigned n_dont_close = 0, n_env = 0;
1088 int dont_close[n_fds + 3];
1089 uid_t uid = (uid_t) -1;
1090 gid_t gid = (gid_t) -1;
1096 rename_process_from_path(command->path);
1098 /* We reset exactly these signals, since they are the
1099 * only ones we set to SIG_IGN in the main daemon. All
1100 * others we leave untouched because we set them to
1101 * SIG_DFL or a valid handler initially, both of which
1102 * will be demoted to SIG_DFL. */
1103 default_signals(SIGNALS_CRASH_HANDLER,
1104 SIGNALS_IGNORE, -1);
1106 if (context->ignore_sigpipe)
1107 ignore_signals(SIGPIPE, -1);
1109 assert_se(sigemptyset(&ss) == 0);
1110 if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) {
1112 r = EXIT_SIGNAL_MASK;
1117 do_idle_pipe_dance(idle_pipe);
1119 /* Close sockets very early to make sure we don't
1120 * block init reexecution because it cannot bind its
1125 dont_close[n_dont_close++] = socket_fd;
1127 memcpy(dont_close + n_dont_close, fds, sizeof(int) * n_fds);
1128 n_dont_close += n_fds;
1131 if (runtime->netns_storage_socket[0] >= 0)
1132 dont_close[n_dont_close++] = runtime->netns_storage_socket[0];
1133 if (runtime->netns_storage_socket[1] >= 0)
1134 dont_close[n_dont_close++] = runtime->netns_storage_socket[1];
1137 err = close_all_fds(dont_close, n_dont_close);
1143 if (!context->same_pgrp)
1150 if (context->tcpwrap_name) {
1152 if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) {
1158 for (i = 0; i < (int) n_fds; i++) {
1159 if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) {
1167 exec_context_tty_reset(context);
1169 if (confirm_spawn) {
1172 err = ask_for_confirmation(&response, argv);
1173 if (err == -ETIMEDOUT)
1174 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1176 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-err));
1177 else if (response == 's') {
1178 write_confirm_message("Skipping execution.\n");
1182 } else if (response == 'n') {
1183 write_confirm_message("Failing execution.\n");
1189 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1190 * must sure to drop O_NONBLOCK */
1192 fd_nonblock(socket_fd, false);
1194 err = setup_input(context, socket_fd, apply_tty_stdin);
1200 err = setup_output(context, STDOUT_FILENO, socket_fd, path_get_file_name(command->path), unit_id, apply_tty_stdin);
1206 err = setup_output(context, STDERR_FILENO, socket_fd, path_get_file_name(command->path), unit_id, apply_tty_stdin);
1213 err = cg_attach_everywhere(cgroup_supported, cgroup_path, 0);
1220 if (context->oom_score_adjust_set) {
1223 snprintf(t, sizeof(t), "%i", context->oom_score_adjust);
1226 if (write_string_file("/proc/self/oom_score_adj", t) < 0) {
1228 r = EXIT_OOM_ADJUST;
1233 if (context->nice_set)
1234 if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) {
1240 if (context->cpu_sched_set) {
1241 struct sched_param param = {
1242 .sched_priority = context->cpu_sched_priority,
1245 r = sched_setscheduler(0,
1246 context->cpu_sched_policy |
1247 (context->cpu_sched_reset_on_fork ?
1248 SCHED_RESET_ON_FORK : 0),
1252 r = EXIT_SETSCHEDULER;
1257 if (context->cpuset)
1258 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
1260 r = EXIT_CPUAFFINITY;
1264 if (context->ioprio_set)
1265 if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
1271 if (context->timer_slack_nsec != (nsec_t) -1)
1272 if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
1274 r = EXIT_TIMERSLACK;
1278 if (context->utmp_id)
1279 utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path);
1281 if (context->user) {
1282 username = context->user;
1283 err = get_user_creds(&username, &uid, &gid, &home, &shell);
1289 if (is_terminal_input(context->std_input)) {
1290 err = chown_terminal(STDIN_FILENO, uid);
1299 if (cgroup_path && context->user && context->pam_name) {
1300 err = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, 0644, uid, gid);
1307 err = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, 0755, uid, gid);
1315 if (apply_permissions) {
1316 err = enforce_groups(context, username, gid);
1323 umask(context->umask);
1326 if (apply_permissions && context->pam_name && username) {
1327 err = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
1334 if (context->private_network && runtime && runtime->netns_storage_socket[0] >= 0) {
1335 err = setup_netns(runtime->netns_storage_socket);
1342 if (!strv_isempty(context->read_write_dirs) ||
1343 !strv_isempty(context->read_only_dirs) ||
1344 !strv_isempty(context->inaccessible_dirs) ||
1345 context->mount_flags != 0 ||
1346 (context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir))) {
1348 char *tmp = NULL, *var = NULL;
1350 /* The runtime struct only contains the parent
1351 * of the private /tmp, which is
1352 * non-accessible to world users. Inside of it
1353 * there's a /tmp that is sticky, and that's
1354 * the one we want to use here. */
1356 if (context->private_tmp && runtime) {
1357 if (runtime->tmp_dir)
1358 tmp = strappenda(runtime->tmp_dir, "/tmp");
1359 if (runtime->var_tmp_dir)
1360 var = strappenda(runtime->var_tmp_dir, "/tmp");
1363 err = setup_namespace(
1364 context->read_write_dirs,
1365 context->read_only_dirs,
1366 context->inaccessible_dirs,
1369 context->mount_flags);
1378 if (context->root_directory)
1379 if (chroot(context->root_directory) < 0) {
1385 if (chdir(context->working_directory ? context->working_directory : "/") < 0) {
1391 _cleanup_free_ char *d = NULL;
1393 if (asprintf(&d, "%s/%s",
1394 context->root_directory ? context->root_directory : "",
1395 context->working_directory ? context->working_directory : "") < 0) {
1408 /* We repeat the fd closing here, to make sure that
1409 * nothing is leaked from the PAM modules */
1410 err = close_all_fds(fds, n_fds);
1412 err = shift_fds(fds, n_fds);
1414 err = flags_fds(fds, n_fds, context->non_blocking);
1420 if (apply_permissions) {
1422 for (i = 0; i < RLIMIT_NLIMITS; i++) {
1423 if (!context->rlimit[i])
1426 if (setrlimit_closest(i, context->rlimit[i]) < 0) {
1433 if (context->capability_bounding_set_drop) {
1434 err = capability_bounding_set_drop(context->capability_bounding_set_drop, false);
1436 r = EXIT_CAPABILITIES;
1441 if (context->user) {
1442 err = enforce_user(context, uid);
1449 /* PR_GET_SECUREBITS is not privileged, while
1450 * PR_SET_SECUREBITS is. So to suppress
1451 * potential EPERMs we'll try not to call
1452 * PR_SET_SECUREBITS unless necessary. */
1453 if (prctl(PR_GET_SECUREBITS) != context->secure_bits)
1454 if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) {
1456 r = EXIT_SECUREBITS;
1460 if (context->capabilities)
1461 if (cap_set_proc(context->capabilities) < 0) {
1463 r = EXIT_CAPABILITIES;
1467 if (context->no_new_privileges)
1468 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
1470 r = EXIT_NO_NEW_PRIVILEGES;
1474 if (context->syscall_filter) {
1475 err = apply_seccomp(context->syscall_filter);
1483 our_env = new(char*, 8);
1486 asprintf(our_env + n_env++, "LISTEN_PID=%lu", (unsigned long) getpid()) < 0 ||
1487 asprintf(our_env + n_env++, "LISTEN_FDS=%u", n_fds) < 0)) ||
1488 (home && asprintf(our_env + n_env++, "HOME=%s", home) < 0) ||
1490 asprintf(our_env + n_env++, "LOGNAME=%s", username) < 0 ||
1491 asprintf(our_env + n_env++, "USER=%s", username) < 0)) ||
1492 (shell && asprintf(our_env + n_env++, "SHELL=%s", shell) < 0) ||
1493 ((is_terminal_input(context->std_input) ||
1494 context->std_output == EXEC_OUTPUT_TTY ||
1495 context->std_error == EXEC_OUTPUT_TTY) && (
1496 !(our_env[n_env++] = strdup(default_term_for_tty(tty_path(context))))))) {
1503 our_env[n_env++] = NULL;
1506 final_env = strv_env_merge(5,
1509 context->environment,
1519 final_argv = replace_env_argv(argv, final_env);
1526 final_env = strv_env_clean(final_env);
1528 if (_unlikely_(log_get_max_level() >= LOG_PRI(LOG_DEBUG))) {
1529 line = exec_command_line(final_argv);
1532 log_struct_unit(LOG_DEBUG,
1534 "EXECUTABLE=%s", command->path,
1535 "MESSAGE=Executing: %s", line,
1542 execve(command->path, final_argv, final_env);
1549 log_struct(LOG_ERR, MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED),
1550 "EXECUTABLE=%s", command->path,
1551 "MESSAGE=Failed at step %s spawning %s: %s",
1552 exit_status_to_string(r, EXIT_STATUS_SYSTEMD),
1553 command->path, strerror(-err),
1562 log_struct_unit(LOG_DEBUG,
1564 "MESSAGE=Forked %s as %lu",
1565 command->path, (unsigned long) pid,
1568 /* We add the new process to the cgroup both in the child (so
1569 * that we can be sure that no user code is ever executed
1570 * outside of the cgroup) and in the parent (so that we can be
1571 * sure that when we kill the cgroup the process will be
1574 cg_attach(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, pid);
1576 exec_status_start(&command->exec_status, pid);
1582 void exec_context_init(ExecContext *c) {
1586 c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0);
1587 c->cpu_sched_policy = SCHED_OTHER;
1588 c->syslog_priority = LOG_DAEMON|LOG_INFO;
1589 c->syslog_level_prefix = true;
1590 c->ignore_sigpipe = true;
1591 c->timer_slack_nsec = (nsec_t) -1;
1594 void exec_context_done(ExecContext *c) {
1599 strv_free(c->environment);
1600 c->environment = NULL;
1602 strv_free(c->environment_files);
1603 c->environment_files = NULL;
1605 for (l = 0; l < ELEMENTSOF(c->rlimit); l++) {
1607 c->rlimit[l] = NULL;
1610 free(c->working_directory);
1611 c->working_directory = NULL;
1612 free(c->root_directory);
1613 c->root_directory = NULL;
1618 free(c->tcpwrap_name);
1619 c->tcpwrap_name = NULL;
1621 free(c->syslog_identifier);
1622 c->syslog_identifier = NULL;
1630 strv_free(c->supplementary_groups);
1631 c->supplementary_groups = NULL;
1636 if (c->capabilities) {
1637 cap_free(c->capabilities);
1638 c->capabilities = NULL;
1641 strv_free(c->read_only_dirs);
1642 c->read_only_dirs = NULL;
1644 strv_free(c->read_write_dirs);
1645 c->read_write_dirs = NULL;
1647 strv_free(c->inaccessible_dirs);
1648 c->inaccessible_dirs = NULL;
1651 CPU_FREE(c->cpuset);
1656 free(c->syscall_filter);
1657 c->syscall_filter = NULL;
1660 void exec_command_done(ExecCommand *c) {
1670 void exec_command_done_array(ExecCommand *c, unsigned n) {
1673 for (i = 0; i < n; i++)
1674 exec_command_done(c+i);
1677 void exec_command_free_list(ExecCommand *c) {
1681 LIST_REMOVE(command, c, i);
1682 exec_command_done(i);
1687 void exec_command_free_array(ExecCommand **c, unsigned n) {
1690 for (i = 0; i < n; i++) {
1691 exec_command_free_list(c[i]);
1696 int exec_context_load_environment(const ExecContext *c, char ***l) {
1697 char **i, **r = NULL;
1702 STRV_FOREACH(i, c->environment_files) {
1705 bool ignore = false;
1707 _cleanup_globfree_ glob_t pglob = {};
1717 if (!path_is_absolute(fn)) {
1725 /* Filename supports globbing, take all matching files */
1727 if (glob(fn, 0, NULL, &pglob) != 0) {
1732 return errno ? -errno : -EINVAL;
1734 count = pglob.gl_pathc;
1742 for (n = 0; n < count; n++) {
1743 k = load_env_file(pglob.gl_pathv[n], NULL, &p);
1751 /* Log invalid environment variables with filename */
1753 p = strv_env_clean_log(p, pglob.gl_pathv[n]);
1760 m = strv_env_merge(2, r, p);
1776 static bool tty_may_match_dev_console(const char *tty) {
1777 char *active = NULL, *console;
1780 if (startswith(tty, "/dev/"))
1783 /* trivial identity? */
1784 if (streq(tty, "console"))
1787 console = resolve_dev_console(&active);
1788 /* if we could not resolve, assume it may */
1792 /* "tty0" means the active VC, so it may be the same sometimes */
1793 b = streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty));
1799 bool exec_context_may_touch_console(ExecContext *ec) {
1800 return (ec->tty_reset || ec->tty_vhangup || ec->tty_vt_disallocate ||
1801 is_terminal_input(ec->std_input) ||
1802 is_terminal_output(ec->std_output) ||
1803 is_terminal_output(ec->std_error)) &&
1804 tty_may_match_dev_console(tty_path(ec));
1807 static void strv_fprintf(FILE *f, char **l) {
1813 fprintf(f, " %s", *g);
1816 void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
1823 prefix = strempty(prefix);
1827 "%sWorkingDirectory: %s\n"
1828 "%sRootDirectory: %s\n"
1829 "%sNonBlocking: %s\n"
1830 "%sPrivateTmp: %s\n"
1831 "%sPrivateNetwork: %s\n"
1832 "%sIgnoreSIGPIPE: %s\n",
1834 prefix, c->working_directory ? c->working_directory : "/",
1835 prefix, c->root_directory ? c->root_directory : "/",
1836 prefix, yes_no(c->non_blocking),
1837 prefix, yes_no(c->private_tmp),
1838 prefix, yes_no(c->private_network),
1839 prefix, yes_no(c->ignore_sigpipe));
1841 STRV_FOREACH(e, c->environment)
1842 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
1844 STRV_FOREACH(e, c->environment_files)
1845 fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
1847 if (c->tcpwrap_name)
1849 "%sTCPWrapName: %s\n",
1850 prefix, c->tcpwrap_name);
1857 if (c->oom_score_adjust_set)
1859 "%sOOMScoreAdjust: %i\n",
1860 prefix, c->oom_score_adjust);
1862 for (i = 0; i < RLIM_NLIMITS; i++)
1864 fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max);
1866 if (c->ioprio_set) {
1870 r = ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str);
1874 "%sIOSchedulingClass: %s\n"
1875 "%sIOPriority: %i\n",
1876 prefix, strna(class_str),
1877 prefix, (int) IOPRIO_PRIO_DATA(c->ioprio));
1881 if (c->cpu_sched_set) {
1885 r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
1889 "%sCPUSchedulingPolicy: %s\n"
1890 "%sCPUSchedulingPriority: %i\n"
1891 "%sCPUSchedulingResetOnFork: %s\n",
1892 prefix, strna(policy_str),
1893 prefix, c->cpu_sched_priority,
1894 prefix, yes_no(c->cpu_sched_reset_on_fork));
1899 fprintf(f, "%sCPUAffinity:", prefix);
1900 for (i = 0; i < c->cpuset_ncpus; i++)
1901 if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
1902 fprintf(f, " %i", i);
1906 if (c->timer_slack_nsec != (nsec_t) -1)
1907 fprintf(f, "%sTimerSlackNSec: %lu\n", prefix, (unsigned long)c->timer_slack_nsec);
1910 "%sStandardInput: %s\n"
1911 "%sStandardOutput: %s\n"
1912 "%sStandardError: %s\n",
1913 prefix, exec_input_to_string(c->std_input),
1914 prefix, exec_output_to_string(c->std_output),
1915 prefix, exec_output_to_string(c->std_error));
1921 "%sTTYVHangup: %s\n"
1922 "%sTTYVTDisallocate: %s\n",
1923 prefix, c->tty_path,
1924 prefix, yes_no(c->tty_reset),
1925 prefix, yes_no(c->tty_vhangup),
1926 prefix, yes_no(c->tty_vt_disallocate));
1928 if (c->std_output == EXEC_OUTPUT_SYSLOG || c->std_output == EXEC_OUTPUT_KMSG || c->std_output == EXEC_OUTPUT_JOURNAL ||
1929 c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE ||
1930 c->std_error == EXEC_OUTPUT_SYSLOG || c->std_error == EXEC_OUTPUT_KMSG || c->std_error == EXEC_OUTPUT_JOURNAL ||
1931 c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE || c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) {
1932 char *fac_str, *lvl_str;
1935 r = log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str);
1939 r = log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str);
1944 "%sSyslogFacility: %s\n"
1945 "%sSyslogLevel: %s\n",
1946 prefix, strna(fac_str),
1947 prefix, strna(lvl_str));
1952 if (c->capabilities) {
1954 if ((t = cap_to_text(c->capabilities, NULL))) {
1955 fprintf(f, "%sCapabilities: %s\n",
1962 fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n",
1964 (c->secure_bits & 1<<SECURE_KEEP_CAPS) ? " keep-caps" : "",
1965 (c->secure_bits & 1<<SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "",
1966 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "",
1967 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "",
1968 (c->secure_bits & 1<<SECURE_NOROOT) ? " noroot" : "",
1969 (c->secure_bits & 1<<SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
1971 if (c->capability_bounding_set_drop) {
1973 fprintf(f, "%sCapabilityBoundingSet:", prefix);
1975 for (l = 0; l <= cap_last_cap(); l++)
1976 if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l))) {
1979 if ((t = cap_to_name(l))) {
1980 fprintf(f, " %s", t);
1989 fprintf(f, "%sUser: %s\n", prefix, c->user);
1991 fprintf(f, "%sGroup: %s\n", prefix, c->group);
1993 if (strv_length(c->supplementary_groups) > 0) {
1994 fprintf(f, "%sSupplementaryGroups:", prefix);
1995 strv_fprintf(f, c->supplementary_groups);
2000 fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
2002 if (strv_length(c->read_write_dirs) > 0) {
2003 fprintf(f, "%sReadWriteDirs:", prefix);
2004 strv_fprintf(f, c->read_write_dirs);
2008 if (strv_length(c->read_only_dirs) > 0) {
2009 fprintf(f, "%sReadOnlyDirs:", prefix);
2010 strv_fprintf(f, c->read_only_dirs);
2014 if (strv_length(c->inaccessible_dirs) > 0) {
2015 fprintf(f, "%sInaccessibleDirs:", prefix);
2016 strv_fprintf(f, c->inaccessible_dirs);
2022 "%sUtmpIdentifier: %s\n",
2023 prefix, c->utmp_id);
2026 void exec_status_start(ExecStatus *s, pid_t pid) {
2031 dual_timestamp_get(&s->start_timestamp);
2034 void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
2037 if (s->pid && s->pid != pid)
2041 dual_timestamp_get(&s->exit_timestamp);
2047 if (context->utmp_id)
2048 utmp_put_dead_process(context->utmp_id, pid, code, status);
2050 exec_context_tty_reset(context);
2054 void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
2055 char buf[FORMAT_TIMESTAMP_MAX];
2068 prefix, (unsigned long) s->pid);
2070 if (s->start_timestamp.realtime > 0)
2072 "%sStart Timestamp: %s\n",
2073 prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime));
2075 if (s->exit_timestamp.realtime > 0)
2077 "%sExit Timestamp: %s\n"
2079 "%sExit Status: %i\n",
2080 prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime),
2081 prefix, sigchld_code_to_string(s->code),
2085 char *exec_command_line(char **argv) {
2093 STRV_FOREACH(a, argv)
2096 if (!(n = new(char, k)))
2100 STRV_FOREACH(a, argv) {
2107 if (strpbrk(*a, WHITESPACE)) {
2118 /* FIXME: this doesn't really handle arguments that have
2119 * spaces and ticks in them */
2124 void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
2126 const char *prefix2;
2135 p2 = strappend(prefix, "\t");
2136 prefix2 = p2 ? p2 : prefix;
2138 cmd = exec_command_line(c->argv);
2141 "%sCommand Line: %s\n",
2142 prefix, cmd ? cmd : strerror(ENOMEM));
2146 exec_status_dump(&c->exec_status, f, prefix2);
2151 void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
2157 LIST_FOREACH(command, c, c)
2158 exec_command_dump(c, f, prefix);
2161 void exec_command_append_list(ExecCommand **l, ExecCommand *e) {
2168 /* It's kind of important, that we keep the order here */
2169 LIST_FIND_TAIL(command, *l, end);
2170 LIST_INSERT_AFTER(command, *l, end, e);
2175 int exec_command_set(ExecCommand *c, const char *path, ...) {
2183 l = strv_new_ap(path, ap);
2204 static int exec_runtime_allocate(ExecRuntime **rt) {
2209 *rt = new0(ExecRuntime, 1);
2214 (*rt)->netns_storage_socket[0] = (*rt)->netns_storage_socket[1] = -1;
2219 int exec_runtime_make(ExecRuntime **rt, ExecContext *c, const char *id) {
2229 if (!c->private_network && !c->private_tmp)
2232 r = exec_runtime_allocate(rt);
2236 if (c->private_network && (*rt)->netns_storage_socket[0] < 0) {
2237 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, (*rt)->netns_storage_socket) < 0)
2241 if (c->private_tmp && !(*rt)->tmp_dir) {
2242 r = setup_tmp_dirs(id, &(*rt)->tmp_dir, &(*rt)->var_tmp_dir);
2250 ExecRuntime *exec_runtime_ref(ExecRuntime *r) {
2252 assert(r->n_ref > 0);
2258 ExecRuntime *exec_runtime_unref(ExecRuntime *r) {
2263 assert(r->n_ref > 0);
2266 if (r->n_ref <= 0) {
2268 free(r->var_tmp_dir);
2269 close_pipe(r->netns_storage_socket);
2276 int exec_runtime_serialize(ExecRuntime *rt, Unit *u, FILE *f, FDSet *fds) {
2285 unit_serialize_item(u, f, "tmp-dir", rt->tmp_dir);
2287 if (rt->var_tmp_dir)
2288 unit_serialize_item(u, f, "var-tmp-dir", rt->var_tmp_dir);
2290 if (rt->netns_storage_socket[0] >= 0) {
2293 copy = fdset_put_dup(fds, rt->netns_storage_socket[0]);
2297 unit_serialize_item_format(u, f, "netns-socket-0", "%i", copy);
2300 if (rt->netns_storage_socket[1] >= 0) {
2303 copy = fdset_put_dup(fds, rt->netns_storage_socket[1]);
2307 unit_serialize_item_format(u, f, "netns-socket-1", "%i", copy);
2313 int exec_runtime_deserialize_item(ExecRuntime **rt, Unit *u, const char *key, const char *value, FDSet *fds) {
2320 if (streq(key, "tmp-dir")) {
2323 r = exec_runtime_allocate(rt);
2327 copy = strdup(value);
2331 free((*rt)->tmp_dir);
2332 (*rt)->tmp_dir = copy;
2334 } else if (streq(key, "var-tmp-dir")) {
2337 r = exec_runtime_allocate(rt);
2341 copy = strdup(value);
2345 free((*rt)->var_tmp_dir);
2346 (*rt)->var_tmp_dir = copy;
2348 } else if (streq(key, "netns-socket-0")) {
2351 r = exec_runtime_allocate(rt);
2355 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
2356 log_debug_unit(u->id, "Failed to parse netns socket value %s", value);
2358 if ((*rt)->netns_storage_socket[0] >= 0)
2359 close_nointr_nofail((*rt)->netns_storage_socket[0]);
2361 (*rt)->netns_storage_socket[0] = fdset_remove(fds, fd);
2363 } else if (streq(key, "netns-socket-1")) {
2366 r = exec_runtime_allocate(rt);
2370 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
2371 log_debug_unit(u->id, "Failed to parse netns socket value %s", value);
2373 if ((*rt)->netns_storage_socket[1] >= 0)
2374 close_nointr_nofail((*rt)->netns_storage_socket[1]);
2376 (*rt)->netns_storage_socket[1] = fdset_remove(fds, fd);
2384 static void *remove_tmpdir_thread(void *p) {
2385 _cleanup_free_ char *path = p;
2387 rm_rf_dangerous(path, false, true, false);
2391 void exec_runtime_destroy(ExecRuntime *rt) {
2395 /* If there are multiple users of this, let's leave the stuff around */
2400 log_debug("Spawning thread to nuke %s", rt->tmp_dir);
2401 asynchronous_job(remove_tmpdir_thread, rt->tmp_dir);
2405 if (rt->var_tmp_dir) {
2406 log_debug("Spawning thread to nuke %s", rt->var_tmp_dir);
2407 asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir);
2408 rt->var_tmp_dir = NULL;
2411 close_pipe(rt->netns_storage_socket);
2414 static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
2415 [EXEC_INPUT_NULL] = "null",
2416 [EXEC_INPUT_TTY] = "tty",
2417 [EXEC_INPUT_TTY_FORCE] = "tty-force",
2418 [EXEC_INPUT_TTY_FAIL] = "tty-fail",
2419 [EXEC_INPUT_SOCKET] = "socket"
2422 DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
2424 static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
2425 [EXEC_OUTPUT_INHERIT] = "inherit",
2426 [EXEC_OUTPUT_NULL] = "null",
2427 [EXEC_OUTPUT_TTY] = "tty",
2428 [EXEC_OUTPUT_SYSLOG] = "syslog",
2429 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console",
2430 [EXEC_OUTPUT_KMSG] = "kmsg",
2431 [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
2432 [EXEC_OUTPUT_JOURNAL] = "journal",
2433 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
2434 [EXEC_OUTPUT_SOCKET] = "socket"
2437 DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);