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 static const char *exec_context_tty_path(const ExecContext
*context
) {
189 if (context
->stdio_as_fds
)
192 if (context
->tty_path
)
193 return context
->tty_path
;
195 return "/dev/console";
198 static void exec_context_tty_reset(const ExecContext
*context
, const ExecParameters
*p
) {
203 path
= exec_context_tty_path(context
);
205 if (context
->tty_vhangup
) {
206 if (p
&& p
->stdin_fd
>= 0)
207 (void) terminal_vhangup_fd(p
->stdin_fd
);
209 (void) terminal_vhangup(path
);
212 if (context
->tty_reset
) {
213 if (p
&& p
->stdin_fd
>= 0)
214 (void) reset_terminal_fd(p
->stdin_fd
, true);
216 (void) reset_terminal(path
);
219 if (context
->tty_vt_disallocate
&& path
)
220 (void) vt_disallocate(path
);
223 static bool is_terminal_output(ExecOutput o
) {
225 o
== EXEC_OUTPUT_TTY
||
226 o
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
227 o
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
228 o
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
;
231 static int open_null_as(int flags
, int nfd
) {
236 fd
= open("/dev/null", flags
|O_NOCTTY
);
241 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
249 static int connect_journal_socket(int fd
, uid_t uid
, gid_t gid
) {
250 union sockaddr_union sa
= {
251 .un
.sun_family
= AF_UNIX
,
252 .un
.sun_path
= "/run/systemd/journal/stdout",
254 uid_t olduid
= UID_INVALID
;
255 gid_t oldgid
= GID_INVALID
;
258 if (gid
!= GID_INVALID
) {
266 if (uid
!= UID_INVALID
) {
276 r
= connect(fd
, &sa
.sa
, offsetof(struct sockaddr_un
, sun_path
) + strlen(sa
.un
.sun_path
));
280 /* If we fail to restore the uid or gid, things will likely
281 fail later on. This should only happen if an LSM interferes. */
283 if (uid
!= UID_INVALID
)
284 (void) seteuid(olduid
);
287 if (gid
!= GID_INVALID
)
288 (void) setegid(oldgid
);
293 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
) {
297 assert(output
< _EXEC_OUTPUT_MAX
);
301 fd
= socket(AF_UNIX
, SOCK_STREAM
, 0);
305 r
= connect_journal_socket(fd
, uid
, gid
);
309 if (shutdown(fd
, SHUT_RD
) < 0) {
314 fd_inc_sndbuf(fd
, SNDBUF_SIZE
);
324 context
->syslog_identifier
? context
->syslog_identifier
: ident
,
326 context
->syslog_priority
,
327 !!context
->syslog_level_prefix
,
328 output
== EXEC_OUTPUT_SYSLOG
|| output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
,
329 output
== EXEC_OUTPUT_KMSG
|| output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
,
330 is_terminal_output(output
));
333 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
340 static int open_terminal_as(const char *path
, mode_t mode
, int nfd
) {
346 fd
= open_terminal(path
, mode
| O_NOCTTY
);
351 r
= dup2(fd
, nfd
) < 0 ? -errno
: nfd
;
359 static bool is_terminal_input(ExecInput i
) {
361 i
== EXEC_INPUT_TTY
||
362 i
== EXEC_INPUT_TTY_FORCE
||
363 i
== EXEC_INPUT_TTY_FAIL
;
366 static int fixup_input(ExecInput std_input
, int socket_fd
, bool apply_tty_stdin
) {
368 if (is_terminal_input(std_input
) && !apply_tty_stdin
)
369 return EXEC_INPUT_NULL
;
371 if (std_input
== EXEC_INPUT_SOCKET
&& socket_fd
< 0)
372 return EXEC_INPUT_NULL
;
377 static int fixup_output(ExecOutput std_output
, int socket_fd
) {
379 if (std_output
== EXEC_OUTPUT_SOCKET
&& socket_fd
< 0)
380 return EXEC_OUTPUT_INHERIT
;
385 static int setup_input(
386 const ExecContext
*context
,
387 const ExecParameters
*params
,
395 if (params
->stdin_fd
>= 0) {
396 if (dup2(params
->stdin_fd
, STDIN_FILENO
) < 0)
399 /* Try to make this the controlling tty, if it is a tty, and reset it */
400 (void) ioctl(STDIN_FILENO
, TIOCSCTTY
, context
->std_input
== EXEC_INPUT_TTY_FORCE
);
401 (void) reset_terminal_fd(STDIN_FILENO
, true);
406 i
= fixup_input(context
->std_input
, socket_fd
, params
->apply_tty_stdin
);
410 case EXEC_INPUT_NULL
:
411 return open_null_as(O_RDONLY
, STDIN_FILENO
);
414 case EXEC_INPUT_TTY_FORCE
:
415 case EXEC_INPUT_TTY_FAIL
: {
418 fd
= acquire_terminal(exec_context_tty_path(context
),
419 i
== EXEC_INPUT_TTY_FAIL
,
420 i
== EXEC_INPUT_TTY_FORCE
,
426 if (fd
!= STDIN_FILENO
) {
427 r
= dup2(fd
, STDIN_FILENO
) < 0 ? -errno
: STDIN_FILENO
;
435 case EXEC_INPUT_SOCKET
:
436 return dup2(socket_fd
, STDIN_FILENO
) < 0 ? -errno
: STDIN_FILENO
;
439 assert_not_reached("Unknown input type");
443 static int setup_output(
445 const ExecContext
*context
,
446 const ExecParameters
*params
,
450 uid_t uid
, gid_t gid
) {
461 if (fileno
== STDOUT_FILENO
&& params
->stdout_fd
>= 0) {
463 if (dup2(params
->stdout_fd
, STDOUT_FILENO
) < 0)
466 return STDOUT_FILENO
;
469 if (fileno
== STDERR_FILENO
&& params
->stderr_fd
>= 0) {
470 if (dup2(params
->stderr_fd
, STDERR_FILENO
) < 0)
473 return STDERR_FILENO
;
476 i
= fixup_input(context
->std_input
, socket_fd
, params
->apply_tty_stdin
);
477 o
= fixup_output(context
->std_output
, socket_fd
);
479 if (fileno
== STDERR_FILENO
) {
481 e
= fixup_output(context
->std_error
, socket_fd
);
483 /* This expects the input and output are already set up */
485 /* Don't change the stderr file descriptor if we inherit all
486 * the way and are not on a tty */
487 if (e
== EXEC_OUTPUT_INHERIT
&&
488 o
== EXEC_OUTPUT_INHERIT
&&
489 i
== EXEC_INPUT_NULL
&&
490 !is_terminal_input(context
->std_input
) &&
494 /* Duplicate from stdout if possible */
495 if (e
== o
|| e
== EXEC_OUTPUT_INHERIT
)
496 return dup2(STDOUT_FILENO
, fileno
) < 0 ? -errno
: fileno
;
500 } else if (o
== EXEC_OUTPUT_INHERIT
) {
501 /* If input got downgraded, inherit the original value */
502 if (i
== EXEC_INPUT_NULL
&& is_terminal_input(context
->std_input
))
503 return open_terminal_as(exec_context_tty_path(context
), O_WRONLY
, fileno
);
505 /* If the input is connected to anything that's not a /dev/null, inherit that... */
506 if (i
!= EXEC_INPUT_NULL
)
507 return dup2(STDIN_FILENO
, fileno
) < 0 ? -errno
: fileno
;
509 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
513 /* We need to open /dev/null here anew, to get the right access mode. */
514 return open_null_as(O_WRONLY
, fileno
);
519 case EXEC_OUTPUT_NULL
:
520 return open_null_as(O_WRONLY
, fileno
);
522 case EXEC_OUTPUT_TTY
:
523 if (is_terminal_input(i
))
524 return dup2(STDIN_FILENO
, fileno
) < 0 ? -errno
: fileno
;
526 /* We don't reset the terminal if this is just about output */
527 return open_terminal_as(exec_context_tty_path(context
), O_WRONLY
, fileno
);
529 case EXEC_OUTPUT_SYSLOG
:
530 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE
:
531 case EXEC_OUTPUT_KMSG
:
532 case EXEC_OUTPUT_KMSG_AND_CONSOLE
:
533 case EXEC_OUTPUT_JOURNAL
:
534 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE
:
535 r
= connect_logger_as(context
, o
, ident
, unit
->id
, fileno
, uid
, gid
);
537 log_unit_error_errno(unit
, r
, "Failed to connect %s to the journal socket, ignoring: %m", fileno
== STDOUT_FILENO
? "stdout" : "stderr");
538 r
= open_null_as(O_WRONLY
, fileno
);
542 case EXEC_OUTPUT_SOCKET
:
543 assert(socket_fd
>= 0);
544 return dup2(socket_fd
, fileno
) < 0 ? -errno
: fileno
;
547 assert_not_reached("Unknown error type");
551 static int chown_terminal(int fd
, uid_t uid
) {
556 /* This might fail. What matters are the results. */
557 (void) fchown(fd
, uid
, -1);
558 (void) fchmod(fd
, TTY_MODE
);
560 if (fstat(fd
, &st
) < 0)
563 if (st
.st_uid
!= uid
|| (st
.st_mode
& 0777) != TTY_MODE
)
569 static int setup_confirm_stdio(int *_saved_stdin
, int *_saved_stdout
) {
570 _cleanup_close_
int fd
= -1, saved_stdin
= -1, saved_stdout
= -1;
573 assert(_saved_stdin
);
574 assert(_saved_stdout
);
576 saved_stdin
= fcntl(STDIN_FILENO
, F_DUPFD
, 3);
580 saved_stdout
= fcntl(STDOUT_FILENO
, F_DUPFD
, 3);
581 if (saved_stdout
< 0)
584 fd
= acquire_terminal(
589 DEFAULT_CONFIRM_USEC
);
593 r
= chown_terminal(fd
, getuid());
597 r
= reset_terminal_fd(fd
, true);
601 if (dup2(fd
, STDIN_FILENO
) < 0)
604 if (dup2(fd
, STDOUT_FILENO
) < 0)
611 *_saved_stdin
= saved_stdin
;
612 *_saved_stdout
= saved_stdout
;
614 saved_stdin
= saved_stdout
= -1;
619 _printf_(1, 2) static int write_confirm_message(const char *format
, ...) {
620 _cleanup_close_
int fd
= -1;
625 fd
= open_terminal("/dev/console", O_WRONLY
|O_NOCTTY
|O_CLOEXEC
);
629 va_start(ap
, format
);
630 vdprintf(fd
, format
, ap
);
636 static int restore_confirm_stdio(int *saved_stdin
, int *saved_stdout
) {
640 assert(saved_stdout
);
644 if (*saved_stdin
>= 0)
645 if (dup2(*saved_stdin
, STDIN_FILENO
) < 0)
648 if (*saved_stdout
>= 0)
649 if (dup2(*saved_stdout
, STDOUT_FILENO
) < 0)
652 *saved_stdin
= safe_close(*saved_stdin
);
653 *saved_stdout
= safe_close(*saved_stdout
);
658 static int ask_for_confirmation(char *response
, char **argv
) {
659 int saved_stdout
= -1, saved_stdin
= -1, r
;
660 _cleanup_free_
char *line
= NULL
;
662 r
= setup_confirm_stdio(&saved_stdin
, &saved_stdout
);
666 line
= exec_command_line(argv
);
670 r
= ask_char(response
, "yns", "Execute %s? [Yes, No, Skip] ", line
);
672 restore_confirm_stdio(&saved_stdin
, &saved_stdout
);
677 static int enforce_groups(const ExecContext
*context
, const char *username
, gid_t gid
) {
678 bool keep_groups
= false;
683 /* Lookup and set GID and supplementary group list. Here too
684 * we avoid NSS lookups for gid=0. */
686 if (context
->group
|| username
) {
687 /* First step, initialize groups from /etc/groups */
688 if (username
&& gid
!= 0) {
689 if (initgroups(username
, gid
) < 0)
695 /* Second step, set our gids */
696 if (setresgid(gid
, gid
, gid
) < 0)
700 if (context
->supplementary_groups
) {
705 /* Final step, initialize any manually set supplementary groups */
706 assert_se((ngroups_max
= (int) sysconf(_SC_NGROUPS_MAX
)) > 0);
708 if (!(gids
= new(gid_t
, ngroups_max
)))
712 k
= getgroups(ngroups_max
, gids
);
720 STRV_FOREACH(i
, context
->supplementary_groups
) {
723 if (k
>= ngroups_max
) {
729 r
= get_group_creds(&g
, gids
+k
);
738 if (setgroups(k
, gids
) < 0) {
749 static int enforce_user(const ExecContext
*context
, uid_t uid
) {
752 /* Sets (but doesn't lookup) the uid and make sure we keep the
753 * capabilities while doing so. */
755 if (context
->capabilities
|| context
->capability_ambient_set
!= 0) {
757 /* First step: If we need to keep capabilities but
758 * drop privileges we need to make sure we keep our
759 * caps, while we drop privileges. */
761 int sb
= context
->secure_bits
| 1<<SECURE_KEEP_CAPS
;
763 if (prctl(PR_GET_SECUREBITS
) != sb
)
764 if (prctl(PR_SET_SECUREBITS
, sb
) < 0)
768 /* Second step: set the capabilities. This will reduce
769 * the capabilities to the minimum we need. */
771 if (context
->capabilities
) {
772 _cleanup_cap_free_ cap_t d
= NULL
;
773 static const cap_value_t bits
[] = {
774 CAP_SETUID
, /* Necessary so that we can run setresuid() below */
775 CAP_SETPCAP
/* Necessary so that we can set PR_SET_SECUREBITS later on */
778 d
= cap_dup(context
->capabilities
);
782 if (cap_set_flag(d
, CAP_EFFECTIVE
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0 ||
783 cap_set_flag(d
, CAP_PERMITTED
, ELEMENTSOF(bits
), bits
, CAP_SET
) < 0)
786 if (cap_set_proc(d
) < 0)
791 /* Third step: actually set the uids */
792 if (setresuid(uid
, uid
, uid
) < 0)
795 /* At this point we should have all necessary capabilities but
796 are otherwise a normal user. However, the caps might got
797 corrupted due to the setresuid() so we need clean them up
798 later. This is done outside of this call. */
805 static int null_conv(
807 const struct pam_message
**msg
,
808 struct pam_response
**resp
,
811 /* We don't support conversations */
816 static int setup_pam(
822 int fds
[], unsigned n_fds
) {
824 static const struct pam_conv conv
= {
829 _cleanup_(barrier_destroy
) Barrier barrier
= BARRIER_NULL
;
830 pam_handle_t
*handle
= NULL
;
832 int pam_code
= PAM_SUCCESS
, r
;
834 bool close_session
= false;
835 pid_t pam_pid
= 0, parent_pid
;
842 /* We set up PAM in the parent process, then fork. The child
843 * will then stay around until killed via PR_GET_PDEATHSIG or
844 * systemd via the cgroup logic. It will then remove the PAM
845 * session again. The parent process will exec() the actual
846 * daemon. We do things this way to ensure that the main PID
847 * of the daemon is the one we initially fork()ed. */
849 r
= barrier_create(&barrier
);
853 if (log_get_max_level() < LOG_DEBUG
)
856 pam_code
= pam_start(name
, user
, &conv
, &handle
);
857 if (pam_code
!= PAM_SUCCESS
) {
863 pam_code
= pam_set_item(handle
, PAM_TTY
, tty
);
864 if (pam_code
!= PAM_SUCCESS
)
868 pam_code
= pam_acct_mgmt(handle
, flags
);
869 if (pam_code
!= PAM_SUCCESS
)
872 pam_code
= pam_open_session(handle
, flags
);
873 if (pam_code
!= PAM_SUCCESS
)
876 close_session
= true;
878 e
= pam_getenvlist(handle
);
880 pam_code
= PAM_BUF_ERR
;
884 /* Block SIGTERM, so that we know that it won't get lost in
887 assert_se(sigprocmask_many(SIG_BLOCK
, &old_ss
, SIGTERM
, -1) >= 0);
889 parent_pid
= getpid();
898 int sig
, ret
= EXIT_PAM
;
900 /* The child's job is to reset the PAM session on
902 barrier_set_role(&barrier
, BARRIER_CHILD
);
904 /* This string must fit in 10 chars (i.e. the length
905 * of "/sbin/init"), to look pretty in /bin/ps */
906 rename_process("(sd-pam)");
908 /* Make sure we don't keep open the passed fds in this
909 child. We assume that otherwise only those fds are
910 open here that have been opened by PAM. */
911 close_many(fds
, n_fds
);
913 /* Drop privileges - we don't need any to pam_close_session
914 * and this will make PR_SET_PDEATHSIG work in most cases.
915 * If this fails, ignore the error - but expect sd-pam threads
916 * to fail to exit normally */
917 if (setresuid(uid
, uid
, uid
) < 0)
918 log_error_errno(r
, "Error: Failed to setresuid() in sd-pam: %m");
920 (void) ignore_signals(SIGPIPE
, -1);
922 /* Wait until our parent died. This will only work if
923 * the above setresuid() succeeds, otherwise the kernel
924 * will not allow unprivileged parents kill their privileged
925 * children this way. We rely on the control groups kill logic
926 * to do the rest for us. */
927 if (prctl(PR_SET_PDEATHSIG
, SIGTERM
) < 0)
930 /* Tell the parent that our setup is done. This is especially
931 * important regarding dropping privileges. Otherwise, unit
932 * setup might race against our setresuid(2) call. */
933 barrier_place(&barrier
);
935 /* Check if our parent process might already have
937 if (getppid() == parent_pid
) {
940 assert_se(sigemptyset(&ss
) >= 0);
941 assert_se(sigaddset(&ss
, SIGTERM
) >= 0);
944 if (sigwait(&ss
, &sig
) < 0) {
951 assert(sig
== SIGTERM
);
956 /* If our parent died we'll end the session */
957 if (getppid() != parent_pid
) {
958 pam_code
= pam_close_session(handle
, flags
);
959 if (pam_code
!= PAM_SUCCESS
)
966 pam_end(handle
, pam_code
| flags
);
970 barrier_set_role(&barrier
, BARRIER_PARENT
);
972 /* If the child was forked off successfully it will do all the
973 * cleanups, so forget about the handle here. */
976 /* Unblock SIGTERM again in the parent */
977 assert_se(sigprocmask(SIG_SETMASK
, &old_ss
, NULL
) >= 0);
979 /* We close the log explicitly here, since the PAM modules
980 * might have opened it, but we don't want this fd around. */
983 /* Synchronously wait for the child to initialize. We don't care for
984 * errors as we cannot recover. However, warn loudly if it happens. */
985 if (!barrier_place_and_sync(&barrier
))
986 log_error("PAM initialization failed");
994 if (pam_code
!= PAM_SUCCESS
) {
995 log_error("PAM failed: %s", pam_strerror(handle
, pam_code
));
996 r
= -EPERM
; /* PAM errors do not map to errno */
998 log_error_errno(r
, "PAM failed: %m");
1002 pam_code
= pam_close_session(handle
, flags
);
1004 pam_end(handle
, pam_code
| flags
);
1014 static void rename_process_from_path(const char *path
) {
1015 char process_name
[11];
1019 /* This resulting string must fit in 10 chars (i.e. the length
1020 * of "/sbin/init") to look pretty in /bin/ps */
1024 rename_process("(...)");
1030 /* The end of the process name is usually more
1031 * interesting, since the first bit might just be
1037 process_name
[0] = '(';
1038 memcpy(process_name
+1, p
, l
);
1039 process_name
[1+l
] = ')';
1040 process_name
[1+l
+1] = 0;
1042 rename_process(process_name
);
1047 static int apply_seccomp(const ExecContext
*c
) {
1048 uint32_t negative_action
, action
;
1049 scmp_filter_ctx
*seccomp
;
1056 negative_action
= c
->syscall_errno
== 0 ? SCMP_ACT_KILL
: SCMP_ACT_ERRNO(c
->syscall_errno
);
1058 seccomp
= seccomp_init(c
->syscall_whitelist
? negative_action
: SCMP_ACT_ALLOW
);
1062 if (c
->syscall_archs
) {
1064 SET_FOREACH(id
, c
->syscall_archs
, i
) {
1065 r
= seccomp_arch_add(seccomp
, PTR_TO_UINT32(id
) - 1);
1073 r
= seccomp_add_secondary_archs(seccomp
);
1078 action
= c
->syscall_whitelist
? SCMP_ACT_ALLOW
: negative_action
;
1079 SET_FOREACH(id
, c
->syscall_filter
, i
) {
1080 r
= seccomp_rule_add(seccomp
, action
, PTR_TO_INT(id
) - 1, 0);
1085 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1089 r
= seccomp_load(seccomp
);
1092 seccomp_release(seccomp
);
1096 static int apply_address_families(const ExecContext
*c
) {
1097 scmp_filter_ctx
*seccomp
;
1103 seccomp
= seccomp_init(SCMP_ACT_ALLOW
);
1107 r
= seccomp_add_secondary_archs(seccomp
);
1111 if (c
->address_families_whitelist
) {
1112 int af
, first
= 0, last
= 0;
1115 /* If this is a whitelist, we first block the address
1116 * families that are out of range and then everything
1117 * that is not in the set. First, we find the lowest
1118 * and highest address family in the set. */
1120 SET_FOREACH(afp
, c
->address_families
, i
) {
1121 af
= PTR_TO_INT(afp
);
1123 if (af
<= 0 || af
>= af_max())
1126 if (first
== 0 || af
< first
)
1129 if (last
== 0 || af
> last
)
1133 assert((first
== 0) == (last
== 0));
1137 /* No entries in the valid range, block everything */
1138 r
= seccomp_rule_add(
1140 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1148 /* Block everything below the first entry */
1149 r
= seccomp_rule_add(
1151 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1154 SCMP_A0(SCMP_CMP_LT
, first
));
1158 /* Block everything above the last entry */
1159 r
= seccomp_rule_add(
1161 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1164 SCMP_A0(SCMP_CMP_GT
, last
));
1168 /* Block everything between the first and last
1170 for (af
= 1; af
< af_max(); af
++) {
1172 if (set_contains(c
->address_families
, INT_TO_PTR(af
)))
1175 r
= seccomp_rule_add(
1177 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1180 SCMP_A0(SCMP_CMP_EQ
, af
));
1189 /* If this is a blacklist, then generate one rule for
1190 * each address family that are then combined in OR
1193 SET_FOREACH(af
, c
->address_families
, i
) {
1195 r
= seccomp_rule_add(
1197 SCMP_ACT_ERRNO(EPROTONOSUPPORT
),
1200 SCMP_A0(SCMP_CMP_EQ
, PTR_TO_INT(af
)));
1206 r
= seccomp_attr_set(seccomp
, SCMP_FLTATR_CTL_NNP
, 0);
1210 r
= seccomp_load(seccomp
);
1213 seccomp_release(seccomp
);
1219 static void do_idle_pipe_dance(int idle_pipe
[4]) {
1223 idle_pipe
[1] = safe_close(idle_pipe
[1]);
1224 idle_pipe
[2] = safe_close(idle_pipe
[2]);
1226 if (idle_pipe
[0] >= 0) {
1229 r
= fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT_USEC
);
1231 if (idle_pipe
[3] >= 0 && r
== 0 /* timeout */) {
1234 /* Signal systemd that we are bored and want to continue. */
1235 n
= write(idle_pipe
[3], "x", 1);
1237 /* Wait for systemd to react to the signal above. */
1238 fd_wait_for_event(idle_pipe
[0], POLLHUP
, IDLE_TIMEOUT2_USEC
);
1241 idle_pipe
[0] = safe_close(idle_pipe
[0]);
1245 idle_pipe
[3] = safe_close(idle_pipe
[3]);
1248 static int build_environment(
1249 const ExecContext
*c
,
1250 const ExecParameters
*p
,
1253 const char *username
,
1257 _cleanup_strv_free_
char **our_env
= NULL
;
1264 our_env
= new0(char*, 11);
1269 _cleanup_free_
char *joined
= NULL
;
1271 if (asprintf(&x
, "LISTEN_PID="PID_FMT
, getpid()) < 0)
1273 our_env
[n_env
++] = x
;
1275 if (asprintf(&x
, "LISTEN_FDS=%u", n_fds
) < 0)
1277 our_env
[n_env
++] = x
;
1279 joined
= strv_join(p
->fd_names
, ":");
1283 x
= strjoin("LISTEN_FDNAMES=", joined
, NULL
);
1286 our_env
[n_env
++] = x
;
1289 if (p
->watchdog_usec
> 0) {
1290 if (asprintf(&x
, "WATCHDOG_PID="PID_FMT
, getpid()) < 0)
1292 our_env
[n_env
++] = x
;
1294 if (asprintf(&x
, "WATCHDOG_USEC="USEC_FMT
, p
->watchdog_usec
) < 0)
1296 our_env
[n_env
++] = x
;
1300 x
= strappend("HOME=", home
);
1303 our_env
[n_env
++] = x
;
1307 x
= strappend("LOGNAME=", username
);
1310 our_env
[n_env
++] = x
;
1312 x
= strappend("USER=", username
);
1315 our_env
[n_env
++] = x
;
1319 x
= strappend("SHELL=", shell
);
1322 our_env
[n_env
++] = x
;
1325 if (is_terminal_input(c
->std_input
) ||
1326 c
->std_output
== EXEC_OUTPUT_TTY
||
1327 c
->std_error
== EXEC_OUTPUT_TTY
||
1330 x
= strdup(default_term_for_tty(exec_context_tty_path(c
)));
1333 our_env
[n_env
++] = x
;
1336 our_env
[n_env
++] = NULL
;
1337 assert(n_env
<= 11);
1345 static int build_pass_environment(const ExecContext
*c
, char ***ret
) {
1346 _cleanup_strv_free_
char **pass_env
= NULL
;
1347 size_t n_env
= 0, n_bufsize
= 0;
1350 STRV_FOREACH(i
, c
->pass_environment
) {
1351 _cleanup_free_
char *x
= NULL
;
1357 x
= strjoin(*i
, "=", v
, NULL
);
1360 if (!GREEDY_REALLOC(pass_env
, n_bufsize
, n_env
+ 2))
1362 pass_env
[n_env
++] = x
;
1363 pass_env
[n_env
] = NULL
;
1373 static bool exec_needs_mount_namespace(
1374 const ExecContext
*context
,
1375 const ExecParameters
*params
,
1376 ExecRuntime
*runtime
) {
1381 if (!strv_isempty(context
->read_write_dirs
) ||
1382 !strv_isempty(context
->read_only_dirs
) ||
1383 !strv_isempty(context
->inaccessible_dirs
))
1386 if (context
->mount_flags
!= 0)
1389 if (context
->private_tmp
&& runtime
&& (runtime
->tmp_dir
|| runtime
->var_tmp_dir
))
1392 if (params
->bus_endpoint_path
)
1395 if (context
->private_devices
||
1396 context
->protect_system
!= PROTECT_SYSTEM_NO
||
1397 context
->protect_home
!= PROTECT_HOME_NO
)
1403 static int close_remaining_fds(
1404 const ExecParameters
*params
,
1405 ExecRuntime
*runtime
,
1407 int *fds
, unsigned n_fds
) {
1409 unsigned n_dont_close
= 0;
1410 int dont_close
[n_fds
+ 7];
1414 if (params
->stdin_fd
>= 0)
1415 dont_close
[n_dont_close
++] = params
->stdin_fd
;
1416 if (params
->stdout_fd
>= 0)
1417 dont_close
[n_dont_close
++] = params
->stdout_fd
;
1418 if (params
->stderr_fd
>= 0)
1419 dont_close
[n_dont_close
++] = params
->stderr_fd
;
1422 dont_close
[n_dont_close
++] = socket_fd
;
1424 memcpy(dont_close
+ n_dont_close
, fds
, sizeof(int) * n_fds
);
1425 n_dont_close
+= n_fds
;
1428 if (params
->bus_endpoint_fd
>= 0)
1429 dont_close
[n_dont_close
++] = params
->bus_endpoint_fd
;
1432 if (runtime
->netns_storage_socket
[0] >= 0)
1433 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[0];
1434 if (runtime
->netns_storage_socket
[1] >= 0)
1435 dont_close
[n_dont_close
++] = runtime
->netns_storage_socket
[1];
1438 return close_all_fds(dont_close
, n_dont_close
);
1441 static int exec_child(
1443 ExecCommand
*command
,
1444 const ExecContext
*context
,
1445 const ExecParameters
*params
,
1446 ExecRuntime
*runtime
,
1449 int *fds
, unsigned n_fds
,
1453 _cleanup_strv_free_
char **our_env
= NULL
, **pass_env
= NULL
, **pam_env
= NULL
, **final_env
= NULL
, **final_argv
= NULL
;
1454 _cleanup_free_
char *mac_selinux_context_net
= NULL
;
1455 const char *username
= NULL
, *home
= NULL
, *shell
= NULL
, *wd
;
1456 uid_t uid
= UID_INVALID
;
1457 gid_t gid
= GID_INVALID
;
1459 bool needs_mount_namespace
;
1465 assert(exit_status
);
1467 rename_process_from_path(command
->path
);
1469 /* We reset exactly these signals, since they are the
1470 * only ones we set to SIG_IGN in the main daemon. All
1471 * others we leave untouched because we set them to
1472 * SIG_DFL or a valid handler initially, both of which
1473 * will be demoted to SIG_DFL. */
1474 (void) default_signals(SIGNALS_CRASH_HANDLER
,
1475 SIGNALS_IGNORE
, -1);
1477 if (context
->ignore_sigpipe
)
1478 (void) ignore_signals(SIGPIPE
, -1);
1480 r
= reset_signal_mask();
1482 *exit_status
= EXIT_SIGNAL_MASK
;
1486 if (params
->idle_pipe
)
1487 do_idle_pipe_dance(params
->idle_pipe
);
1489 /* Close sockets very early to make sure we don't
1490 * block init reexecution because it cannot bind its
1495 r
= close_remaining_fds(params
, runtime
, socket_fd
, fds
, n_fds
);
1497 *exit_status
= EXIT_FDS
;
1501 if (!context
->same_pgrp
)
1503 *exit_status
= EXIT_SETSID
;
1507 exec_context_tty_reset(context
, params
);
1509 if (params
->confirm_spawn
) {
1512 r
= ask_for_confirmation(&response
, argv
);
1513 if (r
== -ETIMEDOUT
)
1514 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1516 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r
));
1517 else if (response
== 's') {
1518 write_confirm_message("Skipping execution.\n");
1519 *exit_status
= EXIT_CONFIRM
;
1521 } else if (response
== 'n') {
1522 write_confirm_message("Failing execution.\n");
1528 if (context
->user
) {
1529 username
= context
->user
;
1530 r
= get_user_creds(&username
, &uid
, &gid
, &home
, &shell
);
1532 *exit_status
= EXIT_USER
;
1537 if (context
->group
) {
1538 const char *g
= context
->group
;
1540 r
= get_group_creds(&g
, &gid
);
1542 *exit_status
= EXIT_GROUP
;
1548 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1549 * must sure to drop O_NONBLOCK */
1551 (void) fd_nonblock(socket_fd
, false);
1553 r
= setup_input(context
, params
, socket_fd
);
1555 *exit_status
= EXIT_STDIN
;
1559 r
= setup_output(unit
, context
, params
, STDOUT_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1561 *exit_status
= EXIT_STDOUT
;
1565 r
= setup_output(unit
, context
, params
, STDERR_FILENO
, socket_fd
, basename(command
->path
), uid
, gid
);
1567 *exit_status
= EXIT_STDERR
;
1571 if (params
->cgroup_path
) {
1572 r
= cg_attach_everywhere(params
->cgroup_supported
, params
->cgroup_path
, 0, NULL
, NULL
);
1574 *exit_status
= EXIT_CGROUP
;
1579 if (context
->oom_score_adjust_set
) {
1580 char t
[DECIMAL_STR_MAX(context
->oom_score_adjust
)];
1582 /* When we can't make this change due to EPERM, then
1583 * let's silently skip over it. User namespaces
1584 * prohibit write access to this file, and we
1585 * shouldn't trip up over that. */
1587 sprintf(t
, "%i", context
->oom_score_adjust
);
1588 r
= write_string_file("/proc/self/oom_score_adj", t
, 0);
1589 if (r
== -EPERM
|| r
== -EACCES
) {
1591 log_unit_debug_errno(unit
, r
, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
1594 *exit_status
= EXIT_OOM_ADJUST
;
1599 if (context
->nice_set
)
1600 if (setpriority(PRIO_PROCESS
, 0, context
->nice
) < 0) {
1601 *exit_status
= EXIT_NICE
;
1605 if (context
->cpu_sched_set
) {
1606 struct sched_param param
= {
1607 .sched_priority
= context
->cpu_sched_priority
,
1610 r
= sched_setscheduler(0,
1611 context
->cpu_sched_policy
|
1612 (context
->cpu_sched_reset_on_fork
?
1613 SCHED_RESET_ON_FORK
: 0),
1616 *exit_status
= EXIT_SETSCHEDULER
;
1621 if (context
->cpuset
)
1622 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context
->cpuset_ncpus
), context
->cpuset
) < 0) {
1623 *exit_status
= EXIT_CPUAFFINITY
;
1627 if (context
->ioprio_set
)
1628 if (ioprio_set(IOPRIO_WHO_PROCESS
, 0, context
->ioprio
) < 0) {
1629 *exit_status
= EXIT_IOPRIO
;
1633 if (context
->timer_slack_nsec
!= NSEC_INFINITY
)
1634 if (prctl(PR_SET_TIMERSLACK
, context
->timer_slack_nsec
) < 0) {
1635 *exit_status
= EXIT_TIMERSLACK
;
1639 if (context
->personality
!= PERSONALITY_INVALID
)
1640 if (personality(context
->personality
) < 0) {
1641 *exit_status
= EXIT_PERSONALITY
;
1645 if (context
->utmp_id
)
1646 utmp_put_init_process(context
->utmp_id
, getpid(), getsid(0), context
->tty_path
,
1647 context
->utmp_mode
== EXEC_UTMP_INIT
? INIT_PROCESS
:
1648 context
->utmp_mode
== EXEC_UTMP_LOGIN
? LOGIN_PROCESS
:
1650 username
? "root" : context
->user
);
1652 if (context
->user
&& is_terminal_input(context
->std_input
)) {
1653 r
= chown_terminal(STDIN_FILENO
, uid
);
1655 *exit_status
= EXIT_STDIN
;
1660 if (params
->bus_endpoint_fd
>= 0 && context
->bus_endpoint
) {
1661 uid_t ep_uid
= (uid
== UID_INVALID
) ? 0 : uid
;
1663 r
= bus_kernel_set_endpoint_policy(params
->bus_endpoint_fd
, ep_uid
, context
->bus_endpoint
);
1665 *exit_status
= EXIT_BUS_ENDPOINT
;
1670 /* If delegation is enabled we'll pass ownership of the cgroup
1671 * (but only in systemd's own controller hierarchy!) to the
1672 * user of the new process. */
1673 if (params
->cgroup_path
&& context
->user
&& params
->cgroup_delegate
) {
1674 r
= cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0644, uid
, gid
);
1676 *exit_status
= EXIT_CGROUP
;
1681 r
= cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, 0755, uid
, gid
);
1683 *exit_status
= EXIT_CGROUP
;
1688 if (!strv_isempty(context
->runtime_directory
) && params
->runtime_prefix
) {
1691 STRV_FOREACH(rt
, context
->runtime_directory
) {
1692 _cleanup_free_
char *p
;
1694 p
= strjoin(params
->runtime_prefix
, "/", *rt
, NULL
);
1696 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1700 r
= mkdir_p_label(p
, context
->runtime_directory_mode
);
1702 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1706 r
= chmod_and_chown(p
, context
->runtime_directory_mode
, uid
, gid
);
1708 *exit_status
= EXIT_RUNTIME_DIRECTORY
;
1714 umask(context
->umask
);
1716 if (params
->apply_permissions
) {
1717 r
= enforce_groups(context
, username
, gid
);
1719 *exit_status
= EXIT_GROUP
;
1723 if (context
->smack_process_label
) {
1724 r
= mac_smack_apply_pid(0, context
->smack_process_label
);
1726 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1730 #ifdef SMACK_DEFAULT_PROCESS_LABEL
1732 _cleanup_free_
char *exec_label
= NULL
;
1734 r
= mac_smack_read(command
->path
, SMACK_ATTR_EXEC
, &exec_label
);
1735 if (r
< 0 && r
!= -ENODATA
&& r
!= -EOPNOTSUPP
) {
1736 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1740 r
= mac_smack_apply_pid(0, exec_label
? : SMACK_DEFAULT_PROCESS_LABEL
);
1742 *exit_status
= EXIT_SMACK_PROCESS_LABEL
;
1749 if (context
->pam_name
&& username
) {
1750 r
= setup_pam(context
->pam_name
, username
, uid
, context
->tty_path
, &pam_env
, fds
, n_fds
);
1752 *exit_status
= EXIT_PAM
;
1759 if (context
->private_network
&& runtime
&& runtime
->netns_storage_socket
[0] >= 0) {
1760 r
= setup_netns(runtime
->netns_storage_socket
);
1762 *exit_status
= EXIT_NETWORK
;
1767 needs_mount_namespace
= exec_needs_mount_namespace(context
, params
, runtime
);
1769 if (needs_mount_namespace
) {
1770 char *tmp
= NULL
, *var
= NULL
;
1772 /* The runtime struct only contains the parent
1773 * of the private /tmp, which is
1774 * non-accessible to world users. Inside of it
1775 * there's a /tmp that is sticky, and that's
1776 * the one we want to use here. */
1778 if (context
->private_tmp
&& runtime
) {
1779 if (runtime
->tmp_dir
)
1780 tmp
= strjoina(runtime
->tmp_dir
, "/tmp");
1781 if (runtime
->var_tmp_dir
)
1782 var
= strjoina(runtime
->var_tmp_dir
, "/tmp");
1785 r
= setup_namespace(
1786 params
->apply_chroot
? context
->root_directory
: NULL
,
1787 context
->read_write_dirs
,
1788 context
->read_only_dirs
,
1789 context
->inaccessible_dirs
,
1792 params
->bus_endpoint_path
,
1793 context
->private_devices
,
1794 context
->protect_home
,
1795 context
->protect_system
,
1796 context
->mount_flags
);
1798 /* If we couldn't set up the namespace this is
1799 * probably due to a missing capability. In this case,
1800 * silently proceeed. */
1801 if (r
== -EPERM
|| r
== -EACCES
) {
1803 log_unit_debug_errno(unit
, r
, "Failed to set up namespace, assuming containerized execution, ignoring: %m");
1806 *exit_status
= EXIT_NAMESPACE
;
1811 if (context
->working_directory_home
)
1813 else if (context
->working_directory
)
1814 wd
= context
->working_directory
;
1818 if (params
->apply_chroot
) {
1819 if (!needs_mount_namespace
&& context
->root_directory
)
1820 if (chroot(context
->root_directory
) < 0) {
1821 *exit_status
= EXIT_CHROOT
;
1825 if (chdir(wd
) < 0 &&
1826 !context
->working_directory_missing_ok
) {
1827 *exit_status
= EXIT_CHDIR
;
1833 d
= strjoina(strempty(context
->root_directory
), "/", strempty(wd
));
1835 !context
->working_directory_missing_ok
) {
1836 *exit_status
= EXIT_CHDIR
;
1842 if (params
->apply_permissions
&& mac_selinux_use() && params
->selinux_context_net
&& socket_fd
>= 0) {
1843 r
= mac_selinux_get_child_mls_label(socket_fd
, command
->path
, context
->selinux_context
, &mac_selinux_context_net
);
1845 *exit_status
= EXIT_SELINUX_CONTEXT
;
1851 /* We repeat the fd closing here, to make sure that
1852 * nothing is leaked from the PAM modules. Note that
1853 * we are more aggressive this time since socket_fd
1854 * and the netns fds we don't need anymore. The custom
1855 * endpoint fd was needed to upload the policy and can
1856 * now be closed as well. */
1857 r
= close_all_fds(fds
, n_fds
);
1859 r
= shift_fds(fds
, n_fds
);
1861 r
= flags_fds(fds
, n_fds
, context
->non_blocking
);
1863 *exit_status
= EXIT_FDS
;
1867 if (params
->apply_permissions
) {
1869 int secure_bits
= context
->secure_bits
;
1871 for (i
= 0; i
< _RLIMIT_MAX
; i
++) {
1872 if (!context
->rlimit
[i
])
1875 if (setrlimit_closest(i
, context
->rlimit
[i
]) < 0) {
1876 *exit_status
= EXIT_LIMITS
;
1881 if (!cap_test_all(context
->capability_bounding_set
)) {
1882 r
= capability_bounding_set_drop(context
->capability_bounding_set
, false);
1884 *exit_status
= EXIT_CAPABILITIES
;
1889 /* This is done before enforce_user, but ambient set
1890 * does not survive over setresuid() if keep_caps is not set. */
1891 if (context
->capability_ambient_set
!= 0) {
1892 r
= capability_ambient_set_apply(context
->capability_ambient_set
, true);
1894 *exit_status
= EXIT_CAPABILITIES
;
1898 if (context
->capabilities
) {
1900 /* The capabilities in ambient set need to be also in the inherited
1901 * set. If they aren't, trying to get them will fail. Add the ambient
1902 * set inherited capabilities to the capability set in the context.
1903 * This is needed because if capabilities are set (using "Capabilities="
1904 * keyword), they will override whatever we set now. */
1906 r
= capability_update_inherited_set(context
->capabilities
, context
->capability_ambient_set
);
1908 *exit_status
= EXIT_CAPABILITIES
;
1914 if (context
->user
) {
1915 r
= enforce_user(context
, uid
);
1917 *exit_status
= EXIT_USER
;
1920 if (context
->capability_ambient_set
!= 0) {
1922 /* Fix the ambient capabilities after user change. */
1923 r
= capability_ambient_set_apply(context
->capability_ambient_set
, false);
1925 *exit_status
= EXIT_CAPABILITIES
;
1929 /* If we were asked to change user and ambient capabilities
1930 * were requested, we had to add keep-caps to the securebits
1931 * so that we would maintain the inherited capability set
1932 * through the setresuid(). Make sure that the bit is added
1933 * also to the context secure_bits so that we don't try to
1934 * drop the bit away next. */
1936 secure_bits
|= 1<<SECURE_KEEP_CAPS
;
1940 /* PR_GET_SECUREBITS is not privileged, while
1941 * PR_SET_SECUREBITS is. So to suppress
1942 * potential EPERMs we'll try not to call
1943 * PR_SET_SECUREBITS unless necessary. */
1944 if (prctl(PR_GET_SECUREBITS
) != secure_bits
)
1945 if (prctl(PR_SET_SECUREBITS
, secure_bits
) < 0) {
1946 *exit_status
= EXIT_SECUREBITS
;
1950 if (context
->capabilities
)
1951 if (cap_set_proc(context
->capabilities
) < 0) {
1952 *exit_status
= EXIT_CAPABILITIES
;
1956 if (context
->no_new_privileges
)
1957 if (prctl(PR_SET_NO_NEW_PRIVS
, 1, 0, 0, 0) < 0) {
1958 *exit_status
= EXIT_NO_NEW_PRIVILEGES
;
1963 if (context
->address_families_whitelist
||
1964 !set_isempty(context
->address_families
)) {
1965 r
= apply_address_families(context
);
1967 *exit_status
= EXIT_ADDRESS_FAMILIES
;
1972 if (context
->syscall_whitelist
||
1973 !set_isempty(context
->syscall_filter
) ||
1974 !set_isempty(context
->syscall_archs
)) {
1975 r
= apply_seccomp(context
);
1977 *exit_status
= EXIT_SECCOMP
;
1984 if (mac_selinux_use()) {
1985 char *exec_context
= mac_selinux_context_net
?: context
->selinux_context
;
1988 r
= setexeccon(exec_context
);
1990 *exit_status
= EXIT_SELINUX_CONTEXT
;
1997 #ifdef HAVE_APPARMOR
1998 if (context
->apparmor_profile
&& mac_apparmor_use()) {
1999 r
= aa_change_onexec(context
->apparmor_profile
);
2000 if (r
< 0 && !context
->apparmor_profile_ignore
) {
2001 *exit_status
= EXIT_APPARMOR_PROFILE
;
2008 r
= build_environment(context
, params
, n_fds
, home
, username
, shell
, &our_env
);
2010 *exit_status
= EXIT_MEMORY
;
2014 r
= build_pass_environment(context
, &pass_env
);
2016 *exit_status
= EXIT_MEMORY
;
2020 final_env
= strv_env_merge(6,
2021 params
->environment
,
2024 context
->environment
,
2029 *exit_status
= EXIT_MEMORY
;
2033 final_argv
= replace_env_argv(argv
, final_env
);
2035 *exit_status
= EXIT_MEMORY
;
2039 final_env
= strv_env_clean(final_env
);
2041 if (_unlikely_(log_get_max_level() >= LOG_DEBUG
)) {
2042 _cleanup_free_
char *line
;
2044 line
= exec_command_line(final_argv
);
2047 log_struct(LOG_DEBUG
,
2049 "EXECUTABLE=%s", command
->path
,
2050 LOG_UNIT_MESSAGE(unit
, "Executing: %s", line
),
2056 execve(command
->path
, final_argv
, final_env
);
2057 *exit_status
= EXIT_EXEC
;
2061 int exec_spawn(Unit
*unit
,
2062 ExecCommand
*command
,
2063 const ExecContext
*context
,
2064 const ExecParameters
*params
,
2065 ExecRuntime
*runtime
,
2068 _cleanup_strv_free_
char **files_env
= NULL
;
2069 int *fds
= NULL
; unsigned n_fds
= 0;
2070 _cleanup_free_
char *line
= NULL
;
2080 assert(params
->fds
|| params
->n_fds
<= 0);
2082 if (context
->std_input
== EXEC_INPUT_SOCKET
||
2083 context
->std_output
== EXEC_OUTPUT_SOCKET
||
2084 context
->std_error
== EXEC_OUTPUT_SOCKET
) {
2086 if (params
->n_fds
!= 1) {
2087 log_unit_error(unit
, "Got more than one socket.");
2091 socket_fd
= params
->fds
[0];
2095 n_fds
= params
->n_fds
;
2098 r
= exec_context_load_environment(unit
, context
, &files_env
);
2100 return log_unit_error_errno(unit
, r
, "Failed to load environment files: %m");
2102 argv
= params
->argv
?: command
->argv
;
2103 line
= exec_command_line(argv
);
2107 log_struct(LOG_DEBUG
,
2109 LOG_UNIT_MESSAGE(unit
, "About to execute: %s", line
),
2110 "EXECUTABLE=%s", command
->path
,
2114 return log_unit_error_errno(unit
, errno
, "Failed to fork: %m");
2119 r
= exec_child(unit
,
2131 log_struct_errno(LOG_ERR
, r
,
2132 LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED
),
2134 LOG_UNIT_MESSAGE(unit
, "Failed at step %s spawning %s: %m",
2135 exit_status_to_string(exit_status
, EXIT_STATUS_SYSTEMD
),
2137 "EXECUTABLE=%s", command
->path
,
2144 log_unit_debug(unit
, "Forked %s as "PID_FMT
, command
->path
, pid
);
2146 /* We add the new process to the cgroup both in the child (so
2147 * that we can be sure that no user code is ever executed
2148 * outside of the cgroup) and in the parent (so that we can be
2149 * sure that when we kill the cgroup the process will be
2151 if (params
->cgroup_path
)
2152 (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER
, params
->cgroup_path
, pid
);
2154 exec_status_start(&command
->exec_status
, pid
);
2160 void exec_context_init(ExecContext
*c
) {
2164 c
->ioprio
= IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE
, 0);
2165 c
->cpu_sched_policy
= SCHED_OTHER
;
2166 c
->syslog_priority
= LOG_DAEMON
|LOG_INFO
;
2167 c
->syslog_level_prefix
= true;
2168 c
->ignore_sigpipe
= true;
2169 c
->timer_slack_nsec
= NSEC_INFINITY
;
2170 c
->personality
= PERSONALITY_INVALID
;
2171 c
->runtime_directory_mode
= 0755;
2172 c
->capability_bounding_set
= CAP_ALL
;
2175 void exec_context_done(ExecContext
*c
) {
2180 c
->environment
= strv_free(c
->environment
);
2181 c
->environment_files
= strv_free(c
->environment_files
);
2182 c
->pass_environment
= strv_free(c
->pass_environment
);
2184 for (l
= 0; l
< ELEMENTSOF(c
->rlimit
); l
++)
2185 c
->rlimit
[l
] = mfree(c
->rlimit
[l
]);
2187 c
->working_directory
= mfree(c
->working_directory
);
2188 c
->root_directory
= mfree(c
->root_directory
);
2189 c
->tty_path
= mfree(c
->tty_path
);
2190 c
->syslog_identifier
= mfree(c
->syslog_identifier
);
2191 c
->user
= mfree(c
->user
);
2192 c
->group
= mfree(c
->group
);
2194 c
->supplementary_groups
= strv_free(c
->supplementary_groups
);
2196 c
->pam_name
= mfree(c
->pam_name
);
2198 if (c
->capabilities
) {
2199 cap_free(c
->capabilities
);
2200 c
->capabilities
= NULL
;
2203 c
->read_only_dirs
= strv_free(c
->read_only_dirs
);
2204 c
->read_write_dirs
= strv_free(c
->read_write_dirs
);
2205 c
->inaccessible_dirs
= strv_free(c
->inaccessible_dirs
);
2208 CPU_FREE(c
->cpuset
);
2210 c
->utmp_id
= mfree(c
->utmp_id
);
2211 c
->selinux_context
= mfree(c
->selinux_context
);
2212 c
->apparmor_profile
= mfree(c
->apparmor_profile
);
2214 c
->syscall_filter
= set_free(c
->syscall_filter
);
2215 c
->syscall_archs
= set_free(c
->syscall_archs
);
2216 c
->address_families
= set_free(c
->address_families
);
2218 c
->runtime_directory
= strv_free(c
->runtime_directory
);
2220 bus_endpoint_free(c
->bus_endpoint
);
2221 c
->bus_endpoint
= NULL
;
2224 int exec_context_destroy_runtime_directory(ExecContext
*c
, const char *runtime_prefix
) {
2229 if (!runtime_prefix
)
2232 STRV_FOREACH(i
, c
->runtime_directory
) {
2233 _cleanup_free_
char *p
;
2235 p
= strjoin(runtime_prefix
, "/", *i
, NULL
);
2239 /* We execute this synchronously, since we need to be
2240 * sure this is gone when we start the service
2242 (void) rm_rf(p
, REMOVE_ROOT
);
2248 void exec_command_done(ExecCommand
*c
) {
2251 c
->path
= mfree(c
->path
);
2253 c
->argv
= strv_free(c
->argv
);
2256 void exec_command_done_array(ExecCommand
*c
, unsigned n
) {
2259 for (i
= 0; i
< n
; i
++)
2260 exec_command_done(c
+i
);
2263 ExecCommand
* exec_command_free_list(ExecCommand
*c
) {
2267 LIST_REMOVE(command
, c
, i
);
2268 exec_command_done(i
);
2275 void exec_command_free_array(ExecCommand
**c
, unsigned n
) {
2278 for (i
= 0; i
< n
; i
++)
2279 c
[i
] = exec_command_free_list(c
[i
]);
2282 typedef struct InvalidEnvInfo
{
2287 static void invalid_env(const char *p
, void *userdata
) {
2288 InvalidEnvInfo
*info
= userdata
;
2290 log_unit_error(info
->unit
, "Ignoring invalid environment assignment '%s': %s", p
, info
->path
);
2293 int exec_context_load_environment(Unit
*unit
, const ExecContext
*c
, char ***l
) {
2294 char **i
, **r
= NULL
;
2299 STRV_FOREACH(i
, c
->environment_files
) {
2302 bool ignore
= false;
2304 _cleanup_globfree_ glob_t pglob
= {};
2314 if (!path_is_absolute(fn
)) {
2322 /* Filename supports globbing, take all matching files */
2324 if (glob(fn
, 0, NULL
, &pglob
) != 0) {
2329 return errno
> 0 ? -errno
: -EINVAL
;
2331 count
= pglob
.gl_pathc
;
2339 for (n
= 0; n
< count
; n
++) {
2340 k
= load_env_file(NULL
, pglob
.gl_pathv
[n
], NULL
, &p
);
2348 /* Log invalid environment variables with filename */
2350 InvalidEnvInfo info
= {
2352 .path
= pglob
.gl_pathv
[n
]
2355 p
= strv_env_clean_with_callback(p
, invalid_env
, &info
);
2363 m
= strv_env_merge(2, r
, p
);
2379 static bool tty_may_match_dev_console(const char *tty
) {
2380 _cleanup_free_
char *active
= NULL
;
2386 if (startswith(tty
, "/dev/"))
2389 /* trivial identity? */
2390 if (streq(tty
, "console"))
2393 console
= resolve_dev_console(&active
);
2394 /* if we could not resolve, assume it may */
2398 /* "tty0" means the active VC, so it may be the same sometimes */
2399 return streq(console
, tty
) || (streq(console
, "tty0") && tty_is_vc(tty
));
2402 bool exec_context_may_touch_console(ExecContext
*ec
) {
2404 return (ec
->tty_reset
||
2406 ec
->tty_vt_disallocate
||
2407 is_terminal_input(ec
->std_input
) ||
2408 is_terminal_output(ec
->std_output
) ||
2409 is_terminal_output(ec
->std_error
)) &&
2410 tty_may_match_dev_console(exec_context_tty_path(ec
));
2413 static void strv_fprintf(FILE *f
, char **l
) {
2419 fprintf(f
, " %s", *g
);
2422 void exec_context_dump(ExecContext
*c
, FILE* f
, const char *prefix
) {
2429 prefix
= strempty(prefix
);
2433 "%sWorkingDirectory: %s\n"
2434 "%sRootDirectory: %s\n"
2435 "%sNonBlocking: %s\n"
2436 "%sPrivateTmp: %s\n"
2437 "%sPrivateNetwork: %s\n"
2438 "%sPrivateDevices: %s\n"
2439 "%sProtectHome: %s\n"
2440 "%sProtectSystem: %s\n"
2441 "%sIgnoreSIGPIPE: %s\n",
2443 prefix
, c
->working_directory
? c
->working_directory
: "/",
2444 prefix
, c
->root_directory
? c
->root_directory
: "/",
2445 prefix
, yes_no(c
->non_blocking
),
2446 prefix
, yes_no(c
->private_tmp
),
2447 prefix
, yes_no(c
->private_network
),
2448 prefix
, yes_no(c
->private_devices
),
2449 prefix
, protect_home_to_string(c
->protect_home
),
2450 prefix
, protect_system_to_string(c
->protect_system
),
2451 prefix
, yes_no(c
->ignore_sigpipe
));
2453 STRV_FOREACH(e
, c
->environment
)
2454 fprintf(f
, "%sEnvironment: %s\n", prefix
, *e
);
2456 STRV_FOREACH(e
, c
->environment_files
)
2457 fprintf(f
, "%sEnvironmentFile: %s\n", prefix
, *e
);
2459 STRV_FOREACH(e
, c
->pass_environment
)
2460 fprintf(f
, "%sPassEnvironment: %s\n", prefix
, *e
);
2462 fprintf(f
, "%sRuntimeDirectoryMode: %04o\n", prefix
, c
->runtime_directory_mode
);
2464 STRV_FOREACH(d
, c
->runtime_directory
)
2465 fprintf(f
, "%sRuntimeDirectory: %s\n", prefix
, *d
);
2472 if (c
->oom_score_adjust_set
)
2474 "%sOOMScoreAdjust: %i\n",
2475 prefix
, c
->oom_score_adjust
);
2477 for (i
= 0; i
< RLIM_NLIMITS
; i
++)
2479 fprintf(f
, "%s%s: " RLIM_FMT
"\n",
2480 prefix
, rlimit_to_string(i
), c
->rlimit
[i
]->rlim_max
);
2481 fprintf(f
, "%s%sSoft: " RLIM_FMT
"\n",
2482 prefix
, rlimit_to_string(i
), c
->rlimit
[i
]->rlim_cur
);
2485 if (c
->ioprio_set
) {
2486 _cleanup_free_
char *class_str
= NULL
;
2488 ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c
->ioprio
), &class_str
);
2490 "%sIOSchedulingClass: %s\n"
2491 "%sIOPriority: %i\n",
2492 prefix
, strna(class_str
),
2493 prefix
, (int) IOPRIO_PRIO_DATA(c
->ioprio
));
2496 if (c
->cpu_sched_set
) {
2497 _cleanup_free_
char *policy_str
= NULL
;
2499 sched_policy_to_string_alloc(c
->cpu_sched_policy
, &policy_str
);
2501 "%sCPUSchedulingPolicy: %s\n"
2502 "%sCPUSchedulingPriority: %i\n"
2503 "%sCPUSchedulingResetOnFork: %s\n",
2504 prefix
, strna(policy_str
),
2505 prefix
, c
->cpu_sched_priority
,
2506 prefix
, yes_no(c
->cpu_sched_reset_on_fork
));
2510 fprintf(f
, "%sCPUAffinity:", prefix
);
2511 for (i
= 0; i
< c
->cpuset_ncpus
; i
++)
2512 if (CPU_ISSET_S(i
, CPU_ALLOC_SIZE(c
->cpuset_ncpus
), c
->cpuset
))
2513 fprintf(f
, " %u", i
);
2517 if (c
->timer_slack_nsec
!= NSEC_INFINITY
)
2518 fprintf(f
, "%sTimerSlackNSec: "NSEC_FMT
"\n", prefix
, c
->timer_slack_nsec
);
2521 "%sStandardInput: %s\n"
2522 "%sStandardOutput: %s\n"
2523 "%sStandardError: %s\n",
2524 prefix
, exec_input_to_string(c
->std_input
),
2525 prefix
, exec_output_to_string(c
->std_output
),
2526 prefix
, exec_output_to_string(c
->std_error
));
2532 "%sTTYVHangup: %s\n"
2533 "%sTTYVTDisallocate: %s\n",
2534 prefix
, c
->tty_path
,
2535 prefix
, yes_no(c
->tty_reset
),
2536 prefix
, yes_no(c
->tty_vhangup
),
2537 prefix
, yes_no(c
->tty_vt_disallocate
));
2539 if (c
->std_output
== EXEC_OUTPUT_SYSLOG
||
2540 c
->std_output
== EXEC_OUTPUT_KMSG
||
2541 c
->std_output
== EXEC_OUTPUT_JOURNAL
||
2542 c
->std_output
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2543 c
->std_output
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2544 c
->std_output
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
||
2545 c
->std_error
== EXEC_OUTPUT_SYSLOG
||
2546 c
->std_error
== EXEC_OUTPUT_KMSG
||
2547 c
->std_error
== EXEC_OUTPUT_JOURNAL
||
2548 c
->std_error
== EXEC_OUTPUT_SYSLOG_AND_CONSOLE
||
2549 c
->std_error
== EXEC_OUTPUT_KMSG_AND_CONSOLE
||
2550 c
->std_error
== EXEC_OUTPUT_JOURNAL_AND_CONSOLE
) {
2552 _cleanup_free_
char *fac_str
= NULL
, *lvl_str
= NULL
;
2554 log_facility_unshifted_to_string_alloc(c
->syslog_priority
>> 3, &fac_str
);
2555 log_level_to_string_alloc(LOG_PRI(c
->syslog_priority
), &lvl_str
);
2558 "%sSyslogFacility: %s\n"
2559 "%sSyslogLevel: %s\n",
2560 prefix
, strna(fac_str
),
2561 prefix
, strna(lvl_str
));
2564 if (c
->capabilities
) {
2565 _cleanup_cap_free_charp_
char *t
;
2567 t
= cap_to_text(c
->capabilities
, NULL
);
2569 fprintf(f
, "%sCapabilities: %s\n", prefix
, t
);
2573 fprintf(f
, "%sSecure Bits:%s%s%s%s%s%s\n",
2575 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS
) ? " keep-caps" : "",
2576 (c
->secure_bits
& 1<<SECURE_KEEP_CAPS_LOCKED
) ? " keep-caps-locked" : "",
2577 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP
) ? " no-setuid-fixup" : "",
2578 (c
->secure_bits
& 1<<SECURE_NO_SETUID_FIXUP_LOCKED
) ? " no-setuid-fixup-locked" : "",
2579 (c
->secure_bits
& 1<<SECURE_NOROOT
) ? " noroot" : "",
2580 (c
->secure_bits
& 1<<SECURE_NOROOT_LOCKED
) ? "noroot-locked" : "");
2582 if (c
->capability_bounding_set
!= CAP_ALL
) {
2584 fprintf(f
, "%sCapabilityBoundingSet:", prefix
);
2586 for (l
= 0; l
<= cap_last_cap(); l
++)
2587 if (c
->capability_bounding_set
& (UINT64_C(1) << l
))
2588 fprintf(f
, " %s", strna(capability_to_name(l
)));
2593 if (c
->capability_ambient_set
!= 0) {
2595 fprintf(f
, "%sAmbientCapabilities:", prefix
);
2597 for (l
= 0; l
<= cap_last_cap(); l
++)
2598 if (c
->capability_ambient_set
& (UINT64_C(1) << l
))
2599 fprintf(f
, " %s", strna(capability_to_name(l
)));
2605 fprintf(f
, "%sUser: %s\n", prefix
, c
->user
);
2607 fprintf(f
, "%sGroup: %s\n", prefix
, c
->group
);
2609 if (strv_length(c
->supplementary_groups
) > 0) {
2610 fprintf(f
, "%sSupplementaryGroups:", prefix
);
2611 strv_fprintf(f
, c
->supplementary_groups
);
2616 fprintf(f
, "%sPAMName: %s\n", prefix
, c
->pam_name
);
2618 if (strv_length(c
->read_write_dirs
) > 0) {
2619 fprintf(f
, "%sReadWriteDirs:", prefix
);
2620 strv_fprintf(f
, c
->read_write_dirs
);
2624 if (strv_length(c
->read_only_dirs
) > 0) {
2625 fprintf(f
, "%sReadOnlyDirs:", prefix
);
2626 strv_fprintf(f
, c
->read_only_dirs
);
2630 if (strv_length(c
->inaccessible_dirs
) > 0) {
2631 fprintf(f
, "%sInaccessibleDirs:", prefix
);
2632 strv_fprintf(f
, c
->inaccessible_dirs
);
2638 "%sUtmpIdentifier: %s\n",
2639 prefix
, c
->utmp_id
);
2641 if (c
->selinux_context
)
2643 "%sSELinuxContext: %s%s\n",
2644 prefix
, c
->selinux_context_ignore
? "-" : "", c
->selinux_context
);
2646 if (c
->personality
!= PERSONALITY_INVALID
)
2648 "%sPersonality: %s\n",
2649 prefix
, strna(personality_to_string(c
->personality
)));
2651 if (c
->syscall_filter
) {
2659 "%sSystemCallFilter: ",
2662 if (!c
->syscall_whitelist
)
2666 SET_FOREACH(id
, c
->syscall_filter
, j
) {
2667 _cleanup_free_
char *name
= NULL
;
2674 name
= seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE
, PTR_TO_INT(id
) - 1);
2675 fputs(strna(name
), f
);
2682 if (c
->syscall_archs
) {
2689 "%sSystemCallArchitectures:",
2693 SET_FOREACH(id
, c
->syscall_archs
, j
)
2694 fprintf(f
, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id
) - 1)));
2699 if (c
->syscall_errno
> 0)
2701 "%sSystemCallErrorNumber: %s\n",
2702 prefix
, strna(errno_to_name(c
->syscall_errno
)));
2704 if (c
->apparmor_profile
)
2706 "%sAppArmorProfile: %s%s\n",
2707 prefix
, c
->apparmor_profile_ignore
? "-" : "", c
->apparmor_profile
);
2710 bool exec_context_maintains_privileges(ExecContext
*c
) {
2713 /* Returns true if the process forked off would run run under
2714 * an unchanged UID or as root. */
2719 if (streq(c
->user
, "root") || streq(c
->user
, "0"))
2725 void exec_status_start(ExecStatus
*s
, pid_t pid
) {
2730 dual_timestamp_get(&s
->start_timestamp
);
2733 void exec_status_exit(ExecStatus
*s
, ExecContext
*context
, pid_t pid
, int code
, int status
) {
2736 if (s
->pid
&& s
->pid
!= pid
)
2740 dual_timestamp_get(&s
->exit_timestamp
);
2746 if (context
->utmp_id
)
2747 utmp_put_dead_process(context
->utmp_id
, pid
, code
, status
);
2749 exec_context_tty_reset(context
, NULL
);
2753 void exec_status_dump(ExecStatus
*s
, FILE *f
, const char *prefix
) {
2754 char buf
[FORMAT_TIMESTAMP_MAX
];
2762 prefix
= strempty(prefix
);
2765 "%sPID: "PID_FMT
"\n",
2768 if (s
->start_timestamp
.realtime
> 0)
2770 "%sStart Timestamp: %s\n",
2771 prefix
, format_timestamp(buf
, sizeof(buf
), s
->start_timestamp
.realtime
));
2773 if (s
->exit_timestamp
.realtime
> 0)
2775 "%sExit Timestamp: %s\n"
2777 "%sExit Status: %i\n",
2778 prefix
, format_timestamp(buf
, sizeof(buf
), s
->exit_timestamp
.realtime
),
2779 prefix
, sigchld_code_to_string(s
->code
),
2783 char *exec_command_line(char **argv
) {
2791 STRV_FOREACH(a
, argv
)
2794 if (!(n
= new(char, k
)))
2798 STRV_FOREACH(a
, argv
) {
2805 if (strpbrk(*a
, WHITESPACE
)) {
2816 /* FIXME: this doesn't really handle arguments that have
2817 * spaces and ticks in them */
2822 void exec_command_dump(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2823 _cleanup_free_
char *cmd
= NULL
;
2824 const char *prefix2
;
2829 prefix
= strempty(prefix
);
2830 prefix2
= strjoina(prefix
, "\t");
2832 cmd
= exec_command_line(c
->argv
);
2834 "%sCommand Line: %s\n",
2835 prefix
, cmd
? cmd
: strerror(ENOMEM
));
2837 exec_status_dump(&c
->exec_status
, f
, prefix2
);
2840 void exec_command_dump_list(ExecCommand
*c
, FILE *f
, const char *prefix
) {
2843 prefix
= strempty(prefix
);
2845 LIST_FOREACH(command
, c
, c
)
2846 exec_command_dump(c
, f
, prefix
);
2849 void exec_command_append_list(ExecCommand
**l
, ExecCommand
*e
) {
2856 /* It's kind of important, that we keep the order here */
2857 LIST_FIND_TAIL(command
, *l
, end
);
2858 LIST_INSERT_AFTER(command
, *l
, end
, e
);
2863 int exec_command_set(ExecCommand
*c
, const char *path
, ...) {
2871 l
= strv_new_ap(path
, ap
);
2892 int exec_command_append(ExecCommand
*c
, const char *path
, ...) {
2893 _cleanup_strv_free_
char **l
= NULL
;
2901 l
= strv_new_ap(path
, ap
);
2907 r
= strv_extend_strv(&c
->argv
, l
, false);
2915 static int exec_runtime_allocate(ExecRuntime
**rt
) {
2920 *rt
= new0(ExecRuntime
, 1);
2925 (*rt
)->netns_storage_socket
[0] = (*rt
)->netns_storage_socket
[1] = -1;
2930 int exec_runtime_make(ExecRuntime
**rt
, ExecContext
*c
, const char *id
) {
2940 if (!c
->private_network
&& !c
->private_tmp
)
2943 r
= exec_runtime_allocate(rt
);
2947 if (c
->private_network
&& (*rt
)->netns_storage_socket
[0] < 0) {
2948 if (socketpair(AF_UNIX
, SOCK_DGRAM
, 0, (*rt
)->netns_storage_socket
) < 0)
2952 if (c
->private_tmp
&& !(*rt
)->tmp_dir
) {
2953 r
= setup_tmp_dirs(id
, &(*rt
)->tmp_dir
, &(*rt
)->var_tmp_dir
);
2961 ExecRuntime
*exec_runtime_ref(ExecRuntime
*r
) {
2963 assert(r
->n_ref
> 0);
2969 ExecRuntime
*exec_runtime_unref(ExecRuntime
*r
) {
2974 assert(r
->n_ref
> 0);
2981 free(r
->var_tmp_dir
);
2982 safe_close_pair(r
->netns_storage_socket
);
2988 int exec_runtime_serialize(Unit
*u
, ExecRuntime
*rt
, FILE *f
, FDSet
*fds
) {
2997 unit_serialize_item(u
, f
, "tmp-dir", rt
->tmp_dir
);
2999 if (rt
->var_tmp_dir
)
3000 unit_serialize_item(u
, f
, "var-tmp-dir", rt
->var_tmp_dir
);
3002 if (rt
->netns_storage_socket
[0] >= 0) {
3005 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[0]);
3009 unit_serialize_item_format(u
, f
, "netns-socket-0", "%i", copy
);
3012 if (rt
->netns_storage_socket
[1] >= 0) {
3015 copy
= fdset_put_dup(fds
, rt
->netns_storage_socket
[1]);
3019 unit_serialize_item_format(u
, f
, "netns-socket-1", "%i", copy
);
3025 int exec_runtime_deserialize_item(Unit
*u
, ExecRuntime
**rt
, const char *key
, const char *value
, FDSet
*fds
) {
3032 if (streq(key
, "tmp-dir")) {
3035 r
= exec_runtime_allocate(rt
);
3039 copy
= strdup(value
);
3043 free((*rt
)->tmp_dir
);
3044 (*rt
)->tmp_dir
= copy
;
3046 } else if (streq(key
, "var-tmp-dir")) {
3049 r
= exec_runtime_allocate(rt
);
3053 copy
= strdup(value
);
3057 free((*rt
)->var_tmp_dir
);
3058 (*rt
)->var_tmp_dir
= copy
;
3060 } else if (streq(key
, "netns-socket-0")) {
3063 r
= exec_runtime_allocate(rt
);
3067 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
3068 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
3070 safe_close((*rt
)->netns_storage_socket
[0]);
3071 (*rt
)->netns_storage_socket
[0] = fdset_remove(fds
, fd
);
3073 } else if (streq(key
, "netns-socket-1")) {
3076 r
= exec_runtime_allocate(rt
);
3080 if (safe_atoi(value
, &fd
) < 0 || !fdset_contains(fds
, fd
))
3081 log_unit_debug(u
, "Failed to parse netns socket value: %s", value
);
3083 safe_close((*rt
)->netns_storage_socket
[1]);
3084 (*rt
)->netns_storage_socket
[1] = fdset_remove(fds
, fd
);
3092 static void *remove_tmpdir_thread(void *p
) {
3093 _cleanup_free_
char *path
= p
;
3095 (void) rm_rf(path
, REMOVE_ROOT
|REMOVE_PHYSICAL
);
3099 void exec_runtime_destroy(ExecRuntime
*rt
) {
3105 /* If there are multiple users of this, let's leave the stuff around */
3110 log_debug("Spawning thread to nuke %s", rt
->tmp_dir
);
3112 r
= asynchronous_job(remove_tmpdir_thread
, rt
->tmp_dir
);
3114 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->tmp_dir
);
3121 if (rt
->var_tmp_dir
) {
3122 log_debug("Spawning thread to nuke %s", rt
->var_tmp_dir
);
3124 r
= asynchronous_job(remove_tmpdir_thread
, rt
->var_tmp_dir
);
3126 log_warning_errno(r
, "Failed to nuke %s: %m", rt
->var_tmp_dir
);
3127 free(rt
->var_tmp_dir
);
3130 rt
->var_tmp_dir
= NULL
;
3133 safe_close_pair(rt
->netns_storage_socket
);
3136 static const char* const exec_input_table
[_EXEC_INPUT_MAX
] = {
3137 [EXEC_INPUT_NULL
] = "null",
3138 [EXEC_INPUT_TTY
] = "tty",
3139 [EXEC_INPUT_TTY_FORCE
] = "tty-force",
3140 [EXEC_INPUT_TTY_FAIL
] = "tty-fail",
3141 [EXEC_INPUT_SOCKET
] = "socket"
3144 DEFINE_STRING_TABLE_LOOKUP(exec_input
, ExecInput
);
3146 static const char* const exec_output_table
[_EXEC_OUTPUT_MAX
] = {
3147 [EXEC_OUTPUT_INHERIT
] = "inherit",
3148 [EXEC_OUTPUT_NULL
] = "null",
3149 [EXEC_OUTPUT_TTY
] = "tty",
3150 [EXEC_OUTPUT_SYSLOG
] = "syslog",
3151 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE
] = "syslog+console",
3152 [EXEC_OUTPUT_KMSG
] = "kmsg",
3153 [EXEC_OUTPUT_KMSG_AND_CONSOLE
] = "kmsg+console",
3154 [EXEC_OUTPUT_JOURNAL
] = "journal",
3155 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE
] = "journal+console",
3156 [EXEC_OUTPUT_SOCKET
] = "socket"
3159 DEFINE_STRING_TABLE_LOOKUP(exec_output
, ExecOutput
);
3161 static const char* const exec_utmp_mode_table
[_EXEC_UTMP_MODE_MAX
] = {
3162 [EXEC_UTMP_INIT
] = "init",
3163 [EXEC_UTMP_LOGIN
] = "login",
3164 [EXEC_UTMP_USER
] = "user",
3167 DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode
, ExecUtmpMode
);