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"
56 #include "alloc-util.h"
58 #include "apparmor-util.h"
62 #include "bus-endpoint.h"
64 #include "capability-util.h"
67 #include "errno-list.h"
69 #include "exit-status.h"
72 #include "formats-util.h"
74 #include "glob-util.h"
81 #include "namespace.h"
82 #include "parse-util.h"
83 #include "path-util.h"
84 #include "process-util.h"
85 #include "rlimit-util.h"
88 #include "seccomp-util.h"
90 #include "securebits.h"
91 #include "selinux-util.h"
92 #include "signal-util.h"
93 #include "smack-util.h"
94 #include "string-table.h"
95 #include "string-util.h"
97 #include "syslog-util.h"
98 #include "terminal-util.h"
100 #include "user-util.h"
102 #include "utmp-wtmp.h"
104 #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
105 #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
107 /* This assumes there is a 'tty' group */
108 #define TTY_MODE 0620
110 #define SNDBUF_SIZE (8*1024*1024)
112 static int shift_fds(int fds
[], unsigned n_fds
) {
113 int start
, restart_from
;
118 /* Modifies the fds array! (sorts it) */
128 for (i
= start
; i
< (int) n_fds
; i
++) {
131 /* Already at right index? */
135 nfd
= fcntl(fds
[i
], F_DUPFD
, i
+ 3);
142 /* Hmm, the fd we wanted isn't free? Then
143 * let's remember that and try again from here */
144 if (nfd
!= i
+3 && restart_from
< 0)
148 if (restart_from
< 0)
151 start
= restart_from
;
157 static int flags_fds(const int fds
[], unsigned n_fds
, bool nonblock
) {
166 /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
168 for (i
= 0; i
< n_fds
; i
++) {
170 r
= fd_nonblock(fds
[i
], nonblock
);
174 /* We unconditionally drop FD_CLOEXEC from the fds,
175 * since after all we want to pass these fds to our
178 r
= fd_cloexec(fds
[i
], false);
186 _pure_
static const char *tty_path(const ExecContext
*context
) {
189 if (context
->tty_path
)
190 return context
->tty_path
;
192 return "/dev/console";
195 static void exec_context_tty_reset(const ExecContext
*context
) {
198 if (context
->tty_vhangup
)
199 terminal_vhangup(tty_path(context
));
201 if (context
->tty_reset
)
202 reset_terminal(tty_path(context
));
204 if (context
->tty_vt_disallocate
&& context
->tty_path
)
205 vt_disallocate(context
->tty_path
);
208 static bool is_terminal_output(ExecOutput o
) {
210 o
== EXEC_OUTPUT_TTY
||
211 o
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
212 o
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
213 o
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
;
216 static int open_null_as(int flags
, int nfd
) {
221 fd
= open("/dev/null", flags
|O_NOCTTY
);
226 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
234 static int connect_journal_socket(int fd
, uid_t uid
, gid_t gid
) {
235 union sockaddr_union sa
= {
236 .un
.sun_family
= AF_UNIX
,
237 .un
.sun_path
= "/run/systemd/journal/stdout",
239 uid_t olduid
= UID_INVALID
;
240 gid_t oldgid
= GID_INVALID
;
243 if (gid
!= GID_INVALID
) {
251 if (uid
!= UID_INVALID
) {
261 r
= connect(fd
, &sa
.sa
, offsetof(struct sockaddr_un
, sun_path
) + strlen(sa
.un
.sun_path
));
265 /* If we fail to restore the uid or gid, things will likely
266 fail later on. This should only happen if an LSM interferes. */
268 if (uid
!= UID_INVALID
)
269 (void) seteuid(olduid
);
272 if (gid
!= GID_INVALID
)
273 (void) setegid(oldgid
);
278 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
) {
282 assert(output
< _EXEC_OUTPUT_MAX
);
286 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
290 r
= connect_journal_socket(fd
, uid
, gid
);
294 if (shutdown(fd
, SHUT_RD
) < 0) {
299 fd_inc_sndbuf(fd
, SNDBUF_SIZE
);
309 context
->syslog_identifier
? context
->syslog_identifier
: ident
,
311 context
->syslog_priority
,
312 !!context
->syslog_level_prefix
,
313 output
== EXEC_OUTPUT_SYSLOG
|| output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
,
314 output
== EXEC_OUTPUT_KMSG
|| output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
,
315 is_terminal_output(output
));
318 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
325 static int open_terminal_as(const char *path
, mode_t mode
, int nfd
) {
331 fd
= open_terminal(path
, mode
| O_NOCTTY
);
336 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
344 static bool is_terminal_input(ExecInput i
) {
346 i
== EXEC_INPUT_TTY
||
347 i
== EXEC_INPUT_TTY_FORCE
||
348 i
== EXEC_INPUT_TTY_FAIL
;
351 static int fixup_input(ExecInput std_input
, int socket_fd
, bool apply_tty_stdin
) {
353 if (is_terminal_input(std_input
) && !apply_tty_stdin
)
354 return EXEC_INPUT_NULL
;
356 if (std_input
== EXEC_INPUT_SOCKET
&& socket_fd
< 0)
357 return EXEC_INPUT_NULL
;
362 static int fixup_output(ExecOutput std_output
, int socket_fd
) {
364 if (std_output
== EXEC_OUTPUT_SOCKET
&& socket_fd
< 0)
365 return EXEC_OUTPUT_INHERIT
;
370 static int setup_input(
371 const ExecContext
*context
,
372 const ExecParameters
*params
,
380 if (params
->stdin_fd
>= 0) {
381 if (dup2(params
->stdin_fd
, STDIN_FILENO
) < 0)
384 /* Try to make this the controlling tty, if it is a tty, and reset it */
385 (void) ioctl(STDIN_FILENO
, TIOCSCTTY
, context
->std_input
== EXEC_INPUT_TTY_FORCE
);
386 (void) reset_terminal_fd(STDIN_FILENO
, true);
391 i
= fixup_input(context
->std_input
, socket_fd
, params
->apply_tty_stdin
);
395 case EXEC_INPUT_NULL
:
396 return open_null_as(O_RDONLY
, STDIN_FILENO
);
399 case EXEC_INPUT_TTY_FORCE
:
400 case EXEC_INPUT_TTY_FAIL
: {
403 fd
= acquire_terminal(tty_path(context
),
404 i
== EXEC_INPUT_TTY_FAIL
,
405 i
== EXEC_INPUT_TTY_FORCE
,
411 if (fd
!= STDIN_FILENO
) {
412 r
= dup2(fd
, STDIN_FILENO
) < 0 ? -errno
: STDIN_FILENO
;
420 case EXEC_INPUT_SOCKET
:
421 return dup2(socket_fd
, STDIN_FILENO
) < 0 ? -errno
: STDIN_FILENO
;
424 assert_not_reached("Unknown input type");
428 static int setup_output(
430 const ExecContext
*context
,
431 const ExecParameters
*params
,
435 uid_t uid
, gid_t gid
) {
446 if (fileno
== STDOUT_FILENO
&& params
->stdout_fd
>= 0) {
448 if (dup2(params
->stdout_fd
, STDOUT_FILENO
) < 0)
451 return STDOUT_FILENO
;
454 if (fileno
== STDERR_FILENO
&& params
->stderr_fd
>= 0) {
455 if (dup2(params
->stderr_fd
, STDERR_FILENO
) < 0)
458 return STDERR_FILENO
;
461 i
= fixup_input(context
->std_input
, socket_fd
, params
->apply_tty_stdin
);
462 o
= fixup_output(context
->std_output
, socket_fd
);
464 if (fileno
== STDERR_FILENO
) {
466 e
= fixup_output(context
->std_error
, socket_fd
);
468 /* This expects the input and output are already set up */
470 /* Don't change the stderr file descriptor if we inherit all
471 * the way and are not on a tty */
472 if (e
== EXEC_OUTPUT_INHERIT
&&
473 o
== EXEC_OUTPUT_INHERIT
&&
474 i
== EXEC_INPUT_NULL
&&
475 !is_terminal_input(context
->std_input
) &&
479 /* Duplicate from stdout if possible */
480 if (e
== o
|| e
== EXEC_OUTPUT_INHERIT
)
481 return dup2(STDOUT_FILENO
, fileno
) < 0 ? -errno
: fileno
;
485 } else if (o
== EXEC_OUTPUT_INHERIT
) {
486 /* If input got downgraded, inherit the original value */
487 if (i
== EXEC_INPUT_NULL
&& is_terminal_input(context
->std_input
))
488 return open_terminal_as(tty_path(context
), O_WRONLY
, fileno
);
490 /* If the input is connected to anything that's not a /dev/null, inherit that... */
491 if (i
!= EXEC_INPUT_NULL
)
492 return dup2(STDIN_FILENO
, fileno
) < 0 ? -errno
: fileno
;
494 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
498 /* We need to open /dev/null here anew, to get the right access mode. */
499 return open_null_as(O_WRONLY
, fileno
);
504 case EXEC_OUTPUT_NULL
:
505 return open_null_as(O_WRONLY
, fileno
);
507 case EXEC_OUTPUT_TTY
:
508 if (is_terminal_input(i
))
509 return dup2(STDIN_FILENO
, fileno
) < 0 ? -errno
: fileno
;
511 /* We don't reset the terminal if this is just about output */
512 return open_terminal_as(tty_path(context
), O_WRONLY
, fileno
);
514 case EXEC_OUTPUT_SYSLOG
:
515 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE
:
516 case EXEC_OUTPUT_KMSG
:
517 case EXEC_OUTPUT_KMSG_AND_CONSOLE
:
518 case EXEC_OUTPUT_JOURNAL
:
519 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE
:
520 r
= connect_logger_as(context
, o
, ident
, unit
->id
, fileno
, uid
, gid
);
522 log_unit_error_errno(unit
, r
, "Failed to connect %s to the journal socket, ignoring: %m", fileno
== STDOUT_FILENO
? "stdout" : "stderr");
523 r
= open_null_as(O_WRONLY
, fileno
);
527 case EXEC_OUTPUT_SOCKET
:
528 assert(socket_fd
>= 0);
529 return dup2(socket_fd
, fileno
) < 0 ? -errno
: fileno
;
532 assert_not_reached("Unknown error type");
536 static int chown_terminal(int fd
, uid_t uid
) {
541 /* This might fail. What matters are the results. */
542 (void) fchown(fd
, uid
, -1);
543 (void) fchmod(fd
, TTY_MODE
);
545 if (fstat(fd
, &st
) < 0)
548 if (st
.st_uid
!= uid
|| (st
.st_mode
& 0777) != TTY_MODE
)
554 static int setup_confirm_stdio(int *_saved_stdin
, int *_saved_stdout
) {
555 _cleanup_close_
int fd
= -1, saved_stdin
= -1, saved_stdout
= -1;
558 assert(_saved_stdin
);
559 assert(_saved_stdout
);
561 saved_stdin
= fcntl(STDIN_FILENO
, F_DUPFD
, 3);
565 saved_stdout
= fcntl(STDOUT_FILENO
, F_DUPFD
, 3);
566 if (saved_stdout
< 0)
569 fd
= acquire_terminal(
574 DEFAULT_CONFIRM_USEC
);
578 r
= chown_terminal(fd
, getuid());
582 r
= reset_terminal_fd(fd
, true);
586 if (dup2(fd
, STDIN_FILENO
) < 0)
589 if (dup2(fd
, STDOUT_FILENO
) < 0)
596 *_saved_stdin
= saved_stdin
;
597 *_saved_stdout
= saved_stdout
;
599 saved_stdin
= saved_stdout
= -1;
604 _printf_(1, 2) static int write_confirm_message(const char *format
, ...) {
605 _cleanup_close_
int fd
= -1;
610 fd
= open_terminal("/dev/console", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
614 va_start(ap
, format
);
615 vdprintf(fd
, format
, ap
);
621 static int restore_confirm_stdio(int *saved_stdin
, int *saved_stdout
) {
625 assert(saved_stdout
);
629 if (*saved_stdin
>= 0)
630 if (dup2(*saved_stdin
, STDIN_FILENO
) < 0)
633 if (*saved_stdout
>= 0)
634 if (dup2(*saved_stdout
, STDOUT_FILENO
) < 0)
637 *saved_stdin
= safe_close(*saved_stdin
);
638 *saved_stdout
= safe_close(*saved_stdout
);
643 static int ask_for_confirmation(char *response
, char **argv
) {
644 int saved_stdout
= -1, saved_stdin
= -1, r
;
645 _cleanup_free_
char *line
= NULL
;
647 r
= setup_confirm_stdio(&saved_stdin
, &saved_stdout
);
651 line
= exec_command_line(argv
);
655 r
= ask_char(response
, "yns", "Execute %s? [Yes, No, Skip] ", line
);
657 restore_confirm_stdio(&saved_stdin
, &saved_stdout
);
662 static int enforce_groups(const ExecContext
*context
, const char *username
, gid_t gid
) {
663 bool keep_groups
= false;
668 /* Lookup and set GID and supplementary group list. Here too
669 * we avoid NSS lookups for gid=0. */
671 if (context
->group
|| username
) {
672 /* First step, initialize groups from /etc/groups */
673 if (username
&& gid
!= 0) {
674 if (initgroups(username
, gid
) < 0)
680 /* Second step, set our gids */
681 if (setresgid(gid
, gid
, gid
) < 0)
685 if (context
->supplementary_groups
) {
690 /* Final step, initialize any manually set supplementary groups */
691 assert_se((ngroups_max
= (int) sysconf(_SC_NGROUPS_MAX
)) > 0);
693 if (!(gids
= new(gid_t
, ngroups_max
)))
697 k
= getgroups(ngroups_max
, gids
);
705 STRV_FOREACH(i
, context
->supplementary_groups
) {
708 if (k
>= ngroups_max
) {
714 r
= get_group_creds(&g
, gids
+k
);
723 if (setgroups(k
, gids
) < 0) {
734 static int enforce_user(const ExecContext
*context
, uid_t uid
) {
737 /* Sets (but doesn't lookup) the uid and make sure we keep the
738 * capabilities while doing so. */
740 if (context
->capabilities
) {
741 _cleanup_cap_free_ cap_t d
= NULL
;
742 static const cap_value_t bits
[] = {
743 CAP_SETUID
, /* Necessary so that we can run setresuid() below */
744 CAP_SETPCAP
/* Necessary so that we can set PR_SET_SECUREBITS later on */
747 /* First step: If we need to keep capabilities but
748 * drop privileges we need to make sure we keep our
749 * caps, while we drop privileges. */
751 int sb
= context
->secure_bits
| 1<<SECURE_KEEP_CAPS
;
753 if (prctl(PR_GET_SECUREBITS
) != sb
)
754 if (prctl(PR_SET_SECUREBITS
, sb
) < 0)
758 /* Second step: set the capabilities. This will reduce
759 * the capabilities to the minimum we need. */
761 d
= cap_dup(context
->capabilities
);
765 if (cap_set_flag(d
, CAP_EFFECTIVE
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0 ||
766 cap_set_flag(d
, CAP_PERMITTED
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0)
769 if (cap_set_proc(d
) < 0)
773 /* Third step: actually set the uids */
774 if (setresuid(uid
, uid
, uid
) < 0)
777 /* At this point we should have all necessary capabilities but
778 are otherwise a normal user. However, the caps might got
779 corrupted due to the setresuid() so we need clean them up
780 later. This is done outside of this call. */
787 static int null_conv(
789 const struct pam_message
**msg
,
790 struct pam_response
**resp
,
793 /* We don't support conversations */
798 static int setup_pam(
804 int fds
[], unsigned n_fds
) {
806 static const struct pam_conv conv
= {
811 _cleanup_(barrier_destroy
) Barrier barrier
= BARRIER_NULL
;
812 pam_handle_t
*handle
= NULL
;
814 int pam_code
= PAM_SUCCESS
;
817 bool close_session
= false;
818 pid_t pam_pid
= 0, parent_pid
;
825 /* We set up PAM in the parent process, then fork. The child
826 * will then stay around until killed via PR_GET_PDEATHSIG or
827 * systemd via the cgroup logic. It will then remove the PAM
828 * session again. The parent process will exec() the actual
829 * daemon. We do things this way to ensure that the main PID
830 * of the daemon is the one we initially fork()ed. */
832 err
= barrier_create(&barrier
);
836 if (log_get_max_level() < LOG_DEBUG
)
839 pam_code
= pam_start(name
, user
, &conv
, &handle
);
840 if (pam_code
!= PAM_SUCCESS
) {
846 pam_code
= pam_set_item(handle
, PAM_TTY
, tty
);
847 if (pam_code
!= PAM_SUCCESS
)
851 pam_code
= pam_acct_mgmt(handle
, flags
);
852 if (pam_code
!= PAM_SUCCESS
)
855 pam_code
= pam_open_session(handle
, flags
);
856 if (pam_code
!= PAM_SUCCESS
)
859 close_session
= true;
861 e
= pam_getenvlist(handle
);
863 pam_code
= PAM_BUF_ERR
;
867 /* Block SIGTERM, so that we know that it won't get lost in
870 assert_se(sigprocmask_many(SIG_BLOCK
, &old_ss
, SIGTERM
, -1) >= 0);
872 parent_pid
= getpid();
882 /* The child's job is to reset the PAM session on
884 barrier_set_role(&barrier
, BARRIER_CHILD
);
886 /* This string must fit in 10 chars (i.e. the length
887 * of "/sbin/init"), to look pretty in /bin/ps */
888 rename_process("(sd-pam)");
890 /* Make sure we don't keep open the passed fds in this
891 child. We assume that otherwise only those fds are
892 open here that have been opened by PAM. */
893 close_many(fds
, n_fds
);
895 /* Drop privileges - we don't need any to pam_close_session
896 * and this will make PR_SET_PDEATHSIG work in most cases.
897 * If this fails, ignore the error - but expect sd-pam threads
898 * to fail to exit normally */
899 if (setresuid(uid
, uid
, uid
) < 0)
900 log_error_errno(r
, "Error: Failed to setresuid() in sd-pam: %m");
902 (void) ignore_signals(SIGPIPE
, -1);
904 /* Wait until our parent died. This will only work if
905 * the above setresuid() succeeds, otherwise the kernel
906 * will not allow unprivileged parents kill their privileged
907 * children this way. We rely on the control groups kill logic
908 * to do the rest for us. */
909 if (prctl(PR_SET_PDEATHSIG
, SIGTERM
) < 0)
912 /* Tell the parent that our setup is done. This is especially
913 * important regarding dropping privileges. Otherwise, unit
914 * setup might race against our setresuid(2) call. */
915 barrier_place(&barrier
);
917 /* Check if our parent process might already have
919 if (getppid() == parent_pid
) {
922 assert_se(sigemptyset(&ss
) >= 0);
923 assert_se(sigaddset(&ss
, SIGTERM
) >= 0);
926 if (sigwait(&ss
, &sig
) < 0) {
933 assert(sig
== SIGTERM
);
938 /* If our parent died we'll end the session */
939 if (getppid() != parent_pid
) {
940 pam_code
= pam_close_session(handle
, flags
);
941 if (pam_code
!= PAM_SUCCESS
)
948 pam_end(handle
, pam_code
| flags
);
952 barrier_set_role(&barrier
, BARRIER_PARENT
);
954 /* If the child was forked off successfully it will do all the
955 * cleanups, so forget about the handle here. */
958 /* Unblock SIGTERM again in the parent */
959 assert_se(sigprocmask(SIG_SETMASK
, &old_ss
, NULL
) >= 0);
961 /* We close the log explicitly here, since the PAM modules
962 * might have opened it, but we don't want this fd around. */
965 /* Synchronously wait for the child to initialize. We don't care for
966 * errors as we cannot recover. However, warn loudly if it happens. */
967 if (!barrier_place_and_sync(&barrier
))
968 log_error("PAM initialization failed");
976 if (pam_code
!= PAM_SUCCESS
) {
977 log_error("PAM failed: %s", pam_strerror(handle
, pam_code
));
978 err
= -EPERM
; /* PAM errors do not map to errno */
980 err
= log_error_errno(err
< 0 ? err
: errno
, "PAM failed: %m");
985 pam_code
= pam_close_session(handle
, flags
);
987 pam_end(handle
, pam_code
| flags
);
995 kill(pam_pid
, SIGTERM
);
996 kill(pam_pid
, SIGCONT
);
1003 static void rename_process_from_path(const char *path
) {
1004 char process_name
[11];
1008 /* This resulting string must fit in 10 chars (i.e. the length
1009 * of "/sbin/init") to look pretty in /bin/ps */
1013 rename_process("(...)");
1019 /* The end of the process name is usually more
1020 * interesting, since the first bit might just be
1026 process_name
[0] = '(';
1027 memcpy(process_name
+1, p
, l
);
1028 process_name
[1+l
] = ')';
1029 process_name
[1+l
+1] = 0;
1031 rename_process(process_name
);
1036 static int apply_seccomp(const ExecContext
*c
) {
1037 uint32_t negative_action
, action
;
1038 scmp_filter_ctx
*seccomp
;
1045 negative_action
= c
->syscall_errno
== 0 ? SCMP_ACT_KILL
: SCMP_ACT_ERRNO(c
->syscall_errno
);
1047 seccomp
= seccomp_init(c
->syscall_whitelist
? negative_action
: SCMP_ACT_ALLOW
);
1051 if (c
->syscall_archs
) {
1053 SET_FOREACH(id
, c
->syscall_archs
, i
) {
1054 r
= seccomp_arch_add(seccomp
, PTR_TO_UINT32(id
) - 1);
1062 r
= seccomp_add_secondary_archs(seccomp
);
1067 action
= c
->syscall_whitelist
? SCMP_ACT_ALLOW
: negative_action
;
1068 SET_FOREACH(id
, c
->syscall_filter
, i
) {
1069 r
= seccomp_rule_add(seccomp
, action
, PTR_TO_INT(id
) - 1, 0);
1074 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1078 r
= seccomp_load(seccomp
);
1081 seccomp_release(seccomp
);
1085 static int apply_address_families(const ExecContext
*c
) {
1086 scmp_filter_ctx
*seccomp
;
1092 seccomp
= seccomp_init(SCMP_ACT_ALLOW
);
1096 r
= seccomp_add_secondary_archs(seccomp
);
1100 if (c
->address_families_whitelist
) {
1101 int af
, first
= 0, last
= 0;
1104 /* If this is a whitelist, we first block the address
1105 * families that are out of range and then everything
1106 * that is not in the set. First, we find the lowest
1107 * and highest address family in the set. */
1109 SET_FOREACH(afp
, c
->address_families
, i
) {
1110 af
= PTR_TO_INT(afp
);
1112 if (af
<= 0 || af
>= af_max())
1115 if (first
== 0 || af
< first
)
1118 if (last
== 0 || af
> last
)
1122 assert((first
== 0) == (last
== 0));
1126 /* No entries in the valid range, block everything */
1127 r
= seccomp_rule_add(
1129 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1137 /* Block everything below the first entry */
1138 r
= seccomp_rule_add(
1140 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1143 SCMP_A0(SCMP_CMP_LT
, first
));
1147 /* Block everything above the last entry */
1148 r
= seccomp_rule_add(
1150 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1153 SCMP_A0(SCMP_CMP_GT
, last
));
1157 /* Block everything between the first and last
1159 for (af
= 1; af
< af_max(); af
++) {
1161 if (set_contains(c
->address_families
, INT_TO_PTR(af
)))
1164 r
= seccomp_rule_add(
1166 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1169 SCMP_A0(SCMP_CMP_EQ
, af
));
1178 /* If this is a blacklist, then generate one rule for
1179 * each address family that are then combined in OR
1182 SET_FOREACH(af
, c
->address_families
, i
) {
1184 r
= seccomp_rule_add(
1186 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1189 SCMP_A0(SCMP_CMP_EQ
, PTR_TO_INT(af
)));
1195 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1199 r
= seccomp_load(seccomp
);
1202 seccomp_release(seccomp
);
1208 static void do_idle_pipe_dance(int idle_pipe
[4]) {
1212 idle_pipe
[1] = safe_close(idle_pipe
[1]);
1213 idle_pipe
[2] = safe_close(idle_pipe
[2]);
1215 if (idle_pipe
[0] >= 0) {
1218 r
= fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT_USEC
);
1220 if (idle_pipe
[3] >= 0 && r
== 0 /* timeout */) {
1223 /* Signal systemd that we are bored and want to continue. */
1224 n
= write(idle_pipe
[3], "x", 1);
1226 /* Wait for systemd to react to the signal above. */
1227 fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT2_USEC
);
1230 idle_pipe
[0] = safe_close(idle_pipe
[0]);
1234 idle_pipe
[3] = safe_close(idle_pipe
[3]);
1237 static int build_environment(
1238 const ExecContext
*c
,
1241 usec_t watchdog_usec
,
1243 const char *username
,
1247 _cleanup_strv_free_
char **our_env
= NULL
;
1254 our_env
= new0(char*, 11);
1259 _cleanup_free_
char *joined
= NULL
;
1261 if (asprintf(&x
, "LISTEN_PID="PID_FMT
, getpid()) < 0)
1263 our_env
[n_env
++] = x
;
1265 if (asprintf(&x
, "LISTEN_FDS=%u", n_fds
) < 0)
1267 our_env
[n_env
++] = x
;
1269 joined
= strv_join(fd_names
, ":");
1273 x
= strjoin("LISTEN_FDNAMES=", joined
, NULL
);
1276 our_env
[n_env
++] = x
;
1279 if (watchdog_usec
> 0) {
1280 if (asprintf(&x
, "WATCHDOG_PID="PID_FMT
, getpid()) < 0)
1282 our_env
[n_env
++] = x
;
1284 if (asprintf(&x
, "WATCHDOG_USEC="USEC_FMT
, watchdog_usec
) < 0)
1286 our_env
[n_env
++] = x
;
1290 x
= strappend("HOME=", home
);
1293 our_env
[n_env
++] = x
;
1297 x
= strappend("LOGNAME=", username
);
1300 our_env
[n_env
++] = x
;
1302 x
= strappend("USER=", username
);
1305 our_env
[n_env
++] = x
;
1309 x
= strappend("SHELL=", shell
);
1312 our_env
[n_env
++] = x
;
1315 if (is_terminal_input(c
->std_input
) ||
1316 c
->std_output
== EXEC_OUTPUT_TTY
||
1317 c
->std_error
== EXEC_OUTPUT_TTY
||
1320 x
= strdup(default_term_for_tty(tty_path(c
)));
1323 our_env
[n_env
++] = x
;
1326 our_env
[n_env
++] = NULL
;
1327 assert(n_env
<= 11);
1335 static int build_pass_environment(const ExecContext
*c
, char ***ret
) {
1336 _cleanup_strv_free_
char **pass_env
= NULL
;
1337 size_t n_env
= 0, n_bufsize
= 0;
1340 STRV_FOREACH(i
, c
->pass_environment
) {
1341 _cleanup_free_
char *x
= NULL
;
1347 x
= strjoin(*i
, "=", v
, NULL
);
1350 if (!GREEDY_REALLOC(pass_env
, n_bufsize
, n_env
+ 2))
1352 pass_env
[n_env
++] = x
;
1353 pass_env
[n_env
] = NULL
;
1363 static bool exec_needs_mount_namespace(
1364 const ExecContext
*context
,
1365 const ExecParameters
*params
,
1366 ExecRuntime
*runtime
) {
1371 if (!strv_isempty(context
->read_write_dirs
) ||
1372 !strv_isempty(context
->read_only_dirs
) ||
1373 !strv_isempty(context
->inaccessible_dirs
))
1376 if (context
->mount_flags
!= 0)
1379 if (context
->private_tmp
&& runtime
&& (runtime
->tmp_dir
|| runtime
->var_tmp_dir
))
1382 if (params
->bus_endpoint_path
)
1385 if (context
->private_devices
||
1386 context
->protect_system
!= PROTECT_SYSTEM_NO
||
1387 context
->protect_home
!= PROTECT_HOME_NO
)
1393 static int close_remaining_fds(
1394 const ExecParameters
*params
,
1395 ExecRuntime
*runtime
,
1397 int *fds
, unsigned n_fds
) {
1399 unsigned n_dont_close
= 0;
1400 int dont_close
[n_fds
+ 7];
1404 if (params
->stdin_fd
>= 0)
1405 dont_close
[n_dont_close
++] = params
->stdin_fd
;
1406 if (params
->stdout_fd
>= 0)
1407 dont_close
[n_dont_close
++] = params
->stdout_fd
;
1408 if (params
->stderr_fd
>= 0)
1409 dont_close
[n_dont_close
++] = params
->stderr_fd
;
1412 dont_close
[n_dont_close
++] = socket_fd
;
1414 memcpy(dont_close
+ n_dont_close
, fds
, sizeof(int) * n_fds
);
1415 n_dont_close
+= n_fds
;
1418 if (params
->bus_endpoint_fd
>= 0)
1419 dont_close
[n_dont_close
++] = params
->bus_endpoint_fd
;
1422 if (runtime
->netns_storage_socket
[0] >= 0)
1423 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[0];
1424 if (runtime
->netns_storage_socket
[1] >= 0)
1425 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[1];
1428 return close_all_fds(dont_close
, n_dont_close
);
1431 static int exec_child(
1433 ExecCommand
*command
,
1434 const ExecContext
*context
,
1435 const ExecParameters
*params
,
1436 ExecRuntime
*runtime
,
1439 int *fds
, unsigned n_fds
,
1443 _cleanup_strv_free_
char **our_env
= NULL
, **pass_env
= NULL
, **pam_env
= NULL
, **final_env
= NULL
, **final_argv
= NULL
;
1444 _cleanup_free_
char *mac_selinux_context_net
= NULL
;
1445 const char *username
= NULL
, *home
= NULL
, *shell
= NULL
, *wd
;
1446 uid_t uid
= UID_INVALID
;
1447 gid_t gid
= GID_INVALID
;
1449 bool needs_mount_namespace
;
1455 assert(exit_status
);
1457 rename_process_from_path(command
->path
);
1459 /* We reset exactly these signals, since they are the
1460 * only ones we set to SIG_IGN in the main daemon. All
1461 * others we leave untouched because we set them to
1462 * SIG_DFL or a valid handler initially, both of which
1463 * will be demoted to SIG_DFL. */
1464 (void) default_signals(SIGNALS_CRASH_HANDLER
,
1465 SIGNALS_IGNORE
, -1);
1467 if (context
->ignore_sigpipe
)
1468 (void) ignore_signals(SIGPIPE
, -1);
1470 r
= reset_signal_mask();
1472 *exit_status
= EXIT_SIGNAL_MASK
;
1476 if (params
->idle_pipe
)
1477 do_idle_pipe_dance(params
->idle_pipe
);
1479 /* Close sockets very early to make sure we don't
1480 * block init reexecution because it cannot bind its
1485 r
= close_remaining_fds(params
, runtime
, socket_fd
, fds
, n_fds
);
1487 *exit_status
= EXIT_FDS
;
1491 if (!context
->same_pgrp
)
1493 *exit_status
= EXIT_SETSID
;
1497 exec_context_tty_reset(context
);
1499 if (params
->confirm_spawn
) {
1502 r
= ask_for_confirmation(&response
, argv
);
1503 if (r
== -ETIMEDOUT
)
1504 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1506 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r
));
1507 else if (response
== 's') {
1508 write_confirm_message("Skipping execution.\n");
1509 *exit_status
= EXIT_CONFIRM
;
1511 } else if (response
== 'n') {
1512 write_confirm_message("Failing execution.\n");
1518 if (context
->user
) {
1519 username
= context
->user
;
1520 r
= get_user_creds(&username
, &uid
, &gid
, &home
, &shell
);
1522 *exit_status
= EXIT_USER
;
1527 if (context
->group
) {
1528 const char *g
= context
->group
;
1530 r
= get_group_creds(&g
, &gid
);
1532 *exit_status
= EXIT_GROUP
;
1538 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1539 * must sure to drop O_NONBLOCK */
1541 (void) fd_nonblock(socket_fd
, false);
1543 r
= setup_input(context
, params
, socket_fd
);
1545 *exit_status
= EXIT_STDIN
;
1549 r
= setup_output(unit
, context
, params
, STDOUT_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1551 *exit_status
= EXIT_STDOUT
;
1555 r
= setup_output(unit
, context
, params
, STDERR_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1557 *exit_status
= EXIT_STDERR
;
1561 if (params
->cgroup_path
) {
1562 r
= cg_attach_everywhere(params
->cgroup_supported
, params
->cgroup_path
, 0, NULL
, NULL
);
1564 *exit_status
= EXIT_CGROUP
;
1569 if (context
->oom_score_adjust_set
) {
1570 char t
[DECIMAL_STR_MAX(context
->oom_score_adjust
)];
1572 /* When we can't make this change due to EPERM, then
1573 * let's silently skip over it. User namespaces
1574 * prohibit write access to this file, and we
1575 * shouldn't trip up over that. */
1577 sprintf(t
, "%i", context
->oom_score_adjust
);
1578 r
= write_string_file("/proc/self/oom_score_adj", t
, 0);
1579 if (r
== -EPERM
|| r
== -EACCES
) {
1581 log_unit_debug_errno(unit
, r
, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
1584 *exit_status
= EXIT_OOM_ADJUST
;
1589 if (context
->nice_set
)
1590 if (setpriority(PRIO_PROCESS
, 0, context
->nice
) < 0) {
1591 *exit_status
= EXIT_NICE
;
1595 if (context
->cpu_sched_set
) {
1596 struct sched_param param
= {
1597 .sched_priority
= context
->cpu_sched_priority
,
1600 r
= sched_setscheduler(0,
1601 context
->cpu_sched_policy
|
1602 (context
->cpu_sched_reset_on_fork
?
1603 SCHED_RESET_ON_FORK
: 0),
1606 *exit_status
= EXIT_SETSCHEDULER
;
1611 if (context
->cpuset
)
1612 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context
->cpuset_ncpus
), context
->cpuset
) < 0) {
1613 *exit_status
= EXIT_CPUAFFINITY
;
1617 if (context
->ioprio_set
)
1618 if (ioprio_set(IOPRIO_WHO_PROCESS
, 0, context
->ioprio
) < 0) {
1619 *exit_status
= EXIT_IOPRIO
;
1623 if (context
->timer_slack_nsec
!= NSEC_INFINITY
)
1624 if (prctl(PR_SET_TIMERSLACK
, context
->timer_slack_nsec
) < 0) {
1625 *exit_status
= EXIT_TIMERSLACK
;
1629 if (context
->personality
!= PERSONALITY_INVALID
)
1630 if (personality(context
->personality
) < 0) {
1631 *exit_status
= EXIT_PERSONALITY
;
1635 if (context
->utmp_id
)
1636 utmp_put_init_process(context
->utmp_id
, getpid(), getsid(0), context
->tty_path
,
1637 context
->utmp_mode
== EXEC_UTMP_INIT
? INIT_PROCESS
:
1638 context
->utmp_mode
== EXEC_UTMP_LOGIN
? LOGIN_PROCESS
:
1640 username
? "root" : context
->user
);
1642 if (context
->user
&& is_terminal_input(context
->std_input
)) {
1643 r
= chown_terminal(STDIN_FILENO
, uid
);
1645 *exit_status
= EXIT_STDIN
;
1650 if (params
->bus_endpoint_fd
>= 0 && context
->bus_endpoint
) {
1651 uid_t ep_uid
= (uid
== UID_INVALID
) ? 0 : uid
;
1653 r
= bus_kernel_set_endpoint_policy(params
->bus_endpoint_fd
, ep_uid
, context
->bus_endpoint
);
1655 *exit_status
= EXIT_BUS_ENDPOINT
;
1660 /* If delegation is enabled we'll pass ownership of the cgroup
1661 * (but only in systemd's own controller hierarchy!) to the
1662 * user of the new process. */
1663 if (params
->cgroup_path
&& context
->user
&& params
->cgroup_delegate
) {
1664 r
= cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0644, uid
, gid
);
1666 *exit_status
= EXIT_CGROUP
;
1671 r
= cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0755, uid
, gid
);
1673 *exit_status
= EXIT_CGROUP
;
1678 if (!strv_isempty(context
->runtime_directory
) && params
->runtime_prefix
) {
1681 STRV_FOREACH(rt
, context
->runtime_directory
) {
1682 _cleanup_free_
char *p
;
1684 p
= strjoin(params
->runtime_prefix
, "/", *rt
, NULL
);
1686 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1690 r
= mkdir_p_label(p
, context
->runtime_directory_mode
);
1692 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1696 r
= chmod_and_chown(p
, context
->runtime_directory_mode
, uid
, gid
);
1698 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1704 umask(context
->umask
);
1706 if (params
->apply_permissions
) {
1707 r
= enforce_groups(context
, username
, gid
);
1709 *exit_status
= EXIT_GROUP
;
1713 if (context
->smack_process_label
) {
1714 r
= mac_smack_apply_pid(0, context
->smack_process_label
);
1716 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1720 #ifdef SMACK_DEFAULT_PROCESS_LABEL
1722 _cleanup_free_
char *exec_label
= NULL
;
1724 r
= mac_smack_read(command
->path
, SMACK_ATTR_EXEC
, &exec_label
);
1725 if (r
< 0 && r
!= -ENODATA
&& r
!= -EOPNOTSUPP
) {
1726 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1730 r
= mac_smack_apply_pid(0, exec_label
? : SMACK_DEFAULT_PROCESS_LABEL
);
1732 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1739 if (context
->pam_name
&& username
) {
1740 r
= setup_pam(context
->pam_name
, username
, uid
, context
->tty_path
, &pam_env
, fds
, n_fds
);
1742 *exit_status
= EXIT_PAM
;
1749 if (context
->private_network
&& runtime
&& runtime
->netns_storage_socket
[0] >= 0) {
1750 r
= setup_netns(runtime
->netns_storage_socket
);
1752 *exit_status
= EXIT_NETWORK
;
1757 needs_mount_namespace
= exec_needs_mount_namespace(context
, params
, runtime
);
1759 if (needs_mount_namespace
) {
1760 char *tmp
= NULL
, *var
= NULL
;
1762 /* The runtime struct only contains the parent
1763 * of the private /tmp, which is
1764 * non-accessible to world users. Inside of it
1765 * there's a /tmp that is sticky, and that's
1766 * the one we want to use here. */
1768 if (context
->private_tmp
&& runtime
) {
1769 if (runtime
->tmp_dir
)
1770 tmp
= strjoina(runtime
->tmp_dir
, "/tmp");
1771 if (runtime
->var_tmp_dir
)
1772 var
= strjoina(runtime
->var_tmp_dir
, "/tmp");
1775 r
= setup_namespace(
1776 params
->apply_chroot
? context
->root_directory
: NULL
,
1777 context
->read_write_dirs
,
1778 context
->read_only_dirs
,
1779 context
->inaccessible_dirs
,
1782 params
->bus_endpoint_path
,
1783 context
->private_devices
,
1784 context
->protect_home
,
1785 context
->protect_system
,
1786 context
->mount_flags
);
1788 /* If we couldn't set up the namespace this is
1789 * probably due to a missing capability. In this case,
1790 * silently proceeed. */
1791 if (r
== -EPERM
|| r
== -EACCES
) {
1793 log_unit_debug_errno(unit
, r
, "Failed to set up namespace, assuming containerized execution, ignoring: %m");
1796 *exit_status
= EXIT_NAMESPACE
;
1801 if (context
->working_directory_home
)
1803 else if (context
->working_directory
)
1804 wd
= context
->working_directory
;
1808 if (params
->apply_chroot
) {
1809 if (!needs_mount_namespace
&& context
->root_directory
)
1810 if (chroot(context
->root_directory
) < 0) {
1811 *exit_status
= EXIT_CHROOT
;
1815 if (chdir(wd
) < 0 &&
1816 !context
->working_directory_missing_ok
) {
1817 *exit_status
= EXIT_CHDIR
;
1823 d
= strjoina(strempty(context
->root_directory
), "/", strempty(wd
));
1825 !context
->working_directory_missing_ok
) {
1826 *exit_status
= EXIT_CHDIR
;
1832 if (params
->apply_permissions
&& mac_selinux_use() && params
->selinux_context_net
&& socket_fd
>= 0) {
1833 r
= mac_selinux_get_child_mls_label(socket_fd
, command
->path
, context
->selinux_context
, &mac_selinux_context_net
);
1835 *exit_status
= EXIT_SELINUX_CONTEXT
;
1841 /* We repeat the fd closing here, to make sure that
1842 * nothing is leaked from the PAM modules. Note that
1843 * we are more aggressive this time since socket_fd
1844 * and the netns fds we don't need anymore. The custom
1845 * endpoint fd was needed to upload the policy and can
1846 * now be closed as well. */
1847 r
= close_all_fds(fds
, n_fds
);
1849 r
= shift_fds(fds
, n_fds
);
1851 r
= flags_fds(fds
, n_fds
, context
->non_blocking
);
1853 *exit_status
= EXIT_FDS
;
1857 if (params
->apply_permissions
) {
1859 for (i
= 0; i
< _RLIMIT_MAX
; i
++) {
1860 if (!context
->rlimit
[i
])
1863 if (setrlimit_closest(i
, context
->rlimit
[i
]) < 0) {
1864 *exit_status
= EXIT_LIMITS
;
1869 if (context
->capability_bounding_set_drop
) {
1870 r
= capability_bounding_set_drop(context
->capability_bounding_set_drop
, false);
1872 *exit_status
= EXIT_CAPABILITIES
;
1877 if (context
->user
) {
1878 r
= enforce_user(context
, uid
);
1880 *exit_status
= EXIT_USER
;
1885 /* PR_GET_SECUREBITS is not privileged, while
1886 * PR_SET_SECUREBITS is. So to suppress
1887 * potential EPERMs we'll try not to call
1888 * PR_SET_SECUREBITS unless necessary. */
1889 if (prctl(PR_GET_SECUREBITS
) != context
->secure_bits
)
1890 if (prctl(PR_SET_SECUREBITS
, context
->secure_bits
) < 0) {
1891 *exit_status
= EXIT_SECUREBITS
;
1895 if (context
->capabilities
)
1896 if (cap_set_proc(context
->capabilities
) < 0) {
1897 *exit_status
= EXIT_CAPABILITIES
;
1901 if (context
->no_new_privileges
)
1902 if (prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0) < 0) {
1903 *exit_status
= EXIT_NO_NEW_PRIVILEGES
;
1908 if (context
->address_families_whitelist
||
1909 !set_isempty(context
->address_families
)) {
1910 r
= apply_address_families(context
);
1912 *exit_status
= EXIT_ADDRESS_FAMILIES
;
1917 if (context
->syscall_whitelist
||
1918 !set_isempty(context
->syscall_filter
) ||
1919 !set_isempty(context
->syscall_archs
)) {
1920 r
= apply_seccomp(context
);
1922 *exit_status
= EXIT_SECCOMP
;
1929 if (mac_selinux_use()) {
1930 char *exec_context
= mac_selinux_context_net
?: context
->selinux_context
;
1933 r
= setexeccon(exec_context
);
1935 *exit_status
= EXIT_SELINUX_CONTEXT
;
1942 #ifdef HAVE_APPARMOR
1943 if (context
->apparmor_profile
&& mac_apparmor_use()) {
1944 r
= aa_change_onexec(context
->apparmor_profile
);
1945 if (r
< 0 && !context
->apparmor_profile_ignore
) {
1946 *exit_status
= EXIT_APPARMOR_PROFILE
;
1953 r
= build_environment(context
, n_fds
, params
->fd_names
, params
->watchdog_usec
, home
, username
, shell
, &our_env
);
1955 *exit_status
= EXIT_MEMORY
;
1959 r
= build_pass_environment(context
, &pass_env
);
1961 *exit_status
= EXIT_MEMORY
;
1965 final_env
= strv_env_merge(6,
1966 params
->environment
,
1969 context
->environment
,
1974 *exit_status
= EXIT_MEMORY
;
1978 final_argv
= replace_env_argv(argv
, final_env
);
1980 *exit_status
= EXIT_MEMORY
;
1984 final_env
= strv_env_clean(final_env
);
1986 if (_unlikely_(log_get_max_level() >= LOG_DEBUG
)) {
1987 _cleanup_free_
char *line
;
1989 line
= exec_command_line(final_argv
);
1992 log_struct(LOG_DEBUG
,
1994 "EXECUTABLE=%s", command
->path
,
1995 LOG_UNIT_MESSAGE(unit
, "Executing: %s", line
),
2001 execve(command
->path
, final_argv
, final_env
);
2002 *exit_status
= EXIT_EXEC
;
2006 int exec_spawn(Unit
*unit
,
2007 ExecCommand
*command
,
2008 const ExecContext
*context
,
2009 const ExecParameters
*params
,
2010 ExecRuntime
*runtime
,
2013 _cleanup_strv_free_
char **files_env
= NULL
;
2014 int *fds
= NULL
; unsigned n_fds
= 0;
2015 _cleanup_free_
char *line
= NULL
;
2025 assert(params
->fds
|| params
->n_fds
<= 0);
2027 if (context
->std_input
== EXEC_INPUT_SOCKET
||
2028 context
->std_output
== EXEC_OUTPUT_SOCKET
||
2029 context
->std_error
== EXEC_OUTPUT_SOCKET
) {
2031 if (params
->n_fds
!= 1) {
2032 log_unit_error(unit
, "Got more than one socket.");
2036 socket_fd
= params
->fds
[0];
2040 n_fds
= params
->n_fds
;
2043 r
= exec_context_load_environment(unit
, context
, &files_env
);
2045 return log_unit_error_errno(unit
, r
, "Failed to load environment files: %m");
2047 argv
= params
->argv
?: command
->argv
;
2048 line
= exec_command_line(argv
);
2052 log_struct(LOG_DEBUG
,
2054 LOG_UNIT_MESSAGE(unit
, "About to execute: %s", line
),
2055 "EXECUTABLE=%s", command
->path
,
2059 return log_unit_error_errno(unit
, r
, "Failed to fork: %m");
2064 r
= exec_child(unit
,
2076 log_struct_errno(LOG_ERR
, r
,
2077 LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED
),
2079 LOG_UNIT_MESSAGE(unit
, "Failed at step %s spawning %s: %m",
2080 exit_status_to_string(exit_status
, EXIT_STATUS_SYSTEMD
),
2082 "EXECUTABLE=%s", command
->path
,
2089 log_unit_debug(unit
, "Forked %s as "PID_FMT
, command
->path
, pid
);
2091 /* We add the new process to the cgroup both in the child (so
2092 * that we can be sure that no user code is ever executed
2093 * outside of the cgroup) and in the parent (so that we can be
2094 * sure that when we kill the cgroup the process will be
2096 if (params
->cgroup_path
)
2097 (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, pid
);
2099 exec_status_start(&command
->exec_status
, pid
);
2105 void exec_context_init(ExecContext
*c
) {
2109 c
->ioprio
= IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE
, 0);
2110 c
->cpu_sched_policy
= SCHED_OTHER
;
2111 c
->syslog_priority
= LOG_DAEMON
|LOG_INFO
;
2112 c
->syslog_level_prefix
= true;
2113 c
->ignore_sigpipe
= true;
2114 c
->timer_slack_nsec
= NSEC_INFINITY
;
2115 c
->personality
= PERSONALITY_INVALID
;
2116 c
->runtime_directory_mode
= 0755;
2119 void exec_context_done(ExecContext
*c
) {
2124 c
->environment
= strv_free(c
->environment
);
2125 c
->environment_files
= strv_free(c
->environment_files
);
2126 c
->pass_environment
= strv_free(c
->pass_environment
);
2128 for (l
= 0; l
< ELEMENTSOF(c
->rlimit
); l
++)
2129 c
->rlimit
[l
] = mfree(c
->rlimit
[l
]);
2131 c
->working_directory
= mfree(c
->working_directory
);
2132 c
->root_directory
= mfree(c
->root_directory
);
2133 c
->tty_path
= mfree(c
->tty_path
);
2134 c
->syslog_identifier
= mfree(c
->syslog_identifier
);
2135 c
->user
= mfree(c
->user
);
2136 c
->group
= mfree(c
->group
);
2138 c
->supplementary_groups
= strv_free(c
->supplementary_groups
);
2140 c
->pam_name
= mfree(c
->pam_name
);
2142 if (c
->capabilities
) {
2143 cap_free(c
->capabilities
);
2144 c
->capabilities
= NULL
;
2147 c
->read_only_dirs
= strv_free(c
->read_only_dirs
);
2148 c
->read_write_dirs
= strv_free(c
->read_write_dirs
);
2149 c
->inaccessible_dirs
= strv_free(c
->inaccessible_dirs
);
2152 CPU_FREE(c
->cpuset
);
2154 c
->utmp_id
= mfree(c
->utmp_id
);
2155 c
->selinux_context
= mfree(c
->selinux_context
);
2156 c
->apparmor_profile
= mfree(c
->apparmor_profile
);
2158 c
->syscall_filter
= set_free(c
->syscall_filter
);
2159 c
->syscall_archs
= set_free(c
->syscall_archs
);
2160 c
->address_families
= set_free(c
->address_families
);
2162 c
->runtime_directory
= strv_free(c
->runtime_directory
);
2164 bus_endpoint_free(c
->bus_endpoint
);
2165 c
->bus_endpoint
= NULL
;
2168 int exec_context_destroy_runtime_directory(ExecContext
*c
, const char *runtime_prefix
) {
2173 if (!runtime_prefix
)
2176 STRV_FOREACH(i
, c
->runtime_directory
) {
2177 _cleanup_free_
char *p
;
2179 p
= strjoin(runtime_prefix
, "/", *i
, NULL
);
2183 /* We execute this synchronously, since we need to be
2184 * sure this is gone when we start the service
2186 (void) rm_rf(p
, REMOVE_ROOT
);
2192 void exec_command_done(ExecCommand
*c
) {
2195 c
->path
= mfree(c
->path
);
2197 c
->argv
= strv_free(c
->argv
);
2200 void exec_command_done_array(ExecCommand
*c
, unsigned n
) {
2203 for (i
= 0; i
< n
; i
++)
2204 exec_command_done(c
+i
);
2207 ExecCommand
* exec_command_free_list(ExecCommand
*c
) {
2211 LIST_REMOVE(command
, c
, i
);
2212 exec_command_done(i
);
2219 void exec_command_free_array(ExecCommand
**c
, unsigned n
) {
2222 for (i
= 0; i
< n
; i
++)
2223 c
[i
] = exec_command_free_list(c
[i
]);
2226 typedef struct InvalidEnvInfo
{
2231 static void invalid_env(const char *p
, void *userdata
) {
2232 InvalidEnvInfo
*info
= userdata
;
2234 log_unit_error(info
->unit
, "Ignoring invalid environment assignment '%s': %s", p
, info
->path
);
2237 int exec_context_load_environment(Unit
*unit
, const ExecContext
*c
, char ***l
) {
2238 char **i
, **r
= NULL
;
2243 STRV_FOREACH(i
, c
->environment_files
) {
2246 bool ignore
= false;
2248 _cleanup_globfree_ glob_t pglob
= {};
2258 if (!path_is_absolute(fn
)) {
2266 /* Filename supports globbing, take all matching files */
2268 if (glob(fn
, 0, NULL
, &pglob
) != 0) {
2273 return errno
? -errno
: -EINVAL
;
2275 count
= pglob
.gl_pathc
;
2283 for (n
= 0; n
< count
; n
++) {
2284 k
= load_env_file(NULL
, pglob
.gl_pathv
[n
], NULL
, &p
);
2292 /* Log invalid environment variables with filename */
2294 InvalidEnvInfo info
= {
2296 .path
= pglob
.gl_pathv
[n
]
2299 p
= strv_env_clean_with_callback(p
, invalid_env
, &info
);
2307 m
= strv_env_merge(2, r
, p
);
2323 static bool tty_may_match_dev_console(const char *tty
) {
2324 _cleanup_free_
char *active
= NULL
;
2327 if (startswith(tty
, "/dev/"))
2330 /* trivial identity? */
2331 if (streq(tty
, "console"))
2334 console
= resolve_dev_console(&active
);
2335 /* if we could not resolve, assume it may */
2339 /* "tty0" means the active VC, so it may be the same sometimes */
2340 return streq(console
, tty
) || (streq(console
, "tty0") && tty_is_vc(tty
));
2343 bool exec_context_may_touch_console(ExecContext
*ec
) {
2344 return (ec
->tty_reset
|| ec
->tty_vhangup
|| ec
->tty_vt_disallocate
||
2345 is_terminal_input(ec
->std_input
) ||
2346 is_terminal_output(ec
->std_output
) ||
2347 is_terminal_output(ec
->std_error
)) &&
2348 tty_may_match_dev_console(tty_path(ec
));
2351 static void strv_fprintf(FILE *f
, char **l
) {
2357 fprintf(f
, " %s", *g
);
2360 void exec_context_dump(ExecContext
*c
, FILE* f
, const char *prefix
) {
2367 prefix
= strempty(prefix
);
2371 "%sWorkingDirectory: %s\n"
2372 "%sRootDirectory: %s\n"
2373 "%sNonBlocking: %s\n"
2374 "%sPrivateTmp: %s\n"
2375 "%sPrivateNetwork: %s\n"
2376 "%sPrivateDevices: %s\n"
2377 "%sProtectHome: %s\n"
2378 "%sProtectSystem: %s\n"
2379 "%sIgnoreSIGPIPE: %s\n",
2381 prefix
, c
->working_directory
? c
->working_directory
: "/",
2382 prefix
, c
->root_directory
? c
->root_directory
: "/",
2383 prefix
, yes_no(c
->non_blocking
),
2384 prefix
, yes_no(c
->private_tmp
),
2385 prefix
, yes_no(c
->private_network
),
2386 prefix
, yes_no(c
->private_devices
),
2387 prefix
, protect_home_to_string(c
->protect_home
),
2388 prefix
, protect_system_to_string(c
->protect_system
),
2389 prefix
, yes_no(c
->ignore_sigpipe
));
2391 STRV_FOREACH(e
, c
->environment
)
2392 fprintf(f
, "%sEnvironment: %s\n", prefix
, *e
);
2394 STRV_FOREACH(e
, c
->environment_files
)
2395 fprintf(f
, "%sEnvironmentFile: %s\n", prefix
, *e
);
2397 STRV_FOREACH(e
, c
->pass_environment
)
2398 fprintf(f
, "%sPassEnvironment: %s\n", prefix
, *e
);
2400 fprintf(f
, "%sRuntimeDirectoryMode: %04o\n", prefix
, c
->runtime_directory_mode
);
2402 STRV_FOREACH(d
, c
->runtime_directory
)
2403 fprintf(f
, "%sRuntimeDirectory: %s\n", prefix
, *d
);
2410 if (c
->oom_score_adjust_set
)
2412 "%sOOMScoreAdjust: %i\n",
2413 prefix
, c
->oom_score_adjust
);
2415 for (i
= 0; i
< RLIM_NLIMITS
; i
++)
2417 fprintf(f
, "%s%s: "RLIM_FMT
"\n",
2418 prefix
, rlimit_to_string(i
), c
->rlimit
[i
]->rlim_max
);
2420 if (c
->ioprio_set
) {
2421 _cleanup_free_
char *class_str
= NULL
;
2423 ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c
->ioprio
), &class_str
);
2425 "%sIOSchedulingClass: %s\n"
2426 "%sIOPriority: %i\n",
2427 prefix
, strna(class_str
),
2428 prefix
, (int) IOPRIO_PRIO_DATA(c
->ioprio
));
2431 if (c
->cpu_sched_set
) {
2432 _cleanup_free_
char *policy_str
= NULL
;
2434 sched_policy_to_string_alloc(c
->cpu_sched_policy
, &policy_str
);
2436 "%sCPUSchedulingPolicy: %s\n"
2437 "%sCPUSchedulingPriority: %i\n"
2438 "%sCPUSchedulingResetOnFork: %s\n",
2439 prefix
, strna(policy_str
),
2440 prefix
, c
->cpu_sched_priority
,
2441 prefix
, yes_no(c
->cpu_sched_reset_on_fork
));
2445 fprintf(f
, "%sCPUAffinity:", prefix
);
2446 for (i
= 0; i
< c
->cpuset_ncpus
; i
++)
2447 if (CPU_ISSET_S(i
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
), c
->cpuset
))
2448 fprintf(f
, " %u", i
);
2452 if (c
->timer_slack_nsec
!= NSEC_INFINITY
)
2453 fprintf(f
, "%sTimerSlackNSec: "NSEC_FMT
"\n", prefix
, c
->timer_slack_nsec
);
2456 "%sStandardInput: %s\n"
2457 "%sStandardOutput: %s\n"
2458 "%sStandardError: %s\n",
2459 prefix
, exec_input_to_string(c
->std_input
),
2460 prefix
, exec_output_to_string(c
->std_output
),
2461 prefix
, exec_output_to_string(c
->std_error
));
2467 "%sTTYVHangup: %s\n"
2468 "%sTTYVTDisallocate: %s\n",
2469 prefix
, c
->tty_path
,
2470 prefix
, yes_no(c
->tty_reset
),
2471 prefix
, yes_no(c
->tty_vhangup
),
2472 prefix
, yes_no(c
->tty_vt_disallocate
));
2474 if (c
->std_output
== EXEC_OUTPUT_SYSLOG
||
2475 c
->std_output
== EXEC_OUTPUT_KMSG
||
2476 c
->std_output
== EXEC_OUTPUT_JOURNAL
||
2477 c
->std_output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2478 c
->std_output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2479 c
->std_output
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
||
2480 c
->std_error
== EXEC_OUTPUT_SYSLOG
||
2481 c
->std_error
== EXEC_OUTPUT_KMSG
||
2482 c
->std_error
== EXEC_OUTPUT_JOURNAL
||
2483 c
->std_error
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2484 c
->std_error
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2485 c
->std_error
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
) {
2487 _cleanup_free_
char *fac_str
= NULL
, *lvl_str
= NULL
;
2489 log_facility_unshifted_to_string_alloc(c
->syslog_priority
>> 3, &fac_str
);
2490 log_level_to_string_alloc(LOG_PRI(c
->syslog_priority
), &lvl_str
);
2493 "%sSyslogFacility: %s\n"
2494 "%sSyslogLevel: %s\n",
2495 prefix
, strna(fac_str
),
2496 prefix
, strna(lvl_str
));
2499 if (c
->capabilities
) {
2500 _cleanup_cap_free_charp_
char *t
;
2502 t
= cap_to_text(c
->capabilities
, NULL
);
2504 fprintf(f
, "%sCapabilities: %s\n", prefix
, t
);
2508 fprintf(f
, "%sSecure Bits:%s%s%s%s%s%s\n",
2510 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS
) ? " keep-caps" : "",
2511 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS_LOCKED
) ? " keep-caps-locked" : "",
2512 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP
) ? " no-setuid-fixup" : "",
2513 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP_LOCKED
) ? " no-setuid-fixup-locked" : "",
2514 (c
->secure_bits
& 1<<SECURE_NOROOT
) ? " noroot" : "",
2515 (c
->secure_bits
& 1<<SECURE_NOROOT_LOCKED
) ? "noroot-locked" : "");
2517 if (c
->capability_bounding_set_drop
) {
2519 fprintf(f
, "%sCapabilityBoundingSet:", prefix
);
2521 for (l
= 0; l
<= cap_last_cap(); l
++)
2522 if (!(c
->capability_bounding_set_drop
& ((uint64_t) 1ULL << (uint64_t) l
)))
2523 fprintf(f
, " %s", strna(capability_to_name(l
)));
2529 fprintf(f
, "%sUser: %s\n", prefix
, c
->user
);
2531 fprintf(f
, "%sGroup: %s\n", prefix
, c
->group
);
2533 if (strv_length(c
->supplementary_groups
) > 0) {
2534 fprintf(f
, "%sSupplementaryGroups:", prefix
);
2535 strv_fprintf(f
, c
->supplementary_groups
);
2540 fprintf(f
, "%sPAMName: %s\n", prefix
, c
->pam_name
);
2542 if (strv_length(c
->read_write_dirs
) > 0) {
2543 fprintf(f
, "%sReadWriteDirs:", prefix
);
2544 strv_fprintf(f
, c
->read_write_dirs
);
2548 if (strv_length(c
->read_only_dirs
) > 0) {
2549 fprintf(f
, "%sReadOnlyDirs:", prefix
);
2550 strv_fprintf(f
, c
->read_only_dirs
);
2554 if (strv_length(c
->inaccessible_dirs
) > 0) {
2555 fprintf(f
, "%sInaccessibleDirs:", prefix
);
2556 strv_fprintf(f
, c
->inaccessible_dirs
);
2562 "%sUtmpIdentifier: %s\n",
2563 prefix
, c
->utmp_id
);
2565 if (c
->selinux_context
)
2567 "%sSELinuxContext: %s%s\n",
2568 prefix
, c
->selinux_context_ignore
? "-" : "", c
->selinux_context
);
2570 if (c
->personality
!= PERSONALITY_INVALID
)
2572 "%sPersonality: %s\n",
2573 prefix
, strna(personality_to_string(c
->personality
)));
2575 if (c
->syscall_filter
) {
2583 "%sSystemCallFilter: ",
2586 if (!c
->syscall_whitelist
)
2590 SET_FOREACH(id
, c
->syscall_filter
, j
) {
2591 _cleanup_free_
char *name
= NULL
;
2598 name
= seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE
, PTR_TO_INT(id
) - 1);
2599 fputs(strna(name
), f
);
2606 if (c
->syscall_archs
) {
2613 "%sSystemCallArchitectures:",
2617 SET_FOREACH(id
, c
->syscall_archs
, j
)
2618 fprintf(f
, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id
) - 1)));
2623 if (c
->syscall_errno
!= 0)
2625 "%sSystemCallErrorNumber: %s\n",
2626 prefix
, strna(errno_to_name(c
->syscall_errno
)));
2628 if (c
->apparmor_profile
)
2630 "%sAppArmorProfile: %s%s\n",
2631 prefix
, c
->apparmor_profile_ignore
? "-" : "", c
->apparmor_profile
);
2634 bool exec_context_maintains_privileges(ExecContext
*c
) {
2637 /* Returns true if the process forked off would run run under
2638 * an unchanged UID or as root. */
2643 if (streq(c
->user
, "root") || streq(c
->user
, "0"))
2649 void exec_status_start(ExecStatus
*s
, pid_t pid
) {
2654 dual_timestamp_get(&s
->start_timestamp
);
2657 void exec_status_exit(ExecStatus
*s
, ExecContext
*context
, pid_t pid
, int code
, int status
) {
2660 if (s
->pid
&& s
->pid
!= pid
)
2664 dual_timestamp_get(&s
->exit_timestamp
);
2670 if (context
->utmp_id
)
2671 utmp_put_dead_process(context
->utmp_id
, pid
, code
, status
);
2673 exec_context_tty_reset(context
);
2677 void exec_status_dump(ExecStatus
*s
, FILE *f
, const char *prefix
) {
2678 char buf
[FORMAT_TIMESTAMP_MAX
];
2686 prefix
= strempty(prefix
);
2689 "%sPID: "PID_FMT
"\n",
2692 if (s
->start_timestamp
.realtime
> 0)
2694 "%sStart Timestamp: %s\n",
2695 prefix
, format_timestamp(buf
, sizeof(buf
), s
->start_timestamp
.realtime
));
2697 if (s
->exit_timestamp
.realtime
> 0)
2699 "%sExit Timestamp: %s\n"
2701 "%sExit Status: %i\n",
2702 prefix
, format_timestamp(buf
, sizeof(buf
), s
->exit_timestamp
.realtime
),
2703 prefix
, sigchld_code_to_string(s
->code
),
2707 char *exec_command_line(char **argv
) {
2715 STRV_FOREACH(a
, argv
)
2718 if (!(n
= new(char, k
)))
2722 STRV_FOREACH(a
, argv
) {
2729 if (strpbrk(*a
, WHITESPACE
)) {
2740 /* FIXME: this doesn't really handle arguments that have
2741 * spaces and ticks in them */
2746 void exec_command_dump(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2747 _cleanup_free_
char *cmd
= NULL
;
2748 const char *prefix2
;
2753 prefix
= strempty(prefix
);
2754 prefix2
= strjoina(prefix
, "\t");
2756 cmd
= exec_command_line(c
->argv
);
2758 "%sCommand Line: %s\n",
2759 prefix
, cmd
? cmd
: strerror(ENOMEM
));
2761 exec_status_dump(&c
->exec_status
, f
, prefix2
);
2764 void exec_command_dump_list(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2767 prefix
= strempty(prefix
);
2769 LIST_FOREACH(command
, c
, c
)
2770 exec_command_dump(c
, f
, prefix
);
2773 void exec_command_append_list(ExecCommand
**l
, ExecCommand
*e
) {
2780 /* It's kind of important, that we keep the order here */
2781 LIST_FIND_TAIL(command
, *l
, end
);
2782 LIST_INSERT_AFTER(command
, *l
, end
, e
);
2787 int exec_command_set(ExecCommand
*c
, const char *path
, ...) {
2795 l
= strv_new_ap(path
, ap
);
2816 int exec_command_append(ExecCommand
*c
, const char *path
, ...) {
2817 _cleanup_strv_free_
char **l
= NULL
;
2825 l
= strv_new_ap(path
, ap
);
2831 r
= strv_extend_strv(&c
->argv
, l
, false);
2839 static int exec_runtime_allocate(ExecRuntime
**rt
) {
2844 *rt
= new0(ExecRuntime
, 1);
2849 (*rt
)->netns_storage_socket
[0] = (*rt
)->netns_storage_socket
[1] = -1;
2854 int exec_runtime_make(ExecRuntime
**rt
, ExecContext
*c
, const char *id
) {
2864 if (!c
->private_network
&& !c
->private_tmp
)
2867 r
= exec_runtime_allocate(rt
);
2871 if (c
->private_network
&& (*rt
)->netns_storage_socket
[0] < 0) {
2872 if (socketpair(AF_UNIX
, SOCK_DGRAM
, 0, (*rt
)->netns_storage_socket
) < 0)
2876 if (c
->private_tmp
&& !(*rt
)->tmp_dir
) {
2877 r
= setup_tmp_dirs(id
, &(*rt
)->tmp_dir
, &(*rt
)->var_tmp_dir
);
2885 ExecRuntime
*exec_runtime_ref(ExecRuntime
*r
) {
2887 assert(r
->n_ref
> 0);
2893 ExecRuntime
*exec_runtime_unref(ExecRuntime
*r
) {
2898 assert(r
->n_ref
> 0);
2905 free(r
->var_tmp_dir
);
2906 safe_close_pair(r
->netns_storage_socket
);
2912 int exec_runtime_serialize(Unit
*u
, ExecRuntime
*rt
, FILE *f
, FDSet
*fds
) {
2921 unit_serialize_item(u
, f
, "tmp-dir", rt
->tmp_dir
);
2923 if (rt
->var_tmp_dir
)
2924 unit_serialize_item(u
, f
, "var-tmp-dir", rt
->var_tmp_dir
);
2926 if (rt
->netns_storage_socket
[0] >= 0) {
2929 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[0]);
2933 unit_serialize_item_format(u
, f
, "netns-socket-0", "%i", copy
);
2936 if (rt
->netns_storage_socket
[1] >= 0) {
2939 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[1]);
2943 unit_serialize_item_format(u
, f
, "netns-socket-1", "%i", copy
);
2949 int exec_runtime_deserialize_item(Unit
*u
, ExecRuntime
**rt
, const char *key
, const char *value
, FDSet
*fds
) {
2956 if (streq(key
, "tmp-dir")) {
2959 r
= exec_runtime_allocate(rt
);
2963 copy
= strdup(value
);
2967 free((*rt
)->tmp_dir
);
2968 (*rt
)->tmp_dir
= copy
;
2970 } else if (streq(key
, "var-tmp-dir")) {
2973 r
= exec_runtime_allocate(rt
);
2977 copy
= strdup(value
);
2981 free((*rt
)->var_tmp_dir
);
2982 (*rt
)->var_tmp_dir
= copy
;
2984 } else if (streq(key
, "netns-socket-0")) {
2987 r
= exec_runtime_allocate(rt
);
2991 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
2992 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
2994 safe_close((*rt
)->netns_storage_socket
[0]);
2995 (*rt
)->netns_storage_socket
[0] = fdset_remove(fds
, fd
);
2997 } else if (streq(key
, "netns-socket-1")) {
3000 r
= exec_runtime_allocate(rt
);
3004 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
3005 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
3007 safe_close((*rt
)->netns_storage_socket
[1]);
3008 (*rt
)->netns_storage_socket
[1] = fdset_remove(fds
, fd
);
3016 static void *remove_tmpdir_thread(void *p
) {
3017 _cleanup_free_
char *path
= p
;
3019 (void) rm_rf(path
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
3023 void exec_runtime_destroy(ExecRuntime
*rt
) {
3029 /* If there are multiple users of this, let's leave the stuff around */
3034 log_debug("Spawning thread to nuke %s", rt
->tmp_dir
);
3036 r
= asynchronous_job(remove_tmpdir_thread
, rt
->tmp_dir
);
3038 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->tmp_dir
);
3045 if (rt
->var_tmp_dir
) {
3046 log_debug("Spawning thread to nuke %s", rt
->var_tmp_dir
);
3048 r
= asynchronous_job(remove_tmpdir_thread
, rt
->var_tmp_dir
);
3050 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->var_tmp_dir
);
3051 free(rt
->var_tmp_dir
);
3054 rt
->var_tmp_dir
= NULL
;
3057 safe_close_pair(rt
->netns_storage_socket
);
3060 static const char* const exec_input_table
[_EXEC_INPUT_MAX
] = {
3061 [EXEC_INPUT_NULL
] = "null",
3062 [EXEC_INPUT_TTY
] = "tty",
3063 [EXEC_INPUT_TTY_FORCE
] = "tty-force",
3064 [EXEC_INPUT_TTY_FAIL
] = "tty-fail",
3065 [EXEC_INPUT_SOCKET
] = "socket"
3068 DEFINE_STRING_TABLE_LOOKUP(exec_input
, ExecInput
);
3070 static const char* const exec_output_table
[_EXEC_OUTPUT_MAX
] = {
3071 [EXEC_OUTPUT_INHERIT
] = "inherit",
3072 [EXEC_OUTPUT_NULL
] = "null",
3073 [EXEC_OUTPUT_TTY
] = "tty",
3074 [EXEC_OUTPUT_SYSLOG
] = "syslog",
3075 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE
] = "syslog+console",
3076 [EXEC_OUTPUT_KMSG
] = "kmsg",
3077 [EXEC_OUTPUT_KMSG_AND_CONSOLE
] = "kmsg+console",
3078 [EXEC_OUTPUT_JOURNAL
] = "journal",
3079 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE
] = "journal+console",
3080 [EXEC_OUTPUT_SOCKET
] = "socket"
3083 DEFINE_STRING_TABLE_LOOKUP(exec_output
, ExecOutput
);
3085 static const char* const exec_utmp_mode_table
[_EXEC_UTMP_MODE_MAX
] = {
3086 [EXEC_UTMP_INIT
] = "init",
3087 [EXEC_UTMP_LOGIN
] = "login",
3088 [EXEC_UTMP_USER
] = "user",
3091 DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode
, ExecUtmpMode
);