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>
47 #include <security/pam_appl.h>
51 #include <selinux/selinux.h>
57 #include "capability.h"
60 #include "sd-messages.h"
62 #include "securebits.h"
63 #include "namespace.h"
65 #include "exit-status.h"
67 #include "utmp-wtmp.h"
69 #include "path-util.h"
70 #include "syscall-list.h"
75 #include "selinux-util.h"
77 #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
78 #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
80 /* This assumes there is a 'tty' group */
83 #define SNDBUF_SIZE (8*1024*1024)
85 static int shift_fds(int fds[], unsigned n_fds) {
86 int start, restart_from;
91 /* Modifies the fds array! (sorts it) */
101 for (i = start; i < (int) n_fds; i++) {
104 /* Already at right index? */
108 if ((nfd = fcntl(fds[i], F_DUPFD, i+3)) < 0)
111 close_nointr_nofail(fds[i]);
114 /* Hmm, the fd we wanted isn't free? Then
115 * let's remember that and try again from here*/
116 if (nfd != i+3 && restart_from < 0)
120 if (restart_from < 0)
123 start = restart_from;
129 static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) {
138 /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
140 for (i = 0; i < n_fds; i++) {
142 if ((r = fd_nonblock(fds[i], nonblock)) < 0)
145 /* We unconditionally drop FD_CLOEXEC from the fds,
146 * since after all we want to pass these fds to our
149 if ((r = fd_cloexec(fds[i], false)) < 0)
156 _pure_ static const char *tty_path(const ExecContext *context) {
159 if (context->tty_path)
160 return context->tty_path;
162 return "/dev/console";
165 static void exec_context_tty_reset(const ExecContext *context) {
168 if (context->tty_vhangup)
169 terminal_vhangup(tty_path(context));
171 if (context->tty_reset)
172 reset_terminal(tty_path(context));
174 if (context->tty_vt_disallocate && context->tty_path)
175 vt_disallocate(context->tty_path);
178 static bool is_terminal_output(ExecOutput o) {
180 o == EXEC_OUTPUT_TTY ||
181 o == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
182 o == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
183 o == EXEC_OUTPUT_JOURNAL_AND_CONSOLE;
186 static int open_null_as(int flags, int nfd) {
191 fd = open("/dev/null", flags|O_NOCTTY);
196 r = dup2(fd, nfd) < 0 ? -errno : nfd;
197 close_nointr_nofail(fd);
204 static int connect_logger_as(const ExecContext *context, ExecOutput output, const char *ident, const char *unit_id, int nfd) {
206 union sockaddr_union sa = {
207 .un.sun_family = AF_UNIX,
208 .un.sun_path = "/run/systemd/journal/stdout",
212 assert(output < _EXEC_OUTPUT_MAX);
216 fd = socket(AF_UNIX, SOCK_STREAM, 0);
220 r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
222 close_nointr_nofail(fd);
226 if (shutdown(fd, SHUT_RD) < 0) {
227 close_nointr_nofail(fd);
231 fd_inc_sndbuf(fd, SNDBUF_SIZE);
241 context->syslog_identifier ? context->syslog_identifier : ident,
243 context->syslog_priority,
244 !!context->syslog_level_prefix,
245 output == EXEC_OUTPUT_SYSLOG || output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
246 output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE,
247 is_terminal_output(output));
250 r = dup2(fd, nfd) < 0 ? -errno : nfd;
251 close_nointr_nofail(fd);
257 static int open_terminal_as(const char *path, mode_t mode, int nfd) {
263 if ((fd = open_terminal(path, mode | O_NOCTTY)) < 0)
267 r = dup2(fd, nfd) < 0 ? -errno : nfd;
268 close_nointr_nofail(fd);
275 static bool is_terminal_input(ExecInput i) {
277 i == EXEC_INPUT_TTY ||
278 i == EXEC_INPUT_TTY_FORCE ||
279 i == EXEC_INPUT_TTY_FAIL;
282 static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) {
284 if (is_terminal_input(std_input) && !apply_tty_stdin)
285 return EXEC_INPUT_NULL;
287 if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0)
288 return EXEC_INPUT_NULL;
293 static int fixup_output(ExecOutput std_output, int socket_fd) {
295 if (std_output == EXEC_OUTPUT_SOCKET && socket_fd < 0)
296 return EXEC_OUTPUT_INHERIT;
301 static int setup_input(const ExecContext *context, int socket_fd, bool apply_tty_stdin) {
306 i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
310 case EXEC_INPUT_NULL:
311 return open_null_as(O_RDONLY, STDIN_FILENO);
314 case EXEC_INPUT_TTY_FORCE:
315 case EXEC_INPUT_TTY_FAIL: {
318 fd = acquire_terminal(tty_path(context),
319 i == EXEC_INPUT_TTY_FAIL,
320 i == EXEC_INPUT_TTY_FORCE,
326 if (fd != STDIN_FILENO) {
327 r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
328 close_nointr_nofail(fd);
335 case EXEC_INPUT_SOCKET:
336 return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
339 assert_not_reached("Unknown input type");
343 static int setup_output(const ExecContext *context, int fileno, int socket_fd, const char *ident, const char *unit_id, bool apply_tty_stdin) {
351 i = fixup_input(context->std_input, socket_fd, apply_tty_stdin);
352 o = fixup_output(context->std_output, socket_fd);
354 if (fileno == STDERR_FILENO) {
356 e = fixup_output(context->std_error, socket_fd);
358 /* This expects the input and output are already set up */
360 /* Don't change the stderr file descriptor if we inherit all
361 * the way and are not on a tty */
362 if (e == EXEC_OUTPUT_INHERIT &&
363 o == EXEC_OUTPUT_INHERIT &&
364 i == EXEC_INPUT_NULL &&
365 !is_terminal_input(context->std_input) &&
369 /* Duplicate from stdout if possible */
370 if (e == o || e == EXEC_OUTPUT_INHERIT)
371 return dup2(STDOUT_FILENO, fileno) < 0 ? -errno : fileno;
375 } else if (o == EXEC_OUTPUT_INHERIT) {
376 /* If input got downgraded, inherit the original value */
377 if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input))
378 return open_terminal_as(tty_path(context), O_WRONLY, fileno);
380 /* If the input is connected to anything that's not a /dev/null, inherit that... */
381 if (i != EXEC_INPUT_NULL)
382 return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
384 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
388 /* We need to open /dev/null here anew, to get the right access mode. */
389 return open_null_as(O_WRONLY, fileno);
394 case EXEC_OUTPUT_NULL:
395 return open_null_as(O_WRONLY, fileno);
397 case EXEC_OUTPUT_TTY:
398 if (is_terminal_input(i))
399 return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
401 /* We don't reset the terminal if this is just about output */
402 return open_terminal_as(tty_path(context), O_WRONLY, fileno);
404 case EXEC_OUTPUT_SYSLOG:
405 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE:
406 case EXEC_OUTPUT_KMSG:
407 case EXEC_OUTPUT_KMSG_AND_CONSOLE:
408 case EXEC_OUTPUT_JOURNAL:
409 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE:
410 r = connect_logger_as(context, o, ident, unit_id, fileno);
412 log_struct_unit(LOG_CRIT, unit_id,
413 "MESSAGE=Failed to connect std%s of %s to the journal socket: %s",
414 fileno == STDOUT_FILENO ? "out" : "err",
415 unit_id, strerror(-r),
418 r = open_null_as(O_WRONLY, fileno);
422 case EXEC_OUTPUT_SOCKET:
423 assert(socket_fd >= 0);
424 return dup2(socket_fd, fileno) < 0 ? -errno : fileno;
427 assert_not_reached("Unknown error type");
431 static int chown_terminal(int fd, uid_t uid) {
436 /* This might fail. What matters are the results. */
437 (void) fchown(fd, uid, -1);
438 (void) fchmod(fd, TTY_MODE);
440 if (fstat(fd, &st) < 0)
443 if (st.st_uid != uid || (st.st_mode & 0777) != TTY_MODE)
449 static int setup_confirm_stdio(int *_saved_stdin,
450 int *_saved_stdout) {
451 int fd = -1, saved_stdin, saved_stdout = -1, r;
453 assert(_saved_stdin);
454 assert(_saved_stdout);
456 saved_stdin = fcntl(STDIN_FILENO, F_DUPFD, 3);
460 saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD, 3);
461 if (saved_stdout < 0) {
466 fd = acquire_terminal(
471 DEFAULT_CONFIRM_USEC);
477 r = chown_terminal(fd, getuid());
481 if (dup2(fd, STDIN_FILENO) < 0) {
486 if (dup2(fd, STDOUT_FILENO) < 0) {
492 close_nointr_nofail(fd);
494 *_saved_stdin = saved_stdin;
495 *_saved_stdout = saved_stdout;
500 if (saved_stdout >= 0)
501 close_nointr_nofail(saved_stdout);
503 if (saved_stdin >= 0)
504 close_nointr_nofail(saved_stdin);
507 close_nointr_nofail(fd);
512 _printf_(1, 2) static int write_confirm_message(const char *format, ...) {
518 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
522 va_start(ap, format);
523 vdprintf(fd, format, ap);
526 close_nointr_nofail(fd);
531 static int restore_confirm_stdio(int *saved_stdin,
537 assert(saved_stdout);
541 if (*saved_stdin >= 0)
542 if (dup2(*saved_stdin, STDIN_FILENO) < 0)
545 if (*saved_stdout >= 0)
546 if (dup2(*saved_stdout, STDOUT_FILENO) < 0)
549 if (*saved_stdin >= 0)
550 close_nointr_nofail(*saved_stdin);
552 if (*saved_stdout >= 0)
553 close_nointr_nofail(*saved_stdout);
558 static int ask_for_confirmation(char *response, char **argv) {
559 int saved_stdout = -1, saved_stdin = -1, r;
562 r = setup_confirm_stdio(&saved_stdin, &saved_stdout);
566 line = exec_command_line(argv);
570 r = ask(response, "yns", "Execute %s? [Yes, No, Skip] ", line);
573 restore_confirm_stdio(&saved_stdin, &saved_stdout);
578 static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) {
579 bool keep_groups = false;
584 /* Lookup and set GID and supplementary group list. Here too
585 * we avoid NSS lookups for gid=0. */
587 if (context->group || username) {
589 if (context->group) {
590 const char *g = context->group;
592 if ((r = get_group_creds(&g, &gid)) < 0)
596 /* First step, initialize groups from /etc/groups */
597 if (username && gid != 0) {
598 if (initgroups(username, gid) < 0)
604 /* Second step, set our gids */
605 if (setresgid(gid, gid, gid) < 0)
609 if (context->supplementary_groups) {
614 /* Final step, initialize any manually set supplementary groups */
615 assert_se((ngroups_max = (int) sysconf(_SC_NGROUPS_MAX)) > 0);
617 if (!(gids = new(gid_t, ngroups_max)))
621 if ((k = getgroups(ngroups_max, gids)) < 0) {
628 STRV_FOREACH(i, context->supplementary_groups) {
631 if (k >= ngroups_max) {
637 r = get_group_creds(&g, gids+k);
646 if (setgroups(k, gids) < 0) {
657 static int enforce_user(const ExecContext *context, uid_t uid) {
660 /* Sets (but doesn't lookup) the uid and make sure we keep the
661 * capabilities while doing so. */
663 if (context->capabilities) {
664 _cleanup_cap_free_ cap_t d = NULL;
665 static const cap_value_t bits[] = {
666 CAP_SETUID, /* Necessary so that we can run setresuid() below */
667 CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */
670 /* First step: If we need to keep capabilities but
671 * drop privileges we need to make sure we keep our
672 * caps, while we drop privileges. */
674 int sb = context->secure_bits | 1<<SECURE_KEEP_CAPS;
676 if (prctl(PR_GET_SECUREBITS) != sb)
677 if (prctl(PR_SET_SECUREBITS, sb) < 0)
681 /* Second step: set the capabilities. This will reduce
682 * the capabilities to the minimum we need. */
684 d = cap_dup(context->capabilities);
688 if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 ||
689 cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0)
692 if (cap_set_proc(d) < 0)
696 /* Third step: actually set the uids */
697 if (setresuid(uid, uid, uid) < 0)
700 /* At this point we should have all necessary capabilities but
701 are otherwise a normal user. However, the caps might got
702 corrupted due to the setresuid() so we need clean them up
703 later. This is done outside of this call. */
710 static int null_conv(
712 const struct pam_message **msg,
713 struct pam_response **resp,
716 /* We don't support conversations */
721 static int setup_pam(
727 int fds[], unsigned n_fds) {
729 static const struct pam_conv conv = {
734 pam_handle_t *handle = NULL;
736 int pam_code = PAM_SUCCESS;
739 bool close_session = false;
740 pid_t pam_pid = 0, parent_pid;
747 /* We set up PAM in the parent process, then fork. The child
748 * will then stay around until killed via PR_GET_PDEATHSIG or
749 * systemd via the cgroup logic. It will then remove the PAM
750 * session again. The parent process will exec() the actual
751 * daemon. We do things this way to ensure that the main PID
752 * of the daemon is the one we initially fork()ed. */
754 if (log_get_max_level() < LOG_PRI(LOG_DEBUG))
757 pam_code = pam_start(name, user, &conv, &handle);
758 if (pam_code != PAM_SUCCESS) {
764 pam_code = pam_set_item(handle, PAM_TTY, tty);
765 if (pam_code != PAM_SUCCESS)
769 pam_code = pam_acct_mgmt(handle, flags);
770 if (pam_code != PAM_SUCCESS)
773 pam_code = pam_open_session(handle, flags);
774 if (pam_code != PAM_SUCCESS)
777 close_session = true;
779 e = pam_getenvlist(handle);
781 pam_code = PAM_BUF_ERR;
785 /* Block SIGTERM, so that we know that it won't get lost in
787 if (sigemptyset(&ss) < 0 ||
788 sigaddset(&ss, SIGTERM) < 0 ||
789 sigprocmask(SIG_BLOCK, &ss, &old_ss) < 0)
792 parent_pid = getpid();
802 /* The child's job is to reset the PAM session on
805 /* This string must fit in 10 chars (i.e. the length
806 * of "/sbin/init"), to look pretty in /bin/ps */
807 rename_process("(sd-pam)");
809 /* Make sure we don't keep open the passed fds in this
810 child. We assume that otherwise only those fds are
811 open here that have been opened by PAM. */
812 close_many(fds, n_fds);
814 /* Drop privileges - we don't need any to pam_close_session
815 * and this will make PR_SET_PDEATHSIG work in most cases.
816 * If this fails, ignore the error - but expect sd-pam threads
817 * to fail to exit normally */
818 if (setresuid(uid, uid, uid) < 0)
819 log_error("Error: Failed to setresuid() in sd-pam: %s", strerror(-r));
821 /* Wait until our parent died. This will only work if
822 * the above setresuid() succeeds, otherwise the kernel
823 * will not allow unprivileged parents kill their privileged
824 * children this way. We rely on the control groups kill logic
825 * to do the rest for us. */
826 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
829 /* Check if our parent process might already have
831 if (getppid() == parent_pid) {
833 if (sigwait(&ss, &sig) < 0) {
840 assert(sig == SIGTERM);
845 /* If our parent died we'll end the session */
846 if (getppid() != parent_pid) {
847 pam_code = pam_close_session(handle, flags);
848 if (pam_code != PAM_SUCCESS)
855 pam_end(handle, pam_code | flags);
859 /* If the child was forked off successfully it will do all the
860 * cleanups, so forget about the handle here. */
863 /* Unblock SIGTERM again in the parent */
864 if (sigprocmask(SIG_SETMASK, &old_ss, NULL) < 0)
867 /* We close the log explicitly here, since the PAM modules
868 * might have opened it, but we don't want this fd around. */
877 if (pam_code != PAM_SUCCESS) {
878 log_error("PAM failed: %s", pam_strerror(handle, pam_code));
879 err = -EPERM; /* PAM errors do not map to errno */
881 log_error("PAM failed: %m");
887 pam_code = pam_close_session(handle, flags);
889 pam_end(handle, pam_code | flags);
897 kill(pam_pid, SIGTERM);
898 kill(pam_pid, SIGCONT);
905 static void rename_process_from_path(const char *path) {
906 char process_name[11];
910 /* This resulting string must fit in 10 chars (i.e. the length
911 * of "/sbin/init") to look pretty in /bin/ps */
915 rename_process("(...)");
921 /* The end of the process name is usually more
922 * interesting, since the first bit might just be
928 process_name[0] = '(';
929 memcpy(process_name+1, p, l);
930 process_name[1+l] = ')';
931 process_name[1+l+1] = 0;
933 rename_process(process_name);
936 static int apply_seccomp(uint32_t *syscall_filter) {
937 static const struct sock_filter header[] = {
938 VALIDATE_ARCHITECTURE,
941 static const struct sock_filter footer[] = {
947 struct sock_filter *f;
948 struct sock_fprog prog = {};
950 assert(syscall_filter);
952 /* First: count the syscalls to check for */
953 for (i = 0, n = 0; i < syscall_max(); i++)
954 if (syscall_filter[i >> 4] & (1 << (i & 31)))
957 /* Second: build the filter program from a header the syscall
958 * matches and the footer */
959 f = alloca(sizeof(struct sock_filter) * (ELEMENTSOF(header) + 2*n + ELEMENTSOF(footer)));
960 memcpy(f, header, sizeof(header));
962 for (i = 0, n = 0; i < syscall_max(); i++)
963 if (syscall_filter[i >> 4] & (1 << (i & 31))) {
964 struct sock_filter item[] = {
965 BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, INDEX_TO_SYSCALL(i), 0, 1),
966 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
969 assert_cc(ELEMENTSOF(item) == 2);
971 f[ELEMENTSOF(header) + 2*n] = item[0];
972 f[ELEMENTSOF(header) + 2*n+1] = item[1];
977 memcpy(f + (ELEMENTSOF(header) + 2*n), footer, sizeof(footer));
979 /* Third: install the filter */
980 prog.len = ELEMENTSOF(header) + ELEMENTSOF(footer) + 2*n;
982 if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) < 0)
988 static void do_idle_pipe_dance(int idle_pipe[4]) {
991 if (idle_pipe[1] >= 0)
992 close_nointr_nofail(idle_pipe[1]);
993 if (idle_pipe[2] >= 0)
994 close_nointr_nofail(idle_pipe[2]);
996 if (idle_pipe[0] >= 0) {
999 r = fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
1001 if (idle_pipe[3] >= 0 && r == 0 /* timeout */) {
1002 /* Signal systemd that we are bored and want to continue. */
1003 write(idle_pipe[3], "x", 1);
1005 /* Wait for systemd to react to the signal above. */
1006 fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT2_USEC);
1009 close_nointr_nofail(idle_pipe[0]);
1013 if (idle_pipe[3] >= 0)
1014 close_nointr_nofail(idle_pipe[3]);
1017 static int build_environment(
1020 usec_t watchdog_usec,
1022 const char *username,
1026 _cleanup_strv_free_ char **our_env = NULL;
1033 our_env = new0(char*, 10);
1038 if (asprintf(&x, "LISTEN_PID="PID_FMT, getpid()) < 0)
1040 our_env[n_env++] = x;
1042 if (asprintf(&x, "LISTEN_FDS=%u", n_fds) < 0)
1044 our_env[n_env++] = x;
1047 if (watchdog_usec > 0) {
1048 if (asprintf(&x, "WATCHDOG_PID="PID_FMT, getpid()) < 0)
1050 our_env[n_env++] = x;
1052 if (asprintf(&x, "WATCHDOG_USEC=%llu", (unsigned long long) watchdog_usec) < 0)
1054 our_env[n_env++] = x;
1058 x = strappend("HOME=", home);
1061 our_env[n_env++] = x;
1065 x = strappend("LOGNAME=", username);
1068 our_env[n_env++] = x;
1070 x = strappend("USER=", username);
1073 our_env[n_env++] = x;
1077 x = strappend("SHELL=", shell);
1080 our_env[n_env++] = x;
1083 if (is_terminal_input(c->std_input) ||
1084 c->std_output == EXEC_OUTPUT_TTY ||
1085 c->std_error == EXEC_OUTPUT_TTY ||
1088 x = strdup(default_term_for_tty(tty_path(c)));
1091 our_env[n_env++] = x;
1094 our_env[n_env++] = NULL;
1095 assert(n_env <= 10);
1103 int exec_spawn(ExecCommand *command,
1105 ExecContext *context,
1106 int fds[], unsigned n_fds,
1108 bool apply_permissions,
1110 bool apply_tty_stdin,
1112 CGroupControllerMask cgroup_supported,
1113 const char *cgroup_path,
1114 const char *unit_id,
1115 usec_t watchdog_usec,
1117 ExecRuntime *runtime,
1120 _cleanup_strv_free_ char **files_env = NULL;
1129 assert(fds || n_fds <= 0);
1131 if (context->std_input == EXEC_INPUT_SOCKET ||
1132 context->std_output == EXEC_OUTPUT_SOCKET ||
1133 context->std_error == EXEC_OUTPUT_SOCKET) {
1145 r = exec_context_load_environment(context, &files_env);
1147 log_struct_unit(LOG_ERR,
1149 "MESSAGE=Failed to load environment files: %s", strerror(-r),
1156 argv = command->argv;
1158 line = exec_command_line(argv);
1162 log_struct_unit(LOG_DEBUG,
1164 "EXECUTABLE=%s", command->path,
1165 "MESSAGE=About to execute: %s", line,
1174 _cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
1175 const char *username = NULL, *home = NULL, *shell = NULL;
1176 unsigned n_dont_close = 0;
1177 int dont_close[n_fds + 3];
1178 uid_t uid = (uid_t) -1;
1179 gid_t gid = (gid_t) -1;
1185 rename_process_from_path(command->path);
1187 /* We reset exactly these signals, since they are the
1188 * only ones we set to SIG_IGN in the main daemon. All
1189 * others we leave untouched because we set them to
1190 * SIG_DFL or a valid handler initially, both of which
1191 * will be demoted to SIG_DFL. */
1192 default_signals(SIGNALS_CRASH_HANDLER,
1193 SIGNALS_IGNORE, -1);
1195 if (context->ignore_sigpipe)
1196 ignore_signals(SIGPIPE, -1);
1198 assert_se(sigemptyset(&ss) == 0);
1199 if (sigprocmask(SIG_SETMASK, &ss, NULL) < 0) {
1201 r = EXIT_SIGNAL_MASK;
1206 do_idle_pipe_dance(idle_pipe);
1208 /* Close sockets very early to make sure we don't
1209 * block init reexecution because it cannot bind its
1214 dont_close[n_dont_close++] = socket_fd;
1216 memcpy(dont_close + n_dont_close, fds, sizeof(int) * n_fds);
1217 n_dont_close += n_fds;
1220 if (runtime->netns_storage_socket[0] >= 0)
1221 dont_close[n_dont_close++] = runtime->netns_storage_socket[0];
1222 if (runtime->netns_storage_socket[1] >= 0)
1223 dont_close[n_dont_close++] = runtime->netns_storage_socket[1];
1226 err = close_all_fds(dont_close, n_dont_close);
1232 if (!context->same_pgrp)
1239 if (context->tcpwrap_name) {
1241 if (!socket_tcpwrap(socket_fd, context->tcpwrap_name)) {
1247 for (i = 0; i < (int) n_fds; i++) {
1248 if (!socket_tcpwrap(fds[i], context->tcpwrap_name)) {
1256 exec_context_tty_reset(context);
1258 if (confirm_spawn) {
1261 err = ask_for_confirmation(&response, argv);
1262 if (err == -ETIMEDOUT)
1263 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1265 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-err));
1266 else if (response == 's') {
1267 write_confirm_message("Skipping execution.\n");
1271 } else if (response == 'n') {
1272 write_confirm_message("Failing execution.\n");
1278 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1279 * must sure to drop O_NONBLOCK */
1281 fd_nonblock(socket_fd, false);
1283 err = setup_input(context, socket_fd, apply_tty_stdin);
1289 err = setup_output(context, STDOUT_FILENO, socket_fd, basename(command->path), unit_id, apply_tty_stdin);
1295 err = setup_output(context, STDERR_FILENO, socket_fd, basename(command->path), unit_id, apply_tty_stdin);
1302 err = cg_attach_everywhere(cgroup_supported, cgroup_path, 0);
1309 if (context->oom_score_adjust_set) {
1312 snprintf(t, sizeof(t), "%i", context->oom_score_adjust);
1315 if (write_string_file("/proc/self/oom_score_adj", t) < 0) {
1317 r = EXIT_OOM_ADJUST;
1322 if (context->nice_set)
1323 if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) {
1329 if (context->cpu_sched_set) {
1330 struct sched_param param = {
1331 .sched_priority = context->cpu_sched_priority,
1334 r = sched_setscheduler(0,
1335 context->cpu_sched_policy |
1336 (context->cpu_sched_reset_on_fork ?
1337 SCHED_RESET_ON_FORK : 0),
1341 r = EXIT_SETSCHEDULER;
1346 if (context->cpuset)
1347 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
1349 r = EXIT_CPUAFFINITY;
1353 if (context->ioprio_set)
1354 if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
1360 if (context->timer_slack_nsec != (nsec_t) -1)
1361 if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
1363 r = EXIT_TIMERSLACK;
1367 if (context->utmp_id)
1368 utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path);
1370 if (context->user) {
1371 username = context->user;
1372 err = get_user_creds(&username, &uid, &gid, &home, &shell);
1378 if (is_terminal_input(context->std_input)) {
1379 err = chown_terminal(STDIN_FILENO, uid);
1388 if (cgroup_path && context->user && context->pam_name) {
1389 err = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, 0644, uid, gid);
1396 err = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, 0755, uid, gid);
1404 if (apply_permissions) {
1405 err = enforce_groups(context, username, gid);
1412 umask(context->umask);
1415 if (apply_permissions && context->pam_name && username) {
1416 err = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
1423 if (context->private_network && runtime && runtime->netns_storage_socket[0] >= 0) {
1424 err = setup_netns(runtime->netns_storage_socket);
1431 if (!strv_isempty(context->read_write_dirs) ||
1432 !strv_isempty(context->read_only_dirs) ||
1433 !strv_isempty(context->inaccessible_dirs) ||
1434 context->mount_flags != 0 ||
1435 (context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir)) ||
1436 context->private_devices) {
1438 char *tmp = NULL, *var = NULL;
1440 /* The runtime struct only contains the parent
1441 * of the private /tmp, which is
1442 * non-accessible to world users. Inside of it
1443 * there's a /tmp that is sticky, and that's
1444 * the one we want to use here. */
1446 if (context->private_tmp && runtime) {
1447 if (runtime->tmp_dir)
1448 tmp = strappenda(runtime->tmp_dir, "/tmp");
1449 if (runtime->var_tmp_dir)
1450 var = strappenda(runtime->var_tmp_dir, "/tmp");
1453 err = setup_namespace(
1454 context->read_write_dirs,
1455 context->read_only_dirs,
1456 context->inaccessible_dirs,
1459 context->private_devices,
1460 context->mount_flags);
1469 if (context->root_directory)
1470 if (chroot(context->root_directory) < 0) {
1476 if (chdir(context->working_directory ? context->working_directory : "/") < 0) {
1482 _cleanup_free_ char *d = NULL;
1484 if (asprintf(&d, "%s/%s",
1485 context->root_directory ? context->root_directory : "",
1486 context->working_directory ? context->working_directory : "") < 0) {
1499 /* We repeat the fd closing here, to make sure that
1500 * nothing is leaked from the PAM modules */
1501 err = close_all_fds(fds, n_fds);
1503 err = shift_fds(fds, n_fds);
1505 err = flags_fds(fds, n_fds, context->non_blocking);
1511 if (apply_permissions) {
1513 for (i = 0; i < RLIMIT_NLIMITS; i++) {
1514 if (!context->rlimit[i])
1517 if (setrlimit_closest(i, context->rlimit[i]) < 0) {
1524 if (context->capability_bounding_set_drop) {
1525 err = capability_bounding_set_drop(context->capability_bounding_set_drop, false);
1527 r = EXIT_CAPABILITIES;
1532 if (context->user) {
1533 err = enforce_user(context, uid);
1540 /* PR_GET_SECUREBITS is not privileged, while
1541 * PR_SET_SECUREBITS is. So to suppress
1542 * potential EPERMs we'll try not to call
1543 * PR_SET_SECUREBITS unless necessary. */
1544 if (prctl(PR_GET_SECUREBITS) != context->secure_bits)
1545 if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) {
1547 r = EXIT_SECUREBITS;
1551 if (context->capabilities)
1552 if (cap_set_proc(context->capabilities) < 0) {
1554 r = EXIT_CAPABILITIES;
1558 if (context->no_new_privileges)
1559 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
1561 r = EXIT_NO_NEW_PRIVILEGES;
1565 if (context->syscall_filter) {
1566 err = apply_seccomp(context->syscall_filter);
1573 if (context->selinux_context && use_selinux()) {
1577 c = context->selinux_context;
1584 err = setexeccon(c);
1585 if (err < 0 && !ignore) {
1586 r = EXIT_SELINUX_CONTEXT;
1593 err = build_environment(context, n_fds, watchdog_usec, home, username, shell, &our_env);
1599 final_env = strv_env_merge(5,
1602 context->environment,
1612 final_argv = replace_env_argv(argv, final_env);
1619 final_env = strv_env_clean(final_env);
1621 if (_unlikely_(log_get_max_level() >= LOG_PRI(LOG_DEBUG))) {
1622 line = exec_command_line(final_argv);
1625 log_struct_unit(LOG_DEBUG,
1627 "EXECUTABLE=%s", command->path,
1628 "MESSAGE=Executing: %s", line,
1635 execve(command->path, final_argv, final_env);
1642 log_struct(LOG_ERR, MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED),
1643 "EXECUTABLE=%s", command->path,
1644 "MESSAGE=Failed at step %s spawning %s: %s",
1645 exit_status_to_string(r, EXIT_STATUS_SYSTEMD),
1646 command->path, strerror(-err),
1655 log_struct_unit(LOG_DEBUG,
1657 "MESSAGE=Forked %s as "PID_FMT,
1661 /* We add the new process to the cgroup both in the child (so
1662 * that we can be sure that no user code is ever executed
1663 * outside of the cgroup) and in the parent (so that we can be
1664 * sure that when we kill the cgroup the process will be
1667 cg_attach(SYSTEMD_CGROUP_CONTROLLER, cgroup_path, pid);
1669 exec_status_start(&command->exec_status, pid);
1675 void exec_context_init(ExecContext *c) {
1679 c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0);
1680 c->cpu_sched_policy = SCHED_OTHER;
1681 c->syslog_priority = LOG_DAEMON|LOG_INFO;
1682 c->syslog_level_prefix = true;
1683 c->ignore_sigpipe = true;
1684 c->timer_slack_nsec = (nsec_t) -1;
1687 void exec_context_done(ExecContext *c) {
1692 strv_free(c->environment);
1693 c->environment = NULL;
1695 strv_free(c->environment_files);
1696 c->environment_files = NULL;
1698 for (l = 0; l < ELEMENTSOF(c->rlimit); l++) {
1700 c->rlimit[l] = NULL;
1703 free(c->working_directory);
1704 c->working_directory = NULL;
1705 free(c->root_directory);
1706 c->root_directory = NULL;
1711 free(c->tcpwrap_name);
1712 c->tcpwrap_name = NULL;
1714 free(c->syslog_identifier);
1715 c->syslog_identifier = NULL;
1723 strv_free(c->supplementary_groups);
1724 c->supplementary_groups = NULL;
1729 if (c->capabilities) {
1730 cap_free(c->capabilities);
1731 c->capabilities = NULL;
1734 strv_free(c->read_only_dirs);
1735 c->read_only_dirs = NULL;
1737 strv_free(c->read_write_dirs);
1738 c->read_write_dirs = NULL;
1740 strv_free(c->inaccessible_dirs);
1741 c->inaccessible_dirs = NULL;
1744 CPU_FREE(c->cpuset);
1749 free(c->selinux_context);
1750 c->selinux_context = NULL;
1752 free(c->syscall_filter);
1753 c->syscall_filter = NULL;
1756 void exec_command_done(ExecCommand *c) {
1766 void exec_command_done_array(ExecCommand *c, unsigned n) {
1769 for (i = 0; i < n; i++)
1770 exec_command_done(c+i);
1773 void exec_command_free_list(ExecCommand *c) {
1777 LIST_REMOVE(command, c, i);
1778 exec_command_done(i);
1783 void exec_command_free_array(ExecCommand **c, unsigned n) {
1786 for (i = 0; i < n; i++) {
1787 exec_command_free_list(c[i]);
1792 int exec_context_load_environment(const ExecContext *c, char ***l) {
1793 char **i, **r = NULL;
1798 STRV_FOREACH(i, c->environment_files) {
1801 bool ignore = false;
1803 _cleanup_globfree_ glob_t pglob = {};
1813 if (!path_is_absolute(fn)) {
1821 /* Filename supports globbing, take all matching files */
1823 if (glob(fn, 0, NULL, &pglob) != 0) {
1828 return errno ? -errno : -EINVAL;
1830 count = pglob.gl_pathc;
1838 for (n = 0; n < count; n++) {
1839 k = load_env_file(pglob.gl_pathv[n], NULL, &p);
1847 /* Log invalid environment variables with filename */
1849 p = strv_env_clean_log(p, pglob.gl_pathv[n]);
1856 m = strv_env_merge(2, r, p);
1872 static bool tty_may_match_dev_console(const char *tty) {
1873 char *active = NULL, *console;
1876 if (startswith(tty, "/dev/"))
1879 /* trivial identity? */
1880 if (streq(tty, "console"))
1883 console = resolve_dev_console(&active);
1884 /* if we could not resolve, assume it may */
1888 /* "tty0" means the active VC, so it may be the same sometimes */
1889 b = streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty));
1895 bool exec_context_may_touch_console(ExecContext *ec) {
1896 return (ec->tty_reset || ec->tty_vhangup || ec->tty_vt_disallocate ||
1897 is_terminal_input(ec->std_input) ||
1898 is_terminal_output(ec->std_output) ||
1899 is_terminal_output(ec->std_error)) &&
1900 tty_may_match_dev_console(tty_path(ec));
1903 static void strv_fprintf(FILE *f, char **l) {
1909 fprintf(f, " %s", *g);
1912 void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
1919 prefix = strempty(prefix);
1923 "%sWorkingDirectory: %s\n"
1924 "%sRootDirectory: %s\n"
1925 "%sNonBlocking: %s\n"
1926 "%sPrivateTmp: %s\n"
1927 "%sPrivateNetwork: %s\n"
1928 "%sPrivateDevices: %s\n"
1929 "%sIgnoreSIGPIPE: %s\n",
1931 prefix, c->working_directory ? c->working_directory : "/",
1932 prefix, c->root_directory ? c->root_directory : "/",
1933 prefix, yes_no(c->non_blocking),
1934 prefix, yes_no(c->private_tmp),
1935 prefix, yes_no(c->private_network),
1936 prefix, yes_no(c->private_devices),
1937 prefix, yes_no(c->ignore_sigpipe));
1939 STRV_FOREACH(e, c->environment)
1940 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
1942 STRV_FOREACH(e, c->environment_files)
1943 fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
1945 if (c->tcpwrap_name)
1947 "%sTCPWrapName: %s\n",
1948 prefix, c->tcpwrap_name);
1955 if (c->oom_score_adjust_set)
1957 "%sOOMScoreAdjust: %i\n",
1958 prefix, c->oom_score_adjust);
1960 for (i = 0; i < RLIM_NLIMITS; i++)
1962 fprintf(f, "%s%s: %llu\n", prefix, rlimit_to_string(i), (unsigned long long) c->rlimit[i]->rlim_max);
1964 if (c->ioprio_set) {
1968 r = ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str);
1972 "%sIOSchedulingClass: %s\n"
1973 "%sIOPriority: %i\n",
1974 prefix, strna(class_str),
1975 prefix, (int) IOPRIO_PRIO_DATA(c->ioprio));
1979 if (c->cpu_sched_set) {
1983 r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
1987 "%sCPUSchedulingPolicy: %s\n"
1988 "%sCPUSchedulingPriority: %i\n"
1989 "%sCPUSchedulingResetOnFork: %s\n",
1990 prefix, strna(policy_str),
1991 prefix, c->cpu_sched_priority,
1992 prefix, yes_no(c->cpu_sched_reset_on_fork));
1997 fprintf(f, "%sCPUAffinity:", prefix);
1998 for (i = 0; i < c->cpuset_ncpus; i++)
1999 if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
2000 fprintf(f, " %u", i);
2004 if (c->timer_slack_nsec != (nsec_t) -1)
2005 fprintf(f, "%sTimerSlackNSec: "NSEC_FMT "\n", prefix, c->timer_slack_nsec);
2008 "%sStandardInput: %s\n"
2009 "%sStandardOutput: %s\n"
2010 "%sStandardError: %s\n",
2011 prefix, exec_input_to_string(c->std_input),
2012 prefix, exec_output_to_string(c->std_output),
2013 prefix, exec_output_to_string(c->std_error));
2019 "%sTTYVHangup: %s\n"
2020 "%sTTYVTDisallocate: %s\n",
2021 prefix, c->tty_path,
2022 prefix, yes_no(c->tty_reset),
2023 prefix, yes_no(c->tty_vhangup),
2024 prefix, yes_no(c->tty_vt_disallocate));
2026 if (c->std_output == EXEC_OUTPUT_SYSLOG ||
2027 c->std_output == EXEC_OUTPUT_KMSG ||
2028 c->std_output == EXEC_OUTPUT_JOURNAL ||
2029 c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
2030 c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
2031 c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE ||
2032 c->std_error == EXEC_OUTPUT_SYSLOG ||
2033 c->std_error == EXEC_OUTPUT_KMSG ||
2034 c->std_error == EXEC_OUTPUT_JOURNAL ||
2035 c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
2036 c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
2037 c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) {
2039 _cleanup_free_ char *fac_str = NULL, *lvl_str = NULL;
2041 log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str);
2042 log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str);
2045 "%sSyslogFacility: %s\n"
2046 "%sSyslogLevel: %s\n",
2047 prefix, strna(fac_str),
2048 prefix, strna(lvl_str));
2051 if (c->capabilities) {
2052 _cleanup_cap_free_charp_ char *t;
2054 t = cap_to_text(c->capabilities, NULL);
2056 fprintf(f, "%sCapabilities: %s\n", prefix, t);
2060 fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n",
2062 (c->secure_bits & 1<<SECURE_KEEP_CAPS) ? " keep-caps" : "",
2063 (c->secure_bits & 1<<SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "",
2064 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "",
2065 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "",
2066 (c->secure_bits & 1<<SECURE_NOROOT) ? " noroot" : "",
2067 (c->secure_bits & 1<<SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
2069 if (c->capability_bounding_set_drop) {
2071 fprintf(f, "%sCapabilityBoundingSet:", prefix);
2073 for (l = 0; l <= cap_last_cap(); l++)
2074 if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l))) {
2075 _cleanup_cap_free_charp_ char *t;
2079 fprintf(f, " %s", t);
2086 fprintf(f, "%sUser: %s\n", prefix, c->user);
2088 fprintf(f, "%sGroup: %s\n", prefix, c->group);
2090 if (strv_length(c->supplementary_groups) > 0) {
2091 fprintf(f, "%sSupplementaryGroups:", prefix);
2092 strv_fprintf(f, c->supplementary_groups);
2097 fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
2099 if (strv_length(c->read_write_dirs) > 0) {
2100 fprintf(f, "%sReadWriteDirs:", prefix);
2101 strv_fprintf(f, c->read_write_dirs);
2105 if (strv_length(c->read_only_dirs) > 0) {
2106 fprintf(f, "%sReadOnlyDirs:", prefix);
2107 strv_fprintf(f, c->read_only_dirs);
2111 if (strv_length(c->inaccessible_dirs) > 0) {
2112 fprintf(f, "%sInaccessibleDirs:", prefix);
2113 strv_fprintf(f, c->inaccessible_dirs);
2119 "%sUtmpIdentifier: %s\n",
2120 prefix, c->utmp_id);
2122 if (c->selinux_context)
2124 "%sSELinuxContext: %s\n",
2125 prefix, c->selinux_context);
2129 void exec_status_start(ExecStatus *s, pid_t pid) {
2134 dual_timestamp_get(&s->start_timestamp);
2137 void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
2140 if (s->pid && s->pid != pid)
2144 dual_timestamp_get(&s->exit_timestamp);
2150 if (context->utmp_id)
2151 utmp_put_dead_process(context->utmp_id, pid, code, status);
2153 exec_context_tty_reset(context);
2157 void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
2158 char buf[FORMAT_TIMESTAMP_MAX];
2170 "%sPID: "PID_FMT"\n",
2173 if (s->start_timestamp.realtime > 0)
2175 "%sStart Timestamp: %s\n",
2176 prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime));
2178 if (s->exit_timestamp.realtime > 0)
2180 "%sExit Timestamp: %s\n"
2182 "%sExit Status: %i\n",
2183 prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime),
2184 prefix, sigchld_code_to_string(s->code),
2188 char *exec_command_line(char **argv) {
2196 STRV_FOREACH(a, argv)
2199 if (!(n = new(char, k)))
2203 STRV_FOREACH(a, argv) {
2210 if (strpbrk(*a, WHITESPACE)) {
2221 /* FIXME: this doesn't really handle arguments that have
2222 * spaces and ticks in them */
2227 void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
2229 const char *prefix2;
2238 p2 = strappend(prefix, "\t");
2239 prefix2 = p2 ? p2 : prefix;
2241 cmd = exec_command_line(c->argv);
2244 "%sCommand Line: %s\n",
2245 prefix, cmd ? cmd : strerror(ENOMEM));
2249 exec_status_dump(&c->exec_status, f, prefix2);
2254 void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
2260 LIST_FOREACH(command, c, c)
2261 exec_command_dump(c, f, prefix);
2264 void exec_command_append_list(ExecCommand **l, ExecCommand *e) {
2271 /* It's kind of important, that we keep the order here */
2272 LIST_FIND_TAIL(command, *l, end);
2273 LIST_INSERT_AFTER(command, *l, end, e);
2278 int exec_command_set(ExecCommand *c, const char *path, ...) {
2286 l = strv_new_ap(path, ap);
2307 static int exec_runtime_allocate(ExecRuntime **rt) {
2312 *rt = new0(ExecRuntime, 1);
2317 (*rt)->netns_storage_socket[0] = (*rt)->netns_storage_socket[1] = -1;
2322 int exec_runtime_make(ExecRuntime **rt, ExecContext *c, const char *id) {
2332 if (!c->private_network && !c->private_tmp)
2335 r = exec_runtime_allocate(rt);
2339 if (c->private_network && (*rt)->netns_storage_socket[0] < 0) {
2340 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, (*rt)->netns_storage_socket) < 0)
2344 if (c->private_tmp && !(*rt)->tmp_dir) {
2345 r = setup_tmp_dirs(id, &(*rt)->tmp_dir, &(*rt)->var_tmp_dir);
2353 ExecRuntime *exec_runtime_ref(ExecRuntime *r) {
2355 assert(r->n_ref > 0);
2361 ExecRuntime *exec_runtime_unref(ExecRuntime *r) {
2366 assert(r->n_ref > 0);
2369 if (r->n_ref <= 0) {
2371 free(r->var_tmp_dir);
2372 close_pipe(r->netns_storage_socket);
2379 int exec_runtime_serialize(ExecRuntime *rt, Unit *u, FILE *f, FDSet *fds) {
2388 unit_serialize_item(u, f, "tmp-dir", rt->tmp_dir);
2390 if (rt->var_tmp_dir)
2391 unit_serialize_item(u, f, "var-tmp-dir", rt->var_tmp_dir);
2393 if (rt->netns_storage_socket[0] >= 0) {
2396 copy = fdset_put_dup(fds, rt->netns_storage_socket[0]);
2400 unit_serialize_item_format(u, f, "netns-socket-0", "%i", copy);
2403 if (rt->netns_storage_socket[1] >= 0) {
2406 copy = fdset_put_dup(fds, rt->netns_storage_socket[1]);
2410 unit_serialize_item_format(u, f, "netns-socket-1", "%i", copy);
2416 int exec_runtime_deserialize_item(ExecRuntime **rt, Unit *u, const char *key, const char *value, FDSet *fds) {
2423 if (streq(key, "tmp-dir")) {
2426 r = exec_runtime_allocate(rt);
2430 copy = strdup(value);
2434 free((*rt)->tmp_dir);
2435 (*rt)->tmp_dir = copy;
2437 } else if (streq(key, "var-tmp-dir")) {
2440 r = exec_runtime_allocate(rt);
2444 copy = strdup(value);
2448 free((*rt)->var_tmp_dir);
2449 (*rt)->var_tmp_dir = copy;
2451 } else if (streq(key, "netns-socket-0")) {
2454 r = exec_runtime_allocate(rt);
2458 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
2459 log_debug_unit(u->id, "Failed to parse netns socket value %s", value);
2461 if ((*rt)->netns_storage_socket[0] >= 0)
2462 close_nointr_nofail((*rt)->netns_storage_socket[0]);
2464 (*rt)->netns_storage_socket[0] = fdset_remove(fds, fd);
2466 } else if (streq(key, "netns-socket-1")) {
2469 r = exec_runtime_allocate(rt);
2473 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
2474 log_debug_unit(u->id, "Failed to parse netns socket value %s", value);
2476 if ((*rt)->netns_storage_socket[1] >= 0)
2477 close_nointr_nofail((*rt)->netns_storage_socket[1]);
2479 (*rt)->netns_storage_socket[1] = fdset_remove(fds, fd);
2487 static void *remove_tmpdir_thread(void *p) {
2488 _cleanup_free_ char *path = p;
2490 rm_rf_dangerous(path, false, true, false);
2494 void exec_runtime_destroy(ExecRuntime *rt) {
2498 /* If there are multiple users of this, let's leave the stuff around */
2503 log_debug("Spawning thread to nuke %s", rt->tmp_dir);
2504 asynchronous_job(remove_tmpdir_thread, rt->tmp_dir);
2508 if (rt->var_tmp_dir) {
2509 log_debug("Spawning thread to nuke %s", rt->var_tmp_dir);
2510 asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir);
2511 rt->var_tmp_dir = NULL;
2514 close_pipe(rt->netns_storage_socket);
2517 static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
2518 [EXEC_INPUT_NULL] = "null",
2519 [EXEC_INPUT_TTY] = "tty",
2520 [EXEC_INPUT_TTY_FORCE] = "tty-force",
2521 [EXEC_INPUT_TTY_FAIL] = "tty-fail",
2522 [EXEC_INPUT_SOCKET] = "socket"
2525 DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
2527 static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
2528 [EXEC_OUTPUT_INHERIT] = "inherit",
2529 [EXEC_OUTPUT_NULL] = "null",
2530 [EXEC_OUTPUT_TTY] = "tty",
2531 [EXEC_OUTPUT_SYSLOG] = "syslog",
2532 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console",
2533 [EXEC_OUTPUT_KMSG] = "kmsg",
2534 [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
2535 [EXEC_OUTPUT_JOURNAL] = "journal",
2536 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
2537 [EXEC_OUTPUT_SOCKET] = "socket"
2540 DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);