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"
57 #include "apparmor-util.h"
61 #include "bus-endpoint.h"
63 #include "capability.h"
66 #include "errno-list.h"
68 #include "exit-status.h"
71 #include "formats-util.h"
77 #include "namespace.h"
78 #include "path-util.h"
79 #include "process-util.h"
82 #include "seccomp-util.h"
84 #include "securebits.h"
85 #include "selinux-util.h"
86 #include "signal-util.h"
87 #include "smack-util.h"
88 #include "string-util.h"
90 #include "terminal-util.h"
93 #include "utmp-wtmp.h"
95 #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
96 #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
98 /* This assumes there is a 'tty' group */
101 #define SNDBUF_SIZE (8*1024*1024)
103 static int shift_fds(int fds
[], unsigned n_fds
) {
104 int start
, restart_from
;
109 /* Modifies the fds array! (sorts it) */
119 for (i
= start
; i
< (int) n_fds
; i
++) {
122 /* Already at right index? */
126 nfd
= fcntl(fds
[i
], F_DUPFD
, i
+ 3);
133 /* Hmm, the fd we wanted isn't free? Then
134 * let's remember that and try again from here */
135 if (nfd
!= i
+3 && restart_from
< 0)
139 if (restart_from
< 0)
142 start
= restart_from
;
148 static int flags_fds(const int fds
[], unsigned n_fds
, bool nonblock
) {
157 /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
159 for (i
= 0; i
< n_fds
; i
++) {
161 r
= fd_nonblock(fds
[i
], nonblock
);
165 /* We unconditionally drop FD_CLOEXEC from the fds,
166 * since after all we want to pass these fds to our
169 r
= fd_cloexec(fds
[i
], false);
177 _pure_
static const char *tty_path(const ExecContext
*context
) {
180 if (context
->tty_path
)
181 return context
->tty_path
;
183 return "/dev/console";
186 static void exec_context_tty_reset(const ExecContext
*context
) {
189 if (context
->tty_vhangup
)
190 terminal_vhangup(tty_path(context
));
192 if (context
->tty_reset
)
193 reset_terminal(tty_path(context
));
195 if (context
->tty_vt_disallocate
&& context
->tty_path
)
196 vt_disallocate(context
->tty_path
);
199 static bool is_terminal_output(ExecOutput o
) {
201 o
== EXEC_OUTPUT_TTY
||
202 o
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
203 o
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
204 o
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
;
207 static int open_null_as(int flags
, int nfd
) {
212 fd
= open("/dev/null", flags
|O_NOCTTY
);
217 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
225 static int connect_journal_socket(int fd
, uid_t uid
, gid_t gid
) {
226 union sockaddr_union sa
= {
227 .un
.sun_family
= AF_UNIX
,
228 .un
.sun_path
= "/run/systemd/journal/stdout",
230 uid_t olduid
= UID_INVALID
;
231 gid_t oldgid
= GID_INVALID
;
234 if (gid
!= GID_INVALID
) {
242 if (uid
!= UID_INVALID
) {
252 r
= connect(fd
, &sa
.sa
, offsetof(struct sockaddr_un
, sun_path
) + strlen(sa
.un
.sun_path
));
256 /* If we fail to restore the uid or gid, things will likely
257 fail later on. This should only happen if an LSM interferes. */
259 if (uid
!= UID_INVALID
)
260 (void) seteuid(olduid
);
263 if (gid
!= GID_INVALID
)
264 (void) setegid(oldgid
);
269 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
) {
273 assert(output
< _EXEC_OUTPUT_MAX
);
277 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
281 r
= connect_journal_socket(fd
, uid
, gid
);
285 if (shutdown(fd
, SHUT_RD
) < 0) {
290 fd_inc_sndbuf(fd
, SNDBUF_SIZE
);
300 context
->syslog_identifier
? context
->syslog_identifier
: ident
,
302 context
->syslog_priority
,
303 !!context
->syslog_level_prefix
,
304 output
== EXEC_OUTPUT_SYSLOG
|| output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
,
305 output
== EXEC_OUTPUT_KMSG
|| output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
,
306 is_terminal_output(output
));
309 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
316 static int open_terminal_as(const char *path
, mode_t mode
, int nfd
) {
322 fd
= open_terminal(path
, mode
| O_NOCTTY
);
327 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
335 static bool is_terminal_input(ExecInput i
) {
337 i
== EXEC_INPUT_TTY
||
338 i
== EXEC_INPUT_TTY_FORCE
||
339 i
== EXEC_INPUT_TTY_FAIL
;
342 static int fixup_input(ExecInput std_input
, int socket_fd
, bool apply_tty_stdin
) {
344 if (is_terminal_input(std_input
) && !apply_tty_stdin
)
345 return EXEC_INPUT_NULL
;
347 if (std_input
== EXEC_INPUT_SOCKET
&& socket_fd
< 0)
348 return EXEC_INPUT_NULL
;
353 static int fixup_output(ExecOutput std_output
, int socket_fd
) {
355 if (std_output
== EXEC_OUTPUT_SOCKET
&& socket_fd
< 0)
356 return EXEC_OUTPUT_INHERIT
;
361 static int setup_input(
362 const ExecContext
*context
,
363 const ExecParameters
*params
,
371 if (params
->stdin_fd
>= 0) {
372 if (dup2(params
->stdin_fd
, STDIN_FILENO
) < 0)
375 /* Try to make this the controlling tty, if it is a tty, and reset it */
376 (void) ioctl(STDIN_FILENO
, TIOCSCTTY
, context
->std_input
== EXEC_INPUT_TTY_FORCE
);
377 (void) reset_terminal_fd(STDIN_FILENO
, true);
382 i
= fixup_input(context
->std_input
, socket_fd
, params
->apply_tty_stdin
);
386 case EXEC_INPUT_NULL
:
387 return open_null_as(O_RDONLY
, STDIN_FILENO
);
390 case EXEC_INPUT_TTY_FORCE
:
391 case EXEC_INPUT_TTY_FAIL
: {
394 fd
= acquire_terminal(tty_path(context
),
395 i
== EXEC_INPUT_TTY_FAIL
,
396 i
== EXEC_INPUT_TTY_FORCE
,
402 if (fd
!= STDIN_FILENO
) {
403 r
= dup2(fd
, STDIN_FILENO
) < 0 ? -errno
: STDIN_FILENO
;
411 case EXEC_INPUT_SOCKET
:
412 return dup2(socket_fd
, STDIN_FILENO
) < 0 ? -errno
: STDIN_FILENO
;
415 assert_not_reached("Unknown input type");
419 static int setup_output(
421 const ExecContext
*context
,
422 const ExecParameters
*params
,
426 uid_t uid
, gid_t gid
) {
437 if (fileno
== STDOUT_FILENO
&& params
->stdout_fd
>= 0) {
439 if (dup2(params
->stdout_fd
, STDOUT_FILENO
) < 0)
442 return STDOUT_FILENO
;
445 if (fileno
== STDERR_FILENO
&& params
->stderr_fd
>= 0) {
446 if (dup2(params
->stderr_fd
, STDERR_FILENO
) < 0)
449 return STDERR_FILENO
;
452 i
= fixup_input(context
->std_input
, socket_fd
, params
->apply_tty_stdin
);
453 o
= fixup_output(context
->std_output
, socket_fd
);
455 if (fileno
== STDERR_FILENO
) {
457 e
= fixup_output(context
->std_error
, socket_fd
);
459 /* This expects the input and output are already set up */
461 /* Don't change the stderr file descriptor if we inherit all
462 * the way and are not on a tty */
463 if (e
== EXEC_OUTPUT_INHERIT
&&
464 o
== EXEC_OUTPUT_INHERIT
&&
465 i
== EXEC_INPUT_NULL
&&
466 !is_terminal_input(context
->std_input
) &&
470 /* Duplicate from stdout if possible */
471 if (e
== o
|| e
== EXEC_OUTPUT_INHERIT
)
472 return dup2(STDOUT_FILENO
, fileno
) < 0 ? -errno
: fileno
;
476 } else if (o
== EXEC_OUTPUT_INHERIT
) {
477 /* If input got downgraded, inherit the original value */
478 if (i
== EXEC_INPUT_NULL
&& is_terminal_input(context
->std_input
))
479 return open_terminal_as(tty_path(context
), O_WRONLY
, fileno
);
481 /* If the input is connected to anything that's not a /dev/null, inherit that... */
482 if (i
!= EXEC_INPUT_NULL
)
483 return dup2(STDIN_FILENO
, fileno
) < 0 ? -errno
: fileno
;
485 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
489 /* We need to open /dev/null here anew, to get the right access mode. */
490 return open_null_as(O_WRONLY
, fileno
);
495 case EXEC_OUTPUT_NULL
:
496 return open_null_as(O_WRONLY
, fileno
);
498 case EXEC_OUTPUT_TTY
:
499 if (is_terminal_input(i
))
500 return dup2(STDIN_FILENO
, fileno
) < 0 ? -errno
: fileno
;
502 /* We don't reset the terminal if this is just about output */
503 return open_terminal_as(tty_path(context
), O_WRONLY
, fileno
);
505 case EXEC_OUTPUT_SYSLOG
:
506 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE
:
507 case EXEC_OUTPUT_KMSG
:
508 case EXEC_OUTPUT_KMSG_AND_CONSOLE
:
509 case EXEC_OUTPUT_JOURNAL
:
510 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE
:
511 r
= connect_logger_as(context
, o
, ident
, unit
->id
, fileno
, uid
, gid
);
513 log_unit_error_errno(unit
, r
, "Failed to connect %s to the journal socket, ignoring: %m", fileno
== STDOUT_FILENO
? "stdout" : "stderr");
514 r
= open_null_as(O_WRONLY
, fileno
);
518 case EXEC_OUTPUT_SOCKET
:
519 assert(socket_fd
>= 0);
520 return dup2(socket_fd
, fileno
) < 0 ? -errno
: fileno
;
523 assert_not_reached("Unknown error type");
527 static int chown_terminal(int fd
, uid_t uid
) {
532 /* This might fail. What matters are the results. */
533 (void) fchown(fd
, uid
, -1);
534 (void) fchmod(fd
, TTY_MODE
);
536 if (fstat(fd
, &st
) < 0)
539 if (st
.st_uid
!= uid
|| (st
.st_mode
& 0777) != TTY_MODE
)
545 static int setup_confirm_stdio(int *_saved_stdin
, int *_saved_stdout
) {
546 _cleanup_close_
int fd
= -1, saved_stdin
= -1, saved_stdout
= -1;
549 assert(_saved_stdin
);
550 assert(_saved_stdout
);
552 saved_stdin
= fcntl(STDIN_FILENO
, F_DUPFD
, 3);
556 saved_stdout
= fcntl(STDOUT_FILENO
, F_DUPFD
, 3);
557 if (saved_stdout
< 0)
560 fd
= acquire_terminal(
565 DEFAULT_CONFIRM_USEC
);
569 r
= chown_terminal(fd
, getuid());
573 r
= reset_terminal_fd(fd
, true);
577 if (dup2(fd
, STDIN_FILENO
) < 0)
580 if (dup2(fd
, STDOUT_FILENO
) < 0)
587 *_saved_stdin
= saved_stdin
;
588 *_saved_stdout
= saved_stdout
;
590 saved_stdin
= saved_stdout
= -1;
595 _printf_(1, 2) static int write_confirm_message(const char *format
, ...) {
596 _cleanup_close_
int fd
= -1;
601 fd
= open_terminal("/dev/console", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
605 va_start(ap
, format
);
606 vdprintf(fd
, format
, ap
);
612 static int restore_confirm_stdio(int *saved_stdin
, int *saved_stdout
) {
616 assert(saved_stdout
);
620 if (*saved_stdin
>= 0)
621 if (dup2(*saved_stdin
, STDIN_FILENO
) < 0)
624 if (*saved_stdout
>= 0)
625 if (dup2(*saved_stdout
, STDOUT_FILENO
) < 0)
628 *saved_stdin
= safe_close(*saved_stdin
);
629 *saved_stdout
= safe_close(*saved_stdout
);
634 static int ask_for_confirmation(char *response
, char **argv
) {
635 int saved_stdout
= -1, saved_stdin
= -1, r
;
636 _cleanup_free_
char *line
= NULL
;
638 r
= setup_confirm_stdio(&saved_stdin
, &saved_stdout
);
642 line
= exec_command_line(argv
);
646 r
= ask_char(response
, "yns", "Execute %s? [Yes, No, Skip] ", line
);
648 restore_confirm_stdio(&saved_stdin
, &saved_stdout
);
653 static int enforce_groups(const ExecContext
*context
, const char *username
, gid_t gid
) {
654 bool keep_groups
= false;
659 /* Lookup and set GID and supplementary group list. Here too
660 * we avoid NSS lookups for gid=0. */
662 if (context
->group
|| username
) {
663 /* First step, initialize groups from /etc/groups */
664 if (username
&& gid
!= 0) {
665 if (initgroups(username
, gid
) < 0)
671 /* Second step, set our gids */
672 if (setresgid(gid
, gid
, gid
) < 0)
676 if (context
->supplementary_groups
) {
681 /* Final step, initialize any manually set supplementary groups */
682 assert_se((ngroups_max
= (int) sysconf(_SC_NGROUPS_MAX
)) > 0);
684 if (!(gids
= new(gid_t
, ngroups_max
)))
688 k
= getgroups(ngroups_max
, gids
);
696 STRV_FOREACH(i
, context
->supplementary_groups
) {
699 if (k
>= ngroups_max
) {
705 r
= get_group_creds(&g
, gids
+k
);
714 if (setgroups(k
, gids
) < 0) {
725 static int enforce_user(const ExecContext
*context
, uid_t uid
) {
728 /* Sets (but doesn't lookup) the uid and make sure we keep the
729 * capabilities while doing so. */
731 if (context
->capabilities
) {
732 _cleanup_cap_free_ cap_t d
= NULL
;
733 static const cap_value_t bits
[] = {
734 CAP_SETUID
, /* Necessary so that we can run setresuid() below */
735 CAP_SETPCAP
/* Necessary so that we can set PR_SET_SECUREBITS later on */
738 /* First step: If we need to keep capabilities but
739 * drop privileges we need to make sure we keep our
740 * caps, while we drop privileges. */
742 int sb
= context
->secure_bits
| 1<<SECURE_KEEP_CAPS
;
744 if (prctl(PR_GET_SECUREBITS
) != sb
)
745 if (prctl(PR_SET_SECUREBITS
, sb
) < 0)
749 /* Second step: set the capabilities. This will reduce
750 * the capabilities to the minimum we need. */
752 d
= cap_dup(context
->capabilities
);
756 if (cap_set_flag(d
, CAP_EFFECTIVE
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0 ||
757 cap_set_flag(d
, CAP_PERMITTED
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0)
760 if (cap_set_proc(d
) < 0)
764 /* Third step: actually set the uids */
765 if (setresuid(uid
, uid
, uid
) < 0)
768 /* At this point we should have all necessary capabilities but
769 are otherwise a normal user. However, the caps might got
770 corrupted due to the setresuid() so we need clean them up
771 later. This is done outside of this call. */
778 static int null_conv(
780 const struct pam_message
**msg
,
781 struct pam_response
**resp
,
784 /* We don't support conversations */
789 static int setup_pam(
795 int fds
[], unsigned n_fds
) {
797 static const struct pam_conv conv
= {
802 _cleanup_(barrier_destroy
) Barrier barrier
= BARRIER_NULL
;
803 pam_handle_t
*handle
= NULL
;
805 int pam_code
= PAM_SUCCESS
;
808 bool close_session
= false;
809 pid_t pam_pid
= 0, parent_pid
;
816 /* We set up PAM in the parent process, then fork. The child
817 * will then stay around until killed via PR_GET_PDEATHSIG or
818 * systemd via the cgroup logic. It will then remove the PAM
819 * session again. The parent process will exec() the actual
820 * daemon. We do things this way to ensure that the main PID
821 * of the daemon is the one we initially fork()ed. */
823 err
= barrier_create(&barrier
);
827 if (log_get_max_level() < LOG_DEBUG
)
830 pam_code
= pam_start(name
, user
, &conv
, &handle
);
831 if (pam_code
!= PAM_SUCCESS
) {
837 pam_code
= pam_set_item(handle
, PAM_TTY
, tty
);
838 if (pam_code
!= PAM_SUCCESS
)
842 pam_code
= pam_acct_mgmt(handle
, flags
);
843 if (pam_code
!= PAM_SUCCESS
)
846 pam_code
= pam_open_session(handle
, flags
);
847 if (pam_code
!= PAM_SUCCESS
)
850 close_session
= true;
852 e
= pam_getenvlist(handle
);
854 pam_code
= PAM_BUF_ERR
;
858 /* Block SIGTERM, so that we know that it won't get lost in
861 assert_se(sigprocmask_many(SIG_BLOCK
, &old_ss
, SIGTERM
, -1) >= 0);
863 parent_pid
= getpid();
873 /* The child's job is to reset the PAM session on
875 barrier_set_role(&barrier
, BARRIER_CHILD
);
877 /* This string must fit in 10 chars (i.e. the length
878 * of "/sbin/init"), to look pretty in /bin/ps */
879 rename_process("(sd-pam)");
881 /* Make sure we don't keep open the passed fds in this
882 child. We assume that otherwise only those fds are
883 open here that have been opened by PAM. */
884 close_many(fds
, n_fds
);
886 /* Drop privileges - we don't need any to pam_close_session
887 * and this will make PR_SET_PDEATHSIG work in most cases.
888 * If this fails, ignore the error - but expect sd-pam threads
889 * to fail to exit normally */
890 if (setresuid(uid
, uid
, uid
) < 0)
891 log_error_errno(r
, "Error: Failed to setresuid() in sd-pam: %m");
893 (void) ignore_signals(SIGPIPE
, -1);
895 /* Wait until our parent died. This will only work if
896 * the above setresuid() succeeds, otherwise the kernel
897 * will not allow unprivileged parents kill their privileged
898 * children this way. We rely on the control groups kill logic
899 * to do the rest for us. */
900 if (prctl(PR_SET_PDEATHSIG
, SIGTERM
) < 0)
903 /* Tell the parent that our setup is done. This is especially
904 * important regarding dropping privileges. Otherwise, unit
905 * setup might race against our setresuid(2) call. */
906 barrier_place(&barrier
);
908 /* Check if our parent process might already have
910 if (getppid() == parent_pid
) {
913 assert_se(sigemptyset(&ss
) >= 0);
914 assert_se(sigaddset(&ss
, SIGTERM
) >= 0);
917 if (sigwait(&ss
, &sig
) < 0) {
924 assert(sig
== SIGTERM
);
929 /* If our parent died we'll end the session */
930 if (getppid() != parent_pid
) {
931 pam_code
= pam_close_session(handle
, flags
);
932 if (pam_code
!= PAM_SUCCESS
)
939 pam_end(handle
, pam_code
| flags
);
943 barrier_set_role(&barrier
, BARRIER_PARENT
);
945 /* If the child was forked off successfully it will do all the
946 * cleanups, so forget about the handle here. */
949 /* Unblock SIGTERM again in the parent */
950 assert_se(sigprocmask(SIG_SETMASK
, &old_ss
, NULL
) >= 0);
952 /* We close the log explicitly here, since the PAM modules
953 * might have opened it, but we don't want this fd around. */
956 /* Synchronously wait for the child to initialize. We don't care for
957 * errors as we cannot recover. However, warn loudly if it happens. */
958 if (!barrier_place_and_sync(&barrier
))
959 log_error("PAM initialization failed");
967 if (pam_code
!= PAM_SUCCESS
) {
968 log_error("PAM failed: %s", pam_strerror(handle
, pam_code
));
969 err
= -EPERM
; /* PAM errors do not map to errno */
971 err
= log_error_errno(err
< 0 ? err
: errno
, "PAM failed: %m");
976 pam_code
= pam_close_session(handle
, flags
);
978 pam_end(handle
, pam_code
| flags
);
986 kill(pam_pid
, SIGTERM
);
987 kill(pam_pid
, SIGCONT
);
994 static void rename_process_from_path(const char *path
) {
995 char process_name
[11];
999 /* This resulting string must fit in 10 chars (i.e. the length
1000 * of "/sbin/init") to look pretty in /bin/ps */
1004 rename_process("(...)");
1010 /* The end of the process name is usually more
1011 * interesting, since the first bit might just be
1017 process_name
[0] = '(';
1018 memcpy(process_name
+1, p
, l
);
1019 process_name
[1+l
] = ')';
1020 process_name
[1+l
+1] = 0;
1022 rename_process(process_name
);
1027 static int apply_seccomp(const ExecContext
*c
) {
1028 uint32_t negative_action
, action
;
1029 scmp_filter_ctx
*seccomp
;
1036 negative_action
= c
->syscall_errno
== 0 ? SCMP_ACT_KILL
: SCMP_ACT_ERRNO(c
->syscall_errno
);
1038 seccomp
= seccomp_init(c
->syscall_whitelist
? negative_action
: SCMP_ACT_ALLOW
);
1042 if (c
->syscall_archs
) {
1044 SET_FOREACH(id
, c
->syscall_archs
, i
) {
1045 r
= seccomp_arch_add(seccomp
, PTR_TO_UINT32(id
) - 1);
1053 r
= seccomp_add_secondary_archs(seccomp
);
1058 action
= c
->syscall_whitelist
? SCMP_ACT_ALLOW
: negative_action
;
1059 SET_FOREACH(id
, c
->syscall_filter
, i
) {
1060 r
= seccomp_rule_add(seccomp
, action
, PTR_TO_INT(id
) - 1, 0);
1065 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1069 r
= seccomp_load(seccomp
);
1072 seccomp_release(seccomp
);
1076 static int apply_address_families(const ExecContext
*c
) {
1077 scmp_filter_ctx
*seccomp
;
1083 seccomp
= seccomp_init(SCMP_ACT_ALLOW
);
1087 r
= seccomp_add_secondary_archs(seccomp
);
1091 if (c
->address_families_whitelist
) {
1092 int af
, first
= 0, last
= 0;
1095 /* If this is a whitelist, we first block the address
1096 * families that are out of range and then everything
1097 * that is not in the set. First, we find the lowest
1098 * and highest address family in the set. */
1100 SET_FOREACH(afp
, c
->address_families
, i
) {
1101 af
= PTR_TO_INT(afp
);
1103 if (af
<= 0 || af
>= af_max())
1106 if (first
== 0 || af
< first
)
1109 if (last
== 0 || af
> last
)
1113 assert((first
== 0) == (last
== 0));
1117 /* No entries in the valid range, block everything */
1118 r
= seccomp_rule_add(
1120 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1128 /* Block everything below the first entry */
1129 r
= seccomp_rule_add(
1131 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1134 SCMP_A0(SCMP_CMP_LT
, first
));
1138 /* Block everything above the last entry */
1139 r
= seccomp_rule_add(
1141 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1144 SCMP_A0(SCMP_CMP_GT
, last
));
1148 /* Block everything between the first and last
1150 for (af
= 1; af
< af_max(); af
++) {
1152 if (set_contains(c
->address_families
, INT_TO_PTR(af
)))
1155 r
= seccomp_rule_add(
1157 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1160 SCMP_A0(SCMP_CMP_EQ
, af
));
1169 /* If this is a blacklist, then generate one rule for
1170 * each address family that are then combined in OR
1173 SET_FOREACH(af
, c
->address_families
, i
) {
1175 r
= seccomp_rule_add(
1177 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1180 SCMP_A0(SCMP_CMP_EQ
, PTR_TO_INT(af
)));
1186 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1190 r
= seccomp_load(seccomp
);
1193 seccomp_release(seccomp
);
1199 static void do_idle_pipe_dance(int idle_pipe
[4]) {
1203 idle_pipe
[1] = safe_close(idle_pipe
[1]);
1204 idle_pipe
[2] = safe_close(idle_pipe
[2]);
1206 if (idle_pipe
[0] >= 0) {
1209 r
= fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT_USEC
);
1211 if (idle_pipe
[3] >= 0 && r
== 0 /* timeout */) {
1214 /* Signal systemd that we are bored and want to continue. */
1215 n
= write(idle_pipe
[3], "x", 1);
1217 /* Wait for systemd to react to the signal above. */
1218 fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT2_USEC
);
1221 idle_pipe
[0] = safe_close(idle_pipe
[0]);
1225 idle_pipe
[3] = safe_close(idle_pipe
[3]);
1228 static int build_environment(
1229 const ExecContext
*c
,
1232 usec_t watchdog_usec
,
1234 const char *username
,
1238 _cleanup_strv_free_
char **our_env
= NULL
;
1245 our_env
= new0(char*, 11);
1250 _cleanup_free_
char *joined
= NULL
;
1252 if (asprintf(&x
, "LISTEN_PID="PID_FMT
, getpid()) < 0)
1254 our_env
[n_env
++] = x
;
1256 if (asprintf(&x
, "LISTEN_FDS=%u", n_fds
) < 0)
1258 our_env
[n_env
++] = x
;
1260 joined
= strv_join(fd_names
, ":");
1264 x
= strjoin("LISTEN_FDNAMES=", joined
, NULL
);
1267 our_env
[n_env
++] = x
;
1270 if (watchdog_usec
> 0) {
1271 if (asprintf(&x
, "WATCHDOG_PID="PID_FMT
, getpid()) < 0)
1273 our_env
[n_env
++] = x
;
1275 if (asprintf(&x
, "WATCHDOG_USEC="USEC_FMT
, watchdog_usec
) < 0)
1277 our_env
[n_env
++] = x
;
1281 x
= strappend("HOME=", home
);
1284 our_env
[n_env
++] = x
;
1288 x
= strappend("LOGNAME=", username
);
1291 our_env
[n_env
++] = x
;
1293 x
= strappend("USER=", username
);
1296 our_env
[n_env
++] = x
;
1300 x
= strappend("SHELL=", shell
);
1303 our_env
[n_env
++] = x
;
1306 if (is_terminal_input(c
->std_input
) ||
1307 c
->std_output
== EXEC_OUTPUT_TTY
||
1308 c
->std_error
== EXEC_OUTPUT_TTY
||
1311 x
= strdup(default_term_for_tty(tty_path(c
)));
1314 our_env
[n_env
++] = x
;
1317 our_env
[n_env
++] = NULL
;
1318 assert(n_env
<= 11);
1326 static bool exec_needs_mount_namespace(
1327 const ExecContext
*context
,
1328 const ExecParameters
*params
,
1329 ExecRuntime
*runtime
) {
1334 if (!strv_isempty(context
->read_write_dirs
) ||
1335 !strv_isempty(context
->read_only_dirs
) ||
1336 !strv_isempty(context
->inaccessible_dirs
))
1339 if (context
->mount_flags
!= 0)
1342 if (context
->private_tmp
&& runtime
&& (runtime
->tmp_dir
|| runtime
->var_tmp_dir
))
1345 if (params
->bus_endpoint_path
)
1348 if (context
->private_devices
||
1349 context
->protect_system
!= PROTECT_SYSTEM_NO
||
1350 context
->protect_home
!= PROTECT_HOME_NO
)
1356 static int close_remaining_fds(
1357 const ExecParameters
*params
,
1358 ExecRuntime
*runtime
,
1360 int *fds
, unsigned n_fds
) {
1362 unsigned n_dont_close
= 0;
1363 int dont_close
[n_fds
+ 7];
1367 if (params
->stdin_fd
>= 0)
1368 dont_close
[n_dont_close
++] = params
->stdin_fd
;
1369 if (params
->stdout_fd
>= 0)
1370 dont_close
[n_dont_close
++] = params
->stdout_fd
;
1371 if (params
->stderr_fd
>= 0)
1372 dont_close
[n_dont_close
++] = params
->stderr_fd
;
1375 dont_close
[n_dont_close
++] = socket_fd
;
1377 memcpy(dont_close
+ n_dont_close
, fds
, sizeof(int) * n_fds
);
1378 n_dont_close
+= n_fds
;
1381 if (params
->bus_endpoint_fd
>= 0)
1382 dont_close
[n_dont_close
++] = params
->bus_endpoint_fd
;
1385 if (runtime
->netns_storage_socket
[0] >= 0)
1386 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[0];
1387 if (runtime
->netns_storage_socket
[1] >= 0)
1388 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[1];
1391 return close_all_fds(dont_close
, n_dont_close
);
1394 static int exec_child(
1396 ExecCommand
*command
,
1397 const ExecContext
*context
,
1398 const ExecParameters
*params
,
1399 ExecRuntime
*runtime
,
1402 int *fds
, unsigned n_fds
,
1406 _cleanup_strv_free_
char **our_env
= NULL
, **pam_env
= NULL
, **final_env
= NULL
, **final_argv
= NULL
;
1407 _cleanup_free_
char *mac_selinux_context_net
= NULL
;
1408 const char *username
= NULL
, *home
= NULL
, *shell
= NULL
, *wd
;
1409 uid_t uid
= UID_INVALID
;
1410 gid_t gid
= GID_INVALID
;
1412 bool needs_mount_namespace
;
1418 assert(exit_status
);
1420 rename_process_from_path(command
->path
);
1422 /* We reset exactly these signals, since they are the
1423 * only ones we set to SIG_IGN in the main daemon. All
1424 * others we leave untouched because we set them to
1425 * SIG_DFL or a valid handler initially, both of which
1426 * will be demoted to SIG_DFL. */
1427 (void) default_signals(SIGNALS_CRASH_HANDLER
,
1428 SIGNALS_IGNORE
, -1);
1430 if (context
->ignore_sigpipe
)
1431 (void) ignore_signals(SIGPIPE
, -1);
1433 r
= reset_signal_mask();
1435 *exit_status
= EXIT_SIGNAL_MASK
;
1439 if (params
->idle_pipe
)
1440 do_idle_pipe_dance(params
->idle_pipe
);
1442 /* Close sockets very early to make sure we don't
1443 * block init reexecution because it cannot bind its
1448 r
= close_remaining_fds(params
, runtime
, socket_fd
, fds
, n_fds
);
1450 *exit_status
= EXIT_FDS
;
1454 if (!context
->same_pgrp
)
1456 *exit_status
= EXIT_SETSID
;
1460 exec_context_tty_reset(context
);
1462 if (params
->confirm_spawn
) {
1465 r
= ask_for_confirmation(&response
, argv
);
1466 if (r
== -ETIMEDOUT
)
1467 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1469 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r
));
1470 else if (response
== 's') {
1471 write_confirm_message("Skipping execution.\n");
1472 *exit_status
= EXIT_CONFIRM
;
1474 } else if (response
== 'n') {
1475 write_confirm_message("Failing execution.\n");
1481 if (context
->user
) {
1482 username
= context
->user
;
1483 r
= get_user_creds(&username
, &uid
, &gid
, &home
, &shell
);
1485 *exit_status
= EXIT_USER
;
1490 if (context
->group
) {
1491 const char *g
= context
->group
;
1493 r
= get_group_creds(&g
, &gid
);
1495 *exit_status
= EXIT_GROUP
;
1501 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1502 * must sure to drop O_NONBLOCK */
1504 (void) fd_nonblock(socket_fd
, false);
1506 r
= setup_input(context
, params
, socket_fd
);
1508 *exit_status
= EXIT_STDIN
;
1512 r
= setup_output(unit
, context
, params
, STDOUT_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1514 *exit_status
= EXIT_STDOUT
;
1518 r
= setup_output(unit
, context
, params
, STDERR_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1520 *exit_status
= EXIT_STDERR
;
1524 if (params
->cgroup_path
) {
1525 r
= cg_attach_everywhere(params
->cgroup_supported
, params
->cgroup_path
, 0, NULL
, NULL
);
1527 *exit_status
= EXIT_CGROUP
;
1532 if (context
->oom_score_adjust_set
) {
1533 char t
[DECIMAL_STR_MAX(context
->oom_score_adjust
)];
1535 /* When we can't make this change due to EPERM, then
1536 * let's silently skip over it. User namespaces
1537 * prohibit write access to this file, and we
1538 * shouldn't trip up over that. */
1540 sprintf(t
, "%i", context
->oom_score_adjust
);
1541 r
= write_string_file("/proc/self/oom_score_adj", t
, 0);
1542 if (r
== -EPERM
|| r
== -EACCES
) {
1544 log_unit_debug_errno(unit
, r
, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
1547 *exit_status
= EXIT_OOM_ADJUST
;
1552 if (context
->nice_set
)
1553 if (setpriority(PRIO_PROCESS
, 0, context
->nice
) < 0) {
1554 *exit_status
= EXIT_NICE
;
1558 if (context
->cpu_sched_set
) {
1559 struct sched_param param
= {
1560 .sched_priority
= context
->cpu_sched_priority
,
1563 r
= sched_setscheduler(0,
1564 context
->cpu_sched_policy
|
1565 (context
->cpu_sched_reset_on_fork
?
1566 SCHED_RESET_ON_FORK
: 0),
1569 *exit_status
= EXIT_SETSCHEDULER
;
1574 if (context
->cpuset
)
1575 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context
->cpuset_ncpus
), context
->cpuset
) < 0) {
1576 *exit_status
= EXIT_CPUAFFINITY
;
1580 if (context
->ioprio_set
)
1581 if (ioprio_set(IOPRIO_WHO_PROCESS
, 0, context
->ioprio
) < 0) {
1582 *exit_status
= EXIT_IOPRIO
;
1586 if (context
->timer_slack_nsec
!= NSEC_INFINITY
)
1587 if (prctl(PR_SET_TIMERSLACK
, context
->timer_slack_nsec
) < 0) {
1588 *exit_status
= EXIT_TIMERSLACK
;
1592 if (context
->personality
!= PERSONALITY_INVALID
)
1593 if (personality(context
->personality
) < 0) {
1594 *exit_status
= EXIT_PERSONALITY
;
1598 if (context
->utmp_id
)
1599 utmp_put_init_process(context
->utmp_id
, getpid(), getsid(0), context
->tty_path
,
1600 context
->utmp_mode
== EXEC_UTMP_INIT
? INIT_PROCESS
:
1601 context
->utmp_mode
== EXEC_UTMP_LOGIN
? LOGIN_PROCESS
:
1603 username
? "root" : context
->user
);
1605 if (context
->user
&& is_terminal_input(context
->std_input
)) {
1606 r
= chown_terminal(STDIN_FILENO
, uid
);
1608 *exit_status
= EXIT_STDIN
;
1613 if (params
->bus_endpoint_fd
>= 0 && context
->bus_endpoint
) {
1614 uid_t ep_uid
= (uid
== UID_INVALID
) ? 0 : uid
;
1616 r
= bus_kernel_set_endpoint_policy(params
->bus_endpoint_fd
, ep_uid
, context
->bus_endpoint
);
1618 *exit_status
= EXIT_BUS_ENDPOINT
;
1623 /* If delegation is enabled we'll pass ownership of the cgroup
1624 * (but only in systemd's own controller hierarchy!) to the
1625 * user of the new process. */
1626 if (params
->cgroup_path
&& context
->user
&& params
->cgroup_delegate
) {
1627 r
= cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0644, uid
, gid
);
1629 *exit_status
= EXIT_CGROUP
;
1634 r
= cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0755, uid
, gid
);
1636 *exit_status
= EXIT_CGROUP
;
1641 if (!strv_isempty(context
->runtime_directory
) && params
->runtime_prefix
) {
1644 STRV_FOREACH(rt
, context
->runtime_directory
) {
1645 _cleanup_free_
char *p
;
1647 p
= strjoin(params
->runtime_prefix
, "/", *rt
, NULL
);
1649 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1653 r
= mkdir_p_label(p
, context
->runtime_directory_mode
);
1655 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1659 r
= chmod_and_chown(p
, context
->runtime_directory_mode
, uid
, gid
);
1661 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1667 umask(context
->umask
);
1669 if (params
->apply_permissions
) {
1670 r
= enforce_groups(context
, username
, gid
);
1672 *exit_status
= EXIT_GROUP
;
1676 if (context
->smack_process_label
) {
1677 r
= mac_smack_apply_pid(0, context
->smack_process_label
);
1679 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1683 #ifdef SMACK_DEFAULT_PROCESS_LABEL
1685 _cleanup_free_
char *exec_label
= NULL
;
1687 r
= mac_smack_read(command
->path
, SMACK_ATTR_EXEC
, &exec_label
);
1688 if (r
< 0 && r
!= -ENODATA
&& r
!= -EOPNOTSUPP
) {
1689 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1693 r
= mac_smack_apply_pid(0, exec_label
? : SMACK_DEFAULT_PROCESS_LABEL
);
1695 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1702 if (context
->pam_name
&& username
) {
1703 r
= setup_pam(context
->pam_name
, username
, uid
, context
->tty_path
, &pam_env
, fds
, n_fds
);
1705 *exit_status
= EXIT_PAM
;
1712 if (context
->private_network
&& runtime
&& runtime
->netns_storage_socket
[0] >= 0) {
1713 r
= setup_netns(runtime
->netns_storage_socket
);
1715 *exit_status
= EXIT_NETWORK
;
1720 needs_mount_namespace
= exec_needs_mount_namespace(context
, params
, runtime
);
1722 if (needs_mount_namespace
) {
1723 char *tmp
= NULL
, *var
= NULL
;
1725 /* The runtime struct only contains the parent
1726 * of the private /tmp, which is
1727 * non-accessible to world users. Inside of it
1728 * there's a /tmp that is sticky, and that's
1729 * the one we want to use here. */
1731 if (context
->private_tmp
&& runtime
) {
1732 if (runtime
->tmp_dir
)
1733 tmp
= strjoina(runtime
->tmp_dir
, "/tmp");
1734 if (runtime
->var_tmp_dir
)
1735 var
= strjoina(runtime
->var_tmp_dir
, "/tmp");
1738 r
= setup_namespace(
1739 params
->apply_chroot
? context
->root_directory
: NULL
,
1740 context
->read_write_dirs
,
1741 context
->read_only_dirs
,
1742 context
->inaccessible_dirs
,
1745 params
->bus_endpoint_path
,
1746 context
->private_devices
,
1747 context
->protect_home
,
1748 context
->protect_system
,
1749 context
->mount_flags
);
1751 /* If we couldn't set up the namespace this is
1752 * probably due to a missing capability. In this case,
1753 * silently proceeed. */
1754 if (r
== -EPERM
|| r
== -EACCES
) {
1756 log_unit_debug_errno(unit
, r
, "Failed to set up namespace, assuming containerized execution, ignoring: %m");
1759 *exit_status
= EXIT_NAMESPACE
;
1764 if (context
->working_directory_home
)
1766 else if (context
->working_directory
)
1767 wd
= context
->working_directory
;
1771 if (params
->apply_chroot
) {
1772 if (!needs_mount_namespace
&& context
->root_directory
)
1773 if (chroot(context
->root_directory
) < 0) {
1774 *exit_status
= EXIT_CHROOT
;
1778 if (chdir(wd
) < 0 &&
1779 !context
->working_directory_missing_ok
) {
1780 *exit_status
= EXIT_CHDIR
;
1786 d
= strjoina(strempty(context
->root_directory
), "/", strempty(wd
));
1788 !context
->working_directory_missing_ok
) {
1789 *exit_status
= EXIT_CHDIR
;
1795 if (params
->apply_permissions
&& mac_selinux_use() && params
->selinux_context_net
&& socket_fd
>= 0) {
1796 r
= mac_selinux_get_child_mls_label(socket_fd
, command
->path
, context
->selinux_context
, &mac_selinux_context_net
);
1798 *exit_status
= EXIT_SELINUX_CONTEXT
;
1804 /* We repeat the fd closing here, to make sure that
1805 * nothing is leaked from the PAM modules. Note that
1806 * we are more aggressive this time since socket_fd
1807 * and the netns fds we don't need anymore. The custom
1808 * endpoint fd was needed to upload the policy and can
1809 * now be closed as well. */
1810 r
= close_all_fds(fds
, n_fds
);
1812 r
= shift_fds(fds
, n_fds
);
1814 r
= flags_fds(fds
, n_fds
, context
->non_blocking
);
1816 *exit_status
= EXIT_FDS
;
1820 if (params
->apply_permissions
) {
1822 for (i
= 0; i
< _RLIMIT_MAX
; i
++) {
1823 if (!context
->rlimit
[i
])
1826 if (setrlimit_closest(i
, context
->rlimit
[i
]) < 0) {
1827 *exit_status
= EXIT_LIMITS
;
1832 if (context
->capability_bounding_set_drop
) {
1833 r
= capability_bounding_set_drop(context
->capability_bounding_set_drop
, false);
1835 *exit_status
= EXIT_CAPABILITIES
;
1840 if (context
->user
) {
1841 r
= enforce_user(context
, uid
);
1843 *exit_status
= EXIT_USER
;
1848 /* PR_GET_SECUREBITS is not privileged, while
1849 * PR_SET_SECUREBITS is. So to suppress
1850 * potential EPERMs we'll try not to call
1851 * PR_SET_SECUREBITS unless necessary. */
1852 if (prctl(PR_GET_SECUREBITS
) != context
->secure_bits
)
1853 if (prctl(PR_SET_SECUREBITS
, context
->secure_bits
) < 0) {
1854 *exit_status
= EXIT_SECUREBITS
;
1858 if (context
->capabilities
)
1859 if (cap_set_proc(context
->capabilities
) < 0) {
1860 *exit_status
= EXIT_CAPABILITIES
;
1864 if (context
->no_new_privileges
)
1865 if (prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0) < 0) {
1866 *exit_status
= EXIT_NO_NEW_PRIVILEGES
;
1871 if (context
->address_families_whitelist
||
1872 !set_isempty(context
->address_families
)) {
1873 r
= apply_address_families(context
);
1875 *exit_status
= EXIT_ADDRESS_FAMILIES
;
1880 if (context
->syscall_whitelist
||
1881 !set_isempty(context
->syscall_filter
) ||
1882 !set_isempty(context
->syscall_archs
)) {
1883 r
= apply_seccomp(context
);
1885 *exit_status
= EXIT_SECCOMP
;
1892 if (mac_selinux_use()) {
1893 char *exec_context
= mac_selinux_context_net
?: context
->selinux_context
;
1896 r
= setexeccon(exec_context
);
1898 *exit_status
= EXIT_SELINUX_CONTEXT
;
1905 #ifdef HAVE_APPARMOR
1906 if (context
->apparmor_profile
&& mac_apparmor_use()) {
1907 r
= aa_change_onexec(context
->apparmor_profile
);
1908 if (r
< 0 && !context
->apparmor_profile_ignore
) {
1909 *exit_status
= EXIT_APPARMOR_PROFILE
;
1916 r
= build_environment(context
, n_fds
, params
->fd_names
, params
->watchdog_usec
, home
, username
, shell
, &our_env
);
1918 *exit_status
= EXIT_MEMORY
;
1922 final_env
= strv_env_merge(5,
1923 params
->environment
,
1925 context
->environment
,
1930 *exit_status
= EXIT_MEMORY
;
1934 final_argv
= replace_env_argv(argv
, final_env
);
1936 *exit_status
= EXIT_MEMORY
;
1940 final_env
= strv_env_clean(final_env
);
1942 if (_unlikely_(log_get_max_level() >= LOG_DEBUG
)) {
1943 _cleanup_free_
char *line
;
1945 line
= exec_command_line(final_argv
);
1948 log_struct(LOG_DEBUG
,
1950 "EXECUTABLE=%s", command
->path
,
1951 LOG_UNIT_MESSAGE(unit
, "Executing: %s", line
),
1957 execve(command
->path
, final_argv
, final_env
);
1958 *exit_status
= EXIT_EXEC
;
1962 int exec_spawn(Unit
*unit
,
1963 ExecCommand
*command
,
1964 const ExecContext
*context
,
1965 const ExecParameters
*params
,
1966 ExecRuntime
*runtime
,
1969 _cleanup_strv_free_
char **files_env
= NULL
;
1970 int *fds
= NULL
; unsigned n_fds
= 0;
1971 _cleanup_free_
char *line
= NULL
;
1981 assert(params
->fds
|| params
->n_fds
<= 0);
1983 if (context
->std_input
== EXEC_INPUT_SOCKET
||
1984 context
->std_output
== EXEC_OUTPUT_SOCKET
||
1985 context
->std_error
== EXEC_OUTPUT_SOCKET
) {
1987 if (params
->n_fds
!= 1) {
1988 log_unit_error(unit
, "Got more than one socket.");
1992 socket_fd
= params
->fds
[0];
1996 n_fds
= params
->n_fds
;
1999 r
= exec_context_load_environment(unit
, context
, &files_env
);
2001 return log_unit_error_errno(unit
, r
, "Failed to load environment files: %m");
2003 argv
= params
->argv
?: command
->argv
;
2004 line
= exec_command_line(argv
);
2008 log_struct(LOG_DEBUG
,
2010 LOG_UNIT_MESSAGE(unit
, "About to execute: %s", line
),
2011 "EXECUTABLE=%s", command
->path
,
2015 return log_unit_error_errno(unit
, r
, "Failed to fork: %m");
2020 r
= exec_child(unit
,
2032 log_struct_errno(LOG_ERR
, r
,
2033 LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED
),
2035 LOG_UNIT_MESSAGE(unit
, "Failed at step %s spawning %s: %m",
2036 exit_status_to_string(exit_status
, EXIT_STATUS_SYSTEMD
),
2038 "EXECUTABLE=%s", command
->path
,
2045 log_unit_debug(unit
, "Forked %s as "PID_FMT
, command
->path
, pid
);
2047 /* We add the new process to the cgroup both in the child (so
2048 * that we can be sure that no user code is ever executed
2049 * outside of the cgroup) and in the parent (so that we can be
2050 * sure that when we kill the cgroup the process will be
2052 if (params
->cgroup_path
)
2053 (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, pid
);
2055 exec_status_start(&command
->exec_status
, pid
);
2061 void exec_context_init(ExecContext
*c
) {
2065 c
->ioprio
= IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE
, 0);
2066 c
->cpu_sched_policy
= SCHED_OTHER
;
2067 c
->syslog_priority
= LOG_DAEMON
|LOG_INFO
;
2068 c
->syslog_level_prefix
= true;
2069 c
->ignore_sigpipe
= true;
2070 c
->timer_slack_nsec
= NSEC_INFINITY
;
2071 c
->personality
= PERSONALITY_INVALID
;
2072 c
->runtime_directory_mode
= 0755;
2075 void exec_context_done(ExecContext
*c
) {
2080 c
->environment
= strv_free(c
->environment
);
2081 c
->environment_files
= strv_free(c
->environment_files
);
2083 for (l
= 0; l
< ELEMENTSOF(c
->rlimit
); l
++)
2084 c
->rlimit
[l
] = mfree(c
->rlimit
[l
]);
2086 c
->working_directory
= mfree(c
->working_directory
);
2087 c
->root_directory
= mfree(c
->root_directory
);
2088 c
->tty_path
= mfree(c
->tty_path
);
2089 c
->syslog_identifier
= mfree(c
->syslog_identifier
);
2090 c
->user
= mfree(c
->user
);
2091 c
->group
= mfree(c
->group
);
2093 c
->supplementary_groups
= strv_free(c
->supplementary_groups
);
2095 c
->pam_name
= mfree(c
->pam_name
);
2097 if (c
->capabilities
) {
2098 cap_free(c
->capabilities
);
2099 c
->capabilities
= NULL
;
2102 c
->read_only_dirs
= strv_free(c
->read_only_dirs
);
2103 c
->read_write_dirs
= strv_free(c
->read_write_dirs
);
2104 c
->inaccessible_dirs
= strv_free(c
->inaccessible_dirs
);
2107 CPU_FREE(c
->cpuset
);
2109 c
->utmp_id
= mfree(c
->utmp_id
);
2110 c
->selinux_context
= mfree(c
->selinux_context
);
2111 c
->apparmor_profile
= mfree(c
->apparmor_profile
);
2113 c
->syscall_filter
= set_free(c
->syscall_filter
);
2114 c
->syscall_archs
= set_free(c
->syscall_archs
);
2115 c
->address_families
= set_free(c
->address_families
);
2117 c
->runtime_directory
= strv_free(c
->runtime_directory
);
2119 bus_endpoint_free(c
->bus_endpoint
);
2120 c
->bus_endpoint
= NULL
;
2123 int exec_context_destroy_runtime_directory(ExecContext
*c
, const char *runtime_prefix
) {
2128 if (!runtime_prefix
)
2131 STRV_FOREACH(i
, c
->runtime_directory
) {
2132 _cleanup_free_
char *p
;
2134 p
= strjoin(runtime_prefix
, "/", *i
, NULL
);
2138 /* We execute this synchronously, since we need to be
2139 * sure this is gone when we start the service
2141 (void) rm_rf(p
, REMOVE_ROOT
);
2147 void exec_command_done(ExecCommand
*c
) {
2150 c
->path
= mfree(c
->path
);
2152 c
->argv
= strv_free(c
->argv
);
2155 void exec_command_done_array(ExecCommand
*c
, unsigned n
) {
2158 for (i
= 0; i
< n
; i
++)
2159 exec_command_done(c
+i
);
2162 ExecCommand
* exec_command_free_list(ExecCommand
*c
) {
2166 LIST_REMOVE(command
, c
, i
);
2167 exec_command_done(i
);
2174 void exec_command_free_array(ExecCommand
**c
, unsigned n
) {
2177 for (i
= 0; i
< n
; i
++)
2178 c
[i
] = exec_command_free_list(c
[i
]);
2181 typedef struct InvalidEnvInfo
{
2186 static void invalid_env(const char *p
, void *userdata
) {
2187 InvalidEnvInfo
*info
= userdata
;
2189 log_unit_error(info
->unit
, "Ignoring invalid environment assignment '%s': %s", p
, info
->path
);
2192 int exec_context_load_environment(Unit
*unit
, const ExecContext
*c
, char ***l
) {
2193 char **i
, **r
= NULL
;
2198 STRV_FOREACH(i
, c
->environment_files
) {
2201 bool ignore
= false;
2203 _cleanup_globfree_ glob_t pglob
= {};
2213 if (!path_is_absolute(fn
)) {
2221 /* Filename supports globbing, take all matching files */
2223 if (glob(fn
, 0, NULL
, &pglob
) != 0) {
2228 return errno
? -errno
: -EINVAL
;
2230 count
= pglob
.gl_pathc
;
2238 for (n
= 0; n
< count
; n
++) {
2239 k
= load_env_file(NULL
, pglob
.gl_pathv
[n
], NULL
, &p
);
2247 /* Log invalid environment variables with filename */
2249 InvalidEnvInfo info
= {
2251 .path
= pglob
.gl_pathv
[n
]
2254 p
= strv_env_clean_with_callback(p
, invalid_env
, &info
);
2262 m
= strv_env_merge(2, r
, p
);
2278 static bool tty_may_match_dev_console(const char *tty
) {
2279 _cleanup_free_
char *active
= NULL
;
2282 if (startswith(tty
, "/dev/"))
2285 /* trivial identity? */
2286 if (streq(tty
, "console"))
2289 console
= resolve_dev_console(&active
);
2290 /* if we could not resolve, assume it may */
2294 /* "tty0" means the active VC, so it may be the same sometimes */
2295 return streq(console
, tty
) || (streq(console
, "tty0") && tty_is_vc(tty
));
2298 bool exec_context_may_touch_console(ExecContext
*ec
) {
2299 return (ec
->tty_reset
|| ec
->tty_vhangup
|| ec
->tty_vt_disallocate
||
2300 is_terminal_input(ec
->std_input
) ||
2301 is_terminal_output(ec
->std_output
) ||
2302 is_terminal_output(ec
->std_error
)) &&
2303 tty_may_match_dev_console(tty_path(ec
));
2306 static void strv_fprintf(FILE *f
, char **l
) {
2312 fprintf(f
, " %s", *g
);
2315 void exec_context_dump(ExecContext
*c
, FILE* f
, const char *prefix
) {
2322 prefix
= strempty(prefix
);
2326 "%sWorkingDirectory: %s\n"
2327 "%sRootDirectory: %s\n"
2328 "%sNonBlocking: %s\n"
2329 "%sPrivateTmp: %s\n"
2330 "%sPrivateNetwork: %s\n"
2331 "%sPrivateDevices: %s\n"
2332 "%sProtectHome: %s\n"
2333 "%sProtectSystem: %s\n"
2334 "%sIgnoreSIGPIPE: %s\n",
2336 prefix
, c
->working_directory
? c
->working_directory
: "/",
2337 prefix
, c
->root_directory
? c
->root_directory
: "/",
2338 prefix
, yes_no(c
->non_blocking
),
2339 prefix
, yes_no(c
->private_tmp
),
2340 prefix
, yes_no(c
->private_network
),
2341 prefix
, yes_no(c
->private_devices
),
2342 prefix
, protect_home_to_string(c
->protect_home
),
2343 prefix
, protect_system_to_string(c
->protect_system
),
2344 prefix
, yes_no(c
->ignore_sigpipe
));
2346 STRV_FOREACH(e
, c
->environment
)
2347 fprintf(f
, "%sEnvironment: %s\n", prefix
, *e
);
2349 STRV_FOREACH(e
, c
->environment_files
)
2350 fprintf(f
, "%sEnvironmentFile: %s\n", prefix
, *e
);
2352 fprintf(f
, "%sRuntimeDirectoryMode: %04o\n", prefix
, c
->runtime_directory_mode
);
2354 STRV_FOREACH(d
, c
->runtime_directory
)
2355 fprintf(f
, "%sRuntimeDirectory: %s\n", prefix
, *d
);
2362 if (c
->oom_score_adjust_set
)
2364 "%sOOMScoreAdjust: %i\n",
2365 prefix
, c
->oom_score_adjust
);
2367 for (i
= 0; i
< RLIM_NLIMITS
; i
++)
2369 fprintf(f
, "%s%s: "RLIM_FMT
"\n",
2370 prefix
, rlimit_to_string(i
), c
->rlimit
[i
]->rlim_max
);
2372 if (c
->ioprio_set
) {
2373 _cleanup_free_
char *class_str
= NULL
;
2375 ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c
->ioprio
), &class_str
);
2377 "%sIOSchedulingClass: %s\n"
2378 "%sIOPriority: %i\n",
2379 prefix
, strna(class_str
),
2380 prefix
, (int) IOPRIO_PRIO_DATA(c
->ioprio
));
2383 if (c
->cpu_sched_set
) {
2384 _cleanup_free_
char *policy_str
= NULL
;
2386 sched_policy_to_string_alloc(c
->cpu_sched_policy
, &policy_str
);
2388 "%sCPUSchedulingPolicy: %s\n"
2389 "%sCPUSchedulingPriority: %i\n"
2390 "%sCPUSchedulingResetOnFork: %s\n",
2391 prefix
, strna(policy_str
),
2392 prefix
, c
->cpu_sched_priority
,
2393 prefix
, yes_no(c
->cpu_sched_reset_on_fork
));
2397 fprintf(f
, "%sCPUAffinity:", prefix
);
2398 for (i
= 0; i
< c
->cpuset_ncpus
; i
++)
2399 if (CPU_ISSET_S(i
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
), c
->cpuset
))
2400 fprintf(f
, " %u", i
);
2404 if (c
->timer_slack_nsec
!= NSEC_INFINITY
)
2405 fprintf(f
, "%sTimerSlackNSec: "NSEC_FMT
"\n", prefix
, c
->timer_slack_nsec
);
2408 "%sStandardInput: %s\n"
2409 "%sStandardOutput: %s\n"
2410 "%sStandardError: %s\n",
2411 prefix
, exec_input_to_string(c
->std_input
),
2412 prefix
, exec_output_to_string(c
->std_output
),
2413 prefix
, exec_output_to_string(c
->std_error
));
2419 "%sTTYVHangup: %s\n"
2420 "%sTTYVTDisallocate: %s\n",
2421 prefix
, c
->tty_path
,
2422 prefix
, yes_no(c
->tty_reset
),
2423 prefix
, yes_no(c
->tty_vhangup
),
2424 prefix
, yes_no(c
->tty_vt_disallocate
));
2426 if (c
->std_output
== EXEC_OUTPUT_SYSLOG
||
2427 c
->std_output
== EXEC_OUTPUT_KMSG
||
2428 c
->std_output
== EXEC_OUTPUT_JOURNAL
||
2429 c
->std_output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2430 c
->std_output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2431 c
->std_output
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
||
2432 c
->std_error
== EXEC_OUTPUT_SYSLOG
||
2433 c
->std_error
== EXEC_OUTPUT_KMSG
||
2434 c
->std_error
== EXEC_OUTPUT_JOURNAL
||
2435 c
->std_error
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2436 c
->std_error
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2437 c
->std_error
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
) {
2439 _cleanup_free_
char *fac_str
= NULL
, *lvl_str
= NULL
;
2441 log_facility_unshifted_to_string_alloc(c
->syslog_priority
>> 3, &fac_str
);
2442 log_level_to_string_alloc(LOG_PRI(c
->syslog_priority
), &lvl_str
);
2445 "%sSyslogFacility: %s\n"
2446 "%sSyslogLevel: %s\n",
2447 prefix
, strna(fac_str
),
2448 prefix
, strna(lvl_str
));
2451 if (c
->capabilities
) {
2452 _cleanup_cap_free_charp_
char *t
;
2454 t
= cap_to_text(c
->capabilities
, NULL
);
2456 fprintf(f
, "%sCapabilities: %s\n", prefix
, t
);
2460 fprintf(f
, "%sSecure Bits:%s%s%s%s%s%s\n",
2462 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS
) ? " keep-caps" : "",
2463 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS_LOCKED
) ? " keep-caps-locked" : "",
2464 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP
) ? " no-setuid-fixup" : "",
2465 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP_LOCKED
) ? " no-setuid-fixup-locked" : "",
2466 (c
->secure_bits
& 1<<SECURE_NOROOT
) ? " noroot" : "",
2467 (c
->secure_bits
& 1<<SECURE_NOROOT_LOCKED
) ? "noroot-locked" : "");
2469 if (c
->capability_bounding_set_drop
) {
2471 fprintf(f
, "%sCapabilityBoundingSet:", prefix
);
2473 for (l
= 0; l
<= cap_last_cap(); l
++)
2474 if (!(c
->capability_bounding_set_drop
& ((uint64_t) 1ULL << (uint64_t) l
)))
2475 fprintf(f
, " %s", strna(capability_to_name(l
)));
2481 fprintf(f
, "%sUser: %s\n", prefix
, c
->user
);
2483 fprintf(f
, "%sGroup: %s\n", prefix
, c
->group
);
2485 if (strv_length(c
->supplementary_groups
) > 0) {
2486 fprintf(f
, "%sSupplementaryGroups:", prefix
);
2487 strv_fprintf(f
, c
->supplementary_groups
);
2492 fprintf(f
, "%sPAMName: %s\n", prefix
, c
->pam_name
);
2494 if (strv_length(c
->read_write_dirs
) > 0) {
2495 fprintf(f
, "%sReadWriteDirs:", prefix
);
2496 strv_fprintf(f
, c
->read_write_dirs
);
2500 if (strv_length(c
->read_only_dirs
) > 0) {
2501 fprintf(f
, "%sReadOnlyDirs:", prefix
);
2502 strv_fprintf(f
, c
->read_only_dirs
);
2506 if (strv_length(c
->inaccessible_dirs
) > 0) {
2507 fprintf(f
, "%sInaccessibleDirs:", prefix
);
2508 strv_fprintf(f
, c
->inaccessible_dirs
);
2514 "%sUtmpIdentifier: %s\n",
2515 prefix
, c
->utmp_id
);
2517 if (c
->selinux_context
)
2519 "%sSELinuxContext: %s%s\n",
2520 prefix
, c
->selinux_context_ignore
? "-" : "", c
->selinux_context
);
2522 if (c
->personality
!= PERSONALITY_INVALID
)
2524 "%sPersonality: %s\n",
2525 prefix
, strna(personality_to_string(c
->personality
)));
2527 if (c
->syscall_filter
) {
2535 "%sSystemCallFilter: ",
2538 if (!c
->syscall_whitelist
)
2542 SET_FOREACH(id
, c
->syscall_filter
, j
) {
2543 _cleanup_free_
char *name
= NULL
;
2550 name
= seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE
, PTR_TO_INT(id
) - 1);
2551 fputs(strna(name
), f
);
2558 if (c
->syscall_archs
) {
2565 "%sSystemCallArchitectures:",
2569 SET_FOREACH(id
, c
->syscall_archs
, j
)
2570 fprintf(f
, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id
) - 1)));
2575 if (c
->syscall_errno
!= 0)
2577 "%sSystemCallErrorNumber: %s\n",
2578 prefix
, strna(errno_to_name(c
->syscall_errno
)));
2580 if (c
->apparmor_profile
)
2582 "%sAppArmorProfile: %s%s\n",
2583 prefix
, c
->apparmor_profile_ignore
? "-" : "", c
->apparmor_profile
);
2586 bool exec_context_maintains_privileges(ExecContext
*c
) {
2589 /* Returns true if the process forked off would run run under
2590 * an unchanged UID or as root. */
2595 if (streq(c
->user
, "root") || streq(c
->user
, "0"))
2601 void exec_status_start(ExecStatus
*s
, pid_t pid
) {
2606 dual_timestamp_get(&s
->start_timestamp
);
2609 void exec_status_exit(ExecStatus
*s
, ExecContext
*context
, pid_t pid
, int code
, int status
) {
2612 if (s
->pid
&& s
->pid
!= pid
)
2616 dual_timestamp_get(&s
->exit_timestamp
);
2622 if (context
->utmp_id
)
2623 utmp_put_dead_process(context
->utmp_id
, pid
, code
, status
);
2625 exec_context_tty_reset(context
);
2629 void exec_status_dump(ExecStatus
*s
, FILE *f
, const char *prefix
) {
2630 char buf
[FORMAT_TIMESTAMP_MAX
];
2638 prefix
= strempty(prefix
);
2641 "%sPID: "PID_FMT
"\n",
2644 if (s
->start_timestamp
.realtime
> 0)
2646 "%sStart Timestamp: %s\n",
2647 prefix
, format_timestamp(buf
, sizeof(buf
), s
->start_timestamp
.realtime
));
2649 if (s
->exit_timestamp
.realtime
> 0)
2651 "%sExit Timestamp: %s\n"
2653 "%sExit Status: %i\n",
2654 prefix
, format_timestamp(buf
, sizeof(buf
), s
->exit_timestamp
.realtime
),
2655 prefix
, sigchld_code_to_string(s
->code
),
2659 char *exec_command_line(char **argv
) {
2667 STRV_FOREACH(a
, argv
)
2670 if (!(n
= new(char, k
)))
2674 STRV_FOREACH(a
, argv
) {
2681 if (strpbrk(*a
, WHITESPACE
)) {
2692 /* FIXME: this doesn't really handle arguments that have
2693 * spaces and ticks in them */
2698 void exec_command_dump(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2699 _cleanup_free_
char *cmd
= NULL
;
2700 const char *prefix2
;
2705 prefix
= strempty(prefix
);
2706 prefix2
= strjoina(prefix
, "\t");
2708 cmd
= exec_command_line(c
->argv
);
2710 "%sCommand Line: %s\n",
2711 prefix
, cmd
? cmd
: strerror(ENOMEM
));
2713 exec_status_dump(&c
->exec_status
, f
, prefix2
);
2716 void exec_command_dump_list(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2719 prefix
= strempty(prefix
);
2721 LIST_FOREACH(command
, c
, c
)
2722 exec_command_dump(c
, f
, prefix
);
2725 void exec_command_append_list(ExecCommand
**l
, ExecCommand
*e
) {
2732 /* It's kind of important, that we keep the order here */
2733 LIST_FIND_TAIL(command
, *l
, end
);
2734 LIST_INSERT_AFTER(command
, *l
, end
, e
);
2739 int exec_command_set(ExecCommand
*c
, const char *path
, ...) {
2747 l
= strv_new_ap(path
, ap
);
2768 int exec_command_append(ExecCommand
*c
, const char *path
, ...) {
2769 _cleanup_strv_free_
char **l
= NULL
;
2777 l
= strv_new_ap(path
, ap
);
2783 r
= strv_extend_strv(&c
->argv
, l
, false);
2791 static int exec_runtime_allocate(ExecRuntime
**rt
) {
2796 *rt
= new0(ExecRuntime
, 1);
2801 (*rt
)->netns_storage_socket
[0] = (*rt
)->netns_storage_socket
[1] = -1;
2806 int exec_runtime_make(ExecRuntime
**rt
, ExecContext
*c
, const char *id
) {
2816 if (!c
->private_network
&& !c
->private_tmp
)
2819 r
= exec_runtime_allocate(rt
);
2823 if (c
->private_network
&& (*rt
)->netns_storage_socket
[0] < 0) {
2824 if (socketpair(AF_UNIX
, SOCK_DGRAM
, 0, (*rt
)->netns_storage_socket
) < 0)
2828 if (c
->private_tmp
&& !(*rt
)->tmp_dir
) {
2829 r
= setup_tmp_dirs(id
, &(*rt
)->tmp_dir
, &(*rt
)->var_tmp_dir
);
2837 ExecRuntime
*exec_runtime_ref(ExecRuntime
*r
) {
2839 assert(r
->n_ref
> 0);
2845 ExecRuntime
*exec_runtime_unref(ExecRuntime
*r
) {
2850 assert(r
->n_ref
> 0);
2857 free(r
->var_tmp_dir
);
2858 safe_close_pair(r
->netns_storage_socket
);
2864 int exec_runtime_serialize(Unit
*u
, ExecRuntime
*rt
, FILE *f
, FDSet
*fds
) {
2873 unit_serialize_item(u
, f
, "tmp-dir", rt
->tmp_dir
);
2875 if (rt
->var_tmp_dir
)
2876 unit_serialize_item(u
, f
, "var-tmp-dir", rt
->var_tmp_dir
);
2878 if (rt
->netns_storage_socket
[0] >= 0) {
2881 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[0]);
2885 unit_serialize_item_format(u
, f
, "netns-socket-0", "%i", copy
);
2888 if (rt
->netns_storage_socket
[1] >= 0) {
2891 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[1]);
2895 unit_serialize_item_format(u
, f
, "netns-socket-1", "%i", copy
);
2901 int exec_runtime_deserialize_item(Unit
*u
, ExecRuntime
**rt
, const char *key
, const char *value
, FDSet
*fds
) {
2908 if (streq(key
, "tmp-dir")) {
2911 r
= exec_runtime_allocate(rt
);
2915 copy
= strdup(value
);
2919 free((*rt
)->tmp_dir
);
2920 (*rt
)->tmp_dir
= copy
;
2922 } else if (streq(key
, "var-tmp-dir")) {
2925 r
= exec_runtime_allocate(rt
);
2929 copy
= strdup(value
);
2933 free((*rt
)->var_tmp_dir
);
2934 (*rt
)->var_tmp_dir
= copy
;
2936 } else if (streq(key
, "netns-socket-0")) {
2939 r
= exec_runtime_allocate(rt
);
2943 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
2944 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
2946 safe_close((*rt
)->netns_storage_socket
[0]);
2947 (*rt
)->netns_storage_socket
[0] = fdset_remove(fds
, fd
);
2949 } else if (streq(key
, "netns-socket-1")) {
2952 r
= exec_runtime_allocate(rt
);
2956 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
2957 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
2959 safe_close((*rt
)->netns_storage_socket
[1]);
2960 (*rt
)->netns_storage_socket
[1] = fdset_remove(fds
, fd
);
2968 static void *remove_tmpdir_thread(void *p
) {
2969 _cleanup_free_
char *path
= p
;
2971 (void) rm_rf(path
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
2975 void exec_runtime_destroy(ExecRuntime
*rt
) {
2981 /* If there are multiple users of this, let's leave the stuff around */
2986 log_debug("Spawning thread to nuke %s", rt
->tmp_dir
);
2988 r
= asynchronous_job(remove_tmpdir_thread
, rt
->tmp_dir
);
2990 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->tmp_dir
);
2997 if (rt
->var_tmp_dir
) {
2998 log_debug("Spawning thread to nuke %s", rt
->var_tmp_dir
);
3000 r
= asynchronous_job(remove_tmpdir_thread
, rt
->var_tmp_dir
);
3002 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->var_tmp_dir
);
3003 free(rt
->var_tmp_dir
);
3006 rt
->var_tmp_dir
= NULL
;
3009 safe_close_pair(rt
->netns_storage_socket
);
3012 static const char* const exec_input_table
[_EXEC_INPUT_MAX
] = {
3013 [EXEC_INPUT_NULL
] = "null",
3014 [EXEC_INPUT_TTY
] = "tty",
3015 [EXEC_INPUT_TTY_FORCE
] = "tty-force",
3016 [EXEC_INPUT_TTY_FAIL
] = "tty-fail",
3017 [EXEC_INPUT_SOCKET
] = "socket"
3020 DEFINE_STRING_TABLE_LOOKUP(exec_input
, ExecInput
);
3022 static const char* const exec_output_table
[_EXEC_OUTPUT_MAX
] = {
3023 [EXEC_OUTPUT_INHERIT
] = "inherit",
3024 [EXEC_OUTPUT_NULL
] = "null",
3025 [EXEC_OUTPUT_TTY
] = "tty",
3026 [EXEC_OUTPUT_SYSLOG
] = "syslog",
3027 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE
] = "syslog+console",
3028 [EXEC_OUTPUT_KMSG
] = "kmsg",
3029 [EXEC_OUTPUT_KMSG_AND_CONSOLE
] = "kmsg+console",
3030 [EXEC_OUTPUT_JOURNAL
] = "journal",
3031 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE
] = "journal+console",
3032 [EXEC_OUTPUT_SOCKET
] = "socket"
3035 DEFINE_STRING_TABLE_LOOKUP(exec_output
, ExecOutput
);
3037 static const char* const exec_utmp_mode_table
[_EXEC_UTMP_MODE_MAX
] = {
3038 [EXEC_UTMP_INIT
] = "init",
3039 [EXEC_UTMP_LOGIN
] = "login",
3040 [EXEC_UTMP_USER
] = "user",
3043 DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode
, ExecUtmpMode
);