]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/core/execute.c
tree-wide: check if return value of lseek() and friends is negative
[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) < 0)
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
2006 safe_close(rt->netns_storage_socket[0]);
2007 rt->netns_storage_socket[0] = deserialize_fd(fds, value);
2008 if (rt->netns_storage_socket[0] < 0)
2009 return 0;
2010
2011 } else if (streq(key, "netns-socket-1")) {
2012
2013 safe_close(rt->netns_storage_socket[1]);
2014 rt->netns_storage_socket[1] = deserialize_fd(fds, value);
2015 if (rt->netns_storage_socket[1] < 0)
2016 return 0;
2017 } else
2018 return 0;
2019
2020 /* If the object is newly created, then put it to the hashmap which manages ExecSharedRuntime objects. */
2021 if (rt_create && u->manager) {
2022 r = hashmap_put(u->manager->exec_shared_runtime_by_id, rt_create->id, rt_create);
2023 if (r < 0) {
2024 log_unit_debug_errno(u, r, "Failed to put runtime parameter to manager's storage: %m");
2025 return 0;
2026 }
2027
2028 rt_create->manager = u->manager;
2029
2030 /* Avoid cleanup */
2031 TAKE_PTR(rt_create);
2032 }
2033
2034 return 1;
2035 }
2036
2037 int exec_shared_runtime_deserialize_one(Manager *m, const char *value, FDSet *fds) {
2038 _cleanup_free_ char *tmp_dir = NULL, *var_tmp_dir = NULL;
2039 char *id = NULL;
2040 int r, netns_fdpair[] = {-1, -1}, ipcns_fdpair[] = {-1, -1};
2041 const char *p, *v = ASSERT_PTR(value);
2042 size_t n;
2043
2044 assert(m);
2045 assert(fds);
2046
2047 n = strcspn(v, " ");
2048 id = strndupa_safe(v, n);
2049 if (v[n] != ' ')
2050 goto finalize;
2051 p = v + n + 1;
2052
2053 v = startswith(p, "tmp-dir=");
2054 if (v) {
2055 n = strcspn(v, " ");
2056 tmp_dir = strndup(v, n);
2057 if (!tmp_dir)
2058 return log_oom();
2059 if (v[n] != ' ')
2060 goto finalize;
2061 p = v + n + 1;
2062 }
2063
2064 v = startswith(p, "var-tmp-dir=");
2065 if (v) {
2066 n = strcspn(v, " ");
2067 var_tmp_dir = strndup(v, n);
2068 if (!var_tmp_dir)
2069 return log_oom();
2070 if (v[n] != ' ')
2071 goto finalize;
2072 p = v + n + 1;
2073 }
2074
2075 v = startswith(p, "netns-socket-0=");
2076 if (v) {
2077 char *buf;
2078
2079 n = strcspn(v, " ");
2080 buf = strndupa_safe(v, n);
2081
2082 netns_fdpair[0] = deserialize_fd(fds, buf);
2083 if (netns_fdpair[0] < 0)
2084 return netns_fdpair[0];
2085 if (v[n] != ' ')
2086 goto finalize;
2087 p = v + n + 1;
2088 }
2089
2090 v = startswith(p, "netns-socket-1=");
2091 if (v) {
2092 char *buf;
2093
2094 n = strcspn(v, " ");
2095 buf = strndupa_safe(v, n);
2096
2097 netns_fdpair[1] = deserialize_fd(fds, buf);
2098 if (netns_fdpair[1] < 0)
2099 return netns_fdpair[1];
2100 if (v[n] != ' ')
2101 goto finalize;
2102 p = v + n + 1;
2103 }
2104
2105 v = startswith(p, "ipcns-socket-0=");
2106 if (v) {
2107 char *buf;
2108
2109 n = strcspn(v, " ");
2110 buf = strndupa_safe(v, n);
2111
2112 ipcns_fdpair[0] = deserialize_fd(fds, buf);
2113 if (ipcns_fdpair[0] < 0)
2114 return ipcns_fdpair[0];
2115 if (v[n] != ' ')
2116 goto finalize;
2117 p = v + n + 1;
2118 }
2119
2120 v = startswith(p, "ipcns-socket-1=");
2121 if (v) {
2122 char *buf;
2123
2124 n = strcspn(v, " ");
2125 buf = strndupa_safe(v, n);
2126
2127 ipcns_fdpair[1] = deserialize_fd(fds, buf);
2128 if (ipcns_fdpair[1] < 0)
2129 return ipcns_fdpair[1];
2130 }
2131
2132 finalize:
2133 r = exec_shared_runtime_add(m, id, &tmp_dir, &var_tmp_dir, netns_fdpair, ipcns_fdpair, NULL);
2134 if (r < 0)
2135 return log_debug_errno(r, "Failed to add exec-runtime: %m");
2136 return 0;
2137 }
2138
2139 void exec_shared_runtime_vacuum(Manager *m) {
2140 ExecSharedRuntime *rt;
2141
2142 assert(m);
2143
2144 /* Free unreferenced ExecSharedRuntime objects. This is used after manager deserialization process. */
2145
2146 HASHMAP_FOREACH(rt, m->exec_shared_runtime_by_id) {
2147 if (rt->n_ref > 0)
2148 continue;
2149
2150 (void) exec_shared_runtime_free(rt);
2151 }
2152 }
2153
2154 int exec_runtime_make(
2155 const Unit *unit,
2156 const ExecContext *context,
2157 ExecSharedRuntime *shared,
2158 DynamicCreds *creds,
2159 ExecRuntime **ret) {
2160 _cleanup_close_pair_ int ephemeral_storage_socket[2] = PIPE_EBADF;
2161 _cleanup_free_ char *ephemeral = NULL;
2162 _cleanup_(exec_runtime_freep) ExecRuntime *rt = NULL;
2163 int r;
2164
2165 assert(unit);
2166 assert(context);
2167 assert(ret);
2168
2169 if (!shared && !creds && !exec_needs_ephemeral(context)) {
2170 *ret = NULL;
2171 return 0;
2172 }
2173
2174 if (exec_needs_ephemeral(context)) {
2175 r = mkdir_p("/var/lib/systemd/ephemeral-trees", 0755);
2176 if (r < 0)
2177 return r;
2178
2179 r = tempfn_random_child("/var/lib/systemd/ephemeral-trees", unit->id, &ephemeral);
2180 if (r < 0)
2181 return r;
2182
2183 if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, ephemeral_storage_socket) < 0)
2184 return -errno;
2185 }
2186
2187 rt = new(ExecRuntime, 1);
2188 if (!rt)
2189 return -ENOMEM;
2190
2191 *rt = (ExecRuntime) {
2192 .shared = shared,
2193 .dynamic_creds = creds,
2194 .ephemeral_copy = TAKE_PTR(ephemeral),
2195 .ephemeral_storage_socket[0] = TAKE_FD(ephemeral_storage_socket[0]),
2196 .ephemeral_storage_socket[1] = TAKE_FD(ephemeral_storage_socket[1]),
2197 };
2198
2199 *ret = TAKE_PTR(rt);
2200 return 1;
2201 }
2202
2203 ExecRuntime* exec_runtime_free(ExecRuntime *rt) {
2204 if (!rt)
2205 return NULL;
2206
2207 exec_shared_runtime_unref(rt->shared);
2208 dynamic_creds_unref(rt->dynamic_creds);
2209
2210 rt->ephemeral_copy = destroy_tree(rt->ephemeral_copy);
2211
2212 safe_close_pair(rt->ephemeral_storage_socket);
2213 return mfree(rt);
2214 }
2215
2216 ExecRuntime* exec_runtime_destroy(ExecRuntime *rt) {
2217 if (!rt)
2218 return NULL;
2219
2220 rt->shared = exec_shared_runtime_destroy(rt->shared);
2221 rt->dynamic_creds = dynamic_creds_destroy(rt->dynamic_creds);
2222 return exec_runtime_free(rt);
2223 }
2224
2225 void exec_runtime_clear(ExecRuntime *rt) {
2226 if (!rt)
2227 return;
2228
2229 safe_close_pair(rt->ephemeral_storage_socket);
2230 rt->ephemeral_copy = mfree(rt->ephemeral_copy);
2231 }
2232
2233 void exec_params_clear(ExecParameters *p) {
2234 if (!p)
2235 return;
2236
2237 p->environment = strv_free(p->environment);
2238 p->fd_names = strv_free(p->fd_names);
2239 p->files_env = strv_free(p->files_env);
2240 p->fds = mfree(p->fds);
2241 p->exec_fd = safe_close(p->exec_fd);
2242 p->user_lookup_fd = -EBADF;
2243 p->bpf_outer_map_fd = -EBADF;
2244 p->unit_id = mfree(p->unit_id);
2245 p->invocation_id = SD_ID128_NULL;
2246 p->invocation_id_string[0] = '\0';
2247 p->confirm_spawn = mfree(p->confirm_spawn);
2248 }
2249
2250 void exec_params_serialized_done(ExecParameters *p) {
2251 if (!p)
2252 return;
2253
2254 close_many_unset(p->fds, p->n_socket_fds + p->n_storage_fds);
2255
2256 p->cgroup_path = mfree(p->cgroup_path);
2257
2258 p->prefix = strv_free(p->prefix);
2259 p->received_credentials_directory = mfree(p->received_credentials_directory);
2260 p->received_encrypted_credentials_directory = mfree(p->received_encrypted_credentials_directory);
2261
2262 if (p->idle_pipe) {
2263 close_many_and_free(p->idle_pipe, 4);
2264 p->idle_pipe = NULL;
2265 }
2266
2267 p->stdin_fd = safe_close(p->stdin_fd);
2268 p->stdout_fd = safe_close(p->stdout_fd);
2269 p->stderr_fd = safe_close(p->stderr_fd);
2270
2271 p->notify_socket = mfree(p->notify_socket);
2272
2273 open_file_free_many(&p->open_files);
2274
2275 p->fallback_smack_process_label = mfree(p->fallback_smack_process_label);
2276
2277 exec_params_clear(p);
2278 }
2279
2280 void exec_directory_done(ExecDirectory *d) {
2281 if (!d)
2282 return;
2283
2284 FOREACH_ARRAY(i, d->items, d->n_items) {
2285 free(i->path);
2286 strv_free(i->symlinks);
2287 }
2288
2289 d->items = mfree(d->items);
2290 d->n_items = 0;
2291 d->mode = 0755;
2292 }
2293
2294 static ExecDirectoryItem *exec_directory_find(ExecDirectory *d, const char *path) {
2295 assert(d);
2296 assert(path);
2297
2298 FOREACH_ARRAY(i, d->items, d->n_items)
2299 if (path_equal(i->path, path))
2300 return i;
2301
2302 return NULL;
2303 }
2304
2305 int exec_directory_add(ExecDirectory *d, const char *path, const char *symlink) {
2306 _cleanup_strv_free_ char **s = NULL;
2307 _cleanup_free_ char *p = NULL;
2308 ExecDirectoryItem *existing;
2309 int r;
2310
2311 assert(d);
2312 assert(path);
2313
2314 existing = exec_directory_find(d, path);
2315 if (existing) {
2316 r = strv_extend(&existing->symlinks, symlink);
2317 if (r < 0)
2318 return r;
2319
2320 return 0; /* existing item is updated */
2321 }
2322
2323 p = strdup(path);
2324 if (!p)
2325 return -ENOMEM;
2326
2327 if (symlink) {
2328 s = strv_new(symlink);
2329 if (!s)
2330 return -ENOMEM;
2331 }
2332
2333 if (!GREEDY_REALLOC(d->items, d->n_items + 1))
2334 return -ENOMEM;
2335
2336 d->items[d->n_items++] = (ExecDirectoryItem) {
2337 .path = TAKE_PTR(p),
2338 .symlinks = TAKE_PTR(s),
2339 };
2340
2341 return 1; /* new item is added */
2342 }
2343
2344 static int exec_directory_item_compare_func(const ExecDirectoryItem *a, const ExecDirectoryItem *b) {
2345 assert(a);
2346 assert(b);
2347
2348 return path_compare(a->path, b->path);
2349 }
2350
2351 void exec_directory_sort(ExecDirectory *d) {
2352 assert(d);
2353
2354 /* Sort the exec directories to make always parent directories processed at first in
2355 * setup_exec_directory(), e.g., even if StateDirectory=foo/bar foo, we need to create foo at first,
2356 * then foo/bar. Also, set .only_create flag if one of the parent directories is contained in the
2357 * list. See also comments in setup_exec_directory() and issue #24783. */
2358
2359 if (d->n_items <= 1)
2360 return;
2361
2362 typesafe_qsort(d->items, d->n_items, exec_directory_item_compare_func);
2363
2364 for (size_t i = 1; i < d->n_items; i++)
2365 for (size_t j = 0; j < i; j++)
2366 if (path_startswith(d->items[i].path, d->items[j].path)) {
2367 d->items[i].only_create = true;
2368 break;
2369 }
2370 }
2371
2372 ExecCleanMask exec_clean_mask_from_string(const char *s) {
2373 ExecDirectoryType t;
2374
2375 assert(s);
2376
2377 if (streq(s, "all"))
2378 return EXEC_CLEAN_ALL;
2379 if (streq(s, "fdstore"))
2380 return EXEC_CLEAN_FDSTORE;
2381
2382 t = exec_resource_type_from_string(s);
2383 if (t < 0)
2384 return (ExecCleanMask) t;
2385
2386 return 1U << t;
2387 }
2388
2389 static const char* const exec_input_table[_EXEC_INPUT_MAX] = {
2390 [EXEC_INPUT_NULL] = "null",
2391 [EXEC_INPUT_TTY] = "tty",
2392 [EXEC_INPUT_TTY_FORCE] = "tty-force",
2393 [EXEC_INPUT_TTY_FAIL] = "tty-fail",
2394 [EXEC_INPUT_SOCKET] = "socket",
2395 [EXEC_INPUT_NAMED_FD] = "fd",
2396 [EXEC_INPUT_DATA] = "data",
2397 [EXEC_INPUT_FILE] = "file",
2398 };
2399
2400 DEFINE_STRING_TABLE_LOOKUP(exec_input, ExecInput);
2401
2402 static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
2403 [EXEC_OUTPUT_INHERIT] = "inherit",
2404 [EXEC_OUTPUT_NULL] = "null",
2405 [EXEC_OUTPUT_TTY] = "tty",
2406 [EXEC_OUTPUT_KMSG] = "kmsg",
2407 [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
2408 [EXEC_OUTPUT_JOURNAL] = "journal",
2409 [EXEC_OUTPUT_JOURNAL_AND_CONSOLE] = "journal+console",
2410 [EXEC_OUTPUT_SOCKET] = "socket",
2411 [EXEC_OUTPUT_NAMED_FD] = "fd",
2412 [EXEC_OUTPUT_FILE] = "file",
2413 [EXEC_OUTPUT_FILE_APPEND] = "append",
2414 [EXEC_OUTPUT_FILE_TRUNCATE] = "truncate",
2415 };
2416
2417 DEFINE_STRING_TABLE_LOOKUP(exec_output, ExecOutput);
2418
2419 static const char* const exec_utmp_mode_table[_EXEC_UTMP_MODE_MAX] = {
2420 [EXEC_UTMP_INIT] = "init",
2421 [EXEC_UTMP_LOGIN] = "login",
2422 [EXEC_UTMP_USER] = "user",
2423 };
2424
2425 DEFINE_STRING_TABLE_LOOKUP(exec_utmp_mode, ExecUtmpMode);
2426
2427 static const char* const exec_preserve_mode_table[_EXEC_PRESERVE_MODE_MAX] = {
2428 [EXEC_PRESERVE_NO] = "no",
2429 [EXEC_PRESERVE_YES] = "yes",
2430 [EXEC_PRESERVE_RESTART] = "restart",
2431 };
2432
2433 DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(exec_preserve_mode, ExecPreserveMode, EXEC_PRESERVE_YES);
2434
2435 /* This table maps ExecDirectoryType to the setting it is configured with in the unit */
2436 static const char* const exec_directory_type_table[_EXEC_DIRECTORY_TYPE_MAX] = {
2437 [EXEC_DIRECTORY_RUNTIME] = "RuntimeDirectory",
2438 [EXEC_DIRECTORY_STATE] = "StateDirectory",
2439 [EXEC_DIRECTORY_CACHE] = "CacheDirectory",
2440 [EXEC_DIRECTORY_LOGS] = "LogsDirectory",
2441 [EXEC_DIRECTORY_CONFIGURATION] = "ConfigurationDirectory",
2442 };
2443
2444 DEFINE_STRING_TABLE_LOOKUP(exec_directory_type, ExecDirectoryType);
2445
2446 /* This table maps ExecDirectoryType to the symlink setting it is configured with in the unit */
2447 static const char* const exec_directory_type_symlink_table[_EXEC_DIRECTORY_TYPE_MAX] = {
2448 [EXEC_DIRECTORY_RUNTIME] = "RuntimeDirectorySymlink",
2449 [EXEC_DIRECTORY_STATE] = "StateDirectorySymlink",
2450 [EXEC_DIRECTORY_CACHE] = "CacheDirectorySymlink",
2451 [EXEC_DIRECTORY_LOGS] = "LogsDirectorySymlink",
2452 [EXEC_DIRECTORY_CONFIGURATION] = "ConfigurationDirectorySymlink",
2453 };
2454
2455 DEFINE_STRING_TABLE_LOOKUP(exec_directory_type_symlink, ExecDirectoryType);
2456
2457 /* And this table maps ExecDirectoryType too, but to a generic term identifying the type of resource. This
2458 * one is supposed to be generic enough to be used for unit types that don't use ExecContext and per-unit
2459 * directories, specifically .timer units with their timestamp touch file. */
2460 static const char* const exec_resource_type_table[_EXEC_DIRECTORY_TYPE_MAX] = {
2461 [EXEC_DIRECTORY_RUNTIME] = "runtime",
2462 [EXEC_DIRECTORY_STATE] = "state",
2463 [EXEC_DIRECTORY_CACHE] = "cache",
2464 [EXEC_DIRECTORY_LOGS] = "logs",
2465 [EXEC_DIRECTORY_CONFIGURATION] = "configuration",
2466 };
2467
2468 DEFINE_STRING_TABLE_LOOKUP(exec_resource_type, ExecDirectoryType);
2469
2470 static const char* const exec_keyring_mode_table[_EXEC_KEYRING_MODE_MAX] = {
2471 [EXEC_KEYRING_INHERIT] = "inherit",
2472 [EXEC_KEYRING_PRIVATE] = "private",
2473 [EXEC_KEYRING_SHARED] = "shared",
2474 };
2475
2476 DEFINE_STRING_TABLE_LOOKUP(exec_keyring_mode, ExecKeyringMode);