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