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"
78 #include "namespace.h"
79 #include "path-util.h"
80 #include "process-util.h"
83 #include "seccomp-util.h"
85 #include "securebits.h"
86 #include "selinux-util.h"
87 #include "signal-util.h"
88 #include "smack-util.h"
89 #include "string-util.h"
91 #include "terminal-util.h"
93 #include "user-util.h"
95 #include "utmp-wtmp.h"
97 #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
98 #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
100 /* This assumes there is a 'tty' group */
101 #define TTY_MODE 0620
103 #define SNDBUF_SIZE (8*1024*1024)
105 static int shift_fds(int fds
[], unsigned n_fds
) {
106 int start
, restart_from
;
111 /* Modifies the fds array! (sorts it) */
121 for (i
= start
; i
< (int) n_fds
; i
++) {
124 /* Already at right index? */
128 nfd
= fcntl(fds
[i
], F_DUPFD
, i
+ 3);
135 /* Hmm, the fd we wanted isn't free? Then
136 * let's remember that and try again from here */
137 if (nfd
!= i
+3 && restart_from
< 0)
141 if (restart_from
< 0)
144 start
= restart_from
;
150 static int flags_fds(const int fds
[], unsigned n_fds
, bool nonblock
) {
159 /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
161 for (i
= 0; i
< n_fds
; i
++) {
163 r
= fd_nonblock(fds
[i
], nonblock
);
167 /* We unconditionally drop FD_CLOEXEC from the fds,
168 * since after all we want to pass these fds to our
171 r
= fd_cloexec(fds
[i
], false);
179 _pure_
static const char *tty_path(const ExecContext
*context
) {
182 if (context
->tty_path
)
183 return context
->tty_path
;
185 return "/dev/console";
188 static void exec_context_tty_reset(const ExecContext
*context
) {
191 if (context
->tty_vhangup
)
192 terminal_vhangup(tty_path(context
));
194 if (context
->tty_reset
)
195 reset_terminal(tty_path(context
));
197 if (context
->tty_vt_disallocate
&& context
->tty_path
)
198 vt_disallocate(context
->tty_path
);
201 static bool is_terminal_output(ExecOutput o
) {
203 o
== EXEC_OUTPUT_TTY
||
204 o
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
205 o
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
206 o
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
;
209 static int open_null_as(int flags
, int nfd
) {
214 fd
= open("/dev/null", flags
|O_NOCTTY
);
219 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
227 static int connect_journal_socket(int fd
, uid_t uid
, gid_t gid
) {
228 union sockaddr_union sa
= {
229 .un
.sun_family
= AF_UNIX
,
230 .un
.sun_path
= "/run/systemd/journal/stdout",
232 uid_t olduid
= UID_INVALID
;
233 gid_t oldgid
= GID_INVALID
;
236 if (gid
!= GID_INVALID
) {
244 if (uid
!= UID_INVALID
) {
254 r
= connect(fd
, &sa
.sa
, offsetof(struct sockaddr_un
, sun_path
) + strlen(sa
.un
.sun_path
));
258 /* If we fail to restore the uid or gid, things will likely
259 fail later on. This should only happen if an LSM interferes. */
261 if (uid
!= UID_INVALID
)
262 (void) seteuid(olduid
);
265 if (gid
!= GID_INVALID
)
266 (void) setegid(oldgid
);
271 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
) {
275 assert(output
< _EXEC_OUTPUT_MAX
);
279 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
283 r
= connect_journal_socket(fd
, uid
, gid
);
287 if (shutdown(fd
, SHUT_RD
) < 0) {
292 fd_inc_sndbuf(fd
, SNDBUF_SIZE
);
302 context
->syslog_identifier
? context
->syslog_identifier
: ident
,
304 context
->syslog_priority
,
305 !!context
->syslog_level_prefix
,
306 output
== EXEC_OUTPUT_SYSLOG
|| output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
,
307 output
== EXEC_OUTPUT_KMSG
|| output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
,
308 is_terminal_output(output
));
311 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
318 static int open_terminal_as(const char *path
, mode_t mode
, int nfd
) {
324 fd
= open_terminal(path
, mode
| O_NOCTTY
);
329 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
337 static bool is_terminal_input(ExecInput i
) {
339 i
== EXEC_INPUT_TTY
||
340 i
== EXEC_INPUT_TTY_FORCE
||
341 i
== EXEC_INPUT_TTY_FAIL
;
344 static int fixup_input(ExecInput std_input
, int socket_fd
, bool apply_tty_stdin
) {
346 if (is_terminal_input(std_input
) && !apply_tty_stdin
)
347 return EXEC_INPUT_NULL
;
349 if (std_input
== EXEC_INPUT_SOCKET
&& socket_fd
< 0)
350 return EXEC_INPUT_NULL
;
355 static int fixup_output(ExecOutput std_output
, int socket_fd
) {
357 if (std_output
== EXEC_OUTPUT_SOCKET
&& socket_fd
< 0)
358 return EXEC_OUTPUT_INHERIT
;
363 static int setup_input(
364 const ExecContext
*context
,
365 const ExecParameters
*params
,
373 if (params
->stdin_fd
>= 0) {
374 if (dup2(params
->stdin_fd
, STDIN_FILENO
) < 0)
377 /* Try to make this the controlling tty, if it is a tty, and reset it */
378 (void) ioctl(STDIN_FILENO
, TIOCSCTTY
, context
->std_input
== EXEC_INPUT_TTY_FORCE
);
379 (void) reset_terminal_fd(STDIN_FILENO
, true);
384 i
= fixup_input(context
->std_input
, socket_fd
, params
->apply_tty_stdin
);
388 case EXEC_INPUT_NULL
:
389 return open_null_as(O_RDONLY
, STDIN_FILENO
);
392 case EXEC_INPUT_TTY_FORCE
:
393 case EXEC_INPUT_TTY_FAIL
: {
396 fd
= acquire_terminal(tty_path(context
),
397 i
== EXEC_INPUT_TTY_FAIL
,
398 i
== EXEC_INPUT_TTY_FORCE
,
404 if (fd
!= STDIN_FILENO
) {
405 r
= dup2(fd
, STDIN_FILENO
) < 0 ? -errno
: STDIN_FILENO
;
413 case EXEC_INPUT_SOCKET
:
414 return dup2(socket_fd
, STDIN_FILENO
) < 0 ? -errno
: STDIN_FILENO
;
417 assert_not_reached("Unknown input type");
421 static int setup_output(
423 const ExecContext
*context
,
424 const ExecParameters
*params
,
428 uid_t uid
, gid_t gid
) {
439 if (fileno
== STDOUT_FILENO
&& params
->stdout_fd
>= 0) {
441 if (dup2(params
->stdout_fd
, STDOUT_FILENO
) < 0)
444 return STDOUT_FILENO
;
447 if (fileno
== STDERR_FILENO
&& params
->stderr_fd
>= 0) {
448 if (dup2(params
->stderr_fd
, STDERR_FILENO
) < 0)
451 return STDERR_FILENO
;
454 i
= fixup_input(context
->std_input
, socket_fd
, params
->apply_tty_stdin
);
455 o
= fixup_output(context
->std_output
, socket_fd
);
457 if (fileno
== STDERR_FILENO
) {
459 e
= fixup_output(context
->std_error
, socket_fd
);
461 /* This expects the input and output are already set up */
463 /* Don't change the stderr file descriptor if we inherit all
464 * the way and are not on a tty */
465 if (e
== EXEC_OUTPUT_INHERIT
&&
466 o
== EXEC_OUTPUT_INHERIT
&&
467 i
== EXEC_INPUT_NULL
&&
468 !is_terminal_input(context
->std_input
) &&
472 /* Duplicate from stdout if possible */
473 if (e
== o
|| e
== EXEC_OUTPUT_INHERIT
)
474 return dup2(STDOUT_FILENO
, fileno
) < 0 ? -errno
: fileno
;
478 } else if (o
== EXEC_OUTPUT_INHERIT
) {
479 /* If input got downgraded, inherit the original value */
480 if (i
== EXEC_INPUT_NULL
&& is_terminal_input(context
->std_input
))
481 return open_terminal_as(tty_path(context
), O_WRONLY
, fileno
);
483 /* If the input is connected to anything that's not a /dev/null, inherit that... */
484 if (i
!= EXEC_INPUT_NULL
)
485 return dup2(STDIN_FILENO
, fileno
) < 0 ? -errno
: fileno
;
487 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
491 /* We need to open /dev/null here anew, to get the right access mode. */
492 return open_null_as(O_WRONLY
, fileno
);
497 case EXEC_OUTPUT_NULL
:
498 return open_null_as(O_WRONLY
, fileno
);
500 case EXEC_OUTPUT_TTY
:
501 if (is_terminal_input(i
))
502 return dup2(STDIN_FILENO
, fileno
) < 0 ? -errno
: fileno
;
504 /* We don't reset the terminal if this is just about output */
505 return open_terminal_as(tty_path(context
), O_WRONLY
, fileno
);
507 case EXEC_OUTPUT_SYSLOG
:
508 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE
:
509 case EXEC_OUTPUT_KMSG
:
510 case EXEC_OUTPUT_KMSG_AND_CONSOLE
:
511 case EXEC_OUTPUT_JOURNAL
:
512 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE
:
513 r
= connect_logger_as(context
, o
, ident
, unit
->id
, fileno
, uid
, gid
);
515 log_unit_error_errno(unit
, r
, "Failed to connect %s to the journal socket, ignoring: %m", fileno
== STDOUT_FILENO
? "stdout" : "stderr");
516 r
= open_null_as(O_WRONLY
, fileno
);
520 case EXEC_OUTPUT_SOCKET
:
521 assert(socket_fd
>= 0);
522 return dup2(socket_fd
, fileno
) < 0 ? -errno
: fileno
;
525 assert_not_reached("Unknown error type");
529 static int chown_terminal(int fd
, uid_t uid
) {
534 /* This might fail. What matters are the results. */
535 (void) fchown(fd
, uid
, -1);
536 (void) fchmod(fd
, TTY_MODE
);
538 if (fstat(fd
, &st
) < 0)
541 if (st
.st_uid
!= uid
|| (st
.st_mode
& 0777) != TTY_MODE
)
547 static int setup_confirm_stdio(int *_saved_stdin
, int *_saved_stdout
) {
548 _cleanup_close_
int fd
= -1, saved_stdin
= -1, saved_stdout
= -1;
551 assert(_saved_stdin
);
552 assert(_saved_stdout
);
554 saved_stdin
= fcntl(STDIN_FILENO
, F_DUPFD
, 3);
558 saved_stdout
= fcntl(STDOUT_FILENO
, F_DUPFD
, 3);
559 if (saved_stdout
< 0)
562 fd
= acquire_terminal(
567 DEFAULT_CONFIRM_USEC
);
571 r
= chown_terminal(fd
, getuid());
575 r
= reset_terminal_fd(fd
, true);
579 if (dup2(fd
, STDIN_FILENO
) < 0)
582 if (dup2(fd
, STDOUT_FILENO
) < 0)
589 *_saved_stdin
= saved_stdin
;
590 *_saved_stdout
= saved_stdout
;
592 saved_stdin
= saved_stdout
= -1;
597 _printf_(1, 2) static int write_confirm_message(const char *format
, ...) {
598 _cleanup_close_
int fd
= -1;
603 fd
= open_terminal("/dev/console", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
607 va_start(ap
, format
);
608 vdprintf(fd
, format
, ap
);
614 static int restore_confirm_stdio(int *saved_stdin
, int *saved_stdout
) {
618 assert(saved_stdout
);
622 if (*saved_stdin
>= 0)
623 if (dup2(*saved_stdin
, STDIN_FILENO
) < 0)
626 if (*saved_stdout
>= 0)
627 if (dup2(*saved_stdout
, STDOUT_FILENO
) < 0)
630 *saved_stdin
= safe_close(*saved_stdin
);
631 *saved_stdout
= safe_close(*saved_stdout
);
636 static int ask_for_confirmation(char *response
, char **argv
) {
637 int saved_stdout
= -1, saved_stdin
= -1, r
;
638 _cleanup_free_
char *line
= NULL
;
640 r
= setup_confirm_stdio(&saved_stdin
, &saved_stdout
);
644 line
= exec_command_line(argv
);
648 r
= ask_char(response
, "yns", "Execute %s? [Yes, No, Skip] ", line
);
650 restore_confirm_stdio(&saved_stdin
, &saved_stdout
);
655 static int enforce_groups(const ExecContext
*context
, const char *username
, gid_t gid
) {
656 bool keep_groups
= false;
661 /* Lookup and set GID and supplementary group list. Here too
662 * we avoid NSS lookups for gid=0. */
664 if (context
->group
|| username
) {
665 /* First step, initialize groups from /etc/groups */
666 if (username
&& gid
!= 0) {
667 if (initgroups(username
, gid
) < 0)
673 /* Second step, set our gids */
674 if (setresgid(gid
, gid
, gid
) < 0)
678 if (context
->supplementary_groups
) {
683 /* Final step, initialize any manually set supplementary groups */
684 assert_se((ngroups_max
= (int) sysconf(_SC_NGROUPS_MAX
)) > 0);
686 if (!(gids
= new(gid_t
, ngroups_max
)))
690 k
= getgroups(ngroups_max
, gids
);
698 STRV_FOREACH(i
, context
->supplementary_groups
) {
701 if (k
>= ngroups_max
) {
707 r
= get_group_creds(&g
, gids
+k
);
716 if (setgroups(k
, gids
) < 0) {
727 static int enforce_user(const ExecContext
*context
, uid_t uid
) {
730 /* Sets (but doesn't lookup) the uid and make sure we keep the
731 * capabilities while doing so. */
733 if (context
->capabilities
) {
734 _cleanup_cap_free_ cap_t d
= NULL
;
735 static const cap_value_t bits
[] = {
736 CAP_SETUID
, /* Necessary so that we can run setresuid() below */
737 CAP_SETPCAP
/* Necessary so that we can set PR_SET_SECUREBITS later on */
740 /* First step: If we need to keep capabilities but
741 * drop privileges we need to make sure we keep our
742 * caps, while we drop privileges. */
744 int sb
= context
->secure_bits
| 1<<SECURE_KEEP_CAPS
;
746 if (prctl(PR_GET_SECUREBITS
) != sb
)
747 if (prctl(PR_SET_SECUREBITS
, sb
) < 0)
751 /* Second step: set the capabilities. This will reduce
752 * the capabilities to the minimum we need. */
754 d
= cap_dup(context
->capabilities
);
758 if (cap_set_flag(d
, CAP_EFFECTIVE
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0 ||
759 cap_set_flag(d
, CAP_PERMITTED
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0)
762 if (cap_set_proc(d
) < 0)
766 /* Third step: actually set the uids */
767 if (setresuid(uid
, uid
, uid
) < 0)
770 /* At this point we should have all necessary capabilities but
771 are otherwise a normal user. However, the caps might got
772 corrupted due to the setresuid() so we need clean them up
773 later. This is done outside of this call. */
780 static int null_conv(
782 const struct pam_message
**msg
,
783 struct pam_response
**resp
,
786 /* We don't support conversations */
791 static int setup_pam(
797 int fds
[], unsigned n_fds
) {
799 static const struct pam_conv conv
= {
804 _cleanup_(barrier_destroy
) Barrier barrier
= BARRIER_NULL
;
805 pam_handle_t
*handle
= NULL
;
807 int pam_code
= PAM_SUCCESS
;
810 bool close_session
= false;
811 pid_t pam_pid
= 0, parent_pid
;
818 /* We set up PAM in the parent process, then fork. The child
819 * will then stay around until killed via PR_GET_PDEATHSIG or
820 * systemd via the cgroup logic. It will then remove the PAM
821 * session again. The parent process will exec() the actual
822 * daemon. We do things this way to ensure that the main PID
823 * of the daemon is the one we initially fork()ed. */
825 err
= barrier_create(&barrier
);
829 if (log_get_max_level() < LOG_DEBUG
)
832 pam_code
= pam_start(name
, user
, &conv
, &handle
);
833 if (pam_code
!= PAM_SUCCESS
) {
839 pam_code
= pam_set_item(handle
, PAM_TTY
, tty
);
840 if (pam_code
!= PAM_SUCCESS
)
844 pam_code
= pam_acct_mgmt(handle
, flags
);
845 if (pam_code
!= PAM_SUCCESS
)
848 pam_code
= pam_open_session(handle
, flags
);
849 if (pam_code
!= PAM_SUCCESS
)
852 close_session
= true;
854 e
= pam_getenvlist(handle
);
856 pam_code
= PAM_BUF_ERR
;
860 /* Block SIGTERM, so that we know that it won't get lost in
863 assert_se(sigprocmask_many(SIG_BLOCK
, &old_ss
, SIGTERM
, -1) >= 0);
865 parent_pid
= getpid();
875 /* The child's job is to reset the PAM session on
877 barrier_set_role(&barrier
, BARRIER_CHILD
);
879 /* This string must fit in 10 chars (i.e. the length
880 * of "/sbin/init"), to look pretty in /bin/ps */
881 rename_process("(sd-pam)");
883 /* Make sure we don't keep open the passed fds in this
884 child. We assume that otherwise only those fds are
885 open here that have been opened by PAM. */
886 close_many(fds
, n_fds
);
888 /* Drop privileges - we don't need any to pam_close_session
889 * and this will make PR_SET_PDEATHSIG work in most cases.
890 * If this fails, ignore the error - but expect sd-pam threads
891 * to fail to exit normally */
892 if (setresuid(uid
, uid
, uid
) < 0)
893 log_error_errno(r
, "Error: Failed to setresuid() in sd-pam: %m");
895 (void) ignore_signals(SIGPIPE
, -1);
897 /* Wait until our parent died. This will only work if
898 * the above setresuid() succeeds, otherwise the kernel
899 * will not allow unprivileged parents kill their privileged
900 * children this way. We rely on the control groups kill logic
901 * to do the rest for us. */
902 if (prctl(PR_SET_PDEATHSIG
, SIGTERM
) < 0)
905 /* Tell the parent that our setup is done. This is especially
906 * important regarding dropping privileges. Otherwise, unit
907 * setup might race against our setresuid(2) call. */
908 barrier_place(&barrier
);
910 /* Check if our parent process might already have
912 if (getppid() == parent_pid
) {
915 assert_se(sigemptyset(&ss
) >= 0);
916 assert_se(sigaddset(&ss
, SIGTERM
) >= 0);
919 if (sigwait(&ss
, &sig
) < 0) {
926 assert(sig
== SIGTERM
);
931 /* If our parent died we'll end the session */
932 if (getppid() != parent_pid
) {
933 pam_code
= pam_close_session(handle
, flags
);
934 if (pam_code
!= PAM_SUCCESS
)
941 pam_end(handle
, pam_code
| flags
);
945 barrier_set_role(&barrier
, BARRIER_PARENT
);
947 /* If the child was forked off successfully it will do all the
948 * cleanups, so forget about the handle here. */
951 /* Unblock SIGTERM again in the parent */
952 assert_se(sigprocmask(SIG_SETMASK
, &old_ss
, NULL
) >= 0);
954 /* We close the log explicitly here, since the PAM modules
955 * might have opened it, but we don't want this fd around. */
958 /* Synchronously wait for the child to initialize. We don't care for
959 * errors as we cannot recover. However, warn loudly if it happens. */
960 if (!barrier_place_and_sync(&barrier
))
961 log_error("PAM initialization failed");
969 if (pam_code
!= PAM_SUCCESS
) {
970 log_error("PAM failed: %s", pam_strerror(handle
, pam_code
));
971 err
= -EPERM
; /* PAM errors do not map to errno */
973 err
= log_error_errno(err
< 0 ? err
: errno
, "PAM failed: %m");
978 pam_code
= pam_close_session(handle
, flags
);
980 pam_end(handle
, pam_code
| flags
);
988 kill(pam_pid
, SIGTERM
);
989 kill(pam_pid
, SIGCONT
);
996 static void rename_process_from_path(const char *path
) {
997 char process_name
[11];
1001 /* This resulting string must fit in 10 chars (i.e. the length
1002 * of "/sbin/init") to look pretty in /bin/ps */
1006 rename_process("(...)");
1012 /* The end of the process name is usually more
1013 * interesting, since the first bit might just be
1019 process_name
[0] = '(';
1020 memcpy(process_name
+1, p
, l
);
1021 process_name
[1+l
] = ')';
1022 process_name
[1+l
+1] = 0;
1024 rename_process(process_name
);
1029 static int apply_seccomp(const ExecContext
*c
) {
1030 uint32_t negative_action
, action
;
1031 scmp_filter_ctx
*seccomp
;
1038 negative_action
= c
->syscall_errno
== 0 ? SCMP_ACT_KILL
: SCMP_ACT_ERRNO(c
->syscall_errno
);
1040 seccomp
= seccomp_init(c
->syscall_whitelist
? negative_action
: SCMP_ACT_ALLOW
);
1044 if (c
->syscall_archs
) {
1046 SET_FOREACH(id
, c
->syscall_archs
, i
) {
1047 r
= seccomp_arch_add(seccomp
, PTR_TO_UINT32(id
) - 1);
1055 r
= seccomp_add_secondary_archs(seccomp
);
1060 action
= c
->syscall_whitelist
? SCMP_ACT_ALLOW
: negative_action
;
1061 SET_FOREACH(id
, c
->syscall_filter
, i
) {
1062 r
= seccomp_rule_add(seccomp
, action
, PTR_TO_INT(id
) - 1, 0);
1067 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1071 r
= seccomp_load(seccomp
);
1074 seccomp_release(seccomp
);
1078 static int apply_address_families(const ExecContext
*c
) {
1079 scmp_filter_ctx
*seccomp
;
1085 seccomp
= seccomp_init(SCMP_ACT_ALLOW
);
1089 r
= seccomp_add_secondary_archs(seccomp
);
1093 if (c
->address_families_whitelist
) {
1094 int af
, first
= 0, last
= 0;
1097 /* If this is a whitelist, we first block the address
1098 * families that are out of range and then everything
1099 * that is not in the set. First, we find the lowest
1100 * and highest address family in the set. */
1102 SET_FOREACH(afp
, c
->address_families
, i
) {
1103 af
= PTR_TO_INT(afp
);
1105 if (af
<= 0 || af
>= af_max())
1108 if (first
== 0 || af
< first
)
1111 if (last
== 0 || af
> last
)
1115 assert((first
== 0) == (last
== 0));
1119 /* No entries in the valid range, block everything */
1120 r
= seccomp_rule_add(
1122 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1130 /* Block everything below the first entry */
1131 r
= seccomp_rule_add(
1133 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1136 SCMP_A0(SCMP_CMP_LT
, first
));
1140 /* Block everything above the last entry */
1141 r
= seccomp_rule_add(
1143 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1146 SCMP_A0(SCMP_CMP_GT
, last
));
1150 /* Block everything between the first and last
1152 for (af
= 1; af
< af_max(); af
++) {
1154 if (set_contains(c
->address_families
, INT_TO_PTR(af
)))
1157 r
= seccomp_rule_add(
1159 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1162 SCMP_A0(SCMP_CMP_EQ
, af
));
1171 /* If this is a blacklist, then generate one rule for
1172 * each address family that are then combined in OR
1175 SET_FOREACH(af
, c
->address_families
, i
) {
1177 r
= seccomp_rule_add(
1179 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1182 SCMP_A0(SCMP_CMP_EQ
, PTR_TO_INT(af
)));
1188 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1192 r
= seccomp_load(seccomp
);
1195 seccomp_release(seccomp
);
1201 static void do_idle_pipe_dance(int idle_pipe
[4]) {
1205 idle_pipe
[1] = safe_close(idle_pipe
[1]);
1206 idle_pipe
[2] = safe_close(idle_pipe
[2]);
1208 if (idle_pipe
[0] >= 0) {
1211 r
= fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT_USEC
);
1213 if (idle_pipe
[3] >= 0 && r
== 0 /* timeout */) {
1216 /* Signal systemd that we are bored and want to continue. */
1217 n
= write(idle_pipe
[3], "x", 1);
1219 /* Wait for systemd to react to the signal above. */
1220 fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT2_USEC
);
1223 idle_pipe
[0] = safe_close(idle_pipe
[0]);
1227 idle_pipe
[3] = safe_close(idle_pipe
[3]);
1230 static int build_environment(
1231 const ExecContext
*c
,
1234 usec_t watchdog_usec
,
1236 const char *username
,
1240 _cleanup_strv_free_
char **our_env
= NULL
;
1247 our_env
= new0(char*, 11);
1252 _cleanup_free_
char *joined
= NULL
;
1254 if (asprintf(&x
, "LISTEN_PID="PID_FMT
, getpid()) < 0)
1256 our_env
[n_env
++] = x
;
1258 if (asprintf(&x
, "LISTEN_FDS=%u", n_fds
) < 0)
1260 our_env
[n_env
++] = x
;
1262 joined
= strv_join(fd_names
, ":");
1266 x
= strjoin("LISTEN_FDNAMES=", joined
, NULL
);
1269 our_env
[n_env
++] = x
;
1272 if (watchdog_usec
> 0) {
1273 if (asprintf(&x
, "WATCHDOG_PID="PID_FMT
, getpid()) < 0)
1275 our_env
[n_env
++] = x
;
1277 if (asprintf(&x
, "WATCHDOG_USEC="USEC_FMT
, watchdog_usec
) < 0)
1279 our_env
[n_env
++] = x
;
1283 x
= strappend("HOME=", home
);
1286 our_env
[n_env
++] = x
;
1290 x
= strappend("LOGNAME=", username
);
1293 our_env
[n_env
++] = x
;
1295 x
= strappend("USER=", username
);
1298 our_env
[n_env
++] = x
;
1302 x
= strappend("SHELL=", shell
);
1305 our_env
[n_env
++] = x
;
1308 if (is_terminal_input(c
->std_input
) ||
1309 c
->std_output
== EXEC_OUTPUT_TTY
||
1310 c
->std_error
== EXEC_OUTPUT_TTY
||
1313 x
= strdup(default_term_for_tty(tty_path(c
)));
1316 our_env
[n_env
++] = x
;
1319 our_env
[n_env
++] = NULL
;
1320 assert(n_env
<= 11);
1328 static bool exec_needs_mount_namespace(
1329 const ExecContext
*context
,
1330 const ExecParameters
*params
,
1331 ExecRuntime
*runtime
) {
1336 if (!strv_isempty(context
->read_write_dirs
) ||
1337 !strv_isempty(context
->read_only_dirs
) ||
1338 !strv_isempty(context
->inaccessible_dirs
))
1341 if (context
->mount_flags
!= 0)
1344 if (context
->private_tmp
&& runtime
&& (runtime
->tmp_dir
|| runtime
->var_tmp_dir
))
1347 if (params
->bus_endpoint_path
)
1350 if (context
->private_devices
||
1351 context
->protect_system
!= PROTECT_SYSTEM_NO
||
1352 context
->protect_home
!= PROTECT_HOME_NO
)
1358 static int close_remaining_fds(
1359 const ExecParameters
*params
,
1360 ExecRuntime
*runtime
,
1362 int *fds
, unsigned n_fds
) {
1364 unsigned n_dont_close
= 0;
1365 int dont_close
[n_fds
+ 7];
1369 if (params
->stdin_fd
>= 0)
1370 dont_close
[n_dont_close
++] = params
->stdin_fd
;
1371 if (params
->stdout_fd
>= 0)
1372 dont_close
[n_dont_close
++] = params
->stdout_fd
;
1373 if (params
->stderr_fd
>= 0)
1374 dont_close
[n_dont_close
++] = params
->stderr_fd
;
1377 dont_close
[n_dont_close
++] = socket_fd
;
1379 memcpy(dont_close
+ n_dont_close
, fds
, sizeof(int) * n_fds
);
1380 n_dont_close
+= n_fds
;
1383 if (params
->bus_endpoint_fd
>= 0)
1384 dont_close
[n_dont_close
++] = params
->bus_endpoint_fd
;
1387 if (runtime
->netns_storage_socket
[0] >= 0)
1388 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[0];
1389 if (runtime
->netns_storage_socket
[1] >= 0)
1390 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[1];
1393 return close_all_fds(dont_close
, n_dont_close
);
1396 static int exec_child(
1398 ExecCommand
*command
,
1399 const ExecContext
*context
,
1400 const ExecParameters
*params
,
1401 ExecRuntime
*runtime
,
1404 int *fds
, unsigned n_fds
,
1408 _cleanup_strv_free_
char **our_env
= NULL
, **pam_env
= NULL
, **final_env
= NULL
, **final_argv
= NULL
;
1409 _cleanup_free_
char *mac_selinux_context_net
= NULL
;
1410 const char *username
= NULL
, *home
= NULL
, *shell
= NULL
, *wd
;
1411 uid_t uid
= UID_INVALID
;
1412 gid_t gid
= GID_INVALID
;
1414 bool needs_mount_namespace
;
1420 assert(exit_status
);
1422 rename_process_from_path(command
->path
);
1424 /* We reset exactly these signals, since they are the
1425 * only ones we set to SIG_IGN in the main daemon. All
1426 * others we leave untouched because we set them to
1427 * SIG_DFL or a valid handler initially, both of which
1428 * will be demoted to SIG_DFL. */
1429 (void) default_signals(SIGNALS_CRASH_HANDLER
,
1430 SIGNALS_IGNORE
, -1);
1432 if (context
->ignore_sigpipe
)
1433 (void) ignore_signals(SIGPIPE
, -1);
1435 r
= reset_signal_mask();
1437 *exit_status
= EXIT_SIGNAL_MASK
;
1441 if (params
->idle_pipe
)
1442 do_idle_pipe_dance(params
->idle_pipe
);
1444 /* Close sockets very early to make sure we don't
1445 * block init reexecution because it cannot bind its
1450 r
= close_remaining_fds(params
, runtime
, socket_fd
, fds
, n_fds
);
1452 *exit_status
= EXIT_FDS
;
1456 if (!context
->same_pgrp
)
1458 *exit_status
= EXIT_SETSID
;
1462 exec_context_tty_reset(context
);
1464 if (params
->confirm_spawn
) {
1467 r
= ask_for_confirmation(&response
, argv
);
1468 if (r
== -ETIMEDOUT
)
1469 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1471 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r
));
1472 else if (response
== 's') {
1473 write_confirm_message("Skipping execution.\n");
1474 *exit_status
= EXIT_CONFIRM
;
1476 } else if (response
== 'n') {
1477 write_confirm_message("Failing execution.\n");
1483 if (context
->user
) {
1484 username
= context
->user
;
1485 r
= get_user_creds(&username
, &uid
, &gid
, &home
, &shell
);
1487 *exit_status
= EXIT_USER
;
1492 if (context
->group
) {
1493 const char *g
= context
->group
;
1495 r
= get_group_creds(&g
, &gid
);
1497 *exit_status
= EXIT_GROUP
;
1503 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1504 * must sure to drop O_NONBLOCK */
1506 (void) fd_nonblock(socket_fd
, false);
1508 r
= setup_input(context
, params
, socket_fd
);
1510 *exit_status
= EXIT_STDIN
;
1514 r
= setup_output(unit
, context
, params
, STDOUT_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1516 *exit_status
= EXIT_STDOUT
;
1520 r
= setup_output(unit
, context
, params
, STDERR_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1522 *exit_status
= EXIT_STDERR
;
1526 if (params
->cgroup_path
) {
1527 r
= cg_attach_everywhere(params
->cgroup_supported
, params
->cgroup_path
, 0, NULL
, NULL
);
1529 *exit_status
= EXIT_CGROUP
;
1534 if (context
->oom_score_adjust_set
) {
1535 char t
[DECIMAL_STR_MAX(context
->oom_score_adjust
)];
1537 /* When we can't make this change due to EPERM, then
1538 * let's silently skip over it. User namespaces
1539 * prohibit write access to this file, and we
1540 * shouldn't trip up over that. */
1542 sprintf(t
, "%i", context
->oom_score_adjust
);
1543 r
= write_string_file("/proc/self/oom_score_adj", t
, 0);
1544 if (r
== -EPERM
|| r
== -EACCES
) {
1546 log_unit_debug_errno(unit
, r
, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
1549 *exit_status
= EXIT_OOM_ADJUST
;
1554 if (context
->nice_set
)
1555 if (setpriority(PRIO_PROCESS
, 0, context
->nice
) < 0) {
1556 *exit_status
= EXIT_NICE
;
1560 if (context
->cpu_sched_set
) {
1561 struct sched_param param
= {
1562 .sched_priority
= context
->cpu_sched_priority
,
1565 r
= sched_setscheduler(0,
1566 context
->cpu_sched_policy
|
1567 (context
->cpu_sched_reset_on_fork
?
1568 SCHED_RESET_ON_FORK
: 0),
1571 *exit_status
= EXIT_SETSCHEDULER
;
1576 if (context
->cpuset
)
1577 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context
->cpuset_ncpus
), context
->cpuset
) < 0) {
1578 *exit_status
= EXIT_CPUAFFINITY
;
1582 if (context
->ioprio_set
)
1583 if (ioprio_set(IOPRIO_WHO_PROCESS
, 0, context
->ioprio
) < 0) {
1584 *exit_status
= EXIT_IOPRIO
;
1588 if (context
->timer_slack_nsec
!= NSEC_INFINITY
)
1589 if (prctl(PR_SET_TIMERSLACK
, context
->timer_slack_nsec
) < 0) {
1590 *exit_status
= EXIT_TIMERSLACK
;
1594 if (context
->personality
!= PERSONALITY_INVALID
)
1595 if (personality(context
->personality
) < 0) {
1596 *exit_status
= EXIT_PERSONALITY
;
1600 if (context
->utmp_id
)
1601 utmp_put_init_process(context
->utmp_id
, getpid(), getsid(0), context
->tty_path
,
1602 context
->utmp_mode
== EXEC_UTMP_INIT
? INIT_PROCESS
:
1603 context
->utmp_mode
== EXEC_UTMP_LOGIN
? LOGIN_PROCESS
:
1605 username
? "root" : context
->user
);
1607 if (context
->user
&& is_terminal_input(context
->std_input
)) {
1608 r
= chown_terminal(STDIN_FILENO
, uid
);
1610 *exit_status
= EXIT_STDIN
;
1615 if (params
->bus_endpoint_fd
>= 0 && context
->bus_endpoint
) {
1616 uid_t ep_uid
= (uid
== UID_INVALID
) ? 0 : uid
;
1618 r
= bus_kernel_set_endpoint_policy(params
->bus_endpoint_fd
, ep_uid
, context
->bus_endpoint
);
1620 *exit_status
= EXIT_BUS_ENDPOINT
;
1625 /* If delegation is enabled we'll pass ownership of the cgroup
1626 * (but only in systemd's own controller hierarchy!) to the
1627 * user of the new process. */
1628 if (params
->cgroup_path
&& context
->user
&& params
->cgroup_delegate
) {
1629 r
= cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0644, uid
, gid
);
1631 *exit_status
= EXIT_CGROUP
;
1636 r
= cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0755, uid
, gid
);
1638 *exit_status
= EXIT_CGROUP
;
1643 if (!strv_isempty(context
->runtime_directory
) && params
->runtime_prefix
) {
1646 STRV_FOREACH(rt
, context
->runtime_directory
) {
1647 _cleanup_free_
char *p
;
1649 p
= strjoin(params
->runtime_prefix
, "/", *rt
, NULL
);
1651 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1655 r
= mkdir_p_label(p
, context
->runtime_directory_mode
);
1657 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1661 r
= chmod_and_chown(p
, context
->runtime_directory_mode
, uid
, gid
);
1663 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1669 umask(context
->umask
);
1671 if (params
->apply_permissions
) {
1672 r
= enforce_groups(context
, username
, gid
);
1674 *exit_status
= EXIT_GROUP
;
1678 if (context
->smack_process_label
) {
1679 r
= mac_smack_apply_pid(0, context
->smack_process_label
);
1681 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1685 #ifdef SMACK_DEFAULT_PROCESS_LABEL
1687 _cleanup_free_
char *exec_label
= NULL
;
1689 r
= mac_smack_read(command
->path
, SMACK_ATTR_EXEC
, &exec_label
);
1690 if (r
< 0 && r
!= -ENODATA
&& r
!= -EOPNOTSUPP
) {
1691 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1695 r
= mac_smack_apply_pid(0, exec_label
? : SMACK_DEFAULT_PROCESS_LABEL
);
1697 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1704 if (context
->pam_name
&& username
) {
1705 r
= setup_pam(context
->pam_name
, username
, uid
, context
->tty_path
, &pam_env
, fds
, n_fds
);
1707 *exit_status
= EXIT_PAM
;
1714 if (context
->private_network
&& runtime
&& runtime
->netns_storage_socket
[0] >= 0) {
1715 r
= setup_netns(runtime
->netns_storage_socket
);
1717 *exit_status
= EXIT_NETWORK
;
1722 needs_mount_namespace
= exec_needs_mount_namespace(context
, params
, runtime
);
1724 if (needs_mount_namespace
) {
1725 char *tmp
= NULL
, *var
= NULL
;
1727 /* The runtime struct only contains the parent
1728 * of the private /tmp, which is
1729 * non-accessible to world users. Inside of it
1730 * there's a /tmp that is sticky, and that's
1731 * the one we want to use here. */
1733 if (context
->private_tmp
&& runtime
) {
1734 if (runtime
->tmp_dir
)
1735 tmp
= strjoina(runtime
->tmp_dir
, "/tmp");
1736 if (runtime
->var_tmp_dir
)
1737 var
= strjoina(runtime
->var_tmp_dir
, "/tmp");
1740 r
= setup_namespace(
1741 params
->apply_chroot
? context
->root_directory
: NULL
,
1742 context
->read_write_dirs
,
1743 context
->read_only_dirs
,
1744 context
->inaccessible_dirs
,
1747 params
->bus_endpoint_path
,
1748 context
->private_devices
,
1749 context
->protect_home
,
1750 context
->protect_system
,
1751 context
->mount_flags
);
1753 /* If we couldn't set up the namespace this is
1754 * probably due to a missing capability. In this case,
1755 * silently proceeed. */
1756 if (r
== -EPERM
|| r
== -EACCES
) {
1758 log_unit_debug_errno(unit
, r
, "Failed to set up namespace, assuming containerized execution, ignoring: %m");
1761 *exit_status
= EXIT_NAMESPACE
;
1766 if (context
->working_directory_home
)
1768 else if (context
->working_directory
)
1769 wd
= context
->working_directory
;
1773 if (params
->apply_chroot
) {
1774 if (!needs_mount_namespace
&& context
->root_directory
)
1775 if (chroot(context
->root_directory
) < 0) {
1776 *exit_status
= EXIT_CHROOT
;
1780 if (chdir(wd
) < 0 &&
1781 !context
->working_directory_missing_ok
) {
1782 *exit_status
= EXIT_CHDIR
;
1788 d
= strjoina(strempty(context
->root_directory
), "/", strempty(wd
));
1790 !context
->working_directory_missing_ok
) {
1791 *exit_status
= EXIT_CHDIR
;
1797 if (params
->apply_permissions
&& mac_selinux_use() && params
->selinux_context_net
&& socket_fd
>= 0) {
1798 r
= mac_selinux_get_child_mls_label(socket_fd
, command
->path
, context
->selinux_context
, &mac_selinux_context_net
);
1800 *exit_status
= EXIT_SELINUX_CONTEXT
;
1806 /* We repeat the fd closing here, to make sure that
1807 * nothing is leaked from the PAM modules. Note that
1808 * we are more aggressive this time since socket_fd
1809 * and the netns fds we don't need anymore. The custom
1810 * endpoint fd was needed to upload the policy and can
1811 * now be closed as well. */
1812 r
= close_all_fds(fds
, n_fds
);
1814 r
= shift_fds(fds
, n_fds
);
1816 r
= flags_fds(fds
, n_fds
, context
->non_blocking
);
1818 *exit_status
= EXIT_FDS
;
1822 if (params
->apply_permissions
) {
1824 for (i
= 0; i
< _RLIMIT_MAX
; i
++) {
1825 if (!context
->rlimit
[i
])
1828 if (setrlimit_closest(i
, context
->rlimit
[i
]) < 0) {
1829 *exit_status
= EXIT_LIMITS
;
1834 if (context
->capability_bounding_set_drop
) {
1835 r
= capability_bounding_set_drop(context
->capability_bounding_set_drop
, false);
1837 *exit_status
= EXIT_CAPABILITIES
;
1842 if (context
->user
) {
1843 r
= enforce_user(context
, uid
);
1845 *exit_status
= EXIT_USER
;
1850 /* PR_GET_SECUREBITS is not privileged, while
1851 * PR_SET_SECUREBITS is. So to suppress
1852 * potential EPERMs we'll try not to call
1853 * PR_SET_SECUREBITS unless necessary. */
1854 if (prctl(PR_GET_SECUREBITS
) != context
->secure_bits
)
1855 if (prctl(PR_SET_SECUREBITS
, context
->secure_bits
) < 0) {
1856 *exit_status
= EXIT_SECUREBITS
;
1860 if (context
->capabilities
)
1861 if (cap_set_proc(context
->capabilities
) < 0) {
1862 *exit_status
= EXIT_CAPABILITIES
;
1866 if (context
->no_new_privileges
)
1867 if (prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0) < 0) {
1868 *exit_status
= EXIT_NO_NEW_PRIVILEGES
;
1873 if (context
->address_families_whitelist
||
1874 !set_isempty(context
->address_families
)) {
1875 r
= apply_address_families(context
);
1877 *exit_status
= EXIT_ADDRESS_FAMILIES
;
1882 if (context
->syscall_whitelist
||
1883 !set_isempty(context
->syscall_filter
) ||
1884 !set_isempty(context
->syscall_archs
)) {
1885 r
= apply_seccomp(context
);
1887 *exit_status
= EXIT_SECCOMP
;
1894 if (mac_selinux_use()) {
1895 char *exec_context
= mac_selinux_context_net
?: context
->selinux_context
;
1898 r
= setexeccon(exec_context
);
1900 *exit_status
= EXIT_SELINUX_CONTEXT
;
1907 #ifdef HAVE_APPARMOR
1908 if (context
->apparmor_profile
&& mac_apparmor_use()) {
1909 r
= aa_change_onexec(context
->apparmor_profile
);
1910 if (r
< 0 && !context
->apparmor_profile_ignore
) {
1911 *exit_status
= EXIT_APPARMOR_PROFILE
;
1918 r
= build_environment(context
, n_fds
, params
->fd_names
, params
->watchdog_usec
, home
, username
, shell
, &our_env
);
1920 *exit_status
= EXIT_MEMORY
;
1924 final_env
= strv_env_merge(5,
1925 params
->environment
,
1927 context
->environment
,
1932 *exit_status
= EXIT_MEMORY
;
1936 final_argv
= replace_env_argv(argv
, final_env
);
1938 *exit_status
= EXIT_MEMORY
;
1942 final_env
= strv_env_clean(final_env
);
1944 if (_unlikely_(log_get_max_level() >= LOG_DEBUG
)) {
1945 _cleanup_free_
char *line
;
1947 line
= exec_command_line(final_argv
);
1950 log_struct(LOG_DEBUG
,
1952 "EXECUTABLE=%s", command
->path
,
1953 LOG_UNIT_MESSAGE(unit
, "Executing: %s", line
),
1959 execve(command
->path
, final_argv
, final_env
);
1960 *exit_status
= EXIT_EXEC
;
1964 int exec_spawn(Unit
*unit
,
1965 ExecCommand
*command
,
1966 const ExecContext
*context
,
1967 const ExecParameters
*params
,
1968 ExecRuntime
*runtime
,
1971 _cleanup_strv_free_
char **files_env
= NULL
;
1972 int *fds
= NULL
; unsigned n_fds
= 0;
1973 _cleanup_free_
char *line
= NULL
;
1983 assert(params
->fds
|| params
->n_fds
<= 0);
1985 if (context
->std_input
== EXEC_INPUT_SOCKET
||
1986 context
->std_output
== EXEC_OUTPUT_SOCKET
||
1987 context
->std_error
== EXEC_OUTPUT_SOCKET
) {
1989 if (params
->n_fds
!= 1) {
1990 log_unit_error(unit
, "Got more than one socket.");
1994 socket_fd
= params
->fds
[0];
1998 n_fds
= params
->n_fds
;
2001 r
= exec_context_load_environment(unit
, context
, &files_env
);
2003 return log_unit_error_errno(unit
, r
, "Failed to load environment files: %m");
2005 argv
= params
->argv
?: command
->argv
;
2006 line
= exec_command_line(argv
);
2010 log_struct(LOG_DEBUG
,
2012 LOG_UNIT_MESSAGE(unit
, "About to execute: %s", line
),
2013 "EXECUTABLE=%s", command
->path
,
2017 return log_unit_error_errno(unit
, r
, "Failed to fork: %m");
2022 r
= exec_child(unit
,
2034 log_struct_errno(LOG_ERR
, r
,
2035 LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED
),
2037 LOG_UNIT_MESSAGE(unit
, "Failed at step %s spawning %s: %m",
2038 exit_status_to_string(exit_status
, EXIT_STATUS_SYSTEMD
),
2040 "EXECUTABLE=%s", command
->path
,
2047 log_unit_debug(unit
, "Forked %s as "PID_FMT
, command
->path
, pid
);
2049 /* We add the new process to the cgroup both in the child (so
2050 * that we can be sure that no user code is ever executed
2051 * outside of the cgroup) and in the parent (so that we can be
2052 * sure that when we kill the cgroup the process will be
2054 if (params
->cgroup_path
)
2055 (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, pid
);
2057 exec_status_start(&command
->exec_status
, pid
);
2063 void exec_context_init(ExecContext
*c
) {
2067 c
->ioprio
= IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE
, 0);
2068 c
->cpu_sched_policy
= SCHED_OTHER
;
2069 c
->syslog_priority
= LOG_DAEMON
|LOG_INFO
;
2070 c
->syslog_level_prefix
= true;
2071 c
->ignore_sigpipe
= true;
2072 c
->timer_slack_nsec
= NSEC_INFINITY
;
2073 c
->personality
= PERSONALITY_INVALID
;
2074 c
->runtime_directory_mode
= 0755;
2077 void exec_context_done(ExecContext
*c
) {
2082 c
->environment
= strv_free(c
->environment
);
2083 c
->environment_files
= strv_free(c
->environment_files
);
2085 for (l
= 0; l
< ELEMENTSOF(c
->rlimit
); l
++)
2086 c
->rlimit
[l
] = mfree(c
->rlimit
[l
]);
2088 c
->working_directory
= mfree(c
->working_directory
);
2089 c
->root_directory
= mfree(c
->root_directory
);
2090 c
->tty_path
= mfree(c
->tty_path
);
2091 c
->syslog_identifier
= mfree(c
->syslog_identifier
);
2092 c
->user
= mfree(c
->user
);
2093 c
->group
= mfree(c
->group
);
2095 c
->supplementary_groups
= strv_free(c
->supplementary_groups
);
2097 c
->pam_name
= mfree(c
->pam_name
);
2099 if (c
->capabilities
) {
2100 cap_free(c
->capabilities
);
2101 c
->capabilities
= NULL
;
2104 c
->read_only_dirs
= strv_free(c
->read_only_dirs
);
2105 c
->read_write_dirs
= strv_free(c
->read_write_dirs
);
2106 c
->inaccessible_dirs
= strv_free(c
->inaccessible_dirs
);
2109 CPU_FREE(c
->cpuset
);
2111 c
->utmp_id
= mfree(c
->utmp_id
);
2112 c
->selinux_context
= mfree(c
->selinux_context
);
2113 c
->apparmor_profile
= mfree(c
->apparmor_profile
);
2115 c
->syscall_filter
= set_free(c
->syscall_filter
);
2116 c
->syscall_archs
= set_free(c
->syscall_archs
);
2117 c
->address_families
= set_free(c
->address_families
);
2119 c
->runtime_directory
= strv_free(c
->runtime_directory
);
2121 bus_endpoint_free(c
->bus_endpoint
);
2122 c
->bus_endpoint
= NULL
;
2125 int exec_context_destroy_runtime_directory(ExecContext
*c
, const char *runtime_prefix
) {
2130 if (!runtime_prefix
)
2133 STRV_FOREACH(i
, c
->runtime_directory
) {
2134 _cleanup_free_
char *p
;
2136 p
= strjoin(runtime_prefix
, "/", *i
, NULL
);
2140 /* We execute this synchronously, since we need to be
2141 * sure this is gone when we start the service
2143 (void) rm_rf(p
, REMOVE_ROOT
);
2149 void exec_command_done(ExecCommand
*c
) {
2152 c
->path
= mfree(c
->path
);
2154 c
->argv
= strv_free(c
->argv
);
2157 void exec_command_done_array(ExecCommand
*c
, unsigned n
) {
2160 for (i
= 0; i
< n
; i
++)
2161 exec_command_done(c
+i
);
2164 ExecCommand
* exec_command_free_list(ExecCommand
*c
) {
2168 LIST_REMOVE(command
, c
, i
);
2169 exec_command_done(i
);
2176 void exec_command_free_array(ExecCommand
**c
, unsigned n
) {
2179 for (i
= 0; i
< n
; i
++)
2180 c
[i
] = exec_command_free_list(c
[i
]);
2183 typedef struct InvalidEnvInfo
{
2188 static void invalid_env(const char *p
, void *userdata
) {
2189 InvalidEnvInfo
*info
= userdata
;
2191 log_unit_error(info
->unit
, "Ignoring invalid environment assignment '%s': %s", p
, info
->path
);
2194 int exec_context_load_environment(Unit
*unit
, const ExecContext
*c
, char ***l
) {
2195 char **i
, **r
= NULL
;
2200 STRV_FOREACH(i
, c
->environment_files
) {
2203 bool ignore
= false;
2205 _cleanup_globfree_ glob_t pglob
= {};
2215 if (!path_is_absolute(fn
)) {
2223 /* Filename supports globbing, take all matching files */
2225 if (glob(fn
, 0, NULL
, &pglob
) != 0) {
2230 return errno
? -errno
: -EINVAL
;
2232 count
= pglob
.gl_pathc
;
2240 for (n
= 0; n
< count
; n
++) {
2241 k
= load_env_file(NULL
, pglob
.gl_pathv
[n
], NULL
, &p
);
2249 /* Log invalid environment variables with filename */
2251 InvalidEnvInfo info
= {
2253 .path
= pglob
.gl_pathv
[n
]
2256 p
= strv_env_clean_with_callback(p
, invalid_env
, &info
);
2264 m
= strv_env_merge(2, r
, p
);
2280 static bool tty_may_match_dev_console(const char *tty
) {
2281 _cleanup_free_
char *active
= NULL
;
2284 if (startswith(tty
, "/dev/"))
2287 /* trivial identity? */
2288 if (streq(tty
, "console"))
2291 console
= resolve_dev_console(&active
);
2292 /* if we could not resolve, assume it may */
2296 /* "tty0" means the active VC, so it may be the same sometimes */
2297 return streq(console
, tty
) || (streq(console
, "tty0") && tty_is_vc(tty
));
2300 bool exec_context_may_touch_console(ExecContext
*ec
) {
2301 return (ec
->tty_reset
|| ec
->tty_vhangup
|| ec
->tty_vt_disallocate
||
2302 is_terminal_input(ec
->std_input
) ||
2303 is_terminal_output(ec
->std_output
) ||
2304 is_terminal_output(ec
->std_error
)) &&
2305 tty_may_match_dev_console(tty_path(ec
));
2308 static void strv_fprintf(FILE *f
, char **l
) {
2314 fprintf(f
, " %s", *g
);
2317 void exec_context_dump(ExecContext
*c
, FILE* f
, const char *prefix
) {
2324 prefix
= strempty(prefix
);
2328 "%sWorkingDirectory: %s\n"
2329 "%sRootDirectory: %s\n"
2330 "%sNonBlocking: %s\n"
2331 "%sPrivateTmp: %s\n"
2332 "%sPrivateNetwork: %s\n"
2333 "%sPrivateDevices: %s\n"
2334 "%sProtectHome: %s\n"
2335 "%sProtectSystem: %s\n"
2336 "%sIgnoreSIGPIPE: %s\n",
2338 prefix
, c
->working_directory
? c
->working_directory
: "/",
2339 prefix
, c
->root_directory
? c
->root_directory
: "/",
2340 prefix
, yes_no(c
->non_blocking
),
2341 prefix
, yes_no(c
->private_tmp
),
2342 prefix
, yes_no(c
->private_network
),
2343 prefix
, yes_no(c
->private_devices
),
2344 prefix
, protect_home_to_string(c
->protect_home
),
2345 prefix
, protect_system_to_string(c
->protect_system
),
2346 prefix
, yes_no(c
->ignore_sigpipe
));
2348 STRV_FOREACH(e
, c
->environment
)
2349 fprintf(f
, "%sEnvironment: %s\n", prefix
, *e
);
2351 STRV_FOREACH(e
, c
->environment_files
)
2352 fprintf(f
, "%sEnvironmentFile: %s\n", prefix
, *e
);
2354 fprintf(f
, "%sRuntimeDirectoryMode: %04o\n", prefix
, c
->runtime_directory_mode
);
2356 STRV_FOREACH(d
, c
->runtime_directory
)
2357 fprintf(f
, "%sRuntimeDirectory: %s\n", prefix
, *d
);
2364 if (c
->oom_score_adjust_set
)
2366 "%sOOMScoreAdjust: %i\n",
2367 prefix
, c
->oom_score_adjust
);
2369 for (i
= 0; i
< RLIM_NLIMITS
; i
++)
2371 fprintf(f
, "%s%s: "RLIM_FMT
"\n",
2372 prefix
, rlimit_to_string(i
), c
->rlimit
[i
]->rlim_max
);
2374 if (c
->ioprio_set
) {
2375 _cleanup_free_
char *class_str
= NULL
;
2377 ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c
->ioprio
), &class_str
);
2379 "%sIOSchedulingClass: %s\n"
2380 "%sIOPriority: %i\n",
2381 prefix
, strna(class_str
),
2382 prefix
, (int) IOPRIO_PRIO_DATA(c
->ioprio
));
2385 if (c
->cpu_sched_set
) {
2386 _cleanup_free_
char *policy_str
= NULL
;
2388 sched_policy_to_string_alloc(c
->cpu_sched_policy
, &policy_str
);
2390 "%sCPUSchedulingPolicy: %s\n"
2391 "%sCPUSchedulingPriority: %i\n"
2392 "%sCPUSchedulingResetOnFork: %s\n",
2393 prefix
, strna(policy_str
),
2394 prefix
, c
->cpu_sched_priority
,
2395 prefix
, yes_no(c
->cpu_sched_reset_on_fork
));
2399 fprintf(f
, "%sCPUAffinity:", prefix
);
2400 for (i
= 0; i
< c
->cpuset_ncpus
; i
++)
2401 if (CPU_ISSET_S(i
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
), c
->cpuset
))
2402 fprintf(f
, " %u", i
);
2406 if (c
->timer_slack_nsec
!= NSEC_INFINITY
)
2407 fprintf(f
, "%sTimerSlackNSec: "NSEC_FMT
"\n", prefix
, c
->timer_slack_nsec
);
2410 "%sStandardInput: %s\n"
2411 "%sStandardOutput: %s\n"
2412 "%sStandardError: %s\n",
2413 prefix
, exec_input_to_string(c
->std_input
),
2414 prefix
, exec_output_to_string(c
->std_output
),
2415 prefix
, exec_output_to_string(c
->std_error
));
2421 "%sTTYVHangup: %s\n"
2422 "%sTTYVTDisallocate: %s\n",
2423 prefix
, c
->tty_path
,
2424 prefix
, yes_no(c
->tty_reset
),
2425 prefix
, yes_no(c
->tty_vhangup
),
2426 prefix
, yes_no(c
->tty_vt_disallocate
));
2428 if (c
->std_output
== EXEC_OUTPUT_SYSLOG
||
2429 c
->std_output
== EXEC_OUTPUT_KMSG
||
2430 c
->std_output
== EXEC_OUTPUT_JOURNAL
||
2431 c
->std_output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2432 c
->std_output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2433 c
->std_output
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
||
2434 c
->std_error
== EXEC_OUTPUT_SYSLOG
||
2435 c
->std_error
== EXEC_OUTPUT_KMSG
||
2436 c
->std_error
== EXEC_OUTPUT_JOURNAL
||
2437 c
->std_error
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2438 c
->std_error
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2439 c
->std_error
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
) {
2441 _cleanup_free_
char *fac_str
= NULL
, *lvl_str
= NULL
;
2443 log_facility_unshifted_to_string_alloc(c
->syslog_priority
>> 3, &fac_str
);
2444 log_level_to_string_alloc(LOG_PRI(c
->syslog_priority
), &lvl_str
);
2447 "%sSyslogFacility: %s\n"
2448 "%sSyslogLevel: %s\n",
2449 prefix
, strna(fac_str
),
2450 prefix
, strna(lvl_str
));
2453 if (c
->capabilities
) {
2454 _cleanup_cap_free_charp_
char *t
;
2456 t
= cap_to_text(c
->capabilities
, NULL
);
2458 fprintf(f
, "%sCapabilities: %s\n", prefix
, t
);
2462 fprintf(f
, "%sSecure Bits:%s%s%s%s%s%s\n",
2464 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS
) ? " keep-caps" : "",
2465 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS_LOCKED
) ? " keep-caps-locked" : "",
2466 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP
) ? " no-setuid-fixup" : "",
2467 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP_LOCKED
) ? " no-setuid-fixup-locked" : "",
2468 (c
->secure_bits
& 1<<SECURE_NOROOT
) ? " noroot" : "",
2469 (c
->secure_bits
& 1<<SECURE_NOROOT_LOCKED
) ? "noroot-locked" : "");
2471 if (c
->capability_bounding_set_drop
) {
2473 fprintf(f
, "%sCapabilityBoundingSet:", prefix
);
2475 for (l
= 0; l
<= cap_last_cap(); l
++)
2476 if (!(c
->capability_bounding_set_drop
& ((uint64_t) 1ULL << (uint64_t) l
)))
2477 fprintf(f
, " %s", strna(capability_to_name(l
)));
2483 fprintf(f
, "%sUser: %s\n", prefix
, c
->user
);
2485 fprintf(f
, "%sGroup: %s\n", prefix
, c
->group
);
2487 if (strv_length(c
->supplementary_groups
) > 0) {
2488 fprintf(f
, "%sSupplementaryGroups:", prefix
);
2489 strv_fprintf(f
, c
->supplementary_groups
);
2494 fprintf(f
, "%sPAMName: %s\n", prefix
, c
->pam_name
);
2496 if (strv_length(c
->read_write_dirs
) > 0) {
2497 fprintf(f
, "%sReadWriteDirs:", prefix
);
2498 strv_fprintf(f
, c
->read_write_dirs
);
2502 if (strv_length(c
->read_only_dirs
) > 0) {
2503 fprintf(f
, "%sReadOnlyDirs:", prefix
);
2504 strv_fprintf(f
, c
->read_only_dirs
);
2508 if (strv_length(c
->inaccessible_dirs
) > 0) {
2509 fprintf(f
, "%sInaccessibleDirs:", prefix
);
2510 strv_fprintf(f
, c
->inaccessible_dirs
);
2516 "%sUtmpIdentifier: %s\n",
2517 prefix
, c
->utmp_id
);
2519 if (c
->selinux_context
)
2521 "%sSELinuxContext: %s%s\n",
2522 prefix
, c
->selinux_context_ignore
? "-" : "", c
->selinux_context
);
2524 if (c
->personality
!= PERSONALITY_INVALID
)
2526 "%sPersonality: %s\n",
2527 prefix
, strna(personality_to_string(c
->personality
)));
2529 if (c
->syscall_filter
) {
2537 "%sSystemCallFilter: ",
2540 if (!c
->syscall_whitelist
)
2544 SET_FOREACH(id
, c
->syscall_filter
, j
) {
2545 _cleanup_free_
char *name
= NULL
;
2552 name
= seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE
, PTR_TO_INT(id
) - 1);
2553 fputs(strna(name
), f
);
2560 if (c
->syscall_archs
) {
2567 "%sSystemCallArchitectures:",
2571 SET_FOREACH(id
, c
->syscall_archs
, j
)
2572 fprintf(f
, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id
) - 1)));
2577 if (c
->syscall_errno
!= 0)
2579 "%sSystemCallErrorNumber: %s\n",
2580 prefix
, strna(errno_to_name(c
->syscall_errno
)));
2582 if (c
->apparmor_profile
)
2584 "%sAppArmorProfile: %s%s\n",
2585 prefix
, c
->apparmor_profile_ignore
? "-" : "", c
->apparmor_profile
);
2588 bool exec_context_maintains_privileges(ExecContext
*c
) {
2591 /* Returns true if the process forked off would run run under
2592 * an unchanged UID or as root. */
2597 if (streq(c
->user
, "root") || streq(c
->user
, "0"))
2603 void exec_status_start(ExecStatus
*s
, pid_t pid
) {
2608 dual_timestamp_get(&s
->start_timestamp
);
2611 void exec_status_exit(ExecStatus
*s
, ExecContext
*context
, pid_t pid
, int code
, int status
) {
2614 if (s
->pid
&& s
->pid
!= pid
)
2618 dual_timestamp_get(&s
->exit_timestamp
);
2624 if (context
->utmp_id
)
2625 utmp_put_dead_process(context
->utmp_id
, pid
, code
, status
);
2627 exec_context_tty_reset(context
);
2631 void exec_status_dump(ExecStatus
*s
, FILE *f
, const char *prefix
) {
2632 char buf
[FORMAT_TIMESTAMP_MAX
];
2640 prefix
= strempty(prefix
);
2643 "%sPID: "PID_FMT
"\n",
2646 if (s
->start_timestamp
.realtime
> 0)
2648 "%sStart Timestamp: %s\n",
2649 prefix
, format_timestamp(buf
, sizeof(buf
), s
->start_timestamp
.realtime
));
2651 if (s
->exit_timestamp
.realtime
> 0)
2653 "%sExit Timestamp: %s\n"
2655 "%sExit Status: %i\n",
2656 prefix
, format_timestamp(buf
, sizeof(buf
), s
->exit_timestamp
.realtime
),
2657 prefix
, sigchld_code_to_string(s
->code
),
2661 char *exec_command_line(char **argv
) {
2669 STRV_FOREACH(a
, argv
)
2672 if (!(n
= new(char, k
)))
2676 STRV_FOREACH(a
, argv
) {
2683 if (strpbrk(*a
, WHITESPACE
)) {
2694 /* FIXME: this doesn't really handle arguments that have
2695 * spaces and ticks in them */
2700 void exec_command_dump(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2701 _cleanup_free_
char *cmd
= NULL
;
2702 const char *prefix2
;
2707 prefix
= strempty(prefix
);
2708 prefix2
= strjoina(prefix
, "\t");
2710 cmd
= exec_command_line(c
->argv
);
2712 "%sCommand Line: %s\n",
2713 prefix
, cmd
? cmd
: strerror(ENOMEM
));
2715 exec_status_dump(&c
->exec_status
, f
, prefix2
);
2718 void exec_command_dump_list(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2721 prefix
= strempty(prefix
);
2723 LIST_FOREACH(command
, c
, c
)
2724 exec_command_dump(c
, f
, prefix
);
2727 void exec_command_append_list(ExecCommand
**l
, ExecCommand
*e
) {
2734 /* It's kind of important, that we keep the order here */
2735 LIST_FIND_TAIL(command
, *l
, end
);
2736 LIST_INSERT_AFTER(command
, *l
, end
, e
);
2741 int exec_command_set(ExecCommand
*c
, const char *path
, ...) {
2749 l
= strv_new_ap(path
, ap
);
2770 int exec_command_append(ExecCommand
*c
, const char *path
, ...) {
2771 _cleanup_strv_free_
char **l
= NULL
;
2779 l
= strv_new_ap(path
, ap
);
2785 r
= strv_extend_strv(&c
->argv
, l
, false);
2793 static int exec_runtime_allocate(ExecRuntime
**rt
) {
2798 *rt
= new0(ExecRuntime
, 1);
2803 (*rt
)->netns_storage_socket
[0] = (*rt
)->netns_storage_socket
[1] = -1;
2808 int exec_runtime_make(ExecRuntime
**rt
, ExecContext
*c
, const char *id
) {
2818 if (!c
->private_network
&& !c
->private_tmp
)
2821 r
= exec_runtime_allocate(rt
);
2825 if (c
->private_network
&& (*rt
)->netns_storage_socket
[0] < 0) {
2826 if (socketpair(AF_UNIX
, SOCK_DGRAM
, 0, (*rt
)->netns_storage_socket
) < 0)
2830 if (c
->private_tmp
&& !(*rt
)->tmp_dir
) {
2831 r
= setup_tmp_dirs(id
, &(*rt
)->tmp_dir
, &(*rt
)->var_tmp_dir
);
2839 ExecRuntime
*exec_runtime_ref(ExecRuntime
*r
) {
2841 assert(r
->n_ref
> 0);
2847 ExecRuntime
*exec_runtime_unref(ExecRuntime
*r
) {
2852 assert(r
->n_ref
> 0);
2859 free(r
->var_tmp_dir
);
2860 safe_close_pair(r
->netns_storage_socket
);
2866 int exec_runtime_serialize(Unit
*u
, ExecRuntime
*rt
, FILE *f
, FDSet
*fds
) {
2875 unit_serialize_item(u
, f
, "tmp-dir", rt
->tmp_dir
);
2877 if (rt
->var_tmp_dir
)
2878 unit_serialize_item(u
, f
, "var-tmp-dir", rt
->var_tmp_dir
);
2880 if (rt
->netns_storage_socket
[0] >= 0) {
2883 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[0]);
2887 unit_serialize_item_format(u
, f
, "netns-socket-0", "%i", copy
);
2890 if (rt
->netns_storage_socket
[1] >= 0) {
2893 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[1]);
2897 unit_serialize_item_format(u
, f
, "netns-socket-1", "%i", copy
);
2903 int exec_runtime_deserialize_item(Unit
*u
, ExecRuntime
**rt
, const char *key
, const char *value
, FDSet
*fds
) {
2910 if (streq(key
, "tmp-dir")) {
2913 r
= exec_runtime_allocate(rt
);
2917 copy
= strdup(value
);
2921 free((*rt
)->tmp_dir
);
2922 (*rt
)->tmp_dir
= copy
;
2924 } else if (streq(key
, "var-tmp-dir")) {
2927 r
= exec_runtime_allocate(rt
);
2931 copy
= strdup(value
);
2935 free((*rt
)->var_tmp_dir
);
2936 (*rt
)->var_tmp_dir
= copy
;
2938 } else if (streq(key
, "netns-socket-0")) {
2941 r
= exec_runtime_allocate(rt
);
2945 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
2946 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
2948 safe_close((*rt
)->netns_storage_socket
[0]);
2949 (*rt
)->netns_storage_socket
[0] = fdset_remove(fds
, fd
);
2951 } else if (streq(key
, "netns-socket-1")) {
2954 r
= exec_runtime_allocate(rt
);
2958 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
2959 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
2961 safe_close((*rt
)->netns_storage_socket
[1]);
2962 (*rt
)->netns_storage_socket
[1] = fdset_remove(fds
, fd
);
2970 static void *remove_tmpdir_thread(void *p
) {
2971 _cleanup_free_
char *path
= p
;
2973 (void) rm_rf(path
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
2977 void exec_runtime_destroy(ExecRuntime
*rt
) {
2983 /* If there are multiple users of this, let's leave the stuff around */
2988 log_debug("Spawning thread to nuke %s", rt
->tmp_dir
);
2990 r
= asynchronous_job(remove_tmpdir_thread
, rt
->tmp_dir
);
2992 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->tmp_dir
);
2999 if (rt
->var_tmp_dir
) {
3000 log_debug("Spawning thread to nuke %s", rt
->var_tmp_dir
);
3002 r
= asynchronous_job(remove_tmpdir_thread
, rt
->var_tmp_dir
);
3004 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->var_tmp_dir
);
3005 free(rt
->var_tmp_dir
);
3008 rt
->var_tmp_dir
= NULL
;
3011 safe_close_pair(rt
->netns_storage_socket
);
3014 static const char* const exec_input_table
[_EXEC_INPUT_MAX
] = {
3015 [EXEC_INPUT_NULL
] = "null",
3016 [EXEC_INPUT_TTY
] = "tty",
3017 [EXEC_INPUT_TTY_FORCE
] = "tty-force",
3018 [EXEC_INPUT_TTY_FAIL
] = "tty-fail",
3019 [EXEC_INPUT_SOCKET
] = "socket"
3022 DEFINE_STRING_TABLE_LOOKUP(exec_input
, ExecInput
);
3024 static const char* const exec_output_table
[_EXEC_OUTPUT_MAX
] = {
3025 [EXEC_OUTPUT_INHERIT
] = "inherit",
3026 [EXEC_OUTPUT_NULL
] = "null",
3027 [EXEC_OUTPUT_TTY
] = "tty",
3028 [EXEC_OUTPUT_SYSLOG
] = "syslog",
3029 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE
] = "syslog+console",
3030 [EXEC_OUTPUT_KMSG
] = "kmsg",
3031 [EXEC_OUTPUT_KMSG_AND_CONSOLE
] = "kmsg+console",
3032 [EXEC_OUTPUT_JOURNAL
] = "journal",
3033 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE
] = "journal+console",
3034 [EXEC_OUTPUT_SOCKET
] = "socket"
3037 DEFINE_STRING_TABLE_LOOKUP(exec_output
, ExecOutput
);
3039 static const char* const exec_utmp_mode_table
[_EXEC_UTMP_MODE_MAX
] = {
3040 [EXEC_UTMP_INIT
] = "init",
3041 [EXEC_UTMP_LOGIN
] = "login",
3042 [EXEC_UTMP_USER
] = "user",
3045 DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode
, ExecUtmpMode
);