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