]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/execute.c
core: add RootHashSignature service parameter
[thirdparty/systemd.git] / src / core / execute.c
index 8e1e77b4b2a5442c741943f978def1495ca85898..4bee1b19665edcdb8f9597f8d7b393dd335b8a34 100644 (file)
@@ -54,6 +54,7 @@
 #include "format-util.h"
 #include "fs-util.h"
 #include "glob-util.h"
+#include "hexdecoct.h"
 #include "io-util.h"
 #include "ioprio.h"
 #include "label.h"
@@ -219,17 +220,10 @@ static bool is_terminal_input(ExecInput i) {
 static bool is_terminal_output(ExecOutput o) {
         return IN_SET(o,
                       EXEC_OUTPUT_TTY,
-                      EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
                       EXEC_OUTPUT_KMSG_AND_CONSOLE,
                       EXEC_OUTPUT_JOURNAL_AND_CONSOLE);
 }
 
-static bool is_syslog_output(ExecOutput o) {
-        return IN_SET(o,
-                      EXEC_OUTPUT_SYSLOG,
-                      EXEC_OUTPUT_SYSLOG_AND_CONSOLE);
-}
-
 static bool is_kmsg_output(ExecOutput o) {
         return IN_SET(o,
                       EXEC_OUTPUT_KMSG,
@@ -361,7 +355,7 @@ static int connect_logger_as(
                 params->flags & EXEC_PASS_LOG_UNIT ? unit->id : "",
                 context->syslog_priority,
                 !!context->syslog_level_prefix,
-                is_syslog_output(output),
+                false,
                 is_kmsg_output(output),
                 is_terminal_output(output)) < 0)
                 return -errno;
@@ -664,8 +658,6 @@ static int setup_output(
                 /* We don't reset the terminal if this is just about output */
                 return open_terminal_as(exec_context_tty_path(context), O_WRONLY, fileno);
 
-        case EXEC_OUTPUT_SYSLOG:
-        case EXEC_OUTPUT_SYSLOG_AND_CONSOLE:
         case EXEC_OUTPUT_KMSG:
         case EXEC_OUTPUT_KMSG_AND_CONSOLE:
         case EXEC_OUTPUT_JOURNAL:
@@ -1388,14 +1380,14 @@ static void rename_process_from_path(const char *path) {
 static bool context_has_address_families(const ExecContext *c) {
         assert(c);
 
-        return c->address_families_whitelist ||
+        return c->address_families_allow_list ||
                 !set_isempty(c->address_families);
 }
 
 static bool context_has_syscall_filters(const ExecContext *c) {
         assert(c);
 
-        return c->syscall_whitelist ||
+        return c->syscall_allow_list ||
                 !hashmap_isempty(c->syscall_filter);
 }
 
@@ -1451,7 +1443,7 @@ static int apply_syscall_filter(const Unit* u, const ExecContext *c, bool needs_
 
         negative_action = c->syscall_errno == 0 ? scmp_act_kill_process() : SCMP_ACT_ERRNO(c->syscall_errno);
 
-        if (c->syscall_whitelist) {
+        if (c->syscall_allow_list) {
                 default_action = negative_action;
                 action = SCMP_ACT_ALLOW;
         } else {
@@ -1460,7 +1452,7 @@ static int apply_syscall_filter(const Unit* u, const ExecContext *c, bool needs_
         }
 
         if (needs_ambient_hack) {
-                r = seccomp_filter_set_add(c->syscall_filter, c->syscall_whitelist, syscall_filter_sets + SYSCALL_FILTER_SET_SETUID);
+                r = seccomp_filter_set_add(c->syscall_filter, c->syscall_allow_list, syscall_filter_sets + SYSCALL_FILTER_SET_SETUID);
                 if (r < 0)
                         return r;
         }
@@ -1491,7 +1483,7 @@ static int apply_address_families(const Unit* u, const ExecContext *c) {
         if (skip_seccomp_unavailable(u, "RestrictAddressFamilies="))
                 return 0;
 
-        return seccomp_restrict_address_families(c->address_families, c->address_families_whitelist);
+        return seccomp_restrict_address_families(c->address_families, c->address_families_allow_list);
 }
 
 static int apply_memory_deny_write_execute(const Unit* u, const ExecContext *c) {
@@ -1577,7 +1569,7 @@ static int apply_protect_kernel_logs(const Unit *u, const ExecContext *c) {
         return seccomp_protect_syslog();
 }
 
-static int apply_protect_clock(const Unit *u, const ExecContext *c)  {
+static int apply_protect_clock(const Unit *u, const ExecContext *c) {
         assert(u);
         assert(c);
 
@@ -1646,6 +1638,41 @@ static int apply_lock_personality(const Unit* u, const ExecContext *c) {
 
 #endif
 
+static int apply_protect_hostname(const Unit *u, const ExecContext *c, int *ret_exit_status) {
+        assert(u);
+        assert(c);
+
+        if (!c->protect_hostname)
+                return 0;
+
+        if (ns_type_supported(NAMESPACE_UTS)) {
+                if (unshare(CLONE_NEWUTS) < 0) {
+                        if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) {
+                                *ret_exit_status = EXIT_NAMESPACE;
+                                return log_unit_error_errno(u, errno, "Failed to set up UTS namespacing: %m");
+                        }
+
+                        log_unit_warning(u, "ProtectHostname=yes is configured, but UTS namespace setup is prohibited (container manager?), ignoring namespace setup.");
+                }
+        } else
+                log_unit_warning(u, "ProtectHostname=yes is configured, but the kernel does not support UTS namespaces, ignoring namespace setup.");
+
+#if HAVE_SECCOMP
+        int r;
+
+        if (skip_seccomp_unavailable(u, "ProtectHostname="))
+                return 0;
+
+        r = seccomp_protect_hostname();
+        if (r < 0) {
+                *ret_exit_status = EXIT_SECCOMP;
+                return log_unit_error_errno(u, r, "Failed to apply hostname restrictions: %m");
+        }
+#endif
+
+        return 0;
+}
+
 static void do_idle_pipe_dance(int idle_pipe[static 4]) {
         assert(idle_pipe);
 
@@ -1785,12 +1812,13 @@ static int build_environment(
 
                 tty_path = exec_context_tty_path(c);
 
-                /* If we are forked off PID 1 and we are supposed to operate on /dev/console, then let's try to inherit
-                 * the $TERM set for PID 1. This is useful for containers so that the $TERM the container manager
-                 * passes to PID 1 ends up all the way in the console login shown. */
+                /* If we are forked off PID 1 and we are supposed to operate on /dev/console, then let's try
+                 * to inherit the $TERM set for PID 1. This is useful for containers so that the $TERM the
+                 * container manager passes to PID 1 ends up all the way in the console login shown. */
 
-                if (path_equal(tty_path, "/dev/console") && getppid() == 1)
+                if (path_equal_ptr(tty_path, "/dev/console") && getppid() == 1)
                         term = getenv("TERM");
+
                 if (!term)
                         term = default_term_for_tty(tty_path);
 
@@ -2531,7 +2559,7 @@ static bool insist_on_sandboxing(
         assert(n_bind_mounts == 0 || bind_mounts);
 
         /* Checks whether we need to insist on fs namespacing. i.e. whether we have settings configured that
-         * would alter the view on the file system beyond making things read-only or invisble, i.e. would
+         * would alter the view on the file system beyond making things read-only or invisible, i.e. would
          * rearrange stuff in a way we cannot ignore gracefully. */
 
         if (context->n_temporary_filesystems > 0)
@@ -2639,6 +2667,9 @@ static int apply_mount_namespace(
                             needs_sandboxing ? context->protect_home : PROTECT_HOME_NO,
                             needs_sandboxing ? context->protect_system : PROTECT_SYSTEM_NO,
                             context->mount_flags,
+                            context->root_hash, context->root_hash_size, context->root_hash_path,
+                            context->root_hash_sig, context->root_hash_sig_size, context->root_hash_sig_path,
+                            context->root_verity,
                             DISSECT_IMAGE_DISCARD_ON_LOOP|DISSECT_IMAGE_RELAX_VAR_CHECK|DISSECT_IMAGE_FSCK,
                             error_path);
 
@@ -3323,6 +3354,14 @@ static int exec_child(
                 }
         }
 
+        if (context->coredump_filter_set) {
+                r = set_coredump_filter(context->coredump_filter);
+                if (ERRNO_IS_PRIVILEGE(r))
+                        log_unit_debug_errno(unit, r, "Failed to adjust coredump_filter, ignoring: %m");
+                else if (r < 0)
+                        return log_unit_error_errno(unit, r, "Failed to adjust coredump_filter: %m");
+        }
+
         if (context->nice_set) {
                 r = setpriority_closest(context->nice);
                 if (r < 0)
@@ -3588,25 +3627,10 @@ static int exec_child(
                 }
         }
 
-        if (context->protect_hostname) {
-                if (ns_type_supported(NAMESPACE_UTS)) {
-                        if (unshare(CLONE_NEWUTS) < 0) {
-                                if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) {
-                                        *exit_status = EXIT_NAMESPACE;
-                                        return log_unit_error_errno(unit, errno, "Failed to set up UTS namespacing: %m");
-                                }
-
-                                log_unit_warning(unit, "ProtectHostname=yes is configured, but UTS namespace setup is prohibited (container manager?), ignoring namespace setup.");
-                        }
-                } else
-                        log_unit_warning(unit, "ProtectHostname=yes is configured, but the kernel does not support UTS namespaces, ignoring namespace setup.");
-#if HAVE_SECCOMP
-                r = seccomp_protect_hostname();
-                if (r < 0) {
-                        *exit_status = EXIT_SECCOMP;
-                        return log_unit_error_errno(unit, r, "Failed to apply hostname restrictions: %m");
-                }
-#endif
+        if (needs_sandboxing) {
+                r = apply_protect_hostname(unit, context, exit_status);
+                if (r < 0)
+                        return r;
         }
 
         /* Drop groups as early as possible.
@@ -4175,6 +4199,13 @@ void exec_context_done(ExecContext *c) {
         c->working_directory = mfree(c->working_directory);
         c->root_directory = mfree(c->root_directory);
         c->root_image = mfree(c->root_image);
+        c->root_hash = mfree(c->root_hash);
+        c->root_hash_size = 0;
+        c->root_hash_path = mfree(c->root_hash_path);
+        c->root_hash_sig = mfree(c->root_hash_sig);
+        c->root_hash_sig_size = 0;
+        c->root_hash_sig_path = mfree(c->root_hash_sig_path);
+        c->root_verity = mfree(c->root_verity);
         c->tty_path = mfree(c->tty_path);
         c->syslog_identifier = mfree(c->syslog_identifier);
         c->user = mfree(c->user);
@@ -4579,6 +4610,30 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
         if (c->root_image)
                 fprintf(f, "%sRootImage: %s\n", prefix, c->root_image);
 
+        if (c->root_hash) {
+                _cleanup_free_ char *encoded = NULL;
+                encoded = hexmem(c->root_hash, c->root_hash_size);
+                if (encoded)
+                        fprintf(f, "%sRootHash: %s\n", prefix, encoded);
+        }
+
+        if (c->root_hash_path)
+                fprintf(f, "%sRootHash: %s\n", prefix, c->root_hash_path);
+
+        if (c->root_hash_sig) {
+                _cleanup_free_ char *encoded = NULL;
+                ssize_t len;
+                len = base64mem(c->root_hash_sig, c->root_hash_sig_size, &encoded);
+                if (len)
+                        fprintf(f, "%sRootHashSignature: base64:%s\n", prefix, encoded);
+        }
+
+        if (c->root_hash_sig_path)
+                fprintf(f, "%sRootHashSignature: %s\n", prefix, c->root_hash_sig_path);
+
+        if (c->root_verity)
+                fprintf(f, "%sRootVerity: %s\n", prefix, c->root_verity);
+
         STRV_FOREACH(e, c->environment)
                 fprintf(f, "%sEnvironment: %s\n", prefix, *e);
 
@@ -4614,6 +4669,11 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
                         "%sOOMScoreAdjust: %i\n",
                         prefix, c->oom_score_adjust);
 
+        if (c->coredump_filter_set)
+                fprintf(f,
+                        "%sCoredumpFilter: 0x%"PRIx64"\n",
+                        prefix, c->coredump_filter);
+
         for (i = 0; i < RLIM_NLIMITS; i++)
                 if (c->rlimit[i]) {
                         fprintf(f, "%sLimit%s: " RLIM_FMT "\n",
@@ -4702,17 +4762,13 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
                         prefix, yes_no(c->tty_vt_disallocate));
 
         if (IN_SET(c->std_output,
-                   EXEC_OUTPUT_SYSLOG,
                    EXEC_OUTPUT_KMSG,
                    EXEC_OUTPUT_JOURNAL,
-                   EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
                    EXEC_OUTPUT_KMSG_AND_CONSOLE,
                    EXEC_OUTPUT_JOURNAL_AND_CONSOLE) ||
             IN_SET(c->std_error,
-                   EXEC_OUTPUT_SYSLOG,
                    EXEC_OUTPUT_KMSG,
                    EXEC_OUTPUT_JOURNAL,
-                   EXEC_OUTPUT_SYSLOG_AND_CONSOLE,
                    EXEC_OUTPUT_KMSG_AND_CONSOLE,
                    EXEC_OUTPUT_JOURNAL_AND_CONSOLE)) {
 
@@ -4878,7 +4934,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) {
                         "%sSystemCallFilter: ",
                         prefix);
 
-                if (!c->syscall_whitelist)
+                if (!c->syscall_allow_list)
                         fputc('~', f);
 
 #if HAVE_SECCOMP
@@ -5730,8 +5786,6 @@ static const char* const exec_output_table[_EXEC_OUTPUT_MAX] = {
         [EXEC_OUTPUT_INHERIT] = "inherit",
         [EXEC_OUTPUT_NULL] = "null",
         [EXEC_OUTPUT_TTY] = "tty",
-        [EXEC_OUTPUT_SYSLOG] = "syslog",
-        [EXEC_OUTPUT_SYSLOG_AND_CONSOLE] = "syslog+console",
         [EXEC_OUTPUT_KMSG] = "kmsg",
         [EXEC_OUTPUT_KMSG_AND_CONSOLE] = "kmsg+console",
         [EXEC_OUTPUT_JOURNAL] = "journal",