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