Sync from SUSE:SLFO:Main grub2 revision 1dac218436a6d596013e239f4ee7d9e4
This commit is contained in:
commit
5a5e453693
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
## Default LFS
|
||||
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||
*.bsp filter=lfs diff=lfs merge=lfs -text
|
||||
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.gem filter=lfs diff=lfs merge=lfs -text
|
||||
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||
*.lz filter=lfs diff=lfs merge=lfs -text
|
||||
*.lzma filter=lfs diff=lfs merge=lfs -text
|
||||
*.obscpio filter=lfs diff=lfs merge=lfs -text
|
||||
*.oxt filter=lfs diff=lfs merge=lfs -text
|
||||
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||
*.png filter=lfs diff=lfs merge=lfs -text
|
||||
*.rpm filter=lfs diff=lfs merge=lfs -text
|
||||
*.tbz filter=lfs diff=lfs merge=lfs -text
|
||||
*.tbz2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||
*.txz filter=lfs diff=lfs merge=lfs -text
|
||||
*.whl filter=lfs diff=lfs merge=lfs -text
|
||||
*.xz filter=lfs diff=lfs merge=lfs -text
|
||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
*.zst filter=lfs diff=lfs merge=lfs -text
|
68
0001-Add-grub_envblk_buf-helper-function.patch
Normal file
68
0001-Add-grub_envblk_buf-helper-function.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From a326e486bdcf99e6be973ba54c0abfb6d2d95b73 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 17 Jan 2022 17:45:00 +0800
|
||||
Subject: [PATCH 1/5] Add grub_envblk_buf helper function
|
||||
|
||||
This helps in creation and initialization of memory buffer for
|
||||
environment block of given size.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/lib/envblk.c | 12 ++++++++++++
|
||||
include/grub/lib/envblk.h | 1 +
|
||||
util/grub-editenv.c | 4 +---
|
||||
3 files changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/lib/envblk.c b/grub-core/lib/envblk.c
|
||||
index 2e4e78b132..24efbe7ffa 100644
|
||||
--- a/grub-core/lib/envblk.c
|
||||
+++ b/grub-core/lib/envblk.c
|
||||
@@ -23,6 +23,18 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/lib/envblk.h>
|
||||
|
||||
+char *
|
||||
+grub_envblk_buf (grub_size_t size)
|
||||
+{
|
||||
+ char *buf;
|
||||
+
|
||||
+ buf = grub_malloc (size);
|
||||
+ grub_memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
|
||||
+ grub_memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', size - sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
|
||||
+
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
grub_envblk_t
|
||||
grub_envblk_open (char *buf, grub_size_t size)
|
||||
{
|
||||
diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h
|
||||
index c3e6559217..83f3fcf841 100644
|
||||
--- a/include/grub/lib/envblk.h
|
||||
+++ b/include/grub/lib/envblk.h
|
||||
@@ -31,6 +31,7 @@ struct grub_envblk
|
||||
};
|
||||
typedef struct grub_envblk *grub_envblk_t;
|
||||
|
||||
+char *grub_envblk_buf (grub_size_t size);
|
||||
grub_envblk_t grub_envblk_open (char *buf, grub_size_t size);
|
||||
int grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value);
|
||||
void grub_envblk_delete (grub_envblk_t envblk, const char *name);
|
||||
diff --git a/util/grub-editenv.c b/util/grub-editenv.c
|
||||
index b8219335f7..a02d3f2a63 100644
|
||||
--- a/util/grub-editenv.c
|
||||
+++ b/util/grub-editenv.c
|
||||
@@ -210,9 +210,7 @@ create_envblk_fs (void)
|
||||
if (! fp)
|
||||
grub_util_error (_("cannot open `%s': %s"), device, strerror (errno));
|
||||
|
||||
- buf = xmalloc (size);
|
||||
- memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
|
||||
- memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', size - sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
|
||||
+ buf = grub_envblk_buf (size);
|
||||
|
||||
if (fseek (fp, offset, SEEK_SET) < 0)
|
||||
grub_util_error (_("cannot seek `%s': %s"), device, strerror (errno));
|
||||
--
|
||||
2.34.1
|
||||
|
526
0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch
Normal file
526
0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch
Normal file
@ -0,0 +1,526 @@
|
||||
From db4da8095b5ba722d22502c8d090e66816a5577d Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Garrett <mjg@redhat.com>
|
||||
Date: Fri, 6 Nov 2020 08:36:36 +0000
|
||||
Subject: [PATCH 1/9] Add support for Linux EFI stub loading on aarch64.
|
||||
|
||||
Add support for Linux EFI stub loading on aarch64.
|
||||
|
||||
v1:
|
||||
Make efi handoff the default loader for arm64 platform.
|
||||
|
||||
v2:
|
||||
The efi shim_lock verifier has been moved to grub core so local
|
||||
shim_lock protocol is no longer needed here for aarch64 efi to verify
|
||||
the loaded kernel image. From now on the framework will take care the
|
||||
verificaion, consolidating the integration of various security verifiers
|
||||
like secure boot, gpg and tpm.
|
||||
|
||||
---
|
||||
grub-core/Makefile.core.def | 4 +-
|
||||
grub-core/loader/arm64/efi/linux.c | 443 +++++++++++++++++++++++++++++
|
||||
include/grub/arm/linux.h | 9 +
|
||||
include/grub/arm64/linux.h | 10 +
|
||||
4 files changed, 465 insertions(+), 1 deletion(-)
|
||||
create mode 100644 grub-core/loader/arm64/efi/linux.c
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1854,7 +1854,7 @@
|
||||
arm_coreboot = loader/arm/linux.c;
|
||||
arm_efi = loader/efi/linux.c;
|
||||
arm_uboot = loader/arm/linux.c;
|
||||
- arm64 = loader/efi/linux.c;
|
||||
+ arm64 = loader/arm64/efi/linux.c;
|
||||
loongarch64 = loader/efi/linux.c;
|
||||
riscv32 = loader/efi/linux.c;
|
||||
riscv64 = loader/efi/linux.c;
|
||||
@@ -1922,7 +1922,7 @@
|
||||
|
||||
module = {
|
||||
name = linuxefi;
|
||||
- efi = lib/fake_module.c;
|
||||
+ x86 = lib/fake_module.c;
|
||||
enable = i386_efi;
|
||||
enable = x86_64_efi;
|
||||
};
|
||||
--- /dev/null
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -0,0 +1,411 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2013 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/charset.h>
|
||||
+#include <grub/command.h>
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/file.h>
|
||||
+#include <grub/fdt.h>
|
||||
+#include <grub/linux.h>
|
||||
+#include <grub/loader.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/cpu/linux.h>
|
||||
+#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/fdtload.h>
|
||||
+#include <grub/efi/memory.h>
|
||||
+#include <grub/efi/pe32.h>
|
||||
+#include <grub/i18n.h>
|
||||
+#include <grub/lib/cmdline.h>
|
||||
+#include <grub/verify.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
+
|
||||
+static grub_dl_t my_mod;
|
||||
+static int loaded;
|
||||
+
|
||||
+static void *kernel_addr;
|
||||
+static grub_uint64_t kernel_size;
|
||||
+static grub_uint32_t handover_offset;
|
||||
+
|
||||
+static char *linux_args;
|
||||
+static grub_uint32_t cmdline_size;
|
||||
+
|
||||
+static grub_addr_t initrd_start;
|
||||
+static grub_addr_t initrd_end;
|
||||
+
|
||||
+#pragma GCC diagnostic push
|
||||
+#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
+
|
||||
+typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_efi_linux_boot (void *kernel_address, grub_off_t offset,
|
||||
+ void *kernel_params)
|
||||
+{
|
||||
+ handover_func hf;
|
||||
+
|
||||
+ hf = (handover_func)((char *)kernel_address + offset);
|
||||
+ hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
||||
+
|
||||
+ return GRUB_ERR_BUG;
|
||||
+}
|
||||
+
|
||||
+#pragma GCC diagnostic pop
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
|
||||
+{
|
||||
+ if (lh->magic != GRUB_LINUX_ARMXX_MAGIC_SIGNATURE)
|
||||
+ return grub_error(GRUB_ERR_BAD_OS, "invalid magic number");
|
||||
+
|
||||
+ if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC)
|
||||
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
+ N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
|
||||
+
|
||||
+ grub_dprintf ("linux", "UEFI stub kernel:\n");
|
||||
+ grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+finalize_params_linux (void)
|
||||
+{
|
||||
+ grub_efi_loaded_image_t *loaded_image = NULL;
|
||||
+ int node, retval, len;
|
||||
+
|
||||
+ void *fdt;
|
||||
+
|
||||
+ fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
|
||||
+
|
||||
+ if (!fdt)
|
||||
+ goto failure;
|
||||
+
|
||||
+ node = grub_fdt_find_subnode (fdt, 0, "chosen");
|
||||
+ if (node < 0)
|
||||
+ node = grub_fdt_add_subnode (fdt, 0, "chosen");
|
||||
+
|
||||
+ if (node < 1)
|
||||
+ goto failure;
|
||||
+
|
||||
+ /* Set initrd info */
|
||||
+ if (initrd_start && initrd_end > initrd_start)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "Initrd @ %p-%p\n",
|
||||
+ (void *) initrd_start, (void *) initrd_end);
|
||||
+
|
||||
+ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
|
||||
+ initrd_start);
|
||||
+ if (retval)
|
||||
+ goto failure;
|
||||
+ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
|
||||
+ initrd_end);
|
||||
+ if (retval)
|
||||
+ goto failure;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_fdt_install() != GRUB_ERR_NONE)
|
||||
+ goto failure;
|
||||
+
|
||||
+ grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n",
|
||||
+ fdt);
|
||||
+
|
||||
+ /* Convert command line to UCS-2 */
|
||||
+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
+ if (!loaded_image)
|
||||
+ goto failure;
|
||||
+
|
||||
+ loaded_image->load_options_size = len =
|
||||
+ (grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
|
||||
+ loaded_image->load_options =
|
||||
+ grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
|
||||
+ if (!loaded_image->load_options)
|
||||
+ return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
|
||||
+
|
||||
+ loaded_image->load_options_size =
|
||||
+ 2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
|
||||
+ (grub_uint8_t *) linux_args, len, NULL);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+failure:
|
||||
+ grub_fdt_unload();
|
||||
+ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+free_params (void)
|
||||
+{
|
||||
+ grub_efi_loaded_image_t *loaded_image = NULL;
|
||||
+
|
||||
+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
+ if (loaded_image)
|
||||
+ {
|
||||
+ if (loaded_image->load_options)
|
||||
+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_efi_uintn_t)loaded_image->load_options,
|
||||
+ GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
|
||||
+ loaded_image->load_options = NULL;
|
||||
+ loaded_image->load_options_size = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_arch_efi_linux_boot_image (grub_addr_t addr,
|
||||
+ grub_size_t size __attribute__ ((unused)),
|
||||
+ char *args)
|
||||
+{
|
||||
+ grub_err_t retval;
|
||||
+
|
||||
+ retval = finalize_params_linux ();
|
||||
+ if (retval != GRUB_ERR_NONE)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ grub_dprintf ("linux", "linux command line: '%s'\n", args);
|
||||
+
|
||||
+ retval = grub_efi_linux_boot ((char *)addr, handover_offset, (void *)addr);
|
||||
+
|
||||
+ /* Never reached... */
|
||||
+ free_params();
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_linux_boot (void)
|
||||
+{
|
||||
+ return (grub_arch_efi_linux_boot_image ((grub_addr_t)kernel_addr, kernel_size, linux_args));
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_linux_unload (void)
|
||||
+{
|
||||
+ grub_dl_unref (my_mod);
|
||||
+ loaded = 0;
|
||||
+ if (initrd_start)
|
||||
+ grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start,
|
||||
+ GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start));
|
||||
+ initrd_start = initrd_end = 0;
|
||||
+ grub_free (linux_args);
|
||||
+ if (kernel_addr)
|
||||
+ grub_efi_free_pages ((grub_addr_t) kernel_addr,
|
||||
+ GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||
+ grub_fdt_unload ();
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * As per linux/Documentation/arm/Booting
|
||||
+ * ARM initrd needs to be covered by kernel linear mapping,
|
||||
+ * so place it in the first 512MB of DRAM.
|
||||
+ *
|
||||
+ * As per linux/Documentation/arm64/booting.txt
|
||||
+ * ARM64 initrd needs to be contained entirely within a 1GB aligned window
|
||||
+ * of up to 32GB of size that covers the kernel image as well.
|
||||
+ * Since the EFI stub loader will attempt to load the kernel near start of
|
||||
+ * RAM, place the buffer in the first 32GB of RAM.
|
||||
+ */
|
||||
+#ifdef __arm__
|
||||
+#define INITRD_MAX_ADDRESS_OFFSET (512U * 1024 * 1024)
|
||||
+#else /* __aarch64__ */
|
||||
+#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024)
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * This function returns a pointer to a legally allocated initrd buffer,
|
||||
+ * or NULL if unsuccessful
|
||||
+ */
|
||||
+static void *
|
||||
+allocate_initrd_mem (int initrd_pages)
|
||||
+{
|
||||
+ grub_addr_t max_addr;
|
||||
+
|
||||
+ if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE)
|
||||
+ return NULL;
|
||||
+
|
||||
+ max_addr += INITRD_MAX_ADDRESS_OFFSET - 1;
|
||||
+
|
||||
+ return grub_efi_allocate_pages_real (max_addr, initrd_pages,
|
||||
+ GRUB_EFI_ALLOCATE_MAX_ADDRESS,
|
||||
+ GRUB_EFI_LOADER_DATA);
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
+ int argc, char *argv[])
|
||||
+{
|
||||
+ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
|
||||
+ int initrd_size, initrd_pages;
|
||||
+ void *initrd_mem = NULL;
|
||||
+
|
||||
+ if (argc == 0)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (!loaded)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("you need to load the kernel first"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_initrd_init (argc, argv, &initrd_ctx))
|
||||
+ goto fail;
|
||||
+
|
||||
+ initrd_size = grub_get_initrd_size (&initrd_ctx);
|
||||
+ grub_dprintf ("linux", "Loading initrd\n");
|
||||
+
|
||||
+ initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size));
|
||||
+ initrd_mem = allocate_initrd_mem (initrd_pages);
|
||||
+
|
||||
+ if (!initrd_mem)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_initrd_load (&initrd_ctx, initrd_mem))
|
||||
+ goto fail;
|
||||
+
|
||||
+ initrd_start = (grub_addr_t) initrd_mem;
|
||||
+ initrd_end = initrd_start + initrd_size;
|
||||
+ grub_dprintf ("linux", "[addr=%p, size=0x%x]\n",
|
||||
+ (void *) initrd_start, initrd_size);
|
||||
+
|
||||
+ fail:
|
||||
+ grub_initrd_close (&initrd_ctx);
|
||||
+ if (initrd_mem && !initrd_start)
|
||||
+ grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
|
||||
+
|
||||
+ return grub_errno;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
+ int argc, char *argv[])
|
||||
+{
|
||||
+ grub_file_t file = 0;
|
||||
+ struct linux_arch_kernel_header lh;
|
||||
+ struct grub_armxx_linux_pe_header *pe;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ grub_dl_ref (my_mod);
|
||||
+
|
||||
+ if (argc == 0)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
|
||||
+ if (!file)
|
||||
+ goto fail;
|
||||
+
|
||||
+ kernel_size = grub_file_size (file);
|
||||
+
|
||||
+ if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
+
|
||||
+ grub_loader_unset();
|
||||
+
|
||||
+ grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size);
|
||||
+ kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||
+ grub_dprintf ("linux", "kernel numpages: %lld\n",
|
||||
+ (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||
+ if (!kernel_addr)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ grub_file_seek (file, 0);
|
||||
+ if (grub_file_read (file, kernel_addr, kernel_size)
|
||||
+ < (grub_int64_t) kernel_size)
|
||||
+ {
|
||||
+ if (!grub_errno)
|
||||
+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]);
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
|
||||
+
|
||||
+ pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
|
||||
+ handover_offset = pe->opt.entry_addr;
|
||||
+
|
||||
+ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
|
||||
+ linux_args = grub_malloc (cmdline_size);
|
||||
+ if (!linux_args)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
|
||||
+ err = grub_create_loader_cmdline (argc, argv,
|
||||
+ linux_args + sizeof (LINUX_IMAGE) - 1,
|
||||
+ cmdline_size,
|
||||
+ GRUB_VERIFY_KERNEL_CMDLINE);
|
||||
+ if (err)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (grub_errno == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
|
||||
+ loaded = 1;
|
||||
+ }
|
||||
+
|
||||
+fail:
|
||||
+ if (file)
|
||||
+ grub_file_close (file);
|
||||
+
|
||||
+ if (grub_errno != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_dl_unref (my_mod);
|
||||
+ loaded = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (linux_args && !loaded)
|
||||
+ grub_free (linux_args);
|
||||
+
|
||||
+ if (kernel_addr && !loaded)
|
||||
+ grub_efi_free_pages ((grub_addr_t) kernel_addr,
|
||||
+ GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||
+
|
||||
+ return grub_errno;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static grub_command_t cmd_linux, cmd_initrd;
|
||||
+
|
||||
+GRUB_MOD_INIT (linux)
|
||||
+{
|
||||
+ cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
|
||||
+ N_("Load Linux."));
|
||||
+ cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
|
||||
+ N_("Load initrd."));
|
||||
+ my_mod = mod;
|
||||
+}
|
||||
+
|
||||
+GRUB_MOD_FINI (linux)
|
||||
+{
|
||||
+ grub_unregister_command (cmd_linux);
|
||||
+ grub_unregister_command (cmd_initrd);
|
||||
+}
|
||||
--- a/include/grub/arm/linux.h
|
||||
+++ b/include/grub/arm/linux.h
|
||||
@@ -20,10 +20,22 @@
|
||||
#ifndef GRUB_ARM_LINUX_HEADER
|
||||
#define GRUB_ARM_LINUX_HEADER 1
|
||||
|
||||
+#include <grub/efi/pe32.h>
|
||||
#include "system.h"
|
||||
|
||||
#include <grub/efi/pe32.h>
|
||||
|
||||
+struct grub_arm_linux_pe_header
|
||||
+{
|
||||
+ grub_uint32_t magic;
|
||||
+ struct grub_pe32_coff_header coff;
|
||||
+ struct grub_pe32_optional_header opt;
|
||||
+};
|
||||
+
|
||||
+#if defined(__arm__)
|
||||
+# define grub_armxx_linux_pe_header grub_arm_linux_pe_header
|
||||
+#endif
|
||||
+
|
||||
#if defined GRUB_MACHINE_UBOOT
|
||||
# include <grub/uboot/uboot.h>
|
||||
# define LINUX_ADDRESS (start_of_ram + 0x8000)
|
||||
--- /dev/null
|
||||
+++ b/include/grub/arm64/linux.h
|
||||
@@ -0,0 +1,39 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2013 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/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef GRUB_ARM64_LINUX_HEADER
|
||||
+#define GRUB_ARM64_LINUX_HEADER 1
|
||||
+
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/efi/pe32.h>
|
||||
+
|
||||
+#define GRUB_LINUX_ARM64_MAGIC_SIGNATURE 0x644d5241 /* 'ARM\x64' */
|
||||
+
|
||||
+struct grub_arm64_linux_pe_header
|
||||
+{
|
||||
+ grub_uint32_t magic;
|
||||
+ struct grub_pe32_coff_header coff;
|
||||
+ struct grub_pe64_optional_header opt;
|
||||
+};
|
||||
+
|
||||
+#if defined(__aarch64__)
|
||||
+# define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE
|
||||
+# define grub_armxx_linux_pe_header grub_arm64_linux_pe_header
|
||||
+#endif
|
||||
+
|
||||
+#endif /* ! GRUB_ARM64_LINUX_HEADER */
|
215
0001-Factor-out-grub_efi_linux_boot.patch
Normal file
215
0001-Factor-out-grub_efi_linux_boot.patch
Normal file
@ -0,0 +1,215 @@
|
||||
From 82d95254ca0496c8843113665bb9a99876101025 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 8 Oct 2021 13:36:45 +0800
|
||||
Subject: [PATCH 01/11] Factor out grub_efi_linux_boot
|
||||
|
||||
Both x86 and arm64 on efi are using handover protocol to boot linux
|
||||
kernel. To enable better code reuse, factor out grub_efi_linux_boot from
|
||||
arm64 so that it can be shared with x86 platform for the common fixes.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/loader/arm64/efi/linux.c | 35 +-----------------
|
||||
grub-core/loader/efi/linux.c | 58 ++++++++++++++++++++++++++++++
|
||||
grub-core/loader/i386/efi/linux.c | 13 ++-----
|
||||
include/grub/efi/linux.h | 29 +++++++++++++++
|
||||
5 files changed, 92 insertions(+), 44 deletions(-)
|
||||
create mode 100644 grub-core/loader/efi/linux.c
|
||||
create mode 100644 include/grub/efi/linux.h
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1860,6 +1860,9 @@
|
||||
riscv64 = loader/efi/linux.c;
|
||||
emu = loader/emu/linux.c;
|
||||
common = loader/linux.c;
|
||||
+ i386_efi = loader/efi/linux_boot.c;
|
||||
+ x86_64_efi = loader/efi/linux_boot.c;
|
||||
+ arm64 = loader/efi/linux_boot.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
--- a/grub-core/loader/arm64/efi/linux.c
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/verify.h>
|
||||
+#include <grub/efi/linux.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -51,40 +52,6 @@
|
||||
static grub_addr_t initrd_start;
|
||||
static grub_addr_t initrd_end;
|
||||
|
||||
-#pragma GCC diagnostic push
|
||||
-#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
-
|
||||
-typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
|
||||
-
|
||||
-static grub_err_t
|
||||
-grub_efi_linux_boot (void *kernel_address, grub_off_t offset,
|
||||
- void *kernel_params)
|
||||
-{
|
||||
- grub_efi_loaded_image_t *loaded_image = NULL;
|
||||
- handover_func hf;
|
||||
-
|
||||
- /*
|
||||
- * Since the EFI loader is not calling the LoadImage() and StartImage()
|
||||
- * services for loading the kernel and booting respectively, it has to
|
||||
- * set the Loaded Image base address.
|
||||
- */
|
||||
- loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
- if (loaded_image)
|
||||
- loaded_image->image_base = kernel_addr;
|
||||
- else
|
||||
- grub_dprintf ("linux", "Loaded Image base address could not be set\n");
|
||||
-
|
||||
- grub_dprintf ("linux", "kernel_addr: %p handover_offset: %p params: %p\n",
|
||||
- kernel_address, (void *)(grub_efi_uintn_t)offset, kernel_params);
|
||||
- hf = (handover_func)((char *)kernel_address + offset);
|
||||
- grub_dprintf ("linux", "handover_func() = %p\n", hf);
|
||||
- hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
||||
-
|
||||
- return GRUB_ERR_BUG;
|
||||
-}
|
||||
-
|
||||
-#pragma GCC diagnostic pop
|
||||
-
|
||||
static grub_err_t
|
||||
grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
|
||||
{
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/linux.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -40,26 +41,18 @@
|
||||
|
||||
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
|
||||
|
||||
-typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *);
|
||||
-
|
||||
static grub_err_t
|
||||
grub_linuxefi_boot (void)
|
||||
{
|
||||
- handover_func hf;
|
||||
int offset = 0;
|
||||
|
||||
#ifdef __x86_64__
|
||||
offset = 512;
|
||||
#endif
|
||||
-
|
||||
- hf = (handover_func)((char *)kernel_mem + handover_offset + offset);
|
||||
-
|
||||
asm volatile ("cli");
|
||||
|
||||
- hf (grub_efi_image_handle, grub_efi_system_table, params);
|
||||
-
|
||||
- /* Not reached */
|
||||
- return GRUB_ERR_NONE;
|
||||
+ return grub_efi_linux_boot ((char *)kernel_mem, handover_offset + offset,
|
||||
+ params);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
--- /dev/null
|
||||
+++ b/include/grub/efi/linux.h
|
||||
@@ -0,0 +1,29 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2014 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/>.
|
||||
+ */
|
||||
+#ifndef GRUB_EFI_LINUX_HEADER
|
||||
+#define GRUB_EFI_LINUX_HEADER 1
|
||||
+
|
||||
+#include <grub/efi/api.h>
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/symbol.h>
|
||||
+
|
||||
+grub_err_t
|
||||
+EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset,
|
||||
+ void *kernel_param);
|
||||
+
|
||||
+#endif /* ! GRUB_EFI_LINUX_HEADER */
|
||||
--- /dev/null
|
||||
+++ b/grub-core/loader/efi/linux_boot.c
|
||||
@@ -0,0 +1,58 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2014 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/cpu/linux.h>
|
||||
+#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/pe32.h>
|
||||
+#include <grub/efi/linux.h>
|
||||
+
|
||||
+#pragma GCC diagnostic push
|
||||
+#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
+
|
||||
+typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_efi_linux_boot (void *kernel_addr, grub_off_t offset,
|
||||
+ void *kernel_params)
|
||||
+{
|
||||
+ grub_efi_loaded_image_t *loaded_image = NULL;
|
||||
+ handover_func hf;
|
||||
+
|
||||
+ /*
|
||||
+ * Since the EFI loader is not calling the LoadImage() and StartImage()
|
||||
+ * services for loading the kernel and booting respectively, it has to
|
||||
+ * set the Loaded Image base address.
|
||||
+ */
|
||||
+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
+ if (loaded_image)
|
||||
+ loaded_image->image_base = kernel_addr;
|
||||
+ else
|
||||
+ grub_dprintf ("linux", "Loaded Image base address could not be set\n");
|
||||
+
|
||||
+ grub_dprintf ("linux", "kernel_addr: %p handover_offset: %p params: %p\n",
|
||||
+ kernel_addr, (void *)(grub_efi_uintn_t)offset, kernel_params);
|
||||
+ hf = (handover_func)((char *)kernel_addr + offset);
|
||||
+ hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
||||
+
|
||||
+ return GRUB_ERR_BUG;
|
||||
+}
|
||||
+
|
||||
+#pragma GCC diagnostic pop
|
66
0001-Fix-infinite-boot-loop-on-headless-system-in-qemu.patch
Normal file
66
0001-Fix-infinite-boot-loop-on-headless-system-in-qemu.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From f76317d9dc35dbc576820ba6c2a6a8e41f5338b5 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 19 May 2022 13:08:12 +0800
|
||||
Subject: [PATCH] Fix infinite boot loop on headless system in qemu
|
||||
|
||||
After finishing headless virtual machine installation via serial
|
||||
console, the reboot fails in grub with infinte boot loop and also
|
||||
keyboard input for serial console is unresponsive.
|
||||
|
||||
The cause of infinte loop boils down to legacy vga driver in grub
|
||||
crashes when '-dispaly none' is used as qemu's display type described in
|
||||
the manual as:
|
||||
|
||||
"Do not display video output. The guest will still see an emulated
|
||||
graphics card, but its output will not be displayed tothe QEMU user.
|
||||
This option differs from the -nographic option in that it only affects
|
||||
what is done with video output; -nographic also changes the destination
|
||||
of the serial and parallel port data."
|
||||
|
||||
Given there's no sensible way found to skip the emulated device from the
|
||||
legacy vga module, we ended up removing it from all_video dependency so
|
||||
it wouldn't be loaded by default. In any case, the vbe module remain
|
||||
loaded and should fulfill the requirement of most hardwares even twenty
|
||||
years old or more.
|
||||
|
||||
The unresponsive serial input is also fixed by ensuring that console
|
||||
input is loaded via appended so that they won't fail altogether with
|
||||
errors by other console device if specifying on the same list.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/genmoddep.awk | 3 +++
|
||||
util/grub.d/00_header.in | 10 +++++++++-
|
||||
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/grub-core/genmoddep.awk
|
||||
+++ b/grub-core/genmoddep.awk
|
||||
@@ -98,6 +98,9 @@
|
||||
}
|
||||
modlist = ""
|
||||
while (getline <"video.lst") {
|
||||
+ if ($1 == "vga") {
|
||||
+ continue;
|
||||
+ }
|
||||
modlist = modlist " " $1;
|
||||
}
|
||||
printf "all_video:%s\n", modlist;
|
||||
--- a/util/grub.d/00_header.in
|
||||
+++ b/util/grub.d/00_header.in
|
||||
@@ -287,7 +287,15 @@
|
||||
;;
|
||||
x*)
|
||||
cat << EOF
|
||||
-terminal_output ${GRUB_TERMINAL_OUTPUT}
|
||||
+
|
||||
+for i in ${GRUB_TERMINAL_OUTPUT}; do
|
||||
+ if [ x\${use_append} = xtrue ]; then
|
||||
+ terminal_output --append \$i
|
||||
+ elif terminal_output \$i; then
|
||||
+ use_append=true;
|
||||
+ fi
|
||||
+done
|
||||
+
|
||||
EOF
|
||||
;;
|
||||
esac
|
286
0001-Improve-TPM-key-protection-on-boot-interruptions.patch
Normal file
286
0001-Improve-TPM-key-protection-on-boot-interruptions.patch
Normal file
@ -0,0 +1,286 @@
|
||||
From fe7ed9104cef56f9e532a0c9a7164393d5d69ae1 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 17 Nov 2023 12:32:59 +0800
|
||||
Subject: [PATCH 1/4] Improve TPM key protection on boot interruptions
|
||||
|
||||
The unattended boot process for full disk encryption relies on an
|
||||
authorized TPM policy to ensure the system's integrity before releasing
|
||||
the key to grub. Subsequently, grub assumes responsibility for securing
|
||||
the boot process, directing it towards a trusted default without any
|
||||
expected interruptions. Any interruption during this process indicates
|
||||
potential modification attempts, and releasing the obtained key to the
|
||||
next stage should not occur in such cases.
|
||||
|
||||
This commit addresses a vulnerability associated with interrupted boot
|
||||
processes that could potentially enable malicious modifications to the
|
||||
default or trusted boot target. To reinforce system security, the code
|
||||
has been updated to incorporate measures that discard the TPM protected
|
||||
key in the event of boot interruptions.
|
||||
|
||||
Furthermore, this patch aims to enhance code readability by renaming
|
||||
structures and function names related to cryptographic keys, improving
|
||||
clarity and maintainability.
|
||||
|
||||
By implementing these changes, this enhancement seeks to fortify the
|
||||
protection of TPM keys, thereby ensuring a more robust defense against
|
||||
potential unauthorized modifications during the boot process.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 38 ++++++++++++++++++++++++++---------
|
||||
grub-core/disk/cryptodisk.c | 8 +++++++-
|
||||
grub-core/loader/linux.c | 6 +++---
|
||||
grub-core/normal/main.c | 2 +-
|
||||
grub-core/normal/menu.c | 7 +++++++
|
||||
grub-core/normal/menu_entry.c | 2 +-
|
||||
include/grub/crypttab.h | 18 ++++++++++-------
|
||||
7 files changed, 59 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index c2217ca98..9397bede9 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -9,17 +9,20 @@
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
-struct grub_key_publisher *kpuber;
|
||||
+grub_crypto_key_list_t *cryptokey_lst;
|
||||
|
||||
grub_err_t
|
||||
-grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path)
|
||||
+grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey)
|
||||
{
|
||||
- struct grub_key_publisher *cur = NULL;
|
||||
+ grub_crypto_key_list_t *cur = NULL;
|
||||
|
||||
- FOR_LIST_ELEMENTS (cur, kpuber)
|
||||
+ FOR_LIST_ELEMENTS (cur, cryptokey_lst)
|
||||
if (grub_uuidcasecmp (cur->name, uuid, sizeof (cur->name)) == 0)
|
||||
break;
|
||||
|
||||
+ if (!cur && !uuid)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
if (!cur)
|
||||
cur = grub_zalloc (sizeof (*cur));
|
||||
if (!cur)
|
||||
@@ -44,21 +47,24 @@ grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len,
|
||||
cur->path = grub_strdup (path);
|
||||
}
|
||||
|
||||
+ if (is_tpmkey >= 0)
|
||||
+ cur->is_tpmkey = is_tpmkey;
|
||||
+
|
||||
if (!cur->name)
|
||||
{
|
||||
cur->name = grub_strdup (uuid);
|
||||
- grub_list_push (GRUB_AS_LIST_P (&kpuber), GRUB_AS_LIST (cur));
|
||||
+ grub_list_push (GRUB_AS_LIST_P (&cryptokey_lst), GRUB_AS_LIST (cur));
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
-grub_initrd_discard_key (void)
|
||||
+grub_cryptokey_discard (void)
|
||||
{
|
||||
- struct grub_key_publisher *cur, *nxt;
|
||||
+ grub_crypto_key_list_t *cur, *nxt;
|
||||
|
||||
- FOR_LIST_ELEMENTS_SAFE (cur, nxt, kpuber)
|
||||
+ FOR_LIST_ELEMENTS_SAFE (cur, nxt, cryptokey_lst)
|
||||
{
|
||||
grub_list_remove (GRUB_AS_LIST (cur));
|
||||
grub_memset (cur->key, 0, cur->key_len);
|
||||
@@ -69,6 +75,20 @@ grub_initrd_discard_key (void)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+grub_cryptokey_tpmkey_discard (void)
|
||||
+{
|
||||
+ grub_crypto_key_list_t *cur = NULL;
|
||||
+
|
||||
+ FOR_LIST_ELEMENTS (cur, cryptokey_lst)
|
||||
+ if (cur->is_tpmkey)
|
||||
+ break;
|
||||
+
|
||||
+ /* Discard all keys if any of them is tpm */
|
||||
+ if (cur)
|
||||
+ grub_cryptokey_discard();
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **argv)
|
||||
@@ -92,7 +112,7 @@ grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
|
||||
/*FIXME: Validate UUID string*/
|
||||
- return grub_initrd_publish_key (argv[1], NULL, 0, path);
|
||||
+ return grub_cryptokey_add_or_update (argv[1], NULL, 0, path, -1);
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index c79d4125a..d90ca06dc 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1071,6 +1071,9 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
struct cryptodisk_read_hook_ctx read_hook_data = {0};
|
||||
int askpass = 0;
|
||||
char *part = NULL;
|
||||
+#ifndef GRUB_UTIL
|
||||
+ int is_tpmkey = 0;
|
||||
+#endif
|
||||
|
||||
dev = grub_cryptodisk_get_by_source_disk (source);
|
||||
|
||||
@@ -1183,6 +1186,9 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
ret = grub_cryptodisk_insert (dev, name, source);
|
||||
if (ret != GRUB_ERR_NONE)
|
||||
goto error;
|
||||
+#ifndef GRUB_UTIL
|
||||
+ is_tpmkey = 1;
|
||||
+#endif
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
@@ -1244,7 +1250,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
if (cargs->key_data && dev)
|
||||
- grub_initrd_publish_key (dev->uuid, (const char *)cargs->key_data, cargs->key_len, NULL);
|
||||
+ grub_cryptokey_add_or_update (dev->uuid, (const char *)cargs->key_data, cargs->key_len, NULL, is_tpmkey);
|
||||
#endif
|
||||
if (askpass)
|
||||
{
|
||||
diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
|
||||
index 9ee8f3790..e5e792958 100644
|
||||
--- a/grub-core/loader/linux.c
|
||||
+++ b/grub-core/loader/linux.c
|
||||
@@ -226,13 +226,13 @@ grub_initrd_init (int argc, char *argv[],
|
||||
int i;
|
||||
int newc = 0;
|
||||
struct dir *root = 0;
|
||||
- struct grub_key_publisher *pk;
|
||||
+ grub_crypto_key_list_t *pk;
|
||||
int numkey = 0;
|
||||
|
||||
initrd_ctx->nfiles = 0;
|
||||
initrd_ctx->components = 0;
|
||||
|
||||
- FOR_LIST_ELEMENTS (pk, kpuber)
|
||||
+ FOR_LIST_ELEMENTS (pk, cryptokey_lst)
|
||||
if (pk->key && pk->path)
|
||||
numkey++;
|
||||
|
||||
@@ -305,7 +305,7 @@ grub_initrd_init (int argc, char *argv[],
|
||||
goto overflow;
|
||||
}
|
||||
|
||||
- FOR_LIST_ELEMENTS (pk, kpuber)
|
||||
+ FOR_LIST_ELEMENTS (pk, cryptokey_lst)
|
||||
if (pk->key && pk->path)
|
||||
{
|
||||
grub_initrd_component (pk->key, pk->key_len, pk->path, initrd_ctx);
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index a3f711d1d..1b426af69 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -479,7 +479,7 @@ grub_cmdline_run (int nested, int force_auth)
|
||||
return;
|
||||
}
|
||||
|
||||
- grub_initrd_discard_key ();
|
||||
+ grub_cryptokey_discard ();
|
||||
grub_normal_reader_init (nested);
|
||||
|
||||
while (1)
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
||||
index 14b0ab1ec..1df2638d7 100644
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <grub/script_sh.h>
|
||||
#include <grub/gfxterm.h>
|
||||
#include <grub/dl.h>
|
||||
+#include <grub/crypttab.h>
|
||||
|
||||
/* Time to delay after displaying an error message about a default/fallback
|
||||
entry failing to boot. */
|
||||
@@ -708,6 +709,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
if (grub_key_is_interrupt (key))
|
||||
{
|
||||
timeout = -1;
|
||||
+ grub_cryptokey_tpmkey_discard();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -790,6 +792,11 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
clear_timeout ();
|
||||
}
|
||||
|
||||
+ /* Timeout is interrupted by external input, Forget tpmkey if timeout
|
||||
+ * is not cut by enter */
|
||||
+ if (c != '\n' && c != '\r')
|
||||
+ grub_cryptokey_tpmkey_discard();
|
||||
+
|
||||
switch (c)
|
||||
{
|
||||
case GRUB_TERM_KEY_HOME:
|
||||
diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
|
||||
index 384ab9ce3..e5ba91ea4 100644
|
||||
--- a/grub-core/normal/menu_entry.c
|
||||
+++ b/grub-core/normal/menu_entry.c
|
||||
@@ -1263,7 +1263,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||
return;
|
||||
}
|
||||
|
||||
- grub_initrd_discard_key();
|
||||
+ grub_cryptokey_discard();
|
||||
|
||||
screen = make_screen (entry);
|
||||
if (! screen)
|
||||
diff --git a/include/grub/crypttab.h b/include/grub/crypttab.h
|
||||
index 113c53cfc..f86404686 100644
|
||||
--- a/include/grub/crypttab.h
|
||||
+++ b/include/grub/crypttab.h
|
||||
@@ -4,21 +4,25 @@
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
|
||||
-struct grub_key_publisher
|
||||
+typedef struct grub_crypto_key_list
|
||||
{
|
||||
- struct grub_key_publisher *next;
|
||||
- struct grub_key_publisher **prev;
|
||||
+ struct grub_crypto_key_list *next;
|
||||
+ struct grub_crypto_key_list **prev;
|
||||
char *name; /* UUID */
|
||||
char *path;
|
||||
char *key;
|
||||
grub_size_t key_len;
|
||||
-};
|
||||
+ int is_tpmkey;
|
||||
+} grub_crypto_key_list_t;
|
||||
|
||||
-extern struct grub_key_publisher *EXPORT_VAR (kpuber);
|
||||
+extern grub_crypto_key_list_t *EXPORT_VAR (cryptokey_lst);
|
||||
|
||||
grub_err_t
|
||||
-grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path);
|
||||
+grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey);
|
||||
|
||||
void
|
||||
-grub_initrd_discard_key (void);
|
||||
+grub_cryptokey_discard (void);
|
||||
+
|
||||
+void
|
||||
+grub_cryptokey_tpmkey_discard (void);
|
||||
#endif /* ! GRUB_CRYPTTAB_HEADER */
|
||||
--
|
||||
2.42.1
|
||||
|
82
0001-Make-grub.cfg-compatible-to-old-binaries.patch
Normal file
82
0001-Make-grub.cfg-compatible-to-old-binaries.patch
Normal file
@ -0,0 +1,82 @@
|
||||
From b8457f2e271917c5c83a4fee286bafedf8c5790c Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 8 Aug 2023 17:57:24 +0800
|
||||
Subject: [PATCH] Make grub.cfg compatible to old binaries
|
||||
|
||||
The new added fwsetup test in the topmost menu is always executed
|
||||
regardless older grub may not be able to handle and thus trapped in a
|
||||
boot loop between grub and fwsetup.
|
||||
|
||||
This in particular is to make sure a smooth transition if grub is rolled
|
||||
back to older release and needs to boot newer snapshots.
|
||||
|
||||
Also removing dashes in the UUID that every version released in the wild
|
||||
can handle.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub-probe.c | 20 +++++++++++++++++++-
|
||||
util/grub.d/30_uefi-firmware.in | 16 ++++++++++------
|
||||
2 files changed, 29 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/util/grub-probe.c b/util/grub-probe.c
|
||||
index e7efcc268..99c738e44 100644
|
||||
--- a/util/grub-probe.c
|
||||
+++ b/util/grub-probe.c
|
||||
@@ -290,8 +290,26 @@ probe_cryptodisk_uuid (grub_disk_t disk, char delim)
|
||||
}
|
||||
if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
{
|
||||
+ grub_size_t i, j;
|
||||
const char *uu = grub_util_cryptodisk_get_uuid (disk);
|
||||
- grub_printf ("%s%c", uu, delim);
|
||||
+ grub_size_t len = grub_strlen (uu);
|
||||
+ char *p = grub_malloc (len + 1);
|
||||
+
|
||||
+ /* Removing dash in the UUID string
|
||||
+ * This keeps old grub binary to work with newer config in a system,
|
||||
+ * especially for snapshots. It is a temporary change to make sure smooth
|
||||
+ * transition from 2.06 to 2.12-rc1 and this hunk can be removed
|
||||
+ * after 2.12-rc1 release stablized.
|
||||
+ */
|
||||
+ for (i = 0, j = 0; i < len; i++)
|
||||
+ {
|
||||
+ if (uu[i] != '-')
|
||||
+ p[j++] = uu[i];
|
||||
+ }
|
||||
+ p[j] = '\0';
|
||||
+
|
||||
+ grub_printf ("%s%c", p, delim);
|
||||
+ grub_free (p);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/util/grub.d/30_uefi-firmware.in b/util/grub.d/30_uefi-firmware.in
|
||||
index 1c2365ddb..96ff112e5 100644
|
||||
--- a/util/grub.d/30_uefi-firmware.in
|
||||
+++ b/util/grub.d/30_uefi-firmware.in
|
||||
@@ -32,11 +32,15 @@ gettext_printf "Adding boot menu entry for UEFI Firmware Settings ...\n" >&2
|
||||
|
||||
cat << EOF
|
||||
if [ "\$grub_platform" = "efi" ]; then
|
||||
- fwsetup --is-supported
|
||||
- if [ "\$?" = 0 ]; then
|
||||
- menuentry '$LABEL' \$menuentry_id_option 'uefi-firmware' {
|
||||
- fwsetup
|
||||
- }
|
||||
- fi
|
||||
+ menuentry '$LABEL' \$menuentry_id_option 'uefi-firmware' {
|
||||
+ fwsetup --is-supported
|
||||
+ if [ "\$?" = 0 ]; then
|
||||
+ fwsetup
|
||||
+ else
|
||||
+ echo "Your firmware doesn't support setup menu entry from a boot loader"
|
||||
+ echo "Press any key to return ..."
|
||||
+ read
|
||||
+ fi
|
||||
+ }
|
||||
fi
|
||||
EOF
|
||||
--
|
||||
2.41.0
|
||||
|
150
0001-Unify-the-check-to-enable-btrfs-relative-path.patch
Normal file
150
0001-Unify-the-check-to-enable-btrfs-relative-path.patch
Normal file
@ -0,0 +1,150 @@
|
||||
From 80bb1b17b3f596dbd7331cf9cb20a46c8ef9800b Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 22 Aug 2020 02:32:43 +0800
|
||||
Subject: [PATCH] Unify the check to enable btrfs relative path
|
||||
|
||||
This unified the test in grub-install and grub-mkconfig that the path to
|
||||
default or selected btrfs subvolume/snapshot is used if the root file
|
||||
system is btrfs and the config has enabled btrfs snapshot booting.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub-install.c | 67 +++++++++++++++++++++++++++------------
|
||||
util/grub-mkconfig_lib.in | 3 +-
|
||||
2 files changed, 48 insertions(+), 22 deletions(-)
|
||||
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -886,6 +886,7 @@
|
||||
const char *efi_file = NULL;
|
||||
char **grub_devices;
|
||||
grub_fs_t grub_fs;
|
||||
+ grub_fs_t root_fs;
|
||||
grub_device_t grub_dev = NULL;
|
||||
enum grub_install_plat platform;
|
||||
char *grubdir, *device_map;
|
||||
@@ -898,6 +899,8 @@
|
||||
int efidir_is_mac = 0;
|
||||
int is_prep = 0;
|
||||
const char *pkgdatadir;
|
||||
+ char *rootdir_path;
|
||||
+ char **rootdir_devices;
|
||||
|
||||
grub_util_host_init (&argc, &argv);
|
||||
product_version = xstrdup (PACKAGE_VERSION);
|
||||
@@ -911,9 +914,6 @@
|
||||
|
||||
grub_util_load_config (&config);
|
||||
|
||||
- if (config.is_suse_btrfs_snapshot_enabled)
|
||||
- use_relative_path_on_btrfs = 1;
|
||||
-
|
||||
if (!bootloader_id && config.grub_distributor)
|
||||
{
|
||||
char *ptr;
|
||||
@@ -1064,6 +1064,45 @@
|
||||
grub_hostfs_init ();
|
||||
grub_host_init ();
|
||||
|
||||
+ {
|
||||
+ char *rootdir_grub_devname;
|
||||
+ grub_device_t rootdir_grub_dev;
|
||||
+ char *t = grub_util_path_concat (2, "/", rootdir);
|
||||
+
|
||||
+ rootdir_path = grub_canonicalize_file_name (t);
|
||||
+ if (!rootdir_path)
|
||||
+ grub_util_error (_("failed to get canonical path of `%s'"), t);
|
||||
+
|
||||
+ rootdir_devices = grub_guess_root_devices (rootdir_path);
|
||||
+ if (!rootdir_devices || !rootdir_devices[0])
|
||||
+ grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
|
||||
+ rootdir_path);
|
||||
+
|
||||
+ for (curdev = rootdir_devices; *curdev; curdev++)
|
||||
+ grub_util_pull_device (*curdev);
|
||||
+
|
||||
+ rootdir_grub_devname = grub_util_get_grub_dev (rootdir_devices[0]);
|
||||
+ if (!rootdir_grub_devname)
|
||||
+ grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
|
||||
+ rootdir_devices[0]);
|
||||
+
|
||||
+ rootdir_grub_dev = grub_device_open (rootdir_grub_devname);
|
||||
+ if (! rootdir_grub_dev)
|
||||
+ grub_util_error ("%s", grub_errmsg);
|
||||
+
|
||||
+ root_fs = grub_fs_probe (rootdir_grub_dev);
|
||||
+ if (!root_fs)
|
||||
+ grub_util_error ("%s", grub_errmsg);
|
||||
+
|
||||
+ if (config.is_suse_btrfs_snapshot_enabled
|
||||
+ && grub_strncmp(root_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0)
|
||||
+ use_relative_path_on_btrfs = 1;
|
||||
+
|
||||
+ free (t);
|
||||
+ free (rootdir_grub_devname);
|
||||
+ grub_device_close (rootdir_grub_dev);
|
||||
+ }
|
||||
+
|
||||
switch (platform)
|
||||
{
|
||||
case GRUB_INSTALL_PLATFORM_I386_EFI:
|
||||
@@ -1454,8 +1493,7 @@
|
||||
debug_image);
|
||||
}
|
||||
|
||||
- if (config.is_suse_btrfs_snapshot_enabled
|
||||
- && grub_strncmp(grub_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0)
|
||||
+ if (use_relative_path_on_btrfs)
|
||||
{
|
||||
if (!load_cfg_f)
|
||||
load_cfg_f = grub_util_fopen (load_cfg, "wb");
|
||||
@@ -1669,21 +1707,13 @@
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
- if (config.is_suse_btrfs_snapshot_enabled
|
||||
- && grub_strncmp(grub_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0)
|
||||
+ if (use_relative_path_on_btrfs)
|
||||
{
|
||||
char *subvol = NULL;
|
||||
char *mount_path = NULL;
|
||||
- char **rootdir_devices = NULL;
|
||||
- char *t = grub_util_path_concat (2, "/", rootdir);
|
||||
- char *rootdir_path = grub_canonicalize_file_name (t);
|
||||
-
|
||||
- if (rootdir_path && grub_util_is_directory (rootdir_path))
|
||||
- rootdir_devices = grub_guess_root_devices (rootdir_path);
|
||||
-
|
||||
- if (rootdir_devices && rootdir_devices[0])
|
||||
- if (grub_strcmp (rootdir_devices[0], grub_devices[0]) == 0)
|
||||
- subvol = grub_util_get_btrfs_subvol (platdir, &mount_path);
|
||||
+
|
||||
+ if (grub_strcmp (rootdir_devices[0], grub_devices[0]) == 0)
|
||||
+ subvol = grub_util_get_btrfs_subvol (platdir, &mount_path);
|
||||
|
||||
if (subvol && mount_path)
|
||||
{
|
||||
@@ -1708,11 +1738,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
- free (t);
|
||||
- free (rootdir_path);
|
||||
- for (curdev = rootdir_devices; *curdev; curdev++)
|
||||
- free (*curdev);
|
||||
- free (rootdir_devices);
|
||||
free (subvol);
|
||||
free (mount_path);
|
||||
}
|
||||
--- a/util/grub-mkconfig_lib.in
|
||||
+++ b/util/grub-mkconfig_lib.in
|
||||
@@ -49,7 +49,8 @@
|
||||
|
||||
make_system_path_relative_to_its_root ()
|
||||
{
|
||||
- if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] ; then
|
||||
+ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] &&
|
||||
+ [ "x${GRUB_FS}" = "xbtrfs" ] ; then
|
||||
"${grub_mkrelpath}" -r "$1"
|
||||
else
|
||||
"${grub_mkrelpath}" "$1"
|
289
0001-Workaround-volatile-efi-boot-variable.patch
Normal file
289
0001-Workaround-volatile-efi-boot-variable.patch
Normal file
@ -0,0 +1,289 @@
|
||||
From 71575829c303fe8522b46fc96b1f99f1aa4178e7 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 19 Mar 2021 22:58:45 +0800
|
||||
Subject: [PATCH] Workaround volatile efi boot variable
|
||||
|
||||
The efi variable in Microsoft Azure virtual machine is volatile that it cannot
|
||||
persist across power cycling. If we use efi variable to communicate with efi
|
||||
boot manager for booting a distribution, the process would silently fail as the
|
||||
default loader in the efi system partition will start to take over the process
|
||||
whenever the efi variable evaporated.
|
||||
|
||||
That will lead to undefined symbol error one day as the default path didn't
|
||||
receive any grub update so it cannot keep up with new ABI requirement by
|
||||
updated grub modules.
|
||||
|
||||
The patch will try to workaround the problem by providing grub update to the
|
||||
default path along with the distribution specific one. To avoid negative side
|
||||
effects of inadvertently overwritting other loader intended in default path,
|
||||
care must be taken to ensure that:
|
||||
|
||||
1. The workaround only takes place on detected Azure virtual machine
|
||||
2. The default path is not in use by shim for the secure boot
|
||||
---
|
||||
Makefile.util.def | 1 +
|
||||
.../osdep/basic/efi_removable_fallback.c | 26 +++
|
||||
grub-core/osdep/efi_removable_fallback.c | 5 +
|
||||
.../osdep/linux/efi_removable_fallback.c | 151 ++++++++++++++++++
|
||||
include/grub/util/install.h | 3 +
|
||||
util/grub-install.c | 19 +++
|
||||
6 files changed, 205 insertions(+)
|
||||
create mode 100644 grub-core/osdep/basic/efi_removable_fallback.c
|
||||
create mode 100644 grub-core/osdep/efi_removable_fallback.c
|
||||
create mode 100644 grub-core/osdep/linux/efi_removable_fallback.c
|
||||
|
||||
--- a/Makefile.util.def
|
||||
+++ b/Makefile.util.def
|
||||
@@ -681,6 +681,9 @@
|
||||
common = grub-core/osdep/journaled_fs.c;
|
||||
extra_dist = grub-core/osdep/basic/journaled_fs.c;
|
||||
extra_dist = grub-core/osdep/linux/journaled_fs.c;
|
||||
+ common = grub-core/osdep/efi_removable_fallback.c;
|
||||
+ extra_dist = grub-core/osdep/basic/efi_removable_fallback.c;
|
||||
+ extra_dist = grub-core/osdep/linux/efi_removable_fallback.c;
|
||||
|
||||
ldadd = '$(LIBLZMA)';
|
||||
ldadd = libgrubmods.a;
|
||||
--- /dev/null
|
||||
+++ b/grub-core/osdep/basic/efi_removable_fallback.c
|
||||
@@ -0,0 +1,26 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2013 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/util/install.h>
|
||||
+
|
||||
+const char *
|
||||
+grub_install_efi_removable_fallback (const char *efidir, enum grub_install_plat platform)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/grub-core/osdep/efi_removable_fallback.c
|
||||
@@ -0,0 +1,5 @@
|
||||
+#ifdef __linux__
|
||||
+#include "linux/efi_removable_fallback.c"
|
||||
+#else
|
||||
+#include "basic/efi_removable_fallback.c"
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/grub-core/osdep/linux/efi_removable_fallback.c
|
||||
@@ -0,0 +1,151 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2013 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <config.h>
|
||||
+
|
||||
+#include <grub/util/install.h>
|
||||
+#include <grub/emu/exec.h>
|
||||
+#include <grub/emu/misc.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+static char *
|
||||
+get_dmi_id (const char *id)
|
||||
+{
|
||||
+ FILE *fp;
|
||||
+ char *buf = NULL;
|
||||
+ size_t len = 0;
|
||||
+
|
||||
+ char *dmi_entry;
|
||||
+
|
||||
+ dmi_entry = grub_util_path_concat (2, "/sys/class/dmi/id", id);
|
||||
+
|
||||
+ fp = grub_util_fopen (dmi_entry, "r");
|
||||
+ if (!fp)
|
||||
+ {
|
||||
+ free (dmi_entry);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (getline (&buf, &len, fp) == -1)
|
||||
+ {
|
||||
+ fclose (fp);
|
||||
+ free (dmi_entry);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ fclose (fp);
|
||||
+ free (dmi_entry);
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static struct dmi {
|
||||
+ const char *id;
|
||||
+ const char *val;
|
||||
+} azure_dmi [3] = {
|
||||
+ {"bios_vendor", "Microsoft Corporation"},
|
||||
+ {"product_name", "Virtual Machine"},
|
||||
+ {"sys_vendor", "Microsoft Corporation"},
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+is_azure (void)
|
||||
+{
|
||||
+ int i;
|
||||
+ int n = sizeof (azure_dmi) / sizeof (struct dmi);
|
||||
+
|
||||
+ for (i = 0; i < n; ++i)
|
||||
+ {
|
||||
+ char *val;
|
||||
+
|
||||
+ val = get_dmi_id (azure_dmi[i].id);
|
||||
+ if (!val)
|
||||
+ break;
|
||||
+ if (strncmp (val, azure_dmi[i].val, strlen (azure_dmi[i].val)) != 0)
|
||||
+ {
|
||||
+ free (val);
|
||||
+ break;
|
||||
+ }
|
||||
+ free (val);
|
||||
+ }
|
||||
+
|
||||
+ return (i == n) ? 1 : 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+guess_shim_installed (const char *instdir)
|
||||
+{
|
||||
+ const char *shim[] = {"fallback.efi", "MokManager.efi", NULL};
|
||||
+ const char **s;
|
||||
+
|
||||
+ for (s = shim; *s ; ++s)
|
||||
+ {
|
||||
+ char *p = grub_util_path_concat (2, instdir, *s);
|
||||
+
|
||||
+ if (access (p, F_OK) == 0)
|
||||
+ {
|
||||
+ free (p);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ free (p);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+const char *
|
||||
+grub_install_efi_removable_fallback (const char *efidir, enum grub_install_plat platform)
|
||||
+{
|
||||
+ char *instdir;
|
||||
+
|
||||
+ if (!is_azure ())
|
||||
+ return NULL;
|
||||
+
|
||||
+ instdir = grub_util_path_concat (3, efidir, "EFI", "BOOT");
|
||||
+
|
||||
+ if (guess_shim_installed (instdir))
|
||||
+ {
|
||||
+ grub_util_info ("skip removable fallback occupied by shim");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ free (instdir);
|
||||
+
|
||||
+ switch (platform)
|
||||
+ {
|
||||
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
|
||||
+ return "BOOTIA32.EFI";
|
||||
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
|
||||
+ return "BOOTX64.EFI";
|
||||
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
|
||||
+ return "BOOTIA64.EFI";
|
||||
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
|
||||
+ return "BOOTARM.EFI";
|
||||
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
|
||||
+ return "BOOTAA64.EFI";
|
||||
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
|
||||
+ return "BOOTRISCV32.EFI";
|
||||
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
|
||||
+ return "BOOTRISCV64.EFI";
|
||||
+ default:
|
||||
+ grub_util_error ("%s", _("You've found a bug"));
|
||||
+ break;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -303,4 +303,7 @@
|
||||
|
||||
int
|
||||
grub_install_sync_fs_journal (const char *path);
|
||||
+
|
||||
+const char *
|
||||
+grub_install_efi_removable_fallback (const char *efidir, enum grub_install_plat platform);
|
||||
#endif
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -901,6 +901,7 @@
|
||||
const char *pkgdatadir;
|
||||
char *rootdir_path;
|
||||
char **rootdir_devices;
|
||||
+ char *efidir_root;
|
||||
|
||||
grub_util_host_init (&argc, &argv);
|
||||
product_version = xstrdup (PACKAGE_VERSION);
|
||||
@@ -1175,6 +1176,7 @@
|
||||
}
|
||||
if (!efidir)
|
||||
grub_util_error ("%s", _("cannot find EFI directory"));
|
||||
+ efidir_root = grub_strdup (efidir);
|
||||
efidir_device_names = grub_guess_root_devices (efidir);
|
||||
if (!efidir_device_names || !efidir_device_names[0])
|
||||
grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
|
||||
@@ -2217,6 +2219,23 @@
|
||||
free (grub_efi_cfg);
|
||||
}
|
||||
}
|
||||
+ if (!removable)
|
||||
+ {
|
||||
+ const char *f;
|
||||
+
|
||||
+ f = grub_install_efi_removable_fallback (efidir_root, platform);
|
||||
+ if (f)
|
||||
+ {
|
||||
+ char *t = grub_util_path_concat (3, efidir_root, "EFI", "BOOT");
|
||||
+ char *dst = grub_util_path_concat (2, t, f);
|
||||
+
|
||||
+ grub_install_mkdir_p (t);
|
||||
+ fprintf (stderr, _("Install to %s as fallback.\n"), dst);
|
||||
+ grub_install_copy_file (imgfile, dst, 1);
|
||||
+ grub_free (t);
|
||||
+ grub_free (dst);
|
||||
+ }
|
||||
+ }
|
||||
if (!removable && update_nvram)
|
||||
{
|
||||
char * efifile_path;
|
4923
0001-add-support-for-UEFI-network-protocols.patch
Normal file
4923
0001-add-support-for-UEFI-network-protocols.patch
Normal file
File diff suppressed because it is too large
Load Diff
179
0001-arm64-Fix-EFI-loader-kernel-image-allocation.patch
Normal file
179
0001-arm64-Fix-EFI-loader-kernel-image-allocation.patch
Normal file
@ -0,0 +1,179 @@
|
||||
From 10d0f70ac194931c63f2cbd6fdebd6697abae992 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Date: Mon, 2 Aug 2021 23:10:01 +1000
|
||||
Subject: [PATCH 1/2] arm64: Fix EFI loader kernel image allocation
|
||||
|
||||
We are currently allocating just enough memory for the file size,
|
||||
which means that the kernel BSS is in limbo (and not even zeroed).
|
||||
|
||||
We are also not honoring the alignment specified in the image
|
||||
PE header.
|
||||
|
||||
This makes us use the PE optional header in which the kernel puts the
|
||||
actual size it needs, including BSS, and make sure we clear it, and
|
||||
honors the specified alignment for the image.
|
||||
|
||||
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
---
|
||||
grub-core/loader/arm64/efi/linux.c | 92 ++++++++++++++++++++----------
|
||||
1 file changed, 63 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||
index b73105347..4da49a182 100644
|
||||