]> git.ipfire.org Git - thirdparty/systemd.git/blame_incremental - src/core/execute.c
Merge pull request #2222 from snakeroot/eventsplat
[thirdparty/systemd.git] / src / core / execute.c
... / ...
CommitLineData
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
112static 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
157static 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
195static 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
208static 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
216static 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
234static 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
278static 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}
325static 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
344static 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
351static 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
362static 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
370static 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
428static 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
536static 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
554static 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
621static 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
643static 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
662static 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
734static 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 || context->capability_ambient_set != 0) {
741
742 /* First step: If we need to keep capabilities but
743 * drop privileges we need to make sure we keep our
744 * caps, while we drop privileges. */
745 if (uid != 0) {
746 int sb = context->secure_bits | 1<<SECURE_KEEP_CAPS;
747
748 if (prctl(PR_GET_SECUREBITS) != sb)
749 if (prctl(PR_SET_SECUREBITS, sb) < 0)
750 return -errno;
751 }
752
753 /* Second step: set the capabilities. This will reduce
754 * the capabilities to the minimum we need. */
755
756 if (context->capabilities) {
757 _cleanup_cap_free_ cap_t d = NULL;
758 static const cap_value_t bits[] = {
759 CAP_SETUID, /* Necessary so that we can run setresuid() below */
760 CAP_SETPCAP /* Necessary so that we can set PR_SET_SECUREBITS later on */
761 };
762
763 d = cap_dup(context->capabilities);
764 if (!d)
765 return -errno;
766
767 if (cap_set_flag(d, CAP_EFFECTIVE, ELEMENTSOF(bits), bits, CAP_SET) < 0 ||
768 cap_set_flag(d, CAP_PERMITTED, ELEMENTSOF(bits), bits, CAP_SET) < 0)
769 return -errno;
770
771 if (cap_set_proc(d) < 0)
772 return -errno;
773 }
774 }
775
776 /* Third step: actually set the uids */
777 if (setresuid(uid, uid, uid) < 0)
778 return -errno;
779
780 /* At this point we should have all necessary capabilities but
781 are otherwise a normal user. However, the caps might got
782 corrupted due to the setresuid() so we need clean them up
783 later. This is done outside of this call. */
784
785 return 0;
786}
787
788#ifdef HAVE_PAM
789
790static int null_conv(
791 int num_msg,
792 const struct pam_message **msg,
793 struct pam_response **resp,
794 void *appdata_ptr) {
795
796 /* We don't support conversations */
797
798 return PAM_CONV_ERR;
799}
800
801static int setup_pam(
802 const char *name,
803 const char *user,
804 uid_t uid,
805 const char *tty,
806 char ***pam_env,
807 int fds[], unsigned n_fds) {
808
809 static const struct pam_conv conv = {
810 .conv = null_conv,
811 .appdata_ptr = NULL
812 };
813
814 _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL;
815 pam_handle_t *handle = NULL;
816 sigset_t old_ss;
817 int pam_code = PAM_SUCCESS;
818 int err = 0;
819 char **e = NULL;
820 bool close_session = false;
821 pid_t pam_pid = 0, parent_pid;
822 int flags = 0;
823
824 assert(name);
825 assert(user);
826 assert(pam_env);
827
828 /* We set up PAM in the parent process, then fork. The child
829 * will then stay around until killed via PR_GET_PDEATHSIG or
830 * systemd via the cgroup logic. It will then remove the PAM
831 * session again. The parent process will exec() the actual
832 * daemon. We do things this way to ensure that the main PID
833 * of the daemon is the one we initially fork()ed. */
834
835 err = barrier_create(&barrier);
836 if (err < 0)
837 goto fail;
838
839 if (log_get_max_level() < LOG_DEBUG)
840 flags |= PAM_SILENT;
841
842 pam_code = pam_start(name, user, &conv, &handle);
843 if (pam_code != PAM_SUCCESS) {
844 handle = NULL;
845 goto fail;
846 }
847
848 if (tty) {
849 pam_code = pam_set_item(handle, PAM_TTY, tty);
850 if (pam_code != PAM_SUCCESS)
851 goto fail;
852 }
853
854 pam_code = pam_acct_mgmt(handle, flags);
855 if (pam_code != PAM_SUCCESS)
856 goto fail;
857
858 pam_code = pam_open_session(handle, flags);
859 if (pam_code != PAM_SUCCESS)
860 goto fail;
861
862 close_session = true;
863
864 e = pam_getenvlist(handle);
865 if (!e) {
866 pam_code = PAM_BUF_ERR;
867 goto fail;
868 }
869
870 /* Block SIGTERM, so that we know that it won't get lost in
871 * the child */
872
873 assert_se(sigprocmask_many(SIG_BLOCK, &old_ss, SIGTERM, -1) >= 0);
874
875 parent_pid = getpid();
876
877 pam_pid = fork();
878 if (pam_pid < 0)
879 goto fail;
880
881 if (pam_pid == 0) {
882 int sig;
883 int r = EXIT_PAM;
884
885 /* The child's job is to reset the PAM session on
886 * termination */
887 barrier_set_role(&barrier, BARRIER_CHILD);
888
889 /* This string must fit in 10 chars (i.e. the length
890 * of "/sbin/init"), to look pretty in /bin/ps */
891 rename_process("(sd-pam)");
892
893 /* Make sure we don't keep open the passed fds in this
894 child. We assume that otherwise only those fds are
895 open here that have been opened by PAM. */
896 close_many(fds, n_fds);
897
898 /* Drop privileges - we don't need any to pam_close_session
899 * and this will make PR_SET_PDEATHSIG work in most cases.
900 * If this fails, ignore the error - but expect sd-pam threads
901 * to fail to exit normally */
902 if (setresuid(uid, uid, uid) < 0)
903 log_error_errno(r, "Error: Failed to setresuid() in sd-pam: %m");
904
905 (void) ignore_signals(SIGPIPE, -1);
906
907 /* Wait until our parent died. This will only work if
908 * the above setresuid() succeeds, otherwise the kernel
909 * will not allow unprivileged parents kill their privileged
910 * children this way. We rely on the control groups kill logic
911 * to do the rest for us. */
912 if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0)
913 goto child_finish;
914
915 /* Tell the parent that our setup is done. This is especially
916 * important regarding dropping privileges. Otherwise, unit
917 * setup might race against our setresuid(2) call. */
918 barrier_place(&barrier);
919
920 /* Check if our parent process might already have
921 * died? */
922 if (getppid() == parent_pid) {
923 sigset_t ss;
924
925 assert_se(sigemptyset(&ss) >= 0);
926 assert_se(sigaddset(&ss, SIGTERM) >= 0);
927
928 for (;;) {
929 if (sigwait(&ss, &sig) < 0) {
930 if (errno == EINTR)
931 continue;
932
933 goto child_finish;
934 }
935
936 assert(sig == SIGTERM);
937 break;
938 }
939 }
940
941 /* If our parent died we'll end the session */
942 if (getppid() != parent_pid) {
943 pam_code = pam_close_session(handle, flags);
944 if (pam_code != PAM_SUCCESS)
945 goto child_finish;
946 }
947
948 r = 0;
949
950 child_finish:
951 pam_end(handle, pam_code | flags);
952 _exit(r);
953 }
954
955 barrier_set_role(&barrier, BARRIER_PARENT);
956
957 /* If the child was forked off successfully it will do all the
958 * cleanups, so forget about the handle here. */
959 handle = NULL;
960
961 /* Unblock SIGTERM again in the parent */
962 assert_se(sigprocmask(SIG_SETMASK, &old_ss, NULL) >= 0);
963
964 /* We close the log explicitly here, since the PAM modules
965 * might have opened it, but we don't want this fd around. */
966 closelog();
967
968 /* Synchronously wait for the child to initialize. We don't care for
969 * errors as we cannot recover. However, warn loudly if it happens. */
970 if (!barrier_place_and_sync(&barrier))
971 log_error("PAM initialization failed");
972
973 *pam_env = e;
974 e = NULL;
975
976 return 0;
977
978fail:
979 if (pam_code != PAM_SUCCESS) {
980 log_error("PAM failed: %s", pam_strerror(handle, pam_code));
981 err = -EPERM; /* PAM errors do not map to errno */
982 } else {
983 err = log_error_errno(err < 0 ? err : errno, "PAM failed: %m");
984 }
985
986 if (handle) {
987 if (close_session)
988 pam_code = pam_close_session(handle, flags);
989
990 pam_end(handle, pam_code | flags);
991 }
992
993 strv_free(e);
994
995 closelog();
996
997 if (pam_pid > 1) {
998 kill(pam_pid, SIGTERM);
999 kill(pam_pid, SIGCONT);
1000 }
1001
1002 return err;
1003}
1004#endif
1005
1006static void rename_process_from_path(const char *path) {
1007 char process_name[11];
1008 const char *p;
1009 size_t l;
1010
1011 /* This resulting string must fit in 10 chars (i.e. the length
1012 * of "/sbin/init") to look pretty in /bin/ps */
1013
1014 p = basename(path);
1015 if (isempty(p)) {
1016 rename_process("(...)");
1017 return;
1018 }
1019
1020 l = strlen(p);
1021 if (l > 8) {
1022 /* The end of the process name is usually more
1023 * interesting, since the first bit might just be
1024 * "systemd-" */
1025 p = p + l - 8;
1026 l = 8;
1027 }
1028
1029 process_name[0] = '(';
1030 memcpy(process_name+1, p, l);
1031 process_name[1+l] = ')';
1032 process_name[1+l+1] = 0;
1033
1034 rename_process(process_name);
1035}
1036
1037#ifdef HAVE_SECCOMP
1038
1039static int apply_seccomp(const ExecContext *c) {
1040 uint32_t negative_action, action;
1041 scmp_filter_ctx *seccomp;
1042 Iterator i;
1043 void *id;
1044 int r;
1045
1046 assert(c);
1047
1048 negative_action = c->syscall_errno == 0 ? SCMP_ACT_KILL : SCMP_ACT_ERRNO(c->syscall_errno);
1049
1050 seccomp = seccomp_init(c->syscall_whitelist ? negative_action : SCMP_ACT_ALLOW);
1051 if (!seccomp)
1052 return -ENOMEM;
1053
1054 if (c->syscall_archs) {
1055
1056 SET_FOREACH(id, c->syscall_archs, i) {
1057 r = seccomp_arch_add(seccomp, PTR_TO_UINT32(id) - 1);
1058 if (r == -EEXIST)
1059 continue;
1060 if (r < 0)
1061 goto finish;
1062 }
1063
1064 } else {
1065 r = seccomp_add_secondary_archs(seccomp);
1066 if (r < 0)
1067 goto finish;
1068 }
1069
1070 action = c->syscall_whitelist ? SCMP_ACT_ALLOW : negative_action;
1071 SET_FOREACH(id, c->syscall_filter, i) {
1072 r = seccomp_rule_add(seccomp, action, PTR_TO_INT(id) - 1, 0);
1073 if (r < 0)
1074 goto finish;
1075 }
1076
1077 r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
1078 if (r < 0)
1079 goto finish;
1080
1081 r = seccomp_load(seccomp);
1082
1083finish:
1084 seccomp_release(seccomp);
1085 return r;
1086}
1087
1088static int apply_address_families(const ExecContext *c) {
1089 scmp_filter_ctx *seccomp;
1090 Iterator i;
1091 int r;
1092
1093 assert(c);
1094
1095 seccomp = seccomp_init(SCMP_ACT_ALLOW);
1096 if (!seccomp)
1097 return -ENOMEM;
1098
1099 r = seccomp_add_secondary_archs(seccomp);
1100 if (r < 0)
1101 goto finish;
1102
1103 if (c->address_families_whitelist) {
1104 int af, first = 0, last = 0;
1105 void *afp;
1106
1107 /* If this is a whitelist, we first block the address
1108 * families that are out of range and then everything
1109 * that is not in the set. First, we find the lowest
1110 * and highest address family in the set. */
1111
1112 SET_FOREACH(afp, c->address_families, i) {
1113 af = PTR_TO_INT(afp);
1114
1115 if (af <= 0 || af >= af_max())
1116 continue;
1117
1118 if (first == 0 || af < first)
1119 first = af;
1120
1121 if (last == 0 || af > last)
1122 last = af;
1123 }
1124
1125 assert((first == 0) == (last == 0));
1126
1127 if (first == 0) {
1128
1129 /* No entries in the valid range, block everything */
1130 r = seccomp_rule_add(
1131 seccomp,
1132 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1133 SCMP_SYS(socket),
1134 0);
1135 if (r < 0)
1136 goto finish;
1137
1138 } else {
1139
1140 /* Block everything below the first entry */
1141 r = seccomp_rule_add(
1142 seccomp,
1143 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1144 SCMP_SYS(socket),
1145 1,
1146 SCMP_A0(SCMP_CMP_LT, first));
1147 if (r < 0)
1148 goto finish;
1149
1150 /* Block everything above the last entry */
1151 r = seccomp_rule_add(
1152 seccomp,
1153 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1154 SCMP_SYS(socket),
1155 1,
1156 SCMP_A0(SCMP_CMP_GT, last));
1157 if (r < 0)
1158 goto finish;
1159
1160 /* Block everything between the first and last
1161 * entry */
1162 for (af = 1; af < af_max(); af++) {
1163
1164 if (set_contains(c->address_families, INT_TO_PTR(af)))
1165 continue;
1166
1167 r = seccomp_rule_add(
1168 seccomp,
1169 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1170 SCMP_SYS(socket),
1171 1,
1172 SCMP_A0(SCMP_CMP_EQ, af));
1173 if (r < 0)
1174 goto finish;
1175 }
1176 }
1177
1178 } else {
1179 void *af;
1180
1181 /* If this is a blacklist, then generate one rule for
1182 * each address family that are then combined in OR
1183 * checks. */
1184
1185 SET_FOREACH(af, c->address_families, i) {
1186
1187 r = seccomp_rule_add(
1188 seccomp,
1189 SCMP_ACT_ERRNO(EPROTONOSUPPORT),
1190 SCMP_SYS(socket),
1191 1,
1192 SCMP_A0(SCMP_CMP_EQ, PTR_TO_INT(af)));
1193 if (r < 0)
1194 goto finish;
1195 }
1196 }
1197
1198 r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0);
1199 if (r < 0)
1200 goto finish;
1201
1202 r = seccomp_load(seccomp);
1203
1204finish:
1205 seccomp_release(seccomp);
1206 return r;
1207}
1208
1209#endif
1210
1211static void do_idle_pipe_dance(int idle_pipe[4]) {
1212 assert(idle_pipe);
1213
1214
1215 idle_pipe[1] = safe_close(idle_pipe[1]);
1216 idle_pipe[2] = safe_close(idle_pipe[2]);
1217
1218 if (idle_pipe[0] >= 0) {
1219 int r;
1220
1221 r = fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT_USEC);
1222
1223 if (idle_pipe[3] >= 0 && r == 0 /* timeout */) {
1224 ssize_t n;
1225
1226 /* Signal systemd that we are bored and want to continue. */
1227 n = write(idle_pipe[3], "x", 1);
1228 if (n > 0)
1229 /* Wait for systemd to react to the signal above. */
1230 fd_wait_for_event(idle_pipe[0], POLLHUP, IDLE_TIMEOUT2_USEC);
1231 }
1232
1233 idle_pipe[0] = safe_close(idle_pipe[0]);
1234
1235 }
1236
1237 idle_pipe[3] = safe_close(idle_pipe[3]);
1238}
1239
1240static int build_environment(
1241 const ExecContext *c,
1242 unsigned n_fds,
1243 char ** fd_names,
1244 usec_t watchdog_usec,
1245 const char *home,
1246 const char *username,
1247 const char *shell,
1248 char ***ret) {
1249
1250 _cleanup_strv_free_ char **our_env = NULL;
1251 unsigned n_env = 0;
1252 char *x;
1253
1254 assert(c);
1255 assert(ret);
1256
1257 our_env = new0(char*, 11);
1258 if (!our_env)
1259 return -ENOMEM;
1260
1261 if (n_fds > 0) {
1262 _cleanup_free_ char *joined = NULL;
1263
1264 if (asprintf(&x, "LISTEN_PID="PID_FMT, getpid()) < 0)
1265 return -ENOMEM;
1266 our_env[n_env++] = x;
1267
1268 if (asprintf(&x, "LISTEN_FDS=%u", n_fds) < 0)
1269 return -ENOMEM;
1270 our_env[n_env++] = x;
1271
1272 joined = strv_join(fd_names, ":");
1273 if (!joined)
1274 return -ENOMEM;
1275
1276 x = strjoin("LISTEN_FDNAMES=", joined, NULL);
1277 if (!x)
1278 return -ENOMEM;
1279 our_env[n_env++] = x;
1280 }
1281
1282 if (watchdog_usec > 0) {
1283 if (asprintf(&x, "WATCHDOG_PID="PID_FMT, getpid()) < 0)
1284 return -ENOMEM;
1285 our_env[n_env++] = x;
1286
1287 if (asprintf(&x, "WATCHDOG_USEC="USEC_FMT, watchdog_usec) < 0)
1288 return -ENOMEM;
1289 our_env[n_env++] = x;
1290 }
1291
1292 if (home) {
1293 x = strappend("HOME=", home);
1294 if (!x)
1295 return -ENOMEM;
1296 our_env[n_env++] = x;
1297 }
1298
1299 if (username) {
1300 x = strappend("LOGNAME=", username);
1301 if (!x)
1302 return -ENOMEM;
1303 our_env[n_env++] = x;
1304
1305 x = strappend("USER=", username);
1306 if (!x)
1307 return -ENOMEM;
1308 our_env[n_env++] = x;
1309 }
1310
1311 if (shell) {
1312 x = strappend("SHELL=", shell);
1313 if (!x)
1314 return -ENOMEM;
1315 our_env[n_env++] = x;
1316 }
1317
1318 if (is_terminal_input(c->std_input) ||
1319 c->std_output == EXEC_OUTPUT_TTY ||
1320 c->std_error == EXEC_OUTPUT_TTY ||
1321 c->tty_path) {
1322
1323 x = strdup(default_term_for_tty(tty_path(c)));
1324 if (!x)
1325 return -ENOMEM;
1326 our_env[n_env++] = x;
1327 }
1328
1329 our_env[n_env++] = NULL;
1330 assert(n_env <= 11);
1331
1332 *ret = our_env;
1333 our_env = NULL;
1334
1335 return 0;
1336}
1337
1338static int build_pass_environment(const ExecContext *c, char ***ret) {
1339 _cleanup_strv_free_ char **pass_env = NULL;
1340 size_t n_env = 0, n_bufsize = 0;
1341 char **i;
1342
1343 STRV_FOREACH(i, c->pass_environment) {
1344 _cleanup_free_ char *x = NULL;
1345 char *v;
1346
1347 v = getenv(*i);
1348 if (!v)
1349 continue;
1350 x = strjoin(*i, "=", v, NULL);
1351 if (!x)
1352 return -ENOMEM;
1353 if (!GREEDY_REALLOC(pass_env, n_bufsize, n_env + 2))
1354 return -ENOMEM;
1355 pass_env[n_env++] = x;
1356 pass_env[n_env] = NULL;
1357 x = NULL;
1358 }
1359
1360 *ret = pass_env;
1361 pass_env = NULL;
1362
1363 return 0;
1364}
1365
1366static bool exec_needs_mount_namespace(
1367 const ExecContext *context,
1368 const ExecParameters *params,
1369 ExecRuntime *runtime) {
1370
1371 assert(context);
1372 assert(params);
1373
1374 if (!strv_isempty(context->read_write_dirs) ||
1375 !strv_isempty(context->read_only_dirs) ||
1376 !strv_isempty(context->inaccessible_dirs))
1377 return true;
1378
1379 if (context->mount_flags != 0)
1380 return true;
1381
1382 if (context->private_tmp && runtime && (runtime->tmp_dir || runtime->var_tmp_dir))
1383 return true;
1384
1385 if (params->bus_endpoint_path)
1386 return true;
1387
1388 if (context->private_devices ||
1389 context->protect_system != PROTECT_SYSTEM_NO ||
1390 context->protect_home != PROTECT_HOME_NO)
1391 return true;
1392
1393 return false;
1394}
1395
1396static int close_remaining_fds(
1397 const ExecParameters *params,
1398 ExecRuntime *runtime,
1399 int socket_fd,
1400 int *fds, unsigned n_fds) {
1401
1402 unsigned n_dont_close = 0;
1403 int dont_close[n_fds + 7];
1404
1405 assert(params);
1406
1407 if (params->stdin_fd >= 0)
1408 dont_close[n_dont_close++] = params->stdin_fd;
1409 if (params->stdout_fd >= 0)
1410 dont_close[n_dont_close++] = params->stdout_fd;
1411 if (params->stderr_fd >= 0)
1412 dont_close[n_dont_close++] = params->stderr_fd;
1413
1414 if (socket_fd >= 0)
1415 dont_close[n_dont_close++] = socket_fd;
1416 if (n_fds > 0) {
1417 memcpy(dont_close + n_dont_close, fds, sizeof(int) * n_fds);
1418 n_dont_close += n_fds;
1419 }
1420
1421 if (params->bus_endpoint_fd >= 0)
1422 dont_close[n_dont_close++] = params->bus_endpoint_fd;
1423
1424 if (runtime) {
1425 if (runtime->netns_storage_socket[0] >= 0)
1426 dont_close[n_dont_close++] = runtime->netns_storage_socket[0];
1427 if (runtime->netns_storage_socket[1] >= 0)
1428 dont_close[n_dont_close++] = runtime->netns_storage_socket[1];
1429 }
1430
1431 return close_all_fds(dont_close, n_dont_close);
1432}
1433
1434static int exec_child(
1435 Unit *unit,
1436 ExecCommand *command,
1437 const ExecContext *context,
1438 const ExecParameters *params,
1439 ExecRuntime *runtime,
1440 char **argv,
1441 int socket_fd,
1442 int *fds, unsigned n_fds,
1443 char **files_env,
1444 int *exit_status) {
1445
1446 _cleanup_strv_free_ char **our_env = NULL, **pass_env = NULL, **pam_env = NULL, **final_env = NULL, **final_argv = NULL;
1447 _cleanup_free_ char *mac_selinux_context_net = NULL;
1448 const char *username = NULL, *home = NULL, *shell = NULL, *wd;
1449 uid_t uid = UID_INVALID;
1450 gid_t gid = GID_INVALID;
1451 int i, r;
1452 bool needs_mount_namespace;
1453
1454 assert(unit);
1455 assert(command);
1456 assert(context);
1457 assert(params);
1458 assert(exit_status);
1459
1460 rename_process_from_path(command->path);
1461
1462 /* We reset exactly these signals, since they are the
1463 * only ones we set to SIG_IGN in the main daemon. All
1464 * others we leave untouched because we set them to
1465 * SIG_DFL or a valid handler initially, both of which
1466 * will be demoted to SIG_DFL. */
1467 (void) default_signals(SIGNALS_CRASH_HANDLER,
1468 SIGNALS_IGNORE, -1);
1469
1470 if (context->ignore_sigpipe)
1471 (void) ignore_signals(SIGPIPE, -1);
1472
1473 r = reset_signal_mask();
1474 if (r < 0) {
1475 *exit_status = EXIT_SIGNAL_MASK;
1476 return r;
1477 }
1478
1479 if (params->idle_pipe)
1480 do_idle_pipe_dance(params->idle_pipe);
1481
1482 /* Close sockets very early to make sure we don't
1483 * block init reexecution because it cannot bind its
1484 * sockets */
1485
1486 log_forget_fds();
1487
1488 r = close_remaining_fds(params, runtime, socket_fd, fds, n_fds);
1489 if (r < 0) {
1490 *exit_status = EXIT_FDS;
1491 return r;
1492 }
1493
1494 if (!context->same_pgrp)
1495 if (setsid() < 0) {
1496 *exit_status = EXIT_SETSID;
1497 return -errno;
1498 }
1499
1500 exec_context_tty_reset(context);
1501
1502 if (params->confirm_spawn) {
1503 char response;
1504
1505 r = ask_for_confirmation(&response, argv);
1506 if (r == -ETIMEDOUT)
1507 write_confirm_message("Confirmation question timed out, assuming positive response.\n");
1508 else if (r < 0)
1509 write_confirm_message("Couldn't ask confirmation question, assuming positive response: %s\n", strerror(-r));
1510 else if (response == 's') {
1511 write_confirm_message("Skipping execution.\n");
1512 *exit_status = EXIT_CONFIRM;
1513 return -ECANCELED;
1514 } else if (response == 'n') {
1515 write_confirm_message("Failing execution.\n");
1516 *exit_status = 0;
1517 return 0;
1518 }
1519 }
1520
1521 if (context->user) {
1522 username = context->user;
1523 r = get_user_creds(&username, &uid, &gid, &home, &shell);
1524 if (r < 0) {
1525 *exit_status = EXIT_USER;
1526 return r;
1527 }
1528 }
1529
1530 if (context->group) {
1531 const char *g = context->group;
1532
1533 r = get_group_creds(&g, &gid);
1534 if (r < 0) {
1535 *exit_status = EXIT_GROUP;
1536 return r;
1537 }
1538 }
1539
1540
1541 /* If a socket is connected to STDIN/STDOUT/STDERR, we
1542 * must sure to drop O_NONBLOCK */
1543 if (socket_fd >= 0)
1544 (void) fd_nonblock(socket_fd, false);
1545
1546 r = setup_input(context, params, socket_fd);
1547 if (r < 0) {
1548 *exit_status = EXIT_STDIN;
1549 return r;
1550 }
1551
1552 r = setup_output(unit, context, params, STDOUT_FILENO, socket_fd, basename(command->path), uid, gid);
1553 if (r < 0) {
1554 *exit_status = EXIT_STDOUT;
1555 return r;
1556 }
1557
1558 r = setup_output(unit, context, params, STDERR_FILENO, socket_fd, basename(command->path), uid, gid);
1559 if (r < 0) {
1560 *exit_status = EXIT_STDERR;
1561 return r;
1562 }
1563
1564 if (params->cgroup_path) {
1565 r = cg_attach_everywhere(params->cgroup_supported, params->cgroup_path, 0, NULL, NULL);
1566 if (r < 0) {
1567 *exit_status = EXIT_CGROUP;
1568 return r;
1569 }
1570 }
1571
1572 if (context->oom_score_adjust_set) {
1573 char t[DECIMAL_STR_MAX(context->oom_score_adjust)];
1574
1575 /* When we can't make this change due to EPERM, then
1576 * let's silently skip over it. User namespaces
1577 * prohibit write access to this file, and we
1578 * shouldn't trip up over that. */
1579
1580 sprintf(t, "%i", context->oom_score_adjust);
1581 r = write_string_file("/proc/self/oom_score_adj", t, 0);
1582 if (r == -EPERM || r == -EACCES) {
1583 log_open();
1584 log_unit_debug_errno(unit, r, "Failed to adjust OOM setting, assuming containerized execution, ignoring: %m");
1585 log_close();
1586 } else if (r < 0) {
1587 *exit_status = EXIT_OOM_ADJUST;
1588 return -errno;
1589 }
1590 }
1591
1592 if (context->nice_set)
1593 if (setpriority(PRIO_PROCESS, 0, context->nice) < 0) {
1594 *exit_status = EXIT_NICE;
1595 return -errno;
1596 }
1597
1598 if (context->cpu_sched_set) {
1599 struct sched_param param = {
1600 .sched_priority = context->cpu_sched_priority,
1601 };
1602
1603 r = sched_setscheduler(0,
1604 context->cpu_sched_policy |
1605 (context->cpu_sched_reset_on_fork ?
1606 SCHED_RESET_ON_FORK : 0),
1607 &param);
1608 if (r < 0) {
1609 *exit_status = EXIT_SETSCHEDULER;
1610 return -errno;
1611 }
1612 }
1613
1614 if (context->cpuset)
1615 if (sched_setaffinity(0, CPU_ALLOC_SIZE(context->cpuset_ncpus), context->cpuset) < 0) {
1616 *exit_status = EXIT_CPUAFFINITY;
1617 return -errno;
1618 }
1619
1620 if (context->ioprio_set)
1621 if (ioprio_set(IOPRIO_WHO_PROCESS, 0, context->ioprio) < 0) {
1622 *exit_status = EXIT_IOPRIO;
1623 return -errno;
1624 }
1625
1626 if (context->timer_slack_nsec != NSEC_INFINITY)
1627 if (prctl(PR_SET_TIMERSLACK, context->timer_slack_nsec) < 0) {
1628 *exit_status = EXIT_TIMERSLACK;
1629 return -errno;
1630 }
1631
1632 if (context->personality != PERSONALITY_INVALID)
1633 if (personality(context->personality) < 0) {
1634 *exit_status = EXIT_PERSONALITY;
1635 return -errno;
1636 }
1637
1638 if (context->utmp_id)
1639 utmp_put_init_process(context->utmp_id, getpid(), getsid(0), context->tty_path,
1640 context->utmp_mode == EXEC_UTMP_INIT ? INIT_PROCESS :
1641 context->utmp_mode == EXEC_UTMP_LOGIN ? LOGIN_PROCESS :
1642 USER_PROCESS,
1643 username ? "root" : context->user);
1644
1645 if (context->user && is_terminal_input(context->std_input)) {
1646 r = chown_terminal(STDIN_FILENO, uid);
1647 if (r < 0) {
1648 *exit_status = EXIT_STDIN;
1649 return r;
1650 }
1651 }
1652
1653 if (params->bus_endpoint_fd >= 0 && context->bus_endpoint) {
1654 uid_t ep_uid = (uid == UID_INVALID) ? 0 : uid;
1655
1656 r = bus_kernel_set_endpoint_policy(params->bus_endpoint_fd, ep_uid, context->bus_endpoint);
1657 if (r < 0) {
1658 *exit_status = EXIT_BUS_ENDPOINT;
1659 return r;
1660 }
1661 }
1662
1663 /* If delegation is enabled we'll pass ownership of the cgroup
1664 * (but only in systemd's own controller hierarchy!) to the
1665 * user of the new process. */
1666 if (params->cgroup_path && context->user && params->cgroup_delegate) {
1667 r = cg_set_task_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0644, uid, gid);
1668 if (r < 0) {
1669 *exit_status = EXIT_CGROUP;
1670 return r;
1671 }
1672
1673
1674 r = cg_set_group_access(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, 0755, uid, gid);
1675 if (r < 0) {
1676 *exit_status = EXIT_CGROUP;
1677 return r;
1678 }
1679 }
1680
1681 if (!strv_isempty(context->runtime_directory) && params->runtime_prefix) {
1682 char **rt;
1683
1684 STRV_FOREACH(rt, context->runtime_directory) {
1685 _cleanup_free_ char *p;
1686
1687 p = strjoin(params->runtime_prefix, "/", *rt, NULL);
1688 if (!p) {
1689 *exit_status = EXIT_RUNTIME_DIRECTORY;
1690 return -ENOMEM;
1691 }
1692
1693 r = mkdir_p_label(p, context->runtime_directory_mode);
1694 if (r < 0) {
1695 *exit_status = EXIT_RUNTIME_DIRECTORY;
1696 return r;
1697 }
1698
1699 r = chmod_and_chown(p, context->runtime_directory_mode, uid, gid);
1700 if (r < 0) {
1701 *exit_status = EXIT_RUNTIME_DIRECTORY;
1702 return r;
1703 }
1704 }
1705 }
1706
1707 umask(context->umask);
1708
1709 if (params->apply_permissions) {
1710 r = enforce_groups(context, username, gid);
1711 if (r < 0) {
1712 *exit_status = EXIT_GROUP;
1713 return r;
1714 }
1715#ifdef HAVE_SMACK
1716 if (context->smack_process_label) {
1717 r = mac_smack_apply_pid(0, context->smack_process_label);
1718 if (r < 0) {
1719 *exit_status = EXIT_SMACK_PROCESS_LABEL;
1720 return r;
1721 }
1722 }
1723#ifdef SMACK_DEFAULT_PROCESS_LABEL
1724 else {
1725 _cleanup_free_ char *exec_label = NULL;
1726
1727 r = mac_smack_read(command->path, SMACK_ATTR_EXEC, &exec_label);
1728 if (r < 0 && r != -ENODATA && r != -EOPNOTSUPP) {
1729 *exit_status = EXIT_SMACK_PROCESS_LABEL;
1730 return r;
1731 }
1732
1733 r = mac_smack_apply_pid(0, exec_label ? : SMACK_DEFAULT_PROCESS_LABEL);
1734 if (r < 0) {
1735 *exit_status = EXIT_SMACK_PROCESS_LABEL;
1736 return r;
1737 }
1738 }
1739#endif
1740#endif
1741#ifdef HAVE_PAM
1742 if (context->pam_name && username) {
1743 r = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds);
1744 if (r < 0) {
1745 *exit_status = EXIT_PAM;
1746 return r;
1747 }
1748 }
1749#endif
1750 }
1751
1752 if (context->private_network && runtime && runtime->netns_storage_socket[0] >= 0) {
1753 r = setup_netns(runtime->netns_storage_socket);
1754 if (r < 0) {
1755 *exit_status = EXIT_NETWORK;
1756 return r;
1757 }
1758 }
1759
1760 needs_mount_namespace = exec_needs_mount_namespace(context, params, runtime);
1761
1762 if (needs_mount_namespace) {
1763 char *tmp = NULL, *var = NULL;
1764
1765 /* The runtime struct only contains the parent
1766 * of the private /tmp, which is
1767 * non-accessible to world users. Inside of it
1768 * there's a /tmp that is sticky, and that's
1769 * the one we want to use here. */
1770
1771 if (context->private_tmp && runtime) {
1772 if (runtime->tmp_dir)
1773 tmp = strjoina(runtime->tmp_dir, "/tmp");
1774 if (runtime->var_tmp_dir)
1775 var = strjoina(runtime->var_tmp_dir, "/tmp");
1776 }
1777
1778 r = setup_namespace(
1779 params->apply_chroot ? context->root_directory : NULL,
1780 context->read_write_dirs,
1781 context->read_only_dirs,
1782 context->inaccessible_dirs,
1783 tmp,
1784 var,
1785 params->bus_endpoint_path,
1786 context->private_devices,
1787 context->protect_home,
1788 context->protect_system,
1789 context->mount_flags);
1790
1791 /* If we couldn't set up the namespace this is
1792 * probably due to a missing capability. In this case,
1793 * silently proceeed. */
1794 if (r == -EPERM || r == -EACCES) {
1795 log_open();
1796 log_unit_debug_errno(unit, r, "Failed to set up namespace, assuming containerized execution, ignoring: %m");
1797 log_close();
1798 } else if (r < 0) {
1799 *exit_status = EXIT_NAMESPACE;
1800 return r;
1801 }
1802 }
1803
1804 if (context->working_directory_home)
1805 wd = home;
1806 else if (context->working_directory)
1807 wd = context->working_directory;
1808 else
1809 wd = "/";
1810
1811 if (params->apply_chroot) {
1812 if (!needs_mount_namespace && context->root_directory)
1813 if (chroot(context->root_directory) < 0) {
1814 *exit_status = EXIT_CHROOT;
1815 return -errno;
1816 }
1817
1818 if (chdir(wd) < 0 &&
1819 !context->working_directory_missing_ok) {
1820 *exit_status = EXIT_CHDIR;
1821 return -errno;
1822 }
1823 } else {
1824 const char *d;
1825
1826 d = strjoina(strempty(context->root_directory), "/", strempty(wd));
1827 if (chdir(d) < 0 &&
1828 !context->working_directory_missing_ok) {
1829 *exit_status = EXIT_CHDIR;
1830 return -errno;
1831 }
1832 }
1833
1834#ifdef HAVE_SELINUX
1835 if (params->apply_permissions && mac_selinux_use() && params->selinux_context_net && socket_fd >= 0) {
1836 r = mac_selinux_get_child_mls_label(socket_fd, command->path, context->selinux_context, &mac_selinux_context_net);
1837 if (r < 0) {
1838 *exit_status = EXIT_SELINUX_CONTEXT;
1839 return r;
1840 }
1841 }
1842#endif
1843
1844 /* We repeat the fd closing here, to make sure that
1845 * nothing is leaked from the PAM modules. Note that
1846 * we are more aggressive this time since socket_fd
1847 * and the netns fds we don't need anymore. The custom
1848 * endpoint fd was needed to upload the policy and can
1849 * now be closed as well. */
1850 r = close_all_fds(fds, n_fds);
1851 if (r >= 0)
1852 r = shift_fds(fds, n_fds);
1853 if (r >= 0)
1854 r = flags_fds(fds, n_fds, context->non_blocking);
1855 if (r < 0) {
1856 *exit_status = EXIT_FDS;
1857 return r;
1858 }
1859
1860 if (params->apply_permissions) {
1861
1862 int secure_bits = context->secure_bits;
1863
1864 for (i = 0; i < _RLIMIT_MAX; i++) {
1865 if (!context->rlimit[i])
1866 continue;
1867
1868 if (setrlimit_closest(i, context->rlimit[i]) < 0) {
1869 *exit_status = EXIT_LIMITS;
1870 return -errno;
1871 }
1872 }
1873
1874 if (!cap_test_all(context->capability_bounding_set)) {
1875 r = capability_bounding_set_drop(context->capability_bounding_set, false);
1876 if (r < 0) {
1877 *exit_status = EXIT_CAPABILITIES;
1878 return r;
1879 }
1880 }
1881
1882 /* This is done before enforce_user, but ambient set
1883 * does not survive over setresuid() if keep_caps is not set. */
1884 if (context->capability_ambient_set != 0) {
1885 r = capability_ambient_set_apply(context->capability_ambient_set, true);
1886 if (r < 0) {
1887 *exit_status = EXIT_CAPABILITIES;
1888 return r;
1889 }
1890
1891 if (context->capabilities) {
1892
1893 /* The capabilities in ambient set need to be also in the inherited
1894 * set. If they aren't, trying to get them will fail. Add the ambient
1895 * set inherited capabilities to the capability set in the context.
1896 * This is needed because if capabilities are set (using "Capabilities="
1897 * keyword), they will override whatever we set now. */
1898
1899 r = capability_update_inherited_set(context->capabilities, context->capability_ambient_set);
1900 if (r < 0) {
1901 *exit_status = EXIT_CAPABILITIES;
1902 return r;
1903 }
1904 }
1905 }
1906
1907 if (context->user) {
1908 r = enforce_user(context, uid);
1909 if (r < 0) {
1910 *exit_status = EXIT_USER;
1911 return r;
1912 }
1913 if (context->capability_ambient_set != 0) {
1914
1915 /* Fix the ambient capabilities after user change. */
1916 r = capability_ambient_set_apply(context->capability_ambient_set, false);
1917 if (r < 0) {
1918 *exit_status = EXIT_CAPABILITIES;
1919 return r;
1920 }
1921
1922 /* If we were asked to change user and ambient capabilities
1923 * were requested, we had to add keep-caps to the securebits
1924 * so that we would maintain the inherited capability set
1925 * through the setresuid(). Make sure that the bit is added
1926 * also to the context secure_bits so that we don't try to
1927 * drop the bit away next. */
1928
1929 secure_bits |= 1<<SECURE_KEEP_CAPS;
1930 }
1931 }
1932
1933 /* PR_GET_SECUREBITS is not privileged, while
1934 * PR_SET_SECUREBITS is. So to suppress
1935 * potential EPERMs we'll try not to call
1936 * PR_SET_SECUREBITS unless necessary. */
1937 if (prctl(PR_GET_SECUREBITS) != secure_bits)
1938 if (prctl(PR_SET_SECUREBITS, secure_bits) < 0) {
1939 *exit_status = EXIT_SECUREBITS;
1940 return -errno;
1941 }
1942
1943 if (context->capabilities)
1944 if (cap_set_proc(context->capabilities) < 0) {
1945 *exit_status = EXIT_CAPABILITIES;
1946 return -errno;
1947 }
1948
1949 if (context->no_new_privileges)
1950 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
1951 *exit_status = EXIT_NO_NEW_PRIVILEGES;
1952 return -errno;
1953 }
1954
1955#ifdef HAVE_SECCOMP
1956 if (context->address_families_whitelist ||
1957 !set_isempty(context->address_families)) {
1958 r = apply_address_families(context);
1959 if (r < 0) {
1960 *exit_status = EXIT_ADDRESS_FAMILIES;
1961 return r;
1962 }
1963 }
1964
1965 if (context->syscall_whitelist ||
1966 !set_isempty(context->syscall_filter) ||
1967 !set_isempty(context->syscall_archs)) {
1968 r = apply_seccomp(context);
1969 if (r < 0) {
1970 *exit_status = EXIT_SECCOMP;
1971 return r;
1972 }
1973 }
1974#endif
1975
1976#ifdef HAVE_SELINUX
1977 if (mac_selinux_use()) {
1978 char *exec_context = mac_selinux_context_net ?: context->selinux_context;
1979
1980 if (exec_context) {
1981 r = setexeccon(exec_context);
1982 if (r < 0) {
1983 *exit_status = EXIT_SELINUX_CONTEXT;
1984 return r;
1985 }
1986 }
1987 }
1988#endif
1989
1990#ifdef HAVE_APPARMOR
1991 if (context->apparmor_profile && mac_apparmor_use()) {
1992 r = aa_change_onexec(context->apparmor_profile);
1993 if (r < 0 && !context->apparmor_profile_ignore) {
1994 *exit_status = EXIT_APPARMOR_PROFILE;
1995 return -errno;
1996 }
1997 }
1998#endif
1999 }
2000
2001 r = build_environment(context, n_fds, params->fd_names, params->watchdog_usec, home, username, shell, &our_env);
2002 if (r < 0) {
2003 *exit_status = EXIT_MEMORY;
2004 return r;
2005 }
2006
2007 r = build_pass_environment(context, &pass_env);
2008 if (r < 0) {
2009 *exit_status = EXIT_MEMORY;
2010 return r;
2011 }
2012
2013 final_env = strv_env_merge(6,
2014 params->environment,
2015 our_env,
2016 pass_env,
2017 context->environment,
2018 files_env,
2019 pam_env,
2020 NULL);
2021 if (!final_env) {
2022 *exit_status = EXIT_MEMORY;
2023 return -ENOMEM;
2024 }
2025
2026 final_argv = replace_env_argv(argv, final_env);
2027 if (!final_argv) {
2028 *exit_status = EXIT_MEMORY;
2029 return -ENOMEM;
2030 }
2031
2032 final_env = strv_env_clean(final_env);
2033
2034 if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) {
2035 _cleanup_free_ char *line;
2036
2037 line = exec_command_line(final_argv);
2038 if (line) {
2039 log_open();
2040 log_struct(LOG_DEBUG,
2041 LOG_UNIT_ID(unit),
2042 "EXECUTABLE=%s", command->path,
2043 LOG_UNIT_MESSAGE(unit, "Executing: %s", line),
2044 NULL);
2045 log_close();
2046 }
2047 }
2048
2049 execve(command->path, final_argv, final_env);
2050 *exit_status = EXIT_EXEC;
2051 return -errno;
2052}
2053
2054int exec_spawn(Unit *unit,
2055 ExecCommand *command,
2056 const ExecContext *context,
2057 const ExecParameters *params,
2058 ExecRuntime *runtime,
2059 pid_t *ret) {
2060
2061 _cleanup_strv_free_ char **files_env = NULL;
2062 int *fds = NULL; unsigned n_fds = 0;
2063 _cleanup_free_ char *line = NULL;
2064 int socket_fd, r;
2065 char **argv;
2066 pid_t pid;
2067
2068 assert(unit);
2069 assert(command);
2070 assert(context);
2071 assert(ret);
2072 assert(params);
2073 assert(params->fds || params->n_fds <= 0);
2074
2075 if (context->std_input == EXEC_INPUT_SOCKET ||
2076 context->std_output == EXEC_OUTPUT_SOCKET ||
2077 context->std_error == EXEC_OUTPUT_SOCKET) {
2078
2079 if (params->n_fds != 1) {
2080 log_unit_error(unit, "Got more than one socket.");
2081 return -EINVAL;
2082 }
2083
2084 socket_fd = params->fds[0];
2085 } else {
2086 socket_fd = -1;
2087 fds = params->fds;
2088 n_fds = params->n_fds;
2089 }
2090
2091 r = exec_context_load_environment(unit, context, &files_env);
2092 if (r < 0)
2093 return log_unit_error_errno(unit, r, "Failed to load environment files: %m");
2094
2095 argv = params->argv ?: command->argv;
2096 line = exec_command_line(argv);
2097 if (!line)
2098 return log_oom();
2099
2100 log_struct(LOG_DEBUG,
2101 LOG_UNIT_ID(unit),
2102 LOG_UNIT_MESSAGE(unit, "About to execute: %s", line),
2103 "EXECUTABLE=%s", command->path,
2104 NULL);
2105 pid = fork();
2106 if (pid < 0)
2107 return log_unit_error_errno(unit, errno, "Failed to fork: %m");
2108
2109 if (pid == 0) {
2110 int exit_status;
2111
2112 r = exec_child(unit,
2113 command,
2114 context,
2115 params,
2116 runtime,
2117 argv,
2118 socket_fd,
2119 fds, n_fds,
2120 files_env,
2121 &exit_status);
2122 if (r < 0) {
2123 log_open();
2124 log_struct_errno(LOG_ERR, r,
2125 LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED),
2126 LOG_UNIT_ID(unit),
2127 LOG_UNIT_MESSAGE(unit, "Failed at step %s spawning %s: %m",
2128 exit_status_to_string(exit_status, EXIT_STATUS_SYSTEMD),
2129 command->path),
2130 "EXECUTABLE=%s", command->path,
2131 NULL);
2132 }
2133
2134 _exit(exit_status);
2135 }
2136
2137 log_unit_debug(unit, "Forked %s as "PID_FMT, command->path, pid);
2138
2139 /* We add the new process to the cgroup both in the child (so
2140 * that we can be sure that no user code is ever executed
2141 * outside of the cgroup) and in the parent (so that we can be
2142 * sure that when we kill the cgroup the process will be
2143 * killed too). */
2144 if (params->cgroup_path)
2145 (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, pid);
2146
2147 exec_status_start(&command->exec_status, pid);
2148
2149 *ret = pid;
2150 return 0;
2151}
2152
2153void exec_context_init(ExecContext *c) {
2154 assert(c);
2155
2156 c->umask = 0022;
2157 c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0);
2158 c->cpu_sched_policy = SCHED_OTHER;
2159 c->syslog_priority = LOG_DAEMON|LOG_INFO;
2160 c->syslog_level_prefix = true;
2161 c->ignore_sigpipe = true;
2162 c->timer_slack_nsec = NSEC_INFINITY;
2163 c->personality = PERSONALITY_INVALID;
2164 c->runtime_directory_mode = 0755;
2165 c->capability_bounding_set = CAP_ALL;
2166}
2167
2168void exec_context_done(ExecContext *c) {
2169 unsigned l;
2170
2171 assert(c);
2172
2173 c->environment = strv_free(c->environment);
2174 c->environment_files = strv_free(c->environment_files);
2175 c->pass_environment = strv_free(c->pass_environment);
2176
2177 for (l = 0; l < ELEMENTSOF(c->rlimit); l++)
2178 c->rlimit[l] = mfree(c->rlimit[l]);
2179
2180 c->working_directory = mfree(c->working_directory);
2181 c->root_directory = mfree(c->root_directory);
2182 c->tty_path = mfree(c->tty_path);
2183 c->syslog_identifier = mfree(c->syslog_identifier);
2184 c->user = mfree(c->user);
2185 c->group = mfree(c->group);
2186
2187 c->supplementary_groups = strv_free(c->supplementary_groups);
2188
2189 c->pam_name = mfree(c->pam_name);
2190
2191 if (c->capabilities) {
2192 cap_free(c->capabilities);
2193 c->capabilities = NULL;
2194 }
2195
2196 c->read_only_dirs = strv_free(c->read_only_dirs);
2197 c->read_write_dirs = strv_free(c->read_write_dirs);
2198 c->inaccessible_dirs = strv_free(c->inaccessible_dirs);
2199
2200 if (c->cpuset)
2201 CPU_FREE(c->cpuset);
2202
2203 c->utmp_id = mfree(c->utmp_id);
2204 c->selinux_context = mfree(c->selinux_context);
2205 c->apparmor_profile = mfree(c->apparmor_profile);
2206
2207 c->syscall_filter = set_free(c->syscall_filter);
2208 c->syscall_archs = set_free(c->syscall_archs);
2209 c->address_families = set_free(c->address_families);
2210
2211 c->runtime_directory = strv_free(c->runtime_directory);
2212
2213 bus_endpoint_free(c->bus_endpoint);
2214 c->bus_endpoint = NULL;
2215}
2216
2217int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_prefix) {
2218 char **i;
2219
2220 assert(c);
2221
2222 if (!runtime_prefix)
2223 return 0;
2224
2225 STRV_FOREACH(i, c->runtime_directory) {
2226 _cleanup_free_ char *p;
2227
2228 p = strjoin(runtime_prefix, "/", *i, NULL);
2229 if (!p)
2230 return -ENOMEM;
2231
2232 /* We execute this synchronously, since we need to be
2233 * sure this is gone when we start the service
2234 * next. */
2235 (void) rm_rf(p, REMOVE_ROOT);
2236 }
2237
2238 return 0;
2239}
2240
2241void exec_command_done(ExecCommand *c) {
2242 assert(c);
2243
2244 c->path = mfree(c->path);
2245
2246 c->argv = strv_free(c->argv);
2247}
2248
2249void exec_command_done_array(ExecCommand *c, unsigned n) {
2250 unsigned i;
2251
2252 for (i = 0; i < n; i++)
2253 exec_command_done(c+i);
2254}
2255
2256ExecCommand* exec_command_free_list(ExecCommand *c) {
2257 ExecCommand *i;
2258
2259 while ((i = c)) {
2260 LIST_REMOVE(command, c, i);
2261 exec_command_done(i);
2262 free(i);
2263 }
2264
2265 return NULL;
2266}
2267
2268void exec_command_free_array(ExecCommand **c, unsigned n) {
2269 unsigned i;
2270
2271 for (i = 0; i < n; i++)
2272 c[i] = exec_command_free_list(c[i]);
2273}
2274
2275typedef struct InvalidEnvInfo {
2276 Unit *unit;
2277 const char *path;
2278} InvalidEnvInfo;
2279
2280static void invalid_env(const char *p, void *userdata) {
2281 InvalidEnvInfo *info = userdata;
2282
2283 log_unit_error(info->unit, "Ignoring invalid environment assignment '%s': %s", p, info->path);
2284}
2285
2286int exec_context_load_environment(Unit *unit, const ExecContext *c, char ***l) {
2287 char **i, **r = NULL;
2288
2289 assert(c);
2290 assert(l);
2291
2292 STRV_FOREACH(i, c->environment_files) {
2293 char *fn;
2294 int k;
2295 bool ignore = false;
2296 char **p;
2297 _cleanup_globfree_ glob_t pglob = {};
2298 int count, n;
2299
2300 fn = *i;
2301
2302 if (fn[0] == '-') {
2303 ignore = true;
2304 fn ++;
2305 }
2306
2307 if (!path_is_absolute(fn)) {
2308 if (ignore)
2309 continue;
2310
2311 strv_free(r);
2312 return -EINVAL;
2313 }
2314
2315 /* Filename supports globbing, take all matching files */
2316 errno = 0;
2317 if (glob(fn, 0, NULL, &pglob) != 0) {
2318 if (ignore)
2319 continue;
2320
2321 strv_free(r);
2322 return errno > 0 ? -errno : -EINVAL;
2323 }
2324 count = pglob.gl_pathc;
2325 if (count == 0) {
2326 if (ignore)
2327 continue;
2328
2329 strv_free(r);
2330 return -EINVAL;
2331 }
2332 for (n = 0; n < count; n++) {
2333 k = load_env_file(NULL, pglob.gl_pathv[n], NULL, &p);
2334 if (k < 0) {
2335 if (ignore)
2336 continue;
2337
2338 strv_free(r);
2339 return k;
2340 }
2341 /* Log invalid environment variables with filename */
2342 if (p) {
2343 InvalidEnvInfo info = {
2344 .unit = unit,
2345 .path = pglob.gl_pathv[n]
2346 };
2347
2348 p = strv_env_clean_with_callback(p, invalid_env, &info);
2349 }
2350
2351 if (r == NULL)
2352 r = p;
2353 else {
2354 char **m;
2355
2356 m = strv_env_merge(2, r, p);
2357 strv_free(r);
2358 strv_free(p);
2359 if (!m)
2360 return -ENOMEM;
2361
2362 r = m;
2363 }
2364 }
2365 }
2366
2367 *l = r;
2368
2369 return 0;
2370}
2371
2372static bool tty_may_match_dev_console(const char *tty) {
2373 _cleanup_free_ char *active = NULL;
2374 char *console;
2375
2376 if (startswith(tty, "/dev/"))
2377 tty += 5;
2378
2379 /* trivial identity? */
2380 if (streq(tty, "console"))
2381 return true;
2382
2383 console = resolve_dev_console(&active);
2384 /* if we could not resolve, assume it may */
2385 if (!console)
2386 return true;
2387
2388 /* "tty0" means the active VC, so it may be the same sometimes */
2389 return streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty));
2390}
2391
2392bool exec_context_may_touch_console(ExecContext *ec) {
2393 return (ec->tty_reset || ec->tty_vhangup || ec->tty_vt_disallocate ||
2394 is_terminal_input(ec->std_input) ||
2395 is_terminal_output(ec->std_output) ||
2396 is_terminal_output(ec->std_error)) &&
2397 tty_may_match_dev_console(tty_path(ec));
2398}
2399
2400static void strv_fprintf(FILE *f, char **l) {
2401 char **g;
2402
2403 assert(f);
2404
2405 STRV_FOREACH(g, l)
2406 fprintf(f, " %s", *g);
2407}
2408
2409void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
2410 char **e, **d;
2411 unsigned i;
2412
2413 assert(c);
2414 assert(f);
2415
2416 prefix = strempty(prefix);
2417
2418 fprintf(f,
2419 "%sUMask: %04o\n"
2420 "%sWorkingDirectory: %s\n"
2421 "%sRootDirectory: %s\n"
2422 "%sNonBlocking: %s\n"
2423 "%sPrivateTmp: %s\n"
2424 "%sPrivateNetwork: %s\n"
2425 "%sPrivateDevices: %s\n"
2426 "%sProtectHome: %s\n"
2427 "%sProtectSystem: %s\n"
2428 "%sIgnoreSIGPIPE: %s\n",
2429 prefix, c->umask,
2430 prefix, c->working_directory ? c->working_directory : "/",
2431 prefix, c->root_directory ? c->root_directory : "/",
2432 prefix, yes_no(c->non_blocking),
2433 prefix, yes_no(c->private_tmp),
2434 prefix, yes_no(c->private_network),
2435 prefix, yes_no(c->private_devices),
2436 prefix, protect_home_to_string(c->protect_home),
2437 prefix, protect_system_to_string(c->protect_system),
2438 prefix, yes_no(c->ignore_sigpipe));
2439
2440 STRV_FOREACH(e, c->environment)
2441 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
2442
2443 STRV_FOREACH(e, c->environment_files)
2444 fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
2445
2446 STRV_FOREACH(e, c->pass_environment)
2447 fprintf(f, "%sPassEnvironment: %s\n", prefix, *e);
2448
2449 fprintf(f, "%sRuntimeDirectoryMode: %04o\n", prefix, c->runtime_directory_mode);
2450
2451 STRV_FOREACH(d, c->runtime_directory)
2452 fprintf(f, "%sRuntimeDirectory: %s\n", prefix, *d);
2453
2454 if (c->nice_set)
2455 fprintf(f,
2456 "%sNice: %i\n",
2457 prefix, c->nice);
2458
2459 if (c->oom_score_adjust_set)
2460 fprintf(f,
2461 "%sOOMScoreAdjust: %i\n",
2462 prefix, c->oom_score_adjust);
2463
2464 for (i = 0; i < RLIM_NLIMITS; i++)
2465 if (c->rlimit[i]) {
2466 fprintf(f, "%s%s: " RLIM_FMT "\n",
2467 prefix, rlimit_to_string(i), c->rlimit[i]->rlim_max);
2468 fprintf(f, "%s%sSoft: " RLIM_FMT "\n",
2469 prefix, rlimit_to_string(i), c->rlimit[i]->rlim_cur);
2470 }
2471
2472 if (c->ioprio_set) {
2473 _cleanup_free_ char *class_str = NULL;
2474
2475 ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str);
2476 fprintf(f,
2477 "%sIOSchedulingClass: %s\n"
2478 "%sIOPriority: %i\n",
2479 prefix, strna(class_str),
2480 prefix, (int) IOPRIO_PRIO_DATA(c->ioprio));
2481 }
2482
2483 if (c->cpu_sched_set) {
2484 _cleanup_free_ char *policy_str = NULL;
2485
2486 sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
2487 fprintf(f,
2488 "%sCPUSchedulingPolicy: %s\n"
2489 "%sCPUSchedulingPriority: %i\n"
2490 "%sCPUSchedulingResetOnFork: %s\n",
2491 prefix, strna(policy_str),
2492 prefix, c->cpu_sched_priority,
2493 prefix, yes_no(c->cpu_sched_reset_on_fork));
2494 }
2495
2496 if (c->cpuset) {
2497 fprintf(f, "%sCPUAffinity:", prefix);
2498 for (i = 0; i < c->cpuset_ncpus; i++)
2499 if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
2500 fprintf(f, " %u", i);
2501 fputs("\n", f);
2502 }
2503
2504 if (c->timer_slack_nsec != NSEC_INFINITY)
2505 fprintf(f, "%sTimerSlackNSec: "NSEC_FMT "\n", prefix, c->timer_slack_nsec);
2506
2507 fprintf(f,
2508 "%sStandardInput: %s\n"
2509 "%sStandardOutput: %s\n"
2510 "%sStandardError: %s\n",
2511 prefix, exec_input_to_string(c->std_input),
2512 prefix, exec_output_to_string(c->std_output),
2513 prefix, exec_output_to_string(c->std_error));
2514
2515 if (c->tty_path)
2516 fprintf(f,
2517 "%sTTYPath: %s\n"
2518 "%sTTYReset: %s\n"
2519 "%sTTYVHangup: %s\n"
2520 "%sTTYVTDisallocate: %s\n",
2521 prefix, c->tty_path,
2522 prefix, yes_no(c->tty_reset),
2523 prefix, yes_no(c->tty_vhangup),
2524 prefix, yes_no(c->tty_vt_disallocate));
2525
2526 if (c->std_output == EXEC_OUTPUT_SYSLOG ||
2527 c->std_output == EXEC_OUTPUT_KMSG ||
2528 c->std_output == EXEC_OUTPUT_JOURNAL ||
2529 c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
2530 c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
2531 c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE ||
2532 c->std_error == EXEC_OUTPUT_SYSLOG ||
2533 c->std_error == EXEC_OUTPUT_KMSG ||
2534 c->std_error == EXEC_OUTPUT_JOURNAL ||
2535 c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
2536 c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
2537 c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) {
2538
2539 _cleanup_free_ char *fac_str = NULL, *lvl_str = NULL;
2540
2541 log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str);
2542 log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str);
2543
2544 fprintf(f,
2545 "%sSyslogFacility: %s\n"
2546 "%sSyslogLevel: %s\n",
2547 prefix, strna(fac_str),
2548 prefix, strna(lvl_str));
2549 }
2550
2551 if (c->capabilities) {
2552 _cleanup_cap_free_charp_ char *t;
2553
2554 t = cap_to_text(c->capabilities, NULL);
2555 if (t)
2556 fprintf(f, "%sCapabilities: %s\n", prefix, t);
2557 }
2558
2559 if (c->secure_bits)
2560 fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n",
2561 prefix,
2562 (c->secure_bits & 1<<SECURE_KEEP_CAPS) ? " keep-caps" : "",
2563 (c->secure_bits & 1<<SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "",
2564 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "",
2565 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "",
2566 (c->secure_bits & 1<<SECURE_NOROOT) ? " noroot" : "",
2567 (c->secure_bits & 1<<SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
2568
2569 if (c->capability_bounding_set != CAP_ALL) {
2570 unsigned long l;
2571 fprintf(f, "%sCapabilityBoundingSet:", prefix);
2572
2573 for (l = 0; l <= cap_last_cap(); l++)
2574 if (c->capability_bounding_set & (UINT64_C(1) << l))
2575 fprintf(f, " %s", strna(capability_to_name(l)));
2576
2577 fputs("\n", f);
2578 }
2579
2580 if (c->capability_ambient_set != 0) {
2581 unsigned long l;
2582 fprintf(f, "%sAmbientCapabilities:", prefix);
2583
2584 for (l = 0; l <= cap_last_cap(); l++)
2585 if (c->capability_ambient_set & (UINT64_C(1) << l))
2586 fprintf(f, " %s", strna(capability_to_name(l)));
2587
2588 fputs("\n", f);
2589 }
2590
2591 if (c->user)
2592 fprintf(f, "%sUser: %s\n", prefix, c->user);
2593 if (c->group)
2594 fprintf(f, "%sGroup: %s\n", prefix, c->group);
2595
2596 if (strv_length(c->supplementary_groups) > 0) {
2597 fprintf(f, "%sSupplementaryGroups:", prefix);
2598 strv_fprintf(f, c->supplementary_groups);
2599 fputs("\n", f);
2600 }
2601
2602 if (c->pam_name)
2603 fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
2604
2605 if (strv_length(c->read_write_dirs) > 0) {
2606 fprintf(f, "%sReadWriteDirs:", prefix);
2607 strv_fprintf(f, c->read_write_dirs);
2608 fputs("\n", f);
2609 }
2610
2611 if (strv_length(c->read_only_dirs) > 0) {
2612 fprintf(f, "%sReadOnlyDirs:", prefix);
2613 strv_fprintf(f, c->read_only_dirs);
2614 fputs("\n", f);
2615 }
2616
2617 if (strv_length(c->inaccessible_dirs) > 0) {
2618 fprintf(f, "%sInaccessibleDirs:", prefix);
2619 strv_fprintf(f, c->inaccessible_dirs);
2620 fputs("\n", f);
2621 }
2622
2623 if (c->utmp_id)
2624 fprintf(f,
2625 "%sUtmpIdentifier: %s\n",
2626 prefix, c->utmp_id);
2627
2628 if (c->selinux_context)
2629 fprintf(f,
2630 "%sSELinuxContext: %s%s\n",
2631 prefix, c->selinux_context_ignore ? "-" : "", c->selinux_context);
2632
2633 if (c->personality != PERSONALITY_INVALID)
2634 fprintf(f,
2635 "%sPersonality: %s\n",
2636 prefix, strna(personality_to_string(c->personality)));
2637
2638 if (c->syscall_filter) {
2639#ifdef HAVE_SECCOMP
2640 Iterator j;
2641 void *id;
2642 bool first = true;
2643#endif
2644
2645 fprintf(f,
2646 "%sSystemCallFilter: ",
2647 prefix);
2648
2649 if (!c->syscall_whitelist)
2650 fputc('~', f);
2651
2652#ifdef HAVE_SECCOMP
2653 SET_FOREACH(id, c->syscall_filter, j) {
2654 _cleanup_free_ char *name = NULL;
2655
2656 if (first)
2657 first = false;
2658 else
2659 fputc(' ', f);
2660
2661 name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
2662 fputs(strna(name), f);
2663 }
2664#endif
2665
2666 fputc('\n', f);
2667 }
2668
2669 if (c->syscall_archs) {
2670#ifdef HAVE_SECCOMP
2671 Iterator j;
2672 void *id;
2673#endif
2674
2675 fprintf(f,
2676 "%sSystemCallArchitectures:",
2677 prefix);
2678
2679#ifdef HAVE_SECCOMP
2680 SET_FOREACH(id, c->syscall_archs, j)
2681 fprintf(f, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id) - 1)));
2682#endif
2683 fputc('\n', f);
2684 }
2685
2686 if (c->syscall_errno > 0)
2687 fprintf(f,
2688 "%sSystemCallErrorNumber: %s\n",
2689 prefix, strna(errno_to_name(c->syscall_errno)));
2690
2691 if (c->apparmor_profile)
2692 fprintf(f,
2693 "%sAppArmorProfile: %s%s\n",
2694 prefix, c->apparmor_profile_ignore ? "-" : "", c->apparmor_profile);
2695}
2696
2697bool exec_context_maintains_privileges(ExecContext *c) {
2698 assert(c);
2699
2700 /* Returns true if the process forked off would run run under
2701 * an unchanged UID or as root. */
2702
2703 if (!c->user)
2704 return true;
2705
2706 if (streq(c->user, "root") || streq(c->user, "0"))
2707 return true;
2708
2709 return false;
2710}
2711
2712void exec_status_start(ExecStatus *s, pid_t pid) {
2713 assert(s);
2714
2715 zero(*s);
2716 s->pid = pid;
2717 dual_timestamp_get(&s->start_timestamp);
2718}
2719
2720void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
2721 assert(s);
2722
2723 if (s->pid && s->pid != pid)
2724 zero(*s);
2725
2726 s->pid = pid;
2727 dual_timestamp_get(&s->exit_timestamp);
2728
2729 s->code = code;
2730 s->status = status;
2731
2732 if (context) {
2733 if (context->utmp_id)
2734 utmp_put_dead_process(context->utmp_id, pid, code, status);
2735
2736 exec_context_tty_reset(context);
2737 }
2738}
2739
2740void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
2741 char buf[FORMAT_TIMESTAMP_MAX];
2742
2743 assert(s);
2744 assert(f);
2745
2746 if (s->pid <= 0)
2747 return;
2748
2749 prefix = strempty(prefix);
2750
2751 fprintf(f,
2752 "%sPID: "PID_FMT"\n",
2753 prefix, s->pid);
2754
2755 if (s->start_timestamp.realtime > 0)
2756 fprintf(f,
2757 "%sStart Timestamp: %s\n",
2758 prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime));
2759
2760 if (s->exit_timestamp.realtime > 0)
2761 fprintf(f,
2762 "%sExit Timestamp: %s\n"
2763 "%sExit Code: %s\n"
2764 "%sExit Status: %i\n",
2765 prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime),
2766 prefix, sigchld_code_to_string(s->code),
2767 prefix, s->status);
2768}
2769
2770char *exec_command_line(char **argv) {
2771 size_t k;
2772 char *n, *p, **a;
2773 bool first = true;
2774
2775 assert(argv);
2776
2777 k = 1;
2778 STRV_FOREACH(a, argv)
2779 k += strlen(*a)+3;
2780
2781 if (!(n = new(char, k)))
2782 return NULL;
2783
2784 p = n;
2785 STRV_FOREACH(a, argv) {
2786
2787 if (!first)
2788 *(p++) = ' ';
2789 else
2790 first = false;
2791
2792 if (strpbrk(*a, WHITESPACE)) {
2793 *(p++) = '\'';
2794 p = stpcpy(p, *a);
2795 *(p++) = '\'';
2796 } else
2797 p = stpcpy(p, *a);
2798
2799 }
2800
2801 *p = 0;
2802
2803 /* FIXME: this doesn't really handle arguments that have
2804 * spaces and ticks in them */
2805
2806 return n;
2807}
2808
2809void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
2810 _cleanup_free_ char *cmd = NULL;
2811 const char *prefix2;
2812
2813 assert(c);
2814 assert(f);
2815
2816 prefix = strempty(prefix);
2817 prefix2 = strjoina(prefix, "\t");
2818
2819 cmd = exec_command_line(c->argv);
2820 fprintf(f,
2821 "%sCommand Line: %s\n",
2822 prefix, cmd ? cmd : strerror(ENOMEM));
2823
2824 exec_status_dump(&c->exec_status, f, prefix2);
2825}
2826
2827void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
2828 assert(f);
2829
2830 prefix = strempty(prefix);
2831
2832 LIST_FOREACH(command, c, c)
2833 exec_command_dump(c, f, prefix);
2834}
2835
2836void exec_command_append_list(ExecCommand **l, ExecCommand *e) {
2837 ExecCommand *end;
2838
2839 assert(l);
2840 assert(e);
2841
2842 if (*l) {
2843 /* It's kind of important, that we keep the order here */
2844 LIST_FIND_TAIL(command, *l, end);
2845 LIST_INSERT_AFTER(command, *l, end, e);
2846 } else
2847 *l = e;
2848}
2849
2850int exec_command_set(ExecCommand *c, const char *path, ...) {
2851 va_list ap;
2852 char **l, *p;
2853
2854 assert(c);
2855 assert(path);
2856
2857 va_start(ap, path);
2858 l = strv_new_ap(path, ap);
2859 va_end(ap);
2860
2861 if (!l)
2862 return -ENOMEM;
2863
2864 p = strdup(path);
2865 if (!p) {
2866 strv_free(l);
2867 return -ENOMEM;
2868 }
2869
2870 free(c->path);
2871 c->path = p;
2872
2873 strv_free(c->argv);
2874 c->argv = l;
2875
2876 return 0;
2877}
2878
2879int exec_command_append(ExecCommand *c, const char *path, ...) {
2880 _cleanup_strv_free_ char **l = NULL;
2881 va_list ap;
2882 int r;
2883
2884 assert(c);
2885 assert(path);
2886
2887 va_start(ap, path);
2888 l = strv_new_ap(path, ap);
2889 va_end(ap);
2890
2891 if (!l)
2892 return -ENOMEM;
2893
2894 r = strv_extend_strv(&c->argv, l, false);
2895 if (r < 0)
2896 return r;
2897
2898 return 0;
2899}
2900
2901
2902static int exec_runtime_allocate(ExecRuntime **rt) {
2903
2904 if (*rt)
2905 return 0;
2906
2907 *rt = new0(ExecRuntime, 1);
2908 if (!*rt)
2909 return -ENOMEM;
2910
2911 (*rt)->n_ref = 1;
2912 (*rt)->netns_storage_socket[0] = (*rt)->netns_storage_socket[1] = -1;
2913
2914 return 0;
2915}
2916
2917int exec_runtime_make(ExecRuntime **rt, ExecContext *c, const char *id) {
2918 int r;
2919
2920 assert(rt);
2921 assert(c);
2922 assert(id);
2923
2924 if (*rt)
2925 return 1;
2926
2927 if (!c->private_network && !c->private_tmp)
2928 return 0;
2929
2930 r = exec_runtime_allocate(rt);
2931 if (r < 0)
2932 return r;
2933
2934 if (c->private_network && (*rt)->netns_storage_socket[0] < 0) {
2935 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, (*rt)->netns_storage_socket) < 0)
2936 return -errno;
2937 }
2938
2939 if (c->private_tmp && !(*rt)->tmp_dir) {
2940 r = setup_tmp_dirs(id, &(*rt)->tmp_dir, &(*rt)->var_tmp_dir);
2941 if (r < 0)
2942 return r;
2943 }
2944
2945 return 1;
2946}
2947
2948ExecRuntime *exec_runtime_ref(ExecRuntime *r) {
2949 assert(r);
2950 assert(r->n_ref > 0);
2951
2952 r->n_ref++;
2953 return r;
2954}
2955
2956ExecRuntime *exec_runtime_unref(ExecRuntime *r) {
2957
2958 if (!r)
2959 return NULL;
2960
2961 assert(r->n_ref > 0);
2962
2963 r->n_ref--;
2964 if (r->n_ref > 0)
2965 return NULL;
2966
2967 free(r->tmp_dir);
2968 free(r->var_tmp_dir);
2969 safe_close_pair(r->netns_storage_socket);
2970 free(r);
2971
2972 return NULL;
2973}
2974
2975int exec_runtime_serialize(Unit *u, ExecRuntime *rt, FILE *f, FDSet *fds) {
2976 assert(u);
2977 assert(f);
2978 assert(fds);
2979
2980 if (!rt)
2981 return 0;
2982
2983 if (rt->tmp_dir)
2984 unit_serialize_item(u, f, "tmp-dir", rt->tmp_dir);
2985
2986 if (rt->var_tmp_dir)
2987 unit_serialize_item(u, f, "var-tmp-dir", rt->var_tmp_dir);
2988
2989 if (rt->netns_storage_socket[0] >= 0) {
2990 int copy;
2991
2992 copy = fdset_put_dup(fds, rt->netns_storage_socket[0]);
2993 if (copy < 0)
2994 return copy;
2995
2996 unit_serialize_item_format(u, f, "netns-socket-0", "%i", copy);
2997 }
2998
2999 if (rt->netns_storage_socket[1] >= 0) {
3000 int copy;
3001
3002 copy = fdset_put_dup(fds, rt->netns_storage_socket[1]);
3003 if (copy < 0)
3004 return copy;
3005
3006 unit_serialize_item_format(u, f, "netns-socket-1", "%i", copy);
3007 }
3008
3009 return 0;
3010}
3011
3012int exec_runtime_deserialize_item(Unit *u, ExecRuntime **rt, const char *key, const char *value, FDSet *fds) {
3013 int r;
3014
3015 assert(rt);
3016 assert(key);
3017 assert(value);
3018
3019 if (streq(key, "tmp-dir")) {
3020 char *copy;
3021
3022 r = exec_runtime_allocate(rt);
3023 if (r < 0)
3024 return log_oom();
3025
3026 copy = strdup(value);
3027 if (!copy)
3028 return log_oom();
3029
3030 free((*rt)->tmp_dir);
3031 (*rt)->tmp_dir = copy;
3032
3033 } else if (streq(key, "var-tmp-dir")) {
3034 char *copy;
3035
3036 r = exec_runtime_allocate(rt);
3037 if (r < 0)
3038 return log_oom();
3039
3040 copy = strdup(value);
3041 if (!copy)
3042 return log_oom();
3043
3044 free((*rt)->var_tmp_dir);
3045 (*rt)->var_tmp_dir = copy;
3046
3047 } else if (streq(key, "netns-socket-0")) {
3048 int fd;
3049
3050 r = exec_runtime_allocate(rt);
3051 if (r < 0)
3052 return log_oom();
3053
3054 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
3055 log_unit_debug(u, "Failed to parse netns socket value: %s", value);
3056 else {
3057 safe_close((*rt)->netns_storage_socket[0]);
3058 (*rt)->netns_storage_socket[0] = fdset_remove(fds, fd);
3059 }
3060 } else if (streq(key, "netns-socket-1")) {
3061 int fd;
3062
3063 r = exec_runtime_allocate(rt);
3064 if (r < 0)
3065 return log_oom();
3066
3067 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
3068 log_unit_debug(u, "Failed to parse netns socket value: %s", value);
3069 else {
3070 safe_close((*rt)->netns_storage_socket[1]);
3071 (*rt)->netns_storage_socket[1] = fdset_remove(fds, fd);
3072 }
3073 } else
3074 return 0;
3075
3076 return 1;
3077}
3078
3079static void *remove_tmpdir_thread(void *p) {
3080 _cleanup_free_ char *path = p;
3081
3082 (void) rm_rf(path, REMOVE_ROOT|REMOVE_PHYSICAL);
3083 return NULL;
3084}
3085
3086void exec_runtime_destroy(ExecRuntime *rt) {
3087 int r;
3088
3089 if (!rt)
3090 return;
3091
3092 /* If there are multiple users of this, let's leave the stuff around */
3093 if (rt->n_ref > 1)
3094 return;
3095
3096 if (rt->tmp_dir) {
3097 log_debug("Spawning thread to nuke %s", rt->tmp_dir);
3098
3099 r = asynchronous_job(remove_tmpdir_thread, rt->tmp_dir);
3100 if (r < 0) {
3101 log_warning_errno(r, "Failed to nuke %s: %m", rt->tmp_dir);
3102 free(rt->tmp_dir);
3103 }
3104
3105 rt->tmp_dir = NULL;
3106 }
3107
3108 if (rt->var_tmp_dir) {
3109 log_debug("Spawning thread to nuke %s", rt->var_tmp_dir);
3110
3111 r = asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir);
3112 if (r < 0) {
3113 log_warning_errno(r, "Failed to nuke %s: %m", rt->var_tmp_dir);
3114 free(rt->var_tmp_dir);
3115 }
3116
3117 rt->var_tmp_dir = NULL;
3118 }
3119
3120 safe_close_pair(rt->netns_storage_socket);
3121}
3122
3123static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
3124 [EXEC_INPUT_NULL] = "null",
3125 [EXEC_INPUT_TTY] = "tty",
3126 [EXEC_INPUT_TTY_FORCE] = "tty-force",
3127 [EXEC_INPUT_TTY_FAIL] = "tty-fail",
3128 [EXEC_INPUT_SOCKET] = "socket"
3129};
3130
3131DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
3132
3133static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
3134 [EXEC_OUTPUT_INHERIT] = "inherit",
3135 [EXEC_OUTPUT_NULL] = "null",
3136 [EXEC_OUTPUT_TTY] = "tty",
3137 [EXEC_OUTPUT_SYSLOG] = "syslog",
3138 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console",
3139 [EXEC_OUTPUT_KMSG] = "kmsg",
3140 [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
3141 [EXEC_OUTPUT_JOURNAL] = "journal",
3142 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
3143 [EXEC_OUTPUT_SOCKET] = "socket"
3144};
3145
3146DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);
3147
3148static const char* const exec_utmp_mode_table[_EXEC_UTMP_MODE_MAX] = {
3149 [EXEC_UTMP_INIT] = "init",
3150 [EXEC_UTMP_LOGIN] = "login",
3151 [EXEC_UTMP_USER] = "user",
3152};
3153
3154DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode, ExecUtmpMode);