e5f65c3fc6
Resolves: RHEL-1086,RHEL-11591,RHEL-16182,RHEL-19483,RHEL-7026
150 lines
7.4 KiB
Diff
150 lines
7.4 KiB
Diff
From 0e471978c582a614467d20d041f65c935c407abf Mon Sep 17 00:00:00 2001
|
|
From: Lennart Poettering <lennart@poettering.net>
|
|
Date: Fri, 14 Oct 2022 15:54:09 +0200
|
|
Subject: [PATCH] gpt-auto-generator: automatically measure root/var volume
|
|
keys into PCR 15
|
|
|
|
let's enable PCR 15 measurements automatically if gpt-auto discovery is
|
|
used and systemd-stub is also used.
|
|
|
|
(cherry picked from commit ff386f985bb51a48a11f74f6370dedf1bbfb4658)
|
|
|
|
Related: RHEL-16182
|
|
---
|
|
man/systemd-gpt-auto-generator.xml | 8 +++++
|
|
src/gpt-auto-generator/gpt-auto-generator.c | 36 ++++++++++++++++++---
|
|
2 files changed, 39 insertions(+), 5 deletions(-)
|
|
|
|
diff --git a/man/systemd-gpt-auto-generator.xml b/man/systemd-gpt-auto-generator.xml
|
|
index 8ad249ec5d..f26bda511c 100644
|
|
--- a/man/systemd-gpt-auto-generator.xml
|
|
+++ b/man/systemd-gpt-auto-generator.xml
|
|
@@ -221,6 +221,13 @@
|
|
systems, make sure to set the correct default subvolumes on them,
|
|
using <command>btrfs subvolume set-default</command>.</para>
|
|
|
|
+ <para>If the system was booted via
|
|
+ <citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry> and the
|
|
+ stub reported to userspace that the kernel image was measured to a TPM2 PCR, then any discovered root and
|
|
+ <filename>/var/</filename> volume identifiers (and volume encryption key in case it is encrypted) will be
|
|
+ automatically measured into PCR 15 on activation, via
|
|
+ <citerefentry><refentrytitle>systemd-pcrfs@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>.</para>
|
|
+
|
|
<para><filename>systemd-gpt-auto-generator</filename> implements
|
|
<citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
|
|
</refsect1>
|
|
@@ -272,6 +279,7 @@
|
|
<citerefentry><refentrytitle>systemd.swap</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
|
<citerefentry><refentrytitle>systemd-fstab-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
|
<citerefentry><refentrytitle>systemd-cryptsetup@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
|
+ <citerefentry><refentrytitle>systemd-pcrfs@.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
|
<citerefentry><refentrytitle>machine-id</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
|
<citerefentry project='die-net'><refentrytitle>cryptsetup</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
|
|
<citerefentry project='man-pages'><refentrytitle>fstab</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
|
diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c
|
|
index 0bab43e69a..2134185f04 100644
|
|
--- a/src/gpt-auto-generator/gpt-auto-generator.c
|
|
+++ b/src/gpt-auto-generator/gpt-auto-generator.c
|
|
@@ -47,10 +47,11 @@ static int add_cryptsetup(
|
|
const char *what,
|
|
bool rw,
|
|
bool require,
|
|
+ bool measure,
|
|
char **ret_device) {
|
|
|
|
#if HAVE_LIBCRYPTSETUP
|
|
- _cleanup_free_ char *e = NULL, *n = NULL, *d = NULL;
|
|
+ _cleanup_free_ char *e = NULL, *n = NULL, *d = NULL, *options = NULL;
|
|
_cleanup_fclose_ FILE *f = NULL;
|
|
int r;
|
|
|
|
@@ -84,7 +85,28 @@ static int add_cryptsetup(
|
|
"After=%s\n",
|
|
d, d);
|
|
|
|
- r = generator_write_cryptsetup_service_section(f, id, what, NULL, rw ? NULL : "read-only");
|
|
+ if (!rw) {
|
|
+ options = strdup("read-only");
|
|
+ if (!options)
|
|
+ return log_oom();
|
|
+ }
|
|
+
|
|
+ if (measure) {
|
|
+ /* We only measure the root volume key into PCR 15 if we are booted with sd-stub (i.e. in a
|
|
+ * UKI), and sd-stub measured the UKI. We do this in order not to step into people's own PCR
|
|
+ * assignment, under the assumption that people who are fine to use sd-stub with its PCR
|
|
+ * assignments are also OK with our PCR 15 use here. */
|
|
+
|
|
+ r = efi_get_variable(EFI_LOADER_VARIABLE(StubPcrKernelImage), NULL, NULL, NULL); /* we don't actually care which PCR the UKI used for itself */
|
|
+ if (r == -ENOENT)
|
|
+ log_debug_errno(r, "Will not measure volume key of volume '%s', because not booted via systemd-stub with measurements enabled.", id);
|
|
+ else if (r < 0)
|
|
+ log_debug_errno(r, "Failed to determine whether booted via systemd-stub with measurements enabled, ignoring: %m");
|
|
+ else if (!strextend_with_separator(&options, ",", "tpm2-measure-pcr=yes"))
|
|
+ return log_oom();
|
|
+ }
|
|
+
|
|
+ r = generator_write_cryptsetup_service_section(f, id, what, NULL, options);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
@@ -139,6 +161,7 @@ static int add_mount(
|
|
const char *fstype,
|
|
bool rw,
|
|
bool growfs,
|
|
+ bool measure,
|
|
const char *options,
|
|
const char *description,
|
|
const char *post) {
|
|
@@ -159,7 +182,7 @@ static int add_mount(
|
|
log_debug("Adding %s: %s fstype=%s", where, what, fstype ?: "(any)");
|
|
|
|
if (streq_ptr(fstype, "crypto_LUKS")) {
|
|
- r = add_cryptsetup(id, what, rw, true, &crypto_what);
|
|
+ r = add_cryptsetup(id, what, rw, /* require= */ true, measure, &crypto_what);
|
|
if (r < 0)
|
|
return r;
|
|
|
|
@@ -277,6 +300,7 @@ static int add_partition_mount(
|
|
p->fstype,
|
|
p->rw,
|
|
p->growfs,
|
|
+ /* measure= */ STR_IN_SET(id, "root", "var"), /* by default measure rootfs and /var, since they contain the "identity" of the system */
|
|
NULL,
|
|
description,
|
|
SPECIAL_LOCAL_FS_TARGET);
|
|
@@ -301,7 +325,7 @@ static int add_partition_swap(DissectedPartition *p) {
|
|
}
|
|
|
|
if (streq_ptr(p->fstype, "crypto_LUKS")) {
|
|
- r = add_cryptsetup("swap", p->node, true, true, &crypto_what);
|
|
+ r = add_cryptsetup("swap", p->node, /* rw= */ true, /* require= */ true, /* measure= */ false, &crypto_what);
|
|
if (r < 0)
|
|
return r;
|
|
what = crypto_what;
|
|
@@ -374,6 +398,7 @@ static int add_automount(
|
|
fstype,
|
|
rw,
|
|
growfs,
|
|
+ /* measure= */ false,
|
|
opt,
|
|
description,
|
|
NULL);
|
|
@@ -582,7 +607,7 @@ static int add_root_cryptsetup(void) {
|
|
/* If a device /dev/gpt-auto-root-luks appears, then make it pull in systemd-cryptsetup-root.service, which
|
|
* sets it up, and causes /dev/gpt-auto-root to appear which is all we are looking for. */
|
|
|
|
- return add_cryptsetup("root", "/dev/gpt-auto-root-luks", true, false, NULL);
|
|
+ return add_cryptsetup("root", "/dev/gpt-auto-root-luks", /* rw= */ true, /* require= */ false, /* measure= */ true, NULL);
|
|
#else
|
|
return 0;
|
|
#endif
|
|
@@ -629,6 +654,7 @@ static int add_root_mount(void) {
|
|
NULL,
|
|
/* rw= */ arg_root_rw > 0,
|
|
/* growfs= */ false,
|
|
+ /* measure= */ true,
|
|
NULL,
|
|
"Root Partition",
|
|
in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);
|