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