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