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 "parse-util.h"
80 #include "path-util.h"
81 #include "process-util.h"
84 #include "seccomp-util.h"
86 #include "securebits.h"
87 #include "selinux-util.h"
88 #include "signal-util.h"
89 #include "smack-util.h"
90 #include "string-util.h"
92 #include "terminal-util.h"
94 #include "user-util.h"
96 #include "utmp-wtmp.h"
98 #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
99 #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
101 /* This assumes there is a 'tty' group */
102 #define TTY_MODE 0620
104 #define SNDBUF_SIZE (8*1024*1024)
106 static int shift_fds(int fds
[], unsigned n_fds
) {
107 int start
, restart_from
;
112 /* Modifies the fds array! (sorts it) */
122 for (i
= start
; i
< (int) n_fds
; i
++) {
125 /* Already at right index? */
129 nfd
= fcntl(fds
[i
], F_DUPFD
, i
+ 3);
136 /* Hmm, the fd we wanted isn't free? Then
137 * let's remember that and try again from here */
138 if (nfd
!= i
+3 && restart_from
< 0)
142 if (restart_from
< 0)
145 start
= restart_from
;
151 static int flags_fds(const int fds
[], unsigned n_fds
, bool nonblock
) {
160 /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
162 for (i
= 0; i
< n_fds
; i
++) {
164 r
= fd_nonblock(fds
[i
], nonblock
);
168 /* We unconditionally drop FD_CLOEXEC from the fds,
169 * since after all we want to pass these fds to our
172 r
= fd_cloexec(fds
[i
], false);
180 _pure_
static const char *tty_path(const ExecContext
*context
) {
183 if (context
->tty_path
)
184 return context
->tty_path
;
186 return "/dev/console";
189 static void exec_context_tty_reset(const ExecContext
*context
) {
192 if (context
->tty_vhangup
)
193 terminal_vhangup(tty_path(context
));
195 if (context
->tty_reset
)
196 reset_terminal(tty_path(context
));
198 if (context
->tty_vt_disallocate
&& context
->tty_path
)
199 vt_disallocate(context
->tty_path
);
202 static bool is_terminal_output(ExecOutput o
) {
204 o
== EXEC_OUTPUT_TTY
||
205 o
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
206 o
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
207 o
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
;
210 static int open_null_as(int flags
, int nfd
) {
215 fd
= open("/dev/null", flags
|O_NOCTTY
);
220 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
228 static int connect_journal_socket(int fd
, uid_t uid
, gid_t gid
) {
229 union sockaddr_union sa
= {
230 .un
.sun_family
= AF_UNIX
,
231 .un
.sun_path
= "/run/systemd/journal/stdout",
233 uid_t olduid
= UID_INVALID
;
234 gid_t oldgid
= GID_INVALID
;
237 if (gid
!= GID_INVALID
) {
245 if (uid
!= UID_INVALID
) {
255 r
= connect(fd
, &sa
.sa
, offsetof(struct sockaddr_un
, sun_path
) + strlen(sa
.un
.sun_path
));
259 /* If we fail to restore the uid or gid, things will likely
260 fail later on. This should only happen if an LSM interferes. */
262 if (uid
!= UID_INVALID
)
263 (void) seteuid(olduid
);
266 if (gid
!= GID_INVALID
)
267 (void) setegid(oldgid
);
272 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
) {
276 assert(output
< _EXEC_OUTPUT_MAX
);
280 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
284 r
= connect_journal_socket(fd
, uid
, gid
);
288 if (shutdown(fd
, SHUT_RD
) < 0) {
293 fd_inc_sndbuf(fd
, SNDBUF_SIZE
);
303 context
->syslog_identifier
? context
->syslog_identifier
: ident
,
305 context
->syslog_priority
,
306 !!context
->syslog_level_prefix
,
307 output
== EXEC_OUTPUT_SYSLOG
|| output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
,
308 output
== EXEC_OUTPUT_KMSG
|| output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
,
309 is_terminal_output(output
));
312 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
319 static int open_terminal_as(const char *path
, mode_t mode
, int nfd
) {
325 fd
= open_terminal(path
, mode
| O_NOCTTY
);
330 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
338 static bool is_terminal_input(ExecInput i
) {
340 i
== EXEC_INPUT_TTY
||
341 i
== EXEC_INPUT_TTY_FORCE
||
342 i
== EXEC_INPUT_TTY_FAIL
;
345 static int fixup_input(ExecInput std_input
, int socket_fd
, bool apply_tty_stdin
) {
347 if (is_terminal_input(std_input
) && !apply_tty_stdin
)
348 return EXEC_INPUT_NULL
;
350 if (std_input
== EXEC_INPUT_SOCKET
&& socket_fd
< 0)
351 return EXEC_INPUT_NULL
;
356 static int fixup_output(ExecOutput std_output
, int socket_fd
) {
358 if (std_output
== EXEC_OUTPUT_SOCKET
&& socket_fd
< 0)
359 return EXEC_OUTPUT_INHERIT
;
364 static int setup_input(
365 const ExecContext
*context
,
366 const ExecParameters
*params
,
374 if (params
->stdin_fd
>= 0) {
375 if (dup2(params
->stdin_fd
, STDIN_FILENO
) < 0)
378 /* Try to make this the controlling tty, if it is a tty, and reset it */
379 (void) ioctl(STDIN_FILENO
, TIOCSCTTY
, context
->std_input
== EXEC_INPUT_TTY_FORCE
);
380 (void) reset_terminal_fd(STDIN_FILENO
, true);
385 i
= fixup_input(context
->std_input
, socket_fd
, params
->apply_tty_stdin
);
389 case EXEC_INPUT_NULL
:
390 return open_null_as(O_RDONLY
, STDIN_FILENO
);
393 case EXEC_INPUT_TTY_FORCE
:
394 case EXEC_INPUT_TTY_FAIL
: {
397 fd
= acquire_terminal(tty_path(context
),
398 i
== EXEC_INPUT_TTY_FAIL
,
399 i
== EXEC_INPUT_TTY_FORCE
,
405 if (fd
!= STDIN_FILENO
) {
406 r
= dup2(fd
, STDIN_FILENO
) < 0 ? -errno
: STDIN_FILENO
;
414 case EXEC_INPUT_SOCKET
:
415 return dup2(socket_fd
, STDIN_FILENO
) < 0 ? -errno
: STDIN_FILENO
;
418 assert_not_reached("Unknown input type");
422 static int setup_output(
424 const ExecContext
*context
,
425 const ExecParameters
*params
,
429 uid_t uid
, gid_t gid
) {
440 if (fileno
== STDOUT_FILENO
&& params
->stdout_fd
>= 0) {
442 if (dup2(params
->stdout_fd
, STDOUT_FILENO
) < 0)
445 return STDOUT_FILENO
;
448 if (fileno
== STDERR_FILENO
&& params
->stderr_fd
>= 0) {
449 if (dup2(params
->stderr_fd
, STDERR_FILENO
) < 0)
452 return STDERR_FILENO
;
455 i
= fixup_input(context
->std_input
, socket_fd
, params
->apply_tty_stdin
);
456 o
= fixup_output(context
->std_output
, socket_fd
);
458 if (fileno
== STDERR_FILENO
) {
460 e
= fixup_output(context
->std_error
, socket_fd
);
462 /* This expects the input and output are already set up */
464 /* Don't change the stderr file descriptor if we inherit all
465 * the way and are not on a tty */
466 if (e
== EXEC_OUTPUT_INHERIT
&&
467 o
== EXEC_OUTPUT_INHERIT
&&
468 i
== EXEC_INPUT_NULL
&&
469 !is_terminal_input(context
->std_input
) &&
473 /* Duplicate from stdout if possible */
474 if (e
== o
|| e
== EXEC_OUTPUT_INHERIT
)
475 return dup2(STDOUT_FILENO
, fileno
) < 0 ? -errno
: fileno
;
479 } else if (o
== EXEC_OUTPUT_INHERIT
) {
480 /* If input got downgraded, inherit the original value */
481 if (i
== EXEC_INPUT_NULL
&& is_terminal_input(context
->std_input
))
482 return open_terminal_as(tty_path(context
), O_WRONLY
, fileno
);
484 /* If the input is connected to anything that's not a /dev/null, inherit that... */
485 if (i
!= EXEC_INPUT_NULL
)
486 return dup2(STDIN_FILENO
, fileno
) < 0 ? -errno
: fileno
;
488 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
492 /* We need to open /dev/null here anew, to get the right access mode. */
493 return open_null_as(O_WRONLY
, fileno
);
498 case EXEC_OUTPUT_NULL
:
499 return open_null_as(O_WRONLY
, fileno
);
501 case EXEC_OUTPUT_TTY
:
502 if (is_terminal_input(i
))
503 return dup2(STDIN_FILENO
, fileno
) < 0 ? -errno
: fileno
;
505 /* We don't reset the terminal if this is just about output */
506 return open_terminal_as(tty_path(context
), O_WRONLY
, fileno
);
508 case EXEC_OUTPUT_SYSLOG
:
509 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE
:
510 case EXEC_OUTPUT_KMSG
:
511 case EXEC_OUTPUT_KMSG_AND_CONSOLE
:
512 case EXEC_OUTPUT_JOURNAL
:
513 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE
:
514 r
= connect_logger_as(context
, o
, ident
, unit
->id
, fileno
, uid
, gid
);
516 log_unit_error_errno(unit
, r
, "Failed to connect %s to the journal socket, ignoring: %m", fileno
== STDOUT_FILENO
? "stdout" : "stderr");
517 r
= open_null_as(O_WRONLY
, fileno
);
521 case EXEC_OUTPUT_SOCKET
:
522 assert(socket_fd
>= 0);
523 return dup2(socket_fd
, fileno
) < 0 ? -errno
: fileno
;
526 assert_not_reached("Unknown error type");
530 static int chown_terminal(int fd
, uid_t uid
) {
535 /* This might fail. What matters are the results. */
536 (void) fchown(fd
, uid
, -1);
537 (void) fchmod(fd
, TTY_MODE
);
539 if (fstat(fd
, &st
) < 0)
542 if (st
.st_uid
!= uid
|| (st
.st_mode
& 0777) != TTY_MODE
)
548 static int setup_confirm_stdio(int *_saved_stdin
, int *_saved_stdout
) {
549 _cleanup_close_
int fd
= -1, saved_stdin
= -1, saved_stdout
= -1;
552 assert(_saved_stdin
);
553 assert(_saved_stdout
);
555 saved_stdin
= fcntl(STDIN_FILENO
, F_DUPFD
, 3);
559 saved_stdout
= fcntl(STDOUT_FILENO
, F_DUPFD
, 3);
560 if (saved_stdout
< 0)
563 fd
= acquire_terminal(
568 DEFAULT_CONFIRM_USEC
);
572 r
= chown_terminal(fd
, getuid());
576 r
= reset_terminal_fd(fd
, true);
580 if (dup2(fd
, STDIN_FILENO
) < 0)
583 if (dup2(fd
, STDOUT_FILENO
) < 0)
590 *_saved_stdin
= saved_stdin
;
591 *_saved_stdout
= saved_stdout
;
593 saved_stdin
= saved_stdout
= -1;
598 _printf_(1, 2) static int write_confirm_message(const char *format
, ...) {
599 _cleanup_close_
int fd
= -1;
604 fd
= open_terminal("/dev/console", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
608 va_start(ap
, format
);
609 vdprintf(fd
, format
, ap
);
615 static int restore_confirm_stdio(int *saved_stdin
, int *saved_stdout
) {
619 assert(saved_stdout
);
623 if (*saved_stdin
>= 0)
624 if (dup2(*saved_stdin
, STDIN_FILENO
) < 0)
627 if (*saved_stdout
>= 0)
628 if (dup2(*saved_stdout
, STDOUT_FILENO
) < 0)
631 *saved_stdin
= safe_close(*saved_stdin
);
632 *saved_stdout
= safe_close(*saved_stdout
);
637 static int ask_for_confirmation(char *response
, char **argv
) {
638 int saved_stdout
= -1, saved_stdin
= -1, r
;
639 _cleanup_free_
char *line
= NULL
;
641 r
= setup_confirm_stdio(&saved_stdin
, &saved_stdout
);
645 line
= exec_command_line(argv
);
649 r
= ask_char(response
, "yns", "Execute %s? [Yes, No, Skip] ", line
);
651 restore_confirm_stdio(&saved_stdin
, &saved_stdout
);
656 static int enforce_groups(const ExecContext
*context
, const char *username
, gid_t gid
) {
657 bool keep_groups
= false;
662 /* Lookup and set GID and supplementary group list. Here too
663 * we avoid NSS lookups for gid=0. */
665 if (context
->group
|| username
) {
666 /* First step, initialize groups from /etc/groups */
667 if (username
&& gid
!= 0) {
668 if (initgroups(username
, gid
) < 0)
674 /* Second step, set our gids */
675 if (setresgid(gid
, gid
, gid
) < 0)
679 if (context
->supplementary_groups
) {
684 /* Final step, initialize any manually set supplementary groups */
685 assert_se((ngroups_max
= (int) sysconf(_SC_NGROUPS_MAX
)) > 0);
687 if (!(gids
= new(gid_t
, ngroups_max
)))
691 k
= getgroups(ngroups_max
, gids
);
699 STRV_FOREACH(i
, context
->supplementary_groups
) {
702 if (k
>= ngroups_max
) {
708 r
= get_group_creds(&g
, gids
+k
);
717 if (setgroups(k
, gids
) < 0) {
728 static int enforce_user(const ExecContext
*context
, uid_t uid
) {
731 /* Sets (but doesn't lookup) the uid and make sure we keep the
732 * capabilities while doing so. */
734 if (context
->capabilities
) {
735 _cleanup_cap_free_ cap_t d
= NULL
;
736 static const cap_value_t bits
[] = {
737 CAP_SETUID
, /* Necessary so that we can run setresuid() below */
738 CAP_SETPCAP
/* Necessary so that we can set PR_SET_SECUREBITS later on */
741 /* First step: If we need to keep capabilities but
742 * drop privileges we need to make sure we keep our
743 * caps, while we drop privileges. */
745 int sb
= context
->secure_bits
| 1<<SECURE_KEEP_CAPS
;
747 if (prctl(PR_GET_SECUREBITS
) != sb
)
748 if (prctl(PR_SET_SECUREBITS
, sb
) < 0)
752 /* Second step: set the capabilities. This will reduce
753 * the capabilities to the minimum we need. */
755 d
= cap_dup(context
->capabilities
);
759 if (cap_set_flag(d
, CAP_EFFECTIVE
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0 ||
760 cap_set_flag(d
, CAP_PERMITTED
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0)
763 if (cap_set_proc(d
) < 0)
767 /* Third step: actually set the uids */
768 if (setresuid(uid
, uid
, uid
) < 0)
771 /* At this point we should have all necessary capabilities but
772 are otherwise a normal user. However, the caps might got
773 corrupted due to the setresuid() so we need clean them up
774 later. This is done outside of this call. */
781 static int null_conv(
783 const struct pam_message
**msg
,
784 struct pam_response
**resp
,
787 /* We don't support conversations */
792 static int setup_pam(
798 int fds
[], unsigned n_fds
) {
800 static const struct pam_conv conv
= {
805 _cleanup_(barrier_destroy
) Barrier barrier
= BARRIER_NULL
;
806 pam_handle_t
*handle
= NULL
;
808 int pam_code
= PAM_SUCCESS
;
811 bool close_session
= false;
812 pid_t pam_pid
= 0, parent_pid
;
819 /* We set up PAM in the parent process, then fork. The child
820 * will then stay around until killed via PR_GET_PDEATHSIG or
821 * systemd via the cgroup logic. It will then remove the PAM
822 * session again. The parent process will exec() the actual
823 * daemon. We do things this way to ensure that the main PID
824 * of the daemon is the one we initially fork()ed. */
826 err
= barrier_create(&barrier
);
830 if (log_get_max_level() < LOG_DEBUG
)
833 pam_code
= pam_start(name
, user
, &conv
, &handle
);
834 if (pam_code
!= PAM_SUCCESS
) {
840 pam_code
= pam_set_item(handle
, PAM_TTY
, tty
);
841 if (pam_code
!= PAM_SUCCESS
)
845 pam_code
= pam_acct_mgmt(handle
, flags
);
846 if (pam_code
!= PAM_SUCCESS
)
849 pam_code
= pam_open_session(handle
, flags
);
850 if (pam_code
!= PAM_SUCCESS
)
853 close_session
= true;
855 e
= pam_getenvlist(handle
);
857 pam_code
= PAM_BUF_ERR
;
861 /* Block SIGTERM, so that we know that it won't get lost in
864 assert_se(sigprocmask_many(SIG_BLOCK
, &old_ss
, SIGTERM
, -1) >= 0);
866 parent_pid
= getpid();
876 /* The child's job is to reset the PAM session on
878 barrier_set_role(&barrier
, BARRIER_CHILD
);
880 /* This string must fit in 10 chars (i.e. the length
881 * of "/sbin/init"), to look pretty in /bin/ps */
882 rename_process("(sd-pam)");
884 /* Make sure we don't keep open the passed fds in this
885 child. We assume that otherwise only those fds are
886 open here that have been opened by PAM. */
887 close_many(fds
, n_fds
);
889 /* Drop privileges - we don't need any to pam_close_session
890 * and this will make PR_SET_PDEATHSIG work in most cases.
891 * If this fails, ignore the error - but expect sd-pam threads
892 * to fail to exit normally */
893 if (setresuid(uid
, uid
, uid
) < 0)
894 log_error_errno(r
, "Error: Failed to setresuid() in sd-pam: %m");
896 (void) ignore_signals(SIGPIPE
, -1);
898 /* Wait until our parent died. This will only work if
899 * the above setresuid() succeeds, otherwise the kernel
900 * will not allow unprivileged parents kill their privileged
901 * children this way. We rely on the control groups kill logic
902 * to do the rest for us. */
903 if (prctl(PR_SET_PDEATHSIG
, SIGTERM
) < 0)
906 /* Tell the parent that our setup is done. This is especially
907 * important regarding dropping privileges. Otherwise, unit
908 * setup might race against our setresuid(2) call. */
909 barrier_place(&barrier
);
911 /* Check if our parent process might already have
913 if (getppid() == parent_pid
) {
916 assert_se(sigemptyset(&ss
) >= 0);
917 assert_se(sigaddset(&ss
, SIGTERM
) >= 0);
920 if (sigwait(&ss
, &sig
) < 0) {
927 assert(sig
== SIGTERM
);
932 /* If our parent died we'll end the session */
933 if (getppid() != parent_pid
) {
934 pam_code
= pam_close_session(handle
, flags
);
935 if (pam_code
!= PAM_SUCCESS
)
942 pam_end(handle
, pam_code
| flags
);
946 barrier_set_role(&barrier
, BARRIER_PARENT
);
948 /* If the child was forked off successfully it will do all the
949 * cleanups, so forget about the handle here. */
952 /* Unblock SIGTERM again in the parent */
953 assert_se(sigprocmask(SIG_SETMASK
, &old_ss
, NULL
) >= 0);
955 /* We close the log explicitly here, since the PAM modules
956 * might have opened it, but we don't want this fd around. */
959 /* Synchronously wait for the child to initialize. We don't care for
960 * errors as we cannot recover. However, warn loudly if it happens. */
961 if (!barrier_place_and_sync(&barrier
))
962 log_error("PAM initialization failed");
970 if (pam_code
!= PAM_SUCCESS
) {
971 log_error("PAM failed: %s", pam_strerror(handle
, pam_code
));
972 err
= -EPERM
; /* PAM errors do not map to errno */
974 err
= log_error_errno(err
< 0 ? err
: errno
, "PAM failed: %m");
979 pam_code
= pam_close_session(handle
, flags
);
981 pam_end(handle
, pam_code
| flags
);
989 kill(pam_pid
, SIGTERM
);
990 kill(pam_pid
, SIGCONT
);
997 static void rename_process_from_path(const char *path
) {
998 char process_name
[11];
1002 /* This resulting string must fit in 10 chars (i.e. the length
1003 * of "/sbin/init") to look pretty in /bin/ps */
1007 rename_process("(...)");
1013 /* The end of the process name is usually more
1014 * interesting, since the first bit might just be
1020 process_name
[0] = '(';
1021 memcpy(process_name
+1, p
, l
);
1022 process_name
[1+l
] = ')';
1023 process_name
[1+l
+1] = 0;
1025 rename_process(process_name
);
1030 static int apply_seccomp(const ExecContext
*c
) {
1031 uint32_t negative_action
, action
;
1032 scmp_filter_ctx
*seccomp
;
1039 negative_action
= c
->syscall_errno
== 0 ? SCMP_ACT_KILL
: SCMP_ACT_ERRNO(c
->syscall_errno
);
1041 seccomp
= seccomp_init(c
->syscall_whitelist
? negative_action
: SCMP_ACT_ALLOW
);
1045 if (c
->syscall_archs
) {
1047 SET_FOREACH(id
, c
->syscall_archs
, i
) {
1048 r
= seccomp_arch_add(seccomp
, PTR_TO_UINT32(id
) - 1);
1056 r
= seccomp_add_secondary_archs(seccomp
);
1061 action
= c
->syscall_whitelist
? SCMP_ACT_ALLOW
: negative_action
;
1062 SET_FOREACH(id
, c
->syscall_filter
, i
) {
1063 r
= seccomp_rule_add(seccomp
, action
, PTR_TO_INT(id
) - 1, 0);
1068 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1072 r
= seccomp_load(seccomp
);
1075 seccomp_release(seccomp
);
1079 static int apply_address_families(const ExecContext
*c
) {
1080 scmp_filter_ctx
*seccomp
;
1086 seccomp
= seccomp_init(SCMP_ACT_ALLOW
);
1090 r
= seccomp_add_secondary_archs(seccomp
);
1094 if (c
->address_families_whitelist
) {
1095 int af
, first
= 0, last
= 0;
1098 /* If this is a whitelist, we first block the address
1099 * families that are out of range and then everything
1100 * that is not in the set. First, we find the lowest
1101 * and highest address family in the set. */
1103 SET_FOREACH(afp
, c
->address_families
, i
) {
1104 af
= PTR_TO_INT(afp
);
1106 if (af
<= 0 || af
>= af_max())
1109 if (first
== 0 || af
< first
)
1112 if (last
== 0 || af
> last
)
1116 assert((first
== 0) == (last
== 0));
1120 /* No entries in the valid range, block everything */
1121 r
= seccomp_rule_add(
1123 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1131 /* Block everything below the first entry */
1132 r
= seccomp_rule_add(
1134 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1137 SCMP_A0(SCMP_CMP_LT
, first
));
1141 /* Block everything above the last entry */
1142 r
= seccomp_rule_add(
1144 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1147 SCMP_A0(SCMP_CMP_GT
, last
));
1151 /* Block everything between the first and last
1153 for (af
= 1; af
< af_max(); af
++) {
1155 if (set_contains(c
->address_families
, INT_TO_PTR(af
)))
1158 r
= seccomp_rule_add(
1160 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1163 SCMP_A0(SCMP_CMP_EQ
, af
));
1172 /* If this is a blacklist, then generate one rule for
1173 * each address family that are then combined in OR
1176 SET_FOREACH(af
, c
->address_families
, i
) {
1178 r
= seccomp_rule_add(
1180 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1183 SCMP_A0(SCMP_CMP_EQ
, PTR_TO_INT(af
)));
1189 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1193 r
= seccomp_load(seccomp
);
1196 seccomp_release(seccomp
);
1202 static void do_idle_pipe_dance(int idle_pipe
[4]) {
1206 idle_pipe
[1] = safe_close(idle_pipe
[1]);
1207 idle_pipe
[2] = safe_close(idle_pipe
[2]);
1209 if (idle_pipe
[0] >= 0) {
1212 r
= fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT_USEC
);
1214 if (idle_pipe
[3] >= 0 && r
== 0 /* timeout */) {
1217 /* Signal systemd that we are bored and want to continue. */
1218 n
= write(idle_pipe
[3], "x", 1);
1220 /* Wait for systemd to react to the signal above. */
1221 fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT2_USEC
);
1224 idle_pipe
[0] = safe_close(idle_pipe
[0]);
1228 idle_pipe
[3] = safe_close(idle_pipe
[3]);
1231 static int build_environment(
1232 const ExecContext
*c
,
1235 usec_t watchdog_usec
,
1237 const char *username
,
1241 _cleanup_strv_free_
char **our_env
= NULL
;
1248 our_env
= new0(char*, 11);
1253 _cleanup_free_
char *joined
= NULL
;
1255 if (asprintf(&x
, "LISTEN_PID="PID_FMT
, getpid()) < 0)
1257 our_env
[n_env
++] = x
;
1259 if (asprintf(&x
, "LISTEN_FDS=%u", n_fds
) < 0)
1261 our_env
[n_env
++] = x
;
1263 joined
= strv_join(fd_names
, ":");
1267 x
= strjoin("LISTEN_FDNAMES=", joined
, NULL
);
1270 our_env
[n_env
++] = x
;
1273 if (watchdog_usec
> 0) {
1274 if (asprintf(&x
, "WATCHDOG_PID="PID_FMT
, getpid()) < 0)
1276 our_env
[n_env
++] = x
;
1278 if (asprintf(&x
, "WATCHDOG_USEC="USEC_FMT
, watchdog_usec
) < 0)
1280 our_env
[n_env
++] = x
;
1284 x
= strappend("HOME=", home
);
1287 our_env
[n_env
++] = x
;
1291 x
= strappend("LOGNAME=", username
);
1294 our_env
[n_env
++] = x
;
1296 x
= strappend("USER=", username
);
1299 our_env
[n_env
++] = x
;
1303 x
= strappend("SHELL=", shell
);
1306 our_env
[n_env
++] = x
;
1309 if (is_terminal_input(c
->std_input
) ||
1310 c
->std_output
== EXEC_OUTPUT_TTY
||
1311 c
->std_error
== EXEC_OUTPUT_TTY
||
1314 x
= strdup(default_term_for_tty(tty_path(c
)));
1317 our_env
[n_env
++] = x
;
1320 our_env
[n_env
++] = NULL
;
1321 assert(n_env
<= 11);
1329 static bool exec_needs_mount_namespace(
1330 const ExecContext
*context
,
1331 const ExecParameters
*params
,
1332 ExecRuntime
*runtime
) {
1337 if (!strv_isempty(context
->read_write_dirs
) ||
1338 !strv_isempty(context
->read_only_dirs
) ||
1339 !strv_isempty(context
->inaccessible_dirs
))
1342 if (context
->mount_flags
!= 0)
1345 if (context
->private_tmp
&& runtime
&& (runtime
->tmp_dir
|| runtime
->var_tmp_dir
))
1348 if (params
->bus_endpoint_path
)
1351 if (context
->private_devices
||
1352 context
->protect_system
!= PROTECT_SYSTEM_NO
||
1353 context
->protect_home
!= PROTECT_HOME_NO
)
1359 static int close_remaining_fds(
1360 const ExecParameters
*params
,
1361 ExecRuntime
*runtime
,
1363 int *fds
, unsigned n_fds
) {
1365 unsigned n_dont_close
= 0;
1366 int dont_close
[n_fds
+ 7];
1370 if (params
->stdin_fd
>= 0)
1371 dont_close
[n_dont_close
++] = params
->stdin_fd
;
1372 if (params
->stdout_fd
>= 0)
1373 dont_close
[n_dont_close
++] = params
->stdout_fd
;
1374 if (params
->stderr_fd
>= 0)
1375 dont_close
[n_dont_close
++] = params
->stderr_fd
;
1378 dont_close
[n_dont_close
++] = socket_fd
;
1380 memcpy(dont_close
+ n_dont_close
, fds
, sizeof(int) * n_fds
);
1381 n_dont_close
+= n_fds
;
1384 if (params
->bus_endpoint_fd
>= 0)
1385 dont_close
[n_dont_close
++] = params
->bus_endpoint_fd
;
1388 if (runtime
->netns_storage_socket
[0] >= 0)
1389 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[0];
1390 if (runtime
->netns_storage_socket
[1] >= 0)
1391 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[1];
1394 return close_all_fds(dont_close
, n_dont_close
);
1397 static int exec_child(
1399 ExecCommand
*command
,
1400 const ExecContext
*context
,
1401 const ExecParameters
*params
,
1402 ExecRuntime
*runtime
,
1405 int *fds
, unsigned n_fds
,
1409 _cleanup_strv_free_
char **our_env
= NULL
, **pam_env
= NULL
, **final_env
= NULL
, **final_argv
= NULL
;
1410 _cleanup_free_
char *mac_selinux_context_net
= NULL
;
1411 const char *username
= NULL
, *home
= NULL
, *shell
= NULL
, *wd
;
1412 uid_t uid
= UID_INVALID
;
1413 gid_t gid
= GID_INVALID
;
1415 bool needs_mount_namespace
;
1421 assert(exit_status
);
1423 rename_process_from_path(command
->path
);
1425 /* We reset exactly these signals, since they are the
1426 * only ones we set to SIG_IGN in the main daemon. All
1427 * others we leave untouched because we set them to
1428 * SIG_DFL or a valid handler initially, both of which
1429 * will be demoted to SIG_DFL. */
1430 (void) default_signals(SIGNALS_CRASH_HANDLER
,
1431 SIGNALS_IGNORE
, -1);
1433 if (context
->ignore_sigpipe
)
1434 (void) ignore_signals(SIGPIPE
, -1);
1436 r
= reset_signal_mask();
1438 *exit_status
= EXIT_SIGNAL_MASK
;
1442 if (params
->idle_pipe
)
1443 do_idle_pipe_dance(params
->idle_pipe
);
1445 /* Close sockets very early to make sure we don't
1446 * block init reexecution because it cannot bind its
1451 r
= close_remaining_fds(params
, runtime
, socket_fd
, fds
, n_fds
);
1453 *exit_status
= EXIT_FDS
;
1457 if (!context
->same_pgrp
)
1459 *exit_status
= EXIT_SETSID
;
1463 exec_context_tty_reset(context
);
1465 if (params
->confirm_spawn
) {
1468 r
= ask_for_confirmation(&response
, argv
);
1469 if (r
== -ETIMEDOUT
)
1470 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1472 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r
));
1473 else if (response
== 's') {
1474 write_confirm_message("Skipping execution.\n");
1475 *exit_status
= EXIT_CONFIRM
;
1477 } else if (response
== 'n') {
1478 write_confirm_message("Failing execution.\n");
1484 if (context
->user
) {
1485 username
= context
->user
;
1486 r
= get_user_creds(&username
, &uid
, &gid
, &home
, &shell
);
1488 *exit_status
= EXIT_USER
;
1493 if (context
->group
) {
1494 const char *g
= context
->group
;
1496 r
= get_group_creds(&g
, &gid
);
1498 *exit_status
= EXIT_GROUP
;
1504 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1505 * must sure to drop O_NONBLOCK */
1507 (void) fd_nonblock(socket_fd
, false);
1509 r
= setup_input(context
, params
, socket_fd
);
1511 *exit_status
= EXIT_STDIN
;
1515 r
= setup_output(unit
, context
, params
, STDOUT_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1517 *exit_status
= EXIT_STDOUT
;
1521 r
= setup_output(unit
, context
, params
, STDERR_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1523 *exit_status
= EXIT_STDERR
;
1527 if (params
->cgroup_path
) {
1528 r
= cg_attach_everywhere(params
->cgroup_supported
, params
->cgroup_path
, 0, NULL
, NULL
);
1530 *exit_status
= EXIT_CGROUP
;
1535 if (context
->oom_score_adjust_set
) {
1536 char t
[DECIMAL_STR_MAX(context
->oom_score_adjust
)];
1538 /* When we can't make this change due to EPERM, then
1539 * let's silently skip over it. User namespaces
1540 * prohibit write access to this file, and we
1541 * shouldn't trip up over that. */
1543 sprintf(t
, "%i", context
->oom_score_adjust
);
1544 r
= write_string_file("/proc/self/oom_score_adj", t
, 0);
1545 if (r
== -EPERM
|| r
== -EACCES
) {
1547 log_unit_debug_errno(unit
, r
, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
1550 *exit_status
= EXIT_OOM_ADJUST
;
1555 if (context
->nice_set
)
1556 if (setpriority(PRIO_PROCESS
, 0, context
->nice
) < 0) {
1557 *exit_status
= EXIT_NICE
;
1561 if (context
->cpu_sched_set
) {
1562 struct sched_param param
= {
1563 .sched_priority
= context
->cpu_sched_priority
,
1566 r
= sched_setscheduler(0,
1567 context
->cpu_sched_policy
|
1568 (context
->cpu_sched_reset_on_fork
?
1569 SCHED_RESET_ON_FORK
: 0),
1572 *exit_status
= EXIT_SETSCHEDULER
;
1577 if (context
->cpuset
)
1578 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context
->cpuset_ncpus
), context
->cpuset
) < 0) {
1579 *exit_status
= EXIT_CPUAFFINITY
;
1583 if (context
->ioprio_set
)
1584 if (ioprio_set(IOPRIO_WHO_PROCESS
, 0, context
->ioprio
) < 0) {
1585 *exit_status
= EXIT_IOPRIO
;
1589 if (context
->timer_slack_nsec
!= NSEC_INFINITY
)
1590 if (prctl(PR_SET_TIMERSLACK
, context
->timer_slack_nsec
) < 0) {
1591 *exit_status
= EXIT_TIMERSLACK
;
1595 if (context
->personality
!= PERSONALITY_INVALID
)
1596 if (personality(context
->personality
) < 0) {
1597 *exit_status
= EXIT_PERSONALITY
;
1601 if (context
->utmp_id
)
1602 utmp_put_init_process(context
->utmp_id
, getpid(), getsid(0), context
->tty_path
,
1603 context
->utmp_mode
== EXEC_UTMP_INIT
? INIT_PROCESS
:
1604 context
->utmp_mode
== EXEC_UTMP_LOGIN
? LOGIN_PROCESS
:
1606 username
? "root" : context
->user
);
1608 if (context
->user
&& is_terminal_input(context
->std_input
)) {
1609 r
= chown_terminal(STDIN_FILENO
, uid
);
1611 *exit_status
= EXIT_STDIN
;
1616 if (params
->bus_endpoint_fd
>= 0 && context
->bus_endpoint
) {
1617 uid_t ep_uid
= (uid
== UID_INVALID
) ? 0 : uid
;
1619 r
= bus_kernel_set_endpoint_policy(params
->bus_endpoint_fd
, ep_uid
, context
->bus_endpoint
);
1621 *exit_status
= EXIT_BUS_ENDPOINT
;
1626 /* If delegation is enabled we'll pass ownership of the cgroup
1627 * (but only in systemd's own controller hierarchy!) to the
1628 * user of the new process. */
1629 if (params
->cgroup_path
&& context
->user
&& params
->cgroup_delegate
) {
1630 r
= cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0644, uid
, gid
);
1632 *exit_status
= EXIT_CGROUP
;
1637 r
= cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0755, uid
, gid
);
1639 *exit_status
= EXIT_CGROUP
;
1644 if (!strv_isempty(context
->runtime_directory
) && params
->runtime_prefix
) {
1647 STRV_FOREACH(rt
, context
->runtime_directory
) {
1648 _cleanup_free_
char *p
;
1650 p
= strjoin(params
->runtime_prefix
, "/", *rt
, NULL
);
1652 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1656 r
= mkdir_p_label(p
, context
->runtime_directory_mode
);
1658 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1662 r
= chmod_and_chown(p
, context
->runtime_directory_mode
, uid
, gid
);
1664 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1670 umask(context
->umask
);
1672 if (params
->apply_permissions
) {
1673 r
= enforce_groups(context
, username
, gid
);
1675 *exit_status
= EXIT_GROUP
;
1679 if (context
->smack_process_label
) {
1680 r
= mac_smack_apply_pid(0, context
->smack_process_label
);
1682 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1686 #ifdef SMACK_DEFAULT_PROCESS_LABEL
1688 _cleanup_free_
char *exec_label
= NULL
;
1690 r
= mac_smack_read(command
->path
, SMACK_ATTR_EXEC
, &exec_label
);
1691 if (r
< 0 && r
!= -ENODATA
&& r
!= -EOPNOTSUPP
) {
1692 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1696 r
= mac_smack_apply_pid(0, exec_label
? : SMACK_DEFAULT_PROCESS_LABEL
);
1698 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1705 if (context
->pam_name
&& username
) {
1706 r
= setup_pam(context
->pam_name
, username
, uid
, context
->tty_path
, &pam_env
, fds
, n_fds
);
1708 *exit_status
= EXIT_PAM
;
1715 if (context
->private_network
&& runtime
&& runtime
->netns_storage_socket
[0] >= 0) {
1716 r
= setup_netns(runtime
->netns_storage_socket
);
1718 *exit_status
= EXIT_NETWORK
;
1723 needs_mount_namespace
= exec_needs_mount_namespace(context
, params
, runtime
);
1725 if (needs_mount_namespace
) {
1726 char *tmp
= NULL
, *var
= NULL
;
1728 /* The runtime struct only contains the parent
1729 * of the private /tmp, which is
1730 * non-accessible to world users. Inside of it
1731 * there's a /tmp that is sticky, and that's
1732 * the one we want to use here. */
1734 if (context
->private_tmp
&& runtime
) {
1735 if (runtime
->tmp_dir
)
1736 tmp
= strjoina(runtime
->tmp_dir
, "/tmp");
1737 if (runtime
->var_tmp_dir
)
1738 var
= strjoina(runtime
->var_tmp_dir
, "/tmp");
1741 r
= setup_namespace(
1742 params
->apply_chroot
? context
->root_directory
: NULL
,
1743 context
->read_write_dirs
,
1744 context
->read_only_dirs
,
1745 context
->inaccessible_dirs
,
1748 params
->bus_endpoint_path
,
1749 context
->private_devices
,
1750 context
->protect_home
,
1751 context
->protect_system
,
1752 context
->mount_flags
);
1754 /* If we couldn't set up the namespace this is
1755 * probably due to a missing capability. In this case,
1756 * silently proceeed. */
1757 if (r
== -EPERM
|| r
== -EACCES
) {
1759 log_unit_debug_errno(unit
, r
, "Failed to set up namespace, assuming containerized execution, ignoring: %m");
1762 *exit_status
= EXIT_NAMESPACE
;
1767 if (context
->working_directory_home
)
1769 else if (context
->working_directory
)
1770 wd
= context
->working_directory
;
1774 if (params
->apply_chroot
) {
1775 if (!needs_mount_namespace
&& context
->root_directory
)
1776 if (chroot(context
->root_directory
) < 0) {
1777 *exit_status
= EXIT_CHROOT
;
1781 if (chdir(wd
) < 0 &&
1782 !context
->working_directory_missing_ok
) {
1783 *exit_status
= EXIT_CHDIR
;
1789 d
= strjoina(strempty(context
->root_directory
), "/", strempty(wd
));
1791 !context
->working_directory_missing_ok
) {
1792 *exit_status
= EXIT_CHDIR
;
1798 if (params
->apply_permissions
&& mac_selinux_use() && params
->selinux_context_net
&& socket_fd
>= 0) {
1799 r
= mac_selinux_get_child_mls_label(socket_fd
, command
->path
, context
->selinux_context
, &mac_selinux_context_net
);
1801 *exit_status
= EXIT_SELINUX_CONTEXT
;
1807 /* We repeat the fd closing here, to make sure that
1808 * nothing is leaked from the PAM modules. Note that
1809 * we are more aggressive this time since socket_fd
1810 * and the netns fds we don't need anymore. The custom
1811 * endpoint fd was needed to upload the policy and can
1812 * now be closed as well. */
1813 r
= close_all_fds(fds
, n_fds
);
1815 r
= shift_fds(fds
, n_fds
);
1817 r
= flags_fds(fds
, n_fds
, context
->non_blocking
);
1819 *exit_status
= EXIT_FDS
;
1823 if (params
->apply_permissions
) {
1825 for (i
= 0; i
< _RLIMIT_MAX
; i
++) {
1826 if (!context
->rlimit
[i
])
1829 if (setrlimit_closest(i
, context
->rlimit
[i
]) < 0) {
1830 *exit_status
= EXIT_LIMITS
;
1835 if (context
->capability_bounding_set_drop
) {
1836 r
= capability_bounding_set_drop(context
->capability_bounding_set_drop
, false);
1838 *exit_status
= EXIT_CAPABILITIES
;
1843 if (context
->user
) {
1844 r
= enforce_user(context
, uid
);
1846 *exit_status
= EXIT_USER
;
1851 /* PR_GET_SECUREBITS is not privileged, while
1852 * PR_SET_SECUREBITS is. So to suppress
1853 * potential EPERMs we'll try not to call
1854 * PR_SET_SECUREBITS unless necessary. */
1855 if (prctl(PR_GET_SECUREBITS
) != context
->secure_bits
)
1856 if (prctl(PR_SET_SECUREBITS
, context
->secure_bits
) < 0) {
1857 *exit_status
= EXIT_SECUREBITS
;
1861 if (context
->capabilities
)
1862 if (cap_set_proc(context
->capabilities
) < 0) {
1863 *exit_status
= EXIT_CAPABILITIES
;
1867 if (context
->no_new_privileges
)
1868 if (prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0) < 0) {
1869 *exit_status
= EXIT_NO_NEW_PRIVILEGES
;
1874 if (context
->address_families_whitelist
||
1875 !set_isempty(context
->address_families
)) {
1876 r
= apply_address_families(context
);
1878 *exit_status
= EXIT_ADDRESS_FAMILIES
;
1883 if (context
->syscall_whitelist
||
1884 !set_isempty(context
->syscall_filter
) ||
1885 !set_isempty(context
->syscall_archs
)) {
1886 r
= apply_seccomp(context
);
1888 *exit_status
= EXIT_SECCOMP
;
1895 if (mac_selinux_use()) {
1896 char *exec_context
= mac_selinux_context_net
?: context
->selinux_context
;
1899 r
= setexeccon(exec_context
);
1901 *exit_status
= EXIT_SELINUX_CONTEXT
;
1908 #ifdef HAVE_APPARMOR
1909 if (context
->apparmor_profile
&& mac_apparmor_use()) {
1910 r
= aa_change_onexec(context
->apparmor_profile
);
1911 if (r
< 0 && !context
->apparmor_profile_ignore
) {
1912 *exit_status
= EXIT_APPARMOR_PROFILE
;
1919 r
= build_environment(context
, n_fds
, params
->fd_names
, params
->watchdog_usec
, home
, username
, shell
, &our_env
);
1921 *exit_status
= EXIT_MEMORY
;
1925 final_env
= strv_env_merge(5,
1926 params
->environment
,
1928 context
->environment
,
1933 *exit_status
= EXIT_MEMORY
;
1937 final_argv
= replace_env_argv(argv
, final_env
);
1939 *exit_status
= EXIT_MEMORY
;
1943 final_env
= strv_env_clean(final_env
);
1945 if (_unlikely_(log_get_max_level() >= LOG_DEBUG
)) {
1946 _cleanup_free_
char *line
;
1948 line
= exec_command_line(final_argv
);
1951 log_struct(LOG_DEBUG
,
1953 "EXECUTABLE=%s", command
->path
,
1954 LOG_UNIT_MESSAGE(unit
, "Executing: %s", line
),
1960 execve(command
->path
, final_argv
, final_env
);
1961 *exit_status
= EXIT_EXEC
;
1965 int exec_spawn(Unit
*unit
,
1966 ExecCommand
*command
,
1967 const ExecContext
*context
,
1968 const ExecParameters
*params
,
1969 ExecRuntime
*runtime
,
1972 _cleanup_strv_free_
char **files_env
= NULL
;
1973 int *fds
= NULL
; unsigned n_fds
= 0;
1974 _cleanup_free_
char *line
= NULL
;
1984 assert(params
->fds
|| params
->n_fds
<= 0);
1986 if (context
->std_input
== EXEC_INPUT_SOCKET
||
1987 context
->std_output
== EXEC_OUTPUT_SOCKET
||
1988 context
->std_error
== EXEC_OUTPUT_SOCKET
) {
1990 if (params
->n_fds
!= 1) {
1991 log_unit_error(unit
, "Got more than one socket.");
1995 socket_fd
= params
->fds
[0];
1999 n_fds
= params
->n_fds
;
2002 r
= exec_context_load_environment(unit
, context
, &files_env
);
2004 return log_unit_error_errno(unit
, r
, "Failed to load environment files: %m");
2006 argv
= params
->argv
?: command
->argv
;
2007 line
= exec_command_line(argv
);
2011 log_struct(LOG_DEBUG
,
2013 LOG_UNIT_MESSAGE(unit
, "About to execute: %s", line
),
2014 "EXECUTABLE=%s", command
->path
,
2018 return log_unit_error_errno(unit
, r
, "Failed to fork: %m");
2023 r
= exec_child(unit
,
2035 log_struct_errno(LOG_ERR
, r
,
2036 LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED
),
2038 LOG_UNIT_MESSAGE(unit
, "Failed at step %s spawning %s: %m",
2039 exit_status_to_string(exit_status
, EXIT_STATUS_SYSTEMD
),
2041 "EXECUTABLE=%s", command
->path
,
2048 log_unit_debug(unit
, "Forked %s as "PID_FMT
, command
->path
, pid
);
2050 /* We add the new process to the cgroup both in the child (so
2051 * that we can be sure that no user code is ever executed
2052 * outside of the cgroup) and in the parent (so that we can be
2053 * sure that when we kill the cgroup the process will be
2055 if (params
->cgroup_path
)
2056 (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, pid
);
2058 exec_status_start(&command
->exec_status
, pid
);
2064 void exec_context_init(ExecContext
*c
) {
2068 c
->ioprio
= IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE
, 0);
2069 c
->cpu_sched_policy
= SCHED_OTHER
;
2070 c
->syslog_priority
= LOG_DAEMON
|LOG_INFO
;
2071 c
->syslog_level_prefix
= true;
2072 c
->ignore_sigpipe
= true;
2073 c
->timer_slack_nsec
= NSEC_INFINITY
;
2074 c
->personality
= PERSONALITY_INVALID
;
2075 c
->runtime_directory_mode
= 0755;
2078 void exec_context_done(ExecContext
*c
) {
2083 c
->environment
= strv_free(c
->environment
);
2084 c
->environment_files
= strv_free(c
->environment_files
);
2086 for (l
= 0; l
< ELEMENTSOF(c
->rlimit
); l
++)
2087 c
->rlimit
[l
] = mfree(c
->rlimit
[l
]);
2089 c
->working_directory
= mfree(c
->working_directory
);
2090 c
->root_directory
= mfree(c
->root_directory
);
2091 c
->tty_path
= mfree(c
->tty_path
);
2092 c
->syslog_identifier
= mfree(c
->syslog_identifier
);
2093 c
->user
= mfree(c
->user
);
2094 c
->group
= mfree(c
->group
);
2096 c
->supplementary_groups
= strv_free(c
->supplementary_groups
);
2098 c
->pam_name
= mfree(c
->pam_name
);
2100 if (c
->capabilities
) {
2101 cap_free(c
->capabilities
);
2102 c
->capabilities
= NULL
;
2105 c
->read_only_dirs
= strv_free(c
->read_only_dirs
);
2106 c
->read_write_dirs
= strv_free(c
->read_write_dirs
);
2107 c
->inaccessible_dirs
= strv_free(c
->inaccessible_dirs
);
2110 CPU_FREE(c
->cpuset
);
2112 c
->utmp_id
= mfree(c
->utmp_id
);
2113 c
->selinux_context
= mfree(c
->selinux_context
);
2114 c
->apparmor_profile
= mfree(c
->apparmor_profile
);
2116 c
->syscall_filter
= set_free(c
->syscall_filter
);
2117 c
->syscall_archs
= set_free(c
->syscall_archs
);
2118 c
->address_families
= set_free(c
->address_families
);
2120 c
->runtime_directory
= strv_free(c
->runtime_directory
);
2122 bus_endpoint_free(c
->bus_endpoint
);
2123 c
->bus_endpoint
= NULL
;
2126 int exec_context_destroy_runtime_directory(ExecContext
*c
, const char *runtime_prefix
) {
2131 if (!runtime_prefix
)
2134 STRV_FOREACH(i
, c
->runtime_directory
) {
2135 _cleanup_free_
char *p
;
2137 p
= strjoin(runtime_prefix
, "/", *i
, NULL
);
2141 /* We execute this synchronously, since we need to be
2142 * sure this is gone when we start the service
2144 (void) rm_rf(p
, REMOVE_ROOT
);
2150 void exec_command_done(ExecCommand
*c
) {
2153 c
->path
= mfree(c
->path
);
2155 c
->argv
= strv_free(c
->argv
);
2158 void exec_command_done_array(ExecCommand
*c
, unsigned n
) {
2161 for (i
= 0; i
< n
; i
++)
2162 exec_command_done(c
+i
);
2165 ExecCommand
* exec_command_free_list(ExecCommand
*c
) {
2169 LIST_REMOVE(command
, c
, i
);
2170 exec_command_done(i
);
2177 void exec_command_free_array(ExecCommand
**c
, unsigned n
) {
2180 for (i
= 0; i
< n
; i
++)
2181 c
[i
] = exec_command_free_list(c
[i
]);
2184 typedef struct InvalidEnvInfo
{
2189 static void invalid_env(const char *p
, void *userdata
) {
2190 InvalidEnvInfo
*info
= userdata
;
2192 log_unit_error(info
->unit
, "Ignoring invalid environment assignment '%s': %s", p
, info
->path
);
2195 int exec_context_load_environment(Unit
*unit
, const ExecContext
*c
, char ***l
) {
2196 char **i
, **r
= NULL
;
2201 STRV_FOREACH(i
, c
->environment_files
) {
2204 bool ignore
= false;
2206 _cleanup_globfree_ glob_t pglob
= {};
2216 if (!path_is_absolute(fn
)) {
2224 /* Filename supports globbing, take all matching files */
2226 if (glob(fn
, 0, NULL
, &pglob
) != 0) {
2231 return errno
? -errno
: -EINVAL
;
2233 count
= pglob
.gl_pathc
;
2241 for (n
= 0; n
< count
; n
++) {
2242 k
= load_env_file(NULL
, pglob
.gl_pathv
[n
], NULL
, &p
);
2250 /* Log invalid environment variables with filename */
2252 InvalidEnvInfo info
= {
2254 .path
= pglob
.gl_pathv
[n
]
2257 p
= strv_env_clean_with_callback(p
, invalid_env
, &info
);
2265 m
= strv_env_merge(2, r
, p
);
2281 static bool tty_may_match_dev_console(const char *tty
) {
2282 _cleanup_free_
char *active
= NULL
;
2285 if (startswith(tty
, "/dev/"))
2288 /* trivial identity? */
2289 if (streq(tty
, "console"))
2292 console
= resolve_dev_console(&active
);
2293 /* if we could not resolve, assume it may */
2297 /* "tty0" means the active VC, so it may be the same sometimes */
2298 return streq(console
, tty
) || (streq(console
, "tty0") && tty_is_vc(tty
));
2301 bool exec_context_may_touch_console(ExecContext
*ec
) {
2302 return (ec
->tty_reset
|| ec
->tty_vhangup
|| ec
->tty_vt_disallocate
||
2303 is_terminal_input(ec
->std_input
) ||
2304 is_terminal_output(ec
->std_output
) ||
2305 is_terminal_output(ec
->std_error
)) &&
2306 tty_may_match_dev_console(tty_path(ec
));
2309 static void strv_fprintf(FILE *f
, char **l
) {
2315 fprintf(f
, " %s", *g
);
2318 void exec_context_dump(ExecContext
*c
, FILE* f
, const char *prefix
) {
2325 prefix
= strempty(prefix
);
2329 "%sWorkingDirectory: %s\n"
2330 "%sRootDirectory: %s\n"
2331 "%sNonBlocking: %s\n"
2332 "%sPrivateTmp: %s\n"
2333 "%sPrivateNetwork: %s\n"
2334 "%sPrivateDevices: %s\n"
2335 "%sProtectHome: %s\n"
2336 "%sProtectSystem: %s\n"
2337 "%sIgnoreSIGPIPE: %s\n",
2339 prefix
, c
->working_directory
? c
->working_directory
: "/",
2340 prefix
, c
->root_directory
? c
->root_directory
: "/",
2341 prefix
, yes_no(c
->non_blocking
),
2342 prefix
, yes_no(c
->private_tmp
),
2343 prefix
, yes_no(c
->private_network
),
2344 prefix
, yes_no(c
->private_devices
),
2345 prefix
, protect_home_to_string(c
->protect_home
),
2346 prefix
, protect_system_to_string(c
->protect_system
),
2347 prefix
, yes_no(c
->ignore_sigpipe
));
2349 STRV_FOREACH(e
, c
->environment
)
2350 fprintf(f
, "%sEnvironment: %s\n", prefix
, *e
);
2352 STRV_FOREACH(e
, c
->environment_files
)
2353 fprintf(f
, "%sEnvironmentFile: %s\n", prefix
, *e
);
2355 fprintf(f
, "%sRuntimeDirectoryMode: %04o\n", prefix
, c
->runtime_directory_mode
);
2357 STRV_FOREACH(d
, c
->runtime_directory
)
2358 fprintf(f
, "%sRuntimeDirectory: %s\n", prefix
, *d
);
2365 if (c
->oom_score_adjust_set
)
2367 "%sOOMScoreAdjust: %i\n",
2368 prefix
, c
->oom_score_adjust
);
2370 for (i
= 0; i
< RLIM_NLIMITS
; i
++)
2372 fprintf(f
, "%s%s: "RLIM_FMT
"\n",
2373 prefix
, rlimit_to_string(i
), c
->rlimit
[i
]->rlim_max
);
2375 if (c
->ioprio_set
) {
2376 _cleanup_free_
char *class_str
= NULL
;
2378 ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c
->ioprio
), &class_str
);
2380 "%sIOSchedulingClass: %s\n"
2381 "%sIOPriority: %i\n",
2382 prefix
, strna(class_str
),
2383 prefix
, (int) IOPRIO_PRIO_DATA(c
->ioprio
));
2386 if (c
->cpu_sched_set
) {
2387 _cleanup_free_
char *policy_str
= NULL
;
2389 sched_policy_to_string_alloc(c
->cpu_sched_policy
, &policy_str
);
2391 "%sCPUSchedulingPolicy: %s\n"
2392 "%sCPUSchedulingPriority: %i\n"
2393 "%sCPUSchedulingResetOnFork: %s\n",
2394 prefix
, strna(policy_str
),
2395 prefix
, c
->cpu_sched_priority
,
2396 prefix
, yes_no(c
->cpu_sched_reset_on_fork
));
2400 fprintf(f
, "%sCPUAffinity:", prefix
);
2401 for (i
= 0; i
< c
->cpuset_ncpus
; i
++)
2402 if (CPU_ISSET_S(i
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
), c
->cpuset
))
2403 fprintf(f
, " %u", i
);
2407 if (c
->timer_slack_nsec
!= NSEC_INFINITY
)
2408 fprintf(f
, "%sTimerSlackNSec: "NSEC_FMT
"\n", prefix
, c
->timer_slack_nsec
);
2411 "%sStandardInput: %s\n"
2412 "%sStandardOutput: %s\n"
2413 "%sStandardError: %s\n",
2414 prefix
, exec_input_to_string(c
->std_input
),
2415 prefix
, exec_output_to_string(c
->std_output
),
2416 prefix
, exec_output_to_string(c
->std_error
));
2422 "%sTTYVHangup: %s\n"
2423 "%sTTYVTDisallocate: %s\n",
2424 prefix
, c
->tty_path
,
2425 prefix
, yes_no(c
->tty_reset
),
2426 prefix
, yes_no(c
->tty_vhangup
),
2427 prefix
, yes_no(c
->tty_vt_disallocate
));
2429 if (c
->std_output
== EXEC_OUTPUT_SYSLOG
||
2430 c
->std_output
== EXEC_OUTPUT_KMSG
||
2431 c
->std_output
== EXEC_OUTPUT_JOURNAL
||
2432 c
->std_output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2433 c
->std_output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2434 c
->std_output
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
||
2435 c
->std_error
== EXEC_OUTPUT_SYSLOG
||
2436 c
->std_error
== EXEC_OUTPUT_KMSG
||
2437 c
->std_error
== EXEC_OUTPUT_JOURNAL
||
2438 c
->std_error
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2439 c
->std_error
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2440 c
->std_error
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
) {
2442 _cleanup_free_
char *fac_str
= NULL
, *lvl_str
= NULL
;
2444 log_facility_unshifted_to_string_alloc(c
->syslog_priority
>> 3, &fac_str
);
2445 log_level_to_string_alloc(LOG_PRI(c
->syslog_priority
), &lvl_str
);
2448 "%sSyslogFacility: %s\n"
2449 "%sSyslogLevel: %s\n",
2450 prefix
, strna(fac_str
),
2451 prefix
, strna(lvl_str
));
2454 if (c
->capabilities
) {
2455 _cleanup_cap_free_charp_
char *t
;
2457 t
= cap_to_text(c
->capabilities
, NULL
);
2459 fprintf(f
, "%sCapabilities: %s\n", prefix
, t
);
2463 fprintf(f
, "%sSecure Bits:%s%s%s%s%s%s\n",
2465 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS
) ? " keep-caps" : "",
2466 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS_LOCKED
) ? " keep-caps-locked" : "",
2467 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP
) ? " no-setuid-fixup" : "",
2468 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP_LOCKED
) ? " no-setuid-fixup-locked" : "",
2469 (c
->secure_bits
& 1<<SECURE_NOROOT
) ? " noroot" : "",
2470 (c
->secure_bits
& 1<<SECURE_NOROOT_LOCKED
) ? "noroot-locked" : "");
2472 if (c
->capability_bounding_set_drop
) {
2474 fprintf(f
, "%sCapabilityBoundingSet:", prefix
);
2476 for (l
= 0; l
<= cap_last_cap(); l
++)
2477 if (!(c
->capability_bounding_set_drop
& ((uint64_t) 1ULL << (uint64_t) l
)))
2478 fprintf(f
, " %s", strna(capability_to_name(l
)));
2484 fprintf(f
, "%sUser: %s\n", prefix
, c
->user
);
2486 fprintf(f
, "%sGroup: %s\n", prefix
, c
->group
);
2488 if (strv_length(c
->supplementary_groups
) > 0) {
2489 fprintf(f
, "%sSupplementaryGroups:", prefix
);
2490 strv_fprintf(f
, c
->supplementary_groups
);
2495 fprintf(f
, "%sPAMName: %s\n", prefix
, c
->pam_name
);
2497 if (strv_length(c
->read_write_dirs
) > 0) {
2498 fprintf(f
, "%sReadWriteDirs:", prefix
);
2499 strv_fprintf(f
, c
->read_write_dirs
);
2503 if (strv_length(c
->read_only_dirs
) > 0) {
2504 fprintf(f
, "%sReadOnlyDirs:", prefix
);
2505 strv_fprintf(f
, c
->read_only_dirs
);
2509 if (strv_length(c
->inaccessible_dirs
) > 0) {
2510 fprintf(f
, "%sInaccessibleDirs:", prefix
);
2511 strv_fprintf(f
, c
->inaccessible_dirs
);
2517 "%sUtmpIdentifier: %s\n",
2518 prefix
, c
->utmp_id
);
2520 if (c
->selinux_context
)
2522 "%sSELinuxContext: %s%s\n",
2523 prefix
, c
->selinux_context_ignore
? "-" : "", c
->selinux_context
);
2525 if (c
->personality
!= PERSONALITY_INVALID
)
2527 "%sPersonality: %s\n",
2528 prefix
, strna(personality_to_string(c
->personality
)));
2530 if (c
->syscall_filter
) {
2538 "%sSystemCallFilter: ",
2541 if (!c
->syscall_whitelist
)
2545 SET_FOREACH(id
, c
->syscall_filter
, j
) {
2546 _cleanup_free_
char *name
= NULL
;
2553 name
= seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE
, PTR_TO_INT(id
) - 1);
2554 fputs(strna(name
), f
);
2561 if (c
->syscall_archs
) {
2568 "%sSystemCallArchitectures:",
2572 SET_FOREACH(id
, c
->syscall_archs
, j
)
2573 fprintf(f
, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id
) - 1)));
2578 if (c
->syscall_errno
!= 0)
2580 "%sSystemCallErrorNumber: %s\n",
2581 prefix
, strna(errno_to_name(c
->syscall_errno
)));
2583 if (c
->apparmor_profile
)
2585 "%sAppArmorProfile: %s%s\n",
2586 prefix
, c
->apparmor_profile_ignore
? "-" : "", c
->apparmor_profile
);
2589 bool exec_context_maintains_privileges(ExecContext
*c
) {
2592 /* Returns true if the process forked off would run run under
2593 * an unchanged UID or as root. */
2598 if (streq(c
->user
, "root") || streq(c
->user
, "0"))
2604 void exec_status_start(ExecStatus
*s
, pid_t pid
) {
2609 dual_timestamp_get(&s
->start_timestamp
);
2612 void exec_status_exit(ExecStatus
*s
, ExecContext
*context
, pid_t pid
, int code
, int status
) {
2615 if (s
->pid
&& s
->pid
!= pid
)
2619 dual_timestamp_get(&s
->exit_timestamp
);
2625 if (context
->utmp_id
)
2626 utmp_put_dead_process(context
->utmp_id
, pid
, code
, status
);
2628 exec_context_tty_reset(context
);
2632 void exec_status_dump(ExecStatus
*s
, FILE *f
, const char *prefix
) {
2633 char buf
[FORMAT_TIMESTAMP_MAX
];
2641 prefix
= strempty(prefix
);
2644 "%sPID: "PID_FMT
"\n",
2647 if (s
->start_timestamp
.realtime
> 0)
2649 "%sStart Timestamp: %s\n",
2650 prefix
, format_timestamp(buf
, sizeof(buf
), s
->start_timestamp
.realtime
));
2652 if (s
->exit_timestamp
.realtime
> 0)
2654 "%sExit Timestamp: %s\n"
2656 "%sExit Status: %i\n",
2657 prefix
, format_timestamp(buf
, sizeof(buf
), s
->exit_timestamp
.realtime
),
2658 prefix
, sigchld_code_to_string(s
->code
),
2662 char *exec_command_line(char **argv
) {
2670 STRV_FOREACH(a
, argv
)
2673 if (!(n
= new(char, k
)))
2677 STRV_FOREACH(a
, argv
) {
2684 if (strpbrk(*a
, WHITESPACE
)) {
2695 /* FIXME: this doesn't really handle arguments that have
2696 * spaces and ticks in them */
2701 void exec_command_dump(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2702 _cleanup_free_
char *cmd
= NULL
;
2703 const char *prefix2
;
2708 prefix
= strempty(prefix
);
2709 prefix2
= strjoina(prefix
, "\t");
2711 cmd
= exec_command_line(c
->argv
);
2713 "%sCommand Line: %s\n",
2714 prefix
, cmd
? cmd
: strerror(ENOMEM
));
2716 exec_status_dump(&c
->exec_status
, f
, prefix2
);
2719 void exec_command_dump_list(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2722 prefix
= strempty(prefix
);
2724 LIST_FOREACH(command
, c
, c
)
2725 exec_command_dump(c
, f
, prefix
);
2728 void exec_command_append_list(ExecCommand
**l
, ExecCommand
*e
) {
2735 /* It's kind of important, that we keep the order here */
2736 LIST_FIND_TAIL(command
, *l
, end
);
2737 LIST_INSERT_AFTER(command
, *l
, end
, e
);
2742 int exec_command_set(ExecCommand
*c
, const char *path
, ...) {
2750 l
= strv_new_ap(path
, ap
);
2771 int exec_command_append(ExecCommand
*c
, const char *path
, ...) {
2772 _cleanup_strv_free_
char **l
= NULL
;
2780 l
= strv_new_ap(path
, ap
);
2786 r
= strv_extend_strv(&c
->argv
, l
, false);
2794 static int exec_runtime_allocate(ExecRuntime
**rt
) {
2799 *rt
= new0(ExecRuntime
, 1);
2804 (*rt
)->netns_storage_socket
[0] = (*rt
)->netns_storage_socket
[1] = -1;
2809 int exec_runtime_make(ExecRuntime
**rt
, ExecContext
*c
, const char *id
) {
2819 if (!c
->private_network
&& !c
->private_tmp
)
2822 r
= exec_runtime_allocate(rt
);
2826 if (c
->private_network
&& (*rt
)->netns_storage_socket
[0] < 0) {
2827 if (socketpair(AF_UNIX
, SOCK_DGRAM
, 0, (*rt
)->netns_storage_socket
) < 0)
2831 if (c
->private_tmp
&& !(*rt
)->tmp_dir
) {
2832 r
= setup_tmp_dirs(id
, &(*rt
)->tmp_dir
, &(*rt
)->var_tmp_dir
);
2840 ExecRuntime
*exec_runtime_ref(ExecRuntime
*r
) {
2842 assert(r
->n_ref
> 0);
2848 ExecRuntime
*exec_runtime_unref(ExecRuntime
*r
) {
2853 assert(r
->n_ref
> 0);
2860 free(r
->var_tmp_dir
);
2861 safe_close_pair(r
->netns_storage_socket
);
2867 int exec_runtime_serialize(Unit
*u
, ExecRuntime
*rt
, FILE *f
, FDSet
*fds
) {
2876 unit_serialize_item(u
, f
, "tmp-dir", rt
->tmp_dir
);
2878 if (rt
->var_tmp_dir
)
2879 unit_serialize_item(u
, f
, "var-tmp-dir", rt
->var_tmp_dir
);
2881 if (rt
->netns_storage_socket
[0] >= 0) {
2884 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[0]);
2888 unit_serialize_item_format(u
, f
, "netns-socket-0", "%i", copy
);
2891 if (rt
->netns_storage_socket
[1] >= 0) {
2894 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[1]);
2898 unit_serialize_item_format(u
, f
, "netns-socket-1", "%i", copy
);
2904 int exec_runtime_deserialize_item(Unit
*u
, ExecRuntime
**rt
, const char *key
, const char *value
, FDSet
*fds
) {
2911 if (streq(key
, "tmp-dir")) {
2914 r
= exec_runtime_allocate(rt
);
2918 copy
= strdup(value
);
2922 free((*rt
)->tmp_dir
);
2923 (*rt
)->tmp_dir
= copy
;
2925 } else if (streq(key
, "var-tmp-dir")) {
2928 r
= exec_runtime_allocate(rt
);
2932 copy
= strdup(value
);
2936 free((*rt
)->var_tmp_dir
);
2937 (*rt
)->var_tmp_dir
= copy
;
2939 } else if (streq(key
, "netns-socket-0")) {
2942 r
= exec_runtime_allocate(rt
);
2946 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
2947 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
2949 safe_close((*rt
)->netns_storage_socket
[0]);
2950 (*rt
)->netns_storage_socket
[0] = fdset_remove(fds
, fd
);
2952 } else if (streq(key
, "netns-socket-1")) {
2955 r
= exec_runtime_allocate(rt
);
2959 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
2960 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
2962 safe_close((*rt
)->netns_storage_socket
[1]);
2963 (*rt
)->netns_storage_socket
[1] = fdset_remove(fds
, fd
);
2971 static void *remove_tmpdir_thread(void *p
) {
2972 _cleanup_free_
char *path
= p
;
2974 (void) rm_rf(path
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
2978 void exec_runtime_destroy(ExecRuntime
*rt
) {
2984 /* If there are multiple users of this, let's leave the stuff around */
2989 log_debug("Spawning thread to nuke %s", rt
->tmp_dir
);
2991 r
= asynchronous_job(remove_tmpdir_thread
, rt
->tmp_dir
);
2993 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->tmp_dir
);
3000 if (rt
->var_tmp_dir
) {
3001 log_debug("Spawning thread to nuke %s", rt
->var_tmp_dir
);
3003 r
= asynchronous_job(remove_tmpdir_thread
, rt
->var_tmp_dir
);
3005 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->var_tmp_dir
);
3006 free(rt
->var_tmp_dir
);
3009 rt
->var_tmp_dir
= NULL
;
3012 safe_close_pair(rt
->netns_storage_socket
);
3015 static const char* const exec_input_table
[_EXEC_INPUT_MAX
] = {
3016 [EXEC_INPUT_NULL
] = "null",
3017 [EXEC_INPUT_TTY
] = "tty",
3018 [EXEC_INPUT_TTY_FORCE
] = "tty-force",
3019 [EXEC_INPUT_TTY_FAIL
] = "tty-fail",
3020 [EXEC_INPUT_SOCKET
] = "socket"
3023 DEFINE_STRING_TABLE_LOOKUP(exec_input
, ExecInput
);
3025 static const char* const exec_output_table
[_EXEC_OUTPUT_MAX
] = {
3026 [EXEC_OUTPUT_INHERIT
] = "inherit",
3027 [EXEC_OUTPUT_NULL
] = "null",
3028 [EXEC_OUTPUT_TTY
] = "tty",
3029 [EXEC_OUTPUT_SYSLOG
] = "syslog",
3030 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE
] = "syslog+console",
3031 [EXEC_OUTPUT_KMSG
] = "kmsg",
3032 [EXEC_OUTPUT_KMSG_AND_CONSOLE
] = "kmsg+console",
3033 [EXEC_OUTPUT_JOURNAL
] = "journal",
3034 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE
] = "journal+console",
3035 [EXEC_OUTPUT_SOCKET
] = "socket"
3038 DEFINE_STRING_TABLE_LOOKUP(exec_output
, ExecOutput
);
3040 static const char* const exec_utmp_mode_table
[_EXEC_UTMP_MODE_MAX
] = {
3041 [EXEC_UTMP_INIT
] = "init",
3042 [EXEC_UTMP_LOGIN
] = "login",
3043 [EXEC_UTMP_USER
] = "user",
3046 DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode
, ExecUtmpMode
);