]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-stub: measure sysext images picked up by sd-stub into PCR 13
authorLennart Poettering <lennart@poettering.net>
Tue, 26 Jul 2022 09:35:57 +0000 (11:35 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 2 Aug 2022 08:28:49 +0000 (10:28 +0200)
Let's grab another so far unused PCR, and measure all sysext images into
it that we load from the ESP. Note that this is possibly partly redundant,
since sysext images should have dm-verity enabled, and that is hooked up
to IMA. However, measuring this explicitly has the benefit that we can
measure filenames too, easily, and that all without need for IMA or
anything like that.

This means: when booting a unified sd-stub kernel through sd-boot we'll
now have:

1. PCR 11: unified kernel image payload (i.e. kernel, initrd, boot
   splash, dtb, osrelease)

2. PCR 12: kernel command line (i.e. the one embedded in the image, plus
   optionally an overriden one) + any credential files picked up by
   sd-stub

3. PCR 13: sysext images picked up by sd-stub

And each of these three PCRs should carry just the above, and start from
zero, thus be pre-calculatable.

Thus, all components and parameters of the OS boot process (i.e.
everything after the boot loader) is now nicely pre-calculable.

NOTE: this actually replaces previous measuring of the syext images into
PCR 4. I added this back in 845707aae23b3129db635604edb95c4048a5922a,
following the train of thought, that sysext images for the initrd should
be measured like the initrd itself they are for, and according to my
thinking that would be a unified kernel which is measured by firmware
into PCR 4 like any other UEFI executables.

However, I think we should depart from that idea. First and foremost
that makes it harder to pre-calculate PCR 4 (since we actually measured
quite incompatible records to the TPM event log), but also I think
there's great value in being able to write policies that bind to the
used sysexts independently of the earlier boot chain (i.e. shim, boot
loader, unified kernel), hence a separate PCR makes more sense.

Strictly speaking, this is a compatibility break, but I think one we can
get away with, simply because the initrd sysext images are currently not
picked up by systemd-sysext yet in the initrd, and because of that we
can be reasonably sure noone uses this yet, and hence relies on the PCR
register used. Hence, let's clean this up before people actually do
start relying on this.

man/systemd-cryptenroll.xml
man/systemd-stub.xml
src/boot/efi/measure.h
src/boot/efi/stub.c

index 4a5127b02d15bfd186ac07def8343036fb6ac6b3..2aa396e3004bfe4790b5b166b0063e512e334d06 100644 (file)
                 <entry><citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry> measures any specified kernel command line into this PCR. <citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry> measures any manually specified kernel command line (i.e. a kernel command line that overrides the one embedded in the unified PE image) and loaded credentials into this PCR. (Note that if <command>systemd-boot</command> and <command>systemd-stub</command> are used in combination the command line might be measured twice!)</entry>
               </row>
 
+              <row>
+                <entry>13</entry>
+                <entry><citerefentry><refentrytitle>systemd-stub</refentrytitle><manvolnum>7</manvolnum></citerefentry> measures any <citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry> images it loads and passed to the booted kernel into this PCR.</entry>
+              </row>
+
               <row>
                 <entry>14</entry>
                 <entry>The shim project measures its "MOK" certificates and hashes into this PCR.</entry>
index df7cabcf503f2047c22cec70d24251d41985d592..1e9bb5d631ba16308b49a5e62ca1a4709d49b184 100644 (file)
       images to the initrd. See
       <citerefentry><refentrytitle>systemd-sysext</refentrytitle><manvolnum>8</manvolnum></citerefentry> for
       details on system extension images. The generated <command>cpio</command> archive containing these
-      system extension images is measured into TPM PCR 4 (if a TPM is present).</para></listitem>
+      system extension images is measured into TPM PCR 13 (if a TPM is present).</para></listitem>
 
       <listitem><para>Files <filename>/loader/credentials/*.cred</filename> are packed up in a
       <command>cpio</command> archive and placed in the <filename>/.extra/global_credentials/</filename>
 
           <row>
             <entry>System Extensions (synthesized initrd from companion files)</entry>
-            <entry>4 + 9</entry>
+            <entry>9 + 13</entry>
           </row>
         </tbody>
       </tgroup>
         formatted as decimal ASCII string (i.e. <literal>12</literal>). This variable is set if a measurement
         was successfully completed, and remains unset otherwise.</para></listitem>
       </varlistentry>
+
+      <varlistentry>
+        <term><varname>StubPcrInitRDSysExts</varname></term>
+
+        <listitem><para>The PCR register index the systemd extensions for the initial RAM disk image, which
+        are picked up from the file system the kernel image is located on.  Formatted as decimal ASCII string
+        (i.e. <literal>13</literal>). This variable is set if a measurement was successfully completed, and
+        remains unset otherwise.</para></listitem>
+      </varlistentry>
     </variablelist>
 
     <para>Note that some of the variables above may also be set by the boot loader. The stub will only set
index df7f04c9fbbd4db8441430c695ab95449ba805ba..141d44aa79c2cb5042625ff1296aae85166020c1 100644 (file)
@@ -22,8 +22,8 @@
 #define TPM_PCR_INDEX_KERNEL_PARAMETERS_COMPAT UINT32_MAX
 #endif
 
-/* This TPM PCR is where most Linux infrastructure extends the initrd binary images into, and so do we. */
-#define TPM_PCR_INDEX_INITRD 4U
+/* This TPM PCR is where we extend the initrd sysext images into which we pass to the booted kernel */
+#define TPM_PCR_INDEX_INITRD_SYSEXTS 13U
 
 #if ENABLE_TPM
 
index 1afbde3295291103532d5671ad80a7da7c0c0aa3..3b74647a18c396fa00bc68712dcb6e936dede246 100644 (file)
@@ -182,8 +182,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         char *cmdline = NULL;
         _cleanup_free_ char *cmdline_owned = NULL;
         int sections_measured = -1, parameters_measured = -1;
+        bool sysext_measured = false, m;
         EFI_STATUS err;
-        bool m;
 
         InitializeLib(image, sys_table);
         debug_hook(L"systemd-stub");
@@ -298,21 +298,24 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                       &m) == EFI_SUCCESS)
                 parameters_measured = parameters_measured < 0 ? m : (parameters_measured && m);
 
