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