]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
boot: move unified kernel PE section definitions into 'fundamental' code
authorLennart Poettering <lennart@poettering.net>
Wed, 27 Jul 2022 08:58:29 +0000 (10:58 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 2 Aug 2022 08:28:49 +0000 (10:28 +0200)
Le's share this code between userspace and uefispace. This is useful
later when pre-measuring expected PCRs from userspace.

meson.build
src/boot/efi/stub.c
src/fundamental/meson.build
src/fundamental/tpm-pcr.c [new file with mode: 0644]
src/fundamental/tpm-pcr.h

index 6bbb2db55d14d4028398a0169912c3c54f72f48c..bfe6b31b959db9ebfc64325333a9e6dfdfc6117b 100644 (file)
@@ -310,6 +310,8 @@ conf.set_quoted('STATUS_UNIT_FORMAT_DEFAULT_STR',             status_unit_format
 
 conf.set10('FIRST_BOOT_FULL_PRESET',                          get_option('first-boot-full-preset'))
 
+conf.set10('EFI_TPM_PCR_COMPAT',                              get_option('efi-tpm-pcr-compat'))
+
 #####################################################################
 
 cc = meson.get_compiler('c')
index 549f3ce1d5bdf4c4ad8a3b67cdb5ef5c1571d0ca..c35ee38749bf7e271853628079ef02f9450f882e 100644 (file)
@@ -149,28 +149,6 @@ static void export_variables(EFI_LOADED_IMAGE_PROTOCOL *loaded_image) {
 }
 
 EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
-
-        enum Section {
-                /* This is the canonical order in which we measure the sections. PLEASE DO NOT REORDER! */
-                SECTION_LINUX,
-                SECTION_OSREL,
-                SECTION_CMDLINE,
-                SECTION_INITRD,
-                SECTION_SPLASH,
-                SECTION_DTB,
-                _SECTION_MAX,
-        };
-
-        static const char * const sections[_SECTION_MAX + 1] = {
-                [SECTION_LINUX]   = ".linux",
-                [SECTION_OSREL]   = ".osrel",
-                [SECTION_CMDLINE] = ".cmdline",
-                [SECTION_INITRD]  = ".initrd",
-                [SECTION_SPLASH]  = ".splash",
-                [SECTION_DTB]     = ".dtb",
-                NULL,
-        };
-
         UINTN cmdline_len = 0, linux_size, initrd_size, dt_size;
         UINTN credential_initrd_size = 0, global_credential_initrd_size = 0, sysext_initrd_size = 0;
         _cleanup_free_ void *credential_initrd = NULL, *global_credential_initrd = NULL;
@@ -178,8 +156,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         EFI_PHYSICAL_ADDRESS linux_base, initrd_base, dt_base;
         _cleanup_(devicetree_cleanup) struct devicetree_state dt_state = {};
         EFI_LOADED_IMAGE_PROTOCOL *loaded_image;
-        UINTN addrs[_SECTION_MAX] = {};
-        UINTN szs[_SECTION_MAX] = {};
+        UINTN addrs[_UNIFIED_SECTION_MAX] = {}, szs[_UNIFIED_SECTION_MAX] = {};
         char *cmdline = NULL;
         _cleanup_free_ char *cmdline_owned = NULL;
         int sections_measured = -1, parameters_measured = -1;
@@ -201,8 +178,8 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         if (err != EFI_SUCCESS)
                 return log_error_status_stall(err, L"Error getting a LoadedImageProtocol handle: %r", err);
 
-        err = pe_memory_locate_sections(loaded_image->ImageBase, sections, addrs, szs);
-        if (err != EFI_SUCCESS || szs[SECTION_LINUX] == 0) {
+        err = pe_memory_locate_sections(loaded_image->ImageBase, unified_sections, addrs, szs);
+        if (err != EFI_SUCCESS || szs[UNIFIED_SECTION_LINUX] == 0) {
                 if (err == EFI_SUCCESS)
                         err = EFI_NOT_FOUND;
                 return log_error_status_stall(err, L"Unable to locate embedded .linux section: %r", err);
@@ -211,7 +188,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         /* Measure all "payload" of this PE image into a separate PCR (i.e. where nothing else is written
          * into so far), so that we have one PCR that we can nicely write policies against because it
          * contains all static data of this image, and thus can be easily be pre-calculated. */
-        for (enum Section section = 0; section < _SECTION_MAX; section++) {
+        for (UnifiedSection section = 0; section < _UNIFIED_SECTION_MAX; section++) {
                 m = false;
 
                 if (szs[section] == 0) /* not found */
@@ -220,9 +197,9 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                 /* First measure the name of the section */
                 (void) tpm_log_event_ascii(
                                 TPM_PCR_INDEX_KERNEL_IMAGE,
-                                POINTER_TO_PHYSICAL_ADDRESS(sections[section]),
-                                strsize8(sections[section]), /* including NUL byte */
-                                sections[section],
+                                POINTER_TO_PHYSICAL_ADDRESS(unified_sections[section]),
+                                strsize8(unified_sections[section]), /* including NUL byte */
+                                unified_sections[section],
                                 &m);
 
                 sections_measured = sections_measured < 0 ? m : (sections_measured && m);
@@ -232,7 +209,7 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                                 TPM_PCR_INDEX_KERNEL_IMAGE,
                                 POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[section],
                                 szs[section],
-                                sections[section],
+                                unified_sections[section],
                                 &m);
 
                 sections_measured = sections_measured < 0 ? m : (sections_measured && m);
@@ -244,11 +221,11 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
                 (void) efivar_set_uint_string(LOADER_GUID, L"StubPcrKernelImage", TPM_PCR_INDEX_KERNEL_IMAGE, 0);
 
         /* Show splash screen as early as possible */
-        graphics_splash((const uint8_t*) loaded_image->ImageBase + addrs[SECTION_SPLASH], szs[SECTION_SPLASH], NULL);
+        graphics_splash((const uint8_t*) loaded_image->ImageBase + addrs[UNIFIED_SECTION_SPLASH], szs[UNIFIED_SECTION_SPLASH], NULL);
 
-        if (szs[SECTION_CMDLINE] > 0) {
-                cmdline = (char *) loaded_image->ImageBase + addrs[SECTION_CMDLINE];
-                cmdline_len = szs[SECTION_CMDLINE];
+        if (szs[UNIFIED_SECTION_CMDLINE] > 0) {
+                cmdline = (char *) loaded_image->ImageBase + addrs[UNIFIED_SECTION_CMDLINE];
+                cmdline_len = szs[UNIFIED_SECTION_CMDLINE];
         }
 
         /* if we are not in secure boot mode, or none was provided, accept a custom command line and replace the built-in one */
@@ -318,14 +295,14 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
         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];
+        linux_size = szs[UNIFIED_SECTION_LINUX];
+        linux_base = POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[UNIFIED_SECTION_LINUX];
 
-        initrd_size = szs[SECTION_INITRD];
-        initrd_base = initrd_size != 0 ? POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[SECTION_INITRD] : 0;
+        initrd_size = szs[UNIFIED_SECTION_INITRD];
+        initrd_base = initrd_size != 0 ? POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[UNIFIED_SECTION_INITRD] : 0;
 
-        dt_size = szs[SECTION_DTB];
-        dt_base = dt_size != 0 ? POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[SECTION_DTB] : 0;
+        dt_size = szs[UNIFIED_SECTION_DTB];
+        dt_base = dt_size != 0 ? POINTER_TO_PHYSICAL_ADDRESS(loaded_image->ImageBase) + addrs[UNIFIED_SECTION_DTB] : 0;
 
         if (credential_initrd || global_credential_initrd || sysext_initrd) {
                 /* If we have generated initrds dynamically, let's combine them with the built-in initrd. */
index a4383f6a27100afc4d44890d9be24f6117a76232..3810d6b456de6146ac112f168f7d5927b2265dce 100644 (file)
@@ -17,6 +17,7 @@ fundamental_source_paths = files(
         'efivars-fundamental.c',
         'sha256.c',
         'string-util-fundamental.c',
+        'tpm-pcr.c',
 )
 
 # for libbasic
diff --git a/src/fundamental/tpm-pcr.c b/src/fundamental/tpm-pcr.c
new file mode 100644 (file)
index 0000000..97b3c7b
--- /dev/null
@@ -0,0 +1,15 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include <stddef.h>
+
+#include "tpm-pcr.h"
+
+const char* const unified_sections[_UNIFIED_SECTION_MAX + 1] = {
+        [UNIFIED_SECTION_LINUX]   = ".linux",
+        [UNIFIED_SECTION_OSREL]   = ".osrel",
+        [UNIFIED_SECTION_CMDLINE] = ".cmdline",
+        [UNIFIED_SECTION_INITRD]  = ".initrd",
+        [UNIFIED_SECTION_SPLASH]  = ".splash",
+        [UNIFIED_SECTION_DTB]     = ".dtb",
+        NULL,
+};
index 6e8b25934b2f0d561eb94f871ad7730f64bb82f4..fb0774f70d133247fa08fb22755fac4f03aa3b53 100644 (file)
 
 /* 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
+
+/* List of PE sections that have special meaning for us in unified kernels. This is the canonical order in
+ * which we measure the sections into TPM PCR 11 (see above). PLEASE DO NOT REORDER! */
+typedef enum UnifiedSection {
+        UNIFIED_SECTION_LINUX,
+        UNIFIED_SECTION_OSREL,
+        UNIFIED_SECTION_CMDLINE,
+        UNIFIED_SECTION_INITRD,
+        UNIFIED_SECTION_SPLASH,
+        UNIFIED_SECTION_DTB,
+        _UNIFIED_SECTION_MAX,
+} UnifiedSection;
+
+extern const char* const unified_sections[_UNIFIED_SECTION_MAX + 1];