Merge pull request #2431 from flatcar/chewi/grub-redhat-patches

sys-boot/grub: Apply Red Hat's large patch set (and drop Gentoo's)
This commit is contained in:
James Le Cuirot 2024-11-08 11:58:42 +00:00 committed by GitHub
commit 2bce0a69b9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 41489 additions and 23 deletions

View File

@ -0,0 +1 @@
- grub 2.12-flatcar3: GRUB now includes many patches from Red Hat to support Secure Boot, as well as Flatcar's own patches. The version string includes a numbered "flatcar" suffix to track changes to these additional patches. This string can be seen in the GRUB menu. ([scripts#2431](https://github.com/flatcar/scripts/pull/2431))

View File

@ -1,7 +1,11 @@
# Bump the flatcar version stated here every time we or Gentoo change patches
# Bump the flatcar version stated here every time we or Red Hat change patches
# that modify parts of GRUB that are installed to the boot partition. Reset the
# version back to 1 when the upstream GRUB version changes.
FLATCAR_VERSION=flatcar2
FLATCAR_VERSION=flatcar3
# Gentoo's patches conflict with Red Hat's patches, and none of Gentoo's patches
# affect Flatcar, so skip them all.
PATCHES=()
# Adjust the version string for Flatcar. This propagates throughout the source.
cros_pre_src_prepare_adjust_version() {

View File

@ -15,6 +15,29 @@ to use a separate repo was scrapped, and two patch files were created. The patch
files migrated only the essential commits, and dropped all the other commits, which
were either half-baked, or redundant at the point of migration.
From version 2.12, Flatcar has adopted Red Hat's large patch set. This fixes
Secure Boot on arm64 and the TPM Event Log on amd64, among many other things.
A further two patches are applied on top. One is for additional GPT
functionality, and the other is for extracting the verity root hash from the
initrd. Gentoo's upstream ebuild is used, but Gentoo's patches are discarded
because they conflict and are not relevant to Flatcar.
Finally, another patch is applied to fix the fallback mechanism, which was
accidentally broken by Red Hat's patches. This has been submitted to Red Hat in
[rhboot/grub2#195](https://github.com/rhboot/grub2/pull/195). It will hopefully
be merged soon.
## How to import the Red Hat patches
Red Hat maintains a fork of GRUB on GitHub with branches for each Fedora release. Generate a diff between the latest upstream release and the latest Fedora branch.
```
git clone https://github.com/rhboot/grub2.git grub
cd grub
git diff grub-<VERSION>..fedora-<VERSION> -- . ':(exclude).gitignore' ':(exclude)bootstrap.conf' > grub-2.12-00-redhat.patch
```
## Summary of the Flatcar patches
The patch starts with adding a new implementation of reading the GPT instead

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,112 @@
From 442b676110c35caedb57408c4a27a6ef74f4c7db Mon Sep 17 00:00:00 2001
From: James Le Cuirot <jlecuirot@microsoft.com>
Date: Thu, 24 Oct 2024 14:42:46 +0100
Subject: [PATCH 1/2] script/execute: Don't let trailing blank lines determine
the return code
grub_script_execute_sourcecode() parses and executes code one line at a
time, updating the return code each time because only the last line
determines the final status. However, trailing new lines were also
executed, masking any failure on the previous line. Fix this by only
trying to execute the command when there is actually one present.
This has presumably never been noticed because this code is not used by
regular functions, only in special cases like eval and menu entries. The
latter generally don't return at all, having booted an OS. When failing
to boot, upstream GRUB triggers the fallback mechanism regardless of the
return code.
We noticed the problem while using Red Hat's patches, which change this
behaviour to take account of the return code. In that case, a failure
takes you back to the menu rather than triggering a fallback.
Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
---
grub-core/script/execute.c | 5 ++++-
tests/grub_script_eval.in | 10 +++++++++-
2 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index c19b4bf70..e369e8318 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -935,7 +935,10 @@ grub_script_execute_sourcecode (const char *source)
break;
}
- ret = grub_script_execute (parsed_script);
+ /* Don't let trailing blank lines determine the return code. */
+ if (parsed_script->cmd)
+ ret = grub_script_execute (parsed_script);
+
grub_script_free (parsed_script);
grub_free (line);
}
diff --git a/tests/grub_script_eval.in b/tests/grub_script_eval.in
index c97b78d77..9c6211042 100644
--- a/tests/grub_script_eval.in
+++ b/tests/grub_script_eval.in
@@ -3,4 +3,12 @@
eval echo "Hello world"
valname=tst
eval $valname=hi
-echo $tst
\ No newline at end of file
+echo $tst
+
+if eval "
+false
+"; then
+ echo should have failed
+else
+ echo failed as expected
+fi
--
2.46.1
From 93eedb6cebe758db09066e084ddd2fb659ebc4fb Mon Sep 17 00:00:00 2001
From: James Le Cuirot <jlecuirot@microsoft.com>
Date: Thu, 24 Oct 2024 15:00:26 +0100
Subject: [PATCH 2/2] normal/menu: Check return code of the script when
executing a menu entry
Don't rely on grub_errno here because grub_script_execute_new_scope()
calls grub_print_error(), which always resets grub_errno back to
GRUB_ERR_NONE. It may also get reset by grub_wait_after_message().
This problem was observed when a "bad signature" error resulted in the
menu being redisplayed rather than the fallback mechanism being
triggered, although another change was also needed to fix it. This only
happens with Red Hat's patches because upstream GRUB triggers the
fallback mechanism regardless of the return code.
Signed-off-by: James Le Cuirot <jlecuirot@microsoft.com>
---
grub-core/normal/menu.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
index cda10fa8b..fd9b8c6d8 100644
--- a/grub-core/normal/menu.c
+++ b/grub-core/normal/menu.c
@@ -376,14 +376,14 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot)
if (ptr && ptr[0] && ptr[1])
grub_env_set ("default", ptr + 1);
- grub_script_execute_new_scope (entry->sourcecode, entry->argc, entry->args);
+ err = grub_script_execute_new_scope (entry->sourcecode, entry->argc, entry->args);
if (errs_before != grub_err_printed_errors)
grub_wait_after_message ();
errs_before = grub_err_printed_errors;
- if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
+ if (err == GRUB_ERR_NONE && grub_loader_is_loaded ())
/* Implicit execution of boot, only if something is loaded. */
err = grub_command_execute ("boot", 0, 0);
--
2.46.1

