From 3e026f665ced2a351429fa93e0bade8681332bf0fd5cb0092124ce9a1efea4cc Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Mon, 19 Sep 2022 06:10:23 +0000 Subject: [PATCH 1/6] Accepting request 1004537 from home:gary_lin:branches:Base:System - Add safety measure to pcr snapshot by checking platform and tpm status * safe_tpm_pcr_snapshot.patch - Fix installation failure due to unavailable nvram device on ppc64le (bsc#1201361) * 0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch - Add patches to dynamically allocate additional memory regions for EFI systems (bsc#1202438) * 0001-mm-Allow-dynamically-requesting-additional-memory-re.patch * 0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch * 0003-kern-efi-mm-Extract-function-to-add-memory-regions.patch * 0004-kern-efi-mm-Pass-up-errors-from-add_memory_regions.patch * 0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch - Enlarge the default heap size and defer the disk cache invalidation (bsc#1202438) * 0001-kern-efi-mm-Enlarge-the-default-heap-size.patch * 0002-mm-Defer-the-disk-cache-invalidation.patch - Add patches for ALP FDE support * 0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch * 0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch * 0003-disk-cryptodisk-When-cheatmounting-use-the-sector-in.patch * 0004-normal-menu-Don-t-show-Booting-s-msg-when-auto-booti.patch * 0005-EFI-suppress-the-Welcome-to-GRUB-message-in-EFI-buil.patch * 0006-EFI-console-Do-not-set-colorstate-until-the-first-te.patch * 0007-EFI-console-Do-not-set-cursor-until-the-first-text-o.patch * 0008-linuxefi-Use-common-grub_initrd_load.patch * 0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch * 0010-templates-import-etc-crypttab-to-grub.cfg.patch OBS-URL: https://build.opensuse.org/request/show/1004537 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=419 --- ...troot-Have-devmapper-recognize-LUKS2.patch | 53 +++ ...nt-of-no-return-for-powerpc-ieee1275.patch | 32 ++ ...efi-mm-Enlarge-the-default-heap-size.patch | 32 ++ ...ally-requesting-additional-memory-re.patch | 133 +++++++ ...e-tpm-verifier-if-tpm-is-not-present.patch | 88 +++++ ...t-Set-up-cheated-LUKS2-cryptodisk-mo.patch | 127 +++++++ ...ys-request-a-fixed-number-of-pages-o.patch | 106 ++++++ ...mm-Defer-the-disk-cache-invalidation.patch | 68 ++++ ...When-cheatmounting-use-the-sector-in.patch | 71 ++++ ...tract-function-to-add-memory-regions.patch | 86 +++++ ...ss-up-errors-from-add_memory_regions.patch | 89 +++++ ...t-show-Booting-s-msg-when-auto-booti.patch | 93 +++++ ...-Welcome-to-GRUB-message-in-EFI-buil.patch | 45 +++ ...-Implement-runtime-addition-of-pages.patch | 77 ++++ ...ot-set-colorstate-until-the-first-te.patch | 54 +++ ...ot-set-cursor-until-the-first-text-o.patch | 75 ++++ ...linuxefi-Use-common-grub_initrd_load.patch | 156 ++++++++ ...ry-to-obviate-the-need-to-input-pass.patch | 338 ++++++++++++++++++ ...ates-import-etc-crypttab-to-grub.cfg.patch | 81 +++++ efi-set-variable-with-attrs.patch | 51 +++ grub-install-record-pcrs.patch | 18 + grub-read-pcr.patch | 151 ++++++++ grub-unseal-debug.patch | 41 +++ grub2.changes | 56 +++ grub2.spec | 33 +- safe_tpm_pcr_snapshot.patch | 90 +++++ tpm-protector-dont-measure-sealed-key.patch | 15 + tpm-protector-export-secret-key.patch | 138 +++++++ tpm-record-pcrs.patch | 235 ++++++++++++ 29 files changed, 2631 insertions(+), 1 deletion(-) create mode 100644 0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch create mode 100644 0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch create mode 100644 0001-kern-efi-mm-Enlarge-the-default-heap-size.patch create mode 100644 0001-mm-Allow-dynamically-requesting-additional-memory-re.patch create mode 100644 0001-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch create mode 100644 0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch create mode 100644 0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch create mode 100644 0002-mm-Defer-the-disk-cache-invalidation.patch create mode 100644 0003-disk-cryptodisk-When-cheatmounting-use-the-sector-in.patch create mode 100644 0003-kern-efi-mm-Extract-function-to-add-memory-regions.patch create mode 100644 0004-kern-efi-mm-Pass-up-errors-from-add_memory_regions.patch create mode 100644 0004-normal-menu-Don-t-show-Booting-s-msg-when-auto-booti.patch create mode 100644 0005-EFI-suppress-the-Welcome-to-GRUB-message-in-EFI-buil.patch create mode 100644 0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch create mode 100644 0006-EFI-console-Do-not-set-colorstate-until-the-first-te.patch create mode 100644 0007-EFI-console-Do-not-set-cursor-until-the-first-text-o.patch create mode 100644 0008-linuxefi-Use-common-grub_initrd_load.patch create mode 100644 0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch create mode 100644 0010-templates-import-etc-crypttab-to-grub.cfg.patch create mode 100644 efi-set-variable-with-attrs.patch create mode 100644 grub-install-record-pcrs.patch create mode 100644 grub-read-pcr.patch create mode 100644 grub-unseal-debug.patch create mode 100644 safe_tpm_pcr_snapshot.patch create mode 100644 tpm-protector-dont-measure-sealed-key.patch create mode 100644 tpm-protector-export-secret-key.patch create mode 100644 tpm-record-pcrs.patch diff --git a/0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch b/0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch new file mode 100644 index 0000000..268417a --- /dev/null +++ b/0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch @@ -0,0 +1,53 @@ +From ebe4ac49e800b18b539564169593ab1c6f163378 Mon Sep 17 00:00:00 2001 +From: Josselin Poiret via Grub-devel +Date: Tue, 14 Jun 2022 15:47:29 +0200 +Subject: [PATCH 01/10] devmapper/getroot: Have devmapper recognize LUKS2 + +Changes UUID comparisons so that LUKS1 and LUKS2 are both recognized +as being LUKS cryptodisks. +--- + grub-core/osdep/devmapper/getroot.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/grub-core/osdep/devmapper/getroot.c b/grub-core/osdep/devmapper/getroot.c +index 9ba5c98655..2bf4264cf0 100644 +--- a/grub-core/osdep/devmapper/getroot.c ++++ b/grub-core/osdep/devmapper/getroot.c +@@ -138,7 +138,8 @@ grub_util_get_dm_abstraction (const char *os_dev) + grub_free (uuid); + return GRUB_DEV_ABSTRACTION_LVM; + } +- if (strncmp (uuid, "CRYPT-LUKS1-", 12) == 0) ++ if (strncmp (uuid, "CRYPT-LUKS1-", sizeof ("CRYPT-LUKS1-") - 1) == 0 ++ || strncmp (uuid, "CRYPT-LUKS2-", sizeof ("CRYPT-LUKS2-") - 1) == 0) + { + grub_free (uuid); + return GRUB_DEV_ABSTRACTION_LUKS; +@@ -179,7 +180,9 @@ grub_util_pull_devmapper (const char *os_dev) + grub_util_pull_device (subdev); + } + } +- if (uuid && strncmp (uuid, "CRYPT-LUKS1-", sizeof ("CRYPT-LUKS1-") - 1) == 0 ++ if (uuid ++ && (strncmp (uuid, "CRYPT-LUKS1-", sizeof ("CRYPT-LUKS1-") - 1) == 0 ++ || strncmp (uuid, "CRYPT-LUKS2-", sizeof ("CRYPT-LUKS2-") - 1) == 0) + && lastsubdev) + { + char *grdev = grub_util_get_grub_dev (lastsubdev); +@@ -253,11 +256,11 @@ grub_util_get_devmapper_grub_dev (const char *os_dev) + { + char *dash; + +- dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS1-") - 1, '-'); ++ dash = grub_strchr (uuid + sizeof ("CRYPT-LUKS*-") - 1, '-'); + if (dash) + *dash = 0; + grub_dev = grub_xasprintf ("cryptouuid/%s", +- uuid + sizeof ("CRYPT-LUKS1-") - 1); ++ uuid + sizeof ("CRYPT-LUKS*-") - 1); + grub_free (uuid); + return grub_dev; + } +-- +2.34.1 + diff --git a/0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch b/0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch new file mode 100644 index 0000000..47696be --- /dev/null +++ b/0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch @@ -0,0 +1,32 @@ +From grub-devel-bounces@gnu.org Thu Aug 25 08:11:08 2022 +From: Michael Chang +Date: Thu, 25 Aug 2022 14:05:01 +0800 +Subject: [PATCH] grub-install: set point of no return for powerpc-ieee1275 + install + +The point of no return is used to define a point where no change should +be reverted in a wake of fatal error that consequently aborts the +process. The powerpc-ieee1275 install apparently missed this point of no +return defintion that newly installed modules could be inadvertently +reverted after successful image embedding so that boot failure is +incurred due to inconsistent state. + +Signed-off-by: Michael Chang +[iluceno@suse.de: Backported to SLES-15-SP4] +Signed-off-by: Ismael Luceno +--- + util/grub-install.c | 1 + + 1 file changed, 1 insertion(+) + +Index: grub-2.06/util/grub-install.c +=================================================================== +--- grub-2.06.orig/util/grub-install.c ++++ grub-2.06/util/grub-install.c +@@ -2160,6 +2160,7 @@ main (int argc, char *argv[]) + { + grub_util_error ("%s", _("failed to copy Grub to the PReP partition")); + } ++ grub_set_install_backup_ponr (); + + if ((signed_grub_mode >= SIGNED_GRUB_FORCE) || ((signed_grub_mode == SIGNED_GRUB_AUTO) && (ppc_sb_state > 0))) + { diff --git a/0001-kern-efi-mm-Enlarge-the-default-heap-size.patch b/0001-kern-efi-mm-Enlarge-the-default-heap-size.patch new file mode 100644 index 0000000..149c5c1 --- /dev/null +++ b/0001-kern-efi-mm-Enlarge-the-default-heap-size.patch @@ -0,0 +1,32 @@ +From 3e08d9afd273b5dade84fec5f7f17113c47b6b75 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Fri, 2 Sep 2022 11:26:39 +0800 +Subject: [PATCH 1/2] kern/efi/mm: Enlarge the default heap size + +The default heap size (0x100000, 1MB) is not enough for the +openSUSE/SUSE theme, and the additional dynamical allocation of memory +regions significantly slows down the loading of the grub2 menu theme. +This commit increases the default heap size to 0x2000000, 32MB, and this +should be enough to cover the theme files. + +Signed-off-by: Gary Lin +--- + grub-core/kern/efi/mm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index 48380d3..70d3e3d 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -39,7 +39,7 @@ + #define MEMORY_MAP_SIZE 0x3000 + + /* The default heap size for GRUB itself in bytes. */ +-#define DEFAULT_HEAP_SIZE 0x100000 ++#define DEFAULT_HEAP_SIZE 0x2000000 + + static void *finish_mmap_buf = 0; + static grub_efi_uintn_t finish_mmap_size = 0; +-- +2.35.3 + diff --git a/0001-mm-Allow-dynamically-requesting-additional-memory-re.patch b/0001-mm-Allow-dynamically-requesting-additional-memory-re.patch new file mode 100644 index 0000000..364e106 --- /dev/null +++ b/0001-mm-Allow-dynamically-requesting-additional-memory-re.patch @@ -0,0 +1,133 @@ +From 23bca58a68264657f176885c3564d07c9938b7f6 Mon Sep 17 00:00:00 2001 +From: Patrick Steinhardt +Date: Thu, 21 Apr 2022 15:24:18 +1000 +Subject: [PATCH 1/5] mm: Allow dynamically requesting additional memory + regions + +Currently, all platforms will set up their heap on initialization of the +platform code. While this works mostly fine, it poses some limitations +on memory management on us. Most notably, allocating big chunks of +memory in the gigabyte range would require us to pre-request this many +bytes from the firmware and add it to the heap from the beginning on +some platforms like EFI. As this isn't needed for most configurations, +it is inefficient and may even negatively impact some usecases when, +e.g., chainloading. Nonetheless, allocating big chunks of memory is +required sometimes, where one example is the upcoming support for the +Argon2 key derival function in LUKS2. + +In order to avoid pre-allocating big chunks of memory, this commit +implements a runtime mechanism to add more pages to the system. When +a given allocation cannot be currently satisfied, we'll call a given +callback set up by the platform's own memory management subsystem, +asking it to add a memory area with at least "n" bytes. If this +succeeds, we retry searching for a valid memory region, which should +now succeed. + +If this fails, we try asking for "n" bytes, possibly spread across +multiple regions, in hopes that region merging means that we end up +with enough memory for things to work out. + +Signed-off-by: Patrick Steinhardt +Signed-off-by: Daniel Axtens +Tested-by: Stefan Berger +Reviewed-by: Daniel Kiper +Tested-by: Patrick Steinhardt +--- + grub-core/kern/mm.c | 30 ++++++++++++++++++++++++++++++ + include/grub/mm.h | 18 ++++++++++++++++++ + 2 files changed, 48 insertions(+) + +diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c +index 5c0a624..0bd9f75 100644 +--- a/grub-core/kern/mm.c ++++ b/grub-core/kern/mm.c +@@ -28,6 +28,9 @@ + - multiple regions may be used as free space. They may not be + contiguous. + ++ - if existing regions are insufficient to satisfy an allocation, a new ++ region can be requested from firmware. ++ + Regions are managed by a singly linked list, and the meta information is + stored in the beginning of each region. Space after the meta information + is used to allocate memory. +@@ -77,6 +80,7 @@ + + + grub_mm_region_t grub_mm_base; ++grub_mm_add_region_func_t grub_mm_add_region_fn; + + /* Get a header from the pointer PTR, and set *P and *R to a pointer + to the header and a pointer to its region, respectively. PTR must +@@ -364,6 +368,32 @@ grub_memalign (grub_size_t align, grub_size_t size) + goto again; + #endif + ++ case 1: ++ /* Request additional pages, contiguous */ ++ count++; ++ ++ if (grub_mm_add_region_fn != NULL && ++ grub_mm_add_region_fn (size, GRUB_MM_ADD_REGION_CONSECUTIVE) == GRUB_ERR_NONE) ++ goto again; ++ ++ /* fallthrough */ ++ ++ case 2: ++ /* Request additional pages, anything at all */ ++ count++; ++ ++ if (grub_mm_add_region_fn != NULL) ++ { ++ /* ++ * Try again even if this fails, in case it was able to partially ++ * satisfy the request ++ */ ++ grub_mm_add_region_fn (size, GRUB_MM_ADD_REGION_NONE); ++ goto again; ++ } ++ ++ /* fallthrough */ ++ + default: + break; + } +diff --git a/include/grub/mm.h b/include/grub/mm.h +index 1754635..67faebf 100644 +--- a/include/grub/mm.h ++++ b/include/grub/mm.h +@@ -20,6 +20,7 @@ + #ifndef GRUB_MM_H + #define GRUB_MM_H 1 + ++#include + #include + #include + #include +@@ -28,6 +29,23 @@ + # define NULL ((void *) 0) + #endif + ++#define GRUB_MM_ADD_REGION_NONE 0 ++#define GRUB_MM_ADD_REGION_CONSECUTIVE (1 << 0) ++ ++/* ++ * Function used to request memory regions of `grub_size_t` bytes. The second ++ * parameter is a bitfield of `GRUB_MM_ADD_REGION` flags. ++ */ ++typedef grub_err_t (*grub_mm_add_region_func_t) (grub_size_t, unsigned int); ++ ++/* ++ * Set this function pointer to enable adding memory-regions at runtime in case ++ * a memory allocation cannot be satisfied with existing regions. ++ */ ++#ifndef GRUB_MACHINE_EMU ++extern grub_mm_add_region_func_t EXPORT_VAR(grub_mm_add_region_fn); ++#endif ++ + void grub_mm_init_region (void *addr, grub_size_t size); + void *EXPORT_FUNC(grub_malloc) (grub_size_t size); + void *EXPORT_FUNC(grub_zalloc) (grub_size_t size); +-- +2.35.3 + diff --git a/0001-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch b/0001-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch new file mode 100644 index 0000000..1deb5b2 --- /dev/null +++ b/0001-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch @@ -0,0 +1,88 @@ +From 12378be5243c1c02ce28de2e5703e87197c69157 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Mon, 29 Aug 2022 11:28:28 +0800 +Subject: [PATCH] tpm: Disable tpm verifier if tpm is not present + +This helps to prevent out of memory error when reading large files via disablig +tpm device as verifier has to read all content into memory in one chunk to +measure the hash and extend to tpm. + +Signed-off-by: Michael Chang +--- + grub-core/commands/efi/tpm.c | 37 +++++++++++++++++++++++++++++++++++++ + grub-core/commands/tpm.c | 4 ++++ + include/grub/tpm.h | 1 + + 3 files changed, 42 insertions(+) + +--- a/grub-core/commands/efi/tpm.c ++++ b/grub-core/commands/efi/tpm.c +@@ -349,3 +349,40 @@ + + return result; + } ++ ++int ++grub_tpm_present () ++{ ++ grub_efi_handle_t tpm_handle; ++ grub_efi_uint8_t protocol_version; ++ ++ if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) ++ return 0; ++ ++ if (protocol_version == 1) ++ { ++ grub_efi_tpm_protocol_t *tpm; ++ ++ tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid, ++ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); ++ if (!tpm) ++ { ++ grub_dprintf ("tpm", "Cannot open TPM protocol\n"); ++ return 0; ++ } ++ return grub_tpm1_present (tpm); ++ } ++ else ++ { ++ grub_efi_tpm2_protocol_t *tpm; ++ ++ tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid, ++ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); ++ if (!tpm) ++ { ++ grub_dprintf ("tpm", "Cannot open TPM protocol\n"); ++ return 0; ++ } ++ return grub_tpm2_present (tpm); ++ } ++} +--- a/grub-core/commands/tpm.c ++++ b/grub-core/commands/tpm.c +@@ -291,6 +291,8 @@ + + GRUB_MOD_INIT (tpm) + { ++ if (!grub_tpm_present()) ++ return; + grub_verifier_register (&grub_tpm_verifier); + + cmd = grub_register_extcmd ("tpm_record_pcrs", grub_tpm_record_pcrs, 0, +@@ -301,6 +303,8 @@ + + GRUB_MOD_FINI (tpm) + { ++ if (!grub_tpm_present()) ++ return; + grub_verifier_unregister (&grub_tpm_verifier); + grub_unregister_extcmd (cmd); + } +--- a/include/grub/tpm.h ++++ b/include/grub/tpm.h +@@ -44,5 +44,6 @@ + grub_uint8_t pcr, const char *description); + struct grub_tpm_digest *grub_tpm_read_pcr (grub_uint8_t index, const char *algo); + void grub_tpm_digest_free (struct grub_tpm_digest *d); ++int grub_tpm_present (void); + + #endif diff --git a/0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch b/0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch new file mode 100644 index 0000000..a03e641 --- /dev/null +++ b/0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch @@ -0,0 +1,127 @@ +From a25627c13b7e1e6998a14b5dd23b04b28465d737 Mon Sep 17 00:00:00 2001 +From: Josselin Poiret via Grub-devel +Date: Tue, 14 Jun 2022 15:47:30 +0200 +Subject: [PATCH 02/10] devmapper/getroot: Set up cheated LUKS2 cryptodisk + mount from DM parameters + +This lets a LUKS2 cryptodisk have its cipher and hash filled out, +otherwise they wouldn't be initialized if cheat mounted. +--- + grub-core/osdep/devmapper/getroot.c | 91 +++++++++++++++++++++++++++++++++++- + 1 file changed, 90 insertions(+), 1 deletion(-) + +--- a/grub-core/osdep/devmapper/getroot.c ++++ b/grub-core/osdep/devmapper/getroot.c +@@ -51,6 +51,8 @@ + #include + #include + ++#include ++ + static int + grub_util_open_dm (const char *os_dev, struct dm_tree **tree, + struct dm_tree_node **node) +@@ -186,7 +188,6 @@ + && lastsubdev) + { + char *grdev = grub_util_get_grub_dev (lastsubdev); +- dm_tree_free (tree); + if (grdev) + { + grub_err_t err; +@@ -194,7 +195,95 @@ + if (err) + grub_util_error (_("can't mount encrypted volume `%s': %s"), + lastsubdev, grub_errmsg); ++ if (strncmp (uuid, "CRYPT-LUKS2-", sizeof ("CRYPT-LUKS2-") - 1) == 0) ++ { ++ /* set LUKS2 cipher from dm parameters, since it is not ++ * possible to determine the correct one without ++ * unlocking, as there might be multiple segments. ++ */ ++ grub_disk_t source; ++ grub_cryptodisk_t cryptodisk; ++ grub_uint64_t start, length; ++ char *target_type; ++ char *params; ++ const char *name; ++ char *cipher, *cipher_mode; ++ struct dm_task *dmt; ++ char *seek_head, *c; ++ unsigned int remaining; ++ ++ source = grub_disk_open (grdev); ++ cryptodisk = grub_cryptodisk_get_by_source_disk (source); ++ grub_disk_close (source); ++ ++ name = dm_tree_node_get_name (node); ++ ++ grub_util_info ("populating parameters of cryptomount `%s' from DM device `%s'", ++ uuid, name); ++ ++ dmt = dm_task_create (DM_DEVICE_TABLE); ++ if (dmt == 0) ++ grub_util_error (_("can't create dm task DM_DEVICE_TABLE")); ++ if (dm_task_set_name (dmt, name) == 0) ++ grub_util_error (_("can't set dm task name to `%s'"), name); ++ if (dm_task_run (dmt) == 0) ++ grub_util_error (_("can't run dm task for `%s'"), name); ++ /* dm_get_next_target doesn't have any error modes, everything has ++ * been handled by dm_task_run. ++ */ ++ dm_get_next_target (dmt, NULL, &start, &length, ++ &target_type, ¶ms); ++ if (strncmp (target_type, "crypt", sizeof ("crypt")) != 0) ++ grub_util_error (_("dm target of type `%s' is not `crypt'"), ++ target_type); ++ ++ /* dm target parameters for dm-crypt is ++ * [<#opt_params> ...] ++ */ ++ c = params; ++ remaining = grub_strlen (c); ++ ++ /* first, get the cipher name from the cipher */ ++ if (!(seek_head = grub_memchr (c, '-', remaining))) ++ grub_util_error (_("can't get cipher from dm-crypt parameters `%s'"), ++ params); ++ cipher = grub_strndup (c, seek_head - c); ++ remaining -= seek_head - c + 1; ++ c = seek_head + 1; ++ ++ /* now, the cipher mode */ ++ if (!(seek_head = grub_memchr (c, ' ', remaining))) ++ grub_util_error (_("can't get cipher mode from dm-crypt parameters `%s'"), ++ params); ++ cipher_mode = grub_strndup (c, seek_head - c); ++ remaining -= seek_head - c + 1; ++ c = seek_head + 1; ++ ++ err = grub_cryptodisk_setcipher (cryptodisk, cipher, cipher_mode); ++ if (err) ++ { ++ grub_util_error (_("can't set cipher of cryptodisk `%s' to `%s' with mode `%s'"), ++ uuid, cipher, cipher_mode); ++ } ++ ++ grub_free (cipher); ++ grub_free (cipher_mode); ++ ++ /* This is the only hash usable by PBKDF2, and we don't ++ * have Argon2 support yet, so set it by default, ++ * otherwise grub-probe would miss the required ++ * abstraction ++ */ ++ cryptodisk->hash = grub_crypto_lookup_md_by_name ("sha256"); ++ if (cryptodisk->hash == 0) ++ { ++ grub_util_error (_("can't lookup hash sha256 by name")); ++ } ++ ++ dm_task_destroy (dmt); ++ } + } ++ dm_tree_free (tree); + grub_free (grdev); + } + else diff --git a/0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch b/0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch new file mode 100644 index 0000000..b0f3ed4 --- /dev/null +++ b/0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch @@ -0,0 +1,106 @@ +From 834cb2ca9ed2d9d7a6926e598accdfe280b615da Mon Sep 17 00:00:00 2001 +From: Patrick Steinhardt +Date: Thu, 21 Apr 2022 15:24:19 +1000 +Subject: [PATCH 2/5] kern/efi/mm: Always request a fixed number of pages on + init + +When initializing the EFI memory subsystem, we will by default request +a quarter of the available memory, bounded by a minimum/maximum value. +Given that we're about to extend the EFI memory system to dynamically +request additional pages from the firmware as required, this scaling of +requested memory based on available memory will not make a lot of sense +anymore. + +Remove this logic as a preparatory patch such that we'll instead defer +to the runtime memory allocator. Note that ideally, we'd want to change +this after dynamic requesting of pages has been implemented for the EFI +platform. But because we'll need to split up initialization of the +memory subsystem and the request of pages from the firmware, we'd have +to duplicate quite some logic at first only to remove it afterwards +again. This seems quite pointless, so we instead have patches slightly +out of order. + +Signed-off-by: Patrick Steinhardt +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +Tested-by: Patrick Steinhardt +--- + grub-core/kern/efi/mm.c | 35 +++-------------------------------- + 1 file changed, 3 insertions(+), 32 deletions(-) + +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index 67a691d..2874522 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -38,9 +38,8 @@ + a multiplier of 4KB. */ + #define MEMORY_MAP_SIZE 0x3000 + +-/* The minimum and maximum heap size for GRUB itself. */ +-#define MIN_HEAP_SIZE 0x100000 +-#define MAX_HEAP_SIZE (1600 * 0x100000) ++/* The default heap size for GRUB itself in bytes. */ ++#define DEFAULT_HEAP_SIZE 0x100000 + + static void *finish_mmap_buf = 0; + static grub_efi_uintn_t finish_mmap_size = 0; +@@ -514,23 +513,6 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, + return filtered_desc; + } + +-/* Return the total number of pages. */ +-static grub_efi_uint64_t +-get_total_pages (grub_efi_memory_descriptor_t *memory_map, +- grub_efi_uintn_t desc_size, +- grub_efi_memory_descriptor_t *memory_map_end) +-{ +- grub_efi_memory_descriptor_t *desc; +- grub_efi_uint64_t total = 0; +- +- for (desc = memory_map; +- desc < memory_map_end; +- desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size)) +- total += desc->num_pages; +- +- return total; +-} +- + /* Add memory regions. */ + static void + add_memory_regions (grub_efi_memory_descriptor_t *memory_map, +@@ -619,8 +601,6 @@ grub_efi_mm_init (void) + grub_efi_memory_descriptor_t *filtered_memory_map_end; + grub_efi_uintn_t map_size; + grub_efi_uintn_t desc_size; +- grub_efi_uint64_t total_pages; +- grub_efi_uint64_t required_pages; + int mm_status; + + /* Prepare a memory region to store two memory maps. */ +@@ -660,22 +640,13 @@ grub_efi_mm_init (void) + filtered_memory_map_end = filter_memory_map (memory_map, filtered_memory_map, + desc_size, memory_map_end); + +- /* By default, request a quarter of the available memory. */ +- total_pages = get_total_pages (filtered_memory_map, desc_size, +- filtered_memory_map_end); +- required_pages = (total_pages >> 2); +- if (required_pages < BYTES_TO_PAGES (MIN_HEAP_SIZE)) +- required_pages = BYTES_TO_PAGES (MIN_HEAP_SIZE); +- else if (required_pages > BYTES_TO_PAGES (MAX_HEAP_SIZE)) +- required_pages = BYTES_TO_PAGES (MAX_HEAP_SIZE); +- + /* Sort the filtered descriptors, so that GRUB can allocate pages + from smaller regions. */ + sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end); + + /* Allocate memory regions for GRUB's memory management. */ + add_memory_regions (filtered_memory_map, desc_size, +- filtered_memory_map_end, required_pages); ++ filtered_memory_map_end, BYTES_TO_PAGES (DEFAULT_HEAP_SIZE)); + + #if 0 + /* For debug. */ +-- +2.35.3 + diff --git a/0002-mm-Defer-the-disk-cache-invalidation.patch b/0002-mm-Defer-the-disk-cache-invalidation.patch new file mode 100644 index 0000000..ddab6ba --- /dev/null +++ b/0002-mm-Defer-the-disk-cache-invalidation.patch @@ -0,0 +1,68 @@ +From 4284d40799aaf5aab11c690f232ce0a191dcfbdb Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Fri, 16 Sep 2022 10:59:55 +0800 +Subject: [PATCH 2/2] mm: Defer the disk cache invalidation + +When the heap memory is used up, the memory management code invalidates +the disk caches first and then requests the additional memory regioins. +Although this could minimize the memory usage, it hurts the loading time +since the disk caches may always miss. + +This patch defers the disk cache invalidation to avoid the possible +delays. + +Signen-off-by: Gary Lin +--- + grub-core/kern/mm.c | 22 +++++++--------------- + 1 file changed, 7 insertions(+), 15 deletions(-) + +diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c +index 0bd9f75..5280e8c 100644 +--- a/grub-core/kern/mm.c ++++ b/grub-core/kern/mm.c +@@ -355,20 +355,6 @@ grub_memalign (grub_size_t align, grub_size_t size) + switch (count) + { + case 0: +- /* Invalidate disk caches. */ +- grub_disk_cache_invalidate_all (); +- count++; +- goto again; +- +-#if 0 +- case 1: +- /* Unload unneeded modules. */ +- grub_dl_unload_unneeded (); +- count++; +- goto again; +-#endif +- +- case 1: + /* Request additional pages, contiguous */ + count++; + +@@ -378,7 +364,7 @@ grub_memalign (grub_size_t align, grub_size_t size) + + /* fallthrough */ + +- case 2: ++ case 1: + /* Request additional pages, anything at all */ + count++; + +@@ -394,6 +380,12 @@ grub_memalign (grub_size_t align, grub_size_t size) + + /* fallthrough */ + ++ case 2: ++ /* Invalidate disk caches. */ ++ grub_disk_cache_invalidate_all (); ++ count++; ++ goto again; ++ + default: + break; + } +-- +2.35.3 + diff --git a/0003-disk-cryptodisk-When-cheatmounting-use-the-sector-in.patch b/0003-disk-cryptodisk-When-cheatmounting-use-the-sector-in.patch new file mode 100644 index 0000000..a80501d --- /dev/null +++ b/0003-disk-cryptodisk-When-cheatmounting-use-the-sector-in.patch @@ -0,0 +1,71 @@ +From 5b694a13545224c2d21afc3e94831be1bcc85770 Mon Sep 17 00:00:00 2001 +From: Fabian Vogt +Date: Tue, 14 Jun 2022 15:55:21 +0200 +Subject: [PATCH 03/10] disk/cryptodisk: When cheatmounting, use the sector + info of the cheat device + +When using grub-probe with cryptodisk, the mapped block device from the host +is used directly instead of decrypting the source device in GRUB code. +In that case, the sector size and count of the host device needs to be used. +This is especially important when using luks2, which does not assign +total_sectors and log_sector_size when scanning, but only later when the +segments in the JSON area are evaluated. With an unset log_sector_size, +grub_open_device complains. + +This fixes grub-probe failing with +"error: sector sizes of 1 bytes aren't supported yet." + +Signed-off-by: Fabian Vogt +--- + grub-core/disk/cryptodisk.c | 20 ++++++++++++++++++-- + 1 file changed, 18 insertions(+), 2 deletions(-) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 6d22bf871c..ae8790f10f 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -698,16 +698,31 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk) + if (!dev) + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "No such device"); + +- disk->log_sector_size = dev->log_sector_size; +- + #ifdef GRUB_UTIL + if (dev->cheat) + { ++ grub_uint64_t cheat_dev_size; ++ unsigned int cheat_log_sector_size; ++ + if (!GRUB_UTIL_FD_IS_VALID (dev->cheat_fd)) + dev->cheat_fd = grub_util_fd_open (dev->cheat, GRUB_UTIL_FD_O_RDONLY); + if (!GRUB_UTIL_FD_IS_VALID (dev->cheat_fd)) + return grub_error (GRUB_ERR_IO, N_("cannot open `%s': %s"), + dev->cheat, grub_util_fd_strerror ()); ++ ++ /* Use the sector size and count of the cheat device */ ++ cheat_dev_size = grub_util_get_fd_size (dev->cheat_fd, dev->cheat, &cheat_log_sector_size); ++ if (cheat_dev_size == -1) ++ { ++ const char *errmsg = grub_util_fd_strerror (); ++ grub_util_fd_close (dev->cheat_fd); ++ dev->cheat_fd = GRUB_UTIL_FD_INVALID; ++ return grub_error (GRUB_ERR_IO, N_("failed to query size of device `%s': %s"), ++ dev->cheat, errmsg); ++ } ++ ++ dev->log_sector_size = cheat_log_sector_size; ++ dev->total_sectors = cheat_dev_size >> cheat_log_sector_size; + } + #endif + +@@ -721,6 +736,7 @@ grub_cryptodisk_open (const char *name, grub_disk_t disk) + } + + disk->data = dev; ++ disk->log_sector_size = dev->log_sector_size; + disk->total_sectors = dev->total_sectors; + disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE; + disk->id = dev->id; +-- +2.34.1 + diff --git a/0003-kern-efi-mm-Extract-function-to-add-memory-regions.patch b/0003-kern-efi-mm-Extract-function-to-add-memory-regions.patch new file mode 100644 index 0000000..e8cf6cd --- /dev/null +++ b/0003-kern-efi-mm-Extract-function-to-add-memory-regions.patch @@ -0,0 +1,86 @@ +From b4500ff77efe3b36256fae1e456ded65fd77cf04 Mon Sep 17 00:00:00 2001 +From: Patrick Steinhardt +Date: Thu, 21 Apr 2022 15:24:20 +1000 +Subject: [PATCH 3/5] kern/efi/mm: Extract function to add memory regions + +In preparation of support for runtime-allocating additional memory +region, this patch extracts the function to retrieve the EFI memory +map and add a subset of it to GRUB's own memory regions. + +Signed-off-by: Patrick Steinhardt +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +Tested-by: Patrick Steinhardt +--- + grub-core/kern/efi/mm.c | 21 +++++++++++++++------ + 1 file changed, 15 insertions(+), 6 deletions(-) + +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index 2874522..087272f 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -592,8 +592,8 @@ print_memory_map (grub_efi_memory_descriptor_t *memory_map, + } + #endif + +-void +-grub_efi_mm_init (void) ++static grub_err_t ++grub_efi_mm_add_regions (grub_size_t required_bytes) + { + grub_efi_memory_descriptor_t *memory_map; + grub_efi_memory_descriptor_t *memory_map_end; +@@ -606,7 +606,7 @@ grub_efi_mm_init (void) + /* Prepare a memory region to store two memory maps. */ + memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); + if (! memory_map) +- grub_fatal ("cannot allocate memory"); ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory for memory map"); + + /* Obtain descriptors for available memory. */ + map_size = MEMORY_MAP_SIZE; +@@ -624,14 +624,14 @@ grub_efi_mm_init (void) + + memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (map_size)); + if (! memory_map) +- grub_fatal ("cannot allocate memory"); ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate memory for new memory map"); + + mm_status = grub_efi_get_memory_map (&map_size, memory_map, 0, + &desc_size, 0); + } + + if (mm_status < 0) +- grub_fatal ("cannot get memory map"); ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, "error fetching memory map from EFI"); + + memory_map_end = NEXT_MEMORY_DESCRIPTOR (memory_map, map_size); + +@@ -646,7 +646,7 @@ grub_efi_mm_init (void) + + /* Allocate memory regions for GRUB's memory management. */ + add_memory_regions (filtered_memory_map, desc_size, +- filtered_memory_map_end, BYTES_TO_PAGES (DEFAULT_HEAP_SIZE)); ++ filtered_memory_map_end, BYTES_TO_PAGES (required_bytes)); + + #if 0 + /* For debug. */ +@@ -664,6 +664,15 @@ grub_efi_mm_init (void) + /* Release the memory maps. */ + grub_efi_free_pages ((grub_addr_t) memory_map, + 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); ++ ++ return GRUB_ERR_NONE; ++} ++ ++void ++grub_efi_mm_init (void) ++{ ++ if (grub_efi_mm_add_regions (DEFAULT_HEAP_SIZE) != GRUB_ERR_NONE) ++ grub_fatal ("%s", grub_errmsg); + } + + #if defined (__aarch64__) || defined (__arm__) || defined (__riscv) +-- +2.35.3 + diff --git a/0004-kern-efi-mm-Pass-up-errors-from-add_memory_regions.patch b/0004-kern-efi-mm-Pass-up-errors-from-add_memory_regions.patch new file mode 100644 index 0000000..d2416a9 --- /dev/null +++ b/0004-kern-efi-mm-Pass-up-errors-from-add_memory_regions.patch @@ -0,0 +1,89 @@ +From 4287786dde414d9b0517d12762904b4b2be19d2a Mon Sep 17 00:00:00 2001 +From: Patrick Steinhardt +Date: Thu, 21 Apr 2022 15:24:21 +1000 +Subject: [PATCH 4/5] kern/efi/mm: Pass up errors from add_memory_regions() + +The function add_memory_regions() is currently only called on system +initialization to allocate a fixed amount of pages. As such, it didn't +need to return any errors: in case it failed, we cannot proceed anyway. +This will change with the upcoming support for requesting more memory +from the firmware at runtime, where it doesn't make sense anymore to +fail hard. + +Refactor the function to return an error to prepare for this. Note that +this does not change the behaviour when initializing the memory system +because grub_efi_mm_init() knows to call grub_fatal() in case +grub_efi_mm_add_regions() returns an error. + +Signed-off-by: Patrick Steinhardt +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +Tested-by: Patrick Steinhardt +--- + grub-core/kern/efi/mm.c | 22 +++++++++++++++------- + 1 file changed, 15 insertions(+), 7 deletions(-) + +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index 087272f..45ea6d5 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -514,7 +514,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, + } + + /* Add memory regions. */ +-static void ++static grub_err_t + add_memory_regions (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end, +@@ -542,9 +542,9 @@ add_memory_regions (grub_efi_memory_descriptor_t *memory_map, + GRUB_EFI_ALLOCATE_ADDRESS, + GRUB_EFI_LOADER_CODE); + if (! addr) +- grub_fatal ("cannot allocate conventional memory %p with %u pages", +- (void *) ((grub_addr_t) start), +- (unsigned) pages); ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "Memory starting at %p (%u pages) marked as free, but EFI would not allocate", ++ (void *) ((grub_addr_t) start), (unsigned) pages); + + grub_mm_init_region (addr, PAGES_TO_BYTES (pages)); + +@@ -554,7 +554,11 @@ add_memory_regions (grub_efi_memory_descriptor_t *memory_map, + } + + if (required_pages > 0) +- grub_fatal ("too little memory"); ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "could not allocate all requested memory: %" PRIuGRUB_UINT64_T " pages still required after iterating EFI memory map", ++ required_pages); ++ ++ return GRUB_ERR_NONE; + } + + void +@@ -601,6 +605,7 @@ grub_efi_mm_add_regions (grub_size_t required_bytes) + grub_efi_memory_descriptor_t *filtered_memory_map_end; + grub_efi_uintn_t map_size; + grub_efi_uintn_t desc_size; ++ grub_err_t err; + int mm_status; + + /* Prepare a memory region to store two memory maps. */ +@@ -645,8 +650,11 @@ grub_efi_mm_add_regions (grub_size_t required_bytes) + sort_memory_map (filtered_memory_map, desc_size, filtered_memory_map_end); + + /* Allocate memory regions for GRUB's memory management. */ +- add_memory_regions (filtered_memory_map, desc_size, +- filtered_memory_map_end, BYTES_TO_PAGES (required_bytes)); ++ err = add_memory_regions (filtered_memory_map, desc_size, ++ filtered_memory_map_end, ++ BYTES_TO_PAGES (required_bytes)); ++ if (err != GRUB_ERR_NONE) ++ return err; + + #if 0 + /* For debug. */ +-- +2.35.3 + diff --git a/0004-normal-menu-Don-t-show-Booting-s-msg-when-auto-booti.patch b/0004-normal-menu-Don-t-show-Booting-s-msg-when-auto-booti.patch new file mode 100644 index 0000000..cdfbc7a --- /dev/null +++ b/0004-normal-menu-Don-t-show-Booting-s-msg-when-auto-booti.patch @@ -0,0 +1,93 @@ +From d4eb747f831d8b011c712f4335f12b572d6f32d9 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 28 Jan 2022 11:30:32 +0100 +Subject: [PATCH 04/10] normal/menu: Don't show "Booting `%s'" msg when + auto-booting with TIMEOUT_STYLE_HIDDEN + +When the user has asked the menu code to be hidden/quiet and the current +entry is being autobooted because the timeout has expired don't show +the "Booting `%s'" msg. + +This is necessary to let flicker-free boots really be flicker free, +otherwise the "Booting `%s'" msg will kick the EFI fb into text mode +and show the msg, breaking the flicker-free experience. + +Signed-off-by: Hans de Goede +--- + grub-core/normal/menu.c | 24 ++++++++++++++++-------- + 1 file changed, 16 insertions(+), 8 deletions(-) + +diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c +index 47fc12551f..470bfc839b 100644 +--- a/grub-core/normal/menu.c ++++ b/grub-core/normal/menu.c +@@ -651,13 +651,15 @@ workaround_snapshot_menu_default_entry (grub_menu_t menu, const char *name, int + entry to be executed is a result of an automatic default selection because + of the timeout. */ + static int +-run_menu (grub_menu_t menu, int nested, int *auto_boot) ++run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot) + { + grub_uint64_t saved_time; + int default_entry, current_entry; + int timeout; + enum timeout_style timeout_style; + ++ *notify_boot = 1; ++ + default_entry = get_entry_number (menu, "default"); + + workaround_snapshot_menu_default_entry (menu, "default", &default_entry); +@@ -734,6 +736,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) + if (timeout == 0) + { + *auto_boot = 1; ++ *notify_boot = timeout_style != TIMEOUT_STYLE_HIDDEN; + return default_entry; + } + +@@ -894,12 +897,16 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) + + /* Callback invoked immediately before a menu entry is executed. */ + static void +-notify_booting (grub_menu_entry_t entry, +- void *userdata __attribute__((unused))) ++notify_booting (grub_menu_entry_t entry, void *userdata) + { +- grub_printf (" "); +- grub_printf_ (N_("Booting `%s'"), entry->title); +- grub_printf ("\n\n"); ++ int *notify_boot = userdata; ++ ++ if (*notify_boot) ++ { ++ grub_printf (" "); ++ grub_printf_ (N_("Booting `%s'"), entry->title); ++ grub_printf ("\n\n"); ++ } + } + + /* Callback invoked when a default menu entry executed because of a timeout +@@ -947,8 +954,9 @@ show_menu (grub_menu_t menu, int nested, int autobooted) + int boot_entry; + grub_menu_entry_t e; + int auto_boot; ++ int notify_boot; + +- boot_entry = run_menu (menu, nested, &auto_boot); ++ boot_entry = run_menu (menu, nested, &auto_boot, ¬ify_boot); + if (boot_entry < 0) + break; + +@@ -960,7 +968,7 @@ show_menu (grub_menu_t menu, int nested, int autobooted) + + if (auto_boot) + grub_menu_execute_with_fallback (menu, e, autobooted, +- &execution_callback, 0); ++ &execution_callback, ¬ify_boot); + else + grub_menu_execute_entry (e, 0); + if (autobooted) +-- +2.34.1 + diff --git a/0005-EFI-suppress-the-Welcome-to-GRUB-message-in-EFI-buil.patch b/0005-EFI-suppress-the-Welcome-to-GRUB-message-in-EFI-buil.patch new file mode 100644 index 0000000..062fdf3 --- /dev/null +++ b/0005-EFI-suppress-the-Welcome-to-GRUB-message-in-EFI-buil.patch @@ -0,0 +1,45 @@ +From d9c7bfe88ce7391618192401c426c218d2a17795 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 28 Jan 2022 11:30:33 +0100 +Subject: [PATCH 05/10] EFI: suppress the "Welcome to GRUB!" message in EFI + builds + +Grub EFI builds are now often used in combination with flicker-free +boot, but this breaks with upstream grub because the "Welcome to GRUB!" +message will kick the EFI fb into text mode and show the msg, +breaking the flicker-free experience. + +EFI systems are so fast, that when the menu or the countdown are enabled +the message will be immediately overwritten, so in these cases not +printing the message does not matter. + +And in case when the timeout_style is set to TIMEOUT_STYLE_HIDDEN, +the user has asked grub to be quiet (for example to allow flickfree +boot) annd thus the message should not be printed. + +Signed-off-by: Hans de Goede +--- + grub-core/kern/main.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c +index 42ea96e39e..35dee404e8 100644 +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -272,10 +272,13 @@ grub_main (void) + + grub_boot_time ("After machine init."); + ++ /* This breaks flicker-free boot on EFI systems, so disable it there. */ ++#ifndef GRUB_MACHINE_EFI + /* Hello. */ + grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); + grub_printf ("Welcome to GRUB!\n\n"); + grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); ++#endif + + #ifndef GRUB_MACHINE_PCBIOS + /* Init verifiers API. */ +-- +2.34.1 + diff --git a/0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch b/0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch new file mode 100644 index 0000000..5790670 --- /dev/null +++ b/0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch @@ -0,0 +1,77 @@ +From 3a2119e11b9c216f3b008a2c61aca52b91ad7547 Mon Sep 17 00:00:00 2001 +From: Patrick Steinhardt +Date: Thu, 21 Apr 2022 15:24:22 +1000 +Subject: [PATCH 5/5] kern/efi/mm: Implement runtime addition of pages + +Adjust the interface of grub_efi_mm_add_regions() to take a set of +GRUB_MM_ADD_REGION_* flags, which most notably is currently only the +GRUB_MM_ADD_REGION_CONSECUTIVE flag. This allows us to set the function +up as callback for the memory subsystem and have it call out to us in +case there's not enough pages available in the current heap. + +Signed-off-by: Patrick Steinhardt +Signed-off-by: Daniel Axtens +Reviewed-by: Daniel Kiper +Tested-by: Patrick Steinhardt +--- + grub-core/kern/efi/mm.c | 15 +++++++++++---- + 1 file changed, 11 insertions(+), 4 deletions(-) + +diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c +index 45ea6d5..48380d3 100644 +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -518,7 +518,8 @@ static grub_err_t + add_memory_regions (grub_efi_memory_descriptor_t *memory_map, + grub_efi_uintn_t desc_size, + grub_efi_memory_descriptor_t *memory_map_end, +- grub_efi_uint64_t required_pages) ++ grub_efi_uint64_t required_pages, ++ unsigned int flags) + { + grub_efi_memory_descriptor_t *desc; + +@@ -532,6 +533,10 @@ add_memory_regions (grub_efi_memory_descriptor_t *memory_map, + + start = desc->physical_start; + pages = desc->num_pages; ++ ++ if (pages < required_pages && (flags & GRUB_MM_ADD_REGION_CONSECUTIVE)) ++ continue; ++ + if (pages > required_pages) + { + start += PAGES_TO_BYTES (pages - required_pages); +@@ -597,7 +602,7 @@ print_memory_map (grub_efi_memory_descriptor_t *memory_map, + #endif + + static grub_err_t +-grub_efi_mm_add_regions (grub_size_t required_bytes) ++grub_efi_mm_add_regions (grub_size_t required_bytes, unsigned int flags) + { + grub_efi_memory_descriptor_t *memory_map; + grub_efi_memory_descriptor_t *memory_map_end; +@@ -652,7 +657,8 @@ grub_efi_mm_add_regions (grub_size_t required_bytes) + /* Allocate memory regions for GRUB's memory management. */ + err = add_memory_regions (filtered_memory_map, desc_size, + filtered_memory_map_end, +- BYTES_TO_PAGES (required_bytes)); ++ BYTES_TO_PAGES (required_bytes), ++ flags); + if (err != GRUB_ERR_NONE) + return err; + +@@ -679,8 +685,9 @@ grub_efi_mm_add_regions (grub_size_t required_bytes) + void + grub_efi_mm_init (void) + { +- if (grub_efi_mm_add_regions (DEFAULT_HEAP_SIZE) != GRUB_ERR_NONE) ++ if (grub_efi_mm_add_regions (DEFAULT_HEAP_SIZE, GRUB_MM_ADD_REGION_NONE) != GRUB_ERR_NONE) + grub_fatal ("%s", grub_errmsg); ++ grub_mm_add_region_fn = grub_efi_mm_add_regions; + } + + #if defined (__aarch64__) || defined (__arm__) || defined (__riscv) +-- +2.35.3 + diff --git a/0006-EFI-console-Do-not-set-colorstate-until-the-first-te.patch b/0006-EFI-console-Do-not-set-colorstate-until-the-first-te.patch new file mode 100644 index 0000000..f556bc1 --- /dev/null +++ b/0006-EFI-console-Do-not-set-colorstate-until-the-first-te.patch @@ -0,0 +1,54 @@ +From 81339347bc10ec609227361434f75c5e36b85b9f Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 28 Jan 2022 12:43:48 +0100 +Subject: [PATCH 06/10] EFI: console: Do not set colorstate until the first + text output + +GRUB_MOD_INIT(normal) does an unconditional: + +grub_env_set ("color_normal", "light-gray/black"); + +which triggers a grub_term_setcolorstate() call. The original version +of the "efi/console: Do not set text-mode until we actually need it" patch: +https://lists.gnu.org/archive/html/grub-devel/2018-03/msg00125.html + +Protected against this by caching the requested state in +grub_console_setcolorstate () and then only applying it when the first +text output actually happens. During refactoring to move the +grub_console_setcolorstate () up higher in the grub-core/term/efi/console.c +file the code to cache the color-state + bail early was accidentally +dropped. + +Restore the cache the color-state + bail early behavior from the original. + +Cc: Javier Martinez Canillas +Fixes: 2d7c3abd871f ("efi/console: Do not set text-mode until we actually need it") +Signed-off-by: Hans de Goede +--- + grub-core/term/efi/console.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c +index 2f1ae85ba7..c44b2ac318 100644 +--- a/grub-core/term/efi/console.c ++++ b/grub-core/term/efi/console.c +@@ -82,6 +82,16 @@ grub_console_setcolorstate (struct grub_term_output *term + { + grub_efi_simple_text_output_interface_t *o; + ++ if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE) ++ { ++ /* ++ * Cache colorstate changes before the first text-output, this avoids ++ * "color_normal" environment writes causing a switch to textmode. ++ */ ++ text_colorstate = state; ++ return; ++ } ++ + if (grub_efi_is_finished) + return; + +-- +2.34.1 + diff --git a/0007-EFI-console-Do-not-set-cursor-until-the-first-text-o.patch b/0007-EFI-console-Do-not-set-cursor-until-the-first-text-o.patch new file mode 100644 index 0000000..531bec5 --- /dev/null +++ b/0007-EFI-console-Do-not-set-cursor-until-the-first-text-o.patch @@ -0,0 +1,75 @@ +From 9b12dc80d4254e22c41805cecf2494a8e6a50e3e Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Fri, 28 Jan 2022 12:43:49 +0100 +Subject: [PATCH 07/10] EFI: console: Do not set cursor until the first text + output + +To allow flickerfree boot the EFI console code does not call +grub_efi_set_text_mode (1) until some text is actually output. + +Depending on if the output text is because of an error loading +e.g. the .cfg file; or because of showing the menu the cursor needs +to be on or off when the first text is shown. + +So far the cursor was hardcoded to being on, but this is causing +drawing artifacts + slow drawing of the menu as reported here: +https://bugzilla.redhat.com/show_bug.cgi?id=1946969 + +Handle the cursorstate in the same way as the colorstate to fix this, +when no text has been output yet, just cache the cursorstate and +then use the last set value when the first text is output. + +Fixes: 2d7c3abd871f ("efi/console: Do not set text-mode until we actually need it") +Signed-off-by: Hans de Goede +--- + grub-core/term/efi/console.c | 19 ++++++++++++++++--- + 1 file changed, 16 insertions(+), 3 deletions(-) + +diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c +index c44b2ac318..a3622e4fe5 100644 +--- a/grub-core/term/efi/console.c ++++ b/grub-core/term/efi/console.c +@@ -31,7 +31,15 @@ typedef enum { + } + grub_text_mode; + ++typedef enum { ++ GRUB_CURSOR_MODE_UNDEFINED = -1, ++ GRUB_CURSOR_MODE_OFF = 0, ++ GRUB_CURSUR_MODE_ON ++} ++grub_cursor_mode; ++ + static grub_text_mode text_mode = GRUB_TEXT_MODE_UNDEFINED; ++static grub_cursor_mode cursor_mode = GRUB_CURSOR_MODE_UNDEFINED; + static grub_term_color_state text_colorstate = GRUB_TERM_COLOR_UNDEFINED; + + static grub_uint32_t +@@ -119,8 +127,12 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), + { + grub_efi_simple_text_output_interface_t *o; + +- if (grub_efi_is_finished) +- return; ++ if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE) ++ { ++ /* Cache cursor changes before the first text-output */ ++ cursor_mode = on; ++ return; ++ } + + o = grub_efi_system_table->con_out; + efi_call_2 (o->enable_cursor, o, on); +@@ -143,7 +155,8 @@ grub_prepare_for_text_output (struct grub_term_output *term) + return GRUB_ERR_BAD_DEVICE; + } + +- grub_console_setcursor (term, 1); ++ if (cursor_mode != GRUB_CURSOR_MODE_UNDEFINED) ++ grub_console_setcursor (term, cursor_mode); + if (text_colorstate != GRUB_TERM_COLOR_UNDEFINED) + grub_console_setcolorstate (term, text_colorstate); + text_mode = GRUB_TEXT_MODE_AVAILABLE; +-- +2.34.1 + diff --git a/0008-linuxefi-Use-common-grub_initrd_load.patch b/0008-linuxefi-Use-common-grub_initrd_load.patch new file mode 100644 index 0000000..2f0209e --- /dev/null +++ b/0008-linuxefi-Use-common-grub_initrd_load.patch @@ -0,0 +1,156 @@ +From adf486860fe0d395579be8b01d4fda8b93377768 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Wed, 8 Jun 2022 16:04:12 +0800 +Subject: [PATCH 08/10] linuxefi: Use common grub_initrd_load + +By using the common initrd loading routine factored out allows to share between +features like concatenating initramfs component. + +For eg. + + initrdefi /initrd-5.16.15-1-default newc:grub.cfg:/grub2/grub.cfg + +The file /grub2/grub.cfg read off from root disk will be available to use as +/grub.cfg in the target initramfs loaded by grub. + +Signed-off-by: Michael Chang +--- + grub-core/loader/i386/efi/linux.c | 87 ++++--------------------------- + 1 file changed, 10 insertions(+), 77 deletions(-) + +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c +index 6b06a8f2ff..f93395fc62 100644 +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -146,44 +147,6 @@ grub_linuxefi_unload (void) + return GRUB_ERR_NONE; + } + +-#define BOUNCE_BUFFER_MAX 0x1000000ull +- +-static grub_ssize_t +-read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len) +-{ +- grub_ssize_t bufpos = 0; +- static grub_size_t bbufsz = 0; +- static char *bbuf = NULL; +- +- if (bbufsz == 0) +- bbufsz = MIN(BOUNCE_BUFFER_MAX, len); +- +- while (!bbuf && bbufsz) +- { +- bbuf = grub_malloc(bbufsz); +- if (!bbuf) +- bbufsz >>= 1; +- } +- if (!bbuf) +- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate bounce buffer")); +- +- while (bufpos < (long long)len) +- { +- grub_ssize_t sz; +- +- sz = grub_file_read (file, bbuf, MIN(bbufsz, len - bufpos)); +- if (sz < 0) +- return sz; +- if (sz == 0) +- break; +- +- grub_memcpy(bufp + bufpos, bbuf, sz); +- bufpos += sz; +- } +- +- return bufpos; +-} +- + #define LOW_U32(val) ((grub_uint32_t)(((grub_addr_t)(val)) & 0xffffffffull)) + #define HIGH_U32(val) ((grub_uint32_t)(((grub_addr_t)(val) >> 32) & 0xffffffffull)) + +@@ -191,10 +154,8 @@ static grub_err_t + grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +- grub_file_t *files = 0; +- int i, nfiles = 0; ++ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; + grub_size_t size = 0; +- grub_uint8_t *ptr; + + if (argc == 0) + { +@@ -208,24 +169,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- files = grub_calloc (argc, sizeof (files[0])); +- if (!files) ++ if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + +- for (i = 0; i < argc; i++) +- { +- files[i] = grub_file_open (argv[i], GRUB_FILE_TYPE_LINUX_INITRD +- | GRUB_FILE_TYPE_NO_DECOMPRESS); +- if (! files[i]) +- goto fail; +- nfiles++; +- if (grub_add (size, ALIGN_UP (grub_file_size (files[i]), 4), &size)) +- { +- grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); +- goto fail; +- } +- } +- ++ size = grub_get_initrd_size (&initrd_ctx); + initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); + if (initrd_mem == NULL) + goto fail; +@@ -238,30 +185,16 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + params->ext_ramdisk_image = HIGH_U32(initrd_mem); + #endif + +- ptr = initrd_mem; +- +- for (i = 0; i < nfiles; i++) +- { +- grub_ssize_t cursize = grub_file_size (files[i]); +- if (read (files[i], ptr, cursize) != cursize) +- { +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- argv[i]); +- goto fail; +- } +- ptr += cursize; +- grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); +- ptr += ALIGN_UP_OVERHEAD (cursize, 4); +- } ++ /* FIXME: Use bounce buffers as many UEFI machines apparently can't DMA ++ * correctly above 4GB ++ */ ++ if (grub_initrd_load (&initrd_ctx, argv, initrd_mem)) ++ goto fail; + + params->ramdisk_size = size; + + fail: +- for (i = 0; i < nfiles; i++) +- grub_file_close (files[i]); +- grub_free (files); +- ++ grub_initrd_close (&initrd_ctx); + if (initrd_mem && grub_errno) + grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, BYTES_TO_PAGES(size)); + +-- +2.34.1 + diff --git a/0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch b/0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch new file mode 100644 index 0000000..72716fd --- /dev/null +++ b/0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch @@ -0,0 +1,338 @@ +From 749f7dee6f63217e536663aebb817aec72a65d5a Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Thu, 9 Jun 2022 21:06:00 +0800 +Subject: [PATCH 09/10] Add crypttab_entry to obviate the need to input + password twice + +This patch adds crypttab_entry command to hint grub where to put the key file +automatically loaded by linux cryptsetup. It's syntax is similar to +/etc/crypttab so that it is relatively straightforward to import. + + crypttab_entry + +For eg: + + crypttab_entry cr_root 5e1dd109e39343f984da57fd742d3f23 none + +Please note the "encrypted-device" only accepts UUID without dashes as it is +the only identification used by grub's cryptodisk device. The crypttab_entry +can also be used multiple times to specify encrypted volumes unlocked by +"cryptomount -a". + +Signed-off-by: Michael Chang +--- + grub-core/Makefile.core.def | 5 ++ + grub-core/commands/crypttab.c | 42 ++++++++++++ + grub-core/disk/cryptodisk.c | 5 ++ + grub-core/loader/linux.c | 126 ++++++++++++++++++++++++++++++++-- + include/grub/linux.h | 3 + + 5 files changed, 177 insertions(+), 4 deletions(-) + create mode 100644 grub-core/commands/crypttab.c + +Index: grub-2.06/grub-core/Makefile.core.def +=================================================================== +--- grub-2.06.orig/grub-core/Makefile.core.def ++++ grub-2.06/grub-core/Makefile.core.def +@@ -2643,3 +2643,8 @@ module = { + cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; + cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)'; + }; ++ ++module = { ++ name = crypttab; ++ common = commands/crypttab.c; ++}; +Index: grub-2.06/grub-core/commands/crypttab.c +=================================================================== +--- /dev/null ++++ grub-2.06/grub-core/commands/crypttab.c +@@ -0,0 +1,42 @@ ++ ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static grub_err_t ++grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char **argv) ++{ ++ char buf[64]; ++ const char *path = argv[2]; ++ ++ if (argc != 3) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("three arguments expected")); ++ ++ if (grub_strcmp (argv[2], "none") == 0 ++ || grub_strcmp (argv[2], "-") == 0) ++ { ++ grub_snprintf (buf, sizeof (buf), "/etc/cryptsetup-keys.d/%s.key", argv[0]); ++ path = buf; ++ } ++ ++ /*FIXME: Validate UUID string*/ ++ return grub_initrd_publish_key (argv[1], NULL, 0, path); ++} ++ ++static grub_command_t cmd; ++ ++GRUB_MOD_INIT(crypttab) ++{ ++ cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry, ++ N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description")); ++} ++ ++GRUB_MOD_FINI(crypttab) ++{ ++ grub_unregister_command (cmd); ++} +Index: grub-2.06/grub-core/disk/cryptodisk.c +=================================================================== +--- grub-2.06.orig/grub-core/disk/cryptodisk.c ++++ grub-2.06/grub-core/disk/cryptodisk.c +@@ -30,6 +30,8 @@ + + #ifdef GRUB_UTIL + #include ++#else ++#include + #endif + + GRUB_MOD_LICENSE ("GPLv3+"); +@@ -1146,6 +1148,10 @@ grub_cryptodisk_scan_device_real (const + dev = NULL; + + cleanup: ++#ifndef GRUB_UTIL ++ if (cargs->key_data) ++ grub_initrd_publish_key (dev->uuid, (const char *)cargs->key_data, cargs->key_len, NULL); ++#endif + if (askpass) + { + cargs->key_len = 0; +Index: grub-2.06/grub-core/loader/linux.c +=================================================================== +--- grub-2.06.orig/grub-core/loader/linux.c ++++ grub-2.06/grub-core/loader/linux.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + + struct newc_head + { +@@ -27,6 +28,7 @@ struct newc_head + struct grub_linux_initrd_component + { + grub_file_t file; ++ char *buf; + char *newc_name; + grub_off_t size; + }; +@@ -38,6 +40,18 @@ struct dir + struct dir *child; + }; + ++struct grub_key_publisher ++{ ++ struct grub_key_publisher *next; ++ struct grub_key_publisher **prev; ++ char *name; /* UUID */ ++ char *path; ++ char *key; ++ grub_size_t key_len; ++}; ++ ++static struct grub_key_publisher *kpuber; ++ + static char + hex (grub_uint8_t val) + { +@@ -149,6 +163,65 @@ insert_dir (const char *name, struct dir + return GRUB_ERR_NONE; + } + ++static grub_err_t ++grub_initrd_component (const char *buf, int bufsz, const char *newc_name, ++ struct grub_linux_initrd_context *initrd_ctx) ++{ ++ struct dir *root = 0; ++ struct grub_linux_initrd_component *comp = initrd_ctx->components + initrd_ctx->nfiles; ++ grub_size_t dir_size, name_len; ++ ++ while (*newc_name == '/') ++ newc_name++; ++ ++ initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); ++ comp->newc_name = grub_strdup (newc_name); ++ if (!comp->newc_name || ++ insert_dir (comp->newc_name, &root, 0, &dir_size)) ++ { ++ /* FIXME: Check NULL file pointer before close */ ++ grub_initrd_close (initrd_ctx); ++ return grub_errno; ++ } ++ /* Should name_len count terminating null ? */ ++ name_len = grub_strlen (comp->newc_name) + 1; ++ if (grub_add (initrd_ctx->size, ++ ALIGN_UP (sizeof (struct newc_head) + name_len, 4), ++ &initrd_ctx->size) || ++ grub_add (initrd_ctx->size, dir_size, &initrd_ctx->size)) ++ goto overflow; ++ ++ comp->buf = grub_malloc (bufsz); ++ if (!comp->buf) ++ { ++ free_dir (root); ++ grub_initrd_close (initrd_ctx); ++ return grub_errno; ++ } ++ grub_memcpy (comp->buf, buf, bufsz); ++ initrd_ctx->nfiles++; ++ comp->size = bufsz; ++ if (grub_add (initrd_ctx->size, comp->size, ++ &initrd_ctx->size)) ++ goto overflow; ++ ++ initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); ++ if (grub_add (initrd_ctx->size, ++ ALIGN_UP (sizeof (struct newc_head) ++ + sizeof ("TRAILER!!!") - 1, 4), ++ &initrd_ctx->size)) ++ goto overflow; ++ ++ free_dir (root); ++ root = 0; ++ return GRUB_ERR_NONE; ++ ++ overflow: ++ free_dir (root); ++ grub_initrd_close (initrd_ctx); ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++} ++ + grub_err_t + grub_initrd_init (int argc, char *argv[], + struct grub_linux_initrd_context *initrd_ctx) +@@ -156,11 +229,17 @@ grub_initrd_init (int argc, char *argv[] + int i; + int newc = 0; + struct dir *root = 0; ++ struct grub_key_publisher *pk; ++ int numkey = 0; + + initrd_ctx->nfiles = 0; + initrd_ctx->components = 0; + +- initrd_ctx->components = grub_calloc (argc, sizeof (initrd_ctx->components[0])); ++ FOR_LIST_ELEMENTS (pk, kpuber) ++ if (pk->key && pk->path) ++ numkey++; ++ ++ initrd_ctx->components = grub_calloc (argc + numkey, sizeof (initrd_ctx->components[0])); + if (!initrd_ctx->components) + return grub_errno; + +@@ -239,7 +318,10 @@ grub_initrd_init (int argc, char *argv[] + free_dir (root); + root = 0; + } +- ++ ++ FOR_LIST_ELEMENTS (pk, kpuber) ++ if (pk->key && pk->path) ++ grub_initrd_component (pk->key, pk->key_len, pk->path, initrd_ctx); + return GRUB_ERR_NONE; + + overflow: +@@ -263,7 +345,9 @@ grub_initrd_close (struct grub_linux_ini + for (i = 0; i < initrd_ctx->nfiles; i++) + { + grub_free (initrd_ctx->components[i].newc_name); +- grub_file_close (initrd_ctx->components[i].file); ++ if (initrd_ctx->components[i].file) ++ grub_file_close (initrd_ctx->components[i].file); ++ grub_free (initrd_ctx->components[i].buf); + } + grub_free (initrd_ctx->components); + initrd_ctx->components = 0; +@@ -297,7 +381,7 @@ grub_initrd_load (struct grub_linux_init + } + ptr += dir_size; + ptr = make_header (ptr, initrd_ctx->components[i].newc_name, +- grub_strlen (initrd_ctx->components[i].newc_name), ++ grub_strlen (initrd_ctx->components[i].newc_name) + 1, + 0100777, + initrd_ctx->components[i].size); + newc = 1; +@@ -312,7 +396,12 @@ grub_initrd_load (struct grub_linux_init + } + + cursize = initrd_ctx->components[i].size; +- if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize) ++ if (initrd_ctx->components[i].buf) ++ { ++ grub_memcpy (ptr, initrd_ctx->components[i].buf, cursize); ++ newc = 1; ++ } ++ else if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize) + != cursize) + { + if (!grub_errno) +@@ -333,3 +422,41 @@ grub_initrd_load (struct grub_linux_init + root = 0; + return GRUB_ERR_NONE; + } ++ ++grub_err_t ++grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path) ++{ ++ struct grub_key_publisher *cur = grub_named_list_find (GRUB_AS_NAMED_LIST (kpuber), uuid); ++ ++ if (!cur) ++ cur = grub_zalloc (sizeof (*cur)); ++ if (!cur) ++ return grub_errno; ++ ++ if (key && key_len) ++ { ++ grub_free (cur->key); ++ cur->key = grub_malloc (key_len); ++ if (!cur->key) ++ { ++ grub_free (cur); ++ return grub_errno; ++ } ++ grub_memcpy (cur->key, key, key_len); ++ cur->key_len = key_len; ++ } ++ ++ if (path) ++ { ++ grub_free (cur->path); ++ cur->path = grub_strdup (path); ++ } ++ ++ if (!cur->name) ++ { ++ cur->name = grub_strdup (uuid); ++ grub_list_push (GRUB_AS_LIST_P (&kpuber), GRUB_AS_LIST (cur)); ++ } ++ ++ return GRUB_ERR_NONE; ++} +Index: grub-2.06/include/grub/linux.h +=================================================================== +--- grub-2.06.orig/include/grub/linux.h ++++ grub-2.06/include/grub/linux.h +@@ -22,3 +22,6 @@ grub_initrd_close (struct grub_linux_ini + grub_err_t + grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, + char *argv[], void *target); ++ ++grub_err_t ++grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path); diff --git a/0010-templates-import-etc-crypttab-to-grub.cfg.patch b/0010-templates-import-etc-crypttab-to-grub.cfg.patch new file mode 100644 index 0000000..b181685 --- /dev/null +++ b/0010-templates-import-etc-crypttab-to-grub.cfg.patch @@ -0,0 +1,81 @@ +From 2d3130c289b293269dcf558a26674f83f77729a6 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Tue, 14 Jun 2022 17:10:01 +0800 +Subject: [PATCH 10/10] templates: import /etc/crypttab to grub.cfg + +The /etc/crypptab is used to setup location of encryption key files during +boot, among other things. It is useful to make use the information by grub to +determine where keys are being looked up. + +This script can be used to import relevant /etc/crypptab entry to grub.cfg. + +Signed-off-by: Michael Chang +--- + Makefile.util.def | 7 +++++++ + util/grub.d/05_crypttab.in | 36 ++++++++++++++++++++++++++++++++++++ + 2 files changed, 43 insertions(+) + create mode 100644 util/grub.d/05_crypttab.in + +diff --git a/Makefile.util.def b/Makefile.util.def +index 08f681cd8b..5e0ba22f3d 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -476,6 +476,13 @@ script = { + installdir = grubconf; + }; + ++script = { ++ name = '05_crypttab'; ++ common = util/grub.d/05_crypttab.in; ++ installdir = grubconf; ++ condition = COND_HOST_LINUX; ++}; ++ + script = { + name = '10_windows'; + common = util/grub.d/10_windows.in; +diff --git a/util/grub.d/05_crypttab.in b/util/grub.d/05_crypttab.in +new file mode 100644 +index 0000000000..c539bc061e +--- /dev/null ++++ b/util/grub.d/05_crypttab.in +@@ -0,0 +1,36 @@ ++#! /bin/sh ++set -e ++ ++# grub-mkconfig helper script. ++# Copyright (C) 2022 Free Software Foundation, Inc. ++# ++# GRUB is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# GRUB is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GRUB. If not, see . ++ ++prefix="@prefix@" ++exec_prefix="@exec_prefix@" ++datarootdir="@datarootdir@" ++ ++export TEXTDOMAIN=@PACKAGE@ ++export TEXTDOMAINDIR="@localedir@" ++ ++. "$pkgdatadir/grub-mkconfig_lib" ++ ++CRYPTTAB=/etc/crypttab ++ ++if [ -r "$CRYPTTAB" ]; then ++ awk '/UUID=/ { sub(/UUID=/,"",$2); \ ++ gsub(/-/,"",$2); \ ++ printf("crypttab_entry %s %s %s\n",$1,$2,$3) \ ++ }' "$CRYPTTAB" ++fi +-- +2.34.1 + diff --git a/efi-set-variable-with-attrs.patch b/efi-set-variable-with-attrs.patch new file mode 100644 index 0000000..d2959d0 --- /dev/null +++ b/efi-set-variable-with-attrs.patch @@ -0,0 +1,51 @@ +Index: grub-2.06/include/grub/efi/efi.h +=================================================================== +--- grub-2.06.orig/include/grub/efi/efi.h ++++ grub-2.06/include/grub/efi/efi.h +@@ -86,6 +86,11 @@ grub_efi_status_t EXPORT_FUNC (grub_efi_ + const grub_efi_guid_t *guid, + grub_size_t *datasize_out, + void **data_out); ++grub_err_t EXPORT_FUNC (grub_efi_set_variable_with_attributes) (const char *var, ++ const grub_efi_guid_t *guid, ++ grub_efi_uint32_t attributes, ++ void *data, ++ grub_size_t datasize); + grub_err_t + EXPORT_FUNC (grub_efi_set_variable) (const char *var, + const grub_efi_guid_t *guid, +Index: grub-2.06/grub-core/kern/efi/efi.c +=================================================================== +--- grub-2.06.orig/grub-core/kern/efi/efi.c ++++ grub-2.06/grub-core/kern/efi/efi.c +@@ -196,6 +196,17 @@ grub_err_t + grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, + void *data, grub_size_t datasize) + { ++ return grub_efi_set_variable_with_attributes(var, guid, ++ (GRUB_EFI_VARIABLE_NON_VOLATILE ++ | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS ++ | GRUB_EFI_VARIABLE_RUNTIME_ACCESS), ++ data, datasize); ++} ++ ++grub_err_t ++grub_efi_set_variable_with_attributes(const char *var, const grub_efi_guid_t *guid, grub_efi_uint32_t attributes, ++ void *data, grub_size_t datasize) ++{ + grub_efi_status_t status; + grub_efi_runtime_services_t *r; + grub_efi_char16_t *var16; +@@ -211,10 +222,8 @@ grub_efi_set_variable(const char *var, c + + r = grub_efi_system_table->runtime_services; + +- status = efi_call_5 (r->set_variable, var16, guid, +- (GRUB_EFI_VARIABLE_NON_VOLATILE +- | GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS +- | GRUB_EFI_VARIABLE_RUNTIME_ACCESS), ++ status = efi_call_5 (r->set_variable, var16, guid, ++ attributes, + datasize, data); + grub_free (var16); + if (status == GRUB_EFI_SUCCESS) diff --git a/grub-install-record-pcrs.patch b/grub-install-record-pcrs.patch new file mode 100644 index 0000000..97ea0a1 --- /dev/null +++ b/grub-install-record-pcrs.patch @@ -0,0 +1,18 @@ +Index: grub-2.06/util/grub-install.c +=================================================================== +--- grub-2.06.orig/util/grub-install.c ++++ grub-2.06/util/grub-install.c +@@ -1457,6 +1457,13 @@ main (int argc, char *argv[]) + + grub_util_unlink (load_cfg); + ++ if (1) ++ { ++ load_cfg_f = grub_util_fopen (load_cfg, "wb"); ++ have_load_cfg = 1; ++ fprintf (load_cfg_f, "tpm_record_pcrs 0-9\n"); ++ } ++ + if (debug_image && debug_image[0]) + { + load_cfg_f = grub_util_fopen (load_cfg, "wb"); diff --git a/grub-read-pcr.patch b/grub-read-pcr.patch new file mode 100644 index 0000000..c4d0fa3 --- /dev/null +++ b/grub-read-pcr.patch @@ -0,0 +1,151 @@ +Index: grub-2.06/include/grub/tpm.h +=================================================================== +--- grub-2.06.orig/include/grub/tpm.h ++++ grub-2.06/include/grub/tpm.h +@@ -34,6 +34,15 @@ + + #define EV_IPL 0x0d + ++struct grub_tpm_digest { ++ const char * algorithm; ++ unsigned int size; ++ unsigned char value[1]; /* variable length */ ++}; ++ + grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size, + grub_uint8_t pcr, const char *description); ++struct grub_tpm_digest *grub_tpm_read_pcr (grub_uint8_t index, const char *algo); ++void grub_tpm_digest_free (struct grub_tpm_digest *d); ++ + #endif +Index: grub-2.06/grub-core/commands/efi/tpm.c +=================================================================== +--- grub-2.06.orig/grub-core/commands/efi/tpm.c ++++ grub-2.06/grub-core/commands/efi/tpm.c +@@ -23,6 +23,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -186,6 +187,91 @@ grub_tpm1_log_event (grub_efi_handle_t t + return grub_efi_log_event_status (status); + } + ++static void ++grub_tpm2_select_pcr(TPML_PCR_SELECTION *o, unsigned int pcrIndex, unsigned int algo) ++{ ++ TPMS_PCR_SELECTION *pcr; ++ ++ pcr = &o->pcrSelections[o->count++]; ++ pcr->hash = algo; ++ pcr->sizeOfSelect = 3; ++ pcr->pcrSelect[TPM2_PCR_TO_SELECT(pcrIndex)] |= TPM2_PCR_TO_BIT(pcrIndex); ++} ++ ++struct grub_tpm_hash_info { ++ const char *name; ++ grub_size_t size; ++ int id; ++}; ++ ++static const struct grub_tpm_hash_info * ++grub_tpm2_get_digest_info (const char *algo) ++{ ++ static struct grub_tpm_hash_info __hashes[] = { ++ { "sha256", 32, TPM_ALG_SHA256 }, /* first entry is the default */ ++ { "sha512", 64, TPM_ALG_SHA512 }, ++ { "sha1", 20, TPM_ALG_SHA1 }, ++ { NULL } ++ }; ++ struct grub_tpm_hash_info *h; ++ ++ if (algo == NULL) ++ return &__hashes[0]; ++ ++ for (h = __hashes; h->name; ++h) ++ if (!grub_strcmp(h->name, algo)) ++ return h; ++ ++ return NULL; ++} ++ ++static grub_err_t ++grub_tpm2_read_pcr (grub_int8_t pcrIndex, const char *algo, struct grub_tpm_digest **ret) ++{ ++ const struct grub_tpm_hash_info *info; ++ TPML_PCR_SELECTION inSelection, outSelection; ++ grub_uint32_t pcrUpdateCounter; ++ TPML_DIGEST digests = { 0 }; ++ TPM2B_DIGEST *d; ++ struct grub_tpm_digest *result; ++ int rc; ++ ++ info = grub_tpm2_get_digest_info (algo); ++ if (info == NULL) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Unknown digest algorithm %s"), algo); ++ ++ grub_memset(&inSelection, 0, sizeof(inSelection)); ++ grub_memset(&outSelection, 0, sizeof(outSelection)); ++ grub_tpm2_select_pcr(&inSelection, pcrIndex, info->id); ++ ++ rc = TPM2_PCR_Read( ++ NULL, ++ &inSelection, ++ &pcrUpdateCounter, ++ &outSelection, ++ &digests, ++ NULL ++ ); ++ ++ if (rc != 0) ++ return grub_error (GRUB_ERR_BAD_DEVICE, "TPM2_PCR_Read failed, status=%d", rc); ++ ++ d = &digests.digests[0]; ++ ++ *ret = result = grub_malloc (sizeof (*result) + d->size); ++ grub_memcpy (result->value, d->buffer, d->size); ++ result->algorithm = info->name; ++ result->size = d->size; ++ ++ return GRUB_ERR_NONE; ++} ++ ++void ++grub_tpm_digest_free (struct grub_tpm_digest *d) ++{ ++ grub_free (d); ++} ++ + static grub_err_t + grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, + grub_size_t size, grub_uint8_t pcr, +@@ -240,3 +326,26 @@ grub_tpm_measure (unsigned char *buf, gr + else + return grub_tpm2_log_event (tpm_handle, buf, size, pcr, description); + } ++ ++struct grub_tpm_digest * ++grub_tpm_read_pcr (grub_uint8_t pcr, const char *algo) ++{ ++ grub_efi_handle_t tpm_handle; ++ grub_efi_uint8_t protocol_version; ++ struct grub_tpm_digest *result = NULL; ++ ++ ++ if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) ++ return 0; ++ ++ if (protocol_version != 2) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, N_("%s: TPM version %d not implemented"), __func__, protocol_version); ++ return NULL; ++ } ++ ++ if (grub_tpm2_read_pcr (pcr, algo, &result)) ++ return NULL; ++ ++ return result; ++} diff --git a/grub-unseal-debug.patch b/grub-unseal-debug.patch new file mode 100644 index 0000000..2d9225b --- /dev/null +++ b/grub-unseal-debug.patch @@ -0,0 +1,41 @@ +Index: grub-2.06/grub-core/tpm2/module.c +=================================================================== +--- grub-2.06.orig/grub-core/tpm2/module.c ++++ grub-2.06/grub-core/tpm2/module.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -449,6 +450,7 @@ grub_tpm2_protector_srk_recover (const s + { + grub_error (err, N_("Failed to unseal sealed key (TPM2_Unseal failed " + "with TSS/TPM error %u)"), rc); ++ grub_millisleep(500); + goto exit4; + } + +@@ -461,6 +463,8 @@ grub_tpm2_protector_srk_recover (const s + goto exit4; + } + ++ grub_printf("TPM2: unsealed %u bytes of key material\n", data.size); ++ + if (ctx->efivar) + { + rc = grub_tpm2_protector_publish_key (data.buffer, data.size, ctx->efivar); +Index: grub-2.06/grub-core/loader/linux.c +=================================================================== +--- grub-2.06.orig/grub-core/loader/linux.c ++++ grub-2.06/grub-core/loader/linux.c +@@ -171,6 +171,7 @@ grub_initrd_component (const char *buf, + struct grub_linux_initrd_component *comp = initrd_ctx->components + initrd_ctx->nfiles; + grub_size_t dir_size, name_len; + ++ grub_printf("Creating initrd component \"%s\" with %u bytes\n", newc_name, bufsz); + while (*newc_name == '/') + newc_name++; + diff --git a/grub2.changes b/grub2.changes index f07f217..db4b4ba 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,59 @@ +------------------------------------------------------------------- +Mon Sep 19 04:07:36 UTC 2022 - Michael Chang + +- Add safety measure to pcr snapshot by checking platform and tpm status + * safe_tpm_pcr_snapshot.patch + +------------------------------------------------------------------- +Fri Sep 16 03:56:14 UTC 2022 - Michael Chang + +- Fix installation failure due to unavailable nvram device on + ppc64le (bsc#1201361) + * 0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch + +------------------------------------------------------------------- +Fri Sep 16 03:12:36 UTC 2022 - Gary Ching-Pang Lin + +- Add patches to dynamically allocate additional memory regions for + EFI systems (bsc#1202438) + * 0001-mm-Allow-dynamically-requesting-additional-memory-re.patch + * 0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch + * 0003-kern-efi-mm-Extract-function-to-add-memory-regions.patch + * 0004-kern-efi-mm-Pass-up-errors-from-add_memory_regions.patch + * 0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch +- Enlarge the default heap size and defer the disk cache + invalidation (bsc#1202438) + * 0001-kern-efi-mm-Enlarge-the-default-heap-size.patch + * 0002-mm-Defer-the-disk-cache-invalidation.patch + +------------------------------------------------------------------- +Thu Sep 15 09:51:07 UTC 2022 - Michael Chang + +- Add patches for ALP FDE support + * 0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch + * 0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch + * 0003-disk-cryptodisk-When-cheatmounting-use-the-sector-in.patch + * 0004-normal-menu-Don-t-show-Booting-s-msg-when-auto-booti.patch + * 0005-EFI-suppress-the-Welcome-to-GRUB-message-in-EFI-buil.patch + * 0006-EFI-console-Do-not-set-colorstate-until-the-first-te.patch + * 0007-EFI-console-Do-not-set-cursor-until-the-first-text-o.patch + * 0008-linuxefi-Use-common-grub_initrd_load.patch + * 0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch + * 0010-templates-import-etc-crypttab-to-grub.cfg.patch + * grub-read-pcr.patch + * efi-set-variable-with-attrs.patch + * tpm-record-pcrs.patch + * tpm-protector-dont-measure-sealed-key.patch + * tpm-protector-export-secret-key.patch + * grub-install-record-pcrs.patch + * grub-unseal-debug.patch + +------------------------------------------------------------------- +Mon Aug 29 03:48:55 UTC 2022 - Michael Chang + +- Fix out of memory error cannot be prevented via disabling tpm (bsc#1202438) + * 0001-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch + ------------------------------------------------------------------- Thu Aug 18 02:47:28 UTC 2022 - Michael Chang diff --git a/grub2.spec b/grub2.spec index 80f4f19..72705d6 100644 --- a/grub2.spec +++ b/grub2.spec @@ -423,6 +423,36 @@ Patch897: 0013-cryptodisk-Support-key-protectors.patch Patch898: 0014-util-grub-protect-Add-new-tool.patch Patch899: fix-tpm2-build.patch Patch900: 0001-crytodisk-fix-cryptodisk-module-looking-up.patch +# fde +Patch901: 0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch +Patch902: 0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch +Patch903: 0003-disk-cryptodisk-When-cheatmounting-use-the-sector-in.patch +Patch904: 0004-normal-menu-Don-t-show-Booting-s-msg-when-auto-booti.patch +Patch905: 0005-EFI-suppress-the-Welcome-to-GRUB-message-in-EFI-buil.patch +Patch906: 0006-EFI-console-Do-not-set-colorstate-until-the-first-te.patch +Patch907: 0007-EFI-console-Do-not-set-cursor-until-the-first-text-o.patch +Patch908: 0008-linuxefi-Use-common-grub_initrd_load.patch +Patch909: 0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch +Patch910: 0010-templates-import-etc-crypttab-to-grub.cfg.patch +Patch911: grub-read-pcr.patch +Patch912: efi-set-variable-with-attrs.patch +Patch913: tpm-record-pcrs.patch +Patch914: tpm-protector-dont-measure-sealed-key.patch +Patch915: tpm-protector-export-secret-key.patch +Patch916: grub-install-record-pcrs.patch +Patch917: grub-unseal-debug.patch +# efi mm +Patch918: 0001-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch +Patch919: 0001-mm-Allow-dynamically-requesting-additional-memory-re.patch +Patch920: 0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch +Patch921: 0003-kern-efi-mm-Extract-function-to-add-memory-regions.patch +Patch922: 0004-kern-efi-mm-Pass-up-errors-from-add_memory_regions.patch +Patch923: 0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch +Patch924: 0001-kern-efi-mm-Enlarge-the-default-heap-size.patch +Patch925: 0002-mm-Defer-the-disk-cache-invalidation.patch +# powerpc-ieee1275 +Patch926: 0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch +Patch927: safe_tpm_pcr_snapshot.patch Requires: gettext-runtime %if 0%{?suse_version} >= 1140 @@ -691,7 +721,7 @@ CD_MODULES="all_video boot cat configfile echo true \ password password_pbkdf2 png reboot search search_fs_uuid \ search_fs_file search_label sleep test video fat loadenv" PXE_MODULES="tftp http" -CRYPTO_MODULES="luks luks2 gcry_rijndael gcry_sha1 gcry_sha256 gcry_sha512" +CRYPTO_MODULES="luks luks2 gcry_rijndael gcry_sha1 gcry_sha256 gcry_sha512 crypttab" %ifarch %{efi} CD_MODULES="${CD_MODULES} chain efifwsetup efinet read tpm tpm2" PXE_MODULES="${PXE_MODULES} efinet" @@ -1214,6 +1244,7 @@ fi %dir %{_sysconfdir}/grub.d %{_sysconfdir}/grub.d/README %config(noreplace) %{_sysconfdir}/grub.d/00_header +%config(noreplace) %{_sysconfdir}/grub.d/05_crypttab %config(noreplace) %{_sysconfdir}/grub.d/10_linux %config(noreplace) %{_sysconfdir}/grub.d/20_linux_xen %config(noreplace) %{_sysconfdir}/grub.d/30_uefi-firmware diff --git a/safe_tpm_pcr_snapshot.patch b/safe_tpm_pcr_snapshot.patch new file mode 100644 index 0000000..388c1ef --- /dev/null +++ b/safe_tpm_pcr_snapshot.patch @@ -0,0 +1,90 @@ +--- + grub-core/commands/tpm.c | 28 ++++++++++++++++++++++------ + util/grub-install.c | 7 +++++-- + 2 files changed, 27 insertions(+), 8 deletions(-) + +--- a/grub-core/commands/tpm.c ++++ b/grub-core/commands/tpm.c +@@ -249,6 +249,8 @@ + return GRUB_ERR_NONE; + } + ++#ifdef GRUB_MACHINE_EFI ++ + static grub_err_t + grub_tpm_record_pcrs (grub_extcmd_context_t ctxt, int argc, char **args) + { +@@ -259,6 +261,10 @@ + grub_size_t size = 0; + int n, rv = 1; + ++ /* To prevent error: unable to read PCR from TPM, if no TPM device available */ ++ if (!grub_tpm_present()) ++ return GRUB_ERR_NONE; ++ + if (argc == 0) + pcr_bitmask = GRUB2_PCR_BITMASK_DEFAULT; + else +@@ -287,13 +293,24 @@ + return rv; + } + ++#else ++ ++static grub_err_t ++grub_tpm_record_pcrs (grub_extcmd_context_t ctxt __attribute__((unused)), ++ int argc __attribute__((unused)), ++ char **args __attribute__((unused))) ++{ ++ return GRUB_ERR_NONE; ++} ++ ++#endif ++ + static grub_extcmd_t cmd; + + GRUB_MOD_INIT (tpm) + { +- if (!grub_tpm_present()) +- return; +- grub_verifier_register (&grub_tpm_verifier); ++ if (grub_tpm_present()) ++ grub_verifier_register (&grub_tpm_verifier); + + cmd = grub_register_extcmd ("tpm_record_pcrs", grub_tpm_record_pcrs, 0, + N_("LIST_OF_PCRS"), +@@ -303,8 +320,7 @@ + + GRUB_MOD_FINI (tpm) + { +- if (!grub_tpm_present()) +- return; +- grub_verifier_unregister (&grub_tpm_verifier); ++ if (grub_tpm_present()) ++ grub_verifier_unregister (&grub_tpm_verifier); + grub_unregister_extcmd (cmd); + } +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -1457,8 +1457,10 @@ + + grub_util_unlink (load_cfg); + +- if (1) ++ /* FIXME: It seems config.is_cryptodisk_enabled is missing here */ ++ if (platform == GRUB_INSTALL_PLATFORM_X86_64_EFI) + { ++ grub_install_push_module ("tpm"); + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + fprintf (load_cfg_f, "tpm_record_pcrs 0-9\n"); +@@ -1466,7 +1468,8 @@ + + if (debug_image && debug_image[0]) + { +- load_cfg_f = grub_util_fopen (load_cfg, "wb"); ++ if (!load_cfg_f) ++ load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + fprintf (load_cfg_f, "set debug='%s'\n", + debug_image); diff --git a/tpm-protector-dont-measure-sealed-key.patch b/tpm-protector-dont-measure-sealed-key.patch new file mode 100644 index 0000000..8357e74 --- /dev/null +++ b/tpm-protector-dont-measure-sealed-key.patch @@ -0,0 +1,15 @@ +Index: grub-2.06/grub-core/tpm2/module.c +=================================================================== +--- grub-2.06.orig/grub-core/tpm2/module.c ++++ grub-2.06/grub-core/tpm2/module.c +@@ -139,7 +139,9 @@ grub_tpm2_protector_srk_read_keyfile (co + void *sealed_key_buffer; + grub_off_t sealed_key_read; + +- sealed_key_file = grub_file_open (filepath, GRUB_FILE_TYPE_NONE); ++ /* Using GRUB_FILE_TYPE_SIGNATURE ensures we do not hash the keyfile into PCR9 ++ * otherwise we'll never be able to predict the value of PCR9 at unseal time */ ++ sealed_key_file = grub_file_open (filepath, GRUB_FILE_TYPE_SIGNATURE); + if (!sealed_key_file) + { + grub_dprintf ("tpm2", "Could not open sealed key file.\n"); diff --git a/tpm-protector-export-secret-key.patch b/tpm-protector-export-secret-key.patch new file mode 100644 index 0000000..70eb493 --- /dev/null +++ b/tpm-protector-export-secret-key.patch @@ -0,0 +1,138 @@ +Index: grub-2.06/grub-core/tpm2/module.c +=================================================================== +--- grub-2.06.orig/grub-core/tpm2/module.c ++++ grub-2.06/grub-core/tpm2/module.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -46,6 +47,7 @@ struct grub_tpm2_protector_context + const char *keyfile; + TPM_HANDLE srk; + TPM_HANDLE nv; ++ const char *efivar; + }; + + static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] = +@@ -122,6 +124,16 @@ static const struct grub_arg_option grub + N_("Required in NV Index mode, the NV handle to read which must " + "readily exist on the TPM and which contains the key."), + }, ++ /* When publishing the unsealed key to a UEFI variable */ ++ { ++ .longarg = "efivar", ++ .shortarg = 'E', ++ .flags = 0, ++ .arg = NULL, ++ .type = ARG_TYPE_STRING, ++ .doc = ++ N_("Publish the unsealed key to the indicated UEFI variable."), ++ }, + /* End of list */ + {0, 0, 0, 0, 0, 0} + }; +@@ -302,6 +314,34 @@ grub_tpm2_protector_srk_get (const struc + } + + static grub_err_t ++grub_tpm2_protector_publish_key (grub_uint8_t *key, grub_size_t key_size, ++ const char *var_name) ++{ ++ grub_efi_guid_t vendor_guid = { 0x58aca851, 0x8af7, 0x4738, { 0xa5, 0x42, 0x26, 0x6e, 0x21, 0xf5, 0xca, 0xd9 }}; ++ grub_uint8_t *tmp_key; ++ grub_err_t err; ++ ++ /* It appears that EFI's set_var function overwrites the key. */ ++ tmp_key = grub_malloc (key_size); ++ if (!tmp_key) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("No memory left to allocate temporary key buffer")); ++ return GRUB_ERR_OUT_OF_MEMORY; ++ } ++ ++ grub_memcpy(tmp_key, key, key_size); ++ ++ err = grub_efi_set_variable_with_attributes(var_name, &vendor_guid, ++ GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | GRUB_EFI_VARIABLE_RUNTIME_ACCESS, ++ tmp_key, key_size); ++ if (err) ++ grub_error (err, N_("Failed to export LUKS key as EFI variable %s"), var_name); ++ ++ grub_free (tmp_key); ++ return err; ++} ++ ++static grub_err_t + grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx, + grub_uint8_t **key, grub_size_t *key_size) + { +@@ -421,6 +461,13 @@ grub_tpm2_protector_srk_recover (const s + goto exit4; + } + ++ if (ctx->efivar) ++ { ++ rc = grub_tpm2_protector_publish_key (data.buffer, data.size, ctx->efivar); ++ if (rc) ++ goto exit4; ++ } ++ + grub_memcpy (key_out, data.buffer, data.size); + + *key = key_out; +@@ -549,20 +596,32 @@ grub_tpm2_protector_check_args (struct g + } + + static grub_err_t +-grub_tpm2_protector_parse_keyfile (const char *value, const char **keyfile) ++grub_tpm2_protector_parse_string (const char *value, const char **var, const char *arg_name) + { + if (grub_strlen (value) == 0) + return GRUB_ERR_BAD_ARGUMENT; + +- *keyfile = grub_strdup (value); +- if (!*keyfile) ++ *var = grub_strdup (value); ++ if (!*var) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, +- N_("No memory to duplicate keyfile path")); ++ N_("No memory to duplicate %s argument"), arg_name); + + return GRUB_ERR_NONE; + } + + static grub_err_t ++grub_tpm2_protector_parse_keyfile (const char *value, const char **keyfile) ++{ ++ return grub_tpm2_protector_parse_string (value, keyfile, "keyfile"); ++} ++ ++static grub_err_t ++grub_tpm2_protector_parse_efivar (const char *value, const char **efivar) ++{ ++ return grub_tpm2_protector_parse_string (value, efivar, "efivar"); ++} ++ ++static grub_err_t + grub_tpm2_protector_parse_mode (const char *value, + grub_tpm2_protector_mode_t *mode) + { +@@ -650,6 +709,14 @@ grub_tpm2_protector_init_cmd_handler (gr + if (err) + return err; + } ++ ++ if (state[7].set) /* efivar */ ++ { ++ err = grub_tpm2_protector_parse_efivar (state[7].arg, ++ &grub_tpm2_protector_ctx.efivar); ++ if (err) ++ return err; ++ } + + err = grub_tpm2_protector_check_args (&grub_tpm2_protector_ctx); + diff --git a/tpm-record-pcrs.patch b/tpm-record-pcrs.patch new file mode 100644 index 0000000..4dde858 --- /dev/null +++ b/tpm-record-pcrs.patch @@ -0,0 +1,235 @@ +Index: grub-2.06/grub-core/commands/tpm.c +=================================================================== +--- grub-2.06.orig/grub-core/commands/tpm.c ++++ grub-2.06/grub-core/commands/tpm.c +@@ -26,6 +26,9 @@ + #include + #include + #include ++#include ++#include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -84,12 +87,220 @@ struct grub_file_verifier grub_tpm_verif + .verify_string = grub_tpm_verify_string, + }; + ++/* ++ * Preserve current PCR values and record them to an EFI variable ++ */ ++#define GRUB2_PCR_BITMASK_DEFAULT ((1 << 16) - 1) ++#define GRUB2_PCR_BITMASK_ALL ((1 << 24) - 1) ++ ++static const struct grub_arg_option grub_tpm_record_pcrs_options[] = ++ { ++ { ++ .longarg = "efivar", ++ .shortarg = 'E', ++ .flags = 0, ++ .arg = NULL, ++ .type = ARG_TYPE_STRING, ++ .doc = ++ N_("The EFI variable to publish the PCRs to (default GrubPcrSnapshot)"), ++ }, ++ ++ {0, 0, 0, 0, 0, 0} ++ }; ++ ++static grub_err_t ++grub_tpm_parse_pcr_index (const char *word, const char **end_ret, unsigned int *index) ++{ ++ const char *end; ++ ++ if (!grub_isdigit (word[0])) ++ return GRUB_ERR_BAD_NUMBER; ++ ++ *index = grub_strtoul(word, &end, 0); ++ if (*index > 32) ++ return GRUB_ERR_BAD_NUMBER; ++ ++ *end_ret = end; ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm_parse_pcr_list (const char *arg, grub_uint32_t *bitmask) ++{ ++ const char *word, *end; ++ unsigned int index, last_index; ++ ++ if (!grub_strcmp (arg, "all")) ++ { ++ *bitmask = GRUB2_PCR_BITMASK_ALL; ++ return GRUB_ERR_NONE; ++ } ++ ++ word = arg; ++ while (1) ++ { ++ if (grub_tpm_parse_pcr_index (word, &end, &index)) ++ goto bad_pcr_index; ++ ++ if (*end == '-') ++ { ++ if (grub_tpm_parse_pcr_index (end + 1, &end, &last_index) || last_index < index) ++ goto bad_pcr_index; ++ ++ while (index <= last_index) ++ *bitmask |= (1 << (index++)); ++ } ++ else ++ *bitmask |= (1 << index); ++ ++ if (*end == '\0') ++ break; ++ ++ if (*end != ',') ++ goto bad_pcr_index; ++ ++ word = end + 1; ++ } ++ ++ return GRUB_ERR_NONE; ++ ++bad_pcr_index: ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot parse PCR list \"%s\""), arg); ++} ++ ++static inline unsigned int ++nbits(grub_uint32_t mask) ++{ ++ unsigned int r = 0; ++ ++ for (; mask != 0; mask >>= 1) ++ r += (mask & 1); ++ return r; ++} ++ ++static grub_err_t ++grub_tpm_snapshot_pcrs (grub_uint32_t pcr_bitmask, const char *algo, ++ void **buffer_ret, grub_size_t *size_ret) ++{ ++ char *buffer; ++ grub_size_t size = 65536; ++ unsigned int wpos = 0; ++ grub_uint8_t pcr; ++ ++ buffer = grub_malloc (size); ++ for (pcr = 0; pcr < 32; ++pcr) ++ { ++ struct grub_tpm_digest *d; ++ unsigned int need, k; ++ ++ if (!(pcr_bitmask & (1 << pcr))) ++ continue; ++ ++ d = grub_tpm_read_pcr (pcr, algo); ++ if (d == NULL) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, N_("unable to read PCR %d from TPM"), pcr); ++ continue; ++ } ++ ++ /* We need room for the PCR index, 2 spaces, newline, NUL. 16 should be enough. */ ++ need = 16 + grub_strlen(d->algorithm) + 2 * d->size; ++ if (wpos + need > size) ++ { ++ buffer = grub_realloc (buffer, size + need); ++ if (buffer == NULL) ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("Not enough memory when dumping PCR registers")); ++ } ++ ++ grub_snprintf (buffer + wpos, size - wpos, "%02d %s ", pcr, d->algorithm); ++ wpos = grub_strlen(buffer); ++ ++ for (k = 0; k < d->size; ++k) ++ { ++ grub_snprintf (buffer + wpos, size - wpos, "%02x", d->value[k]); ++ wpos += 2; ++ } ++ ++ buffer[wpos++] = '\n'; ++ buffer[wpos] = '\0'; ++ ++ grub_tpm_digest_free (d); ++ } ++ ++ *buffer_ret = buffer; ++ *size_ret = wpos; ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm_write_pcrs_to_efi (void *data, grub_size_t size, const char *var_name) ++{ ++ grub_efi_guid_t vendor_guid = { 0x7ce323f2, 0xb841, 0x4d30, { 0xa0, 0xe9, 0x54, 0x74, 0xa7, 0x6c, 0x9a, 0x3f }}; ++ grub_err_t rc; ++ ++ rc = grub_efi_set_variable_with_attributes(var_name, &vendor_guid, ++ GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | GRUB_EFI_VARIABLE_RUNTIME_ACCESS, ++ data, size); ++ ++ if (rc) ++ return grub_error (GRUB_ERR_BAD_DEVICE, N_("Failed to publish PCR snapshot to UEFI variable %s"), var_name); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm_record_pcrs (grub_extcmd_context_t ctxt, int argc, char **args) ++{ ++ struct grub_arg_list *state = ctxt->state; ++ grub_uint32_t pcr_bitmask = 0; ++ const char *efivar; ++ void *buffer = NULL; ++ grub_size_t size = 0; ++ int n, rv = 1; ++ ++ if (argc == 0) ++ pcr_bitmask = GRUB2_PCR_BITMASK_DEFAULT; ++ else ++ { ++ for (n = 0; n < argc; ++n) ++ if (grub_tpm_parse_pcr_list (args[n], &pcr_bitmask)) ++ return 1; ++ } ++ ++ if (grub_tpm_snapshot_pcrs (pcr_bitmask, NULL, &buffer, &size)) ++ goto out; ++ ++ if (state[0].set) ++ efivar = state[0].arg; ++ else ++ efivar = "GrubPcrSnapshot"; ++ ++ if (grub_tpm_write_pcrs_to_efi (buffer, size, efivar)) ++ goto out; ++ ++ rv = 0; ++ ++out: ++ if (buffer) ++ grub_free (buffer); ++ return rv; ++} ++ ++static grub_extcmd_t cmd; ++ + GRUB_MOD_INIT (tpm) + { + grub_verifier_register (&grub_tpm_verifier); ++ ++ cmd = grub_register_extcmd ("tpm_record_pcrs", grub_tpm_record_pcrs, 0, ++ N_("LIST_OF_PCRS"), ++ N_("Snapshot one or more PCR values and record them in an EFI variable."), ++ grub_tpm_record_pcrs_options); + } + + GRUB_MOD_FINI (tpm) + { + grub_verifier_unregister (&grub_tpm_verifier); ++ grub_unregister_extcmd (cmd); + } From 59128383263a6ccd39389b6b286a31cad122b0deb1fa2a737318634bf60f5eff Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Wed, 28 Sep 2022 02:40:56 +0000 Subject: [PATCH 2/6] Accepting request 1006353 from home:michael-chang:branches:Base:System - Add patch to fix kernel relocation error in low memory * 0001-linux-fix-efi_relocate_kernel-failure.patch OBS-URL: https://build.opensuse.org/request/show/1006353 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=420 --- ...inux-fix-efi_relocate_kernel-failure.patch | 182 ++++++++++++++++++ grub2.changes | 6 + grub2.spec | 1 + 3 files changed, 189 insertions(+) create mode 100644 0001-linux-fix-efi_relocate_kernel-failure.patch diff --git a/0001-linux-fix-efi_relocate_kernel-failure.patch b/0001-linux-fix-efi_relocate_kernel-failure.patch new file mode 100644 index 0000000..33541ff --- /dev/null +++ b/0001-linux-fix-efi_relocate_kernel-failure.patch @@ -0,0 +1,182 @@ +From 80487d82ee1c179c01fad1a23f26fcca79c0ace5 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Mon, 26 Sep 2022 12:04:41 +0800 +Subject: [PATCH] linux: fix efi_relocate_kernel failure + +With the dynamic allocated heap in new memory manager, it could use up all +usable memory with no reservation on subsequent kernel loading leading to +following error: + + EFI stub: ERROR: Failed to allocate usable memory for kernel + EFI stub: ERROR: efi_relocate_kernel() failed! + EFI stub: ERROR: efi_main failed! + +The patch tries to returning the memory pages allocated by grub to the firmware +before handing over to linux kernel. This could eliminate the worry that we +have no limited amount of memory exclusively set for grub to guarentee the +memory requirement for booting subsequent component can be met. + +Signed-off-by: Michael Chang +--- + grub-core/Makefile.am | 7 +++++++ + grub-core/Makefile.core.def | 2 +- + grub-core/loader/efi/linux.c | 16 ++++++++++++++++ + grub-core/loader/i386/efi/linux.c | 13 ++++++++++--- + 4 files changed, 34 insertions(+), 4 deletions(-) + +diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am +index dc07ba6f8..3b1f101fd 100644 +--- a/grub-core/Makefile.am ++++ b/grub-core/Makefile.am +@@ -124,6 +124,7 @@ if COND_i386_efi + KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h +@@ -185,6 +186,7 @@ if COND_x86_64_efi + KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/pci.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h +@@ -194,6 +196,7 @@ endif + if COND_ia64_efi + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h + endif + +@@ -281,6 +284,7 @@ endif + if COND_arm_efi + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/arm/system.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h + endif +@@ -288,18 +292,21 @@ endif + if COND_arm64_efi + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h + endif + + if COND_riscv32_efi + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h + endif + + if COND_riscv64_efi + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/linux.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h + endif + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 211d2166b..a8c5684dd 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -392,6 +392,7 @@ kernel = { + extra_dist = kern/i386/realmode.S; + extra_dist = boot/i386/pc/lzma_decode.S; + extra_dist = kern/mips/cache_flush.S; ++ efi = loader/efi/linux.c; + }; + + program = { +@@ -1855,7 +1856,6 @@ module = { + riscv64 = loader/riscv/linux.c; + emu = loader/emu/linux.c; + common = loader/linux.c; +- efi = loader/efi/linux.c; + }; + + module = { +diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c +index 9265cf420..6ee0ca966 100644 +--- a/grub-core/loader/efi/linux.c ++++ b/grub-core/loader/efi/linux.c +@@ -23,6 +23,8 @@ + #include + #include + #include ++#include ++#include + + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wcast-align" +@@ -38,6 +40,8 @@ grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset, + int offset = 0; + + #ifdef __x86_64__ ++ grub_efi_simple_text_output_interface_t *o; ++ o = grub_efi_system_table->con_out; + offset = 512; + #endif + +@@ -55,9 +59,21 @@ grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset, + grub_dprintf ("linux", "kernel_addr: %p handover_offset: %p params: %p\n", + kernel_addr, (void *)(grub_efi_uintn_t)handover_offset, kernel_params); + hf = (handover_func)((char *)kernel_addr + handover_offset + offset); ++#ifdef __x86_64__ ++ grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); ++#endif + hf (grub_efi_image_handle, grub_efi_system_table, kernel_params); + ++#ifdef __x86_64__ ++ efi_call_2 (o->output_string, o, L"cannot boot linux kernel via efi handover\r\n" ++ L"rebooting in 5 seconds... *\r\n"); ++ efi_call_1 (grub_efi_system_table->boot_services->stall, 5000000); ++ efi_call_4 (grub_efi_system_table->runtime_services->reset_system, ++ GRUB_EFI_RESET_COLD, GRUB_EFI_SUCCESS, 0, NULL); ++ for (;;) ; ++#else + return GRUB_ERR_BUG; ++#endif + } + + #pragma GCC diagnostic pop +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c +index 6b06a8f2f..b9b0d4a5f 100644 +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -90,6 +90,8 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) + { + grub_uint64_t max = max_addresses[i].addr; + grub_efi_uintn_t pages; ++ grub_efi_status_t status; ++ grub_efi_boot_services_t *b; + + /* + * When we're *not* loading the kernel, or >4GB allocations aren't +@@ -104,9 +106,14 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) + pages, (void *)(grub_addr_t)max); + + prev_max = max; +- addr = grub_efi_allocate_pages_real (max, pages, +- max_addresses[i].alloc_type, +- GRUB_EFI_LOADER_DATA); ++ b = grub_efi_system_table->boot_services; ++ status = efi_call_4 (b->allocate_pages, max_addresses[i].alloc_type, GRUB_EFI_LOADER_DATA, pages, &max); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ max = 0; ++ } ++ addr = (void *) ((grub_addr_t) max); + if (addr) + grub_dprintf ("linux", "Allocated at %p\n", addr); + } +-- +2.37.3 + diff --git a/grub2.changes b/grub2.changes index db4b4ba..ce1b380 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Sep 23 10:13:54 UTC 2022 - Michael Chang + +- Add patch to fix kernel relocation error in low memory + * 0001-linux-fix-efi_relocate_kernel-failure.patch + ------------------------------------------------------------------- Mon Sep 19 04:07:36 UTC 2022 - Michael Chang diff --git a/grub2.spec b/grub2.spec index 72705d6..dc86684 100644 --- a/grub2.spec +++ b/grub2.spec @@ -453,6 +453,7 @@ Patch925: 0002-mm-Defer-the-disk-cache-invalidation.patch # powerpc-ieee1275 Patch926: 0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch Patch927: safe_tpm_pcr_snapshot.patch +Patch928: 0001-linux-fix-efi_relocate_kernel-failure.patch Requires: gettext-runtime %if 0%{?suse_version} >= 1140 From 90fcdec2e437e7357a8775b17954a83fadf5a8ed9c097f286a217b5437dbc0b1 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Tue, 4 Oct 2022 06:01:45 +0000 Subject: [PATCH 3/6] Accepting request 1007215 from home:michael-chang:tmp Added minor fix to safe_tpm_pcr_snapshot.patch OBS-URL: https://build.opensuse.org/request/show/1007215 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=421 --- safe_tpm_pcr_snapshot.patch | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/safe_tpm_pcr_snapshot.patch b/safe_tpm_pcr_snapshot.patch index 388c1ef..1a79db8 100644 --- a/safe_tpm_pcr_snapshot.patch +++ b/safe_tpm_pcr_snapshot.patch @@ -1,7 +1,7 @@ --- grub-core/commands/tpm.c | 28 ++++++++++++++++++++++------ - util/grub-install.c | 7 +++++-- - 2 files changed, 27 insertions(+), 8 deletions(-) + util/grub-install.c | 6 ++++-- + 2 files changed, 26 insertions(+), 8 deletions(-) --- a/grub-core/commands/tpm.c +++ b/grub-core/commands/tpm.c @@ -66,19 +66,18 @@ } --- a/util/grub-install.c +++ b/util/grub-install.c -@@ -1457,8 +1457,10 @@ +@@ -1457,8 +1457,9 @@ grub_util_unlink (load_cfg); - if (1) -+ /* FIXME: It seems config.is_cryptodisk_enabled is missing here */ -+ if (platform == GRUB_INSTALL_PLATFORM_X86_64_EFI) ++ if (platform == GRUB_INSTALL_PLATFORM_X86_64_EFI && have_cryptodisk) { + grub_install_push_module ("tpm"); load_cfg_f = grub_util_fopen (load_cfg, "wb"); have_load_cfg = 1; fprintf (load_cfg_f, "tpm_record_pcrs 0-9\n"); -@@ -1466,7 +1468,8 @@ +@@ -1466,7 +1467,8 @@ if (debug_image && debug_image[0]) { From 3c95b540391f93cc5cf4e57d04d46fcdafc578e7ffe49725f5947d55922106c1 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Thu, 6 Oct 2022 08:48:42 +0000 Subject: [PATCH 4/6] Accepting request 1008353 from home:michael-chang:bsc:1204037 - Fix firmware oops after disk decrypting failure (bsc#1204037) * 0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch OBS-URL: https://build.opensuse.org/request/show/1008353 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=422 --- ...ry-to-obviate-the-need-to-input-pass.patch | 66 ++++++++----------- grub2.changes | 6 ++ 2 files changed, 34 insertions(+), 38 deletions(-) diff --git a/0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch b/0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch index 72716fd..f0fef49 100644 --- a/0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch +++ b/0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch @@ -21,19 +21,17 @@ can also be used multiple times to specify encrypted volumes unlocked by Signed-off-by: Michael Chang --- - grub-core/Makefile.core.def | 5 ++ - grub-core/commands/crypttab.c | 42 ++++++++++++ - grub-core/disk/cryptodisk.c | 5 ++ - grub-core/loader/linux.c | 126 ++++++++++++++++++++++++++++++++-- - include/grub/linux.h | 3 + - 5 files changed, 177 insertions(+), 4 deletions(-) + grub-core/Makefile.core.def | 5 + + grub-core/commands/crypttab.c | 42 ++++++++++++ + grub-core/disk/cryptodisk.c | 6 + + grub-core/loader/linux.c | 137 ++++++++++++++++++++++++++++++++++++++++-- + include/grub/linux.h | 3 + 5 files changed, 188 insertions(+), 5 deletions(-) create mode 100644 grub-core/commands/crypttab.c -Index: grub-2.06/grub-core/Makefile.core.def -=================================================================== ---- grub-2.06.orig/grub-core/Makefile.core.def -+++ grub-2.06/grub-core/Makefile.core.def -@@ -2643,3 +2643,8 @@ module = { +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -2643,3 +2643,8 @@ cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)'; }; @@ -42,10 +40,8 @@ Index: grub-2.06/grub-core/Makefile.core.def + name = crypttab; + common = commands/crypttab.c; +}; -Index: grub-2.06/grub-core/commands/crypttab.c -=================================================================== --- /dev/null -+++ grub-2.06/grub-core/commands/crypttab.c ++++ b/grub-core/commands/crypttab.c @@ -0,0 +1,42 @@ + +#include @@ -89,10 +85,8 @@ Index: grub-2.06/grub-core/commands/crypttab.c +{ + grub_unregister_command (cmd); +} -Index: grub-2.06/grub-core/disk/cryptodisk.c -=================================================================== ---- grub-2.06.orig/grub-core/disk/cryptodisk.c -+++ grub-2.06/grub-core/disk/cryptodisk.c +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c @@ -30,6 +30,8 @@ #ifdef GRUB_UTIL @@ -102,21 +96,19 @@ Index: grub-2.06/grub-core/disk/cryptodisk.c #endif GRUB_MOD_LICENSE ("GPLv3+"); -@@ -1146,6 +1148,10 @@ grub_cryptodisk_scan_device_real (const +@@ -1146,6 +1148,10 @@ dev = NULL; cleanup: +#ifndef GRUB_UTIL -+ if (cargs->key_data) ++ if (cargs->key_data && dev) + grub_initrd_publish_key (dev->uuid, (const char *)cargs->key_data, cargs->key_len, NULL); +#endif if (askpass) { cargs->key_len = 0; -Index: grub-2.06/grub-core/loader/linux.c -=================================================================== ---- grub-2.06.orig/grub-core/loader/linux.c -+++ grub-2.06/grub-core/loader/linux.c +--- a/grub-core/loader/linux.c ++++ b/grub-core/loader/linux.c @@ -5,6 +5,7 @@ #include #include @@ -125,7 +117,7 @@ Index: grub-2.06/grub-core/loader/linux.c struct newc_head { -@@ -27,6 +28,7 @@ struct newc_head +@@ -27,6 +28,7 @@ struct grub_linux_initrd_component { grub_file_t file; @@ -133,7 +125,7 @@ Index: grub-2.06/grub-core/loader/linux.c char *newc_name; grub_off_t size; }; -@@ -38,6 +40,18 @@ struct dir +@@ -38,6 +40,18 @@ struct dir *child; }; @@ -152,7 +144,7 @@ Index: grub-2.06/grub-core/loader/linux.c static char hex (grub_uint8_t val) { -@@ -149,6 +163,65 @@ insert_dir (const char *name, struct dir +@@ -149,6 +163,65 @@ return GRUB_ERR_NONE; } @@ -218,7 +210,7 @@ Index: grub-2.06/grub-core/loader/linux.c grub_err_t grub_initrd_init (int argc, char *argv[], struct grub_linux_initrd_context *initrd_ctx) -@@ -156,11 +229,17 @@ grub_initrd_init (int argc, char *argv[] +@@ -156,11 +229,17 @@ int i; int newc = 0; struct dir *root = 0; @@ -237,7 +229,7 @@ Index: grub-2.06/grub-core/loader/linux.c if (!initrd_ctx->components) return grub_errno; -@@ -239,7 +318,10 @@ grub_initrd_init (int argc, char *argv[] +@@ -239,7 +318,10 @@ free_dir (root); root = 0; } @@ -249,7 +241,7 @@ Index: grub-2.06/grub-core/loader/linux.c return GRUB_ERR_NONE; overflow: -@@ -263,7 +345,9 @@ grub_initrd_close (struct grub_linux_ini +@@ -263,7 +345,9 @@ for (i = 0; i < initrd_ctx->nfiles; i++) { grub_free (initrd_ctx->components[i].newc_name); @@ -260,7 +252,7 @@ Index: grub-2.06/grub-core/loader/linux.c } grub_free (initrd_ctx->components); initrd_ctx->components = 0; -@@ -297,7 +381,7 @@ grub_initrd_load (struct grub_linux_init +@@ -297,7 +381,7 @@ } ptr += dir_size; ptr = make_header (ptr, initrd_ctx->components[i].newc_name, @@ -269,7 +261,7 @@ Index: grub-2.06/grub-core/loader/linux.c 0100777, initrd_ctx->components[i].size); newc = 1; -@@ -312,7 +396,12 @@ grub_initrd_load (struct grub_linux_init +@@ -312,7 +396,12 @@ } cursize = initrd_ctx->components[i].size; @@ -283,7 +275,7 @@ Index: grub-2.06/grub-core/loader/linux.c != cursize) { if (!grub_errno) -@@ -333,3 +422,41 @@ grub_initrd_load (struct grub_linux_init +@@ -333,3 +422,41 @@ root = 0; return GRUB_ERR_NONE; } @@ -325,11 +317,9 @@ Index: grub-2.06/grub-core/loader/linux.c + + return GRUB_ERR_NONE; +} -Index: grub-2.06/include/grub/linux.h -=================================================================== ---- grub-2.06.orig/include/grub/linux.h -+++ grub-2.06/include/grub/linux.h -@@ -22,3 +22,6 @@ grub_initrd_close (struct grub_linux_ini +--- a/include/grub/linux.h ++++ b/include/grub/linux.h +@@ -22,3 +22,6 @@ grub_err_t grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, char *argv[], void *target); diff --git a/grub2.changes b/grub2.changes index ce1b380..9443c83 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Thu Oct 6 07:13:23 UTC 2022 - Michael Chang + +- Fix firmware oops after disk decrypting failure (bsc#1204037) + * 0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch + ------------------------------------------------------------------- Fri Sep 23 10:13:54 UTC 2022 - Michael Chang From eb7c39ad64fbe02fac4c0506c554cac38b7a26fc50b31b0d281f9129b31f3f11 Mon Sep 17 00:00:00 2001 From: Dirk Mueller Date: Mon, 24 Oct 2022 11:44:15 +0000 Subject: [PATCH 5/6] Accepting request 1030619 from home:michael-chang:ped:2150 - Include loopback into signed grub2 image (jsc#PED-2150) OBS-URL: https://build.opensuse.org/request/show/1030619 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=423 --- grub2.changes | 5 +++++ grub2.spec | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/grub2.changes b/grub2.changes index 9443c83..c9a1830 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,8 @@ +------------------------------------------------------------------- +Mon Oct 24 01:58:08 UTC 2022 - Michael Chang + +- Include loopback into signed grub2 image (jsc#PED-2150) + ------------------------------------------------------------------- Thu Oct 6 07:13:23 UTC 2022 - Michael Chang diff --git a/grub2.spec b/grub2.spec index dc86684..153dfb6 100644 --- a/grub2.spec +++ b/grub2.spec @@ -720,7 +720,7 @@ CD_MODULES="all_video boot cat configfile echo true \ font gfxmenu gfxterm gzio halt iso9660 \ jpeg minicmd normal part_apple part_msdos part_gpt \ password password_pbkdf2 png reboot search search_fs_uuid \ - search_fs_file search_label sleep test video fat loadenv" + search_fs_file search_label sleep test video fat loadenv loopback" PXE_MODULES="tftp http" CRYPTO_MODULES="luks luks2 gcry_rijndael gcry_sha1 gcry_sha256 gcry_sha512 crypttab" %ifarch %{efi} From 61a62ea9894f41d9f6971db792870252042fc490693a056ea32577159c721d68 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Tue, 1 Nov 2022 04:59:50 +0000 Subject: [PATCH 6/6] Accepting request 1032365 from home:michael-chang:15sp5 - NVMeoFC support on grub (jsc#PED-996) * 0001-ieee1275-add-support-for-NVMeoFC.patch * 0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch * 0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch * 0004-ofpath-controller-name-update.patch - TDX: Enhance grub2 measurement to TD RTMR (jsc#PED-1265) * 0001-commands-efi-tpm-Refine-the-status-of-log-event.patch * 0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch * 0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch - Measure the kernel on POWER10 and extend TPM PCRs (PED-1990) * 0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch * 0002-ieee1275-implement-vec5-for-cas-negotiation.patch - Fix efi pcr snapshot related funtion is defined but not used on powerpc platform. * safe_tpm_pcr_snapshot.patch OBS-URL: https://build.opensuse.org/request/show/1032365 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=424 --- ...i-tpm-Refine-the-status-of-log-event.patch | 39 ++ ...ort-for-trusted-boot-using-a-vTPM-2..patch | 239 +++++++++++ 0001-ieee1275-add-support-for-NVMeoFC.patch | 250 ++++++++++++ ...-Use-grub_strcpy-instead-of-grub_mem.patch | 40 ++ ...5-implement-vec5-for-cas-negotiation.patch | 73 ++++ ...enable-NVMeoF-logical-device-transla.patch | 373 ++++++++++++++++++ ...-EFI_CC_MEASUREMENT_PROTOCOL-support.patch | 260 ++++++++++++ ...ge-the-logic-of-ieee1275_get_devargs.patch | 62 +++ 0004-ofpath-controller-name-update.patch | 28 ++ grub2.changes | 19 + grub2.spec | 12 + safe_tpm_pcr_snapshot.patch | 58 ++- 12 files changed, 1442 insertions(+), 11 deletions(-) create mode 100644 0001-commands-efi-tpm-Refine-the-status-of-log-event.patch create mode 100644 0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch create mode 100644 0001-ieee1275-add-support-for-NVMeoFC.patch create mode 100644 0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch create mode 100644 0002-ieee1275-implement-vec5-for-cas-negotiation.patch create mode 100644 0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch create mode 100644 0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch create mode 100644 0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch create mode 100644 0004-ofpath-controller-name-update.patch diff --git a/0001-commands-efi-tpm-Refine-the-status-of-log-event.patch b/0001-commands-efi-tpm-Refine-the-status-of-log-event.patch new file mode 100644 index 0000000..c284274 --- /dev/null +++ b/0001-commands-efi-tpm-Refine-the-status-of-log-event.patch @@ -0,0 +1,39 @@ +From d2c0426b3f0f91b941037263c83859a46ebb0c4f Mon Sep 17 00:00:00 2001 +From: Lu Ken +Date: Wed, 13 Jul 2022 10:06:10 +0800 +Subject: [PATCH 1/3] commands/efi/tpm: Refine the status of log event + +1. Use macro GRUB_ERR_NONE instead of hard code 0. +2. Keep lowercase of the first char for the status string of log event. + +Signed-off-by: Lu Ken +Reviewed-by: Daniel Kiper +--- + grub-core/commands/efi/tpm.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c +index f296b8698..19737b462 100644 +--- a/grub-core/commands/efi/tpm.c ++++ b/grub-core/commands/efi/tpm.c +@@ -136,13 +136,13 @@ grub_efi_log_event_status (grub_efi_status_t status) + switch (status) + { + case GRUB_EFI_SUCCESS: +- return 0; ++ return GRUB_ERR_NONE; + case GRUB_EFI_DEVICE_ERROR: +- return grub_error (GRUB_ERR_IO, N_("Command failed")); ++ return grub_error (GRUB_ERR_IO, N_("command failed")); + case GRUB_EFI_INVALID_PARAMETER: +- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("invalid parameter")); + case GRUB_EFI_BUFFER_TOO_SMALL: +- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Output buffer too small")); ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("output buffer too small")); + case GRUB_EFI_NOT_FOUND: + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("TPM unavailable")); + default: +-- +2.35.3 + diff --git a/0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch b/0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch new file mode 100644 index 0000000..f3f26ea --- /dev/null +++ b/0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch @@ -0,0 +1,239 @@ +From f86bd28391e6d92f8084f0b789ba4a8f6d789dfa Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Sun, 15 Mar 2020 12:37:10 -0400 +Subject: [PATCH 1/2] ibmvtpm: Add support for trusted boot using a vTPM 2.0 + +Add support for trusted boot using a vTPM 2.0 on the IBM IEEE1275 +PowerPC platform. With this patch grub now measures text and binary data +into the TPM's PCRs 8 and 9 in the same way as the x86_64 platform +does. + +This patch requires Daniel Axtens's patches for claiming more memory. + +For vTPM support to work on PowerVM, system driver levels 1010.30 +or 1020.00 are required. + +Note: Previous versions of firmware levels with the 2hash-ext-log +API call have a bug that, once this API call is invoked, has the +effect of disabling the vTPM driver under Linux causing an error +message to be displayed in the Linux kernel log. Those users will +have to update their machines to the firmware levels mentioned +above. + +Cc: Eric Snowberg +Signed-off-by: Stefan Berger +--- + docs/grub.texi | 3 +- + grub-core/Makefile.core.def | 7 ++ + grub-core/commands/ieee1275/ibmvtpm.c | 152 ++++++++++++++++++++++++++ + include/grub/ieee1275/ieee1275.h | 3 + + 4 files changed, 164 insertions(+), 1 deletion(-) + create mode 100644 grub-core/commands/ieee1275/ibmvtpm.c + +diff --git a/docs/grub.texi b/docs/grub.texi +index 4504bcabe..026aacacf 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -6204,7 +6204,8 @@ tpm module is loaded. As such it is recommended that the tpm module be built + into @file{core.img} in order to avoid a potential gap in measurement between + @file{core.img} being loaded and the tpm module being loaded. + +-Measured boot is currently only supported on EFI platforms. ++Measured boot is currently only supported on EFI and IBM IEEE1275 PowerPC ++platforms. + + @node Lockdown + @section Lockdown when booting on a secure setup +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index cee596872..54733425c 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1141,6 +1141,13 @@ module = { + enable = powerpc_ieee1275; + }; + ++module = { ++ name = tpm; ++ common = commands/tpm.c; ++ ieee1275 = commands/ieee1275/ibmvtpm.c; ++ enable = powerpc_ieee1275; ++}; ++ + module = { + name = terminal; + common = commands/terminal.c; +diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c +new file mode 100644 +index 000000000..e68b8448b +--- /dev/null ++++ b/grub-core/commands/ieee1275/ibmvtpm.c +@@ -0,0 +1,152 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2021 Free Software Foundation, Inc. ++ * Copyright (C) 2021 IBM Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ * ++ * IBM vTPM support code. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static grub_ieee1275_ihandle_t tpm_ihandle; ++static grub_uint8_t tpm_version; ++ ++#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t)0) ++ ++static void ++tpm_get_tpm_version (void) ++{ ++ grub_ieee1275_phandle_t vtpm; ++ char buffer[20]; ++ ++ if (!grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) && ++ !grub_ieee1275_get_property (vtpm, "compatible", buffer, ++ sizeof (buffer), NULL) && ++ !grub_strcmp (buffer, "IBM,vtpm20")) ++ tpm_version = 2; ++} ++ ++static grub_err_t ++tpm_init (void) ++{ ++ static int init_success = 0; ++ ++ if (!init_success) ++ { ++ if (grub_ieee1275_open ("/vdevice/vtpm", &tpm_ihandle) < 0) { ++ tpm_ihandle = IEEE1275_IHANDLE_INVALID; ++ return GRUB_ERR_UNKNOWN_DEVICE; ++ } ++ ++ init_success = 1; ++ ++ tpm_get_tpm_version (); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static int ++ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex, ++ grub_uint32_t eventtype, ++ const char *description, ++ grub_size_t description_size, ++ void *buf, grub_size_t size) ++{ ++ struct tpm_2hash_ext_log ++ { ++ struct grub_ieee1275_common_hdr common; ++ grub_ieee1275_cell_t method; ++ grub_ieee1275_cell_t ihandle; ++ grub_ieee1275_cell_t size; ++ grub_ieee1275_cell_t buf; ++ grub_ieee1275_cell_t description_size; ++ grub_ieee1275_cell_t description; ++ grub_ieee1275_cell_t eventtype; ++ grub_ieee1275_cell_t pcrindex; ++ grub_ieee1275_cell_t catch_result; ++ grub_ieee1275_cell_t rc; ++ } ++ args; ++ ++ INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 2); ++ args.method = (grub_ieee1275_cell_t) "2hash-ext-log"; ++ args.ihandle = tpm_ihandle; ++ args.pcrindex = pcrindex; ++ args.eventtype = eventtype; ++ args.description = (grub_ieee1275_cell_t) description; ++ args.description_size = description_size; ++ args.buf = (grub_ieee1275_cell_t) buf; ++ args.size = (grub_ieee1275_cell_t) size; ++ ++ if (IEEE1275_CALL_ENTRY_FN (&args) == -1) ++ return -1; ++ ++ /* ++ * catch_result is set if firmware does not support 2hash-ext-log ++ * rc is GRUB_IEEE1275_CELL_FALSE (0) on failure ++ */ ++ if ((args.catch_result) || args.rc == GRUB_IEEE1275_CELL_FALSE) ++ return -1; ++ ++ return 0; ++} ++ ++static grub_err_t ++tpm2_log_event (unsigned char *buf, ++ grub_size_t size, grub_uint8_t pcr, ++ const char *description) ++{ ++ static int error_displayed = 0; ++ int err; ++ ++ err = ibmvtpm_2hash_ext_log (pcr, EV_IPL, ++ description, ++ grub_strlen(description) + 1, ++ buf, size); ++ if (err && !error_displayed) ++ { ++ error_displayed++; ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ "2HASH-EXT-LOG failed: Firmware is likely too old.\n"); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, ++ const char *description) ++{ ++ grub_err_t err = tpm_init(); ++ ++ /* Absence of a TPM isn't a failure. */ ++ if (err != GRUB_ERR_NONE) ++ return GRUB_ERR_NONE; ++ ++ grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n", ++ pcr, size, description); ++ ++ if (tpm_version == 2) ++ return tpm2_log_event (buf, size, pcr, description); ++ ++ return GRUB_ERR_NONE; ++} +diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h +index 591f4f12c..8a621af7c 100644 +--- a/include/grub/ieee1275/ieee1275.h ++++ b/include/grub/ieee1275/ieee1275.h +@@ -24,6 +24,9 @@ + #include + #include + ++#define GRUB_IEEE1275_CELL_FALSE ((grub_ieee1275_cell_t) 0) ++#define GRUB_IEEE1275_CELL_TRUE ((grub_ieee1275_cell_t) -1) ++ + struct grub_ieee1275_mem_region + { + unsigned int start; +-- +2.35.3 + diff --git a/0001-ieee1275-add-support-for-NVMeoFC.patch b/0001-ieee1275-add-support-for-NVMeoFC.patch new file mode 100644 index 0000000..f9cbc98 --- /dev/null +++ b/0001-ieee1275-add-support-for-NVMeoFC.patch @@ -0,0 +1,250 @@ +From c125cb45a7885d7bf168a05cfa4da3e681244649 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Tue, 15 Feb 2022 13:11:48 -0500 +Subject: [PATCH 1/4] ieee1275: add support for NVMeoFC + +Implements the functions to scan and discovery of NVMeoFC. +--- + grub-core/disk/ieee1275/ofdisk.c | 217 ++++++++++++++++++++++++++++++- + 1 file changed, 213 insertions(+), 4 deletions(-) + +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index 410f4b849..852bb95be 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -206,12 +206,10 @@ dev_iterate_real (const char *name, const char *path) + return; + } + ++ + static void +-dev_iterate (const struct grub_ieee1275_devalias *alias) ++dev_iterate_fcp_disks(const struct grub_ieee1275_devalias *alias) + { +- if (grub_strcmp (alias->type, "fcp") == 0) +- { +- + /* If we are dealing with fcp devices, we need + * to find the WWPNs and LUNs to iterate them */ + grub_ieee1275_ihandle_t ihandle; +@@ -323,6 +321,217 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) + grub_free (buf); + return; + ++} ++ ++static void ++dev_iterate_fcp_nvmeof (const struct grub_ieee1275_devalias *alias) ++{ ++ ++ ++ char *bufptr; ++ grub_ieee1275_ihandle_t ihandle; ++ ++ ++ // Create the structs for the parameters passing to PFW ++ struct nvme_args_ ++ { ++ struct grub_ieee1275_common_hdr common; ++ grub_ieee1275_cell_t method; ++ grub_ieee1275_cell_t ihandle; ++ grub_ieee1275_cell_t catch_result; ++ grub_ieee1275_cell_t nentries; ++ grub_ieee1275_cell_t table; ++ } nvme_discovery_controllers_args, nvme_controllers_args, nvme_namespaces_args; ++ ++ ++ // Create the structs for the results from PFW ++ ++ struct discovery_controllers_table_struct_ ++ { ++ grub_uint64_t table[256]; ++ grub_uint32_t len; ++ } discovery_controllers_table; ++ ++ /* struct nvme_controllers_table_entry ++ * this the return of nvme-controllers method tables, containing: ++ * - 2-byte controller ID ++ * - 256-byte transport address string ++ * - 256-byte field containing null-terminated NVM subsystem NQN string up to 223 characters ++ */ ++ struct nvme_controllers_table_entry_ ++ { ++ grub_uint16_t id; ++ char wwpn[256]; ++ char nqn[256]; ++ }; ++ ++ struct nvme_controllers_table_entry_* nvme_controllers_table = grub_malloc(sizeof(struct nvme_controllers_table_entry_)*256); ++ ++ grub_uint32_t nvme_controllers_table_entries; ++ ++ struct nvme_controllers_table_entry_real ++ { ++ grub_uint16_t id; ++ char wwpn[256]; ++ char nqn[256]; ++ }; ++ ++ /* Allocate memory for building the NVMeoF path */ ++ char *buf = grub_malloc (grub_strlen (alias->path) + 512); ++ if (!buf) ++ { ++ grub_ieee1275_close(ihandle); ++ return; ++ } ++ ++ /* Copy the alias->path to buf so we can work with */ ++ bufptr = grub_stpcpy (buf, alias->path); ++ grub_snprintf (bufptr, 32, "/nvme-of"); ++ ++ /* ++ * Open the nvme-of layer ++ * Ex. /pci@bus/fibre-channel@@dev,func/nvme-of ++ */ ++ if(grub_ieee1275_open (buf, &ihandle)) ++ { ++ grub_dprintf("disk", "failed to open the disk while iterating FCP disk path=%s\n", buf); ++ return; ++ } ++ ++ /* ++ * Call to nvme-discovery-controllers method from the nvme-of layer ++ * to get a list of the NVMe discovery controllers per the binding ++ */ ++ ++ INIT_IEEE1275_COMMON (&nvme_discovery_controllers_args.common, "call-method", 2, 2); ++ nvme_discovery_controllers_args.method = (grub_ieee1275_cell_t) "nvme-discovery-controllers"; ++ nvme_discovery_controllers_args.ihandle = ihandle; ++ ++ if (IEEE1275_CALL_ENTRY_FN (&nvme_discovery_controllers_args) == -1) ++ { ++ grub_dprintf("disk", "failed to get the targets while iterating FCP disk path=%s\n", buf); ++ grub_ieee1275_close(ihandle); ++ return; ++ } ++ ++ /* After closing the device, the info is lost. So lets copy each buffer in the buffers table */ ++ ++ discovery_controllers_table.len = (grub_uint32_t) nvme_discovery_controllers_args.nentries; ++ ++ unsigned int i=0; ++ for(i = 0; i < discovery_controllers_table.len; i++){ ++ discovery_controllers_table.table[i] = ((grub_uint64_t*)nvme_discovery_controllers_args.table)[i]; ++ } ++ ++ grub_ieee1275_close(ihandle); ++ ++ grub_dprintf("ofdisk","NVMeoF: Found %d discovery controllers\n",discovery_controllers_table.len); ++ ++ /* For each nvme discovery controller */ ++ int current_buffer_index; ++ for(current_buffer_index = 0; current_buffer_index < (int) discovery_controllers_table.len; current_buffer_index++){ ++ ++ ++ grub_snprintf (bufptr, 64, "/nvme-of/controller@%" PRIxGRUB_UINT64_T ",ffff", ++ discovery_controllers_table.table[current_buffer_index]); ++ ++ grub_dprintf("ofdisk","nvmeof controller=%s\n",buf); ++ ++ if(grub_ieee1275_open (buf, &ihandle)) ++ { ++ grub_dprintf("ofdisk", "failed to open the disk while getting nvme-controllers path=%s\n", buf); ++ continue; ++ } ++ ++ ++ INIT_IEEE1275_COMMON (&nvme_controllers_args.common, "call-method", 2, 2); ++ nvme_controllers_args.method = (grub_ieee1275_cell_t) "nvme-controllers"; ++ nvme_controllers_args.ihandle = ihandle; ++ nvme_controllers_args.catch_result = 0; ++ ++ ++ if (IEEE1275_CALL_ENTRY_FN (&nvme_controllers_args) == -1) ++ { ++ grub_dprintf("ofdisk", "failed to get the nvme-controllers while iterating FCP disk path\n"); ++ grub_ieee1275_close(ihandle); ++ continue; ++ } ++ ++ ++ /* Copy the buffer list to nvme_controllers_table */ ++ nvme_controllers_table_entries = ((grub_uint32_t) nvme_controllers_args.nentries); ++ struct nvme_controllers_table_entry_* nvme_controllers_table_ = (struct nvme_controllers_table_entry_*) nvme_controllers_args.table; ++ ++ for(i = 0; i < nvme_controllers_table_entries; i++){ ++ nvme_controllers_table[i].id = (grub_uint16_t) nvme_controllers_table_[i].id; ++ grub_strcpy(nvme_controllers_table[i].wwpn, nvme_controllers_table_[i].wwpn); ++ grub_strcpy(nvme_controllers_table[i].nqn, nvme_controllers_table_[i].nqn); ++ } ++ ++ grub_ieee1275_close(ihandle); ++ ++ int nvme_controller_index; ++ int bufptr_pos2; ++ grub_dprintf("ofdisk","NVMeoF: found %d nvme controllers\n",(int) nvme_controllers_args.nentries); ++ ++ /* For each nvme controller */ ++ for(nvme_controller_index = 0; nvme_controller_index < (int) nvme_controllers_args.nentries; nvme_controller_index++){ ++ /* Open the nvme controller ++ * /pci@bus/fibre-channel@dev,func/nvme-of/controller@transport-addr,ctlr-id:nqn=tgt-subsystem-nqn ++ */ ++ ++ bufptr_pos2 = grub_snprintf (bufptr, 512, "/nvme-of/controller@%s,ffff:nqn=%s", ++ nvme_controllers_table[nvme_controller_index].wwpn, nvme_controllers_table[nvme_controller_index].nqn); ++ ++ grub_dprintf("ofdisk","NVMeoF: nvmeof controller=%s\n",buf); ++ ++ if(grub_ieee1275_open (buf, &ihandle)){ ++ grub_dprintf("ofdisk","failed to open the path=%s\n",buf); ++ continue; ++ } ++ ++ INIT_IEEE1275_COMMON (&nvme_namespaces_args.common, "call-method", 2, 2); ++ nvme_namespaces_args.method = (grub_ieee1275_cell_t) "get-namespace-list"; ++ nvme_namespaces_args.ihandle = ihandle; ++ nvme_namespaces_args.catch_result = 0; ++ ++ if (IEEE1275_CALL_ENTRY_FN (&nvme_namespaces_args) == -1) ++ { ++ grub_dprintf("ofdisk", "failed to get the nvme-namespace-list while iterating FCP disk path\n"); ++ grub_ieee1275_close(ihandle); ++ continue; ++ } ++ ++ grub_uint32_t *namespaces = (grub_uint32_t*) nvme_namespaces_args.table; ++ grub_dprintf("ofdisk","NVMeoF: found %d namespaces\n",(int)nvme_namespaces_args.nentries); ++ ++ grub_ieee1275_close(ihandle); ++ ++ grub_uint32_t namespace_index = 0; ++ for(namespace_index=0; namespace_index < nvme_namespaces_args.nentries; namespace_index++){ ++ grub_snprintf (bufptr+bufptr_pos2, 512, "/namespace@%"PRIxGRUB_UINT32_T,namespaces[namespace_index]); ++ grub_dprintf("ofdisk","NVMeoF: namespace=%s\n",buf); ++ dev_iterate_real(buf,buf); ++ } ++ ++ dev_iterate_real(buf,buf); ++ } ++ } ++ grub_free(buf); ++ return; ++} ++ ++static void ++dev_iterate (const struct grub_ieee1275_devalias *alias) ++{ ++ if (grub_strcmp (alias->type, "fcp") == 0) ++ { ++ // Iterate disks ++ dev_iterate_fcp_disks(alias); ++ ++ // Iterate NVMeoF ++ dev_iterate_fcp_nvmeof(alias); ++ + } + else if (grub_strcmp (alias->type, "vscsi") == 0) + { +-- +2.35.3 + diff --git a/0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch b/0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch new file mode 100644 index 0000000..77b5555 --- /dev/null +++ b/0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch @@ -0,0 +1,40 @@ +From 1f41f020f73131574cd7aee4e0e09d4c56277d1e Mon Sep 17 00:00:00 2001 +From: Lu Ken +Date: Wed, 13 Jul 2022 10:06:11 +0800 +Subject: [PATCH 2/3] commands/efi/tpm: Use grub_strcpy() instead of + grub_memcpy() + +The event description is a string, so using grub_strcpy() is cleaner than +using grub_memcpy(). + +Signed-off-by: Lu Ken +Reviewed-by: Daniel Kiper +--- + grub-core/commands/efi/tpm.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c +index 19737b462..e032617d8 100644 +--- a/grub-core/commands/efi/tpm.c ++++ b/grub-core/commands/efi/tpm.c +@@ -177,7 +177,7 @@ grub_tpm1_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, + event->PCRIndex = pcr; + event->EventType = EV_IPL; + event->EventSize = grub_strlen (description) + 1; +- grub_memcpy (event->Event, description, event->EventSize); ++ grub_strcpy ((char *) event->Event, description); + + algorithm = TCG_ALG_SHA; + status = efi_call_7 (tpm->log_extend_event, tpm, (grub_addr_t) buf, (grub_uint64_t) size, +@@ -299,7 +299,7 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, + event->Header.EventType = EV_IPL; + event->Size = + sizeof (*event) - sizeof (event->Event) + grub_strlen (description) + 1; +- grub_memcpy (event->Event, description, grub_strlen (description) + 1); ++ grub_strcpy ((char *) event->Event, description); + + status = efi_call_5 (tpm->hash_log_extend_event, tpm, 0, (grub_addr_t) buf, + (grub_uint64_t) size, event); +-- +2.35.3 + diff --git a/0002-ieee1275-implement-vec5-for-cas-negotiation.patch b/0002-ieee1275-implement-vec5-for-cas-negotiation.patch new file mode 100644 index 0000000..27e05ab --- /dev/null +++ b/0002-ieee1275-implement-vec5-for-cas-negotiation.patch @@ -0,0 +1,73 @@ +From 6c7c4007ad621029295797b439158d36d0f62487 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Thu, 25 Aug 2022 11:37:56 -0400 +Subject: [PATCH 2/2] ieee1275: implement vec5 for cas negotiation + +As a legacy support, if the vector 5 is not implemented, Power +Hypervisor will consider the max CPUs as 64 instead 256 currently +supported during client-architecture-support negotiation. + +This patch implements the vector 5 and set the MAX CPUs to 256 while +setting the others values to 0 (default). + +Signed-off-by: Diego Domingos +Signed-off-by: Robbie Harwood +--- + grub-core/kern/ieee1275/init.c | 20 +++++++++++++++++++- + 1 file changed, 19 insertions(+), 1 deletion(-) + +diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c +index 7d7178d3e..3aa40313f 100644 +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -311,6 +311,18 @@ struct option_vector2 { + grub_uint8_t max_pft_size; + } __attribute__((packed)); + ++struct option_vector5 { ++ grub_uint8_t byte1; ++ grub_uint8_t byte2; ++ grub_uint8_t byte3; ++ grub_uint8_t cmo; ++ grub_uint8_t associativity; ++ grub_uint8_t bin_opts; ++ grub_uint8_t micro_checkpoint; ++ grub_uint8_t reserved0; ++ grub_uint32_t max_cpus; ++} __attribute__((packed)); ++ + struct pvr_entry { + grub_uint32_t mask; + grub_uint32_t entry; +@@ -329,6 +341,8 @@ struct cas_vector { + grub_uint16_t vec3; + grub_uint8_t vec4_size; + grub_uint16_t vec4; ++ grub_uint8_t vec5_size; ++ struct option_vector5 vec5; + } __attribute__((packed)); + + /* Call ibm,client-architecture-support to try to get more RMA. +@@ -349,7 +363,7 @@ grub_ieee1275_ibm_cas (void) + } args; + struct cas_vector vector = { + .pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */ +- .num_vecs = 4 - 1, ++ .num_vecs = 5 - 1, + .vec1_size = 0, + .vec1 = 0x80, /* ignore */ + .vec2_size = 1 + sizeof(struct option_vector2) - 2, +@@ -360,6 +374,10 @@ grub_ieee1275_ibm_cas (void) + .vec3 = 0x00e0, // ask for FP + VMX + DFP but don't halt if unsatisfied + .vec4_size = 2 - 1, + .vec4 = 0x0001, // set required minimum capacity % to the lowest value ++ .vec5_size = 1 + sizeof(struct option_vector5) - 2, ++ .vec5 = { ++ 0, 0, 0, 0, 0, 0, 0, 0, 256 ++ } + }; + + INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2); +-- +2.35.3 + diff --git a/0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch b/0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch new file mode 100644 index 0000000..19a1527 --- /dev/null +++ b/0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch @@ -0,0 +1,373 @@ +From 9e61624db77e5073961126457f599bc70e877fd1 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Tue, 15 Mar 2022 15:59:41 -0400 +Subject: [PATCH 2/4] ieee1275/ofpath: enable NVMeoF logical device translation + +This patch add code to enable the translation of logical devices to the of NVMeoFC paths. +--- + grub-core/osdep/linux/ofpath.c | 260 +++++++++++++++++++++++++++++++-- + include/grub/util/ofpath.h | 29 ++++ + 2 files changed, 280 insertions(+), 9 deletions(-) + +diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c +index 89beceef4..212782d3f 100644 +--- a/grub-core/osdep/linux/ofpath.c ++++ b/grub-core/osdep/linux/ofpath.c +@@ -137,7 +137,7 @@ trim_newline (char *path) + *end-- = '\0'; + } + +-#define MAX_DISK_CAT 64 ++#define MAX_DISK_CAT 512 + + static char * + find_obppath (const char *sysfs_path_orig) +@@ -313,6 +313,69 @@ get_basename(char *p) + return ret; + } + ++ ++void ++add_filename_to_pile(char *filename, struct ofpath_files_list_root* root){ ++ struct ofpath_files_list_node* file; ++ ++ file = malloc(sizeof(struct ofpath_files_list_node)); ++ ++ file->filename = filename; ++ ++ if(root->first == NULL){ ++ root->items = 1; ++ root->first = file; ++ file->next = NULL; ++ } else { ++ root->items++; ++ file->next = root->first; ++ root->first = file; ++ } ++} ++ ++ ++void ++find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth){ ++ struct dirent *ep; ++ struct stat statbuf; ++ DIR *dp; ++ ++ if(depth > max_depth){ ++ return; ++ } ++ ++ if((dp = opendir(directory)) == NULL){ ++ ++ return; ++ } ++ ++ while((ep = readdir(dp)) != NULL){ ++ ++ char* full_path = malloc(1024*sizeof(char)); ++ snprintf(full_path,1024,"%s/%s",directory,ep->d_name); ++ ++ lstat(full_path,&statbuf); ++ ++ if(S_ISLNK(statbuf.st_mode)){ ++ ++ continue; ++ } ++ ++ if(!strcmp(ep->d_name,".") || !strcmp(ep->d_name,"..")){ ++ continue; ++ } ++ ++ if(!strcmp(ep->d_name,filename)){ ++ add_filename_to_pile(full_path, root); ++ } ++ ++ find_file(filename, full_path, root, max_depth, depth+1); ++ ++ } ++ closedir(dp); ++} ++ ++ + static char * + of_path_of_vdisk(const char *sys_devname __attribute__((unused)), + const char *device, +@@ -351,7 +414,142 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi + return ret; + } + +-#ifdef __sparc__ ++char* ++of_find_fc_host(char* host_wwpn){ ++ ++ FILE* fp; ++ char *buf; ++ char portname_filename[sizeof("port_name")] = "port_name"; ++ char devices_path[sizeof("/sys/devices")] = "/sys/devices"; ++ ++ struct ofpath_files_list_root* portnames_file_list; ++ ++ portnames_file_list=malloc(sizeof(portnames_file_list)); ++ portnames_file_list->items=0; ++ portnames_file_list->first=NULL; ++ ++ find_file(portname_filename, devices_path, portnames_file_list, 10, 0); ++ ++ struct ofpath_files_list_node* node = portnames_file_list->first; ++ while(node != NULL){ ++ fp = fopen(node->filename,"r"); ++ buf = malloc(sizeof(char)*512); ++ fscanf(fp, "%s", buf); ++ fclose(fp); ++ if((strcmp(buf,host_wwpn) == 0) && grub_strstr(node->filename, "fc_host")){ ++ return node->filename; ++ } ++ node = node->next; ++ } ++ ++ return NULL; ++} ++ ++void ++of_path_get_nvmeof_adapter_info(char* sysfs_path, ++ struct ofpath_nvmeof_info* nvmeof_info){ ++ ++ FILE *fp; ++ char *buf, *buf2, *buf3; ++ ++ nvmeof_info->host_wwpn = malloc(sizeof(char)*256); ++ nvmeof_info->target_wwpn = malloc(sizeof(char)*256); ++ nvmeof_info->nqn = malloc(sizeof(char)*256); ++ ++ buf = malloc(sizeof(char)*512); ++ snprintf(buf,512,"%s/subsysnqn",sysfs_path); ++ fp = fopen(buf,"r"); ++ fscanf(fp, "%s", nvmeof_info->nqn); ++ fclose(fp); ++ ++ snprintf(buf,512,"%s/cntlid",sysfs_path); ++ fp = fopen(buf,"r"); ++ fscanf(fp, "%u", &(nvmeof_info->cntlid)); ++ fclose(fp); ++ ++ //snprintf(buf,512,"%s/nsid",sysfs_path); ++ //fp = fopen(buf,"r"); ++ //fscanf(fp, "%u", &(nvmeof_info->nsid)); ++ //fclose(fp); ++ ++ snprintf(buf,512,"%s/address",sysfs_path); ++ fp = fopen(buf,"r"); ++ buf2 = malloc(sizeof(char)*512); ++ fscanf(fp, "%s", buf2); ++ fclose(fp); ++ ++ nvmeof_info->host_wwpn = strrchr(buf2,'-')+1; ++ ++ buf3=strchr(buf2,'-')+1; ++ buf3=strchr(buf3,'-')+1; ++ nvmeof_info->target_wwpn = buf3; ++ buf3 = strchr(nvmeof_info->target_wwpn,','); ++ *buf3 = '\0'; ++ ++ ++ free(buf); ++ ++ return; ++} ++ ++#define MAX_NVME_NSID_DIGITS 6 ++ ++static char * ++of_path_get_nvme_controller_name_node(const char* devname) ++{ ++ char *controller_node, *end; ++ ++ controller_node = strdup(devname); ++ ++ end = grub_strchr(controller_node+1, 'n'); ++ ++ if(end != NULL){ ++ *end = '\0'; ++ } ++ ++ return controller_node; ++} ++ ++unsigned int ++of_path_get_nvme_nsid(const char* devname) ++{ ++ unsigned int nsid; ++ char *sysfs_path, *buf; ++ FILE *fp; ++ ++ buf=malloc(sizeof(char)*512); ++ ++ sysfs_path = block_device_get_sysfs_path_and_link (devname); ++ ++ snprintf(buf,512,"%s/%s/nsid",sysfs_path,devname); ++ fp = fopen(buf,"r"); ++ fscanf(fp, "%u", &(nsid)); ++ fclose(fp); ++ ++ free(sysfs_path); ++ free(buf); ++ ++ return nsid; ++ ++} ++ ++static char * ++nvme_get_syspath(const char *nvmedev) ++{ ++ char *sysfs_path, *controller_node; ++ sysfs_path = block_device_get_sysfs_path_and_link (nvmedev); ++ ++ if(strstr(sysfs_path,"nvme-subsystem")){ ++ controller_node = of_path_get_nvme_controller_name_node(nvmedev); ++ strcat(sysfs_path,"/"); ++ strcat(sysfs_path,controller_node); ++ sysfs_path = xrealpath(sysfs_path); ++ } ++ ++ return sysfs_path; ++} ++ ++ + static char * + of_path_of_nvme(const char *sys_devname __attribute__((unused)), + const char *device, +@@ -360,6 +558,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)), + { + char *sysfs_path, *of_path, disk[MAX_DISK_CAT]; + const char *digit_string, *part_end; ++ int chars_written; + + digit_string = trailing_digits (device); + part_end = devicenode + strlen (devicenode) - 1; +@@ -379,15 +578,61 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)), + /* Remove the p. */ + *end = '\0'; + sscanf (digit_string, "%d", &part); +- snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1)); +- sysfs_path = block_device_get_sysfs_path_and_link (nvmedev); ++ ++ sysfs_path = nvme_get_syspath(nvmedev); ++ ++ /* If is a NVMeoF */ ++ if(strstr(sysfs_path,"nvme-fabrics")){ ++ struct ofpath_nvmeof_info* nvmeof_info; ++ nvmeof_info = malloc(sizeof(nvmeof_info)); ++ ++ of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info); ++ ++ sysfs_path = of_find_fc_host(nvmeof_info->host_wwpn); ++ ++ chars_written = snprintf(disk,sizeof(disk),"/nvme-of/controller@%s,%x:nqn=%s", ++ nvmeof_info->target_wwpn, ++ 0xffff, ++ nvmeof_info->nqn); ++ ++ unsigned int nsid = of_path_get_nvme_nsid(nvmedev); ++ ++ if(nsid){ ++ snprintf(disk+chars_written,sizeof(disk) - chars_written, ++ "/namespace@%x:%d",nsid, part); ++ } ++ ++ } else { ++ snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1)); ++ } + free (nvmedev); + } + else + { + /* We do not have the parition. */ +- snprintf (disk, sizeof (disk), "/disk@1"); +- sysfs_path = block_device_get_sysfs_path_and_link (device); ++ sysfs_path = nvme_get_syspath (device); ++ if(strstr(sysfs_path,"nvme-fabrics")){ ++ struct ofpath_nvmeof_info* nvmeof_info; ++ nvmeof_info = malloc(sizeof(nvmeof_info)); ++ ++ of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info); ++ ++ sysfs_path = of_find_fc_host(nvmeof_info->host_wwpn); ++ ++ chars_written = snprintf(disk,sizeof(disk),"/nvme-of/controller@%s,%x:nqn=%s", ++ nvmeof_info->target_wwpn, ++ 0xffff, ++ nvmeof_info->nqn); ++ ++ unsigned int nsid = of_path_get_nvme_nsid(device); ++ if(nsid){ ++ snprintf(disk+chars_written,sizeof(disk) - chars_written, ++ "/namespace@%x",nsid); ++ } ++ } else { ++ snprintf (disk, sizeof (disk), "/disk@1"); ++ } ++ + } + + of_path = find_obppath (sysfs_path); +@@ -398,7 +643,6 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)), + free (sysfs_path); + return of_path; + } +-#endif + + static void + of_fc_port_name(const char *path, const char *subpath, char *port_name) +@@ -840,11 +1084,9 @@ grub_util_devname_to_ofpath (const char *sys_devname) + /* All the models I've seen have a devalias "floppy". + New models have no floppy at all. */ + ofpath = xstrdup ("floppy"); +-#ifdef __sparc__ + else if (device[0] == 'n' && device[1] == 'v' && device[2] == 'm' + && device[3] == 'e') + ofpath = of_path_of_nvme (name_buf, device, devnode, devicenode); +-#endif + else + { + grub_util_warn (_("unknown device type %s"), device); +diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h +index b43c523cb..a0ec30620 100644 +--- a/include/grub/util/ofpath.h ++++ b/include/grub/util/ofpath.h +@@ -3,4 +3,33 @@ + + char *grub_util_devname_to_ofpath (const char *devname); + ++struct ofpath_files_list_node { ++ char* filename; ++ struct ofpath_files_list_node* next; ++}; ++ ++struct ofpath_files_list_root { ++ int items; ++ struct ofpath_files_list_node* first; ++}; ++ ++struct ofpath_nvmeof_info { ++ char* host_wwpn; ++ char* target_wwpn; ++ char* nqn; ++ int cntlid; ++ int nsid; ++}; ++ ++void of_path_get_nvmeof_adapter_info(char* sysfs_path, ++ struct ofpath_nvmeof_info* nvmeof_info); ++ ++unsigned int of_path_get_nvme_nsid(const char* devname); ++ ++void add_filename_to_pile(char *filename, struct ofpath_files_list_root* root); ++ ++void find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth); ++ ++char* of_find_fc_host(char* host_wwpn); ++ + #endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */ +-- +2.35.3 + diff --git a/0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch b/0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch new file mode 100644 index 0000000..ffe842f --- /dev/null +++ b/0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch @@ -0,0 +1,260 @@ +From 029c952f37dedb086c85bfb5fbc0de15cd4dbf0f Mon Sep 17 00:00:00 2001 +From: Lu Ken +Date: Wed, 13 Jul 2022 10:06:12 +0800 +Subject: [PATCH 3/3] efi/tpm: Add EFI_CC_MEASUREMENT_PROTOCOL support + +The EFI_CC_MEASUREMENT_PROTOCOL abstracts the measurement for virtual firmware +in confidential computing environment. It is similar to the EFI_TCG2_PROTOCOL. +It was proposed by Intel and ARM and approved by UEFI organization. + +It is defined in Intel GHCI specification: https://cdrdv2.intel.com/v1/dl/getContent/726790 . +The EDKII header file is available at https://github.com/tianocore/edk2/blob/master/MdePkg/Include/Protocol/CcMeasurement.h . + +Signed-off-by: Lu Ken +Reviewed-by: Daniel Kiper +--- + grub-core/commands/efi/tpm.c | 48 +++++++++++ + include/grub/efi/cc.h | 151 +++++++++++++++++++++++++++++++++++ + 2 files changed, 199 insertions(+) + create mode 100644 include/grub/efi/cc.h + +diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c +index e032617d8..630fd8a82 100644 +--- a/grub-core/commands/efi/tpm.c ++++ b/grub-core/commands/efi/tpm.c +@@ -22,6 +22,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -32,6 +33,7 @@ typedef TCG_PCR_EVENT grub_tpm_event_t; + + static grub_efi_guid_t tpm_guid = EFI_TPM_GUID; + static grub_efi_guid_t tpm2_guid = EFI_TPM2_GUID; ++static grub_efi_guid_t cc_measurement_guid = GRUB_EFI_CC_MEASUREMENT_PROTOCOL_GUID; + + static grub_efi_handle_t *grub_tpm_handle; + static grub_uint8_t grub_tpm_version; +@@ -308,6 +310,50 @@ grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, + return grub_efi_log_event_status (status); + } + ++static void ++grub_cc_log_event (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, ++ const char *description) ++{ ++ grub_efi_cc_event_t *event; ++ grub_efi_status_t status; ++ grub_efi_cc_protocol_t *cc; ++ grub_efi_cc_mr_index_t mr; ++ ++ cc = grub_efi_locate_protocol (&cc_measurement_guid, NULL); ++ if (cc == NULL) ++ return; ++ ++ status = efi_call_3 (cc->map_pcr_to_mr_index, cc, pcr, &mr); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ grub_efi_log_event_status (status); ++ return; ++ } ++ ++ event = grub_zalloc (sizeof (grub_efi_cc_event_t) + ++ grub_strlen (description) + 1); ++ if (event == NULL) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate CC event buffer")); ++ return; ++ } ++ ++ event->Header.HeaderSize = sizeof (grub_efi_cc_event_header_t); ++ event->Header.HeaderVersion = GRUB_EFI_CC_EVENT_HEADER_VERSION; ++ event->Header.MrIndex = mr; ++ event->Header.EventType = EV_IPL; ++ event->Size = sizeof (*event) + grub_strlen (description) + 1; ++ grub_strcpy ((char *) event->Event, description); ++ ++ status = efi_call_5 (cc->hash_log_extend_event, cc, 0, ++ (grub_efi_physical_address_t)(grub_addr_t) buf, ++ (grub_efi_uint64_t) size, event); ++ grub_free (event); ++ ++ if (status != GRUB_EFI_SUCCESS) ++ grub_efi_log_event_status (status); ++} ++ + grub_err_t + grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, + const char *description) +@@ -315,6 +361,8 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, + grub_efi_handle_t tpm_handle; + grub_efi_uint8_t protocol_version; + ++ grub_cc_log_event(buf, size, pcr, description); ++ + if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) + return 0; + +diff --git a/include/grub/efi/cc.h b/include/grub/efi/cc.h +new file mode 100644 +index 000000000..896030689 +--- /dev/null ++++ b/include/grub/efi/cc.h +@@ -0,0 +1,151 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Free Software Foundation, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_EFI_CC_H ++#define GRUB_EFI_CC_H 1 ++ ++#include ++#include ++#include ++ ++#define GRUB_EFI_CC_MEASUREMENT_PROTOCOL_GUID \ ++ { 0x96751a3d, 0x72f4, 0x41a6, \ ++ { 0xa7, 0x94, 0xed, 0x5d, 0x0e, 0x67, 0xae, 0x6b } \ ++ }; ++ ++struct grub_efi_cc_version ++{ ++ grub_efi_uint8_t Major; ++ grub_efi_uint8_t Minor; ++}; ++typedef struct grub_efi_cc_version grub_efi_cc_version_t; ++ ++/* EFI_CC Type/SubType definition. */ ++#define GRUB_EFI_CC_TYPE_NONE 0 ++#define GRUB_EFI_CC_TYPE_SEV 1 ++#define GRUB_EFI_CC_TYPE_TDX 2 ++ ++struct grub_efi_cc_type ++{ ++ grub_efi_uint8_t Type; ++ grub_efi_uint8_t SubType; ++}; ++typedef struct grub_efi_cc_type grub_efi_cc_type_t; ++ ++typedef grub_efi_uint32_t grub_efi_cc_event_log_bitmap_t; ++typedef grub_efi_uint32_t grub_efi_cc_event_log_format_t; ++typedef grub_efi_uint32_t grub_efi_cc_event_algorithm_bitmap_t; ++typedef grub_efi_uint32_t grub_efi_cc_mr_index_t; ++ ++/* Intel TDX measure register index. */ ++#define GRUB_TDX_MR_INDEX_MRTD 0 ++#define GRUB_TDX_MR_INDEX_RTMR0 1 ++#define GRUB_TDX_MR_INDEX_RTMR1 2 ++#define GRUB_TDX_MR_INDEX_RTMR2 3 ++#define GRUB_TDX_MR_INDEX_RTMR3 4 ++ ++#define GRUB_EFI_CC_EVENT_LOG_FORMAT_TCG_2 0x00000002 ++#define GRUB_EFI_CC_BOOT_HASH_ALG_SHA384 0x00000004 ++#define GRUB_EFI_CC_EVENT_HEADER_VERSION 1 ++ ++struct grub_efi_cc_event_header ++{ ++ /* Size of the event header itself (sizeof(EFI_TD_EVENT_HEADER)). */ ++ grub_efi_uint32_t HeaderSize; ++ ++ /* ++ * Header version. For this version of this specification, ++ * the value shall be 1. ++ */ ++ grub_efi_uint16_t HeaderVersion; ++ ++ /* Index of the MR that shall be extended. */ ++ grub_efi_cc_mr_index_t MrIndex; ++ ++ /* Type of the event that shall be extended (and optionally logged). */ ++ grub_efi_uint32_t EventType; ++} GRUB_PACKED; ++typedef struct grub_efi_cc_event_header grub_efi_cc_event_header_t; ++ ++struct grub_efi_cc_event ++{ ++ /* Total size of the event including the Size component, the header and the Event data. */ ++ grub_efi_uint32_t Size; ++ grub_efi_cc_event_header_t Header; ++ grub_efi_uint8_t Event[0]; ++} GRUB_PACKED; ++typedef struct grub_efi_cc_event grub_efi_cc_event_t; ++ ++struct grub_efi_cc_boot_service_capability ++{ ++ /* Allocated size of the structure. */ ++ grub_efi_uint8_t Size; ++ ++ /* ++ * Version of the grub_efi_cc_boot_service_capability_t structure itself. ++ * For this version of the protocol, the Major version shall be set to 1 ++ * and the Minor version shall be set to 1. ++ */ ++ grub_efi_cc_version_t StructureVersion; ++ ++ /* ++ * Version of the EFI TD protocol. ++ * For this version of the protocol, the Major version shall be set to 1 ++ * and the Minor version shall be set to 1. ++ */ ++ grub_efi_cc_version_t ProtocolVersion; ++ ++ /* Supported hash algorithms. */ ++ grub_efi_cc_event_algorithm_bitmap_t HashAlgorithmBitmap; ++ ++ /* Bitmap of supported event log formats. */ ++ grub_efi_cc_event_log_bitmap_t SupportedEventLogs; ++ ++ /* Indicates the CC type. */ ++ grub_efi_cc_type_t CcType; ++}; ++typedef struct grub_efi_cc_boot_service_capability grub_efi_cc_boot_service_capability_t; ++ ++struct grub_efi_cc_protocol ++{ ++ grub_efi_status_t ++ (*get_capability) (struct grub_efi_cc_protocol *this, ++ grub_efi_cc_boot_service_capability_t *ProtocolCapability); ++ ++ grub_efi_status_t ++ (*get_event_log) (struct grub_efi_cc_protocol *this, ++ grub_efi_cc_event_log_format_t EventLogFormat, ++ grub_efi_physical_address_t *EventLogLocation, ++ grub_efi_physical_address_t *EventLogLastEntry, ++ grub_efi_boolean_t *EventLogTruncated); ++ ++ grub_efi_status_t ++ (*hash_log_extend_event) (struct grub_efi_cc_protocol *this, ++ grub_efi_uint64_t Flags, ++ grub_efi_physical_address_t DataToHash, ++ grub_efi_uint64_t DataToHashLen, ++ grub_efi_cc_event_t *EfiCcEvent); ++ ++ grub_efi_status_t ++ (*map_pcr_to_mr_index) (struct grub_efi_cc_protocol *this, ++ grub_efi_uint32_t PcrIndex, ++ grub_efi_cc_mr_index_t *MrIndex); ++}; ++typedef struct grub_efi_cc_protocol grub_efi_cc_protocol_t; ++ ++#endif +-- +2.35.3 + diff --git a/0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch b/0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch new file mode 100644 index 0000000..bc89763 --- /dev/null +++ b/0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch @@ -0,0 +1,62 @@ +From 1729400ab816804a28ebf50cb1310607b2c4b75e Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Fri, 25 Feb 2022 12:49:51 -0500 +Subject: [PATCH 3/4] ieee1275: change the logic of ieee1275_get_devargs() + +Usually grub will parse the PFW arguments by searching for the first occurence of the character ':'. +However, we can have this char more than once on NQN. +This patch changes the logic to find the last occurence of this char so we can get the proper values +for NVMeoFC +--- + grub-core/kern/ieee1275/openfw.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c +index f819bd106..655a71310 100644 +--- a/grub-core/kern/ieee1275/openfw.c ++++ b/grub-core/kern/ieee1275/openfw.c +@@ -354,6 +354,13 @@ static char * + grub_ieee1275_get_devargs (const char *path) + { + char *colon = grub_strchr (path, ':'); ++ char *colon_check = colon; ++ ++ /* Find the last occurence of colon */ ++ while(colon_check){ ++ colon = colon_check; ++ colon_check = grub_strchr (colon+1, ':'); ++ } + + if (! colon) + return 0; +@@ -368,6 +375,18 @@ grub_ieee1275_get_devname (const char *path) + char *colon = grub_strchr (path, ':'); + int pathlen = grub_strlen (path); + struct grub_ieee1275_devalias curalias; ++ ++ /* Check some special cases */ ++ if(grub_strstr(path, "nvme-of")){ ++ char *namespace_split = grub_strstr(path,"/namespace@"); ++ if(namespace_split){ ++ colon = grub_strchr (namespace_split, ':'); ++ } else { ++ colon = NULL; ++ } ++ ++ } ++ + if (colon) + pathlen = (int)(colon - path); + +@@ -693,7 +712,7 @@ grub_ieee1275_get_boot_dev (void) + return NULL; + } + +- bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); ++ bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64 + 256); + if (! bootpath) + { + grub_print_error (); +-- +2.35.3 + diff --git a/0004-ofpath-controller-name-update.patch b/0004-ofpath-controller-name-update.patch new file mode 100644 index 0000000..3ab01e5 --- /dev/null +++ b/0004-ofpath-controller-name-update.patch @@ -0,0 +1,28 @@ +From 7717cd9c27f18703287403af1a955588e3d0261f Mon Sep 17 00:00:00 2001 +From: mamatha +Date: Sat, 24 Sep 2022 11:22:39 +0530 +Subject: [PATCH 4/4] ofpath controller name update + +patch to update ofpath controller name + +Signed-off-by: mamatha +--- + grub-core/osdep/linux/ofpath.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c +index 212782d3f..7d31cfd0f 100644 +--- a/grub-core/osdep/linux/ofpath.c ++++ b/grub-core/osdep/linux/ofpath.c +@@ -483,6 +483,8 @@ of_path_get_nvmeof_adapter_info(char* sysfs_path, + buf3=strchr(buf2,'-')+1; + buf3=strchr(buf3,'-')+1; + nvmeof_info->target_wwpn = buf3; ++ buf3=strchr(buf3,'x')+1; ++ nvmeof_info->target_wwpn = buf3; + buf3 = strchr(nvmeof_info->target_wwpn,','); + *buf3 = '\0'; + +-- +2.35.3 + diff --git a/grub2.changes b/grub2.changes index c9a1830..985e158 100644 --- a/grub2.changes +++ b/grub2.changes @@ -1,3 +1,22 @@ +------------------------------------------------------------------- +Fri Oct 28 04:58:28 UTC 2022 - Michael Chang + +- NVMeoFC support on grub (jsc#PED-996) + * 0001-ieee1275-add-support-for-NVMeoFC.patch + * 0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch + * 0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch + * 0004-ofpath-controller-name-update.patch +- TDX: Enhance grub2 measurement to TD RTMR (jsc#PED-1265) + * 0001-commands-efi-tpm-Refine-the-status-of-log-event.patch + * 0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch + * 0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch +- Measure the kernel on POWER10 and extend TPM PCRs (PED-1990) + * 0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch + * 0002-ieee1275-implement-vec5-for-cas-negotiation.patch +- Fix efi pcr snapshot related funtion is defined but not used on powerpc + platform. + * safe_tpm_pcr_snapshot.patch + ------------------------------------------------------------------- Mon Oct 24 01:58:08 UTC 2022 - Michael Chang diff --git a/grub2.spec b/grub2.spec index 153dfb6..fe4793b 100644 --- a/grub2.spec +++ b/grub2.spec @@ -454,6 +454,18 @@ Patch925: 0002-mm-Defer-the-disk-cache-invalidation.patch Patch926: 0001-grub-install-set-point-of-no-return-for-powerpc-ieee1275.patch Patch927: safe_tpm_pcr_snapshot.patch Patch928: 0001-linux-fix-efi_relocate_kernel-failure.patch +# (PED-996) NVMeoFC support on Grub (grub2) +Patch929: 0001-ieee1275-add-support-for-NVMeoFC.patch +Patch930: 0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch +Patch931: 0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch +Patch932: 0004-ofpath-controller-name-update.patch +# (PED-1265) TDX: Enhance grub2 measurement to TD RTMR +Patch933: 0001-commands-efi-tpm-Refine-the-status-of-log-event.patch +Patch934: 0002-commands-efi-tpm-Use-grub_strcpy-instead-of-grub_mem.patch +Patch935: 0003-efi-tpm-Add-EFI_CC_MEASUREMENT_PROTOCOL-support.patch +# (PED-1990) GRUB2: Measure the kernel on POWER10 and extend TPM PCRs +Patch936: 0001-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch +Patch937: 0002-ieee1275-implement-vec5-for-cas-negotiation.patch Requires: gettext-runtime %if 0%{?suse_version} >= 1140 diff --git a/safe_tpm_pcr_snapshot.patch b/safe_tpm_pcr_snapshot.patch index 1a79db8..40f729e 100644 --- a/safe_tpm_pcr_snapshot.patch +++ b/safe_tpm_pcr_snapshot.patch @@ -1,20 +1,50 @@ --- - grub-core/commands/tpm.c | 28 ++++++++++++++++++++++------ + grub-core/commands/tpm.c | 46 ++++++++++++++++++++++++++++++++++++---------- util/grub-install.c | 6 ++++-- - 2 files changed, 26 insertions(+), 8 deletions(-) + 2 files changed, 40 insertions(+), 12 deletions(-) --- a/grub-core/commands/tpm.c +++ b/grub-core/commands/tpm.c -@@ -249,6 +249,8 @@ - return GRUB_ERR_NONE; - } +@@ -27,8 +27,10 @@ + #include + #include + #include ++#ifdef GRUB_MACHINE_EFI + #include + #include ++#endif + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -87,12 +89,6 @@ + .verify_string = grub_tpm_verify_string, + }; + +-/* +- * Preserve current PCR values and record them to an EFI variable +- */ +-#define GRUB2_PCR_BITMASK_DEFAULT ((1 << 16) - 1) +-#define GRUB2_PCR_BITMASK_ALL ((1 << 24) - 1) +- + static const struct grub_arg_option grub_tpm_record_pcrs_options[] = + { + { +@@ -108,6 +104,14 @@ + {0, 0, 0, 0, 0, 0} + }; +#ifdef GRUB_MACHINE_EFI ++ ++/* ++ * Preserve current PCR values and record them to an EFI variable ++ */ ++#define GRUB2_PCR_BITMASK_DEFAULT ((1 << 16) - 1) ++#define GRUB2_PCR_BITMASK_ALL ((1 << 24) - 1) + static grub_err_t - grub_tpm_record_pcrs (grub_extcmd_context_t ctxt, int argc, char **args) + grub_tpm_parse_pcr_index (const char *word, const char **end_ret, unsigned int *index) { -@@ -259,6 +261,10 @@ +@@ -259,6 +263,10 @@ grub_size_t size = 0; int n, rv = 1; @@ -25,7 +55,7 @@ if (argc == 0) pcr_bitmask = GRUB2_PCR_BITMASK_DEFAULT; else -@@ -287,13 +293,24 @@ +@@ -287,13 +295,28 @@ return rv; } @@ -47,21 +77,27 @@ { - if (!grub_tpm_present()) - return; -- grub_verifier_register (&grub_tpm_verifier); ++#ifdef GRUB_MACHINE_EFI + if (grub_tpm_present()) + grub_verifier_register (&grub_tpm_verifier); ++#else + grub_verifier_register (&grub_tpm_verifier); ++#endif cmd = grub_register_extcmd ("tpm_record_pcrs", grub_tpm_record_pcrs, 0, N_("LIST_OF_PCRS"), -@@ -303,8 +320,7 @@ +@@ -303,8 +326,11 @@ GRUB_MOD_FINI (tpm) { - if (!grub_tpm_present()) - return; -- grub_verifier_unregister (&grub_tpm_verifier); ++#ifdef GRUB_MACHINE_EFI + if (grub_tpm_present()) + grub_verifier_unregister (&grub_tpm_verifier); ++#else + grub_verifier_unregister (&grub_tpm_verifier); ++#endif grub_unregister_extcmd (cmd); } --- a/util/grub-install.c