]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/execute.c
Merge pull request #29558 from mrc0mmand/varlinkctl-tests
[thirdparty/systemd.git] / src / core / execute.c
1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <poll.h>
6 #include <sys/file.h>
7 #include <sys/mman.h>
8 #include <sys/personality.h>
9 #include <sys/prctl.h>
10 #include <sys/shm.h>
11 #include <sys/types.h>
12 #include <sys/un.h>
13 #include <unistd.h>
14 #include <utmpx.h>
15
16 #include <linux/fs.h> /* Must be included after <sys/mount.h> */
17
18 #include "sd-messages.h"
19
20 #include "af-list.h"
21 #include "alloc-util.h"
22 #include "async.h"
23 #include "cap-list.h"
24 #include "capability-util.h"
25 #include "cgroup-setup.h"
26 #include "constants.h"
27 #include "cpu-set-util.h"
28 #include "env-file.h"
29 #include "env-util.h"
30 #include "errno-list.h"
31 #include "escape.h"
32 #include "exec-credential.h"
33 #include "execute.h"
34 #include "execute-serialize.h"
35 #include "exit-status.h"
36 #include "fd-util.h"
37 #include "fileio.h"
38 #include "format-util.h"
39 #include "glob-util.h"
40 #include "hexdecoct.h"
41 #include "ioprio-util.h"
42 #include "lock-util.h"
43 #include "log.h"
44 #include "macro.h"
45 #include "manager.h"
46 #include "manager-dump.h"
47 #include "memory-util.h"
48 #include "missing_fs.h"
49 #include "missing_prctl.h"
50 #include "mkdir-label.h"
51 #include "namespace.h"
52 #include "parse-util.h"
53 #include "path-util.h"
54 #include "process-util.h"
55 #include "rlimit-util.h"
56 #include "rm-rf.h"
57 #include "seccomp-util.h"
58 #include "securebits-util.h"
59 #include "selinux-util.h"
60 #include "serialize.h"
61 #include "sort-util.h"
62 #include "special.h"
63 #include "stat-util.h"
64 #include "string-table.h"
65 #include "string-util.h"
66 #include "strv.h"
67 #include "syslog-util.h"
68 #include "terminal-util.h"
69 #include "tmpfile-util.h"
70 #include "umask-util.h"
71 #include "unit-serialize.h"
72 #include "user-util.h"
73 #include "utmp-wtmp.h"
74
75 const char *exec_context_tty_path(const ExecContext *context) {
76 assert(context);
77
78 if (context->stdio_as_fds)
79 return NULL;
80
81 if (context->tty_path)
82 return context->tty_path;
83
84 return "/dev/console";
85 }
86
87 int exec_context_tty_size(const ExecContext *context, unsigned *ret_rows, unsigned *ret_cols) {
88 unsigned rows, cols;
89 const char *tty;
90
91 assert(context);
92 assert(ret_rows);
93 assert(ret_cols);
94
95 rows = context->tty_rows;
96 cols = context->tty_cols;
97
98 tty = exec_context_tty_path(context);
99 if (tty)
100 (void) proc_cmdline_tty_size(tty, rows == UINT_MAX ? &rows : NULL, cols == UINT_MAX ? &cols : NULL);
101
102 *ret_rows = rows;
103 *ret_cols = cols;
104
105 return 0;
106 }
107
108 void exec_context_tty_reset(const ExecContext *context, const ExecParameters *p) {
109 _cleanup_close_ int fd = -EBADF;
110 const char *path = exec_context_tty_path(ASSERT_PTR(context));
111
112 /* Take a lock around the device for the duration of the setup that we do here.
113 * systemd-vconsole-setup.service also takes the lock to avoid being interrupted.
114 * We open a new fd that will be closed automatically, and operate on it for convenience.
115 */
116
117 if (p && p->stdin_fd >= 0) {
118 fd = xopenat_lock(p->stdin_fd, NULL,
119 O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY, 0, 0, LOCK_BSD, LOCK_EX);
120 if (fd < 0)
121 return;
122 } else if (path) {
123 fd = open_terminal(path, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NONBLOCK);
124 if (fd < 0)
125 return;
126
127 if (lock_generic(fd, LOCK_BSD, LOCK_EX) < 0)
128 return;
129 } else
130 return; /* nothing to do */
131
132 if (context->tty_vhangup)
133 (void) terminal_vhangup_fd(fd);
134
135 if (context->tty_reset)
136 (void) reset_terminal_fd(fd, true);
137
138 if (p && p->stdin_fd >= 0) {
139 unsigned rows = context->tty_rows, cols = context->tty_cols;
140
141 (void) exec_context_tty_size(context, &rows, &cols);
142 (void) terminal_set_size_fd(p->stdin_fd, path, rows, cols);
143 }
144
145 if (context->tty_vt_disallocate && path)
146 (void) vt_disallocate(path);
147 }
148
149 static bool is_terminal_input(ExecInput i) {
150 return IN_SET(i,
151 EXEC_INPUT_TTY,
152 EXEC_INPUT_TTY_FORCE,
153 EXEC_INPUT_TTY_FAIL);
154 }
155
156 static bool is_terminal_output(ExecOutput o) {
157 return IN_SET(o,
158 EXEC_OUTPUT_TTY,
159 EXEC_OUTPUT_KMSG_AND_CONSOLE,
160 EXEC_OUTPUT_JOURNAL_AND_CONSOLE);
161 }
162
163 bool exec_needs_network_namespace(const ExecContext *context) {
164 assert(context);
165
166 return context->private_network || context->network_namespace_path;
167 }
168
169 static bool exec_needs_ephemeral(const ExecContext *context) {
170 return (context->root_image || context->root_directory) && context->root_ephemeral;
171 }
172
173 bool exec_needs_ipc_namespace(const ExecContext *context) {
174 assert(context);
175
176 return context->private_ipc || context->ipc_namespace_path;
177 }
178
179 bool exec_needs_mount_namespace(
180 const ExecContext *context,
181 const ExecParameters *params,
182 const ExecRuntime *runtime) {
183
184 assert(context);
185
186 if (context->root_image)
187 return true;
188
189 if (!strv_isempty(context->read_write_paths) ||
190 !strv_isempty(context->read_only_paths) ||
191 !strv_isempty(context->inaccessible_paths) ||
192 !strv_isempty(context->exec_paths) ||
193 !strv_isempty(context->no_exec_paths))
194 return true;
195
196 if (context->n_bind_mounts > 0)
197 return true;
198
199 if (context->n_temporary_filesystems > 0)
200 return true;
201
202 if (context->n_mount_images > 0)
203 return true;
204
205 if (context->n_extension_images > 0)
206 return true;
207
208 if (!strv_isempty(context->extension_directories))
209 return true;
210
211 if (!IN_SET(context->mount_propagation_flag, 0, MS_SHARED))
212 return true;
213
214 if (context->private_tmp && runtime && runtime->shared && (runtime->shared->tmp_dir || runtime->shared->var_tmp_dir))
215 return true;
216
217 if (context->private_devices ||
218 context->private_mounts > 0 ||
219 (context->private_mounts < 0 && exec_needs_network_namespace(context)) ||
220 context->protect_system != PROTECT_SYSTEM_NO ||
221 context->protect_home != PROTECT_HOME_NO ||
222 context->protect_kernel_tunables ||
223 context->protect_kernel_modules ||
224 context->protect_kernel_logs ||
225 context->protect_control_groups ||
226 context->protect_proc != PROTECT_PROC_DEFAULT ||
227 context->proc_subset != PROC_SUBSET_ALL ||
228 exec_needs_ipc_namespace(context))
229 return true;
230
231 if (context->root_directory) {
232 if (exec_context_get_effective_mount_apivfs(context))
233 return true;
234
235 for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
236 if (params && !params->prefix[t])
237 continue;
238
239 if (context->directories[t].n_items > 0)
240 return true;
241 }
242 }
243
244 if (context->dynamic_user &&
245 (context->directories[EXEC_DIRECTORY_STATE].n_items > 0 ||
246 context->directories[EXEC_DIRECTORY_CACHE].n_items > 0 ||
247 context->directories[EXEC_DIRECTORY_LOGS].n_items > 0))
248 return true;
249
250 if (context->log_namespace)
251 return true;
252
253 return false;
254 }
255
256 bool exec_directory_is_private(const ExecContext *context, ExecDirectoryType type) {
257 assert(context);
258
259 if (!context->dynamic_user)
260 return false;
261
262 if (type == EXEC_DIRECTORY_CONFIGURATION)
263 return false;
264
265 if (type == EXEC_DIRECTORY_RUNTIME && context->runtime_directory_preserve_mode == EXEC_PRESERVE_NO)
266 return false;
267
268 return true;
269 }
270
271 int exec_params_get_cgroup_path(
272 const ExecParameters *params,
273 const CGroupContext *c,
274 char **ret) {
275
276 const char *subgroup = NULL;
277 char *p;
278
279 assert(params);
280 assert(ret);
281
282 if (!params->cgroup_path)
283 return -EINVAL;
284
285 /* If we are called for a unit where cgroup delegation is on, and the payload created its own populated
286 * subcgroup (which we expect it to do, after all it asked for delegation), then we cannot place the control
287 * processes started after the main unit's process in the unit's main cgroup because it is now an inner one,
288 * and inner cgroups may not contain processes. Hence, if delegation is on, and this is a control process,
289 * let's use ".control" as subcgroup instead. Note that we do so only for ExecStartPost=, ExecReload=,
290 * ExecStop=, ExecStopPost=, i.e. for the commands where the main process is already forked. For ExecStartPre=
291 * this is not necessary, the cgroup is still empty. We distinguish these cases with the EXEC_CONTROL_CGROUP
292 * flag, which is only passed for the former statements, not for the latter. */
293
294 if (FLAGS_SET(params->flags, EXEC_CGROUP_DELEGATE) && (FLAGS_SET(params->flags, EXEC_CONTROL_CGROUP) || c->delegate_subgroup)) {
295 if (FLAGS_SET(params->flags, EXEC_IS_CONTROL))
296 subgroup = ".control";
297 else
298 subgroup = c->delegate_subgroup;
299 }
300
301 if (subgroup)
302 p = path_join(params->cgroup_path, subgroup);
303 else
304 p = strdup(params->cgroup_path);
305 if (!p)
306 return -ENOMEM;
307
308 *ret = p;
309 return !!subgroup;
310 }
311
312 bool exec_context_get_cpu_affinity_from_numa(const ExecContext *c) {
313 assert(c);
314
315 return c->cpu_affinity_from_numa;
316 }
317
318 static void log_command_line(Unit *unit, const char *msg, const char *executable, char **argv) {
319 assert(unit);
320 assert(msg);
321 assert(executable);
322
323 if (!DEBUG_LOGGING)
324 return;
325
326 _cleanup_free_ char *cmdline = quote_command_line(argv, SHELL_ESCAPE_EMPTY);
327
328 log_unit_struct(unit, LOG_DEBUG,
329 "EXECUTABLE=%s", executable,
330 LOG_UNIT_MESSAGE(unit, "%s: %s", msg, strnull(cmdline)),
331 LOG_UNIT_INVOCATION_ID(unit));
332 }
333
334 static int exec_context_load_environment(const Unit *unit, const ExecContext *c, char ***l);
335
336 int exec_spawn(Unit *unit,
337 ExecCommand *command,
338 const ExecContext *context,
339 ExecParameters *params,
340 ExecRuntime *runtime,
341 const CGroupContext *cgroup_context,
342 pid_t *ret) {
343
344 char serialization_fd_number[DECIMAL_STR_MAX(int) + 1];
345 _cleanup_free_ char *subcgroup_path = NULL, *log_level = NULL, *executor_path = NULL;
346 _cleanup_fdset_free_ FDSet *fdset = NULL;
347 _cleanup_fclose_ FILE *f = NULL;
348 pid_t pid;
349 int r;
350
351 assert(unit);
352 assert(unit->manager);
353 assert(unit->manager->executor_fd >= 0);
354 assert(command);
355 assert(context);
356 assert(ret);
357 assert(params);
358 assert(params->fds || (params->n_socket_fds + params->n_storage_fds <= 0));
359 assert(!params->files_env); /* We fill this field, ensure it comes NULL-initialized to us */
360
361 LOG_CONTEXT_PUSH_UNIT(unit);
362
363 r = exec_context_load_environment(unit, context, &params->files_env);
364 if (r < 0)
365 return log_unit_error_errno(unit, r, "Failed to load environment files: %m");
366
367 /* Fork with up-to-date SELinux label database, so the child inherits the up-to-date db
368 and, until the next SELinux policy changes, we save further reloads in future children. */
369 mac_selinux_maybe_reload();
370
371 /* We won't know the real executable path until we create the mount namespace in the child, but we
372 want to log from the parent, so we use the possibly inaccurate path here. */
373 log_command_line(unit, "About to execute", command->path, command->argv);
374
375 if (params->cgroup_path) {
376 r = exec_params_get_cgroup_path(params, cgroup_context, &subcgroup_path);
377 if (r < 0)
378 return log_unit_error_errno(unit, r, "Failed to acquire subcgroup path: %m");
379 if (r > 0) {
380 /* If there's a subcgroup, then let's create it here now (the main cgroup was already
381 * realized by the unit logic) */
382
383 r = cg_create(SYSTEMD_CGROUP_CONTROLLER, subcgroup_path);
384 if (r < 0)
385 return log_unit_error_errno(unit, r, "Failed to create subcgroup '%s': %m", subcgroup_path);
386 }
387 }
388
389 /* In order to avoid copy-on-write traps and OOM-kills when pid1's memory.current is above the
390 * child's memory.max, serialize all the state needed to start the unit, and pass it to the
391 * systemd-executor binary. clone() with CLONE_VM + CLONE_VFORK will pause the parent until the exec
392 * and ensure all memory is shared. The child immediately execs the new binary so the delay should
393 * be minimal. Once glibc provides a clone3 wrapper we can switch to that, and clone directly in the
394 * target cgroup. */
395
396 r = open_serialization_file("sd-executor-state", &f);
397 if (r < 0)
398 return log_unit_error_errno(unit, r, "Failed to open serialization stream: %m");
399
400 fdset = fdset_new();
401 if (!fdset)
402 return log_oom();
403
404 r = exec_serialize_invocation(f, fdset, context, command, params, runtime, cgroup_context);
405 if (r < 0)
406 return log_unit_error_errno(unit, r, "Failed to serialize parameters: %m");
407
408 if (fseeko(f, 0, SEEK_SET) == (off_t) -1)
409 return log_unit_error_errno(unit, errno, "Failed to reseek on serialization stream: %m");
410
411 r = fd_cloexec(fileno(f), false);
412 if (r < 0)
413 return log_unit_error_errno(unit, r, "Failed to set O_CLOEXEC on serialization fd: %m");
414
415 r = fdset_cloexec(fdset, false);
416 if (r < 0)
417 return log_unit_error_errno(unit, r, "Failed to set O_CLOEXEC on serialized fds: %m");
418
419 r = log_level_to_string_alloc(log_get_max_level(), &log_level);
420 if (r < 0)
421 return log_unit_error_errno(unit, r, "Failed to convert log level to string: %m");
422
423 r = fd_get_path(unit->manager->executor_fd, &executor_path);
424 if (r < 0)
425 return log_unit_error_errno(unit, r, "Failed to get executor path from fd: %m");
426
427 xsprintf(serialization_fd_number, "%i", fileno(f));
428
429 /* The executor binary is pinned, to avoid compatibility problems during upgrades. */
430 r = posix_spawn_wrapper(
431 FORMAT_PROC_FD_PATH(unit->manager->executor_fd),
432 STRV_MAKE(executor_path,
433 "--deserialize", serialization_fd_number,
434 "--log-level", log_level,
435 "--log-target", log_target_to_string(manager_get_executor_log_target(unit->manager))),
436 environ,
437 &pid);
438 if (r < 0)
439 return log_unit_error_errno(unit, r, "Failed to spawn executor: %m");
440
441 log_unit_debug(unit, "Forked %s as "PID_FMT, command->path, pid);
442
443 /* We add the new process to the cgroup both in the child (so that we can be sure that no user code is ever
444 * executed outside of the cgroup) and in the parent (so that we can be sure that when we kill the cgroup the
445 * process will be killed too). */
446 if (subcgroup_path)
447 (void) cg_attach(SYSTEMD_CGROUP_CONTROLLER, subcgroup_path, pid);
448
449 exec_status_start(&command->exec_status, pid);
450
451 *ret = pid;
452 return 0;
453 }
454
455 void exec_context_init(ExecContext *c) {
456 assert(c);
457
458 /* When initializing a bool member to 'true', make sure to serialize in execute-serialize.c using
459 * serialize_bool() instead of serialize_bool_elide(). */
460
461 *c = (ExecContext) {
462 .umask = 0022,
463 .ioprio = IOPRIO_DEFAULT_CLASS_AND_PRIO,
464 .cpu_sched_policy = SCHED_OTHER,
465 .syslog_priority = LOG_DAEMON|LOG_INFO,
466 .syslog_level_prefix = true,
467 .ignore_sigpipe = true,
468 .timer_slack_nsec = NSEC_INFINITY,
469 .personality = PERSONALITY_INVALID,
470 .timeout_clean_usec = USEC_INFINITY,
471 .capability_bounding_set = CAP_MASK_UNSET,
472 .restrict_namespaces = NAMESPACE_FLAGS_INITIAL,
473 .log_level_max = -1,
474 #if HAVE_SECCOMP
475 .syscall_errno = SECCOMP_ERROR_NUMBER_KILL,
476 #endif
477 .tty_rows = UINT_MAX,
478 .tty_cols = UINT_MAX,
479 .private_mounts = -1,
480 .memory_ksm = -1,
481 .set_login_environment = -1,
482 };
483
484 FOREACH_ARRAY(d, c->directories, _EXEC_DIRECTORY_TYPE_MAX)
485 d->mode = 0755;
486
487 numa_policy_reset(&c->numa_policy);
488
489 assert_cc(NAMESPACE_FLAGS_INITIAL != NAMESPACE_FLAGS_ALL);
490 }
491
492 void exec_context_done(ExecContext *c) {
493 assert(c);
494
495 c->environment = strv_free(c->environment);
496 c->environment_files = strv_free(c->environment_files);
497 c->pass_environment = strv_free(c->pass_environment);
498 c->unset_environment = strv_free(c->unset_environment);
499
500 rlimit_free_all(c->rlimit);
501
502 for (size_t l = 0; l < 3; l++) {
503 c->stdio_fdname[l] = mfree(c->stdio_fdname[l]);
504 c->stdio_file[l] = mfree(c->stdio_file[l]);
505 }
506
507 c->working_directory = mfree(c->working_directory);
508 c->root_directory = mfree(c->root_directory);
509 c->root_image = mfree(c->root_image);
510 c->root_image_options = mount_options_free_all(c->root_image_options);
511 c->root_hash = mfree(c->root_hash);
512 c->root_hash_size = 0;
513 c->root_hash_path = mfree(c->root_hash_path);
514 c->root_hash_sig = mfree(c->root_hash_sig);
515 c->root_hash_sig_size = 0;
516 c->root_hash_sig_path = mfree(c->root_hash_sig_path);
517 c->root_verity = mfree(c->root_verity);
518 c->extension_images = mount_image_free_many(c->extension_images, &c->n_extension_images);
519 c->extension_directories = strv_free(c->extension_directories);
520 c->tty_path = mfree(c->tty_path);
521 c->syslog_identifier = mfree(c->syslog_identifier);
522 c->user = mfree(c->user);
523 c->group = mfree(c->group);
524
525 c->supplementary_groups = strv_free(c->supplementary_groups);
526
527 c->pam_name = mfree(c->pam_name);
528
529 c->read_only_paths = strv_free(c->read_only_paths);
530 c->read_write_paths = strv_free(c->read_write_paths);
531 c->inaccessible_paths = strv_free(c->inaccessible_paths);
532 c->exec_paths = strv_free(c->exec_paths);
533 c->no_exec_paths = strv_free(c->no_exec_paths);
534 c->exec_search_path = strv_free(c->exec_search_path);
535
536 bind_mount_free_many(c->bind_mounts, c->n_bind_mounts);
537 c->bind_mounts = NULL;
538 c->n_bind_mounts = 0;
539 temporary_filesystem_free_many(c->temporary_filesystems, c->n_temporary_filesystems);
540 c->temporary_filesystems = NULL;
541 c->n_temporary_filesystems = 0;
542 c->mount_images = mount_image_free_many(c->mount_images, &c->n_mount_images);
543
544 cpu_set_reset(&c->cpu_set);
545 numa_policy_reset(&c->numa_policy);
546
547 c->utmp_id = mfree(c->utmp_id);
548 c->selinux_context = mfree(c->selinux_context);
549 c->apparmor_profile = mfree(c->apparmor_profile);
550 c->smack_process_label = mfree(c->smack_process_label);
551
552 c->restrict_filesystems = set_free_free(c->restrict_filesystems);
553
554 c->syscall_filter = hashmap_free(c->syscall_filter);
555 c->syscall_archs = set_free(c->syscall_archs);
556 c->address_families = set_free(c->address_families);
557
558 for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++)
559 exec_directory_done(&c->directories[t]);
560
561 c->log_level_max = -1;
562
563 exec_context_free_log_extra_fields(c);
564 c->log_filter_allowed_patterns = set_free_free(c->log_filter_allowed_patterns);
565 c->log_filter_denied_patterns = set_free_free(c->log_filter_denied_patterns);
566
567 c->log_ratelimit_interval_usec = 0;
568 c->log_ratelimit_burst = 0;
569
570 c->stdin_data = mfree(c->stdin_data);
571 c->stdin_data_size = 0;
572
573 c->network_namespace_path = mfree(c->network_namespace_path);
574 c->ipc_namespace_path = mfree(c->ipc_namespace_path);
575
576 c->log_namespace = mfree(c->log_namespace);
577
578 c->load_credentials = hashmap_free(c->load_credentials);
579 c->set_credentials = hashmap_free(c->set_credentials);
580 c->import_credentials = set_free_free(c->import_credentials);
581
582 c->root_image_policy = image_policy_free(c->root_image_policy);
583 c->mount_image_policy = image_policy_free(c->mount_image_policy);
584 c->extension_image_policy = image_policy_free(c->extension_image_policy);
585 }
586
587 int exec_context_destroy_runtime_directory(const ExecContext *c, const char *runtime_prefix) {
588 assert(c);
589
590 if (!runtime_prefix)
591 return 0;
592
593 FOREACH_ARRAY(i, c->directories[EXEC_DIRECTORY_RUNTIME].items, c->directories[EXEC_DIRECTORY_RUNTIME].n_items) {
594 _cleanup_free_ char *p = NULL;
595
596 if (exec_directory_is_private(c, EXEC_DIRECTORY_RUNTIME))
597 p = path_join(runtime_prefix, "private", i->path);
598 else
599 p = path_join(runtime_prefix, i->path);
600 if (!p)
601 return -ENOMEM;
602
603 /* We execute this synchronously, since we need to be sure this is gone when we start the
604 * service next. */
605 (void) rm_rf(p, REMOVE_ROOT);
606
607 STRV_FOREACH(symlink, i->symlinks) {
608 _cleanup_free_ char *symlink_abs = NULL;
609
610 if (exec_directory_is_private(c, EXEC_DIRECTORY_RUNTIME))
611 symlink_abs = path_join(runtime_prefix, "private", *symlink);
612 else
613 symlink_abs = path_join(runtime_prefix, *symlink);
614 if (!symlink_abs)
615 return -ENOMEM;
616
617 (void) unlink(symlink_abs);
618 }
619 }
620
621 return 0;
622 }
623
624 int exec_context_destroy_mount_ns_dir(Unit *u) {
625 _cleanup_free_ char *p = NULL;
626
627 if (!u || !MANAGER_IS_SYSTEM(u->manager))
628 return 0;
629
630 p = path_join("/run/systemd/propagate/", u->id);
631 if (!p)
632 return -ENOMEM;
633
634 /* This is only filled transiently (see mount_in_namespace()), should be empty or even non-existent*/
635 if (rmdir(p) < 0 && errno != ENOENT)
636 log_unit_debug_errno(u, errno, "Unable to remove propagation dir '%s', ignoring: %m", p);
637
638 return 0;
639 }
640
641 void exec_command_done(ExecCommand *c) {
642 assert(c);
643
644 c->path = mfree(c->path);
645 c->argv = strv_free(c->argv);
646 }
647
648 void exec_command_done_array(ExecCommand *c, size_t n) {
649 FOREACH_ARRAY(i, c, n)
650 exec_command_done(i);
651 }
652
653 ExecCommand* exec_command_free_list(ExecCommand *c) {
654 ExecCommand *i;
655
656 while ((i = LIST_POP(command, c))) {
657 exec_command_done(i);
658 free(i);
659 }
660
661 return NULL;
662 }
663
664 void exec_command_free_array(ExecCommand **c, size_t n) {
665 FOREACH_ARRAY(i, c, n)
666 *i = exec_command_free_list(*i);
667 }
668
669 void exec_command_reset_status_array(ExecCommand *c, size_t n) {
670 FOREACH_ARRAY(i, c, n)
671 exec_status_reset(&i->exec_status);
672 }
673
674 void exec_command_reset_status_list_array(ExecCommand **c, size_t n) {
675 FOREACH_ARRAY(i, c, n)
676 LIST_FOREACH(command, z, *i)
677 exec_status_reset(&z->exec_status);
678 }
679
680 typedef struct InvalidEnvInfo {
681 const Unit *unit;
682 const char *path;
683 } InvalidEnvInfo;
684
685 static void invalid_env(const char *p, void *userdata) {
686 InvalidEnvInfo *info = userdata;
687
688 log_unit_error(info->unit, "Ignoring invalid environment assignment '%s': %s", p, info->path);
689 }
690
691 const char* exec_context_fdname(const ExecContext *c, int fd_index) {
692 assert(c);
693
694 switch (fd_index) {
695
696 case STDIN_FILENO:
697 if (c->std_input != EXEC_INPUT_NAMED_FD)
698 return NULL;
699
700 return c->stdio_fdname[STDIN_FILENO] ?: "stdin";
701
702 case STDOUT_FILENO:
703 if (c->std_output != EXEC_OUTPUT_NAMED_FD)
704 return NULL;
705
706 return c->stdio_fdname[STDOUT_FILENO] ?: "stdout";
707
708 case STDERR_FILENO:
709 if (c->std_error != EXEC_OUTPUT_NAMED_FD)
710 return NULL;
711
712 return c->stdio_fdname[STDERR_FILENO] ?: "stderr";
713
714 default:
715 return NULL;
716 }
717 }
718
719 static int exec_context_load_environment(const Unit *unit, const ExecContext *c, char ***ret) {
720 _cleanup_strv_free_ char **v = NULL;
721 int r;
722
723 assert(c);
724 assert(ret);
725
726 STRV_FOREACH(i, c->environment_files) {
727 _cleanup_globfree_ glob_t pglob = {};
728 bool ignore = false;
729 char *fn = *i;
730
731 if (fn[0] == '-') {
732 ignore = true;
733 fn++;
734 }
735
736 if (!path_is_absolute(fn)) {
737 if (ignore)
738 continue;
739 return -EINVAL;
740 }
741
742 /* Filename supports globbing, take all matching files */
743 r = safe_glob(fn, 0, &pglob);
744 if (r < 0) {
745 if (ignore)
746 continue;
747 return r;
748 }
749
750 /* When we don't match anything, -ENOENT should be returned */
751 assert(pglob.gl_pathc > 0);
752
753 FOREACH_ARRAY(path, pglob.gl_pathv, pglob.gl_pathc) {
754 _cleanup_strv_free_ char **p = NULL;
755
756 r = load_env_file(NULL, *path, &p);
757 if (r < 0) {
758 if (ignore)
759 continue;
760 return r;
761 }
762
763 /* Log invalid environment variables with filename */
764 if (p) {
765 InvalidEnvInfo info = {
766 .unit = unit,
767 .path = *path,
768 };
769
770 p = strv_env_clean_with_callback(p, invalid_env, &info);
771 }
772
773 if (!v)
774 v = TAKE_PTR(p);
775 else {
776 char **m = strv_env_merge(v, p);
777 if (!m)
778 return -ENOMEM;
779
780 strv_free_and_replace(v, m);
781 }
782 }
783 }
784
785 *ret = TAKE_PTR(v);
786
787 return 0;
788 }
789
790 static bool tty_may_match_dev_console(const char *tty) {
791 _cleanup_free_ char *resolved = NULL;
792
793 if (!tty)
794 return true;
795
796 tty = skip_dev_prefix(tty);
797
798 /* trivial identity? */
799 if (streq(tty, "console"))
800 return true;
801
802 if (resolve_dev_console(&resolved) < 0)
803 return true; /* if we could not resolve, assume it may */
804
805 /* "tty0" means the active VC, so it may be the same sometimes */
806 return path_equal(resolved, tty) || (streq(resolved, "tty0") && tty_is_vc(tty));
807 }
808
809 static bool exec_context_may_touch_tty(const ExecContext *ec) {
810 assert(ec);
811
812 return ec->tty_reset ||
813 ec->tty_vhangup ||
814 ec->tty_vt_disallocate ||
815 is_terminal_input(ec->std_input) ||
816 is_terminal_output(ec->std_output) ||
817 is_terminal_output(ec->std_error);
818 }
819
820 bool exec_context_may_touch_console(const ExecContext *ec) {
821
822 return exec_context_may_touch_tty(ec) &&
823 tty_may_match_dev_console(exec_context_tty_path(ec));
824 }
825
826 static void strv_fprintf(FILE *f, char **l) {
827 assert(f);
828
829 STRV_FOREACH(g, l)
830 fprintf(f, " %s", *g);
831 }
832
833 static void strv_dump(FILE* f, const char *prefix, const char *name, char **strv) {
834 assert(f);
835 assert(prefix);
836 assert(name);
837
838 if (!strv_isempty(strv)) {
839 fprintf(f, "%s%s:", prefix, name);
840 strv_fprintf(f, strv);
841 fputs("\n", f);
842 }
843 }
844
845 void exec_params_dump(const ExecParameters *p, FILE* f, const char *prefix) {
846 assert(p);
847 assert(f);
848
849 prefix = strempty(prefix);
850
851 fprintf(f,
852 "%sRuntimeScope: %s\n"
853 "%sExecFlags: %u\n"
854 "%sSELinuxContextNetwork: %s\n"
855 "%sCgroupSupportedMask: %u\n"
856 "%sCgroupPath: %s\n"
857 "%sCrededentialsDirectory: %s\n"
858 "%sEncryptedCredentialsDirectory: %s\n"
859 "%sConfirmSpawn: %s\n"
860 "%sShallConfirmSpawn: %s\n"
861 "%sWatchdogUSec: " USEC_FMT "\n"
862 "%sNotifySocket: %s\n"
863 "%sFallbackSmackProcessLabel: %s\n",
864 prefix, runtime_scope_to_string(p->runtime_scope),
865 prefix, p->flags,
866 prefix, yes_no(p->selinux_context_net),
867 prefix, p->cgroup_supported,
868 prefix, p->cgroup_path,
869 prefix, strempty(p->received_credentials_directory),
870 prefix, strempty(p->received_encrypted_credentials_directory),
871 prefix, strempty(p->confirm_spawn),
872 prefix, yes_no(p->shall_confirm_spawn),
873 prefix, p->watchdog_usec,
874 prefix, strempty(p->notify_socket),
875 prefix, strempty(p->fallback_smack_process_label));
876
877 strv_dump(f, prefix, "FdNames", p->fd_names);
878 strv_dump(f, prefix, "Environment", p->environment);
879 strv_dump(f, prefix, "Prefix", p->prefix);
880
881 LIST_FOREACH(open_files, file, p->open_files)
882 fprintf(f, "%sOpenFile: %s %s", prefix, file->path, open_file_flags_to_string(file->flags));
883
884 strv_dump(f, prefix, "FilesEnv", p->files_env);
885 }
886
887 void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
888 int r;
889
890 assert(c);
891 assert(f);
892
893 prefix = strempty(prefix);
894
895 fprintf(f,
896 "%sUMask: %04o\n"
897 "%sWorkingDirectory: %s\n"
898 "%sRootDirectory: %s\n"
899 "%sRootEphemeral: %s\n"
900 "%sNonBlocking: %s\n"
901 "%sPrivateTmp: %s\n"
902 "%sPrivateDevices: %s\n"
903 "%sProtectKernelTunables: %s\n"
904 "%sProtectKernelModules: %s\n"
905 "%sProtectKernelLogs: %s\n"
906 "%sProtectClock: %s\n"
907 "%sProtectControlGroups: %s\n"
908 "%sPrivateNetwork: %s\n"
909 "%sPrivateUsers: %s\n"
910 "%sProtectHome: %s\n"
911 "%sProtectSystem: %s\n"
912 "%sMountAPIVFS: %s\n"
913 "%sIgnoreSIGPIPE: %s\n"
914 "%sMemoryDenyWriteExecute: %s\n"
915 "%sRestrictRealtime: %s\n"
916 "%sRestrictSUIDSGID: %s\n"
917 "%sKeyringMode: %s\n"
918 "%sProtectHostname: %s\n"
919 "%sProtectProc: %s\n"
920 "%sProcSubset: %s\n",
921 prefix, c->umask,
922 prefix, empty_to_root(c->working_directory),
923 prefix, empty_to_root(c->root_directory),
924 prefix, yes_no(c->root_ephemeral),
925 prefix, yes_no(c->non_blocking),
926 prefix, yes_no(c->private_tmp),
927 prefix, yes_no(c->private_devices),
928 prefix, yes_no(c->protect_kernel_tunables),
929 prefix, yes_no(c->protect_kernel_modules),
930 prefix, yes_no(c->protect_kernel_logs),
931 prefix, yes_no(c->protect_clock),
932 prefix, yes_no(c->protect_control_groups),
933 prefix, yes_no(c->private_network),
934 prefix, yes_no(c->private_users),
935 prefix, protect_home_to_string(c->protect_home),
936 prefix, protect_system_to_string(c->protect_system),
937 prefix, yes_no(exec_context_get_effective_mount_apivfs(c)),
938 prefix, yes_no(c->ignore_sigpipe),
939 prefix, yes_no(c->memory_deny_write_execute),
940 prefix, yes_no(c->restrict_realtime),
941 prefix, yes_no(c->restrict_suid_sgid),
942 prefix, exec_keyring_mode_to_string(c->keyring_mode),
943 prefix, yes_no(c->protect_hostname),
944 prefix, protect_proc_to_string(c->protect_proc),
945 prefix, proc_subset_to_string(c->proc_subset));
946
947 if (c->set_login_environment >= 0)
948 fprintf(f, "%sSetLoginEnvironment: %s\n", prefix, yes_no(c->set_login_environment > 0));
949
950 if (c->root_image)
951 fprintf(f, "%sRootImage: %s\n", prefix, c->root_image);
952
953 if (c->root_image_options) {
954 fprintf(f, "%sRootImageOptions:", prefix);
955 LIST_FOREACH(mount_options, o, c->root_image_options)
956 if (!isempty(o->options))
957 fprintf(f, " %s:%s",
958 partition_designator_to_string(o->partition_designator),
959 o->options);
960 fprintf(f, "\n");
961 }
962
963 if (c->root_hash) {
964 _cleanup_free_ char *encoded = NULL;
965 encoded = hexmem(c->root_hash, c->root_hash_size);
966 if (encoded)
967 fprintf(f, "%sRootHash: %s\n", prefix, encoded);
968 }
969
970 if (c->root_hash_path)
971 fprintf(f, "%sRootHash: %s\n", prefix, c->root_hash_path);
972
973 if (c->root_hash_sig) {
974 _cleanup_free_ char *encoded = NULL;
975 ssize_t len;
976 len = base64mem(c->root_hash_sig, c->root_hash_sig_size, &encoded);
977 if (len)
978 fprintf(f, "%sRootHashSignature: base64:%s\n", prefix, encoded);
979 }
980
981 if (c->root_hash_sig_path)
982 fprintf(f, "%sRootHashSignature: %s\n", prefix, c->root_hash_sig_path);
983
984 if (c->root_verity)
985 fprintf(f, "%sRootVerity: %s\n", prefix, c->root_verity);
986
987 STRV_FOREACH(e, c->environment)
988 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
989
990 STRV_FOREACH(e, c->environment_files)
991 fprintf(f, "%sEnvironmentFile: %s\n", prefix, *e);
992
993 STRV_FOREACH(e, c->pass_environment)
994 fprintf(f, "%sPassEnvironment: %s\n", prefix, *e);
995
996 STRV_FOREACH(e, c->unset_environment)
997 fprintf(f, "%sUnsetEnvironment: %s\n", prefix, *e);
998
999 fprintf(f, "%sRuntimeDirectoryPreserve: %s\n", prefix, exec_preserve_mode_to_string(c->runtime_directory_preserve_mode));
1000
1001 for (ExecDirectoryType dt = 0; dt < _EXEC_DIRECTORY_TYPE_MAX; dt++) {
1002 fprintf(f, "%s%sMode: %04o\n", prefix, exec_directory_type_to_string(dt), c->directories[dt].mode);
1003
1004 for (size_t i = 0; i < c->directories[dt].n_items; i++) {
1005 fprintf(f, "%s%s: %s\n", prefix, exec_directory_type_to_string(dt), c->directories[dt].items[i].path);
1006
1007 STRV_FOREACH(d, c->directories[dt].items[i].symlinks)
1008 fprintf(f, "%s%s: %s:%s\n", prefix, exec_directory_type_symlink_to_string(dt), c->directories[dt].items[i].path, *d);
1009 }
1010 }
1011
1012 fprintf(f, "%sTimeoutCleanSec: %s\n", prefix, FORMAT_TIMESPAN(c->timeout_clean_usec, USEC_PER_SEC));
1013
1014 if (c->memory_ksm >= 0)
1015 fprintf(f, "%sMemoryKSM: %s\n", prefix, yes_no(c->memory_ksm > 0));
1016
1017 if (c->nice_set)
1018 fprintf(f, "%sNice: %i\n", prefix, c->nice);
1019
1020 if (c->oom_score_adjust_set)
1021 fprintf(f, "%sOOMScoreAdjust: %i\n", prefix, c->oom_score_adjust);
1022
1023 if (c->coredump_filter_set)
1024 fprintf(f, "%sCoredumpFilter: 0x%"PRIx64"\n", prefix, c->coredump_filter);
1025
1026 for (unsigned i = 0; i < RLIM_NLIMITS; i++)
1027 if (c->rlimit[i]) {
1028 fprintf(f, "%sLimit%s: " RLIM_FMT "\n",
1029 prefix, rlimit_to_string(i), c->rlimit[i]->rlim_max);
1030 fprintf(f, "%sLimit%sSoft: " RLIM_FMT "\n",
1031 prefix, rlimit_to_string(i), c->rlimit[i]->rlim_cur);
1032 }
1033
1034 if (c->ioprio_set) {
1035 _cleanup_free_ char *class_str = NULL;
1036
1037 r = ioprio_class_to_string_alloc(ioprio_prio_class(c->ioprio), &class_str);
1038 if (r >= 0)
1039 fprintf(f, "%sIOSchedulingClass: %s\n", prefix, class_str);
1040
1041 fprintf(f, "%sIOPriority: %d\n", prefix, ioprio_prio_data(c->ioprio));
1042 }
1043
1044 if (c->cpu_sched_set) {
1045 _cleanup_free_ char *policy_str = NULL;
1046
1047 r = sched_policy_to_string_alloc(c->cpu_sched_policy, &policy_str);
1048 if (r >= 0)
1049 fprintf(f, "%sCPUSchedulingPolicy: %s\n", prefix, policy_str);
1050
1051 fprintf(f,
1052 "%sCPUSchedulingPriority: %i\n"
1053 "%sCPUSchedulingResetOnFork: %s\n",
1054 prefix, c->cpu_sched_priority,
1055 prefix, yes_no(c->cpu_sched_reset_on_fork));
1056 }
1057
1058 if (c->cpu_set.set) {
1059 _cleanup_free_ char *affinity = NULL;
1060
1061 affinity = cpu_set_to_range_string(&c->cpu_set);
1062 fprintf(f, "%sCPUAffinity: %s\n", prefix, affinity);
1063 }
1064
1065 if (mpol_is_valid(numa_policy_get_type(&c->numa_policy))) {
1066 _cleanup_free_ char *nodes = NULL;
1067
1068 nodes = cpu_set_to_range_string(&c->numa_policy.nodes);
1069 fprintf(f, "%sNUMAPolicy: %s\n", prefix, mpol_to_string(numa_policy_get_type(&c->numa_policy)));
1070 fprintf(f, "%sNUMAMask: %s\n", prefix, strnull(nodes));
1071 }
1072
1073 if (c->timer_slack_nsec != NSEC_INFINITY)
1074 fprintf(f, "%sTimerSlackNSec: "NSEC_FMT "\n", prefix, c->timer_slack_nsec);
1075
1076 fprintf(f,
1077 "%sStandardInput: %s\n"
1078 "%sStandardOutput: %s\n"
1079 "%sStandardError: %s\n",
1080 prefix, exec_input_to_string(c->std_input),
1081 prefix, exec_output_to_string(c->std_output),
1082 prefix, exec_output_to_string(c->std_error));
1083
1084 if (c->std_input == EXEC_INPUT_NAMED_FD)
1085 fprintf(f, "%sStandardInputFileDescriptorName: %s\n", prefix, c->stdio_fdname[STDIN_FILENO]);
1086 if (c->std_output == EXEC_OUTPUT_NAMED_FD)
1087 fprintf(f, "%sStandardOutputFileDescriptorName: %s\n", prefix, c->stdio_fdname[STDOUT_FILENO]);
1088 if (c->std_error == EXEC_OUTPUT_NAMED_FD)
1089 fprintf(f, "%sStandardErrorFileDescriptorName: %s\n", prefix, c->stdio_fdname[STDERR_FILENO]);
1090
1091 if (c->std_input == EXEC_INPUT_FILE)
1092 fprintf(f, "%sStandardInputFile: %s\n", prefix, c->stdio_file[STDIN_FILENO]);
1093 if (c->std_output == EXEC_OUTPUT_FILE)
1094 fprintf(f, "%sStandardOutputFile: %s\n", prefix, c->stdio_file[STDOUT_FILENO]);
1095 if (c->std_output == EXEC_OUTPUT_FILE_APPEND)
1096 fprintf(f, "%sStandardOutputFileToAppend: %s\n", prefix, c->stdio_file[STDOUT_FILENO]);
1097 if (c->std_output == EXEC_OUTPUT_FILE_TRUNCATE)
1098 fprintf(f, "%sStandardOutputFileToTruncate: %s\n", prefix, c->stdio_file[STDOUT_FILENO]);
1099 if (c->std_error == EXEC_OUTPUT_FILE)
1100 fprintf(f, "%sStandardErrorFile: %s\n", prefix, c->stdio_file[STDERR_FILENO]);
1101 if (c->std_error == EXEC_OUTPUT_FILE_APPEND)
1102 fprintf(f, "%sStandardErrorFileToAppend: %s\n", prefix, c->stdio_file[STDERR_FILENO]);
1103 if (c->std_error == EXEC_OUTPUT_FILE_TRUNCATE)
1104 fprintf(f, "%sStandardErrorFileToTruncate: %s\n", prefix, c->stdio_file[STDERR_FILENO]);
1105
1106 if (c->tty_path)
1107 fprintf(f,
1108 "%sTTYPath: %s\n"
1109 "%sTTYReset: %s\n"
1110 "%sTTYVHangup: %s\n"
1111 "%sTTYVTDisallocate: %s\n"
1112 "%sTTYRows: %u\n"
1113 "%sTTYColumns: %u\n",
1114 prefix, c->tty_path,
1115 prefix, yes_no(c->tty_reset),
1116 prefix, yes_no(c->tty_vhangup),
1117 prefix, yes_no(c->tty_vt_disallocate),
1118 prefix, c->tty_rows,
1119 prefix, c->tty_cols);
1120
1121 if (IN_SET(c->std_output,
1122 EXEC_OUTPUT_KMSG,
1123 EXEC_OUTPUT_JOURNAL,
1124 EXEC_OUTPUT_KMSG_AND_CONSOLE,
1125 EXEC_OUTPUT_JOURNAL_AND_CONSOLE) ||
1126 IN_SET(c->std_error,
1127 EXEC_OUTPUT_KMSG,
1128 EXEC_OUTPUT_JOURNAL,
1129 EXEC_OUTPUT_KMSG_AND_CONSOLE,
1130 EXEC_OUTPUT_JOURNAL_AND_CONSOLE)) {
1131
1132 _cleanup_free_ char *fac_str = NULL, *lvl_str = NULL;
1133
1134 r = log_facility_unshifted_to_string_alloc(c->syslog_priority >> 3, &fac_str);
1135 if (r >= 0)
1136 fprintf(f, "%sSyslogFacility: %s\n", prefix, fac_str);
1137
1138 r = log_level_to_string_alloc(LOG_PRI(c->syslog_priority), &lvl_str);
1139 if (r >= 0)
1140 fprintf(f, "%sSyslogLevel: %s\n", prefix, lvl_str);
1141 }
1142
1143 if (c->log_level_max >= 0) {
1144 _cleanup_free_ char *t = NULL;
1145
1146 (void) log_level_to_string_alloc(c->log_level_max, &t);
1147
1148 fprintf(f, "%sLogLevelMax: %s\n", prefix, strna(t));
1149 }
1150
1151 if (c->log_ratelimit_interval_usec > 0)
1152 fprintf(f,
1153 "%sLogRateLimitIntervalSec: %s\n",
1154 prefix, FORMAT_TIMESPAN(c->log_ratelimit_interval_usec, USEC_PER_SEC));
1155
1156 if (c->log_ratelimit_burst > 0)
1157 fprintf(f, "%sLogRateLimitBurst: %u\n", prefix, c->log_ratelimit_burst);
1158
1159 if (!set_isempty(c->log_filter_allowed_patterns) || !set_isempty(c->log_filter_denied_patterns)) {
1160 fprintf(f, "%sLogFilterPatterns:", prefix);
1161
1162 char *pattern;
1163 SET_FOREACH(pattern, c->log_filter_allowed_patterns)
1164 fprintf(f, " %s", pattern);
1165 SET_FOREACH(pattern, c->log_filter_denied_patterns)
1166 fprintf(f, " ~%s", pattern);
1167 fputc('\n', f);
1168 }
1169
1170 FOREACH_ARRAY(field, c->log_extra_fields, c->n_log_extra_fields) {
1171 fprintf(f, "%sLogExtraFields: ", prefix);
1172 fwrite(field->iov_base, 1, field->iov_len, f);
1173 fputc('\n', f);
1174 }
1175
1176 if (c->log_namespace)
1177 fprintf(f, "%sLogNamespace: %s\n", prefix, c->log_namespace);
1178
1179 if (c->secure_bits) {
1180 _cleanup_free_ char *str = NULL;
1181
1182 r = secure_bits_to_string_alloc(c->secure_bits, &str);
1183 if (r >= 0)
1184 fprintf(f, "%sSecure Bits: %s\n", prefix, str);
1185 }
1186
1187 if (c->capability_bounding_set != CAP_MASK_UNSET) {
1188 _cleanup_free_ char *str = NULL;
1189
1190 r = capability_set_to_string(c->capability_bounding_set, &str);
1191 if (r >= 0)
1192 fprintf(f, "%sCapabilityBoundingSet: %s\n", prefix, str);
1193 }
1194
1195 if (c->capability_ambient_set != 0) {
1196 _cleanup_free_ char *str = NULL;
1197
1198 r = capability_set_to_string(c->capability_ambient_set, &str);
1199 if (r >= 0)
1200 fprintf(f, "%sAmbientCapabilities: %s\n", prefix, str);
1201 }
1202
1203 if (c->user)
1204 fprintf(f, "%sUser: %s\n", prefix, c->user);
1205 if (c->group)
1206 fprintf(f, "%sGroup: %s\n", prefix, c->group);
1207
1208 fprintf(f, "%sDynamicUser: %s\n", prefix, yes_no(c->dynamic_user));
1209
1210 strv_dump(f, prefix, "SupplementaryGroups", c->supplementary_groups);
1211
1212 if (c->pam_name)
1213 fprintf(f, "%sPAMName: %s\n", prefix, c->pam_name);
1214
1215 strv_dump(f, prefix, "ReadWritePaths", c->read_write_paths);
1216 strv_dump(f, prefix, "ReadOnlyPaths", c->read_only_paths);
1217 strv_dump(f, prefix, "InaccessiblePaths", c->inaccessible_paths);
1218 strv_dump(f, prefix, "ExecPaths", c->exec_paths);
1219 strv_dump(f, prefix, "NoExecPaths", c->no_exec_paths);
1220 strv_dump(f, prefix, "ExecSearchPath", c->exec_search_path);
1221
1222 FOREACH_ARRAY(mount, c->bind_mounts, c->n_bind_mounts)
1223 fprintf(f, "%s%s: %s%s:%s:%s\n", prefix,
1224 mount->read_only ? "BindReadOnlyPaths" : "BindPaths",
1225 mount->ignore_enoent ? "-": "",
1226 mount->source,
1227 mount->destination,
1228 mount->recursive ? "rbind" : "norbind");
1229
1230 FOREACH_ARRAY(tmpfs, c->temporary_filesystems, c->n_temporary_filesystems)
1231 fprintf(f, "%sTemporaryFileSystem: %s%s%s\n", prefix,
1232 tmpfs->path,
1233 isempty(tmpfs->options) ? "" : ":",
1234 strempty(tmpfs->options));
1235
1236 if (c->utmp_id)
1237 fprintf(f,
1238 "%sUtmpIdentifier: %s\n",
1239 prefix, c->utmp_id);
1240
1241 if (c->selinux_context)
1242 fprintf(f,
1243 "%sSELinuxContext: %s%s\n",
1244 prefix, c->selinux_context_ignore ? "-" : "", c->selinux_context);
1245
1246 if (c->apparmor_profile)
1247 fprintf(f,
1248 "%sAppArmorProfile: %s%s\n",
1249 prefix, c->apparmor_profile_ignore ? "-" : "", c->apparmor_profile);
1250
1251 if (c->smack_process_label)
1252 fprintf(f,
1253 "%sSmackProcessLabel: %s%s\n",
1254 prefix, c->smack_process_label_ignore ? "-" : "", c->smack_process_label);
1255
1256 if (c->personality != PERSONALITY_INVALID)
1257 fprintf(f,
1258 "%sPersonality: %s\n",
1259 prefix, strna(personality_to_string(c->personality)));
1260
1261 fprintf(f,
1262 "%sLockPersonality: %s\n",
1263 prefix, yes_no(c->lock_personality));
1264
1265 if (c->syscall_filter) {
1266 fprintf(f,
1267 "%sSystemCallFilter: ",
1268 prefix);
1269
1270 if (!c->syscall_allow_list)
1271 fputc('~', f);
1272
1273 #if HAVE_SECCOMP
1274 void *id, *val;
1275 bool first = true;
1276 HASHMAP_FOREACH_KEY(val, id, c->syscall_filter) {
1277 _cleanup_free_ char *name = NULL;
1278 const char *errno_name = NULL;
1279 int num = PTR_TO_INT(val);
1280
1281 if (first)
1282 first = false;
1283 else
1284 fputc(' ', f);
1285
1286 name = seccomp_syscall_resolve_num_arch(SCMP_ARCH_NATIVE, PTR_TO_INT(id) - 1);
1287 fputs(strna(name), f);
1288
1289 if (num >= 0) {
1290 errno_name = seccomp_errno_or_action_to_string(num);
1291 if (errno_name)
1292 fprintf(f, ":%s", errno_name);
1293 else
1294 fprintf(f, ":%d", num);
1295 }
1296 }
1297 #endif
1298
1299 fputc('\n', f);
1300 }
1301
1302 if (c->syscall_archs) {
1303 fprintf(f,
1304 "%sSystemCallArchitectures:",
1305 prefix);
1306
1307 #if HAVE_SECCOMP
1308 void *id;
1309 SET_FOREACH(id, c->syscall_archs)
1310 fprintf(f, " %s", strna(seccomp_arch_to_string(PTR_TO_UINT32(id) - 1)));
1311 #endif
1312 fputc('\n', f);
1313 }
1314
1315 if (exec_context_restrict_namespaces_set(c)) {
1316 _cleanup_free_ char *s = NULL;
1317
1318 r = namespace_flags_to_string(c->restrict_namespaces, &s);
1319 if (r >= 0)
1320 fprintf(f, "%sRestrictNamespaces: %s\n",
1321 prefix, strna(s));
1322 }
1323
1324 #if HAVE_LIBBPF
1325 if (exec_context_restrict_filesystems_set(c)) {
1326 char *fs;
1327 SET_FOREACH(fs, c->restrict_filesystems)
1328 fprintf(f, "%sRestrictFileSystems: %s\n", prefix, fs);
1329 }
1330 #endif
1331
1332 if (c->network_namespace_path)
1333 fprintf(f,
1334 "%sNetworkNamespacePath: %s\n",
1335 prefix, c->network_namespace_path);
1336
1337 if (c->syscall_errno > 0) {
1338 fprintf(f, "%sSystemCallErrorNumber: ", prefix);
1339
1340 #if HAVE_SECCOMP
1341 const char *errno_name = seccomp_errno_or_action_to_string(c->syscall_errno);
1342 if (errno_name)
1343 fputs(errno_name, f);
1344 else
1345 fprintf(f, "%d", c->syscall_errno);
1346 #endif
1347 fputc('\n', f);
1348 }
1349
1350 FOREACH_ARRAY(mount, c->mount_images, c->n_mount_images) {
1351 fprintf(f, "%sMountImages: %s%s:%s", prefix,
1352 mount->ignore_enoent ? "-": "",
1353 mount->source,
1354 mount->destination);
1355 LIST_FOREACH(mount_options, o, mount->mount_options)
1356 fprintf(f, ":%s:%s",
1357 partition_designator_to_string(o->partition_designator),
1358 strempty(o->options));
1359 fprintf(f, "\n");
1360 }
1361
1362 FOREACH_ARRAY(mount, c->extension_images, c->n_extension_images) {
1363 fprintf(f, "%sExtensionImages: %s%s", prefix,
1364 mount->ignore_enoent ? "-": "",
1365 mount->source);
1366 LIST_FOREACH(mount_options, o, mount->mount_options)
1367 fprintf(f, ":%s:%s",
1368 partition_designator_to_string(o->partition_designator),
1369 strempty(o->options));
1370 fprintf(f, "\n");
1371 }
1372
1373 strv_dump(f, prefix, "ExtensionDirectories", c->extension_directories);
1374 }
1375
1376 bool exec_context_maintains_privileges(const ExecContext *c) {
1377 assert(c);
1378
1379 /* Returns true if the process forked off would run under
1380 * an unchanged UID or as root. */
1381
1382 if (!c->user)
1383 return true;
1384
1385 if (streq(c->user, "root") || streq(c->user, "0"))
1386 return true;
1387
1388 return false;
1389 }
1390
1391 int exec_context_get_effective_ioprio(const ExecContext *c) {
1392 int p;
1393
1394 assert(c);
1395
1396 if (c->ioprio_set)
1397 return c->ioprio;
1398
1399 p = ioprio_get(IOPRIO_WHO_PROCESS, 0);
1400 if (p < 0)
1401 return IOPRIO_DEFAULT_CLASS_AND_PRIO;
1402
1403 return ioprio_normalize(p);
1404 }
1405
1406 bool exec_context_get_effective_mount_apivfs(const ExecContext *c) {
1407 assert(c);
1408
1409 /* Explicit setting wins */
1410 if (c->mount_apivfs_set)
1411 return c->mount_apivfs;
1412
1413 /* Default to "yes" if root directory or image are specified */
1414 if (exec_context_with_rootfs(c))
1415 return true;
1416
1417 return false;
1418 }
1419
1420 void exec_context_free_log_extra_fields(ExecContext *c) {
1421 assert(c);
1422
1423 FOREACH_ARRAY(field, c->log_extra_fields, c->n_log_extra_fields)
1424 free(field->iov_base);
1425
1426 c->log_extra_fields = mfree(c->log_extra_fields);
1427 c->n_log_extra_fields = 0;
1428 }
1429
1430 void exec_context_revert_tty(ExecContext *c) {
1431 _cleanup_close_ int fd = -EBADF;
1432 const char *path;
1433 struct stat st;
1434 int r;
1435
1436 assert(c);
1437
1438 /* First, reset the TTY (possibly kicking everybody else from the TTY) */
1439 exec_context_tty_reset(c, NULL);
1440
1441 /* And then undo what chown_terminal() did earlier. Note that we only do this if we have a path
1442 * configured. If the TTY was passed to us as file descriptor we assume the TTY is opened and managed
1443 * by whoever passed it to us and thus knows better when and how to chmod()/chown() it back. */
1444 if (!exec_context_may_touch_tty(c))
1445 return;
1446
1447 path = exec_context_tty_path(c);
1448 if (!path)
1449 return;
1450
1451 fd = open(path, O_PATH|O_CLOEXEC);
1452 if (fd < 0)
1453 return (void) log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
1454 "Failed to open TTY inode of '%s' to adjust ownership/access mode, ignoring: %m",
1455 path);
1456
1457 if (fstat(fd, &st) < 0)
1458 return (void) log_warning_errno(errno, "Failed to stat TTY '%s', ignoring: %m", path);
1459
1460 /* Let's add a superficial check that we only do this for stuff that looks like a TTY. We only check
1461 * if things are a character device, since a proper check either means we'd have to open the TTY and
1462 * use isatty(), but we'd rather not do that since opening TTYs comes with all kinds of side-effects
1463 * and is slow. Or we'd have to hardcode dev_t major information, which we'd rather avoid. Why bother
1464 * with this at all? → https://github.com/systemd/systemd/issues/19213 */
1465 if (!S_ISCHR(st.st_mode))
1466 return log_warning("Configured TTY '%s' is not actually a character device, ignoring.", path);
1467
1468 r = fchmod_and_chown(fd, TTY_MODE, 0, TTY_GID);
1469 if (r < 0)
1470 log_warning_errno(r, "Failed to reset TTY ownership/access mode of %s, ignoring: %m", path);
1471 }
1472
1473 int exec_context_get_clean_directories(
1474 ExecContext *c,
1475 char **prefix,
1476 ExecCleanMask mask,
1477 char ***ret) {
1478
1479 _cleanup_strv_free_ char **l = NULL;
1480 int r;
1481
1482 assert(c);
1483 assert(prefix);
1484 assert(ret);
1485
1486 for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++) {
1487 if (!FLAGS_SET(mask, 1U << t))
1488 continue;
1489
1490 if (!prefix[t])
1491 continue;
1492
1493 FOREACH_ARRAY(i, c->directories[t].items, c->directories[t].n_items) {
1494 char *j;
1495
1496 j = path_join(prefix[t], i->path);
1497 if (!j)
1498 return -ENOMEM;
1499
1500 r = strv_consume(&l, j);
1501 if (r < 0)
1502 return r;
1503
1504 /* Also remove private directories unconditionally. */
1505 if (t != EXEC_DIRECTORY_CONFIGURATION) {
1506 j = path_join(prefix[t], "private", i->path);
1507 if (!j)
1508 return -ENOMEM;
1509
1510 r = strv_consume(&l, j);
1511 if (r < 0)
1512 return r;
1513 }
1514
1515 STRV_FOREACH(symlink, i->symlinks) {
1516 j = path_join(prefix[t], *symlink);
1517 if (!j)
1518 return -ENOMEM;
1519
1520 r = strv_consume(&l, j);
1521 if (r < 0)
1522 return r;
1523 }
1524 }
1525 }
1526
1527 *ret = TAKE_PTR(l);
1528 return 0;
1529 }
1530
1531 int exec_context_get_clean_mask(ExecContext *c, ExecCleanMask *ret) {
1532 ExecCleanMask mask = 0;
1533
1534 assert(c);
1535 assert(ret);
1536
1537 for (ExecDirectoryType t = 0; t < _EXEC_DIRECTORY_TYPE_MAX; t++)
1538 if (c->directories[t].n_items > 0)
1539 mask |= 1U << t;
1540
1541 *ret = mask;
1542 return 0;
1543 }
1544
1545 void exec_status_start(ExecStatus *s, pid_t pid) {
1546 assert(s);
1547
1548 *s = (ExecStatus) {
1549 .pid = pid,
1550 };
1551
1552 dual_timestamp_get(&s->start_timestamp);
1553 }
1554
1555 void exec_status_exit(ExecStatus *s, const ExecContext *context, pid_t pid, int code, int status) {
1556 assert(s);
1557
1558 if (s->pid != pid)
1559 *s = (ExecStatus) {
1560 .pid = pid,
1561 };
1562
1563 dual_timestamp_get(&s->exit_timestamp);
1564
1565 s->code = code;
1566 s->status = status;
1567
1568 if (context && context->utmp_id)
1569 (void) utmp_put_dead_process(context->utmp_id, pid, code, status);
1570 }
1571
1572 void exec_status_reset(ExecStatus *s) {
1573 assert(s);
1574
1575 *s = (ExecStatus) {};
1576 }
1577
1578 void exec_status_dump(const ExecStatus *s, FILE *f, const char *prefix) {
1579 assert(s);
1580 assert(f);
1581
1582 if (s->pid <= 0)
1583 return;
1584
1585 prefix = strempty(prefix);
1586
1587 fprintf(f,
1588 "%sPID: "PID_FMT"\n",
1589 prefix, s->pid);
1590
1591 if (dual_timestamp_is_set(&s->start_timestamp))
1592 fprintf(f,
1593 "%sStart Timestamp: %s\n",
1594 prefix, FORMAT_TIMESTAMP(s->start_timestamp.realtime));
1595
1596 if (dual_timestamp_is_set(&s->exit_timestamp))
1597 fprintf(f,
1598 "%sExit Timestamp: %s\n"
1599 "%sExit Code: %s\n"
1600 "%sExit Status: %i\n",
1601 prefix, FORMAT_TIMESTAMP(s->exit_timestamp.realtime),
1602 prefix, sigchld_code_to_string(s->code),
1603 prefix, s->status);
1604 }
1605
1606 static void exec_command_dump(ExecCommand *c, FILE *f, const char *prefix) {
1607 _cleanup_free_ char *cmd = NULL;
1608 const char *prefix2;
1609
1610 assert(c);
1611 assert(f);
1612
1613 prefix = strempty(prefix);
1614 prefix2 = strjoina(prefix, "\t");
1615
1616 cmd = quote_command_line(c->argv, SHELL_ESCAPE_EMPTY);
1617
1618 fprintf(f,
1619 "%sCommand Line: %s\n",
1620 prefix, strnull(cmd));
1621
1622 exec_status_dump(&c->exec_status, f, prefix2);
1623 }
1624
1625 void exec_command_dump_list(ExecCommand *c, FILE *f, const char *prefix) {
1626 assert(f);
1627
1628 prefix = strempty(prefix);
1629
1630 LIST_FOREACH(command, i, c)
1631 exec_command_dump(i, f, prefix);
1632 }
1633
1634 void exec_command_append_list(ExecCommand **l, ExecCommand *e) {
1635 ExecCommand *end;
1636
1637 assert(l);
1638 assert(e);
1639
1640 if (*l) {
1641 /* It's kind of important, that we keep the order here */
1642 end = LIST_FIND_TAIL(command, *l);
1643 LIST_INSERT_AFTER(command, *l, end, e);
1644 } else
1645 *l = e;
1646 }
1647
1648 int exec_command_set(ExecCommand *c, const char *path, ...) {
1649 va_list ap;
1650 char **l, *p;
1651
1652 assert(c);
1653 assert(path);
1654
1655 va_start(ap, path);
1656 l = strv_new_ap(path, ap);
1657 va_end(ap);
1658
1659 if (!l)
1660 return -ENOMEM;
1661
1662 p = strdup(path);
1663 if (!p) {
1664 strv_free(l);
1665 return -ENOMEM;
1666 }
1667
1668 free_and_replace(c->path, p);
1669
1670 return strv_free_and_replace(c->argv, l);
1671 }
1672
1673 int exec_command_append(ExecCommand *c, const char *path, ...) {
1674 _cleanup_strv_free_ char **l = NULL;
1675 va_list ap;
1676 int r;
1677
1678 assert(c);
1679 assert(path);
1680
1681 va_start(ap, path);
1682 l = strv_new_ap(path, ap);
1683 va_end(ap);
1684
1685 if (!l)
1686 return -ENOMEM;
1687
1688 r = strv_extend_strv(&c->argv, l, false);
1689 if (r < 0)
1690 return r;
1691
1692 return 0;
1693 }
1694
1695 static char *destroy_tree(char *path) {
1696 if (!path)
1697 return NULL;
1698
1699 if (!path_equal(path, RUN_SYSTEMD_EMPTY)) {
1700 log_debug("Spawning process to nuke '%s'", path);
1701
1702 (void) asynchronous_rm_rf(path, REMOVE_ROOT|REMOVE_SUBVOLUME|REMOVE_PHYSICAL);
1703 }
1704
1705 return mfree(path);
1706 }
1707
1708 void exec_shared_runtime_done(ExecSharedRuntime *rt) {
1709 if (!rt)
1710 return;
1711
1712 if (rt->manager)
1713 (void) hashmap_remove(rt->manager->exec_shared_runtime_by_id, rt->id);
1714
1715 rt->id = mfree(rt->id);
1716 rt->tmp_dir = mfree(rt->tmp_dir);
1717 rt->var_tmp_dir = mfree(rt->var_tmp_dir);
1718 safe_close_pair(rt->netns_storage_socket);
1719 safe_close_pair(rt->ipcns_storage_socket);
1720 }
1721
1722 static ExecSharedRuntime* exec_shared_runtime_free(ExecSharedRuntime *rt) {
1723 exec_shared_runtime_done(rt);
1724
1725 return mfree(rt);
1726 }
1727
1728 DEFINE_TRIVIAL_UNREF_FUNC(ExecSharedRuntime, exec_shared_runtime, exec_shared_runtime_free);
1729 DEFINE_TRIVIAL_CLEANUP_FUNC(ExecSharedRuntime*, exec_shared_runtime_free);
1730
1731 ExecSharedRuntime* exec_shared_runtime_destroy(ExecSharedRuntime *rt) {
1732 if (!rt)
1733 return NULL;
1734
1735 assert(rt->n_ref > 0);
1736 rt->n_ref--;
1737
1738 if (rt->n_ref > 0)
1739 return NULL;
1740
1741 rt->tmp_dir = destroy_tree(rt->tmp_dir);
1742 rt->var_tmp_dir = destroy_tree(rt->var_tmp_dir);
1743
1744 return exec_shared_runtime_free(rt);
1745 }
1746
1747 static int exec_shared_runtime_allocate(ExecSharedRuntime **ret, const char *id) {
1748 _cleanup_free_ char *id_copy = NULL;
1749 ExecSharedRuntime *n;
1750
1751 assert(ret);
1752
1753 id_copy = strdup(id);
1754 if (!id_copy)
1755 return -ENOMEM;
1756
1757 n = new(ExecSharedRuntime, 1);
1758 if (!n)
1759 return -ENOMEM;
1760
1761 *n = (ExecSharedRuntime) {
1762 .id = TAKE_PTR(id_copy),
1763 .netns_storage_socket = PIPE_EBADF,
1764 .ipcns_storage_socket = PIPE_EBADF,
1765 };
1766
1767 *ret = n;
1768 return 0;
1769 }
1770
1771 static int exec_shared_runtime_add(
1772 Manager *m,
1773 const char *id,
1774 char **tmp_dir,
1775 char **var_tmp_dir,
1776 int netns_storage_socket[2],
1777 int ipcns_storage_socket[2],
1778 ExecSharedRuntime **ret) {
1779
1780 _cleanup_(exec_shared_runtime_freep) ExecSharedRuntime *rt = NULL;
1781 int r;
1782
1783 assert(m);
1784 assert(id);
1785
1786 /* tmp_dir, var_tmp_dir, {net,ipc}ns_storage_socket fds are donated on success */
1787
1788 r = exec_shared_runtime_allocate(&rt, id);
1789 if (r < 0)
1790 return r;
1791
1792 r = hashmap_ensure_put(&m->exec_shared_runtime_by_id, &string_hash_ops, rt->id, rt);
1793 if (r < 0)
1794 return r;
1795
1796 assert(!!rt->tmp_dir == !!rt->var_tmp_dir); /* We require both to be set together */
1797 rt->tmp_dir = TAKE_PTR(*tmp_dir);
1798 rt->var_tmp_dir = TAKE_PTR(*var_tmp_dir);
1799
1800 if (netns_storage_socket) {
1801 rt->netns_storage_socket[0] = TAKE_FD(netns_storage_socket[0]);
1802 rt->netns_storage_socket[1] = TAKE_FD(netns_storage_socket[1]);
1803 }
1804
1805 if (ipcns_storage_socket) {
1806 rt->ipcns_storage_socket[0] = TAKE_FD(ipcns_storage_socket[0]);
1807 rt->ipcns_storage_socket[1] = TAKE_FD(ipcns_storage_socket[1]);
1808 }
1809
1810 rt->manager = m;
1811
1812 if (ret)
1813 *ret = rt;
1814 /* do not remove created ExecSharedRuntime object when the operation succeeds. */
1815 TAKE_PTR(rt);
1816 return 0;
1817 }
1818
1819 static int exec_shared_runtime_make(
1820 Manager *m,
1821 const ExecContext *c,
1822 const char *id,
1823 ExecSharedRuntime **ret) {
1824
1825 _cleanup_(namespace_cleanup_tmpdirp) char *tmp_dir = NULL, *var_tmp_dir = NULL;
1826 _cleanup_close_pair_ int netns_storage_socket[2] = PIPE_EBADF, ipcns_storage_socket[2] = PIPE_EBADF;
1827 int r;
1828
1829 assert(m);
1830 assert(c);
1831 assert(id);
1832
1833 /* It is not necessary to create ExecSharedRuntime object. */
1834 if (!exec_needs_network_namespace(c) && !exec_needs_ipc_namespace(c) && !c->private_tmp) {
1835 *ret = NULL;
1836 return 0;
1837 }
1838
1839 if (c->private_tmp &&
1840 !(prefixed_path_strv_contains(c->inaccessible_paths, "/tmp") &&
1841 (prefixed_path_strv_contains(c->inaccessible_paths, "/var/tmp") ||
1842 prefixed_path_strv_contains(c->inaccessible_paths, "/var")))) {
1843 r = setup_tmp_dirs(id, &tmp_dir, &var_tmp_dir);
1844 if (r < 0)
1845 return r;
1846 }
1847
1848 if (exec_needs_network_namespace(c)) {
1849 if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, netns_storage_socket) < 0)
1850 return -errno;
1851 }
1852
1853 if (exec_needs_ipc_namespace(c)) {
1854 if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, ipcns_storage_socket) < 0)
1855 return -errno;
1856 }
1857
1858 r = exec_shared_runtime_add(m, id, &tmp_dir, &var_tmp_dir, netns_storage_socket, ipcns_storage_socket, ret);
1859 if (r < 0)
1860 return r;
1861
1862 return 1;
1863 }
1864
1865 int exec_shared_runtime_acquire(Manager *m, const ExecContext *c, const char *id, bool create, ExecSharedRuntime **ret) {
1866 ExecSharedRuntime *rt;
1867 int r;
1868
1869 assert(m);
1870 assert(id);
1871 assert(ret);
1872
1873 rt = hashmap_get(m->exec_shared_runtime_by_id, id);
1874 if (rt)
1875 /* We already have an ExecSharedRuntime object, let's increase the ref count and reuse it */
1876 goto ref;
1877
1878 if (!create) {
1879 *ret = NULL;
1880 return 0;
1881 }
1882
1883 /* If not found, then create a new object. */
1884 r = exec_shared_runtime_make(m, c, id, &rt);
1885 if (r < 0)
1886 return r;
1887 if (r == 0) {
1888 /* When r == 0, it is not necessary to create ExecSharedRuntime object. */
1889 *ret = NULL;
1890 return 0;
1891 }
1892
1893 ref:
1894 /* increment reference counter. */
1895 rt->n_ref++;
1896 *ret = rt;
1897 return 1;
1898 }
1899
1900 int exec_shared_runtime_serialize(const Manager *m, FILE *f, FDSet *fds) {
1901 ExecSharedRuntime *rt;
1902
1903 assert(m);
1904 assert(f);
1905 assert(fds);
1906
1907 HASHMAP_FOREACH(rt, m->exec_shared_runtime_by_id) {
1908 fprintf(f, "exec-runtime=%s", rt->id);
1909
1910 if (rt->tmp_dir)
1911 fprintf(f, " tmp-dir=%s", rt->tmp_dir);
1912
1913 if (rt->var_tmp_dir)
1914 fprintf(f, " var-tmp-dir=%s", rt->var_tmp_dir);
1915
1916 if (rt->netns_storage_socket[0] >= 0) {
1917 int copy;
1918
1919 copy = fdset_put_dup(fds, rt->netns_storage_socket[0]);
1920 if (copy < 0)
1921 return copy;
1922
1923 fprintf(f, " netns-socket-0=%i", copy);
1924 }
1925
1926 if (rt->netns_storage_socket[1] >= 0) {
1927 int copy;
1928
1929 copy = fdset_put_dup(fds, rt->netns_storage_socket[1]);
1930 if (copy < 0)
1931 return copy;
1932
1933 fprintf(f, " netns-socket-1=%i", copy);
1934 }
1935
1936 if (rt->ipcns_storage_socket[0] >= 0) {
1937 int copy;
1938
1939 copy = fdset_put_dup(fds, rt->ipcns_storage_socket[0]);
1940 if (copy < 0)
1941 return copy;
1942
1943 fprintf(f, " ipcns-socket-0=%i", copy);
1944 }
1945
1946 if (rt->ipcns_storage_socket[1] >= 0) {
1947 int copy;
1948
1949 copy = fdset_put_dup(fds, rt->ipcns_storage_socket[1]);
1950 if (copy < 0)
1951 return copy;
1952
1953 fprintf(f, " ipcns-socket-1=%i", copy);
1954 }
1955
1956 fputc('\n', f);
1957 }
1958
1959 return 0;
1960 }
1961
1962 int exec_shared_runtime_deserialize_compat(Unit *u, const char *key, const char *value, FDSet *fds) {
1963 _cleanup_(exec_shared_runtime_freep) ExecSharedRuntime *rt_create = NULL;
1964 ExecSharedRuntime *rt = NULL;
1965 int r;
1966
1967 /* This is for the migration from old (v237 or earlier) deserialization text.
1968 * Due to the bug #7790, this may not work with the units that use JoinsNamespaceOf=.
1969 * Even if the ExecSharedRuntime object originally created by the other unit, we cannot judge
1970 * so or not from the serialized text, then we always creates a new object owned by this. */
1971
1972 assert(u);
1973 assert(key);
1974 assert(value);
1975
1976 /* Manager manages ExecSharedRuntime objects by the unit id.
1977 * So, we omit the serialized text when the unit does not have id (yet?)... */
1978 if (isempty(u->id)) {
1979 log_unit_debug(u, "Invocation ID not found. Dropping runtime parameter.");
1980 return 0;
1981 }
1982
1983 if (u->manager) {
1984 if (hashmap_ensure_allocated(&u->manager->exec_shared_runtime_by_id, &string_hash_ops) < 0)
1985 return log_oom();
1986
1987 rt = hashmap_get(u->manager->exec_shared_runtime_by_id, u->id);
1988 }
1989 if (!rt) {
1990 if (exec_shared_runtime_allocate(&rt_create, u->id) < 0)
1991 return log_oom();
1992
1993 rt = rt_create;
1994 }
1995
1996 if (streq(key, "tmp-dir")) {
1997 if (free_and_strdup_warn(&rt->tmp_dir, value) < 0)
1998 return -ENOMEM;
1999
2000 } else if (streq(key, "var-tmp-dir")) {
2001 if (free_and_strdup_warn(&rt->var_tmp_dir, value) < 0)
2002 return -ENOMEM;
2003
2004 } else if (streq(key, "netns-socket-0")) {
2005 int fd;
2006
2007 if ((fd = parse_fd(value)) < 0 || !fdset_contains(fds, fd)) {
2008 log_unit_debug(u, "Failed to parse netns socket value: %s", value);
2009 return 0;
2010 }
2011
2012 safe_close(rt->netns_storage_socket[0]);
2013 rt->netns_storage_socket[0] = fdset_remove(fds, fd);
2014
2015 } else if (streq(key, "netns-socket-1")) {
2016 int fd;
2017
2018 if ((fd = parse_fd(value)) < 0 || !fdset_contains(fds, fd)) {
2019 log_unit_debug(u, "Failed to parse netns socket value: %s", value);
2020 return 0;
2021 }
2022
2023 safe_close(rt->netns_storage_socket[1]);
2024 rt->netns_storage_socket[1] = fdset_remove(fds, fd);
2025
2026 } else
2027 return 0;
2028
2029 /* If the object is newly created, then put it to the hashmap which manages ExecSharedRuntime objects. */
2030 if (rt_create && u->manager) {
2031 r = hashmap_put(u->manager->exec_shared_runtime_by_id, rt_create->id, rt_create);
2032 if (r < 0) {
2033 log_unit_debug_errno(u, r, "Failed to put runtime parameter to manager's storage: %m");
2034 return 0;
2035 }
2036
2037 rt_create->manager = u->manager;
2038
2039 /* Avoid cleanup */
2040 TAKE_PTR(rt_create);
2041 }
2042
2043 return 1;
2044 }
2045
2046 int exec_shared_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) {
2047 _cleanup_free_ char *tmp_dir = NULL, *var_tmp_dir = NULL;
2048 char *id = NULL;
2049 int r, netns_fdpair[] = {-1, -1}, ipcns_fdpair[] = {-1, -1};
2050 const char *p, *v = ASSERT_PTR(value);
2051 size_t n;
2052
2053 assert(m);
2054 assert(fds);
2055
2056 n = strcspn(v, " ");
2057 id = strndupa_safe(v, n);
2058 if (v[n] != ' ')
2059 goto finalize;
2060 p = v + n + 1;
2061
2062 v = startswith(p, "tmp-dir=");
2063 if (v) {
2064 n = strcspn(v, " ");
2065 tmp_dir = strndup(v, n);
2066 if (!tmp_dir)
2067 return log_oom();
2068 if (v[n] != ' ')
2069 goto finalize;
2070 p = v + n + 1;
2071 }
2072
2073 v = startswith(p, "var-tmp-dir=");
2074 if (v) {
2075 n = strcspn(v, " ");
2076 var_tmp_dir = strndup(v, n);
2077 if (!var_tmp_dir)
2078 return log_oom();
2079 if (v[n] != ' ')
2080 goto finalize;
2081 p = v + n + 1;
2082 }
2083
2084 v = startswith(p, "netns-socket-0=");
2085 if (v) {
2086 char *buf;
2087
2088 n = strcspn(v, " ");
2089 buf = strndupa_safe(v, n);
2090
2091 netns_fdpair[0] = parse_fd(buf);
2092 if (netns_fdpair[0] < 0)
2093 return log_debug_errno(netns_fdpair[0], "Unable to parse exec-runtime specification netns-socket-0=%s: %m", buf);
2094 if (!fdset_contains(fds, netns_fdpair[0]))
2095 return log_debug_errno(SYNTHETIC_ERRNO(EBADF),
2096 "exec-runtime specification netns-socket-0= refers to unknown fd %d: %m", netns_fdpair[0]);
2097 netns_fdpair[0] = fdset_remove(fds, netns_fdpair[0]);
2098 if (v[n] != ' ')
2099 goto finalize;
2100 p = v + n + 1;
2101 }
2102
2103 v = startswith(p, "netns-socket-1=");
2104 if (v) {
2105 char *buf;
2106
2107 n = strcspn(v, " ");
2108 buf = strndupa_safe(v, n);
2109
2110 netns_fdpair[1] = parse_fd(buf);
2111 if (netns_fdpair[1] < 0)
2112 return log_debug_errno(netns_fdpair[1], "Unable to parse exec-runtime specification netns-socket-1=%s: %m", buf);
2113 if (!fdset_contains(fds, netns_fdpair[1]))
2114 return log_debug_errno(SYNTHETIC_ERRNO(EBADF),
2115 "exec-runtime specification netns-socket-1= refers to unknown fd %d: %m", netns_fdpair[1]);
2116 netns_fdpair[1] = fdset_remove(fds, netns_fdpair[1]);
2117 if (v[n] != ' ')
2118 goto finalize;
2119 p = v + n + 1;
2120 }
2121
2122 v = startswith(p, "ipcns-socket-0=");
2123 if (v) {
2124 char *buf;
2125
2126 n = strcspn(v, " ");
2127 buf = strndupa_safe(v, n);
2128
2129 ipcns_fdpair[0] = parse_fd(buf);
2130 if (ipcns_fdpair[0] < 0)
2131 return log_debug_errno(ipcns_fdpair[0], "Unable to parse exec-runtime specification ipcns-socket-0=%s: %m", buf);
2132 if (!fdset_contains(fds, ipcns_fdpair[0]))
2133 return log_debug_errno(SYNTHETIC_ERRNO(EBADF),
2134 "exec-runtime specification ipcns-socket-0= refers to unknown fd %d: %m", ipcns_fdpair[0]);
2135 ipcns_fdpair[0] = fdset_remove(fds, ipcns_fdpair[0]);
2136 if (v[n] != ' ')
2137 goto finalize;
2138 p = v + n + 1;
2139 }
2140
2141 v = startswith(p, "ipcns-socket-1=");
2142 if (v) {
2143 char *buf;
2144
2145 n = strcspn(v, " ");
2146 buf = strndupa_safe(v, n);
2147
2148 ipcns_fdpair[1] = parse_fd(buf);
2149 if (ipcns_fdpair[1] < 0)
2150 return log_debug_errno(ipcns_fdpair[1], "Unable to parse exec-runtime specification ipcns-socket-1=%s: %m", buf);
2151 if (!fdset_contains(fds, ipcns_fdpair[1]))
2152 return log_debug_errno(SYNTHETIC_ERRNO(EBADF),
2153 "exec-runtime specification ipcns-socket-1= refers to unknown fd %d: %m", ipcns_fdpair[1]);
2154 ipcns_fdpair[1] = fdset_remove(fds, ipcns_fdpair[1]);
2155 }
2156
2157 finalize:
2158 r = exec_shared_runtime_add(m, id, &tmp_dir, &var_tmp_dir, netns_fdpair, ipcns_fdpair, NULL);
2159 if (r < 0)
2160 return log_debug_errno(r, "Failed to add exec-runtime: %m");
2161 return 0;
2162 }
2163
2164 void exec_shared_runtime_vacuum(Manager *m) {
2165 ExecSharedRuntime *rt;
2166
2167 assert(m);
2168
2169 /* Free unreferenced ExecSharedRuntime objects. This is used after manager deserialization process. */
2170
2171 HASHMAP_FOREACH(rt, m->exec_shared_runtime_by_id) {
2172 if (rt->n_ref > 0)
2173 continue;
2174
2175 (void) exec_shared_runtime_free(rt);
2176 }
2177 }
2178
2179 int exec_runtime_make(
2180 const Unit *unit,
2181 const ExecContext *context,
2182 ExecSharedRuntime *shared,
2183 DynamicCreds *creds,
2184 ExecRuntime **ret) {
2185 _cleanup_close_pair_ int ephemeral_storage_socket[2] = PIPE_EBADF;
2186 _cleanup_free_ char *ephemeral = NULL;
2187 _cleanup_(exec_runtime_freep) ExecRuntime *rt = NULL;
2188 int r;
2189
2190 assert(unit);
2191 assert(context);
2192 assert(ret);
2193
2194 if (!shared && !creds && !exec_needs_ephemeral(context)) {
2195 *ret = NULL;
2196 return 0;
2197 }
2198
2199 if (exec_needs_ephemeral(context)) {
2200 r = mkdir_p("/var/lib/systemd/ephemeral-trees", 0755);
2201 if (r < 0)
2202 return r;
2203
2204 r = tempfn_random_child("/var/lib/systemd/ephemeral-trees", unit->id, &ephemeral);
2205 if (r < 0)
2206 return r;
2207
2208 if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, ephemeral_storage_socket) < 0)
2209 return -errno;
2210 }
2211
2212 rt = new(ExecRuntime, 1);
2213 if (!rt)
2214 return -ENOMEM;
2215
2216 *rt = (ExecRuntime) {
2217 .shared = shared,
2218 .dynamic_creds = creds,
2219 .ephemeral_copy = TAKE_PTR(ephemeral),
2220 .ephemeral_storage_socket[0] = TAKE_FD(ephemeral_storage_socket[0]),
2221 .ephemeral_storage_socket[1] = TAKE_FD(ephemeral_storage_socket[1]),
2222 };
2223
2224 *ret = TAKE_PTR(rt);
2225 return 1;
2226 }
2227
2228 ExecRuntime* exec_runtime_free(ExecRuntime *rt) {
2229 if (!rt)
2230 return NULL;
2231
2232 exec_shared_runtime_unref(rt->shared);
2233 dynamic_creds_unref(rt->dynamic_creds);
2234
2235 rt->ephemeral_copy = destroy_tree(rt->ephemeral_copy);
2236
2237 safe_close_pair(rt->ephemeral_storage_socket);
2238 return mfree(rt);
2239 }
2240
2241 ExecRuntime* exec_runtime_destroy(ExecRuntime *rt) {
2242 if (!rt)
2243 return NULL;
2244
2245 rt->shared = exec_shared_runtime_destroy(rt->shared);
2246 rt->dynamic_creds = dynamic_creds_destroy(rt->dynamic_creds);
2247 return exec_runtime_free(rt);
2248 }
2249
2250 void exec_runtime_clear(ExecRuntime *rt) {
2251 if (!rt)
2252 return;
2253
2254 safe_close_pair(rt->ephemeral_storage_socket);
2255 rt->ephemeral_copy = mfree(rt->ephemeral_copy);
2256 }
2257
2258 void exec_params_clear(ExecParameters *p) {
2259 if (!p)
2260 return;
2261
2262 p->environment = strv_free(p->environment);
2263 p->fd_names = strv_free(p->fd_names);
2264 p->files_env = strv_free(p->files_env);
2265 p->fds = mfree(p->fds);
2266 p->exec_fd = safe_close(p->exec_fd);
2267 p->user_lookup_fd = -EBADF;
2268 p->bpf_outer_map_fd = -EBADF;
2269 p->unit_id = mfree(p->unit_id);
2270 p->invocation_id = SD_ID128_NULL;
2271 p->invocation_id_string[0] = '\0';
2272 p->confirm_spawn = mfree(p->confirm_spawn);
2273 }
2274
2275 void exec_params_serialized_done(ExecParameters *p) {
2276 if (!p)
2277 return;
2278
2279 for (size_t i = 0; p->fds && i < p->n_socket_fds + p->n_storage_fds; i++)
2280 p->fds[i] = safe_close(p->fds[i]);
2281
2282 p->cgroup_path = mfree(p->cgroup_path);
2283
2284 p->prefix = strv_free(p->prefix);
2285 p->received_credentials_directory = mfree(p->received_credentials_directory);
2286 p->received_encrypted_credentials_directory = mfree(p->received_encrypted_credentials_directory);
2287
2288 for (size_t i = 0; p->idle_pipe && i < 4; i++)
2289 p->idle_pipe[i] = safe_close(p->idle_pipe[i]);
2290 p->idle_pipe = mfree(p->idle_pipe);
2291
2292 p->stdin_fd = safe_close(p->stdin_fd);
2293 p->stdout_fd = safe_close(p->stdout_fd);
2294 p->stderr_fd = safe_close(p->stderr_fd);
2295
2296 p->notify_socket = mfree(p->notify_socket);
2297
2298 open_file_free_many(&p->open_files);
2299
2300 p->fallback_smack_process_label = mfree(p->fallback_smack_process_label);
2301
2302 exec_params_clear(p);
2303 }
2304
2305 void exec_directory_done(ExecDirectory *d) {
2306 if (!d)
2307 return;
2308
2309 FOREACH_ARRAY(i, d->items, d->n_items) {
2310 free(i->path);
2311 strv_free(i->symlinks);
2312 }
2313
2314 d->items = mfree(d->items);
2315 d->n_items = 0;
2316 d->mode = 0755;
2317 }
2318
2319 static ExecDirectoryItem *exec_directory_find(ExecDirectory *d, const char *path) {
2320 assert(d);
2321 assert(path);
2322
2323 FOREACH_ARRAY(i, d->items, d->n_items)
2324 if (path_equal(i->path, path))
2325 return i;
2326
2327 return NULL;
2328 }
2329
2330 int exec_directory_add(ExecDirectory *d, const char *path, const char *symlink) {
2331 _cleanup_strv_free_ char **s = NULL;
2332 _cleanup_free_ char *p = NULL;
2333 ExecDirectoryItem *existing;
2334 int r;
2335
2336 assert(d);
2337 assert(path);
2338
2339 existing = exec_directory_find(d, path);
2340 if (existing) {
2341 r = strv_extend(&existing->symlinks, symlink);
2342 if (r < 0)
2343 return r;
2344
2345 return 0; /* existing item is updated */
2346 }
2347
2348 p = strdup(path);
2349 if (!p)
2350 return -ENOMEM;
2351
2352 if (symlink) {
2353 s = strv_new(symlink);
2354 if (!s)
2355 return -ENOMEM;
2356 }
2357
2358 if (!GREEDY_REALLOC(d->items, d->n_items + 1))
2359 return -ENOMEM;
2360
2361 d->items[d->n_items++] = (ExecDirectoryItem) {
2362 .path = TAKE_PTR(p),
2363 .symlinks = TAKE_PTR(s),
2364 };
2365
2366 return 1; /* new item is added */
2367 }
2368
2369 static int exec_directory_item_compare_func(const ExecDirectoryItem *a, const ExecDirectoryItem *b) {
2370 assert(a);
2371 assert(b);
2372
2373 return path_compare(a->path, b->path);
2374 }
2375
2376 void exec_directory_sort(ExecDirectory *d) {
2377 assert(d);
2378
2379 /* Sort the exec directories to make always parent directories processed at first in
2380 * setup_exec_directory(), e.g., even if StateDirectory=foo/bar foo, we need to create foo at first,
2381 * then foo/bar. Also, set .only_create flag if one of the parent directories is contained in the
2382 * list. See also comments in setup_exec_directory() and issue #24783. */
2383
2384 if (d->n_items <= 1)
2385 return;
2386
2387 typesafe_qsort(d->items, d->n_items, exec_directory_item_compare_func);
2388
2389 for (size_t i = 1; i < d->n_items; i++)
2390 for (size_t j = 0; j < i; j++)
2391 if (path_startswith(d->items[i].path, d->items[j].path)) {
2392 d->items[i].only_create = true;
2393 break;
2394 }
2395 }
2396
2397 ExecCleanMask exec_clean_mask_from_string(const char *s) {
2398 ExecDirectoryType t;
2399
2400 assert(s);
2401
2402 if (streq(s, "all"))
2403 return EXEC_CLEAN_ALL;
2404 if (streq(s, "fdstore"))
2405 return EXEC_CLEAN_FDSTORE;
2406
2407 t = exec_resource_type_from_string(s);
2408 if (t < 0)
2409 return (ExecCleanMask) t;
2410
2411 return 1U << t;
2412 }
2413
2414 static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
2415 [EXEC_INPUT_NULL] = "null",
2416 [EXEC_INPUT_TTY] = "tty",
2417 [EXEC_INPUT_TTY_FORCE] = "tty-force",
2418 [EXEC_INPUT_TTY_FAIL] = "tty-fail",
2419 [EXEC_INPUT_SOCKET] = "socket",
2420 [EXEC_INPUT_NAMED_FD] = "fd",
2421 [EXEC_INPUT_DATA] = "data",
2422 [EXEC_INPUT_FILE] = "file",
2423 };
2424
2425 DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
2426
2427 static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
2428 [EXEC_OUTPUT_INHERIT] = "inherit",
2429 [EXEC_OUTPUT_NULL] = "null",
2430 [EXEC_OUTPUT_TTY] = "tty",
2431 [EXEC_OUTPUT_KMSG] = "kmsg",
2432 [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
2433 [EXEC_OUTPUT_JOURNAL] = "journal",
2434 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
2435 [EXEC_OUTPUT_SOCKET] = "socket",
2436 [EXEC_OUTPUT_NAMED_FD] = "fd",
2437 [EXEC_OUTPUT_FILE] = "file",
2438 [EXEC_OUTPUT_FILE_APPEND] = "append",
2439 [EXEC_OUTPUT_FILE_TRUNCATE] = "truncate",
2440 };
2441
2442 DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);
2443
2444 static const char* const exec_utmp_mode_table[_EXEC_UTMP_MODE_MAX] = {
2445 [EXEC_UTMP_INIT] = "init",
2446 [EXEC_UTMP_LOGIN] = "login",
2447 [EXEC_UTMP_USER] = "user",
2448 };
2449
2450 DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode, ExecUtmpMode);
2451
2452 static const char* const exec_preserve_mode_table[_EXEC_PRESERVE_MODE_MAX] = {
2453 [EXEC_PRESERVE_NO] = "no",
2454 [EXEC_PRESERVE_YES] = "yes",
2455 [EXEC_PRESERVE_RESTART] = "restart",
2456 };
2457
2458 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(exec_preserve_mode, ExecPreserveMode, EXEC_PRESERVE_YES);
2459
2460 /* This table maps ExecDirectoryType to the setting it is configured with in the unit */
2461 static const char* const exec_directory_type_table[_EXEC_DIRECTORY_TYPE_MAX] = {
2462 [EXEC_DIRECTORY_RUNTIME] = "RuntimeDirectory",
2463 [EXEC_DIRECTORY_STATE] = "StateDirectory",
2464 [EXEC_DIRECTORY_CACHE] = "CacheDirectory",
2465 [EXEC_DIRECTORY_LOGS] = "LogsDirectory",
2466 [EXEC_DIRECTORY_CONFIGURATION] = "ConfigurationDirectory",
2467 };
2468
2469 DEFINE_STRING_TABLE_LOOKUP(exec_directory_type, ExecDirectoryType);
2470
2471 /* This table maps ExecDirectoryType to the symlink setting it is configured with in the unit */
2472 static const char* const exec_directory_type_symlink_table[_EXEC_DIRECTORY_TYPE_MAX] = {
2473 [EXEC_DIRECTORY_RUNTIME] = "RuntimeDirectorySymlink",
2474 [EXEC_DIRECTORY_STATE] = "StateDirectorySymlink",
2475 [EXEC_DIRECTORY_CACHE] = "CacheDirectorySymlink",
2476 [EXEC_DIRECTORY_LOGS] = "LogsDirectorySymlink",
2477 [EXEC_DIRECTORY_CONFIGURATION] = "ConfigurationDirectorySymlink",
2478 };
2479
2480 DEFINE_STRING_TABLE_LOOKUP(exec_directory_type_symlink, ExecDirectoryType);
2481
2482 /* And this table maps ExecDirectoryType too, but to a generic term identifying the type of resource. This
2483 * one is supposed to be generic enough to be used for unit types that don't use ExecContext and per-unit
2484 * directories, specifically .timer units with their timestamp touch file. */
2485 static const char* const exec_resource_type_table[_EXEC_DIRECTORY_TYPE_MAX] = {
2486 [EXEC_DIRECTORY_RUNTIME] = "runtime",
2487 [EXEC_DIRECTORY_STATE] = "state",
2488 [EXEC_DIRECTORY_CACHE] = "cache",
2489 [EXEC_DIRECTORY_LOGS] = "logs",
2490 [EXEC_DIRECTORY_CONFIGURATION] = "configuration",
2491 };
2492
2493 DEFINE_STRING_TABLE_LOOKUP(exec_resource_type, ExecDirectoryType);
2494
2495 static const char* const exec_keyring_mode_table[_EXEC_KEYRING_MODE_MAX] = {
2496 [EXEC_KEYRING_INHERIT] = "inherit",
2497 [EXEC_KEYRING_PRIVATE] = "private",
2498 [EXEC_KEYRING_SHARED] = "shared",
2499 };
2500
2501 DEFINE_STRING_TABLE_LOOKUP(exec_keyring_mode, ExecKeyringMode);