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
|| context
->capability_ambient_set
!= 0) {
742 /* First step: If we need to keep capabilities but
743 * drop privileges we need to make sure we keep our
744 * caps, while we drop privileges. */
746 int sb
= context
->secure_bits
| 1<<SECURE_KEEP_CAPS
;
748 if (prctl(PR_GET_SECUREBITS
) != sb
)
749 if (prctl(PR_SET_SECUREBITS
, sb
) < 0)
753 /* Second step: set the capabilities. This will reduce
754 * the capabilities to the minimum we need. */
756 if (context
->capabilities
) {
757 _cleanup_cap_free_ cap_t d
= NULL
;
758 static const cap_value_t bits
[] = {
759 CAP_SETUID
, /* Necessary so that we can run setresuid() below */
760 CAP_SETPCAP
/* Necessary so that we can set PR_SET_SECUREBITS later on */
763 d
= cap_dup(context
->capabilities
);
767 if (cap_set_flag(d
, CAP_EFFECTIVE
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0 ||
768 cap_set_flag(d
, CAP_PERMITTED
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0)
771 if (cap_set_proc(d
) < 0)
776 /* Third step: actually set the uids */
777 if (setresuid(uid
, uid
, uid
) < 0)
780 /* At this point we should have all necessary capabilities but
781 are otherwise a normal user. However, the caps might got
782 corrupted due to the setresuid() so we need clean them up
783 later. This is done outside of this call. */
790 static int null_conv(
792 const struct pam_message
**msg
,
793 struct pam_response
**resp
,
796 /* We don't support conversations */
801 static int setup_pam(
807 int fds
[], unsigned n_fds
) {
809 static const struct pam_conv conv
= {
814 _cleanup_(barrier_destroy
) Barrier barrier
= BARRIER_NULL
;
815 pam_handle_t
*handle
= NULL
;
817 int pam_code
= PAM_SUCCESS
, r
;
819 bool close_session
= false;
820 pid_t pam_pid
= 0, parent_pid
;
827 /* We set up PAM in the parent process, then fork. The child
828 * will then stay around until killed via PR_GET_PDEATHSIG or
829 * systemd via the cgroup logic. It will then remove the PAM
830 * session again. The parent process will exec() the actual
831 * daemon. We do things this way to ensure that the main PID
832 * of the daemon is the one we initially fork()ed. */
834 r
= barrier_create(&barrier
);
838 if (log_get_max_level() < LOG_DEBUG
)
841 pam_code
= pam_start(name
, user
, &conv
, &handle
);
842 if (pam_code
!= PAM_SUCCESS
) {
848 pam_code
= pam_set_item(handle
, PAM_TTY
, tty
);
849 if (pam_code
!= PAM_SUCCESS
)
853 pam_code
= pam_acct_mgmt(handle
, flags
);
854 if (pam_code
!= PAM_SUCCESS
)
857 pam_code
= pam_open_session(handle
, flags
);
858 if (pam_code
!= PAM_SUCCESS
)
861 close_session
= true;
863 e
= pam_getenvlist(handle
);
865 pam_code
= PAM_BUF_ERR
;
869 /* Block SIGTERM, so that we know that it won't get lost in
872 assert_se(sigprocmask_many(SIG_BLOCK
, &old_ss
, SIGTERM
, -1) >= 0);
874 parent_pid
= getpid();
883 int sig
, ret
= EXIT_PAM
;
885 /* The child's job is to reset the PAM session on
887 barrier_set_role(&barrier
, BARRIER_CHILD
);
889 /* This string must fit in 10 chars (i.e. the length
890 * of "/sbin/init"), to look pretty in /bin/ps */
891 rename_process("(sd-pam)");
893 /* Make sure we don't keep open the passed fds in this
894 child. We assume that otherwise only those fds are
895 open here that have been opened by PAM. */
896 close_many(fds
, n_fds
);
898 /* Drop privileges - we don't need any to pam_close_session
899 * and this will make PR_SET_PDEATHSIG work in most cases.
900 * If this fails, ignore the error - but expect sd-pam threads
901 * to fail to exit normally */
902 if (setresuid(uid
, uid
, uid
) < 0)
903 log_error_errno(r
, "Error: Failed to setresuid() in sd-pam: %m");
905 (void) ignore_signals(SIGPIPE
, -1);
907 /* Wait until our parent died. This will only work if
908 * the above setresuid() succeeds, otherwise the kernel
909 * will not allow unprivileged parents kill their privileged
910 * children this way. We rely on the control groups kill logic
911 * to do the rest for us. */
912 if (prctl(PR_SET_PDEATHSIG
, SIGTERM
) < 0)
915 /* Tell the parent that our setup is done. This is especially
916 * important regarding dropping privileges. Otherwise, unit
917 * setup might race against our setresuid(2) call. */
918 barrier_place(&barrier
);
920 /* Check if our parent process might already have
922 if (getppid() == parent_pid
) {
925 assert_se(sigemptyset(&ss
) >= 0);
926 assert_se(sigaddset(&ss
, SIGTERM
) >= 0);
929 if (sigwait(&ss
, &sig
) < 0) {
936 assert(sig
== SIGTERM
);
941 /* If our parent died we'll end the session */
942 if (getppid() != parent_pid
) {
943 pam_code
= pam_close_session(handle
, flags
);
944 if (pam_code
!= PAM_SUCCESS
)
951 pam_end(handle
, pam_code
| flags
);
955 barrier_set_role(&barrier
, BARRIER_PARENT
);
957 /* If the child was forked off successfully it will do all the
958 * cleanups, so forget about the handle here. */
961 /* Unblock SIGTERM again in the parent */
962 assert_se(sigprocmask(SIG_SETMASK
, &old_ss
, NULL
) >= 0);
964 /* We close the log explicitly here, since the PAM modules
965 * might have opened it, but we don't want this fd around. */
968 /* Synchronously wait for the child to initialize. We don't care for
969 * errors as we cannot recover. However, warn loudly if it happens. */
970 if (!barrier_place_and_sync(&barrier
))
971 log_error("PAM initialization failed");
979 if (pam_code
!= PAM_SUCCESS
) {
980 log_error("PAM failed: %s", pam_strerror(handle
, pam_code
));
981 r
= -EPERM
; /* PAM errors do not map to errno */
983 log_error_errno(r
, "PAM failed: %m");
987 pam_code
= pam_close_session(handle
, flags
);
989 pam_end(handle
, pam_code
| flags
);
999 static void rename_process_from_path(const char *path
) {
1000 char process_name
[11];
1004 /* This resulting string must fit in 10 chars (i.e. the length
1005 * of "/sbin/init") to look pretty in /bin/ps */
1009 rename_process("(...)");
1015 /* The end of the process name is usually more
1016 * interesting, since the first bit might just be
1022 process_name
[0] = '(';
1023 memcpy(process_name
+1, p
, l
);
1024 process_name
[1+l
] = ')';
1025 process_name
[1+l
+1] = 0;
1027 rename_process(process_name
);
1032 static int apply_seccomp(const ExecContext
*c
) {
1033 uint32_t negative_action
, action
;
1034 scmp_filter_ctx
*seccomp
;
1041 negative_action
= c
->syscall_errno
== 0 ? SCMP_ACT_KILL
: SCMP_ACT_ERRNO(c
->syscall_errno
);
1043 seccomp
= seccomp_init(c
->syscall_whitelist
? negative_action
: SCMP_ACT_ALLOW
);
1047 if (c
->syscall_archs
) {
1049 SET_FOREACH(id
, c
->syscall_archs
, i
) {
1050 r
= seccomp_arch_add(seccomp
, PTR_TO_UINT32(id
) - 1);
1058 r
= seccomp_add_secondary_archs(seccomp
);
1063 action
= c
->syscall_whitelist
? SCMP_ACT_ALLOW
: negative_action
;
1064 SET_FOREACH(id
, c
->syscall_filter
, i
) {
1065 r
= seccomp_rule_add(seccomp
, action
, PTR_TO_INT(id
) - 1, 0);
1070 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1074 r
= seccomp_load(seccomp
);
1077 seccomp_release(seccomp
);
1081 static int apply_address_families(const ExecContext
*c
) {
1082 scmp_filter_ctx
*seccomp
;
1088 seccomp
= seccomp_init(SCMP_ACT_ALLOW
);
1092 r
= seccomp_add_secondary_archs(seccomp
);
1096 if (c
->address_families_whitelist
) {
1097 int af
, first
= 0, last
= 0;
1100 /* If this is a whitelist, we first block the address
1101 * families that are out of range and then everything
1102 * that is not in the set. First, we find the lowest
1103 * and highest address family in the set. */
1105 SET_FOREACH(afp
, c
->address_families
, i
) {
1106 af
= PTR_TO_INT(afp
);
1108 if (af
<= 0 || af
>= af_max())
1111 if (first
== 0 || af
< first
)
1114 if (last
== 0 || af
> last
)
1118 assert((first
== 0) == (last
== 0));
1122 /* No entries in the valid range, block everything */
1123 r
= seccomp_rule_add(
1125 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1133 /* Block everything below the first entry */
1134 r
= seccomp_rule_add(
1136 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1139 SCMP_A0(SCMP_CMP_LT
, first
));
1143 /* Block everything above the last entry */
1144 r
= seccomp_rule_add(
1146 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1149 SCMP_A0(SCMP_CMP_GT
, last
));
1153 /* Block everything between the first and last
1155 for (af
= 1; af
< af_max(); af
++) {
1157 if (set_contains(c
->address_families
, INT_TO_PTR(af
)))
1160 r
= seccomp_rule_add(
1162 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1165 SCMP_A0(SCMP_CMP_EQ
, af
));
1174 /* If this is a blacklist, then generate one rule for
1175 * each address family that are then combined in OR
1178 SET_FOREACH(af
, c
->address_families
, i
) {
1180 r
= seccomp_rule_add(
1182 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1185 SCMP_A0(SCMP_CMP_EQ
, PTR_TO_INT(af
)));
1191 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1195 r
= seccomp_load(seccomp
);
1198 seccomp_release(seccomp
);
1204 static void do_idle_pipe_dance(int idle_pipe
[4]) {
1208 idle_pipe
[1] = safe_close(idle_pipe
[1]);
1209 idle_pipe
[2] = safe_close(idle_pipe
[2]);
1211 if (idle_pipe
[0] >= 0) {
1214 r
= fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT_USEC
);
1216 if (idle_pipe
[3] >= 0 && r
== 0 /* timeout */) {
1219 /* Signal systemd that we are bored and want to continue. */
1220 n
= write(idle_pipe
[3], "x", 1);
1222 /* Wait for systemd to react to the signal above. */
1223 fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT2_USEC
);
1226 idle_pipe
[0] = safe_close(idle_pipe
[0]);
1230 idle_pipe
[3] = safe_close(idle_pipe
[3]);
1233 static int build_environment(
1234 const ExecContext
*c
,
1237 usec_t watchdog_usec
,
1239 const char *username
,
1243 _cleanup_strv_free_
char **our_env
= NULL
;
1250 our_env
= new0(char*, 11);
1255 _cleanup_free_
char *joined
= NULL
;
1257 if (asprintf(&x
, "LISTEN_PID="PID_FMT
, getpid()) < 0)
1259 our_env
[n_env
++] = x
;
1261 if (asprintf(&x
, "LISTEN_FDS=%u", n_fds
) < 0)
1263 our_env
[n_env
++] = x
;
1265 joined
= strv_join(fd_names
, ":");
1269 x
= strjoin("LISTEN_FDNAMES=", joined
, NULL
);
1272 our_env
[n_env
++] = x
;
1275 if (watchdog_usec
> 0) {
1276 if (asprintf(&x
, "WATCHDOG_PID="PID_FMT
, getpid()) < 0)
1278 our_env
[n_env
++] = x
;
1280 if (asprintf(&x
, "WATCHDOG_USEC="USEC_FMT
, watchdog_usec
) < 0)
1282 our_env
[n_env
++] = x
;
1286 x
= strappend("HOME=", home
);
1289 our_env
[n_env
++] = x
;
1293 x
= strappend("LOGNAME=", username
);
1296 our_env
[n_env
++] = x
;
1298 x
= strappend("USER=", username
);
1301 our_env
[n_env
++] = x
;
1305 x
= strappend("SHELL=", shell
);
1308 our_env
[n_env
++] = x
;
1311 if (is_terminal_input(c
->std_input
) ||
1312 c
->std_output
== EXEC_OUTPUT_TTY
||
1313 c
->std_error
== EXEC_OUTPUT_TTY
||
1316 x
= strdup(default_term_for_tty(tty_path(c
)));
1319 our_env
[n_env
++] = x
;
1322 our_env
[n_env
++] = NULL
;
1323 assert(n_env
<= 11);
1331 static int build_pass_environment(const ExecContext
*c
, char ***ret
) {
1332 _cleanup_strv_free_
char **pass_env
= NULL
;
1333 size_t n_env
= 0, n_bufsize
= 0;
1336 STRV_FOREACH(i
, c
->pass_environment
) {
1337 _cleanup_free_
char *x
= NULL
;
1343 x
= strjoin(*i
, "=", v
, NULL
);
1346 if (!GREEDY_REALLOC(pass_env
, n_bufsize
, n_env
+ 2))
1348 pass_env
[n_env
++] = x
;
1349 pass_env
[n_env
] = NULL
;
1359 static bool exec_needs_mount_namespace(
1360 const ExecContext
*context
,
1361 const ExecParameters
*params
,
1362 ExecRuntime
*runtime
) {
1367 if (!strv_isempty(context
->read_write_dirs
) ||
1368 !strv_isempty(context
->read_only_dirs
) ||
1369 !strv_isempty(context
->inaccessible_dirs
))
1372 if (context
->mount_flags
!= 0)
1375 if (context
->private_tmp
&& runtime
&& (runtime
->tmp_dir
|| runtime
->var_tmp_dir
))
1378 if (params
->bus_endpoint_path
)
1381 if (context
->private_devices
||
1382 context
->protect_system
!= PROTECT_SYSTEM_NO
||
1383 context
->protect_home
!= PROTECT_HOME_NO
)
1389 static int close_remaining_fds(
1390 const ExecParameters
*params
,
1391 ExecRuntime
*runtime
,
1393 int *fds
, unsigned n_fds
) {
1395 unsigned n_dont_close
= 0;
1396 int dont_close
[n_fds
+ 7];
1400 if (params
->stdin_fd
>= 0)
1401 dont_close
[n_dont_close
++] = params
->stdin_fd
;
1402 if (params
->stdout_fd
>= 0)
1403 dont_close
[n_dont_close
++] = params
->stdout_fd
;
1404 if (params
->stderr_fd
>= 0)
1405 dont_close
[n_dont_close
++] = params
->stderr_fd
;
1408 dont_close
[n_dont_close
++] = socket_fd
;
1410 memcpy(dont_close
+ n_dont_close
, fds
, sizeof(int) * n_fds
);
1411 n_dont_close
+= n_fds
;
1414 if (params
->bus_endpoint_fd
>= 0)
1415 dont_close
[n_dont_close
++] = params
->bus_endpoint_fd
;
1418 if (runtime
->netns_storage_socket
[0] >= 0)
1419 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[0];
1420 if (runtime
->netns_storage_socket
[1] >= 0)
1421 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[1];
1424 return close_all_fds(dont_close
, n_dont_close
);
1427 static int exec_child(
1429 ExecCommand
*command
,
1430 const ExecContext
*context
,
1431 const ExecParameters
*params
,
1432 ExecRuntime
*runtime
,
1435 int *fds
, unsigned n_fds
,
1439 _cleanup_strv_free_
char **our_env
= NULL
, **pass_env
= NULL
, **pam_env
= NULL
, **final_env
= NULL
, **final_argv
= NULL
;
1440 _cleanup_free_
char *mac_selinux_context_net
= NULL
;
1441 const char *username
= NULL
, *home
= NULL
, *shell
= NULL
, *wd
;
1442 uid_t uid
= UID_INVALID
;
1443 gid_t gid
= GID_INVALID
;
1445 bool needs_mount_namespace
;
1451 assert(exit_status
);
1453 rename_process_from_path(command
->path
);
1455 /* We reset exactly these signals, since they are the
1456 * only ones we set to SIG_IGN in the main daemon. All
1457 * others we leave untouched because we set them to
1458 * SIG_DFL or a valid handler initially, both of which
1459 * will be demoted to SIG_DFL. */
1460 (void) default_signals(SIGNALS_CRASH_HANDLER
,
1461 SIGNALS_IGNORE
, -1);
1463 if (context
->ignore_sigpipe
)
1464 (void) ignore_signals(SIGPIPE
, -1);
1466 r
= reset_signal_mask();
1468 *exit_status
= EXIT_SIGNAL_MASK
;
1472 if (params
->idle_pipe
)
1473 do_idle_pipe_dance(params
->idle_pipe
);
1475 /* Close sockets very early to make sure we don't
1476 * block init reexecution because it cannot bind its
1481 r
= close_remaining_fds(params
, runtime
, socket_fd
, fds
, n_fds
);
1483 *exit_status
= EXIT_FDS
;
1487 if (!context
->same_pgrp
)
1489 *exit_status
= EXIT_SETSID
;
1493 exec_context_tty_reset(context
);
1495 if (params
->confirm_spawn
) {
1498 r
= ask_for_confirmation(&response
, argv
);
1499 if (r
== -ETIMEDOUT
)
1500 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1502 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r
));
1503 else if (response
== 's') {
1504 write_confirm_message("Skipping execution.\n");
1505 *exit_status
= EXIT_CONFIRM
;
1507 } else if (response
== 'n') {
1508 write_confirm_message("Failing execution.\n");
1514 if (context
->user
) {
1515 username
= context
->user
;
1516 r
= get_user_creds(&username
, &uid
, &gid
, &home
, &shell
);
1518 *exit_status
= EXIT_USER
;
1523 if (context
->group
) {
1524 const char *g
= context
->group
;
1526 r
= get_group_creds(&g
, &gid
);
1528 *exit_status
= EXIT_GROUP
;
1534 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1535 * must sure to drop O_NONBLOCK */
1537 (void) fd_nonblock(socket_fd
, false);
1539 r
= setup_input(context
, params
, socket_fd
);
1541 *exit_status
= EXIT_STDIN
;
1545 r
= setup_output(unit
, context
, params
, STDOUT_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1547 *exit_status
= EXIT_STDOUT
;
1551 r
= setup_output(unit
, context
, params
, STDERR_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1553 *exit_status
= EXIT_STDERR
;
1557 if (params
->cgroup_path
) {
1558 r
= cg_attach_everywhere(params
->cgroup_supported
, params
->cgroup_path
, 0, NULL
, NULL
);
1560 *exit_status
= EXIT_CGROUP
;
1565 if (context
->oom_score_adjust_set
) {
1566 char t
[DECIMAL_STR_MAX(context
->oom_score_adjust
)];
1568 /* When we can't make this change due to EPERM, then
1569 * let's silently skip over it. User namespaces
1570 * prohibit write access to this file, and we
1571 * shouldn't trip up over that. */
1573 sprintf(t
, "%i", context
->oom_score_adjust
);
1574 r
= write_string_file("/proc/self/oom_score_adj", t
, 0);
1575 if (r
== -EPERM
|| r
== -EACCES
) {
1577 log_unit_debug_errno(unit
, r
, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
1580 *exit_status
= EXIT_OOM_ADJUST
;
1585 if (context
->nice_set
)
1586 if (setpriority(PRIO_PROCESS
, 0, context
->nice
) < 0) {
1587 *exit_status
= EXIT_NICE
;
1591 if (context
->cpu_sched_set
) {
1592 struct sched_param param
= {
1593 .sched_priority
= context
->cpu_sched_priority
,
1596 r
= sched_setscheduler(0,
1597 context
->cpu_sched_policy
|
1598 (context
->cpu_sched_reset_on_fork
?
1599 SCHED_RESET_ON_FORK
: 0),
1602 *exit_status
= EXIT_SETSCHEDULER
;
1607 if (context
->cpuset
)
1608 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context
->cpuset_ncpus
), context
->cpuset
) < 0) {
1609 *exit_status
= EXIT_CPUAFFINITY
;
1613 if (context
->ioprio_set
)
1614 if (ioprio_set(IOPRIO_WHO_PROCESS
, 0, context
->ioprio
) < 0) {
1615 *exit_status
= EXIT_IOPRIO
;
1619 if (context
->timer_slack_nsec
!= NSEC_INFINITY
)
1620 if (prctl(PR_SET_TIMERSLACK
, context
->timer_slack_nsec
) < 0) {
1621 *exit_status
= EXIT_TIMERSLACK
;
1625 if (context
->personality
!= PERSONALITY_INVALID
)
1626 if (personality(context
->personality
) < 0) {
1627 *exit_status
= EXIT_PERSONALITY
;
1631 if (context
->utmp_id
)
1632 utmp_put_init_process(context
->utmp_id
, getpid(), getsid(0), context
->tty_path
,
1633 context
->utmp_mode
== EXEC_UTMP_INIT
? INIT_PROCESS
:
1634 context
->utmp_mode
== EXEC_UTMP_LOGIN
? LOGIN_PROCESS
:
1636 username
? "root" : context
->user
);
1638 if (context
->user
&& is_terminal_input(context
->std_input
)) {
1639 r
= chown_terminal(STDIN_FILENO
, uid
);
1641 *exit_status
= EXIT_STDIN
;
1646 if (params
->bus_endpoint_fd
>= 0 && context
->bus_endpoint
) {
1647 uid_t ep_uid
= (uid
== UID_INVALID
) ? 0 : uid
;
1649 r
= bus_kernel_set_endpoint_policy(params
->bus_endpoint_fd
, ep_uid
, context
->bus_endpoint
);
1651 *exit_status
= EXIT_BUS_ENDPOINT
;
1656 /* If delegation is enabled we'll pass ownership of the cgroup
1657 * (but only in systemd's own controller hierarchy!) to the
1658 * user of the new process. */
1659 if (params
->cgroup_path
&& context
->user
&& params
->cgroup_delegate
) {
1660 r
= cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0644, uid
, gid
);
1662 *exit_status
= EXIT_CGROUP
;
1667 r
= cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0755, uid
, gid
);
1669 *exit_status
= EXIT_CGROUP
;
1674 if (!strv_isempty(context
->runtime_directory
) && params
->runtime_prefix
) {
1677 STRV_FOREACH(rt
, context
->runtime_directory
) {
1678 _cleanup_free_
char *p
;
1680 p
= strjoin(params
->runtime_prefix
, "/", *rt
, NULL
);
1682 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1686 r
= mkdir_p_label(p
, context
->runtime_directory_mode
);
1688 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1692 r
= chmod_and_chown(p
, context
->runtime_directory_mode
, uid
, gid
);
1694 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1700 umask(context
->umask
);
1702 if (params
->apply_permissions
) {
1703 r
= enforce_groups(context
, username
, gid
);
1705 *exit_status
= EXIT_GROUP
;
1709 if (context
->smack_process_label
) {
1710 r
= mac_smack_apply_pid(0, context
->smack_process_label
);
1712 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1716 #ifdef SMACK_DEFAULT_PROCESS_LABEL
1718 _cleanup_free_
char *exec_label
= NULL
;
1720 r
= mac_smack_read(command
->path
, SMACK_ATTR_EXEC
, &exec_label
);
1721 if (r
< 0 && r
!= -ENODATA
&& r
!= -EOPNOTSUPP
) {
1722 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1726 r
= mac_smack_apply_pid(0, exec_label
? : SMACK_DEFAULT_PROCESS_LABEL
);
1728 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1735 if (context
->pam_name
&& username
) {
1736 r
= setup_pam(context
->pam_name
, username
, uid
, context
->tty_path
, &pam_env
, fds
, n_fds
);
1738 *exit_status
= EXIT_PAM
;
1745 if (context
->private_network
&& runtime
&& runtime
->netns_storage_socket
[0] >= 0) {
1746 r
= setup_netns(runtime
->netns_storage_socket
);
1748 *exit_status
= EXIT_NETWORK
;
1753 needs_mount_namespace
= exec_needs_mount_namespace(context
, params
, runtime
);
1755 if (needs_mount_namespace
) {
1756 char *tmp
= NULL
, *var
= NULL
;
1758 /* The runtime struct only contains the parent
1759 * of the private /tmp, which is
1760 * non-accessible to world users. Inside of it
1761 * there's a /tmp that is sticky, and that's
1762 * the one we want to use here. */
1764 if (context
->private_tmp
&& runtime
) {
1765 if (runtime
->tmp_dir
)
1766 tmp
= strjoina(runtime
->tmp_dir
, "/tmp");
1767 if (runtime
->var_tmp_dir
)
1768 var
= strjoina(runtime
->var_tmp_dir
, "/tmp");
1771 r
= setup_namespace(
1772 params
->apply_chroot
? context
->root_directory
: NULL
,
1773 context
->read_write_dirs
,
1774 context
->read_only_dirs
,
1775 context
->inaccessible_dirs
,
1778 params
->bus_endpoint_path
,
1779 context
->private_devices
,
1780 context
->protect_home
,
1781 context
->protect_system
,
1782 context
->mount_flags
);
1784 /* If we couldn't set up the namespace this is
1785 * probably due to a missing capability. In this case,
1786 * silently proceeed. */
1787 if (r
== -EPERM
|| r
== -EACCES
) {
1789 log_unit_debug_errno(unit
, r
, "Failed to set up namespace, assuming containerized execution, ignoring: %m");
1792 *exit_status
= EXIT_NAMESPACE
;
1797 if (context
->working_directory_home
)
1799 else if (context
->working_directory
)
1800 wd
= context
->working_directory
;
1804 if (params
->apply_chroot
) {
1805 if (!needs_mount_namespace
&& context
->root_directory
)
1806 if (chroot(context
->root_directory
) < 0) {
1807 *exit_status
= EXIT_CHROOT
;
1811 if (chdir(wd
) < 0 &&
1812 !context
->working_directory_missing_ok
) {
1813 *exit_status
= EXIT_CHDIR
;
1819 d
= strjoina(strempty(context
->root_directory
), "/", strempty(wd
));
1821 !context
->working_directory_missing_ok
) {
1822 *exit_status
= EXIT_CHDIR
;
1828 if (params
->apply_permissions
&& mac_selinux_use() && params
->selinux_context_net
&& socket_fd
>= 0) {
1829 r
= mac_selinux_get_child_mls_label(socket_fd
, command
->path
, context
->selinux_context
, &mac_selinux_context_net
);
1831 *exit_status
= EXIT_SELINUX_CONTEXT
;
1837 /* We repeat the fd closing here, to make sure that
1838 * nothing is leaked from the PAM modules. Note that
1839 * we are more aggressive this time since socket_fd
1840 * and the netns fds we don't need anymore. The custom
1841 * endpoint fd was needed to upload the policy and can
1842 * now be closed as well. */
1843 r
= close_all_fds(fds
, n_fds
);
1845 r
= shift_fds(fds
, n_fds
);
1847 r
= flags_fds(fds
, n_fds
, context
->non_blocking
);
1849 *exit_status
= EXIT_FDS
;
1853 if (params
->apply_permissions
) {
1855 int secure_bits
= context
->secure_bits
;
1857 for (i
= 0; i
< _RLIMIT_MAX
; i
++) {
1858 if (!context
->rlimit
[i
])
1861 if (setrlimit_closest(i
, context
->rlimit
[i
]) < 0) {
1862 *exit_status
= EXIT_LIMITS
;
1867 if (!cap_test_all(context
->capability_bounding_set
)) {
1868 r
= capability_bounding_set_drop(context
->capability_bounding_set
, false);
1870 *exit_status
= EXIT_CAPABILITIES
;
1875 /* This is done before enforce_user, but ambient set
1876 * does not survive over setresuid() if keep_caps is not set. */
1877 if (context
->capability_ambient_set
!= 0) {
1878 r
= capability_ambient_set_apply(context
->capability_ambient_set
, true);
1880 *exit_status
= EXIT_CAPABILITIES
;
1884 if (context
->capabilities
) {
1886 /* The capabilities in ambient set need to be also in the inherited
1887 * set. If they aren't, trying to get them will fail. Add the ambient
1888 * set inherited capabilities to the capability set in the context.
1889 * This is needed because if capabilities are set (using "Capabilities="
1890 * keyword), they will override whatever we set now. */
1892 r
= capability_update_inherited_set(context
->capabilities
, context
->capability_ambient_set
);
1894 *exit_status
= EXIT_CAPABILITIES
;
1900 if (context
->user
) {
1901 r
= enforce_user(context
, uid
);
1903 *exit_status
= EXIT_USER
;
1906 if (context
->capability_ambient_set
!= 0) {
1908 /* Fix the ambient capabilities after user change. */
1909 r
= capability_ambient_set_apply(context
->capability_ambient_set
, false);
1911 *exit_status
= EXIT_CAPABILITIES
;
1915 /* If we were asked to change user and ambient capabilities
1916 * were requested, we had to add keep-caps to the securebits
1917 * so that we would maintain the inherited capability set
1918 * through the setresuid(). Make sure that the bit is added
1919 * also to the context secure_bits so that we don't try to
1920 * drop the bit away next. */
1922 secure_bits
|= 1<<SECURE_KEEP_CAPS
;
1926 /* PR_GET_SECUREBITS is not privileged, while
1927 * PR_SET_SECUREBITS is. So to suppress
1928 * potential EPERMs we'll try not to call
1929 * PR_SET_SECUREBITS unless necessary. */
1930 if (prctl(PR_GET_SECUREBITS
) != secure_bits
)
1931 if (prctl(PR_SET_SECUREBITS
, secure_bits
) < 0) {
1932 *exit_status
= EXIT_SECUREBITS
;
1936 if (context
->capabilities
)
1937 if (cap_set_proc(context
->capabilities
) < 0) {
1938 *exit_status
= EXIT_CAPABILITIES
;
1942 if (context
->no_new_privileges
)
1943 if (prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0) < 0) {
1944 *exit_status
= EXIT_NO_NEW_PRIVILEGES
;
1949 if (context
->address_families_whitelist
||
1950 !set_isempty(context
->address_families
)) {
1951 r
= apply_address_families(context
);
1953 *exit_status
= EXIT_ADDRESS_FAMILIES
;
1958 if (context
->syscall_whitelist
||
1959 !set_isempty(context
->syscall_filter
) ||
1960 !set_isempty(context
->syscall_archs
)) {
1961 r
= apply_seccomp(context
);
1963 *exit_status
= EXIT_SECCOMP
;
1970 if (mac_selinux_use()) {
1971 char *exec_context
= mac_selinux_context_net
?: context
->selinux_context
;
1974 r
= setexeccon(exec_context
);
1976 *exit_status
= EXIT_SELINUX_CONTEXT
;
1983 #ifdef HAVE_APPARMOR
1984 if (context
->apparmor_profile
&& mac_apparmor_use()) {
1985 r
= aa_change_onexec(context
->apparmor_profile
);
1986 if (r
< 0 && !context
->apparmor_profile_ignore
) {
1987 *exit_status
= EXIT_APPARMOR_PROFILE
;
1994 r
= build_environment(context
, n_fds
, params
->fd_names
, params
->watchdog_usec
, home
, username
, shell
, &our_env
);
1996 *exit_status
= EXIT_MEMORY
;
2000 r
= build_pass_environment(context
, &pass_env
);
2002 *exit_status
= EXIT_MEMORY
;
2006 final_env
= strv_env_merge(6,
2007 params
->environment
,
2010 context
->environment
,
2015 *exit_status
= EXIT_MEMORY
;
2019 final_argv
= replace_env_argv(argv
, final_env
);
2021 *exit_status
= EXIT_MEMORY
;
2025 final_env
= strv_env_clean(final_env
);
2027 if (_unlikely_(log_get_max_level() >= LOG_DEBUG
)) {
2028 _cleanup_free_
char *line
;
2030 line
= exec_command_line(final_argv
);
2033 log_struct(LOG_DEBUG
,
2035 "EXECUTABLE=%s", command
->path
,
2036 LOG_UNIT_MESSAGE(unit
, "Executing: %s", line
),
2042 execve(command
->path
, final_argv
, final_env
);
2043 *exit_status
= EXIT_EXEC
;
2047 int exec_spawn(Unit
*unit
,
2048 ExecCommand
*command
,
2049 const ExecContext
*context
,
2050 const ExecParameters
*params
,
2051 ExecRuntime
*runtime
,
2054 _cleanup_strv_free_
char **files_env
= NULL
;
2055 int *fds
= NULL
; unsigned n_fds
= 0;
2056 _cleanup_free_
char *line
= NULL
;
2066 assert(params
->fds
|| params
->n_fds
<= 0);
2068 if (context
->std_input
== EXEC_INPUT_SOCKET
||
2069 context
->std_output
== EXEC_OUTPUT_SOCKET
||
2070 context
->std_error
== EXEC_OUTPUT_SOCKET
) {
2072 if (params
->n_fds
!= 1) {
2073 log_unit_error(unit
, "Got more than one socket.");
2077 socket_fd
= params
->fds
[0];
2081 n_fds
= params
->n_fds
;
2084 r
= exec_context_load_environment(unit
, context
, &files_env
);
2086 return log_unit_error_errno(unit
, r
, "Failed to load environment files: %m");
2088 argv
= params
->argv
?: command
->argv
;
2089 line
= exec_command_line(argv
);
2093 log_struct(LOG_DEBUG
,
2095 LOG_UNIT_MESSAGE(unit
, "About to execute: %s", line
),
2096 "EXECUTABLE=%s", command
->path
,
2100 return log_unit_error_errno(unit
, errno
, "Failed to fork: %m");
2105 r
= exec_child(unit
,
2117 log_struct_errno(LOG_ERR
, r
,
2118 LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED
),
2120 LOG_UNIT_MESSAGE(unit
, "Failed at step %s spawning %s: %m",
2121 exit_status_to_string(exit_status
, EXIT_STATUS_SYSTEMD
),
2123 "EXECUTABLE=%s", command
->path
,
2130 log_unit_debug(unit
, "Forked %s as "PID_FMT
, command
->path
, pid
);
2132 /* We add the new process to the cgroup both in the child (so
2133 * that we can be sure that no user code is ever executed
2134 * outside of the cgroup) and in the parent (so that we can be
2135 * sure that when we kill the cgroup the process will be
2137 if (params
->cgroup_path
)
2138 (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, pid
);
2140 exec_status_start(&command
->exec_status
, pid
);
2146 void exec_context_init(ExecContext
*c
) {
2150 c
->ioprio
= IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE
, 0);
2151 c
->cpu_sched_policy
= SCHED_OTHER
;
2152 c
->syslog_priority
= LOG_DAEMON
|LOG_INFO
;
2153 c
->syslog_level_prefix
= true;
2154 c
->ignore_sigpipe
= true;
2155 c
->timer_slack_nsec
= NSEC_INFINITY
;
2156 c
->personality
= PERSONALITY_INVALID
;
2157 c
->runtime_directory_mode
= 0755;
2158 c
->capability_bounding_set
= CAP_ALL
;
2161 void exec_context_done(ExecContext
*c
) {
2166 c
->environment
= strv_free(c
->environment
);
2167 c
->environment_files
= strv_free(c
->environment_files
);
2168 c
->pass_environment
= strv_free(c
->pass_environment
);
2170 for (l
= 0; l
< ELEMENTSOF(c
->rlimit
); l
++)
2171 c
->rlimit
[l
] = mfree(c
->rlimit
[l
]);
2173 c
->working_directory
= mfree(c
->working_directory
);
2174 c
->root_directory
= mfree(c
->root_directory
);
2175 c
->tty_path
= mfree(c
->tty_path
);
2176 c
->syslog_identifier
= mfree(c
->syslog_identifier
);
2177 c
->user
= mfree(c
->user
);
2178 c
->group
= mfree(c
->group
);
2180 c
->supplementary_groups
= strv_free(c
->supplementary_groups
);
2182 c
->pam_name
= mfree(c
->pam_name
);
2184 if (c
->capabilities
) {
2185 cap_free(c
->capabilities
);
2186 c
->capabilities
= NULL
;
2189 c
->read_only_dirs
= strv_free(c
->read_only_dirs
);
2190 c
->read_write_dirs
= strv_free(c
->read_write_dirs
);
2191 c
->inaccessible_dirs
= strv_free(c
->inaccessible_dirs
);
2194 CPU_FREE(c
->cpuset
);
2196 c
->utmp_id
= mfree(c
->utmp_id
);
2197 c
->selinux_context
= mfree(c
->selinux_context
);
2198 c
->apparmor_profile
= mfree(c
->apparmor_profile
);
2200 c
->syscall_filter
= set_free(c
->syscall_filter
);
2201 c
->syscall_archs
= set_free(c
->syscall_archs
);
2202 c
->address_families
= set_free(c
->address_families
);
2204 c
->runtime_directory
= strv_free(c
->runtime_directory
);
2206 bus_endpoint_free(c
->bus_endpoint
);
2207 c
->bus_endpoint
= NULL
;
2210 int exec_context_destroy_runtime_directory(ExecContext
*c
, const char *runtime_prefix
) {
2215 if (!runtime_prefix
)
2218 STRV_FOREACH(i
, c
->runtime_directory
) {
2219 _cleanup_free_
char *p
;
2221 p
= strjoin(runtime_prefix
, "/", *i
, NULL
);
2225 /* We execute this synchronously, since we need to be
2226 * sure this is gone when we start the service
2228 (void) rm_rf(p
, REMOVE_ROOT
);
2234 void exec_command_done(ExecCommand
*c
) {
2237 c
->path
= mfree(c
->path
);
2239 c
->argv
= strv_free(c
->argv
);
2242 void exec_command_done_array(ExecCommand
*c
, unsigned n
) {
2245 for (i
= 0; i
< n
; i
++)
2246 exec_command_done(c
+i
);
2249 ExecCommand
* exec_command_free_list(ExecCommand
*c
) {
2253 LIST_REMOVE(command
, c
, i
);
2254 exec_command_done(i
);
2261 void exec_command_free_array(ExecCommand
**c
, unsigned n
) {
2264 for (i
= 0; i
< n
; i
++)
2265 c
[i
] = exec_command_free_list(c
[i
]);
2268 typedef struct InvalidEnvInfo
{
2273 static void invalid_env(const char *p
, void *userdata
) {
2274 InvalidEnvInfo
*info
= userdata
;
2276 log_unit_error(info
->unit
, "Ignoring invalid environment assignment '%s': %s", p
, info
->path
);
2279 int exec_context_load_environment(Unit
*unit
, const ExecContext
*c
, char ***l
) {
2280 char **i
, **r
= NULL
;
2285 STRV_FOREACH(i
, c
->environment_files
) {
2288 bool ignore
= false;
2290 _cleanup_globfree_ glob_t pglob
= {};
2300 if (!path_is_absolute(fn
)) {
2308 /* Filename supports globbing, take all matching files */
2310 if (glob(fn
, 0, NULL
, &pglob
) != 0) {
2315 return errno
> 0 ? -errno
: -EINVAL
;
2317 count
= pglob
.gl_pathc
;
2325 for (n
= 0; n
< count
; n
++) {
2326 k
= load_env_file(NULL
, pglob
.gl_pathv
[n
], NULL
, &p
);
2334 /* Log invalid environment variables with filename */
2336 InvalidEnvInfo info
= {
2338 .path
= pglob
.gl_pathv
[n
]
2341 p
= strv_env_clean_with_callback(p
, invalid_env
, &info
);
2349 m
= strv_env_merge(2, r
, p
);
2365 static bool tty_may_match_dev_console(const char *tty
) {
2366 _cleanup_free_
char *active
= NULL
;
2369 if (startswith(tty
, "/dev/"))
2372 /* trivial identity? */
2373 if (streq(tty
, "console"))
2376 console
= resolve_dev_console(&active
);
2377 /* if we could not resolve, assume it may */
2381 /* "tty0" means the active VC, so it may be the same sometimes */
2382 return streq(console
, tty
) || (streq(console
, "tty0") && tty_is_vc(tty
));
2385 bool exec_context_may_touch_console(ExecContext
*ec
) {
2386 return (ec
->tty_reset
|| ec
->tty_vhangup
|| ec
->tty_vt_disallocate
||
2387 is_terminal_input(ec
->std_input
) ||
2388 is_terminal_output(ec
->std_output
) ||
2389 is_terminal_output(ec
->std_error
)) &&
2390 tty_may_match_dev_console(tty_path(ec
));
2393 static void strv_fprintf(FILE *f
, char **l
) {
2399 fprintf(f
, " %s", *g
);
2402 void exec_context_dump(ExecContext
*c
, FILE* f
, const char *prefix
) {
2409 prefix
= strempty(prefix
);
2413 "%sWorkingDirectory: %s\n"
2414 "%sRootDirectory: %s\n"
2415 "%sNonBlocking: %s\n"
2416 "%sPrivateTmp: %s\n"
2417 "%sPrivateNetwork: %s\n"
2418 "%sPrivateDevices: %s\n"
2419 "%sProtectHome: %s\n"
2420 "%sProtectSystem: %s\n"
2421 "%sIgnoreSIGPIPE: %s\n",
2423 prefix
, c
->working_directory
? c
->working_directory
: "/",
2424 prefix
, c
->root_directory
? c
->root_directory
: "/",
2425 prefix
, yes_no(c
->non_blocking
),
2426 prefix
, yes_no(c
->private_tmp
),
2427 prefix
, yes_no(c
->private_network
),
2428 prefix
, yes_no(c
->private_devices
),
2429 prefix
, protect_home_to_string(c
->protect_home
),
2430 prefix
, protect_system_to_string(c
->protect_system
),
2431 prefix
, yes_no(c
->ignore_sigpipe
));
2433 STRV_FOREACH(e
, c
->environment
)
2434 fprintf(f
, "%sEnvironment: %s\n", prefix
, *e
);
2436 STRV_FOREACH(e
, c
->environment_files
)
2437 fprintf(f
, "%sEnvironmentFile: %s\n", prefix
, *e
);
2439 STRV_FOREACH(e
, c
->pass_environment
)
2440 fprintf(f
, "%sPassEnvironment: %s\n", prefix
, *e
);
2442 fprintf(f
, "%sRuntimeDirectoryMode: %04o\n", prefix
, c
->runtime_directory_mode
);
2444 STRV_FOREACH(d
, c
->runtime_directory
)
2445 fprintf(f
, "%sRuntimeDirectory: %s\n", prefix
, *d
);
2452 if (c
->oom_score_adjust_set
)
2454 "%sOOMScoreAdjust: %i\n",
2455 prefix
, c
->oom_score_adjust
);
2457 for (i
= 0; i
< RLIM_NLIMITS
; i
++)
2459 fprintf(f
, "%s%s: " RLIM_FMT
"\n",
2460 prefix
, rlimit_to_string(i
), c
->rlimit
[i
]->rlim_max
);
2461 fprintf(f
, "%s%sSoft: " RLIM_FMT
"\n",
2462 prefix
, rlimit_to_string(i
), c
->rlimit
[i
]->rlim_cur
);
2465 if (c
->ioprio_set
) {
2466 _cleanup_free_
char *class_str
= NULL
;
2468 ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c
->ioprio
), &class_str
);
2470 "%sIOSchedulingClass: %s\n"
2471 "%sIOPriority: %i\n",
2472 prefix
, strna(class_str
),
2473 prefix
, (int) IOPRIO_PRIO_DATA(c
->ioprio
));
2476 if (c
->cpu_sched_set
) {
2477 _cleanup_free_
char *policy_str
= NULL
;
2479 sched_policy_to_string_alloc(c
->cpu_sched_policy
, &policy_str
);
2481 "%sCPUSchedulingPolicy: %s\n"
2482 "%sCPUSchedulingPriority: %i\n"
2483 "%sCPUSchedulingResetOnFork: %s\n",
2484 prefix
, strna(policy_str
),
2485 prefix
, c
->cpu_sched_priority
,
2486 prefix
, yes_no(c
->cpu_sched_reset_on_fork
));
2490 fprintf(f
, "%sCPUAffinity:", prefix
);
2491 for (i
= 0; i
< c
->cpuset_ncpus
; i
++)
2492 if (CPU_ISSET_S(i
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
), c
->cpuset
))
2493 fprintf(f
, " %u", i
);
2497 if (c
->timer_slack_nsec
!= NSEC_INFINITY
)
2498 fprintf(f
, "%sTimerSlackNSec: "NSEC_FMT
"\n", prefix
, c
->timer_slack_nsec
);
2501 "%sStandardInput: %s\n"
2502 "%sStandardOutput: %s\n"
2503 "%sStandardError: %s\n",
2504 prefix
, exec_input_to_string(c
->std_input
),
2505 prefix
, exec_output_to_string(c
->std_output
),
2506 prefix
, exec_output_to_string(c
->std_error
));
2512 "%sTTYVHangup: %s\n"
2513 "%sTTYVTDisallocate: %s\n",
2514 prefix
, c
->tty_path
,
2515 prefix
, yes_no(c
->tty_reset
),
2516 prefix
, yes_no(c
->tty_vhangup
),
2517 prefix
, yes_no(c
->tty_vt_disallocate
));
2519 if (c
->std_output
== EXEC_OUTPUT_SYSLOG
||
2520 c
->std_output
== EXEC_OUTPUT_KMSG
||
2521 c
->std_output
== EXEC_OUTPUT_JOURNAL
||
2522 c
->std_output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2523 c
->std_output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2524 c
->std_output
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
||
2525 c
->std_error
== EXEC_OUTPUT_SYSLOG
||
2526 c
->std_error
== EXEC_OUTPUT_KMSG
||
2527 c
->std_error
== EXEC_OUTPUT_JOURNAL
||
2528 c
->std_error
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2529 c
->std_error
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2530 c
->std_error
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
) {
2532 _cleanup_free_
char *fac_str
= NULL
, *lvl_str
= NULL
;
2534 log_facility_unshifted_to_string_alloc(c
->syslog_priority
>> 3, &fac_str
);
2535 log_level_to_string_alloc(LOG_PRI(c
->syslog_priority
), &lvl_str
);
2538 "%sSyslogFacility: %s\n"
2539 "%sSyslogLevel: %s\n",
2540 prefix
, strna(fac_str
),
2541 prefix
, strna(lvl_str
));
2544 if (c
->capabilities
) {
2545 _cleanup_cap_free_charp_
char *t
;
2547 t
= cap_to_text(c
->capabilities
, NULL
);
2549 fprintf(f
, "%sCapabilities: %s\n", prefix
, t
);
2553 fprintf(f
, "%sSecure Bits:%s%s%s%s%s%s\n",
2555 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS
) ? " keep-caps" : "",
2556 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS_LOCKED
) ? " keep-caps-locked" : "",
2557 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP
) ? " no-setuid-fixup" : "",
2558 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP_LOCKED
) ? " no-setuid-fixup-locked" : "",
2559 (c
->secure_bits
& 1<<SECURE_NOROOT
) ? " noroot" : "",
2560 (c
->secure_bits
& 1<<SECURE_NOROOT_LOCKED
) ? "noroot-locked" : "");
2562 if (c
->capability_bounding_set
!= CAP_ALL
) {
2564 fprintf(f
, "%sCapabilityBoundingSet:", prefix
);
2566 for (l
= 0; l
<= cap_last_cap(); l
++)
2567 if (c
->capability_bounding_set
& (UINT64_C(1) << l
))
2568 fprintf(f
, " %s", strna(capability_to_name(l
)));
2573 if (c
->capability_ambient_set
!= 0) {
2575 fprintf(f
, "%sAmbientCapabilities:", prefix
);
2577 for (l
= 0; l
<= cap_last_cap(); l
++)
2578 if (c
->capability_ambient_set
& (UINT64_C(1) << l
))
2579 fprintf(f
, " %s", strna(capability_to_name(l
)));
2585 fprintf(f
, "%sUser: %s\n", prefix
, c
->user
);
2587 fprintf(f
, "%sGroup: %s\n", prefix
, c
->group
);
2589 if (strv_length(c
->supplementary_groups
) > 0) {
2590 fprintf(f
, "%sSupplementaryGroups:", prefix
);
2591 strv_fprintf(f
, c
->supplementary_groups
);
2596 fprintf(f
, "%sPAMName: %s\n", prefix
, c
->pam_name
);
2598 if (strv_length(c
->read_write_dirs
) > 0) {
2599 fprintf(f
, "%sReadWriteDirs:", prefix
);
2600 strv_fprintf(f
, c
->read_write_dirs
);
2604 if (strv_length(c
->read_only_dirs
) > 0) {
2605 fprintf(f
, "%sReadOnlyDirs:", prefix
);
2606 strv_fprintf(f
, c
->read_only_dirs
);
2610 if (strv_length(c
->inaccessible_dirs
) > 0) {
2611 fprintf(f
, "%sInaccessibleDirs:", prefix
);
2612 strv_fprintf(f
, c
->inaccessible_dirs
);
2618 "%sUtmpIdentifier: %s\n",
2619 prefix
, c
->utmp_id
);
2621 if (c
->selinux_context
)
2623 "%sSELinuxContext: %s%s\n",
2624 prefix
, c
->selinux_context_ignore
? "-" : "", c
->selinux_context
);
2626 if (c
->personality
!= PERSONALITY_INVALID
)
2628 "%sPersonality: %s\n",
2629 prefix
, strna(personality_to_string(c
->personality
)));
2631 if (c
->syscall_filter
) {
2639 "%sSystemCallFilter: ",
2642 if (!c
->syscall_whitelist
)
2646 SET_FOREACH(id
, c
->syscall_filter
, j
) {
2647 _cleanup_free_
char *name
= NULL
;
2654 name
= seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE
, PTR_TO_INT(id
) - 1);
2655 fputs(strna(name
), f
);
2662 if (c
->syscall_archs
) {
2669 "%sSystemCallArchitectures:",
2673 SET_FOREACH(id
, c
->syscall_archs
, j
)
2674 fprintf(f
, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id
) - 1)));
2679 if (c
->syscall_errno
> 0)
2681 "%sSystemCallErrorNumber: %s\n",
2682 prefix
, strna(errno_to_name(c
->syscall_errno
)));
2684 if (c
->apparmor_profile
)
2686 "%sAppArmorProfile: %s%s\n",
2687 prefix
, c
->apparmor_profile_ignore
? "-" : "", c
->apparmor_profile
);
2690 bool exec_context_maintains_privileges(ExecContext
*c
) {
2693 /* Returns true if the process forked off would run run under
2694 * an unchanged UID or as root. */
2699 if (streq(c
->user
, "root") || streq(c
->user
, "0"))
2705 void exec_status_start(ExecStatus
*s
, pid_t pid
) {
2710 dual_timestamp_get(&s
->start_timestamp
);
2713 void exec_status_exit(ExecStatus
*s
, ExecContext
*context
, pid_t pid
, int code
, int status
) {
2716 if (s
->pid
&& s
->pid
!= pid
)
2720 dual_timestamp_get(&s
->exit_timestamp
);
2726 if (context
->utmp_id
)
2727 utmp_put_dead_process(context
->utmp_id
, pid
, code
, status
);
2729 exec_context_tty_reset(context
);
2733 void exec_status_dump(ExecStatus
*s
, FILE *f
, const char *prefix
) {
2734 char buf
[FORMAT_TIMESTAMP_MAX
];
2742 prefix
= strempty(prefix
);
2745 "%sPID: "PID_FMT
"\n",
2748 if (s
->start_timestamp
.realtime
> 0)
2750 "%sStart Timestamp: %s\n",
2751 prefix
, format_timestamp(buf
, sizeof(buf
), s
->start_timestamp
.realtime
));
2753 if (s
->exit_timestamp
.realtime
> 0)
2755 "%sExit Timestamp: %s\n"
2757 "%sExit Status: %i\n",
2758 prefix
, format_timestamp(buf
, sizeof(buf
), s
->exit_timestamp
.realtime
),
2759 prefix
, sigchld_code_to_string(s
->code
),
2763 char *exec_command_line(char **argv
) {
2771 STRV_FOREACH(a
, argv
)
2774 if (!(n
= new(char, k
)))
2778 STRV_FOREACH(a
, argv
) {
2785 if (strpbrk(*a
, WHITESPACE
)) {
2796 /* FIXME: this doesn't really handle arguments that have
2797 * spaces and ticks in them */
2802 void exec_command_dump(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2803 _cleanup_free_
char *cmd
= NULL
;
2804 const char *prefix2
;
2809 prefix
= strempty(prefix
);
2810 prefix2
= strjoina(prefix
, "\t");
2812 cmd
= exec_command_line(c
->argv
);
2814 "%sCommand Line: %s\n",
2815 prefix
, cmd
? cmd
: strerror(ENOMEM
));
2817 exec_status_dump(&c
->exec_status
, f
, prefix2
);
2820 void exec_command_dump_list(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2823 prefix
= strempty(prefix
);
2825 LIST_FOREACH(command
, c
, c
)
2826 exec_command_dump(c
, f
, prefix
);
2829 void exec_command_append_list(ExecCommand
**l
, ExecCommand
*e
) {
2836 /* It's kind of important, that we keep the order here */
2837 LIST_FIND_TAIL(command
, *l
, end
);
2838 LIST_INSERT_AFTER(command
, *l
, end
, e
);
2843 int exec_command_set(ExecCommand
*c
, const char *path
, ...) {
2851 l
= strv_new_ap(path
, ap
);
2872 int exec_command_append(ExecCommand
*c
, const char *path
, ...) {
2873 _cleanup_strv_free_
char **l
= NULL
;
2881 l
= strv_new_ap(path
, ap
);
2887 r
= strv_extend_strv(&c
->argv
, l
, false);
2895 static int exec_runtime_allocate(ExecRuntime
**rt
) {
2900 *rt
= new0(ExecRuntime
, 1);
2905 (*rt
)->netns_storage_socket
[0] = (*rt
)->netns_storage_socket
[1] = -1;
2910 int exec_runtime_make(ExecRuntime
**rt
, ExecContext
*c
, const char *id
) {
2920 if (!c
->private_network
&& !c
->private_tmp
)
2923 r
= exec_runtime_allocate(rt
);
2927 if (c
->private_network
&& (*rt
)->netns_storage_socket
[0] < 0) {
2928 if (socketpair(AF_UNIX
, SOCK_DGRAM
, 0, (*rt
)->netns_storage_socket
) < 0)
2932 if (c
->private_tmp
&& !(*rt
)->tmp_dir
) {
2933 r
= setup_tmp_dirs(id
, &(*rt
)->tmp_dir
, &(*rt
)->var_tmp_dir
);
2941 ExecRuntime
*exec_runtime_ref(ExecRuntime
*r
) {
2943 assert(r
->n_ref
> 0);
2949 ExecRuntime
*exec_runtime_unref(ExecRuntime
*r
) {
2954 assert(r
->n_ref
> 0);
2961 free(r
->var_tmp_dir
);
2962 safe_close_pair(r
->netns_storage_socket
);
2968 int exec_runtime_serialize(Unit
*u
, ExecRuntime
*rt
, FILE *f
, FDSet
*fds
) {
2977 unit_serialize_item(u
, f
, "tmp-dir", rt
->tmp_dir
);
2979 if (rt
->var_tmp_dir
)
2980 unit_serialize_item(u
, f
, "var-tmp-dir", rt
->var_tmp_dir
);
2982 if (rt
->netns_storage_socket
[0] >= 0) {
2985 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[0]);
2989 unit_serialize_item_format(u
, f
, "netns-socket-0", "%i", copy
);
2992 if (rt
->netns_storage_socket
[1] >= 0) {
2995 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[1]);
2999 unit_serialize_item_format(u
, f
, "netns-socket-1", "%i", copy
);
3005 int exec_runtime_deserialize_item(Unit
*u
, ExecRuntime
**rt
, const char *key
, const char *value
, FDSet
*fds
) {
3012 if (streq(key
, "tmp-dir")) {
3015 r
= exec_runtime_allocate(rt
);
3019 copy
= strdup(value
);
3023 free((*rt
)->tmp_dir
);
3024 (*rt
)->tmp_dir
= copy
;
3026 } else if (streq(key
, "var-tmp-dir")) {
3029 r
= exec_runtime_allocate(rt
);
3033 copy
= strdup(value
);
3037 free((*rt
)->var_tmp_dir
);
3038 (*rt
)->var_tmp_dir
= copy
;
3040 } else if (streq(key
, "netns-socket-0")) {
3043 r
= exec_runtime_allocate(rt
);
3047 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
3048 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
3050 safe_close((*rt
)->netns_storage_socket
[0]);
3051 (*rt
)->netns_storage_socket
[0] = fdset_remove(fds
, fd
);
3053 } else if (streq(key
, "netns-socket-1")) {
3056 r
= exec_runtime_allocate(rt
);
3060 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
3061 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
3063 safe_close((*rt
)->netns_storage_socket
[1]);
3064 (*rt
)->netns_storage_socket
[1] = fdset_remove(fds
, fd
);
3072 static void *remove_tmpdir_thread(void *p
) {
3073 _cleanup_free_
char *path
= p
;
3075 (void) rm_rf(path
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
3079 void exec_runtime_destroy(ExecRuntime
*rt
) {
3085 /* If there are multiple users of this, let's leave the stuff around */
3090 log_debug("Spawning thread to nuke %s", rt
->tmp_dir
);
3092 r
= asynchronous_job(remove_tmpdir_thread
, rt
->tmp_dir
);
3094 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->tmp_dir
);
3101 if (rt
->var_tmp_dir
) {
3102 log_debug("Spawning thread to nuke %s", rt
->var_tmp_dir
);
3104 r
= asynchronous_job(remove_tmpdir_thread
, rt
->var_tmp_dir
);
3106 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->var_tmp_dir
);
3107 free(rt
->var_tmp_dir
);
3110 rt
->var_tmp_dir
= NULL
;
3113 safe_close_pair(rt
->netns_storage_socket
);
3116 static const char* const exec_input_table
[_EXEC_INPUT_MAX
] = {
3117 [EXEC_INPUT_NULL
] = "null",
3118 [EXEC_INPUT_TTY
] = "tty",
3119 [EXEC_INPUT_TTY_FORCE
] = "tty-force",
3120 [EXEC_INPUT_TTY_FAIL
] = "tty-fail",
3121 [EXEC_INPUT_SOCKET
] = "socket"
3124 DEFINE_STRING_TABLE_LOOKUP(exec_input
, ExecInput
);
3126 static const char* const exec_output_table
[_EXEC_OUTPUT_MAX
] = {
3127 [EXEC_OUTPUT_INHERIT
] = "inherit",
3128 [EXEC_OUTPUT_NULL
] = "null",
3129 [EXEC_OUTPUT_TTY
] = "tty",
3130 [EXEC_OUTPUT_SYSLOG
] = "syslog",
3131 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE
] = "syslog+console",
3132 [EXEC_OUTPUT_KMSG
] = "kmsg",
3133 [EXEC_OUTPUT_KMSG_AND_CONSOLE
] = "kmsg+console",
3134 [EXEC_OUTPUT_JOURNAL
] = "journal",
3135 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE
] = "journal+console",
3136 [EXEC_OUTPUT_SOCKET
] = "socket"
3139 DEFINE_STRING_TABLE_LOOKUP(exec_output
, ExecOutput
);
3141 static const char* const exec_utmp_mode_table
[_EXEC_UTMP_MODE_MAX
] = {
3142 [EXEC_UTMP_INIT
] = "init",
3143 [EXEC_UTMP_LOGIN
] = "login",
3144 [EXEC_UTMP_USER
] = "user",
3147 DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode
, ExecUtmpMode
);