forked from pool/grub2
Accepting request 867030 from home:michael-chang:branches:Base:System
- Secure Boot support in GRUB on aarch64 (jsc#SLE-15864) * 0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch * 0002-arm64-make-sure-fdt-has-address-cells-and-size-cells.patch * 0003-Make-grub_error-more-verbose.patch * 0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch * 0005-Make-linux_arm_kernel_header.hdr_offset-be-at-the-ri.patch * 0006-efi-Set-image-base-address-before-jumping-to-the-PE-.patch * 0007-linuxefi-fail-kernel-validation-without-shim-protoco.patch * 0008-squash-Add-support-for-Linux-EFI-stub-loading-on-aar.patch OBS-URL: https://build.opensuse.org/request/show/867030 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=369
This commit is contained in:
parent
18241ef23c
commit
5a314d1a22
544
0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch
Normal file
544
0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch
Normal file
@ -0,0 +1,544 @@
|
|||||||
|
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/8] Add support for Linux EFI stub loading on aarch64.
|
||||||
|
|
||||||
|
Add support for Linux EFI stub loading on aarch64.
|
||||||
|
---
|
||||||
|
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
|
||||||
|
|
||||||
|
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||||
|
index 3ea9dace0..cfdd31431 100644
|
||||||
|
--- a/grub-core/Makefile.core.def
|
||||||
|
+++ b/grub-core/Makefile.core.def
|
||||||
|
@@ -1854,9 +1854,11 @@ module = {
|
||||||
|
|
||||||
|
module = {
|
||||||
|
name = linuxefi;
|
||||||
|
- efi = lib/fake_module.c;
|
||||||
|
+ x86 = lib/fake_module.c;
|
||||||
|
+ arm64 = loader/arm64/efi/linux.c;
|
||||||
|
enable = i386_efi;
|
||||||
|
enable = x86_64_efi;
|
||||||
|
+ enable = arm64_efi;
|
||||||
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
new file mode 100644
|
||||||
|
index 000000000..d81a6d843
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
@@ -0,0 +1,443 @@
|
||||||
|
+/*
|
||||||
|
+ * 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;
|
||||||
|
+
|
||||||
|
+#define SHIM_LOCK_GUID \
|
||||||
|
+ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} }
|
||||||
|
+
|
||||||
|
+struct grub_efi_shim_lock
|
||||||
|
+{
|
||||||
|
+ grub_efi_status_t (*verify) (void *buffer, grub_uint32_t size);
|
||||||
|
+};
|
||||||
|
+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
|
||||||
|
+
|
||||||
|
+static grub_efi_boolean_t
|
||||||
|
+grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
|
||||||
|
+{
|
||||||
|
+ grub_efi_guid_t guid = SHIM_LOCK_GUID;
|
||||||
|
+ grub_efi_shim_lock_t *shim_lock;
|
||||||
|
+
|
||||||
|
+ shim_lock = grub_efi_locate_protocol(&guid, NULL);
|
||||||
|
+
|
||||||
|
+ if (!shim_lock)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
|
||||||
|
+ return 1;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#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
|
||||||
|
+
|
||||||
|
+/* FIXME: This is copy of grub_arch_efi_linux_check_image () */
|
||||||
|
+static grub_err_t
|
||||||
|
+grub_arch_efi_linux_check_image_XX (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;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* FIXME: This is to replace grub_arch_efi_linux_boot_image */
|
||||||
|
+static grub_err_t
|
||||||
|
+grub_arch_efi_linux_boot_image_XX (grub_addr_t addr, 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_XX ((grub_addr_t)kernel_addr, 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, argv, 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_XX (&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);
|
||||||
|
+
|
||||||
|
+ if (!grub_linuxefi_secure_validate (kernel_addr, kernel_size))
|
||||||
|
+ {
|
||||||
|
+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ 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 ("linuxefi", grub_cmd_linux, 0,
|
||||||
|
+ N_("Load Linux."));
|
||||||
|
+ cmd_initrd = grub_register_command ("initrdefi", grub_cmd_initrd, 0,
|
||||||
|
+ N_("Load initrd."));
|
||||||
|
+ my_mod = mod;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+GRUB_MOD_FINI (linux)
|
||||||
|
+{
|
||||||
|
+ grub_unregister_command (cmd_linux);
|
||||||
|
+ grub_unregister_command (cmd_initrd);
|
||||||
|
+}
|
||||||
|
diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
|
||||||
|
index 2e98a6689..775297db8 100644
|
||||||
|
--- a/include/grub/arm/linux.h
|
||||||
|
+++ b/include/grub/arm/linux.h
|
||||||
|
@@ -20,6 +20,7 @@
|
||||||
|
#ifndef GRUB_ARM_LINUX_HEADER
|
||||||
|
#define GRUB_ARM_LINUX_HEADER 1
|
||||||
|
|
||||||
|
+#include <grub/efi/pe32.h>
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
#define GRUB_LINUX_ARM_MAGIC_SIGNATURE 0x016f2818
|
||||||
|
@@ -34,9 +35,17 @@ struct linux_arm_kernel_header {
|
||||||
|
grub_uint32_t hdr_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
+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_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE
|
||||||
|
# define linux_arch_kernel_header linux_arm_kernel_header
|
||||||
|
+# define grub_armxx_linux_pe_header grub_arm_linux_pe_header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined GRUB_MACHINE_UBOOT
|
||||||
|
diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h
|
||||||
|
index 4269adc6d..a3be9dd70 100644
|
||||||
|
--- a/include/grub/arm64/linux.h
|
||||||
|
+++ b/include/grub/arm64/linux.h
|
||||||
|
@@ -19,6 +19,8 @@
|
||||||
|
#ifndef GRUB_ARM64_LINUX_HEADER
|
||||||
|
#define GRUB_ARM64_LINUX_HEADER 1
|
||||||
|
|
||||||
|
+#include <grub/efi/pe32.h>
|
||||||
|
+
|
||||||
|
#define GRUB_LINUX_ARM64_MAGIC_SIGNATURE 0x644d5241 /* 'ARM\x64' */
|
||||||
|
|
||||||
|
/* From linux/Documentation/arm64/booting.txt */
|
||||||
|
@@ -36,9 +38,17 @@ struct linux_arm64_kernel_header
|
||||||
|
grub_uint32_t hdr_offset; /* Offset of PE/COFF header */
|
||||||
|
};
|
||||||
|
|
||||||
|
+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 linux_arch_kernel_header linux_arm64_kernel_header
|
||||||
|
+# define grub_armxx_linux_pe_header grub_arm64_linux_pe_header
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* ! GRUB_ARM64_LINUX_HEADER */
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
From e27acddebd30175587155613042abffd2e9a5de8 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Mark Salter <msalter@redhat.com>
|
||||||
|
Date: Mon, 17 Apr 2017 08:44:29 -0400
|
||||||
|
Subject: [PATCH 2/8] arm64: make sure fdt has #address-cells and #size-cells
|
||||||
|
properties
|
||||||
|
|
||||||
|
Recent upstream changes to kexec-tools relies on #address-cells
|
||||||
|
and #size-cells properties in the FDT. If grub2 needs to create
|
||||||
|
a chosen node, it is likely because firmware did not provide one.
|
||||||
|
In that case, set #address-cells and #size-cells properties to
|
||||||
|
make sure they exist.
|
||||||
|
---
|
||||||
|
grub-core/loader/arm64/efi/linux.c | 16 +++++++++++++++-
|
||||||
|
1 file changed, 15 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
index d81a6d843..98c4f038b 100644
|
||||||
|
--- a/grub-core/loader/arm64/efi/linux.c
|
||||||
|
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
@@ -126,7 +126,21 @@ finalize_params_linux (void)
|
||||||
|
|
||||||
|
node = grub_fdt_find_subnode (fdt, 0, "chosen");
|
||||||
|
if (node < 0)
|
||||||
|
- node = grub_fdt_add_subnode (fdt, 0, "chosen");
|
||||||
|
+ {
|
||||||
|
+ /*
|
||||||
|
+ * If we have to create a chosen node, Make sure we
|
||||||
|
+ * have #address-cells and #size-cells properties.
|
||||||
|
+ */
|
||||||
|
+ retval = grub_fdt_set_prop32(fdt, 0, "#address-cells", 2);
|
||||||
|
+ if (retval)
|
||||||
|
+ goto failure;
|
||||||
|
+
|
||||||
|
+ retval = grub_fdt_set_prop32(fdt, 0, "#size-cells", 2);
|
||||||
|
+ if (retval)
|
||||||
|
+ goto failure;
|
||||||
|
+
|
||||||
|
+ node = grub_fdt_add_subnode (fdt, 0, "chosen");
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (node < 1)
|
||||||
|
goto failure;
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
101
0003-Make-grub_error-more-verbose.patch
Normal file
101
0003-Make-grub_error-more-verbose.patch
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
From 3526c4e467ee01a3cfd2f4d627433d078a1ab780 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Mon, 27 Aug 2018 13:14:06 -0400
|
||||||
|
Subject: [PATCH 3/8] Make grub_error() more verbose
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
---
|
||||||
|
grub-core/kern/efi/mm.c | 17 ++++++++++++++---
|
||||||
|
grub-core/kern/err.c | 13 +++++++++++--
|
||||||
|
include/grub/err.h | 5 ++++-
|
||||||
|
3 files changed, 29 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
|
||||||
|
index a9e37108c..15595a46e 100644
|
||||||
|
--- a/grub-core/kern/efi/mm.c
|
||||||
|
+++ b/grub-core/kern/efi/mm.c
|
||||||
|
@@ -157,12 +157,20 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
||||||
|
|
||||||
|
/* Limit the memory access to less than 4GB for 32-bit platforms. */
|
||||||
|
if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
|
||||||
|
- return 0;
|
||||||
|
+ {
|
||||||
|
+ grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||||
|
+ N_("invalid memory address (0x%llx > 0x%llx)"),
|
||||||
|
+ address, GRUB_EFI_MAX_USABLE_ADDRESS);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
- return 0;
|
||||||
|
+ {
|
||||||
|
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
if (address == 0)
|
||||||
|
{
|
||||||
|
@@ -172,7 +180,10 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
||||||
|
status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
||||||
|
grub_efi_free_pages (0, pages);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
- return 0;
|
||||||
|
+ {
|
||||||
|
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_efi_store_alloc (address, pages);
|
||||||
|
diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c
|
||||||
|
index 53c734de7..aebfe0cf8 100644
|
||||||
|
--- a/grub-core/kern/err.c
|
||||||
|
+++ b/grub-core/kern/err.c
|
||||||
|
@@ -33,15 +33,24 @@ static struct grub_error_saved grub_error_stack_items[GRUB_ERROR_STACK_SIZE];
|
||||||
|
static int grub_error_stack_pos;
|
||||||
|
static int grub_error_stack_assert;
|
||||||
|
|
||||||
|
+#ifdef grub_error
|
||||||
|
+#undef grub_error
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
grub_err_t
|
||||||
|
-grub_error (grub_err_t n, const char *fmt, ...)
|
||||||
|
+grub_error (grub_err_t n, const char *file, const int line, const char *fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
+ int m;
|
||||||
|
|
||||||
|
grub_errno = n;
|
||||||
|
|
||||||
|
+ m = grub_snprintf (grub_errmsg, sizeof (grub_errmsg), "%s:%d:", file, line);
|
||||||
|
+ if (m < 0)
|
||||||
|
+ m = 0;
|
||||||
|
+
|
||||||
|
va_start (ap, fmt);
|
||||||
|
- grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap);
|
||||||
|
+ grub_vsnprintf (grub_errmsg + m, sizeof (grub_errmsg) - m, _(fmt), ap);
|
||||||
|
va_end (ap);
|
||||||
|
|
||||||
|
return n;
|
||||||
|
diff --git a/include/grub/err.h b/include/grub/err.h
|
||||||
|
index 24ba9f5f5..b68bbec3c 100644
|
||||||
|
--- a/include/grub/err.h
|
||||||
|
+++ b/include/grub/err.h
|
||||||
|
@@ -85,7 +85,10 @@ struct grub_error_saved
|
||||||
|
extern grub_err_t EXPORT_VAR(grub_errno);
|
||||||
|
extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG];
|
||||||
|
|
||||||
|
-grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...);
|
||||||
|
+grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *file, const int line, const char *fmt, ...);
|
||||||
|
+
|
||||||
|
+#define grub_error(n, fmt, ...) grub_error (n, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||||
|
+
|
||||||
|
void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn));
|
||||||
|
void EXPORT_FUNC(grub_error_push) (void);
|
||||||
|
int EXPORT_FUNC(grub_error_pop) (void);
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
308
0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch
Normal file
308
0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch
Normal file
@ -0,0 +1,308 @@
|
|||||||
|
From 5d417346956bc3108183020a8a9f20ddda034b48 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 11 Jul 2019 14:38:57 +0200
|
||||||
|
Subject: [PATCH 4/8] arm/arm64 loader: Better memory allocation and error
|
||||||
|
messages.
|
||||||
|
|
||||||
|
On mustang, our memory map looks like:
|
||||||
|
|
||||||
|
Type Physical start - end #Pages Size Attributes
|
||||||
|
reserved 0000004000000000-00000040001fffff 00000200 2MiB UC WC WT WB
|
||||||
|
conv-mem 0000004000200000-0000004393ffffff 00393e00 14654MiB UC WC WT WB
|
||||||
|
ldr-code 0000004394000000-00000043f7ffffff 00064000 1600MiB UC WC WT WB
|
||||||
|
BS-data 00000043f8000000-00000043f801ffff 00000020 128KiB UC WC WT WB
|
||||||
|
conv-mem 00000043f8020000-00000043fa15bfff 0000213c 34032KiB UC WC WT WB
|
||||||
|
ldr-code 00000043fa15c000-00000043fa2a1fff 00000146 1304KiB UC WC WT WB
|
||||||
|
ldr-data 00000043fa2a2000-00000043fa3e8fff 00000147 1308KiB UC WC WT WB
|
||||||
|
conv-mem 00000043fa3e9000-00000043fa3e9fff 00000001 4KiB UC WC WT WB
|
||||||
|
ldr-data 00000043fa3ea000-00000043fa3eafff 00000001 4KiB UC WC WT WB
|
||||||
|
ldr-code 00000043fa3eb000-00000043fa4affff 000000c5 788KiB UC WC WT WB
|
||||||
|
BS-code 00000043fa4b0000-00000043fa59ffff 000000f0 960KiB UC WC WT WB
|
||||||
|
RT-code 00000043fa5a0000-00000043fa5affff 00000010 64KiB RT UC WC WT WB
|
||||||
|
RT-data 00000043fa5b0000-00000043fa5bffff 00000010 64KiB RT UC WC WT WB
|
||||||
|
RT-code 00000043fa5c0000-00000043fa5cffff 00000010 64KiB RT UC WC WT WB
|
||||||
|
ldr-data 00000043fa5d0000-00000043fa5d0fff 00000001 4KiB UC WC WT WB
|
||||||
|
BS-code 00000043fa5d1000-00000043fa5ddfff 0000000d 52KiB UC WC WT WB
|
||||||
|
reserved 00000043fa5de000-00000043fa60ffff 00000032 200KiB UC WC WT WB
|
||||||
|
ACPI-rec 00000043fa610000-00000043fa6affff 000000a0 640KiB UC WC WT WB
|
||||||
|
ACPI-nvs 00000043fa6b0000-00000043fa6bffff 00000010 64KiB UC WC WT WB
|
||||||
|
ACPI-rec 00000043fa6c0000-00000043fa70ffff 00000050 320KiB UC WC WT WB
|
||||||
|
RT-code 00000043fa710000-00000043fa72ffff 00000020 128KiB RT UC WC WT WB
|
||||||
|
RT-data 00000043fa730000-00000043fa78ffff 00000060 384KiB RT UC WC WT WB
|
||||||
|
RT-code 00000043fa790000-00000043fa79ffff 00000010 64KiB RT UC WC WT WB
|
||||||
|
RT-data 00000043fa7a0000-00000043fa99ffff 00000200 2MiB RT UC WC WT WB
|
||||||
|
RT-code 00000043fa9a0000-00000043fa9affff 00000010 64KiB RT UC WC WT WB
|
||||||
|
RT-data 00000043fa9b0000-00000043fa9cffff 00000020 128KiB RT UC WC WT WB
|
||||||
|
BS-code 00000043fa9d0000-00000043fa9d9fff 0000000a 40KiB UC WC WT WB
|
||||||
|
reserved 00000043fa9da000-00000043fa9dbfff 00000002 8KiB UC WC WT WB
|
||||||
|
conv-mem 00000043fa9dc000-00000043fc29dfff 000018c2 25352KiB UC WC WT WB
|
||||||
|
BS-data 00000043fc29e000-00000043fc78afff 000004ed 5044KiB UC WC WT WB
|
||||||
|
conv-mem 00000043fc78b000-00000043fca01fff 00000277 2524KiB UC WC WT WB
|
||||||
|
BS-data 00000043fca02000-00000043fcea3fff 000004a2 4744KiB UC WC WT WB
|
||||||
|
conv-mem 00000043fcea4000-00000043fcea4fff 00000001 4KiB UC WC WT WB
|
||||||
|
BS-data 00000043fcea5000-00000043fd192fff 000002ee 3000KiB UC WC WT WB
|
||||||
|
conv-mem 00000043fd193000-00000043fd2b0fff 0000011e 1144KiB UC WC WT WB
|
||||||
|
BS-data 00000043fd2b1000-00000043ff80ffff 0000255f 38268KiB UC WC WT WB
|
||||||
|
BS-code 00000043ff810000-00000043ff99ffff 00000190 1600KiB UC WC WT WB
|
||||||
|
RT-code 00000043ff9a0000-00000043ff9affff 00000010 64KiB RT UC WC WT WB
|
||||||
|
conv-mem 00000043ff9b0000-00000043ff9bffff 00000010 64KiB UC WC WT WB
|
||||||
|
RT-data 00000043ff9c0000-00000043ff9effff 00000030 192KiB RT UC WC WT WB
|
||||||
|
conv-mem 00000043ff9f0000-00000043ffa05fff 00000016 88KiB UC WC WT WB
|
||||||
|
BS-data 00000043ffa06000-00000043ffffffff 000005fa 6120KiB UC WC WT WB
|
||||||
|
MMIO 0000000010510000-0000000010510fff 00000001 4KiB RT
|
||||||
|
MMIO 0000000010548000-0000000010549fff 00000002 8KiB RT
|
||||||
|
MMIO 0000000017000000-0000000017001fff 00000002 8KiB RT
|
||||||
|
MMIO 000000001c025000-000000001c025fff 00000001 4KiB RT
|
||||||
|
|
||||||
|
This patch adds a requirement when we're trying to find the base of ram, that
|
||||||
|
the memory we choose is actually /allocatable/ conventional memory, not merely
|
||||||
|
write-combining. On this machine that means we wind up with an allocation
|
||||||
|
around 0x4392XXXXXX, which is a reasonable address.
|
||||||
|
|
||||||
|
This also changes grub_efi_allocate_pages_real() so that if 0 is allocated, it
|
||||||
|
tries to allocate again starting with the same max address it did the first
|
||||||
|
time, rather than interposing GRUB_EFI_MAX_USABLE_ADDRESS there, so that any
|
||||||
|
per-platform constraints on its given address are maintained.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
|
||||||
|
squash! arm/arm64 loader: Better memory allocation and error messages.
|
||||||
|
|
||||||
|
Use PRIxGRUB_* conversion specifier in printf's format string to
|
||||||
|
correspond properly to the data type of arguments.
|
||||||
|
|
||||||
|
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||||
|
---
|
||||||
|
grub-core/kern/efi/mm.c | 33 ++++++++++---
|
||||||
|
grub-core/loader/arm64/efi/linux.c | 78 ++++++++++++++++++++++--------
|
||||||
|
2 files changed, 84 insertions(+), 27 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
|
||||||
|
index 15595a46e..324e1dca0 100644
|
||||||
|
--- a/grub-core/kern/efi/mm.c
|
||||||
|
+++ b/grub-core/kern/efi/mm.c
|
||||||
|
@@ -154,6 +154,7 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
||||||
|
{
|
||||||
|
grub_efi_status_t status;
|
||||||
|
grub_efi_boot_services_t *b;
|
||||||
|
+ grub_efi_physical_address_t ret = address;
|
||||||
|
|
||||||
|
/* Limit the memory access to less than 4GB for 32-bit platforms. */
|
||||||
|
if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
|
||||||
|
@@ -165,19 +166,22 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
||||||
|
}
|
||||||
|
|
||||||
|
b = grub_efi_system_table->boot_services;
|
||||||
|
- status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
||||||
|
+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
+ grub_dprintf ("efi",
|
||||||
|
+ "allocate_pages(%d, %d, 0x%0" PRIxGRUB_SIZE ", 0x%016" PRIxGRUB_UINT64_T ") = 0x%016" PRIxGRUB_SIZE "\n",
|
||||||
|
+ alloctype, memtype, pages, address, status);
|
||||||
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (address == 0)
|
||||||
|
+ if (ret == 0)
|
||||||
|
{
|
||||||
|
/* Uggh, the address 0 was allocated... This is too annoying,
|
||||||
|
so reallocate another one. */
|
||||||
|
- address = GRUB_EFI_MAX_USABLE_ADDRESS;
|
||||||
|
- status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &address);
|
||||||
|
+ ret = address;
|
||||||
|
+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret);
|
||||||
|
grub_efi_free_pages (0, pages);
|
||||||
|
if (status != GRUB_EFI_SUCCESS)
|
||||||
|
{
|
||||||
|
@@ -186,9 +190,9 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- grub_efi_store_alloc (address, pages);
|
||||||
|
+ grub_efi_store_alloc (ret, pages);
|
||||||
|
|
||||||
|
- return (void *) ((grub_addr_t) address);
|
||||||
|
+ return (void *) ((grub_addr_t) ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
@@ -699,8 +703,21 @@ grub_efi_get_ram_base(grub_addr_t *base_addr)
|
||||||
|
for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS;
|
||||||
|
(grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size);
|
||||||
|
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||||
|
- if (desc->attribute & GRUB_EFI_MEMORY_WB)
|
||||||
|
- *base_addr = grub_min (*base_addr, desc->physical_start);
|
||||||
|
+ {
|
||||||
|
+ if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY &&
|
||||||
|
+ (desc->attribute & GRUB_EFI_MEMORY_WB))
|
||||||
|
+ {
|
||||||
|
+ *base_addr = grub_min (*base_addr, desc->physical_start);
|
||||||
|
+ grub_dprintf ("efi", "setting base_addr=0x%016" PRIxGRUB_ADDR "\n", *base_addr);
|
||||||
|
+ }
|
||||||
|
+ else
|
||||||
|
+ {
|
||||||
|
+ grub_dprintf ("efi", "ignoring address 0x%016" PRIxGRUB_UINT64_T "\n", desc->physical_start);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (*base_addr == GRUB_EFI_MAX_USABLE_ADDRESS)
|
||||||
|
+ grub_dprintf ("efi", "base_addr 0x%016" PRIxGRUB_ADDR " is probably wrong.\n", *base_addr);
|
||||||
|
|
||||||
|
grub_free(memory_map);
|
||||||
|
|
||||||
|
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
index 98c4f038b..4d084950a 100644
|
||||||
|
--- a/grub-core/loader/arm64/efi/linux.c
|
||||||
|
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
@@ -116,13 +116,15 @@ finalize_params_linux (void)
|
||||||
|
{
|
||||||
|
grub_efi_loaded_image_t *loaded_image = NULL;
|
||||||
|
int node, retval, len;
|
||||||
|
-
|
||||||
|
+ grub_err_t err = GRUB_ERR_NONE;
|
||||||
|
void *fdt;
|
||||||
|
|
||||||
|
fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
|
||||||
|
-
|
||||||
|
if (!fdt)
|
||||||
|
- goto failure;
|
||||||
|
+ {
|
||||||
|
+ err = grub_error(GRUB_ERR_BAD_OS, "failed to load FDT");
|
||||||
|
+ goto failure;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
node = grub_fdt_find_subnode (fdt, 0, "chosen");
|
||||||
|
if (node < 0)
|
||||||
|
@@ -133,17 +135,26 @@ finalize_params_linux (void)
|
||||||
|
*/
|
||||||
|
retval = grub_fdt_set_prop32(fdt, 0, "#address-cells", 2);
|
||||||
|
if (retval)
|
||||||
|
- goto failure;
|
||||||
|
+ {
|
||||||
|
+ err = grub_error(retval, "Could not find #address-cells");
|
||||||
|
+ goto failure;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
retval = grub_fdt_set_prop32(fdt, 0, "#size-cells", 2);
|
||||||
|
if (retval)
|
||||||
|
- goto failure;
|
||||||
|
+ {
|
||||||
|
+ err = grub_error(retval, "Could not find #size-cells");
|
||||||
|
+ goto failure;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
node = grub_fdt_add_subnode (fdt, 0, "chosen");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (node < 1)
|
||||||
|
- goto failure;
|
||||||
|
+ {
|
||||||
|
+ err = grub_error(grub_errno, "failed to load chosen fdt node.");
|
||||||
|
+ goto failure;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* Set initrd info */
|
||||||
|
if (initrd_start && initrd_end > initrd_start)
|
||||||
|
@@ -154,15 +165,26 @@ finalize_params_linux (void)
|
||||||
|
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
|
||||||
|
initrd_start);
|
||||||
|
if (retval)
|
||||||
|
- goto failure;
|
||||||
|
+ {
|
||||||
|
+ err = grub_error(retval, "Failed to set linux,initrd-start property");
|
||||||
|
+ goto failure;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
|
||||||
|
initrd_end);
|
||||||
|
if (retval)
|
||||||
|
- goto failure;
|
||||||
|
+ {
|
||||||
|
+ err = grub_error(retval, "Failed to set linux,initrd-end property");
|
||||||
|
+ goto failure;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (grub_fdt_install() != GRUB_ERR_NONE)
|
||||||
|
- goto failure;
|
||||||
|
+ retval = grub_fdt_install();
|
||||||
|
+ if (retval != GRUB_ERR_NONE)
|
||||||
|
+ {
|
||||||
|
+ err = grub_error(retval, "Failed to install fdt");
|
||||||
|
+ goto failure;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n",
|
||||||
|
fdt);
|
||||||
|
@@ -170,14 +192,20 @@ finalize_params_linux (void)
|
||||||
|
/* Convert command line to UCS-2 */
|
||||||
|
loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||||
|
if (!loaded_image)
|
||||||
|
- goto failure;
|
||||||
|
+ {
|
||||||
|
+ err = grub_error(grub_errno, "Failed to install fdt");
|
||||||
|
+ 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");
|
||||||
|
+ {
|
||||||
|
+ err = grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
|
||||||
|
+ goto failure;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
loaded_image->load_options_size =
|
||||||
|
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
|
||||||
|
@@ -187,7 +215,7 @@ finalize_params_linux (void)
|
||||||
|
|
||||||
|
failure:
|
||||||
|
grub_fdt_unload();
|
||||||
|
- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
|
||||||
|
+ return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
@@ -272,16 +300,28 @@ grub_linux_unload (void)
|
||||||
|
static void *
|
||||||
|
allocate_initrd_mem (int initrd_pages)
|
||||||
|
{
|
||||||
|
- grub_addr_t max_addr;
|
||||||
|
+ grub_addr_t max_addr = 0;
|
||||||
|
+ grub_err_t err;
|
||||||
|
+ void *ret;
|
||||||
|
+
|
||||||
|
+ err = grub_efi_get_ram_base (&max_addr);
|
||||||
|
+ if (err != GRUB_ERR_NONE)
|
||||||
|
+ {
|
||||||
|
+ grub_error (err, "grub_efi_get_ram_base() failed");
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE)
|
||||||
|
- return NULL;
|
||||||
|
+ grub_dprintf ("linux", "max_addr: 0x%016lx, INITRD_MAX_ADDRESS_OFFSET: 0x%016llx\n",
|
||||||
|
+ max_addr, INITRD_MAX_ADDRESS_OFFSET);
|
||||||
|
|
||||||
|
max_addr += INITRD_MAX_ADDRESS_OFFSET - 1;
|
||||||
|
+ grub_dprintf ("linux", "calling grub_efi_allocate_pages_real (0x%016lx, 0x%08x, EFI_ALLOCATE_MAX_ADDRESS, EFI_LOADER_DATA)", max_addr, initrd_pages);
|
||||||
|
|
||||||
|
- return grub_efi_allocate_pages_real (max_addr, initrd_pages,
|
||||||
|
- GRUB_EFI_ALLOCATE_MAX_ADDRESS,
|
||||||
|
- GRUB_EFI_LOADER_DATA);
|
||||||
|
+ ret = grub_efi_allocate_pages_real (max_addr, initrd_pages,
|
||||||
|
+ GRUB_EFI_ALLOCATE_MAX_ADDRESS,
|
||||||
|
+ GRUB_EFI_LOADER_DATA);
|
||||||
|
+ grub_dprintf ("linux", "got 0x%016llx\n", (unsigned long long)ret);
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,75 @@
|
|||||||
|
From 669aa440ca34f6d8982c92b79fa2ee84c20618c6 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Peter Jones <pjones@redhat.com>
|
||||||
|
Date: Thu, 16 Aug 2018 11:08:11 -0400
|
||||||
|
Subject: [PATCH 5/8] Make linux_arm_kernel_header.hdr_offset be at the right
|
||||||
|
place
|
||||||
|
|
||||||
|
The kernel in front of me (slightly edited to make objdump work) looks like:
|
||||||
|
|
||||||
|
00000000 4d 5a 10 13 4d 5a 10 13 4d 5a 10 13 4d 5a 10 13 |MZ..MZ..MZ..MZ..|
|
||||||
|
00000010 4d 5a 10 13 4d 5a 10 13 4d 5a 10 13 00 00 a0 e1 |MZ..MZ..MZ......|
|
||||||
|
00000020 f6 03 00 ea 18 28 6f 01 00 00 00 00 00 32 74 00 |.....(o......2t.|
|
||||||
|
00000030 01 02 03 04 45 45 45 45 74 a2 00 00 40 00 00 00 |....EEEEt...@...|
|
||||||
|
00000040 50 45 00 00 4c 01 04 00 00 00 00 00 00 00 00 00 |PE..L...........|
|
||||||
|
00000050 00 00 00 00 90 00 06 03 0b 01 02 14 00 20 74 00 |............. t.|
|
||||||
|
00000060 00 14 00 00 00 00 00 00 b4 19 00 00 00 10 00 00 |................|
|
||||||
|
00000070 00 30 74 00 00 00 00 00 00 10 00 00 00 02 00 00 |.0t.............|
|
||||||
|
00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
||||||
|
00000090 00 44 74 00 00 10 00 00 00 00 00 00 0a 00 00 00 |.Dt.............|
|
||||||
|
000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
||||||
|
000000b0 00 00 00 00 06 00 00 00 00 00 00 00 00 00 00 00 |................|
|
||||||
|
000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
|
||||||
|
*
|
||||||
|
|
||||||
|
(I don't know why the MZ header is there 7 times, but the offsets work out, so
|
||||||
|
it's merely a surprising distraction.)
|
||||||
|
|
||||||
|
If linux_arm_kernel_header.reserved2 is 16 bytes, that means hdr_offset is
|
||||||
|
here:
|
||||||
|
|
||||||
|
00000030 01 02 03 04 45 45 45 45 74 a2 00 00 40 00 00 00 |....EEEEt...@...|
|
||||||
|
00000040 50 45 00 00 4c 01 04 00 00 00 00 00 00 00 00 00 |PE..L...........|
|
||||||
|
^^^^^^^^^^^
|
||||||
|
|
||||||
|
But it's supposed to be 4 bytes before that.
|
||||||
|
|
||||||
|
This patch makes the reserved field be 3*32 instead of 4*32, and that means we
|
||||||
|
can find the PE header correcrtly at 0x40 by reading the value at 0x3c.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||||
|
---
|
||||||
|
grub-core/loader/arm64/efi/linux.c | 3 +++
|
||||||
|
include/grub/arm/linux.h | 2 +-
|
||||||
|
2 files changed, 4 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
index 4d084950a..83d09b7e5 100644
|
||||||
|
--- a/grub-core/loader/arm64/efi/linux.c
|
||||||
|
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
@@ -86,7 +86,10 @@ grub_efi_linux_boot (void *kernel_address, grub_off_t offset,
|
||||||
|
{
|
||||||
|
handover_func hf;
|
||||||
|
|
||||||
|
+ 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;
|
||||||
|
diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
|
||||||
|
index 775297db8..b582f67f6 100644
|
||||||
|
--- a/include/grub/arm/linux.h
|
||||||
|
+++ b/include/grub/arm/linux.h
|
||||||
|
@@ -31,7 +31,7 @@ struct linux_arm_kernel_header {
|
||||||
|
grub_uint32_t magic;
|
||||||
|
grub_uint32_t start; /* _start */
|
||||||
|
grub_uint32_t end; /* _edata */
|
||||||
|
- grub_uint32_t reserved2[4];
|
||||||
|
+ grub_uint32_t reserved2[3];
|
||||||
|
grub_uint32_t hdr_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,58 @@
|
|||||||
|
From 3741c6807923ae97b0d87e61c59c8de8af544484 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
Date: Thu, 23 Apr 2020 15:06:46 +0200
|
||||||
|
Subject: [PATCH 6/8] efi: Set image base address before jumping to the PE/COFF
|
||||||
|
entry point
|
||||||
|
|
||||||
|
Upstream GRUB uses the EFI LoadImage() and StartImage() to boot the Linux
|
||||||
|
kernel. But our custom EFI loader that supports Secure Boot instead uses
|
||||||
|
the EFI handover protocol (for x86) or jumping directly to the PE/COFF
|
||||||
|
entry point (for aarch64).
|
||||||
|
|
||||||
|
This is done to allow the bootloader to verify the images using the shim
|
||||||
|
lock protocol to avoid booting untrusted binaries.
|
||||||
|
|
||||||
|
Since the bootloader loads the kernel from the boot media instead of using
|
||||||
|
LoadImage(), it is responsible to set the Loaded Image base address before
|
||||||
|
booting the kernel.
|
||||||
|
|
||||||
|
Otherwise the kernel EFI stub will complain that it was not set correctly
|
||||||
|
and print the following warning message:
|
||||||
|
|
||||||
|
EFI stub: ERROR: FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value
|
||||||
|
|
||||||
|
Resolves: rhbz#1825411
|
||||||
|
|
||||||
|
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||||
|
---
|
||||||
|
grub-core/loader/arm64/efi/linux.c | 12 ++++++++++++
|
||||||
|
1 file changed, 12 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
index 83d09b7e5..a4041be5c 100644
|
||||||
|
--- a/grub-core/loader/arm64/efi/linux.c
|
||||||
|
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
@@ -84,8 +84,20 @@ 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);
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -0,0 +1,97 @@
|
|||||||
|
From 496890ebd2605eb1ff15f8d96c30b5d617f1bb85 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Chang <mchang@suse.com>
|
||||||
|
Date: Fri, 6 Nov 2020 11:19:06 +0000
|
||||||
|
Subject: [PATCH 7/8] linuxefi: fail kernel validation without shim protocol.
|
||||||
|
|
||||||
|
If certificates that signed grub are installed into db, grub can be
|
||||||
|
booted directly. It will then boot any kernel without signature
|
||||||
|
validation. The booted kernel will think it was booted in secureboot
|
||||||
|
mode and will implement lockdown, yet it could have been tampered.
|
||||||
|
|
||||||
|
This version of the patch skips calling verification, when booted
|
||||||
|
without secureboot. And is indented with gnu ident.
|
||||||
|
|
||||||
|
CVE-2020-15705
|
||||||
|
|
||||||
|
Reported-by: Mathieu Trudel-Lapierre <cyphermox@ubuntu.com>
|
||||||
|
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||||
|
---
|
||||||
|
grub-core/loader/arm64/efi/linux.c | 38 +++++++++++++++++++++++-------
|
||||||
|
1 file changed, 29 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
index a4041be5c..0e5782caa 100644
|
||||||
|
--- a/grub-core/loader/arm64/efi/linux.c
|
||||||
|
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
@@ -58,21 +58,35 @@ struct grub_efi_shim_lock
|
||||||
|
};
|
||||||
|
typedef struct grub_efi_shim_lock grub_efi_shim_lock_t;
|
||||||
|
|
||||||
|
-static grub_efi_boolean_t
|
||||||
|
+// Returns 1 on success, -1 on error, 0 when not available
|
||||||
|
+static int
|
||||||
|
grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
|
||||||
|
{
|
||||||
|
grub_efi_guid_t guid = SHIM_LOCK_GUID;
|
||||||
|
grub_efi_shim_lock_t *shim_lock;
|
||||||
|
+ grub_efi_status_t status;
|
||||||
|
|
||||||
|
shim_lock = grub_efi_locate_protocol(&guid, NULL);
|
||||||
|
-
|
||||||
|
+ grub_dprintf ("secureboot", "shim_lock: %p\n", shim_lock);
|
||||||
|
if (!shim_lock)
|
||||||
|
- return 1;
|
||||||
|
+ {
|
||||||
|
+ grub_dprintf ("secureboot", "shim not available\n");
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (shim_lock->verify(data, size) == GRUB_EFI_SUCCESS)
|
||||||
|
- return 1;
|
||||||
|
+ grub_dprintf ("secureboot", "Asking shim to verify kernel signature\n");
|
||||||
|
+ status = shim_lock->verify (data, size);
|
||||||
|
+ grub_dprintf ("secureboot", "shim_lock->verify(): %ld\n", (long int)status);
|
||||||
|
+ if (status == GRUB_EFI_SUCCESS)
|
||||||
|
+ {
|
||||||
|
+ grub_dprintf ("secureboot", "Kernel signature verification passed\n");
|
||||||
|
+ return 1;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- return 0;
|
||||||
|
+ grub_dprintf ("secureboot", "Kernel signature verification failed (0x%lx)\n",
|
||||||
|
+ (unsigned long) status);
|
||||||
|
+
|
||||||
|
+ return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
@@ -399,6 +413,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
struct linux_arch_kernel_header lh;
|
||||||
|
struct grub_armxx_linux_pe_header *pe;
|
||||||
|
grub_err_t err;
|
||||||
|
+ int rc;
|
||||||
|
|
||||||
|
grub_dl_ref (my_mod);
|
||||||
|
|
||||||
|
@@ -443,10 +458,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
|
||||||
|
grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
|
||||||
|
|
||||||
|
- if (!grub_linuxefi_secure_validate (kernel_addr, kernel_size))
|
||||||
|
+ if (grub_efi_secure_boot ())
|
||||||
|
{
|
||||||
|
- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), argv[0]);
|
||||||
|
- goto fail;
|
||||||
|
+ rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size);
|
||||||
|
+ if (rc <= 0)
|
||||||
|
+ {
|
||||||
|
+ grub_error (GRUB_ERR_INVALID_COMMAND,
|
||||||
|
+ N_("%s has invalid signature"), argv[0]);
|
||||||
|
+ goto fail;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
101
0008-squash-Add-support-for-Linux-EFI-stub-loading-on-aar.patch
Normal file
101
0008-squash-Add-support-for-Linux-EFI-stub-loading-on-aar.patch
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
From 5f98e139f74a1280dee4f1579eeab05e08541e8c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Michael Chang <mchang@suse.com>
|
||||||
|
Date: Tue, 10 Nov 2020 04:33:21 +0000
|
||||||
|
Subject: [PATCH 8/8] squash! Add support for Linux EFI stub loading on
|
||||||
|
aarch64.
|
||||||
|
|
||||||
|
Make efi handoff the default loader for arm64 platform.
|
||||||
|
|
||||||
|
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||||
|
---
|
||||||
|
grub-core/Makefile.core.def | 4 +---
|
||||||
|
grub-core/loader/arm64/efi/linux.c | 20 ++++++++++----------
|
||||||
|
2 files changed, 11 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||||
|
index cfdd31431..ce4f71ebe 100644
|
||||||
|
--- a/grub-core/Makefile.core.def
|
||||||
|
+++ b/grub-core/Makefile.core.def
|
||||||
|
@@ -1787,7 +1787,7 @@ module = {
|
||||||
|
arm_coreboot = loader/arm/linux.c;
|
||||||
|
arm_efi = loader/arm64/linux.c;
|
||||||
|
arm_uboot = loader/arm/linux.c;
|
||||||
|
- arm64 = loader/arm64/linux.c;
|
||||||
|
+ arm64 = loader/arm64/efi/linux.c;
|
||||||
|
riscv32 = loader/riscv/linux.c;
|
||||||
|
riscv64 = loader/riscv/linux.c;
|
||||||
|
emu = loader/emu/linux.c;
|
||||||
|
@@ -1855,10 +1855,8 @@ module = {
|
||||||
|
module = {
|
||||||
|
name = linuxefi;
|
||||||
|
x86 = lib/fake_module.c;
|
||||||
|
- arm64 = loader/arm64/efi/linux.c;
|
||||||
|
enable = i386_efi;
|
||||||
|
enable = x86_64_efi;
|
||||||
|
- enable = arm64_efi;
|
||||||
|
};
|
||||||
|
|
||||||
|
module = {
|
||||||
|
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
index 0e5782caa..7a8c6dfe4 100644
|
||||||
|
--- a/grub-core/loader/arm64/efi/linux.c
|
||||||
|
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||||
|
@@ -123,9 +123,8 @@ grub_efi_linux_boot (void *kernel_address, grub_off_t offset,
|
||||||
|
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
-/* FIXME: This is copy of grub_arch_efi_linux_check_image () */
|
||||||
|
-static grub_err_t
|
||||||
|
-grub_arch_efi_linux_check_image_XX (struct linux_arch_kernel_header * lh)
|
||||||
|
+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");
|
||||||
|
@@ -263,9 +262,10 @@ free_params (void)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* FIXME: This is to replace grub_arch_efi_linux_boot_image */
|
||||||
|
-static grub_err_t
|
||||||
|
-grub_arch_efi_linux_boot_image_XX (grub_addr_t addr, char *args)
|
||||||
|
+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;
|
||||||
|
|
||||||
|
@@ -285,7 +285,7 @@ grub_arch_efi_linux_boot_image_XX (grub_addr_t addr, char *args)
|
||||||
|
static grub_err_t
|
||||||
|
grub_linux_boot (void)
|
||||||
|
{
|
||||||
|
- return (grub_arch_efi_linux_boot_image_XX ((grub_addr_t)kernel_addr, linux_args));
|
||||||
|
+ return (grub_arch_efi_linux_boot_image ((grub_addr_t)kernel_addr, kernel_size, linux_args));
|
||||||
|
}
|
||||||
|
|
||||||
|
static grub_err_t
|
||||||
|
@@ -432,7 +432,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||||
|
if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
|
||||||
|
return grub_errno;
|
||||||
|
|
||||||
|
- if (grub_arch_efi_linux_check_image_XX (&lh) != GRUB_ERR_NONE)
|
||||||
|
+ if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
grub_loader_unset();
|
||||||
|
@@ -518,9 +518,9 @@ static grub_command_t cmd_linux, cmd_initrd;
|
||||||
|
|
||||||
|
GRUB_MOD_INIT (linux)
|
||||||
|
{
|
||||||
|
- cmd_linux = grub_register_command ("linuxefi", grub_cmd_linux, 0,
|
||||||
|
+ cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
|
||||||
|
N_("Load Linux."));
|
||||||
|
- cmd_initrd = grub_register_command ("initrdefi", grub_cmd_initrd, 0,
|
||||||
|
+ cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
|
||||||
|
N_("Load initrd."));
|
||||||
|
my_mod = mod;
|
||||||
|
}
|
||||||
|
--
|
||||||
|
2.26.2
|
||||||
|
|
@ -1,3 +1,16 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Jan 27 04:13:32 UTC 2021 - Michael Chang <mchang@suse.com>
|
||||||
|
|
||||||
|
- Secure Boot support in GRUB on aarch64 (jsc#SLE-15864)
|
||||||
|
* 0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch
|
||||||
|
* 0002-arm64-make-sure-fdt-has-address-cells-and-size-cells.patch
|
||||||
|
* 0003-Make-grub_error-more-verbose.patch
|
||||||
|
* 0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch
|
||||||
|
* 0005-Make-linux_arm_kernel_header.hdr_offset-be-at-the-ri.patch
|
||||||
|
* 0006-efi-Set-image-base-address-before-jumping-to-the-PE-.patch
|
||||||
|
* 0007-linuxefi-fail-kernel-validation-without-shim-protoco.patch
|
||||||
|
* 0008-squash-Add-support-for-Linux-EFI-stub-loading-on-aar.patch
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Thu Jan 21 07:59:39 UTC 2021 - Michael Chang <mchang@suse.com>
|
Thu Jan 21 07:59:39 UTC 2021 - Michael Chang <mchang@suse.com>
|
||||||
|
|
||||||
|
17
grub2.spec
17
grub2.spec
@ -336,6 +336,15 @@ Patch721: 0001-efi-linux-provide-linux-command.patch
|
|||||||
# (bsc#1176062)
|
# (bsc#1176062)
|
||||||
Patch722: 0001-Warn-if-MBR-gap-is-small-and-user-uses-advanced-modu.patch
|
Patch722: 0001-Warn-if-MBR-gap-is-small-and-user-uses-advanced-modu.patch
|
||||||
Patch723: 0002-grub-install-Avoid-incompleted-install-on-i386-pc.patch
|
Patch723: 0002-grub-install-Avoid-incompleted-install-on-i386-pc.patch
|
||||||
|
# Secure Boot support in GRUB on aarch64 (jsc#SLE-15864)
|
||||||
|
Patch730: 0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch
|
||||||
|
Patch731: 0002-arm64-make-sure-fdt-has-address-cells-and-size-cells.patch
|
||||||
|
Patch732: 0003-Make-grub_error-more-verbose.patch
|
||||||
|
Patch733: 0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch
|
||||||
|
Patch734: 0005-Make-linux_arm_kernel_header.hdr_offset-be-at-the-ri.patch
|
||||||
|
Patch735: 0006-efi-Set-image-base-address-before-jumping-to-the-PE-.patch
|
||||||
|
Patch736: 0007-linuxefi-fail-kernel-validation-without-shim-protoco.patch
|
||||||
|
Patch737: 0008-squash-Add-support-for-Linux-EFI-stub-loading-on-aar.patch
|
||||||
|
|
||||||
Requires: gettext-runtime
|
Requires: gettext-runtime
|
||||||
%if 0%{?suse_version} >= 1140
|
%if 0%{?suse_version} >= 1140
|
||||||
@ -666,6 +675,14 @@ swap partition while in resuming
|
|||||||
%patch721 -p1
|
%patch721 -p1
|
||||||
%patch722 -p1
|
%patch722 -p1
|
||||||
%patch723 -p1
|
%patch723 -p1
|
||||||
|
%patch730 -p1
|
||||||
|
%patch731 -p1
|
||||||
|
%patch732 -p1
|
||||||
|
%patch733 -p1
|
||||||
|
%patch734 -p1
|
||||||
|
%patch735 -p1
|
||||||
|
%patch736 -p1
|
||||||
|
%patch737 -p1
|
||||||
|
|
||||||
%build
|
%build
|
||||||
# collect evidence to debug spurious build failure on SLE15
|
# collect evidence to debug spurious build failure on SLE15
|
||||||
|
Loading…
Reference in New Issue
Block a user