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