View File

@ -16,9 +16,9 @@ Signed-off-by: Sayan Chowdhury <schowdhury@microsoft.com>
---
diff -Naur a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
--- a/grub-core/loader/efi/linux.c 2023-10-03 12:21:48.000000000 -0000
+++ b/grub-core/loader/efi/linux.c 2024-09-12 10:18:36.454803371 -0000
@@ -34,6 +34,8 @@
--- a/grub-core/loader/efi/linux.c 2024-09-05 16:04:35.466205483 -0000
+++ b/grub-core/loader/efi/linux.c 2024-09-05 16:54:36.760503901 -0000
@@ -38,6 +38,8 @@
#include <grub/lib/cmdline.h>
#include <grub/verify.h>
@ -27,9 +27,9 @@ diff -Naur a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
GRUB_MOD_LICENSE ("GPLv3+");
static grub_dl_t my_mod;
@@ -533,7 +535,8 @@
grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
@@ -833,7 +835,8 @@
kernel = NULL;
#endif
- cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
+ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE)
@ -37,7 +37,7 @@ diff -Naur a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
linux_args = grub_malloc (cmdline_size);
if (!linux_args)
{
@@ -550,6 +553,7 @@
@@ -850,6 +853,7 @@
if (grub_errno == GRUB_ERR_NONE)
{
@ -45,29 +45,64 @@ diff -Naur a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
loaded = 1;
}
diff -Naur a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
--- a/grub-core/loader/i386/linux.c 2023-10-03 12:21:48.000000000 -0000
+++ b/grub-core/loader/i386/linux.c 2024-09-12 10:28:05.571587951 -0000
@@ -38,6 +38,8 @@
#include <grub/machine/kernel.h>
diff -Naur a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
--- a/grub-core/loader/i386/efi/linux.c 2024-09-11 15:08:38.463525457 -0000
+++ b/grub-core/loader/i386/efi/linux.c 2024-09-11 15:10:30.732085424 -0000
@@ -31,6 +31,8 @@
#include <grub/tpm.h>
#include <grub/safemath.h>
+#include <grub/verity-hash.h>
+
GRUB_MOD_LICENSE ("GPLv3+");
#ifdef GRUB_MACHINE_PCBIOS
@@ -1018,6 +1020,7 @@
goto fail;
}
static grub_dl_t my_mod;
@@ -466,7 +468,7 @@
grub_dprintf ("linux", "new lh is at %p\n", lh);
+ grub_pass_verity_hash (&lh, linux_cmdline, maximal_cmdline_size);
len = prot_file_size;
if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno)
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
grub_dprintf ("linux", "setting up cmdline\n");
- cmdline = kernel_alloc (KERNEL_MEM, lh->cmdline_size + 1,
+ cmdline = kernel_alloc (KERNEL_MEM, lh->cmdline_size + 1 + VERITY_CMDLINE_LENGTH,
GRUB_EFI_LOADER_DATA,
N_("can't allocate cmdline"));
if (!cmdline)
@@ -479,6 +481,9 @@
lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1),
GRUB_VERIFY_KERNEL_CMDLINE);
+ grub_pass_verity_hash (kernel, cmdline + sizeof (LINUX_IMAGE) - 1,
+ lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1) + VERITY_CMDLINE_LENGTH);
+
grub_dprintf ("linux", "cmdline:%s\n", cmdline);
grub_dprintf ("linux", "setting lh->cmd_line_ptr to 0x%08x\n",
LOW_U32(cmdline));
diff -Naur a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c
--- a/grub-core/loader/i386/pc/linux.c 2024-09-11 15:08:38.464525462 -0000
+++ b/grub-core/loader/i386/pc/linux.c 2024-09-11 15:12:26.552628521 -0000
@@ -38,6 +38,8 @@
#include <grub/safemath.h>
#include <grub/efi/sb.h>
+#include <grub/verity-hash.h>
+
GRUB_MOD_LICENSE ("GPLv3+");
#define GRUB_LINUX_CL_OFFSET 0x9000
@@ -358,6 +360,11 @@
if (err)
goto fail;
+ grub_pass_verity_hash (&lh,
+ (char *)grub_linux_real_chunk
+ + GRUB_LINUX_CL_OFFSET + sizeof (LINUX_IMAGE) - 1,
+ maximal_cmdline_size);
+
if (grub_linux_is_bzimage)
grub_linux_prot_target = GRUB_LINUX_BZIMAGE_ADDR;
else
diff -Naur a/include/grub/verity-hash.h b/include/grub/verity-hash.h
--- a/include/grub/verity-hash.h 1970-01-01 00:00:00.000000000 -0000
+++ b/include/grub/verity-hash.h 2024-09-12 10:18:39.993826952 -0000
+++ b/include/grub/verity-hash.h 2024-09-11 15:07:54.473295324 -0000
@@ -0,0 +1,51 @@
+/* CoreOS verity hash */
+