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