]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/execute.c
83ae3f6253e969a02b6db0c51e8d5558a3ec6de1
[thirdparty/systemd.git] / src / core / execute.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include <errno.h>
23 #include <fcntl.h>
24 #include <glob.h>
25 #include <grp.h>
26 #include <poll.h>
27 #include <signal.h>
28 #include <string.h>
29 #include <sys/personality.h>
30 #include <sys/prctl.h>
31 #include <sys/socket.h>
32 #include <sys/stat.h>
33 #include <sys/un.h>
34 #include <unistd.h>
35 #include <utmpx.h>
36
37 #ifdef HAVE_PAM
38 #include <security/pam_appl.h>
39 #endif
40
41 #ifdef HAVE_SELINUX
42 #include <selinux/selinux.h>
43 #endif
44
45 #ifdef HAVE_SECCOMP
46 #include <seccomp.h>
47 #endif
48
49 #ifdef HAVE_APPARMOR
50 #include <sys/apparmor.h>
51 #endif
52
53 #include "sd-messages.h"
54
55 #include "af-list.h"
56 #ifdef HAVE_APPARMOR
57 #include "apparmor-util.h"
58 #endif
59 #include "async.h"
60 #include "barrier.h"
61 #include "bus-endpoint.h"
62 #include "cap-list.h"
63 #include "capability.h"
64 #include "def.h"
65 #include "env-util.h"
66 #include "errno-list.h"
67 #include "execute.h"
68 #include "exit-status.h"
69 #include "fd-util.h"
70 #include "fileio.h"
71 #include "formats-util.h"
72 #include "ioprio.h"
73 #include "log.h"
74 #include "macro.h"
75 #include "missing.h"
76 #include "mkdir.h"
77 #include "namespace.h"
78 #include "path-util.h"
79 #include "process-util.h"
80 #include "rm-rf.h"
81 #ifdef HAVE_SECCOMP
82 #include "seccomp-util.h"
83 #endif
84 #include "securebits.h"
85 #include "selinux-util.h"
86 #include "signal-util.h"
87 #include "smack-util.h"
88 #include "string-util.h"
89 #include "strv.h"
90 #include "terminal-util.h"
91 #include "unit.h"
92 #include "util.h"
93 #include "utmp-wtmp.h"
94
95 #define IDLE_TIMEOUT_USEC (5*USEC_PER_SEC)
96 #define IDLE_TIMEOUT2_USEC (1*USEC_PER_SEC)
97
98 /* This assumes there is a 'tty' group */
99 #define TTY_MODE 0620
100
101 #define SNDBUF_SIZE (8*1024*1024)
102
103 static int shift_fds(int fds[], unsigned n_fds) {
104 int start, restart_from;
105
106 if (n_fds <= 0)
107 return 0;
108
109 /* Modifies the fds array! (sorts it) */
110
111 assert(fds);
112
113 start = 0;
114 for (;;) {
115 int i;
116
117 restart_from = -1;
118
119 for (i = start; i < (int) n_fds; i++) {
120 int nfd;
121
122 /* Already at right index? */
123 if (fds[i] == i+3)
124 continue;
125
126 nfd = fcntl(fds[i], F_DUPFD, i + 3);
127 if (nfd < 0)
128 return -errno;
129
130 safe_close(fds[i]);
131 fds[i] = nfd;
132
133 /* Hmm, the fd we wanted isn't free? Then
134 * let's remember that and try again from here */
135 if (nfd != i+3 && restart_from < 0)
136 restart_from = i;
137 }
138
139 if (restart_from < 0)
140 break;
141
142 start = restart_from;
143 }
144
145 return 0;
146 }
147
148 static int flags_fds(const int fds[], unsigned n_fds, bool nonblock) {
149 unsigned i;
150 int r;
151
152 if (n_fds <= 0)
153 return 0;
154
155 assert(fds);
156
157 /* Drops/Sets O_NONBLOCK and FD_CLOEXEC from the file flags */
158
159 for (i = 0; i < n_fds; i++) {
160
161 r = fd_nonblock(fds[i], nonblock);
162 if (r < 0)
163 return r;
164
165 /* We unconditionally drop FD_CLOEXEC from the fds,
166 * since after all we want to pass these fds to our
167 * children */
168
169 r = fd_cloexec(fds[i], false);
170 if (r < 0)
171 return r;
172 }
173
174 return 0;
175 }
176
177 _pure_ static const char *tty_path(const ExecContext *context) {
178 assert(context);
179
180 if (context->tty_path)
181 return context->tty_path;
182
183 return "/dev/console";
184 }
185
186 static void exec_context_tty_reset(const ExecContext *context) {
187 assert(context);
188
189 if (context->tty_vhangup)
190 terminal_vhangup(tty_path(context));
191
192 if (context->tty_reset)
193 reset_terminal(tty_path(context));
194
195 if (context->tty_vt_disallocate && context->tty_path)
196 vt_disallocate(context->tty_path);
197 }
198
199 static bool is_terminal_output(ExecOutput o) {
200 return
201 o == EXEC_OUTPUT_TTY ||
202 o == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
203 o == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
204 o == EXEC_OUTPUT_JOURNAL_AND_CONSOLE;
205 }
206
207 static int open_null_as(int flags, int nfd) {
208 int fd, r;
209
210 assert(nfd >= 0);
211
212 fd = open("/dev/null", flags|O_NOCTTY);
213 if (fd < 0)
214 return -errno;
215
216 if (fd != nfd) {
217 r = dup2(fd, nfd) < 0 ? -errno : nfd;
218 safe_close(fd);
219 } else
220 r = nfd;
221
222 return r;
223 }
224
225 static int connect_journal_socket(int fd, uid_t uid, gid_t gid) {
226 union sockaddr_union sa = {
227 .un.sun_family = AF_UNIX,
228 .un.sun_path = "/run/systemd/journal/stdout",
229 };
230 uid_t olduid = UID_INVALID;
231 gid_t oldgid = GID_INVALID;
232 int r;
233
234 if (gid != GID_INVALID) {
235 oldgid = getgid();
236
237 r = setegid(gid);
238 if (r < 0)
239 return -errno;
240 }
241
242 if (uid != UID_INVALID) {
243 olduid = getuid();
244
245 r = seteuid(uid);
246 if (r < 0) {
247 r = -errno;
248 goto restore_gid;
249 }
250 }
251
252 r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path));
253 if (r < 0)
254 r = -errno;
255
256 /* If we fail to restore the uid or gid, things will likely
257 fail later on. This should only happen if an LSM interferes. */
258
259 if (uid != UID_INVALID)
260 (void) seteuid(olduid);
261
262 restore_gid:
263 if (gid != GID_INVALID)
264 (void) setegid(oldgid);
265
266 return r;
267 }
268
269 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) {
270 int fd, r;
271
272 assert(context);
273 assert(output < _EXEC_OUTPUT_MAX);
274 assert(ident);
275 assert(nfd >= 0);
276
277 fd = socket(AF_UNIX, SOCK_STREAM, 0);
278 if (fd < 0)
279 return -errno;
280
281 r = connect_journal_socket(fd, uid, gid);
282 if (r < 0)
283 return r;
284
285 if (shutdown(fd, SHUT_RD) < 0) {
286 safe_close(fd);
287 return -errno;
288 }
289
290 fd_inc_sndbuf(fd, SNDBUF_SIZE);
291
292 dprintf(fd,
293 "%s\n"
294 "%s\n"
295 "%i\n"
296 "%i\n"
297 "%i\n"
298 "%i\n"
299 "%i\n",
300 context->syslog_identifier ? context->syslog_identifier : ident,
301 unit_id,
302 context->syslog_priority,
303 !!context->syslog_level_prefix,
304 output == EXEC_OUTPUT_SYSLOG || output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
305 output == EXEC_OUTPUT_KMSG || output == EXEC_OUTPUT_KMSG_AND_CONSOLE,
306 is_terminal_output(output));
307
308 if (fd != nfd) {
309 r = dup2(fd, nfd) < 0 ? -errno : nfd;
310 safe_close(fd);
311 } else
312 r = nfd;
313
314 return r;
315 }
316 static int open_terminal_as(const char *path, mode_t mode, int nfd) {
317 int fd, r;
318
319 assert(path);
320 assert(nfd >= 0);
321
322 fd = open_terminal(path, mode | O_NOCTTY);
323 if (fd < 0)
324 return fd;
325
326 if (fd != nfd) {
327 r = dup2(fd, nfd) < 0 ? -errno : nfd;
328 safe_close(fd);
329 } else
330 r = nfd;
331
332 return r;
333 }
334
335 static bool is_terminal_input(ExecInput i) {
336 return
337 i == EXEC_INPUT_TTY ||
338 i == EXEC_INPUT_TTY_FORCE ||
339 i == EXEC_INPUT_TTY_FAIL;
340 }
341
342 static int fixup_input(ExecInput std_input, int socket_fd, bool apply_tty_stdin) {
343
344 if (is_terminal_input(std_input) && !apply_tty_stdin)
345 return EXEC_INPUT_NULL;
346
347 if (std_input == EXEC_INPUT_SOCKET && socket_fd < 0)
348 return EXEC_INPUT_NULL;
349
350 return std_input;
351 }
352
353 static int fixup_output(ExecOutput std_output, int socket_fd) {
354
355 if (std_output == EXEC_OUTPUT_SOCKET && socket_fd < 0)
356 return EXEC_OUTPUT_INHERIT;
357
358 return std_output;
359 }
360
361 static int setup_input(
362 const ExecContext *context,
363 const ExecParameters *params,
364 int socket_fd) {
365
366 ExecInput i;
367
368 assert(context);
369 assert(params);
370
371 if (params->stdin_fd >= 0) {
372 if (dup2(params->stdin_fd, STDIN_FILENO) < 0)
373 return -errno;
374
375 /* Try to make this the controlling tty, if it is a tty, and reset it */
376 (void) ioctl(STDIN_FILENO, TIOCSCTTY, context->std_input == EXEC_INPUT_TTY_FORCE);
377 (void) reset_terminal_fd(STDIN_FILENO, true);
378
379 return STDIN_FILENO;
380 }
381
382 i = fixup_input(context->std_input, socket_fd, params->apply_tty_stdin);
383
384 switch (i) {
385
386 case EXEC_INPUT_NULL:
387 return open_null_as(O_RDONLY, STDIN_FILENO);
388
389 case EXEC_INPUT_TTY:
390 case EXEC_INPUT_TTY_FORCE:
391 case EXEC_INPUT_TTY_FAIL: {
392 int fd, r;
393
394 fd = acquire_terminal(tty_path(context),
395 i == EXEC_INPUT_TTY_FAIL,
396 i == EXEC_INPUT_TTY_FORCE,
397 false,
398 USEC_INFINITY);
399 if (fd < 0)
400 return fd;
401
402 if (fd != STDIN_FILENO) {
403 r = dup2(fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
404 safe_close(fd);
405 } else
406 r = STDIN_FILENO;
407
408 return r;
409 }
410
411 case EXEC_INPUT_SOCKET:
412 return dup2(socket_fd, STDIN_FILENO) < 0 ? -errno : STDIN_FILENO;
413
414 default:
415 assert_not_reached("Unknown input type");
416 }
417 }
418
419 static int setup_output(
420 Unit *unit,
421 const ExecContext *context,
422 const ExecParameters *params,
423 int fileno,
424 int socket_fd,
425 const char *ident,
426 uid_t uid, gid_t gid) {
427
428 ExecOutput o;
429 ExecInput i;
430 int r;
431
432 assert(unit);
433 assert(context);
434 assert(params);
435 assert(ident);
436
437 if (fileno == STDOUT_FILENO && params->stdout_fd >= 0) {
438
439 if (dup2(params->stdout_fd, STDOUT_FILENO) < 0)
440 return -errno;
441
442 return STDOUT_FILENO;
443 }
444
445 if (fileno == STDERR_FILENO && params->stderr_fd >= 0) {
446 if (dup2(params->stderr_fd, STDERR_FILENO) < 0)
447 return -errno;
448
449 return STDERR_FILENO;
450 }
451
452 i = fixup_input(context->std_input, socket_fd, params->apply_tty_stdin);
453 o = fixup_output(context->std_output, socket_fd);
454
455 if (fileno == STDERR_FILENO) {
456 ExecOutput e;
457 e = fixup_output(context->std_error, socket_fd);
458
459 /* This expects the input and output are already set up */
460
461 /* Don't change the stderr file descriptor if we inherit all
462 * the way and are not on a tty */
463 if (e == EXEC_OUTPUT_INHERIT &&
464 o == EXEC_OUTPUT_INHERIT &&
465 i == EXEC_INPUT_NULL &&
466 !is_terminal_input(context->std_input) &&
467 getppid () != 1)
468 return fileno;
469
470 /* Duplicate from stdout if possible */
471 if (e == o || e == EXEC_OUTPUT_INHERIT)
472 return dup2(STDOUT_FILENO, fileno) < 0 ? -errno : fileno;
473
474 o = e;
475
476 } else if (o == EXEC_OUTPUT_INHERIT) {
477 /* If input got downgraded, inherit the original value */
478 if (i == EXEC_INPUT_NULL && is_terminal_input(context->std_input))
479 return open_terminal_as(tty_path(context), O_WRONLY, fileno);
480
481 /* If the input is connected to anything that's not a /dev/null, inherit that... */
482 if (i != EXEC_INPUT_NULL)
483 return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
484
485 /* If we are not started from PID 1 we just inherit STDOUT from our parent process. */
486 if (getppid() != 1)
487 return fileno;
488
489 /* We need to open /dev/null here anew, to get the right access mode. */
490 return open_null_as(O_WRONLY, fileno);
491 }
492
493 switch (o) {
494
495 case EXEC_OUTPUT_NULL:
496 return open_null_as(O_WRONLY, fileno);
497
498 case EXEC_OUTPUT_TTY:
499 if (is_terminal_input(i))
500 return dup2(STDIN_FILENO, fileno) < 0 ? -errno : fileno;
501
502 /* We don't reset the terminal if this is just about output */
503 return open_terminal_as(tty_path(context), O_WRONLY, fileno);
504
505 case EXEC_OUTPUT_SYSLOG:
506 case EXEC_OUTPUT_SYSLOG_AND_CONSOLE:
507 case EXEC_OUTPUT_KMSG:
508 case EXEC_OUTPUT_KMSG_AND_CONSOLE:
509 case EXEC_OUTPUT_JOURNAL:
510 case EXEC_OUTPUT_JOURNAL_AND_CONSOLE:
511 r = connect_logger_as(context, o, ident, unit->id, fileno, uid, gid);
512 if (r < 0) {
513 log_unit_error_errno(unit, r, "Failed to connect %s to the journal socket, ignoring: %m", fileno == STDOUT_FILENO ? "stdout" : "stderr");
514 r = open_null_as(O_WRONLY, fileno);
515 }
516 return r;
517
518 case EXEC_OUTPUT_SOCKET:
519 assert(socket_fd >= 0);
520 return dup2(socket_fd, fileno) < 0 ? -errno : fileno;
521
522 default:
523 assert_not_reached("Unknown error type");
524 }
525 }
526
527 static int chown_terminal(int fd, uid_t uid) {
528 struct stat st;
529
530 assert(fd >= 0);
531
532 /* This might fail. What matters are the results. */
533 (void) fchown(fd, uid, -1);
534 (void) fchmod(fd, TTY_MODE);
535
536 if (fstat(fd, &st) < 0)
537 return -errno;
538
539 if (st.st_uid != uid || (st.st_mode & 0777) != TTY_MODE)
540 return -EPERM;
541
542 return 0;
543 }
544
545 static int setup_confirm_stdio(int *_saved_stdin, int *_saved_stdout) {
546 _cleanup_close_ int fd = -1, saved_stdin = -1, saved_stdout = -1;
547 int r;
548
549 assert(_saved_stdin);
550 assert(_saved_stdout);
551
552 saved_stdin = fcntl(STDIN_FILENO, F_DUPFD, 3);
553 if (saved_stdin < 0)
554 return -errno;
555
556 saved_stdout = fcntl(STDOUT_FILENO, F_DUPFD, 3);
557 if (saved_stdout < 0)
558 return -errno;
559
560 fd = acquire_terminal(
561 "/dev/console",
562 false,
563 false,
564 false,
565 DEFAULT_CONFIRM_USEC);
566 if (fd < 0)
567 return fd;
568
569 r = chown_terminal(fd, getuid());
570 if (r < 0)
571 return r;
572
573 r = reset_terminal_fd(fd, true);
574 if (r < 0)
575 return r;
576
577 if (dup2(fd, STDIN_FILENO) < 0)
578 return -errno;
579
580 if (dup2(fd, STDOUT_FILENO) < 0)
581 return -errno;
582
583 if (fd >= 2)
584 safe_close(fd);
585 fd = -1;
586
587 *_saved_stdin = saved_stdin;
588 *_saved_stdout = saved_stdout;
589
590 saved_stdin = saved_stdout = -1;
591
592 return 0;
593 }
594
595 _printf_(1, 2) static int write_confirm_message(const char *format, ...) {
596 _cleanup_close_ int fd = -1;
597 va_list ap;
598
599 assert(format);
600
601 fd = open_terminal("/dev/console", O_WRONLY|O_NOCTTY|O_CLOEXEC);
602 if (fd < 0)
603 return fd;
604
605 va_start(ap, format);
606 vdprintf(fd, format, ap);
607 va_end(ap);
608
609 return 0;
610 }
611
612 static int restore_confirm_stdio(int *saved_stdin, int *saved_stdout) {
613 int r = 0;
614
615 assert(saved_stdin);
616 assert(saved_stdout);
617
618 release_terminal();
619
620 if (*saved_stdin >= 0)
621 if (dup2(*saved_stdin, STDIN_FILENO) < 0)
622 r = -errno;
623
624 if (*saved_stdout >= 0)
625 if (dup2(*saved_stdout, STDOUT_FILENO) < 0)
626 r = -errno;
627
628 *saved_stdin = safe_close(*saved_stdin);
629 *saved_stdout = safe_close(*saved_stdout);
630
631 return r;
632 }
633
634 static int ask_for_confirmation(char *response, char **argv) {
635 int saved_stdout = -1, saved_stdin = -1, r;
636 _cleanup_free_ char *line = NULL;
637
638 r = setup_confirm_stdio(&saved_stdin, &saved_stdout);
639 if (r < 0)
640 return r;
641
642 line = exec_command_line(argv);
643 if (!line)
644 return -ENOMEM;
645
646 r = ask_char(response, "yns", "Execute %s? [Yes, No, Skip] ", line);
647
648 restore_confirm_stdio(&saved_stdin, &saved_stdout);
649
650 return r;
651 }
652
653 static int enforce_groups(const ExecContext *context, const char *username, gid_t gid) {
654 bool keep_groups = false;
655 int r;
656
657 assert(context);
658
659 /* Lookup and set GID and supplementary group list. Here too
660 * we avoid NSS lookups for gid=0. */
661
662 if (context->group || username) {
663 /* First step, initialize groups from /etc/groups */
664 if (username && gid != 0) {
665 if (initgroups(username, gid) < 0)
666 return -errno;
667
668 keep_groups = true;
669 }
670
671 /* Second step, set our gids */
672 if (setresgid(gid, gid, gid) < 0)
673 return -errno;
674 }
675
676 if (context->supplementary_groups) {
677 int ngroups_max, k;
678 gid_t *gids;
679 char **i;
680
681 /* Final step, initialize any manually set supplementary groups */
682 assert_se((ngroups_max = (int) sysconf(_SC_NGROUPS_MAX)) > 0);
683
684 if (!(gids = new(gid_t, ngroups_max)))
685 return -ENOMEM;
686
687 if (keep_groups) {
688 k = getgroups(ngroups_max, gids);
689 if (k < 0) {
690 free(gids);
691 return -errno;
692 }
693 } else
694 k = 0;
695
696 STRV_FOREACH(i, context->supplementary_groups) {
697 const char *g;
698
699 if (k >= ngroups_max) {
700 free(gids);
701 return -E2BIG;
702 }
703
704 g = *i;
705 r = get_group_creds(&g, gids+k);
706 if (r < 0) {
707 free(gids);
708 return r;
709 }
710
711 k++;
712 }
713
714 if (setgroups(k, gids) < 0) {
715 free(gids);
716 return -errno;
717 }
718
719 free(gids);
720 }
721
722 return 0;
723 }
724
725 static int enforce_user(const ExecContext *context, uid_t uid) {
726 assert(context);
727
728 /* Sets (but doesn't lookup) the uid and make sure we keep the
729 * capabilities while doing so. */
730
731 if (context->capabilities) {
732 _cleanup_cap_free_ cap_t d = NULL;
733 static const cap_value_t bits[] = {
734 CAP_SETUID, /* Necessary so that we can run setresuid() below */
735 CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */
736 };
737
738 /* First step: If we need to keep capabilities but
739 * drop privileges we need to make sure we keep our
740 * caps, while we drop privileges. */
741 if (uid != 0) {
742 int sb = context->secure_bits | 1<<SECURE_KEEP_CAPS;
743
744 if (prctl(PR_GET_SECUREBITS) != sb)
745 if (prctl(PR_SET_SECUREBITS, sb) < 0)
746 return -errno;
747 }
748
749 /* Second step: set the capabilities. This will reduce
750 * the capabilities to the minimum we need. */
751
752 d = cap_dup(context->capabilities);
753 if (!d)
754 return -errno;
755
756 if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 ||
757 cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0)
758 return -errno;
759
760 if (cap_set_proc(d) < 0)
761 return -errno;
762 }
763
764 /* Third step: actually set the uids */
765 if (setresuid(uid, uid, uid) < 0)
766 return -errno;
767
768 /* At this point we should have all necessary capabilities but
769 are otherwise a normal user. However, the caps might got
770 corrupted due to the setresuid() so we need clean them up
771 later. This is done outside of this call. */
772
773 return 0;
774 }
775
776 #ifdef HAVE_PAM
777
778 static int null_conv(
779 int num_msg,
780 const struct pam_message **msg,
781 struct pam_response **resp,
782 void *appdata_ptr) {
783
784 /* We don't support conversations */
785
786 return PAM_CONV_ERR;
787 }
788
789 static int setup_pam(
790 const char *name,
791 const char *user,
792 uid_t uid,
793 const char *tty,
794 char ***pam_env,
795 int fds[], unsigned n_fds) {
796
797 static const struct pam_conv conv = {
798 .conv = null_conv,
799 .appdata_ptr = NULL
800 };
801
802 _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
803 pam_handle_t *handle = NULL;
804 sigset_t old_ss;
805 int pam_code = PAM_SUCCESS;
806 int err = 0;
807 char **e = NULL;
808 bool close_session = false;
809 pid_t pam_pid = 0, parent_pid;
810 int flags = 0;
811
812 assert(name);
813 assert(user);
814 assert(pam_env);
815
816 /* We set up PAM in the parent process, then fork. The child
817 * will then stay around until killed via PR_GET_PDEATHSIG or
818 * systemd via the cgroup logic. It will then remove the PAM
819 * session again. The parent process will exec() the actual
820 * daemon. We do things this way to ensure that the main PID
821 * of the daemon is the one we initially fork()ed. */
822
823 err = barrier_create(&barrier);
824 if (err < 0)
825 goto fail;
826
827 if (log_get_max_level() < LOG_DEBUG)
828 flags |= PAM_SILENT;
829
830 pam_code = pam_start(name, user, &conv, &handle);
831 if (pam_code != PAM_SUCCESS) {
832 handle = NULL;
833 goto fail;
834 }
835
836 if (tty) {
837 pam_code = pam_set_item(handle, PAM_TTY, tty);
838 if (pam_code != PAM_SUCCESS)
839 goto fail;
840 }
841
842 pam_code = pam_acct_mgmt(handle, flags);
843 if (pam_code != PAM_SUCCESS)
844 goto fail;
845
846 pam_code = pam_open_session(handle, flags);
847 if (pam_code != PAM_SUCCESS)
848 goto fail;
849
850 close_session = true;
851
852 e = pam_getenvlist(handle);
853 if (!e) {
854 pam_code = PAM_BUF_ERR;
855 goto fail;
856 }
857
858 /* Block SIGTERM, so that we know that it won't get lost in
859 * the child */
860
861 assert_se(sigprocmask_many(SIG_BLOCK, &old_ss, SIGTERM, -1) >= 0);
862
863 parent_pid = getpid();
864
865 pam_pid = fork();
866 if (pam_pid < 0)
867 goto fail;
868
869 if (pam_pid == 0) {
870 int sig;
871 int r = EXIT_PAM;
872
873 /* The child's job is to reset the PAM session on
874 * termination */
875 barrier_set_role(&barrier, BARRIER_CHILD);
876
877 /* This string must fit in 10 chars (i.e. the length
878 * of "/sbin/init"), to look pretty in /bin/ps */
879 rename_process("(sd-pam)");
880
881 /* Make sure we don't keep open the passed fds in this
882 child. We assume that otherwise only those fds are
883 open here that have been opened by PAM. */
884 close_many(fds, n_fds);
885
886 /* Drop privileges - we don't need any to pam_close_session
887 * and this will make PR_SET_PDEATHSIG work in most cases.
888 * If this fails, ignore the error - but expect sd-pam threads
889 * to fail to exit normally */
890 if (setresuid(uid, uid, uid) < 0)
891 log_error_errno(r, "Error: Failed to setresuid() in sd-pam: %m");
892
893 (void) ignore_signals(SIGPIPE, -1);
894
895 /* Wait until our parent died. This will only work if
896 * the above setresuid() succeeds, otherwise the kernel
897 * will not allow unprivileged parents kill their privileged
898 * children this way. We rely on the control groups kill logic
899 * to do the rest for us. */
900 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
901 goto child_finish;
902
903 /* Tell the parent that our setup is done. This is especially
904 * important regarding dropping privileges. Otherwise, unit
905 * setup might race against our setresuid(2) call. */
906 barrier_place(&barrier);
907
908 /* Check if our parent process might already have
909 * died? */
910 if (getppid() == parent_pid) {
911 sigset_t ss;
912
913 assert_se(sigemptyset(&ss) >= 0);
914 assert_se(sigaddset(&ss, SIGTERM) >= 0);
915
916 for (;;) {
917 if (sigwait(&ss, &sig) < 0) {
918 if (errno == EINTR)
919 continue;
920
921 goto child_finish;
922 }
923
924 assert(sig == SIGTERM);
925 break;
926 }
927 }
928
929 /* If our parent died we'll end the session */
930 if (getppid() != parent_pid) {
931 pam_code = pam_close_session(handle, flags);
932 if (pam_code != PAM_SUCCESS)
933 goto child_finish;
934 }
935
936 r = 0;
937
938 child_finish:
939 pam_end(handle, pam_code | flags);
940 _exit(r);
941 }
942
943 barrier_set_role(&barrier, BARRIER_PARENT);
944
945 /* If the child was forked off successfully it will do all the
946 * cleanups, so forget about the handle here. */
947 handle = NULL;
948
949 /* Unblock SIGTERM again in the parent */
950 assert_se(sigprocmask(SIG_SETMASK, &old_ss, NULL) >= 0);
951
952 /* We close the log explicitly here, since the PAM modules
953 * might have opened it, but we don't want this fd around. */
954 closelog();
955
956 /* Synchronously wait for the child to initialize. We don't care for
957 * errors as we cannot recover. However, warn loudly if it happens. */
958 if (!barrier_place_and_sync(&barrier))
959 log_error("PAM initialization failed");
960
961 *pam_env = e;
962 e = NULL;
963
964 return 0;
965
966 fail:
967 if (pam_code != PAM_SUCCESS) {
968 log_error("PAM failed: %s", pam_strerror(handle, pam_code));
969 err = -EPERM; /* PAM errors do not map to errno */
970 } else {
971 err = log_error_errno(err < 0 ? err : errno, "PAM failed: %m");
972 }
973
974 if (handle) {
975 if (close_session)
976 pam_code = pam_close_session(handle, flags);
977
978 pam_end(handle, pam_code | flags);
979 }
980
981 strv_free(e);
982
983 closelog();
984
985 if (pam_pid > 1) {
986 kill(pam_pid, SIGTERM);
987 kill(pam_pid, SIGCONT);
988 }
989
990 return err;
991 }
992 #endif
993
994 static void rename_process_from_path(const char *path) {
995 char process_name[11];
996 const char *p;
997 size_t l;
998
999 /* This resulting string must fit in 10 chars (i.e. the length
1000 * of "/sbin/init") to look pretty in /bin/ps */
1001
1002 p = basename(path);
1003 if (isempty(p)) {
1004 rename_process("(...)");
1005 return;
1006 }
1007
1008 l = strlen(p);
1009 if (l > 8) {
1010 /* The end of the process name is usually more
1011 * interesting, since the first bit might just be
1012 * "systemd-" */
1013 p = p + l - 8;
1014 l = 8;
1015 }
1016
1017 process_name[0] = '(';
1018 memcpy(process_name+1, p, l);
1019 process_name[1+l] = ')';
1020 process_name[1+l+1] = 0;
1021
1022 rename_process(process_name);
1023 }
1024
1025 #ifdef HAVE_SECCOMP
1026
1027 static int apply_seccomp(const ExecContext *c) {
1028 uint32_t negative_action, action;
1029 scmp_filter_ctx *seccomp;
1030 Iterator i;
1031 void *id;
1032 int r;
1033
1034 assert(c);
1035
1036 negative_action = c->syscall_errno == 0 ? SCMP_ACT_KILL : SCMP_ACT_ERRNO(c->syscall_errno);
1037
1038 seccomp = seccomp_init(c->syscall_whitelist ? negative_action : SCMP_ACT_ALLOW);
1039 if (!seccomp)
1040 return -ENOMEM;
1041
1042 if (c->syscall_archs) {
1043
1044 SET_FOREACH(id, c->syscall_archs, i) {
1045 r = seccomp_arch_add(seccomp, PTR_TO_UINT32(id) - 1);
1046 if (r == -EEXIST)
1047 continue;
1048 if (r < 0)
1049 goto finish;
1050 }
1051
1052 } else {
1053 r = seccomp_add_secondary_archs(seccomp);
1054 if (r < 0)
1055 goto finish;
1056 }
1057
1058 action = c->syscall_whitelist ? SCMP_ACT_ALLOW : negative_action;
1059 SET_FOREACH(id, c->syscall_filter, i) {
1060 r = seccomp_rule_add(seccomp, action, PTR_TO_INT(id) - 1, 0);
1061 if (r < 0)
1062 goto finish;
1063 }
1064
1065 r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
1066 if (r < 0)
1067 goto finish;
1068
1069 r = seccomp_load(seccomp);
1070
1071 finish:
1072 seccomp_release(seccomp);
1073 return r;
1074 }
1075
1076 static int apply_address_families(const ExecContext *c) {
1077 scmp_filter_ctx *seccomp;
1078 Iterator i;
1079 int r;
1080
1081 assert(c);
1082
1083 seccomp = seccomp_init(SCMP_ACT_ALLOW);
1084 if (!seccomp)
1085 return -ENOMEM;
1086
1087 r = seccomp_add_secondary_archs(seccomp);
1088 if (r < 0)
1089 goto finish;
1090
1091 if (c->address_families_whitelist) {
1092 int af, first = 0, last = 0;
1093 void *afp;
1094
1095 /* If this is a whitelist, we first block the address
1096 * families that are out of range and then everything
1097 * that is not in the set. First, we find the lowest
1098 * and highest address family in the set. */
1099
1100 SET_FOREACH(afp, c->address_families, i) {
1101 af = PTR_TO_INT(afp);
1102
1103 if (af <= 0 || af >= af_max())
1104 continue;
1105
1106 if (first == 0 || af < first)
1107 first = af;
1108
1109 if (last == 0 || af > last)
1110 last = af;
1111 }
1112
1113 assert((first == 0) == (last == 0));
1114
1115 if (first == 0) {
1116
1117 /* No entries in the valid range, block everything */
1118 r = seccomp_rule_add(
1119 seccomp,
1120 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1121 SCMP_SYS(socket),
1122 0);
1123 if (r < 0)
1124 goto finish;
1125
1126 } else {
1127
1128 /* Block everything below the first entry */
1129 r = seccomp_rule_add(
1130 seccomp,
1131 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1132 SCMP_SYS(socket),
1133 1,
1134 SCMP_A0(SCMP_CMP_LT, first));
1135 if (r < 0)
1136 goto finish;
1137
1138 /* Block everything above the last entry */
1139 r = seccomp_rule_add(
1140 seccomp,
1141 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1142 SCMP_SYS(socket),
1143 1,
1144 SCMP_A0(SCMP_CMP_GT, last));
1145 if (r < 0)
1146 goto finish;
1147
1148 /* Block everything between the first and last
1149 * entry */
1150 for (af = 1; af < af_max(); af++) {
1151
1152 if (set_contains(c->address_families, INT_TO_PTR(af)))
1153 continue;
1154
1155 r = seccomp_rule_add(
1156 seccomp,
1157 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1158 SCMP_SYS(socket),
1159 1,
1160 SCMP_A0(SCMP_CMP_EQ, af));
1161 if (r < 0)
1162 goto finish;
1163 }
1164 }
1165
1166 } else {
1167 void *af;
1168
1169 /* If this is a blacklist, then generate one rule for
1170 * each address family that are then combined in OR
1171 * checks. */
1172
1173 SET_FOREACH(af, c->address_families, i) {
1174
1175 r = seccomp_rule_add(
1176 seccomp,
1177 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1178 SCMP_SYS(socket),
1179 1,
1180 SCMP_A0(SCMP_CMP_EQ, PTR_TO_INT(af)));
1181 if (r < 0)
1182 goto finish;
1183 }
1184 }
1185
1186 r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
1187 if (r < 0)
1188 goto finish;
1189
1190 r = seccomp_load(seccomp);
1191
1192 finish:
1193 seccomp_release(seccomp);
1194 return r;
1195 }
1196
1197 #endif
1198
1199 static void do_idle_pipe_dance(int idle_pipe[4]) {
1200 assert(idle_pipe);
1201
1202
1203 idle_pipe[1] = safe_close(idle_pipe[1]);
1204 idle_pipe[2] = safe_close(idle_pipe[2]);
1205
1206 if (idle_pipe[0] >= 0) {
1207 int r;
1208
1209 r = fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
1210
1211 if (idle_pipe[3] >= 0 && r == 0 /* timeout */) {
1212 ssize_t n;
1213
1214 /* Signal systemd that we are bored and want to continue. */
1215 n = write(idle_pipe[3], "x", 1);
1216 if (n > 0)
1217 /* Wait for systemd to react to the signal above. */
1218 fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT2_USEC);
1219 }
1220
1221 idle_pipe[0] = safe_close(idle_pipe[0]);
1222
1223 }
1224
1225 idle_pipe[3] = safe_close(idle_pipe[3]);
1226 }
1227
1228 static int build_environment(
1229 const ExecContext *c,
1230 unsigned n_fds,
1231 char ** fd_names,
1232 usec_t watchdog_usec,
1233 const char *home,
1234 const char *username,
1235 const char *shell,
1236 char ***ret) {
1237
1238 _cleanup_strv_free_ char **our_env = NULL;
1239 unsigned n_env = 0;
1240 char *x;
1241
1242 assert(c);
1243 assert(ret);
1244
1245 our_env = new0(char*, 11);
1246 if (!our_env)
1247 return -ENOMEM;
1248
1249 if (n_fds > 0) {
1250 _cleanup_free_ char *joined = NULL;
1251
1252 if (asprintf(&x, "LISTEN_PID="PID_FMT, getpid()) < 0)
1253 return -ENOMEM;
1254 our_env[n_env++] = x;
1255
1256 if (asprintf(&x, "LISTEN_FDS=%u", n_fds) < 0)
1257 return -ENOMEM;
1258 our_env[n_env++] = x;
1259
1260 joined = strv_join(fd_names, ":");
1261 if (!joined)
1262 return -ENOMEM;
1263
1264 x = strjoin("LISTEN_FDNAMES=", joined, NULL);
1265 if (!x)
1266 return -ENOMEM;
1267 our_env[n_env++] = x;
1268 }
1269
1270 if (watchdog_usec > 0) {
1271 if (asprintf(&x, "WATCHDOG_PID="PID_FMT, getpid()) < 0)
1272 return -ENOMEM;
1273 our_env[n_env++] = x;
1274
1275 if (asprintf(&x, "WATCHDOG_USEC="USEC_FMT, watchdog_usec) < 0)
1276 return -ENOMEM;
1277 our_env[n_env++] = x;
1278 }
1279
1280 if (home) {
1281 x = strappend("HOME=", home);
1282 if (!x)
1283 return -ENOMEM;
1284 our_env[n_env++] = x;
1285 }
1286
1287 if (username) {
1288 x = strappend("LOGNAME=", username);
1289 if (!x)
1290 return -ENOMEM;
1291 our_env[n_env++] = x;
1292
1293 x = strappend("USER=", username);
1294 if (!x)
1295 return -ENOMEM;
1296 our_env[n_env++] = x;
1297 }
1298
1299 if (shell) {
1300 x = strappend("SHELL=", shell);
1301 if (!x)
1302 return -ENOMEM;
1303 our_env[n_env++] = x;
1304 }
1305
1306 if (is_terminal_input(c->std_input) ||
1307 c->std_output == EXEC_OUTPUT_TTY ||
1308 c->std_error == EXEC_OUTPUT_TTY ||
1309 c->tty_path) {
1310
1311 x = strdup(default_term_for_tty(tty_path(c)));
1312 if (!x)
1313 return -ENOMEM;
1314 our_env[n_env++] = x;
1315 }
1316
1317 our_env[n_env++] = NULL;
1318 assert(n_env <= 11);
1319
1320 *ret = our_env;
1321 our_env = NULL;
1322
1323 return 0;
1324 }
1325
1326 static bool exec_needs_mount_namespace(
1327 const ExecContext *context,
1328 const ExecParameters *params,
1329 ExecRuntime *runtime) {
1330
1331 assert(context);
1332 assert(params);
1333
1334 if (!strv_isempty(context->read_write_dirs) ||
1335 !strv_isempty(context->read_only_dirs) ||
1336 !strv_isempty(context->inaccessible_dirs))
1337 return true;
1338
1339 if (context->mount_flags != 0)
1340 return true;
1341
1342 if (context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir))
1343 return true;
1344
1345 if (params->bus_endpoint_path)
1346 return true;
1347
1348 if (context->private_devices ||
1349 context->protect_system != PROTECT_SYSTEM_NO ||
1350 context->protect_home != PROTECT_HOME_NO)
1351 return true;
1352
1353 return false;
1354 }
1355
1356 static int close_remaining_fds(
1357 const ExecParameters *params,
1358 ExecRuntime *runtime,
1359 int socket_fd,
1360 int *fds, unsigned n_fds) {
1361
1362 unsigned n_dont_close = 0;
1363 int dont_close[n_fds + 7];
1364
1365 assert(params);
1366
1367 if (params->stdin_fd >= 0)
1368 dont_close[n_dont_close++] = params->stdin_fd;
1369 if (params->stdout_fd >= 0)
1370 dont_close[n_dont_close++] = params->stdout_fd;
1371 if (params->stderr_fd >= 0)
1372 dont_close[n_dont_close++] = params->stderr_fd;
1373
1374 if (socket_fd >= 0)
1375 dont_close[n_dont_close++] = socket_fd;
1376 if (n_fds > 0) {
1377 memcpy(dont_close + n_dont_close, fds, sizeof(int) * n_fds);
1378 n_dont_close += n_fds;
1379 }
1380
1381 if (params->bus_endpoint_fd >= 0)
1382 dont_close[n_dont_close++] = params->bus_endpoint_fd;
1383
1384 if (runtime) {
1385 if (runtime->netns_storage_socket[0] >= 0)
1386 dont_close[n_dont_close++] = runtime->netns_storage_socket[0];
1387 if (runtime->netns_storage_socket[1] >= 0)
1388 dont_close[n_dont_close++] = runtime->netns_storage_socket[1];
1389 }
1390
1391 return close_all_fds(dont_close, n_dont_close);
1392 }
1393
1394 static int exec_child(
1395 Unit *unit,
1396 ExecCommand *command,
1397 const ExecContext *context,
1398 const ExecParameters *params,
1399 ExecRuntime *runtime,
1400 char **argv,
1401 int socket_fd,
1402 int *fds, unsigned n_fds,
1403 char **files_env,
1404 int *exit_status) {
1405
1406 _cleanup_strv_free_ char **our_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
1407 _cleanup_free_ char *mac_selinux_context_net = NULL;
1408 const char *username = NULL, *home = NULL, *shell = NULL, *wd;
1409 uid_t uid = UID_INVALID;
1410 gid_t gid = GID_INVALID;
1411 int i, r;
1412 bool needs_mount_namespace;
1413
1414 assert(unit);
1415 assert(command);
1416 assert(context);
1417 assert(params);
1418 assert(exit_status);
1419
1420 rename_process_from_path(command->path);
1421
1422 /* We reset exactly these signals, since they are the
1423 * only ones we set to SIG_IGN in the main daemon. All
1424 * others we leave untouched because we set them to
1425 * SIG_DFL or a valid handler initially, both of which
1426 * will be demoted to SIG_DFL. */
1427 (void) default_signals(SIGNALS_CRASH_HANDLER,
1428 SIGNALS_IGNORE, -1);
1429
1430 if (context->ignore_sigpipe)
1431 (void) ignore_signals(SIGPIPE, -1);
1432
1433 r = reset_signal_mask();
1434 if (r < 0) {
1435 *exit_status = EXIT_SIGNAL_MASK;
1436 return r;
1437 }
1438
1439 if (params->idle_pipe)
1440 do_idle_pipe_dance(params->idle_pipe);
1441
1442 /* Close sockets very early to make sure we don't
1443 * block init reexecution because it cannot bind its
1444 * sockets */
1445
1446 log_forget_fds();
1447
1448 r = close_remaining_fds(params, runtime, socket_fd, fds, n_fds);
1449 if (r < 0) {
1450 *exit_status = EXIT_FDS;
1451 return r;
1452 }
1453
1454 if (!context->same_pgrp)
1455 if (setsid() < 0) {
1456 *exit_status = EXIT_SETSID;
1457 return -errno;
1458 }
1459
1460 exec_context_tty_reset(context);
1461
1462 if (params->confirm_spawn) {
1463 char response;
1464
1465 r = ask_for_confirmation(&response, argv);
1466 if (r == -ETIMEDOUT)
1467 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1468 else if (r < 0)
1469 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r));
1470 else if (response == 's') {
1471 write_confirm_message("Skipping execution.\n");
1472 *exit_status = EXIT_CONFIRM;
1473 return -ECANCELED;
1474 } else if (response == 'n') {
1475 write_confirm_message("Failing execution.\n");
1476 *exit_status = 0;
1477 return 0;
1478 }
1479 }
1480
1481 if (context->user) {
1482 username = context->user;
1483 r = get_user_creds(&username, &uid, &gid, &home, &shell);
1484 if (r < 0) {
1485 *exit_status = EXIT_USER;
1486 return r;
1487 }
1488 }
1489
1490 if (context->group) {
1491 const char *g = context->group;
1492
1493 r = get_group_creds(&g, &gid);
1494 if (r < 0) {
1495 *exit_status = EXIT_GROUP;
1496 return r;
1497 }
1498 }
1499
1500
1501 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1502 * must sure to drop O_NONBLOCK */
1503 if (socket_fd >= 0)
1504 (void) fd_nonblock(socket_fd, false);
1505
1506 r = setup_input(context, params, socket_fd);
1507 if (r < 0) {
1508 *exit_status = EXIT_STDIN;
1509 return r;
1510 }
1511
1512 r = setup_output(unit, context, params, STDOUT_FILENO, socket_fd, basename(command->path), uid, gid);
1513 if (r < 0) {
1514 *exit_status = EXIT_STDOUT;
1515 return r;
1516 }
1517
1518 r = setup_output(unit, context, params, STDERR_FILENO, socket_fd, basename(command->path), uid, gid);
1519 if (r < 0) {
1520 *exit_status = EXIT_STDERR;
1521 return r;
1522 }
1523
1524 if (params->cgroup_path) {
1525 r = cg_attach_everywhere(params->cgroup_supported, params->cgroup_path, 0, NULL, NULL);
1526 if (r < 0) {
1527 *exit_status = EXIT_CGROUP;
1528 return r;
1529 }
1530 }
1531
1532 if (context->oom_score_adjust_set) {
1533 char t[DECIMAL_STR_MAX(context->oom_score_adjust)];
1534
1535 /* When we can't make this change due to EPERM, then
1536 * let's silently skip over it. User namespaces
1537 * prohibit write access to this file, and we
1538 * shouldn't trip up over that. */
1539
1540 sprintf(t, "%i", context->oom_score_adjust);
1541 r = write_string_file("/proc/self/oom_score_adj", t, 0);
1542 if (r == -EPERM || r == -EACCES) {
1543 log_open();
1544 log_unit_debug_errno(unit, r, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
1545 log_close();
1546 } else if (r < 0) {
1547 *exit_status = EXIT_OOM_ADJUST;
1548 return -errno;
1549 }
1550 }
1551
1552 if (context->nice_set)
1553 if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) {
1554 *exit_status = EXIT_NICE;
1555 return -errno;
1556 }
1557
1558 if (context->cpu_sched_set) {
1559 struct sched_param param = {
1560 .sched_priority = context->cpu_sched_priority,
1561 };
1562
1563 r = sched_setscheduler(0,
1564 context->cpu_sched_policy |
1565 (context->cpu_sched_reset_on_fork ?
1566 SCHED_RESET_ON_FORK : 0),
1567 &param);
1568 if (r < 0) {
1569 *exit_status = EXIT_SETSCHEDULER;
1570 return -errno;
1571 }
1572 }
1573
1574 if (context->cpuset)
1575 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
1576 *exit_status = EXIT_CPUAFFINITY;
1577 return -errno;
1578 }
1579
1580 if (context->ioprio_set)
1581 if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
1582 *exit_status = EXIT_IOPRIO;
1583 return -errno;
1584 }
1585
1586 if (context->timer_slack_nsec != NSEC_INFINITY)
1587 if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
1588 *exit_status = EXIT_TIMERSLACK;
1589 return -errno;
1590 }
1591
1592 if (context->personality != PERSONALITY_INVALID)
1593 if (personality(context->personality) < 0) {
1594 *exit_status = EXIT_PERSONALITY;
1595 return -errno;
1596 }
1597
1598 if (context->utmp_id)
1599 utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path,
1600 context->utmp_mode == EXEC_UTMP_INIT ? INIT_PROCESS :
1601 context->utmp_mode == EXEC_UTMP_LOGIN ? LOGIN_PROCESS :
1602 USER_PROCESS,
1603 username ? "root" : context->user);
1604
1605 if (context->user && is_terminal_input(context->std_input)) {
1606 r = chown_terminal(STDIN_FILENO, uid);
1607 if (r < 0) {
1608 *exit_status = EXIT_STDIN;
1609 return r;
1610 }
1611 }
1612
1613 if (params->bus_endpoint_fd >= 0 && context->bus_endpoint) {
1614 uid_t ep_uid = (uid == UID_INVALID) ? 0 : uid;
1615
1616 r = bus_kernel_set_endpoint_policy(params->bus_endpoint_fd, ep_uid, context->bus_endpoint);
1617 if (r < 0) {
1618 *exit_status = EXIT_BUS_ENDPOINT;
1619 return r;
1620 }
1621 }
1622
1623 /* If delegation is enabled we'll pass ownership of the cgroup
1624 * (but only in systemd's own controller hierarchy!) to the
1625 * user of the new process. */
1626 if (params->cgroup_path && context->user && params->cgroup_delegate) {
1627 r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0644, uid, gid);
1628 if (r < 0) {
1629 *exit_status = EXIT_CGROUP;
1630 return r;
1631 }
1632
1633
1634 r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0755, uid, gid);
1635 if (r < 0) {
1636 *exit_status = EXIT_CGROUP;
1637 return r;
1638 }
1639 }
1640
1641 if (!strv_isempty(context->runtime_directory) && params->runtime_prefix) {
1642 char **rt;
1643
1644 STRV_FOREACH(rt, context->runtime_directory) {
1645 _cleanup_free_ char *p;
1646
1647 p = strjoin(params->runtime_prefix, "/", *rt, NULL);
1648 if (!p) {
1649 *exit_status = EXIT_RUNTIME_DIRECTORY;
1650 return -ENOMEM;
1651 }
1652
1653 r = mkdir_p_label(p, context->runtime_directory_mode);
1654 if (r < 0) {
1655 *exit_status = EXIT_RUNTIME_DIRECTORY;
1656 return r;
1657 }
1658
1659 r = chmod_and_chown(p, context->runtime_directory_mode, uid, gid);
1660 if (r < 0) {
1661 *exit_status = EXIT_RUNTIME_DIRECTORY;
1662 return r;
1663 }
1664 }
1665 }
1666
1667 umask(context->umask);
1668
1669 if (params->apply_permissions) {
1670 r = enforce_groups(context, username, gid);
1671 if (r < 0) {
1672 *exit_status = EXIT_GROUP;
1673 return r;
1674 }
1675 #ifdef HAVE_SMACK
1676 if (context->smack_process_label) {
1677 r = mac_smack_apply_pid(0, context->smack_process_label);
1678 if (r < 0) {
1679 *exit_status = EXIT_SMACK_PROCESS_LABEL;
1680 return r;
1681 }
1682 }
1683 #ifdef SMACK_DEFAULT_PROCESS_LABEL
1684 else {
1685 _cleanup_free_ char *exec_label = NULL;
1686
1687 r = mac_smack_read(command->path, SMACK_ATTR_EXEC, &exec_label);
1688 if (r < 0 && r != -ENODATA && r != -EOPNOTSUPP) {
1689 *exit_status = EXIT_SMACK_PROCESS_LABEL;
1690 return r;
1691 }
1692
1693 r = mac_smack_apply_pid(0, exec_label ? : SMACK_DEFAULT_PROCESS_LABEL);
1694 if (r < 0) {
1695 *exit_status = EXIT_SMACK_PROCESS_LABEL;
1696 return r;
1697 }
1698 }
1699 #endif
1700 #endif
1701 #ifdef HAVE_PAM
1702 if (context->pam_name && username) {
1703 r = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
1704 if (r < 0) {
1705 *exit_status = EXIT_PAM;
1706 return r;
1707 }
1708 }
1709 #endif
1710 }
1711
1712 if (context->private_network && runtime && runtime->netns_storage_socket[0] >= 0) {
1713 r = setup_netns(runtime->netns_storage_socket);
1714 if (r < 0) {
1715 *exit_status = EXIT_NETWORK;
1716 return r;
1717 }
1718 }
1719
1720 needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime);
1721
1722 if (needs_mount_namespace) {
1723 char *tmp = NULL, *var = NULL;
1724
1725 /* The runtime struct only contains the parent
1726 * of the private /tmp, which is
1727 * non-accessible to world users. Inside of it
1728 * there's a /tmp that is sticky, and that's
1729 * the one we want to use here. */
1730
1731 if (context->private_tmp && runtime) {
1732 if (runtime->tmp_dir)
1733 tmp = strjoina(runtime->tmp_dir, "/tmp");
1734 if (runtime->var_tmp_dir)
1735 var = strjoina(runtime->var_tmp_dir, "/tmp");
1736 }
1737
1738 r = setup_namespace(
1739 params->apply_chroot ? context->root_directory : NULL,
1740 context->read_write_dirs,
1741 context->read_only_dirs,
1742 context->inaccessible_dirs,
1743 tmp,
1744 var,
1745 params->bus_endpoint_path,
1746 context->private_devices,
1747 context->protect_home,
1748 context->protect_system,
1749 context->mount_flags);
1750
1751 /* If we couldn't set up the namespace this is
1752 * probably due to a missing capability. In this case,
1753 * silently proceeed. */
1754 if (r == -EPERM || r == -EACCES) {
1755 log_open();
1756 log_unit_debug_errno(unit, r, "Failed to set up namespace, assuming containerized execution, ignoring: %m");
1757 log_close();
1758 } else if (r < 0) {
1759 *exit_status = EXIT_NAMESPACE;
1760 return r;
1761 }
1762 }
1763
1764 if (context->working_directory_home)
1765 wd = home;
1766 else if (context->working_directory)
1767 wd = context->working_directory;
1768 else
1769 wd = "/";
1770
1771 if (params->apply_chroot) {
1772 if (!needs_mount_namespace && context->root_directory)
1773 if (chroot(context->root_directory) < 0) {
1774 *exit_status = EXIT_CHROOT;
1775 return -errno;
1776 }
1777
1778 if (chdir(wd) < 0 &&
1779 !context->working_directory_missing_ok) {
1780 *exit_status = EXIT_CHDIR;
1781 return -errno;
1782 }
1783 } else {
1784 const char *d;
1785
1786 d = strjoina(strempty(context->root_directory), "/", strempty(wd));
1787 if (chdir(d) < 0 &&
1788 !context->working_directory_missing_ok) {
1789 *exit_status = EXIT_CHDIR;
1790 return -errno;
1791 }
1792 }
1793
1794 #ifdef HAVE_SELINUX
1795 if (params->apply_permissions && mac_selinux_use() && params->selinux_context_net && socket_fd >= 0) {
1796 r = mac_selinux_get_child_mls_label(socket_fd, command->path, context->selinux_context, &mac_selinux_context_net);
1797 if (r < 0) {
1798 *exit_status = EXIT_SELINUX_CONTEXT;
1799 return r;
1800 }
1801 }
1802 #endif
1803
1804 /* We repeat the fd closing here, to make sure that
1805 * nothing is leaked from the PAM modules. Note that
1806 * we are more aggressive this time since socket_fd
1807 * and the netns fds we don't need anymore. The custom
1808 * endpoint fd was needed to upload the policy and can
1809 * now be closed as well. */
1810 r = close_all_fds(fds, n_fds);
1811 if (r >= 0)
1812 r = shift_fds(fds, n_fds);
1813 if (r >= 0)
1814 r = flags_fds(fds, n_fds, context->non_blocking);
1815 if (r < 0) {
1816 *exit_status = EXIT_FDS;
1817 return r;
1818 }
1819
1820 if (params->apply_permissions) {
1821
1822 for (i = 0; i < _RLIMIT_MAX; i++) {
1823 if (!context->rlimit[i])
1824 continue;
1825
1826 if (setrlimit_closest(i, context->rlimit[i]) < 0) {
1827 *exit_status = EXIT_LIMITS;
1828 return -errno;
1829 }
1830 }
1831
1832 if (context->capability_bounding_set_drop) {
1833 r = capability_bounding_set_drop(context->capability_bounding_set_drop, false);
1834 if (r < 0) {
1835 *exit_status = EXIT_CAPABILITIES;
1836 return r;
1837 }
1838 }
1839
1840 if (context->user) {
1841 r = enforce_user(context, uid);
1842 if (r < 0) {
1843 *exit_status = EXIT_USER;
1844 return r;
1845 }
1846 }
1847
1848 /* PR_GET_SECUREBITS is not privileged, while
1849 * PR_SET_SECUREBITS is. So to suppress
1850 * potential EPERMs we'll try not to call
1851 * PR_SET_SECUREBITS unless necessary. */
1852 if (prctl(PR_GET_SECUREBITS) != context->secure_bits)
1853 if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) {
1854 *exit_status = EXIT_SECUREBITS;
1855 return -errno;
1856 }
1857
1858 if (context->capabilities)
1859 if (cap_set_proc(context->capabilities) < 0) {
1860 *exit_status = EXIT_CAPABILITIES;
1861 return -errno;
1862 }
1863
1864 if (context->no_new_privileges)
1865 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
1866 *exit_status = EXIT_NO_NEW_PRIVILEGES;
1867 return -errno;
1868 }
1869
1870 #ifdef HAVE_SECCOMP
1871 if (context->address_families_whitelist ||
1872 !set_isempty(context->address_families)) {
1873 r = apply_address_families(context);
1874 if (r < 0) {
1875 *exit_status = EXIT_ADDRESS_FAMILIES;
1876 return r;
1877 }
1878 }
1879
1880 if (context->syscall_whitelist ||
1881 !set_isempty(context->syscall_filter) ||
1882 !set_isempty(context->syscall_archs)) {
1883 r = apply_seccomp(context);
1884 if (r < 0) {
1885 *exit_status = EXIT_SECCOMP;
1886 return r;
1887 }
1888 }
1889 #endif
1890
1891 #ifdef HAVE_SELINUX
1892 if (mac_selinux_use()) {
1893 char *exec_context = mac_selinux_context_net ?: context->selinux_context;
1894
1895 if (exec_context) {
1896 r = setexeccon(exec_context);
1897 if (r < 0) {
1898 *exit_status = EXIT_SELINUX_CONTEXT;
1899 return r;
1900 }
1901 }
1902 }
1903 #endif
1904
1905 #ifdef HAVE_APPARMOR
1906 if (context->apparmor_profile && mac_apparmor_use()) {
1907 r = aa_change_onexec(context->apparmor_profile);
1908 if (r < 0 && !context->apparmor_profile_ignore) {
1909 *exit_status = EXIT_APPARMOR_PROFILE;
1910 return -errno;
1911 }
1912 }
1913 #endif
1914 }
1915
1916 r = build_environment(context, n_fds, params->fd_names, params->watchdog_usec, home, username, shell, &our_env);
1917 if (r < 0) {
1918 *exit_status = EXIT_MEMORY;
1919 return r;
1920 }
1921
1922 final_env = strv_env_merge(5,
1923 params->environment,
1924 our_env,
1925 context->environment,
1926 files_env,
1927 pam_env,
1928 NULL);
1929 if (!final_env) {
1930 *exit_status = EXIT_MEMORY;
1931 return -ENOMEM;
1932 }
1933
1934 final_argv = replace_env_argv(argv, final_env);
1935 if (!final_argv) {
1936 *exit_status = EXIT_MEMORY;
1937 return -ENOMEM;
1938 }
1939
1940 final_env = strv_env_clean(final_env);
1941
1942 if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) {
1943 _cleanup_free_ char *line;
1944
1945 line = exec_command_line(final_argv);
1946 if (line) {
1947 log_open();
1948 log_struct(LOG_DEBUG,
1949 LOG_UNIT_ID(unit),
1950 "EXECUTABLE=%s", command->path,
1951 LOG_UNIT_MESSAGE(unit, "Executing: %s", line),
1952 NULL);
1953 log_close();
1954 }
1955 }
1956
1957 execve(command->path, final_argv, final_env);
1958 *exit_status = EXIT_EXEC;
1959 return -errno;
1960 }
1961
1962 int exec_spawn(Unit *unit,
1963 ExecCommand *command,
1964 const ExecContext *context,
1965 const ExecParameters *params,
1966 ExecRuntime *runtime,
1967 pid_t *ret) {
1968
1969 _cleanup_strv_free_ char **files_env = NULL;
1970 int *fds = NULL; unsigned n_fds = 0;
1971 _cleanup_free_ char *line = NULL;
1972 int socket_fd, r;
1973 char **argv;
1974 pid_t pid;
1975
1976 assert(unit);
1977 assert(command);
1978 assert(context);
1979 assert(ret);
1980 assert(params);
1981 assert(params->fds || params->n_fds <= 0);
1982
1983 if (context->std_input == EXEC_INPUT_SOCKET ||
1984 context->std_output == EXEC_OUTPUT_SOCKET ||
1985 context->std_error == EXEC_OUTPUT_SOCKET) {
1986
1987 if (params->n_fds != 1) {
1988 log_unit_error(unit, "Got more than one socket.");
1989 return -EINVAL;
1990 }
1991
1992 socket_fd = params->fds[0];
1993 } else {
1994 socket_fd = -1;
1995 fds = params->fds;
1996 n_fds = params->n_fds;
1997 }
1998
1999 r = exec_context_load_environment(unit, context, &files_env);
2000 if (r < 0)
2001 return log_unit_error_errno(unit, r, "Failed to load environment files: %m");
2002
2003 argv = params->argv ?: command->argv;
2004 line = exec_command_line(argv);
2005 if (!line)
2006 return log_oom();
2007
2008 log_struct(LOG_DEBUG,
2009 LOG_UNIT_ID(unit),
2010 LOG_UNIT_MESSAGE(unit, "About to execute: %s", line),
2011 "EXECUTABLE=%s", command->path,
2012 NULL);
2013 pid = fork();
2014 if (pid < 0)
2015 return log_unit_error_errno(unit, r, "Failed to fork: %m");
2016
2017 if (pid == 0) {
2018 int exit_status;
2019
2020 r = exec_child(unit,
2021 command,
2022 context,
2023 params,
2024 runtime,
2025 argv,
2026 socket_fd,
2027 fds, n_fds,
2028 files_env,
2029 &exit_status);
2030 if (r < 0) {
2031 log_open();
2032 log_struct_errno(LOG_ERR, r,
2033 LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED),
2034 LOG_UNIT_ID(unit),
2035 LOG_UNIT_MESSAGE(unit, "Failed at step %s spawning %s: %m",
2036 exit_status_to_string(exit_status, EXIT_STATUS_SYSTEMD),
2037 command->path),
2038 "EXECUTABLE=%s", command->path,
2039 NULL);
2040 }
2041
2042 _exit(exit_status);
2043 }
2044
2045 log_unit_debug(unit, "Forked %s as "PID_FMT, command->path, pid);
2046
2047 /* We add the new process to the cgroup both in the child (so
2048 * that we can be sure that no user code is ever executed
2049 * outside of the cgroup) and in the parent (so that we can be
2050 * sure that when we kill the cgroup the process will be
2051 * killed too). */
2052 if (params->cgroup_path)
2053 (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, pid);
2054
2055 exec_status_start(&command->exec_status, pid);
2056
2057 *ret = pid;
2058 return 0;
2059 }
2060
2061 void exec_context_init(ExecContext *c) {
2062 assert(c);
2063
2064 c->umask = 0022;
2065 c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0);
2066 c->cpu_sched_policy = SCHED_OTHER;
2067 c->syslog_priority = LOG_DAEMON|LOG_INFO;
2068 c->syslog_level_prefix = true;
2069 c->ignore_sigpipe = true;
2070 c->timer_slack_nsec = NSEC_INFINITY;
2071 c->personality = PERSONALITY_INVALID;
2072 c->runtime_directory_mode = 0755;
2073 }
2074
2075 void exec_context_done(ExecContext *c) {
2076 unsigned l;
2077
2078 assert(c);
2079
2080 c->environment = strv_free(c->environment);
2081 c->environment_files = strv_free(c->environment_files);
2082
2083 for (l = 0; l < ELEMENTSOF(c->rlimit); l++)
2084 c->rlimit[l] = mfree(c->rlimit[l]);
2085
2086 c->working_directory = mfree(c->working_directory);
2087 c->root_directory = mfree(c->root_directory);
2088 c->tty_path = mfree(c->tty_path);
2089 c->syslog_identifier = mfree(c->syslog_identifier);
2090 c->user = mfree(c->user);
2091 c->group = mfree(c->group);
2092
2093 c->supplementary_groups = strv_free(c->supplementary_groups);
2094
2095 c->pam_name = mfree(c->pam_name);
2096
2097 if (c->capabilities) {
2098 cap_free(c->capabilities);
2099 c->capabilities = NULL;
2100 }
2101
2102 c->read_only_dirs = strv_free(c->read_only_dirs);
2103 c->read_write_dirs = strv_free(c->read_write_dirs);
2104 c->inaccessible_dirs = strv_free(c->inaccessible_dirs);
2105
2106 if (c->cpuset)
2107 CPU_FREE(c->cpuset);
2108
2109 c->utmp_id = mfree(c->utmp_id);
2110 c->selinux_context = mfree(c->selinux_context);
2111 c->apparmor_profile = mfree(c->apparmor_profile);
2112
2113 c->syscall_filter = set_free(c->syscall_filter);
2114 c->syscall_archs = set_free(c->syscall_archs);
2115 c->address_families = set_free(c->address_families);
2116
2117 c->runtime_directory = strv_free(c->runtime_directory);
2118
2119 bus_endpoint_free(c->bus_endpoint);
2120 c->bus_endpoint = NULL;
2121 }
2122
2123 int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_prefix) {
2124 char **i;
2125
2126 assert(c);
2127
2128 if (!runtime_prefix)
2129 return 0;
2130
2131 STRV_FOREACH(i, c->runtime_directory) {
2132 _cleanup_free_ char *p;
2133
2134 p = strjoin(runtime_prefix, "/", *i, NULL);
2135 if (!p)
2136 return -ENOMEM;
2137
2138 /* We execute this synchronously, since we need to be
2139 * sure this is gone when we start the service
2140 * next. */
2141 (void) rm_rf(p, REMOVE_ROOT);
2142 }
2143
2144 return 0;
2145 }
2146
2147 void exec_command_done(ExecCommand *c) {
2148 assert(c);
2149
2150 c->path = mfree(c->path);
2151
2152 c->argv = strv_free(c->argv);
2153 }
2154
2155 void exec_command_done_array(ExecCommand *c, unsigned n) {
2156 unsigned i;
2157
2158 for (i = 0; i < n; i++)
2159 exec_command_done(c+i);
2160 }
2161
2162 ExecCommand* exec_command_free_list(ExecCommand *c) {
2163 ExecCommand *i;
2164
2165 while ((i = c)) {
2166 LIST_REMOVE(command, c, i);
2167 exec_command_done(i);
2168 free(i);
2169 }
2170
2171 return NULL;
2172 }
2173
2174 void exec_command_free_array(ExecCommand **c, unsigned n) {
2175 unsigned i;
2176
2177 for (i = 0; i < n; i++)
2178 c[i] = exec_command_free_list(c[i]);
2179 }
2180
2181 typedef struct InvalidEnvInfo {
2182 Unit *unit;
2183 const char *path;
2184 } InvalidEnvInfo;
2185
2186 static void invalid_env(const char *p, void *userdata) {
2187 InvalidEnvInfo *info = userdata;
2188
2189 log_unit_error(info->unit, "Ignoring invalid environment assignment '%s': %s", p, info->path);
2190 }
2191
2192 int exec_context_load_environment(Unit *unit, const ExecContext *c, char ***l) {
2193 char **i, **r = NULL;
2194
2195 assert(c);
2196 assert(l);
2197
2198 STRV_FOREACH(i, c->environment_files) {
2199 char *fn;
2200 int k;
2201 bool ignore = false;
2202 char **p;
2203 _cleanup_globfree_ glob_t pglob = {};
2204 int count, n;
2205
2206 fn = *i;
2207
2208 if (fn[0] == '-') {
2209 ignore = true;
2210 fn ++;
2211 }
2212
2213 if (!path_is_absolute(fn)) {
2214 if (ignore)
2215 continue;
2216
2217 strv_free(r);
2218 return -EINVAL;
2219 }
2220
2221 /* Filename supports globbing, take all matching files */
2222 errno = 0;
2223 if (glob(fn, 0, NULL, &pglob) != 0) {
2224 if (ignore)
2225 continue;
2226
2227 strv_free(r);
2228 return errno ? -errno : -EINVAL;
2229 }
2230 count = pglob.gl_pathc;
2231 if (count == 0) {
2232 if (ignore)
2233 continue;
2234
2235 strv_free(r);
2236 return -EINVAL;
2237 }
2238 for (n = 0; n < count; n++) {
2239 k = load_env_file(NULL, pglob.gl_pathv[n], NULL, &p);
2240 if (k < 0) {
2241 if (ignore)
2242 continue;
2243
2244 strv_free(r);
2245 return k;
2246 }
2247 /* Log invalid environment variables with filename */
2248 if (p) {
2249 InvalidEnvInfo info = {
2250 .unit = unit,
2251 .path = pglob.gl_pathv[n]
2252 };
2253
2254 p = strv_env_clean_with_callback(p, invalid_env, &info);
2255 }
2256
2257 if (r == NULL)
2258 r = p;
2259 else {
2260 char **m;
2261
2262 m = strv_env_merge(2, r, p);
2263 strv_free(r);
2264 strv_free(p);
2265 if (!m)
2266 return -ENOMEM;
2267
2268 r = m;
2269 }
2270 }
2271 }
2272
2273 *l = r;
2274
2275 return 0;
2276 }
2277
2278 static bool tty_may_match_dev_console(const char *tty) {
2279 _cleanup_free_ char *active = NULL;
2280 char *console;
2281
2282 if (startswith(tty, "/dev/"))
2283 tty += 5;
2284
2285 /* trivial identity? */
2286 if (streq(tty, "console"))
2287 return true;
2288
2289 console = resolve_dev_console(&active);
2290 /* if we could not resolve, assume it may */
2291 if (!console)
2292 return true;
2293
2294 /* "tty0" means the active VC, so it may be the same sometimes */
2295 return streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty));
2296 }
2297
2298 bool exec_context_may_touch_console(ExecContext *ec) {
2299 return (ec->tty_reset || ec->tty_vhangup || ec->tty_vt_disallocate ||
2300 is_terminal_input(ec->std_input) ||
2301 is_terminal_output(ec->std_output) ||
2302 is_terminal_output(ec->std_error)) &&
2303 tty_may_match_dev_console(tty_path(ec));
2304 }
2305
2306 static void strv_fprintf(FILE *f, char **l) {
2307 char **g;
2308
2309 assert(f);
2310
2311 STRV_FOREACH(g, l)
2312 fprintf(f, " %s", *g);
2313 }
2314
2315 void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
2316 char **e, **d;
2317 unsigned i;
2318
2319 assert(c);
2320 assert(f);
2321
2322 prefix = strempty(prefix);
2323
2324 fprintf(f,
2325 "%sUMask: %04o\n"
2326 "%sWorkingDirectory: %s\n"
2327 "%sRootDirectory: %s\n"
2328 "%sNonBlocking: %s\n"
2329 "%sPrivateTmp: %s\n"
2330 "%sPrivateNetwork: %s\n"
2331 "%sPrivateDevices: %s\n"
2332 "%sProtectHome: %s\n"
2333 "%sProtectSystem: %s\n"
2334 "%sIgnoreSIGPIPE: %s\n",
2335 prefix, c->umask,
2336 prefix, c->working_directory ? c->working_directory : "/",
2337 prefix, c->root_directory ? c->root_directory : "/",
2338 prefix, yes_no(c->non_blocking),
2339 prefix, yes_no(c->private_tmp),
2340 prefix, yes_no(c->private_network),
2341 prefix, yes_no(c->private_devices),
2342 prefix, protect_home_to_string(c->protect_home),
2343 prefix, protect_system_to_string(c->protect_system),
2344 prefix, yes_no(c->ignore_sigpipe));
2345
2346 STRV_FOREACH(e, c->environment)
2347 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
2348
2349 STRV_FOREACH(e, c->environment_files)
2350 fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
2351
2352 fprintf(f, "%sRuntimeDirectoryMode: %04o\n", prefix, c->runtime_directory_mode);
2353
2354 STRV_FOREACH(d, c->runtime_directory)
2355 fprintf(f, "%sRuntimeDirectory: %s\n", prefix, *d);
2356
2357 if (c->nice_set)
2358 fprintf(f,
2359 "%sNice: %i\n",
2360 prefix, c->nice);
2361
2362 if (c->oom_score_adjust_set)
2363 fprintf(f,
2364 "%sOOMScoreAdjust: %i\n",
2365 prefix, c->oom_score_adjust);
2366
2367 for (i = 0; i < RLIM_NLIMITS; i++)
2368 if (c->rlimit[i])
2369 fprintf(f, "%s%s: "RLIM_FMT"\n",
2370 prefix, rlimit_to_string(i), c->rlimit[i]->rlim_max);
2371
2372 if (c->ioprio_set) {
2373 _cleanup_free_ char *class_str = NULL;
2374
2375 ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str);
2376 fprintf(f,
2377 "%sIOSchedulingClass: %s\n"
2378 "%sIOPriority: %i\n",
2379 prefix, strna(class_str),
2380 prefix, (int) IOPRIO_PRIO_DATA(c->ioprio));
2381 }
2382
2383 if (c->cpu_sched_set) {
2384 _cleanup_free_ char *policy_str = NULL;
2385
2386 sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
2387 fprintf(f,
2388 "%sCPUSchedulingPolicy: %s\n"
2389 "%sCPUSchedulingPriority: %i\n"
2390 "%sCPUSchedulingResetOnFork: %s\n",
2391 prefix, strna(policy_str),
2392 prefix, c->cpu_sched_priority,
2393 prefix, yes_no(c->cpu_sched_reset_on_fork));
2394 }
2395
2396 if (c->cpuset) {
2397 fprintf(f, "%sCPUAffinity:", prefix);
2398 for (i = 0; i < c->cpuset_ncpus; i++)
2399 if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
2400 fprintf(f, " %u", i);
2401 fputs("\n", f);
2402 }
2403
2404 if (c->timer_slack_nsec != NSEC_INFINITY)
2405 fprintf(f, "%sTimerSlackNSec: "NSEC_FMT "\n", prefix, c->timer_slack_nsec);
2406
2407 fprintf(f,
2408 "%sStandardInput: %s\n"
2409 "%sStandardOutput: %s\n"
2410 "%sStandardError: %s\n",
2411 prefix, exec_input_to_string(c->std_input),
2412 prefix, exec_output_to_string(c->std_output),
2413 prefix, exec_output_to_string(c->std_error));
2414
2415 if (c->tty_path)
2416 fprintf(f,
2417 "%sTTYPath: %s\n"
2418 "%sTTYReset: %s\n"
2419 "%sTTYVHangup: %s\n"
2420 "%sTTYVTDisallocate: %s\n",
2421 prefix, c->tty_path,
2422 prefix, yes_no(c->tty_reset),
2423 prefix, yes_no(c->tty_vhangup),
2424 prefix, yes_no(c->tty_vt_disallocate));
2425
2426 if (c->std_output == EXEC_OUTPUT_SYSLOG ||
2427 c->std_output == EXEC_OUTPUT_KMSG ||
2428 c->std_output == EXEC_OUTPUT_JOURNAL ||
2429 c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
2430 c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
2431 c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE ||
2432 c->std_error == EXEC_OUTPUT_SYSLOG ||
2433 c->std_error == EXEC_OUTPUT_KMSG ||
2434 c->std_error == EXEC_OUTPUT_JOURNAL ||
2435 c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
2436 c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
2437 c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) {
2438
2439 _cleanup_free_ char *fac_str = NULL, *lvl_str = NULL;
2440
2441 log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str);
2442 log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str);
2443
2444 fprintf(f,
2445 "%sSyslogFacility: %s\n"
2446 "%sSyslogLevel: %s\n",
2447 prefix, strna(fac_str),
2448 prefix, strna(lvl_str));
2449 }
2450
2451 if (c->capabilities) {
2452 _cleanup_cap_free_charp_ char *t;
2453
2454 t = cap_to_text(c->capabilities, NULL);
2455 if (t)
2456 fprintf(f, "%sCapabilities: %s\n", prefix, t);
2457 }
2458
2459 if (c->secure_bits)
2460 fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n",
2461 prefix,
2462 (c->secure_bits & 1<<SECURE_KEEP_CAPS) ? " keep-caps" : "",
2463 (c->secure_bits & 1<<SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "",
2464 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "",
2465 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "",
2466 (c->secure_bits & 1<<SECURE_NOROOT) ? " noroot" : "",
2467 (c->secure_bits & 1<<SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
2468
2469 if (c->capability_bounding_set_drop) {
2470 unsigned long l;
2471 fprintf(f, "%sCapabilityBoundingSet:", prefix);
2472
2473 for (l = 0; l <= cap_last_cap(); l++)
2474 if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l)))
2475 fprintf(f, " %s", strna(capability_to_name(l)));
2476
2477 fputs("\n", f);
2478 }
2479
2480 if (c->user)
2481 fprintf(f, "%sUser: %s\n", prefix, c->user);
2482 if (c->group)
2483 fprintf(f, "%sGroup: %s\n", prefix, c->group);
2484
2485 if (strv_length(c->supplementary_groups) > 0) {
2486 fprintf(f, "%sSupplementaryGroups:", prefix);
2487 strv_fprintf(f, c->supplementary_groups);
2488 fputs("\n", f);
2489 }
2490
2491 if (c->pam_name)
2492 fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
2493
2494 if (strv_length(c->read_write_dirs) > 0) {
2495 fprintf(f, "%sReadWriteDirs:", prefix);
2496 strv_fprintf(f, c->read_write_dirs);
2497 fputs("\n", f);
2498 }
2499
2500 if (strv_length(c->read_only_dirs) > 0) {
2501 fprintf(f, "%sReadOnlyDirs:", prefix);
2502 strv_fprintf(f, c->read_only_dirs);
2503 fputs("\n", f);
2504 }
2505
2506 if (strv_length(c->inaccessible_dirs) > 0) {
2507 fprintf(f, "%sInaccessibleDirs:", prefix);
2508 strv_fprintf(f, c->inaccessible_dirs);
2509 fputs("\n", f);
2510 }
2511
2512 if (c->utmp_id)
2513 fprintf(f,
2514 "%sUtmpIdentifier: %s\n",
2515 prefix, c->utmp_id);
2516
2517 if (c->selinux_context)
2518 fprintf(f,
2519 "%sSELinuxContext: %s%s\n",
2520 prefix, c->selinux_context_ignore ? "-" : "", c->selinux_context);
2521
2522 if (c->personality != PERSONALITY_INVALID)
2523 fprintf(f,
2524 "%sPersonality: %s\n",
2525 prefix, strna(personality_to_string(c->personality)));
2526
2527 if (c->syscall_filter) {
2528 #ifdef HAVE_SECCOMP
2529 Iterator j;
2530 void *id;
2531 bool first = true;
2532 #endif
2533
2534 fprintf(f,
2535 "%sSystemCallFilter: ",
2536 prefix);
2537
2538 if (!c->syscall_whitelist)
2539 fputc('~', f);
2540
2541 #ifdef HAVE_SECCOMP
2542 SET_FOREACH(id, c->syscall_filter, j) {
2543 _cleanup_free_ char *name = NULL;
2544
2545 if (first)
2546 first = false;
2547 else
2548 fputc(' ', f);
2549
2550 name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
2551 fputs(strna(name), f);
2552 }
2553 #endif
2554
2555 fputc('\n', f);
2556 }
2557
2558 if (c->syscall_archs) {
2559 #ifdef HAVE_SECCOMP
2560 Iterator j;
2561 void *id;
2562 #endif
2563
2564 fprintf(f,
2565 "%sSystemCallArchitectures:",
2566 prefix);
2567
2568 #ifdef HAVE_SECCOMP
2569 SET_FOREACH(id, c->syscall_archs, j)
2570 fprintf(f, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id) - 1)));
2571 #endif
2572 fputc('\n', f);
2573 }
2574
2575 if (c->syscall_errno != 0)
2576 fprintf(f,
2577 "%sSystemCallErrorNumber: %s\n",
2578 prefix, strna(errno_to_name(c->syscall_errno)));
2579
2580 if (c->apparmor_profile)
2581 fprintf(f,
2582 "%sAppArmorProfile: %s%s\n",
2583 prefix, c->apparmor_profile_ignore ? "-" : "", c->apparmor_profile);
2584 }
2585
2586 bool exec_context_maintains_privileges(ExecContext *c) {
2587 assert(c);
2588
2589 /* Returns true if the process forked off would run run under
2590 * an unchanged UID or as root. */
2591
2592 if (!c->user)
2593 return true;
2594
2595 if (streq(c->user, "root") || streq(c->user, "0"))
2596 return true;
2597
2598 return false;
2599 }
2600
2601 void exec_status_start(ExecStatus *s, pid_t pid) {
2602 assert(s);
2603
2604 zero(*s);
2605 s->pid = pid;
2606 dual_timestamp_get(&s->start_timestamp);
2607 }
2608
2609 void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
2610 assert(s);
2611
2612 if (s->pid && s->pid != pid)
2613 zero(*s);
2614
2615 s->pid = pid;
2616 dual_timestamp_get(&s->exit_timestamp);
2617
2618 s->code = code;
2619 s->status = status;
2620
2621 if (context) {
2622 if (context->utmp_id)
2623 utmp_put_dead_process(context->utmp_id, pid, code, status);
2624
2625 exec_context_tty_reset(context);
2626 }
2627 }
2628
2629 void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
2630 char buf[FORMAT_TIMESTAMP_MAX];
2631
2632 assert(s);
2633 assert(f);
2634
2635 if (s->pid <= 0)
2636 return;
2637
2638 prefix = strempty(prefix);
2639
2640 fprintf(f,
2641 "%sPID: "PID_FMT"\n",
2642 prefix, s->pid);
2643
2644 if (s->start_timestamp.realtime > 0)
2645 fprintf(f,
2646 "%sStart Timestamp: %s\n",
2647 prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime));
2648
2649 if (s->exit_timestamp.realtime > 0)
2650 fprintf(f,
2651 "%sExit Timestamp: %s\n"
2652 "%sExit Code: %s\n"
2653 "%sExit Status: %i\n",
2654 prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime),
2655 prefix, sigchld_code_to_string(s->code),
2656 prefix, s->status);
2657 }
2658
2659 char *exec_command_line(char **argv) {
2660 size_t k;
2661 char *n, *p, **a;
2662 bool first = true;
2663
2664 assert(argv);
2665
2666 k = 1;
2667 STRV_FOREACH(a, argv)
2668 k += strlen(*a)+3;
2669
2670 if (!(n = new(char, k)))
2671 return NULL;
2672
2673 p = n;
2674 STRV_FOREACH(a, argv) {
2675
2676 if (!first)
2677 *(p++) = ' ';
2678 else
2679 first = false;
2680
2681 if (strpbrk(*a, WHITESPACE)) {
2682 *(p++) = '\'';
2683 p = stpcpy(p, *a);
2684 *(p++) = '\'';
2685 } else
2686 p = stpcpy(p, *a);
2687
2688 }
2689
2690 *p = 0;
2691
2692 /* FIXME: this doesn't really handle arguments that have
2693 * spaces and ticks in them */
2694
2695 return n;
2696 }
2697
2698 void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
2699 _cleanup_free_ char *cmd = NULL;
2700 const char *prefix2;
2701
2702 assert(c);
2703 assert(f);
2704
2705 prefix = strempty(prefix);
2706 prefix2 = strjoina(prefix, "\t");
2707
2708 cmd = exec_command_line(c->argv);
2709 fprintf(f,
2710 "%sCommand Line: %s\n",
2711 prefix, cmd ? cmd : strerror(ENOMEM));
2712
2713 exec_status_dump(&c->exec_status, f, prefix2);
2714 }
2715
2716 void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
2717 assert(f);
2718
2719 prefix = strempty(prefix);
2720
2721 LIST_FOREACH(command, c, c)
2722 exec_command_dump(c, f, prefix);
2723 }
2724
2725 void exec_command_append_list(ExecCommand **l, ExecCommand *e) {
2726 ExecCommand *end;
2727
2728 assert(l);
2729 assert(e);
2730
2731 if (*l) {
2732 /* It's kind of important, that we keep the order here */
2733 LIST_FIND_TAIL(command, *l, end);
2734 LIST_INSERT_AFTER(command, *l, end, e);
2735 } else
2736 *l = e;
2737 }
2738
2739 int exec_command_set(ExecCommand *c, const char *path, ...) {
2740 va_list ap;
2741 char **l, *p;
2742
2743 assert(c);
2744 assert(path);
2745
2746 va_start(ap, path);
2747 l = strv_new_ap(path, ap);
2748 va_end(ap);
2749
2750 if (!l)
2751 return -ENOMEM;
2752
2753 p = strdup(path);
2754 if (!p) {
2755 strv_free(l);
2756 return -ENOMEM;
2757 }
2758
2759 free(c->path);
2760 c->path = p;
2761
2762 strv_free(c->argv);
2763 c->argv = l;
2764
2765 return 0;
2766 }
2767
2768 int exec_command_append(ExecCommand *c, const char *path, ...) {
2769 _cleanup_strv_free_ char **l = NULL;
2770 va_list ap;
2771 int r;
2772
2773 assert(c);
2774 assert(path);
2775
2776 va_start(ap, path);
2777 l = strv_new_ap(path, ap);
2778 va_end(ap);
2779
2780 if (!l)
2781 return -ENOMEM;
2782
2783 r = strv_extend_strv(&c->argv, l, false);
2784 if (r < 0)
2785 return r;
2786
2787 return 0;
2788 }
2789
2790
2791 static int exec_runtime_allocate(ExecRuntime **rt) {
2792
2793 if (*rt)
2794 return 0;
2795
2796 *rt = new0(ExecRuntime, 1);
2797 if (!*rt)
2798 return -ENOMEM;
2799
2800 (*rt)->n_ref = 1;
2801 (*rt)->netns_storage_socket[0] = (*rt)->netns_storage_socket[1] = -1;
2802
2803 return 0;
2804 }
2805
2806 int exec_runtime_make(ExecRuntime **rt, ExecContext *c, const char *id) {
2807 int r;
2808
2809 assert(rt);
2810 assert(c);
2811 assert(id);
2812
2813 if (*rt)
2814 return 1;
2815
2816 if (!c->private_network && !c->private_tmp)
2817 return 0;
2818
2819 r = exec_runtime_allocate(rt);
2820 if (r < 0)
2821 return r;
2822
2823 if (c->private_network && (*rt)->netns_storage_socket[0] < 0) {
2824 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, (*rt)->netns_storage_socket) < 0)
2825 return -errno;
2826 }
2827
2828 if (c->private_tmp && !(*rt)->tmp_dir) {
2829 r = setup_tmp_dirs(id, &(*rt)->tmp_dir, &(*rt)->var_tmp_dir);
2830 if (r < 0)
2831 return r;
2832 }
2833
2834 return 1;
2835 }
2836
2837 ExecRuntime *exec_runtime_ref(ExecRuntime *r) {
2838 assert(r);
2839 assert(r->n_ref > 0);
2840
2841 r->n_ref++;
2842 return r;
2843 }
2844
2845 ExecRuntime *exec_runtime_unref(ExecRuntime *r) {
2846
2847 if (!r)
2848 return NULL;
2849
2850 assert(r->n_ref > 0);
2851
2852 r->n_ref--;
2853 if (r->n_ref > 0)
2854 return NULL;
2855
2856 free(r->tmp_dir);
2857 free(r->var_tmp_dir);
2858 safe_close_pair(r->netns_storage_socket);
2859 free(r);
2860
2861 return NULL;
2862 }
2863
2864 int exec_runtime_serialize(Unit *u, ExecRuntime *rt, FILE *f, FDSet *fds) {
2865 assert(u);
2866 assert(f);
2867 assert(fds);
2868
2869 if (!rt)
2870 return 0;
2871
2872 if (rt->tmp_dir)
2873 unit_serialize_item(u, f, "tmp-dir", rt->tmp_dir);
2874
2875 if (rt->var_tmp_dir)
2876 unit_serialize_item(u, f, "var-tmp-dir", rt->var_tmp_dir);
2877
2878 if (rt->netns_storage_socket[0] >= 0) {
2879 int copy;
2880
2881 copy = fdset_put_dup(fds, rt->netns_storage_socket[0]);
2882 if (copy < 0)
2883 return copy;
2884
2885 unit_serialize_item_format(u, f, "netns-socket-0", "%i", copy);
2886 }
2887
2888 if (rt->netns_storage_socket[1] >= 0) {
2889 int copy;
2890
2891 copy = fdset_put_dup(fds, rt->netns_storage_socket[1]);
2892 if (copy < 0)
2893 return copy;
2894
2895 unit_serialize_item_format(u, f, "netns-socket-1", "%i", copy);
2896 }
2897
2898 return 0;
2899 }
2900
2901 int exec_runtime_deserialize_item(Unit *u, ExecRuntime **rt, const char *key, const char *value, FDSet *fds) {
2902 int r;
2903
2904 assert(rt);
2905 assert(key);
2906 assert(value);
2907
2908 if (streq(key, "tmp-dir")) {
2909 char *copy;
2910
2911 r = exec_runtime_allocate(rt);
2912 if (r < 0)
2913 return log_oom();
2914
2915 copy = strdup(value);
2916 if (!copy)
2917 return log_oom();
2918
2919 free((*rt)->tmp_dir);
2920 (*rt)->tmp_dir = copy;
2921
2922 } else if (streq(key, "var-tmp-dir")) {
2923 char *copy;
2924
2925 r = exec_runtime_allocate(rt);
2926 if (r < 0)
2927 return log_oom();
2928
2929 copy = strdup(value);
2930 if (!copy)
2931 return log_oom();
2932
2933 free((*rt)->var_tmp_dir);
2934 (*rt)->var_tmp_dir = copy;
2935
2936 } else if (streq(key, "netns-socket-0")) {
2937 int fd;
2938
2939 r = exec_runtime_allocate(rt);
2940 if (r < 0)
2941 return log_oom();
2942
2943 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
2944 log_unit_debug(u, "Failed to parse netns socket value: %s", value);
2945 else {
2946 safe_close((*rt)->netns_storage_socket[0]);
2947 (*rt)->netns_storage_socket[0] = fdset_remove(fds, fd);
2948 }
2949 } else if (streq(key, "netns-socket-1")) {
2950 int fd;
2951
2952 r = exec_runtime_allocate(rt);
2953 if (r < 0)
2954 return log_oom();
2955
2956 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
2957 log_unit_debug(u, "Failed to parse netns socket value: %s", value);
2958 else {
2959 safe_close((*rt)->netns_storage_socket[1]);
2960 (*rt)->netns_storage_socket[1] = fdset_remove(fds, fd);
2961 }
2962 } else
2963 return 0;
2964
2965 return 1;
2966 }
2967
2968 static void *remove_tmpdir_thread(void *p) {
2969 _cleanup_free_ char *path = p;
2970
2971 (void) rm_rf(path, REMOVE_ROOT|REMOVE_PHYSICAL);
2972 return NULL;
2973 }
2974
2975 void exec_runtime_destroy(ExecRuntime *rt) {
2976 int r;
2977
2978 if (!rt)
2979 return;
2980
2981 /* If there are multiple users of this, let's leave the stuff around */
2982 if (rt->n_ref > 1)
2983 return;
2984
2985 if (rt->tmp_dir) {
2986 log_debug("Spawning thread to nuke %s", rt->tmp_dir);
2987
2988 r = asynchronous_job(remove_tmpdir_thread, rt->tmp_dir);
2989 if (r < 0) {
2990 log_warning_errno(r, "Failed to nuke %s: %m", rt->tmp_dir);
2991 free(rt->tmp_dir);
2992 }
2993
2994 rt->tmp_dir = NULL;
2995 }
2996
2997 if (rt->var_tmp_dir) {
2998 log_debug("Spawning thread to nuke %s", rt->var_tmp_dir);
2999
3000 r = asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir);
3001 if (r < 0) {
3002 log_warning_errno(r, "Failed to nuke %s: %m", rt->var_tmp_dir);
3003 free(rt->var_tmp_dir);
3004 }
3005
3006 rt->var_tmp_dir = NULL;
3007 }
3008
3009 safe_close_pair(rt->netns_storage_socket);
3010 }
3011
3012 static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
3013 [EXEC_INPUT_NULL] = "null",
3014 [EXEC_INPUT_TTY] = "tty",
3015 [EXEC_INPUT_TTY_FORCE] = "tty-force",
3016 [EXEC_INPUT_TTY_FAIL] = "tty-fail",
3017 [EXEC_INPUT_SOCKET] = "socket"
3018 };
3019
3020 DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
3021
3022 static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
3023 [EXEC_OUTPUT_INHERIT] = "inherit",
3024 [EXEC_OUTPUT_NULL] = "null",
3025 [EXEC_OUTPUT_TTY] = "tty",
3026 [EXEC_OUTPUT_SYSLOG] = "syslog",
3027 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console",
3028 [EXEC_OUTPUT_KMSG] = "kmsg",
3029 [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
3030 [EXEC_OUTPUT_JOURNAL] = "journal",
3031 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
3032 [EXEC_OUTPUT_SOCKET] = "socket"
3033 };
3034
3035 DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);
3036
3037 static const char* const exec_utmp_mode_table[_EXEC_UTMP_MODE_MAX] = {
3038 [EXEC_UTMP_INIT] = "init",
3039 [EXEC_UTMP_LOGIN] = "login",
3040 [EXEC_UTMP_USER] = "user",
3041 };
3042
3043 DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode, ExecUtmpMode);