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/personality.h>
30 #include <sys/prctl.h>
31 #include <sys/socket.h>
38 #include <security/pam_appl.h>
42 #include <selinux/selinux.h>
50 #include <sys/apparmor.h>
53 #include "sd-messages.h"
58 #include "bus-endpoint.h"
60 #include "capability.h"
63 #include "errno-list.h"
64 #include "exit-status.h"
66 #include "formats-util.h"
72 #include "namespace.h"
73 #include "path-util.h"
74 #include "process-util.h"
76 #include "securebits.h"
77 #include "selinux-util.h"
78 #include "signal-util.h"
79 #include "smack-util.h"
81 #include "terminal-util.h"
84 #include "utmp-wtmp.h"
87 #include "apparmor-util.h"
91 #include "seccomp-util.h"
96 #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
97 #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
99 /* This assumes there is a 'tty' group */
100 #define TTY_MODE 0620
102 #define SNDBUF_SIZE (8*1024*1024)
104 static int shift_fds(int fds
[], unsigned n_fds
) {
105 int start
, restart_from
;
110 /* Modifies the fds array! (sorts it) */
120 for (i
= start
; i
< (int) n_fds
; i
++) {
123 /* Already at right index? */
127 nfd
= fcntl(fds
[i
], F_DUPFD
, i
+ 3);
134 /* Hmm, the fd we wanted isn't free? Then
135 * let's remember that and try again from here */
136 if (nfd
!= i
+3 && restart_from
< 0)
140 if (restart_from
< 0)
143 start
= restart_from
;
149 static int flags_fds(const int fds
[], unsigned n_fds
, bool nonblock
) {
158 /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
160 for (i
= 0; i
< n_fds
; i
++) {
162 r
= fd_nonblock(fds
[i
], nonblock
);
166 /* We unconditionally drop FD_CLOEXEC from the fds,
167 * since after all we want to pass these fds to our
170 r
= fd_cloexec(fds
[i
], false);
178 _pure_
static const char *tty_path(const ExecContext
*context
) {
181 if (context
->tty_path
)
182 return context
->tty_path
;
184 return "/dev/console";
187 static void exec_context_tty_reset(const ExecContext
*context
) {
190 if (context
->tty_vhangup
)
191 terminal_vhangup(tty_path(context
));
193 if (context
->tty_reset
)
194 reset_terminal(tty_path(context
));
196 if (context
->tty_vt_disallocate
&& context
->tty_path
)
197 vt_disallocate(context
->tty_path
);
200 static bool is_terminal_output(ExecOutput o
) {
202 o
== EXEC_OUTPUT_TTY
||
203 o
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
204 o
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
205 o
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
;
208 static int open_null_as(int flags
, int nfd
) {
213 fd
= open("/dev/null", flags
|O_NOCTTY
);
218 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
226 static int connect_journal_socket(int fd
, uid_t uid
, gid_t gid
) {
227 union sockaddr_union sa
= {
228 .un
.sun_family
= AF_UNIX
,
229 .un
.sun_path
= "/run/systemd/journal/stdout",
231 uid_t olduid
= UID_INVALID
;
232 gid_t oldgid
= GID_INVALID
;
235 if (gid
!= GID_INVALID
) {
243 if (uid
!= UID_INVALID
) {
253 r
= connect(fd
, &sa
.sa
, offsetof(struct sockaddr_un
, sun_path
) + strlen(sa
.un
.sun_path
));
257 /* If we fail to restore the uid or gid, things will likely
258 fail later on. This should only happen if an LSM interferes. */
260 if (uid
!= UID_INVALID
)
261 (void) seteuid(olduid
);
264 if (gid
!= GID_INVALID
)
265 (void) setegid(oldgid
);
270 static int connect_logger_as(const ExecContext
*context
, ExecOutput output
, const char *ident
, const char *unit_id
, int nfd
, uid_t uid
, gid_t gid
) {
274 assert(output
< _EXEC_OUTPUT_MAX
);
278 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
282 r
= connect_journal_socket(fd
, uid
, gid
);
286 if (shutdown(fd
, SHUT_RD
) < 0) {
291 fd_inc_sndbuf(fd
, SNDBUF_SIZE
);
301 context
->syslog_identifier
? context
->syslog_identifier
: ident
,
303 context
->syslog_priority
,
304 !!context
->syslog_level_prefix
,
305 output
== EXEC_OUTPUT_SYSLOG
|| output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
,
306 output
== EXEC_OUTPUT_KMSG
|| output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
,
307 is_terminal_output(output
));
310 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
317 static int open_terminal_as(const char *path
, mode_t mode
, int nfd
) {
323 fd
= open_terminal(path
, mode
| O_NOCTTY
);
328 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
336 static bool is_terminal_input(ExecInput i
) {
338 i
== EXEC_INPUT_TTY
||
339 i
== EXEC_INPUT_TTY_FORCE
||
340 i
== EXEC_INPUT_TTY_FAIL
;
343 static int fixup_input(ExecInput std_input
, int socket_fd
, bool apply_tty_stdin
) {
345 if (is_terminal_input(std_input
) && !apply_tty_stdin
)
346 return EXEC_INPUT_NULL
;
348 if (std_input
== EXEC_INPUT_SOCKET
&& socket_fd
< 0)
349 return EXEC_INPUT_NULL
;
354 static int fixup_output(ExecOutput std_output
, int socket_fd
) {
356 if (std_output
== EXEC_OUTPUT_SOCKET
&& socket_fd
< 0)
357 return EXEC_OUTPUT_INHERIT
;
362 static int setup_input(
363 const ExecContext
*context
,
364 const ExecParameters
*params
,
372 if (params
->stdin_fd
>= 0) {
373 if (dup2(params
->stdin_fd
, STDIN_FILENO
) < 0)
376 /* Try to make this the controlling tty, if it is a tty, and reset it */
377 (void) ioctl(STDIN_FILENO
, TIOCSCTTY
, context
->std_input
== EXEC_INPUT_TTY_FORCE
);
378 (void) reset_terminal_fd(STDIN_FILENO
, true);
383 i
= fixup_input(context
->std_input
, socket_fd
, params
->apply_tty_stdin
);
387 case EXEC_INPUT_NULL
:
388 return open_null_as(O_RDONLY
, STDIN_FILENO
);
391 case EXEC_INPUT_TTY_FORCE
:
392 case EXEC_INPUT_TTY_FAIL
: {
395 fd
= acquire_terminal(tty_path(context
),
396 i
== EXEC_INPUT_TTY_FAIL
,
397 i
== EXEC_INPUT_TTY_FORCE
,
403 if (fd
!= STDIN_FILENO
) {
404 r
= dup2(fd
, STDIN_FILENO
) < 0 ? -errno
: STDIN_FILENO
;
412 case EXEC_INPUT_SOCKET
:
413 return dup2(socket_fd
, STDIN_FILENO
) < 0 ? -errno
: STDIN_FILENO
;
416 assert_not_reached("Unknown input type");
420 static int setup_output(
422 const ExecContext
*context
,
423 const ExecParameters
*params
,
427 uid_t uid
, gid_t gid
) {
438 if (fileno
== STDOUT_FILENO
&& params
->stdout_fd
>= 0) {
440 if (dup2(params
->stdout_fd
, STDOUT_FILENO
) < 0)
443 return STDOUT_FILENO
;
446 if (fileno
== STDERR_FILENO
&& params
->stderr_fd
>= 0) {
447 if (dup2(params
->stderr_fd
, STDERR_FILENO
) < 0)
450 return STDERR_FILENO
;
453 i
= fixup_input(context
->std_input
, socket_fd
, params
->apply_tty_stdin
);
454 o
= fixup_output(context
->std_output
, socket_fd
);
456 if (fileno
== STDERR_FILENO
) {
458 e
= fixup_output(context
->std_error
, socket_fd
);
460 /* This expects the input and output are already set up */
462 /* Don't change the stderr file descriptor if we inherit all
463 * the way and are not on a tty */
464 if (e
== EXEC_OUTPUT_INHERIT
&&
465 o
== EXEC_OUTPUT_INHERIT
&&
466 i
== EXEC_INPUT_NULL
&&
467 !is_terminal_input(context
->std_input
) &&
471 /* Duplicate from stdout if possible */
472 if (e
== o
|| e
== EXEC_OUTPUT_INHERIT
)
473 return dup2(STDOUT_FILENO
, fileno
) < 0 ? -errno
: fileno
;
477 } else if (o
== EXEC_OUTPUT_INHERIT
) {
478 /* If input got downgraded, inherit the original value */
479 if (i
== EXEC_INPUT_NULL
&& is_terminal_input(context
->std_input
))
480 return open_terminal_as(tty_path(context
), O_WRONLY
, fileno
);
482 /* If the input is connected to anything that's not a /dev/null, inherit that... */
483 if (i
!= EXEC_INPUT_NULL
)
484 return dup2(STDIN_FILENO
, fileno
) < 0 ? -errno
: fileno
;
486 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
490 /* We need to open /dev/null here anew, to get the right access mode. */
491 return open_null_as(O_WRONLY
, fileno
);
496 case EXEC_OUTPUT_NULL
:
497 return open_null_as(O_WRONLY
, fileno
);
499 case EXEC_OUTPUT_TTY
:
500 if (is_terminal_input(i
))
501 return dup2(STDIN_FILENO
, fileno
) < 0 ? -errno
: fileno
;
503 /* We don't reset the terminal if this is just about output */
504 return open_terminal_as(tty_path(context
), O_WRONLY
, fileno
);
506 case EXEC_OUTPUT_SYSLOG
:
507 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE
:
508 case EXEC_OUTPUT_KMSG
:
509 case EXEC_OUTPUT_KMSG_AND_CONSOLE
:
510 case EXEC_OUTPUT_JOURNAL
:
511 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE
:
512 r
= connect_logger_as(context
, o
, ident
, unit
->id
, fileno
, uid
, gid
);
514 log_unit_error_errno(unit
, r
, "Failed to connect %s to the journal socket, ignoring: %m", fileno
== STDOUT_FILENO
? "stdout" : "stderr");
515 r
= open_null_as(O_WRONLY
, fileno
);
519 case EXEC_OUTPUT_SOCKET
:
520 assert(socket_fd
>= 0);
521 return dup2(socket_fd
, fileno
) < 0 ? -errno
: fileno
;
524 assert_not_reached("Unknown error type");
528 static int chown_terminal(int fd
, uid_t uid
) {
533 /* This might fail. What matters are the results. */
534 (void) fchown(fd
, uid
, -1);
535 (void) fchmod(fd
, TTY_MODE
);
537 if (fstat(fd
, &st
) < 0)
540 if (st
.st_uid
!= uid
|| (st
.st_mode
& 0777) != TTY_MODE
)
546 static int setup_confirm_stdio(int *_saved_stdin
, int *_saved_stdout
) {
547 _cleanup_close_
int fd
= -1, saved_stdin
= -1, saved_stdout
= -1;
550 assert(_saved_stdin
);
551 assert(_saved_stdout
);
553 saved_stdin
= fcntl(STDIN_FILENO
, F_DUPFD
, 3);
557 saved_stdout
= fcntl(STDOUT_FILENO
, F_DUPFD
, 3);
558 if (saved_stdout
< 0)
561 fd
= acquire_terminal(
566 DEFAULT_CONFIRM_USEC
);
570 r
= chown_terminal(fd
, getuid());
574 r
= reset_terminal_fd(fd
, true);
578 if (dup2(fd
, STDIN_FILENO
) < 0)
581 if (dup2(fd
, STDOUT_FILENO
) < 0)
588 *_saved_stdin
= saved_stdin
;
589 *_saved_stdout
= saved_stdout
;
591 saved_stdin
= saved_stdout
= -1;
596 _printf_(1, 2) static int write_confirm_message(const char *format
, ...) {
597 _cleanup_close_
int fd
= -1;
602 fd
= open_terminal("/dev/console", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
606 va_start(ap
, format
);
607 vdprintf(fd
, format
, ap
);
613 static int restore_confirm_stdio(int *saved_stdin
, int *saved_stdout
) {
617 assert(saved_stdout
);
621 if (*saved_stdin
>= 0)
622 if (dup2(*saved_stdin
, STDIN_FILENO
) < 0)
625 if (*saved_stdout
>= 0)
626 if (dup2(*saved_stdout
, STDOUT_FILENO
) < 0)
629 *saved_stdin
= safe_close(*saved_stdin
);
630 *saved_stdout
= safe_close(*saved_stdout
);
635 static int ask_for_confirmation(char *response
, char **argv
) {
636 int saved_stdout
= -1, saved_stdin
= -1, r
;
637 _cleanup_free_
char *line
= NULL
;
639 r
= setup_confirm_stdio(&saved_stdin
, &saved_stdout
);
643 line
= exec_command_line(argv
);
647 r
= ask_char(response
, "yns", "Execute %s? [Yes, No, Skip] ", line
);
649 restore_confirm_stdio(&saved_stdin
, &saved_stdout
);
654 static int enforce_groups(const ExecContext
*context
, const char *username
, gid_t gid
) {
655 bool keep_groups
= false;
660 /* Lookup and set GID and supplementary group list. Here too
661 * we avoid NSS lookups for gid=0. */
663 if (context
->group
|| username
) {
664 /* First step, initialize groups from /etc/groups */
665 if (username
&& gid
!= 0) {
666 if (initgroups(username
, gid
) < 0)
672 /* Second step, set our gids */
673 if (setresgid(gid
, gid
, gid
) < 0)
677 if (context
->supplementary_groups
) {
682 /* Final step, initialize any manually set supplementary groups */
683 assert_se((ngroups_max
= (int) sysconf(_SC_NGROUPS_MAX
)) > 0);
685 if (!(gids
= new(gid_t
, ngroups_max
)))
689 k
= getgroups(ngroups_max
, gids
);
697 STRV_FOREACH(i
, context
->supplementary_groups
) {
700 if (k
>= ngroups_max
) {
706 r
= get_group_creds(&g
, gids
+k
);
715 if (setgroups(k
, gids
) < 0) {
726 static int enforce_user(const ExecContext
*context
, uid_t uid
) {
729 /* Sets (but doesn't lookup) the uid and make sure we keep the
730 * capabilities while doing so. */
732 if (context
->capabilities
) {
733 _cleanup_cap_free_ cap_t d
= NULL
;
734 static const cap_value_t bits
[] = {
735 CAP_SETUID
, /* Necessary so that we can run setresuid() below */
736 CAP_SETPCAP
/* Necessary so that we can set PR_SET_SECUREBITS later on */
739 /* First step: If we need to keep capabilities but
740 * drop privileges we need to make sure we keep our
741 * caps, while we drop privileges. */
743 int sb
= context
->secure_bits
| 1<<SECURE_KEEP_CAPS
;
745 if (prctl(PR_GET_SECUREBITS
) != sb
)
746 if (prctl(PR_SET_SECUREBITS
, sb
) < 0)
750 /* Second step: set the capabilities. This will reduce
751 * the capabilities to the minimum we need. */
753 d
= cap_dup(context
->capabilities
);
757 if (cap_set_flag(d
, CAP_EFFECTIVE
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0 ||
758 cap_set_flag(d
, CAP_PERMITTED
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0)
761 if (cap_set_proc(d
) < 0)
765 /* Third step: actually set the uids */
766 if (setresuid(uid
, uid
, uid
) < 0)
769 /* At this point we should have all necessary capabilities but
770 are otherwise a normal user. However, the caps might got
771 corrupted due to the setresuid() so we need clean them up
772 later. This is done outside of this call. */
779 static int null_conv(
781 const struct pam_message
**msg
,
782 struct pam_response
**resp
,
785 /* We don't support conversations */
790 static int setup_pam(
796 int fds
[], unsigned n_fds
) {
798 static const struct pam_conv conv
= {
803 _cleanup_(barrier_destroy
) Barrier barrier
= BARRIER_NULL
;
804 pam_handle_t
*handle
= NULL
;
806 int pam_code
= PAM_SUCCESS
;
809 bool close_session
= false;
810 pid_t pam_pid
= 0, parent_pid
;
817 /* We set up PAM in the parent process, then fork. The child
818 * will then stay around until killed via PR_GET_PDEATHSIG or
819 * systemd via the cgroup logic. It will then remove the PAM
820 * session again. The parent process will exec() the actual
821 * daemon. We do things this way to ensure that the main PID
822 * of the daemon is the one we initially fork()ed. */
824 err
= barrier_create(&barrier
);
828 if (log_get_max_level() < LOG_DEBUG
)
831 pam_code
= pam_start(name
, user
, &conv
, &handle
);
832 if (pam_code
!= PAM_SUCCESS
) {
838 pam_code
= pam_set_item(handle
, PAM_TTY
, tty
);
839 if (pam_code
!= PAM_SUCCESS
)
843 pam_code
= pam_acct_mgmt(handle
, flags
);
844 if (pam_code
!= PAM_SUCCESS
)
847 pam_code
= pam_open_session(handle
, flags
);
848 if (pam_code
!= PAM_SUCCESS
)
851 close_session
= true;
853 e
= pam_getenvlist(handle
);
855 pam_code
= PAM_BUF_ERR
;
859 /* Block SIGTERM, so that we know that it won't get lost in
862 assert_se(sigprocmask_many(SIG_BLOCK
, &old_ss
, SIGTERM
, -1) >= 0);
864 parent_pid
= getpid();
874 /* The child's job is to reset the PAM session on
876 barrier_set_role(&barrier
, BARRIER_CHILD
);
878 /* This string must fit in 10 chars (i.e. the length
879 * of "/sbin/init"), to look pretty in /bin/ps */
880 rename_process("(sd-pam)");
882 /* Make sure we don't keep open the passed fds in this
883 child. We assume that otherwise only those fds are
884 open here that have been opened by PAM. */
885 close_many(fds
, n_fds
);
887 /* Drop privileges - we don't need any to pam_close_session
888 * and this will make PR_SET_PDEATHSIG work in most cases.
889 * If this fails, ignore the error - but expect sd-pam threads
890 * to fail to exit normally */
891 if (setresuid(uid
, uid
, uid
) < 0)
892 log_error_errno(r
, "Error: Failed to setresuid() in sd-pam: %m");
894 (void) ignore_signals(SIGPIPE
, -1);
896 /* Wait until our parent died. This will only work if
897 * the above setresuid() succeeds, otherwise the kernel
898 * will not allow unprivileged parents kill their privileged
899 * children this way. We rely on the control groups kill logic
900 * to do the rest for us. */
901 if (prctl(PR_SET_PDEATHSIG
, SIGTERM
) < 0)
904 /* Tell the parent that our setup is done. This is especially
905 * important regarding dropping privileges. Otherwise, unit
906 * setup might race against our setresuid(2) call. */
907 barrier_place(&barrier
);
909 /* Check if our parent process might already have
911 if (getppid() == parent_pid
) {
914 assert_se(sigemptyset(&ss
) >= 0);
915 assert_se(sigaddset(&ss
, SIGTERM
) >= 0);
918 if (sigwait(&ss
, &sig
) < 0) {
925 assert(sig
== SIGTERM
);
930 /* If our parent died we'll end the session */
931 if (getppid() != parent_pid
) {
932 pam_code
= pam_close_session(handle
, flags
);
933 if (pam_code
!= PAM_SUCCESS
)
940 pam_end(handle
, pam_code
| flags
);
944 barrier_set_role(&barrier
, BARRIER_PARENT
);
946 /* If the child was forked off successfully it will do all the
947 * cleanups, so forget about the handle here. */
950 /* Unblock SIGTERM again in the parent */
951 assert_se(sigprocmask(SIG_SETMASK
, &old_ss
, NULL
) >= 0);
953 /* We close the log explicitly here, since the PAM modules
954 * might have opened it, but we don't want this fd around. */
957 /* Synchronously wait for the child to initialize. We don't care for
958 * errors as we cannot recover. However, warn loudly if it happens. */
959 if (!barrier_place_and_sync(&barrier
))
960 log_error("PAM initialization failed");
968 if (pam_code
!= PAM_SUCCESS
) {
969 log_error("PAM failed: %s", pam_strerror(handle
, pam_code
));
970 err
= -EPERM
; /* PAM errors do not map to errno */
972 err
= log_error_errno(err
< 0 ? err
: errno
, "PAM failed: %m");
977 pam_code
= pam_close_session(handle
, flags
);
979 pam_end(handle
, pam_code
| flags
);
987 kill(pam_pid
, SIGTERM
);
988 kill(pam_pid
, SIGCONT
);
995 static void rename_process_from_path(const char *path
) {
996 char process_name
[11];
1000 /* This resulting string must fit in 10 chars (i.e. the length
1001 * of "/sbin/init") to look pretty in /bin/ps */
1005 rename_process("(...)");
1011 /* The end of the process name is usually more
1012 * interesting, since the first bit might just be
1018 process_name
[0] = '(';
1019 memcpy(process_name
+1, p
, l
);
1020 process_name
[1+l
] = ')';
1021 process_name
[1+l
+1] = 0;
1023 rename_process(process_name
);
1028 static int apply_seccomp(const ExecContext
*c
) {
1029 uint32_t negative_action
, action
;
1030 scmp_filter_ctx
*seccomp
;
1037 negative_action
= c
->syscall_errno
== 0 ? SCMP_ACT_KILL
: SCMP_ACT_ERRNO(c
->syscall_errno
);
1039 seccomp
= seccomp_init(c
->syscall_whitelist
? negative_action
: SCMP_ACT_ALLOW
);
1043 if (c
->syscall_archs
) {
1045 SET_FOREACH(id
, c
->syscall_archs
, i
) {
1046 r
= seccomp_arch_add(seccomp
, PTR_TO_UINT32(id
) - 1);
1054 r
= seccomp_add_secondary_archs(seccomp
);
1059 action
= c
->syscall_whitelist
? SCMP_ACT_ALLOW
: negative_action
;
1060 SET_FOREACH(id
, c
->syscall_filter
, i
) {
1061 r
= seccomp_rule_add(seccomp
, action
, PTR_TO_INT(id
) - 1, 0);
1066 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1070 r
= seccomp_load(seccomp
);
1073 seccomp_release(seccomp
);
1077 static int apply_address_families(const ExecContext
*c
) {
1078 scmp_filter_ctx
*seccomp
;
1084 seccomp
= seccomp_init(SCMP_ACT_ALLOW
);
1088 r
= seccomp_add_secondary_archs(seccomp
);
1092 if (c
->address_families_whitelist
) {
1093 int af
, first
= 0, last
= 0;
1096 /* If this is a whitelist, we first block the address
1097 * families that are out of range and then everything
1098 * that is not in the set. First, we find the lowest
1099 * and highest address family in the set. */
1101 SET_FOREACH(afp
, c
->address_families
, i
) {
1102 af
= PTR_TO_INT(afp
);
1104 if (af
<= 0 || af
>= af_max())
1107 if (first
== 0 || af
< first
)
1110 if (last
== 0 || af
> last
)
1114 assert((first
== 0) == (last
== 0));
1118 /* No entries in the valid range, block everything */
1119 r
= seccomp_rule_add(
1121 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1129 /* Block everything below the first entry */
1130 r
= seccomp_rule_add(
1132 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1135 SCMP_A0(SCMP_CMP_LT
, first
));
1139 /* Block everything above the last entry */
1140 r
= seccomp_rule_add(
1142 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1145 SCMP_A0(SCMP_CMP_GT
, last
));
1149 /* Block everything between the first and last
1151 for (af
= 1; af
< af_max(); af
++) {
1153 if (set_contains(c
->address_families
, INT_TO_PTR(af
)))
1156 r
= seccomp_rule_add(
1158 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1161 SCMP_A0(SCMP_CMP_EQ
, af
));
1170 /* If this is a blacklist, then generate one rule for
1171 * each address family that are then combined in OR
1174 SET_FOREACH(af
, c
->address_families
, i
) {
1176 r
= seccomp_rule_add(
1178 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1181 SCMP_A0(SCMP_CMP_EQ
, PTR_TO_INT(af
)));
1187 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1191 r
= seccomp_load(seccomp
);
1194 seccomp_release(seccomp
);
1200 static void do_idle_pipe_dance(int idle_pipe
[4]) {
1204 idle_pipe
[1] = safe_close(idle_pipe
[1]);
1205 idle_pipe
[2] = safe_close(idle_pipe
[2]);
1207 if (idle_pipe
[0] >= 0) {
1210 r
= fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT_USEC
);
1212 if (idle_pipe
[3] >= 0 && r
== 0 /* timeout */) {
1215 /* Signal systemd that we are bored and want to continue. */
1216 n
= write(idle_pipe
[3], "x", 1);
1218 /* Wait for systemd to react to the signal above. */
1219 fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT2_USEC
);
1222 idle_pipe
[0] = safe_close(idle_pipe
[0]);
1226 idle_pipe
[3] = safe_close(idle_pipe
[3]);
1229 static int build_environment(
1230 const ExecContext
*c
,
1233 usec_t watchdog_usec
,
1235 const char *username
,
1239 _cleanup_strv_free_
char **our_env
= NULL
;
1246 our_env
= new0(char*, 11);
1251 _cleanup_free_
char *joined
= NULL
;
1253 if (asprintf(&x
, "LISTEN_PID="PID_FMT
, getpid()) < 0)
1255 our_env
[n_env
++] = x
;
1257 if (asprintf(&x
, "LISTEN_FDS=%u", n_fds
) < 0)
1259 our_env
[n_env
++] = x
;
1261 joined
= strv_join(fd_names
, ":");
1265 x
= strjoin("LISTEN_FDNAMES=", joined
, NULL
);
1268 our_env
[n_env
++] = x
;
1271 if (watchdog_usec
> 0) {
1272 if (asprintf(&x
, "WATCHDOG_PID="PID_FMT
, getpid()) < 0)
1274 our_env
[n_env
++] = x
;
1276 if (asprintf(&x
, "WATCHDOG_USEC="USEC_FMT
, watchdog_usec
) < 0)
1278 our_env
[n_env
++] = x
;
1282 x
= strappend("HOME=", home
);
1285 our_env
[n_env
++] = x
;
1289 x
= strappend("LOGNAME=", username
);
1292 our_env
[n_env
++] = x
;
1294 x
= strappend("USER=", username
);
1297 our_env
[n_env
++] = x
;
1301 x
= strappend("SHELL=", shell
);
1304 our_env
[n_env
++] = x
;
1307 if (is_terminal_input(c
->std_input
) ||
1308 c
->std_output
== EXEC_OUTPUT_TTY
||
1309 c
->std_error
== EXEC_OUTPUT_TTY
||
1312 x
= strdup(default_term_for_tty(tty_path(c
)));
1315 our_env
[n_env
++] = x
;
1318 our_env
[n_env
++] = NULL
;
1319 assert(n_env
<= 11);
1327 static bool exec_needs_mount_namespace(
1328 const ExecContext
*context
,
1329 const ExecParameters
*params
,
1330 ExecRuntime
*runtime
) {
1335 if (!strv_isempty(context
->read_write_dirs
) ||
1336 !strv_isempty(context
->read_only_dirs
) ||
1337 !strv_isempty(context
->inaccessible_dirs
))
1340 if (context
->mount_flags
!= 0)
1343 if (context
->private_tmp
&& runtime
&& (runtime
->tmp_dir
|| runtime
->var_tmp_dir
))
1346 if (params
->bus_endpoint_path
)
1349 if (context
->private_devices
||
1350 context
->protect_system
!= PROTECT_SYSTEM_NO
||
1351 context
->protect_home
!= PROTECT_HOME_NO
)
1357 static int close_remaining_fds(
1358 const ExecParameters
*params
,
1359 ExecRuntime
*runtime
,
1361 int *fds
, unsigned n_fds
) {
1363 unsigned n_dont_close
= 0;
1364 int dont_close
[n_fds
+ 7];
1368 if (params
->stdin_fd
>= 0)
1369 dont_close
[n_dont_close
++] = params
->stdin_fd
;
1370 if (params
->stdout_fd
>= 0)
1371 dont_close
[n_dont_close
++] = params
->stdout_fd
;
1372 if (params
->stderr_fd
>= 0)
1373 dont_close
[n_dont_close
++] = params
->stderr_fd
;
1376 dont_close
[n_dont_close
++] = socket_fd
;
1378 memcpy(dont_close
+ n_dont_close
, fds
, sizeof(int) * n_fds
);
1379 n_dont_close
+= n_fds
;
1382 if (params
->bus_endpoint_fd
>= 0)
1383 dont_close
[n_dont_close
++] = params
->bus_endpoint_fd
;
1386 if (runtime
->netns_storage_socket
[0] >= 0)
1387 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[0];
1388 if (runtime
->netns_storage_socket
[1] >= 0)
1389 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[1];
1392 return close_all_fds(dont_close
, n_dont_close
);
1395 static int exec_child(
1397 ExecCommand
*command
,
1398 const ExecContext
*context
,
1399 const ExecParameters
*params
,
1400 ExecRuntime
*runtime
,
1403 int *fds
, unsigned n_fds
,
1407 _cleanup_strv_free_
char **our_env
= NULL
, **pam_env
= NULL
, **final_env
= NULL
, **final_argv
= NULL
;
1408 _cleanup_free_
char *mac_selinux_context_net
= NULL
;
1409 const char *username
= NULL
, *home
= NULL
, *shell
= NULL
, *wd
;
1410 uid_t uid
= UID_INVALID
;
1411 gid_t gid
= GID_INVALID
;
1413 bool needs_mount_namespace
;
1419 assert(exit_status
);
1421 rename_process_from_path(command
->path
);
1423 /* We reset exactly these signals, since they are the
1424 * only ones we set to SIG_IGN in the main daemon. All
1425 * others we leave untouched because we set them to
1426 * SIG_DFL or a valid handler initially, both of which
1427 * will be demoted to SIG_DFL. */
1428 (void) default_signals(SIGNALS_CRASH_HANDLER
,
1429 SIGNALS_IGNORE
, -1);
1431 if (context
->ignore_sigpipe
)
1432 (void) ignore_signals(SIGPIPE
, -1);
1434 r
= reset_signal_mask();
1436 *exit_status
= EXIT_SIGNAL_MASK
;
1440 if (params
->idle_pipe
)
1441 do_idle_pipe_dance(params
->idle_pipe
);
1443 /* Close sockets very early to make sure we don't
1444 * block init reexecution because it cannot bind its
1449 r
= close_remaining_fds(params
, runtime
, socket_fd
, fds
, n_fds
);
1451 *exit_status
= EXIT_FDS
;
1455 if (!context
->same_pgrp
)
1457 *exit_status
= EXIT_SETSID
;
1461 exec_context_tty_reset(context
);
1463 if (params
->confirm_spawn
) {
1466 r
= ask_for_confirmation(&response
, argv
);
1467 if (r
== -ETIMEDOUT
)
1468 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1470 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r
));
1471 else if (response
== 's') {
1472 write_confirm_message("Skipping execution.\n");
1473 *exit_status
= EXIT_CONFIRM
;
1475 } else if (response
== 'n') {
1476 write_confirm_message("Failing execution.\n");
1482 if (context
->user
) {
1483 username
= context
->user
;
1484 r
= get_user_creds(&username
, &uid
, &gid
, &home
, &shell
);
1486 *exit_status
= EXIT_USER
;
1491 if (context
->group
) {
1492 const char *g
= context
->group
;
1494 r
= get_group_creds(&g
, &gid
);
1496 *exit_status
= EXIT_GROUP
;
1502 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1503 * must sure to drop O_NONBLOCK */
1505 (void) fd_nonblock(socket_fd
, false);
1507 r
= setup_input(context
, params
, socket_fd
);
1509 *exit_status
= EXIT_STDIN
;
1513 r
= setup_output(unit
, context
, params
, STDOUT_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1515 *exit_status
= EXIT_STDOUT
;
1519 r
= setup_output(unit
, context
, params
, STDERR_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1521 *exit_status
= EXIT_STDERR
;
1525 if (params
->cgroup_path
) {
1526 r
= cg_attach_everywhere(params
->cgroup_supported
, params
->cgroup_path
, 0, NULL
, NULL
);
1528 *exit_status
= EXIT_CGROUP
;
1533 if (context
->oom_score_adjust_set
) {
1534 char t
[DECIMAL_STR_MAX(context
->oom_score_adjust
)];
1536 /* When we can't make this change due to EPERM, then
1537 * let's silently skip over it. User namespaces
1538 * prohibit write access to this file, and we
1539 * shouldn't trip up over that. */
1541 sprintf(t
, "%i", context
->oom_score_adjust
);
1542 r
= write_string_file("/proc/self/oom_score_adj", t
, 0);
1543 if (r
== -EPERM
|| r
== -EACCES
) {
1545 log_unit_debug_errno(unit
, r
, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
1548 *exit_status
= EXIT_OOM_ADJUST
;
1553 if (context
->nice_set
)
1554 if (setpriority(PRIO_PROCESS
, 0, context
->nice
) < 0) {
1555 *exit_status
= EXIT_NICE
;
1559 if (context
->cpu_sched_set
) {
1560 struct sched_param param
= {
1561 .sched_priority
= context
->cpu_sched_priority
,
1564 r
= sched_setscheduler(0,
1565 context
->cpu_sched_policy
|
1566 (context
->cpu_sched_reset_on_fork
?
1567 SCHED_RESET_ON_FORK
: 0),
1570 *exit_status
= EXIT_SETSCHEDULER
;
1575 if (context
->cpuset
)
1576 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context
->cpuset_ncpus
), context
->cpuset
) < 0) {
1577 *exit_status
= EXIT_CPUAFFINITY
;
1581 if (context
->ioprio_set
)
1582 if (ioprio_set(IOPRIO_WHO_PROCESS
, 0, context
->ioprio
) < 0) {
1583 *exit_status
= EXIT_IOPRIO
;
1587 if (context
->timer_slack_nsec
!= NSEC_INFINITY
)
1588 if (prctl(PR_SET_TIMERSLACK
, context
->timer_slack_nsec
) < 0) {
1589 *exit_status
= EXIT_TIMERSLACK
;
1593 if (context
->personality
!= PERSONALITY_INVALID
)
1594 if (personality(context
->personality
) < 0) {
1595 *exit_status
= EXIT_PERSONALITY
;
1599 if (context
->utmp_id
)
1600 utmp_put_init_process(context
->utmp_id
, getpid(), getsid(0), context
->tty_path
,
1601 context
->utmp_mode
== EXEC_UTMP_INIT
? INIT_PROCESS
:
1602 context
->utmp_mode
== EXEC_UTMP_LOGIN
? LOGIN_PROCESS
:
1604 username
? "root" : context
->user
);
1606 if (context
->user
&& is_terminal_input(context
->std_input
)) {
1607 r
= chown_terminal(STDIN_FILENO
, uid
);
1609 *exit_status
= EXIT_STDIN
;
1614 if (params
->bus_endpoint_fd
>= 0 && context
->bus_endpoint
) {
1615 uid_t ep_uid
= (uid
== UID_INVALID
) ? 0 : uid
;
1617 r
= bus_kernel_set_endpoint_policy(params
->bus_endpoint_fd
, ep_uid
, context
->bus_endpoint
);
1619 *exit_status
= EXIT_BUS_ENDPOINT
;
1624 /* If delegation is enabled we'll pass ownership of the cgroup
1625 * (but only in systemd's own controller hierarchy!) to the
1626 * user of the new process. */
1627 if (params
->cgroup_path
&& context
->user
&& params
->cgroup_delegate
) {
1628 r
= cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0644, uid
, gid
);
1630 *exit_status
= EXIT_CGROUP
;
1635 r
= cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0755, uid
, gid
);
1637 *exit_status
= EXIT_CGROUP
;
1642 if (!strv_isempty(context
->runtime_directory
) && params
->runtime_prefix
) {
1645 STRV_FOREACH(rt
, context
->runtime_directory
) {
1646 _cleanup_free_
char *p
;
1648 p
= strjoin(params
->runtime_prefix
, "/", *rt
, NULL
);
1650 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1654 r
= mkdir_p_label(p
, context
->runtime_directory_mode
);
1656 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1660 r
= chmod_and_chown(p
, context
->runtime_directory_mode
, uid
, gid
);
1662 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1668 umask(context
->umask
);
1670 if (params
->apply_permissions
) {
1671 r
= enforce_groups(context
, username
, gid
);
1673 *exit_status
= EXIT_GROUP
;
1677 if (context
->smack_process_label
) {
1678 r
= mac_smack_apply_pid(0, context
->smack_process_label
);
1680 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1684 #ifdef SMACK_DEFAULT_PROCESS_LABEL
1686 _cleanup_free_
char *exec_label
= NULL
;
1688 r
= mac_smack_read(command
->path
, SMACK_ATTR_EXEC
, &exec_label
);
1689 if (r
< 0 && r
!= -ENODATA
&& r
!= -EOPNOTSUPP
) {
1690 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1694 r
= mac_smack_apply_pid(0, exec_label
? : SMACK_DEFAULT_PROCESS_LABEL
);
1696 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1703 if (context
->pam_name
&& username
) {
1704 r
= setup_pam(context
->pam_name
, username
, uid
, context
->tty_path
, &pam_env
, fds
, n_fds
);
1706 *exit_status
= EXIT_PAM
;
1713 if (context
->private_network
&& runtime
&& runtime
->netns_storage_socket
[0] >= 0) {
1714 r
= setup_netns(runtime
->netns_storage_socket
);
1716 *exit_status
= EXIT_NETWORK
;
1721 needs_mount_namespace
= exec_needs_mount_namespace(context
, params
, runtime
);
1723 if (needs_mount_namespace
) {
1724 char *tmp
= NULL
, *var
= NULL
;
1726 /* The runtime struct only contains the parent
1727 * of the private /tmp, which is
1728 * non-accessible to world users. Inside of it
1729 * there's a /tmp that is sticky, and that's
1730 * the one we want to use here. */
1732 if (context
->private_tmp
&& runtime
) {
1733 if (runtime
->tmp_dir
)
1734 tmp
= strjoina(runtime
->tmp_dir
, "/tmp");
1735 if (runtime
->var_tmp_dir
)
1736 var
= strjoina(runtime
->var_tmp_dir
, "/tmp");
1739 r
= setup_namespace(
1740 params
->apply_chroot
? context
->root_directory
: NULL
,
1741 context
->read_write_dirs
,
1742 context
->read_only_dirs
,
1743 context
->inaccessible_dirs
,
1746 params
->bus_endpoint_path
,
1747 context
->private_devices
,
1748 context
->protect_home
,
1749 context
->protect_system
,
1750 context
->mount_flags
);
1752 /* If we couldn't set up the namespace this is
1753 * probably due to a missing capability. In this case,
1754 * silently proceeed. */
1755 if (r
== -EPERM
|| r
== -EACCES
) {
1757 log_unit_debug_errno(unit
, r
, "Failed to set up namespace, assuming containerized execution, ignoring: %m");
1760 *exit_status
= EXIT_NAMESPACE
;
1765 if (context
->working_directory_home
)
1767 else if (context
->working_directory
)
1768 wd
= context
->working_directory
;
1772 if (params
->apply_chroot
) {
1773 if (!needs_mount_namespace
&& context
->root_directory
)
1774 if (chroot(context
->root_directory
) < 0) {
1775 *exit_status
= EXIT_CHROOT
;
1779 if (chdir(wd
) < 0 &&
1780 !context
->working_directory_missing_ok
) {
1781 *exit_status
= EXIT_CHDIR
;
1787 d
= strjoina(strempty(context
->root_directory
), "/", strempty(wd
));
1789 !context
->working_directory_missing_ok
) {
1790 *exit_status
= EXIT_CHDIR
;
1796 if (params
->apply_permissions
&& mac_selinux_use() && params
->selinux_context_net
&& socket_fd
>= 0) {
1797 r
= mac_selinux_get_child_mls_label(socket_fd
, command
->path
, context
->selinux_context
, &mac_selinux_context_net
);
1799 *exit_status
= EXIT_SELINUX_CONTEXT
;
1805 /* We repeat the fd closing here, to make sure that
1806 * nothing is leaked from the PAM modules. Note that
1807 * we are more aggressive this time since socket_fd
1808 * and the netns fds we don't need anymore. The custom
1809 * endpoint fd was needed to upload the policy and can
1810 * now be closed as well. */
1811 r
= close_all_fds(fds
, n_fds
);
1813 r
= shift_fds(fds
, n_fds
);
1815 r
= flags_fds(fds
, n_fds
, context
->non_blocking
);
1817 *exit_status
= EXIT_FDS
;
1821 if (params
->apply_permissions
) {
1823 for (i
= 0; i
< _RLIMIT_MAX
; i
++) {
1824 if (!context
->rlimit
[i
])
1827 if (setrlimit_closest(i
, context
->rlimit
[i
]) < 0) {
1828 *exit_status
= EXIT_LIMITS
;
1833 if (context
->capability_bounding_set_drop
) {
1834 r
= capability_bounding_set_drop(context
->capability_bounding_set_drop
, false);
1836 *exit_status
= EXIT_CAPABILITIES
;
1841 if (context
->user
) {
1842 r
= enforce_user(context
, uid
);
1844 *exit_status
= EXIT_USER
;
1849 /* PR_GET_SECUREBITS is not privileged, while
1850 * PR_SET_SECUREBITS is. So to suppress
1851 * potential EPERMs we'll try not to call
1852 * PR_SET_SECUREBITS unless necessary. */
1853 if (prctl(PR_GET_SECUREBITS
) != context
->secure_bits
)
1854 if (prctl(PR_SET_SECUREBITS
, context
->secure_bits
) < 0) {
1855 *exit_status
= EXIT_SECUREBITS
;
1859 if (context
->capabilities
)
1860 if (cap_set_proc(context
->capabilities
) < 0) {
1861 *exit_status
= EXIT_CAPABILITIES
;
1865 if (context
->no_new_privileges
)
1866 if (prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0) < 0) {
1867 *exit_status
= EXIT_NO_NEW_PRIVILEGES
;
1872 if (context
->address_families_whitelist
||
1873 !set_isempty(context
->address_families
)) {
1874 r
= apply_address_families(context
);
1876 *exit_status
= EXIT_ADDRESS_FAMILIES
;
1881 if (context
->syscall_whitelist
||
1882 !set_isempty(context
->syscall_filter
) ||
1883 !set_isempty(context
->syscall_archs
)) {
1884 r
= apply_seccomp(context
);
1886 *exit_status
= EXIT_SECCOMP
;
1893 if (mac_selinux_use()) {
1894 char *exec_context
= mac_selinux_context_net
?: context
->selinux_context
;
1897 r
= setexeccon(exec_context
);
1899 *exit_status
= EXIT_SELINUX_CONTEXT
;
1906 #ifdef HAVE_APPARMOR
1907 if (context
->apparmor_profile
&& mac_apparmor_use()) {
1908 r
= aa_change_onexec(context
->apparmor_profile
);
1909 if (r
< 0 && !context
->apparmor_profile_ignore
) {
1910 *exit_status
= EXIT_APPARMOR_PROFILE
;
1917 r
= build_environment(context
, n_fds
, params
->fd_names
, params
->watchdog_usec
, home
, username
, shell
, &our_env
);
1919 *exit_status
= EXIT_MEMORY
;
1923 final_env
= strv_env_merge(5,
1924 params
->environment
,
1926 context
->environment
,
1931 *exit_status
= EXIT_MEMORY
;
1935 final_argv
= replace_env_argv(argv
, final_env
);
1937 *exit_status
= EXIT_MEMORY
;
1941 final_env
= strv_env_clean(final_env
);
1943 if (_unlikely_(log_get_max_level() >= LOG_DEBUG
)) {
1944 _cleanup_free_
char *line
;
1946 line
= exec_command_line(final_argv
);
1949 log_struct(LOG_DEBUG
,
1951 "EXECUTABLE=%s", command
->path
,
1952 LOG_UNIT_MESSAGE(unit
, "Executing: %s", line
),
1958 execve(command
->path
, final_argv
, final_env
);
1959 *exit_status
= EXIT_EXEC
;
1963 int exec_spawn(Unit
*unit
,
1964 ExecCommand
*command
,
1965 const ExecContext
*context
,
1966 const ExecParameters
*params
,
1967 ExecRuntime
*runtime
,
1970 _cleanup_strv_free_
char **files_env
= NULL
;
1971 int *fds
= NULL
; unsigned n_fds
= 0;
1972 _cleanup_free_
char *line
= NULL
;
1982 assert(params
->fds
|| params
->n_fds
<= 0);
1984 if (context
->std_input
== EXEC_INPUT_SOCKET
||
1985 context
->std_output
== EXEC_OUTPUT_SOCKET
||
1986 context
->std_error
== EXEC_OUTPUT_SOCKET
) {
1988 if (params
->n_fds
!= 1) {
1989 log_unit_error(unit
, "Got more than one socket.");
1993 socket_fd
= params
->fds
[0];
1997 n_fds
= params
->n_fds
;
2000 r
= exec_context_load_environment(unit
, context
, &files_env
);
2002 return log_unit_error_errno(unit
, r
, "Failed to load environment files: %m");
2004 argv
= params
->argv
?: command
->argv
;
2005 line
= exec_command_line(argv
);
2009 log_struct(LOG_DEBUG
,
2011 LOG_UNIT_MESSAGE(unit
, "About to execute: %s", line
),
2012 "EXECUTABLE=%s", command
->path
,
2016 return log_unit_error_errno(unit
, r
, "Failed to fork: %m");
2021 r
= exec_child(unit
,
2033 log_struct_errno(LOG_ERR
, r
,
2034 LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED
),
2036 LOG_UNIT_MESSAGE(unit
, "Failed at step %s spawning %s: %m",
2037 exit_status_to_string(exit_status
, EXIT_STATUS_SYSTEMD
),
2039 "EXECUTABLE=%s", command
->path
,
2046 log_unit_debug(unit
, "Forked %s as "PID_FMT
, command
->path
, pid
);
2048 /* We add the new process to the cgroup both in the child (so
2049 * that we can be sure that no user code is ever executed
2050 * outside of the cgroup) and in the parent (so that we can be
2051 * sure that when we kill the cgroup the process will be
2053 if (params
->cgroup_path
)
2054 (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, pid
);
2056 exec_status_start(&command
->exec_status
, pid
);
2062 void exec_context_init(ExecContext
*c
) {
2066 c
->ioprio
= IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE
, 0);
2067 c
->cpu_sched_policy
= SCHED_OTHER
;
2068 c
->syslog_priority
= LOG_DAEMON
|LOG_INFO
;
2069 c
->syslog_level_prefix
= true;
2070 c
->ignore_sigpipe
= true;
2071 c
->timer_slack_nsec
= NSEC_INFINITY
;
2072 c
->personality
= PERSONALITY_INVALID
;
2073 c
->runtime_directory_mode
= 0755;
2076 void exec_context_done(ExecContext
*c
) {
2081 c
->environment
= strv_free(c
->environment
);
2082 c
->environment_files
= strv_free(c
->environment_files
);
2084 for (l
= 0; l
< ELEMENTSOF(c
->rlimit
); l
++)
2085 c
->rlimit
[l
] = mfree(c
->rlimit
[l
]);
2087 c
->working_directory
= mfree(c
->working_directory
);
2088 c
->root_directory
= mfree(c
->root_directory
);
2089 c
->tty_path
= mfree(c
->tty_path
);
2090 c
->syslog_identifier
= mfree(c
->syslog_identifier
);
2091 c
->user
= mfree(c
->user
);
2092 c
->group
= mfree(c
->group
);
2094 c
->supplementary_groups
= strv_free(c
->supplementary_groups
);
2096 c
->pam_name
= mfree(c
->pam_name
);
2098 if (c
->capabilities
) {
2099 cap_free(c
->capabilities
);
2100 c
->capabilities
= NULL
;
2103 c
->read_only_dirs
= strv_free(c
->read_only_dirs
);
2104 c
->read_write_dirs
= strv_free(c
->read_write_dirs
);
2105 c
->inaccessible_dirs
= strv_free(c
->inaccessible_dirs
);
2108 CPU_FREE(c
->cpuset
);
2110 c
->utmp_id
= mfree(c
->utmp_id
);
2111 c
->selinux_context
= mfree(c
->selinux_context
);
2112 c
->apparmor_profile
= mfree(c
->apparmor_profile
);
2114 c
->syscall_filter
= set_free(c
->syscall_filter
);
2115 c
->syscall_archs
= set_free(c
->syscall_archs
);
2116 c
->address_families
= set_free(c
->address_families
);
2118 c
->runtime_directory
= strv_free(c
->runtime_directory
);
2120 bus_endpoint_free(c
->bus_endpoint
);
2121 c
->bus_endpoint
= NULL
;
2124 int exec_context_destroy_runtime_directory(ExecContext
*c
, const char *runtime_prefix
) {
2129 if (!runtime_prefix
)
2132 STRV_FOREACH(i
, c
->runtime_directory
) {
2133 _cleanup_free_
char *p
;
2135 p
= strjoin(runtime_prefix
, "/", *i
, NULL
);
2139 /* We execute this synchronously, since we need to be
2140 * sure this is gone when we start the service
2142 (void) rm_rf(p
, REMOVE_ROOT
);
2148 void exec_command_done(ExecCommand
*c
) {
2151 c
->path
= mfree(c
->path
);
2153 c
->argv
= strv_free(c
->argv
);
2156 void exec_command_done_array(ExecCommand
*c
, unsigned n
) {
2159 for (i
= 0; i
< n
; i
++)
2160 exec_command_done(c
+i
);
2163 ExecCommand
* exec_command_free_list(ExecCommand
*c
) {
2167 LIST_REMOVE(command
, c
, i
);
2168 exec_command_done(i
);
2175 void exec_command_free_array(ExecCommand
**c
, unsigned n
) {
2178 for (i
= 0; i
< n
; i
++)
2179 c
[i
] = exec_command_free_list(c
[i
]);
2182 typedef struct InvalidEnvInfo
{
2187 static void invalid_env(const char *p
, void *userdata
) {
2188 InvalidEnvInfo
*info
= userdata
;
2190 log_unit_error(info
->unit
, "Ignoring invalid environment assignment '%s': %s", p
, info
->path
);
2193 int exec_context_load_environment(Unit
*unit
, const ExecContext
*c
, char ***l
) {
2194 char **i
, **r
= NULL
;
2199 STRV_FOREACH(i
, c
->environment_files
) {
2202 bool ignore
= false;
2204 _cleanup_globfree_ glob_t pglob
= {};
2214 if (!path_is_absolute(fn
)) {
2222 /* Filename supports globbing, take all matching files */
2224 if (glob(fn
, 0, NULL
, &pglob
) != 0) {
2229 return errno
? -errno
: -EINVAL
;
2231 count
= pglob
.gl_pathc
;
2239 for (n
= 0; n
< count
; n
++) {
2240 k
= load_env_file(NULL
, pglob
.gl_pathv
[n
], NULL
, &p
);
2248 /* Log invalid environment variables with filename */
2250 InvalidEnvInfo info
= {
2252 .path
= pglob
.gl_pathv
[n
]
2255 p
= strv_env_clean_with_callback(p
, invalid_env
, &info
);
2263 m
= strv_env_merge(2, r
, p
);
2279 static bool tty_may_match_dev_console(const char *tty
) {
2280 _cleanup_free_
char *active
= NULL
;
2283 if (startswith(tty
, "/dev/"))
2286 /* trivial identity? */
2287 if (streq(tty
, "console"))
2290 console
= resolve_dev_console(&active
);
2291 /* if we could not resolve, assume it may */
2295 /* "tty0" means the active VC, so it may be the same sometimes */
2296 return streq(console
, tty
) || (streq(console
, "tty0") && tty_is_vc(tty
));
2299 bool exec_context_may_touch_console(ExecContext
*ec
) {
2300 return (ec
->tty_reset
|| ec
->tty_vhangup
|| ec
->tty_vt_disallocate
||
2301 is_terminal_input(ec
->std_input
) ||
2302 is_terminal_output(ec
->std_output
) ||
2303 is_terminal_output(ec
->std_error
)) &&
2304 tty_may_match_dev_console(tty_path(ec
));
2307 static void strv_fprintf(FILE *f
, char **l
) {
2313 fprintf(f
, " %s", *g
);
2316 void exec_context_dump(ExecContext
*c
, FILE* f
, const char *prefix
) {
2323 prefix
= strempty(prefix
);
2327 "%sWorkingDirectory: %s\n"
2328 "%sRootDirectory: %s\n"
2329 "%sNonBlocking: %s\n"
2330 "%sPrivateTmp: %s\n"
2331 "%sPrivateNetwork: %s\n"
2332 "%sPrivateDevices: %s\n"
2333 "%sProtectHome: %s\n"
2334 "%sProtectSystem: %s\n"
2335 "%sIgnoreSIGPIPE: %s\n",
2337 prefix
, c
->working_directory
? c
->working_directory
: "/",
2338 prefix
, c
->root_directory
? c
->root_directory
: "/",
2339 prefix
, yes_no(c
->non_blocking
),
2340 prefix
, yes_no(c
->private_tmp
),
2341 prefix
, yes_no(c
->private_network
),
2342 prefix
, yes_no(c
->private_devices
),
2343 prefix
, protect_home_to_string(c
->protect_home
),
2344 prefix
, protect_system_to_string(c
->protect_system
),
2345 prefix
, yes_no(c
->ignore_sigpipe
));
2347 STRV_FOREACH(e
, c
->environment
)
2348 fprintf(f
, "%sEnvironment: %s\n", prefix
, *e
);
2350 STRV_FOREACH(e
, c
->environment_files
)
2351 fprintf(f
, "%sEnvironmentFile: %s\n", prefix
, *e
);
2353 fprintf(f
, "%sRuntimeDirectoryMode: %04o\n", prefix
, c
->runtime_directory_mode
);
2355 STRV_FOREACH(d
, c
->runtime_directory
)
2356 fprintf(f
, "%sRuntimeDirectory: %s\n", prefix
, *d
);
2363 if (c
->oom_score_adjust_set
)
2365 "%sOOMScoreAdjust: %i\n",
2366 prefix
, c
->oom_score_adjust
);
2368 for (i
= 0; i
< RLIM_NLIMITS
; i
++)
2370 fprintf(f
, "%s%s: "RLIM_FMT
"\n",
2371 prefix
, rlimit_to_string(i
), c
->rlimit
[i
]->rlim_max
);
2373 if (c
->ioprio_set
) {
2374 _cleanup_free_
char *class_str
= NULL
;
2376 ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c
->ioprio
), &class_str
);
2378 "%sIOSchedulingClass: %s\n"
2379 "%sIOPriority: %i\n",
2380 prefix
, strna(class_str
),
2381 prefix
, (int) IOPRIO_PRIO_DATA(c
->ioprio
));
2384 if (c
->cpu_sched_set
) {
2385 _cleanup_free_
char *policy_str
= NULL
;
2387 sched_policy_to_string_alloc(c
->cpu_sched_policy
, &policy_str
);
2389 "%sCPUSchedulingPolicy: %s\n"
2390 "%sCPUSchedulingPriority: %i\n"
2391 "%sCPUSchedulingResetOnFork: %s\n",
2392 prefix
, strna(policy_str
),
2393 prefix
, c
->cpu_sched_priority
,
2394 prefix
, yes_no(c
->cpu_sched_reset_on_fork
));
2398 fprintf(f
, "%sCPUAffinity:", prefix
);
2399 for (i
= 0; i
< c
->cpuset_ncpus
; i
++)
2400 if (CPU_ISSET_S(i
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
), c
->cpuset
))
2401 fprintf(f
, " %u", i
);
2405 if (c
->timer_slack_nsec
!= NSEC_INFINITY
)
2406 fprintf(f
, "%sTimerSlackNSec: "NSEC_FMT
"\n", prefix
, c
->timer_slack_nsec
);
2409 "%sStandardInput: %s\n"
2410 "%sStandardOutput: %s\n"
2411 "%sStandardError: %s\n",
2412 prefix
, exec_input_to_string(c
->std_input
),
2413 prefix
, exec_output_to_string(c
->std_output
),
2414 prefix
, exec_output_to_string(c
->std_error
));
2420 "%sTTYVHangup: %s\n"
2421 "%sTTYVTDisallocate: %s\n",
2422 prefix
, c
->tty_path
,
2423 prefix
, yes_no(c
->tty_reset
),
2424 prefix
, yes_no(c
->tty_vhangup
),
2425 prefix
, yes_no(c
->tty_vt_disallocate
));
2427 if (c
->std_output
== EXEC_OUTPUT_SYSLOG
||
2428 c
->std_output
== EXEC_OUTPUT_KMSG
||
2429 c
->std_output
== EXEC_OUTPUT_JOURNAL
||
2430 c
->std_output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2431 c
->std_output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2432 c
->std_output
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
||
2433 c
->std_error
== EXEC_OUTPUT_SYSLOG
||
2434 c
->std_error
== EXEC_OUTPUT_KMSG
||
2435 c
->std_error
== EXEC_OUTPUT_JOURNAL
||
2436 c
->std_error
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2437 c
->std_error
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2438 c
->std_error
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
) {
2440 _cleanup_free_
char *fac_str
= NULL
, *lvl_str
= NULL
;
2442 log_facility_unshifted_to_string_alloc(c
->syslog_priority
>> 3, &fac_str
);
2443 log_level_to_string_alloc(LOG_PRI(c
->syslog_priority
), &lvl_str
);
2446 "%sSyslogFacility: %s\n"
2447 "%sSyslogLevel: %s\n",
2448 prefix
, strna(fac_str
),
2449 prefix
, strna(lvl_str
));
2452 if (c
->capabilities
) {
2453 _cleanup_cap_free_charp_
char *t
;
2455 t
= cap_to_text(c
->capabilities
, NULL
);
2457 fprintf(f
, "%sCapabilities: %s\n", prefix
, t
);
2461 fprintf(f
, "%sSecure Bits:%s%s%s%s%s%s\n",
2463 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS
) ? " keep-caps" : "",
2464 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS_LOCKED
) ? " keep-caps-locked" : "",
2465 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP
) ? " no-setuid-fixup" : "",
2466 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP_LOCKED
) ? " no-setuid-fixup-locked" : "",
2467 (c
->secure_bits
& 1<<SECURE_NOROOT
) ? " noroot" : "",
2468 (c
->secure_bits
& 1<<SECURE_NOROOT_LOCKED
) ? "noroot-locked" : "");
2470 if (c
->capability_bounding_set_drop
) {
2472 fprintf(f
, "%sCapabilityBoundingSet:", prefix
);
2474 for (l
= 0; l
<= cap_last_cap(); l
++)
2475 if (!(c
->capability_bounding_set_drop
& ((uint64_t) 1ULL << (uint64_t) l
)))
2476 fprintf(f
, " %s", strna(capability_to_name(l
)));
2482 fprintf(f
, "%sUser: %s\n", prefix
, c
->user
);
2484 fprintf(f
, "%sGroup: %s\n", prefix
, c
->group
);
2486 if (strv_length(c
->supplementary_groups
) > 0) {
2487 fprintf(f
, "%sSupplementaryGroups:", prefix
);
2488 strv_fprintf(f
, c
->supplementary_groups
);
2493 fprintf(f
, "%sPAMName: %s\n", prefix
, c
->pam_name
);
2495 if (strv_length(c
->read_write_dirs
) > 0) {
2496 fprintf(f
, "%sReadWriteDirs:", prefix
);
2497 strv_fprintf(f
, c
->read_write_dirs
);
2501 if (strv_length(c
->read_only_dirs
) > 0) {
2502 fprintf(f
, "%sReadOnlyDirs:", prefix
);
2503 strv_fprintf(f
, c
->read_only_dirs
);
2507 if (strv_length(c
->inaccessible_dirs
) > 0) {
2508 fprintf(f
, "%sInaccessibleDirs:", prefix
);
2509 strv_fprintf(f
, c
->inaccessible_dirs
);
2515 "%sUtmpIdentifier: %s\n",
2516 prefix
, c
->utmp_id
);
2518 if (c
->selinux_context
)
2520 "%sSELinuxContext: %s%s\n",
2521 prefix
, c
->selinux_context_ignore
? "-" : "", c
->selinux_context
);
2523 if (c
->personality
!= PERSONALITY_INVALID
)
2525 "%sPersonality: %s\n",
2526 prefix
, strna(personality_to_string(c
->personality
)));
2528 if (c
->syscall_filter
) {
2536 "%sSystemCallFilter: ",
2539 if (!c
->syscall_whitelist
)
2543 SET_FOREACH(id
, c
->syscall_filter
, j
) {
2544 _cleanup_free_
char *name
= NULL
;
2551 name
= seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE
, PTR_TO_INT(id
) - 1);
2552 fputs(strna(name
), f
);
2559 if (c
->syscall_archs
) {
2566 "%sSystemCallArchitectures:",
2570 SET_FOREACH(id
, c
->syscall_archs
, j
)
2571 fprintf(f
, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id
) - 1)));
2576 if (c
->syscall_errno
!= 0)
2578 "%sSystemCallErrorNumber: %s\n",
2579 prefix
, strna(errno_to_name(c
->syscall_errno
)));
2581 if (c
->apparmor_profile
)
2583 "%sAppArmorProfile: %s%s\n",
2584 prefix
, c
->apparmor_profile_ignore
? "-" : "", c
->apparmor_profile
);
2587 bool exec_context_maintains_privileges(ExecContext
*c
) {
2590 /* Returns true if the process forked off would run run under
2591 * an unchanged UID or as root. */
2596 if (streq(c
->user
, "root") || streq(c
->user
, "0"))
2602 void exec_status_start(ExecStatus
*s
, pid_t pid
) {
2607 dual_timestamp_get(&s
->start_timestamp
);
2610 void exec_status_exit(ExecStatus
*s
, ExecContext
*context
, pid_t pid
, int code
, int status
) {
2613 if (s
->pid
&& s
->pid
!= pid
)
2617 dual_timestamp_get(&s
->exit_timestamp
);
2623 if (context
->utmp_id
)
2624 utmp_put_dead_process(context
->utmp_id
, pid
, code
, status
);
2626 exec_context_tty_reset(context
);
2630 void exec_status_dump(ExecStatus
*s
, FILE *f
, const char *prefix
) {
2631 char buf
[FORMAT_TIMESTAMP_MAX
];
2639 prefix
= strempty(prefix
);
2642 "%sPID: "PID_FMT
"\n",
2645 if (s
->start_timestamp
.realtime
> 0)
2647 "%sStart Timestamp: %s\n",
2648 prefix
, format_timestamp(buf
, sizeof(buf
), s
->start_timestamp
.realtime
));
2650 if (s
->exit_timestamp
.realtime
> 0)
2652 "%sExit Timestamp: %s\n"
2654 "%sExit Status: %i\n",
2655 prefix
, format_timestamp(buf
, sizeof(buf
), s
->exit_timestamp
.realtime
),
2656 prefix
, sigchld_code_to_string(s
->code
),
2660 char *exec_command_line(char **argv
) {
2668 STRV_FOREACH(a
, argv
)
2671 if (!(n
= new(char, k
)))
2675 STRV_FOREACH(a
, argv
) {
2682 if (strpbrk(*a
, WHITESPACE
)) {
2693 /* FIXME: this doesn't really handle arguments that have
2694 * spaces and ticks in them */
2699 void exec_command_dump(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2700 _cleanup_free_
char *cmd
= NULL
;
2701 const char *prefix2
;
2706 prefix
= strempty(prefix
);
2707 prefix2
= strjoina(prefix
, "\t");
2709 cmd
= exec_command_line(c
->argv
);
2711 "%sCommand Line: %s\n",
2712 prefix
, cmd
? cmd
: strerror(ENOMEM
));
2714 exec_status_dump(&c
->exec_status
, f
, prefix2
);
2717 void exec_command_dump_list(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2720 prefix
= strempty(prefix
);
2722 LIST_FOREACH(command
, c
, c
)
2723 exec_command_dump(c
, f
, prefix
);
2726 void exec_command_append_list(ExecCommand
**l
, ExecCommand
*e
) {
2733 /* It's kind of important, that we keep the order here */
2734 LIST_FIND_TAIL(command
, *l
, end
);
2735 LIST_INSERT_AFTER(command
, *l
, end
, e
);
2740 int exec_command_set(ExecCommand
*c
, const char *path
, ...) {
2748 l
= strv_new_ap(path
, ap
);
2769 int exec_command_append(ExecCommand
*c
, const char *path
, ...) {
2770 _cleanup_strv_free_
char **l
= NULL
;
2778 l
= strv_new_ap(path
, ap
);
2784 r
= strv_extend_strv(&c
->argv
, l
, false);
2792 static int exec_runtime_allocate(ExecRuntime
**rt
) {
2797 *rt
= new0(ExecRuntime
, 1);
2802 (*rt
)->netns_storage_socket
[0] = (*rt
)->netns_storage_socket
[1] = -1;
2807 int exec_runtime_make(ExecRuntime
**rt
, ExecContext
*c
, const char *id
) {
2817 if (!c
->private_network
&& !c
->private_tmp
)
2820 r
= exec_runtime_allocate(rt
);
2824 if (c
->private_network
&& (*rt
)->netns_storage_socket
[0] < 0) {
2825 if (socketpair(AF_UNIX
, SOCK_DGRAM
, 0, (*rt
)->netns_storage_socket
) < 0)
2829 if (c
->private_tmp
&& !(*rt
)->tmp_dir
) {
2830 r
= setup_tmp_dirs(id
, &(*rt
)->tmp_dir
, &(*rt
)->var_tmp_dir
);
2838 ExecRuntime
*exec_runtime_ref(ExecRuntime
*r
) {
2840 assert(r
->n_ref
> 0);
2846 ExecRuntime
*exec_runtime_unref(ExecRuntime
*r
) {
2851 assert(r
->n_ref
> 0);
2858 free(r
->var_tmp_dir
);
2859 safe_close_pair(r
->netns_storage_socket
);
2865 int exec_runtime_serialize(Unit
*u
, ExecRuntime
*rt
, FILE *f
, FDSet
*fds
) {
2874 unit_serialize_item(u
, f
, "tmp-dir", rt
->tmp_dir
);
2876 if (rt
->var_tmp_dir
)
2877 unit_serialize_item(u
, f
, "var-tmp-dir", rt
->var_tmp_dir
);
2879 if (rt
->netns_storage_socket
[0] >= 0) {
2882 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[0]);
2886 unit_serialize_item_format(u
, f
, "netns-socket-0", "%i", copy
);
2889 if (rt
->netns_storage_socket
[1] >= 0) {
2892 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[1]);
2896 unit_serialize_item_format(u
, f
, "netns-socket-1", "%i", copy
);
2902 int exec_runtime_deserialize_item(Unit
*u
, ExecRuntime
**rt
, const char *key
, const char *value
, FDSet
*fds
) {
2909 if (streq(key
, "tmp-dir")) {
2912 r
= exec_runtime_allocate(rt
);
2916 copy
= strdup(value
);
2920 free((*rt
)->tmp_dir
);
2921 (*rt
)->tmp_dir
= copy
;
2923 } else if (streq(key
, "var-tmp-dir")) {
2926 r
= exec_runtime_allocate(rt
);
2930 copy
= strdup(value
);
2934 free((*rt
)->var_tmp_dir
);
2935 (*rt
)->var_tmp_dir
= copy
;
2937 } else if (streq(key
, "netns-socket-0")) {
2940 r
= exec_runtime_allocate(rt
);
2944 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
2945 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
2947 safe_close((*rt
)->netns_storage_socket
[0]);
2948 (*rt
)->netns_storage_socket
[0] = fdset_remove(fds
, fd
);
2950 } else if (streq(key
, "netns-socket-1")) {
2953 r
= exec_runtime_allocate(rt
);
2957 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
2958 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
2960 safe_close((*rt
)->netns_storage_socket
[1]);
2961 (*rt
)->netns_storage_socket
[1] = fdset_remove(fds
, fd
);
2969 static void *remove_tmpdir_thread(void *p
) {
2970 _cleanup_free_
char *path
= p
;
2972 (void) rm_rf(path
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
2976 void exec_runtime_destroy(ExecRuntime
*rt
) {
2982 /* If there are multiple users of this, let's leave the stuff around */
2987 log_debug("Spawning thread to nuke %s", rt
->tmp_dir
);
2989 r
= asynchronous_job(remove_tmpdir_thread
, rt
->tmp_dir
);
2991 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->tmp_dir
);
2998 if (rt
->var_tmp_dir
) {
2999 log_debug("Spawning thread to nuke %s", rt
->var_tmp_dir
);
3001 r
= asynchronous_job(remove_tmpdir_thread
, rt
->var_tmp_dir
);
3003 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->var_tmp_dir
);
3004 free(rt
->var_tmp_dir
);
3007 rt
->var_tmp_dir
= NULL
;
3010 safe_close_pair(rt
->netns_storage_socket
);
3013 static const char* const exec_input_table
[_EXEC_INPUT_MAX
] = {
3014 [EXEC_INPUT_NULL
] = "null",
3015 [EXEC_INPUT_TTY
] = "tty",
3016 [EXEC_INPUT_TTY_FORCE
] = "tty-force",
3017 [EXEC_INPUT_TTY_FAIL
] = "tty-fail",
3018 [EXEC_INPUT_SOCKET
] = "socket"
3021 DEFINE_STRING_TABLE_LOOKUP(exec_input
, ExecInput
);
3023 static const char* const exec_output_table
[_EXEC_OUTPUT_MAX
] = {
3024 [EXEC_OUTPUT_INHERIT
] = "inherit",
3025 [EXEC_OUTPUT_NULL
] = "null",
3026 [EXEC_OUTPUT_TTY
] = "tty",
3027 [EXEC_OUTPUT_SYSLOG
] = "syslog",
3028 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE
] = "syslog+console",
3029 [EXEC_OUTPUT_KMSG
] = "kmsg",
3030 [EXEC_OUTPUT_KMSG_AND_CONSOLE
] = "kmsg+console",
3031 [EXEC_OUTPUT_JOURNAL
] = "journal",
3032 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE
] = "journal+console",
3033 [EXEC_OUTPUT_SOCKET
] = "socket"
3036 DEFINE_STRING_TABLE_LOOKUP(exec_output
, ExecOutput
);
3038 static const char* const exec_utmp_mode_table
[_EXEC_UTMP_MODE_MAX
] = {
3039 [EXEC_UTMP_INIT
] = "init",
3040 [EXEC_UTMP_LOGIN
] = "login",
3041 [EXEC_UTMP_USER
] = "user",
3044 DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode
, ExecUtmpMode
);