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