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