forked from pool/grub2
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
This commit is contained in:
parent
761268d847
commit
3e026f665c
53
0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch
Normal file
53
0001-devmapper-getroot-Have-devmapper-recognize-LUKS2.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From ebe4ac49e800b18b539564169593ab1c6f163378 Mon Sep 17 00:00:00 2001
|
||||
From: Josselin Poiret via Grub-devel <grub-devel@gnu.org>
|
||||
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
|
||||
|
@ -0,0 +1,32 @@
|
||||
From grub-devel-bounces@gnu.org Thu Aug 25 08:11:08 2022
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
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 <mchang@suse.com>
|
||||
[iluceno@suse.de: Backported to SLES-15-SP4]
|
||||
Signed-off-by: Ismael Luceno <iluceno@suse.de>
|
||||
---
|
||||
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)))
|
||||
{
|
32
0001-kern-efi-mm-Enlarge-the-default-heap-size.patch
Normal file
32
0001-kern-efi-mm-Enlarge-the-default-heap-size.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 3e08d9afd273b5dade84fec5f7f17113c47b6b75 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
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 <glin@suse.com>
|
||||
---
|
||||
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
|
||||
|
133
0001-mm-Allow-dynamically-requesting-additional-memory-re.patch
Normal file
133
0001-mm-Allow-dynamically-requesting-additional-memory-re.patch
Normal file
@ -0,0 +1,133 @@
|
||||
From 23bca58a68264657f176885c3564d07c9938b7f6 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
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 <ps@pks.im>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Patrick Steinhardt <ps@pks.im>
|
||||
---
|
||||
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 <grub/err.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/symbol.h>
|
||||
#include <config.h>
|
||||
@@ -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
|
||||
|
88
0001-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch
Normal file
88
0001-tpm-Disable-tpm-verifier-if-tpm-is-not-present.patch
Normal file
@ -0,0 +1,88 @@
|
||||
From 12378be5243c1c02ce28de2e5703e87197c69157 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
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 <mchang@suse.com>
|
||||
---
|
||||
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
|
127
0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch
Normal file
127
0002-devmapper-getroot-Set-up-cheated-LUKS2-cryptodisk-mo.patch
Normal file
@ -0,0 +1,127 @@
|
||||
From a25627c13b7e1e6998a14b5dd23b04b28465d737 Mon Sep 17 00:00:00 2001
|
||||
From: Josselin Poiret via Grub-devel <grub-devel@gnu.org>
|
||||
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 <grub/emu/misc.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
|
||||
+#include <grub/cryptodisk.h>
|
||||
+
|
||||
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
|
||||
+ * <cipher> <key> <iv_offset> <device path> <offset> [<#opt_params> <opt_param1> ...]
|
||||
+ */
|
||||
+ 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
|
106
0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch
Normal file
106
0002-kern-efi-mm-Always-request-a-fixed-number-of-pages-o.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From 834cb2ca9ed2d9d7a6926e598accdfe280b615da Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
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 <ps@pks.im>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Patrick Steinhardt <ps@pks.im>
|
||||
---
|
||||
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
|
||||
|
68
0002-mm-Defer-the-disk-cache-invalidation.patch
Normal file
68
0002-mm-Defer-the-disk-cache-invalidation.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From 4284d40799aaf5aab11c690f232ce0a191dcfbdb Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
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 <glin@suse.com>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,71 @@
|
||||
From 5b694a13545224c2d21afc3e94831be1bcc85770 Mon Sep 17 00:00:00 2001
|
||||
From: Fabian Vogt <fvogt@suse.de>
|
||||
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 <fvogt@suse.de>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,86 @@
|
||||
From b4500ff77efe3b36256fae1e456ded65fd77cf04 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
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 <ps@pks.im>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Patrick Steinhardt <ps@pks.im>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,89 @@
|
||||
From 4287786dde414d9b0517d12762904b4b2be19d2a Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
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 <ps@pks.im>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Patrick Steinhardt <ps@pks.im>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,93 @@
|
||||
From d4eb747f831d8b011c712f4335f12b572d6f32d9 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
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 <hdegoede@redhat.com>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,45 @@
|
||||
From d9c7bfe88ce7391618192401c426c218d2a17795 Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
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 <hdegoede@redhat.com>
|
||||
---
|
||||
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
|
||||
|
77
0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch
Normal file
77
0005-kern-efi-mm-Implement-runtime-addition-of-pages.patch
Normal file
@ -0,0 +1,77 @@
|
||||
From 3a2119e11b9c216f3b008a2c61aca52b91ad7547 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Steinhardt <ps@pks.im>
|
||||
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 <ps@pks.im>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Patrick Steinhardt <ps@pks.im>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,54 @@
|
||||
From 81339347bc10ec609227361434f75c5e36b85b9f Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
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 <javierm@redhat.com>
|
||||
Fixes: 2d7c3abd871f ("efi/console: Do not set text-mode until we actually need it")
|
||||
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
|
||||
---
|
||||
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
|
||||
|
@ -0,0 +1,75 @@
|
||||
From 9b12dc80d4254e22c41805cecf2494a8e6a50e3e Mon Sep 17 00:00:00 2001
|
||||
From: Hans de Goede <hdegoede@redhat.com>
|
||||
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 <hdegoede@redhat.com>
|
||||
---
|
||||
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
|
||||
|
156
0008-linuxefi-Use-common-grub_initrd_load.patch
Normal file
156
0008-linuxefi-Use-common-grub_initrd_load.patch
Normal file
@ -0,0 +1,156 @@
|
||||
From adf486860fe0d395579be8b01d4fda8b93377768 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
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 <mchang@suse.com>
|
||||
---
|
||||
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 <grub/cpu/efi/memory.h>
|
||||
#include <grub/tpm.h>
|
||||
#include <grub/safemath.h>
|
||||
+#include <grub/linux.h>
|
||||
|
||||
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
|
||||
|
338
0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch
Normal file
338
0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch
Normal file
@ -0,0 +1,338 @@
|
||||
From 749f7dee6f63217e536663aebb817aec72a65d5a Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
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 <volume-name> <encrypted-device> <key-file>
|
||||
|
||||
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 <mchang@suse.com>
|
||||
---
|
||||
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 <grub/dl.h>
|
||||
+#include <grub/command.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/i18n.h>
|
||||
+#include <grub/linux.h>
|
||||
+
|
||||
+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 <grub/emu/hostdisk.h>
|
||||
+#else
|
||||
+#include <grub/linux.h>
|
||||
#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 <grub/file.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/safemath.h>
|
||||
+#include <grub/list.h>
|
||||
|
||||
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);
|
81
0010-templates-import-etc-crypttab-to-grub.cfg.patch
Normal file
81
0010-templates-import-etc-crypttab-to-grub.cfg.patch
Normal file
@ -0,0 +1,81 @@
|
||||
From 2d3130c289b293269dcf558a26674f83f77729a6 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
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 <mchang@suse.com>
|
||||
---
|
||||
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 <http://www.gnu.org/licenses/>.
|
||||
+
|
||||
+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
|
||||
|
51
efi-set-variable-with-attrs.patch
Normal file
51
efi-set-variable-with-attrs.patch
Normal file
@ -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)
|
18
grub-install-record-pcrs.patch
Normal file
18
grub-install-record-pcrs.patch
Normal file
@ -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");
|
151
grub-read-pcr.patch
Normal file
151
grub-read-pcr.patch
Normal file
@ -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 <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/efi/tpm.h>
|
||||
+#include <grub/tpm2/tpm2.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/tpm.h>
|
||||
#include <grub/term.h>
|
||||
@@ -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;
|
||||
+}
|
41
grub-unseal-debug.patch
Normal file
41
grub-unseal-debug.patch
Normal file
@ -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 <grub/misc.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/protector.h>
|
||||
+#include <grub/time.h>
|
||||
#include <grub/tpm2/buffer.h>
|
||||
#include <grub/tpm2/internal/args.h>
|
||||
#include <grub/tpm2/mu.h>
|
||||
@@ -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++;
|
||||
|
@ -1,3 +1,59 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Sep 19 04:07:36 UTC 2022 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- 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 <mchang@suse.com>
|
||||
|
||||
- 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 <glin@suse.com>
|
||||
|
||||
- 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 <mchang@suse.com>
|
||||
|
||||
- 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 <mchang@suse.com>
|
||||
|
||||
- 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 <mchang@suse.com>
|
||||
|
||||
|
33
grub2.spec
33
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
|
||||
|
90
safe_tpm_pcr_snapshot.patch
Normal file
90
safe_tpm_pcr_snapshot.patch
Normal file
@ -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);
|
15
tpm-protector-dont-measure-sealed-key.patch
Normal file
15
tpm-protector-dont-measure-sealed-key.patch
Normal file
@ -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");
|
138
tpm-protector-export-secret-key.patch
Normal file
138
tpm-protector-export-secret-key.patch
Normal file
@ -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 <grub/tpm2/internal/args.h>
|
||||
#include <grub/tpm2/mu.h>
|
||||
#include <grub/tpm2/tpm2.h>
|
||||
+#include <grub/efi/efi.h>
|
||||
|
||||
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);
|
||||
|
235
tpm-record-pcrs.patch
Normal file
235
tpm-record-pcrs.patch
Normal file
@ -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 <grub/term.h>
|
||||
#include <grub/verify.h>
|
||||
#include <grub/dl.h>
|
||||
+#include <grub/extcmd.h>
|
||||
+#include <grub/tpm2/tpm2.h>
|
||||
+#include <grub/efi/efi.h>
|
||||
|
||||
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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user