]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
gpt-auto-generator: automatically measure root/var volume keys into PCR 15
authorLennart Poettering <lennart@poettering.net>
Fri, 14 Oct 2022 13:54:09 +0000 (15:54 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 17 Jan 2023 08:42:16 +0000 (09:42 +0100)
let's enable PCR 15 measurements automatically if gpt-auto discovery is
used and systemd-stub is also used.

man/systemd-gpt-auto-generator.xml
src/gpt-auto-generator/gpt-auto-generator.c

index 4ccc80994d0a0bbaaaf164f5e78c78580eab3c0f..bd542cb7f721a9c9a53836db418b12a8889f7900 100644 (file)
     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>
       <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>,
index 98c0ca08106e9f511921d91e595fb3812f00f195..1fc75865240d8ae166e73c1cc2eaff222ed98b68 100644 (file)
@@ -52,10 +52,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;
 
@@ -89,7 +90,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;
 
@@ -144,6 +166,7 @@ static int add_mount(
                 const char *fstype,
                 bool rw,
                 bool growfs,
+                bool measure,
                 const char *options,
                 const char *description,
                 const char *post) {
@@ -164,7 +187,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;
 
@@ -291,6 +314,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);
@@ -315,7 +339,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;
@@ -384,6 +408,7 @@ static int add_automount(
                       fstype,
                       rw,
                       growfs,
+                      /* measure= */ false,
                       options,
                       description,
                       NULL);
@@ -592,7 +617,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
@@ -639,6 +664,7 @@ static int add_root_mount(void) {
                         arg_root_fstype,
                         /* rw= */ arg_root_rw > 0,
                         /* growfs= */ false,
+                        /* measure= */ true,
                         arg_root_options,
                         "Root Partition",
                         in_initrd() ? SPECIAL_INITRD_ROOT_FS_TARGET : SPECIAL_LOCAL_FS_TARGET);