diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml index a5c98d3458..20bbae4487 100644 --- a/man/org.freedesktop.systemd1.xml +++ b/man/org.freedesktop.systemd1.xml @@ -3333,6 +3333,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b MountAPIVFS = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly b BindJournalSockets = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly s KeyringMode = '...'; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly s ProtectProc = '...'; @@ -3932,6 +3934,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { + + @@ -4642,6 +4646,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { + + @@ -5468,6 +5474,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b MountAPIVFS = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly b BindJournalSockets = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly s KeyringMode = '...'; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly s ProtectProc = '...'; @@ -6079,6 +6087,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { + + @@ -6763,6 +6773,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { + + @@ -7453,6 +7465,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b MountAPIVFS = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly b BindJournalSockets = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly s KeyringMode = '...'; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly s ProtectProc = '...'; @@ -7990,6 +8004,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { + + @@ -8586,6 +8602,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { + + @@ -9399,6 +9417,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly b MountAPIVFS = ...; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") + readonly b BindJournalSockets = ...; + @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly s KeyringMode = '...'; @org.freedesktop.DBus.Property.EmitsChangedSignal("const") readonly s ProtectProc = '...'; @@ -9922,6 +9942,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { + + @@ -10504,6 +10526,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { + + @@ -12149,8 +12173,9 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \ StatusBusError, StatusVarlinkError, LiveMountResult, - PrivateTmpEx, and - ImportCredentialEx were added in version 257. + PrivateTmpEx, + ImportCredentialEx, and + BindJournalSockets were added in version 257. Socket Unit Objects @@ -12187,8 +12212,9 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \ EffectiveTasksMax, MemoryZSwapWriteback, and PassFileDescriptorsToExec were added in version 256. - PrivateTmpEx, and - ImportCredentialEx were added in version 257. + PrivateTmpEx, + ImportCredentialEx, and + BindJournalSockets were added in version 257. Mount Unit Objects @@ -12222,8 +12248,9 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \ EffectiveMemoryMax, EffectiveTasksMax, and MemoryZSwapWriteback were added in version 256. - PrivateTmpEx, and - ImportCredentialEx were added in version 257. + PrivateTmpEx, + ImportCredentialEx, and + BindJournalSockets were added in version 257. Swap Unit Objects @@ -12257,8 +12284,9 @@ $ gdbus introspect --system --dest org.freedesktop.systemd1 \ EffectiveMemoryMax, EffectiveTasksMax, and MemoryZSwapWriteback were added in version 256. - PrivateTmpEx, and - ImportCredentialEx were added in version 257. + PrivateTmpEx, + ImportCredentialEx, and + BindJournalSockets were added in version 257. Slice Unit Objects diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index c9ae38bf1f..0318961569 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -366,6 +366,23 @@ + + BindJournalSockets= + + Takes a boolean argument. If true, sockets from + systemd-journald.socket8 + will be bind mounted into the mount namespace. This is particularly useful when a different instance + of /run/ is employed, to make sure processes running in the namespace + can still make use of sd-journal3. + + + This option is implied when LogNamespace= is used, + when MountAPIVFS=yes, or when PrivateDevices=yes is used + in conjunction with either RootDirectory= or RootImage=. + + + + ProtectProc= diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 2954f63422..4679f54a3e 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -55,6 +55,7 @@ static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_protect_system, protect_system, static BUS_DEFINE_PROPERTY_GET_ENUM(property_get_personality, personality, unsigned long); static BUS_DEFINE_PROPERTY_GET(property_get_ioprio, "i", ExecContext, exec_context_get_effective_ioprio); static BUS_DEFINE_PROPERTY_GET(property_get_mount_apivfs, "b", ExecContext, exec_context_get_effective_mount_apivfs); +static BUS_DEFINE_PROPERTY_GET(property_get_bind_journal_sockets, "b", ExecContext, exec_context_get_effective_bind_journal_sockets); static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_class, "i", ExecContext, exec_context_get_effective_ioprio, ioprio_prio_class); static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext, exec_context_get_effective_ioprio, ioprio_prio_data); static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL); @@ -1193,6 +1194,7 @@ const sd_bus_vtable bus_exec_vtable[] = { SD_BUS_PROPERTY("BindReadOnlyPaths", "a(ssbt)", property_get_bind_paths, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("TemporaryFileSystem", "a(ss)", property_get_temporary_filesystems, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("MountAPIVFS", "b", property_get_mount_apivfs, 0, SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("BindJournalSockets", "b", property_get_bind_journal_sockets, 0, SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("KeyringMode", "s", property_get_exec_keyring_mode, offsetof(ExecContext, keyring_mode), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ProtectProc", "s", property_get_protect_proc, offsetof(ExecContext, protect_proc), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ProcSubset", "s", property_get_proc_subset, offsetof(ExecContext, proc_subset), SD_BUS_VTABLE_PROPERTY_CONST), @@ -1864,6 +1866,9 @@ int bus_exec_context_set_transient_property( if (streq(name, "MountAPIVFS")) return bus_set_transient_tristate(u, name, &c->mount_apivfs, message, flags, error); + if (streq(name, "BindJournalSockets")) + return bus_set_transient_tristate(u, name, &c->bind_journal_sockets, message, flags, error); + if (streq(name, "PrivateNetwork")) return bus_set_transient_bool(u, name, &c->private_network, message, flags, error); diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c index 183bca092d..af5552379e 100644 --- a/src/core/exec-invoke.c +++ b/src/core/exec-invoke.c @@ -3240,6 +3240,7 @@ static int apply_mount_namespace( .private_tmp = needs_sandboxing ? context->private_tmp : false, .mount_apivfs = needs_sandboxing && exec_context_get_effective_mount_apivfs(context), + .bind_journal_sockets = needs_sandboxing && exec_context_get_effective_bind_journal_sockets(context), /* If NNP is on, we can turn on MS_NOSUID, since it won't have any effect anymore. */ .mount_nosuid = needs_sandboxing && context->no_new_privileges && !mac_selinux_use(), @@ -3861,6 +3862,7 @@ static bool exec_context_need_unprivileged_private_users( context->ipc_namespace_path || context->private_mounts > 0 || context->mount_apivfs > 0 || + context->bind_journal_sockets > 0 || context->n_bind_mounts > 0 || context->n_temporary_filesystems > 0 || context->root_directory || diff --git a/src/core/execute-serialize.c b/src/core/execute-serialize.c index 84628f91fb..32d6118ab7 100644 --- a/src/core/execute-serialize.c +++ b/src/core/execute-serialize.c @@ -1854,6 +1854,10 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) { if (r < 0) return r; + r = serialize_item_tristate(f, "exec-context-bind-journal-sockets", c->bind_journal_sockets); + if (r < 0) + return r; + r = serialize_item_tristate(f, "exec-context-memory-ksm", c->memory_ksm); if (r < 0) return r; @@ -2726,6 +2730,10 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) { r = safe_atoi(val, &c->mount_apivfs); if (r < 0) return r; + } else if ((val = startswith(l, "exec-context-bind-journal-sockets="))) { + r = safe_atoi(val, &c->bind_journal_sockets); + if (r < 0) + return r; } else if ((val = startswith(l, "exec-context-memory-ksm="))) { r = safe_atoi(val, &c->memory_ksm); if (r < 0) diff --git a/src/core/execute.c b/src/core/execute.c index 5bbd1d835c..7a365e23b9 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -284,7 +284,7 @@ bool exec_needs_mount_namespace( context->directories[EXEC_DIRECTORY_LOGS].n_items > 0)) return true; - if (context->log_namespace) + if (exec_context_get_effective_bind_journal_sockets(context)) return true; return false; @@ -539,6 +539,7 @@ void exec_context_init(ExecContext *c) { .tty_cols = UINT_MAX, .private_mounts = -1, .mount_apivfs = -1, + .bind_journal_sockets = -1, .memory_ksm = -1, .set_login_environment = -1, }; @@ -979,6 +980,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { "%sProtectHome: %s\n" "%sProtectSystem: %s\n" "%sMountAPIVFS: %s\n" + "%sBindJournalSockets: %s\n" "%sIgnoreSIGPIPE: %s\n" "%sMemoryDenyWriteExecute: %s\n" "%sRestrictRealtime: %s\n" @@ -1004,6 +1006,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { prefix, protect_home_to_string(c->protect_home), prefix, protect_system_to_string(c->protect_system), prefix, yes_no(exec_context_get_effective_mount_apivfs(c)), + prefix, yes_no(exec_context_get_effective_bind_journal_sockets(c)), prefix, yes_no(c->ignore_sigpipe), prefix, yes_no(c->memory_deny_write_execute), prefix, yes_no(c->restrict_realtime), @@ -1486,6 +1489,27 @@ bool exec_context_get_effective_mount_apivfs(const ExecContext *c) { return false; } +bool exec_context_get_effective_bind_journal_sockets(const ExecContext *c) { + assert(c); + + /* If log namespace is specified, "/run/systemd/journal.namespace/" would be bind mounted to + * "/run/systemd/journal/", which effectively means BindJournalSockets=yes */ + if (c->log_namespace) + return true; + + if (c->bind_journal_sockets >= 0) + return c->bind_journal_sockets > 0; + + if (exec_context_get_effective_mount_apivfs(c)) + return true; + + /* When PrivateDevices=yes, /dev/log gets symlinked to /run/systemd/journal/dev-log */ + if (exec_context_with_rootfs(c) && c->private_devices) + return true; + + return false; +} + void exec_context_free_log_extra_fields(ExecContext *c) { assert(c); diff --git a/src/core/execute.h b/src/core/execute.h index a3fc52bfd0..5754273999 100644 --- a/src/core/execute.h +++ b/src/core/execute.h @@ -313,6 +313,7 @@ struct ExecContext { int private_mounts; int mount_apivfs; + int bind_journal_sockets; int memory_ksm; PrivateTmp private_tmp; bool private_network; @@ -519,6 +520,7 @@ bool exec_context_maintains_privileges(const ExecContext *c); int exec_context_get_effective_ioprio(const ExecContext *c); bool exec_context_get_effective_mount_apivfs(const ExecContext *c); +bool exec_context_get_effective_bind_journal_sockets(const ExecContext *c); void exec_context_free_log_extra_fields(ExecContext *c); diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in index 7441d3c759..32ac87ce85 100644 --- a/src/core/load-fragment-gperf.gperf.in +++ b/src/core/load-fragment-gperf.gperf.in @@ -137,6 +137,7 @@ {{type}}.ProtectHome, config_parse_protect_home, 0, offsetof({{type}}, exec_context.protect_home) {{type}}.MountFlags, config_parse_exec_mount_propagation_flag, 0, offsetof({{type}}, exec_context.mount_propagation_flag) {{type}}.MountAPIVFS, config_parse_tristate, 0, offsetof({{type}}, exec_context.mount_apivfs) +{{type}}.BindJournalSockets, config_parse_tristate, 0, offsetof({{type}}, exec_context.bind_journal_sockets) {{type}}.Personality, config_parse_personality, 0, offsetof({{type}}, exec_context.personality) {{type}}.RuntimeDirectoryPreserve, config_parse_exec_preserve_mode, 0, offsetof({{type}}, exec_context.runtime_directory_preserve_mode) {{type}}.RuntimeDirectoryMode, config_parse_mode, 0, offsetof({{type}}, exec_context.directories[EXEC_DIRECTORY_RUNTIME].mode) diff --git a/src/core/namespace.c b/src/core/namespace.c index 314268e2eb..323ff4c279 100644 --- a/src/core/namespace.c +++ b/src/core/namespace.c @@ -93,7 +93,7 @@ typedef struct MountEntry { const char *path_const; /* Memory allocated on stack or static */ MountMode mode; bool ignore:1; /* Ignore if path does not exist? */ - bool has_prefix:1; /* Already is prefixed by the root dir? */ + bool has_prefix:1; /* Already prefixed by the root dir? */ bool read_only:1; /* Shall this mount point be read-only? */ bool nosuid:1; /* Shall set MS_NOSUID on the mount itself */ bool noexec:1; /* Shall set MS_NOEXEC on the mount itself */ @@ -120,6 +120,12 @@ typedef struct MountList { size_t n_mounts; } MountList; +static const BindMount bind_journal_sockets_table[] = { + { (char*) "/run/systemd/journal/socket", (char*) "/run/systemd/journal/socket", .read_only = true, .ignore_enoent = true }, + { (char*) "/run/systemd/journal/stdout", (char*) "/run/systemd/journal/stdout", .read_only = true, .ignore_enoent = true }, + { (char*) "/run/systemd/journal/dev-log", (char*) "/run/systemd/journal/dev-log", .read_only = true, .ignore_enoent = true }, +}; + /* If MountAPIVFS= is used, let's mount /sys, /proc, /dev and /run into the it, but only as a fallback if the user hasn't mounted * something there already. These mounts are hence overridden by any other explicitly configured mounts. */ static const MountEntry apivfs_table[] = { @@ -1078,7 +1084,7 @@ static int create_temporary_mount_point(RuntimeScope scope, char **ret) { return 0; } -static int mount_private_dev(MountEntry *m, RuntimeScope scope) { +static int mount_private_dev(const MountEntry *m, const NamespaceParameters *p) { static const char devnodes[] = "/dev/null\0" "/dev/zero\0" @@ -1093,8 +1099,9 @@ static int mount_private_dev(MountEntry *m, RuntimeScope scope) { int r; assert(m); + assert(p); - r = create_temporary_mount_point(scope, &temporary_mount); + r = create_temporary_mount_point(p->runtime_scope, &temporary_mount); if (r < 0) return r; @@ -1139,9 +1146,13 @@ static int mount_private_dev(MountEntry *m, RuntimeScope scope) { FOREACH_STRING(d, "/dev/mqueue", "/dev/hugepages") (void) bind_mount_device_dir(temporary_mount, d); - const char *devlog = strjoina(temporary_mount, "/dev/log"); - if (symlink("/run/systemd/journal/dev-log", devlog) < 0) - log_debug_errno(errno, "Failed to create symlink '%s' to /run/systemd/journal/dev-log, ignoring: %m", devlog); + if ((!p->root_image && !p->root_directory) || p->bind_journal_sockets) { + const char *devlog = strjoina(temporary_mount, "/dev/log"); + if (symlink("/run/systemd/journal/dev-log", devlog) < 0) + log_debug_errno(errno, + "Failed to create symlink '%s' to /run/systemd/journal/dev-log, ignoring: %m", + devlog); + } NULSTR_FOREACH(d, devnodes) { r = clone_device_node(d, temporary_mount, &can_mknod); @@ -1720,7 +1731,7 @@ static int apply_one_mount( break; case MOUNT_PRIVATE_DEV: - return mount_private_dev(m, p->runtime_scope); + return mount_private_dev(m, p); case MOUNT_BIND_DEV: return mount_bind_dev(m); @@ -2585,6 +2596,11 @@ int setup_namespace(const NamespaceParameters *p, char **error_path) { .read_only = true, .source_malloc = TAKE_PTR(q), }; + + } else if (p->bind_journal_sockets) { + r = append_bind_mounts(&ml, bind_journal_sockets_table, ELEMENTSOF(bind_journal_sockets_table)); + if (r < 0) + return r; } /* Will be used to add bind mounts at runtime */ diff --git a/src/core/namespace.h b/src/core/namespace.h index bff99b9daa..538d23753c 100644 --- a/src/core/namespace.h +++ b/src/core/namespace.h @@ -152,6 +152,7 @@ struct NamespaceParameters { bool private_ipc; bool mount_apivfs; + bool bind_journal_sockets; bool mount_nosuid; ProtectHome protect_home; diff --git a/src/portable/profile/default/service.conf b/src/portable/profile/default/service.conf index d2551ef8c8..07f985cefa 100644 --- a/src/portable/profile/default/service.conf +++ b/src/portable/profile/default/service.conf @@ -2,7 +2,7 @@ [Service] MountAPIVFS=yes -BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout +BindJournalSockets=yes BindReadOnlyPaths=/etc/machine-id BindReadOnlyPaths=-/etc/resolv.conf BindReadOnlyPaths=/run/dbus/system_bus_socket diff --git a/src/portable/profile/nonetwork/service.conf b/src/portable/profile/nonetwork/service.conf index 83e4770e78..ee7aa2d525 100644 --- a/src/portable/profile/nonetwork/service.conf +++ b/src/portable/profile/nonetwork/service.conf @@ -2,7 +2,7 @@ [Service] MountAPIVFS=yes -BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout +BindJournalSockets=yes BindReadOnlyPaths=/etc/machine-id BindReadOnlyPaths=/run/dbus/system_bus_socket DynamicUser=yes diff --git a/src/portable/profile/strict/service.conf b/src/portable/profile/strict/service.conf index bb877c517d..ed14387b5d 100644 --- a/src/portable/profile/strict/service.conf +++ b/src/portable/profile/strict/service.conf @@ -2,7 +2,7 @@ [Service] MountAPIVFS=yes -BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout +BindJournalSockets=yes BindReadOnlyPaths=/etc/machine-id DynamicUser=yes RemoveIPC=yes diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c index 6ce76ded43..edfe1482c8 100644 --- a/src/shared/bus-unit-util.c +++ b/src/shared/bus-unit-util.c @@ -1076,6 +1076,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con "ProtectClock", "ProtectControlGroups", "MountAPIVFS", + "BindJournalSockets", "CPUSchedulingResetOnFork", "LockPersonality", "ProtectHostname", diff --git a/test/test-functions b/test/test-functions index 33e41a1aaa..64a664b69e 100644 --- a/test/test-functions +++ b/test/test-functions @@ -731,7 +731,9 @@ install_verity_minimal() { cat echo grep + ls mount + mountpoint sleep touch ) diff --git a/test/units/TEST-50-DISSECT.dissect.sh b/test/units/TEST-50-DISSECT.dissect.sh index 9a05899cab..5e4899788f 100755 --- a/test/units/TEST-50-DISSECT.dissect.sh +++ b/test/units/TEST-50-DISSECT.dissect.sh @@ -9,12 +9,6 @@ set -o pipefail # shellcheck source=test/units/util.sh . "$(dirname "$0")"/util.sh -BIND_LOG_SOCKETS=( - --property BindReadOnlyPaths=/dev/log - --property BindReadOnlyPaths=/run/systemd/journal/socket - --property BindReadOnlyPaths=/run/systemd/journal/stdout -) - systemd-dissect --json=short "$MINIMAL_IMAGE.raw" | \ grep -q -F '{"rw":"ro","designator":"root","partition_uuid":null,"partition_label":null,"fstype":"squashfs","architecture":null,"verity":"external"' systemd-dissect "$MINIMAL_IMAGE.raw" | grep -q -F "MARKER=1" @@ -80,21 +74,25 @@ fi systemd-dissect --umount "$IMAGE_DIR/mount" systemd-dissect --umount "$IMAGE_DIR/mount2" -systemd-run -P -p RootImage="$MINIMAL_IMAGE.raw" "${BIND_LOG_SOCKETS[@]}" cat /usr/lib/os-release | grep -q -F "MARKER=1" +# Test BindJournalSockets= +systemd-run --wait -p RootImage="$MINIMAL_IMAGE.raw" mountpoint /run/systemd/journal/socket +(! systemd-run --wait -p RootImage="$MINIMAL_IMAGE.raw" -p BindJournalSockets=no ls /run/systemd/journal/socket) +(! systemd-run --wait -p RootImage="$MINIMAL_IMAGE.raw" -p MountAPIVFS=no ls /run/systemd/journal/socket) + +systemd-run -P -p RootImage="$MINIMAL_IMAGE.raw" cat /usr/lib/os-release | grep -q -F "MARKER=1" mv "$MINIMAL_IMAGE.verity" "$MINIMAL_IMAGE.fooverity" mv "$MINIMAL_IMAGE.roothash" "$MINIMAL_IMAGE.foohash" systemd-run -P \ -p RootImage="$MINIMAL_IMAGE.raw" \ -p RootHash="$MINIMAL_IMAGE.foohash" \ -p RootVerity="$MINIMAL_IMAGE.fooverity" \ - "${BIND_LOG_SOCKETS[@]}" \ + -p BindJournalSockets=yes \ cat /usr/lib/os-release | grep -q -F "MARKER=1" # Let's use the long option name just here as a test systemd-run -P \ --property RootImage="$MINIMAL_IMAGE.raw" \ --property RootHash="$MINIMAL_IMAGE_ROOTHASH" \ --property RootVerity="$MINIMAL_IMAGE.fooverity" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/os-release | grep -q -F "MARKER=1" mv "$MINIMAL_IMAGE.fooverity" "$MINIMAL_IMAGE.verity" mv "$MINIMAL_IMAGE.foohash" "$MINIMAL_IMAGE.roothash" @@ -142,56 +140,48 @@ systemd-run --wait -P \ -p RootImage="$MINIMAL_IMAGE.gpt" \ -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ -p MountAPIVFS=yes \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/os-release | grep -q -F "MARKER=1" systemd-run --wait -P \ -p RootImage="$MINIMAL_IMAGE.gpt" \ -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ -p RootImagePolicy='*' \ -p MountAPIVFS=yes \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/os-release | grep -q -F "MARKER=1" (! systemd-run --wait -P \ -p RootImage="$MINIMAL_IMAGE.gpt" \ -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ -p RootImagePolicy='~' \ -p MountAPIVFS=yes \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/os-release | grep -q -F "MARKER=1") (! systemd-run --wait -P \ -p RootImage="$MINIMAL_IMAGE.gpt" \ -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ -p RootImagePolicy='-' \ -p MountAPIVFS=yes \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/os-release | grep -q -F "MARKER=1") (! systemd-run --wait -P \ -p RootImage="$MINIMAL_IMAGE.gpt" \ -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ -p RootImagePolicy='root=absent' \ -p MountAPIVFS=yes \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/os-release | grep -q -F "MARKER=1") systemd-run --wait -P \ -p RootImage="$MINIMAL_IMAGE.gpt" \ -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ -p RootImagePolicy='root=verity' \ -p MountAPIVFS=yes \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/os-release | grep -q -F "MARKER=1" systemd-run --wait -P \ -p RootImage="$MINIMAL_IMAGE.gpt" \ -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ -p RootImagePolicy='root=signed' \ -p MountAPIVFS=yes \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/os-release | grep -q -F "MARKER=1" (! systemd-run --wait -P \ -p RootImage="$MINIMAL_IMAGE.gpt" \ -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ -p RootImagePolicy='root=encrypted' \ -p MountAPIVFS=yes \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/os-release | grep -q -F "MARKER=1") systemd-dissect --root-hash "$MINIMAL_IMAGE_ROOTHASH" --mount "$MINIMAL_IMAGE.gpt" "$IMAGE_DIR/mount" @@ -211,17 +201,14 @@ systemd-run -P \ -p RootImage="$MINIMAL_IMAGE.gpt" \ -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ -p MountAPIVFS=yes \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/os-release | grep -q -F "MARKER=1" systemd-run -P \ -p RootImage="$MINIMAL_IMAGE.raw" \ -p RootImageOptions="root:nosuid,dev home:ro,dev ro,noatime" \ - "${BIND_LOG_SOCKETS[@]}" \ mount | grep -F "squashfs" | grep -q -F "nosuid" systemd-run -P \ -p RootImage="$MINIMAL_IMAGE.gpt" \ -p RootImageOptions="root:ro,noatime root:ro,dev" \ - "${BIND_LOG_SOCKETS[@]}" \ mount | grep -F "squashfs" | grep -q -F "noatime" mkdir -p "$IMAGE_DIR/result" @@ -234,7 +221,6 @@ TemporaryFileSystem=/run RootImage=$MINIMAL_IMAGE.raw RootImageOptions=root:ro,noatime home:ro,dev relatime,dev RootImageOptions=nosuid,dev -BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout EOF systemctl start testservice-50a.service grep -F "squashfs" "$IMAGE_DIR/result/a" | grep -q -F "noatime" @@ -251,7 +237,6 @@ RootImageOptions=root:ro,noatime,nosuid home:ro,dev nosuid,dev RootImageOptions=home:ro,dev nosuid,dev,%%foo # this is the default, but let's specify once to test the parser MountAPIVFS=yes -BindReadOnlyPaths=/dev/log /run/systemd/journal/socket /run/systemd/journal/stdout EOF systemctl start testservice-50b.service grep -F "squashfs" "$IMAGE_DIR/result/b" | grep -q -F "noatime" @@ -284,27 +269,23 @@ systemd-run -P \ -p TemporaryFileSystem=/run \ -p RootImage="$MINIMAL_IMAGE.raw" \ -p MountImages="$MINIMAL_IMAGE.gpt:/run/img1 $MINIMAL_IMAGE.raw:/run/img2" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/os-release | grep -q -F "MARKER=1" systemd-run -P \ -p TemporaryFileSystem=/run \ -p RootImage="$MINIMAL_IMAGE.raw" \ -p MountImages="$MINIMAL_IMAGE.gpt:/run/img1 $MINIMAL_IMAGE.raw:/run/img2" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /run/img1/usr/lib/os-release | grep -q -F "MARKER=1" systemd-run -P \ -p TemporaryFileSystem=/run \ -p RootImage="$MINIMAL_IMAGE.gpt" \ -p RootHash="$MINIMAL_IMAGE_ROOTHASH" \ -p MountImages="$MINIMAL_IMAGE.gpt:/run/img1 $MINIMAL_IMAGE.raw:/run/img2" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /run/img2/usr/lib/os-release | grep -q -F "MARKER=1" cat >/run/systemd/system/testservice-50c.service </run/result/c" @@ -352,42 +333,34 @@ systemctl is-active testservice-50d.service systemd-run -P \ --property ExtensionImages=/tmp/app0.raw \ --property RootImage="$MINIMAL_IMAGE.raw" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /opt/script0.sh | grep -q -F "extension-release.app0" systemd-run -P \ --property ExtensionImages=/tmp/app0.raw \ --property RootImage="$MINIMAL_IMAGE.raw" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" systemd-run -P \ --property ExtensionImages="/tmp/app0.raw /tmp/app1.raw" \ --property RootImage="$MINIMAL_IMAGE.raw" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /opt/script0.sh | grep -q -F "extension-release.app0" systemd-run -P \ --property ExtensionImages="/tmp/app0.raw /tmp/app1.raw" \ --property RootImage="$MINIMAL_IMAGE.raw" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" systemd-run -P \ --property ExtensionImages="/tmp/app0.raw /tmp/app1.raw" \ --property RootImage="$MINIMAL_IMAGE.raw" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /opt/script1.sh | grep -q -F "extension-release.app2" systemd-run -P \ --property ExtensionImages="/tmp/app0.raw /tmp/app1.raw" \ --property RootImage="$MINIMAL_IMAGE.raw" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/systemd/system/other_file | grep -q -F "MARKER=1" systemd-run -P \ --property ExtensionImages=/tmp/app-nodistro.raw \ --property RootImage="$MINIMAL_IMAGE.raw" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" systemd-run -P \ --property ExtensionImages=/etc/service-scoped-test.raw \ --property RootImage="$MINIMAL_IMAGE.raw" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /etc/systemd/system/some_file | grep -q -F "MARKER_CONFEXT_123" # Check that two identical verity images at different paths do not fail with -ELOOP from OverlayFS @@ -412,7 +385,6 @@ ln -fs /tmp/symlink-test/app-nodistro-v1.raw /tmp/symlink-test/app-nodistro.raw systemd-run -P \ --property ExtensionImages=/tmp/symlink-test/app-nodistro.raw \ --property RootImage="$MINIMAL_IMAGE.raw" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" # Symlink check again but for confext @@ -422,20 +394,17 @@ ln -fs /etc/symlink-test/service-scoped-test-v1.raw /etc/symlink-test/service-sc systemd-run -P \ --property ExtensionImages=/etc/symlink-test/service-scoped-test.raw \ --property RootImage="$MINIMAL_IMAGE.raw" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /etc/systemd/system/some_file | grep -q -F "MARKER_CONFEXT_123" # And again mixing sysext and confext systemd-run -P \ --property ExtensionImages=/tmp/symlink-test/app-nodistro.raw \ --property ExtensionImages=/etc/symlink-test/service-scoped-test.raw \ --property RootImage="$MINIMAL_IMAGE.raw" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /etc/systemd/system/some_file | grep -q -F "MARKER_CONFEXT_123" systemd-run -P \ --property ExtensionImages=/tmp/symlink-test/app-nodistro.raw \ --property ExtensionImages=/etc/symlink-test/service-scoped-test.raw \ --property RootImage="$MINIMAL_IMAGE.raw" \ - "${BIND_LOG_SOCKETS[@]}" \ cat /usr/lib/systemd/system/some_file | grep -q -F "MARKER=1" cat >/run/systemd/system/testservice-50e.service </run/systemd/system/testservice-50f.service <