summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2022-10-16 23:25:04 +0200
committerLennart Poettering <lennart@poettering.net>2023-01-17 09:42:16 +0100
commit04959faa632272a8fc9cdac3121b2e4af721c1b6 (patch)
tree71b689e13950e8464c66653d67970aa178567db1
parent50072ccf1bfee8a53563a083a3a52b26f0d5678f (diff)
downloadsystemd-04959faa632272a8fc9cdac3121b2e4af721c1b6.tar.gz
generators: optionally, measure file systems at boot
If we use gpt-auto-generator, automatically measure root fs and /var. Otherwise, add x-systemd.measure option to request this.
-rw-r--r--src/basic/special.h2
-rw-r--r--src/fstab-generator/fstab-generator.c19
-rw-r--r--src/gpt-auto-generator/gpt-auto-generator.c6
-rw-r--r--src/shared/generator.c37
-rw-r--r--src/shared/generator.h4
-rw-r--r--units/meson.build2
-rw-r--r--units/systemd-pcrfs-root.service.in24
-rw-r--r--units/systemd-pcrfs@.service.in25
8 files changed, 115 insertions, 4 deletions
diff --git a/src/basic/special.h b/src/basic/special.h
index 9bb36c5732..0e4342eb40 100644
--- a/src/basic/special.h
+++ b/src/basic/special.h
@@ -89,6 +89,8 @@
#define SPECIAL_UDEVD_SERVICE "systemd-udevd.service"
#define SPECIAL_GROWFS_SERVICE "systemd-growfs@.service"
#define SPECIAL_GROWFS_ROOT_SERVICE "systemd-growfs-root.service"
+#define SPECIAL_PCRFS_SERVICE "systemd-pcrfs@.service"
+#define SPECIAL_PCRFS_ROOT_SERVICE "systemd-pcrfs-root.service"
/* Services systemd relies on */
#define SPECIAL_DBUS_SERVICE "dbus.service"
diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c
index b0ea536eb2..4b763bc247 100644
--- a/src/fstab-generator/fstab-generator.c
+++ b/src/fstab-generator/fstab-generator.c
@@ -40,6 +40,7 @@ typedef enum MountPointFlags {
MOUNT_MAKEFS = 1 << 3,
MOUNT_GROWFS = 1 << 4,
MOUNT_RW_ONLY = 1 << 5,
+ MOUNT_PCRFS = 1 << 6,
} MountPointFlags;
static bool arg_sysroot_check = false;
@@ -176,6 +177,8 @@ static int add_swap(
if (flags & MOUNT_GROWFS)
/* TODO: swap devices must be wiped and recreated */
log_warning("%s: growing swap devices is currently unsupported.", what);
+ if (flags & MOUNT_PCRFS)
+ log_warning("%s: measuring swap devices is currently unsupported.", what);
if (!(flags & MOUNT_NOAUTO)) {
r = generator_add_symlink(arg_dest, SPECIAL_SWAP_TARGET,
@@ -525,6 +528,12 @@ static int add_mount(
return r;
}
+ if (flags & MOUNT_PCRFS) {
+ r = generator_hook_up_pcrfs(dest, where, target_unit);
+ if (r < 0)
+ return r;
+ }
+
if (!FLAGS_SET(flags, MOUNT_AUTOMOUNT)) {
if (!FLAGS_SET(flags, MOUNT_NOAUTO) && strv_isempty(wanted_by) && strv_isempty(required_by)) {
r = generator_add_symlink(dest, target_unit,
@@ -658,7 +667,7 @@ static int parse_fstab(bool initrd) {
while ((me = getmntent(f))) {
_cleanup_free_ char *where = NULL, *what = NULL, *canonical_where = NULL;
- bool makefs, growfs, noauto, nofail;
+ bool makefs, growfs, pcrfs, noauto, nofail;
MountPointFlags flags;
int k;
@@ -718,16 +727,18 @@ static int parse_fstab(bool initrd) {
makefs = fstab_test_option(me->mnt_opts, "x-systemd.makefs\0");
growfs = fstab_test_option(me->mnt_opts, "x-systemd.growfs\0");
+ pcrfs = fstab_test_option(me->mnt_opts, "x-systemd.pcrfs\0");
noauto = fstab_test_yes_no_option(me->mnt_opts, "noauto\0" "auto\0");
nofail = fstab_test_yes_no_option(me->mnt_opts, "nofail\0" "fail\0");
- log_debug("Found entry what=%s where=%s type=%s makefs=%s growfs=%s noauto=%s nofail=%s",
+ log_debug("Found entry what=%s where=%s type=%s makefs=%s growfs=%s pcrfs=%s noauto=%s nofail=%s",
what, where, me->mnt_type,
- yes_no(makefs), yes_no(growfs),
+ yes_no(makefs), yes_no(growfs), yes_no(pcrfs),
yes_no(noauto), yes_no(nofail));
flags = makefs * MOUNT_MAKEFS |
growfs * MOUNT_GROWFS |
+ pcrfs * MOUNT_PCRFS |
noauto * MOUNT_NOAUTO |
nofail * MOUNT_NOFAIL;
@@ -911,7 +922,7 @@ static int add_sysroot_mount(void) {
fstype,
opts,
is_device_path(what) ? 1 : 0, /* passno */
- flags, /* makefs, growfs off, noauto off, nofail off, automount off */
+ flags, /* makefs off, pcrfs off, noauto off, nofail off, automount off */
SPECIAL_INITRD_ROOT_FS_TARGET);
}
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
index 1fc7586524..63bb2a3cbb 100644
--- a/src/gpt-auto-generator/gpt-auto-generator.c
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
@@ -259,6 +259,12 @@ static int add_mount(
return r;
}
+ if (measure) {
+ r = generator_hook_up_pcrfs(arg_dest, where, post);
+ if (r < 0)
+ return r;
+ }
+
if (post) {
r = generator_add_symlink(arg_dest, post, "requires", unit);
if (r < 0)
diff --git a/src/shared/generator.c b/src/shared/generator.c
index 6c82d0f0ef..64f4a2741c 100644
--- a/src/shared/generator.c
+++ b/src/shared/generator.c
@@ -650,6 +650,43 @@ int generator_hook_up_growfs(
return generator_add_symlink_full(dir, where_unit, "wants", growfs_unit_path, instance);
}
+int generator_hook_up_pcrfs(
+ const char *dir,
+ const char *where,
+ const char *target) {
+
+ const char *pcrfs_unit, *pcrfs_unit_path;
+ _cleanup_free_ char *where_unit = NULL, *instance = NULL;
+ int r;
+
+ assert(dir);
+ assert(where);
+
+ r = unit_name_from_path(where, ".mount", &where_unit);
+ if (r < 0)
+ return log_error_errno(r, "Failed to make unit name from path '%s': %m", where);
+
+ if (empty_or_root(where)) {
+ pcrfs_unit = SPECIAL_PCRFS_ROOT_SERVICE;
+ pcrfs_unit_path = SYSTEM_DATA_UNIT_DIR "/" SPECIAL_PCRFS_ROOT_SERVICE;
+ } else {
+ pcrfs_unit = SPECIAL_PCRFS_SERVICE;
+ pcrfs_unit_path = SYSTEM_DATA_UNIT_DIR "/" SPECIAL_PCRFS_SERVICE;
+
+ r = unit_name_path_escape(where, &instance);
+ if (r < 0)
+ return log_error_errno(r, "Failed to escape path '%s': %m", where);
+ }
+
+ if (target) {
+ r = generator_add_ordering(dir, target, "After", pcrfs_unit, instance);
+ if (r < 0)
+ return r;
+ }
+
+ return generator_add_symlink_full(dir, where_unit, "wants", pcrfs_unit_path, instance);
+}
+
int generator_enable_remount_fs_service(const char *dir) {
/* Pull in systemd-remount-fs.service */
return generator_add_symlink(dir, SPECIAL_LOCAL_FS_TARGET, "wants",
diff --git a/src/shared/generator.h b/src/shared/generator.h
index a4049dbd8f..111900fd45 100644
--- a/src/shared/generator.h
+++ b/src/shared/generator.h
@@ -81,6 +81,10 @@ int generator_hook_up_growfs(
const char *dir,
const char *where,
const char *target);
+int generator_hook_up_pcrfs(
+ const char *dir,
+ const char *where,
+ const char *target);
int generator_enable_remount_fs_service(const char *dir);
diff --git a/units/meson.build b/units/meson.build
index 62ce438a3f..d59796b62b 100644
--- a/units/meson.build
+++ b/units/meson.build
@@ -267,6 +267,8 @@ in_units = [
'sysinit.target.wants/'],
['systemd-pcrmachine.service', 'HAVE_GNU_EFI HAVE_OPENSSL HAVE_TPM2',
'sysinit.target.wants/'],
+ ['systemd-pcrfs-root.service', ''],
+ ['systemd-pcrfs@.service', ''],
['systemd-growfs-root.service', ''],
['systemd-growfs@.service', ''],
]
diff --git a/units/systemd-pcrfs-root.service.in b/units/systemd-pcrfs-root.service.in
new file mode 100644
index 0000000000..b0da413bb4
--- /dev/null
+++ b/units/systemd-pcrfs-root.service.in
@@ -0,0 +1,24 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=TPM2 PCR Root File System Measurement
+Documentation=man:systemd-pcrfs-root.service(8)
+DefaultDependencies=no
+Conflicts=shutdown.target
+After=systemd-pcrmachine.service
+Before=shutdown.target
+AssertPathExists=!/etc/initrd-release
+ConditionSecurity=tpm2
+ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart={{ROOTLIBEXECDIR}}/systemd-pcrphase --file-system=/
diff --git a/units/systemd-pcrfs@.service.in b/units/systemd-pcrfs@.service.in
new file mode 100644
index 0000000000..ec1ff118c3
--- /dev/null
+++ b/units/systemd-pcrfs@.service.in
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+#
+# This file is part of systemd.
+#
+# systemd is free software; you can redistribute it and/or modify it
+# under the terms of the GNU Lesser General Public License as published by
+# the Free Software Foundation; either version 2.1 of the License, or
+# (at your option) any later version.
+
+[Unit]
+Description=TPM2 PCR File System Measurement of %f
+Documentation=man:systemd-pcrfs@.service(8)
+DefaultDependencies=no
+BindsTo=%i.mount
+Conflicts=shutdown.target
+After=%i.mount systemd-pcrfs-root.service
+Before=shutdown.target
+AssertPathExists=!/etc/initrd-release
+ConditionSecurity=tpm2
+ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f
+
+[Service]
+Type=oneshot
+RemainAfterExit=yes
+ExecStart={{ROOTLIBEXECDIR}}/systemd-pcrphase --file-system=%f