-        (void) pack_cpio(loaded_image,
-                         NULL,
-                         L".raw",
-                         ".extra/sysext",
-                         /* dir_mode= */ 0555,
-                         /* access_mode= */ 0444,
-                         /* tpm_pcr= */ (uint32_t[]) { TPM_PCR_INDEX_INITRD },
-                         /* n_tpm_pcr= */ 1,
-                         L"System extension initrd",
-                         &sysext_initrd,
-                         &sysext_initrd_size,
-                         NULL);
+        if (pack_cpio(loaded_image,
+                      NULL,
+                      L".raw",
+                      ".extra/sysext",
+                      /* dir_mode= */ 0555,
+                      /* access_mode= */ 0444,
+                      /* tpm_pcr= */ (uint32_t[]) { TPM_PCR_INDEX_INITRD_SYSEXTS },
+                      /* n_tpm_pcr= */ 1,
+                      L"System extension initrd",
+                      &sysext_initrd,
+                      &sysext_initrd_size,
+                      &m) == EFI_SUCCESS)
+                sysext_measured = m;
 
         if (parameters_measured > 0)
                 (void) efivar_set_uint_string(LOADER_GUID, L"StubPcrKernelParameters", TPM_PCR_INDEX_KERNEL_PARAMETERS, 0);
+        if (sysext_measured)
+                (void) efivar_set_uint_string(LOADER_GUID, L"StubPcrInitRDSysExts", TPM_PCR_INDEX_INITRD_SYSEXTS, 0);
 
         linux_size = szs[SECTION_LINUX];
         linux_base = POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[SECTION_LINUX];