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