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
;
820 bool close_session
= false;
821 pid_t pam_pid
= 0, parent_pid
;
828 /* We set up PAM in the parent process, then fork. The child
829 * will then stay around until killed via PR_GET_PDEATHSIG or
830 * systemd via the cgroup logic. It will then remove the PAM
831 * session again. The parent process will exec() the actual
832 * daemon. We do things this way to ensure that the main PID
833 * of the daemon is the one we initially fork()ed. */
835 err
= barrier_create(&barrier
);
839 if (log_get_max_level() < LOG_DEBUG
)
842 pam_code
= pam_start(name
, user
, &conv
, &handle
);
843 if (pam_code
!= PAM_SUCCESS
) {
849 pam_code
= pam_set_item(handle
, PAM_TTY
, tty
);
850 if (pam_code
!= PAM_SUCCESS
)
854 pam_code
= pam_acct_mgmt(handle
, flags
);
855 if (pam_code
!= PAM_SUCCESS
)
858 pam_code
= pam_open_session(handle
, flags
);
859 if (pam_code
!= PAM_SUCCESS
)
862 close_session
= true;
864 e
= pam_getenvlist(handle
);
866 pam_code
= PAM_BUF_ERR
;
870 /* Block SIGTERM, so that we know that it won't get lost in
873 assert_se(sigprocmask_many(SIG_BLOCK
, &old_ss
, SIGTERM
, -1) >= 0);
875 parent_pid
= getpid();
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 err
= -EPERM
; /* PAM errors do not map to errno */
983 err
= log_error_errno(err
< 0 ? err
: errno
, "PAM failed: %m");
988 pam_code
= pam_close_session(handle
, flags
);
990 pam_end(handle
, pam_code
| flags
);
1000 static void rename_process_from_path(const char *path
) {
1001 char process_name
[11];
1005 /* This resulting string must fit in 10 chars (i.e. the length
1006 * of "/sbin/init") to look pretty in /bin/ps */
1010 rename_process("(...)");
1016 /* The end of the process name is usually more
1017 * interesting, since the first bit might just be
1023 process_name
[0] = '(';
1024 memcpy(process_name
+1, p
, l
);
1025 process_name
[1+l
] = ')';
1026 process_name
[1+l
+1] = 0;
1028 rename_process(process_name
);
1033 static int apply_seccomp(const ExecContext
*c
) {
1034 uint32_t negative_action
, action
;
1035 scmp_filter_ctx
*seccomp
;
1042 negative_action
= c
->syscall_errno
== 0 ? SCMP_ACT_KILL
: SCMP_ACT_ERRNO(c
->syscall_errno
);
1044 seccomp
= seccomp_init(c
->syscall_whitelist
? negative_action
: SCMP_ACT_ALLOW
);
1048 if (c
->syscall_archs
) {
1050 SET_FOREACH(id
, c
->syscall_archs
, i
) {
1051 r
= seccomp_arch_add(seccomp
, PTR_TO_UINT32(id
) - 1);
1059 r
= seccomp_add_secondary_archs(seccomp
);
1064 action
= c
->syscall_whitelist
? SCMP_ACT_ALLOW
: negative_action
;
1065 SET_FOREACH(id
, c
->syscall_filter
, i
) {
1066 r
= seccomp_rule_add(seccomp
, action
, PTR_TO_INT(id
) - 1, 0);
1071 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1075 r
= seccomp_load(seccomp
);
1078 seccomp_release(seccomp
);
1082 static int apply_address_families(const ExecContext
*c
) {
1083 scmp_filter_ctx
*seccomp
;
1089 seccomp
= seccomp_init(SCMP_ACT_ALLOW
);
1093 r
= seccomp_add_secondary_archs(seccomp
);
1097 if (c
->address_families_whitelist
) {
1098 int af
, first
= 0, last
= 0;
1101 /* If this is a whitelist, we first block the address
1102 * families that are out of range and then everything
1103 * that is not in the set. First, we find the lowest
1104 * and highest address family in the set. */
1106 SET_FOREACH(afp
, c
->address_families
, i
) {
1107 af
= PTR_TO_INT(afp
);
1109 if (af
<= 0 || af
>= af_max())
1112 if (first
== 0 || af
< first
)
1115 if (last
== 0 || af
> last
)
1119 assert((first
== 0) == (last
== 0));
1123 /* No entries in the valid range, block everything */
1124 r
= seccomp_rule_add(
1126 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1134 /* Block everything below the first entry */
1135 r
= seccomp_rule_add(
1137 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1140 SCMP_A0(SCMP_CMP_LT
, first
));
1144 /* Block everything above the last entry */
1145 r
= seccomp_rule_add(
1147 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1150 SCMP_A0(SCMP_CMP_GT
, last
));
1154 /* Block everything between the first and last
1156 for (af
= 1; af
< af_max(); af
++) {
1158 if (set_contains(c
->address_families
, INT_TO_PTR(af
)))
1161 r
= seccomp_rule_add(
1163 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1166 SCMP_A0(SCMP_CMP_EQ
, af
));
1175 /* If this is a blacklist, then generate one rule for
1176 * each address family that are then combined in OR
1179 SET_FOREACH(af
, c
->address_families
, i
) {
1181 r
= seccomp_rule_add(
1183 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1186 SCMP_A0(SCMP_CMP_EQ
, PTR_TO_INT(af
)));
1192 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1196 r
= seccomp_load(seccomp
);
1199 seccomp_release(seccomp
);
1205 static void do_idle_pipe_dance(int idle_pipe
[4]) {
1209 idle_pipe
[1] = safe_close(idle_pipe
[1]);
1210 idle_pipe
[2] = safe_close(idle_pipe
[2]);
1212 if (idle_pipe
[0] >= 0) {
1215 r
= fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT_USEC
);
1217 if (idle_pipe
[3] >= 0 && r
== 0 /* timeout */) {
1220 /* Signal systemd that we are bored and want to continue. */
1221 n
= write(idle_pipe
[3], "x", 1);
1223 /* Wait for systemd to react to the signal above. */
1224 fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT2_USEC
);
1227 idle_pipe
[0] = safe_close(idle_pipe
[0]);
1231 idle_pipe
[3] = safe_close(idle_pipe
[3]);
1234 static int build_environment(
1235 const ExecContext
*c
,
1238 usec_t watchdog_usec
,
1240 const char *username
,
1244 _cleanup_strv_free_
char **our_env
= NULL
;
1251 our_env
= new0(char*, 11);
1256 _cleanup_free_
char *joined
= NULL
;
1258 if (asprintf(&x
, "LISTEN_PID="PID_FMT
, getpid()) < 0)
1260 our_env
[n_env
++] = x
;
1262 if (asprintf(&x
, "LISTEN_FDS=%u", n_fds
) < 0)
1264 our_env
[n_env
++] = x
;
1266 joined
= strv_join(fd_names
, ":");
1270 x
= strjoin("LISTEN_FDNAMES=", joined
, NULL
);
1273 our_env
[n_env
++] = x
;
1276 if (watchdog_usec
> 0) {
1277 if (asprintf(&x
, "WATCHDOG_PID="PID_FMT
, getpid()) < 0)
1279 our_env
[n_env
++] = x
;
1281 if (asprintf(&x
, "WATCHDOG_USEC="USEC_FMT
, watchdog_usec
) < 0)
1283 our_env
[n_env
++] = x
;
1287 x
= strappend("HOME=", home
);
1290 our_env
[n_env
++] = x
;
1294 x
= strappend("LOGNAME=", username
);
1297 our_env
[n_env
++] = x
;
1299 x
= strappend("USER=", username
);
1302 our_env
[n_env
++] = x
;
1306 x
= strappend("SHELL=", shell
);
1309 our_env
[n_env
++] = x
;
1312 if (is_terminal_input(c
->std_input
) ||
1313 c
->std_output
== EXEC_OUTPUT_TTY
||
1314 c
->std_error
== EXEC_OUTPUT_TTY
||
1317 x
= strdup(default_term_for_tty(tty_path(c
)));
1320 our_env
[n_env
++] = x
;
1323 our_env
[n_env
++] = NULL
;
1324 assert(n_env
<= 11);
1332 static int build_pass_environment(const ExecContext
*c
, char ***ret
) {
1333 _cleanup_strv_free_
char **pass_env
= NULL
;
1334 size_t n_env
= 0, n_bufsize
= 0;
1337 STRV_FOREACH(i
, c
->pass_environment
) {
1338 _cleanup_free_
char *x
= NULL
;
1344 x
= strjoin(*i
, "=", v
, NULL
);
1347 if (!GREEDY_REALLOC(pass_env
, n_bufsize
, n_env
+ 2))
1349 pass_env
[n_env
++] = x
;
1350 pass_env
[n_env
] = NULL
;
1360 static bool exec_needs_mount_namespace(
1361 const ExecContext
*context
,
1362 const ExecParameters
*params
,
1363 ExecRuntime
*runtime
) {
1368 if (!strv_isempty(context
->read_write_dirs
) ||
1369 !strv_isempty(context
->read_only_dirs
) ||
1370 !strv_isempty(context
->inaccessible_dirs
))
1373 if (context
->mount_flags
!= 0)
1376 if (context
->private_tmp
&& runtime
&& (runtime
->tmp_dir
|| runtime
->var_tmp_dir
))
1379 if (params
->bus_endpoint_path
)
1382 if (context
->private_devices
||
1383 context
->protect_system
!= PROTECT_SYSTEM_NO
||
1384 context
->protect_home
!= PROTECT_HOME_NO
)
1390 static int close_remaining_fds(
1391 const ExecParameters
*params
,
1392 ExecRuntime
*runtime
,
1394 int *fds
, unsigned n_fds
) {
1396 unsigned n_dont_close
= 0;
1397 int dont_close
[n_fds
+ 7];
1401 if (params
->stdin_fd
>= 0)
1402 dont_close
[n_dont_close
++] = params
->stdin_fd
;
1403 if (params
->stdout_fd
>= 0)
1404 dont_close
[n_dont_close
++] = params
->stdout_fd
;
1405 if (params
->stderr_fd
>= 0)
1406 dont_close
[n_dont_close
++] = params
->stderr_fd
;
1409 dont_close
[n_dont_close
++] = socket_fd
;
1411 memcpy(dont_close
+ n_dont_close
, fds
, sizeof(int) * n_fds
);
1412 n_dont_close
+= n_fds
;
1415 if (params
->bus_endpoint_fd
>= 0)
1416 dont_close
[n_dont_close
++] = params
->bus_endpoint_fd
;
1419 if (runtime
->netns_storage_socket
[0] >= 0)
1420 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[0];
1421 if (runtime
->netns_storage_socket
[1] >= 0)
1422 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[1];
1425 return close_all_fds(dont_close
, n_dont_close
);
1428 static int exec_child(
1430 ExecCommand
*command
,
1431 const ExecContext
*context
,
1432 const ExecParameters
*params
,
1433 ExecRuntime
*runtime
,
1436 int *fds
, unsigned n_fds
,
1440 _cleanup_strv_free_
char **our_env
= NULL
, **pass_env
= NULL
, **pam_env
= NULL
, **final_env
= NULL
, **final_argv
= NULL
;
1441 _cleanup_free_
char *mac_selinux_context_net
= NULL
;
1442 const char *username
= NULL
, *home
= NULL
, *shell
= NULL
, *wd
;
1443 uid_t uid
= UID_INVALID
;
1444 gid_t gid
= GID_INVALID
;
1446 bool needs_mount_namespace
;
1452 assert(exit_status
);
1454 rename_process_from_path(command
->path
);
1456 /* We reset exactly these signals, since they are the
1457 * only ones we set to SIG_IGN in the main daemon. All
1458 * others we leave untouched because we set them to
1459 * SIG_DFL or a valid handler initially, both of which
1460 * will be demoted to SIG_DFL. */
1461 (void) default_signals(SIGNALS_CRASH_HANDLER
,
1462 SIGNALS_IGNORE
, -1);
1464 if (context
->ignore_sigpipe
)
1465 (void) ignore_signals(SIGPIPE
, -1);
1467 r
= reset_signal_mask();
1469 *exit_status
= EXIT_SIGNAL_MASK
;
1473 if (params
->idle_pipe
)
1474 do_idle_pipe_dance(params
->idle_pipe
);
1476 /* Close sockets very early to make sure we don't
1477 * block init reexecution because it cannot bind its
1482 r
= close_remaining_fds(params
, runtime
, socket_fd
, fds
, n_fds
);
1484 *exit_status
= EXIT_FDS
;
1488 if (!context
->same_pgrp
)
1490 *exit_status
= EXIT_SETSID
;
1494 exec_context_tty_reset(context
);
1496 if (params
->confirm_spawn
) {
1499 r
= ask_for_confirmation(&response
, argv
);
1500 if (r
== -ETIMEDOUT
)
1501 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1503 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r
));
1504 else if (response
== 's') {
1505 write_confirm_message("Skipping execution.\n");
1506 *exit_status
= EXIT_CONFIRM
;
1508 } else if (response
== 'n') {
1509 write_confirm_message("Failing execution.\n");
1515 if (context
->user
) {
1516 username
= context
->user
;
1517 r
= get_user_creds(&username
, &uid
, &gid
, &home
, &shell
);
1519 *exit_status
= EXIT_USER
;
1524 if (context
->group
) {
1525 const char *g
= context
->group
;
1527 r
= get_group_creds(&g
, &gid
);
1529 *exit_status
= EXIT_GROUP
;
1535 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1536 * must sure to drop O_NONBLOCK */
1538 (void) fd_nonblock(socket_fd
, false);
1540 r
= setup_input(context
, params
, socket_fd
);
1542 *exit_status
= EXIT_STDIN
;
1546 r
= setup_output(unit
, context
, params
, STDOUT_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1548 *exit_status
= EXIT_STDOUT
;
1552 r
= setup_output(unit
, context
, params
, STDERR_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1554 *exit_status
= EXIT_STDERR
;
1558 if (params
->cgroup_path
) {
1559 r
= cg_attach_everywhere(params
->cgroup_supported
, params
->cgroup_path
, 0, NULL
, NULL
);
1561 *exit_status
= EXIT_CGROUP
;
1566 if (context
->oom_score_adjust_set
) {
1567 char t
[DECIMAL_STR_MAX(context
->oom_score_adjust
)];
1569 /* When we can't make this change due to EPERM, then
1570 * let's silently skip over it. User namespaces
1571 * prohibit write access to this file, and we
1572 * shouldn't trip up over that. */
1574 sprintf(t
, "%i", context
->oom_score_adjust
);
1575 r
= write_string_file("/proc/self/oom_score_adj", t
, 0);
1576 if (r
== -EPERM
|| r
== -EACCES
) {
1578 log_unit_debug_errno(unit
, r
, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
1581 *exit_status
= EXIT_OOM_ADJUST
;
1586 if (context
->nice_set
)
1587 if (setpriority(PRIO_PROCESS
, 0, context
->nice
) < 0) {
1588 *exit_status
= EXIT_NICE
;
1592 if (context
->cpu_sched_set
) {
1593 struct sched_param param
= {
1594 .sched_priority
= context
->cpu_sched_priority
,
1597 r
= sched_setscheduler(0,
1598 context
->cpu_sched_policy
|
1599 (context
->cpu_sched_reset_on_fork
?
1600 SCHED_RESET_ON_FORK
: 0),
1603 *exit_status
= EXIT_SETSCHEDULER
;
1608 if (context
->cpuset
)
1609 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context
->cpuset_ncpus
), context
->cpuset
) < 0) {
1610 *exit_status
= EXIT_CPUAFFINITY
;
1614 if (context
->ioprio_set
)
1615 if (ioprio_set(IOPRIO_WHO_PROCESS
, 0, context
->ioprio
) < 0) {
1616 *exit_status
= EXIT_IOPRIO
;
1620 if (context
->timer_slack_nsec
!= NSEC_INFINITY
)
1621 if (prctl(PR_SET_TIMERSLACK
, context
->timer_slack_nsec
) < 0) {
1622 *exit_status
= EXIT_TIMERSLACK
;
1626 if (context
->personality
!= PERSONALITY_INVALID
)
1627 if (personality(context
->personality
) < 0) {
1628 *exit_status
= EXIT_PERSONALITY
;
1632 if (context
->utmp_id
)
1633 utmp_put_init_process(context
->utmp_id
, getpid(), getsid(0), context
->tty_path
,
1634 context
->utmp_mode
== EXEC_UTMP_INIT
? INIT_PROCESS
:
1635 context
->utmp_mode
== EXEC_UTMP_LOGIN
? LOGIN_PROCESS
:
1637 username
? "root" : context
->user
);
1639 if (context
->user
&& is_terminal_input(context
->std_input
)) {
1640 r
= chown_terminal(STDIN_FILENO
, uid
);
1642 *exit_status
= EXIT_STDIN
;
1647 if (params
->bus_endpoint_fd
>= 0 && context
->bus_endpoint
) {
1648 uid_t ep_uid
= (uid
== UID_INVALID
) ? 0 : uid
;
1650 r
= bus_kernel_set_endpoint_policy(params
->bus_endpoint_fd
, ep_uid
, context
->bus_endpoint
);
1652 *exit_status
= EXIT_BUS_ENDPOINT
;
1657 /* If delegation is enabled we'll pass ownership of the cgroup
1658 * (but only in systemd's own controller hierarchy!) to the
1659 * user of the new process. */
1660 if (params
->cgroup_path
&& context
->user
&& params
->cgroup_delegate
) {
1661 r
= cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0644, uid
, gid
);
1663 *exit_status
= EXIT_CGROUP
;
1668 r
= cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0755, uid
, gid
);
1670 *exit_status
= EXIT_CGROUP
;
1675 if (!strv_isempty(context
->runtime_directory
) && params
->runtime_prefix
) {
1678 STRV_FOREACH(rt
, context
->runtime_directory
) {
1679 _cleanup_free_
char *p
;
1681 p
= strjoin(params
->runtime_prefix
, "/", *rt
, NULL
);
1683 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1687 r
= mkdir_p_label(p
, context
->runtime_directory_mode
);
1689 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1693 r
= chmod_and_chown(p
, context
->runtime_directory_mode
, uid
, gid
);
1695 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1701 umask(context
->umask
);
1703 if (params
->apply_permissions
) {
1704 r
= enforce_groups(context
, username
, gid
);
1706 *exit_status
= EXIT_GROUP
;
1710 if (context
->smack_process_label
) {
1711 r
= mac_smack_apply_pid(0, context
->smack_process_label
);
1713 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1717 #ifdef SMACK_DEFAULT_PROCESS_LABEL
1719 _cleanup_free_
char *exec_label
= NULL
;
1721 r
= mac_smack_read(command
->path
, SMACK_ATTR_EXEC
, &exec_label
);
1722 if (r
< 0 && r
!= -ENODATA
&& r
!= -EOPNOTSUPP
) {
1723 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1727 r
= mac_smack_apply_pid(0, exec_label
? : SMACK_DEFAULT_PROCESS_LABEL
);
1729 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1736 if (context
->pam_name
&& username
) {
1737 r
= setup_pam(context
->pam_name
, username
, uid
, context
->tty_path
, &pam_env
, fds
, n_fds
);
1739 *exit_status
= EXIT_PAM
;
1746 if (context
->private_network
&& runtime
&& runtime
->netns_storage_socket
[0] >= 0) {
1747 r
= setup_netns(runtime
->netns_storage_socket
);
1749 *exit_status
= EXIT_NETWORK
;
1754 needs_mount_namespace
= exec_needs_mount_namespace(context
, params
, runtime
);
1756 if (needs_mount_namespace
) {
1757 char *tmp
= NULL
, *var
= NULL
;
1759 /* The runtime struct only contains the parent
1760 * of the private /tmp, which is
1761 * non-accessible to world users. Inside of it
1762 * there's a /tmp that is sticky, and that's
1763 * the one we want to use here. */
1765 if (context
->private_tmp
&& runtime
) {
1766 if (runtime
->tmp_dir
)
1767 tmp
= strjoina(runtime
->tmp_dir
, "/tmp");
1768 if (runtime
->var_tmp_dir
)
1769 var
= strjoina(runtime
->var_tmp_dir
, "/tmp");
1772 r
= setup_namespace(
1773 params
->apply_chroot
? context
->root_directory
: NULL
,
1774 context
->read_write_dirs
,
1775 context
->read_only_dirs
,
1776 context
->inaccessible_dirs
,
1779 params
->bus_endpoint_path
,
1780 context
->private_devices
,
1781 context
->protect_home
,
1782 context
->protect_system
,
1783 context
->mount_flags
);
1785 /* If we couldn't set up the namespace this is
1786 * probably due to a missing capability. In this case,
1787 * silently proceeed. */
1788 if (r
== -EPERM
|| r
== -EACCES
) {
1790 log_unit_debug_errno(unit
, r
, "Failed to set up namespace, assuming containerized execution, ignoring: %m");
1793 *exit_status
= EXIT_NAMESPACE
;
1798 if (context
->working_directory_home
)
1800 else if (context
->working_directory
)
1801 wd
= context
->working_directory
;
1805 if (params
->apply_chroot
) {
1806 if (!needs_mount_namespace
&& context
->root_directory
)
1807 if (chroot(context
->root_directory
) < 0) {
1808 *exit_status
= EXIT_CHROOT
;
1812 if (chdir(wd
) < 0 &&
1813 !context
->working_directory_missing_ok
) {
1814 *exit_status
= EXIT_CHDIR
;
1820 d
= strjoina(strempty(context
->root_directory
), "/", strempty(wd
));
1822 !context
->working_directory_missing_ok
) {
1823 *exit_status
= EXIT_CHDIR
;
1829 if (params
->apply_permissions
&& mac_selinux_use() && params
->selinux_context_net
&& socket_fd
>= 0) {
1830 r
= mac_selinux_get_child_mls_label(socket_fd
, command
->path
, context
->selinux_context
, &mac_selinux_context_net
);
1832 *exit_status
= EXIT_SELINUX_CONTEXT
;
1838 /* We repeat the fd closing here, to make sure that
1839 * nothing is leaked from the PAM modules. Note that
1840 * we are more aggressive this time since socket_fd
1841 * and the netns fds we don't need anymore. The custom
1842 * endpoint fd was needed to upload the policy and can
1843 * now be closed as well. */
1844 r
= close_all_fds(fds
, n_fds
);
1846 r
= shift_fds(fds
, n_fds
);
1848 r
= flags_fds(fds
, n_fds
, context
->non_blocking
);
1850 *exit_status
= EXIT_FDS
;
1854 if (params
->apply_permissions
) {
1856 int secure_bits
= context
->secure_bits
;
1858 for (i
= 0; i
< _RLIMIT_MAX
; i
++) {
1859 if (!context
->rlimit
[i
])
1862 if (setrlimit_closest(i
, context
->rlimit
[i
]) < 0) {
1863 *exit_status
= EXIT_LIMITS
;
1868 if (!cap_test_all(context
->capability_bounding_set
)) {
1869 r
= capability_bounding_set_drop(context
->capability_bounding_set
, false);
1871 *exit_status
= EXIT_CAPABILITIES
;
1876 /* This is done before enforce_user, but ambient set
1877 * does not survive over setresuid() if keep_caps is not set. */
1878 if (context
->capability_ambient_set
!= 0) {
1879 r
= capability_ambient_set_apply(context
->capability_ambient_set
, true);
1881 *exit_status
= EXIT_CAPABILITIES
;
1885 if (context
->capabilities
) {
1887 /* The capabilities in ambient set need to be also in the inherited
1888 * set. If they aren't, trying to get them will fail. Add the ambient
1889 * set inherited capabilities to the capability set in the context.
1890 * This is needed because if capabilities are set (using "Capabilities="
1891 * keyword), they will override whatever we set now. */
1893 r
= capability_update_inherited_set(context
->capabilities
, context
->capability_ambient_set
);
1895 *exit_status
= EXIT_CAPABILITIES
;
1901 if (context
->user
) {
1902 r
= enforce_user(context
, uid
);
1904 *exit_status
= EXIT_USER
;
1907 if (context
->capability_ambient_set
!= 0) {
1909 /* Fix the ambient capabilities after user change. */
1910 r
= capability_ambient_set_apply(context
->capability_ambient_set
, false);
1912 *exit_status
= EXIT_CAPABILITIES
;
1916 /* If we were asked to change user and ambient capabilities
1917 * were requested, we had to add keep-caps to the securebits
1918 * so that we would maintain the inherited capability set
1919 * through the setresuid(). Make sure that the bit is added
1920 * also to the context secure_bits so that we don't try to
1921 * drop the bit away next. */
1923 secure_bits
|= 1<<SECURE_KEEP_CAPS
;
1927 /* PR_GET_SECUREBITS is not privileged, while
1928 * PR_SET_SECUREBITS is. So to suppress
1929 * potential EPERMs we'll try not to call
1930 * PR_SET_SECUREBITS unless necessary. */
1931 if (prctl(PR_GET_SECUREBITS
) != secure_bits
)
1932 if (prctl(PR_SET_SECUREBITS
, secure_bits
) < 0) {
1933 *exit_status
= EXIT_SECUREBITS
;
1937 if (context
->capabilities
)
1938 if (cap_set_proc(context
->capabilities
) < 0) {
1939 *exit_status
= EXIT_CAPABILITIES
;
1943 if (context
->no_new_privileges
)
1944 if (prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0) < 0) {
1945 *exit_status
= EXIT_NO_NEW_PRIVILEGES
;
1950 if (context
->address_families_whitelist
||
1951 !set_isempty(context
->address_families
)) {
1952 r
= apply_address_families(context
);
1954 *exit_status
= EXIT_ADDRESS_FAMILIES
;
1959 if (context
->syscall_whitelist
||
1960 !set_isempty(context
->syscall_filter
) ||
1961 !set_isempty(context
->syscall_archs
)) {
1962 r
= apply_seccomp(context
);
1964 *exit_status
= EXIT_SECCOMP
;
1971 if (mac_selinux_use()) {
1972 char *exec_context
= mac_selinux_context_net
?: context
->selinux_context
;
1975 r
= setexeccon(exec_context
);
1977 *exit_status
= EXIT_SELINUX_CONTEXT
;
1984 #ifdef HAVE_APPARMOR
1985 if (context
->apparmor_profile
&& mac_apparmor_use()) {
1986 r
= aa_change_onexec(context
->apparmor_profile
);
1987 if (r
< 0 && !context
->apparmor_profile_ignore
) {
1988 *exit_status
= EXIT_APPARMOR_PROFILE
;
1995 r
= build_environment(context
, n_fds
, params
->fd_names
, params
->watchdog_usec
, home
, username
, shell
, &our_env
);
1997 *exit_status
= EXIT_MEMORY
;
2001 r
= build_pass_environment(context
, &pass_env
);
2003 *exit_status
= EXIT_MEMORY
;
2007 final_env
= strv_env_merge(6,
2008 params
->environment
,
2011 context
->environment
,
2016 *exit_status
= EXIT_MEMORY
;
2020 final_argv
= replace_env_argv(argv
, final_env
);
2022 *exit_status
= EXIT_MEMORY
;
2026 final_env
= strv_env_clean(final_env
);
2028 if (_unlikely_(log_get_max_level() >= LOG_DEBUG
)) {
2029 _cleanup_free_
char *line
;
2031 line
= exec_command_line(final_argv
);
2034 log_struct(LOG_DEBUG
,
2036 "EXECUTABLE=%s", command
->path
,
2037 LOG_UNIT_MESSAGE(unit
, "Executing: %s", line
),
2043 execve(command
->path
, final_argv
, final_env
);
2044 *exit_status
= EXIT_EXEC
;
2048 int exec_spawn(Unit
*unit
,
2049 ExecCommand
*command
,
2050 const ExecContext
*context
,
2051 const ExecParameters
*params
,
2052 ExecRuntime
*runtime
,
2055 _cleanup_strv_free_
char **files_env
= NULL
;
2056 int *fds
= NULL
; unsigned n_fds
= 0;
2057 _cleanup_free_
char *line
= NULL
;
2067 assert(params
->fds
|| params
->n_fds
<= 0);
2069 if (context
->std_input
== EXEC_INPUT_SOCKET
||
2070 context
->std_output
== EXEC_OUTPUT_SOCKET
||
2071 context
->std_error
== EXEC_OUTPUT_SOCKET
) {
2073 if (params
->n_fds
!= 1) {
2074 log_unit_error(unit
, "Got more than one socket.");
2078 socket_fd
= params
->fds
[0];
2082 n_fds
= params
->n_fds
;
2085 r
= exec_context_load_environment(unit
, context
, &files_env
);
2087 return log_unit_error_errno(unit
, r
, "Failed to load environment files: %m");
2089 argv
= params
->argv
?: command
->argv
;
2090 line
= exec_command_line(argv
);
2094 log_struct(LOG_DEBUG
,
2096 LOG_UNIT_MESSAGE(unit
, "About to execute: %s", line
),
2097 "EXECUTABLE=%s", command
->path
,
2101 return log_unit_error_errno(unit
, errno
, "Failed to fork: %m");
2106 r
= exec_child(unit
,
2118 log_struct_errno(LOG_ERR
, r
,
2119 LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED
),
2121 LOG_UNIT_MESSAGE(unit
, "Failed at step %s spawning %s: %m",
2122 exit_status_to_string(exit_status
, EXIT_STATUS_SYSTEMD
),
2124 "EXECUTABLE=%s", command
->path
,
2131 log_unit_debug(unit
, "Forked %s as "PID_FMT
, command
->path
, pid
);
2133 /* We add the new process to the cgroup both in the child (so
2134 * that we can be sure that no user code is ever executed
2135 * outside of the cgroup) and in the parent (so that we can be
2136 * sure that when we kill the cgroup the process will be
2138 if (params
->cgroup_path
)
2139 (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, pid
);
2141 exec_status_start(&command
->exec_status
, pid
);
2147 void exec_context_init(ExecContext
*c
) {
2151 c
->ioprio
= IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE
, 0);
2152 c
->cpu_sched_policy
= SCHED_OTHER
;
2153 c
->syslog_priority
= LOG_DAEMON
|LOG_INFO
;
2154 c
->syslog_level_prefix
= true;
2155 c
->ignore_sigpipe
= true;
2156 c
->timer_slack_nsec
= NSEC_INFINITY
;
2157 c
->personality
= PERSONALITY_INVALID
;
2158 c
->runtime_directory_mode
= 0755;
2159 c
->capability_bounding_set
= CAP_ALL
;
2162 void exec_context_done(ExecContext
*c
) {
2167 c
->environment
= strv_free(c
->environment
);
2168 c
->environment_files
= strv_free(c
->environment_files
);
2169 c
->pass_environment
= strv_free(c
->pass_environment
);
2171 for (l
= 0; l
< ELEMENTSOF(c
->rlimit
); l
++)
2172 c
->rlimit
[l
] = mfree(c
->rlimit
[l
]);
2174 c
->working_directory
= mfree(c
->working_directory
);
2175 c
->root_directory
= mfree(c
->root_directory
);
2176 c
->tty_path
= mfree(c
->tty_path
);
2177 c
->syslog_identifier
= mfree(c
->syslog_identifier
);
2178 c
->user
= mfree(c
->user
);
2179 c
->group
= mfree(c
->group
);
2181 c
->supplementary_groups
= strv_free(c
->supplementary_groups
);
2183 c
->pam_name
= mfree(c
->pam_name
);
2185 if (c
->capabilities
) {
2186 cap_free(c
->capabilities
);
2187 c
->capabilities
= NULL
;
2190 c
->read_only_dirs
= strv_free(c
->read_only_dirs
);
2191 c
->read_write_dirs
= strv_free(c
->read_write_dirs
);
2192 c
->inaccessible_dirs
= strv_free(c
->inaccessible_dirs
);
2195 CPU_FREE(c
->cpuset
);
2197 c
->utmp_id
= mfree(c
->utmp_id
);
2198 c
->selinux_context
= mfree(c
->selinux_context
);
2199 c
->apparmor_profile
= mfree(c
->apparmor_profile
);
2201 c
->syscall_filter
= set_free(c
->syscall_filter
);
2202 c
->syscall_archs
= set_free(c
->syscall_archs
);
2203 c
->address_families
= set_free(c
->address_families
);
2205 c
->runtime_directory
= strv_free(c
->runtime_directory
);
2207 bus_endpoint_free(c
->bus_endpoint
);
2208 c
->bus_endpoint
= NULL
;
2211 int exec_context_destroy_runtime_directory(ExecContext
*c
, const char *runtime_prefix
) {
2216 if (!runtime_prefix
)
2219 STRV_FOREACH(i
, c
->runtime_directory
) {
2220 _cleanup_free_
char *p
;
2222 p
= strjoin(runtime_prefix
, "/", *i
, NULL
);
2226 /* We execute this synchronously, since we need to be
2227 * sure this is gone when we start the service
2229 (void) rm_rf(p
, REMOVE_ROOT
);
2235 void exec_command_done(ExecCommand
*c
) {
2238 c
->path
= mfree(c
->path
);
2240 c
->argv
= strv_free(c
->argv
);
2243 void exec_command_done_array(ExecCommand
*c
, unsigned n
) {
2246 for (i
= 0; i
< n
; i
++)
2247 exec_command_done(c
+i
);
2250 ExecCommand
* exec_command_free_list(ExecCommand
*c
) {
2254 LIST_REMOVE(command
, c
, i
);
2255 exec_command_done(i
);
2262 void exec_command_free_array(ExecCommand
**c
, unsigned n
) {
2265 for (i
= 0; i
< n
; i
++)
2266 c
[i
] = exec_command_free_list(c
[i
]);
2269 typedef struct InvalidEnvInfo
{
2274 static void invalid_env(const char *p
, void *userdata
) {
2275 InvalidEnvInfo
*info
= userdata
;
2277 log_unit_error(info
->unit
, "Ignoring invalid environment assignment '%s': %s", p
, info
->path
);
2280 int exec_context_load_environment(Unit
*unit
, const ExecContext
*c
, char ***l
) {
2281 char **i
, **r
= NULL
;
2286 STRV_FOREACH(i
, c
->environment_files
) {
2289 bool ignore
= false;
2291 _cleanup_globfree_ glob_t pglob
= {};
2301 if (!path_is_absolute(fn
)) {
2309 /* Filename supports globbing, take all matching files */
2311 if (glob(fn
, 0, NULL
, &pglob
) != 0) {
2316 return errno
> 0 ? -errno
: -EINVAL
;
2318 count
= pglob
.gl_pathc
;
2326 for (n
= 0; n
< count
; n
++) {
2327 k
= load_env_file(NULL
, pglob
.gl_pathv
[n
], NULL
, &p
);
2335 /* Log invalid environment variables with filename */
2337 InvalidEnvInfo info
= {
2339 .path
= pglob
.gl_pathv
[n
]
2342 p
= strv_env_clean_with_callback(p
, invalid_env
, &info
);
2350 m
= strv_env_merge(2, r
, p
);
2366 static bool tty_may_match_dev_console(const char *tty
) {
2367 _cleanup_free_
char *active
= NULL
;
2370 if (startswith(tty
, "/dev/"))
2373 /* trivial identity? */
2374 if (streq(tty
, "console"))
2377 console
= resolve_dev_console(&active
);
2378 /* if we could not resolve, assume it may */
2382 /* "tty0" means the active VC, so it may be the same sometimes */
2383 return streq(console
, tty
) || (streq(console
, "tty0") && tty_is_vc(tty
));
2386 bool exec_context_may_touch_console(ExecContext
*ec
) {
2387 return (ec
->tty_reset
|| ec
->tty_vhangup
|| ec
->tty_vt_disallocate
||
2388 is_terminal_input(ec
->std_input
) ||
2389 is_terminal_output(ec
->std_output
) ||
2390 is_terminal_output(ec
->std_error
)) &&
2391 tty_may_match_dev_console(tty_path(ec
));
2394 static void strv_fprintf(FILE *f
, char **l
) {
2400 fprintf(f
, " %s", *g
);
2403 void exec_context_dump(ExecContext
*c
, FILE* f
, const char *prefix
) {
2410 prefix
= strempty(prefix
);
2414 "%sWorkingDirectory: %s\n"
2415 "%sRootDirectory: %s\n"
2416 "%sNonBlocking: %s\n"
2417 "%sPrivateTmp: %s\n"
2418 "%sPrivateNetwork: %s\n"
2419 "%sPrivateDevices: %s\n"
2420 "%sProtectHome: %s\n"
2421 "%sProtectSystem: %s\n"
2422 "%sIgnoreSIGPIPE: %s\n",
2424 prefix
, c
->working_directory
? c
->working_directory
: "/",
2425 prefix
, c
->root_directory
? c
->root_directory
: "/",
2426 prefix
, yes_no(c
->non_blocking
),
2427 prefix
, yes_no(c
->private_tmp
),
2428 prefix
, yes_no(c
->private_network
),
2429 prefix
, yes_no(c
->private_devices
),
2430 prefix
, protect_home_to_string(c
->protect_home
),
2431 prefix
, protect_system_to_string(c
->protect_system
),
2432 prefix
, yes_no(c
->ignore_sigpipe
));
2434 STRV_FOREACH(e
, c
->environment
)
2435 fprintf(f
, "%sEnvironment: %s\n", prefix
, *e
);
2437 STRV_FOREACH(e
, c
->environment_files
)
2438 fprintf(f
, "%sEnvironmentFile: %s\n", prefix
, *e
);
2440 STRV_FOREACH(e
, c
->pass_environment
)
2441 fprintf(f
, "%sPassEnvironment: %s\n", prefix
, *e
);
2443 fprintf(f
, "%sRuntimeDirectoryMode: %04o\n", prefix
, c
->runtime_directory_mode
);
2445 STRV_FOREACH(d
, c
->runtime_directory
)
2446 fprintf(f
, "%sRuntimeDirectory: %s\n", prefix
, *d
);
2453 if (c
->oom_score_adjust_set
)
2455 "%sOOMScoreAdjust: %i\n",
2456 prefix
, c
->oom_score_adjust
);
2458 for (i
= 0; i
< RLIM_NLIMITS
; i
++)
2460 fprintf(f
, "%s%s: " RLIM_FMT
"\n",
2461 prefix
, rlimit_to_string(i
), c
->rlimit
[i
]->rlim_max
);
2462 fprintf(f
, "%s%sSoft: " RLIM_FMT
"\n",
2463 prefix
, rlimit_to_string(i
), c
->rlimit
[i
]->rlim_cur
);
2466 if (c
->ioprio_set
) {
2467 _cleanup_free_
char *class_str
= NULL
;
2469 ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c
->ioprio
), &class_str
);
2471 "%sIOSchedulingClass: %s\n"
2472 "%sIOPriority: %i\n",
2473 prefix
, strna(class_str
),
2474 prefix
, (int) IOPRIO_PRIO_DATA(c
->ioprio
));
2477 if (c
->cpu_sched_set
) {
2478 _cleanup_free_
char *policy_str
= NULL
;
2480 sched_policy_to_string_alloc(c
->cpu_sched_policy
, &policy_str
);
2482 "%sCPUSchedulingPolicy: %s\n"
2483 "%sCPUSchedulingPriority: %i\n"
2484 "%sCPUSchedulingResetOnFork: %s\n",
2485 prefix
, strna(policy_str
),
2486 prefix
, c
->cpu_sched_priority
,
2487 prefix
, yes_no(c
->cpu_sched_reset_on_fork
));
2491 fprintf(f
, "%sCPUAffinity:", prefix
);
2492 for (i
= 0; i
< c
->cpuset_ncpus
; i
++)
2493 if (CPU_ISSET_S(i
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
), c
->cpuset
))
2494 fprintf(f
, " %u", i
);
2498 if (c
->timer_slack_nsec
!= NSEC_INFINITY
)
2499 fprintf(f
, "%sTimerSlackNSec: "NSEC_FMT
"\n", prefix
, c
->timer_slack_nsec
);
2502 "%sStandardInput: %s\n"
2503 "%sStandardOutput: %s\n"
2504 "%sStandardError: %s\n",
2505 prefix
, exec_input_to_string(c
->std_input
),
2506 prefix
, exec_output_to_string(c
->std_output
),
2507 prefix
, exec_output_to_string(c
->std_error
));
2513 "%sTTYVHangup: %s\n"
2514 "%sTTYVTDisallocate: %s\n",
2515 prefix
, c
->tty_path
,
2516 prefix
, yes_no(c
->tty_reset
),
2517 prefix
, yes_no(c
->tty_vhangup
),
2518 prefix
, yes_no(c
->tty_vt_disallocate
));
2520 if (c
->std_output
== EXEC_OUTPUT_SYSLOG
||
2521 c
->std_output
== EXEC_OUTPUT_KMSG
||
2522 c
->std_output
== EXEC_OUTPUT_JOURNAL
||
2523 c
->std_output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2524 c
->std_output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2525 c
->std_output
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
||
2526 c
->std_error
== EXEC_OUTPUT_SYSLOG
||
2527 c
->std_error
== EXEC_OUTPUT_KMSG
||
2528 c
->std_error
== EXEC_OUTPUT_JOURNAL
||
2529 c
->std_error
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2530 c
->std_error
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2531 c
->std_error
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
) {
2533 _cleanup_free_
char *fac_str
= NULL
, *lvl_str
= NULL
;
2535 log_facility_unshifted_to_string_alloc(c
->syslog_priority
>> 3, &fac_str
);
2536 log_level_to_string_alloc(LOG_PRI(c
->syslog_priority
), &lvl_str
);
2539 "%sSyslogFacility: %s\n"
2540 "%sSyslogLevel: %s\n",
2541 prefix
, strna(fac_str
),
2542 prefix
, strna(lvl_str
));
2545 if (c
->capabilities
) {
2546 _cleanup_cap_free_charp_
char *t
;
2548 t
= cap_to_text(c
->capabilities
, NULL
);
2550 fprintf(f
, "%sCapabilities: %s\n", prefix
, t
);
2554 fprintf(f
, "%sSecure Bits:%s%s%s%s%s%s\n",
2556 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS
) ? " keep-caps" : "",
2557 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS_LOCKED
) ? " keep-caps-locked" : "",
2558 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP
) ? " no-setuid-fixup" : "",
2559 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP_LOCKED
) ? " no-setuid-fixup-locked" : "",
2560 (c
->secure_bits
& 1<<SECURE_NOROOT
) ? " noroot" : "",
2561 (c
->secure_bits
& 1<<SECURE_NOROOT_LOCKED
) ? "noroot-locked" : "");
2563 if (c
->capability_bounding_set
!= CAP_ALL
) {
2565 fprintf(f
, "%sCapabilityBoundingSet:", prefix
);
2567 for (l
= 0; l
<= cap_last_cap(); l
++)
2568 if (c
->capability_bounding_set
& (UINT64_C(1) << l
))
2569 fprintf(f
, " %s", strna(capability_to_name(l
)));
2574 if (c
->capability_ambient_set
!= 0) {
2576 fprintf(f
, "%sAmbientCapabilities:", prefix
);
2578 for (l
= 0; l
<= cap_last_cap(); l
++)
2579 if (c
->capability_ambient_set
& (UINT64_C(1) << l
))
2580 fprintf(f
, " %s", strna(capability_to_name(l
)));
2586 fprintf(f
, "%sUser: %s\n", prefix
, c
->user
);
2588 fprintf(f
, "%sGroup: %s\n", prefix
, c
->group
);
2590 if (strv_length(c
->supplementary_groups
) > 0) {
2591 fprintf(f
, "%sSupplementaryGroups:", prefix
);
2592 strv_fprintf(f
, c
->supplementary_groups
);
2597 fprintf(f
, "%sPAMName: %s\n", prefix
, c
->pam_name
);
2599 if (strv_length(c
->read_write_dirs
) > 0) {
2600 fprintf(f
, "%sReadWriteDirs:", prefix
);
2601 strv_fprintf(f
, c
->read_write_dirs
);
2605 if (strv_length(c
->read_only_dirs
) > 0) {
2606 fprintf(f
, "%sReadOnlyDirs:", prefix
);
2607 strv_fprintf(f
, c
->read_only_dirs
);
2611 if (strv_length(c
->inaccessible_dirs
) > 0) {
2612 fprintf(f
, "%sInaccessibleDirs:", prefix
);
2613 strv_fprintf(f
, c
->inaccessible_dirs
);
2619 "%sUtmpIdentifier: %s\n",
2620 prefix
, c
->utmp_id
);
2622 if (c
->selinux_context
)
2624 "%sSELinuxContext: %s%s\n",
2625 prefix
, c
->selinux_context_ignore
? "-" : "", c
->selinux_context
);
2627 if (c
->personality
!= PERSONALITY_INVALID
)
2629 "%sPersonality: %s\n",
2630 prefix
, strna(personality_to_string(c
->personality
)));
2632 if (c
->syscall_filter
) {
2640 "%sSystemCallFilter: ",
2643 if (!c
->syscall_whitelist
)
2647 SET_FOREACH(id
, c
->syscall_filter
, j
) {
2648 _cleanup_free_
char *name
= NULL
;
2655 name
= seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE
, PTR_TO_INT(id
) - 1);
2656 fputs(strna(name
), f
);
2663 if (c
->syscall_archs
) {
2670 "%sSystemCallArchitectures:",
2674 SET_FOREACH(id
, c
->syscall_archs
, j
)
2675 fprintf(f
, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id
) - 1)));
2680 if (c
->syscall_errno
> 0)
2682 "%sSystemCallErrorNumber: %s\n",
2683 prefix
, strna(errno_to_name(c
->syscall_errno
)));
2685 if (c
->apparmor_profile
)
2687 "%sAppArmorProfile: %s%s\n",
2688 prefix
, c
->apparmor_profile_ignore
? "-" : "", c
->apparmor_profile
);
2691 bool exec_context_maintains_privileges(ExecContext
*c
) {
2694 /* Returns true if the process forked off would run run under
2695 * an unchanged UID or as root. */
2700 if (streq(c
->user
, "root") || streq(c
->user
, "0"))
2706 void exec_status_start(ExecStatus
*s
, pid_t pid
) {
2711 dual_timestamp_get(&s
->start_timestamp
);
2714 void exec_status_exit(ExecStatus
*s
, ExecContext
*context
, pid_t pid
, int code
, int status
) {
2717 if (s
->pid
&& s
->pid
!= pid
)
2721 dual_timestamp_get(&s
->exit_timestamp
);
2727 if (context
->utmp_id
)
2728 utmp_put_dead_process(context
->utmp_id
, pid
, code
, status
);
2730 exec_context_tty_reset(context
);
2734 void exec_status_dump(ExecStatus
*s
, FILE *f
, const char *prefix
) {
2735 char buf
[FORMAT_TIMESTAMP_MAX
];
2743 prefix
= strempty(prefix
);
2746 "%sPID: "PID_FMT
"\n",
2749 if (s
->start_timestamp
.realtime
> 0)
2751 "%sStart Timestamp: %s\n",
2752 prefix
, format_timestamp(buf
, sizeof(buf
), s
->start_timestamp
.realtime
));
2754 if (s
->exit_timestamp
.realtime
> 0)
2756 "%sExit Timestamp: %s\n"
2758 "%sExit Status: %i\n",
2759 prefix
, format_timestamp(buf
, sizeof(buf
), s
->exit_timestamp
.realtime
),
2760 prefix
, sigchld_code_to_string(s
->code
),
2764 char *exec_command_line(char **argv
) {
2772 STRV_FOREACH(a
, argv
)
2775 if (!(n
= new(char, k
)))
2779 STRV_FOREACH(a
, argv
) {
2786 if (strpbrk(*a
, WHITESPACE
)) {
2797 /* FIXME: this doesn't really handle arguments that have
2798 * spaces and ticks in them */
2803 void exec_command_dump(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2804 _cleanup_free_
char *cmd
= NULL
;
2805 const char *prefix2
;
2810 prefix
= strempty(prefix
);
2811 prefix2
= strjoina(prefix
, "\t");
2813 cmd
= exec_command_line(c
->argv
);
2815 "%sCommand Line: %s\n",
2816 prefix
, cmd
? cmd
: strerror(ENOMEM
));
2818 exec_status_dump(&c
->exec_status
, f
, prefix2
);
2821 void exec_command_dump_list(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2824 prefix
= strempty(prefix
);
2826 LIST_FOREACH(command
, c
, c
)
2827 exec_command_dump(c
, f
, prefix
);
2830 void exec_command_append_list(ExecCommand
**l
, ExecCommand
*e
) {
2837 /* It's kind of important, that we keep the order here */
2838 LIST_FIND_TAIL(command
, *l
, end
);
2839 LIST_INSERT_AFTER(command
, *l
, end
, e
);
2844 int exec_command_set(ExecCommand
*c
, const char *path
, ...) {
2852 l
= strv_new_ap(path
, ap
);
2873 int exec_command_append(ExecCommand
*c
, const char *path
, ...) {
2874 _cleanup_strv_free_
char **l
= NULL
;
2882 l
= strv_new_ap(path
, ap
);
2888 r
= strv_extend_strv(&c
->argv
, l
, false);
2896 static int exec_runtime_allocate(ExecRuntime
**rt
) {
2901 *rt
= new0(ExecRuntime
, 1);
2906 (*rt
)->netns_storage_socket
[0] = (*rt
)->netns_storage_socket
[1] = -1;
2911 int exec_runtime_make(ExecRuntime
**rt
, ExecContext
*c
, const char *id
) {
2921 if (!c
->private_network
&& !c
->private_tmp
)
2924 r
= exec_runtime_allocate(rt
);
2928 if (c
->private_network
&& (*rt
)->netns_storage_socket
[0] < 0) {
2929 if (socketpair(AF_UNIX
, SOCK_DGRAM
, 0, (*rt
)->netns_storage_socket
) < 0)
2933 if (c
->private_tmp
&& !(*rt
)->tmp_dir
) {
2934 r
= setup_tmp_dirs(id
, &(*rt
)->tmp_dir
, &(*rt
)->var_tmp_dir
);
2942 ExecRuntime
*exec_runtime_ref(ExecRuntime
*r
) {
2944 assert(r
->n_ref
> 0);
2950 ExecRuntime
*exec_runtime_unref(ExecRuntime
*r
) {
2955 assert(r
->n_ref
> 0);
2962 free(r
->var_tmp_dir
);
2963 safe_close_pair(r
->netns_storage_socket
);
2969 int exec_runtime_serialize(Unit
*u
, ExecRuntime
*rt
, FILE *f
, FDSet
*fds
) {
2978 unit_serialize_item(u
, f
, "tmp-dir", rt
->tmp_dir
);
2980 if (rt
->var_tmp_dir
)
2981 unit_serialize_item(u
, f
, "var-tmp-dir", rt
->var_tmp_dir
);
2983 if (rt
->netns_storage_socket
[0] >= 0) {
2986 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[0]);
2990 unit_serialize_item_format(u
, f
, "netns-socket-0", "%i", copy
);
2993 if (rt
->netns_storage_socket
[1] >= 0) {
2996 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[1]);
3000 unit_serialize_item_format(u
, f
, "netns-socket-1", "%i", copy
);
3006 int exec_runtime_deserialize_item(Unit
*u
, ExecRuntime
**rt
, const char *key
, const char *value
, FDSet
*fds
) {
3013 if (streq(key
, "tmp-dir")) {
3016 r
= exec_runtime_allocate(rt
);
3020 copy
= strdup(value
);
3024 free((*rt
)->tmp_dir
);
3025 (*rt
)->tmp_dir
= copy
;
3027 } else if (streq(key
, "var-tmp-dir")) {
3030 r
= exec_runtime_allocate(rt
);
3034 copy
= strdup(value
);
3038 free((*rt
)->var_tmp_dir
);
3039 (*rt
)->var_tmp_dir
= copy
;
3041 } else if (streq(key
, "netns-socket-0")) {
3044 r
= exec_runtime_allocate(rt
);
3048 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
3049 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
3051 safe_close((*rt
)->netns_storage_socket
[0]);
3052 (*rt
)->netns_storage_socket
[0] = fdset_remove(fds
, fd
);
3054 } else if (streq(key
, "netns-socket-1")) {
3057 r
= exec_runtime_allocate(rt
);
3061 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
3062 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
3064 safe_close((*rt
)->netns_storage_socket
[1]);
3065 (*rt
)->netns_storage_socket
[1] = fdset_remove(fds
, fd
);
3073 static void *remove_tmpdir_thread(void *p
) {
3074 _cleanup_free_
char *path
= p
;
3076 (void) rm_rf(path
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
3080 void exec_runtime_destroy(ExecRuntime
*rt
) {
3086 /* If there are multiple users of this, let's leave the stuff around */
3091 log_debug("Spawning thread to nuke %s", rt
->tmp_dir
);
3093 r
= asynchronous_job(remove_tmpdir_thread
, rt
->tmp_dir
);
3095 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->tmp_dir
);
3102 if (rt
->var_tmp_dir
) {
3103 log_debug("Spawning thread to nuke %s", rt
->var_tmp_dir
);
3105 r
= asynchronous_job(remove_tmpdir_thread
, rt
->var_tmp_dir
);
3107 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->var_tmp_dir
);
3108 free(rt
->var_tmp_dir
);
3111 rt
->var_tmp_dir
= NULL
;
3114 safe_close_pair(rt
->netns_storage_socket
);
3117 static const char* const exec_input_table
[_EXEC_INPUT_MAX
] = {
3118 [EXEC_INPUT_NULL
] = "null",
3119 [EXEC_INPUT_TTY
] = "tty",
3120 [EXEC_INPUT_TTY_FORCE
] = "tty-force",
3121 [EXEC_INPUT_TTY_FAIL
] = "tty-fail",
3122 [EXEC_INPUT_SOCKET
] = "socket"
3125 DEFINE_STRING_TABLE_LOOKUP(exec_input
, ExecInput
);
3127 static const char* const exec_output_table
[_EXEC_OUTPUT_MAX
] = {
3128 [EXEC_OUTPUT_INHERIT
] = "inherit",
3129 [EXEC_OUTPUT_NULL
] = "null",
3130 [EXEC_OUTPUT_TTY
] = "tty",
3131 [EXEC_OUTPUT_SYSLOG
] = "syslog",
3132 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE
] = "syslog+console",
3133 [EXEC_OUTPUT_KMSG
] = "kmsg",
3134 [EXEC_OUTPUT_KMSG_AND_CONSOLE
] = "kmsg+console",
3135 [EXEC_OUTPUT_JOURNAL
] = "journal",
3136 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE
] = "journal+console",
3137 [EXEC_OUTPUT_SOCKET
] = "socket"
3140 DEFINE_STRING_TABLE_LOOKUP(exec_output
, ExecOutput
);
3142 static const char* const exec_utmp_mode_table
[_EXEC_UTMP_MODE_MAX
] = {
3143 [EXEC_UTMP_INIT
] = "init",
3144 [EXEC_UTMP_LOGIN
] = "login",
3145 [EXEC_UTMP_USER
] = "user",
3148 DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode
, ExecUtmpMode
);