]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/execute.c
Revert "tree-wide: Always use recvmsg with MSG_CMSG_CLOEXEC"
[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>
f2b68789 40#include <sys/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
d35fbf6b 1620 if (chdir(context->working_directory ? context->working_directory : "/") < 0) {
ff0af2a1 1621 *exit_status = EXIT_CHDIR;
d35fbf6b
DM
1622 return -errno;
1623 }
1624 } else {
1625 _cleanup_free_ char *d = NULL;
8aa75193 1626
d35fbf6b
DM
1627 if (asprintf(&d, "%s/%s",
1628 context->root_directory ? context->root_directory : "",
1629 context->working_directory ? context->working_directory : "") < 0) {
ff0af2a1 1630 *exit_status = EXIT_MEMORY;
d35fbf6b 1631 return -ENOMEM;
8aa75193 1632 }
8aa75193 1633
d35fbf6b 1634 if (chdir(d) < 0) {
ff0af2a1 1635 *exit_status = EXIT_CHDIR;
d35fbf6b
DM
1636 return -errno;
1637 }
1638 }
e66cf1a3 1639
9008e1ac
MS
1640#ifdef HAVE_SELINUX
1641 if (params->apply_permissions && mac_selinux_use() && params->selinux_context_net && socket_fd >= 0) {
ff0af2a1
LP
1642 r = mac_selinux_get_child_mls_label(socket_fd, command->path, context->selinux_context, &mac_selinux_context_net);
1643 if (r < 0) {
1644 *exit_status = EXIT_SELINUX_CONTEXT;
1645 return r;
9008e1ac
MS
1646 }
1647 }
1648#endif
1649
d35fbf6b
DM
1650 /* We repeat the fd closing here, to make sure that
1651 * nothing is leaked from the PAM modules. Note that
1652 * we are more aggressive this time since socket_fd
e44da745
DM
1653 * and the netns fds we don't need anymore. The custom
1654 * endpoint fd was needed to upload the policy and can
1655 * now be closed as well. */
ff0af2a1
LP
1656 r = close_all_fds(fds, n_fds);
1657 if (r >= 0)
1658 r = shift_fds(fds, n_fds);
1659 if (r >= 0)
1660 r = flags_fds(fds, n_fds, context->non_blocking);
1661 if (r < 0) {
1662 *exit_status = EXIT_FDS;
1663 return r;
d35fbf6b 1664 }
e66cf1a3 1665
d35fbf6b 1666 if (params->apply_permissions) {
e66cf1a3 1667
d35fbf6b
DM
1668 for (i = 0; i < _RLIMIT_MAX; i++) {
1669 if (!context->rlimit[i])
1670 continue;
1671
1672 if (setrlimit_closest(i, context->rlimit[i]) < 0) {
ff0af2a1 1673 *exit_status = EXIT_LIMITS;
d35fbf6b 1674 return -errno;
e66cf1a3
LP
1675 }
1676 }
1677
d35fbf6b 1678 if (context->capability_bounding_set_drop) {
ff0af2a1
LP
1679 r = capability_bounding_set_drop(context->capability_bounding_set_drop, false);
1680 if (r < 0) {
1681 *exit_status = EXIT_CAPABILITIES;
1682 return r;
3b8bddde 1683 }
4c2630eb 1684 }
3b8bddde 1685
2ca620c4
WC
1686#ifdef HAVE_SMACK
1687 if (context->smack_process_label) {
ff0af2a1
LP
1688 r = mac_smack_apply_pid(0, context->smack_process_label);
1689 if (r < 0) {
1690 *exit_status = EXIT_SMACK_PROCESS_LABEL;
1691 return r;
2ca620c4
WC
1692 }
1693 }
1694#endif
1695
d35fbf6b 1696 if (context->user) {
ff0af2a1
LP
1697 r = enforce_user(context, uid);
1698 if (r < 0) {
1699 *exit_status = EXIT_USER;
1700 return r;
5b6319dc
LP
1701 }
1702 }
d35fbf6b
DM
1703
1704 /* PR_GET_SECUREBITS is not privileged, while
1705 * PR_SET_SECUREBITS is. So to suppress
1706 * potential EPERMs we'll try not to call
1707 * PR_SET_SECUREBITS unless necessary. */
1708 if (prctl(PR_GET_SECUREBITS) != context->secure_bits)
1709 if (prctl(PR_SET_SECUREBITS, context->secure_bits) < 0) {
ff0af2a1 1710 *exit_status = EXIT_SECUREBITS;
d35fbf6b 1711 return -errno;
ff01d048 1712 }
5b6319dc 1713
d35fbf6b
DM
1714 if (context->capabilities)
1715 if (cap_set_proc(context->capabilities) < 0) {
ff0af2a1 1716 *exit_status = EXIT_CAPABILITIES;
d35fbf6b 1717 return -errno;
613b411c
LP
1718 }
1719
d35fbf6b
DM
1720 if (context->no_new_privileges)
1721 if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
ff0af2a1 1722 *exit_status = EXIT_NO_NEW_PRIVILEGES;
d35fbf6b
DM
1723 return -errno;
1724 }
1725
1726#ifdef HAVE_SECCOMP
1727 if (context->address_families_whitelist ||
1728 !set_isempty(context->address_families)) {
ff0af2a1
LP
1729 r = apply_address_families(context);
1730 if (r < 0) {
1731 *exit_status = EXIT_ADDRESS_FAMILIES;
1732 return r;
4c2630eb
MS
1733 }
1734 }
04aa0cb9 1735
d35fbf6b
DM
1736 if (context->syscall_whitelist ||
1737 !set_isempty(context->syscall_filter) ||
1738 !set_isempty(context->syscall_archs)) {
ff0af2a1
LP
1739 r = apply_seccomp(context);
1740 if (r < 0) {
1741 *exit_status = EXIT_SECCOMP;
1742 return r;
81a2b7ce 1743 }
d35fbf6b
DM
1744 }
1745#endif
81a2b7ce 1746
d35fbf6b 1747#ifdef HAVE_SELINUX
6baa7db0 1748 if (mac_selinux_use()) {
9008e1ac 1749 char *exec_context = mac_selinux_context_net ?: context->selinux_context;
16115b0a 1750
9008e1ac 1751 if (exec_context) {
ff0af2a1
LP
1752 r = setexeccon(exec_context);
1753 if (r < 0) {
1754 *exit_status = EXIT_SELINUX_CONTEXT;
1755 return r;
16115b0a 1756 }
81a2b7ce 1757 }
81a2b7ce 1758 }
d35fbf6b 1759#endif
81a2b7ce 1760
d35fbf6b 1761#ifdef HAVE_APPARMOR
6baa7db0 1762 if (context->apparmor_profile && mac_apparmor_use()) {
ff0af2a1
LP
1763 r = aa_change_onexec(context->apparmor_profile);
1764 if (r < 0 && !context->apparmor_profile_ignore) {
1765 *exit_status = EXIT_APPARMOR_PROFILE;
5482192e 1766 return -errno;
d35fbf6b 1767 }
034c6ed7 1768 }
d35fbf6b
DM
1769#endif
1770 }
034c6ed7 1771
ff0af2a1
LP
1772 r = build_environment(context, n_fds, params->watchdog_usec, home, username, shell, &our_env);
1773 if (r < 0) {
1774 *exit_status = EXIT_MEMORY;
1775 return r;
d35fbf6b 1776 }
034c6ed7 1777
d35fbf6b
DM
1778 final_env = strv_env_merge(5,
1779 params->environment,
1780 our_env,
1781 context->environment,
1782 files_env,
1783 pam_env,
1784 NULL);
1785 if (!final_env) {
ff0af2a1 1786 *exit_status = EXIT_MEMORY;
d35fbf6b
DM
1787 return -ENOMEM;
1788 }
81a2b7ce 1789
d35fbf6b
DM
1790 final_argv = replace_env_argv(argv, final_env);
1791 if (!final_argv) {
ff0af2a1 1792 *exit_status = EXIT_MEMORY;
d35fbf6b
DM
1793 return -ENOMEM;
1794 }
034c6ed7 1795
d35fbf6b 1796 final_env = strv_env_clean(final_env);
260abb78 1797
553d2243 1798 if (_unlikely_(log_get_max_level() >= LOG_DEBUG)) {
d35fbf6b 1799 _cleanup_free_ char *line;
81a2b7ce 1800
d35fbf6b
DM
1801 line = exec_command_line(final_argv);
1802 if (line) {
1803 log_open();
e2cc6eca
LP
1804 log_unit_struct(params->unit_id,
1805 LOG_DEBUG,
d35fbf6b 1806 "EXECUTABLE=%s", command->path,
e2cc6eca 1807 LOG_MESSAGE("Executing: %s", line),
d35fbf6b
DM
1808 NULL);
1809 log_close();
1810 }
1811 }
1812 execve(command->path, final_argv, final_env);
ff0af2a1 1813 *exit_status = EXIT_EXEC;
d35fbf6b
DM
1814 return -errno;
1815}
81a2b7ce 1816
d35fbf6b
DM
1817int exec_spawn(ExecCommand *command,
1818 const ExecContext *context,
1819 const ExecParameters *params,
1820 ExecRuntime *runtime,
1821 pid_t *ret) {
8351ceae 1822
d35fbf6b
DM
1823 _cleanup_strv_free_ char **files_env = NULL;
1824 int *fds = NULL; unsigned n_fds = 0;
ff0af2a1
LP
1825 _cleanup_free_ char *line = NULL;
1826 int socket_fd, r;
1827 char **argv;
d35fbf6b 1828 pid_t pid;
8351ceae 1829
d35fbf6b
DM
1830 assert(command);
1831 assert(context);
1832 assert(ret);
1833 assert(params);
1834 assert(params->fds || params->n_fds <= 0);
4298d0b5 1835
d35fbf6b
DM
1836 if (context->std_input == EXEC_INPUT_SOCKET ||
1837 context->std_output == EXEC_OUTPUT_SOCKET ||
1838 context->std_error == EXEC_OUTPUT_SOCKET) {
17df7223 1839
ff0af2a1
LP
1840 if (params->n_fds != 1) {
1841 log_unit_error(params->unit_id, "Got more than one socket.");
d35fbf6b 1842 return -EINVAL;
ff0af2a1 1843 }
eef65bf3 1844
d35fbf6b
DM
1845 socket_fd = params->fds[0];
1846 } else {
1847 socket_fd = -1;
1848 fds = params->fds;
1849 n_fds = params->n_fds;
1850 }
94f04347 1851
ff0af2a1
LP
1852 r = exec_context_load_environment(context, params->unit_id, &files_env);
1853 if (r < 0)
1854 return log_unit_error_errno(params->unit_id, r, "Failed to load environment files: %m");
034c6ed7 1855
d35fbf6b 1856 argv = params->argv ?: command->argv;
d35fbf6b
DM
1857 line = exec_command_line(argv);
1858 if (!line)
1859 return log_oom();
fab56fc5 1860
e2cc6eca
LP
1861 log_unit_struct(params->unit_id,
1862 LOG_DEBUG,
d35fbf6b 1863 "EXECUTABLE=%s", command->path,
e2cc6eca 1864 LOG_MESSAGE("About to execute: %s", line),
d35fbf6b 1865 NULL);
d35fbf6b
DM
1866 pid = fork();
1867 if (pid < 0)
ff0af2a1 1868 return log_unit_error_errno(params->unit_id, r, "Failed to fork: %m");
d35fbf6b
DM
1869
1870 if (pid == 0) {
ff0af2a1
LP
1871 int exit_status;
1872
1873 r = exec_child(command,
1874 context,
1875 params,
1876 runtime,
1877 argv,
1878 socket_fd,
1879 fds, n_fds,
1880 files_env,
1881 &exit_status);
1882 if (r < 0) {
4c2630eb 1883 log_open();
ff0af2a1
LP
1884 log_unit_struct(params->unit_id,
1885 LOG_ERR,
1886 LOG_MESSAGE_ID(SD_MESSAGE_SPAWN_FAILED),
1887 "EXECUTABLE=%s", command->path,
1888 LOG_MESSAGE("Failed at step %s spawning %s: %s",
1889 exit_status_to_string(exit_status, EXIT_STATUS_SYSTEMD),
1890 command->path, strerror(-r)),
1891 LOG_ERRNO(r),
1892 NULL);
4c2630eb
MS
1893 }
1894
ff0af2a1 1895 _exit(exit_status);
034c6ed7
LP
1896 }
1897
ff0af2a1 1898 log_unit_debug(params->unit_id, "Forked %s as "PID_FMT, command->path, pid);
23635a85 1899
80876c20
LP
1900 /* We add the new process to the cgroup both in the child (so
1901 * that we can be sure that no user code is ever executed
1902 * outside of the cgroup) and in the parent (so that we can be
1903 * sure that when we kill the cgroup the process will be
1904 * killed too). */
d35fbf6b
DM
1905 if (params->cgroup_path)
1906 cg_attach(SYSTEMD_CGROUP_CONTROLLER, params->cgroup_path, pid);
2da3263a 1907
b58b4116 1908 exec_status_start(&command->exec_status, pid);
9fb86720 1909
034c6ed7 1910 *ret = pid;
5cb5a6ff
LP
1911 return 0;
1912}
1913
034c6ed7
LP
1914void exec_context_init(ExecContext *c) {
1915 assert(c);
1916
4c12626c 1917 c->umask = 0022;
9eba9da4 1918 c->ioprio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_BE, 0);
94f04347 1919 c->cpu_sched_policy = SCHED_OTHER;
071830ff 1920 c->syslog_priority = LOG_DAEMON|LOG_INFO;
74922904 1921 c->syslog_level_prefix = true;
353e12c2 1922 c->ignore_sigpipe = true;
3a43da28 1923 c->timer_slack_nsec = NSEC_INFINITY;
ac45f971 1924 c->personality = 0xffffffffUL;
e66cf1a3 1925 c->runtime_directory_mode = 0755;
034c6ed7
LP
1926}
1927
613b411c 1928void exec_context_done(ExecContext *c) {
5cb5a6ff
LP
1929 unsigned l;
1930
1931 assert(c);
1932
1933 strv_free(c->environment);
034c6ed7 1934 c->environment = NULL;
5cb5a6ff 1935
8c7be95e
LP
1936 strv_free(c->environment_files);
1937 c->environment_files = NULL;
1938
034c6ed7 1939 for (l = 0; l < ELEMENTSOF(c->rlimit); l++) {
5cb5a6ff 1940 free(c->rlimit[l]);
034c6ed7
LP
1941 c->rlimit[l] = NULL;
1942 }
1943
9eba9da4
LP
1944 free(c->working_directory);
1945 c->working_directory = NULL;
1946 free(c->root_directory);
1947 c->root_directory = NULL;
5cb5a6ff 1948
80876c20
LP
1949 free(c->tty_path);
1950 c->tty_path = NULL;
1951
071830ff
LP
1952 free(c->syslog_identifier);
1953 c->syslog_identifier = NULL;
1954
5cb5a6ff 1955 free(c->user);
034c6ed7
LP
1956 c->user = NULL;
1957
5cb5a6ff 1958 free(c->group);
034c6ed7
LP
1959 c->group = NULL;
1960
1961 strv_free(c->supplementary_groups);
1962 c->supplementary_groups = NULL;
94f04347 1963
5b6319dc
LP
1964 free(c->pam_name);
1965 c->pam_name = NULL;
1966
94f04347
LP
1967 if (c->capabilities) {
1968 cap_free(c->capabilities);
1969 c->capabilities = NULL;
1970 }
15ae422b
LP
1971
1972 strv_free(c->read_only_dirs);
1973 c->read_only_dirs = NULL;
1974
1975 strv_free(c->read_write_dirs);
1976 c->read_write_dirs = NULL;
1977
1978 strv_free(c->inaccessible_dirs);
1979 c->inaccessible_dirs = NULL;
82c121a4
LP
1980
1981 if (c->cpuset)
1982 CPU_FREE(c->cpuset);
86a3475b
LP
1983
1984 free(c->utmp_id);
1985 c->utmp_id = NULL;
b9a0e010 1986
7b52a628
MS
1987 free(c->selinux_context);
1988 c->selinux_context = NULL;
1989
eef65bf3
MS
1990 free(c->apparmor_profile);
1991 c->apparmor_profile = NULL;
1992
17df7223
LP
1993 set_free(c->syscall_filter);
1994 c->syscall_filter = NULL;
57183d11
LP
1995
1996 set_free(c->syscall_archs);
1997 c->syscall_archs = NULL;
4298d0b5
LP
1998
1999 set_free(c->address_families);
2000 c->address_families = NULL;
e66cf1a3
LP
2001
2002 strv_free(c->runtime_directory);
2003 c->runtime_directory = NULL;
bb7dd0b0
DM
2004
2005 bus_endpoint_free(c->bus_endpoint);
2006 c->bus_endpoint = NULL;
e66cf1a3
LP
2007}
2008
2009int exec_context_destroy_runtime_directory(ExecContext *c, const char *runtime_prefix) {
2010 char **i;
2011
2012 assert(c);
2013
2014 if (!runtime_prefix)
2015 return 0;
2016
2017 STRV_FOREACH(i, c->runtime_directory) {
2018 _cleanup_free_ char *p;
2019
2020 p = strjoin(runtime_prefix, "/", *i, NULL);
2021 if (!p)
2022 return -ENOMEM;
2023
2024 /* We execute this synchronously, since we need to be
2025 * sure this is gone when we start the service
2026 * next. */
24167f3d 2027 rm_rf(p, false, true, false);
e66cf1a3
LP
2028 }
2029
2030 return 0;
5cb5a6ff
LP
2031}
2032
43d0fcbd
LP
2033void exec_command_done(ExecCommand *c) {
2034 assert(c);
2035
2036 free(c->path);
2037 c->path = NULL;
2038
2039 strv_free(c->argv);
2040 c->argv = NULL;
2041}
2042
2043void exec_command_done_array(ExecCommand *c, unsigned n) {
2044 unsigned i;
2045
2046 for (i = 0; i < n; i++)
2047 exec_command_done(c+i);
2048}
2049
f1acf85a 2050ExecCommand* exec_command_free_list(ExecCommand *c) {
5cb5a6ff
LP
2051 ExecCommand *i;
2052
2053 while ((i = c)) {
71fda00f 2054 LIST_REMOVE(command, c, i);
43d0fcbd 2055 exec_command_done(i);
5cb5a6ff
LP
2056 free(i);
2057 }
f1acf85a
ZJS
2058
2059 return NULL;
5cb5a6ff
LP
2060}
2061
034c6ed7
LP
2062void exec_command_free_array(ExecCommand **c, unsigned n) {
2063 unsigned i;
2064
f1acf85a
ZJS
2065 for (i = 0; i < n; i++)
2066 c[i] = exec_command_free_list(c[i]);
034c6ed7
LP
2067}
2068
039f0e70
LP
2069typedef struct InvalidEnvInfo {
2070 const char *unit_id;
2071 const char *path;
2072} InvalidEnvInfo;
2073
2074static void invalid_env(const char *p, void *userdata) {
2075 InvalidEnvInfo *info = userdata;
2076
2077 log_unit_error(info->unit_id, "Ignoring invalid environment assignment '%s': %s", p, info->path);
2078}
2079
7491ccf2 2080int exec_context_load_environment(const ExecContext *c, const char *unit_id, char ***l) {
8c7be95e
LP
2081 char **i, **r = NULL;
2082
2083 assert(c);
2084 assert(l);
2085
2086 STRV_FOREACH(i, c->environment_files) {
2087 char *fn;
2088 int k;
2089 bool ignore = false;
2090 char **p;
7fd1b19b 2091 _cleanup_globfree_ glob_t pglob = {};
2bef10ab 2092 int count, n;
8c7be95e
LP
2093
2094 fn = *i;
2095
2096 if (fn[0] == '-') {
2097 ignore = true;
2098 fn ++;
2099 }
2100
2101 if (!path_is_absolute(fn)) {
8c7be95e
LP
2102 if (ignore)
2103 continue;
2104
2105 strv_free(r);
2106 return -EINVAL;
2107 }
2108
2bef10ab 2109 /* Filename supports globbing, take all matching files */
2bef10ab
PL
2110 errno = 0;
2111 if (glob(fn, 0, NULL, &pglob) != 0) {
2bef10ab
PL
2112 if (ignore)
2113 continue;
8c7be95e 2114
2bef10ab
PL
2115 strv_free(r);
2116 return errno ? -errno : -EINVAL;
2117 }
2118 count = pglob.gl_pathc;
2119 if (count == 0) {
8c7be95e
LP
2120 if (ignore)
2121 continue;
2122
2123 strv_free(r);
2bef10ab 2124 return -EINVAL;
8c7be95e 2125 }
2bef10ab 2126 for (n = 0; n < count; n++) {
717603e3 2127 k = load_env_file(NULL, pglob.gl_pathv[n], NULL, &p);
2bef10ab
PL
2128 if (k < 0) {
2129 if (ignore)
2130 continue;
8c7be95e 2131
2bef10ab 2132 strv_free(r);
2bef10ab 2133 return k;
e9c1ea9d 2134 }
ebc05a09 2135 /* Log invalid environment variables with filename */
039f0e70
LP
2136 if (p) {
2137 InvalidEnvInfo info = {
2138 .unit_id = unit_id,
2139 .path = pglob.gl_pathv[n]
2140 };
2141
2142 p = strv_env_clean_with_callback(p, invalid_env, &info);
2143 }
8c7be95e 2144
2bef10ab
PL
2145 if (r == NULL)
2146 r = p;
2147 else {
2148 char **m;
8c7be95e 2149
2bef10ab
PL
2150 m = strv_env_merge(2, r, p);
2151 strv_free(r);
2152 strv_free(p);
c84a9488 2153 if (!m)
2bef10ab 2154 return -ENOMEM;
2bef10ab
PL
2155
2156 r = m;
2157 }
8c7be95e
LP
2158 }
2159 }
2160
2161 *l = r;
2162
2163 return 0;
2164}
2165
6ac8fdc9 2166static bool tty_may_match_dev_console(const char *tty) {
e1d75803
RC
2167 _cleanup_free_ char *active = NULL;
2168 char *console;
6ac8fdc9
MS
2169
2170 if (startswith(tty, "/dev/"))
2171 tty += 5;
2172
2173 /* trivial identity? */
2174 if (streq(tty, "console"))
2175 return true;
2176
2177 console = resolve_dev_console(&active);
2178 /* if we could not resolve, assume it may */
2179 if (!console)
2180 return true;
2181
2182 /* "tty0" means the active VC, so it may be the same sometimes */
e1d75803 2183 return streq(console, tty) || (streq(console, "tty0") && tty_is_vc(tty));
6ac8fdc9
MS
2184}
2185
2186bool exec_context_may_touch_console(ExecContext *ec) {
2187 return (ec->tty_reset || ec->tty_vhangup || ec->tty_vt_disallocate ||
2188 is_terminal_input(ec->std_input) ||
2189 is_terminal_output(ec->std_output) ||
2190 is_terminal_output(ec->std_error)) &&
2191 tty_may_match_dev_console(tty_path(ec));
2192}
2193
15ae422b
LP
2194static void strv_fprintf(FILE *f, char **l) {
2195 char **g;
2196
2197 assert(f);
2198
2199 STRV_FOREACH(g, l)
2200 fprintf(f, " %s", *g);
2201}
2202
5cb5a6ff 2203void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
507f22bd 2204 char **e;
94f04347 2205 unsigned i;
9eba9da4 2206
5cb5a6ff
LP
2207 assert(c);
2208 assert(f);
2209
4ad49000 2210 prefix = strempty(prefix);
5cb5a6ff
LP
2211
2212 fprintf(f,
94f04347
LP
2213 "%sUMask: %04o\n"
2214 "%sWorkingDirectory: %s\n"
451a074f 2215 "%sRootDirectory: %s\n"
15ae422b 2216 "%sNonBlocking: %s\n"
64747e2d 2217 "%sPrivateTmp: %s\n"
4819ff03 2218 "%sPrivateNetwork: %s\n"
7f112f50 2219 "%sPrivateDevices: %s\n"
1b8689f9
LP
2220 "%sProtectHome: %s\n"
2221 "%sProtectSystem: %s\n"
3bb07b76 2222 "%sIgnoreSIGPIPE: %s\n",
5cb5a6ff 2223 prefix, c->umask,
9eba9da4 2224 prefix, c->working_directory ? c->working_directory : "/",
451a074f 2225 prefix, c->root_directory ? c->root_directory : "/",
15ae422b 2226 prefix, yes_no(c->non_blocking),
64747e2d 2227 prefix, yes_no(c->private_tmp),
4819ff03 2228 prefix, yes_no(c->private_network),
7f112f50 2229 prefix, yes_no(c->private_devices),
1b8689f9
LP
2230 prefix, protect_home_to_string(c->protect_home),
2231 prefix, protect_system_to_string(c->protect_system),
3bb07b76 2232 prefix, yes_no(c->ignore_sigpipe));
fb33a393 2233
8c7be95e
LP
2234 STRV_FOREACH(e, c->environment)
2235 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
2236
2237 STRV_FOREACH(e, c->environment_files)
2238 fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
94f04347 2239
fb33a393
LP
2240 if (c->nice_set)
2241 fprintf(f,
2242 "%sNice: %i\n",
2243 prefix, c->nice);
2244
dd6c17b1 2245 if (c->oom_score_adjust_set)
fb33a393 2246 fprintf(f,
dd6c17b1
LP
2247 "%sOOMScoreAdjust: %i\n",
2248 prefix, c->oom_score_adjust);
9eba9da4 2249
94f04347
LP
2250 for (i = 0; i < RLIM_NLIMITS; i++)
2251 if (c->rlimit[i])
de0671ee
ZJS
2252 fprintf(f, "%s%s: "RLIM_FMT"\n",
2253 prefix, rlimit_to_string(i), c->rlimit[i]->rlim_max);
94f04347 2254
f8b69d1d 2255 if (c->ioprio_set) {
1756a011 2256 _cleanup_free_ char *class_str = NULL;
f8b69d1d 2257
1756a011 2258 ioprio_class_to_string_alloc(IOPRIO_PRIO_CLASS(c->ioprio), &class_str);
9eba9da4
LP
2259 fprintf(f,
2260 "%sIOSchedulingClass: %s\n"
2261 "%sIOPriority: %i\n",
f8b69d1d 2262 prefix, strna(class_str),
9eba9da4 2263 prefix, (int) IOPRIO_PRIO_DATA(c->ioprio));
f8b69d1d 2264 }
94f04347 2265
f8b69d1d 2266 if (c->cpu_sched_set) {
1756a011 2267 _cleanup_free_ char *policy_str = NULL;
f8b69d1d 2268
1756a011 2269 sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
94f04347
LP
2270 fprintf(f,
2271 "%sCPUSchedulingPolicy: %s\n"
38b48754
LP
2272 "%sCPUSchedulingPriority: %i\n"
2273 "%sCPUSchedulingResetOnFork: %s\n",
f8b69d1d 2274 prefix, strna(policy_str),
38b48754
LP
2275 prefix, c->cpu_sched_priority,
2276 prefix, yes_no(c->cpu_sched_reset_on_fork));
b929bf04 2277 }
94f04347 2278
82c121a4 2279 if (c->cpuset) {
94f04347 2280 fprintf(f, "%sCPUAffinity:", prefix);
82c121a4
LP
2281 for (i = 0; i < c->cpuset_ncpus; i++)
2282 if (CPU_ISSET_S(i, CPU_ALLOC_SIZE(c->cpuset_ncpus), c->cpuset))
43a99a7a 2283 fprintf(f, " %u", i);
94f04347
LP
2284 fputs("\n", f);
2285 }
2286
3a43da28 2287 if (c->timer_slack_nsec != NSEC_INFINITY)
ccd06097 2288 fprintf(f, "%sTimerSlackNSec: "NSEC_FMT "\n", prefix, c->timer_slack_nsec);
94f04347
LP
2289
2290 fprintf(f,
80876c20
LP
2291 "%sStandardInput: %s\n"
2292 "%sStandardOutput: %s\n"
2293 "%sStandardError: %s\n",
2294 prefix, exec_input_to_string(c->std_input),
2295 prefix, exec_output_to_string(c->std_output),
2296 prefix, exec_output_to_string(c->std_error));
2297
2298 if (c->tty_path)
2299 fprintf(f,
6ea832a2
LP
2300 "%sTTYPath: %s\n"
2301 "%sTTYReset: %s\n"
2302 "%sTTYVHangup: %s\n"
2303 "%sTTYVTDisallocate: %s\n",
2304 prefix, c->tty_path,
2305 prefix, yes_no(c->tty_reset),
2306 prefix, yes_no(c->tty_vhangup),
2307 prefix, yes_no(c->tty_vt_disallocate));
94f04347 2308
5ce70e5b
ZJS
2309 if (c->std_output == EXEC_OUTPUT_SYSLOG ||
2310 c->std_output == EXEC_OUTPUT_KMSG ||
2311 c->std_output == EXEC_OUTPUT_JOURNAL ||
2312 c->std_output == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
2313 c->std_output == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
2314 c->std_output == EXEC_OUTPUT_JOURNAL_AND_CONSOLE ||
2315 c->std_error == EXEC_OUTPUT_SYSLOG ||
2316 c->std_error == EXEC_OUTPUT_KMSG ||
2317 c->std_error == EXEC_OUTPUT_JOURNAL ||
2318 c->std_error == EXEC_OUTPUT_SYSLOG_AND_CONSOLE ||
2319 c->std_error == EXEC_OUTPUT_KMSG_AND_CONSOLE ||
2320 c->std_error == EXEC_OUTPUT_JOURNAL_AND_CONSOLE) {
f8b69d1d 2321
5ce70e5b 2322 _cleanup_free_ char *fac_str = NULL, *lvl_str = NULL;
f8b69d1d 2323
5ce70e5b
ZJS
2324 log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str);
2325 log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str);
f8b69d1d 2326
94f04347
LP
2327 fprintf(f,
2328 "%sSyslogFacility: %s\n"
2329 "%sSyslogLevel: %s\n",
f8b69d1d
MS
2330 prefix, strna(fac_str),
2331 prefix, strna(lvl_str));
f8b69d1d 2332 }
94f04347
LP
2333
2334 if (c->capabilities) {
5ce70e5b
ZJS
2335 _cleanup_cap_free_charp_ char *t;
2336
2337 t = cap_to_text(c->capabilities, NULL);
2338 if (t)
2339 fprintf(f, "%sCapabilities: %s\n", prefix, t);
94f04347
LP
2340 }
2341
2342 if (c->secure_bits)
2343 fprintf(f, "%sSecure Bits:%s%s%s%s%s%s\n",
2344 prefix,
cbb21cca
ZJS
2345 (c->secure_bits & 1<<SECURE_KEEP_CAPS) ? " keep-caps" : "",
2346 (c->secure_bits & 1<<SECURE_KEEP_CAPS_LOCKED) ? " keep-caps-locked" : "",
2347 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP) ? " no-setuid-fixup" : "",
2348 (c->secure_bits & 1<<SECURE_NO_SETUID_FIXUP_LOCKED) ? " no-setuid-fixup-locked" : "",
2349 (c->secure_bits & 1<<SECURE_NOROOT) ? " noroot" : "",
2350 (c->secure_bits & 1<<SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
94f04347
LP
2351
2352 if (c->capability_bounding_set_drop) {
ae556c21 2353 unsigned long l;
260abb78 2354 fprintf(f, "%sCapabilityBoundingSet:", prefix);
94f04347 2355
64685e0c 2356 for (l = 0; l <= cap_last_cap(); l++)
2822da4f
LP
2357 if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) l)))
2358 fprintf(f, " %s", strna(capability_to_name(l)));
94f04347
LP
2359
2360 fputs("\n", f);
2361 }
2362
2363 if (c->user)
f2d3769a 2364 fprintf(f, "%sUser: %s\n", prefix, c->user);
94f04347 2365 if (c->group)
f2d3769a 2366 fprintf(f, "%sGroup: %s\n", prefix, c->group);
94f04347 2367
15ae422b 2368 if (strv_length(c->supplementary_groups) > 0) {
94f04347 2369 fprintf(f, "%sSupplementaryGroups:", prefix);
15ae422b
LP
2370 strv_fprintf(f, c->supplementary_groups);
2371 fputs("\n", f);
2372 }
94f04347 2373
5b6319dc 2374 if (c->pam_name)
f2d3769a 2375 fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
5b6319dc 2376
15ae422b
LP
2377 if (strv_length(c->read_write_dirs) > 0) {
2378 fprintf(f, "%sReadWriteDirs:", prefix);
2379 strv_fprintf(f, c->read_write_dirs);
2380 fputs("\n", f);
2381 }
2382
2383 if (strv_length(c->read_only_dirs) > 0) {
2384 fprintf(f, "%sReadOnlyDirs:", prefix);
2385 strv_fprintf(f, c->read_only_dirs);
2386 fputs("\n", f);
2387 }
94f04347 2388
15ae422b
LP
2389 if (strv_length(c->inaccessible_dirs) > 0) {
2390 fprintf(f, "%sInaccessibleDirs:", prefix);
2391 strv_fprintf(f, c->inaccessible_dirs);
94f04347
LP
2392 fputs("\n", f);
2393 }
2e22afe9 2394
169c1bda
LP
2395 if (c->utmp_id)
2396 fprintf(f,
2397 "%sUtmpIdentifier: %s\n",
2398 prefix, c->utmp_id);
7b52a628
MS
2399
2400 if (c->selinux_context)
2401 fprintf(f,
5f8640fb
LP
2402 "%sSELinuxContext: %s%s\n",
2403 prefix, c->selinux_context_ignore ? "-" : "", c->selinux_context);
17df7223 2404
ac45f971
LP
2405 if (c->personality != 0xffffffffUL)
2406 fprintf(f,
2407 "%sPersonality: %s\n",
2408 prefix, strna(personality_to_string(c->personality)));
2409
17df7223 2410 if (c->syscall_filter) {
351a19b1 2411#ifdef HAVE_SECCOMP
17df7223
LP
2412 Iterator j;
2413 void *id;
2414 bool first = true;
351a19b1 2415#endif
17df7223
LP
2416
2417 fprintf(f,
57183d11 2418 "%sSystemCallFilter: ",
17df7223
LP
2419 prefix);
2420
2421 if (!c->syscall_whitelist)
2422 fputc('~', f);
2423
351a19b1 2424#ifdef HAVE_SECCOMP
17df7223
LP
2425 SET_FOREACH(id, c->syscall_filter, j) {
2426 _cleanup_free_ char *name = NULL;
2427
2428 if (first)
2429 first = false;
2430 else
2431 fputc(' ', f);
2432
57183d11 2433 name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
17df7223
LP
2434 fputs(strna(name), f);
2435 }
351a19b1 2436#endif
17df7223
LP
2437
2438 fputc('\n', f);
2439 }
2440
57183d11
LP
2441 if (c->syscall_archs) {
2442#ifdef HAVE_SECCOMP
2443 Iterator j;
2444 void *id;
2445#endif
2446
2447 fprintf(f,
2448 "%sSystemCallArchitectures:",
2449 prefix);
2450
2451#ifdef HAVE_SECCOMP
2452 SET_FOREACH(id, c->syscall_archs, j)
2453 fprintf(f, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id) - 1)));
2454#endif
2455 fputc('\n', f);
2456 }
2457
17df7223
LP
2458 if (c->syscall_errno != 0)
2459 fprintf(f,
2460 "%sSystemCallErrorNumber: %s\n",
2461 prefix, strna(errno_to_name(c->syscall_errno)));
eef65bf3
MS
2462
2463 if (c->apparmor_profile)
2464 fprintf(f,
2465 "%sAppArmorProfile: %s%s\n",
2466 prefix, c->apparmor_profile_ignore ? "-" : "", c->apparmor_profile);
5cb5a6ff
LP
2467}
2468
a931ad47
LP
2469bool exec_context_maintains_privileges(ExecContext *c) {
2470 assert(c);
2471
2472 /* Returns true if the process forked off would run run under
2473 * an unchanged UID or as root. */
2474
2475 if (!c->user)
2476 return true;
2477
2478 if (streq(c->user, "root") || streq(c->user, "0"))
2479 return true;
2480
2481 return false;
2482}
2483
b58b4116 2484void exec_status_start(ExecStatus *s, pid_t pid) {
034c6ed7 2485 assert(s);
5cb5a6ff 2486
b58b4116
LP
2487 zero(*s);
2488 s->pid = pid;
2489 dual_timestamp_get(&s->start_timestamp);
2490}
2491
6ea832a2 2492void exec_status_exit(ExecStatus *s, ExecContext *context, pid_t pid, int code, int status) {
b58b4116
LP
2493 assert(s);
2494
0b1f4ae6 2495 if (s->pid && s->pid != pid)
b58b4116
LP
2496 zero(*s);
2497
034c6ed7 2498 s->pid = pid;
63983207 2499 dual_timestamp_get(&s->exit_timestamp);
9fb86720 2500
034c6ed7
LP
2501 s->code = code;
2502 s->status = status;
169c1bda 2503
6ea832a2
LP
2504 if (context) {
2505 if (context->utmp_id)
2506 utmp_put_dead_process(context->utmp_id, pid, code, status);
2507
2508 exec_context_tty_reset(context);
2509 }
9fb86720
LP
2510}
2511
2512void exec_status_dump(ExecStatus *s, FILE *f, const char *prefix) {
2513 char buf[FORMAT_TIMESTAMP_MAX];
2514
2515 assert(s);
2516 assert(f);
2517
9fb86720
LP
2518 if (s->pid <= 0)
2519 return;
2520
4c940960
LP
2521 prefix = strempty(prefix);
2522
9fb86720 2523 fprintf(f,
ccd06097
ZJS
2524 "%sPID: "PID_FMT"\n",
2525 prefix, s->pid);
9fb86720 2526
63983207 2527 if (s->start_timestamp.realtime > 0)
9fb86720
LP
2528 fprintf(f,
2529 "%sStart Timestamp: %s\n",
63983207 2530 prefix, format_timestamp(buf, sizeof(buf), s->start_timestamp.realtime));
9fb86720 2531
63983207 2532 if (s->exit_timestamp.realtime > 0)
9fb86720
LP
2533 fprintf(f,
2534 "%sExit Timestamp: %s\n"
2535 "%sExit Code: %s\n"
2536 "%sExit Status: %i\n",
63983207 2537 prefix, format_timestamp(buf, sizeof(buf), s->exit_timestamp.realtime),
9fb86720
LP
2538 prefix, sigchld_code_to_string(s->code),
2539 prefix, s->status);
5cb5a6ff 2540}
44d8db9e 2541
9e2f7c11 2542char *exec_command_line(char **argv) {
44d8db9e
LP
2543 size_t k;
2544 char *n, *p, **a;
2545 bool first = true;
2546
9e2f7c11 2547 assert(argv);
44d8db9e 2548
9164977d 2549 k = 1;
9e2f7c11 2550 STRV_FOREACH(a, argv)
44d8db9e
LP
2551 k += strlen(*a)+3;
2552
2553 if (!(n = new(char, k)))
2554 return NULL;
2555
2556 p = n;
9e2f7c11 2557 STRV_FOREACH(a, argv) {
44d8db9e
LP
2558
2559 if (!first)
2560 *(p++) = ' ';
2561 else
2562 first = false;
2563
2564 if (strpbrk(*a, WHITESPACE)) {
2565 *(p++) = '\'';
2566 p = stpcpy(p, *a);
2567 *(p++) = '\'';
2568 } else
2569 p = stpcpy(p, *a);
2570
2571 }
2572
9164977d
LP
2573 *p = 0;
2574
44d8db9e
LP
2575 /* FIXME: this doesn't really handle arguments that have
2576 * spaces and ticks in them */
2577
2578 return n;
2579}
2580
2581void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
e1d75803 2582 _cleanup_free_ char *cmd = NULL;
4c940960 2583 const char *prefix2;
44d8db9e
LP
2584
2585 assert(c);
2586 assert(f);
2587
4c940960 2588 prefix = strempty(prefix);
63c372cb 2589 prefix2 = strjoina(prefix, "\t");
44d8db9e 2590
9e2f7c11 2591 cmd = exec_command_line(c->argv);
44d8db9e
LP
2592 fprintf(f,
2593 "%sCommand Line: %s\n",
2594 prefix, cmd ? cmd : strerror(ENOMEM));
2595
9fb86720 2596 exec_status_dump(&c->exec_status, f, prefix2);
44d8db9e
LP
2597}
2598
2599void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
2600 assert(f);
2601
4c940960 2602 prefix = strempty(prefix);
44d8db9e
LP
2603
2604 LIST_FOREACH(command, c, c)
2605 exec_command_dump(c, f, prefix);
2606}
94f04347 2607
a6a80b4f
LP
2608void exec_command_append_list(ExecCommand **l, ExecCommand *e) {
2609 ExecCommand *end;
2610
2611 assert(l);
2612 assert(e);
2613
2614 if (*l) {
35b8ca3a 2615 /* It's kind of important, that we keep the order here */
71fda00f
LP
2616 LIST_FIND_TAIL(command, *l, end);
2617 LIST_INSERT_AFTER(command, *l, end, e);
a6a80b4f
LP
2618 } else
2619 *l = e;
2620}
2621
26fd040d
LP
2622int exec_command_set(ExecCommand *c, const char *path, ...) {
2623 va_list ap;
2624 char **l, *p;
2625
2626 assert(c);
2627 assert(path);
2628
2629 va_start(ap, path);
2630 l = strv_new_ap(path, ap);
2631 va_end(ap);
2632
2633 if (!l)
2634 return -ENOMEM;
2635
250a918d
LP
2636 p = strdup(path);
2637 if (!p) {
26fd040d
LP
2638 strv_free(l);
2639 return -ENOMEM;
2640 }
2641
2642 free(c->path);
2643 c->path = p;
2644
2645 strv_free(c->argv);
2646 c->argv = l;
2647
2648 return 0;
2649}
2650
86b23b07 2651int exec_command_append(ExecCommand *c, const char *path, ...) {
e63ff941 2652 _cleanup_strv_free_ char **l = NULL;
86b23b07 2653 va_list ap;
86b23b07
JS
2654 int r;
2655
2656 assert(c);
2657 assert(path);
2658
2659 va_start(ap, path);
2660 l = strv_new_ap(path, ap);
2661 va_end(ap);
2662
2663 if (!l)
2664 return -ENOMEM;
2665
2666 r = strv_extend_strv(&c->argv, l);
e63ff941 2667 if (r < 0)
86b23b07 2668 return r;
86b23b07
JS
2669
2670 return 0;
2671}
2672
2673
613b411c
LP
2674static int exec_runtime_allocate(ExecRuntime **rt) {
2675
2676 if (*rt)
2677 return 0;
2678
2679 *rt = new0(ExecRuntime, 1);
f146f5e1 2680 if (!*rt)
613b411c
LP
2681 return -ENOMEM;
2682
2683 (*rt)->n_ref = 1;
2684 (*rt)->netns_storage_socket[0] = (*rt)->netns_storage_socket[1] = -1;
2685
2686 return 0;
2687}
2688
2689int exec_runtime_make(ExecRuntime **rt, ExecContext *c, const char *id) {
2690 int r;
2691
2692 assert(rt);
2693 assert(c);
2694 assert(id);
2695
2696 if (*rt)
2697 return 1;
2698
2699 if (!c->private_network && !c->private_tmp)
2700 return 0;
2701
2702 r = exec_runtime_allocate(rt);
2703 if (r < 0)
2704 return r;
2705
2706 if (c->private_network && (*rt)->netns_storage_socket[0] < 0) {
2707 if (socketpair(AF_UNIX, SOCK_DGRAM, 0, (*rt)->netns_storage_socket) < 0)
2708 return -errno;
2709 }
2710
2711 if (c->private_tmp && !(*rt)->tmp_dir) {
2712 r = setup_tmp_dirs(id, &(*rt)->tmp_dir, &(*rt)->var_tmp_dir);
2713 if (r < 0)
2714 return r;
2715 }
2716
2717 return 1;
2718}
2719
2720ExecRuntime *exec_runtime_ref(ExecRuntime *r) {
2721 assert(r);
2722 assert(r->n_ref > 0);
2723
2724 r->n_ref++;
2725 return r;
2726}
2727
2728ExecRuntime *exec_runtime_unref(ExecRuntime *r) {
2729
2730 if (!r)
2731 return NULL;
2732
2733 assert(r->n_ref > 0);
2734
2735 r->n_ref--;
2736 if (r->n_ref <= 0) {
2737 free(r->tmp_dir);
2738 free(r->var_tmp_dir);
3d94f76c 2739 safe_close_pair(r->netns_storage_socket);
613b411c
LP
2740 free(r);
2741 }
2742
2743 return NULL;
2744}
2745
2746int exec_runtime_serialize(ExecRuntime *rt, Unit *u, FILE *f, FDSet *fds) {
2747 assert(u);
2748 assert(f);
2749 assert(fds);
2750
2751 if (!rt)
2752 return 0;
2753
2754 if (rt->tmp_dir)
2755 unit_serialize_item(u, f, "tmp-dir", rt->tmp_dir);
2756
2757 if (rt->var_tmp_dir)
2758 unit_serialize_item(u, f, "var-tmp-dir", rt->var_tmp_dir);
2759
2760 if (rt->netns_storage_socket[0] >= 0) {
2761 int copy;
2762
2763 copy = fdset_put_dup(fds, rt->netns_storage_socket[0]);
2764 if (copy < 0)
2765 return copy;
2766
2767 unit_serialize_item_format(u, f, "netns-socket-0", "%i", copy);
2768 }
2769
2770 if (rt->netns_storage_socket[1] >= 0) {
2771 int copy;
2772
2773 copy = fdset_put_dup(fds, rt->netns_storage_socket[1]);
2774 if (copy < 0)
2775 return copy;
2776
2777 unit_serialize_item_format(u, f, "netns-socket-1", "%i", copy);
2778 }
2779
2780 return 0;
2781}
2782
2783int exec_runtime_deserialize_item(ExecRuntime **rt, Unit *u, const char *key, const char *value, FDSet *fds) {
2784 int r;
2785
2786 assert(rt);
2787 assert(key);
2788 assert(value);
2789
2790 if (streq(key, "tmp-dir")) {
2791 char *copy;
2792
2793 r = exec_runtime_allocate(rt);
2794 if (r < 0)
2795 return r;
2796
2797 copy = strdup(value);
2798 if (!copy)
2799 return log_oom();
2800
2801 free((*rt)->tmp_dir);
2802 (*rt)->tmp_dir = copy;
2803
2804 } else if (streq(key, "var-tmp-dir")) {
2805 char *copy;
2806
2807 r = exec_runtime_allocate(rt);
2808 if (r < 0)
2809 return r;
2810
2811 copy = strdup(value);
2812 if (!copy)
2813 return log_oom();
2814
2815 free((*rt)->var_tmp_dir);
2816 (*rt)->var_tmp_dir = copy;
2817
2818 } else if (streq(key, "netns-socket-0")) {
2819 int fd;
2820
2821 r = exec_runtime_allocate(rt);
2822 if (r < 0)
2823 return r;
2824
2825 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
79008bdd 2826 log_unit_debug(u->id, "Failed to parse netns socket value %s", value);
613b411c 2827 else {
03e334a1 2828 safe_close((*rt)->netns_storage_socket[0]);
613b411c
LP
2829 (*rt)->netns_storage_socket[0] = fdset_remove(fds, fd);
2830 }
2831 } else if (streq(key, "netns-socket-1")) {
2832 int fd;
2833
2834 r = exec_runtime_allocate(rt);
2835 if (r < 0)
2836 return r;
2837
2838 if (safe_atoi(value, &fd) < 0 || !fdset_contains(fds, fd))
79008bdd 2839 log_unit_debug(u->id, "Failed to parse netns socket value %s", value);
613b411c 2840 else {
03e334a1 2841 safe_close((*rt)->netns_storage_socket[1]);
613b411c
LP
2842 (*rt)->netns_storage_socket[1] = fdset_remove(fds, fd);
2843 }
2844 } else
2845 return 0;
2846
2847 return 1;
2848}
2849
2850static void *remove_tmpdir_thread(void *p) {
2851 _cleanup_free_ char *path = p;
2852
2853 rm_rf_dangerous(path, false, true, false);
2854 return NULL;
2855}
2856
2857void exec_runtime_destroy(ExecRuntime *rt) {
98b47d54
LP
2858 int r;
2859
613b411c
LP
2860 if (!rt)
2861 return;
2862
2863 /* If there are multiple users of this, let's leave the stuff around */
2864 if (rt->n_ref > 1)
2865 return;
2866
2867 if (rt->tmp_dir) {
2868 log_debug("Spawning thread to nuke %s", rt->tmp_dir);
98b47d54
LP
2869
2870 r = asynchronous_job(remove_tmpdir_thread, rt->tmp_dir);
2871 if (r < 0) {
da927ba9 2872 log_warning_errno(r, "Failed to nuke %s: %m", rt->tmp_dir);
98b47d54
LP
2873 free(rt->tmp_dir);
2874 }
2875
613b411c
LP
2876 rt->tmp_dir = NULL;
2877 }
2878
2879 if (rt->var_tmp_dir) {
2880 log_debug("Spawning thread to nuke %s", rt->var_tmp_dir);
98b47d54
LP
2881
2882 r = asynchronous_job(remove_tmpdir_thread, rt->var_tmp_dir);
2883 if (r < 0) {
da927ba9 2884 log_warning_errno(r, "Failed to nuke %s: %m", rt->var_tmp_dir);
98b47d54
LP
2885 free(rt->var_tmp_dir);
2886 }
2887
613b411c
LP
2888 rt->var_tmp_dir = NULL;
2889 }
2890
3d94f76c 2891 safe_close_pair(rt->netns_storage_socket);
613b411c
LP
2892}
2893
80876c20
LP
2894static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
2895 [EXEC_INPUT_NULL] = "null",
2896 [EXEC_INPUT_TTY] = "tty",
2897 [EXEC_INPUT_TTY_FORCE] = "tty-force",
4f2d528d
LP
2898 [EXEC_INPUT_TTY_FAIL] = "tty-fail",
2899 [EXEC_INPUT_SOCKET] = "socket"
80876c20
LP
2900};
2901
8a0867d6
LP
2902DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
2903
94f04347 2904static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
80876c20 2905 [EXEC_OUTPUT_INHERIT] = "inherit",
94f04347 2906 [EXEC_OUTPUT_NULL] = "null",
80876c20 2907 [EXEC_OUTPUT_TTY] = "tty",
94f04347 2908 [EXEC_OUTPUT_SYSLOG] = "syslog",
28dbc1e8 2909 [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console",
9a6bca7a 2910 [EXEC_OUTPUT_KMSG] = "kmsg",
28dbc1e8 2911 [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
706343f4
LP
2912 [EXEC_OUTPUT_JOURNAL] = "journal",
2913 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
4f2d528d 2914 [EXEC_OUTPUT_SOCKET] = "socket"
94f04347
LP
2915};
2916
2917DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);