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