diff --git a/0001-Add-grub_envblk_buf-helper-function.patch b/0001-Add-grub_envblk_buf-helper-function.patch new file mode 100644 index 0000000000000000000000000000000000000000..4b994d5805e11f527e35d6407b2e5648f74aa3e4 --- /dev/null +++ b/0001-Add-grub_envblk_buf-helper-function.patch @@ -0,0 +1,68 @@ +From a326e486bdcf99e6be973ba54c0abfb6d2d95b73 Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 +--- + 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 + #include + ++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 + diff --git a/0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch b/0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch new file mode 100644 index 0000000000000000000000000000000000000000..075636fe48b76fcc84f4645a449e332103ce9dce --- /dev/null +++ b/0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch @@ -0,0 +1,526 @@ +From db4da8095b5ba722d22502c8d090e66816a5577d Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++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 + #include "system.h" + + #include + ++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 + # 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 . ++ */ ++ ++#ifndef GRUB_ARM64_LINUX_HEADER ++#define GRUB_ARM64_LINUX_HEADER 1 ++ ++#include ++#include ++ ++#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 */ diff --git a/0001-Factor-out-grub_efi_linux_boot.patch b/0001-Factor-out-grub_efi_linux_boot.patch new file mode 100644 index 0000000000000000000000000000000000000000..d430d258f52e69548191bc89eab71562f2c52ed1 --- /dev/null +++ b/0001-Factor-out-grub_efi_linux_boot.patch @@ -0,0 +1,215 @@ +From 82d95254ca0496c8843113665bb9a99876101025 Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 +--- + 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 + #include + #include ++#include + + 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 + #include + #include ++#include + + 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 . ++ */ ++#ifndef GRUB_EFI_LINUX_HEADER ++#define GRUB_EFI_LINUX_HEADER 1 ++ ++#include ++#include ++#include ++ ++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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#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 diff --git a/0001-Fix-infinite-boot-loop-on-headless-system-in-qemu.patch b/0001-Fix-infinite-boot-loop-on-headless-system-in-qemu.patch new file mode 100644 index 0000000000000000000000000000000000000000..606827ce2c35e88f66582cbb999168f61a055255 --- /dev/null +++ b/0001-Fix-infinite-boot-loop-on-headless-system-in-qemu.patch @@ -0,0 +1,66 @@ +From f76317d9dc35dbc576820ba6c2a6a8e41f5338b5 Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 +--- + 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 diff --git a/0001-Improve-TPM-key-protection-on-boot-interruptions.patch b/0001-Improve-TPM-key-protection-on-boot-interruptions.patch new file mode 100644 index 0000000000000000000000000000000000000000..8065b0da95e454210387ea2a80cf12f4a6ba6ef2 --- /dev/null +++ b/0001-Improve-TPM-key-protection-on-boot-interruptions.patch @@ -0,0 +1,286 @@ +From fe7ed9104cef56f9e532a0c9a7164393d5d69ae1 Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 +--- + 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 + #include + #include ++#include + + /* 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 + #include + +-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 + diff --git a/0001-Make-grub.cfg-compatible-to-old-binaries.patch b/0001-Make-grub.cfg-compatible-to-old-binaries.patch new file mode 100644 index 0000000000000000000000000000000000000000..ef24a4836d64b1fd616164689e84d5f1c18f57c9 --- /dev/null +++ b/0001-Make-grub.cfg-compatible-to-old-binaries.patch @@ -0,0 +1,82 @@ +From b8457f2e271917c5c83a4fee286bafedf8c5790c Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 +--- + 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 + diff --git a/0001-Revert-templates-Fix-user-facing-typo-with-an-incorr.patch b/0001-Revert-templates-Fix-user-facing-typo-with-an-incorr.patch deleted file mode 100644 index fcc78251bdddae408b96d354061a322d4721d694..0000000000000000000000000000000000000000 --- a/0001-Revert-templates-Fix-user-facing-typo-with-an-incorr.patch +++ /dev/null @@ -1,24 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Fri, 11 Jun 2021 12:10:45 +0200 -Subject: [PATCH] Revert "templates: Fix user-facing typo with an incorrect use - of "it's"" - -This reverts commit 722737630889607c3b5761f1f5a48f1674cd2821. ---- - util/grub.d/30_os-prober.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in -index 5984e92d291..94622481284 100644 ---- a/util/grub.d/30_os-prober.in -+++ b/util/grub.d/30_os-prober.in -@@ -36,7 +36,7 @@ if ! command -v os-prober > /dev/null || ! command -v linux-boot-prober > /dev/n - exit 0 - fi - --grub_warn "$(gettext_printf "os-prober will be executed to detect other bootable partitions.\nIts output will be used to detect bootable binaries on them and create new boot entries.")" -+grub_warn "$(gettext_printf "os-prober will be executed to detect other bootable partitions.\nIt's output will be used to detect bootable binaries on them and create new boot entries.")" - - OSPROBED="`os-prober | tr ' ' '^' | paste -s -d ' '`" - if [ -z "${OSPROBED}" ] ; then diff --git a/0001-Unify-the-check-to-enable-btrfs-relative-path.patch b/0001-Unify-the-check-to-enable-btrfs-relative-path.patch new file mode 100644 index 0000000000000000000000000000000000000000..520a5de2c32baad51704151c1e83d3b84593cff7 --- /dev/null +++ b/0001-Unify-the-check-to-enable-btrfs-relative-path.patch @@ -0,0 +1,150 @@ +From 80bb1b17b3f596dbd7331cf9cb20a46c8ef9800b Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 +--- + 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: +@@ -1478,8 +1517,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"); +@@ -1670,21 +1708,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) + { +@@ -1709,11 +1739,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" diff --git a/0001-Workaround-volatile-efi-boot-variable.patch b/0001-Workaround-volatile-efi-boot-variable.patch new file mode 100644 index 0000000000000000000000000000000000000000..d64e136e3737cf0907193093d12e06ed9d704afc --- /dev/null +++ b/0001-Workaround-volatile-efi-boot-variable.patch @@ -0,0 +1,289 @@ +From 71575829c303fe8522b46fc96b1f99f1aa4178e7 Mon Sep 17 00:00:00 2001 +From: Michael Chang +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 . ++ */ ++ ++#include ++ ++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 . ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++ ++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; diff --git a/0082-Support-UEFI-networking-protocols.patch b/0001-add-support-for-UEFI-network-protocols.patch similarity index 88% rename from 0082-Support-UEFI-networking-protocols.patch rename to 0001-add-support-for-UEFI-network-protocols.patch index fb143862d55710f868b5a325fa61b231e2369592..f62796dd4c35ddb9556bc25679445ea0b531ed21 100644 --- a/0082-Support-UEFI-networking-protocols.patch +++ b/0001-add-support-for-UEFI-network-protocols.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 5d6111790e1cd07d1156f47bca0733f6d715337f Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Wed, 22 Feb 2017 14:27:50 +0800 Subject: [PATCH] Support UEFI networking protocols @@ -23,11 +23,23 @@ V3: * Finish HTTP transaction in one go * Fix bsc#1076132 -Signed-off-by: Michael Chang -[pjones: make efi_netfs not duplicate symbols from efinet] -Signed-off-by: Peter Jones +V4: + * Add fs_ prefix with upstream commit + ad4bfeec5 Change fs functions to add fs_ prefix + +V5: + * Use overflow checking primitives where the arithmetic expression for + buffer allocations may include unvalidated data + * Use grub_calloc for overflow check and return NULL when it would + occur. + +V6: + * Don't force grub_print_error if no best route found as boot process + could be interrupted by logged error. The default interface will be + used as fallback in this case + --- - grub-core/Makefile.core.def | 12 + + grub-core/Makefile.core.def | 18 + grub-core/io/bufio.c | 2 +- grub-core/kern/efi/efi.c | 96 ++- grub-core/net/drivers/efi/efinet.c | 27 + @@ -39,12 +51,12 @@ Signed-off-by: Peter Jones grub-core/net/efi/net.c | 1428 ++++++++++++++++++++++++++++++++++++ grub-core/net/efi/pxe.c | 424 +++++++++++ grub-core/net/net.c | 74 ++ - util/grub-mknetdir.c | 23 +- - include/grub/efi/api.h | 180 ++++- + include/grub/efi/api.h | 181 ++++- include/grub/efi/dhcp.h | 343 +++++++++ include/grub/efi/http.h | 215 ++++++ include/grub/net/efi.h | 144 ++++ - 17 files changed, 4620 insertions(+), 41 deletions(-) + util/grub-mknetdir.c | 23 +- + 17 files changed, 4627 insertions(+), 41 deletions(-) create mode 100644 grub-core/net/efi/dhcp.c create mode 100644 grub-core/net/efi/efi_netfs.c create mode 100644 grub-core/net/efi/http.c @@ -56,24 +68,9 @@ Signed-off-by: Peter Jones create mode 100644 include/grub/efi/http.h create mode 100644 include/grub/net/efi.h -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 4b7c45a7b06..c40170f2dd2 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -2299,6 +2299,12 @@ module = { - common = hook/datehook.c; - }; - -+module = { -+ name = efi_netfs; -+ common = net/efi/efi_netfs.c; -+ enable = efi; -+}; -+ - module = { - name = net; - common = net/net.c; -@@ -2312,6 +2318,12 @@ module = { +@@ -2362,6 +2362,12 @@ common = net/ethernet.c; common = net/arp.c; common = net/netbuff.c; @@ -86,11 +83,9 @@ index 4b7c45a7b06..c40170f2dd2 100644 }; module = { -diff --git a/grub-core/io/bufio.c b/grub-core/io/bufio.c -index a458c3aca78..1637731535e 100644 --- a/grub-core/io/bufio.c +++ b/grub-core/io/bufio.c -@@ -139,7 +139,7 @@ grub_bufio_read (grub_file_t file, char *buf, grub_size_t len) +@@ -139,7 +139,7 @@ return res; /* Need to read some more. */ @@ -99,11 +94,9 @@ index a458c3aca78..1637731535e 100644 /* Now read between file->offset + res and bufio->buffer_at. */ if (file->offset + res < next_buf) { -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index d6a2fb57789..2a446f5031b 100644 --- a/grub-core/kern/efi/efi.c +++ b/grub-core/kern/efi/efi.c -@@ -755,7 +755,7 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) +@@ -770,7 +770,7 @@ { grub_efi_ipv4_device_path_t *ipv4 = (grub_efi_ipv4_device_path_t *) dp; @@ -112,7 +105,7 @@ index d6a2fb57789..2a446f5031b 100644 (unsigned) ipv4->local_ip_address[0], (unsigned) ipv4->local_ip_address[1], (unsigned) ipv4->local_ip_address[2], -@@ -768,33 +768,60 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) +@@ -783,33 +783,60 @@ (unsigned) ipv4->remote_port, (unsigned) ipv4->protocol, (unsigned) ipv4->static_ip_address); @@ -190,7 +183,7 @@ index d6a2fb57789..2a446f5031b 100644 } break; case GRUB_EFI_INFINIBAND_DEVICE_PATH_SUBTYPE: -@@ -834,6 +861,39 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp) +@@ -856,6 +883,39 @@ dump_vendor_path ("Messaging", (grub_efi_vendor_device_path_t *) dp); break; @@ -230,19 +223,26 @@ index d6a2fb57789..2a446f5031b 100644 default: grub_printf ("/UnknownMessaging(%x)", (unsigned) subtype); break; -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 715a6168d77..e11d759f19a 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c -@@ -27,6 +27,7 @@ - #include - #include +@@ -24,6 +24,7 @@ + #include + #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); -@@ -491,6 +492,17 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u +@@ -345,7 +346,7 @@ + } + + static grub_efi_handle_t +-grub_efi_locate_device_path (grub_efi_guid_t *protocol, grub_efi_device_path_t *device_path, ++grub_efi_locate_device_path (grub_guid_t *protocol, grub_efi_device_path_t *device_path, + grub_efi_device_path_t **r_device_path) + { + grub_efi_handle_t handle; +@@ -498,6 +499,17 @@ ldp = grub_efi_find_last_device_path (ddp); @@ -260,7 +260,7 @@ index 715a6168d77..e11d759f19a 100644 if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) -@@ -760,6 +772,7 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, +@@ -765,6 +777,7 @@ if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE @@ -268,11 +268,10 @@ index 715a6168d77..e11d759f19a 100644 && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)) continue; dup_dp = grub_efi_duplicate_device_path (dp); -@@ -774,6 +787,15 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - dup_ldp->length = sizeof (*dup_ldp); +@@ -780,6 +793,15 @@ } -+ dup_ldp = grub_efi_find_last_device_path (dup_dp); + dup_ldp = grub_efi_find_last_device_path (dup_dp); + if (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_DNS_DEVICE_PATH_SUBTYPE) + { + dup_ldp = grub_efi_find_last_device_path (dup_dp); @@ -281,10 +280,11 @@ index 715a6168d77..e11d759f19a 100644 + dup_ldp->length = sizeof (*dup_ldp); + } + - dup_ldp = grub_efi_find_last_device_path (dup_dp); ++ dup_ldp = grub_efi_find_last_device_path (dup_dp); dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -@@ -845,6 +867,9 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, + dup_ldp->length = sizeof (*dup_ldp); +@@ -860,6 +882,9 @@ GRUB_MOD_INIT(efinet) { @@ -294,20 +294,17 @@ index 715a6168d77..e11d759f19a 100644 grub_efinet_findcards (); grub_efi_net_config = grub_efi_net_config_real; } -@@ -856,5 +881,7 @@ GRUB_MOD_FINI(efinet) - FOR_NET_CARDS_SAFE (card, next) +@@ -871,5 +896,7 @@ + FOR_NET_CARDS_SAFE (card, next) if (card->driver == &efidriver) grub_net_card_unregister (card); + + grub_efi_net_config = NULL; } -diff --git a/grub-core/net/efi/dhcp.c b/grub-core/net/efi/dhcp.c -new file mode 100644 -index 00000000000..dbef63d8c08 --- /dev/null +++ b/grub-core/net/efi/dhcp.c -@@ -0,0 +1,397 @@ +@@ -0,0 +1,399 @@ +#include +#include +#include @@ -385,16 +382,16 @@ index 00000000000..dbef63d8c08 + grub_efi_uint32_t option_count = 0; + grub_efi_uint32_t i; + -+ status = efi_call_4 (dhcp4->parse, dhcp4, reply_packet, &option_count, NULL); ++ status = dhcp4->parse (dhcp4, reply_packet, &option_count, NULL); + + if (status != GRUB_EFI_BUFFER_TOO_SMALL) + return NULL; + -+ option_list = grub_malloc (option_count * sizeof(*option_list)); ++ option_list = grub_calloc (option_count, sizeof(*option_list)); + if (!option_list) + return NULL; + -+ status = efi_call_4 (dhcp4->parse, dhcp4, reply_packet, &option_count, option_list); ++ status = dhcp4->parse (dhcp4, reply_packet, &option_count, option_list); + if (status != GRUB_EFI_SUCCESS) + { + grub_free (option_list); @@ -443,13 +440,13 @@ index 00000000000..dbef63d8c08 + + if (!mode->started) + { -+ status = efi_call_2 (pxe->start, pxe, 0); ++ status = pxe->start (pxe, 0); + + if (status != GRUB_EFI_SUCCESS) + grub_printf ("Couldn't start PXE\n"); + } + -+ status = efi_call_2 (pxe->dhcp, pxe, 0); ++ status = pxe->dhcp (pxe, 0); + if (status != GRUB_EFI_SUCCESS) + { + grub_printf ("dhcp4 configure failed, %d\n", (int)status); @@ -500,7 +497,7 @@ index 00000000000..dbef63d8c08 + config.option_list = &options; + + /* FIXME: What if the dhcp has bounded */ -+ status = efi_call_2 (netdev->dhcp4->configure, netdev->dhcp4, &config); ++ status = netdev->dhcp4->configure (netdev->dhcp4, &config); + grub_free (options); + if (status != GRUB_EFI_SUCCESS) + { @@ -508,14 +505,14 @@ index 00000000000..dbef63d8c08 + continue; + } + -+ status = efi_call_2 (netdev->dhcp4->start, netdev->dhcp4, NULL); ++ status = netdev->dhcp4->start (netdev->dhcp4, NULL); + if (status != GRUB_EFI_SUCCESS) + { + grub_printf ("dhcp4 start failed, %d\n", (int)status); + continue; + } + -+ status = efi_call_2 (netdev->dhcp4->get_mode_data, netdev->dhcp4, &mode); ++ status = netdev->dhcp4->get_mode_data (netdev->dhcp4, &mode); + if (status != GRUB_EFI_SUCCESS) + { + grub_printf ("dhcp4 get mode failed, %d\n", (int)status); @@ -616,21 +613,21 @@ index 00000000000..dbef63d8c08 + config.rapid_commit = 0; + config.solicit_retransmission = &retrans; + -+ status = efi_call_2 (dev->dhcp6->configure, dev->dhcp6, &config); ++ status = dev->dhcp6->configure (dev->dhcp6, &config); + grub_free (opt); + if (status != GRUB_EFI_SUCCESS) + { + grub_printf ("dhcp6 configure failed, %d\n", (int)status); + continue; + } -+ status = efi_call_1 (dev->dhcp6->start, dev->dhcp6); ++ status = dev->dhcp6->start (dev->dhcp6); + if (status != GRUB_EFI_SUCCESS) + { + grub_printf ("dhcp6 start failed, %d\n", (int)status); + continue; + } + -+ status = efi_call_3 (dev->dhcp6->get_mode_data, dev->dhcp6, &mode, NULL); ++ status = dev->dhcp6->get_mode_data (dev->dhcp6, &mode, NULL); + if (status != GRUB_EFI_SUCCESS) + { + grub_printf ("dhcp4 get mode failed, %d\n", (int)status); @@ -666,12 +663,14 @@ index 00000000000..dbef63d8c08 + grub_efi_dhcp6_packet_option_t **options = NULL; + grub_efi_uint32_t i; + -+ status = efi_call_4 (dev->dhcp6->parse, dev->dhcp6, mode.ia->reply_packet, &count, NULL); ++ status = dev->dhcp6->parse (dev->dhcp6, mode.ia->reply_packet, &count, NULL); + + if (status == GRUB_EFI_BUFFER_TOO_SMALL && count) + { -+ options = grub_malloc (count * sizeof(*options)); -+ status = efi_call_4 (dev->dhcp6->parse, dev->dhcp6, mode.ia->reply_packet, &count, options); ++ options = grub_calloc (count, sizeof(*options)); ++ if (!options) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ status = dev->dhcp6->parse (dev->dhcp6, mode.ia->reply_packet, &count, options); + } + + if (status != GRUB_EFI_SUCCESS) @@ -696,8 +695,8 @@ index 00000000000..dbef63d8c08 + grub_free (options); + } + -+ efi_call_1 (b->free_pool, mode.client_id); -+ efi_call_1 (b->free_pool, mode.ia); ++ b->free_pool (mode.client_id); ++ b->free_pool (mode.ia); + } + + return GRUB_ERR_NONE; @@ -705,81 +704,16 @@ index 00000000000..dbef63d8c08 + +grub_command_func_t grub_efi_net_bootp = grub_cmd_efi_bootp; +grub_command_func_t grub_efi_net_bootp6 = grub_cmd_efi_bootp6; -diff --git a/grub-core/net/efi/efi_netfs.c b/grub-core/net/efi/efi_netfs.c -new file mode 100644 -index 00000000000..ef371d885ea ---- /dev/null -+++ b/grub-core/net/efi/efi_netfs.c -@@ -0,0 +1,57 @@ -+#include -+#include -+#define EFI_NET_CMD_PREFIX "net_efi" -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static grub_command_t cmd_efi_lsroutes; -+static grub_command_t cmd_efi_lscards; -+static grub_command_t cmd_efi_lsaddrs; -+static grub_command_t cmd_efi_addaddr; -+static grub_command_t cmd_efi_bootp; -+static grub_command_t cmd_efi_bootp6; -+ -+static int initialized; -+ -+GRUB_MOD_INIT(efi_netfs) -+{ -+ if (grub_net_open) -+ return; -+ -+ if (grub_efi_net_fs_init ()) -+ { -+ cmd_efi_lsroutes = grub_register_command ("net_efi_ls_routes", grub_efi_net_list_routes, -+ "", N_("list network routes")); -+ cmd_efi_lscards = grub_register_command ("net_efi_ls_cards", grub_efi_net_list_cards, -+ "", N_("list network cards")); -+ cmd_efi_lsaddrs = grub_register_command ("net_efi_ls_addr", grub_efi_net_list_addrs, -+ "", N_("list network addresses")); -+ cmd_efi_addaddr = grub_register_command ("net_efi_add_addr", grub_efi_net_add_addr, -+ N_("SHORTNAME CARD ADDRESS [HWADDRESS]"), -+ N_("Add a network address.")); -+ cmd_efi_bootp = grub_register_command ("net_efi_bootp", grub_efi_net_bootp, -+ N_("[CARD]"), -+ N_("perform a bootp autoconfiguration")); -+ cmd_efi_bootp6 = grub_register_command ("net_efi_bootp6", grub_efi_net_bootp6, -+ N_("[CARD]"), -+ N_("perform a bootp autoconfiguration")); -+ initialized = 1; -+ } -+} -+ -+GRUB_MOD_FINI(efi_netfs) -+{ -+ if (initialized) -+ { -+ grub_unregister_command (cmd_efi_lsroutes); -+ grub_unregister_command (cmd_efi_lscards); -+ grub_unregister_command (cmd_efi_lsaddrs); -+ grub_unregister_command (cmd_efi_addaddr); -+ grub_unregister_command (cmd_efi_bootp); -+ grub_unregister_command (cmd_efi_bootp6); -+ grub_efi_net_fs_fini (); -+ initialized = 0; -+ return; -+ } -+} -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -new file mode 100644 -index 00000000000..3f61fd2fa5b --- /dev/null +++ b/grub-core/net/efi/http.c -@@ -0,0 +1,419 @@ +@@ -0,0 +1,424 @@ + +#include +#include +#include +#include +#include ++#include + +static void +http_configure (struct grub_efi_net_device *dev, int prefer_ip6) @@ -802,7 +736,7 @@ index 00000000000..3f61fd2fa5b + + http_config.local_address_is_ipv6 = 1; + sz = sizeof (manual_address); -+ status = efi_call_4 (dev->ip6_config->get_data, dev->ip6_config, ++ status = dev->ip6_config->get_data (dev->ip6_config, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS, + &sz, &manual_address); + @@ -834,19 +768,19 @@ index 00000000000..3f61fd2fa5b + http_config.access_point.ipv4_node = &httpv4_node; + } + -+ status = efi_call_2 (http->configure, http, &http_config); ++ status = http->configure (http, &http_config); + + if (status == GRUB_EFI_ALREADY_STARTED) + { + /* XXX: This hangs HTTPS boot */ +#if 0 -+ if (efi_call_2 (http->configure, http, NULL) != GRUB_EFI_SUCCESS) ++ if (http->configure (http, NULL) != GRUB_EFI_SUCCESS) + { + grub_error (GRUB_ERR_IO, N_("couldn't reset http instance")); + grub_print_error (); + return; + } -+ status = efi_call_2 (http->configure, http, &http_config); ++ status = http->configure (http, &http_config); +#endif + return; + } @@ -862,14 +796,14 @@ index 00000000000..3f61fd2fa5b +static grub_efi_boolean_t request_callback_done; +static grub_efi_boolean_t response_callback_done; + -+static void ++static void __grub_efi_api +grub_efi_http_request_callback (grub_efi_event_t event __attribute__ ((unused)), + void *context __attribute__ ((unused))) +{ + request_callback_done = 1; +} + -+static void ++static void __grub_efi_api +grub_efi_http_response_callback (grub_efi_event_t event __attribute__ ((unused)), + void *context __attribute__ ((unused))) +{ @@ -904,6 +838,7 @@ index 00000000000..3f61fd2fa5b + grub_efi_char16_t *ucs2_url; + grub_size_t url_len, ucs2_url_len; + const char *protocol = (use_https == 1) ? "https" : "http"; ++ grub_size_t sz; + + if (grub_efi_string_to_ip6_address (server, &address, &rest) && *rest == 0) + url = grub_xasprintf ("%s://[%s]%s", protocol, server, name); @@ -916,8 +851,11 @@ index 00000000000..3f61fd2fa5b + } + + url_len = grub_strlen (url); -+ ucs2_url_len = url_len * GRUB_MAX_UTF16_PER_UTF8; -+ ucs2_url = grub_malloc ((ucs2_url_len + 1) * sizeof (ucs2_url[0])); ++ if (grub_mul (url_len, GRUB_MAX_UTF16_PER_UTF8, &ucs2_url_len) || ++ grub_add (ucs2_url_len, 1, &sz)) ++ return GRUB_ERR_OUT_OF_RANGE; ++ ++ ucs2_url = grub_calloc (sz, sizeof (ucs2_url[0])); + + if (!ucs2_url) + { @@ -945,7 +883,7 @@ index 00000000000..3f61fd2fa5b + request_token.message = &request_message; + + request_callback_done = 0; -+ status = efi_call_5 (b->create_event, ++ status = b->create_event ( + GRUB_EFI_EVT_NOTIFY_SIGNAL, + GRUB_EFI_TPL_CALLBACK, + grub_efi_http_request_callback, @@ -955,20 +893,20 @@ index 00000000000..3f61fd2fa5b + if (status != GRUB_EFI_SUCCESS) + { + grub_free (request_data.url); -+ return grub_error (GRUB_ERR_IO, "Fail to create an event! status=0x%x\n", status); ++ return grub_error (GRUB_ERR_IO, "Fail to create an event! status=0x%" PRIxGRUB_SIZE, status); + } + -+ status = efi_call_2 (http->request, http, &request_token); ++ status = http->request (http, &request_token); + + if (status != GRUB_EFI_SUCCESS) + { -+ efi_call_1 (b->close_event, request_token.event); ++ b->close_event (request_token.event); + grub_free (request_data.url); -+ return grub_error (GRUB_ERR_IO, "Fail to send a request! status=0x%x\n", status); ++ return grub_error (GRUB_ERR_IO, "Fail to send a request! status=0x%" PRIxGRUB_SIZE, status); + } + /* TODO: Add Timeout */ + while (!request_callback_done) -+ efi_call_1(http->poll, http); ++ http->poll (http); + + response_data.status_code = GRUB_EFI_HTTP_STATUS_UNSUPPORTED_STATUS; + response_message.data.response = &response_data; @@ -981,7 +919,7 @@ index 00000000000..3f61fd2fa5b + response_message.body = NULL; + response_token.event = NULL; + -+ status = efi_call_5 (b->create_event, ++ status = b->create_event ( + GRUB_EFI_EVT_NOTIFY_SIGNAL, + GRUB_EFI_TPL_CALLBACK, + grub_efi_http_response_callback, @@ -990,9 +928,9 @@ index 00000000000..3f61fd2fa5b + + if (status != GRUB_EFI_SUCCESS) + { -+ efi_call_1 (b->close_event, request_token.event); ++ b->close_event (request_token.event); + grub_free (request_data.url); -+ return grub_error (GRUB_ERR_IO, "Fail to create an event! status=0x%x\n", status); ++ return grub_error (GRUB_ERR_IO, "Fail to create an event! status=0x%" PRIxGRUB_SIZE, status); + } + + response_token.status = GRUB_EFI_SUCCESS; @@ -1000,28 +938,28 @@ index 00000000000..3f61fd2fa5b + + /* wait for HTTP response */ + response_callback_done = 0; -+ status = efi_call_2 (http->response, http, &response_token); ++ status = http->response (http, &response_token); + + if (status != GRUB_EFI_SUCCESS) + { -+ efi_call_1 (b->close_event, response_token.event); -+ efi_call_1 (b->close_event, request_token.event); ++ b->close_event (response_token.event); ++ b->close_event (request_token.event); + grub_free (request_data.url); + return grub_error (GRUB_ERR_IO, "Fail to receive a response! status=%d\n", (int)status); + } + + /* TODO: Add Timeout */ + while (!response_callback_done) -+ efi_call_1 (http->poll, http); ++ http->poll (http); + + if (response_message.data.response->status_code != GRUB_EFI_HTTP_STATUS_200_OK) + { + grub_efi_http_status_code_t status_code = response_message.data.response->status_code; + + if (response_message.headers) -+ efi_call_1 (b->free_pool, response_message.headers); -+ efi_call_1 (b->close_event, response_token.event); -+ efi_call_1 (b->close_event, request_token.event); ++ b->free_pool (response_message.headers); ++ b->close_event (response_token.event); ++ b->close_event (request_token.event); + grub_free (request_data.url); + if (status_code == GRUB_EFI_HTTP_STATUS_404_NOT_FOUND) + { @@ -1049,9 +987,9 @@ index 00000000000..3f61fd2fa5b + } + + if (response_message.headers) -+ efi_call_1 (b->free_pool, response_message.headers); -+ efi_call_1 (b->close_event, response_token.event); -+ efi_call_1 (b->close_event, request_token.event); ++ b->free_pool (response_message.headers); ++ b->close_event (response_token.event); ++ b->close_event (request_token.event); + grub_free (request_data.url); + + return GRUB_ERR_NONE; @@ -1076,7 +1014,7 @@ index 00000000000..3f61fd2fa5b + return -1; + } + -+ efi_call_5 (b->create_event, ++ b->create_event ( + GRUB_EFI_EVT_NOTIFY_SIGNAL, + GRUB_EFI_TPL_CALLBACK, + grub_efi_http_response_callback, @@ -1096,23 +1034,23 @@ index 00000000000..3f61fd2fa5b + + response_callback_done = 0; + -+ status = efi_call_2 (http->response, http, &response_token); ++ status = http->response (http, &response_token); + if (status != GRUB_EFI_SUCCESS) + { -+ efi_call_1 (b->close_event, response_token.event); ++ b->close_event (response_token.event); + grub_error (GRUB_ERR_IO, "Error! status=%d\n", (int)status); + return -1; + } + + while (!response_callback_done) -+ efi_call_1(http->poll, http); ++ http->poll (http); + + sum += response_message.body_length; + buf += response_message.body_length; + len -= response_message.body_length; + } + -+ efi_call_1 (b->close_event, response_token.event); ++ b->close_event (response_token.event); + + return sum; +} @@ -1193,27 +1131,28 @@ index 00000000000..3f61fd2fa5b + .read = grub_efihttp_read, + .close = grub_efihttp_close + }; -diff --git a/grub-core/net/efi/ip4_config.c b/grub-core/net/efi/ip4_config.c -new file mode 100644 -index 00000000000..b711a5d9457 --- /dev/null +++ b/grub-core/net/efi/ip4_config.c -@@ -0,0 +1,398 @@ +@@ -0,0 +1,409 @@ + +#include +#include +#include +#include +#include ++#include + +char * +grub_efi_hw_address_to_string (grub_efi_uint32_t hw_address_size, grub_efi_mac_address_t hw_address) +{ + char *hw_addr, *p; -+ int sz, s; ++ int s; + int i; ++ grub_size_t sz; + -+ sz = (int)hw_address_size * (sizeof ("XX:") - 1) + 1; ++ if (grub_mul (hw_address_size, sizeof ("XX:") - 1, &sz) || ++ grub_add (sz, 1, &sz)) ++ return NULL; + + hw_addr = grub_malloc (sz); + if (!hw_addr) @@ -1263,7 +1202,7 @@ index 00000000000..b711a5d9457 + for (i = 0; i < 4; i++) + { + unsigned long t; -+ t = grub_strtoul (ptr, (char **) &ptr, 0); ++ t = grub_strtoul (ptr, &ptr, 0); + if (grub_errno) + { + grub_errno = GRUB_ERR_NONE; @@ -1305,7 +1244,7 @@ index 00000000000..b711a5d9457 + if (!interface_info) + return NULL; + -+ status = efi_call_4 (ip4_config->get_data, ip4_config, ++ status = ip4_config->get_data (ip4_config, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO, + &sz, interface_info); + @@ -1313,7 +1252,7 @@ index 00000000000..b711a5d9457 + { + grub_free (interface_info); + interface_info = grub_malloc (sz); -+ status = efi_call_4 (ip4_config->get_data, ip4_config, ++ status = ip4_config->get_data (ip4_config, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO, + &sz, interface_info); + } @@ -1339,7 +1278,7 @@ index 00000000000..b711a5d9457 + if (!manual_address) + return NULL; + -+ status = efi_call_4 (ip4_config->get_data, ip4_config, ++ status = ip4_config->get_data (ip4_config, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, + &sz, manual_address); + @@ -1429,12 +1368,19 @@ index 00000000000..b711a5d9457 + grub_efi_ip4_config2_interface_info_t *interface_info; + char **ret; + int i, id; ++ grub_size_t sz; + + interface_info = efi_ip4_config_interface_info (dev->ip4_config); + if (!interface_info) + return NULL; + -+ ret = grub_malloc (sizeof (*ret) * (interface_info->route_table_size + 1)); ++ if (grub_add (interface_info->route_table_size, 1, &sz)) ++ { ++ grub_free (interface_info); ++ return NULL; ++ } ++ ++ ret = grub_calloc (sz, sizeof (*ret)); + + if (!ret) + { @@ -1546,7 +1492,7 @@ index 00000000000..b711a5d9457 + } + } + -+ status = efi_call_4 (dev->ip4_config->set_data, dev->ip4_config, ++ status = dev->ip4_config->set_data (dev->ip4_config, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, + sizeof(*address), address); + @@ -1562,7 +1508,7 @@ index 00000000000..b711a5d9457 +{ + grub_efi_status_t status; + -+ status = efi_call_4 (dev->ip4_config->set_data, dev->ip4_config, ++ status = dev->ip4_config->set_data (dev->ip4_config, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_GATEWAY, + sizeof (address->ip4), &address->ip4); + @@ -1578,7 +1524,7 @@ index 00000000000..b711a5d9457 +{ + grub_efi_status_t status; + -+ status = efi_call_4 (dev->ip4_config->set_data, dev->ip4_config, ++ status = dev->ip4_config->set_data (dev->ip4_config, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, + sizeof (address->ip4), &address->ip4); + @@ -1597,17 +1543,15 @@ index 00000000000..b711a5d9457 + .set_gateway = grub_efi_ip4_interface_set_gateway, + .set_dns = grub_efi_ip4_interface_set_dns + }; -diff --git a/grub-core/net/efi/ip6_config.c b/grub-core/net/efi/ip6_config.c -new file mode 100644 -index 00000000000..017c4d05bc7 --- /dev/null +++ b/grub-core/net/efi/ip6_config.c -@@ -0,0 +1,422 @@ +@@ -0,0 +1,430 @@ +#include +#include +#include +#include +#include ++#include + +char * +grub_efi_ip6_address_to_string (grub_efi_pxe_ipv6_address_t *address) @@ -1689,7 +1633,7 @@ index 00000000000..017c4d05bc7 + ptr++; + continue; + } -+ t = grub_strtoul (ptr, (char **) &ptr, 16); ++ t = grub_strtoul (ptr, &ptr, 16); + if (grub_errno) + { + grub_errno = GRUB_ERR_NONE; @@ -1729,7 +1673,7 @@ index 00000000000..017c4d05bc7 + sz = sizeof (*interface_info) + sizeof (*interface_info->route_table); + interface_info = grub_malloc (sz); + -+ status = efi_call_4 (ip6_config->get_data, ip6_config, ++ status = ip6_config->get_data (ip6_config, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO, + &sz, interface_info); + @@ -1737,7 +1681,7 @@ index 00000000000..017c4d05bc7 + { + grub_free (interface_info); + interface_info = grub_malloc (sz); -+ status = efi_call_4 (ip6_config->get_data, ip6_config, ++ status = ip6_config->get_data (ip6_config, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO, + &sz, interface_info); + } @@ -1763,7 +1707,7 @@ index 00000000000..017c4d05bc7 + if (!manual_address) + return NULL; + -+ status = efi_call_4 (ip6_config->get_data, ip6_config, ++ status = ip6_config->get_data (ip6_config, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS, + &sz, manual_address); + @@ -1834,12 +1778,19 @@ index 00000000000..017c4d05bc7 + grub_efi_ip6_config_interface_info_t *interface_info; + char **ret; + int i, id; ++ grub_size_t sz; + + interface_info = efi_ip6_config_interface_info (dev->ip6_config); + if (!interface_info) + return NULL; + -+ ret = grub_malloc (sizeof (*ret) * (interface_info->route_count + 1)); ++ if (grub_add (interface_info->route_count, 1, &sz)) ++ { ++ grub_free (interface_info); ++ return NULL; ++ } ++ ++ ret = grub_calloc (sz, sizeof (*ret)); + + if (!ret) + { @@ -1974,7 +1925,7 @@ index 00000000000..017c4d05bc7 + } + } + -+ status = efi_call_4 (dev->ip6_config->set_data, dev->ip6_config, ++ status = dev->ip6_config->set_data (dev->ip6_config, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS, + sizeof(*address), address); + @@ -1990,7 +1941,7 @@ index 00000000000..017c4d05bc7 +{ + grub_efi_status_t status; + -+ status = efi_call_4 (dev->ip6_config->set_data, dev->ip6_config, ++ status = dev->ip6_config->set_data (dev->ip6_config, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_GATEWAY, + sizeof (address->ip6), &address->ip6); + @@ -2006,7 +1957,7 @@ index 00000000000..017c4d05bc7 + + grub_efi_status_t status; + -+ status = efi_call_4 (dev->ip6_config->set_data, dev->ip6_config, ++ status = dev->ip6_config->set_data (dev->ip6_config, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, + sizeof (address->ip6), &address->ip6); + @@ -2025,12 +1976,9 @@ index 00000000000..017c4d05bc7 + .set_gateway = grub_efi_ip6_interface_set_gateway, + .set_dns = grub_efi_ip6_interface_set_dns + }; -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -new file mode 100644 -index 00000000000..86bce6535d3 --- /dev/null +++ b/grub-core/net/efi/net.c -@@ -0,0 +1,1428 @@ +@@ -0,0 +1,1440 @@ +#include +#include +#include @@ -2045,20 +1993,21 @@ index 00000000000..86bce6535d3 +#include +#include +#include ++#include + +GRUB_MOD_LICENSE ("GPLv3+"); + +#define GRUB_EFI_IP6_PREFIX_LENGTH 64 + -+static grub_efi_guid_t ip4_config_guid = GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID; -+static grub_efi_guid_t ip6_config_guid = GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID; -+static grub_efi_guid_t http_service_binding_guid = GRUB_EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID; -+static grub_efi_guid_t http_guid = GRUB_EFI_HTTP_PROTOCOL_GUID; -+static grub_efi_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID; -+static grub_efi_guid_t dhcp4_service_binding_guid = GRUB_EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID; -+static grub_efi_guid_t dhcp4_guid = GRUB_EFI_DHCP4_PROTOCOL_GUID; -+static grub_efi_guid_t dhcp6_service_binding_guid = GRUB_EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID; -+static grub_efi_guid_t dhcp6_guid = GRUB_EFI_DHCP6_PROTOCOL_GUID; ++static grub_guid_t ip4_config_guid = GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID; ++static grub_guid_t ip6_config_guid = GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID; ++static grub_guid_t http_service_binding_guid = GRUB_EFI_HTTP_SERVICE_BINDING_PROTOCOL_GUID; ++static grub_guid_t http_guid = GRUB_EFI_HTTP_PROTOCOL_GUID; ++static grub_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID; ++static grub_guid_t dhcp4_service_binding_guid = GRUB_EFI_DHCP4_SERVICE_BINDING_PROTOCOL_GUID; ++static grub_guid_t dhcp4_guid = GRUB_EFI_DHCP4_PROTOCOL_GUID; ++static grub_guid_t dhcp6_service_binding_guid = GRUB_EFI_DHCP6_SERVICE_BINDING_PROTOCOL_GUID; ++static grub_guid_t dhcp6_guid = GRUB_EFI_DHCP6_PROTOCOL_GUID; + +struct grub_efi_net_device *net_devices; + @@ -2073,13 +2022,13 @@ index 00000000000..86bce6535d3 +#define efi_net_interface(m,...) efi_net_interface_ ## m (net_interface, ## __VA_ARGS__) + +static grub_efi_handle_t -+grub_efi_locate_device_path (grub_efi_guid_t *protocol, grub_efi_device_path_t *device_path, ++grub_efi_locate_device_path (grub_guid_t *protocol, grub_efi_device_path_t *device_path, + grub_efi_device_path_t **r_device_path) +{ + grub_efi_handle_t handle; + grub_efi_status_t status; + -+ status = efi_call_3 (grub_efi_system_table->boot_services->locate_device_path, ++ status = grub_efi_system_table->boot_services->locate_device_path ( + protocol, &device_path, &handle); + + if (status != GRUB_EFI_SUCCESS) @@ -2270,7 +2219,15 @@ index 00000000000..86bce6535d3 + + if (code == GRUB_NET_DHCP6_OPTION_BOOTFILE_URL) + { -+ char *url = grub_malloc (len + 1); ++ char *url; ++ grub_size_t sz; ++ ++ if (grub_add (len, 1, &sz)) ++ return; ++ ++ url = grub_malloc (sz); ++ if (!url) ++ return; + + grub_memcpy (url, dhcp_opt->data, len); + url[len] = 0; @@ -2379,7 +2336,7 @@ index 00000000000..86bce6535d3 + device, + path); + -+ grub_memcpy (net_ip.ip6.address, pxe->mode->station_ip.v6, sizeof(net_ip.ip6.address)); ++ grub_memcpy (net_ip.ip6.address, pxe->mode->station_ip.v6.addr, sizeof(net_ip.ip6.address)); + net_ip.ip6.prefix_length = GRUB_EFI_IP6_PREFIX_LENGTH; + net_ip.ip6.is_anycast = 0; + net_ip.is_ip6 = 1; @@ -2398,8 +2355,8 @@ index 00000000000..86bce6535d3 + path, + 1); + -+ grub_memcpy (net_ip.ip4.address, pxe->mode->station_ip.v4, sizeof (net_ip.ip4.address)); -+ grub_memcpy (net_ip.ip4.subnet_mask, pxe->mode->subnet_mask.v4, sizeof (net_ip.ip4.subnet_mask)); ++ grub_memcpy (net_ip.ip4.address, pxe->mode->station_ip.v4.addr, sizeof (net_ip.ip4.address)); ++ grub_memcpy (net_ip.ip4.subnet_mask, pxe->mode->subnet_mask.v4.addr, sizeof (net_ip.ip4.subnet_mask)); + net_ip.is_ip6 = 0; + return (grub_efi_net_create_interface (netdev, + netdev->card_name, @@ -2721,7 +2678,7 @@ index 00000000000..86bce6535d3 +} + +static grub_efi_handle_t -+grub_efi_service_binding (grub_efi_handle_t dev, grub_efi_guid_t *service_binding_guid) ++grub_efi_service_binding (grub_efi_handle_t dev, grub_guid_t *service_binding_guid) +{ + grub_efi_service_binding_t *service; + grub_efi_status_t status; @@ -2734,10 +2691,10 @@ index 00000000000..86bce6535d3 + return NULL; + } + -+ status = efi_call_2 (service->create_child, service, &child_dev); ++ status = service->create_child (service, &child_dev); + if (status != GRUB_EFI_SUCCESS) + { -+ grub_error (GRUB_ERR_IO, N_("Failed to create child device of http service %x"), status); ++ grub_error (GRUB_ERR_IO, N_("Failed to create child device of http service %" PRIxGRUB_SIZE), status); + return NULL; + } + @@ -2760,7 +2717,7 @@ index 00000000000..86bce6535d3 + { + grub_uint32_t subnet_mask_size; + -+ subnet_mask_size = grub_strtoul (rest + 1, (char **) &rest, 0); ++ subnet_mask_size = grub_strtoul (rest + 1, &rest, 0); + + if (!grub_errno && subnet_mask_size <= 32 && *rest == 0) + { @@ -2789,7 +2746,7 @@ index 00000000000..86bce6535d3 + { + grub_efi_uint8_t prefix_length; + -+ prefix_length = grub_strtoul (rest + 1, (char **) &rest, 0); ++ prefix_length = grub_strtoul (rest + 1, &rest, 0); + if (!grub_errno && prefix_length <= 128 && *rest == 0) + { + ip6->prefix_length = prefix_length; @@ -2823,13 +2780,16 @@ index 00000000000..86bce6535d3 + grub_efi_net_interface_t *inf; + int is_ip6 = 0; + ++ grub_error_push (); + err = grub_efi_net_parse_address (server, &ip4, &ip6, &is_ip6, 0); + + if (err) + { -+ grub_print_error (); ++ grub_dprintf ("efinetfs", "error in matching route : %s\n", grub_errmsg); ++ grub_error_pop (); + return NULL; + } ++ grub_error_pop (); + + if (is_ip6) + { @@ -2944,7 +2904,7 @@ index 00000000000..86bce6535d3 + { + grub_efi_ip4_config2_policy_t ip4_policy = GRUB_EFI_IP4_CONFIG2_POLICY_STATIC; + -+ if (efi_call_4 (dev->ip4_config->set_data, dev->ip4_config, ++ if (dev->ip4_config->set_data (dev->ip4_config, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_POLICY, + sizeof (ip4_policy), &ip4_policy) != GRUB_EFI_SUCCESS) + grub_dprintf ("efinetfs", "could not set GRUB_EFI_IP4_CONFIG2_POLICY_STATIC on dev `%s'", dev->card_name); @@ -2953,7 +2913,7 @@ index 00000000000..86bce6535d3 + { + grub_efi_ip6_config_policy_t ip6_policy = GRUB_EFI_IP6_CONFIG_POLICY_MANUAL; + -+ if (efi_call_4 (dev->ip6_config->set_data, dev->ip6_config, ++ if (dev->ip6_config->set_data (dev->ip6_config, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_POLICY, + sizeof (ip6_policy), &ip6_policy) != GRUB_EFI_SUCCESS) + grub_dprintf ("efinetfs", "could not set GRUB_EFI_IP6_CONFIG_POLICY_MANUAL on dev `%s'", dev->card_name); @@ -3459,9 +3419,6 @@ index 00000000000..86bce6535d3 + grub_net_open = NULL; + grub_fs_unregister (&grub_efi_netfs); +} -diff --git a/grub-core/net/efi/pxe.c b/grub-core/net/efi/pxe.c -new file mode 100644 -index 00000000000..531949cba5c --- /dev/null +++ b/grub-core/net/efi/pxe.c @@ -0,0 +1,424 @@ @@ -3484,7 +3441,7 @@ index 00000000000..531949cba5c + if (!manual_address) + return NULL; + -+ status = efi_call_4 (ip6_config->get_data, ip6_config, ++ status = ip6_config->get_data (ip6_config, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS, + &sz, manual_address); + @@ -3509,7 +3466,7 @@ index 00000000000..531949cba5c + if (!manual_address) + return NULL; + -+ status = efi_call_4 (ip4_config->get_data, ip4_config, ++ status = ip4_config->get_data (ip4_config, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS, + &sz, manual_address); + @@ -3532,7 +3489,7 @@ index 00000000000..531949cba5c + if (!mode->started) + { + grub_efi_status_t status; -+ status = efi_call_2 (pxe->start, pxe, prefer_ip6); ++ status = pxe->start (pxe, prefer_ip6); + + if (status != GRUB_EFI_SUCCESS) + grub_printf ("Couldn't start PXE\n"); @@ -3549,13 +3506,13 @@ index 00000000000..531949cba5c + manual_address = efi_ip6_config_manual_address (dev->ip6_config); + + if (manual_address && -+ grub_memcmp (manual_address->address, mode->station_ip.v6, sizeof (manual_address->address)) != 0) ++ grub_memcmp (manual_address->address, mode->station_ip.v6.addr, sizeof (manual_address->address)) != 0) + { + grub_efi_status_t status; + grub_efi_pxe_ip_address_t station_ip; + + grub_memcpy (station_ip.v6.addr, manual_address->address, sizeof (station_ip.v6.addr)); -+ status = efi_call_3 (pxe->set_station_ip, pxe, &station_ip, NULL); ++ status = pxe->set_station_ip (pxe, &station_ip, NULL); + + if (status != GRUB_EFI_SUCCESS) + grub_printf ("Couldn't set station ip\n"); @@ -3569,7 +3526,7 @@ index 00000000000..531949cba5c + manual_address = efi_ip4_config_manual_address (dev->ip4_config); + + if (manual_address && -+ grub_memcmp (manual_address->address, mode->station_ip.v4, sizeof (manual_address->address)) != 0) ++ grub_memcmp (manual_address->address, mode->station_ip.v4.addr, sizeof (manual_address->address)) != 0) + { + grub_efi_status_t status; + grub_efi_pxe_ip_address_t station_ip; @@ -3578,7 +3535,7 @@ index 00000000000..531949cba5c + grub_memcpy (station_ip.v4.addr, manual_address->address, sizeof (station_ip.v4.addr)); + grub_memcpy (subnet_mask.v4.addr, manual_address->subnet_mask, sizeof (subnet_mask.v4.addr)); + -+ status = efi_call_3 (pxe->set_station_ip, pxe, &station_ip, &subnet_mask); ++ status = pxe->set_station_ip (pxe, &station_ip, &subnet_mask); + + if (status != GRUB_EFI_SUCCESS) + grub_printf ("Couldn't set station ip\n"); @@ -3654,7 +3611,7 @@ index 00000000000..531949cba5c + ptr++; + continue; + } -+ t = grub_strtoul (ptr, (char **) &ptr, 16); ++ t = grub_strtoul (ptr, &ptr, 16); + if (grub_errno) + { + grub_errno = GRUB_ERR_NONE; @@ -3692,7 +3649,7 @@ index 00000000000..531949cba5c + int type __attribute__((unused))) +{ + int i; -+ char *p; ++ const char *p; + grub_efi_status_t status; + grub_efi_pxe_ip_address_t server_ip; + grub_efi_uint64_t file_size = 0; @@ -3731,7 +3688,7 @@ index 00000000000..531949cba5c + server_ip.v4.addr[i] = grub_strtoul (p, &p, 10); + } + -+ status = efi_call_10 (pxe->mtftp, ++ status = pxe->mtftp ( + pxe, + GRUB_EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE, + NULL, @@ -3780,7 +3737,7 @@ index 00000000000..531949cba5c + grub_size_t len) +{ + int i; -+ char *p; ++ const char *p; + grub_efi_status_t status; + grub_efi_pxe_t *pxe = (prefer_ip6) ? dev->ip6_pxe : dev->ip4_pxe; + grub_efi_uint64_t bufsz = len; @@ -3816,7 +3773,7 @@ index 00000000000..531949cba5c + server_ip.v4.addr[i] = grub_strtoul (p, &p, 10); + } + -+ status = efi_call_10 (pxe->mtftp, ++ status = pxe->mtftp ( + pxe, + GRUB_EFI_PXE_BASE_CODE_TFTP_READ_FILE, + buf, @@ -3847,7 +3804,7 @@ index 00000000000..531949cba5c + return 0; + } + -+ status = efi_call_10 (pxe->mtftp, ++ status = pxe->mtftp ( + pxe, + GRUB_EFI_PXE_BASE_CODE_TFTP_READ_FILE, + buf2, @@ -3889,8 +3846,6 @@ index 00000000000..531949cba5c + .close = pxe_close + }; + -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 0ce5e675ed7..55aed92722c 100644 --- a/grub-core/net/net.c +++ b/grub-core/net/net.c @@ -32,6 +32,9 @@ @@ -3903,8 +3858,8 @@ index 0ce5e675ed7..55aed92722c 100644 GRUB_MOD_LICENSE ("GPLv3+"); -@@ -2033,8 +2036,49 @@ static grub_command_t cmd_addaddr, cmd_deladdr, cmd_addroute, cmd_delroute; - static grub_command_t cmd_lsroutes, cmd_lscards; +@@ -2014,8 +2017,49 @@ + static grub_command_t cmd_setvlan, cmd_lsroutes, cmd_lscards; static grub_command_t cmd_lsaddr, cmd_slaac; +#ifdef GRUB_MACHINE_EFI @@ -3953,7 +3908,7 @@ index 0ce5e675ed7..55aed92722c 100644 grub_register_variable_hook ("net_default_server", defserver_get_env, defserver_set_env); grub_env_export ("net_default_server"); -@@ -2082,10 +2126,37 @@ GRUB_MOD_INIT(net) +@@ -2066,10 +2110,37 @@ grub_net_restore_hw, GRUB_LOADER_PREBOOT_HOOK_PRIO_DISK); grub_net_poll_cards_idle = grub_net_poll_cards_idle_real; @@ -3991,102 +3946,18 @@ index 0ce5e675ed7..55aed92722c 100644 grub_register_variable_hook ("net_default_server", 0, 0); grub_register_variable_hook ("pxe_default_server", 0, 0); -@@ -2104,4 +2175,7 @@ GRUB_MOD_FINI(net) +@@ -2088,4 +2159,7 @@ grub_net_fini_hw (0); grub_loader_unregister_preboot_hook (fini_hnd); - grub_net_poll_cards_idle = grub_net_poll_cards_idle_real; + grub_net_poll_cards_idle = NULL; +#ifdef GRUB_MACHINE_EFI + init_mode = INIT_MODE_NONE; +#endif } -diff --git a/util/grub-mknetdir.c b/util/grub-mknetdir.c -index a2461cda1c4..77958dd9dd5 100644 ---- a/util/grub-mknetdir.c -+++ b/util/grub-mknetdir.c -@@ -32,13 +32,15 @@ - - static char *rootdir = NULL, *subdir = NULL; - static char *debug_image = NULL; -+static char efi_netfs = 0; - - enum - { - OPTION_NET_DIRECTORY = 0x301, - OPTION_SUBDIR, - OPTION_DEBUG, -- OPTION_DEBUG_IMAGE -+ OPTION_DEBUG_IMAGE, -+ OPTION_DEBUG_EFI_NETFS - }; - - static struct argp_option options[] = { -@@ -49,6 +51,7 @@ static struct argp_option options[] = { - 0, N_("relative subdirectory on network server"), 2}, - {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, - {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2}, -+ {"debug-efi-netfs", OPTION_DEBUG_EFI_NETFS, 0, OPTION_HIDDEN, 0, 2}, - {0, 0, 0, 0, 0, 0} - }; - -@@ -67,6 +70,9 @@ argp_parser (int key, char *arg, struct argp_state *state) - free (subdir); - subdir = xstrdup (arg); - return 0; -+ case OPTION_DEBUG_EFI_NETFS: -+ efi_netfs = 1; -+ return 0; - /* This is an undocumented feature... */ - case OPTION_DEBUG: - verbosity++; -@@ -82,7 +88,6 @@ argp_parser (int key, char *arg, struct argp_state *state) - } - } - -- - struct argp argp = { - options, argp_parser, NULL, - "\v"N_("Prepares GRUB network boot images at net_directory/subdir " -@@ -92,7 +97,7 @@ struct argp argp = { - - static char *base; - --static const struct -+static struct - { - const char *mkimage_target; - const char *netmodule; -@@ -156,6 +161,7 @@ process_input_dir (const char *input_dir, enum grub_install_plat platform) - grub_install_push_module (targets[platform].netmodule); - - output = grub_util_path_concat_ext (2, grubdir, "core", targets[platform].ext); -+ - grub_install_make_image_wrap (input_dir, prefix, output, - 0, load_cfg, - targets[platform].mkimage_target, 0); -@@ -195,7 +201,16 @@ main (int argc, char *argv[]) - - grub_install_mkdir_p (base); - -- grub_install_push_module ("tftp"); -+ if (!efi_netfs) -+ { -+ grub_install_push_module ("tftp"); -+ grub_install_push_module ("http"); -+ } -+ else -+ { -+ targets[GRUB_INSTALL_PLATFORM_I386_EFI].netmodule = "efi_netfs"; -+ targets[GRUB_INSTALL_PLATFORM_X86_64_EFI].netmodule = "efi_netfs"; -+ } - - if (!grub_install_source_directory) - { -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 0b490195ad9..f431f49973e 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h -@@ -622,6 +622,23 @@ typedef union - +@@ -653,6 +653,23 @@ + typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4))); typedef grub_efi_uint64_t grub_efi_physical_address_t; typedef grub_efi_uint64_t grub_efi_virtual_address_t; +typedef struct { @@ -4107,9 +3978,9 @@ index 0b490195ad9..f431f49973e 100644 + grub_efi_pxe_ipv6_address_t v6; +} grub_efi_pxe_ip_address_t; - struct grub_efi_guid - { -@@ -889,6 +906,8 @@ struct grub_efi_ipv6_device_path + /* XXX although the spec does not specify the padding, this actually + must have the padding! */ +@@ -902,6 +919,8 @@ grub_efi_uint16_t remote_port; grub_efi_uint16_t protocol; grub_efi_uint8_t static_ip_address; @@ -4118,7 +3989,7 @@ index 0b490195ad9..f431f49973e 100644 } GRUB_PACKED; typedef struct grub_efi_ipv6_device_path grub_efi_ipv6_device_path_t; -@@ -938,6 +957,15 @@ struct grub_efi_uri_device_path +@@ -960,6 +979,15 @@ } GRUB_PACKED; typedef struct grub_efi_uri_device_path grub_efi_uri_device_path_t; @@ -4134,7 +4005,7 @@ index 0b490195ad9..f431f49973e 100644 #define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10 /* Media Device Path. */ -@@ -1020,6 +1048,23 @@ struct grub_efi_bios_device_path +@@ -1042,6 +1070,23 @@ } GRUB_PACKED; typedef struct grub_efi_bios_device_path grub_efi_bios_device_path_t; @@ -4142,11 +4013,11 @@ index 0b490195ad9..f431f49973e 100644 +struct grub_efi_service_binding; + +typedef grub_efi_status_t -+(*grub_efi_service_binding_create_child) (struct grub_efi_service_binding *this, ++(__grub_efi_api *grub_efi_service_binding_create_child) (struct grub_efi_service_binding *this, + grub_efi_handle_t *child_handle); + +typedef grub_efi_status_t -+(*grub_efi_service_binding_destroy_child) (struct grub_efi_service_binding *this, ++(__grub_efi_api *grub_efi_service_binding_destroy_child) (struct grub_efi_service_binding *this, + grub_efi_handle_t *child_handle); + +typedef struct grub_efi_service_binding @@ -4158,9 +4029,9 @@ index 0b490195ad9..f431f49973e 100644 struct grub_efi_open_protocol_information_entry { grub_efi_handle_t agent_handle; -@@ -1569,23 +1614,27 @@ typedef struct grub_efi_pxe_tftp_error - grub_efi_char8_t error_string[127]; - } grub_efi_pxe_tftp_error_t; +@@ -1544,23 +1589,28 @@ + + typedef grub_uint8_t grub_efi_pxe_packet_t[1472]; -typedef struct { - grub_uint8_t addr[4]; @@ -4182,15 +4053,16 @@ index 0b490195ad9..f431f49973e 100644 + GRUB_EFI_PXE_BASE_CODE_MTFTP_LAST +} grub_efi_pxe_base_code_tftp_opcode_t; - typedef struct { +-typedef struct { - grub_uint8_t addr[32]; -} grub_efi_pxe_mac_address_t; -- + -typedef union { -- grub_uint32_t addr[4]; -- grub_efi_pxe_ipv4_address_t v4; -- grub_efi_pxe_ipv6_address_t v6; +- grub_uint32_t addr[4]; +- grub_efi_pxe_ipv4_address_t v4; +- grub_efi_pxe_ipv6_address_t v6; -} grub_efi_pxe_ip_address_t; ++typedef struct { + grub_efi_ip_address_t mcast_ip; + grub_efi_pxe_base_code_udp_port_t c_port; + grub_efi_pxe_base_code_udp_port_t s_port; @@ -4199,20 +4071,29 @@ index 0b490195ad9..f431f49973e 100644 +} grub_efi_pxe_base_code_mtftp_info_t; #define GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT 8 - typedef struct grub_efi_pxe_ip_filter -@@ -1652,17 +1701,31 @@ typedef struct grub_efi_pxe_mode + typedef struct { +@@ -1610,18 +1660,32 @@ typedef struct grub_efi_pxe { grub_uint64_t rev; -- void (*start) (void); -+ grub_efi_status_t (*start) (struct grub_efi_pxe *this, grub_efi_boolean_t use_ipv6); - void (*stop) (void); -- void (*dhcp) (void); -+ grub_efi_status_t (*dhcp) (struct grub_efi_pxe *this, +- void *start; +- void *stop; +- void *dhcp; +- void *discover; +- void *mftp; +- void *udpwrite; +- void *udpread; +- void *setipfilter; +- void *arp; +- void *setparams; +- void *setstationip; +- void *setpackets; ++ grub_efi_status_t (__grub_efi_api *start) (struct grub_efi_pxe *this, grub_efi_boolean_t use_ipv6); ++ void (__grub_efi_api *stop) (void); ++ grub_efi_status_t (__grub_efi_api *dhcp) (struct grub_efi_pxe *this, + grub_efi_boolean_t sort_offers); - void (*discover) (void); -- void (*mftp) (void); -+ grub_efi_status_t (*mtftp) (struct grub_efi_pxe *this, ++ void (__grub_efi_api *discover) (void); ++ grub_efi_status_t (__grub_efi_api *mtftp) (struct grub_efi_pxe *this, + grub_efi_pxe_base_code_tftp_opcode_t operation, + void *buffer_ptr, + grub_efi_boolean_t overwrite, @@ -4223,20 +4104,20 @@ index 0b490195ad9..f431f49973e 100644 + grub_efi_char8_t *filename, + grub_efi_pxe_base_code_mtftp_info_t *info, + grub_efi_boolean_t dont_use_buffer); - void (*udpwrite) (void); - void (*udpread) (void); - void (*setipfilter) (void); - void (*arp) (void); - void (*setparams) (void); -- void (*setstationip) (void); -+ grub_efi_status_t (*set_station_ip) (struct grub_efi_pxe *this, ++ void (__grub_efi_api *udpwrite) (void); ++ void (__grub_efi_api *udpread) (void); ++ void (__grub_efi_api *setipfilter) (void); ++ void (__grub_efi_api *arp) (void); ++ void (__grub_efi_api *setparams) (void); ++ grub_efi_status_t (__grub_efi_api *set_station_ip) (struct grub_efi_pxe *this, + grub_efi_pxe_ip_address_t *new_station_ip, + grub_efi_pxe_ip_address_t *new_subnet_mask); + //void (*setstationip) (void); - void (*setpackets) (void); ++ void (__grub_efi_api *setpackets) (void); struct grub_efi_pxe_mode *mode; } grub_efi_pxe_t; -@@ -1924,6 +1987,44 @@ struct grub_efi_ip4_config2_protocol + +@@ -1921,6 +1985,44 @@ }; typedef struct grub_efi_ip4_config2_protocol grub_efi_ip4_config2_protocol_t; @@ -4281,7 +4162,7 @@ index 0b490195ad9..f431f49973e 100644 enum grub_efi_ip6_config_data_type { GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO, GRUB_EFI_IP6_CONFIG_DATA_TYPE_ALT_INTERFACEID, -@@ -1958,6 +2059,49 @@ struct grub_efi_ip6_config_protocol +@@ -1955,4 +2057,47 @@ }; typedef struct grub_efi_ip6_config_protocol grub_efi_ip6_config_protocol_t; @@ -4328,12 +4209,7 @@ index 0b490195ad9..f431f49973e 100644 +}; +typedef struct grub_efi_ip6_config_manual_address grub_efi_ip6_config_manual_address_t; + - #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ - || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \ - || defined(__riscv) -diff --git a/include/grub/efi/dhcp.h b/include/grub/efi/dhcp.h -new file mode 100644 -index 00000000000..fdb88eb810e + #endif /* ! GRUB_EFI_API_HEADER */ --- /dev/null +++ b/include/grub/efi/dhcp.h @@ -0,0 +1,343 @@ @@ -4492,27 +4368,27 @@ index 00000000000..fdb88eb810e +typedef struct grub_efi_dhcp4_mode_data grub_efi_dhcp4_mode_data_t; + +struct grub_efi_dhcp4_protocol { -+ grub_efi_status_t (*get_mode_data) (grub_efi_dhcp4_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *get_mode_data) (grub_efi_dhcp4_protocol_t *this, + grub_efi_dhcp4_mode_data_t *dhcp4_mode_data); -+ grub_efi_status_t (*configure) (grub_efi_dhcp4_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *configure) (grub_efi_dhcp4_protocol_t *this, + grub_efi_dhcp4_config_data_t *dhcp4_cfg_data); -+ grub_efi_status_t (*start) (grub_efi_dhcp4_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *start) (grub_efi_dhcp4_protocol_t *this, + grub_efi_event_t completion_event); -+ grub_efi_status_t (*renew_rebind) (grub_efi_dhcp4_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *renew_rebind) (grub_efi_dhcp4_protocol_t *this, + grub_efi_boolean_t rebind_request, + grub_efi_event_t completion_event); -+ grub_efi_status_t (*release) (grub_efi_dhcp4_protocol_t *this); -+ grub_efi_status_t (*stop) (grub_efi_dhcp4_protocol_t *this); -+ grub_efi_status_t (*build) (grub_efi_dhcp4_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *release) (grub_efi_dhcp4_protocol_t *this); ++ grub_efi_status_t (__grub_efi_api *stop) (grub_efi_dhcp4_protocol_t *this); ++ grub_efi_status_t (__grub_efi_api *build) (grub_efi_dhcp4_protocol_t *this, + grub_efi_dhcp4_packet_t *seed_packet, + grub_efi_uint32_t delete_count, + grub_efi_uint8_t *delete_list, + grub_efi_uint32_t append_count, + grub_efi_dhcp4_packet_option_t *append_list[], + grub_efi_dhcp4_packet_t **new_packet); -+ grub_efi_status_t (*transmit_receive) (grub_efi_dhcp4_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *transmit_receive) (grub_efi_dhcp4_protocol_t *this, + grub_efi_dhcp4_transmit_receive_token_t *token); -+ grub_efi_status_t (*parse) (grub_efi_dhcp4_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *parse) (grub_efi_dhcp4_protocol_t *this, + grub_efi_dhcp4_packet_t *packet, + grub_efi_uint32_t *option_count, + grub_efi_dhcp4_packet_option_t *packet_option_list[]); @@ -4647,42 +4523,39 @@ index 00000000000..fdb88eb810e +typedef struct grub_efi_dhcp6_config_data grub_efi_dhcp6_config_data_t; + +struct grub_efi_dhcp6_protocol { -+ grub_efi_status_t (*get_mode_data) (grub_efi_dhcp6_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *get_mode_data) (grub_efi_dhcp6_protocol_t *this, + grub_efi_dhcp6_mode_data_t *dhcp6_mode_data, + grub_efi_dhcp6_config_data_t *dhcp6_config_data); -+ grub_efi_status_t (*configure) (grub_efi_dhcp6_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *configure) (grub_efi_dhcp6_protocol_t *this, + grub_efi_dhcp6_config_data_t *dhcp6_cfg_data); -+ grub_efi_status_t (*start) (grub_efi_dhcp6_protocol_t *this); -+ grub_efi_status_t (*info_request) (grub_efi_dhcp6_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *start) (grub_efi_dhcp6_protocol_t *this); ++ grub_efi_status_t (__grub_efi_api *info_request) (grub_efi_dhcp6_protocol_t *this, + grub_efi_boolean_t send_client_id, + grub_efi_dhcp6_packet_option_t *option_request, + grub_efi_uint32_t option_count, + grub_efi_dhcp6_packet_option_t *option_list[], + grub_efi_dhcp6_retransmission_t *retransmission, + grub_efi_event_t timeout_event, -+ grub_efi_status_t (*reply_callback) (grub_efi_dhcp6_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *reply_callback) (grub_efi_dhcp6_protocol_t *this, + void *context, + grub_efi_dhcp6_packet_t *packet), + void *callback_context); -+ grub_efi_status_t (*renew_rebind) (grub_efi_dhcp6_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *renew_rebind) (grub_efi_dhcp6_protocol_t *this, + grub_efi_boolean_t rebind_request); -+ grub_efi_status_t (*decline) (grub_efi_dhcp6_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *decline) (grub_efi_dhcp6_protocol_t *this, + grub_efi_uint32_t address_count, + grub_efi_ipv6_address_t *addresses); -+ grub_efi_status_t (*release) (grub_efi_dhcp6_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *release) (grub_efi_dhcp6_protocol_t *this, + grub_efi_uint32_t address_count, + grub_efi_ipv6_address_t *addresses); -+ grub_efi_status_t (*stop) (grub_efi_dhcp6_protocol_t *this); -+ grub_efi_status_t (*parse) (grub_efi_dhcp6_protocol_t *this, ++ grub_efi_status_t (__grub_efi_api *stop) (grub_efi_dhcp6_protocol_t *this); ++ grub_efi_status_t (__grub_efi_api *parse) (grub_efi_dhcp6_protocol_t *this, + grub_efi_dhcp6_packet_t *packet, + grub_efi_uint32_t *option_count, + grub_efi_dhcp6_packet_option_t *packet_option_list[]); +}; + +#endif /* ! GRUB_EFI_DHCP_HEADER */ -diff --git a/include/grub/efi/http.h b/include/grub/efi/http.h -new file mode 100644 -index 00000000000..c5e9a89f505 --- /dev/null +++ b/include/grub/efi/http.h @@ -0,0 +1,215 @@ @@ -4876,34 +4749,31 @@ index 00000000000..c5e9a89f505 + +struct grub_efi_http { + grub_efi_status_t -+ (*get_mode_data) (struct grub_efi_http *this, ++ (__grub_efi_api *get_mode_data) (struct grub_efi_http *this, + grub_efi_http_config_data_t *http_config_data); + + grub_efi_status_t -+ (*configure) (struct grub_efi_http *this, ++ (__grub_efi_api *configure) (struct grub_efi_http *this, + grub_efi_http_config_data_t *http_config_data); + + grub_efi_status_t -+ (*request) (struct grub_efi_http *this, ++ (__grub_efi_api *request) (struct grub_efi_http *this, + grub_efi_http_token_t *token); + + grub_efi_status_t -+ (*cancel) (struct grub_efi_http *this, ++ (__grub_efi_api *cancel) (struct grub_efi_http *this, + grub_efi_http_token_t *token); + + grub_efi_status_t -+ (*response) (struct grub_efi_http *this, ++ (__grub_efi_api *response) (struct grub_efi_http *this, + grub_efi_http_token_t *token); + + grub_efi_status_t -+ (*poll) (struct grub_efi_http *this); ++ (__grub_efi_api *poll) (struct grub_efi_http *this); +}; +typedef struct grub_efi_http grub_efi_http_t; + +#endif /* !GRUB_EFI_HTTP_HEADER */ -diff --git a/include/grub/net/efi.h b/include/grub/net/efi.h -new file mode 100644 -index 00000000000..de90d223e8e --- /dev/null +++ b/include/grub/net/efi.h @@ -0,0 +1,144 @@ diff --git a/0192-arm64-Fix-EFI-loader-kernel-image-allocation.patch b/0001-arm64-Fix-EFI-loader-kernel-image-allocation.patch similarity index 64% rename from 0192-arm64-Fix-EFI-loader-kernel-image-allocation.patch rename to 0001-arm64-Fix-EFI-loader-kernel-image-allocation.patch index 0472a42f3511e081b54059d895b09d35ea6666f8..81ea27422676c3c745da3f1fe57c9a41e3743b7d 100644 --- a/0192-arm64-Fix-EFI-loader-kernel-image-allocation.patch +++ b/0001-arm64-Fix-EFI-loader-kernel-image-allocation.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 10d0f70ac194931c63f2cbd6fdebd6697abae992 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 2 Aug 2021 23:10:01 +1000 -Subject: [PATCH] arm64: Fix EFI loader kernel image allocation +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). @@ -14,20 +14,15 @@ 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 -[pjones: arm: check for the PE magic for the compiled arch] -Signed-off-by: Peter Jones -Signed-off-by: Robbie Harwood --- - grub-core/loader/arm64/linux.c | 100 +++++++++++++++++++++++++++-------------- - include/grub/arm/linux.h | 1 + - include/grub/arm64/linux.h | 1 + - 3 files changed, 68 insertions(+), 34 deletions(-) + grub-core/loader/arm64/efi/linux.c | 92 ++++++++++++++++++++---------- + 1 file changed, 63 insertions(+), 29 deletions(-) -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index 47f8cf0d84b..f18d90bd749 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -41,6 +41,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); +diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c +index b73105347..4da49a182 100644 +--- a/grub-core/loader/arm64/efi/linux.c ++++ b/grub-core/loader/arm64/efi/linux.c +@@ -39,6 +39,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); static grub_dl_t my_mod; static int loaded; @@ -36,7 +31,7 @@ index 47f8cf0d84b..f18d90bd749 100644 static void *kernel_addr; static grub_uint64_t kernel_size; static grub_uint32_t handover_offset; -@@ -204,9 +206,8 @@ grub_linux_unload (void) +@@ -258,9 +260,8 @@ grub_linux_unload (void) GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start)); initrd_start = initrd_end = 0; grub_free (linux_args); @@ -48,7 +43,7 @@ index 47f8cf0d84b..f18d90bd749 100644 grub_fdt_unload (); return GRUB_ERR_NONE; } -@@ -311,14 +312,35 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), +@@ -365,14 +366,35 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } @@ -62,7 +57,7 @@ index 47f8cf0d84b..f18d90bd749 100644 + + pe = (void *)((unsigned long)kernel + lh->hdr_offset); + -+ if (pe->opt.magic != GRUB_PE32_PEXX_MAGIC) ++ if (pe->opt.magic != GRUB_PE32_PE64_MAGIC) + return grub_error(GRUB_ERR_BAD_OS, "Invalid PE optional header magic"); + + *total_size = pe->opt.image_size; @@ -81,87 +76,74 @@ index 47f8cf0d84b..f18d90bd749 100644 - struct grub_armxx_linux_pe_header *pe; grub_err_t err; + grub_off_t filelen; -+ grub_uint32_t align; ++ grub_uint32_t align = 0; + void *kernel = NULL; - int rc; grub_dl_ref (my_mod); -@@ -333,40 +355,24 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + +@@ -386,39 +408,49 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), 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) + filelen = grub_file_size (file); + kernel = grub_malloc(filelen); + if (!kernel) - { -- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ { + grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel load buffer")); - goto fail; - } ++ goto fail; ++ } -- grub_file_seek (file, 0); -- if (grub_file_read (file, kernel_addr, kernel_size) -- < (grub_int64_t) kernel_size) +- if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh)) +- return grub_errno; + if (grub_file_read (file, kernel, filelen) < (grub_ssize_t)filelen) - { -- if (!grub_errno) -- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]); ++ { + grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), + argv[0]); - goto fail; - } - -- grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); -- - if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) - { -- rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size); -+ rc = grub_linuxefi_secure_validate (kernel, filelen); - if (rc <= 0) - { - grub_error (GRUB_ERR_INVALID_COMMAND, -@@ -375,8 +381,32 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - } ++ goto fail; ++ } -- pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset); -- handover_offset = pe->opt.entry_addr; +- if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE) ++ grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); ++ + if (grub_arch_efi_linux_check_image (kernel) != GRUB_ERR_NONE) + goto fail; + if (parse_pe_header (kernel, &kernel_size, &handover_offset, &align) != GRUB_ERR_NONE) -+ goto fail; + goto fail; + grub_dprintf ("linux", "kernel mem size : %lld\n", (long long) kernel_size); + grub_dprintf ("linux", "kernel entry offset : %d\n", handover_offset); + grub_dprintf ("linux", "kernel alignment : 0x%x\n", align); -+ -+ grub_loader_unset(); -+ + + 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) + kernel_alloc_pages = GRUB_EFI_BYTES_TO_PAGES (kernel_size + align - 1); + kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages); + grub_dprintf ("linux", "kernel numpages: %d\n", kernel_alloc_pages); + if (!kernel_alloc_addr) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto fail; -+ } + { + 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; +- } + kernel_addr = (void *)ALIGN_UP((grub_uint64_t)kernel_alloc_addr, align); -+ -+ grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); + + grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); +- +- pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset); +- handover_offset = pe->opt.entry_addr; + grub_memcpy (kernel_addr, kernel, grub_min(filelen, kernel_size)); + if (kernel_size > filelen) + grub_memset ((char *)kernel_addr + filelen, 0, kernel_size - filelen); @@ -170,7 +152,7 @@ index 47f8cf0d84b..f18d90bd749 100644 cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); linux_args = grub_malloc (cmdline_size); -@@ -400,6 +430,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -442,6 +474,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), } fail: @@ -180,7 +162,7 @@ index 47f8cf0d84b..f18d90bd749 100644 if (file) grub_file_close (file); -@@ -412,9 +445,8 @@ fail: +@@ -454,9 +489,8 @@ fail: if (linux_args && !loaded) grub_free (linux_args); @@ -192,27 +174,6 @@ index 47f8cf0d84b..f18d90bd749 100644 return grub_errno; } -diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h -index b582f67f661..966a5074f53 100644 ---- a/include/grub/arm/linux.h -+++ b/include/grub/arm/linux.h -@@ -44,6 +44,7 @@ struct grub_arm_linux_pe_header - - #if defined(__arm__) - # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM_MAGIC_SIGNATURE -+# define GRUB_PE32_PEXX_MAGIC GRUB_PE32_PE32_MAGIC - # define linux_arch_kernel_header linux_arm_kernel_header - # define grub_armxx_linux_pe_header grub_arm_linux_pe_header - #endif -diff --git a/include/grub/arm64/linux.h b/include/grub/arm64/linux.h -index ea030312df3..422bf2bf24b 100644 ---- a/include/grub/arm64/linux.h -+++ b/include/grub/arm64/linux.h -@@ -48,6 +48,7 @@ struct grub_arm64_linux_pe_header - - #if defined(__aarch64__) - # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE -+# define GRUB_PE32_PEXX_MAGIC GRUB_PE32_PE64_MAGIC - # define linux_arch_kernel_header linux_arm64_kernel_header - # define grub_armxx_linux_pe_header grub_arm64_linux_pe_header - #endif +-- +2.31.1 + diff --git a/0001-clean-up-crypttab-and-linux-modules-dependency.patch b/0001-clean-up-crypttab-and-linux-modules-dependency.patch new file mode 100644 index 0000000000000000000000000000000000000000..e419155e95d3b3eee7740a673a10303017373102 --- /dev/null +++ b/0001-clean-up-crypttab-and-linux-modules-dependency.patch @@ -0,0 +1,205 @@ +From e9422d6869f1b2d78a7cfbfcae1610953d87705b Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Thu, 16 Feb 2023 21:28:07 +0800 +Subject: [PATCH 1/2] clean up crypttab and linux modules dependency + +The linux module could have quite a few dependency to other modules, the +i386-pc build in particular has many. + + linux: normal vbe video boot cmdline relocator mmap + +That will be easy to cause loop dependency if one of these modules has +to require function from linux. To avoid falling into the pitfall in +future extension, we move away the key publish related function from +linux to crypttab module in that it is also a right thing to do. + +Signed-off-by: Michael Chang +--- + grub-core/commands/crypttab.c | 48 +++++++++++++++++++++++++++++- + grub-core/disk/cryptodisk.c | 2 +- + grub-core/loader/linux.c | 55 +---------------------------------- + include/grub/crypttab.h | 22 ++++++++++++++ + include/grub/linux.h | 3 -- + 5 files changed, 71 insertions(+), 59 deletions(-) + create mode 100644 include/grub/crypttab.h + +--- a/grub-core/commands/crypttab.c ++++ b/grub-core/commands/crypttab.c +@@ -3,10 +3,56 @@ + #include + #include + #include +-#include ++#include ++#include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + ++struct grub_key_publisher *kpuber; ++ ++grub_err_t ++grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path) ++{ ++ struct grub_key_publisher *cur = NULL; ++ ++ FOR_LIST_ELEMENTS (cur, kpuber) ++ if (grub_uuidcasecmp (cur->name, uuid, sizeof (cur->name)) == 0) ++ break; ++ ++ if (!cur) ++ cur = grub_zalloc (sizeof (*cur)); ++ if (!cur) ++ return grub_errno; ++ ++ if (key && key_len) ++ { ++ grub_free (cur->key); ++ cur->key = grub_malloc (key_len); ++ if (!cur->key) ++ { ++ grub_free (cur); ++ return grub_errno; ++ } ++ grub_memcpy (cur->key, key, key_len); ++ cur->key_len = key_len; ++ } ++ ++ if (path) ++ { ++ grub_free (cur->path); ++ cur->path = grub_strdup (path); ++ } ++ ++ if (!cur->name) ++ { ++ cur->name = grub_strdup (uuid); ++ grub_list_push (GRUB_AS_LIST_P (&kpuber), GRUB_AS_LIST (cur)); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ + static grub_err_t + grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)), + int argc, char **argv) +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -31,7 +31,7 @@ + #ifdef GRUB_UTIL + #include + #else +-#include ++#include + #endif + + GRUB_MOD_LICENSE ("GPLv3+"); +--- a/grub-core/loader/linux.c ++++ b/grub-core/loader/linux.c +@@ -6,6 +6,7 @@ + #include + #include + #include ++#include + + struct newc_head + { +@@ -40,18 +41,6 @@ + struct dir *child; + }; + +-struct grub_key_publisher +-{ +- struct grub_key_publisher *next; +- struct grub_key_publisher **prev; +- char *name; /* UUID */ +- char *path; +- char *key; +- grub_size_t key_len; +-}; +- +-static struct grub_key_publisher *kpuber; +- + static char + hex (grub_uint8_t val) + { +@@ -436,45 +425,3 @@ + root = 0; + return GRUB_ERR_NONE; + } +- +-grub_err_t +-grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path) +-{ +- struct grub_key_publisher *cur = NULL; +- +- FOR_LIST_ELEMENTS (cur, kpuber) +- if (grub_uuidcasecmp (cur->name, uuid, sizeof (cur->name)) == 0) +- break; +- +- if (!cur) +- cur = grub_zalloc (sizeof (*cur)); +- if (!cur) +- return grub_errno; +- +- if (key && key_len) +- { +- grub_free (cur->key); +- cur->key = grub_malloc (key_len); +- if (!cur->key) +- { +- grub_free (cur); +- return grub_errno; +- } +- grub_memcpy (cur->key, key, key_len); +- cur->key_len = key_len; +- } +- +- if (path) +- { +- grub_free (cur->path); +- cur->path = grub_strdup (path); +- } +- +- if (!cur->name) +- { +- cur->name = grub_strdup (uuid); +- grub_list_push (GRUB_AS_LIST_P (&kpuber), GRUB_AS_LIST (cur)); +- } +- +- return GRUB_ERR_NONE; +-} +--- /dev/null ++++ b/include/grub/crypttab.h +@@ -0,0 +1,22 @@ ++#ifndef GRUB_CRYPTTAB_HEADER ++#define GRUB_CRYPTTAB_HEADER 1 ++ ++#include ++#include ++ ++struct grub_key_publisher ++{ ++ struct grub_key_publisher *next; ++ struct grub_key_publisher **prev; ++ char *name; /* UUID */ ++ char *path; ++ char *key; ++ grub_size_t key_len; ++}; ++ ++extern struct grub_key_publisher *EXPORT_VAR (kpuber); ++ ++grub_err_t ++grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path); ++ ++#endif /* ! GRUB_CRYPTTAB_HEADER */ +--- a/include/grub/linux.h ++++ b/include/grub/linux.h +@@ -22,6 +22,3 @@ + grub_err_t + grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, + void *target); +- +-grub_err_t +-grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path); diff --git a/0001-disk-Optimize-disk-iteration-by-moving-memdisk-to-th.patch b/0001-disk-Optimize-disk-iteration-by-moving-memdisk-to-th.patch new file mode 100644 index 0000000000000000000000000000000000000000..97e8ad8717d7874a08b3463c47a7598409355f05 --- /dev/null +++ b/0001-disk-Optimize-disk-iteration-by-moving-memdisk-to-th.patch @@ -0,0 +1,37 @@ +From 5846e14a4dbf0c73969a32625d841e4f842ccdea Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Wed, 31 Jan 2024 18:44:27 +0800 +Subject: [PATCH] disk: Optimize disk iteration by moving memdisk to the end + +When performing file or UUID-based searches, prioritize returning +operating system disk devices over the memdisk. The memdisk, typically +used for internal grub data, is moved to the last position in the search +order. This improves search efficiency and prevents potential unexpected +results. + +Signed-off-by: Michael Chang +--- + include/grub/disk.h | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/include/grub/disk.h b/include/grub/disk.h +index bf0958885..f4fd7a00f 100644 +--- a/include/grub/disk.h ++++ b/include/grub/disk.h +@@ -244,7 +244,12 @@ grub_disk_dev_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data) + + for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) + for (p = grub_disk_dev_list; p; p = p->next) +- if (p->disk_iterate && (p->disk_iterate) (hook, hook_data, pull)) ++ if (p->id != GRUB_DISK_DEVICE_MEMDISK_ID && p->disk_iterate && (p->disk_iterate) (hook, hook_data, pull)) ++ return 1; ++ ++ for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) ++ for (p = grub_disk_dev_list; p; p = p->next) ++ if (p->id == GRUB_DISK_DEVICE_MEMDISK_ID && p->disk_iterate && (p->disk_iterate) (hook, hook_data, pull)) + return 1; + + return 0; +-- +2.43.0 + diff --git a/0001-efi-linux-provide-linux-command.patch b/0001-efi-linux-provide-linux-command.patch new file mode 100644 index 0000000000000000000000000000000000000000..4cc96dc0a73c288220c98ce40d1597ca6c33a020 --- /dev/null +++ b/0001-efi-linux-provide-linux-command.patch @@ -0,0 +1,103 @@ +From 987ab0dfbe7ef42bb6386fb7b428d3b965ba6d2b Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Mon, 7 Sep 2020 17:02:57 +0800 +Subject: [PATCH] efi/linux: provide linux command + +The linux kernel's efi handover entry point is used to boot efistub of +the linux kernel. Since then the efistub has been improved with many new +features and fixes that ordinary 32-bit entry point cannot provide. + +Besides, nearly every x86 efi kernel is built with efistub enabled so it +is of little value to keep 32-bit entry as default to boot kernel +without needed kconfig options enabled. + +For all good reasons, making efi handover the default entry point for +booting kernel in x86 efi platform so that linux command works in the +same way to linuxefi. This can also reduce the complexity of providing +general grub configuation for x86 system due to the linux command may +not be available in signed image for UEFI Secure Boot and linuxefi is +not available for leagcy bios booting. + +Signed-off-by: Michael Chang +--- + grub-core/Makefile.core.def | 6 ++++-- + grub-core/gensyminfo.sh.in | 3 +++ + grub-core/loader/i386/efi/linux.c | 17 +++++++++++++---- + 3 files changed, 20 insertions(+), 6 deletions(-) + +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1840,7 +1840,9 @@ + + module = { + name = linux; +- x86 = loader/i386/linux.c; ++ i386_pc = loader/i386/linux.c; ++ i386_efi = loader/i386/efi/linux.c; ++ x86_64_efi = loader/i386/efi/linux.c; + i386_xen_pvh = loader/i386/linux.c; + xen = loader/i386/xen.c; + i386_pc = lib/i386/pc/vesa_modes_table.c; +@@ -1856,8 +1858,6 @@ + loongarch64 = loader/efi/linux.c; + riscv32 = loader/efi/linux.c; + riscv64 = loader/efi/linux.c; +- i386_efi = loader/efi/linux.c; +- x86_64_efi = loader/efi/linux.c; + emu = loader/emu/linux.c; + common = loader/linux.c; + }; +@@ -1922,7 +1922,7 @@ + + module = { + name = linuxefi; +- efi = loader/i386/efi/linux.c; ++ efi = lib/fake_module.c; + enable = i386_efi; + enable = x86_64_efi; + }; +--- a/grub-core/gensyminfo.sh.in ++++ b/grub-core/gensyminfo.sh.in +@@ -35,3 +35,6 @@ + + # Print all undefined symbols used by module + @TARGET_NM@ -u @TARGET_NMFLAGS_MINUS_P@ -p $module | sed "s@^\([^ ]*\).*@undefined $modname \1@g" ++ ++# Specify linuxefi module should load default linux ++test "$modname" = "linuxefi" && echo "undefined $modname grub_initrd_init" || true +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -333,20 +333,29 @@ + } + + static grub_command_t cmd_linux, cmd_initrd; ++static grub_command_t cmd_linuxefi, cmd_initrdefi; + +-GRUB_MOD_INIT(linuxefi) ++GRUB_MOD_INIT(linux) + { +- cmd_linux = ++ cmd_linuxefi = + grub_register_command ("linuxefi", grub_cmd_linux, + 0, N_("Load Linux.")); +- cmd_initrd = ++ cmd_initrdefi = + grub_register_command ("initrdefi", grub_cmd_initrd, + 0, N_("Load initrd.")); ++ 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(linuxefi) ++GRUB_MOD_FINI(linux) + { ++ grub_unregister_command (cmd_linuxefi); ++ grub_unregister_command (cmd_initrdefi); + grub_unregister_command (cmd_linux); + grub_unregister_command (cmd_initrd); + } diff --git a/0001-font-Try-memdisk-fonts-with-the-same-name.patch b/0001-font-Try-memdisk-fonts-with-the-same-name.patch new file mode 100644 index 0000000000000000000000000000000000000000..30e1995e81e841c01054849ae12769bfd963c102 --- /dev/null +++ b/0001-font-Try-memdisk-fonts-with-the-same-name.patch @@ -0,0 +1,39 @@ +From d02304f70b5b9c79761d8084ab9dfc66d84688e2 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Wed, 30 Nov 2022 17:02:50 +0800 +Subject: [PATCH] font: Try memdisk fonts with the same name + +--- + grub-core/font/font.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/grub-core/font/font.c b/grub-core/font/font.c +index 18de52562..92ff415bf 100644 +--- a/grub-core/font/font.c ++++ b/grub-core/font/font.c +@@ -451,7 +451,21 @@ grub_font_load (const char *filename) + #endif + + if (filename[0] == '(' || filename[0] == '/' || filename[0] == '+') +- file = grub_buffile_open (filename, GRUB_FILE_TYPE_FONT, 1024); ++ { ++ char *n = grub_strdup (filename); ++ char *p = grub_strrchr (n, '/'); ++ if (p) ++ { ++ char *q = grub_strrchr (p, '.'); ++ if (q) ++ *q = 0; ++ p++; ++ file = try_open_from_prefix ("(memdisk)", p); ++ } ++ grub_free (n); ++ if (!file) ++ file = grub_buffile_open (filename, GRUB_FILE_TYPE_FONT, 1024); ++ } + else + { + file = try_open_from_prefix ("(memdisk)", filename); +-- +2.41.0 + diff --git a/0001-fs-xfs-always-verify-the-total-number-of-entries-is-.patch b/0001-fs-xfs-always-verify-the-total-number-of-entries-is-.patch new file mode 100644 index 0000000000000000000000000000000000000000..bf75d1e34008a5d0390a2054f8dec88bd585f344 --- /dev/null +++ b/0001-fs-xfs-always-verify-the-total-number-of-entries-is-.patch @@ -0,0 +1,48 @@ +From 045aae8fe7238aabc217700df4d17d83b7d891f3 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Tue, 23 Jan 2024 12:46:16 +0800 +Subject: [PATCH] fs/xfs: always verify the total number of entries is not zero + +--- + grub-core/fs/xfs.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c +index bc2224dbb..1ce5fa4fc 100644 +--- a/grub-core/fs/xfs.c ++++ b/grub-core/fs/xfs.c +@@ -900,6 +900,8 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + { + struct grub_xfs_dir2_entry *direntry = + grub_xfs_first_de(dir->data, dirblock); ++ struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock); ++ + int entries = -1; + char *end = dirblock + dirblk_size; + +@@ -918,18 +920,16 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir, + */ + if (dir->inode.nextents == grub_cpu_to_be32_compile_time (1)) + { +- struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock); +- + end = (char *) tail; + + /* Subtract the space used by leaf nodes. */ + end -= grub_be_to_cpu32 (tail->leaf_count) * sizeof (struct grub_xfs_dir_leaf_entry); ++ } + +- entries = grub_be_to_cpu32 (tail->leaf_count) - grub_be_to_cpu32 (tail->leaf_stale); ++ entries = grub_be_to_cpu32 (tail->leaf_count) - grub_be_to_cpu32 (tail->leaf_stale); + +- if (!entries) +- continue; +- } ++ if (!entries) ++ continue; + + /* Iterate over all entries within this block. */ + while ((char *) direntry < (char *) end) +-- +2.43.0 + diff --git a/0001-grub-install-Add-SUSE-signed-image-support-for-power.patch b/0001-grub-install-Add-SUSE-signed-image-support-for-power.patch new file mode 100644 index 0000000000000000000000000000000000000000..6f58dfee053b5d2fff10b6f2191fc522b57def1c --- /dev/null +++ b/0001-grub-install-Add-SUSE-signed-image-support-for-power.patch @@ -0,0 +1,101 @@ +From 83a6f72e1896bd012b7fbca21317e96c2c22b327 Mon Sep 17 00:00:00 2001 +From: Michal Suchanek +Date: Wed, 12 Jan 2022 19:25:54 +0100 +Subject: [PATCH] grub-install: Add SUSE signed image support for powerpc. + +Signed-off-by: Michal Suchanek +--- + grub-core/osdep/linux/platform.c | 13 +++++++++++++ + include/grub/util/install.h | 3 +++ + util/grub-install.c | 29 ++++++++++++++++++++++++++--- + 3 files changed, 42 insertions(+), 3 deletions(-) + +--- a/grub-core/osdep/linux/platform.c ++++ b/grub-core/osdep/linux/platform.c +@@ -154,3 +154,16 @@ + grub_util_info ("... not found"); + return "i386-pc"; + } ++ ++int ++grub_install_get_powerpc_secure_boot (void) ++{ ++ int32_t ret = -1; ++ FILE *fp = grub_util_fopen ("/proc/device-tree/ibm,secure-boot", "rb"); ++ if (fp) { ++ if (fread (&ret , 1, sizeof(ret), fp) > 0) ++ ret = grub_be_to_cpu32(ret); ++ fclose(fp); ++ } ++ return ret; ++} +--- a/include/grub/util/install.h ++++ b/include/grub/util/install.h +@@ -233,6 +233,9 @@ + grub_install_get_default_x86_platform (void); + + int ++grub_install_get_powerpc_secure_boot (void); ++ ++int + grub_install_register_efi (grub_device_t efidir_grub_dev, + const char *efifile_path, + const char *efi_distributor); +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -321,10 +321,10 @@ + {"suse-enable-tpm", OPTION_SUSE_ENABLE_TPM, 0, 0, N_("install TPM modules"), 0}, + {"suse-force-signed", OPTION_SUSE_FORCE_SIGNED, 0, 0, + N_("force installation of signed grub" "%s." +- "This option is only available on ARM64 EFI targets."), 0}, ++ "This option is only available on ARM64 EFI and powerpc targets."), 0}, + {"suse-inhibit-signed", OPTION_SUSE_INHIBIT_SIGNED, 0, 0, + N_("inhibit installation of signed grub. " +- "This option is only available on ARM64 EFI targets."), 0}, ++ "This option is only available on ARM64 EFI and powerpc targets."), 0}, + {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, + {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2}, + {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2}, +@@ -1749,6 +1749,7 @@ + char mkimage_target[200]; + const char *core_name = NULL; + char *signed_imgfile = NULL; ++ int ppc_sb_state = -1; + + switch (platform) + { +@@ -1796,11 +1797,33 @@ + grub_install_get_platform_platform (platform)); + break; + ++ ++ case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: ++ ppc_sb_state = grub_install_get_powerpc_secure_boot(); ++ ++ if ((signed_grub_mode >= SIGNED_GRUB_FORCE) || ((signed_grub_mode == SIGNED_GRUB_AUTO) && (ppc_sb_state > 0))) ++ { ++ signed_imgfile = grub_util_path_concat (2, grub_install_source_directory, "grub.elf"); ++ if (!grub_util_is_regular (signed_imgfile)) ++ { ++ if ((signed_grub_mode >= SIGNED_GRUB_FORCE) || (ppc_sb_state > 1)) ++ grub_util_error ("signed image `%s' does not exist\n", signed_imgfile); ++ else ++ { ++ free (signed_imgfile); ++ signed_imgfile = NULL; ++ } ++ } ++ } ++ ++ if (signed_imgfile) ++ fprintf (stderr, _("Use signed file in %s for installation.\n"), signed_imgfile); ++ ++ /* fallthrough. */ + case GRUB_INSTALL_PLATFORM_I386_COREBOOT: + case GRUB_INSTALL_PLATFORM_ARM_COREBOOT: + case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT: + case GRUB_INSTALL_PLATFORM_I386_IEEE1275: +- case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: diff --git a/0001-grub-install-bailout-root-device-probing.patch b/0001-grub-install-bailout-root-device-probing.patch new file mode 100644 index 0000000000000000000000000000000000000000..0a5c7125f81ee10ed77510783fb34644eb99db78 --- /dev/null +++ b/0001-grub-install-bailout-root-device-probing.patch @@ -0,0 +1,163 @@ +From 58dcf7985b20de876a6fc44a591aa377d0a0302c Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Thu, 10 Feb 2022 22:16:58 +0800 +Subject: [PATCH] grub-install: bailout root device probing + +The root device is probed to test if the filesystem is btrfs in order to setup +boot configs for snapshot booting. However when the root device is a lvm thin +volume, due to lack in grub support, the probing will be errored out and entire +installation process aborts. + +Here we call out stat to bailout the situation whenever grub fails to probe +filesystem in it's own right. + + stat -f -c %T / + +The command is also used by grub-mkconfig for the same purpose. + +Signed-off-by: Michael Chang +--- + grub-core/osdep/basic/no_platform.c | 5 +++++ + grub-core/osdep/unix/platform.c | 34 +++++++++++++++++++++++++++++ + grub-core/osdep/windows/platform.c | 6 +++++ + include/grub/util/install.h | 3 +++ + util/grub-install.c | 31 ++++++++++++++++++-------- + 5 files changed, 70 insertions(+), 9 deletions(-) + +--- a/grub-core/osdep/basic/no_platform.c ++++ b/grub-core/osdep/basic/no_platform.c +@@ -51,3 +51,8 @@ + grub_util_error ("%s", _("no zIPL routines are available for your platform")); + } + ++char * ++grub_install_get_filesystem (const char *path) ++{ ++ return NULL; ++} +--- a/grub-core/osdep/unix/platform.c ++++ b/grub-core/osdep/unix/platform.c +@@ -250,3 +250,37 @@ + "-z", dest, NULL })) + grub_util_error (_("`%s' failed.\n"), PACKAGE"-zipl-setup"); + } ++ ++char * ++grub_install_get_filesystem (const char *path) ++{ ++ int fd; ++ pid_t pid; ++ FILE *fp; ++ ssize_t len; ++ char *buf = NULL; ++ size_t bufsz = 0; ++ ++ pid = grub_util_exec_pipe ((const char * []){ "stat", "-f", "-c", "%T", path, NULL }, &fd); ++ if (!pid) ++ return NULL; ++ ++ fp = fdopen (fd, "r"); ++ if (!fp) ++ return NULL; ++ ++ len = getline (&buf, &bufsz, fp); ++ if (len == -1) ++ { ++ free (buf); ++ fclose (fp); ++ return NULL; ++ } ++ ++ fclose (fp); ++ ++ if (len > 0 && buf[len - 1] == '\n') ++ buf[len - 1] = '\0'; ++ ++ return buf; ++} +--- a/grub-core/osdep/windows/platform.c ++++ b/grub-core/osdep/windows/platform.c +@@ -440,3 +440,9 @@ + { + grub_util_error ("%s", _("no zIPL routines are available for your platform")); + } ++ ++char * ++grub_install_get_filesystem (const char *path) ++{ ++ return NULL; ++} +--- a/include/grub/util/install.h ++++ b/include/grub/util/install.h +@@ -251,6 +251,9 @@ + void + grub_install_zipl (const char *d, int i, int f); + ++char * ++grub_install_get_filesystem (const char *path); ++ + int + grub_install_compress_gzip (const char *src, const char *dest); + int +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -887,7 +887,6 @@ + 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; +@@ -1067,8 +1066,10 @@ + grub_host_init (); + + { +- char *rootdir_grub_devname; +- grub_device_t rootdir_grub_dev; ++ grub_device_t rootdir_grub_dev = NULL; ++ char *rootdir_grub_devname = NULL; ++ char *root_fs_name = NULL; ++ + char *t = grub_util_path_concat (2, "/", rootdir); + + rootdir_path = grub_canonicalize_file_name (t); +@@ -1089,20 +1090,32 @@ + rootdir_devices[0]); + + rootdir_grub_dev = grub_device_open (rootdir_grub_devname); +- if (! rootdir_grub_dev) +- grub_util_error ("%s", grub_errmsg); ++ if (!rootdir_grub_dev) ++ { ++ root_fs_name = grub_install_get_filesystem (t); ++ if (root_fs_name) ++ grub_errno = 0; ++ } ++ else ++ { ++ grub_fs_t root_fs = grub_fs_probe (rootdir_grub_dev); ++ if (root_fs) ++ root_fs_name = grub_strdup (root_fs->name); ++ } + +- root_fs = grub_fs_probe (rootdir_grub_dev); +- if (!root_fs) ++ if (!root_fs_name) + grub_util_error ("%s", grub_errmsg); + + if (config.is_suse_btrfs_snapshot_enabled +- && grub_strncmp(root_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0) ++ && root_fs_name ++ && grub_strncmp(root_fs_name, "btrfs", sizeof ("btrfs") - 1) == 0) + use_relative_path_on_btrfs = 1; + ++ free (root_fs_name); + free (t); + free (rootdir_grub_devname); +- grub_device_close (rootdir_grub_dev); ++ if (rootdir_grub_dev) ++ grub_device_close (rootdir_grub_dev); + } + + switch (platform) diff --git a/0001-grub-probe-Deduplicate-probed-partmap-output.patch b/0001-grub-probe-Deduplicate-probed-partmap-output.patch new file mode 100644 index 0000000000000000000000000000000000000000..9af5ef1d1a655820f510003e0efa1aade09835ee --- /dev/null +++ b/0001-grub-probe-Deduplicate-probed-partmap-output.patch @@ -0,0 +1,110 @@ +From ed0ac581ad3866197fc05c7cf48e39419a51f606 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Fri, 18 Mar 2022 13:19:33 +0800 +Subject: [PATCH] grub-probe: Deduplicate probed partmap output + +If the target device being probed is staked on top of other physical or logical +devices, all containing device's partition map type will be printed once if +--target=partmap is used. This usually results in duplicated output as same +partition map type. + +This in turn may clutter grub.cfg with many duplicated insmod part_[a-z]+ if +the /boot is RAIDed because --target=partmap output is used to producing +partmap modules required to access disk device. + +Let's deduplicate that to make the grub.cfg looks better and disciplined. + +Signed-off-by: Michael Chang +--- + util/grub-probe.c | 59 +++++++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 55 insertions(+), 4 deletions(-) + +diff --git a/util/grub-probe.c b/util/grub-probe.c +index c08e46bbb..fb94f28fd 100644 +--- a/util/grub-probe.c ++++ b/util/grub-probe.c +@@ -153,6 +153,50 @@ do_print (const char *x, void *data) + grub_printf ("%s%c", x, delim); + } + ++static int ++check_duplicate_partmap (const char *name) ++{ ++ static int alloc, used; ++ static char **partmaps; ++ int i; ++ ++ if (!name) ++ { ++ if (partmaps) ++ { ++ for (i= 0; i < used; ++i) ++ free (partmaps[i]); ++ free (partmaps); ++ partmaps = NULL; ++ alloc = 0; ++ used = 0; ++ } ++ return 1; ++ } ++ ++ for (i= 0; i < used; ++i) ++ if (strcmp (partmaps[i], name) == 0) ++ return 1; ++ ++ if (alloc <= used) ++ { ++ alloc = (alloc) ? (alloc << 1) : 4; ++ partmaps = xrealloc (partmaps, alloc * sizeof (*partmaps)); ++ } ++ ++ partmaps[used++] = strdup (name); ++ return 0; ++} ++ ++static void ++do_print_partmap (const char *x, void *data) ++{ ++ char delim = *(const char *) data; ++ if (check_duplicate_partmap (x) != 0) ++ return; ++ grub_printf ("%s%c", x, delim); ++} ++ + static void + probe_partmap (grub_disk_t disk, char delim) + { +@@ -165,10 +209,14 @@ probe_partmap (grub_disk_t disk, char delim) + } + + for (part = disk->partition; part; part = part->parent) +- printf ("%s%c", part->partmap->name, delim); ++ { ++ if (check_duplicate_partmap (part->partmap->name) != 0) ++ continue; ++ printf ("%s%c", part->partmap->name, delim); ++ } + + if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID) +- grub_diskfilter_get_partmap (disk, do_print, &delim); ++ grub_diskfilter_get_partmap (disk, do_print_partmap, &delim); + + /* In case of LVM/RAID, check the member devices as well. */ + if (disk->dev->disk_memberlist) +@@ -674,8 +722,11 @@ probe (const char *path, char **device_names, char delim) + probe_cryptodisk_uuid (dev->disk, delim); + + else if (print == PRINT_PARTMAP) +- /* Check if dev->disk itself is contained in a partmap. */ +- probe_partmap (dev->disk, delim); ++ { ++ /* Check if dev->disk itself is contained in a partmap. */ ++ probe_partmap (dev->disk, delim); ++ check_duplicate_partmap (NULL); ++ } + + else if (print == PRINT_PARTUUID) + { +-- +2.35.1 + diff --git a/0001-grub2-Can-t-setup-a-default-boot-device-correctly-on.patch b/0001-grub2-Can-t-setup-a-default-boot-device-correctly-on.patch new file mode 100644 index 0000000000000000000000000000000000000000..5a1a8ddbe9171eb760d9bf300d4770c98fcbd1c5 --- /dev/null +++ b/0001-grub2-Can-t-setup-a-default-boot-device-correctly-on.patch @@ -0,0 +1,44 @@ +From a59b58f6ae327a8f6949991cb5531db01e1ba14d Mon Sep 17 00:00:00 2001 +From: Wen Xiong +Date: Tue, 7 Feb 2023 15:10:15 -0500 +Subject: [PATCH] grub2: Can't setup a default boot device correctly on nvme + device in Beta3 + +The patch in Bug 200486 - SUSE1205666 - SLES15SP5 Beta1: Setup multiple dev path + for a nvmf boot device in grub2 caused the issue. That patch didn't consider +nvme devices carefully. + +The new patch will check "nvme-of" instead of "nvme" to call +build_multi_boot_device(). + +Signed-off-by: Wen Xiong +--- + grub-core/osdep/unix/platform.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c +index db8fa4b95..fb47c0ffa 100644 +--- a/grub-core/osdep/unix/platform.c ++++ b/grub-core/osdep/unix/platform.c +@@ -288,11 +288,15 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device, + } + *ptr = '\0'; + } +- else if (grub_strstr(install_device, "nvme")) +- boot_device = build_multi_boot_device(install_device); +- else ++ else { + boot_device = get_ofpathname (install_device); + ++ if (grub_strstr(boot_device, "nvme-of")) { ++ free (boot_device); ++ boot_device = build_multi_boot_device(install_device); ++ } ++ } ++ + if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device", + boot_device, NULL })) + { +-- +2.39.1 + diff --git a/0001-grub2-Set-multiple-device-path-for-a-nvmf-boot-devic.patch b/0001-grub2-Set-multiple-device-path-for-a-nvmf-boot-devic.patch new file mode 100644 index 0000000000000000000000000000000000000000..184762616037be82c7984c88543e06eebc6bf0c5 --- /dev/null +++ b/0001-grub2-Set-multiple-device-path-for-a-nvmf-boot-devic.patch @@ -0,0 +1,164 @@ +From 3e77c5494fd06f430588ae9c304fea370439d531 Mon Sep 17 00:00:00 2001 +From: Wen Xiong +Date: Thu, 15 Dec 2022 21:33:41 -0500 +Subject: [PATCH] grub2: Set multiple device path for a nvmf boot device + +nvmf support native multipath(ANA) by default. +The patch added the support for setting multiple +device path for a nvmf boot device. + +localhost:~ grub2-install -v /dev/nvme1n1p1 +... +... +... +grub2-install: info: executing nvsetenv boot-device /pci@800000020000132/fibre-channel@0,1/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0,1/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec. +Installation finished. No error reported. + +localhost:~ # bootlist -m normal -o +nvme7n1 +nvme5n1 +nvme1n1 +nvme4n1 + +localhost:~ # bootlist -m normal -r +/pci@800000020000132/fibre-channel@0,1/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec +/pci@800000020000132/fibre-channel@0/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec +/pci@800000020000132/fibre-channel@0/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec +/pci@800000020000132/fibre-channel@0,1/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec + +Signed-off-by: Wen Xiong +--- + grub-core/osdep/linux/ofpath.c | 6 ++--- + grub-core/osdep/unix/platform.c | 48 +++++++++++++++++++++++++++++++++ + include/grub/util/install.h | 3 +++ + include/grub/util/ofpath.h | 9 +++++++ + 4 files changed, 63 insertions(+), 3 deletions(-) + +--- a/grub-core/osdep/linux/ofpath.c ++++ b/grub-core/osdep/linux/ofpath.c +@@ -209,7 +209,7 @@ + } + } + +-static char * ++char * + xrealpath (const char *in) + { + char *out; +@@ -224,7 +224,7 @@ + return out; + } + +-static char * ++char * + block_device_get_sysfs_path_and_link(const char *devicenode) + { + char *rpath; +@@ -535,7 +535,7 @@ + + } + +-static char * ++char * + nvme_get_syspath(const char *nvmedev) + { + char *sysfs_path, *controller_node; +--- a/grub-core/osdep/unix/platform.c ++++ b/grub-core/osdep/unix/platform.c +@@ -19,6 +19,7 @@ + #include + + #include ++#include + #include + #include + #include +@@ -131,6 +132,51 @@ + return rc; + } + ++char * ++build_multi_boot_device(const char *install_device) ++{ ++ char *sysfs_path; ++ char *nvme_ns; ++ unsigned int nsid; ++ char *ptr; ++ char *boot_device_string; ++ struct dirent *ep; ++ DIR *dp; ++ ++ nvme_ns = strchr(install_device, 'n'); ++ nsid = of_path_get_nvme_nsid(nvme_ns); ++ sysfs_path = nvme_get_syspath(nvme_ns); ++ strcat(sysfs_path, "/device"); ++ sysfs_path = xrealpath(sysfs_path); ++ ++ dp = opendir(sysfs_path); ++ ptr = boot_device_string = xmalloc (1000); ++ ++ /* We cannot have a boot list with more than five entries */ ++ while((ep = readdir(dp)) != NULL){ ++ char *nvme_device; ++ ++ if (grub_strstr(ep->d_name, "nvme")) { ++ nvme_device = xasprintf ("%s%s%x ", ++ get_ofpathname(ep->d_name),"/namespace@", nsid); ++ if ((strlen(boot_device_string) + strlen(nvme_device)) >= 200*5 - 1) { ++ grub_util_warn (_("More than five entries cannot be specified in the bootlist")); ++ free(nvme_device); ++ break; ++ } ++ ++ strncpy(ptr, nvme_device, strlen(nvme_device)); ++ ptr += strlen(nvme_device); ++ free(nvme_device); ++ } ++ } ++ ++ *--ptr = '\0'; ++ closedir(dp); ++ ++ return boot_device_string; ++} ++ + int + grub_install_register_efi (const grub_disk_t *efidir_grub_disk, + const char *efifile_path, +@@ -242,6 +288,8 @@ + } + *ptr = '\0'; + } ++ else if (grub_strstr(install_device, "nvme")) ++ boot_device = build_multi_boot_device(install_device); + else + boot_device = get_ofpathname (install_device); + +--- a/include/grub/util/install.h ++++ b/include/grub/util/install.h +@@ -241,6 +241,9 @@ + const char *efi_distributor, + const char *force_disk); + ++char * ++build_multi_boot_device(const char *install_device); ++ + void + grub_install_register_ieee1275 (int is_prep, const char *install_device, + int partno, const char *relpath); +--- a/include/grub/util/ofpath.h ++++ b/include/grub/util/ofpath.h +@@ -32,4 +32,13 @@ + + char* of_find_fc_host(char* host_wwpn); + ++char* nvme_get_syspath(const char *nvmedev); ++ ++char* block_device_get_sysfs_path_and_link(const char *devicenode); ++ ++char* xrealpath (const char *in); ++ ++unsigned int of_path_get_nvme_nsid(const char* devname); ++ ++ + #endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */ diff --git a/0156-ieee1275-Avoiding-many-unecessary-open-close.patch b/0001-ieee1275-Avoiding-many-unecessary-open-close.patch similarity index 71% rename from 0156-ieee1275-Avoiding-many-unecessary-open-close.patch rename to 0001-ieee1275-Avoiding-many-unecessary-open-close.patch index 6a0ad75b7c3e581a0144d9db8de9c5ceec3ea7f6..896765df5c9806e8b2e33ae6943331970ae32f04 100644 --- a/0156-ieee1275-Avoiding-many-unecessary-open-close.patch +++ b/0001-ieee1275-Avoiding-many-unecessary-open-close.patch @@ -1,18 +1,24 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Diego Domingos -Date: Mon, 14 Dec 2020 17:42:45 +0100 +From e9d3202d5cffb89223ff61ac93de86a0cac1b50c Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Thu, 19 Nov 2020 10:47:25 -0300 Subject: [PATCH] ieee1275: Avoiding many unecessary open/close -Signed-off-by: Diego Domingos +This patch aims to change the grub_ofdisk_open and grub_ofdisk_close behaviors. Since some devices (Fibre Channel and NVMe) can have a long time for shutdown notification, we should avoid open and close the disks as much as we can. + +So, we are changing how those functions works. The grub_ofdisk_close will take care of just changing the disk element status, by doing a soft close, i.e, the firmware will not be called. On the other hand, the grub_ofdisk_open will take care of closing the current disk opened only if the disk requested in the current call is different from the current one. This close will be responsible to request the firmware to actually close the disk. + +Yet, this patch modifies the grub_ofdisk_get_block_size function, avoiding open and close calls inside of it. + +Thank you Michael Chang (mchang@suse.com) for all support. + +Signed-off-by: Diego Domingos --- - grub-core/disk/ieee1275/ofdisk.c | 64 ++++++++++++++++++++++------------------ + grub-core/disk/ieee1275/ofdisk.c | 64 +++++++++++++++++--------------- 1 file changed, 35 insertions(+), 29 deletions(-) -diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c -index 03674cb477e..ea7f78ac7d8 100644 --- a/grub-core/disk/ieee1275/ofdisk.c +++ b/grub-core/disk/ieee1275/ofdisk.c -@@ -44,7 +44,7 @@ struct ofdisk_hash_ent +@@ -44,7 +44,7 @@ }; static grub_err_t @@ -21,7 +27,7 @@ index 03674cb477e..ea7f78ac7d8 100644 struct ofdisk_hash_ent *op); #define OFDISK_HASH_SZ 8 -@@ -461,6 +461,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) +@@ -461,6 +461,7 @@ grub_ssize_t actual; grub_uint32_t block_size = 0; grub_err_t err; @@ -29,7 +35,7 @@ index 03674cb477e..ea7f78ac7d8 100644 if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) != 0) return grub_error (GRUB_ERR_UNKNOWN_DEVICE, -@@ -471,6 +472,35 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) +@@ -471,6 +472,35 @@ grub_dprintf ("disk", "Opening `%s'.\n", devpath); @@ -65,7 +71,7 @@ index 03674cb477e..ea7f78ac7d8 100644 if (grub_ieee1275_finddevice (devpath, &dev)) { grub_free (devpath); -@@ -491,25 +521,18 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) +@@ -491,25 +521,18 @@ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device"); } @@ -94,7 +100,7 @@ index 03674cb477e..ea7f78ac7d8 100644 if (err) { grub_free (devpath); -@@ -532,13 +555,6 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) +@@ -528,13 +551,6 @@ static void grub_ofdisk_close (grub_disk_t disk) { @@ -108,7 +114,7 @@ index 03674cb477e..ea7f78ac7d8 100644 disk->data = 0; } -@@ -685,7 +701,7 @@ grub_ofdisk_init (void) +@@ -681,7 +697,7 @@ } static grub_err_t @@ -117,7 +123,7 @@ index 03674cb477e..ea7f78ac7d8 100644 struct ofdisk_hash_ent *op) { struct size_args_ieee1275 -@@ -698,16 +714,6 @@ grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size, +@@ -694,16 +710,6 @@ grub_ieee1275_cell_t size2; } args_ieee1275; diff --git a/0001-ieee1275-add-support-for-NVMeoFC.patch b/0001-ieee1275-add-support-for-NVMeoFC.patch new file mode 100644 index 0000000000000000000000000000000000000000..b2faefc8567ba949e3e267e3bd9ead10a5f78260 --- /dev/null +++ b/0001-ieee1275-add-support-for-NVMeoFC.patch @@ -0,0 +1,250 @@ +From c125cb45a7885d7bf168a05cfa4da3e681244649 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Tue, 15 Feb 2022 13:11:48 -0500 +Subject: [PATCH 1/4] ieee1275: add support for NVMeoFC + +Implements the functions to scan and discovery of NVMeoFC. +--- + grub-core/disk/ieee1275/ofdisk.c | 217 ++++++++++++++++++++++++++++++- + 1 file changed, 213 insertions(+), 4 deletions(-) + +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index 410f4b849..852bb95be 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -206,12 +206,10 @@ dev_iterate_real (const char *name, const char *path) + return; + } + ++ + static void +-dev_iterate (const struct grub_ieee1275_devalias *alias) ++dev_iterate_fcp_disks(const struct grub_ieee1275_devalias *alias) + { +- if (grub_strcmp (alias->type, "fcp") == 0) +- { +- + /* If we are dealing with fcp devices, we need + * to find the WWPNs and LUNs to iterate them */ + grub_ieee1275_ihandle_t ihandle; +@@ -323,6 +321,217 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) + grub_free (buf); + return; + ++} ++ ++static void ++dev_iterate_fcp_nvmeof (const struct grub_ieee1275_devalias *alias) ++{ ++ ++ ++ char *bufptr; ++ grub_ieee1275_ihandle_t ihandle; ++ ++ ++ // Create the structs for the parameters passing to PFW ++ struct nvme_args_ ++ { ++ struct grub_ieee1275_common_hdr common; ++ grub_ieee1275_cell_t method; ++ grub_ieee1275_cell_t ihandle; ++ grub_ieee1275_cell_t catch_result; ++ grub_ieee1275_cell_t nentries; ++ grub_ieee1275_cell_t table; ++ } nvme_discovery_controllers_args, nvme_controllers_args, nvme_namespaces_args; ++ ++ ++ // Create the structs for the results from PFW ++ ++ struct discovery_controllers_table_struct_ ++ { ++ grub_uint64_t table[256]; ++ grub_uint32_t len; ++ } discovery_controllers_table; ++ ++ /* struct nvme_controllers_table_entry ++ * this the return of nvme-controllers method tables, containing: ++ * - 2-byte controller ID ++ * - 256-byte transport address string ++ * - 256-byte field containing null-terminated NVM subsystem NQN string up to 223 characters ++ */ ++ struct nvme_controllers_table_entry_ ++ { ++ grub_uint16_t id; ++ char wwpn[256]; ++ char nqn[256]; ++ }; ++ ++ struct nvme_controllers_table_entry_* nvme_controllers_table = grub_malloc(sizeof(struct nvme_controllers_table_entry_)*256); ++ ++ grub_uint32_t nvme_controllers_table_entries; ++ ++ struct nvme_controllers_table_entry_real ++ { ++ grub_uint16_t id; ++ char wwpn[256]; ++ char nqn[256]; ++ }; ++ ++ /* Allocate memory for building the NVMeoF path */ ++ char *buf = grub_malloc (grub_strlen (alias->path) + 512); ++ if (!buf) ++ { ++ grub_ieee1275_close(ihandle); ++ return; ++ } ++ ++ /* Copy the alias->path to buf so we can work with */ ++ bufptr = grub_stpcpy (buf, alias->path); ++ grub_snprintf (bufptr, 32, "/nvme-of"); ++ ++ /* ++ * Open the nvme-of layer ++ * Ex. /pci@bus/fibre-channel@@dev,func/nvme-of ++ */ ++ if(grub_ieee1275_open (buf, &ihandle)) ++ { ++ grub_dprintf("disk", "failed to open the disk while iterating FCP disk path=%s\n", buf); ++ return; ++ } ++ ++ /* ++ * Call to nvme-discovery-controllers method from the nvme-of layer ++ * to get a list of the NVMe discovery controllers per the binding ++ */ ++ ++ INIT_IEEE1275_COMMON (&nvme_discovery_controllers_args.common, "call-method", 2, 2); ++ nvme_discovery_controllers_args.method = (grub_ieee1275_cell_t) "nvme-discovery-controllers"; ++ nvme_discovery_controllers_args.ihandle = ihandle; ++ ++ if (IEEE1275_CALL_ENTRY_FN (&nvme_discovery_controllers_args) == -1) ++ { ++ grub_dprintf("disk", "failed to get the targets while iterating FCP disk path=%s\n", buf); ++ grub_ieee1275_close(ihandle); ++ return; ++ } ++ ++ /* After closing the device, the info is lost. So lets copy each buffer in the buffers table */ ++ ++ discovery_controllers_table.len = (grub_uint32_t) nvme_discovery_controllers_args.nentries; ++ ++ unsigned int i=0; ++ for(i = 0; i < discovery_controllers_table.len; i++){ ++ discovery_controllers_table.table[i] = ((grub_uint64_t*)nvme_discovery_controllers_args.table)[i]; ++ } ++ ++ grub_ieee1275_close(ihandle); ++ ++ grub_dprintf("ofdisk","NVMeoF: Found %d discovery controllers\n",discovery_controllers_table.len); ++ ++ /* For each nvme discovery controller */ ++ int current_buffer_index; ++ for(current_buffer_index = 0; current_buffer_index < (int) discovery_controllers_table.len; current_buffer_index++){ ++ ++ ++ grub_snprintf (bufptr, 64, "/nvme-of/controller@%" PRIxGRUB_UINT64_T ",ffff", ++ discovery_controllers_table.table[current_buffer_index]); ++ ++ grub_dprintf("ofdisk","nvmeof controller=%s\n",buf); ++ ++ if(grub_ieee1275_open (buf, &ihandle)) ++ { ++ grub_dprintf("ofdisk", "failed to open the disk while getting nvme-controllers path=%s\n", buf); ++ continue; ++ } ++ ++ ++ INIT_IEEE1275_COMMON (&nvme_controllers_args.common, "call-method", 2, 2); ++ nvme_controllers_args.method = (grub_ieee1275_cell_t) "nvme-controllers"; ++ nvme_controllers_args.ihandle = ihandle; ++ nvme_controllers_args.catch_result = 0; ++ ++ ++ if (IEEE1275_CALL_ENTRY_FN (&nvme_controllers_args) == -1) ++ { ++ grub_dprintf("ofdisk", "failed to get the nvme-controllers while iterating FCP disk path\n"); ++ grub_ieee1275_close(ihandle); ++ continue; ++ } ++ ++ ++ /* Copy the buffer list to nvme_controllers_table */ ++ nvme_controllers_table_entries = ((grub_uint32_t) nvme_controllers_args.nentries); ++ struct nvme_controllers_table_entry_* nvme_controllers_table_ = (struct nvme_controllers_table_entry_*) nvme_controllers_args.table; ++ ++ for(i = 0; i < nvme_controllers_table_entries; i++){ ++ nvme_controllers_table[i].id = (grub_uint16_t) nvme_controllers_table_[i].id; ++ grub_strcpy(nvme_controllers_table[i].wwpn, nvme_controllers_table_[i].wwpn); ++ grub_strcpy(nvme_controllers_table[i].nqn, nvme_controllers_table_[i].nqn); ++ } ++ ++ grub_ieee1275_close(ihandle); ++ ++ int nvme_controller_index; ++ int bufptr_pos2; ++ grub_dprintf("ofdisk","NVMeoF: found %d nvme controllers\n",(int) nvme_controllers_args.nentries); ++ ++ /* For each nvme controller */ ++ for(nvme_controller_index = 0; nvme_controller_index < (int) nvme_controllers_args.nentries; nvme_controller_index++){ ++ /* Open the nvme controller ++ * /pci@bus/fibre-channel@dev,func/nvme-of/controller@transport-addr,ctlr-id:nqn=tgt-subsystem-nqn ++ */ ++ ++ bufptr_pos2 = grub_snprintf (bufptr, 512, "/nvme-of/controller@%s,ffff:nqn=%s", ++ nvme_controllers_table[nvme_controller_index].wwpn, nvme_controllers_table[nvme_controller_index].nqn); ++ ++ grub_dprintf("ofdisk","NVMeoF: nvmeof controller=%s\n",buf); ++ ++ if(grub_ieee1275_open (buf, &ihandle)){ ++ grub_dprintf("ofdisk","failed to open the path=%s\n",buf); ++ continue; ++ } ++ ++ INIT_IEEE1275_COMMON (&nvme_namespaces_args.common, "call-method", 2, 2); ++ nvme_namespaces_args.method = (grub_ieee1275_cell_t) "get-namespace-list"; ++ nvme_namespaces_args.ihandle = ihandle; ++ nvme_namespaces_args.catch_result = 0; ++ ++ if (IEEE1275_CALL_ENTRY_FN (&nvme_namespaces_args) == -1) ++ { ++ grub_dprintf("ofdisk", "failed to get the nvme-namespace-list while iterating FCP disk path\n"); ++ grub_ieee1275_close(ihandle); ++ continue; ++ } ++ ++ grub_uint32_t *namespaces = (grub_uint32_t*) nvme_namespaces_args.table; ++ grub_dprintf("ofdisk","NVMeoF: found %d namespaces\n",(int)nvme_namespaces_args.nentries); ++ ++ grub_ieee1275_close(ihandle); ++ ++ grub_uint32_t namespace_index = 0; ++ for(namespace_index=0; namespace_index < nvme_namespaces_args.nentries; namespace_index++){ ++ grub_snprintf (bufptr+bufptr_pos2, 512, "/namespace@%"PRIxGRUB_UINT32_T,namespaces[namespace_index]); ++ grub_dprintf("ofdisk","NVMeoF: namespace=%s\n",buf); ++ dev_iterate_real(buf,buf); ++ } ++ ++ dev_iterate_real(buf,buf); ++ } ++ } ++ grub_free(buf); ++ return; ++} ++ ++static void ++dev_iterate (const struct grub_ieee1275_devalias *alias) ++{ ++ if (grub_strcmp (alias->type, "fcp") == 0) ++ { ++ // Iterate disks ++ dev_iterate_fcp_disks(alias); ++ ++ // Iterate NVMeoF ++ dev_iterate_fcp_nvmeof(alias); ++ + } + else if (grub_strcmp (alias->type, "vscsi") == 0) + { +-- +2.35.3 + diff --git a/0001-ieee1275-implement-FCP-methods-for-WWPN-and-LUNs.patch b/0001-ieee1275-implement-FCP-methods-for-WWPN-and-LUNs.patch new file mode 100644 index 0000000000000000000000000000000000000000..28b9dbf2e7ac093bce72d58854f9fcffa529f9c9 --- /dev/null +++ b/0001-ieee1275-implement-FCP-methods-for-WWPN-and-LUNs.patch @@ -0,0 +1,146 @@ +From a37d0cc089edd66ab35f1a27b0da09dd2f02deb3 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Mon, 24 Jun 2019 10:15:56 -0400 +Subject: [PATCH] ieee1275: implement FCP methods for WWPN and LUNs + +This patch enables the fcp-targets and fcp-luns methods which are +responsible to get WWPNs and LUNs for fibre channel devices. + +Those methods are specially necessary if the boot directory and grub +installation are in different FCP disks, allowing the dev_iterate() +to find the WWPNs and LUNs when called by searchfs.uuid tool. +--- + grub-core/disk/ieee1275/ofdisk.c | 117 ++++++++++++++++++++++++++++++- + 1 file changed, 116 insertions(+), 1 deletion(-) + +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index ea7f78ac7..258a6e389 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -209,7 +209,122 @@ dev_iterate_real (const char *name, const char *path) + static void + dev_iterate (const struct grub_ieee1275_devalias *alias) + { +- if (grub_strcmp (alias->type, "vscsi") == 0) ++ if (grub_strcmp (alias->type, "fcp") == 0) ++ { ++ ++ /* If we are dealing with fcp devices, we need ++ * to find the WWPNs and LUNs to iterate them */ ++ grub_ieee1275_ihandle_t ihandle; ++ grub_uint64_t *ptr_targets, *ptr_luns, k, l; ++ unsigned int i, j, pos; ++ char *buf, *bufptr; ++ ++ struct set_fcp_targets_args ++ { ++ struct grub_ieee1275_common_hdr common; ++ grub_ieee1275_cell_t method; ++ grub_ieee1275_cell_t ihandle; ++ grub_ieee1275_cell_t catch_result; ++ grub_ieee1275_cell_t nentries; ++ grub_ieee1275_cell_t table; ++ } args_targets; ++ ++ struct set_fcp_luns_args ++ { ++ struct grub_ieee1275_common_hdr common; ++ grub_ieee1275_cell_t method; ++ grub_ieee1275_cell_t ihandle; ++ grub_ieee1275_cell_t wwpn_h; ++ grub_ieee1275_cell_t wwpn_l; ++ grub_ieee1275_cell_t catch_result; ++ grub_ieee1275_cell_t nentries; ++ grub_ieee1275_cell_t table; ++ } args_luns; ++ ++ struct args_ret ++ { ++ grub_uint64_t addr; ++ grub_uint64_t len; ++ }; ++ ++ if(grub_ieee1275_open (alias->path, &ihandle)) ++ { ++ grub_dprintf("disk", "failed to open the disk while iterating FCP disk path=%s\n", alias->path); ++ return; ++ } ++ ++ /* Setup the fcp-targets method to call via pfw*/ ++ INIT_IEEE1275_COMMON (&args_targets.common, "call-method", 2, 3); ++ args_targets.method = (grub_ieee1275_cell_t) "fcp-targets"; ++ args_targets.ihandle = ihandle; ++ ++ /* Setup the fcp-luns method to call via pfw */ ++ INIT_IEEE1275_COMMON (&args_luns.common, "call-method", 4, 3); ++ args_luns.method = (grub_ieee1275_cell_t) "fcp-luns"; ++ args_luns.ihandle = ihandle; ++ ++ if (IEEE1275_CALL_ENTRY_FN (&args_targets) == -1) ++ { ++ grub_dprintf("disk", "failed to get the targets while iterating FCP disk path=%s\n", alias->path); ++ grub_ieee1275_close(ihandle); ++ return; ++ } ++ ++ buf = grub_malloc (grub_strlen (alias->path) + 32 + 32); ++ ++ if (!buf) ++ { ++ grub_ieee1275_close(ihandle); ++ return; ++ } ++ ++ bufptr = grub_stpcpy (buf, alias->path); ++ ++ /* Iterate over entries returned by pfw. Each entry contains a ++ * pointer to wwpn table and his length. */ ++ struct args_ret *targets_table = (struct args_ret *)(args_targets.table); ++ for (i=0; i< args_targets.nentries; i++) ++ { ++ ptr_targets = (grub_uint64_t*)(grub_uint32_t) targets_table[i].addr; ++ /* Iterate over all wwpns in given table */ ++ for(k=0;k> 32); ++ pos=grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T, ++ *ptr_targets++); ++ /* Get the luns for given wwpn target */ ++ if (IEEE1275_CALL_ENTRY_FN (&args_luns) == -1) ++ { ++ grub_dprintf("disk", "failed to get the LUNS while iterating FCP disk path=%s\n", buf); ++ grub_ieee1275_close (ihandle); ++ grub_free (buf); ++ return; ++ } ++ ++ struct args_ret *luns_table = (struct args_ret *)(args_luns.table); ++ ++ /* Iterate over all LUNs */ ++ for(j=0;jtype, "vscsi") == 0) + { + static grub_ieee1275_ihandle_t ihandle; + struct set_color_args +-- +2.31.1 + diff --git a/0001-ieee1275-ofdisk-retry-on-open-and-read-failure.patch b/0001-ieee1275-ofdisk-retry-on-open-and-read-failure.patch new file mode 100644 index 0000000000000000000000000000000000000000..48326928afa9cbb9f39ae52b3a0bf2c97d51e5f8 --- /dev/null +++ b/0001-ieee1275-ofdisk-retry-on-open-and-read-failure.patch @@ -0,0 +1,172 @@ +From f4728ed5307b6be6377b7bdafcab55fd3676a761 Mon Sep 17 00:00:00 2001 +From: Mukesh Kumar Chaurasiya +Date: Mon, 17 Jul 2023 16:02:34 +0530 +Subject: [PATCH] ieee1275/ofdisk: retry on open and read failure + +Sometimes, when booting from a very busy SAN, the access to the +disk can fail and then grub will eventually drop to grub prompt. +This scenario is more frequent when deploying many machines at +the same time using the same SAN. +This patch aims to force the ofdisk module to retry the open or +read function for network disks excluding after it fails. We use +DEFAULT_RETRY_TIMEOUT, which is 15 seconds to specify the time it'll +retry to access the disk before it definitely fails. The timeout can be +changed by setting the environment variable ofdisk_retry_timeout. +If the environment variable fails to read, grub will consider the +default value of 15 seconds. + +Signed-off-by: Diego Domingos +Signed-off-by: Mukesh Kumar Chaurasiya +--- + docs/grub.texi | 8 ++++ + grub-core/disk/ieee1275/ofdisk.c | 80 +++++++++++++++++++++++++++++++- + 2 files changed, 86 insertions(+), 2 deletions(-) + +diff --git a/docs/grub.texi b/docs/grub.texi +index d3f0f6577..c8ebc083d 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -3315,6 +3315,7 @@ These variables have special meaning to GRUB. + * net_default_ip:: + * net_default_mac:: + * net_default_server:: ++* ofdisk_retry_timeout:: + * pager:: + * prefix:: + * pxe_blksize:: +@@ -3744,6 +3745,13 @@ The default is the value of @samp{color_normal} (@pxref{color_normal}). + @xref{Network}. + + ++@node ofdisk_retry_timeout ++@subsection ofdisk_retry_timeout ++ ++The time in seconds till which the grub will retry to open or read a disk in ++case of failure to do so. This value defaults to 15 seconds. ++ ++ + @node pager + @subsection pager + +diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c +index 7197d5401..f96bbb58c 100644 +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -24,6 +24,9 @@ + #include + #include + #include ++#include ++ ++#define RETRY_DEFAULT_TIMEOUT 15 + + static char *last_devpath; + static grub_ieee1275_ihandle_t last_ihandle; +@@ -783,7 +786,7 @@ compute_dev_path (const char *name) + } + + static grub_err_t +-grub_ofdisk_open (const char *name, grub_disk_t disk) ++grub_ofdisk_open_real (const char *name, grub_disk_t disk) + { + grub_ieee1275_phandle_t dev; + char *devpath; +@@ -879,6 +882,56 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) + return 0; + } + ++static grub_uint64_t ++grub_ofdisk_disk_timeout (grub_disk_t disk) ++{ ++ grub_uint64_t retry; ++ const char *timeout = grub_env_get ("ofdisk_retry_timeout"); ++ ++ if (!(grub_strstr (disk->name, "fibre-channel@") || ++ grub_strstr (disk->name, "vfc-client")) || ++ grub_strstr(disk->name, "nvme-of")) ++ { ++ /* Do not retry in case of non network drives */ ++ return 0; ++ } ++ ++ if (timeout != NULL) ++ { ++ retry = grub_strtoul (timeout, 0, 10); ++ if (grub_errno != GRUB_ERR_NONE) ++ { ++ grub_errno = GRUB_ERR_NONE; ++ return RETRY_DEFAULT_TIMEOUT; ++ } ++ if (retry) ++ return retry; ++ } ++ return RETRY_DEFAULT_TIMEOUT; ++} ++ ++static grub_err_t ++grub_ofdisk_open (const char *name, grub_disk_t disk) ++{ ++ grub_err_t err; ++ grub_uint64_t timeout = grub_get_time_ms () + (grub_ofdisk_disk_timeout (disk) * 1000); ++ _Bool cont; ++ do ++ { ++ err = grub_ofdisk_open_real (name, disk); ++ cont = grub_get_time_ms () < timeout; ++ if (err == GRUB_ERR_UNKNOWN_DEVICE && cont) ++ { ++ grub_dprintf ("ofdisk","Failed to open disk %s. Retrying...\n", name); ++ grub_errno = GRUB_ERR_NONE; ++ } ++ else ++ break; ++ grub_millisleep (1000); ++ } while (cont); ++ return err; ++} ++ + static void + grub_ofdisk_close (grub_disk_t disk) + { +@@ -915,7 +968,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector) + } + + static grub_err_t +-grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, ++grub_ofdisk_read_real (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, char *buf) + { + grub_err_t err; +@@ -934,6 +987,29 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, + return 0; + } + ++static grub_err_t ++grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, ++ grub_size_t size, char *buf) ++{ ++ grub_err_t err; ++ grub_uint64_t timeout = grub_get_time_ms () + (grub_ofdisk_disk_timeout (disk) * 1000); ++ _Bool cont; ++ do ++ { ++ err = grub_ofdisk_read_real (disk, sector, size, buf); ++ cont = grub_get_time_ms () < timeout; ++ if (err == GRUB_ERR_UNKNOWN_DEVICE && cont) ++ { ++ grub_dprintf ("ofdisk","Failed to read disk %s. Retrying...\n", (char*)disk->data); ++ grub_errno = GRUB_ERR_NONE; ++ } ++ else ++ break; ++ grub_millisleep (1000); ++ } while (cont); ++ return err; ++} ++ + static grub_err_t + grub_ofdisk_write (grub_disk_t disk, grub_disk_addr_t sector, + grub_size_t size, const char *buf) +-- +2.41.0 + diff --git a/0157-ieee1275-powerpc-implements-fibre-channel-discovery-.patch b/0001-ieee1275-powerpc-implements-fibre-channel-discovery-.patch similarity index 75% rename from 0157-ieee1275-powerpc-implements-fibre-channel-discovery-.patch rename to 0001-ieee1275-powerpc-implements-fibre-channel-discovery-.patch index 9fa02bb1748cd09b8bc33e536d1736bca49b5c96..1eb3b5c237352e95f9569ebde7fc3f990d07c471 100644 --- a/0157-ieee1275-powerpc-implements-fibre-channel-discovery-.patch +++ b/0001-ieee1275-powerpc-implements-fibre-channel-discovery-.patch @@ -1,28 +1,25 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From ca30b3c6fd8c848f510445316d0c4a8fca6061ba Mon Sep 17 00:00:00 2001 From: Diego Domingos -Date: Mon, 14 Dec 2020 17:45:28 +0100 -Subject: [PATCH] ieee1275/powerpc: implements fibre channel discovery for +Date: Wed, 24 Jun 2020 08:17:18 -0400 +Subject: [PATCH 1/2] ieee1275/powerpc: implements fibre channel discovery for ofpathname grub-ofpathname doesn't work with fibre channel because there is no function currently implemented for it. This patch enables it by prividing a function that looks for the port name, building the entire path for OF devices. - -Signed-off-by: Diego Domingos --- - grub-core/osdep/linux/ofpath.c | 49 ++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 49 insertions(+) + grub-core/osdep/linux/ofpath.c | 48 ++++++++++++++++++++++++++++++++++ + 1 file changed, 48 insertions(+) diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c -index a6153d35954..0f5d54e9f2d 100644 +index a6153d359..f2bc9fc5c 100644 --- a/grub-core/osdep/linux/ofpath.c +++ b/grub-core/osdep/linux/ofpath.c -@@ -350,6 +350,38 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi - return ret; +@@ -399,6 +399,37 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)), } + #endif -+ +static void +of_fc_port_name(const char *path, const char *subpath, char *port_name) +{ @@ -47,17 +44,17 @@ index a6153d35954..0f5d54e9f2d 100644 + grub_util_error (_("cannot read `%s': %s"), bname, strerror (errno)); + + sscanf(port_name,"0x%s",port_name); -+ ++ + close(fd); + + free(bname); + free(basepath); +} + - #ifdef __sparc__ - static char * - of_path_of_nvme(const char *sys_devname __attribute__((unused)), -@@ -577,6 +609,16 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev + static int + vendor_is_ATA(const char *path) + { +@@ -577,6 +608,16 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev digit_string = trailing_digits (device); if (strncmp (of_path, "/vdevice/", sizeof ("/vdevice/") - 1) == 0) { @@ -65,7 +62,7 @@ index a6153d35954..0f5d54e9f2d 100644 + { + char * port_name = xmalloc(sizeof(char)*17); + of_fc_port_name(sysfs_path, p, port_name); -+ ++ + snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name); + free(port_name); + } @@ -74,7 +71,7 @@ index a6153d35954..0f5d54e9f2d 100644 unsigned long id = 0x8000 | (tgt << 8) | (bus << 5) | lun; if (*digit_string == '\0') { -@@ -590,6 +632,13 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev +@@ -590,6 +631,13 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev snprintf(disk, sizeof (disk), "/%s@%04lx000000000000:%c", disk_name, id, 'a' + (part - 1)); } @@ -82,9 +79,12 @@ index a6153d35954..0f5d54e9f2d 100644 + } else if (strstr(of_path,"fibre-channel")||(strstr(of_path,"vfc-client"))){ + char * port_name = xmalloc(sizeof(char)*17); + of_fc_port_name(sysfs_path, p, port_name); -+ ++ + snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name); + free(port_name); } else { +-- +2.26.2 + diff --git a/0001-install-fix-software-raid1-on-esp.patch b/0001-install-fix-software-raid1-on-esp.patch new file mode 100644 index 0000000000000000000000000000000000000000..4052e5a27075052d7a424f0ed77afbcfe3d6ea52 --- /dev/null +++ b/0001-install-fix-software-raid1-on-esp.patch @@ -0,0 +1,396 @@ +From 6444774dae24f439dae3b4bc8d73449d50f06240 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Thu, 31 Dec 2020 21:54:07 +0800 +Subject: [PATCH] install: fix software raid1 on esp + +While running grub-install on an efi system where efi system partition +is configured as mdadm software raid1, it fails with errors like this: + + grub2-install: info: copying `/boot/grub2/x86_64-efi/core.efi' -> `/boot/efi/EFI/opensuse/grubx64.efi'. + grub2-install: info: Registering with EFI: distributor = `opensuse', path = `\EFI\opensuse\grubx64.efi', ESP at mduuid/9182c46b9d469f79b48850b68f3371a5. + grub2-install: info: executing efibootmgr --version /dev/null. + grub2-install: info: executing modprobe -q efivars. + grub2-install: info: executing efibootmgr -c -d. + efibootmgr: option requires an argument -- 'd' + efibootmgr version 14 + usage: efibootmgr [options] + +This should work with mdadm raid1 with metadata 0.9 and 1.0 whose +superblocks are at the end of device. However +grub_install_register_efi() doesn't seem to work if the target is +multiple devices so that it errors out. + +The patch changes grub_install_register_efi() to accept multiple devices +that can be used to creating efi boot entries for probed raid1 member +devices on mounted efi system partition. + +This patch also adds check for metadata 0.9 or 1.0 or the validation +will fail to continue the install. + +Signed-off-by: Michael Chang +--- + grub-core/disk/diskfilter.c | 27 +++---- + grub-core/disk/mdraid1x_linux.c | 3 + + grub-core/osdep/basic/no_platform.c | 3 +- + grub-core/osdep/unix/platform.c | 57 +++++++++++---- + grub-core/osdep/windows/platform.c | 3 +- + include/grub/diskfilter.h | 3 +- + include/grub/util/install.h | 5 +- + util/grub-install.c | 107 ++++++++++++++++++++++++++-- + 8 files changed, 171 insertions(+), 37 deletions(-) + +--- a/grub-core/disk/diskfilter.c ++++ b/grub-core/disk/diskfilter.c +@@ -159,8 +159,8 @@ + for (m = arr->pvs; m; m = m->next) + if (m->disk && m->disk->id == disk->id + && m->disk->dev->id == disk->dev->id +- && m->part_start == grub_partition_get_start (disk->partition) +- && m->part_size == grub_disk_native_sectors (disk)) ++ && grub_partition_get_start (m->disk->partition) == grub_partition_get_start (disk->partition) ++ && grub_disk_native_sectors (m->disk) == grub_disk_native_sectors (disk)) + return 0; + } + +@@ -1340,19 +1340,23 @@ + ? (grub_memcmp (pv->id.uuid, id->uuid, id->uuidlen) == 0) + : (pv->id.id == id->id)) + { ++ char *part_name = NULL; + struct grub_diskfilter_lv *lv; + /* FIXME: Check whether the update time of the superblocks are + the same. */ +- if (pv->disk && grub_disk_native_sectors (disk) >= pv->part_size) ++ if (pv->disk && grub_disk_native_sectors (disk) >= grub_disk_native_sectors (pv->disk)) + return GRUB_ERR_NONE; +- pv->disk = grub_disk_open (disk->name); ++ if (disk->partition) ++ { ++ char *p = grub_partition_get_name (disk->partition); ++ if (p) ++ part_name = grub_xasprintf ("%s,%s", disk->name, p); ++ grub_free (p); ++ } ++ pv->disk = grub_disk_open (part_name ? : disk->name); ++ grub_free (part_name); + if (!pv->disk) + return grub_errno; +- /* This could happen to LVM on RAID, pv->disk points to the +- raid device, we shouldn't change it. */ +- pv->start_sector -= pv->part_start; +- pv->part_start = grub_partition_get_start (disk->partition); +- pv->part_size = grub_disk_native_sectors (disk); + + #ifdef GRUB_UTIL + { +@@ -1369,7 +1373,6 @@ + #endif + if (start_sector != (grub_uint64_t)-1) + pv->start_sector = start_sector; +- pv->start_sector += pv->part_start; + /* Add the device to the array. */ + for (lv = array->lvs; lv; lv = lv->next) + if (!lv->became_readable_at && lv->fullname && is_lv_readable (lv, 0)) +@@ -1457,8 +1460,8 @@ + { + if (pv->disk && pv->disk->id == disk->id + && pv->disk->dev->id == disk->dev->id +- && pv->part_start == grub_partition_get_start (disk->partition) +- && pv->part_size == grub_disk_native_sectors (disk)) ++ && grub_partition_get_start (pv->disk->partition) == grub_partition_get_start (disk->partition) ++ && grub_disk_native_sectors (pv->disk) == grub_disk_native_sectors (disk)) + { + if (vg_out) + *vg_out = vg; +--- a/grub-core/disk/mdraid1x_linux.c ++++ b/grub-core/disk/mdraid1x_linux.c +@@ -208,6 +208,9 @@ + grub_le_to_cpu32 (sb.chunksize), + grub_le_to_cpu32 (sb.layout), + grub_le_to_cpu32 (sb.level)); ++#ifdef GRUB_UTIL ++ array->mdraid1x_minor_version = minor_version; ++#endif + + return array; + } +--- a/grub-core/osdep/basic/no_platform.c ++++ b/grub-core/osdep/basic/no_platform.c +@@ -33,7 +33,8 @@ + void + grub_install_register_efi (grub_device_t efidir_grub_dev, + const char *efifile_path, +- const char *efi_distributor) ++ const char *efi_distributor, ++ const char *force_disk) + { + grub_util_error ("%s", _("no EFI routines are available for your platform")); + } +--- a/grub-core/osdep/unix/platform.c ++++ b/grub-core/osdep/unix/platform.c +@@ -132,15 +132,14 @@ + } + + int +-grub_install_register_efi (grub_device_t efidir_grub_dev, ++grub_install_register_efi (const grub_disk_t *efidir_grub_disk, + const char *efifile_path, +- const char *efi_distributor) ++ const char *efi_distributor, ++ const char *force_disk) + { +- const char * efidir_disk; +- int efidir_part; + int ret; +- efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk); +- efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1; ++ const grub_disk_t *curdisk; ++ int ndev = 0; + + if (grub_util_exec_redirect_null ((const char * []){ "efibootmgr", "--version", NULL })) + { +@@ -158,22 +157,50 @@ + if (ret) + return ret; + +- char *efidir_part_str = xasprintf ("%d", efidir_part); ++ for (curdisk = efidir_grub_disk; *curdisk; curdisk++) ++ ndev++; + +- if (!verbosity) +- ret = grub_util_exec ((const char * []){ "efibootmgr", "-q", ++ for (curdisk = efidir_grub_disk; *curdisk; curdisk++) ++ { ++ const char * efidir_disk; ++ int efidir_part; ++ char *efidir_part_str; ++ char *new_efi_distributor = NULL; ++ grub_disk_t disk = *curdisk; ++ ++ efidir_disk = force_disk ? : grub_util_biosdisk_get_osdev (disk); ++ if (!efidir_disk) ++ grub_util_error (_("%s: no device for efi"), disk->name); ++ ++ efidir_part = disk->partition ? disk->partition->number + 1 : 1; ++ efidir_part_str = xasprintf ("%d", efidir_part); ++ if (ndev > 1) ++ { ++ const char *p = grub_strrchr (efidir_disk, '/'); ++ new_efi_distributor = xasprintf ("%s (%s%d)\n", ++ efi_distributor, ++ p ? p + 1: efidir_disk, ++ efidir_part); ++ } ++ ++ if (!verbosity) ++ ret = grub_util_exec ((const char * []){ "efibootmgr", "-q", + "-c", "-d", efidir_disk, + "-p", efidir_part_str, "-w", +- "-L", efi_distributor, "-l", ++ "-L", new_efi_distributor ? : efi_distributor, "-l", + efifile_path, NULL }); +- else +- ret = grub_util_exec ((const char * []){ "efibootmgr", ++ else ++ ret = grub_util_exec ((const char * []){ "efibootmgr", + "-c", "-d", efidir_disk, + "-p", efidir_part_str, "-w", +- "-L", efi_distributor, "-l", ++ "-L", new_efi_distributor ? : efi_distributor, "-l", + efifile_path, NULL }); +- free (efidir_part_str); +- return ret; ++ free (efidir_part_str); ++ free (new_efi_distributor); ++ if (ret) ++ return ret; ++ } ++ return 0; + } + + void +--- a/grub-core/osdep/windows/platform.c ++++ b/grub-core/osdep/windows/platform.c +@@ -204,7 +204,8 @@ + int + grub_install_register_efi (grub_device_t efidir_grub_dev, + const char *efifile_path, +- const char *efi_distributor) ++ const char *efi_distributor, ++ const char *force_disk) + { + grub_uint16_t *boot_order, *new_boot_order; + grub_uint16_t *distributor16; +--- a/include/grub/diskfilter.h ++++ b/include/grub/diskfilter.h +@@ -49,6 +49,7 @@ + + #ifdef GRUB_UTIL + struct grub_diskfilter *driver; ++ grub_uint8_t mdraid1x_minor_version; + #endif + }; + +@@ -66,8 +67,6 @@ + /* Optional. */ + char *name; + grub_disk_t disk; +- grub_disk_addr_t part_start; +- grub_disk_addr_t part_size; + grub_disk_addr_t start_sector; /* Sector number where the data area starts. */ + struct grub_diskfilter_pv *next; + /* Optional. */ +--- a/include/grub/util/install.h ++++ b/include/grub/util/install.h +@@ -236,9 +236,10 @@ + grub_install_get_powerpc_secure_boot (void); + + int +-grub_install_register_efi (grub_device_t efidir_grub_dev, ++grub_install_register_efi (const grub_disk_t *efidir_grub_disk, + const char *efifile_path, +- const char *efi_distributor); ++ const char *efi_distributor, ++ const char *force_disk); + + void + grub_install_register_ieee1275 (int is_prep, const char *install_device, +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -1719,6 +1719,40 @@ + } + } + prefix_drive = xasprintf ("(%s)", grub_drives[0]); ++ ++ if (platform == GRUB_INSTALL_PLATFORM_X86_64_EFI ++ && grub_dev->disk ++ && grub_dev->disk->partition ++ && grub_fs->fs_uuid) ++ { ++ int raid_level; ++ char *uuid = NULL; ++ char *escaped_relpath = NULL; ++ ++ raid_level = probe_raid_level (grub_dev->disk); ++ if (raid_level != 1) ++ goto out; ++ ++ escaped_relpath = escape (relative_grubdir); ++ if (!escaped_relpath) ++ goto out; ++ ++ if (grub_fs->fs_uuid (grub_dev, &uuid) || !uuid) ++ { ++ grub_print_error (); ++ grub_errno = 0; ++ goto out; ++ } ++ ++ if (!load_cfg_f) ++ load_cfg_f = grub_util_fopen (load_cfg, "wb"); ++ have_load_cfg = 1; ++ fprintf (load_cfg_f, "search --no-floppy --fs-uuid --set=root --hint='%s' %s\n", grub_drives[0], uuid); ++ fprintf (load_cfg_f, "set prefix=($root)'%s'\n", escaped_relpath); ++ grub_install_push_module ("search"); ++ out: ++ grub_free (escaped_relpath); ++ } + } + + #ifdef __linux__ +@@ -2258,9 +2292,13 @@ + { + /* Try to make this image bootable using the EFI Boot Manager, if available. */ + int ret; +- ret = grub_install_register_efi (efidir_grub_dev, ++ grub_disk_t efidir_grub_disk[2]; ++ efidir_grub_disk[0] = efidir_grub_dev->disk; ++ efidir_grub_disk[1] = NULL; ++ ret = grub_install_register_efi (efidir_grub_disk, + "\\System\\Library\\CoreServices", +- efi_distributor); ++ efi_distributor, ++ NULL); + if (ret) + grub_util_error (_("efibootmgr failed to register the boot entry: %s"), + strerror (ret)); +@@ -2314,7 +2352,11 @@ + { + char * efifile_path; + char * part; ++ int raid_level; + int ret; ++ grub_disk_t *efidir_grub_disk; ++ grub_disk_memberlist_t list = NULL, cur; ++ char * force_disk = NULL; + + /* Try to make this image bootable using the EFI Boot Manager, if available. */ + if (!efi_distributor || efi_distributor[0] == '\0') +@@ -2331,8 +2373,65 @@ + efidir_grub_dev->disk->name, + (part ? ",": ""), (part ? : "")); + grub_free (part); +- ret = grub_install_register_efi (efidir_grub_dev, +- efifile_path, efi_distributor); ++ ++ raid_level = probe_raid_level (efidir_grub_dev->disk); ++ if (raid_level >= 0 && raid_level != 1) ++ grub_util_warn (_("unsupported raid level %d detected for efi system partition"), raid_level); ++ if (raid_level == 1 && !efidir_grub_dev->disk->partition) ++ { ++ const char *raidname = NULL; ++ ++ if (efidir_grub_dev->disk->dev->disk_raidname) ++ raidname = efidir_grub_dev->disk->dev->disk_raidname (efidir_grub_dev->disk); ++ if (raidname ++ && (grub_strncmp (raidname, "mdraid09", sizeof ("mdraid09")) == 0 ++ || (grub_strcmp (raidname, "mdraid1x") == 0 ++ && ((struct grub_diskfilter_lv *) efidir_grub_dev->disk->data)->vg->mdraid1x_minor_version == 0))) ++ { ++ if (efidir_grub_dev->disk->dev->disk_memberlist) ++ list = efidir_grub_dev->disk->dev->disk_memberlist (efidir_grub_dev->disk); ++ } ++ else ++ { ++ grub_util_warn (_("this array has metadata at the start and may not be suitable as a efi system partition." ++ " please ensure that your firmware understands md/v1.x metadata, or use --metadata=0.90" ++ " to create the array.")); ++ /* Try to continue regardless metadata, nothing to lose here */ ++ if (efidir_grub_dev->disk->dev->disk_memberlist) ++ list = efidir_grub_dev->disk->dev->disk_memberlist (efidir_grub_dev->disk); ++ } ++ } ++ else if (raid_level == 1) ++ force_disk = grub_util_get_os_disk (install_device); ++ if (list) ++ { ++ int i; ++ int ndisk = 0; ++ ++ for (cur = list; cur; cur = cur->next) ++ ++ndisk; ++ efidir_grub_disk = xcalloc (ndisk + 1, sizeof (*efidir_grub_disk)); ++ for (cur = list, i = 0; i < ndisk; cur = cur->next, i++) ++ efidir_grub_disk[i] = cur->disk; ++ efidir_grub_disk[ndisk] = NULL; ++ } ++ else ++ { ++ efidir_grub_disk = xcalloc (2, sizeof (*efidir_grub_disk)); ++ efidir_grub_disk[0] = efidir_grub_dev->disk; ++ efidir_grub_disk[1] = NULL; ++ } ++ ret = grub_install_register_efi (efidir_grub_disk, ++ efifile_path, efi_distributor, ++ force_disk); ++ while (list) ++ { ++ cur = list; ++ list = list->next; ++ grub_free (cur); ++ } ++ grub_free (force_disk); ++ grub_free (efidir_grub_disk); + if (ret) + grub_util_error (_("efibootmgr failed to register the boot entry: %s"), + strerror (ret)); diff --git a/0001-kern-mm.c-Make-grub_calloc-inline.patch b/0001-kern-mm.c-Make-grub_calloc-inline.patch new file mode 100644 index 0000000000000000000000000000000000000000..c48157c5e6abc38a7e42dff2aa93df6d3d42c6c5 --- /dev/null +++ b/0001-kern-mm.c-Make-grub_calloc-inline.patch @@ -0,0 +1,109 @@ +From c2475f1337dff2e2a3e45514119d5186e55753c1 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Thu, 13 Aug 2020 09:36:45 +0800 +Subject: [PATCH] kern/mm.c : Make grub_calloc inline + +To circumvent the situation that symbol 'grub_calloc' not found would +happen if system is using stray grub (ie not managed by system update) +as stage1 that can be too old to load updated modules. +--- + grub-core/kern/mm.c | 28 ---------------------------- + include/grub/mm.h | 32 +++++++++++++++++++++++++++++++- + 2 files changed, 31 insertions(+), 29 deletions(-) + +--- a/grub-core/kern/mm.c ++++ b/grub-core/kern/mm.c +@@ -63,14 +63,10 @@ + + #include + #include +-#include +-#include + #include + #include + #include +-#include + #include +-#include + + #ifdef MM_DEBUG + # undef grub_calloc +@@ -553,30 +549,6 @@ + return 0; + } + +-/* +- * Allocate NMEMB instances of SIZE bytes and return the pointer, or error on +- * integer overflow. +- */ +-void * +-grub_calloc (grub_size_t nmemb, grub_size_t size) +-{ +- void *ret; +- grub_size_t sz = 0; +- +- if (grub_mul (nmemb, size, &sz)) +- { +- grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); +- return NULL; +- } +- +- ret = grub_memalign (0, sz); +- if (!ret) +- return NULL; +- +- grub_memset (ret, 0, sz); +- return ret; +-} +- + /* Allocate SIZE bytes and return the pointer. */ + void * + grub_malloc (grub_size_t size) +--- a/include/grub/mm.h ++++ b/include/grub/mm.h +@@ -47,7 +47,6 @@ + #endif + + void grub_mm_init_region (void *addr, grub_size_t size); +-void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size); + void *EXPORT_FUNC(grub_malloc) (grub_size_t size); + void *EXPORT_FUNC(grub_zalloc) (grub_size_t size); + void EXPORT_FUNC(grub_free) (void *ptr); +@@ -55,6 +54,37 @@ + #ifndef GRUB_MACHINE_EMU + void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size); + #endif ++#if !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU) ++#include ++#include ++#include ++#include ++/* ++ * Allocate NMEMB instances of SIZE bytes and return the pointer, or error on ++ * integer overflow. ++ */ ++static inline void * ++grub_calloc (grub_size_t nmemb, grub_size_t size) ++{ ++ void *ret; ++ grub_size_t sz = 0; ++ ++ if (grub_mul (nmemb, size, &sz)) ++ { ++ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ return NULL; ++ } ++ ++ ret = grub_memalign (0, sz); ++ if (!ret) ++ return NULL; ++ ++ grub_memset (ret, 0, sz); ++ return ret; ++} ++#else ++void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size); ++#endif + + void grub_mm_check_real (const char *file, int line); + #define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__); diff --git a/0001-loader-arm64-efi-linux-Remove-magic-number-header-fi.patch b/0001-loader-arm64-efi-linux-Remove-magic-number-header-fi.patch new file mode 100644 index 0000000000000000000000000000000000000000..0a234189cfc3db547de31ecec08c579132cb628c --- /dev/null +++ b/0001-loader-arm64-efi-linux-Remove-magic-number-header-fi.patch @@ -0,0 +1,43 @@ +From d683bed5c76c54e6bc5c26eef2f8d7136a3c75c4 Mon Sep 17 00:00:00 2001 +From: Ard Biesheuvel +Date: Thu, 11 Aug 2022 16:51:57 +0200 +Subject: [PATCH] loader/arm64/efi/linux: Remove magic number header field + check + +The "ARM\x64" magic number in the file header identifies an image as one +that implements the bare metal boot protocol, allowing the loader to +simply move the file to a suitably aligned address in memory, with +sufficient headroom for the trailing .bss segment (the required memory +size is described in the header as well). + +Note of this matters for GRUB, as it only supports EFI boot. EFI does +not care about this magic number, and nor should GRUB: this prevents us +from booting other PE linux images, such as the generic EFI zboot +decompressor, which is a pure PE/COFF image, and does not implement the +bare metal boot protocol. + +So drop the magic number check. + +Signed-off-by: Ard Biesheuvel +Reviewed-by: Daniel Kiper +--- + grub-core/loader/arm64/efi/linux.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c +index 33df0e1fd..a9f5e05e4 100644 +--- a/grub-core/loader/arm64/efi/linux.c ++++ b/grub-core/loader/arm64/efi/linux.c +@@ -57,9 +57,6 @@ static grub_addr_t initrd_end; + 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")); +-- +2.43.0 + diff --git a/0001-luks2-Use-grub-tpm2-token-for-TPM2-protected-volume-.patch b/0001-luks2-Use-grub-tpm2-token-for-TPM2-protected-volume-.patch new file mode 100644 index 0000000000000000000000000000000000000000..6a71e3152c7693dcbfb662e488192dc0a814bf34 --- /dev/null +++ b/0001-luks2-Use-grub-tpm2-token-for-TPM2-protected-volume-.patch @@ -0,0 +1,142 @@ +From 06af22d6c893b0249712e9a486e0cbae15160e5c Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Mon, 23 Oct 2023 16:11:53 +0800 +Subject: [PATCH] luks2: Use grub-tpm2 token for TPM2-protected volume unlock + +This commit enables the use of the grub-tpm2 token for unlocking LUKS2 +volumes protected by TPM2. The token tracks keyslots associated with a +sealed key, making the unsealing process more efficient and secure. + +Signed-Off-by Michael Chang +--- + grub-core/disk/luks2.c | 81 ++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 79 insertions(+), 2 deletions(-) + +diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c +index d5106402f..fe5ba777a 100644 +--- a/grub-core/disk/luks2.c ++++ b/grub-core/disk/luks2.c +@@ -124,6 +124,14 @@ struct grub_luks2_digest + }; + typedef struct grub_luks2_digest grub_luks2_digest_t; + ++struct grub_luks2_token_tpm ++{ ++ grub_uint64_t idx; ++ grub_uint64_t keyslots; ++ const char *timestamp; ++}; ++typedef struct grub_luks2_token_tpm grub_luks2_token_tpm_t; ++ + gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src, + grub_uint8_t * dst, grub_size_t blocksize, + grub_size_t blocknumbers); +@@ -257,6 +265,39 @@ luks2_parse_digest (grub_luks2_digest_t *out, const grub_json_t *digest) + return GRUB_ERR_NONE; + } + ++static grub_err_t ++luks2_parse_token_tpm (grub_luks2_token_tpm_t *out, const grub_json_t *token) ++{ ++ grub_json_t keyslots, o; ++ grub_size_t i, size; ++ grub_uint64_t bit; ++ const char *type; ++ ++ if (grub_json_getstring (&type, token, "type")) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid token type"); ++ else if (grub_strcmp (type, "grub-tpm2")) ++ return GRUB_ERR_NONE; ++ ++ if (grub_json_getvalue (&keyslots, token, "keyslots") || ++ grub_json_getstring (&out->timestamp, token, "timestamp")) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing token parameters"); ++ ++ if (grub_json_getsize (&size, &keyslots)) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ "Token references no keyslots"); ++ ++ out->keyslots = 0; ++ for (i = 0; i < size; i++) ++ { ++ if (grub_json_getchild (&o, &keyslots, i) || ++ grub_json_getuint64 (&bit, &o, NULL)) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid keyslot"); ++ out->keyslots |= (1 << bit); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ + static grub_err_t + luks2_get_keyslot (grub_luks2_keyslot_t *k, grub_luks2_digest_t *d, grub_luks2_segment_t *s, + const grub_json_t *root, grub_size_t keyslot_json_idx) +@@ -561,13 +602,14 @@ luks2_recover_key (grub_disk_t source, + { + grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN]; + char cipher[32], *json_header = NULL, *ptr; +- grub_size_t candidate_key_len = 0, json_idx, size; ++ grub_size_t candidate_key_len = 0, json_idx, size, tsize; + grub_luks2_header_t header; + grub_luks2_keyslot_t keyslot; + grub_luks2_digest_t digest; + grub_luks2_segment_t segment; ++ grub_luks2_token_tpm_t token_tpm; + gcry_err_code_t gcry_ret; +- grub_json_t *json = NULL, keyslots; ++ grub_json_t *json = NULL, keyslots, tokens; + grub_err_t ret; + + if (cargs->key_data == NULL || cargs->key_len == 0) +@@ -605,6 +647,37 @@ luks2_recover_key (grub_disk_t source, + goto err; + } + ++ token_tpm.keyslots = 0; ++ tsize = 0; ++ if (cargs->protectors) ++ { ++ int i; ++ for (i = 0; cargs->protectors[i]; i++) ++ if (grub_strcmp(cargs->protectors[i], "tpm2") == 0) ++ break; ++ ++ if (!cargs->protectors[i] || ++ cargs->key_cache[i].invalid || ++ grub_json_getvalue (&tokens, json, "tokens") || ++ grub_json_getsize (&tsize, &tokens)) ++ grub_dprintf ("luks2", "No valid token or not a tpm2 protector\n"); ++ } ++ ++ for (json_idx = 0; json_idx < tsize; json_idx++) ++ { ++ grub_json_t token; ++ ++ if (grub_json_getchild (&token, &tokens, json_idx) || ++ grub_json_getuint64 (&token_tpm.idx, &token, NULL) || ++ grub_json_getchild (&token, &token, 0) || ++ luks2_parse_token_tpm (&token_tpm, &token)) ++ { ++ grub_dprintf ("luks2", "Could not parse token index %" PRIuGRUB_SIZE "\n", json_idx); ++ grub_errno = GRUB_ERR_NONE; ++ continue; ++ } ++ } ++ + if (grub_disk_native_sectors (source) == GRUB_DISK_SIZE_UNKNOWN) + { + /* FIXME: Allow use of source disk, and maybe cause errors in read. */ +@@ -641,6 +714,10 @@ luks2_recover_key (grub_disk_t source, + continue; + } + ++ if (token_tpm.keyslots && ++ !(token_tpm.keyslots & (1 << keyslot.idx))) ++ continue; ++ + grub_dprintf ("luks2", "Trying keyslot \"%" PRIuGRUB_UINT64_T "\"\n", keyslot.idx); + + /* Sector size should be one of 512, 1024, 2048, or 4096. */ +-- +2.42.0 + diff --git a/0001-ofdisk-enhance-boot-time-by-focusing-on-boot-disk-re.patch b/0001-ofdisk-enhance-boot-time-by-focusing-on-boot-disk-re.patch new file mode 100644 index 0000000000000000000000000000000000000000..7621011e81b77fa12ac59fed670fb993eec89dcf --- /dev/null +++ b/0001-ofdisk-enhance-boot-time-by-focusing-on-boot-disk-re.patch @@ -0,0 +1,238 @@ +From b353ca96bf002a9262fdf74637f39615d003d069 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Fri, 8 Dec 2023 11:51:57 +0800 +Subject: [PATCH 1/2] ofdisk: enhance boot time by focusing on boot disk + relevance + +After a historical review, it's clear that a boot delay regression +coincided with the introduction of the fcp iterating patch. Reverting +this patch has shown promising signs in mitigating the issue. In order +to improve the efficiency, a more refined discovery process is proposed, +aiming to exclude device types differing from the boot disk to curtail +unnecessary iterations. + +This patch extends prior efforts by exclusively targeting root device +discovery linked to the boot disk, verifying device types to prevent +process elongation. + +It is worth noting that grub's opportunistic approach to assembling the +root device, seeking accessible results in parallel during iteration, +sometimes allows even a partially assembled RAID, albeit in a degraded +mode. However, delays stem from unrelated devices appearing before the +actual boot device. + +To streamline the boot process, the patch utilizes parent nodes in +conjunction with block device nodes to extract essential boot-related +information. This refined identification method efficiently limits the +application's scope to devices connected to the chosen boot device, +notably optimizing subsequent device iteration. By adeptly filtering out +devices not linked to the same FCP (Fibre Channel Protocol) device, it +significantly enhances boot efficiency, ensuring a more streamlined and +efficient boot process. + +Signed-off-by: Michael Chang +--- + grub-core/disk/ieee1275/ofdisk.c | 136 +++++++++++++++++++++++++++++-- + 1 file changed, 131 insertions(+), 5 deletions(-) + +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -31,6 +31,13 @@ + static char *last_devpath; + static grub_ieee1275_ihandle_t last_ihandle; + ++#define IEEE1275_DISK_ALIAS "/disk@" ++#define IEEE1275_NVMEOF_DISK_ALIAS "/nvme-of/controller@" ++ ++static char *boot_type; ++static char *boot_parent; ++static int is_boot_nvmeof; ++ + struct ofdisk_hash_ent + { + char *devpath; +@@ -529,12 +536,21 @@ + { + if (grub_strcmp (alias->type, "fcp") == 0) + { +- // Iterate disks +- dev_iterate_fcp_disks(alias); +- +- // Iterate NVMeoF +- dev_iterate_fcp_nvmeof(alias); ++ if (boot_type && ++ grub_strcmp (boot_type, alias->type) != 0) ++ { ++ grub_dprintf ("ofdisk", "Skipped device: %s, type %s did not match boot_type %s\n", ++ alias->path, alias->type, boot_type); ++ goto iter_children; ++ } + ++ if (grub_strcmp (boot_parent, alias->path) == 0) ++ { ++ if (is_boot_nvmeof) ++ dev_iterate_fcp_nvmeof(alias); ++ else ++ dev_iterate_fcp_disks(alias); ++ } + } + else if (grub_strcmp (alias->type, "vscsi") == 0) + { +@@ -552,6 +568,14 @@ + char *buf, *bufptr; + unsigned i; + ++ if (boot_type && ++ grub_strcmp (boot_type, alias->type) != 0) ++ { ++ grub_dprintf ("ofdisk", "Skipped device: %s, type %s did not match boot_type %s\n", ++ alias->path, alias->type, boot_type); ++ return; ++ } ++ + if (grub_ieee1275_open (alias->path, &ihandle)) + return; + +@@ -615,6 +639,14 @@ + grub_uint16_t table_size; + grub_ieee1275_ihandle_t ihandle; + ++ if (boot_type && ++ grub_strcmp (boot_type, alias->type) != 0) ++ { ++ grub_dprintf ("ofdisk", "Skipped device: %s, type %s did not match boot_type %s\n", ++ alias->path, alias->type, boot_type); ++ goto iter_children; ++ } ++ + buf = grub_malloc (grub_strlen (alias->path) + + sizeof ("/disk@7766554433221100")); + if (!buf) +@@ -674,6 +706,7 @@ + return; + } + ++ iter_children: + { + struct grub_ieee1275_devalias child; + +@@ -1046,6 +1079,68 @@ + .next = 0 + }; + ++static char * ++get_parent_devname (const char *devname, int *is_nvmeof) ++{ ++ char *parent, *pptr; ++ ++ if (is_nvmeof) ++ *is_nvmeof = 0; ++ ++ parent = grub_strdup (devname); ++ ++ if (parent == NULL) ++ { ++ grub_print_error (); ++ return NULL; ++ } ++ ++ pptr = grub_strstr (parent, IEEE1275_DISK_ALIAS); ++ ++ if (pptr != NULL) ++ { ++ *pptr = '\0'; ++ return parent; ++ } ++ ++ pptr = grub_strstr (parent, IEEE1275_NVMEOF_DISK_ALIAS); ++ ++ if (pptr != NULL) ++ { ++ *pptr = '\0'; ++ if (is_nvmeof) ++ *is_nvmeof = 1; ++ return parent; ++ } ++ ++ return parent; ++} ++ ++static char * ++get_boot_device_parent (const char *bootpath, int *is_nvmeof) ++{ ++ char *dev, *canon, *parent; ++ ++ dev = grub_ieee1275_get_aliasdevname (bootpath); ++ canon = grub_ieee1275_canonicalise_devname (dev); ++ ++ if (!canon) ++ { ++ /* This should not happen. */ ++ grub_error (GRUB_ERR_BAD_DEVICE, "canonicalise devname failed"); ++ grub_print_error (); ++ return NULL; ++ } ++ else ++ grub_dprintf ("ofdisk", "%s is canonical %s\n", bootpath, canon); ++ ++ parent = get_parent_devname (canon, is_nvmeof); ++ grub_dprintf ("ofdisk", "%s is parent of %s\n", parent, canon); ++ ++ grub_free (canon); ++ return parent; ++} ++ + static void + insert_bootpath (void) + { +@@ -1081,6 +1176,12 @@ + char *device = grub_ieee1275_get_devname (bootpath); + op = ofdisk_hash_add (device, NULL); + op->is_boot = 1; ++ boot_parent = get_boot_device_parent (bootpath, &is_boot_nvmeof); ++ boot_type = grub_ieee1275_get_device_type (boot_parent); ++ if (boot_type) ++ grub_dprintf ("ofdisk", "the boot device type %s is used for root device discovery, others excluded\n", boot_type); ++ else ++ grub_dprintf ("ofdisk", "unknown boot device type, will use all devices to discover root and may be slow\n"); + } + grub_free (type); + grub_free (bootpath); +@@ -1097,12 +1198,37 @@ + grub_disk_dev_unregister (&grub_ofdisk_dev); + } + ++static const char * ++grub_env_get_boot_type (struct grub_env_var *var __attribute__ ((unused)), ++ const char *val __attribute__ ((unused))) ++{ ++ static char *ret; ++ ++ if (!ret) ++ ret = grub_xasprintf("boot: %s type: %s is_nvmeof: %d", ++ boot_parent, ++ boot_type ? : "unknown", ++ is_boot_nvmeof); ++ ++ return ret; ++} ++ ++static char * ++grub_env_set_boot_type (struct grub_env_var *var __attribute__ ((unused)), ++ const char *val __attribute__ ((unused))) ++{ ++ /* READ ONLY */ ++ return NULL; ++} ++ + void + grub_ofdisk_init (void) + { + grub_disk_firmware_fini = grub_ofdisk_fini; + + insert_bootpath (); ++ grub_register_variable_hook ("ofdisk_boot_type", grub_env_get_boot_type, ++ grub_env_set_boot_type ); + + grub_disk_dev_register (&grub_ofdisk_dev); + } diff --git a/0001-ofdisk-improve-boot-time-by-lookup-boot-disk-first.patch b/0001-ofdisk-improve-boot-time-by-lookup-boot-disk-first.patch new file mode 100644 index 0000000000000000000000000000000000000000..1772c8bdfba9890191d1d0e430b6749856447501 --- /dev/null +++ b/0001-ofdisk-improve-boot-time-by-lookup-boot-disk-first.patch @@ -0,0 +1,58 @@ +From b0f9dcabe96e5689ecfba9b6abcd27e685eabd48 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Wed, 11 May 2022 09:56:11 -0400 +Subject: [PATCH] ofdisk: improve boot time by lookup boot disk first + +While booting lvm, grub will try to build up logical volumes via hooks +to disk iteration where on-disk metadata can be read and parsed. However +the process can become very slow on multipath as reachable disks are +duplicated by multiple I/O paths and they all get inspected. + +Fortunately grub allows lvm to be lazy binding and opportunistic that +root volume can be created when it's needed using a smaller set of +discovered disks. The disk iteration can also be controlled by pull +methods to only returning specified disks. That said we may be able to +take advantage of existing design to cause less overhead in lvm +construction. + +This patch will return boot disks in OpenFirmware so they can be used +first. If lvm managed to create root volume out of those boot disks then +it is all very nice as they are readily available. Otherwise disk +scanning will be performed to present all discoverable disks to grub as +what it was done in the past. The result maybe again time consuming but +we have nothing to lose here. + +Signed-off-by: Michael Chang +--- + grub-core/disk/ieee1275/ofdisk.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -491,10 +491,11 @@ + { + unsigned i; + +- if (pull != GRUB_DISK_PULL_NONE) ++ if (pull > GRUB_DISK_PULL_REMOVABLE) + return 0; + +- scan (); ++ if (pull == GRUB_DISK_PULL_REMOVABLE) ++ scan (); + + for (i = 0; i < ARRAY_SIZE (ofdisk_hash); i++) + { +@@ -532,6 +533,12 @@ + if (!ent->is_boot && ent->is_removable) + continue; + ++ if (pull == GRUB_DISK_PULL_NONE && !ent->is_boot) ++ continue; ++ ++ if (pull == GRUB_DISK_PULL_REMOVABLE && ent->is_boot) ++ continue; ++ + if (hook (ent->grub_shortest, hook_data)) + return 1; + } diff --git a/0001-openfw-Ensure-get_devargs-and-get_devname-functions-.patch b/0001-openfw-Ensure-get_devargs-and-get_devname-functions-.patch new file mode 100644 index 0000000000000000000000000000000000000000..db5f897d9963c03179b41fa7693e25aa8cf2b9a3 --- /dev/null +++ b/0001-openfw-Ensure-get_devargs-and-get_devname-functions-.patch @@ -0,0 +1,52 @@ +From 468628bdc39800341e7aa6ff7795cc0d93cfaf3f Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Tue, 11 Apr 2023 10:59:34 +0800 +Subject: [PATCH 1/2] openfw: Ensure get_devargs and get_devname functions are + consistent + +Commit 165c9b234 changed the logic of ieee1275_get_devargs() to use the +first or second occurrence of a colon as a separator between device name +and arguments. However, this didn't align with the complementary +function ieee1275_get_devname, which uses the first occurrence of a +colon after the namespace keyword as arguments for the nvme-of device. + +This commit addresses the inconsistency by ensuring that both functions +follow a common logic. Now, get_devargs and get_devname functions are +consistent with each other, making it easier to understand and maintain +the codebase. + +Signed-off-by: Michael Chang +--- + grub-core/kern/ieee1275/openfw.c | 15 +++++++++------ + 1 file changed, 9 insertions(+), 6 deletions(-) + +diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c +index e2ffec32d..3bbd07d95 100644 +--- a/grub-core/kern/ieee1275/openfw.c ++++ b/grub-core/kern/ieee1275/openfw.c +@@ -354,13 +354,16 @@ static char * + grub_ieee1275_get_devargs (const char *path) + { + char *colon = grub_strchr (path, ':'); +- char *colon_check = colon; + +- /* Find the last occurence of colon */ +- while(colon_check){ +- colon = colon_check; +- colon_check = grub_strchr (colon+1, ':'); +- } ++ /* Use the same logic in grub_ieee1275_get_devname for nvme-of arguments */ ++ if (grub_strstr(path, "nvme-of")) ++ { ++ char *namespace_split = grub_strstr(path,"/namespace@"); ++ if (namespace_split) ++ colon = grub_strchr (namespace_split, ':'); ++ else ++ colon = NULL; ++ } + + if (! colon) + return 0; +-- +2.39.2 + diff --git a/0001-protectors-Add-key-protectors-framework.patch b/0001-protectors-Add-key-protectors-framework.patch new file mode 100644 index 0000000000000000000000000000000000000000..f658e919d20006d302fd944873fe6b159cd13ba4 --- /dev/null +++ b/0001-protectors-Add-key-protectors-framework.patch @@ -0,0 +1,177 @@ +From 5affde982dea827580e36ccc658e439397f51ce8 Mon Sep 17 00:00:00 2001 +From: Hernan Gatta +Date: Tue, 1 Feb 2022 05:02:53 -0800 +Subject: [PATCH 1/5] protectors: Add key protectors framework + +A key protector encapsulates functionality to retrieve an unlocking key +for a fully-encrypted disk from a specific source. A key protector +module registers itself with the key protectors framework when it is +loaded and unregisters when unloaded. Additionally, a key protector may +accept parameters that describe how it should operate. + +The key protectors framework, besides offering registration and +unregistration functions, also offers a one-stop routine for finding and +invoking a key protector by name. If a key protector with the specified +name exists and if an unlocking key is successfully retrieved by it, the +function returns to the caller the retrieved key and its length. + +Signed-off-by: Hernan Gatta +Signed-off-by: Gary Lin +--- + grub-core/Makefile.am | 1 + + grub-core/Makefile.core.def | 1 + + grub-core/kern/protectors.c | 75 +++++++++++++++++++++++++++++++++++++ + include/grub/protector.h | 48 ++++++++++++++++++++++++ + 4 files changed, 125 insertions(+) + create mode 100644 grub-core/kern/protectors.c + create mode 100644 include/grub/protector.h + +--- a/grub-core/Makefile.am ++++ b/grub-core/Makefile.am +@@ -90,6 +90,7 @@ + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h ++KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/protector.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h + KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -149,6 +149,7 @@ + common = kern/misc.c; + common = kern/parser.c; + common = kern/partition.c; ++ common = kern/protectors.c; + common = kern/rescue_parser.c; + common = kern/rescue_reader.c; + common = kern/term.c; +--- /dev/null ++++ b/grub-core/kern/protectors.c +@@ -0,0 +1,75 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++ ++struct grub_key_protector *grub_key_protectors = NULL; ++ ++grub_err_t ++grub_key_protector_register (struct grub_key_protector *protector) ++{ ++ if (protector == NULL || protector->name == NULL || grub_strlen(protector->name) == 0) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ if (grub_key_protectors && ++ grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), ++ protector->name)) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors), ++ GRUB_AS_LIST (protector)); ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_key_protector_unregister (struct grub_key_protector *protector) ++{ ++ if (protector == NULL) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ grub_list_remove (GRUB_AS_LIST (protector)); ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_key_protector_recover_key (const char *protector, grub_uint8_t **key, ++ grub_size_t *key_size) ++{ ++ struct grub_key_protector *kp = NULL; ++ ++ if (grub_key_protectors == NULL) ++ return GRUB_ERR_OUT_OF_RANGE; ++ ++ if (protector == NULL || grub_strlen (protector) == 0) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors), ++ protector); ++ if (kp == NULL) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("A key protector with name '%s' could not be found. " ++ "Is the name spelled correctly and is the " ++ "corresponding module loaded?"), protector); ++ ++ return kp->recover_key (key, key_size); ++} +--- /dev/null ++++ b/include/grub/protector.h +@@ -0,0 +1,48 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_PROTECTOR_HEADER ++#define GRUB_PROTECTOR_HEADER 1 ++ ++#include ++#include ++ ++struct grub_key_protector ++{ ++ struct grub_key_protector *next; ++ struct grub_key_protector **prev; ++ ++ const char *name; ++ ++ grub_err_t (*recover_key) (grub_uint8_t **key, grub_size_t *key_size); ++}; ++ ++extern struct grub_key_protector *EXPORT_VAR (grub_key_protectors); ++ ++grub_err_t ++EXPORT_FUNC (grub_key_protector_register) (struct grub_key_protector *protector); ++ ++grub_err_t ++EXPORT_FUNC (grub_key_protector_unregister) (struct grub_key_protector *protector); ++ ++grub_err_t ++EXPORT_FUNC (grub_key_protector_recover_key) (const char *protector, ++ grub_uint8_t **key, ++ grub_size_t *key_size); ++ ++#endif /* ! GRUB_PROTECTOR_HEADER */ diff --git a/0001-protectors-Implement-NV-index.patch b/0001-protectors-Implement-NV-index.patch new file mode 100644 index 0000000000000000000000000000000000000000..2cb214de1292da3acdab08728223854d7f517a8b --- /dev/null +++ b/0001-protectors-Implement-NV-index.patch @@ -0,0 +1,80 @@ +From c3efb4ecbe91b63c127b92122dad3fa53d4efc69 Mon Sep 17 00:00:00 2001 +From: Patrick Colp +Date: Mon, 31 Jul 2023 07:01:45 -0700 +Subject: [PATCH 1/4] protectors: Implement NV index + +Currently with the TPM2 protector, only SRK mode is supported and +NV index support is just a stub. Implement the NV index option. + +Note: This only extends support on the unseal path. grub2_protect +has not been updated. tpm2-tools can be used to insert a key into +the NV index. + +An example of inserting a key using tpm2-tools: + + # Get random key. + tpm2_getrandom 32 > key.dat + + # Create primary object. + tpm2_createprimary -C o -g sha256 -G rsa -c primary.ctx + + # Create policy object. `pcrs.dat` contains the PCR values to seal against. + tpm2_startauthsession -S session.dat + tpm2_policypcr -S session.dat -l sha256:7,11 -f pcrs.dat -L policy.dat + tpm2_flushcontext session.dat + + # Seal key into TPM. + cat key.dat | tpm2_create -C primary.ctx -u key.pub -r key.priv -L policy.dat -i- + tpm2_load -C primary.ctx -u key.pub -r key.priv -n sealing.name -c sealing.ctx + tpm2_evictcontrol -C o -c sealing.ctx 0x81000000 + +Then to unseal the key in grub, add this to grub.cfg: + + tpm2_key_protector_init --mode=nv --nvindex=0x81000000 --pcrs=7,11 + cryptomount -u --protector tpm2 + +Signed-off-by: Patrick Colp +--- + grub-core/tpm2/module.c | 25 ++++++++++++++++++++----- + 1 file changed, 20 insertions(+), 5 deletions(-) + +diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c +index 5274296b7..d3a64187a 100644 +--- a/grub-core/tpm2/module.c ++++ b/grub-core/tpm2/module.c +@@ -757,12 +757,27 @@ static grub_err_t + grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context *ctx, + grub_uint8_t **key, grub_size_t *key_size) + { +- (void)ctx; +- (void)key; +- (void)key_size; ++ TPM_HANDLE sealed_handle = ctx->nv; ++ tpm2key_policy_t policy_seq = NULL; ++ grub_err_t err; ++ ++ /* Create a basic policy sequence based on the given PCR selection */ ++ err = grub_tpm2_protector_simple_policy_seq (ctx, &policy_seq); ++ if (err != GRUB_ERR_NONE) ++ goto exit; ++ ++ err = grub_tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size); ++ ++ /* Pop error messages on success */ ++ if (err == GRUB_ERR_NONE) ++ while (grub_error_pop ()); ++ ++exit: ++ TPM2_FlushContext (sealed_handle); + +- return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, +- N_("NV Index mode is not implemented yet")); ++ grub_tpm2key_free_policy_seq (policy_seq); ++ ++ return err; + } + + static grub_err_t +-- +2.35.3 + diff --git a/0001-squash-ieee1275-ofpath-enable-NVMeoF-logical-device-.patch b/0001-squash-ieee1275-ofpath-enable-NVMeoF-logical-device-.patch new file mode 100644 index 0000000000000000000000000000000000000000..abfae3b1afcc5bc9d684fc024c05a50b522b15e1 --- /dev/null +++ b/0001-squash-ieee1275-ofpath-enable-NVMeoF-logical-device-.patch @@ -0,0 +1,60 @@ +From 72a582b1c3954f9b917a4d687c95fc94faf551c6 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Wed, 24 Jan 2024 18:03:51 +0800 +Subject: [PATCH] squash! ieee1275/ofpath: enable NVMeoF logical device + translation + +Fixes build error on gcc-14: + +[ 73s] In file included from ../grub-core/osdep/ofpath.c:2: +[ 73s] ../grub-core/osdep/linux/ofpath.c: In function 'of_find_fc_host': +[ 73s] ../grub-core/osdep/linux/ofpath.c:427:22: error: allocation of insufficient size '8' for type 'struct ofpath_files_list_root' with size '16' [-Werror=alloc-size] +[ 73s] 427 | portnames_file_list=malloc(sizeof(portnames_file_list)); +[ 73s] | ^ +[ 73s] ../grub-core/osdep/linux/ofpath.c: In function 'of_path_of_nvme': +[ 73s] ../grub-core/osdep/linux/ofpath.c:589:21: error: allocation of insufficient size '8' for type 'struct ofpath_nvmeof_info' with size '32' [-Werror=alloc-size] +[ 73s] 589 | nvmeof_info = malloc(sizeof(nvmeof_info)); +[ 73s] | ^ +[ 73s] ../grub-core/osdep/linux/ofpath.c:618:21: error: allocation of insufficient size '8' for type 'struct ofpath_nvmeof_info' with size '32' [-Werror=alloc-size] +[ 73s] 618 | nvmeof_info = malloc(sizeof(nvmeof_info)); +[ 73s] | ^ + +Signed-off-by: Michael Chang +--- + grub-core/osdep/linux/ofpath.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c +index 7129099db..55ed7ddf2 100644 +--- a/grub-core/osdep/linux/ofpath.c ++++ b/grub-core/osdep/linux/ofpath.c +@@ -424,7 +424,7 @@ of_find_fc_host(char* host_wwpn){ + + struct ofpath_files_list_root* portnames_file_list; + +- portnames_file_list=malloc(sizeof(portnames_file_list)); ++ portnames_file_list=malloc(sizeof(*portnames_file_list)); + portnames_file_list->items=0; + portnames_file_list->first=NULL; + +@@ -586,7 +586,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)), + /* If is a NVMeoF */ + if(strstr(sysfs_path,"nvme-fabrics")){ + struct ofpath_nvmeof_info* nvmeof_info; +- nvmeof_info = malloc(sizeof(nvmeof_info)); ++ nvmeof_info = malloc(sizeof(*nvmeof_info)); + + of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info); + +@@ -615,7 +615,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)), + sysfs_path = nvme_get_syspath (device); + if(strstr(sysfs_path,"nvme-fabrics")){ + struct ofpath_nvmeof_info* nvmeof_info; +- nvmeof_info = malloc(sizeof(nvmeof_info)); ++ nvmeof_info = malloc(sizeof(*nvmeof_info)); + + of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info); + +-- +2.43.0 + diff --git a/0001-templates-Follow-the-path-of-usr-merged-kernel-confi.patch b/0001-templates-Follow-the-path-of-usr-merged-kernel-confi.patch new file mode 100644 index 0000000000000000000000000000000000000000..98f71391a548301d782920e4b9e2721e066daaf5 --- /dev/null +++ b/0001-templates-Follow-the-path-of-usr-merged-kernel-confi.patch @@ -0,0 +1,40 @@ +From 60d1d3b959e72c2cbd014be311c350a9b11b1289 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Tue, 7 Sep 2021 10:06:50 +0800 +Subject: [PATCH] templates: Follow the path of usr merged kernel config + +The background for usr merge can be found at: + +https://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/ + +This patch adapts related mkconfig scripts to follow the usr merge for +looking up kernel configs. + +Signed-off-by: Michael Chang +--- + util/grub.d/10_linux.in | 2 +- + util/grub.d/20_linux_xen.in | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -351,7 +351,7 @@ + fi + + config= +- for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do ++ for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" "/usr/lib/modules/${version}/config" ; do + if test -e "${i}" ; then + config="${i}" + break +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -307,7 +307,7 @@ + version=$(echo $basename | sed -e "s,^[^0-9]*-,,g") + dirname=$(dirname $i) + config= +- for j in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do ++ for j in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" "/usr/lib/modules/${version}/config" ; do + if test -e "${j}" ; then + config="${j}" + break diff --git a/0001-tpm2-Add-TPM2-types-structures-and-command-constants.patch b/0001-tpm2-Add-TPM2-types-structures-and-command-constants.patch new file mode 100644 index 0000000000000000000000000000000000000000..80e203ab80f7de009b7b9ae7f7a64a09ba126fce --- /dev/null +++ b/0001-tpm2-Add-TPM2-types-structures-and-command-constants.patch @@ -0,0 +1,204 @@ +From 5a417f32f1afe0ffca7f5cbff67145a157b1589b Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Tue, 7 Feb 2023 18:31:12 +0800 +Subject: [PATCH 1/4] tpm2: Add TPM2 types, structures, and command constants + +Add new TPM2 types and structures as the preparation to support +authorized policy. + +* New types: + TPM_ALG_ECDAA, TPM_ALG_ECDSA, TPM_ALG_ECSCHNORR, TPM_ALG_RSASSA, + TPM_ALG_RSAPSS, TPM_ALG_SM2, and TPMI_ALG_SIG_SCHEME + +* New structures: + TPMS_EMPTY, TPMS_SIGNATURE_RSA, TPMS_SIGNATURE_ECC, + TPMS_SIGNATURE_ECDSA, TPMS_SIGNATURE_ECDAA, TPMS_SIGNATURE_SM2, + TPMS_SIGNATURE_ECSCHNORR, TPMU_SIGNATURE, and TPMT_TK_VERIFIED + +* New command constants: + TPM_CC_LoadExternal, TPM_CC_HashSequenceStart, TPM_CC_SequenceUpdate, + TPM_CC_SequenceComplete, TPM_CC_Hash, TPM_CC_VerifySignature, + TPM_CC_PolicyAuthorize + +Signed-off-by: Gary Lin +--- + include/grub/tpm2/internal/structs.h | 86 ++++++++++++++++++++++++++++ + include/grub/tpm2/internal/types.h | 42 +++++++++----- + 2 files changed, 114 insertions(+), 14 deletions(-) + +diff --git a/include/grub/tpm2/internal/structs.h b/include/grub/tpm2/internal/structs.h +index 72d71eb70..db9eb6cf6 100644 +--- a/include/grub/tpm2/internal/structs.h ++++ b/include/grub/tpm2/internal/structs.h +@@ -672,4 +672,90 @@ struct TPMT_TK_CREATION + }; + typedef struct TPMT_TK_CREATION TPMT_TK_CREATION; + ++/* TPMS_EMPTY Structure */ ++struct TPMS_EMPTY { ++ grub_uint8_t empty[1]; /* a structure with no member */ ++}; ++typedef struct TPMS_EMPTY TPMS_EMPTY; ++ ++/* TPMS_SIGNATURE_RSA Structure */ ++struct TPMS_SIGNATURE_RSA { ++ TPMI_ALG_HASH hash; ++ TPM2B_PUBLIC_KEY_RSA sig; ++}; ++typedef struct TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSA; ++ ++/* Definition of Types for RSA Signature */ ++typedef TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSASSA; ++typedef TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSAPSS; ++ ++/* TPMS_SIGNATURE_ECC Structure */ ++struct TPMS_SIGNATURE_ECC { ++ TPMI_ALG_HASH hash; ++ TPM2B_ECC_PARAMETER signatureR; ++ TPM2B_ECC_PARAMETER signatureS; ++}; ++typedef struct TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECC; ++ ++/* Definition of Types for ECC TPMS_SIGNATURE_ECC */ ++typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDSA; ++typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDAA; ++typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_SM2; ++typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECSCHNORR; ++ ++/* TPMU_SIGNATURE Structure */ ++union TPMU_SIGNATURE { ++ TPMS_SIGNATURE_RSASSA rsassa; ++ TPMS_SIGNATURE_RSAPSS rsapss; ++ TPMS_SIGNATURE_ECDSA ecdsa; ++ TPMS_SIGNATURE_ECDAA ecdaa; ++ TPMS_SIGNATURE_SM2 sm2; ++ TPMS_SIGNATURE_ECSCHNORR ecschnorr; ++ TPMT_HA hmac; ++ TPMS_SCHEME_HASH any; ++ TPMS_EMPTY null; ++}; ++typedef union TPMU_SIGNATURE TPMU_SIGNATURE; ++ ++/* TPMT_SIGNATURE Structure */ ++struct TPMT_SIGNATURE { ++ TPMI_ALG_SIG_SCHEME sigAlg; ++ TPMU_SIGNATURE signature; ++}; ++typedef struct TPMT_SIGNATURE TPMT_SIGNATURE; ++ ++static inline TPMI_ALG_HASH ++TPMT_SIGNATURE_get_hash_alg (TPMT_SIGNATURE *sig) ++{ ++ switch (sig->sigAlg) ++ { ++ case TPM_ALG_RSASSA: ++ return sig->signature.rsassa.hash; ++ case TPM_ALG_RSAPSS: ++ return sig->signature.rsapss.hash; ++ case TPM_ALG_ECDSA: ++ return sig->signature.ecdsa.hash; ++ case TPM_ALG_ECDAA: ++ return sig->signature.ecdaa.hash; ++ case TPM_ALG_SM2: ++ return sig->signature.sm2.hash; ++ case TPM_ALG_ECSCHNORR: ++ return sig->signature.ecschnorr.hash; ++ case TPM_ALG_HMAC: ++ return sig->signature.hmac.hashAlg; ++ default: ++ break; ++ } ++ ++ return TPM_ALG_NULL; ++} ++ ++/* TPMT_TK_VERIFIED Structure */ ++struct TPMT_TK_VERIFIED { ++ TPM_ST tag; ++ TPMI_RH_HIERARCHY hierarchy; ++ TPM2B_DIGEST digest; ++}; ++typedef struct TPMT_TK_VERIFIED TPMT_TK_VERIFIED; ++ + #endif /* ! GRUB_TPM2_INTERNAL_STRUCTS_HEADER */ +diff --git a/include/grub/tpm2/internal/types.h b/include/grub/tpm2/internal/types.h +index 9714f75d4..a1902ef0c 100644 +--- a/include/grub/tpm2/internal/types.h ++++ b/include/grub/tpm2/internal/types.h +@@ -181,6 +181,9 @@ typedef grub_uint16_t TPM_ALG_ID; + #define TPM_ALG_CFB ((TPM_ALG_ID) 0x0043) + #define TPM_ALG_ECB ((TPM_ALG_ID) 0x0044) + #define TPM_ALG_ECC ((TPM_ALG_ID) 0x0023) ++#define TPM_ALG_ECDAA ((TPM_ALG_ID) 0x001A) ++#define TPM_ALG_ECDSA ((TPM_ALG_ID) 0x0018) ++#define TPM_ALG_ECSCHNORR ((TPM_ALG_ID) 0x001C) + #define TPM_ALG_HMAC ((TPM_ALG_ID) 0x0005) + #define TPM_ALG_KDF1_SP800_108 ((TPM_ALG_ID) 0x0022) + #define TPM_ALG_KDF1_SP800_56A ((TPM_ALG_ID) 0x0020) +@@ -189,10 +192,13 @@ typedef grub_uint16_t TPM_ALG_ID; + #define TPM_ALG_MGF1 ((TPM_ALG_ID) 0x0007) + #define TPM_ALG_NULL ((TPM_ALG_ID) 0x0010) + #define TPM_ALG_RSA ((TPM_ALG_ID) 0x0001) ++#define TPM_ALG_RSASSA ((TPM_ALG_ID) 0x0014) ++#define TPM_ALG_RSAPSS ((TPM_ALG_ID) 0x0016) + #define TPM_ALG_SHA1 ((TPM_ALG_ID) 0x0004) + #define TPM_ALG_SHA256 ((TPM_ALG_ID) 0x000B) + #define TPM_ALG_SHA384 ((TPM_ALG_ID) 0x000C) + #define TPM_ALG_SHA512 ((TPM_ALG_ID) 0x000D) ++#define TPM_ALG_SM2 ((TPM_ALG_ID) 0x001B) + #define TPM_ALG_SM3_256 ((TPM_ALG_ID) 0x0012) + #define TPM_ALG_SM4 ((TPM_ALG_ID) 0x0013) + #define TPM_ALG_SYMCIPHER ((TPM_ALG_ID) 0x0025) +@@ -299,20 +305,27 @@ typedef grub_uint16_t TPM2_ECC_CURVE; + /* TPM_CC Constants */ + typedef grub_uint32_t TPM_CC; + +-#define TPM_CC_EvictControl ((TPM_CC) 0x00000120) +-#define TPM_CC_CreatePrimary ((TPM_CC) 0x00000131) +-#define TPM_CC_Create ((TPM_CC) 0x00000153) +-#define TPM_CC_FlushContext ((TPM_CC) 0x00000165) +-#define TPM_CC_ReadPublic ((TPM_CC) 0x00000173) +-#define TPM_CC_StartAuthSession ((TPM_CC) 0x00000176) +-#define TPM_CC_PolicyPCR ((TPM_CC) 0x0000017f) +-#define TPM_CC_NV_Read ((TPM_CC) 0x0000014e) +-#define TPM_CC_NV_ReadPublic ((TPM_CC) 0x00000169) +-#define TPM_CC_GetCapability ((TPM_CC) 0x0000017a) +-#define TPM_CC_PCR_Read ((TPM_CC) 0x0000017e) +-#define TPM_CC_Load ((TPM_CC) 0x00000157) +-#define TPM_CC_Unseal ((TPM_CC) 0x0000015e) +-#define TPM_CC_PolicyGetDigest ((TPM_CC) 0x00000189) ++#define TPM_CC_EvictControl ((TPM_CC) 0x00000120) ++#define TPM_CC_CreatePrimary ((TPM_CC) 0x00000131) ++#define TPM_CC_Create ((TPM_CC) 0x00000153) ++#define TPM_CC_FlushContext ((TPM_CC) 0x00000165) ++#define TPM_CC_ReadPublic ((TPM_CC) 0x00000173) ++#define TPM_CC_StartAuthSession ((TPM_CC) 0x00000176) ++#define TPM_CC_PolicyPCR ((TPM_CC) 0x0000017f) ++#define TPM_CC_NV_Read ((TPM_CC) 0x0000014e) ++#define TPM_CC_NV_ReadPublic ((TPM_CC) 0x00000169) ++#define TPM_CC_GetCapability ((TPM_CC) 0x0000017a) ++#define TPM_CC_PCR_Read ((TPM_CC) 0x0000017e) ++#define TPM_CC_Load ((TPM_CC) 0x00000157) ++#define TPM_CC_LoadExternal ((TPM_CC) 0x00000167) ++#define TPM_CC_Unseal ((TPM_CC) 0x0000015e) ++#define TPM_CC_PolicyGetDigest ((TPM_CC) 0x00000189) ++#define TPM_CC_HashSequenceStart ((TPM_CC) 0x00000186) ++#define TPM_CC_SequenceUpdate ((TPM_CC) 0x0000015c) ++#define TPM_CC_SequenceComplete ((TPM_CC) 0x0000013e) ++#define TPM_CC_Hash ((TPM_CC) 0x0000017d) ++#define TPM_CC_VerifySignature ((TPM_CC) 0x00000177) ++#define TPM_CC_PolicyAuthorize ((TPM_CC) 0x0000016a) + + /* Hash algorithm sizes */ + #define TPM_SHA1_DIGEST_SIZE 20 +@@ -354,6 +367,7 @@ typedef TPM_ALG_ID TPMI_ALG_ECC_SCHEME; + typedef TPM_ALG_ID TPMI_ALG_ASYM_SCHEME; + typedef TPM_ALG_ID TPMI_ALG_RSA_SCHEME; + typedef TPM_ALG_ID TPMI_ALG_SYM; ++typedef TPM_ALG_ID TPMI_ALG_SIG_SCHEME; + + /* TPM_KEY_BITS Type */ + typedef grub_uint16_t TPM_KEY_BITS; +-- +2.35.3 + diff --git a/0001-xen_boot-add-missing-grub_arch_efi_linux_load_image_.patch b/0001-xen_boot-add-missing-grub_arch_efi_linux_load_image_.patch new file mode 100644 index 0000000000000000000000000000000000000000..474c99dbddde49ad798b7bc64027f317bae8fbcb --- /dev/null +++ b/0001-xen_boot-add-missing-grub_arch_efi_linux_load_image_.patch @@ -0,0 +1,83 @@ +From 6c06378c1bf6ae21788427e62ab0011b7f1bc2f0 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Fri, 25 Nov 2022 16:11:24 +0800 +Subject: [PATCH] xen_boot: add missing grub_arch_efi_linux_load_image_header + +The new xen_boot module has used grub_arch_efi_linux_load_image_header +exported by grub-core/loader/arm64/linux.c. It is not a problem for +upstream but many downstream projects may not use it and take +grub-core/loader/arm64/efi/linux.c as a replacement as PE entry is the +preferred way in combination with shim loader. + +This patch did a trivial workaround just adding back the dropped +defintion to the xen_boot itself. + +Signed-off-by: Michael Chang +--- + grub-core/loader/arm64/xen_boot.c | 50 +++++++++++++++++++++++++++++++ + 1 file changed, 50 insertions(+) + +diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c +index 26e1472c9..b82a2db89 100644 +--- a/grub-core/loader/arm64/xen_boot.c ++++ b/grub-core/loader/arm64/xen_boot.c +@@ -84,6 +84,56 @@ static int loaded; + static struct xen_boot_binary *xen_hypervisor; + static struct xen_boot_binary *module_head; + ++/* The function is exported by grub-core/loader/arm64/linux.c that is not built ++ * because we use PE entry provided by grub-core/loader/arm64/efi/linux.c ++ */ ++static bool initrd_use_loadfile2 = false; ++ ++grub_err_t ++grub_arch_efi_linux_load_image_header (grub_file_t file, ++ struct linux_arch_kernel_header * lh) ++{ ++ grub_file_seek (file, 0); ++ if (grub_file_read (file, lh, sizeof (*lh)) < (grub_ssize_t) sizeof (*lh)) ++ return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read Linux image header"); ++ ++ 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); ++ ++ /* ++ * The PE/COFF spec permits the COFF header to appear anywhere in the file, so ++ * we need to double check whether it was where we expected it, and if not, we ++ * must load it from the correct offset into the pe_image_header field of ++ * struct linux_arch_kernel_header. ++ */ ++ if ((grub_uint8_t *) lh + lh->hdr_offset != (grub_uint8_t *) &lh->pe_image_header) ++ { ++ if (grub_file_seek (file, lh->hdr_offset) == (grub_off_t) -1 ++ || grub_file_read (file, &lh->pe_image_header, ++ sizeof (struct grub_pe_image_header)) ++ != sizeof (struct grub_pe_image_header)) ++ return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header"); ++ } ++ ++ /* ++ * Linux kernels built for any architecture are guaranteed to support the ++ * LoadFile2 based initrd loading protocol if the image version is >= 1. ++ */ ++ if (lh->pe_image_header.optional_header.major_image_version >= 1) ++ initrd_use_loadfile2 = true; ++ else ++ initrd_use_loadfile2 = false; ++ ++ grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n", ++ initrd_use_loadfile2 ? "en" : "dis"); ++ ++ return GRUB_ERR_NONE; ++} ++ + static __inline grub_addr_t + xen_boot_address_align (grub_addr_t start, grub_size_t align) + { +-- +2.41.0 + diff --git a/0083-AUDIT-0-http-boot-tracker-bug.patch b/0002-AUDIT-0-http-boot-tracker-bug.patch similarity index 71% rename from 0083-AUDIT-0-http-boot-tracker-bug.patch rename to 0002-AUDIT-0-http-boot-tracker-bug.patch index ef3e67b7f3ae4483fccfcd9707bee1f794b9c013..7935f3fcc5c1d7cbad4eea8c196dedb5b2b61079 100644 --- a/0083-AUDIT-0-http-boot-tracker-bug.patch +++ b/0002-AUDIT-0-http-boot-tracker-bug.patch @@ -1,4 +1,4 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From b5c3492f31a98f5ef0f9bec2c0665ad0b71ad5cb Mon Sep 17 00:00:00 2001 From: Sebastian Krahmer Date: Tue, 28 Nov 2017 17:24:38 +0800 Subject: [PATCH] AUDIT-0: http boot tracker bug @@ -15,17 +15,17 @@ This is no big issue for pure http boot, since its going to execute an untrusted kernel anyway, but it will break trusted boot scenarios, where only signed code is allowed to be executed. +v2: Fix GCC 13 build failure (bsc#1201089) + Signed-off-by: Michael Chang --- grub-core/net/efi/net.c | 4 +++- grub-core/net/http.c | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -index 86bce6535d3..4bb308026ce 100644 --- a/grub-core/net/efi/net.c +++ b/grub-core/net/efi/net.c -@@ -645,8 +645,10 @@ grub_efihttp_chunk_read (grub_file_t file, char *buf, +@@ -654,8 +654,10 @@ rd = efi_net_interface (read, file, chunk, sz); @@ -37,21 +37,17 @@ index 86bce6535d3..4bb308026ce 100644 if (buf) { -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index 12a2632ea55..b52b558d631 100644 --- a/grub-core/net/http.c +++ b/grub-core/net/http.c -@@ -31,7 +31,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); - - enum - { -- HTTP_PORT = 80 -+ HTTP_PORT = 80, -+ HTTP_MAX_CHUNK_SIZE = 0x80000000 - }; +@@ -30,6 +30,7 @@ + GRUB_MOD_LICENSE ("GPLv3+"); + #define HTTP_PORT ((grub_uint16_t) 80) ++#define HTTP_MAX_CHUNK_SIZE GRUB_INT_MAX -@@ -78,6 +79,8 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len) + typedef struct http_data + { +@@ -82,6 +83,8 @@ if (data->in_chunk_len == 2) { data->chunk_rem = grub_strtoul (ptr, 0, 16); diff --git a/0002-Add-grub_disk_write_tail-helper-function.patch b/0002-Add-grub_disk_write_tail-helper-function.patch new file mode 100644 index 0000000000000000000000000000000000000000..2b178ee9f72d06be18b8747a8045206b2303d6df --- /dev/null +++ b/0002-Add-grub_disk_write_tail-helper-function.patch @@ -0,0 +1,53 @@ +From c0d00403a297d6023eab6189ba87dc8a3f6d1e85 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Mon, 7 Feb 2022 20:44:40 +0800 +Subject: [PATCH 2/5] Add grub_disk_write_tail helper function + +This helps in writing data to partition where the end of buffer is +aligned to end of partition. + +Signed-off-by: Michael Chang +--- + grub-core/lib/disk.c | 18 ++++++++++++++++++ + include/grub/disk.h | 3 +++ + 2 files changed, 21 insertions(+) + +--- a/grub-core/lib/disk.c ++++ b/grub-core/lib/disk.c +@@ -52,6 +52,24 @@ + } + + grub_err_t ++grub_disk_write_tail (grub_disk_t disk, grub_size_t size, const void *buf) ++{ ++ grub_partition_t part; ++ grub_disk_addr_t sector; ++ grub_off_t offset; ++ ++ if (!disk->partition) ++ return GRUB_ERR_NONE; ++ ++ part = disk->partition; ++ sector = part->len; ++ sector -= (size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS; ++ offset = size & (GRUB_DISK_SECTOR_SIZE - 1); ++ ++ return grub_disk_write (disk, sector, offset, size, buf); ++} ++ ++grub_err_t + grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector, + grub_off_t offset, grub_size_t size, const void *buf) + { +--- a/include/grub/disk.h ++++ b/include/grub/disk.h +@@ -252,6 +252,9 @@ + grub_off_t offset, + grub_size_t size, + void *buf); ++grub_err_t grub_disk_write_tail (grub_disk_t disk, ++ grub_size_t size, ++ const void *buf); + grub_err_t grub_disk_write (grub_disk_t disk, + grub_disk_addr_t sector, + grub_off_t offset, diff --git a/0002-Arm-check-for-the-PE-magic-for-the-compiled-arch.patch b/0002-Arm-check-for-the-PE-magic-for-the-compiled-arch.patch new file mode 100644 index 0000000000000000000000000000000000000000..23c9e08de24320fdb5ee2d60d2f63585d2224708 --- /dev/null +++ b/0002-Arm-check-for-the-PE-magic-for-the-compiled-arch.patch @@ -0,0 +1,57 @@ +From 337b3d963d28b3544e8817428fb68ca559613a39 Mon Sep 17 00:00:00 2001 +From: Peter Jones +Date: Thu, 9 Sep 2021 10:59:28 -0400 +Subject: [PATCH 2/2] Arm: check for the PE magic for the compiled arch + +In "arm64: Fix EFI loader kernel image allocation", Ben fixed the kernel +alignment to match the alignment given in the PE header. In doing so, a +check for valid PE magic was added, which was hard-coded to the value +seen on Aarch64 (GRUB_PE32_PE64_MAGIC). + +Unfortunately, this code is shared between 64-bit and 32-bit, and so +that value broke 32-bit Arm systems. + +This patch adds a constant definition for GRUB_PE32_PEXX_MAGIC, which is +either GRUB_PE32_PE64_MAGIC or GRUB_PE32_PE32_MAGIC, depending on which +platform is being built, and uses it in the header magic check. + +Resolves: rhbz#2000756 + +Signed-off-by: Peter Jones +--- + grub-core/loader/arm64/efi/linux.c | 2 +- + include/grub/arm/linux.h | 1 + + include/grub/arm64/linux.h | 1 + + 3 files changed, 3 insertions(+), 1 deletion(-) + +--- a/grub-core/loader/arm64/efi/linux.c ++++ b/grub-core/loader/arm64/efi/linux.c +@@ -376,7 +376,7 @@ + + pe = (void *)((unsigned long)kernel + lh->hdr_offset); + +- if (pe->opt.magic != GRUB_PE32_PE64_MAGIC) ++ if (pe->opt.magic != GRUB_PE32_PEXX_MAGIC) + return grub_error(GRUB_ERR_BAD_OS, "Invalid PE optional header magic"); + + *total_size = pe->opt.image_size; +--- a/include/grub/arm/linux.h ++++ b/include/grub/arm/linux.h +@@ -33,6 +33,7 @@ + }; + + #if defined(__arm__) ++# define GRUB_PE32_PEXX_MAGIC GRUB_PE32_PE32_MAGIC + # define grub_armxx_linux_pe_header grub_arm_linux_pe_header + #endif + +--- a/include/grub/arm64/linux.h ++++ b/include/grub/arm64/linux.h +@@ -33,6 +33,7 @@ + + #if defined(__aarch64__) + # define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE ++# define GRUB_PE32_PEXX_MAGIC GRUB_PE32_PE64_MAGIC + # define grub_armxx_linux_pe_header grub_arm64_linux_pe_header + #endif + diff --git a/0002-Fix-race-in-EFI-validation.patch b/0002-Fix-race-in-EFI-validation.patch new file mode 100644 index 0000000000000000000000000000000000000000..4a8bc7cb61b422709084309936f63d4e4aa3b196 --- /dev/null +++ b/0002-Fix-race-in-EFI-validation.patch @@ -0,0 +1,92 @@ +From e72dcb40356f56efd86ab88c2f5cb7411d1e898b Mon Sep 17 00:00:00 2001 +From: Matthew Garrett +Date: Tue, 14 Jul 2015 16:58:51 -0700 +Subject: [PATCH 02/11] Fix race in EFI validation + +--- + grub-core/loader/i386/efi/linux.c | 40 +++++++------------------------ + 1 file changed, 9 insertions(+), 31 deletions(-) + +diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c +index 06814cae3..1e09c88ab 100644 +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -154,7 +154,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + grub_file_t file = 0; + struct linux_i386_kernel_header lh; + grub_ssize_t len, start, filelen; +- void *kernel; ++ void *kernel = NULL; + grub_err_t err; + + grub_dl_ref (my_mod); +@@ -185,10 +185,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- grub_file_seek (file, 0); +- +- grub_free(kernel); +- + params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); + + if (! params) +@@ -199,13 +195,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + + grub_memset (params, 0, 16384); + +- if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) +- { +- if (!grub_errno) +- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), +- argv[0]); +- goto fail; +- } ++ grub_memcpy (&lh, kernel, sizeof (lh)); + + if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) + { +@@ -271,26 +261,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + goto fail; + } + +- if (grub_file_seek (file, start) == (grub_off_t) -1) +- { +- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), +- argv[0]); +- goto fail; +- } +- +- if (grub_file_read (file, kernel_mem, len) != len && !grub_errno) +- { +- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), +- argv[0]); +- } +- +- if (grub_errno == GRUB_ERR_NONE) +- { +- grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); +- loaded = 1; +- lh.code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem; +- } ++ grub_memcpy (kernel_mem, (char *)kernel + start, len); ++ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); ++ loaded=1; + ++ lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; + /* Grub linuxefi erroneously initialize linux's boot_params with non-zero values. (bsc#1025563) + + From https://www.kernel.org/doc/Documentation/x86/boot.txt: +@@ -307,6 +282,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + if (file) + grub_file_close (file); + ++ if (kernel) ++ grub_free (kernel); ++ + if (grub_errno != GRUB_ERR_NONE) + { + grub_dl_unref (my_mod); +-- +2.31.1 + diff --git a/0002-Mark-environmet-blocks-as-used-for-image-embedding.patch b/0002-Mark-environmet-blocks-as-used-for-image-embedding.patch new file mode 100644 index 0000000000000000000000000000000000000000..b125335c47deae5330f15d26d85799161309eef0 --- /dev/null +++ b/0002-Mark-environmet-blocks-as-used-for-image-embedding.patch @@ -0,0 +1,57 @@ +From f01314a822dbe9ad39b2f7d0f3717ef6e4c24f4a Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Fri, 15 Apr 2022 21:45:04 +0800 +Subject: [PATCH 2/2] Mark environmet blocks as used for image embedding. + +Now that grub will attempt to use full btrfs bootloader area, the +embedded image could have overlapped with environment blocks if it's +size grows too much. Let's define a dedicated area for environment +blocks to the used block mappings for the embedding process so it can be +skipped. + +Signed-off-by: Michael Chang +--- + grub-core/fs/btrfs.c | 3 ++- + include/grub/fs.h | 2 ++ + util/grub-editenv.c | 2 +- + 3 files changed, 5 insertions(+), 2 deletions(-) + +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -2637,7 +2637,7 @@ + + static const struct { + struct embed_region available; +- struct embed_region used[6]; ++ struct embed_region used[7]; + } btrfs_head = { + .available = {0, GRUB_DISK_KiB_TO_SECTORS (1024)}, /* The first 1 MiB. */ + .used = { +@@ -2645,6 +2645,7 @@ + {GRUB_DISK_KiB_TO_SECTORS (64) - 1, 1}, /* Overflow guard. */ + {GRUB_DISK_KiB_TO_SECTORS (64), GRUB_DISK_KiB_TO_SECTORS (4)}, /* 4 KiB superblock. */ + {GRUB_DISK_KiB_TO_SECTORS (68), 1}, /* Overflow guard. */ ++ {GRUB_DISK_KiB_TO_SECTORS (ENV_BTRFS_OFFSET) - 1, 3}, /* Environment Block. */ + {GRUB_DISK_KiB_TO_SECTORS (1024) - 1, 1}, /* Overflow guard. */ + {0, 0} /* Array terminator. */ + } +--- a/include/grub/fs.h ++++ b/include/grub/fs.h +@@ -128,4 +128,6 @@ + + grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device); + ++#define ENV_BTRFS_OFFSET (256) ++ + #endif /* ! GRUB_FS_HEADER */ +--- a/util/grub-editenv.c ++++ b/util/grub-editenv.c +@@ -128,7 +128,7 @@ + int offset; + int size; + } fs_envblk_spec[] = { +- { "btrfs", 256 * 1024, GRUB_DISK_SECTOR_SIZE }, ++ { "btrfs", ENV_BTRFS_OFFSET * 1024, GRUB_DISK_SECTOR_SIZE }, + { NULL, 0, 0 } + }; + diff --git a/0002-Restrict-cryptsetup-key-file-permission-for-better-s.patch b/0002-Restrict-cryptsetup-key-file-permission-for-better-s.patch new file mode 100644 index 0000000000000000000000000000000000000000..9d9ea21e8500e3aff97f3eb09722b7c48b235509 --- /dev/null +++ b/0002-Restrict-cryptsetup-key-file-permission-for-better-s.patch @@ -0,0 +1,59 @@ +From 9f18541245858f53fea72d8d60304f9015d88b5f Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Fri, 17 Mar 2023 22:00:23 +0800 +Subject: [PATCH 2/2] Restrict cryptsetup key file permission for better + security + +GRUB's default permission 777 for concatenated initrd files was too +permissive for the cryptsetup key file, causing a complaint from +systemd-cryptsetup during boot. This commit replaces the 0777 permission +with a more secure 0400 permission for the key file. + +Signed-off-by: Michael Chang +--- + grub-core/loader/linux.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/grub-core/loader/linux.c ++++ b/grub-core/loader/linux.c +@@ -32,6 +32,7 @@ + char *buf; + char *newc_name; + grub_off_t size; ++ grub_uint32_t mode; + }; + + struct dir +@@ -203,6 +204,7 @@ + grub_memcpy (comp->buf, buf, bufsz); + initrd_ctx->nfiles++; + comp->size = bufsz; ++ comp->mode = 0100400; + if (grub_add (initrd_ctx->size, comp->size, + &initrd_ctx->size)) + goto overflow; +@@ -272,6 +274,7 @@ + grub_initrd_close (initrd_ctx); + return grub_errno; + } ++ initrd_ctx->components[i].mode = 0100777; + name_len = grub_strlen (initrd_ctx->components[i].newc_name) + 1; + if (grub_add (initrd_ctx->size, + ALIGN_UP (sizeof (struct newc_head) + name_len, 4), +@@ -374,6 +377,7 @@ + if (initrd_ctx->components[i].newc_name) + { + grub_size_t dir_size; ++ grub_uint32_t mode = initrd_ctx->components[i].mode; + + if (insert_dir (initrd_ctx->components[i].newc_name, &root, ptr, + &dir_size)) +@@ -385,7 +389,7 @@ + ptr += dir_size; + ptr = make_header (ptr, initrd_ctx->components[i].newc_name, + grub_strlen (initrd_ctx->components[i].newc_name) + 1, +- 0100777, ++ mode, + initrd_ctx->components[i].size); + newc = 1; + } diff --git a/0002-Restrict-file-access-on-cryptodisk-print.patch b/0002-Restrict-file-access-on-cryptodisk-print.patch new file mode 100644 index 0000000000000000000000000000000000000000..463904f92a164c7ad385fe9b1662e6ee90f5a789 --- /dev/null +++ b/0002-Restrict-file-access-on-cryptodisk-print.patch @@ -0,0 +1,197 @@ +From 912384e63c1e3b6aa9d90effb71cd535a17da1e2 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Sat, 18 Nov 2023 19:02:31 +0800 +Subject: [PATCH 2/4] Restrict file access on cryptodisk print + +When the encrypted partition is automatically unlocked by TPM, granting +access to the system upon validation of its known good state, there's a +potential vulnerability. Grub gains access to file systems that were +previously inaccessible to the public, enabling certain commands from +the grub console to print content. This arises due to grub lacking +restrictions similar to those imposed by password authentication, which +typically occurs before privileged access is granted. + +Although the automatic unlocking process ensures system integrity and a +secure environment for grub to operate in, it doesn't directly address +the issue of authentication for viewing encrypted partition content. + +This commit addresses this security loophole by implementing a file +filter upon adding a TPM key. The newly added file filter will +specifically verify if the disk is encrypted, denying access and +returning an "Access Denied: prohibited to view encrypted data" error +message to alert the user. + +Since the policy to filter out unwanted commands from leaking encrypted +content is irreversible, it is advisable to make the loaded module +persistent to prevent its removal. + +This enhancement aims to bolster security measures and prevent +unauthorized access to encrypted data. + +Signed-Off-by Michael Chang +--- + grub-core/commands/crypttab.c | 35 ++++++++++++++++++++++++++++++++++- + grub-core/disk/diskfilter.c | 35 +++++++++++++++++++++++++++++++++++ + include/grub/disk.h | 10 ++++++++++ + include/grub/file.h | 1 + + 4 files changed, 80 insertions(+), 1 deletion(-) + +diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c +index 9397bede9..d3acc4b59 100644 +--- a/grub-core/commands/crypttab.c ++++ b/grub-core/commands/crypttab.c +@@ -6,11 +6,39 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + + grub_crypto_key_list_t *cryptokey_lst; + ++static grub_file_t ++grub_nocat_open (grub_file_t io, enum grub_file_type type) ++{ ++ grub_disk_t disk; ++ ++ /* Network device */ ++ if (!io->device->disk) ++ return io; ++ ++ disk = io->device->disk; ++ ++ if (grub_disk_is_crypto (disk)) ++ { ++ switch (type & GRUB_FILE_TYPE_MASK) ++ { ++ case GRUB_FILE_TYPE_CAT: ++ case GRUB_FILE_TYPE_HEXCAT: ++ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to view encrypted data")); ++ return NULL; ++ default: ++ break; ++ } ++ } ++ ++ return io; ++} ++ + grub_err_t + grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey) + { +@@ -48,7 +76,11 @@ grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key + } + + if (is_tpmkey >= 0) +- cur->is_tpmkey = is_tpmkey; ++ { ++ cur->is_tpmkey = is_tpmkey; ++ if (is_tpmkey) ++ grub_file_filter_register (GRUB_FILE_FILTER_NOCAT, grub_nocat_open); ++ } + + if (!cur->name) + { +@@ -121,6 +153,7 @@ GRUB_MOD_INIT(crypttab) + { + cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry, + N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description")); ++ grub_dl_set_persistent (mod); + } + + GRUB_MOD_FINI(crypttab) +diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c +index 5c5fabe1a..b0c1c880d 100644 +--- a/grub-core/disk/diskfilter.c ++++ b/grub-core/disk/diskfilter.c +@@ -558,6 +558,39 @@ find_lv (const char *name) + return NULL; + } + ++static int ++grub_diskfilter_has_cryptodisk (const struct grub_diskfilter_lv *lv) ++{ ++ struct grub_diskfilter_pv *pv; ++ ++ if (!lv) ++ return 0; ++ ++ if (lv->vg->pvs) ++ for (pv = lv->vg->pvs; pv; pv = pv->next) ++ { ++ if (!pv->disk) ++ { ++ grub_dprintf ("diskfilter", _("Couldn't find physical volume `%s'." ++ " Some modules may be missing from core image."), ++ pv->name); ++ continue; ++ } ++ ++ switch (pv->disk->dev->id) ++ { ++ case GRUB_DISK_DEVICE_CRYPTODISK_ID: ++ return 1; ++ case GRUB_DISK_DEVICE_DISKFILTER_ID: ++ return grub_diskfilter_has_cryptodisk (pv->disk->data); ++ default: ++ break; ++ } ++ } ++ ++ return 0; ++} ++ + static grub_err_t + grub_diskfilter_open (const char *name, grub_disk_t disk) + { +@@ -589,6 +622,8 @@ grub_diskfilter_open (const char *name, grub_disk_t disk) + + disk->total_sectors = lv->size; + disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE; ++ disk->is_crypto_diskfilter = grub_diskfilter_has_cryptodisk (lv); ++ + return 0; + } + +diff --git a/include/grub/disk.h b/include/grub/disk.h +index 3b3db6222..63982f16c 100644 +--- a/include/grub/disk.h ++++ b/include/grub/disk.h +@@ -147,6 +147,8 @@ struct grub_disk + + /* Device-specific data. */ + void *data; ++ ++ int is_crypto_diskfilter; + }; + typedef struct grub_disk *grub_disk_t; + +@@ -314,4 +316,12 @@ void grub_mdraid1x_fini (void); + void grub_diskfilter_fini (void); + #endif + ++static inline int ++grub_disk_is_crypto (grub_disk_t disk) ++{ ++ return ((disk->is_crypto_diskfilter || ++ disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) ? ++ 1 : 0); ++} ++ + #endif /* ! GRUB_DISK_HEADER */ +diff --git a/include/grub/file.h b/include/grub/file.h +index fde58f0fa..fcfd32ce2 100644 +--- a/include/grub/file.h ++++ b/include/grub/file.h +@@ -185,6 +185,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook); + /* Filters with lower ID are executed first. */ + typedef enum grub_file_filter_id + { ++ GRUB_FILE_FILTER_NOCAT, + GRUB_FILE_FILTER_VERIFY, + GRUB_FILE_FILTER_GZIO, + GRUB_FILE_FILTER_XZIO, +-- +2.42.1 + diff --git a/0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch b/0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch deleted file mode 100644 index 4187765fb6bd501b572e08283f95550b6989a6af..0000000000000000000000000000000000000000 --- a/0002-Revert-templates-Properly-disable-the-os-prober-by-d.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Fri, 11 Jun 2021 12:10:54 +0200 -Subject: [PATCH] Revert "templates: Properly disable the os-prober by default" - -This reverts commit 54e0a1bbf1e9106901a557195bb35e5e20fb3925. ---- - util/grub-mkconfig.in | 5 +---- - util/grub.d/30_os-prober.in | 8 ++++---- - 2 files changed, 5 insertions(+), 8 deletions(-) - -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index f8cbb8d7a2b..d3e879b8e5c 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -140,9 +140,6 @@ GRUB_DEVICE_PARTUUID="`${grub_probe} --device ${GRUB_DEVICE} --target=partuuid 2 - GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`" - GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true - --# Disable os-prober by default due to security reasons. --GRUB_DISABLE_OS_PROBER="true" -- - # Filesystem for the device containing our userland. Used for stuff like - # choosing Hurd filesystem module. - GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`" -@@ -204,7 +201,6 @@ export GRUB_DEVICE \ - GRUB_DEVICE_PARTUUID \ - GRUB_DEVICE_BOOT \ - GRUB_DEVICE_BOOT_UUID \ -- GRUB_DISABLE_OS_PROBER \ - GRUB_FS \ - GRUB_FONT \ - GRUB_PRELOAD_MODULES \ -@@ -246,6 +242,7 @@ export GRUB_DEFAULT \ - GRUB_BACKGROUND \ - GRUB_THEME \ - GRUB_GFXPAYLOAD_LINUX \ -+ GRUB_DISABLE_OS_PROBER \ - GRUB_INIT_TUNE \ - GRUB_SAVEDEFAULT \ - GRUB_ENABLE_CRYPTODISK \ -diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in -index 94622481284..80685b15f4d 100644 ---- a/util/grub.d/30_os-prober.in -+++ b/util/grub.d/30_os-prober.in -@@ -26,8 +26,8 @@ export TEXTDOMAINDIR="@localedir@" - - . "$pkgdatadir/grub-mkconfig_lib" - --if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then -- grub_warn "$(gettext_printf "os-prober will not be executed to detect other bootable partitions.\nSystems on them will not be added to the GRUB boot configuration.\nCheck GRUB_DISABLE_OS_PROBER documentation entry.")" -+if [ "x${GRUB_DISABLE_OS_PROBER}" = "xfalse" ]; then -+ gettext_printf "os-prober will not be executed to detect other bootable partitions.\nSystems on them will not be added to the GRUB boot configuration.\nCheck GRUB_DISABLE_OS_PROBER documentation entry.\n" - exit 0 - fi - -@@ -36,12 +36,12 @@ if ! command -v os-prober > /dev/null || ! command -v linux-boot-prober > /dev/n - exit 0 - fi - --grub_warn "$(gettext_printf "os-prober will be executed to detect other bootable partitions.\nIt's output will be used to detect bootable binaries on them and create new boot entries.")" -- - OSPROBED="`os-prober | tr ' ' '^' | paste -s -d ' '`" - if [ -z "${OSPROBED}" ] ; then - # empty os-prober output, nothing doing - exit 0 -+else -+ grub_warn "$(gettext_printf "os-prober was executed to detect other bootable partitions.\nIt's output will be used to detect bootable binaries on them and create new boot entries.")" - fi - - osx_entry() { diff --git a/0002-arm64-make-sure-fdt-has-address-cells-and-size-cells.patch b/0002-arm64-make-sure-fdt-has-address-cells-and-size-cells.patch new file mode 100644 index 0000000000000000000000000000000000000000..d521887a9443aeb544705c731b9d85fd1b3bf1dc --- /dev/null +++ b/0002-arm64-make-sure-fdt-has-address-cells-and-size-cells.patch @@ -0,0 +1,40 @@ +From e27acddebd30175587155613042abffd2e9a5de8 Mon Sep 17 00:00:00 2001 +From: Mark Salter +Date: Mon, 17 Apr 2017 08:44:29 -0400 +Subject: [PATCH 2/9] 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(-) + +--- a/grub-core/loader/arm64/efi/linux.c ++++ b/grub-core/loader/arm64/efi/linux.c +@@ -99,7 +99,21 @@ + + 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; diff --git a/0002-cmdline-Provide-cmdline-functions-as-module.patch b/0002-cmdline-Provide-cmdline-functions-as-module.patch new file mode 100644 index 0000000000000000000000000000000000000000..308721e52a155d197ab41d555bb8998c72fffefa --- /dev/null +++ b/0002-cmdline-Provide-cmdline-functions-as-module.patch @@ -0,0 +1,47 @@ +From 42cb0ebbffd660608612f9e32150a6596c6933c4 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Mon, 17 Aug 2020 17:25:56 +0800 +Subject: [PATCH 2/2] cmdline: Provide cmdline functions as module + +The command line processing is needed by many loader modules, hence we should +make it a sharable one rather than belonging to linux loader. This can cut the +dependency to linux module among multiple loaders like multiboot linuxefi and +so on to make custom boot image much more flexible to compose. + +Signed-off-by: Michael Chang +--- + grub-core/Makefile.core.def | 6 +++++- + grub-core/lib/cmdline.c | 3 +++ + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1860,7 +1860,6 @@ + x86_64_efi = loader/efi/linux.c; + emu = loader/emu/linux.c; + common = loader/linux.c; +- common = lib/cmdline.c; + }; + + module = { +@@ -2611,3 +2610,8 @@ + efi = commands/bli.c; + enable = efi; + }; ++ ++module = { ++ name = cmdline; ++ common = lib/cmdline.c; ++}; +--- a/grub-core/lib/cmdline.c ++++ b/grub-core/lib/cmdline.c +@@ -19,6 +19,9 @@ + + #include + #include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); + + static unsigned int check_arg (char *c, int *has_space) + { diff --git a/0002-cryptodisk-Fallback-to-passphrase.patch b/0002-cryptodisk-Fallback-to-passphrase.patch new file mode 100644 index 0000000000000000000000000000000000000000..43e78e2ba669409084fa97b987e5124abeb4d87a --- /dev/null +++ b/0002-cryptodisk-Fallback-to-passphrase.patch @@ -0,0 +1,41 @@ +From 7cc578baf26986c2badce998125b429a2aeb4d33 Mon Sep 17 00:00:00 2001 +From: Patrick Colp +Date: Sun, 30 Jul 2023 12:58:18 -0700 +Subject: [PATCH 2/4] cryptodisk: Fallback to passphrase + +If a protector is specified, but it fails to unlock the disk, fall back +to asking for the passphrase. However, an error was set indicating that +the protector(s) failed. Later code (e.g., LUKS code) fails as +`grub_errno` is now set. Print the existing errors out first, before +proceeding with the passphrase. + +Signed-off-by: Patrick Colp +--- + grub-core/disk/cryptodisk.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index 6620fca00..cf37a0934 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -1191,11 +1191,16 @@ grub_cryptodisk_scan_device_real (const char *name, + source->name, source->partition != NULL ? "," : "", + part != NULL ? part : N_("UNKNOWN"), dev->uuid); + grub_free (part); +- goto error; + } + + if (!cargs->key_len) + { ++ if (grub_errno) ++ { ++ grub_print_error (); ++ grub_errno = GRUB_ERR_NONE; ++ } ++ + /* Get the passphrase from the user, if no key data. */ + askpass = 1; + part = grub_partition_get_name (source->partition); +-- +2.35.3 + diff --git a/0002-discard-cached-key-before-entering-grub-shell-and-ed.patch b/0002-discard-cached-key-before-entering-grub-shell-and-ed.patch new file mode 100644 index 0000000000000000000000000000000000000000..2f4a07a19301593e86513039917dd24587fff824 --- /dev/null +++ b/0002-discard-cached-key-before-entering-grub-shell-and-ed.patch @@ -0,0 +1,88 @@ +From 2271da7522d8406c528d2a9079d810e140f8041a Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Fri, 3 Feb 2023 19:40:31 +0800 +Subject: [PATCH 2/2] discard cached key before entering grub shell and editor + mode + +The cached key is cleared in case of anyone poking around it by means of +the interactive shell offerings. + +Signed-off-by: Michael Chang +--- + grub-core/commands/crypttab.c | 16 ++++++++++++++++ + grub-core/normal/main.c | 2 ++ + grub-core/normal/menu_entry.c | 3 +++ + include/grub/crypttab.h | 2 ++ + 4 files changed, 23 insertions(+) + +--- a/grub-core/commands/crypttab.c ++++ b/grub-core/commands/crypttab.c +@@ -53,6 +53,22 @@ + return GRUB_ERR_NONE; + } + ++void ++grub_initrd_discard_key (void) ++{ ++ struct grub_key_publisher *cur, *nxt; ++ ++ FOR_LIST_ELEMENTS_SAFE (cur, nxt, kpuber) ++ { ++ grub_list_remove (GRUB_AS_LIST (cur)); ++ grub_memset (cur->key, 0, cur->key_len); ++ grub_free (cur->name); ++ grub_free (cur->path); ++ grub_free (cur->key); ++ grub_free (cur); ++ } ++} ++ + static grub_err_t + grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)), + int argc, char **argv) +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -37,6 +37,7 @@ + #ifdef GRUB_MACHINE_IEEE1275 + #include + #endif ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -478,6 +479,7 @@ + return; + } + ++ grub_initrd_discard_key (); + grub_normal_reader_init (nested); + + while (1) +--- a/grub-core/normal/menu_entry.c ++++ b/grub-core/normal/menu_entry.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + enum update_mode + { +@@ -1262,6 +1263,8 @@ + return; + } + ++ grub_initrd_discard_key(); ++ + screen = make_screen (entry); + if (! screen) + return; +--- a/include/grub/crypttab.h ++++ b/include/grub/crypttab.h +@@ -19,4 +19,6 @@ + grub_err_t + grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path); + ++void ++grub_initrd_discard_key (void); + #endif /* ! GRUB_CRYPTTAB_HEADER */ diff --git a/0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch b/0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch new file mode 100644 index 0000000000000000000000000000000000000000..92ea1dedda10cf6ac9afac9fcf251ebaa2c4e5c1 --- /dev/null +++ b/0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch @@ -0,0 +1,373 @@ +From 9e61624db77e5073961126457f599bc70e877fd1 Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Tue, 15 Mar 2022 15:59:41 -0400 +Subject: [PATCH 2/4] ieee1275/ofpath: enable NVMeoF logical device translation + +This patch add code to enable the translation of logical devices to the of NVMeoFC paths. +--- + grub-core/osdep/linux/ofpath.c | 260 +++++++++++++++++++++++++++++++-- + include/grub/util/ofpath.h | 29 ++++ + 2 files changed, 280 insertions(+), 9 deletions(-) + +diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c +index 89beceef4..212782d3f 100644 +--- a/grub-core/osdep/linux/ofpath.c ++++ b/grub-core/osdep/linux/ofpath.c +@@ -137,7 +137,7 @@ trim_newline (char *path) + *end-- = '\0'; + } + +-#define MAX_DISK_CAT 64 ++#define MAX_DISK_CAT 512 + + static char * + find_obppath (const char *sysfs_path_orig) +@@ -313,6 +313,69 @@ get_basename(char *p) + return ret; + } + ++ ++void ++add_filename_to_pile(char *filename, struct ofpath_files_list_root* root){ ++ struct ofpath_files_list_node* file; ++ ++ file = malloc(sizeof(struct ofpath_files_list_node)); ++ ++ file->filename = filename; ++ ++ if(root->first == NULL){ ++ root->items = 1; ++ root->first = file; ++ file->next = NULL; ++ } else { ++ root->items++; ++ file->next = root->first; ++ root->first = file; ++ } ++} ++ ++ ++void ++find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth){ ++ struct dirent *ep; ++ struct stat statbuf; ++ DIR *dp; ++ ++ if(depth > max_depth){ ++ return; ++ } ++ ++ if((dp = opendir(directory)) == NULL){ ++ ++ return; ++ } ++ ++ while((ep = readdir(dp)) != NULL){ ++ ++ char* full_path = malloc(1024*sizeof(char)); ++ snprintf(full_path,1024,"%s/%s",directory,ep->d_name); ++ ++ lstat(full_path,&statbuf); ++ ++ if(S_ISLNK(statbuf.st_mode)){ ++ ++ continue; ++ } ++ ++ if(!strcmp(ep->d_name,".") || !strcmp(ep->d_name,"..")){ ++ continue; ++ } ++ ++ if(!strcmp(ep->d_name,filename)){ ++ add_filename_to_pile(full_path, root); ++ } ++ ++ find_file(filename, full_path, root, max_depth, depth+1); ++ ++ } ++ closedir(dp); ++} ++ ++ + static char * + of_path_of_vdisk(const char *sys_devname __attribute__((unused)), + const char *device, +@@ -351,7 +414,142 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi + return ret; + } + +-#ifdef __sparc__ ++char* ++of_find_fc_host(char* host_wwpn){ ++ ++ FILE* fp; ++ char *buf; ++ char portname_filename[sizeof("port_name")] = "port_name"; ++ char devices_path[sizeof("/sys/devices")] = "/sys/devices"; ++ ++ struct ofpath_files_list_root* portnames_file_list; ++ ++ portnames_file_list=malloc(sizeof(portnames_file_list)); ++ portnames_file_list->items=0; ++ portnames_file_list->first=NULL; ++ ++ find_file(portname_filename, devices_path, portnames_file_list, 10, 0); ++ ++ struct ofpath_files_list_node* node = portnames_file_list->first; ++ while(node != NULL){ ++ fp = fopen(node->filename,"r"); ++ buf = malloc(sizeof(char)*512); ++ fscanf(fp, "%s", buf); ++ fclose(fp); ++ if((strcmp(buf,host_wwpn) == 0) && grub_strstr(node->filename, "fc_host")){ ++ return node->filename; ++ } ++ node = node->next; ++ } ++ ++ return NULL; ++} ++ ++void ++of_path_get_nvmeof_adapter_info(char* sysfs_path, ++ struct ofpath_nvmeof_info* nvmeof_info){ ++ ++ FILE *fp; ++ char *buf, *buf2, *buf3; ++ ++ nvmeof_info->host_wwpn = malloc(sizeof(char)*256); ++ nvmeof_info->target_wwpn = malloc(sizeof(char)*256); ++ nvmeof_info->nqn = malloc(sizeof(char)*256); ++ ++ buf = malloc(sizeof(char)*512); ++ snprintf(buf,512,"%s/subsysnqn",sysfs_path); ++ fp = fopen(buf,"r"); ++ fscanf(fp, "%s", nvmeof_info->nqn); ++ fclose(fp); ++ ++ snprintf(buf,512,"%s/cntlid",sysfs_path); ++ fp = fopen(buf,"r"); ++ fscanf(fp, "%u", &(nvmeof_info->cntlid)); ++ fclose(fp); ++ ++ //snprintf(buf,512,"%s/nsid",sysfs_path); ++ //fp = fopen(buf,"r"); ++ //fscanf(fp, "%u", &(nvmeof_info->nsid)); ++ //fclose(fp); ++ ++ snprintf(buf,512,"%s/address",sysfs_path); ++ fp = fopen(buf,"r"); ++ buf2 = malloc(sizeof(char)*512); ++ fscanf(fp, "%s", buf2); ++ fclose(fp); ++ ++ nvmeof_info->host_wwpn = strrchr(buf2,'-')+1; ++ ++ buf3=strchr(buf2,'-')+1; ++ buf3=strchr(buf3,'-')+1; ++ nvmeof_info->target_wwpn = buf3; ++ buf3 = strchr(nvmeof_info->target_wwpn,','); ++ *buf3 = '\0'; ++ ++ ++ free(buf); ++ ++ return; ++} ++ ++#define MAX_NVME_NSID_DIGITS 6 ++ ++static char * ++of_path_get_nvme_controller_name_node(const char* devname) ++{ ++ char *controller_node, *end; ++ ++ controller_node = strdup(devname); ++ ++ end = grub_strchr(controller_node+1, 'n'); ++ ++ if(end != NULL){ ++ *end = '\0'; ++ } ++ ++ return controller_node; ++} ++ ++unsigned int ++of_path_get_nvme_nsid(const char* devname) ++{ ++ unsigned int nsid; ++ char *sysfs_path, *buf; ++ FILE *fp; ++ ++ buf=malloc(sizeof(char)*512); ++ ++ sysfs_path = block_device_get_sysfs_path_and_link (devname); ++ ++ snprintf(buf,512,"%s/%s/nsid",sysfs_path,devname); ++ fp = fopen(buf,"r"); ++ fscanf(fp, "%u", &(nsid)); ++ fclose(fp); ++ ++ free(sysfs_path); ++ free(buf); ++ ++ return nsid; ++ ++} ++ ++static char * ++nvme_get_syspath(const char *nvmedev) ++{ ++ char *sysfs_path, *controller_node; ++ sysfs_path = block_device_get_sysfs_path_and_link (nvmedev); ++ ++ if(strstr(sysfs_path,"nvme-subsystem")){ ++ controller_node = of_path_get_nvme_controller_name_node(nvmedev); ++ strcat(sysfs_path,"/"); ++ strcat(sysfs_path,controller_node); ++ sysfs_path = xrealpath(sysfs_path); ++ } ++ ++ return sysfs_path; ++} ++ ++ + static char * + of_path_of_nvme(const char *sys_devname __attribute__((unused)), + const char *device, +@@ -360,6 +558,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)), + { + char *sysfs_path, *of_path, disk[MAX_DISK_CAT]; + const char *digit_string, *part_end; ++ int chars_written; + + digit_string = trailing_digits (device); + part_end = devicenode + strlen (devicenode) - 1; +@@ -379,15 +578,61 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)), + /* Remove the p. */ + *end = '\0'; + sscanf (digit_string, "%d", &part); +- snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1)); +- sysfs_path = block_device_get_sysfs_path_and_link (nvmedev); ++ ++ sysfs_path = nvme_get_syspath(nvmedev); ++ ++ /* If is a NVMeoF */ ++ if(strstr(sysfs_path,"nvme-fabrics")){ ++ struct ofpath_nvmeof_info* nvmeof_info; ++ nvmeof_info = malloc(sizeof(nvmeof_info)); ++ ++ of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info); ++ ++ sysfs_path = of_find_fc_host(nvmeof_info->host_wwpn); ++ ++ chars_written = snprintf(disk,sizeof(disk),"/nvme-of/controller@%s,%x:nqn=%s", ++ nvmeof_info->target_wwpn, ++ 0xffff, ++ nvmeof_info->nqn); ++ ++ unsigned int nsid = of_path_get_nvme_nsid(nvmedev); ++ ++ if(nsid){ ++ snprintf(disk+chars_written,sizeof(disk) - chars_written, ++ "/namespace@%x:%d",nsid, part); ++ } ++ ++ } else { ++ snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1)); ++ } + free (nvmedev); + } + else + { + /* We do not have the parition. */ +- snprintf (disk, sizeof (disk), "/disk@1"); +- sysfs_path = block_device_get_sysfs_path_and_link (device); ++ sysfs_path = nvme_get_syspath (device); ++ if(strstr(sysfs_path,"nvme-fabrics")){ ++ struct ofpath_nvmeof_info* nvmeof_info; ++ nvmeof_info = malloc(sizeof(nvmeof_info)); ++ ++ of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info); ++ ++ sysfs_path = of_find_fc_host(nvmeof_info->host_wwpn); ++ ++ chars_written = snprintf(disk,sizeof(disk),"/nvme-of/controller@%s,%x:nqn=%s", ++ nvmeof_info->target_wwpn, ++ 0xffff, ++ nvmeof_info->nqn); ++ ++ unsigned int nsid = of_path_get_nvme_nsid(device); ++ if(nsid){ ++ snprintf(disk+chars_written,sizeof(disk) - chars_written, ++ "/namespace@%x",nsid); ++ } ++ } else { ++ snprintf (disk, sizeof (disk), "/disk@1"); ++ } ++ + } + + of_path = find_obppath (sysfs_path); +@@ -398,7 +643,6 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)), + free (sysfs_path); + return of_path; + } +-#endif + + static void + of_fc_port_name(const char *path, const char *subpath, char *port_name) +@@ -840,11 +1084,9 @@ grub_util_devname_to_ofpath (const char *sys_devname) + /* All the models I've seen have a devalias "floppy". + New models have no floppy at all. */ + ofpath = xstrdup ("floppy"); +-#ifdef __sparc__ + else if (device[0] == 'n' && device[1] == 'v' && device[2] == 'm' + && device[3] == 'e') + ofpath = of_path_of_nvme (name_buf, device, devnode, devicenode); +-#endif + else + { + grub_util_warn (_("unknown device type %s"), device); +diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h +index b43c523cb..a0ec30620 100644 +--- a/include/grub/util/ofpath.h ++++ b/include/grub/util/ofpath.h +@@ -3,4 +3,33 @@ + + char *grub_util_devname_to_ofpath (const char *devname); + ++struct ofpath_files_list_node { ++ char* filename; ++ struct ofpath_files_list_node* next; ++}; ++ ++struct ofpath_files_list_root { ++ int items; ++ struct ofpath_files_list_node* first; ++}; ++ ++struct ofpath_nvmeof_info { ++ char* host_wwpn; ++ char* target_wwpn; ++ char* nqn; ++ int cntlid; ++ int nsid; ++}; ++ ++void of_path_get_nvmeof_adapter_info(char* sysfs_path, ++ struct ofpath_nvmeof_info* nvmeof_info); ++ ++unsigned int of_path_get_nvme_nsid(const char* devname); ++ ++void add_filename_to_pile(char *filename, struct ofpath_files_list_root* root); ++ ++void find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth); ++ ++char* of_find_fc_host(char* host_wwpn); ++ + #endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */ +-- +2.35.3 + diff --git a/0158-ieee1275-powerpc-enables-device-mapper-discovery.patch b/0002-ieee1275-powerpc-enables-device-mapper-discovery.patch similarity index 81% rename from 0158-ieee1275-powerpc-enables-device-mapper-discovery.patch rename to 0002-ieee1275-powerpc-enables-device-mapper-discovery.patch index 6f1c21b383fd252e4854dc3887291f85548cb242..0701c404b0a1490d819229fba04f004b4fbcfaf1 100644 --- a/0158-ieee1275-powerpc-enables-device-mapper-discovery.patch +++ b/0002-ieee1275-powerpc-enables-device-mapper-discovery.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 8b31ebfa42eb5af0633191d26fcdcea8c539e521 Mon Sep 17 00:00:00 2001 From: Diego Domingos -Date: Mon, 14 Dec 2020 17:47:16 +0100 -Subject: [PATCH] ieee1275/powerpc: enables device mapper discovery +Date: Wed, 24 Jun 2020 08:22:50 -0400 +Subject: [PATCH 2/2] ieee1275/powerpc: enables device mapper discovery this patch enables the device mapper discovery on ofpath.c. Currently, when we are dealing with a device like /dev/dm-* the ofpath returns null @@ -11,13 +11,14 @@ This patch implements a function that will look into /sys/block/dm-* devices and search recursively inside slaves directory to find the root disk. -Signed-off-by: Diego Domingos +v2: +Fix gcc-12 error: pointer 'device_path' may be used after 'free' +[-Werror=use-after-free] + --- - grub-core/osdep/linux/ofpath.c | 64 +++++++++++++++++++++++++++++++++++++++++- + grub-core/osdep/linux/ofpath.c | 64 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) -diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c -index 0f5d54e9f2d..cc849d9c94c 100644 --- a/grub-core/osdep/linux/ofpath.c +++ b/grub-core/osdep/linux/ofpath.c @@ -37,6 +37,7 @@ @@ -28,7 +29,7 @@ index 0f5d54e9f2d..cc849d9c94c 100644 #ifdef __sparc__ typedef enum -@@ -755,13 +756,74 @@ strip_trailing_digits (const char *p) +@@ -754,13 +755,74 @@ return new; } @@ -77,7 +78,7 @@ index 0f5d54e9f2d..cc849d9c94c 100644 + closedir (dp); + } + else -+ grub_util_warn (_("cannot open directory `%s'"), device_path); ++ grub_util_warn (_("cannot open directory `/sys/block/%s/slaves'"), curr_device); + } + + free (directory); diff --git a/0002-ofdisk-add-early_log-support.patch b/0002-ofdisk-add-early_log-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..33a38dbaa10829bcb87e54a459a5688ac21225de --- /dev/null +++ b/0002-ofdisk-add-early_log-support.patch @@ -0,0 +1,164 @@ +From 8959b9d97b00f791ffe02b5e3ec3fdf6bff25838 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Tue, 12 Dec 2023 15:34:18 +0800 +Subject: [PATCH 2/2] ofdisk: add early_log support + +The command ofdisk_early_msg can be used to review debug message logged +before output console is initialized. + +For eg: + + grub> ofdisk_early_msg + /vdevice/v-scsi@71000002/disk@8000000000000000 is canonical + /vdevice/v-scsi@71000002/disk@8000000000000000 + + /vdevice/v-scsi@71000002 is parent of + /vdevice/v-scsi@71000002/disk@80000000 + 00000000 + + the boot device type vscsi is used for root device discovery, others excluded + +We can use it in conjunction with the $ofdisk_boot_type variable to get +better understanding the boot device information. + + grub> echo $ofdisk_boot_type + boot: /vdevice/v-scsi@71000002 type: vscsi is_nvmeof? 0 + +Signed-off-by: Michael Chang +--- + grub-core/disk/ieee1275/ofdisk.c | 75 +++++++++++++++++++++++++++++--- + 1 file changed, 70 insertions(+), 5 deletions(-) + +--- a/grub-core/disk/ieee1275/ofdisk.c ++++ b/grub-core/disk/ieee1275/ofdisk.c +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #define RETRY_DEFAULT_TIMEOUT 15 + +@@ -60,6 +61,9 @@ + #define OFDISK_HASH_SZ 8 + static struct ofdisk_hash_ent *ofdisk_hash[OFDISK_HASH_SZ]; + ++static void early_log (const char *fmt, ...); ++static void print_early_log (void); ++ + static int + ofdisk_hash_fn (const char *devpath) + { +@@ -1132,10 +1136,10 @@ + return NULL; + } + else +- grub_dprintf ("ofdisk", "%s is canonical %s\n", bootpath, canon); ++ early_log ("%s is canonical %s\n", bootpath, canon); + + parent = get_parent_devname (canon, is_nvmeof); +- grub_dprintf ("ofdisk", "%s is parent of %s\n", parent, canon); ++ early_log ("%s is parent of %s\n", parent, canon); + + grub_free (canon); + return parent; +@@ -1179,9 +1183,9 @@ + boot_parent = get_boot_device_parent (bootpath, &is_boot_nvmeof); + boot_type = grub_ieee1275_get_device_type (boot_parent); + if (boot_type) +- grub_dprintf ("ofdisk", "the boot device type %s is used for root device discovery, others excluded\n", boot_type); ++ early_log ("the boot device type %s is used for root device discovery, others excluded\n", boot_type); + else +- grub_dprintf ("ofdisk", "unknown boot device type, will use all devices to discover root and may be slow\n"); ++ early_log ("unknown boot device type, will use all devices to discover root and may be slow\n"); + } + grub_free (type); + grub_free (bootpath); +@@ -1205,7 +1209,7 @@ + static char *ret; + + if (!ret) +- ret = grub_xasprintf("boot: %s type: %s is_nvmeof: %d", ++ ret = grub_xasprintf("boot: %s type: %s is_nvmeof? %d", + boot_parent, + boot_type ? : "unknown", + is_boot_nvmeof); +@@ -1221,6 +1225,17 @@ + return NULL; + } + ++static grub_err_t ++grub_cmd_early_msg (struct grub_command *cmd __attribute__ ((unused)), ++ int argc __attribute__ ((unused)), ++ char *argv[] __attribute__ ((unused))) ++{ ++ print_early_log (); ++ return 0; ++} ++ ++static grub_command_t cmd_early_msg; ++ + void + grub_ofdisk_init (void) + { +@@ -1230,6 +1245,9 @@ + grub_register_variable_hook ("ofdisk_boot_type", grub_env_get_boot_type, + grub_env_set_boot_type ); + ++ cmd_early_msg = ++ grub_register_command ("ofdisk_early_msg", grub_cmd_early_msg, ++ 0, N_("Show early boot message in ofdisk.")); + grub_disk_dev_register (&grub_ofdisk_dev); + } + +@@ -1278,3 +1296,50 @@ + + return 0; + } ++ ++struct ofdisk_early_msg ++{ ++ struct ofdisk_early_msg *next; ++ char *msg; ++}; ++ ++static struct ofdisk_early_msg *early_msg_head; ++static struct ofdisk_early_msg **early_msg_last = &early_msg_head; ++ ++static void ++early_log (const char *fmt, ...) ++{ ++ struct ofdisk_early_msg *n; ++ va_list args; ++ ++ grub_error_push (); ++ n = grub_malloc (sizeof (*n)); ++ if (!n) ++ { ++ grub_errno = 0; ++ grub_error_pop (); ++ return; ++ } ++ n->next = 0; ++ ++ va_start (args, fmt); ++ n->msg = grub_xvasprintf (fmt, args); ++ va_end (args); ++ ++ *early_msg_last = n; ++ early_msg_last = &n->next; ++ ++ grub_errno = 0; ++ grub_error_pop (); ++} ++ ++static void ++print_early_log (void) ++{ ++ struct ofdisk_early_msg *cur; ++ ++ if (!early_msg_head) ++ grub_printf ("no early log is available\n"); ++ for (cur = early_msg_head; cur; cur = cur->next) ++ grub_printf ("%s\n", cur->msg); ++} diff --git a/0002-prep_loadenv-Fix-regex-for-Open-Firmware-device-spec.patch b/0002-prep_loadenv-Fix-regex-for-Open-Firmware-device-spec.patch new file mode 100644 index 0000000000000000000000000000000000000000..e2f05121f0476ee3243183490b99e497cbc78efd --- /dev/null +++ b/0002-prep_loadenv-Fix-regex-for-Open-Firmware-device-spec.patch @@ -0,0 +1,205 @@ +From 990902e28c390217d25ea474e5ef163d79eadc7f Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Fri, 31 Mar 2023 15:19:58 +0800 +Subject: [PATCH 2/2] prep_loadenv: Fix regex for Open Firmware device + specifier with encoded commas + +The Open Firmware device specifier allows for comma-separated properties +of a component, but this conflicts with the way that grub separates +device and partition in its device specifier. To address this, grub +encodes commas in Open Firmware device strings with a leading backslash +as an established convention. + +However, the regular expression used to extract the boot device +substring from the $cmdpath environment variable did not properly retain +commas with leading backslashes as part of the device. This could cause +the comma to be incorrectly interpreted as a partition delimiter and +result in a broken name for the boot disk. + +To fix this issue, we have updated the regular expression to properly +handle the encoded comma in the Open Firmware device specifier, ensuring +that the correct boot device is identified and used. + +v2: +Fix the issue of freeing an uninitialized pointer in early_prep_loadenv. + +Signed-off-by: Michael Chang +--- + grub-core/commands/prep_loadenv.c | 108 ++++++++++++++++++++++-------- + 1 file changed, 79 insertions(+), 29 deletions(-) + +--- a/grub-core/commands/prep_loadenv.c ++++ b/grub-core/commands/prep_loadenv.c +@@ -15,7 +15,7 @@ + GRUB_MOD_LICENSE ("GPLv3+"); + + static char * +-match_substr (regmatch_t *match, const char *str) ++match_substr (const regmatch_t *match, const char *str) + { + if (match->rm_so != -1) + { +@@ -185,24 +185,18 @@ + return err; + } + +-static grub_err_t +-boot_disk_prep_partname (char **name) ++static regmatch_t * ++regex_match_str (const char *pattern, const char *str, grub_size_t *nmatch) + { + regex_t regex; + int ret; + grub_size_t s; + char *comperr; +- const char *cmdpath; + regmatch_t *matches = NULL; + grub_err_t err = GRUB_ERR_NONE; + +- *name = NULL; +- +- cmdpath = grub_env_get ("cmdpath"); +- if (!cmdpath) +- return GRUB_ERR_NONE; +- +- ret = regcomp (®ex, "\\(([^,]+)(,?.*)?\\)(.*)", REG_EXTENDED); ++ *nmatch = 0; ++ ret = regcomp (®ex, pattern, REG_EXTENDED); + if (ret) + goto fail; + +@@ -210,22 +204,11 @@ + if (! matches) + goto fail; + +- ret = regexec (®ex, cmdpath, regex.re_nsub + 1, matches, 0); +- if (!ret) ++ ret = regexec (®ex, str, regex.re_nsub + 1, matches, 0); ++ if (ret == 0) + { +- char *devname = devname = match_substr (matches + 1, cmdpath); +- if (!devname) +- { +- err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "%s contains no disk name", cmdpath); +- goto out; +- } +- +- err = prep_partname (devname, name); +- out: +- grub_free (devname); +- regfree (®ex); +- grub_free (matches); +- return err; ++ *nmatch = regex.re_nsub + 1; ++ return matches; + } + + fail: +@@ -235,13 +218,60 @@ + if (!comperr) + { + regfree (®ex); +- return grub_errno; ++ return NULL; + } + regerror (ret, ®ex, comperr, s); + err = grub_error (GRUB_ERR_TEST_FAILURE, "%s", comperr); + regfree (®ex); + grub_free (comperr); +- return err; ++ return NULL; ++} ++ ++static grub_err_t ++boot_disk_prep_partname (const char *varname, char **name) ++{ ++ const char *cmdpath; ++ regmatch_t *matches; ++ grub_size_t nmatch; ++ char *devname = NULL; ++ ++ *name = NULL; ++ ++ if (varname) ++ cmdpath = grub_env_get (varname); ++ else ++ cmdpath = grub_env_get ("cmdpath"); ++ if (!cmdpath) ++ return GRUB_ERR_NONE; ++ ++ matches = regex_match_str("\\((.*)\\)(.*)", cmdpath, &nmatch); ++ if (matches && nmatch >= 2) ++ devname = match_substr (matches + 1, cmdpath); ++ if (devname == NULL) ++ goto quit; ++ grub_free (matches); ++ ++ matches = regex_match_str ("(.*[^\\])(,.*)", devname, &nmatch); ++ if (matches && nmatch >= 2) ++ { ++ char *n = match_substr (matches + 1, devname); ++ grub_free (devname); ++ devname = n; ++ } ++ else ++ grub_errno = GRUB_ERR_NONE; ++ if (devname) ++ { ++ grub_printf ("search prep from disk `%s'\n", devname); ++ prep_partname (devname, name); ++ } ++ ++ quit: ++ grub_free (devname); ++ grub_free (matches); ++ if (grub_errno) ++ grub_print_error (); ++ return GRUB_ERR_NONE; + } + + static grub_err_t +@@ -274,13 +304,31 @@ + return GRUB_ERR_NONE; + } + ++static grub_err_t ++grub_cmd_prep_partname (grub_command_t cmd __attribute__ ((unused)), ++ int argc, ++ char **argv) ++{ ++ char *prep = NULL; ++ const char *varname = NULL; ++ ++ if (argc > 0) ++ varname = argv[0]; ++ ++ boot_disk_prep_partname(varname, &prep); ++ if (prep) ++ grub_printf ("prep: %s\n", prep); ++ ++ return GRUB_ERR_NONE; ++} ++ + static void + early_prep_loadenv (void) + { + grub_err_t err; +- char *prep; ++ char *prep = NULL; + +- err = boot_disk_prep_partname (&prep); ++ err = boot_disk_prep_partname (NULL, &prep); + if (err == GRUB_ERR_NONE && prep) + err = prep_read_envblk (prep); + if (err == GRUB_ERR_BAD_FILE_TYPE || err == GRUB_ERR_FILE_NOT_FOUND) +@@ -296,6 +344,10 @@ + { + early_env_hook = early_prep_loadenv; + cmd_prep_load = ++ grub_register_command("prep_partname", grub_cmd_prep_partname, ++ "VARNAME", ++ N_("Get partition name of PReP.")); ++ cmd_prep_load = + grub_register_command("prep_load_env", grub_cmd_prep_loadenv, + "DEVICE", + N_("Load variables from environment block file.")); diff --git a/0002-tpm2-Add-TPM-Software-Stack-TSS.patch b/0002-tpm2-Add-TPM-Software-Stack-TSS.patch new file mode 100644 index 0000000000000000000000000000000000000000..4e584ee09fe3d60960a81c0cb0b1f5316bd8bd8d --- /dev/null +++ b/0002-tpm2-Add-TPM-Software-Stack-TSS.patch @@ -0,0 +1,3569 @@ +From c5a42cf3340aa740132bcdb8e8cee22c23306ef5 Mon Sep 17 00:00:00 2001 +From: Hernan Gatta +Date: Tue, 1 Feb 2022 05:02:54 -0800 +Subject: [PATCH v6 09/20] tpm2: Add TPM Software Stack (TSS) + +A Trusted Platform Module (TPM) Software Stack (TSS) provides logic to +compose, submit, and parse TPM commands and responses. + +A limited number of TPM commands may be accessed via the EFI TCG2 +protocol. This protocol exposes functionality that is primarily geared +toward TPM usage within the context of Secure Boot. For all other TPM +commands, however, such as sealing and unsealing, this protocol does not +provide any help, with the exception of passthrough command submission. + +The SubmitCommand method allows a caller to send raw commands to the +system's TPM and to receive the corresponding response. These +command/response pairs are formatted using the TPM wire protocol. To +construct commands in this way, and to parse the TPM's response, it is +necessary to, first, possess knowledge of the various TPM structures, and, +second, of the TPM wire protocol itself. + +As such, this patch includes a set of header files that define the +necessary TPM structures and TSS functions, implementations of various +TPM2_* functions (inventoried below), and logic to write and read command +and response buffers, respectively, using the TPM wire protocol. + +Functions: TPM2_Create, TPM2_CreatePrimary, TPM2_EvictControl, +TPM2_FlushContext, TPM2_Load, TPM2_PCR_Read, TPM2_PolicyGetDigest, +TPM2_PolicyPCR, TPM2_ReadPublic, TPM2_StartAuthSession, TPM2_Unseal. + +Signed-off-by: Hernan Gatta +Signed-off-by: Gary Lin +--- + grub-core/tpm2/buffer.c | 145 +++++ + grub-core/tpm2/mu.c | 807 +++++++++++++++++++++++++ + grub-core/tpm2/tcg2.c | 143 +++++ + grub-core/tpm2/tpm2.c | 761 +++++++++++++++++++++++ + include/grub/tpm2/buffer.h | 65 ++ + include/grub/tpm2/internal/functions.h | 117 ++++ + include/grub/tpm2/internal/structs.h | 675 +++++++++++++++++++++ + include/grub/tpm2/internal/types.h | 370 ++++++++++++ + include/grub/tpm2/mu.h | 292 +++++++++ + include/grub/tpm2/tcg2.h | 34 ++ + include/grub/tpm2/tpm2.h | 34 ++ + 11 files changed, 3443 insertions(+) + create mode 100644 grub-core/tpm2/buffer.c + create mode 100644 grub-core/tpm2/mu.c + create mode 100644 grub-core/tpm2/tcg2.c + create mode 100644 grub-core/tpm2/tpm2.c + create mode 100644 include/grub/tpm2/buffer.h + create mode 100644 include/grub/tpm2/internal/functions.h + create mode 100644 include/grub/tpm2/internal/structs.h + create mode 100644 include/grub/tpm2/internal/types.h + create mode 100644 include/grub/tpm2/mu.h + create mode 100644 include/grub/tpm2/tcg2.h + create mode 100644 include/grub/tpm2/tpm2.h + +diff --git a/grub-core/tpm2/buffer.c b/grub-core/tpm2/buffer.c +new file mode 100644 +index 000000000..cb9f29497 +--- /dev/null ++++ b/grub-core/tpm2/buffer.c +@@ -0,0 +1,145 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++ ++void grub_tpm2_buffer_init (grub_tpm2_buffer_t buffer) ++{ ++ grub_memset (buffer->data, 0xDD, sizeof (buffer->data)); ++ buffer->size = 0; ++ buffer->offset = 0; ++ buffer->cap = sizeof (buffer->data); ++ buffer->error = 0; ++} ++ ++void ++grub_tpm2_buffer_pack (grub_tpm2_buffer_t buffer, const void* data, ++ grub_size_t size) ++{ ++ grub_uint32_t r = buffer->cap - buffer->size; ++ ++ if (buffer->error) ++ return; ++ ++ if (size > r) ++ { ++ buffer->error = 1; ++ return; ++ } ++ ++ grub_memcpy (&buffer->data[buffer->size], (void*) data, size); ++ buffer->size += size; ++} ++ ++void ++grub_tpm2_buffer_pack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t value) ++{ ++ grub_tpm2_buffer_pack (buffer, (const char*) &value, sizeof (value)); ++} ++ ++void ++grub_tpm2_buffer_pack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t value) ++{ ++ grub_uint16_t tmp = grub_cpu_to_be16 (value); ++ grub_tpm2_buffer_pack (buffer, (const char*) &tmp, sizeof (tmp)); ++} ++ ++void ++grub_tpm2_buffer_pack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t value) ++{ ++ grub_uint32_t tmp = grub_cpu_to_be32 (value); ++ grub_tpm2_buffer_pack (buffer, (const char*) &tmp, sizeof (tmp)); ++} ++ ++void ++grub_tpm2_buffer_unpack (grub_tpm2_buffer_t buffer, void* data, ++ grub_size_t size) ++{ ++ grub_uint32_t r = buffer->size - buffer->offset; ++ ++ if (buffer->error) ++ return; ++ ++ if (size > r) ++ { ++ buffer->error = 1; ++ return; ++ } ++ ++ grub_memcpy (data, &buffer->data[buffer->offset], size); ++ buffer->offset += size; ++} ++ ++void ++grub_tpm2_buffer_unpack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t* value) ++{ ++ grub_uint32_t r = buffer->size - buffer->offset; ++ ++ if (buffer->error) ++ return; ++ ++ if (sizeof (*value) > r) ++ { ++ buffer->error = 1; ++ return; ++ } ++ ++ grub_memcpy (value, &buffer->data[buffer->offset], sizeof (*value)); ++ buffer->offset += sizeof (*value); ++} ++ ++void ++grub_tpm2_buffer_unpack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t* value) ++{ ++ grub_uint16_t tmp; ++ grub_uint32_t r = buffer->size - buffer->offset; ++ ++ if (buffer->error) ++ return; ++ ++ if (sizeof (tmp) > r) ++ { ++ buffer->error = 1; ++ return; ++ } ++ ++ grub_memcpy (&tmp, &buffer->data[buffer->offset], sizeof (tmp)); ++ buffer->offset += sizeof (tmp); ++ *value = grub_be_to_cpu16 (tmp); ++} ++ ++void ++grub_tpm2_buffer_unpack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t* value) ++{ ++ grub_uint32_t tmp; ++ grub_uint32_t r = buffer->size - buffer->offset; ++ ++ if (buffer->error) ++ return; ++ ++ if (sizeof (tmp) > r) ++ { ++ buffer->error = 1; ++ return; ++ } ++ ++ grub_memcpy (&tmp, &buffer->data[buffer->offset], sizeof (tmp)); ++ buffer->offset += sizeof (tmp); ++ *value = grub_be_to_cpu32 (tmp); ++} +diff --git a/grub-core/tpm2/mu.c b/grub-core/tpm2/mu.c +new file mode 100644 +index 000000000..1617f37cd +--- /dev/null ++++ b/grub-core/tpm2/mu.c +@@ -0,0 +1,807 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++ ++void ++grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_AUTH_COMMAND* authCommand) ++{ ++ grub_uint32_t start; ++ grub_uint32_t tmp; ++ ++ grub_tpm2_buffer_pack_u32 (buffer, 0); ++ start = buffer->size; ++ ++ grub_tpm2_buffer_pack_u32 (buffer, authCommand->sessionHandle); ++ ++ grub_tpm2_buffer_pack_u16 (buffer, authCommand->nonce.size); ++ grub_tpm2_buffer_pack (buffer, authCommand->nonce.buffer, ++ authCommand->nonce.size); ++ ++ grub_tpm2_buffer_pack_u8 (buffer, ++ *((const grub_uint8_t*) &authCommand->sessionAttributes)); ++ ++ grub_tpm2_buffer_pack_u16 (buffer, authCommand->hmac.size); ++ grub_tpm2_buffer_pack (buffer, authCommand->hmac.buffer, ++ authCommand->hmac.size); ++ ++ tmp = grub_cpu_to_be32 (buffer->size - start); ++ grub_memcpy (&buffer->data[start - sizeof (grub_uint32_t)], &tmp, ++ sizeof (tmp)); ++} ++ ++void ++grub_tpm2_mu_TPM2B_Marshal (grub_tpm2_buffer_t buffer, ++ const grub_uint16_t size, ++ const grub_uint8_t* b) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, size); ++ ++ for (grub_uint16_t i = 0; i < size; i++) ++ grub_tpm2_buffer_pack_u8 (buffer, b[i]); ++} ++ ++void ++grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_SYM_OBJECT algorithm, ++ const TPMU_SYM_KEY_BITS *p) ++{ ++ switch (algorithm) ++ { ++ case TPM_ALG_AES: ++ case TPM_ALG_SM4: ++ case TPM_ALG_CAMELLIA: ++ case TPM_ALG_XOR: ++ grub_tpm2_buffer_pack_u16 (buffer, *((const grub_uint16_t*) p)); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_SYM_OBJECT algorithm, ++ const TPMU_SYM_MODE *p) ++{ ++ switch (algorithm) ++ { ++ case TPM_ALG_AES: ++ case TPM_ALG_SM4: ++ case TPM_ALG_CAMELLIA: ++ grub_tpm2_buffer_pack_u16 (buffer, *((const grub_uint16_t*) p)); ++ break; ++ case TPM_ALG_XOR: ++ case TPM_ALG_NULL: ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_SYM_DEF *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->algorithm); ++ grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, &p->keyBits); ++ grub_tpm2_mu_TPMU_SYM_MODE_Marshal (buffer, p->algorithm, &p->mode); ++} ++ ++void ++grub_tpm2_mu_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_PCR_SELECTION* pcrSelection) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, pcrSelection->hash); ++ grub_tpm2_buffer_pack_u8 (buffer, pcrSelection->sizeOfSelect); ++ ++ for (grub_uint32_t i = 0; i < pcrSelection->sizeOfSelect; i++) ++ grub_tpm2_buffer_pack_u8 (buffer, pcrSelection->pcrSelect[i]); ++} ++ ++void ++grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buffer, ++ const TPML_PCR_SELECTION* pcrSelection) ++{ ++ grub_tpm2_buffer_pack_u32 (buffer, pcrSelection->count); ++ ++ for (grub_uint32_t i = 0; i < pcrSelection->count; i++) ++ grub_tpm2_mu_TPMS_PCR_SELECTION_Marshal (buffer, ++ &pcrSelection->pcrSelections[i]); ++} ++ ++void ++grub_tpm2_mu_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMA_OBJECT *p) ++{ ++ grub_tpm2_buffer_pack_u32 (buffer, *((const grub_uint32_t*) p)); ++} ++ ++void ++grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SCHEME_XOR *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); ++ grub_tpm2_buffer_pack_u16 (buffer, p->kdf); ++} ++ ++void ++grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SCHEME_HMAC *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); ++} ++ ++void ++grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_KEYEDHASH_SCHEME scheme, ++ const TPMU_SCHEME_KEYEDHASH *p) ++{ ++ switch (scheme) ++ { ++ case TPM_ALG_HMAC: ++ grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (buffer, &p->hmac); ++ break; ++ case TPM_ALG_XOR: ++ grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (buffer, &p->exclusiveOr); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_KEYEDHASH_SCHEME *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->scheme); ++ grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_KEYEDHASH_PARMS *p) ++{ ++ grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (buffer, &p->scheme); ++} ++ ++void ++grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_SYM_DEF_OBJECT *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->algorithm); ++ grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (buffer, p->algorithm, &p->keyBits); ++ grub_tpm2_mu_TPMU_SYM_MODE_Marshal (buffer, p->algorithm, &p->mode); ++} ++ ++void ++grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_RSA_DECRYPT scheme, ++ const TPMU_ASYM_SCHEME *p __attribute__ ((unused))) ++{ ++ switch (scheme) ++ { ++ case TPM_ALG_NULL: ++ break; ++ default: ++ /* Unsupported */ ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_RSA_SCHEME *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->scheme); ++ grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_RSA_PARMS *p) ++{ ++ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric); ++ grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (buffer, &p->scheme); ++ grub_tpm2_buffer_pack_u16 (buffer, p->keyBits); ++ grub_tpm2_buffer_pack_u32 (buffer, p->exponent); ++} ++ ++void ++grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SYMCIPHER_PARMS *p) ++{ ++ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->sym); ++} ++ ++void ++grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_ECC_SCHEME *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->scheme); ++ grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_KDF scheme, ++ const TPMU_KDF_SCHEME *p) ++{ ++ switch (scheme) ++ { ++ case TPM_ALG_MGF1: ++ grub_tpm2_buffer_pack_u16 (buffer, p->mgf1.hashAlg); ++ break; ++ case TPM_ALG_KDF1_SP800_56A: ++ grub_tpm2_buffer_pack_u16 (buffer, p->kdf1_sp800_56a.hashAlg); ++ break; ++ case TPM_ALG_KDF2: ++ grub_tpm2_buffer_pack_u16 (buffer, p->kdf2.hashAlg); ++ break; ++ case TPM_ALG_KDF1_SP800_108: ++ grub_tpm2_buffer_pack_u16 (buffer, p->kdf1_sp800_108.hashAlg); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_KDF_SCHEME *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->scheme); ++ grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_ECC_PARMS *p) ++{ ++ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (buffer, &p->symmetric); ++ grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (buffer, &p->scheme); ++ grub_tpm2_buffer_pack_u16 (buffer, p->curveID); ++ grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (buffer, &p->kdf); ++} ++ ++void ++grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buffer, ++ const grub_uint32_t type, ++ const TPMU_PUBLIC_PARMS *p) ++{ ++ switch (type) ++ { ++ case TPM_ALG_KEYEDHASH: ++ grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (buffer, &p->keyedHashDetail); ++ break; ++ case TPM_ALG_SYMCIPHER: ++ grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Marshal (buffer, &p->symDetail); ++ break; ++ case TPM_ALG_RSA: ++ grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (buffer, &p->rsaDetail); ++ break; ++ case TPM_ALG_ECC: ++ grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (buffer, &p->eccDetail); ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_ECC_POINT *p) ++{ ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->x.size, p->x.buffer); ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->y.size, p->y.buffer); ++} ++ ++void ++grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_PUBLIC type, ++ const TPMU_PUBLIC_ID *p) ++{ ++ switch(type) ++ { ++ case TPM_ALG_KEYEDHASH: ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->keyedHash.size, ++ p->keyedHash.buffer); ++ break; ++ case TPM_ALG_SYMCIPHER: ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer); ++ break; ++ case TPM_ALG_RSA: ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer); ++ break; ++ case TPM_ALG_ECC: ++ grub_tpm2_mu_TPMS_ECC_POINT_Marshal (buffer, &p->ecc); ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_PUBLIC *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->type); ++ grub_tpm2_buffer_pack_u16 (buffer, p->nameAlg); ++ grub_tpm2_mu_TPMA_OBJECT_Marshal (buffer, &p->objectAttributes); ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->authPolicy.size, p->authPolicy.buffer); ++ grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (buffer, p->type, &p->parameters); ++ grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (buffer, p->type, &p->unique); ++} ++ ++void ++grub_tpm2_mu_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buffer, ++ const TPM2B_PUBLIC *p) ++{ ++ grub_uint32_t start; ++ grub_uint16_t size; ++ ++ if (p) ++ { ++ grub_tpm2_buffer_pack_u16 (buffer, p->size); ++ ++ start = buffer->size; ++ grub_tpm2_mu_TPMT_PUBLIC_Marshal (buffer, &p->publicArea); ++ size = grub_cpu_to_be16 (buffer->size - start); ++ grub_memcpy (&buffer->data[start - sizeof (grub_uint16_t)], &size, ++ sizeof (size)); ++ } ++ else ++ grub_tpm2_buffer_pack_u16 (buffer, 0); ++} ++ ++void ++grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SENSITIVE_CREATE *p) ++{ ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->userAuth.size, p->userAuth.buffer); ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->data.size, p->data.buffer); ++} ++ ++void ++grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPM2B_SENSITIVE_CREATE *sensitiveCreate) ++{ ++ grub_uint32_t start; ++ grub_uint16_t size; ++ ++ if (sensitiveCreate) ++ { ++ grub_tpm2_buffer_pack_u16 (buffer, sensitiveCreate->size); ++ start = buffer->size; ++ grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (buffer, ++ &sensitiveCreate->sensitive); ++ size = grub_cpu_to_be16 (buffer->size - start); ++ ++ grub_memcpy (&buffer->data[start - sizeof (grub_uint16_t)], &size, ++ sizeof (size)); ++ } ++ else ++ grub_tpm2_buffer_pack_u16 (buffer, 0); ++} ++ ++void ++grub_tpm2_mu_TPM2B_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B* p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->size); ++ ++ for (grub_uint16_t i = 0; i < p->size; i++) ++ grub_tpm2_buffer_unpack_u8 (buffer, &p->buffer[i]); ++} ++ ++void ++grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_AUTH_RESPONSE* p) ++{ ++ grub_uint8_t tmp; ++ grub_uint32_t tmp32; ++ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->nonce.size); ++ ++ if (p->nonce.size) ++ grub_tpm2_buffer_unpack (buffer, &p->nonce.buffer, p->nonce.size); ++ ++ grub_tpm2_buffer_unpack_u8 (buffer, &tmp); ++ tmp32 = tmp; ++ grub_memcpy (&p->sessionAttributes, &tmp32, sizeof (grub_uint32_t)); ++ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->hmac.size); ++ ++ if (p->hmac.size) ++ grub_tpm2_buffer_unpack (buffer, &p->hmac.buffer, p->hmac.size); ++} ++ ++void ++grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_DIGEST* digest) ++{ ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*)digest); ++} ++ ++void ++grub_tpm2_mu_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMA_OBJECT *p) ++{ ++ grub_tpm2_buffer_unpack_u32 (buffer, (grub_uint32_t*)p); ++} ++ ++void ++grub_tpm2_mu_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SCHEME_HMAC *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); ++} ++ ++void ++grub_tpm2_mu_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SCHEME_XOR *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf); ++} ++ ++void ++grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_KEYEDHASH_SCHEME scheme, ++ TPMU_SCHEME_KEYEDHASH *p) ++{ ++ switch (scheme) ++ { ++ case TPM_ALG_HMAC: ++ grub_tpm2_mu_TPMS_SCHEME_HMAC_Unmarshal (buffer, &p->hmac); ++ break; ++ case TPM_ALG_XOR: ++ grub_tpm2_mu_TPMS_SCHEME_XOR_Unmarshal (buffer, &p->exclusiveOr); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_KEYEDHASH_SCHEME *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); ++ grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Unmarshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_KEYEDHASH_PARMS *p) ++{ ++ grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Unmarshal (buffer, &p->scheme); ++} ++ ++void ++grub_tpm2_mu_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_SYM_OBJECT algorithm, ++ TPMU_SYM_KEY_BITS *p) ++{ ++ switch (algorithm) ++ { ++ case TPM_ALG_AES: ++ case TPM_ALG_SM4: ++ case TPM_ALG_CAMELLIA: ++ case TPM_ALG_XOR: ++ grub_tpm2_buffer_unpack_u16 (buffer, (grub_uint16_t*) p); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_SYM_OBJECT algorithm, ++ TPMU_SYM_MODE *p) ++{ ++ switch (algorithm) ++ { ++ case TPM_ALG_AES: ++ case TPM_ALG_SM4: ++ case TPM_ALG_CAMELLIA: ++ grub_tpm2_buffer_unpack_u16 (buffer, (grub_uint16_t*) p); ++ break; ++ case TPM_ALG_XOR: ++ case TPM_ALG_NULL: ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_SYM_DEF_OBJECT *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->algorithm); ++ grub_tpm2_mu_TPMU_SYM_KEY_BITS_Unmarshal (buffer, p->algorithm, &p->keyBits); ++ grub_tpm2_mu_TPMU_SYM_MODE_Unmarshal (buffer, p->algorithm, &p->mode); ++} ++ ++void ++grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SYMCIPHER_PARMS *p) ++{ ++ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->sym); ++} ++ ++void ++grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_RSA_DECRYPT scheme, ++ TPMU_ASYM_SCHEME *p __attribute__((unused))) ++{ ++ switch (scheme) ++ { ++ case TPM_ALG_NULL: ++ break; ++ default: ++ /* Unsupported */ ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_RSA_SCHEME *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); ++ grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_tpm2_mu_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_RSA_PARMS *p) ++{ ++ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->symmetric); ++ grub_tpm2_mu_TPMT_RSA_SCHEME_Unmarshal (buffer, &p->scheme); ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->keyBits); ++ grub_tpm2_buffer_unpack_u32 (buffer, &p->exponent); ++} ++ ++void ++grub_tpm2_mu_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_ECC_SCHEME *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); ++ grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_tpm2_mu_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_KDF scheme, ++ TPMU_KDF_SCHEME *p) ++{ ++ switch (scheme) ++ { ++ case TPM_ALG_MGF1: ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->mgf1.hashAlg); ++ break; ++ case TPM_ALG_KDF1_SP800_56A: ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf1_sp800_56a.hashAlg); ++ break; ++ case TPM_ALG_KDF2: ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf2.hashAlg); ++ break; ++ case TPM_ALG_KDF1_SP800_108: ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->kdf1_sp800_108.hashAlg); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_KDF_SCHEME *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->scheme); ++ grub_tpm2_mu_TPMU_KDF_SCHEME_Unmarshal (buffer, p->scheme, &p->details); ++} ++ ++void ++grub_tpm2_mu_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_ECC_PARMS *p) ++{ ++ grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (buffer, &p->symmetric); ++ grub_tpm2_mu_TPMT_ECC_SCHEME_Unmarshal (buffer, &p->scheme ); ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->curveID); ++ grub_tpm2_mu_TPMT_KDF_SCHEME_Unmarshal (buffer, &p->kdf); ++} ++ ++void ++grub_tpm2_mu_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buffer, ++ grub_uint32_t type, ++ TPMU_PUBLIC_PARMS *p) ++{ ++ switch (type) ++ { ++ case TPM_ALG_KEYEDHASH: ++ grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Unmarshal (buffer, &p->keyedHashDetail); ++ break; ++ case TPM_ALG_SYMCIPHER: ++ grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Unmarshal (buffer, &p->symDetail); ++ break; ++ case TPM_ALG_RSA: ++ grub_tpm2_mu_TPMS_RSA_PARMS_Unmarshal (buffer, &p->rsaDetail); ++ break; ++ case TPM_ALG_ECC: ++ grub_tpm2_mu_TPMS_ECC_PARMS_Unmarshal (buffer, &p->eccDetail); ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_ECC_POINT *p) ++{ ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->x); ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->y); ++} ++ ++void ++grub_tpm2_mu_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_PUBLIC type, ++ TPMU_PUBLIC_ID *p) ++{ ++ switch(type) ++ { ++ case TPM_ALG_KEYEDHASH: ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->keyedHash); ++ break; ++ case TPM_ALG_SYMCIPHER: ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->sym); ++ break; ++ case TPM_ALG_RSA: ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->rsa); ++ break; ++ case TPM_ALG_ECC: ++ grub_tpm2_mu_TPMS_ECC_POINT_Unmarshal (buffer, &p->ecc); ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_PUBLIC *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->type); ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->nameAlg); ++ grub_tpm2_mu_TPMA_OBJECT_Unmarshal (buffer, &p->objectAttributes); ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->authPolicy); ++ grub_tpm2_mu_TPMU_PUBLIC_PARMS_Unmarshal (buffer, p->type, &p->parameters); ++ grub_tpm2_mu_TPMU_PUBLIC_ID_Unmarshal (buffer, p->type, &p->unique); ++} ++ ++void ++grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_PUBLIC *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->size); ++ grub_tpm2_mu_TPMT_PUBLIC_Unmarshal (buffer, &p->publicArea); ++} ++ ++void ++grub_tpm2_mu_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_NV_PUBLIC *p) ++{ ++ grub_tpm2_buffer_unpack_u32 (buffer, &p->nvIndex); ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->nameAlg); ++ grub_tpm2_buffer_unpack_u32 (buffer, &p->attributes); ++ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buffer, &p->authPolicy); ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->dataSize); ++} ++ ++void ++grub_tpm2_mu_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_NV_PUBLIC *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->size); ++ grub_tpm2_mu_TPMS_NV_PUBLIC_Unmarshal (buffer, &p->nvPublic); ++} ++ ++void ++grub_tpm2_mu_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPM2B_NAME *n) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &n->size); ++ grub_tpm2_buffer_unpack (buffer, n->name, n->size); ++} ++ ++void ++grub_tpm2_mu_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_TAGGED_PROPERTY* property) ++{ ++ grub_tpm2_buffer_unpack_u32 (buffer, &property->property); ++ grub_tpm2_buffer_unpack_u32 (buffer, &property->value); ++} ++ ++void ++grub_tpm2_mu_TPMS_CAPABILITY_DATA_tpmProperties_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_CAPABILITY_DATA* capabilityData) ++{ ++ grub_tpm2_buffer_unpack_u32 (buffer, ++ &capabilityData->data.tpmProperties.count); ++ ++ if (buffer->error) ++ return; ++ ++ for (grub_uint32_t i = 0; i < capabilityData->data.tpmProperties.count; i++) ++ grub_tpm2_mu_TPMS_TAGGED_PROPERTY_Unmarshal (buffer, ++ &capabilityData->data.tpmProperties.tpmProperty[i]); ++} ++ ++void ++grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_TK_CREATION *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); ++ grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->digest); ++} ++ ++void ++grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_PCR_SELECTION* pcrSelection) ++{ ++ grub_tpm2_buffer_unpack_u16 (buf, &pcrSelection->hash); ++ grub_tpm2_buffer_unpack_u8 (buf, &pcrSelection->sizeOfSelect); ++ ++ for (grub_uint32_t i = 0; i < pcrSelection->sizeOfSelect; i++) ++ grub_tpm2_buffer_unpack_u8 (buf, &pcrSelection->pcrSelect[i]); ++} ++ ++void ++grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf, ++ TPML_PCR_SELECTION* pcrSelection) ++{ ++ grub_tpm2_buffer_unpack_u32 (buf, &pcrSelection->count); ++ ++ for (grub_uint32_t i = 0; i < pcrSelection->count; i++) ++ grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (buf, &pcrSelection->pcrSelections[i]); ++} ++ ++void ++grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buf, ++ TPML_DIGEST* digest) ++{ ++ grub_tpm2_buffer_unpack_u32 (buf, &digest->count); ++ ++ for (grub_uint32_t i = 0; i < digest->count; i++) ++ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buf, &digest->digests[i]); ++} +diff --git a/grub-core/tpm2/tcg2.c b/grub-core/tpm2/tcg2.c +new file mode 100644 +index 000000000..9e4b7f565 +--- /dev/null ++++ b/grub-core/tpm2/tcg2.c +@@ -0,0 +1,143 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static grub_err_t ++grub_tcg2_get_caps (grub_efi_tpm2_protocol_t *protocol, int *tpm2, ++ grub_size_t *max_output_size) ++{ ++ grub_efi_status_t status; ++ ++ static int has_caps = 0; ++ static EFI_TCG2_BOOT_SERVICE_CAPABILITY caps = ++ { ++ .Size = (grub_uint8_t) sizeof (caps) ++ }; ++ ++ if (has_caps) ++ goto exit; ++ ++ status = protocol->get_capability (protocol, &caps); ++ if (status != GRUB_EFI_SUCCESS || !caps.TPMPresentFlag) ++ return GRUB_ERR_FILE_NOT_FOUND; ++ ++ has_caps = 1; ++ ++exit: ++ if (tpm2) ++ *tpm2 = caps.TPMPresentFlag; ++ if (max_output_size) ++ *max_output_size = caps.MaxResponseSize; ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tcg2_get_protocol (grub_efi_tpm2_protocol_t **protocol) ++{ ++ static grub_guid_t tpm2_guid = EFI_TPM2_GUID; ++ static grub_efi_tpm2_protocol_t *tpm2_protocol = NULL; ++ ++ int tpm2; ++ grub_efi_handle_t *handles; ++ grub_efi_uintn_t num_handles; ++ grub_efi_handle_t tpm2_handle; ++ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; ++ ++ if (tpm2_protocol) ++ { ++ *protocol = tpm2_protocol; ++ return GRUB_ERR_NONE; ++ } ++ ++ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, &tpm2_guid, NULL, ++ &num_handles); ++ if (!handles || !num_handles) ++ return err; ++ ++ tpm2_handle = handles[0]; ++ ++ tpm2_protocol = grub_efi_open_protocol (tpm2_handle, &tpm2_guid, ++ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); ++ if (!tpm2_protocol) ++ goto exit; ++ ++ err = grub_tcg2_get_caps (tpm2_protocol, &tpm2, NULL); ++ if (err || !tpm2) ++ goto exit; ++ ++ *protocol = tpm2_protocol; ++ err = GRUB_ERR_NONE; ++ ++exit: ++ grub_free (handles); ++ return err; ++} ++ ++grub_err_t ++grub_tcg2_get_max_output_size (grub_size_t *size) ++{ ++ grub_err_t err; ++ grub_size_t max; ++ grub_efi_tpm2_protocol_t *protocol; ++ ++ if (!size) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ err = grub_tcg2_get_protocol (&protocol); ++ if (err) ++ return err; ++ ++ err = grub_tcg2_get_caps (protocol, NULL, &max); ++ if (err) ++ return err; ++ ++ *size = max; ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_tcg2_submit_command (grub_size_t input_size, ++ grub_uint8_t *input, ++ grub_size_t output_size, ++ grub_uint8_t *output) ++{ ++ grub_err_t err; ++ grub_efi_status_t status; ++ grub_efi_tpm2_protocol_t *protocol; ++ ++ if (!input_size || !input || !output_size || !output) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ err = grub_tcg2_get_protocol (&protocol); ++ if (err) ++ return err; ++ ++ status = protocol->submit_command (protocol, input_size, input, ++ output_size, output); ++ if (status != GRUB_EFI_SUCCESS) ++ return GRUB_ERR_INVALID_COMMAND; ++ ++ return GRUB_ERR_NONE; ++} +diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c +new file mode 100644 +index 000000000..d67699a24 +--- /dev/null ++++ b/grub-core/tpm2/tpm2.c +@@ -0,0 +1,761 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static TPM_RC ++grub_tpm2_submit_command_real (const TPMI_ST_COMMAND_TAG tag, ++ const TPM_CC commandCode, ++ TPM_RC *responseCode, ++ const struct grub_tpm2_buffer *in, ++ struct grub_tpm2_buffer *out) ++{ ++ grub_err_t err; ++ struct grub_tpm2_buffer buf; ++ TPMI_ST_COMMAND_TAG tag_out; ++ grub_uint32_t command_size; ++ grub_size_t max_output_size; ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&buf); ++ grub_tpm2_buffer_pack_u16 (&buf, tag); ++ grub_tpm2_buffer_pack_u32 (&buf, 0); ++ grub_tpm2_buffer_pack_u32 (&buf, commandCode); ++ grub_tpm2_buffer_pack (&buf, in->data, in->size); ++ ++ if (buf.error) ++ return TPM_RC_FAILURE; ++ ++ command_size = grub_swap_bytes32 (buf.size); ++ grub_memcpy (&buf.data[sizeof (grub_uint16_t)], &command_size, ++ sizeof (command_size)); ++ ++ /* Stay within output block limits */ ++ err = grub_tcg2_get_max_output_size (&max_output_size); ++ if (err || max_output_size > out->cap) ++ max_output_size = out->cap - 1; ++ ++ /* Submit */ ++ err = grub_tcg2_submit_command (buf.size, buf.data, max_output_size, ++ out->data); ++ if (err) ++ return TPM_RC_FAILURE; ++ ++ /* Unmarshal*/ ++ out->size = sizeof (grub_uint16_t) + sizeof (grub_uint32_t) + ++ sizeof (grub_uint32_t); ++ grub_tpm2_buffer_unpack_u16 (out, &tag_out); ++ grub_tpm2_buffer_unpack_u32 (out, &command_size); ++ grub_tpm2_buffer_unpack_u32 (out, responseCode); ++ out->size = command_size; ++ if (out->error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++static TPM_RC ++grub_tpm2_submit_command (const TPMI_ST_COMMAND_TAG tag, ++ const TPM_CC commandCode, ++ TPM_RC *responseCode, ++ const struct grub_tpm2_buffer *in, ++ struct grub_tpm2_buffer *out) ++{ ++ TPM_RC err; ++ int retry_cnt = 0; ++ ++ /* Catch TPM_RC_RETRY and send the command again */ ++ do { ++ err = grub_tpm2_submit_command_real (tag, commandCode, responseCode, ++ in, out); ++ if (*responseCode != TPM_RC_RETRY) ++ break; ++ ++ retry_cnt++; ++ } while (retry_cnt < 3); ++ ++ return err; ++} ++ ++TPM_RC ++TPM2_CreatePrimary (const TPMI_RH_HIERARCHY primaryHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_SENSITIVE_CREATE *inSensitive, ++ const TPM2B_PUBLIC *inPublic, ++ const TPM2B_DATA *outsideInfo, ++ const TPML_PCR_SELECTION *creationPCR, ++ TPM_HANDLE *objectHandle, ++ TPM2B_PUBLIC *outPublic, ++ TPM2B_CREATION_DATA *creationData, ++ TPM2B_DIGEST *creationHash, ++ TPMT_TK_CREATION *creationTicket, ++ TPM2B_NAME *name, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM_HANDLE objectHandleTmp; ++ TPM2B_PUBLIC outPublicTmp; ++ TPM2B_CREATION_DATA creationDataTmp; ++ TPM2B_DIGEST creationHashTmp; ++ TPMT_TK_CREATION creationTicketTmp; ++ TPM2B_NAME nameTmp; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ grub_uint32_t parameterSize; ++ ++ if (!inSensitive || !inPublic || !outsideInfo || !creationPCR) ++ return TPM_RC_VALUE; ++ ++ if (!objectHandle) ++ objectHandle = &objectHandleTmp; ++ if (!outPublic) ++ outPublic = &outPublicTmp; ++ if (!creationData) ++ creationData = &creationDataTmp; ++ if (!creationHash) ++ creationHash = &creationHashTmp; ++ if (!creationTicket) ++ creationTicket = &creationTicketTmp; ++ if (!name) ++ name = &nameTmp; ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (outPublic, 0, sizeof (*outPublic)); ++ grub_memset (creationData, 0, sizeof (*creationData)); ++ grub_memset (creationHash, 0, sizeof (*creationHash)); ++ grub_memset (creationTicket, 0, sizeof (*creationTicket)); ++ grub_memset (name, 0, sizeof (*name)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, primaryHandle); ++ if (authCommand) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (&in, inSensitive); ++ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic); ++ grub_tpm2_mu_TPM2B_Marshal (&in, outsideInfo->size, outsideInfo->buffer); ++ grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, creationPCR); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_CreatePrimary, &responseCode, &in, ++ &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ grub_tpm2_buffer_unpack_u32 (&out, objectHandle); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&out, outPublic); ++ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)creationData); ++ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)creationHash); ++ grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (&out, creationTicket); ++ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)name); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_StartAuthSession (const TPMI_DH_OBJECT tpmKey, ++ const TPMI_DH_ENTITY bind, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_NONCE *nonceCaller, ++ const TPM2B_ENCRYPTED_SECRET *encryptedSalt, ++ const TPM_SE sessionType, ++ const TPMT_SYM_DEF *symmetric, ++ const TPMI_ALG_HASH authHash, ++ TPMI_SH_AUTH_SESSION *sessionHandle, ++ TPM2B_NONCE *nonceTpm, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMI_SH_AUTH_SESSION sessionHandleTmp; ++ TPM2B_NONCE nonceTpmTmp; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ grub_uint32_t param_size; ++ ++ if (!nonceCaller || !symmetric) ++ return TPM_RC_VALUE; ++ ++ if (tpmKey == TPM_RH_NULL && ++ (encryptedSalt && encryptedSalt->size != 0)) ++ return TPM_RC_VALUE; ++ ++ if (!sessionHandle) ++ sessionHandle = &sessionHandleTmp; ++ if (!nonceTpm) ++ nonceTpm = &nonceTpmTmp; ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (sessionHandle, 0, sizeof (*sessionHandle)); ++ grub_memset (nonceTpm, 0, sizeof (*nonceTpm)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, tpmKey); ++ grub_tpm2_buffer_pack_u32 (&in, bind); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_tpm2_mu_TPM2B_Marshal (&in, nonceCaller->size, nonceCaller->buffer); ++ if (encryptedSalt) ++ grub_tpm2_mu_TPM2B_Marshal (&in, encryptedSalt->size, encryptedSalt->secret); ++ else ++ grub_tpm2_buffer_pack_u16 (&in, 0); ++ grub_tpm2_buffer_pack_u8 (&in, sessionType); ++ grub_tpm2_mu_TPMT_SYM_DEF_Marshal (&in, symmetric); ++ grub_tpm2_buffer_pack_u16 (&in, authHash); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_StartAuthSession, &responseCode, ++ &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ grub_tpm2_buffer_unpack_u32 (&out, sessionHandle); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)nonceTpm); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_PolicyPCR (const TPMI_SH_POLICY policySessions, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_DIGEST *pcrDigest, ++ const TPML_PCR_SELECTION *pcrs, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ grub_uint32_t param_size; ++ ++ if (!pcrs) ++ return TPM_RC_VALUE; ++ ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, policySessions); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ if (pcrDigest) ++ grub_tpm2_mu_TPM2B_Marshal (&in, pcrDigest->size, pcrDigest->buffer); ++ else ++ grub_tpm2_buffer_pack_u16 (&in, 0); ++ grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, pcrs); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_PolicyPCR, &responseCode, &in, ++ &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_ReadPublic (const TPMI_DH_OBJECT objectHandle, ++ const TPMS_AUTH_COMMAND* authCommand, ++ TPM2B_PUBLIC *outPublic) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ grub_uint32_t parameterSize; ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, objectHandle); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_ReadPublic, &responseCode, &in, ++ &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&out, outPublic); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_Load (const TPMI_DH_OBJECT parent_handle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_PRIVATE *inPrivate, ++ const TPM2B_PUBLIC *inPublic, ++ TPM_HANDLE *objectHandle, ++ TPM2B_NAME *name, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM_HANDLE objectHandleTmp; ++ TPM2B_NAME nonceTmp; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ grub_uint32_t param_size; ++ ++ if (!inPrivate || !inPublic) ++ return TPM_RC_VALUE; ++ ++ if (!objectHandle) ++ objectHandle = &objectHandleTmp; ++ if (!name) ++ name = &nonceTmp; ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (objectHandle, 0, sizeof (*objectHandle)); ++ grub_memset (name, 0, sizeof (*name)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, parent_handle); ++ if (authCommand) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_tpm2_mu_TPM2B_Marshal (&in, inPrivate->size, inPrivate->buffer); ++ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_Load, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ grub_tpm2_buffer_unpack_u32 (&out, objectHandle); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)name); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_Unseal (const TPMI_DH_OBJECT itemHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ TPM2B_SENSITIVE_DATA *outData, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM2B_SENSITIVE_DATA outDataTmp; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ grub_uint32_t param_size; ++ ++ if (!outData) ++ outData = &outDataTmp; ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (outData, 0, sizeof (*outData)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, itemHandle); ++ if (authCommand) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_Unseal, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ // Unmarhsal ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)outData); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_FlushContext (const TPMI_DH_CONTEXT handle) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM_RC responseCode; ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, handle); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (TPM_ST_NO_SESSIONS, TPM_CC_FlushContext, ++ &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand, ++ const TPML_PCR_SELECTION *pcrSelectionIn, ++ grub_uint32_t *pcrUpdateCounter, ++ TPML_PCR_SELECTION *pcrSelectionOut, ++ TPML_DIGEST *pcrValues, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ grub_uint32_t pcrUpdateCounterTmp; ++ TPML_PCR_SELECTION pcrSelectionOutTmp; ++ TPML_DIGEST pcrValuesTmp; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ grub_uint32_t parameterSize; ++ ++ if (!pcrSelectionIn) ++ return TPM_RC_VALUE; ++ ++ if (!pcrUpdateCounter) ++ pcrUpdateCounter = &pcrUpdateCounterTmp; ++ if (!pcrSelectionOut) ++ pcrSelectionOut = &pcrSelectionOutTmp; ++ if (!pcrValues) ++ pcrValues = &pcrValuesTmp; ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ if (authCommand) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, pcrSelectionIn); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_PCR_Read, &responseCode, &in, ++ &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_tpm2_buffer_unpack_u32 (&out, pcrUpdateCounter); ++ grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (&out, pcrSelectionOut); ++ grub_tpm2_mu_TPML_DIGEST_Unmarshal (&out, pcrValues); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_PolicyGetDigest (const TPMI_SH_POLICY policySession, ++ const TPMS_AUTH_COMMAND *authCommand, ++ TPM2B_DIGEST *policyDigest, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPM2B_DIGEST policyDigestTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ grub_uint32_t parameterSize; ++ ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ if (!policyDigest) ++ policyDigest = &policyDigestTmp; ++ ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ grub_memset (policyDigest, 0, sizeof (*policyDigest)); ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, policySession); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_PolicyGetDigest, &responseCode, ++ &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)policyDigest); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_Create (const TPMI_DH_OBJECT parentHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_SENSITIVE_CREATE *inSensitive, ++ const TPM2B_PUBLIC *inPublic, ++ const TPM2B_DATA *outsideInfo, ++ const TPML_PCR_SELECTION *creationPCR, ++ TPM2B_PRIVATE *outPrivate, ++ TPM2B_PUBLIC *outPublic, ++ TPM2B_CREATION_DATA *creationData, ++ TPM2B_DIGEST *creationHash, ++ TPMT_TK_CREATION *creationTicket, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM2B_PUBLIC outPublicTmp; ++ TPM2B_PRIVATE outPrivateTmp; ++ TPM2B_CREATION_DATA creationDataTmp; ++ TPM2B_DIGEST creationHashTmp; ++ TPMT_TK_CREATION creationTicketTmp; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS:TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ TPM_RC rc; ++ grub_uint32_t parameterSize; ++ ++ if (!inSensitive || !inPublic || !outsideInfo || !creationPCR) ++ return TPM_RC_VALUE; ++ ++ if (!outPrivate) ++ outPrivate = &outPrivateTmp; ++ if (!outPublic) ++ outPublic = &outPublicTmp; ++ if (!creationData) ++ creationData = &creationDataTmp; ++ if (!creationHash) ++ creationHash = &creationHashTmp; ++ if (!creationTicket) ++ creationTicket = &creationTicketTmp; ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (outPrivate, 0, sizeof (*outPrivate)); ++ grub_memset (outPublic, 0, sizeof (*outPublic)); ++ grub_memset (creationData, 0, sizeof (*creationData)); ++ grub_memset (creationHash, 0, sizeof (*creationHash)); ++ grub_memset (creationTicket, 0, sizeof (*creationTicket)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, parentHandle); ++ if (authCommand) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (&in, inSensitive); ++ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic); ++ grub_tpm2_mu_TPM2B_Marshal (&in, outsideInfo->size, outsideInfo->buffer); ++ grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&in, creationPCR); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_Create, &responseCode, &in, ++ &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)outPrivate); ++ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&out, outPublic); ++ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)creationData); ++ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)creationHash); ++ grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (&out, creationTicket); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_EvictControl (const TPMI_RH_PROVISION auth, ++ const TPMI_DH_OBJECT objectHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPMI_DH_PERSISTENT persistentHandle, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ TPM_RC rc; ++ grub_uint32_t parameterSize; ++ ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, auth); ++ grub_tpm2_buffer_pack_u32 (&in, objectHandle); ++ if (authCommand) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_tpm2_buffer_pack_u32 (&in, persistentHandle); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_EvictControl, &responseCode, &in, ++ &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ if (tag == TPM_ST_SESSIONS) ++ { ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); ++ } ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} +diff --git a/include/grub/tpm2/buffer.h b/include/grub/tpm2/buffer.h +new file mode 100644 +index 000000000..87dcd8d6c +--- /dev/null ++++ b/include/grub/tpm2/buffer.h +@@ -0,0 +1,65 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_TPM2_BUFFER_HEADER ++#define GRUB_TPM2_BUFFER_HEADER 1 ++ ++#include ++ ++#define GRUB_TPM2_BUFFER_CAPACITY 4096 ++ ++struct grub_tpm2_buffer ++{ ++ grub_uint8_t data[GRUB_TPM2_BUFFER_CAPACITY]; ++ grub_size_t size; ++ grub_size_t offset; ++ grub_size_t cap; ++ int error; ++}; ++typedef struct grub_tpm2_buffer *grub_tpm2_buffer_t; ++ ++void ++grub_tpm2_buffer_init (grub_tpm2_buffer_t buffer); ++ ++void ++grub_tpm2_buffer_pack (grub_tpm2_buffer_t buffer, const void* data, ++ grub_size_t size); ++ ++void ++grub_tpm2_buffer_pack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t value); ++ ++void ++grub_tpm2_buffer_pack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t value); ++ ++void ++grub_tpm2_buffer_pack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t value); ++ ++void ++grub_tpm2_buffer_unpack (grub_tpm2_buffer_t buffer, void* data, ++ grub_size_t size); ++ ++void ++grub_tpm2_buffer_unpack_u8 (grub_tpm2_buffer_t buffer, grub_uint8_t* value); ++ ++void ++grub_tpm2_buffer_unpack_u16 (grub_tpm2_buffer_t buffer, grub_uint16_t* value); ++ ++void ++grub_tpm2_buffer_unpack_u32 (grub_tpm2_buffer_t buffer, grub_uint32_t* value); ++ ++#endif /* ! GRUB_TPM2_BUFFER_HEADER */ +diff --git a/include/grub/tpm2/internal/functions.h b/include/grub/tpm2/internal/functions.h +new file mode 100644 +index 000000000..9380f26a2 +--- /dev/null ++++ b/include/grub/tpm2/internal/functions.h +@@ -0,0 +1,117 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER ++#define GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER 1 ++ ++#include ++ ++TPM_RC ++TPM2_CreatePrimary (const TPMI_RH_HIERARCHY primaryHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_SENSITIVE_CREATE *inSensitive, ++ const TPM2B_PUBLIC *inPublic, ++ const TPM2B_DATA *outsideInfo, ++ const TPML_PCR_SELECTION *creationPCR, ++ TPM_HANDLE *objectHandle, ++ TPM2B_PUBLIC *outPublic, ++ TPM2B_CREATION_DATA *creationData, ++ TPM2B_DIGEST *creationHash, ++ TPMT_TK_CREATION *creationTicket, ++ TPM2B_NAME *name, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_StartAuthSession (const TPMI_DH_OBJECT tpmKey, ++ const TPMI_DH_ENTITY bind, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_NONCE *nonceCaller, ++ const TPM2B_ENCRYPTED_SECRET *encryptedSalt, ++ const TPM_SE sessionType, ++ const TPMT_SYM_DEF *symmetric, ++ const TPMI_ALG_HASH authHash, ++ TPMI_SH_AUTH_SESSION *sessionHandle, ++ TPM2B_NONCE *nonceTpm, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_PolicyPCR (const TPMI_SH_POLICY policySession, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_DIGEST *pcrDigest, ++ const TPML_PCR_SELECTION *pcrs, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_ReadPublic (const TPMI_DH_OBJECT objectHandle, ++ const TPMS_AUTH_COMMAND* authCommand, ++ TPM2B_PUBLIC *outPublic); ++ ++TPM_RC ++TPM2_Load (const TPMI_DH_OBJECT parent_handle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_PRIVATE *inPrivate, ++ const TPM2B_PUBLIC *inPublic, ++ TPM_HANDLE *objectHandle, ++ TPM2B_NAME *name, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_Unseal (const TPMI_DH_OBJECT item_handle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ TPM2B_SENSITIVE_DATA *outData, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_FlushContext (const TPMI_DH_CONTEXT handle); ++ ++TPM_RC ++TPM2_PCR_Read (const TPMS_AUTH_COMMAND *authCommand, ++ const TPML_PCR_SELECTION *pcrSelectionIn, ++ grub_uint32_t *pcrUpdateCounter, ++ TPML_PCR_SELECTION *pcrSelectionOut, ++ TPML_DIGEST *pcrValues, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_PolicyGetDigest (const TPMI_SH_POLICY policySession, ++ const TPMS_AUTH_COMMAND *authCommand, ++ TPM2B_DIGEST *policyDigest, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_Create (const TPMI_DH_OBJECT parentHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_SENSITIVE_CREATE *inSensitive, ++ const TPM2B_PUBLIC *inPublic, ++ const TPM2B_DATA *outsideInfo, ++ const TPML_PCR_SELECTION *creationPCR, ++ TPM2B_PRIVATE *outPrivate, ++ TPM2B_PUBLIC *outPublic, ++ TPM2B_CREATION_DATA *creationData, ++ TPM2B_DIGEST *creationHash, ++ TPMT_TK_CREATION *creationTicket, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_EvictControl (const TPMI_RH_PROVISION auth, ++ const TPMI_DH_OBJECT objectHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPMI_DH_PERSISTENT persistentHandle, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++#endif /* ! GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER */ +diff --git a/include/grub/tpm2/internal/structs.h b/include/grub/tpm2/internal/structs.h +new file mode 100644 +index 000000000..72d71eb70 +--- /dev/null ++++ b/include/grub/tpm2/internal/structs.h +@@ -0,0 +1,675 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_TPM2_INTERNAL_STRUCTS_HEADER ++#define GRUB_TPM2_INTERNAL_STRUCTS_HEADER 1 ++ ++#include ++ ++/* TPMS_TAGGED_PROPERTY Structure */ ++struct TPMS_TAGGED_PROPERTY ++{ ++ TPM_PT property; ++ grub_uint32_t value; ++}; ++typedef struct TPMS_TAGGED_PROPERTY TPMS_TAGGED_PROPERTY; ++ ++/* TPML_TAGGED_TPM_PROPERTY Structure */ ++struct TPML_TAGGED_TPM_PROPERTY ++{ ++ grub_uint32_t count; ++ TPMS_TAGGED_PROPERTY tpmProperty[TPM_MAX_TPM_PROPERTIES]; ++}; ++typedef struct TPML_TAGGED_TPM_PROPERTY TPML_TAGGED_TPM_PROPERTY; ++ ++/* TPMU_CAPABILITIES Structure */ ++union TPMU_CAPABILITIES ++{ ++ TPML_TAGGED_TPM_PROPERTY tpmProperties; ++}; ++typedef union TPMU_CAPABILITIES TPMU_CAPABILITIES; ++ ++/* TPMS_CAPABILITY_DATA Structure */ ++struct TPMS_CAPABILITY_DATA ++{ ++ TPM_CAP capability; ++ TPMU_CAPABILITIES data; ++}; ++typedef struct TPMS_CAPABILITY_DATA TPMS_CAPABILITY_DATA; ++ ++/* TPMS_PCR_SELECT Structure */ ++struct TPMS_PCR_SELECT ++{ ++ grub_uint8_t sizeOfSelect; ++ grub_uint8_t pcrSelect[TPM_PCR_SELECT_MAX]; ++}; ++typedef struct TPMS_PCR_SELECT TPMS_PCR_SELECT; ++ ++/* TPMS_PCR_SELECTION Structure */ ++struct TPMS_PCR_SELECTION ++{ ++ TPMI_ALG_HASH hash; ++ grub_uint8_t sizeOfSelect; ++ grub_uint8_t pcrSelect[TPM_PCR_SELECT_MAX]; ++}; ++typedef struct TPMS_PCR_SELECTION TPMS_PCR_SELECTION; ++ ++static inline void TPMS_PCR_SELECTION_SelectPCR(TPMS_PCR_SELECTION* self, grub_uint32_t n) ++{ ++ self->pcrSelect[(n / 8)] |= (1 << (n % 8)); ++} ++ ++/* TPML_PCR_SELECTION Structure */ ++struct TPML_PCR_SELECTION ++{ ++ grub_uint32_t count; ++ TPMS_PCR_SELECTION pcrSelections[TPM_NUM_PCR_BANKS]; ++}; ++typedef struct TPML_PCR_SELECTION TPML_PCR_SELECTION; ++ ++/* TPMU_HA Structure */ ++union TPMU_HA ++{ ++ grub_uint8_t sha1[TPM_SHA1_DIGEST_SIZE]; ++ grub_uint8_t sha256[TPM_SHA256_DIGEST_SIZE]; ++ grub_uint8_t sha384[TPM_SHA384_DIGEST_SIZE]; ++ grub_uint8_t sha512[TPM_SHA512_DIGEST_SIZE]; ++ grub_uint8_t sm3_256[TPM_SM3_256_DIGEST_SIZE]; ++}; ++typedef union TPMU_HA TPMU_HA; ++ ++/* TPM2B Structure */ ++struct TPM2B ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[1]; ++}; ++typedef struct TPM2B TPM2B; ++ ++/* TPM2B_DIGEST Structure */ ++struct TPM2B_DIGEST ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[sizeof(TPMU_HA)]; ++}; ++typedef struct TPM2B_DIGEST TPM2B_DIGEST; ++ ++/* TPML_DIGEST Structure */ ++struct TPML_DIGEST ++{ ++ grub_uint32_t count; ++ TPM2B_DIGEST digests[8]; ++}; ++typedef struct TPML_DIGEST TPML_DIGEST; ++ ++/* TPM2B_NONCE Type */ ++typedef TPM2B_DIGEST TPM2B_NONCE; ++ ++/* TPMA_SESSION Structure */ ++struct TPMA_SESSION ++{ ++ unsigned int continueSession:1; ++ unsigned int auditExclusive:1; ++ unsigned int auditReset:1; ++ unsigned int reserved1:2; ++ unsigned int decrypt:1; ++ unsigned int encrypt:1; ++ unsigned int audit:1; ++ unsigned int reserved:24; ++}; ++typedef struct TPMA_SESSION TPMA_SESSION; ++ ++/* TPM2B_AUTH Type */ ++typedef TPM2B_DIGEST TPM2B_AUTH; ++ ++/* TPMS_AUTH_COMMAND Structure */ ++struct TPMS_AUTH_COMMAND ++{ ++ TPMI_SH_AUTH_SESSION sessionHandle; ++ TPM2B_NONCE nonce; ++ TPMA_SESSION sessionAttributes; ++ TPM2B_AUTH hmac; ++}; ++typedef struct TPMS_AUTH_COMMAND TPMS_AUTH_COMMAND; ++ ++/* TPMS_AUTH_RESPONSE Structure */ ++struct TPMS_AUTH_RESPONSE ++{ ++ TPM2B_NONCE nonce; ++ TPMA_SESSION sessionAttributes; ++ TPM2B_AUTH hmac; ++}; ++typedef struct TPMS_AUTH_RESPONSE TPMS_AUTH_RESPONSE; ++ ++/* TPM2B_SENSITIVE_DATA Structure */ ++struct TPM2B_SENSITIVE_DATA ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_SYM_DATA]; ++}; ++typedef struct TPM2B_SENSITIVE_DATA TPM2B_SENSITIVE_DATA; ++ ++/* TPMS_SENSITIVE_CREATE Structure */ ++struct TPMS_SENSITIVE_CREATE ++{ ++ TPM2B_AUTH userAuth; ++ TPM2B_SENSITIVE_DATA data; ++}; ++typedef struct TPMS_SENSITIVE_CREATE TPMS_SENSITIVE_CREATE; ++ ++/* TPM2B_SENSITIVE_CREATE Structure */ ++struct TPM2B_SENSITIVE_CREATE ++{ ++ grub_uint16_t size; ++ TPMS_SENSITIVE_CREATE sensitive; ++}; ++typedef struct TPM2B_SENSITIVE_CREATE TPM2B_SENSITIVE_CREATE; ++ ++/* TPMA_OBJECT Structure */ ++struct TPMA_OBJECT ++{ ++ unsigned int reserved1:1; ++ unsigned int fixedTPM:1; ++ unsigned int stClear:1; ++ unsigned int reserved2:1; ++ unsigned int fixedParent:1; ++ unsigned int sensitiveDataOrigin:1; ++ unsigned int userWithAuth:1; ++ unsigned int adminWithPolicy:1; ++ unsigned int reserved3:2; ++ unsigned int noDA:1; ++ unsigned int encryptedDuplication:1; ++ unsigned int reserved4:4; ++ unsigned int restricted:1; ++ unsigned int decrypt:1; ++ unsigned int sign:1; ++ unsigned int reserved5:13; ++}; ++typedef struct TPMA_OBJECT TPMA_OBJECT; ++ ++/* TPMS_SCHEME_HASH Structure */ ++struct TPMS_SCHEME_HASH ++{ ++ TPMI_ALG_HASH hashAlg; ++}; ++typedef struct TPMS_SCHEME_HASH TPMS_SCHEME_HASH; ++ ++/* TPMS_SCHEME_HASH Types */ ++typedef TPMS_SCHEME_HASH TPMS_KEY_SCHEME_ECDH; ++typedef TPMS_SCHEME_HASH TPMS_KEY_SCHEME_ECMQV; ++typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_RSASSA; ++typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_RSAPSS; ++typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_ECDSA; ++typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_ECDAA; ++typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_SM2; ++typedef TPMS_SCHEME_HASH TPMS_SIG_SCHEME_ECSCHNORR; ++typedef TPMS_SCHEME_HASH TPMS_ENC_SCHEME_RSAES; ++typedef TPMS_SCHEME_HASH TPMS_ENC_SCHEME_OAEP; ++typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF2; ++typedef TPMS_SCHEME_HASH TPMS_SCHEME_MGF1; ++typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF1_SP800_56A; ++typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF2; ++typedef TPMS_SCHEME_HASH TPMS_SCHEME_KDF1_SP800_108; ++ ++/* TPMS_SCHEME_HMAC Type */ ++typedef TPMS_SCHEME_HASH TPMS_SCHEME_HMAC; ++ ++/* TPMS_SCHEME_XOR Structure */ ++struct TPMS_SCHEME_XOR ++{ ++ TPMI_ALG_HASH hashAlg; ++ TPMI_ALG_KDF kdf; ++}; ++typedef struct TPMS_SCHEME_XOR TPMS_SCHEME_XOR; ++ ++/* TPMU_SCHEME_KEYEDHASH Union */ ++union TPMU_SCHEME_KEYEDHASH ++{ ++ TPMS_SCHEME_HMAC hmac; ++ TPMS_SCHEME_XOR exclusiveOr; ++}; ++typedef union TPMU_SCHEME_KEYEDHASH TPMU_SCHEME_KEYEDHASH; ++ ++/* TPMT_KEYEDHASH_SCHEME Structure */ ++struct TPMT_KEYEDHASH_SCHEME ++{ ++ TPMI_ALG_KEYEDHASH_SCHEME scheme; ++ TPMU_SCHEME_KEYEDHASH details; ++}; ++typedef struct TPMT_KEYEDHASH_SCHEME TPMT_KEYEDHASH_SCHEME; ++ ++/* TPMS_KEYEDHASH_PARMS Structure */ ++struct TPMS_KEYEDHASH_PARMS ++{ ++ TPMT_KEYEDHASH_SCHEME scheme; ++}; ++typedef struct TPMS_KEYEDHASH_PARMS TPMS_KEYEDHASH_PARMS; ++ ++/* TPMU_SYM_KEY_BITS Union */ ++union TPMU_SYM_KEY_BITS ++{ ++ TPM_KEY_BITS aes; ++ TPM_KEY_BITS exclusiveOr; ++ TPM_KEY_BITS sm4; ++ TPM_KEY_BITS camellia; ++}; ++typedef union TPMU_SYM_KEY_BITS TPMU_SYM_KEY_BITS; ++ ++/* TPMU_SYM_MODE Union */ ++union TPMU_SYM_MODE ++{ ++ TPMI_ALG_SYM_MODE aes; ++ TPMI_ALG_SYM_MODE sm4; ++ TPMI_ALG_SYM_MODE camellia; ++ TPMI_ALG_SYM_MODE sym; ++}; ++typedef union TPMU_SYM_MODE TPMU_SYM_MODE; ++ ++/* TPMT_SYM_DEF_OBJECT Structure */ ++struct TPMT_SYM_DEF_OBJECT ++{ ++ TPMI_ALG_SYM_OBJECT algorithm; ++ TPMU_SYM_KEY_BITS keyBits; ++ TPMU_SYM_MODE mode; ++}; ++typedef struct TPMT_SYM_DEF_OBJECT TPMT_SYM_DEF_OBJECT; ++ ++/* TPMS_SYMCIPHER_PARMS Structure */ ++struct TPMS_SYMCIPHER_PARMS ++{ ++ TPMT_SYM_DEF_OBJECT sym; ++}; ++typedef struct TPMS_SYMCIPHER_PARMS TPMS_SYMCIPHER_PARMS; ++ ++/* TPMU_ASYM_SCHEME Union */ ++union TPMU_ASYM_SCHEME ++{ ++ TPMS_KEY_SCHEME_ECDH ecdh; ++ TPMS_KEY_SCHEME_ECMQV ecmqv; ++ TPMS_SIG_SCHEME_RSASSA rsassa; ++ TPMS_SIG_SCHEME_RSAPSS rsapss; ++ TPMS_SIG_SCHEME_ECDSA ecdsa; ++ TPMS_SIG_SCHEME_ECDAA ecdaa; ++ TPMS_SIG_SCHEME_SM2 sm2; ++ TPMS_SIG_SCHEME_ECSCHNORR ecschnorr; ++ TPMS_ENC_SCHEME_RSAES rsaes; ++ TPMS_ENC_SCHEME_OAEP oaep; ++ TPMS_SCHEME_HASH anySig; ++ unsigned char padding[4]; ++}; ++typedef union TPMU_ASYM_SCHEME TPMU_ASYM_SCHEME; ++ ++/* TPMT_RSA_SCHEME Structure */ ++struct TPMT_RSA_SCHEME ++{ ++ TPMI_ALG_RSA_SCHEME scheme; ++ TPMU_ASYM_SCHEME details; ++}; ++typedef struct TPMT_RSA_SCHEME TPMT_RSA_SCHEME; ++ ++/* TPMS_RSA_PARMS Structure */ ++struct TPMS_RSA_PARMS ++{ ++ TPMT_SYM_DEF_OBJECT symmetric; ++ TPMT_RSA_SCHEME scheme; ++ TPM_KEY_BITS keyBits; ++ grub_uint32_t exponent; ++}; ++typedef struct TPMS_RSA_PARMS TPMS_RSA_PARMS; ++ ++/* TPMT_ECC_SCHEME Structure */ ++struct TPMT_ECC_SCHEME ++{ ++ TPMI_ALG_ECC_SCHEME scheme; ++ TPMU_ASYM_SCHEME details; ++}; ++typedef struct TPMT_ECC_SCHEME TPMT_ECC_SCHEME; ++ ++/* TPMU_KDF_SCHEME Union */ ++union TPMU_KDF_SCHEME ++{ ++ TPMS_SCHEME_MGF1 mgf1; ++ TPMS_SCHEME_KDF1_SP800_56A kdf1_sp800_56a; ++ TPMS_SCHEME_KDF2 kdf2; ++ TPMS_SCHEME_KDF1_SP800_108 kdf1_sp800_108; ++}; ++typedef union TPMU_KDF_SCHEME TPMU_KDF_SCHEME; ++ ++/* TPMT_KDF_SCHEME Structure */ ++struct TPMT_KDF_SCHEME ++{ ++ TPMI_ALG_KDF scheme; ++ TPMU_KDF_SCHEME details; ++}; ++typedef struct TPMT_KDF_SCHEME TPMT_KDF_SCHEME; ++ ++/* TPMS_ECC_PARMS Structure */ ++struct TPMS_ECC_PARMS ++{ ++ TPMT_SYM_DEF_OBJECT symmetric; ++ TPMT_ECC_SCHEME scheme; ++ TPMI_ECC_CURVE curveID; ++ TPMT_KDF_SCHEME kdf; ++}; ++typedef struct TPMS_ECC_PARMS TPMS_ECC_PARMS; ++ ++/* TPMT_ASYM_SCHEME Structure */ ++struct TPMT_ASYM_SCHEME ++{ ++ TPMI_ALG_ASYM_SCHEME scheme; ++ TPMU_ASYM_SCHEME details; ++}; ++typedef struct TPMT_ASYM_SCHEME TPMT_ASYM_SCHEME; ++ ++/* TPMS_ASYM_PARMS Structure */ ++struct TPMS_ASYM_PARMS ++{ ++ TPMT_SYM_DEF_OBJECT symmetric; ++ TPMT_ASYM_SCHEME scheme; ++}; ++typedef struct TPMS_ASYM_PARMS TPMS_ASYM_PARMS; ++ ++/* TPMU_PUBLIC_PARMS Union */ ++union TPMU_PUBLIC_PARMS ++{ ++ TPMS_KEYEDHASH_PARMS keyedHashDetail; ++ TPMS_SYMCIPHER_PARMS symDetail; ++ TPMS_RSA_PARMS rsaDetail; ++ TPMS_ECC_PARMS eccDetail; ++ TPMS_ASYM_PARMS asymDetail; ++}; ++typedef union TPMU_PUBLIC_PARMS TPMU_PUBLIC_PARMS; ++ ++/* TPM2B_PUBLIC_KEY_RSA Structure */ ++struct TPM2B_PUBLIC_KEY_RSA ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_RSA_KEY_BYTES]; ++}; ++typedef struct TPM2B_PUBLIC_KEY_RSA TPM2B_PUBLIC_KEY_RSA; ++ ++/* TPM2B_ECC_PARAMETER Structure */ ++struct TPM2B_ECC_PARAMETER ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_ECC_KEY_BYTES]; ++}; ++typedef struct TPM2B_ECC_PARAMETER TPM2B_ECC_PARAMETER; ++ ++/* TPMS_ECC_POINT Structure */ ++struct TPMS_ECC_POINT ++{ ++ TPM2B_ECC_PARAMETER x; ++ TPM2B_ECC_PARAMETER y; ++}; ++typedef struct TPMS_ECC_POINT TPMS_ECC_POINT; ++ ++/* TPMU_ENCRYPTED_SECRET Union */ ++union TPMU_ENCRYPTED_SECRET ++{ ++ grub_uint8_t ecc[sizeof(TPMS_ECC_POINT)]; ++ grub_uint8_t rsa[TPM_MAX_RSA_KEY_BYTES]; ++ grub_uint8_t symmetric[sizeof(TPM2B_DIGEST)]; ++ grub_uint8_t keyedHash[sizeof(TPM2B_DIGEST)]; ++}; ++typedef union TPMU_ENCRYPTED_SECRET TPMU_ENCRYPTED_SECRET; ++ ++/* TPM2B_ENCRYPTED_SECRET Structure */ ++struct TPM2B_ENCRYPTED_SECRET ++{ ++ grub_uint16_t size; ++ grub_uint8_t secret[sizeof(TPMU_ENCRYPTED_SECRET)]; ++}; ++typedef struct TPM2B_ENCRYPTED_SECRET TPM2B_ENCRYPTED_SECRET; ++ ++/* TPMU_PUBLIC_ID Union */ ++union TPMU_PUBLIC_ID ++{ ++ TPM2B_DIGEST keyedHash; ++ TPM2B_DIGEST sym; ++ TPM2B_PUBLIC_KEY_RSA rsa; ++ TPMS_ECC_POINT ecc; ++}; ++typedef union TPMU_PUBLIC_ID TPMU_PUBLIC_ID; ++ ++/* TPMT_PUBLIC Structure */ ++struct TPMT_PUBLIC ++{ ++ TPMI_ALG_PUBLIC type; ++ TPMI_ALG_HASH nameAlg; ++ TPMA_OBJECT objectAttributes; ++ TPM2B_DIGEST authPolicy; ++ TPMU_PUBLIC_PARMS parameters; ++ TPMU_PUBLIC_ID unique; ++}; ++typedef struct TPMT_PUBLIC TPMT_PUBLIC; ++ ++/* TPM2B_PUBLIC Structure */ ++struct TPM2B_PUBLIC ++{ ++ grub_uint16_t size; ++ TPMT_PUBLIC publicArea; ++}; ++typedef struct TPM2B_PUBLIC TPM2B_PUBLIC; ++ ++/* TPMT_HA Structure */ ++struct TPMT_HA ++{ ++ TPMI_ALG_HASH hashAlg; ++ TPMU_HA digest; ++}; ++typedef struct TPMT_HA TPMT_HA; ++ ++/* TPM2B_DATA Structure */ ++struct TPM2B_DATA ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[sizeof(TPMT_HA)]; ++}; ++typedef struct TPM2B_DATA TPM2B_DATA; ++ ++/* TPMA_LOCALITY Structure */ ++struct TPMA_LOCALITY ++{ ++ unsigned char TPM_LOC_ZERO:1; ++ unsigned char TPM_LOC_ONE:1; ++ unsigned char TPM_LOC_TWO:1; ++ unsigned char TPM_LOC_THREE:1; ++ unsigned char TPM_LOC_FOUR:1; ++ unsigned char Extended:3; ++}; ++typedef struct TPMA_LOCALITY TPMA_LOCALITY; ++ ++/* TPMU_NAME Union */ ++union TPMU_NAME ++{ ++ TPMT_HA digest; ++ TPM_HANDLE handle; ++}; ++typedef union TPMU_NAME TPMU_NAME; ++ ++/* TPM2B_NAME Structure */ ++struct TPM2B_NAME ++{ ++ grub_uint16_t size; ++ grub_uint8_t name[sizeof(TPMU_NAME)]; ++}; ++typedef struct TPM2B_NAME TPM2B_NAME; ++ ++/* TPMS_CREATION_DATA Structure */ ++struct TPMS_CREATION_DATA ++{ ++ TPML_PCR_SELECTION pcrSelect; ++ TPM2B_DIGEST pcrDigest; ++ TPMA_LOCALITY locality; ++ TPM_ALG_ID parentNameAlg; ++ TPM2B_NAME parentName; ++ TPM2B_NAME parentQualifiedName; ++ TPM2B_DATA outsideInfo; ++}; ++typedef struct TPMS_CREATION_DATA TPMS_CREATION_DATA; ++ ++/* TPM2B_CREATION_DATA Structure */ ++struct TPM2B_CREATION_DATA ++{ ++ grub_uint16_t size; ++ TPMS_CREATION_DATA creationData; ++}; ++typedef struct TPM2B_CREATION_DATA TPM2B_CREATION_DATA; ++ ++/* TPMT_SYM_DEF Structure */ ++struct TPMT_SYM_DEF ++{ ++ TPMI_ALG_SYM algorithm; ++ TPMU_SYM_KEY_BITS keyBits; ++ TPMU_SYM_MODE mode; ++}; ++typedef struct TPMT_SYM_DEF TPMT_SYM_DEF; ++ ++/* TPM2B_MAX_BUFFER Structure */ ++struct TPM2B_MAX_BUFFER ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_DIGEST_BUFFER]; ++}; ++typedef struct TPM2B_MAX_BUFFER TPM2B_MAX_BUFFER; ++ ++/* TPMT_TK_HASHCHECK Structure */ ++struct TPMT_TK_HASHCHECK ++{ ++ TPM_ST tag; ++ TPMI_RH_HIERARCHY hierarchy; ++ TPM2B_DIGEST digest; ++}; ++typedef struct TPMT_TK_HASHCHECK TPMT_TK_HASHCHECK; ++ ++/* TPM2B_SYM_KEY Structure */ ++struct TPM2B_SYM_KEY ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_SYM_KEY_BYTES]; ++}; ++typedef struct TPM2B_SYM_KEY TPM2B_SYM_KEY; ++ ++/* TPM2B_PRIVATE_KEY_RSA Structure */ ++struct TPM2B_PRIVATE_KEY_RSA ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_RSA_KEY_BYTES/2]; ++}; ++typedef struct TPM2B_PRIVATE_KEY_RSA TPM2B_PRIVATE_KEY_RSA; ++ ++/* TPM2B_PRIVATE_VENDOR_SPECIFIC Structure */ ++struct TPM2B_PRIVATE_VENDOR_SPECIFIC ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_PRIVATE_VENDOR_SPECIFIC_BYTES]; ++}; ++typedef struct TPM2B_PRIVATE_VENDOR_SPECIFIC TPM2B_PRIVATE_VENDOR_SPECIFIC; ++ ++/* TPM2B_PRIVATE_VENDOR_SPECIFIC Union */ ++union TPMU_SENSITIVE_COMPOSITE ++{ ++ TPM2B_PRIVATE_KEY_RSA rsa; ++ TPM2B_ECC_PARAMETER ecc; ++ TPM2B_SENSITIVE_DATA bits; ++ TPM2B_SYM_KEY sym; ++ TPM2B_PRIVATE_VENDOR_SPECIFIC any; ++}; ++typedef union TPMU_SENSITIVE_COMPOSITE TPMU_SENSITIVE_COMPOSITE; ++ ++/* TPMT_SENSITIVE Structure */ ++struct TPMT_SENSITIVE ++{ ++ TPMI_ALG_PUBLIC sensitiveType; ++ TPM2B_AUTH authValue; ++ TPM2B_DIGEST seedValue; ++ TPMU_SENSITIVE_COMPOSITE sensitive; ++}; ++typedef struct TPMT_SENSITIVE TPMT_SENSITIVE; ++ ++/* TPM2B_SENSITIVE Structure */ ++struct TPM2B_SENSITIVE ++{ ++ grub_uint16_t size; ++ TPMT_SENSITIVE sensitiveArea; ++}; ++typedef struct TPM2B_SENSITIVE TPM2B_SENSITIVE; ++ ++/* _PRIVATE Structure */ ++struct _PRIVATE ++{ ++ TPM2B_DIGEST integrityOuter; ++ TPM2B_DIGEST integrityInner; ++ TPM2B_SENSITIVE sensitive; ++}; ++typedef struct _PRIVATE _PRIVATE; ++ ++/* TPM2B_PRIVATE Structure */ ++struct TPM2B_PRIVATE ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[sizeof(_PRIVATE)]; ++}; ++typedef struct TPM2B_PRIVATE TPM2B_PRIVATE; ++ ++/* TPML_DIGEST_VALUES Structure */ ++struct TPML_DIGEST_VALUES ++{ ++ grub_uint16_t count; ++ TPMT_HA digests[TPM_NUM_PCR_BANKS]; ++}; ++typedef struct TPML_DIGEST_VALUES TPML_DIGEST_VALUES; ++ ++/* TPM2B_MAX_NV_BUFFER Structure */ ++struct TPM2B_MAX_NV_BUFFER ++{ ++ grub_uint16_t size; ++ grub_uint8_t buffer[TPM_MAX_NV_BUFFER_SIZE]; ++}; ++typedef struct TPM2B_MAX_NV_BUFFER TPM2B_MAX_NV_BUFFER; ++ ++/* TPMS_NV_PUBLIC Structure */ ++struct TPMS_NV_PUBLIC ++{ ++ TPMI_RH_NV_INDEX nvIndex; ++ TPMI_ALG_HASH nameAlg; ++ TPMA_NV attributes; ++ TPM2B_DIGEST authPolicy; ++ grub_uint16_t dataSize; ++}; ++typedef struct TPMS_NV_PUBLIC TPMS_NV_PUBLIC; ++ ++/* TPM2B_NV_PUBLIC Structure */ ++struct TPM2B_NV_PUBLIC ++{ ++ grub_uint16_t size; ++ TPMS_NV_PUBLIC nvPublic; ++}; ++typedef struct TPM2B_NV_PUBLIC TPM2B_NV_PUBLIC; ++ ++/* TPMT_TK_CREATION Structure */ ++struct TPMT_TK_CREATION ++{ ++ TPM_ST tag; ++ TPMI_RH_HIERARCHY hierarchy; ++ TPM2B_DIGEST digest; ++}; ++typedef struct TPMT_TK_CREATION TPMT_TK_CREATION; ++ ++#endif /* ! GRUB_TPM2_INTERNAL_STRUCTS_HEADER */ +diff --git a/include/grub/tpm2/internal/types.h b/include/grub/tpm2/internal/types.h +new file mode 100644 +index 000000000..9118cad5d +--- /dev/null ++++ b/include/grub/tpm2/internal/types.h +@@ -0,0 +1,370 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_TPM2_INTERNAL_TYPES_HEADER ++#define GRUB_TPM2_INTERNAL_TYPES_HEADER 1 ++ ++#include ++ ++/* TPM2_RC Constants */ ++typedef grub_uint32_t TPM_RC; ++ ++#define TPM_RC_1 ((TPM_RC) 0x100) ++#define TPM_RC_2 ((TPM_RC) 0x200) ++#define TPM_RC_3 ((TPM_RC) 0x300) ++#define TPM_RC_4 ((TPM_RC) 0x400) ++#define TPM_RC_5 ((TPM_RC) 0x500) ++#define TPM_RC_6 ((TPM_RC) 0x600) ++#define TPM_RC_7 ((TPM_RC) 0x700) ++#define TPM_RC_8 ((TPM_RC) 0x800) ++#define TPM_RC_9 ((TPM_RC) 0x900) ++#define TPM_RC_A ((TPM_RC) 0xA00) ++#define TPM_RC_ASYMMETRIC ((TPM_RC) 0x081) ++#define TPM_RC_ATTRIBUTES ((TPM_RC) 0x082) ++#define TPM_RC_AUTH_CONTEXT ((TPM_RC) 0x145) ++#define TPM_RC_AUTH_FAIL ((TPM_RC) 0x08E) ++#define TPM_RC_AUTH_MISSING ((TPM_RC) 0x125) ++#define TPM_RC_AUTHSIZE ((TPM_RC) 0x144) ++#define TPM_RC_AUTH_TYPE ((TPM_RC) 0x124) ++#define TPM_RC_AUTH_UNAVAILABLE ((TPM_RC) 0x12F) ++#define TPM_RC_B ((TPM_RC) 0xB00) ++#define TPM_RC_BAD_AUTH ((TPM_RC) 0x0A2) ++#define TPM_RC_BAD_CONTEXT ((TPM_RC) 0x150) ++#define TPM_RC_BAD_TAG ((TPM_RC) 0x01E) ++#define TPM_RC_BINDING ((TPM_RC) 0x0A5) ++#define TPM_RC_C ((TPM_RC) 0xC00) ++#define TPM_RC_CANCELED ((TPM_RC) 0x909) ++#define TPM_RC_COMMAND_CODE ((TPM_RC) 0x143) ++#define TPM_RC_COMMAND_SIZE ((TPM_RC) 0x142) ++#define TPM_RC_CONTEXT_GAP ((TPM_RC) 0x901) ++#define TPM_RC_CPHASH ((TPM_RC) 0x151) ++#define TPM_RC_CURVE ((TPM_RC) 0x0A6) ++#define TPM_RC_D ((TPM_RC) 0xD00) ++#define TPM_RC_DISABLED ((TPM_RC) 0x120) ++#define TPM_RC_E ((TPM_RC) 0xE00) ++#define TPM_RC_ECC_POINT ((TPM_RC) 0x0A7) ++#define TPM_RC_EXCLUSIVE ((TPM_RC) 0x121) ++#define TPM_RC_EXPIRED ((TPM_RC) 0x0A3) ++#define TPM_RC_F ((TPM_RC) 0xF00) ++#define TPM_RC_FAILURE ((TPM_RC) 0x101) ++#define TPM_RC_H ((TPM_RC) 0x000) ++#define TPM_RC_HANDLE ((TPM_RC) 0x08B) ++#define TPM_RC_HASH ((TPM_RC) 0x083) ++#define TPM_RC_HIERARCHY ((TPM_RC) 0x085) ++#define TPM_RC_HMAC ((TPM_RC) 0x119) ++#define TPM_RC_INITIALIZE ((TPM_RC) 0x100) ++#define TPM_RC_INSUFFICIENT ((TPM_RC) 0x09A) ++#define TPM_RC_INTEGRITY ((TPM_RC) 0x09F) ++#define TPM_RC_KDF ((TPM_RC) 0x08C) ++#define TPM_RC_KEY ((TPM_RC) 0x09C) ++#define TPM_RC_KEY_SIZE ((TPM_RC) 0x087) ++#define TPM_RC_LOCALITY ((TPM_RC) 0x907) ++#define TPM_RC_LOCKOUT ((TPM_RC) 0x921) ++#define TPM_RC_MEMORY ((TPM_RC) 0x904) ++#define TPM_RC_MGF ((TPM_RC) 0x088) ++#define TPM_RC_MODE ((TPM_RC) 0x089) ++#define TPM_RC_NEEDS_TEST ((TPM_RC) 0x153) ++#define TPM_RC_N_MASK ((TPM_RC) 0xF00) ++#define TPM_RC_NONCE ((TPM_RC) 0x08F) ++#define TPM_RC_NO_RESULT ((TPM_RC) 0x154) ++#define TPM_RC_NOT_USED ((TPM_RC) 0x97F) ++#define TPM_RC_NV_AUTHORIZATION ((TPM_RC) 0x149) ++#define TPM_RC_NV_DEFINED ((TPM_RC) 0x14C) ++#define TPM_RC_NV_LOCKED ((TPM_RC) 0x148) ++#define TPM_RC_NV_RANGE ((TPM_RC) 0x146) ++#define TPM_RC_NV_RATE ((TPM_RC) 0x920) ++#define TPM_RC_NV_SIZE ((TPM_RC) 0x147) ++#define TPM_RC_NV_SPACE ((TPM_RC) 0x14B) ++#define TPM_RC_NV_UNAVAILABLE ((TPM_RC) 0x923) ++#define TPM_RC_NV_UNINITIALIZED ((TPM_RC) 0x14A) ++#define TPM_RC_OBJECT_HANDLES ((TPM_RC) 0x906) ++#define TPM_RC_OBJECT_MEMORY ((TPM_RC) 0x902) ++#define TPM_RC_P ((TPM_RC) 0x040) ++#define TPM_RC_PARENT ((TPM_RC) 0x152) ++#define TPM_RC_PCR ((TPM_RC) 0x127) ++#define TPM_RC_PCR_CHANGED ((TPM_RC) 0x128) ++#define TPM_RC_POLICY ((TPM_RC) 0x126) ++#define TPM_RC_POLICY_CC ((TPM_RC) 0x0A4) ++#define TPM_RC_POLICY_FAIL ((TPM_RC) 0x09D) ++#define TPM_RC_PP ((TPM_RC) 0x090) ++#define TPM_RC_PRIVATE ((TPM_RC) 0x10B) ++#define TPM_RC_RANGE ((TPM_RC) 0x08D) ++#define TPM_RC_REBOOT ((TPM_RC) 0x130) ++#define TPM_RC_REFERENCE_H0 ((TPM_RC) 0x910) ++#define TPM_RC_REFERENCE_H1 ((TPM_RC) 0x911) ++#define TPM_RC_REFERENCE_H2 ((TPM_RC) 0x912) ++#define TPM_RC_REFERENCE_H3 ((TPM_RC) 0x913) ++#define TPM_RC_REFERENCE_H4 ((TPM_RC) 0x914) ++#define TPM_RC_REFERENCE_H5 ((TPM_RC) 0x915) ++#define TPM_RC_REFERENCE_H6 ((TPM_RC) 0x916) ++#define TPM_RC_REFERENCE_S0 ((TPM_RC) 0x918) ++#define TPM_RC_REFERENCE_S1 ((TPM_RC) 0x919) ++#define TPM_RC_REFERENCE_S2 ((TPM_RC) 0x91A) ++#define TPM_RC_REFERENCE_S3 ((TPM_RC) 0x91B) ++#define TPM_RC_REFERENCE_S4 ((TPM_RC) 0x91C) ++#define TPM_RC_REFERENCE_S5 ((TPM_RC) 0x91D) ++#define TPM_RC_REFERENCE_S6 ((TPM_RC) 0x91E) ++#define TPM_RC_RESERVED_BITS ((TPM_RC) 0x0A1) ++#define TPM_RC_RETRY ((TPM_RC) 0x922) ++#define TPM_RC_S ((TPM_RC) 0x800) ++#define TPM_RC_SCHEME ((TPM_RC) 0x092) ++#define TPM_RC_SELECTOR ((TPM_RC) 0x098) ++#define TPM_RC_SENSITIVE ((TPM_RC) 0x155) ++#define TPM_RC_SEQUENCE ((TPM_RC) 0x103) ++#define TPM_RC_SESSION_HANDLES ((TPM_RC) 0x905) ++#define TPM_RC_SESSION_MEMORY ((TPM_RC) 0x903) ++#define TPM_RC_SIGNATURE ((TPM_RC) 0x09B) ++#define TPM_RC_SIZE ((TPM_RC) 0x095) ++#define TPM_RC_SUCCESS ((TPM_RC) 0x000) ++#define TPM_RC_SYMMETRIC ((TPM_RC) 0x096) ++#define TPM_RC_TAG ((TPM_RC) 0x097) ++#define TPM_RC_TESTING ((TPM_RC) 0x90A) ++#define TPM_RC_TICKET ((TPM_RC) 0x0A0) ++#define TPM_RC_TOO_MANY_CONTEXTS ((TPM_RC) 0x12E) ++#define TPM_RC_TYPE ((TPM_RC) 0x08A) ++#define TPM_RC_UNBALANCED ((TPM_RC) 0x131) ++#define TPM_RC_UPGRADE ((TPM_RC) 0x12D) ++#define TPM_RC_VALUE ((TPM_RC) 0x084) ++#define TPM_RC_YIELDED ((TPM_RC) 0x908) ++ ++/* TPMA_NV Constants */ ++typedef grub_uint32_t TPMA_NV; ++ ++#define TPMA_NV_PPWRITE ((TPMA_NV) 0x00000001) ++#define TPMA_NV_OWNERWRITE ((TPMA_NV) 0x00000002) ++#define TPMA_NV_AUTHWRITE ((TPMA_NV) 0x00000004) ++#define TPMA_NV_POLICYWRITE ((TPMA_NV) 0x00000008) ++#define TPMA_NV_TPM2_NT_MASK ((TPMA_NV) 0x000000F0) ++#define TPMA_NV_TPM2_NT_SHIFT (4) ++#define TPMA_NV_RESERVED1_MASK ((TPMA_NV) 0x00000300) ++#define TPMA_NV_POLICY_DELETE ((TPMA_NV) 0x00000400) ++#define TPMA_NV_WRITELOCKED ((TPMA_NV) 0x00000800) ++#define TPMA_NV_WRITEALL ((TPMA_NV) 0x00001000) ++#define TPMA_NV_WRITEDEFINE ((TPMA_NV) 0x00002000) ++#define TPMA_NV_WRITE_STCLEAR ((TPMA_NV) 0x00004000) ++#define TPMA_NV_GLOBALLOCK ((TPMA_NV) 0x00008000) ++#define TPMA_NV_PPREAD ((TPMA_NV) 0x00010000) ++#define TPMA_NV_OWNERREAD ((TPMA_NV) 0x00020000) ++#define TPMA_NV_AUTHREAD ((TPMA_NV) 0x00040000) ++#define TPMA_NV_POLICYREAD ((TPMA_NV) 0x00080000) ++#define TPMA_NV_RESERVED2_MASK ((TPMA_NV) 0x01F00000) ++#define TPMA_NV_NO_DA ((TPMA_NV) 0x02000000) ++#define TPMA_NV_ORDERLY ((TPMA_NV) 0x04000000) ++#define TPMA_NV_CLEAR_STCLEAR ((TPMA_NV) 0x08000000) ++#define TPMA_NV_READLOCKED ((TPMA_NV) 0x10000000) ++#define TPMA_NV_WRITTEN ((TPMA_NV) 0x20000000) ++#define TPMA_NV_PLATFORMCREATE ((TPMA_NV) 0x40000000) ++#define TPMA_NV_READ_STCLEAR ((TPMA_NV) 0x80000000) ++ ++/* TPM_ALG_ID Constants */ ++typedef grub_uint16_t TPM_ALG_ID; ++ ++#define TPM_ALG_ERROR ((TPM_ALG_ID) 0x0000) ++#define TPM_ALG_AES ((TPM_ALG_ID) 0x0006) ++#define TPM_ALG_CAMELLIA ((TPM_ALG_ID) 0x0026) ++#define TPM_ALG_CBC ((TPM_ALG_ID) 0x0042) ++#define TPM_ALG_CFB ((TPM_ALG_ID) 0x0043) ++#define TPM_ALG_ECB ((TPM_ALG_ID) 0x0044) ++#define TPM_ALG_ECC ((TPM_ALG_ID) 0x0023) ++#define TPM_ALG_HMAC ((TPM_ALG_ID) 0x0005) ++#define TPM_ALG_KDF1_SP800_108 ((TPM_ALG_ID) 0x0022) ++#define TPM_ALG_KDF1_SP800_56A ((TPM_ALG_ID) 0x0020) ++#define TPM_ALG_KDF2 ((TPM_ALG_ID) 0x0021) ++#define TPM_ALG_KEYEDHASH ((TPM_ALG_ID) 0x0008) ++#define TPM_ALG_MGF1 ((TPM_ALG_ID) 0x0007) ++#define TPM_ALG_NULL ((TPM_ALG_ID) 0x0010) ++#define TPM_ALG_RSA ((TPM_ALG_ID) 0x0001) ++#define TPM_ALG_SHA1 ((TPM_ALG_ID) 0x0004) ++#define TPM_ALG_SHA256 ((TPM_ALG_ID) 0x000B) ++#define TPM_ALG_SHA384 ((TPM_ALG_ID) 0x000C) ++#define TPM_ALG_SHA512 ((TPM_ALG_ID) 0x000D) ++#define TPM_ALG_SM3_256 ((TPM_ALG_ID) 0x0012) ++#define TPM_ALG_SM4 ((TPM_ALG_ID) 0x0013) ++#define TPM_ALG_SYMCIPHER ((TPM_ALG_ID) 0x0025) ++#define TPM_ALG_XOR ((TPM_ALG_ID) 0x000A) ++ ++/* TPM_CAP Constants */ ++typedef grub_uint32_t TPM_CAP; ++ ++#define TPM_CAP_FIRST ((TPM_CAP) 0x00000000) ++#define TPM_CAP_ALGS ((TPM_CAP) 0x00000000) ++#define TPM_CAP_HANDLES ((TPM_CAP) 0x00000001) ++#define TPM_CAP_COMMANDS ((TPM_CAP) 0x00000002) ++#define TPM_CAP_PP_COMMANDS ((TPM_CAP) 0x00000003) ++#define TPM_CAP_AUDIT_COMMANDS ((TPM_CAP) 0x00000004) ++#define TPM_CAP_PCRS ((TPM_CAP) 0x00000005) ++#define TPM_CAP_TPM_PROPERTIES ((TPM_CAP) 0x00000006) ++#define TPM_CAP_PCR_PROPERTIES ((TPM_CAP) 0x00000007) ++#define TPM_CAP_ECC_CURVES ((TPM_CAP) 0x00000008) ++#define TPM_CAP_LAST ((TPM_CAP) 0x00000008) ++#define TPM_CAP_VENDOR_PROPERTY ((TPM_CAP) 0x00000100) ++ ++/* TPM_PT Constants */ ++typedef grub_uint32_t TPM_PT; ++ ++#define TPM_PT_NONE ((TPM_PT) 0x00000000) ++#define PT_GROUP ((TPM_PT) 0x00000100) ++#define PT_FIXED ((TPM_PT) (PT_GROUP * 1)) ++#define TPM_PT_FAMILY_INDICATOR ((TPM_PT) (PT_FIXED + 0)) ++#define TPM_PT_LEVEL ((TPM_PT) (PT_FIXED + 1)) ++#define TPM_PT_REVISION ((TPM_PT) (PT_FIXED + 2)) ++#define TPM_PT_DAY_OF_YEAR ((TPM_PT) (PT_FIXED + 3)) ++#define TPM_PT_YEAR ((TPM_PT) (PT_FIXED + 4)) ++#define TPM_PT_PCR_COUNT ((TPM_PT) (PT_FIXED + 18)) ++ ++/* TPM_SE Constants */ ++typedef grub_uint8_t TPM_SE; ++ ++#define TPM_SE_HMAC ((TPM_SE) 0x00) ++#define TPM_SE_POLICY ((TPM_SE) 0x01) ++#define TPM_SE_TRIAL ((TPM_SE) 0x03) ++ ++/* TPMI_YES_NO Constants */ ++typedef grub_uint8_t TPMI_YES_NO; ++ ++#define TPM_NO ((TPMI_YES_NO)0) ++#define TPM_YES ((TPMI_YES_NO)1) ++ ++/* TPM_ST Constants */ ++typedef grub_uint16_t TPM_ST; ++typedef TPM_ST TPMI_ST_COMMAND_TAG; ++ ++#define TPM_ST_NO_SESSIONS ((TPMI_ST_COMMAND_TAG) 0x8001) ++#define TPM_ST_SESSIONS ((TPMI_ST_COMMAND_TAG) 0x8002) ++ ++/* TPM_HANDLE Types */ ++typedef grub_uint32_t TPM_HANDLE; ++ ++typedef TPM_HANDLE TPMI_RH_HIERARCHY; ++typedef TPM_HANDLE TPMI_RH_LOCKOUT; ++typedef TPM_HANDLE TPMI_SH_AUTH_SESSION; ++typedef TPM_HANDLE TPMI_DH_CONTEXT; ++typedef TPM_HANDLE TPMI_DH_OBJECT; ++typedef TPM_HANDLE TPMI_DH_ENTITY; ++typedef TPM_HANDLE TPMI_SH_POLICY; ++typedef TPM_HANDLE TPMI_DH_PCR; ++typedef TPM_HANDLE TPMI_RH_NV_AUTH; ++typedef TPM_HANDLE TPMI_RH_NV_INDEX; ++ ++/* TPM_RH Constants */ ++typedef TPM_HANDLE TPM_RH; ++ ++#define TPM_RH_FIRST ((TPM_RH) 0x40000000) ++#define TPM_RH_SRK ((TPM_RH) 0x40000000) ++#define TPM_RH_OWNER ((TPM_RH) 0x40000001) ++#define TPM_RH_REVOKE ((TPM_RH) 0x40000002) ++#define TPM_RH_TRANSPORT ((TPM_RH) 0x40000003) ++#define TPM_RH_OPERATOR ((TPM_RH) 0x40000004) ++#define TPM_RH_ADMIN ((TPM_RH) 0x40000005) ++#define TPM_RH_EK ((TPM_RH) 0x40000006) ++#define TPM_RH_NULL ((TPM_RH) 0x40000007) ++#define TPM_RH_UNASSIGNED ((TPM_RH) 0x40000008) ++#define TPM_RS_PW ((TPM_RH) 0x40000009) ++#define TPM_RH_LOCKOUT ((TPM_RH) 0x4000000A) ++#define TPM_RH_ENDORSEMENT ((TPM_RH) 0x4000000B) ++#define TPM_RH_PLATFORM ((TPM_RH) 0x4000000C) ++#define TPM_RH_PLATFORM_NV ((TPM_RH) 0x4000000D) ++#define TPM_RH_AUTH_00 ((TPM_RH) 0x40000010) ++#define TPM_RH_AUTH_FF ((TPM_RH) 0x4000010F) ++#define TPM_RH_LAST ((TPM_RH) 0x4000010F) ++ ++/* TPM_ECC_CURVE Constants */ ++typedef grub_uint16_t TPM_ECC_CURVE; ++ ++#define TPM_ECC_NONE ((TPM_ECC_CURVE) 0x0000) ++#define TPM_ECC_NIST_P192 ((TPM_ECC_CURVE) 0x0001) ++#define TPM_ECC_NIST_P224 ((TPM_ECC_CURVE) 0x0002) ++#define TPM_ECC_NIST_P256 ((TPM_ECC_CURVE) 0x0003) ++#define TPM_ECC_NIST_P384 ((TPM_ECC_CURVE) 0x0004) ++#define TPM_ECC_NIST_P521 ((TPM_ECC_CURVE) 0x0005) ++#define TPM_ECC_BN_P256 ((TPM_ECC_CURVE) 0x0010) ++#define TPM_ECC_BN_P638 ((TPM_ECC_CURVE) 0x0011) ++#define TPM_ECC_SM2_P256 ((TPM_ECC_CURVE) 0x0020) ++ ++/* TPM_CC Constants */ ++typedef grub_uint32_t TPM_CC; ++ ++#define TPM_CC_EvictControl ((TPM_CC) 0x00000120) ++#define TPM_CC_CreatePrimary ((TPM_CC) 0x00000131) ++#define TPM_CC_Create ((TPM_CC) 0x00000153) ++#define TPM_CC_FlushContext ((TPM_CC) 0x00000165) ++#define TPM_CC_ReadPublic ((TPM_CC) 0x00000173) ++#define TPM_CC_StartAuthSession ((TPM_CC) 0x00000176) ++#define TPM_CC_PolicyPCR ((TPM_CC) 0x0000017f) ++#define TPM_CC_NV_Read ((TPM_CC) 0x0000014e) ++#define TPM_CC_NV_ReadPublic ((TPM_CC) 0x00000169) ++#define TPM_CC_GetCapability ((TPM_CC) 0x0000017a) ++#define TPM_CC_PCR_Read ((TPM_CC) 0x0000017e) ++#define TPM_CC_Load ((TPM_CC) 0x00000157) ++#define TPM_CC_Unseal ((TPM_CC) 0x0000015e) ++#define TPM_CC_PolicyGetDigest ((TPM_CC) 0x00000189) ++ ++/* Hash algorithm sizes */ ++#define TPM_SHA1_DIGEST_SIZE 20 ++#define TPM_SHA256_DIGEST_SIZE 32 ++#define TPM_SM3_256_DIGEST_SIZE 32 ++#define TPM_SHA384_DIGEST_SIZE 48 ++#define TPM_SHA512_DIGEST_SIZE 64 ++ ++/* Encryption algorithm sizes */ ++#define TPM_MAX_SYM_BLOCK_SIZE 16 ++#define TPM_MAX_SYM_DATA 256 ++#define TPM_MAX_ECC_KEY_BYTES 128 ++#define TPM_MAX_SYM_KEY_BYTES 32 ++#define TPM_MAX_RSA_KEY_BYTES 512 ++ ++/* Buffer Size Constants */ ++#define TPM_MAX_PCRS 32 ++#define TPM_NUM_PCR_BANKS 16 ++#define TPM_PCR_SELECT_MAX ((TPM_MAX_PCRS + 7) / 8) ++#define TPM_MAX_DIGEST_BUFFER 1024 ++#define TPM_MAX_TPM_PROPERTIES 8 ++#define TPM_MAX_NV_BUFFER_SIZE 2048 ++#define TPM_PRIVATE_VENDOR_SPECIFIC_BYTES 1280 ++ ++/* TPM_GENERATED Constants */ ++typedef grub_uint32_t TPM_GENERATED; ++ ++#define TPM_GENERATED_VALUE ((TPM_GENERATED) 0xff544347) ++ ++/* TPM_ALG_ID Types */ ++typedef TPM_ALG_ID TPMI_ALG_PUBLIC; ++typedef TPM_ALG_ID TPMI_ALG_HASH; ++typedef TPM_ALG_ID TPMI_ALG_KEYEDHASH_SCHEME; ++typedef TPM_ALG_ID TPMI_ALG_KDF; ++typedef TPM_ALG_ID TPMI_ALG_SYM_OBJECT; ++typedef TPM_ALG_ID TPMI_ALG_SYM_MODE; ++typedef TPM_ALG_ID TPMI_ALG_RSA_DECRYPT; ++typedef TPM_ALG_ID TPMI_ALG_ECC_SCHEME; ++typedef TPM_ALG_ID TPMI_ALG_ASYM_SCHEME; ++typedef TPM_ALG_ID TPMI_ALG_RSA_SCHEME; ++typedef TPM_ALG_ID TPMI_ALG_SYM; ++ ++/* TPM_KEY_BITS Type */ ++typedef grub_uint16_t TPM_KEY_BITS; ++ ++/* TPM_ECC_CURVE Types */ ++typedef TPM_ECC_CURVE TPMI_ECC_CURVE; ++ ++/* TPMI_RH_PROVISION Type */ ++typedef TPM_HANDLE TPMI_RH_PROVISION; ++ ++/* TPMI_RH_PROVISION Type */ ++typedef TPM_HANDLE TPMI_DH_PERSISTENT; ++ ++#endif /* ! GRUB_TPM2_INTERNAL_TYPES_HEADER */ +diff --git a/include/grub/tpm2/mu.h b/include/grub/tpm2/mu.h +new file mode 100644 +index 000000000..c545976db +--- /dev/null ++++ b/include/grub/tpm2/mu.h +@@ -0,0 +1,292 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_TPM2_MU_HEADER ++#define GRUB_TPM2_MU_HEADER 1 ++ ++#include ++#include ++ ++void ++grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (grub_tpm2_buffer_t buf, ++ const TPMS_AUTH_COMMAND* authCommand); ++ ++void ++grub_tpm2_mu_TPM2B_Marshal (grub_tpm2_buffer_t buf, ++ const grub_uint16_t size, ++ const grub_uint8_t* buffer); ++ ++void ++grub_tpm2_mu_TPMU_SYM_KEY_BITS_Marshal (grub_tpm2_buffer_t buf, ++ const TPMI_ALG_SYM_OBJECT algorithm, ++ const TPMU_SYM_KEY_BITS *p); ++ ++void ++grub_tpm2_mu_TPMU_SYM_MODE_Marshal (grub_tpm2_buffer_t buf, ++ const TPMI_ALG_SYM_OBJECT algorithm, ++ const TPMU_SYM_MODE *p); ++ ++void ++grub_tpm2_mu_TPMT_SYM_DEF_Marshal (grub_tpm2_buffer_t buf, ++ const TPMT_SYM_DEF *p); ++ ++void ++grub_tpm2_mu_TPMS_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buf, ++ const TPMS_PCR_SELECTION* pcrSelection); ++ ++void ++grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (grub_tpm2_buffer_t buf, ++ const TPML_PCR_SELECTION* pcrSelection); ++ ++void ++grub_tpm2_mu_TPMA_OBJECT_Marshal (grub_tpm2_buffer_t buf, ++ const TPMA_OBJECT *p); ++ ++void ++grub_tpm2_mu_TPMS_SCHEME_XOR_Marshal (grub_tpm2_buffer_t buf, ++ const TPMS_SCHEME_XOR *p); ++ ++void ++grub_tpm2_mu_TPMS_SCHEME_HMAC_Marshal (grub_tpm2_buffer_t buf, ++ const TPMS_SCHEME_HMAC *p); ++ ++void ++grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Marshal (grub_tpm2_buffer_t buf, ++ const TPMI_ALG_KEYEDHASH_SCHEME scheme, ++ const TPMU_SCHEME_KEYEDHASH *p); ++ ++void ++grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Marshal (grub_tpm2_buffer_t buf, ++ const TPMT_KEYEDHASH_SCHEME *p); ++ ++void ++grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Marshal (grub_tpm2_buffer_t buf, ++ const TPMS_KEYEDHASH_PARMS *p); ++ ++void ++grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Marshal (grub_tpm2_buffer_t buf, ++ const TPMT_SYM_DEF_OBJECT *p); ++ ++void ++grub_tpm2_mu_TPMU_ASYM_SCHEME_Marshal (grub_tpm2_buffer_t buf, ++ const TPMI_ALG_RSA_DECRYPT scheme, ++ const TPMU_ASYM_SCHEME *p); ++ ++void ++grub_tpm2_mu_TPMT_RSA_SCHEME_Marshal (grub_tpm2_buffer_t buf, ++ const TPMT_RSA_SCHEME *p); ++ ++void ++grub_tpm2_mu_TPMS_RSA_PARMS_Marshal (grub_tpm2_buffer_t buf, ++ const TPMS_RSA_PARMS *p); ++ ++void ++grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Marshal (grub_tpm2_buffer_t buf, ++ const TPMS_SYMCIPHER_PARMS *p); ++ ++void ++grub_tpm2_mu_TPMT_ECC_SCHEME_Marshal (grub_tpm2_buffer_t buf, ++ const TPMT_ECC_SCHEME *p); ++ ++void ++grub_tpm2_mu_TPMU_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buf, ++ const TPMI_ALG_KDF scheme, ++ const TPMU_KDF_SCHEME *p); ++ ++void ++grub_tpm2_mu_TPMT_KDF_SCHEME_Marshal (grub_tpm2_buffer_t buf, ++ const TPMT_KDF_SCHEME *p); ++ ++void ++grub_tpm2_mu_TPMS_ECC_PARMS_Marshal (grub_tpm2_buffer_t buf, ++ const TPMS_ECC_PARMS *p); ++ ++void ++grub_tpm2_mu_TPMU_PUBLIC_PARMS_Marshal (grub_tpm2_buffer_t buf, ++ const grub_uint32_t type, ++ const TPMU_PUBLIC_PARMS *p); ++ ++void ++grub_tpm2_mu_TPMS_ECC_POINT_Marshal (grub_tpm2_buffer_t buf, ++ const TPMS_ECC_POINT *p); ++ ++void ++grub_tpm2_mu_TPMU_PUBLIC_ID_Marshal (grub_tpm2_buffer_t buf, ++ const TPMI_ALG_PUBLIC type, ++ const TPMU_PUBLIC_ID *p); ++ ++void ++grub_tpm2_mu_TPMT_PUBLIC_Marshal (grub_tpm2_buffer_t buf, ++ const TPMT_PUBLIC *p); ++ ++void ++grub_tpm2_mu_TPM2B_PUBLIC_Marshal (grub_tpm2_buffer_t buf, ++ const TPM2B_PUBLIC *p); ++ ++void ++grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buf, ++ const TPMS_SENSITIVE_CREATE *p); ++ ++void ++grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buf, ++ const TPM2B_SENSITIVE_CREATE *sensitiveCreate); ++ ++void ++grub_tpm2_mu_TPM2B_Unmarshal (grub_tpm2_buffer_t buf, ++ TPM2B* p); ++ ++void ++grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_AUTH_RESPONSE* p); ++ ++void ++grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (grub_tpm2_buffer_t buf, ++ TPM2B_DIGEST* digest); ++ ++void ++grub_tpm2_mu_TPMA_OBJECT_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMA_OBJECT *p); ++ ++void ++grub_tpm2_mu_TPMS_SCHEME_HMAC_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_SCHEME_HMAC *p); ++ ++void ++grub_tpm2_mu_TPMS_SCHEME_XOR_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_SCHEME_XOR *p); ++ ++void ++grub_tpm2_mu_TPMU_SCHEME_KEYEDHASH_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMI_ALG_KEYEDHASH_SCHEME scheme, ++ TPMU_SCHEME_KEYEDHASH *p); ++ ++void ++grub_tpm2_mu_TPMT_KEYEDHASH_SCHEME_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMT_KEYEDHASH_SCHEME *p); ++ ++void ++grub_tpm2_mu_TPMS_KEYEDHASH_PARMS_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_KEYEDHASH_PARMS *p); ++ ++void ++grub_tpm2_mu_TPMU_SYM_KEY_BITS_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMI_ALG_SYM_OBJECT algorithm, ++ TPMU_SYM_KEY_BITS *p); ++ ++void ++grub_tpm2_mu_TPMU_SYM_MODE_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMI_ALG_SYM_OBJECT algorithm, ++ TPMU_SYM_MODE *p); ++ ++void ++grub_tpm2_mu_TPMT_SYM_DEF_OBJECT_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMT_SYM_DEF_OBJECT *p); ++ ++void ++grub_tpm2_mu_TPMS_SYMCIPHER_PARMS_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_SYMCIPHER_PARMS *p); ++ ++void ++grub_tpm2_mu_TPMU_ASYM_SCHEME_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMI_ALG_RSA_DECRYPT scheme, ++ TPMU_ASYM_SCHEME *p); ++ ++void ++grub_tpm2_mu_TPMT_RSA_SCHEME_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMT_RSA_SCHEME *p); ++ ++void ++grub_tpm2_mu_TPMS_RSA_PARMS_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_RSA_PARMS *p); ++ ++void ++grub_tpm2_mu_TPMT_ECC_SCHEME_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMT_ECC_SCHEME *p); ++ ++void ++grub_tpm2_mu_TPMU_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMI_ALG_KDF scheme, ++ TPMU_KDF_SCHEME *p); ++ ++void ++grub_tpm2_mu_TPMT_KDF_SCHEME_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMT_KDF_SCHEME *p); ++ ++void ++grub_tpm2_mu_TPMS_ECC_PARMS_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_ECC_PARMS *p); ++ ++void ++grub_tpm2_mu_TPMU_PUBLIC_PARMS_Unmarshal (grub_tpm2_buffer_t buf, ++ grub_uint32_t type, ++ TPMU_PUBLIC_PARMS *p); ++ ++void ++grub_tpm2_mu_TPMS_ECC_POINT_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_ECC_POINT *p); ++ ++void ++grub_tpm2_mu_TPMU_PUBLIC_ID_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMI_ALG_PUBLIC type, ++ TPMU_PUBLIC_ID *p); ++ ++void ++grub_tpm2_mu_TPMT_PUBLIC_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMT_PUBLIC *p); ++ ++void ++grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (grub_tpm2_buffer_t buf, ++ TPM2B_PUBLIC *p); ++ ++void ++grub_tpm2_mu_TPMS_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_NV_PUBLIC *p); ++ ++void ++grub_tpm2_mu_TPM2B_NV_PUBLIC_Unmarshal (grub_tpm2_buffer_t buf, ++ TPM2B_NV_PUBLIC *p); ++ ++void ++grub_tpm2_mu_TPM2B_NAME_Unmarshal (grub_tpm2_buffer_t buf, ++ TPM2B_NAME *n); ++ ++void ++grub_tpm2_mu_TPMS_TAGGED_PROPERTY_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_TAGGED_PROPERTY* property); ++ ++void ++grub_tpm2_mu_TPMS_CAPABILITY_DATA_tpmProperties_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_CAPABILITY_DATA* capabilityData); ++ ++void ++grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMT_TK_CREATION *p); ++ ++void ++grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_PCR_SELECTION* pcrSelection); ++ ++void ++grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf, ++ TPML_PCR_SELECTION* pcrSelection); ++ ++void ++grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buf, ++ TPML_DIGEST* digest); ++ ++#endif /* ! GRUB_TPM2_MU_HEADER */ +diff --git a/include/grub/tpm2/tcg2.h b/include/grub/tpm2/tcg2.h +new file mode 100644 +index 000000000..553b3fd93 +--- /dev/null ++++ b/include/grub/tpm2/tcg2.h +@@ -0,0 +1,34 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_TPM2_TCG2_HEADER ++#define GRUB_TPM2_TCG2_HEADER 1 ++ ++#include ++#include ++ ++grub_err_t ++grub_tcg2_get_max_output_size (grub_size_t *size); ++ ++grub_err_t ++grub_tcg2_submit_command (grub_size_t input_size, ++ grub_uint8_t *input, ++ grub_size_t output_size, ++ grub_uint8_t *output); ++ ++#endif /* ! GRUB_TPM2_TCG2_HEADER */ +diff --git a/include/grub/tpm2/tpm2.h b/include/grub/tpm2/tpm2.h +new file mode 100644 +index 000000000..cfdc9edcd +--- /dev/null ++++ b/include/grub/tpm2/tpm2.h +@@ -0,0 +1,34 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_TPM2_TPM2_HEADER ++#define GRUB_TPM2_TPM2_HEADER 1 ++ ++#include ++#include ++#include ++ ++/* Well-Known Windows SRK handle */ ++#define TPM2_SRK_HANDLE 0x81000001 ++ ++typedef struct TPM2_SEALED_KEY { ++ TPM2B_PUBLIC public; ++ TPM2B_PRIVATE private; ++} TPM2_SEALED_KEY; ++ ++#endif /* ! GRUB_TPM2_TPM2_HEADER */ +-- +2.35.3 + diff --git a/0002-tpm2-Add-more-marshal-unmarshal-functions.patch b/0002-tpm2-Add-more-marshal-unmarshal-functions.patch new file mode 100644 index 0000000000000000000000000000000000000000..c8079c138ea30e27b833df3467c9783e658b7c5a --- /dev/null +++ b/0002-tpm2-Add-more-marshal-unmarshal-functions.patch @@ -0,0 +1,427 @@ +From 1d34522075949581ccb34a08dd73607566517824 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Tue, 7 Feb 2023 18:33:42 +0800 +Subject: [PATCH 2/4] tpm2: Add more marshal/unmarshal functions + +Add a few more marshal/unmarshal functions to support authorized policy. + +* Marshal: + grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal() + grub_tpm2_mu_TPMT_SENSITIVE_Marshal() + grub_tpm2_mu_TPM2B_SENSITIVE_Marshal() + grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal() + grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal() + grub_tpm2_mu_TPMU_HA_Marshal() + grub_tpm2_mu_TPMT_HA_Marshal() + grub_tpm2_mu_TPMU_SIGNATURE_Marshal() + grub_tpm2_mu_TPMT_SIGNATURE_Marshal() + grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal() + +* Unmarshal: + grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal() + grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal() + grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal() + grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal() + grub_tpm2_mu_TPMU_HA_Unmarshal() + grub_tpm2_mu_TPMT_HA_Unmarshal() + grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal() + grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal() + +Signed-off-by: Gary Lin +--- + grub-core/tpm2/mu.c | 262 +++++++++++++++++++++++++++++++++++++++++ + include/grub/tpm2/mu.h | 75 ++++++++++++ + 2 files changed, 337 insertions(+) + +diff --git a/grub-core/tpm2/mu.c b/grub-core/tpm2/mu.c +index 1617f37cd..3a9a3c1be 100644 +--- a/grub-core/tpm2/mu.c ++++ b/grub-core/tpm2/mu.c +@@ -383,6 +383,49 @@ grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, + grub_tpm2_mu_TPM2B_Marshal (buffer, p->data.size, p->data.buffer); + } + ++void ++grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_PUBLIC type, ++ const TPMU_SENSITIVE_COMPOSITE *p) ++{ ++ switch(type) ++ { ++ case TPM_ALG_RSA: ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer); ++ break; ++ case TPM_ALG_ECC: ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->ecc.size, p->ecc.buffer); ++ break; ++ case TPM_ALG_KEYEDHASH: ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->bits.size, p->bits.buffer); ++ break; ++ case TPM_ALG_SYMCIPHER: ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer); ++ break; ++ default: ++ buffer->error = 1; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_SENSITIVE *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->sensitiveType); ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->authValue.size, p->authValue.buffer); ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->seedValue.size, p->seedValue.buffer); ++ grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (buffer, p->sensitiveType, ++ &p->sensitive); ++} ++ ++void ++grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPM2B_SENSITIVE *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->size); ++ grub_tpm2_mu_TPMT_SENSITIVE_Marshal (buffer, &p->sensitiveArea); ++} ++ + void + grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, + const TPM2B_SENSITIVE_CREATE *sensitiveCreate) +@@ -405,6 +448,113 @@ grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer, + grub_tpm2_buffer_pack_u16 (buffer, 0); + } + ++void ++grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SIGNATURE_RSA *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->hash); ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->sig.size, p->sig.buffer); ++} ++ ++void ++grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMS_SIGNATURE_ECC *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->hash); ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->signatureR.size, p->signatureR.buffer); ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->signatureS.size, p->signatureS.buffer); ++} ++ ++void ++grub_tpm2_mu_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_HASH hashAlg, ++ const TPMU_HA *p) ++{ ++ switch (hashAlg) ++ { ++ case TPM_ALG_SHA1: ++ for (grub_uint16_t i = 0; i < TPM_SHA1_DIGEST_SIZE; i++) ++ grub_tpm2_buffer_pack_u8 (buffer, p->sha1[i]); ++ break; ++ case TPM_ALG_SHA256: ++ for (grub_uint16_t i = 0; i < TPM_SHA256_DIGEST_SIZE; i++) ++ grub_tpm2_buffer_pack_u8 (buffer, p->sha256[i]); ++ break; ++ case TPM_ALG_SHA384: ++ for (grub_uint16_t i = 0; i < TPM_SHA384_DIGEST_SIZE; i++) ++ grub_tpm2_buffer_pack_u8 (buffer, p->sha384[i]); ++ break; ++ case TPM_ALG_SHA512: ++ for (grub_uint16_t i = 0; i < TPM_SHA512_DIGEST_SIZE; i++) ++ grub_tpm2_buffer_pack_u8 (buffer, p->sha512[i]); ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_HA *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg); ++ grub_tpm2_mu_TPMU_HA_Marshal (buffer, p->hashAlg, &p->digest); ++} ++ ++void ++grub_tpm2_mu_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMI_ALG_SIG_SCHEME sigAlg, ++ const TPMU_SIGNATURE *p) ++{ ++ switch (sigAlg) ++ { ++ case TPM_ALG_RSASSA: ++ grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsassa); ++ break; ++ case TPM_ALG_RSAPSS: ++ grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsapss); ++ break; ++ case TPM_ALG_ECDSA: ++ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdsa); ++ break; ++ case TPM_ALG_ECDAA: ++ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdaa); ++ break; ++ case TPM_ALG_SM2: ++ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->sm2); ++ break; ++ case TPM_ALG_ECSCHNORR: ++ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecschnorr); ++ break; ++ case TPM_ALG_HMAC: ++ grub_tpm2_mu_TPMT_HA_Marshal (buffer, &p->hmac); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_SIGNATURE *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->sigAlg); ++ grub_tpm2_mu_TPMU_SIGNATURE_Marshal (buffer, p->sigAlg, &p->signature); ++} ++ ++void ++grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer, ++ const TPMT_TK_VERIFIED *p) ++{ ++ grub_tpm2_buffer_pack_u16 (buffer, p->tag); ++ grub_tpm2_buffer_pack_u32 (buffer, p->hierarchy); ++ grub_tpm2_mu_TPM2B_Marshal (buffer, p->digest.size, p->digest.buffer); ++} ++ + void + grub_tpm2_mu_TPM2B_Unmarshal (grub_tpm2_buffer_t buffer, + TPM2B* p) +@@ -775,6 +925,24 @@ grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer, + grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->digest); + } + ++void ++grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_TK_HASHCHECK *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); ++ grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->digest); ++} ++ ++void ++grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_TK_VERIFIED *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->tag); ++ grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy); ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->digest); ++} ++ + void + grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf, + TPMS_PCR_SELECTION* pcrSelection) +@@ -805,3 +973,97 @@ grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buf, + for (grub_uint32_t i = 0; i < digest->count; i++) + grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buf, &digest->digests[i]); + } ++ ++void ++grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SIGNATURE_RSA *rsa) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &rsa->hash); ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*)&rsa->sig); ++} ++ ++void ++grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMS_SIGNATURE_ECC *ecc) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &ecc->hash); ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*)&ecc->signatureR); ++ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*)&ecc->signatureS); ++} ++ ++void ++grub_tpm2_mu_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_HASH hashAlg, ++ TPMU_HA *p) ++{ ++ switch (hashAlg) ++ { ++ case TPM_ALG_SHA1: ++ grub_tpm2_buffer_unpack (buffer, &p->sha1, TPM_SHA1_DIGEST_SIZE); ++ break; ++ case TPM_ALG_SHA256: ++ grub_tpm2_buffer_unpack (buffer, &p->sha256, TPM_SHA256_DIGEST_SIZE); ++ break; ++ case TPM_ALG_SHA384: ++ grub_tpm2_buffer_unpack (buffer, &p->sha384, TPM_SHA384_DIGEST_SIZE); ++ break; ++ case TPM_ALG_SHA512: ++ grub_tpm2_buffer_unpack (buffer, &p->sha512, TPM_SHA512_DIGEST_SIZE); ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_HA *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg); ++ grub_tpm2_mu_TPMU_HA_Unmarshal (buffer, p->hashAlg, &p->digest); ++} ++ ++void ++grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMI_ALG_SIG_SCHEME sigAlg, ++ TPMU_SIGNATURE *p) ++{ ++ switch (sigAlg) ++ { ++ case TPM_ALG_RSASSA: ++ grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsassa); ++ break; ++ case TPM_ALG_RSAPSS: ++ grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsapss); ++ break; ++ case TPM_ALG_ECDSA: ++ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdsa); ++ break; ++ case TPM_ALG_ECDAA: ++ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdaa); ++ break; ++ case TPM_ALG_SM2: ++ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->sm2); ++ break; ++ case TPM_ALG_ECSCHNORR: ++ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecschnorr); ++ break; ++ case TPM_ALG_HMAC: ++ grub_tpm2_mu_TPMT_HA_Unmarshal (buffer, &p->hmac); ++ break; ++ case TPM_ALG_NULL: ++ break; ++ default: ++ buffer->error = 1; ++ break; ++ } ++} ++ ++void ++grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer, ++ TPMT_SIGNATURE *p) ++{ ++ grub_tpm2_buffer_unpack_u16 (buffer, &p->sigAlg); ++ grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (buffer, p->sigAlg, &p->signature); ++} +diff --git a/include/grub/tpm2/mu.h b/include/grub/tpm2/mu.h +index c545976db..afb842ab5 100644 +--- a/include/grub/tpm2/mu.h ++++ b/include/grub/tpm2/mu.h +@@ -147,6 +147,47 @@ grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buf, + const TPM2B_SENSITIVE_CREATE *sensitiveCreate); + + void ++grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buf, ++ const TPMI_ALG_PUBLIC type, ++ const TPMU_SENSITIVE_COMPOSITE *p); ++void ++grub_tpm2_mu_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buf, ++ const TPMT_SENSITIVE *p); ++ ++void ++grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buf, ++ const TPM2B_SENSITIVE *p); ++ ++void ++grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buf, ++ const TPMS_SIGNATURE_RSA *p); ++ ++void ++grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buf, ++ const TPMS_SIGNATURE_ECC *p); ++ ++void ++grub_tpm2_mu_TPMU_HA_Marshal (grub_tpm2_buffer_t buf, ++ const TPMI_ALG_HASH hashAlg, ++ const TPMU_HA *p); ++ ++void ++grub_tpm2_mu_TPMT_HA_Marshal (grub_tpm2_buffer_t buf, ++ const TPMT_HA *p); ++ ++void ++grub_tpm2_mu_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buf, ++ const TPMI_ALG_SIG_SCHEME sigAlg, ++ const TPMU_SIGNATURE *p); ++ ++void ++grub_tpm2_mu_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buf, ++ const TPMT_SIGNATURE *p); ++ ++void ++grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buf, ++ const TPMT_TK_VERIFIED *p); ++void + grub_tpm2_mu_TPM2B_Unmarshal (grub_tpm2_buffer_t buf, + TPM2B* p); + +@@ -277,6 +318,14 @@ void + grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buf, + TPMT_TK_CREATION *p); + ++void ++grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMT_TK_HASHCHECK *p); ++ ++void ++grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMT_TK_VERIFIED *p); ++ + void + grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf, + TPMS_PCR_SELECTION* pcrSelection); +@@ -289,4 +338,30 @@ void + grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buf, + TPML_DIGEST* digest); + ++void ++grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_SIGNATURE_RSA *p); ++ ++void ++grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMS_SIGNATURE_ECC *p); ++ ++void ++grub_tpm2_mu_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMI_ALG_HASH hashAlg, ++ TPMU_HA *p); ++ ++void ++grub_tpm2_mu_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMT_HA *p); ++ ++void ++grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMI_ALG_SIG_SCHEME sigAlg, ++ TPMU_SIGNATURE *p); ++ ++void ++grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buf, ++ TPMT_SIGNATURE *p); ++ + #endif /* ! GRUB_TPM2_MU_HEADER */ +-- +2.35.3 + diff --git a/0009-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch b/0003-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch similarity index 73% rename from 0009-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch rename to 0003-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch index f3aae38990761f1ebbfbf16e0d2c98b73cdf185f..bb987edef7fcdac090ec70dd0efdbb54c91a31f6 100644 --- a/0009-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch +++ b/0003-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch @@ -1,46 +1,20 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 25069a23257ba9c6db644bbe6114dafb879063e5 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 8 Jul 2019 12:32:37 +0200 -Subject: [PATCH] Handle multi-arch (64-on-32) boot in linuxefi loader. +Subject: [PATCH 03/11] Handle multi-arch (64-on-32) boot in linuxefi loader. Allow booting 64-bit kernels on 32-bit EFI on x86. Signed-off-by: Peter Jones --- - grub-core/loader/efi/linux.c | 9 +++- - grub-core/loader/i386/efi/linux.c | 110 ++++++++++++++++++++++++++------------ - include/grub/i386/linux.h | 7 ++- - 3 files changed, 89 insertions(+), 37 deletions(-) + grub-core/loader/efi/linux.c | 11 ++- + grub-core/loader/i386/efi/linux.c | 127 +++++++++++++++++++----------- + include/grub/i386/linux.h | 7 +- + 3 files changed, 97 insertions(+), 48 deletions(-) -diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c -index c8ecce6dfd0..0622dfa48d4 100644 ---- a/grub-core/loader/efi/linux.c -+++ b/grub-core/loader/efi/linux.c -@@ -69,12 +69,17 @@ grub_linuxefi_secure_validate (void *data, grub_uint32_t size) - 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, -+grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset, - void *kernel_params) - { - handover_func hf; -+ int offset = 0; - -- hf = (handover_func)((char *)kernel_addr + offset); -+#ifdef __x86_64__ -+ offset = 512; -+#endif -+ -+ hf = (handover_func)((char *)kernel_addr + handover_offset + offset); - hf (grub_efi_image_handle, grub_efi_system_table, kernel_params); - - return GRUB_ERR_BUG; -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 6b24cbb9483..3017d0f3e52 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c -@@ -44,14 +44,10 @@ static char *linux_cmdline; +@@ -44,14 +44,10 @@ static grub_err_t grub_linuxefi_boot (void) { @@ -57,7 +31,7 @@ index 6b24cbb9483..3017d0f3e52 100644 params); } -@@ -153,14 +149,20 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), +@@ -147,14 +143,20 @@ return grub_errno; } @@ -77,10 +51,10 @@ index 6b24cbb9483..3017d0f3e52 100644 + grub_ssize_t start, filelen; void *kernel = NULL; + int setup_header_end_offset; - int rc; + grub_err_t err; grub_dl_ref (my_mod); -@@ -200,48 +202,79 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -185,45 +187,79 @@ goto fail; } @@ -94,14 +68,12 @@ index 6b24cbb9483..3017d0f3e52 100644 goto fail; } -- grub_dprintf ("linux", "params = %lx\n", (unsigned long) params); +- grub_memset (params, 0, 16384); + grub_dprintf ("linux", "params = %p\n", params); -- grub_memset (params, 0, 16384); +- grub_memcpy (&lh, kernel, sizeof (lh)); + grub_memset (params, 0, sizeof(*params)); -- grub_memcpy (&lh, kernel, sizeof (lh)); -- - if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) + setup_header_end_offset = *((grub_uint8_t *)kernel + 0x201); + grub_dprintf ("linux", "copying %lu bytes from %p to %p\n", @@ -145,6 +117,8 @@ index 6b24cbb9483..3017d0f3e52 100644 goto fail; } +- linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, +- BYTES_TO_PAGES(lh.cmdline_size + 1)); +#if defined(__x86_64__) || defined(__aarch64__) + grub_dprintf ("linux", "checking lh->xloadflags\n"); + if (!(lh->xloadflags & LINUX_XLF_KERNEL_64)) @@ -153,7 +127,7 @@ index 6b24cbb9483..3017d0f3e52 100644 + goto fail; + } +#endif -+ + +#if defined(__i386__) + if ((lh->xloadflags & LINUX_XLF_KERNEL_64) && + !(lh->xloadflags & LINUX_XLF_EFI_HANDOVER_32)) @@ -164,21 +138,21 @@ index 6b24cbb9483..3017d0f3e52 100644 + } +#endif + - grub_dprintf ("linux", "setting up cmdline\n"); - linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, -- BYTES_TO_PAGES(lh.cmdline_size + 1)); -- ++ grub_dprintf ("linux", "setting up cmdline\n"); ++ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, + BYTES_TO_PAGES(lh->cmdline_size + 1)); if (!linux_cmdline) { grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); -@@ -254,22 +287,24 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -233,27 +269,26 @@ grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, + err = grub_create_loader_cmdline (argc, argv, linux_cmdline + sizeof (LINUX_IMAGE) - 1, - lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1), + lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1), GRUB_VERIFY_KERNEL_CMDLINE); + if (err) + goto fail; - lh.cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline; + grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline); @@ -193,19 +167,23 @@ index 6b24cbb9483..3017d0f3e52 100644 - len = grub_file_size(file) - start; + start = (lh->setup_sects + 1) * 512; -- kernel_mem = grub_efi_allocate_pages_max(lh.pref_address, -- BYTES_TO_PAGES(lh.init_size)); +- kernel_mem = grub_efi_allocate_fixed (lh.pref_address, +- BYTES_TO_PAGES(lh.init_size)); + kernel_mem = grub_efi_allocate_pages_max(lh->pref_address, + BYTES_TO_PAGES(lh->init_size)); if (!kernel_mem) - kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, +- { +- grub_errno = GRUB_ERR_NONE; +- kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, - BYTES_TO_PAGES(lh.init_size)); +- } ++ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, + BYTES_TO_PAGES(lh->init_size)); if (!kernel_mem) { -@@ -277,14 +312,21 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -261,21 +296,23 @@ goto fail; } @@ -218,47 +196,82 @@ index 6b24cbb9483..3017d0f3e52 100644 + lh->code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem; - lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; -- grub_memcpy (params, &lh, 2 * 512); +- /* Grub linuxefi erroneously initialize linux's boot_params with non-zero values. (bsc#1025563) + grub_memcpy (kernel_mem, (char *)kernel + start, filelen - start); -- params->type_of_loader = 0x21; +- From https://www.kernel.org/doc/Documentation/x86/boot.txt: +- The memory for struct boot_params could be allocated anywhere (even above 4G) +- and initialized to all zero. +- Then, the setup header at offset 0x01f1 of kernel image on should be +- loaded into struct boot_params and examined. */ +- grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x01f1); + grub_dprintf ("linux", "setting lh->type_of_loader\n"); + lh->type_of_loader = 0x6; -+ + +- params->type_of_loader = 0x21; + grub_dprintf ("linux", "setting lh->ext_loader_{type,ver}\n"); + params->ext_loader_type = 0; + params->ext_loader_ver = 2; - grub_dprintf("linux", "kernel_mem: %p handover_offset: %08x\n", - kernel_mem, handover_offset); ++ grub_dprintf("linux", "kernel_mem: %p handover_offset: %08x\n", ++ kernel_mem, handover_offset); + + fail: -@@ -301,10 +343,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -291,8 +328,10 @@ loaded = 0; } - if (linux_cmdline && !loaded) +- grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1)); + if (linux_cmdline && lh && !loaded) - grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) - linux_cmdline, -- BYTES_TO_PAGES(lh.cmdline_size + 1)); ++ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) ++ linux_cmdline, + BYTES_TO_PAGES(lh->cmdline_size + 1)); if (kernel_mem && !loaded) - grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, -diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h -index eddf9251d9a..25ef52c04eb 100644 + grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h -@@ -138,7 +138,12 @@ struct linux_i386_kernel_header +@@ -148,6 +148,11 @@ grub_uint32_t kernel_alignment; grub_uint8_t relocatable; grub_uint8_t min_alignment; -- grub_uint8_t pad[2]; +#define LINUX_XLF_KERNEL_64 (1<<0) +#define LINUX_XLF_CAN_BE_LOADED_ABOVE_4G (1<<1) +#define LINUX_XLF_EFI_HANDOVER_32 (1<<2) +#define LINUX_XLF_EFI_HANDOVER_64 (1<<3) +#define LINUX_XLF_EFI_KEXEC (1<<4) -+ grub_uint16_t xloadflags; + grub_uint16_t xloadflags; grub_uint32_t cmdline_size; grub_uint32_t hardware_subarch; - grub_uint64_t hardware_subarch_data; +--- a/grub-core/loader/efi/linux_boot.c ++++ b/grub-core/loader/efi/linux_boot.c +@@ -30,11 +30,16 @@ + 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, ++grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset, + void *kernel_params) + { + grub_efi_loaded_image_t *loaded_image = NULL; + handover_func hf; ++ int offset = 0; ++ ++#ifdef __x86_64__ ++ offset = 512; ++#endif + + /* + * Since the EFI loader is not calling the LoadImage() and StartImage() +@@ -48,8 +53,8 @@ + 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); ++ kernel_addr, (void *)(grub_efi_uintn_t)handover_offset, kernel_params); ++ hf = (handover_func)((char *)kernel_addr + handover_offset + offset); + hf (grub_efi_image_handle, grub_efi_system_table, kernel_params); + + return GRUB_ERR_BUG; diff --git a/0097-Make-grub_error-more-verbose.patch b/0003-Make-grub_error-more-verbose.patch similarity index 70% rename from 0097-Make-grub_error-more-verbose.patch rename to 0003-Make-grub_error-more-verbose.patch index 2492e9f689c7c4c1dff34193317668148eba9d79..4dfb07a1bb11bd5a6ec818e48b317e7898c5aaf4 100644 --- a/0097-Make-grub_error-more-verbose.patch +++ b/0003-Make-grub_error-more-verbose.patch @@ -1,19 +1,18 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 3526c4e467ee01a3cfd2f4d627433d078a1ab780 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Mon, 27 Aug 2018 13:14:06 -0400 -Subject: [PATCH] Make grub_error() more verbose +Subject: [PATCH 3/9] Make grub_error() more verbose Signed-off-by: Peter Jones --- - grub-core/kern/err.c | 13 +++++++++++-- - include/grub/err.h | 8 ++++++-- - 2 files changed, 17 insertions(+), 4 deletions(-) + 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/err.c b/grub-core/kern/err.c -index 53c734de70e..aebfe0cf839 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]; +@@ -33,15 +33,24 @@ static int grub_error_stack_pos; static int grub_error_stack_assert; @@ -40,21 +39,18 @@ index 53c734de70e..aebfe0cf839 100644 va_end (ap); return n; -diff --git a/include/grub/err.h b/include/grub/err.h -index b08d5d0de4c..c0f90ef07c8 100644 --- a/include/grub/err.h +++ b/include/grub/err.h -@@ -85,8 +85,12 @@ struct grub_error_saved +@@ -86,8 +86,11 @@ 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, ...) - __attribute__ ((format (GNU_PRINTF, 2, 3))); +grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *file, const int line, const char *fmt, ...) -+ __attribute__ ((format (GNU_PRINTF, 4, 5))); ++ __attribute__ ((format (GNU_PRINTF, 4, 5))); + +#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); diff --git a/0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch b/0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch new file mode 100644 index 0000000000000000000000000000000000000000..3c42a63deea1322fd47a032bc38bdeffb391fc83 --- /dev/null +++ b/0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch @@ -0,0 +1,117 @@ +From 6c8d390809956d355fed8bc830f64e86838e3e82 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Sat, 18 Nov 2023 21:42:00 +0800 +Subject: [PATCH 3/4] Restrict 'ls' and auto file completion on cryptodisk + print + +The 'ls' command allows file listing, while file completion assists in +providing matched file names by partially inputting via the TAB key. +Both functionalities should be restricted when the disk is automatically +unlocked for the same reasons as highlighted in the previous patch +addressing the limitation on file access to the cryptodisk. + +Given that no file is explicitly opened for listing, employing file +filters becomes impractical. Consequently, this patch focuses on +modifying relevant routines separately to incorporate necessary checks. +The objective is to introduce measures that prevent 'ls' and auto file +completion from accessing encrypted data when the disk is automatically +unlocked. + +By implementing these modifications, any attempt to utilize 'ls' or file +completion on the cryptodisk will result in an "Access Denied: +prohibited to browse encrypted data" error message, thus effectively +alerting the user about the restricted access. + +While protecting content within disk files from viewing is essential, +it's equally crucial to restrict access to in-memory content. This +includes prohibiting access to the decrypted in-memory copies of disk +files. + +This enhancement aims to fortify security protocols by extending +restrictions to additional functionalities beyond direct file access. + +Signed-Off-by Michael Chang +--- + grub-core/commands/ls.c | 8 ++++++++ + grub-core/commands/minicmd.c | 6 ++++++ + grub-core/kern/corecmd.c | 8 ++++++++ + grub-core/normal/completion.c | 8 ++++++++ + 4 files changed, 30 insertions(+) + +diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c +index 8e98c73cc..aeb336a73 100644 +--- a/grub-core/commands/ls.c ++++ b/grub-core/commands/ls.c +@@ -183,6 +183,14 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human) + if (! dev) + goto fail; + ++ if (dev->disk && ++ grub_disk_is_crypto (dev->disk) && ++ grub_file_filters[GRUB_FILE_FILTER_NOCAT]) ++ { ++ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content")); ++ goto fail; ++ } ++ + fs = grub_fs_probe (dev); + path = grub_strchr (dirname, ')'); + if (! path) +diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c +index fa498931e..8f2ac0539 100644 +--- a/grub-core/commands/minicmd.c ++++ b/grub-core/commands/minicmd.c +@@ -101,6 +101,12 @@ grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)), + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, "no address specified"); + ++ /* NOCAT filter is applied to prevent cat alike command from revealing file ++ * content, the dump command should also be prohibited to revealing memory ++ * content as well */ ++ if (grub_file_filters[GRUB_FILE_FILTER_NOCAT]) ++ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited by security policy")); ++ + #if GRUB_CPU_SIZEOF_VOID_P == GRUB_CPU_SIZEOF_LONG + #define grub_strtoaddr grub_strtoul + #else +diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c +index 62d434ba9..b639bc3ae 100644 +--- a/grub-core/kern/corecmd.c ++++ b/grub-core/kern/corecmd.c +@@ -135,6 +135,14 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)), + if (! dev) + goto fail; + ++ if (dev->disk && ++ grub_disk_is_crypto (dev->disk) && ++ grub_file_filters[GRUB_FILE_FILTER_NOCAT]) ++ { ++ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content")); ++ goto fail; ++ } ++ + fs = grub_fs_probe (dev); + path = grub_strchr (argv[0], ')'); + if (! path) +diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c +index 18cadfa85..d003ec37d 100644 +--- a/grub-core/normal/completion.c ++++ b/grub-core/normal/completion.c +@@ -259,6 +259,14 @@ complete_file (void) + goto fail; + } + ++ if (dev->disk && ++ grub_disk_is_crypto (dev->disk) && ++ grub_file_filters[GRUB_FILE_FILTER_NOCAT]) ++ { ++ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content")); ++ goto fail; ++ } ++ + fs = grub_fs_probe (dev); + if (! fs) + { +-- +2.42.1 + diff --git a/0003-Revert-templates-Disable-the-os-prober-by-default.patch b/0003-Revert-templates-Disable-the-os-prober-by-default.patch deleted file mode 100644 index 68cacfca1bead3a89fecede8564df9c71cb49f7b..0000000000000000000000000000000000000000 --- a/0003-Revert-templates-Disable-the-os-prober-by-default.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Fri, 11 Jun 2021 12:10:58 +0200 -Subject: [PATCH] Revert "templates: Disable the os-prober by default" - -This reverts commit e346414725a70e5c74ee87ca14e580c66f517666. ---- - docs/grub.texi | 18 ++++++++---------- - util/grub.d/30_os-prober.in | 5 +---- - 2 files changed, 9 insertions(+), 14 deletions(-) - -diff --git a/docs/grub.texi b/docs/grub.texi -index f8b4b3b21a7..69f08d289f9 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -1519,13 +1519,10 @@ boot sequence. If you have problems, set this option to @samp{text} and - GRUB will tell Linux to boot in normal text mode. - - @item GRUB_DISABLE_OS_PROBER --The @command{grub-mkconfig} has a feature to use the external --@command{os-prober} program to discover other operating systems installed on --the same machine and generate appropriate menu entries for them. It is disabled --by default since automatic and silent execution of @command{os-prober}, and --creating boot entries based on that data, is a potential attack vector. Set --this option to @samp{false} to enable this feature in the --@command{grub-mkconfig} command. -+Normally, @command{grub-mkconfig} will try to use the external -+@command{os-prober} program, if installed, to discover other operating -+systems installed on the same system and generate appropriate menu entries -+for them. Set this option to @samp{true} to disable this. - - @item GRUB_OS_PROBER_SKIP_LIST - List of space-separated FS UUIDs of filesystems to be ignored from os-prober -@@ -1853,9 +1850,10 @@ than zero; otherwise 0. - @section Multi-boot manual config - - Currently autogenerating config files for multi-boot environments depends on --os-prober and has several shortcomings. Due to that it is disabled by default. --It is advised to use the power of GRUB syntax and do it yourself. A possible --configuration is detailed here, feel free to adjust to your needs. -+os-prober and has several shortcomings. While fixing it is scheduled for the -+next release, meanwhile you can make use of the power of GRUB syntax and do it -+yourself. A possible configuration is detailed here, feel free to adjust to your -+needs. - - First create a separate GRUB partition, big enough to hold GRUB. Some of the - following entries show how to load OS installer images from this same partition, -diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in -index 80685b15f4d..1b91c102f35 100644 ---- a/util/grub.d/30_os-prober.in -+++ b/util/grub.d/30_os-prober.in -@@ -26,8 +26,7 @@ export TEXTDOMAINDIR="@localedir@" - - . "$pkgdatadir/grub-mkconfig_lib" - --if [ "x${GRUB_DISABLE_OS_PROBER}" = "xfalse" ]; then -- gettext_printf "os-prober will not be executed to detect other bootable partitions.\nSystems on them will not be added to the GRUB boot configuration.\nCheck GRUB_DISABLE_OS_PROBER documentation entry.\n" -+if [ "x${GRUB_DISABLE_OS_PROBER}" = "xtrue" ]; then - exit 0 - fi - -@@ -40,8 +39,6 @@ OSPROBED="`os-prober | tr ' ' '^' | paste -s -d ' '`" - if [ -z "${OSPROBED}" ] ; then - # empty os-prober output, nothing doing - exit 0 --else -- grub_warn "$(gettext_printf "os-prober was executed to detect other bootable partitions.\nIt's output will be used to detect bootable binaries on them and create new boot entries.")" - fi - - osx_entry() { diff --git a/0076-bootp-New-net_bootp6-command.patch b/0003-bootp-New-net_bootp6-command.patch similarity index 63% rename from 0076-bootp-New-net_bootp6-command.patch rename to 0003-bootp-New-net_bootp6-command.patch index 21b3871bf51e027c408a1cd9f8ac6f31ef70a71a..6b98cd2687c17d5cec9b60abef8b2c44344e9e8d 100644 --- a/0076-bootp-New-net_bootp6-command.patch +++ b/0003-bootp-New-net_bootp6-command.patch @@ -1,25 +1,24 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From f6c8c7985fd88fc89cd49227c9e74feaf58cfdd6 Mon Sep 17 00:00:00 2001 From: Michael Chang -Date: Wed, 10 Jul 2019 15:42:36 +0200 -Subject: [PATCH] bootp: New net_bootp6 command +Date: Sun, 10 Jul 2016 23:46:06 +0800 +Subject: [PATCH 3/8] bootp: New net_bootp6 command Implement new net_bootp6 command for IPv6 network auto configuration via the DHCPv6 protocol (RFC3315). Signed-off-by: Michael Chang Signed-off-by: Ken Lin -[pjones: Put back our code to add a local route] -Signed-off-by: Peter Jones + +V1: + * Use grub_calloc for overflow check and return NULL when it would + occur. + --- - grub-core/net/bootp.c | 1059 ++++++++++++++++++++++++++++++------ - grub-core/net/drivers/efi/efinet.c | 20 +- - grub-core/net/ip.c | 39 ++ - include/grub/efi/api.h | 2 +- - include/grub/net.h | 91 ++-- - 5 files changed, 1002 insertions(+), 209 deletions(-) + grub-core/net/bootp.c | 908 +++++++++++++++++++++++++++++++++++++++++++++++++- + grub-core/net/ip.c | 39 +++ + include/grub/net.h | 72 ++++ + 3 files changed, 1018 insertions(+), 1 deletion(-) -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index 08b6b2b5d6c..fe93b80f1cf 100644 --- a/grub-core/net/bootp.c +++ b/grub-core/net/bootp.c @@ -24,6 +24,98 @@ @@ -121,7 +120,7 @@ index 08b6b2b5d6c..fe93b80f1cf 100644 struct grub_dhcp_discover_options { -@@ -604,6 +696,584 @@ out: +@@ -610,6 +702,578 @@ return err; } @@ -269,7 +268,7 @@ index 08b6b2b5d6c..fe93b80f1cf 100644 + break; + } + dhcp6->num_dns_server = ln = len >> 4; -+ dhcp6->dns_server_addrs = la = grub_zalloc (ln * sizeof (*la)); ++ dhcp6->dns_server_addrs = la = grub_calloc (ln, sizeof (*la)); + + for (po = opt->data; ln > 0; po += 0x10, la++, ln--) + { @@ -372,7 +371,6 @@ index 08b6b2b5d6c..fe93b80f1cf 100644 +} + +static grub_dhcp6_session_t grub_dhcp6_sessions; -+#define FOR_DHCP6_SESSIONS_SAFE(var, next) FOR_LIST_ELEMENTS_SAFE (var, next, grub_dhcp6_sessions) +#define FOR_DHCP6_SESSIONS(var) FOR_LIST_ELEMENTS (var, grub_dhcp6_sessions) + +static void @@ -427,7 +425,7 @@ index 08b6b2b5d6c..fe93b80f1cf 100644 + grub_dhcp6_session_t se; + struct grub_datetime date; + grub_err_t err; -+ grub_int32_t t = 0; ++ grub_int64_t t = 0; + + se = grub_malloc (sizeof (*se)); + @@ -464,13 +462,13 @@ index 08b6b2b5d6c..fe93b80f1cf 100644 +static void +grub_dhcp6_session_remove_all (void) +{ -+ grub_dhcp6_session_t se, next; ++ grub_dhcp6_session_t se; + -+ FOR_DHCP6_SESSIONS_SAFE (se, next) ++ FOR_DHCP6_SESSIONS (se) + { + grub_dhcp6_session_remove (se); ++ se = grub_dhcp6_sessions; + } -+ grub_dhcp6_sessions = NULL; +} + +static grub_err_t @@ -664,7 +662,6 @@ index 08b6b2b5d6c..fe93b80f1cf 100644 +{ + struct grub_net_network_level_interface *inf; + grub_dhcp6_options_t dhcp6; -+ int mask = -1; + + dhcp6 = grub_dhcp6_options_get (v6h, size); + if (!dhcp6) @@ -696,23 +693,19 @@ index 08b6b2b5d6c..fe93b80f1cf 100644 + } + + grub_dhcp6_options_free (dhcp6); -+ -+ if (inf) -+ grub_net_add_ipv6_local (inf, mask); -+ + return inf; +} + /* * This is called directly from net/ip.c:handle_dgram(), because those * BOOTP/DHCP packets are a bit special due to their improper -@@ -672,6 +1342,77 @@ grub_net_process_dhcp (struct grub_net_buff *nb, +@@ -678,6 +1342,77 @@ } } +grub_err_t +grub_net_process_dhcp6 (struct grub_net_buff *nb, -+ struct grub_net_card *card __attribute__ ((unused))) ++ struct grub_net_card *card __attribute__ ((unused))) +{ + const struct grub_net_dhcp6_packet *v6h; + grub_dhcp6_session_t se; @@ -735,9 +728,9 @@ index 08b6b2b5d6c..fe93b80f1cf 100644 + FOR_DHCP6_SESSIONS (se) + { + if (se->transaction_id == v6h->transaction_id && -+ grub_memcmp (options->client_duid, &se->duid, sizeof (se->duid)) == 0 && -+ se->iaid == options->iaid) -+ break; ++ grub_memcmp (options->client_duid, &se->duid, sizeof (se->duid)) == 0 && ++ se->iaid == options->iaid) ++ break; + } + + if (!se) @@ -750,11 +743,11 @@ index 08b6b2b5d6c..fe93b80f1cf 100644 + if (v6h->message_type == GRUB_NET_DHCP6_ADVERTISE) + { + if (se->adv) -+ { -+ grub_dprintf ("bootp", "Skipped DHCPv6 Advertised .. \n"); -+ grub_dhcp6_options_free (options); -+ return GRUB_ERR_NONE; -+ } ++ { ++ grub_dprintf ("bootp", "Skipped DHCPv6 Advertised .. \n"); ++ grub_dhcp6_options_free (options); ++ return GRUB_ERR_NONE; ++ } + + se->adv = options; + return grub_dhcp6_session_send_request (se); @@ -762,11 +755,11 @@ index 08b6b2b5d6c..fe93b80f1cf 100644 + else if (v6h->message_type == GRUB_NET_DHCP6_REPLY) + { + if (!se->adv) -+ { -+ grub_dprintf ("bootp", "Skipped DHCPv6 Reply .. \n"); -+ grub_dhcp6_options_free (options); -+ return GRUB_ERR_NONE; -+ } ++ { ++ grub_dprintf ("bootp", "Skipped DHCPv6 Reply .. \n"); ++ grub_dhcp6_options_free (options); ++ return GRUB_ERR_NONE; ++ } + + se->reply = options; + grub_dhcp6_session_configure_network (se); @@ -784,342 +777,183 @@ index 08b6b2b5d6c..fe93b80f1cf 100644 static grub_err_t grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)), int argc, char **args) -@@ -897,180 +1638,174 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), +@@ -903,7 +1638,174 @@ return err; } -static grub_command_t cmd_getdhcp, cmd_bootp, cmd_dhcp; -- --struct grub_net_network_level_interface * --grub_net_configure_by_dhcpv6_ack (const char *name, -- struct grub_net_card *card, -- grub_net_interface_flags_t flags -- __attribute__((__unused__)), -- const grub_net_link_level_address_t *hwaddr, -- const struct grub_net_dhcpv6_packet *packet, -- int is_def, char **device, char **path) +static grub_err_t +grub_cmd_bootp6 (struct grub_command *cmd __attribute__ ((unused)), -+ int argc, char **args) - { -- struct grub_net_network_level_interface *inter = NULL; -- struct grub_net_network_level_address addr; -- int mask = -1; ++ int argc, char **args) ++{ + struct grub_net_card *card; + grub_uint32_t iaid = 0; + int interval; + grub_err_t err; + grub_dhcp6_session_t se; - -- if (!device || !path) -- return NULL; ++ + err = GRUB_ERR_NONE; - -- *device = 0; -- *path = 0; ++ + FOR_NET_CARDS (card) + { + struct grub_net_network_level_interface *iface; - -- grub_dprintf ("net", "mac address is %02x:%02x:%02x:%02x:%02x:%02x\n", -- hwaddr->mac[0], hwaddr->mac[1], hwaddr->mac[2], -- hwaddr->mac[3], hwaddr->mac[4], hwaddr->mac[5]); ++ + if (argc > 0 && grub_strcmp (card->name, args[0]) != 0) + continue; - -- if (is_def) -- grub_net_default_server = 0; ++ + iface = grub_net_ipv6_get_link_local (card, &card->default_address); + if (!iface) + { -+ grub_dhcp6_session_remove_all (); -+ return grub_errno; ++ grub_dhcp6_session_remove_all (); ++ return grub_errno; + } - -- if (is_def && !grub_net_default_server && packet) ++ + grub_dhcp6_session_add (iface, iaid++); + } + + for (interval = 200; interval < 10000; interval *= 2) - { -- const grub_uint8_t *options = packet->dhcp_options; -- unsigned int option_max = 1024 - OFFSET_OF (dhcp_options, packet); -- unsigned int i; -- -- for (i = 0; i < option_max - sizeof (grub_net_dhcpv6_option_t); ) -- { -- grub_uint16_t num, len; -- grub_net_dhcpv6_option_t *opt = -- (grub_net_dhcpv6_option_t *)(options + i); -- -- num = grub_be_to_cpu16(opt->option_num); -- len = grub_be_to_cpu16(opt->option_len); -- -- grub_dprintf ("net", "got dhcpv6 option %d len %d\n", num, len); -- -- if (len == 0) -- break; -- -- if (len + i > 1024) -- break; -- -- if (num == GRUB_NET_DHCP6_BOOTFILE_URL) -- { -- char *scheme, *userinfo, *host, *file; -- char *tmp; -- int hostlen; -- int port; -- int rc = extract_url_info ((const char *)opt->option_data, -- (grub_size_t)len, -- &scheme, &userinfo, &host, &port, -- &file); -- if (rc < 0) -- continue; -- -- /* right now this only handles tftp. */ -- if (grub_strcmp("tftp", scheme)) -- { -- grub_free (scheme); -- grub_free (userinfo); -- grub_free (host); -- grub_free (file); -- continue; -- } -- grub_free (userinfo); -- -- hostlen = grub_strlen (host); -- if (hostlen > 2 && host[0] == '[' && host[hostlen-1] == ']') -- { -- tmp = host+1; -- host[hostlen-1] = '\0'; -- } -- else -- tmp = host; -- -- *device = grub_xasprintf ("%s,%s", scheme, tmp); -- grub_free (scheme); -- grub_free (host); -- -- if (file && *file) -- { -- tmp = grub_strrchr (file, '/'); -- if (tmp) -- *(tmp+1) = '\0'; -- else -- file[0] = '\0'; -- } -- else if (!file) -- file = grub_strdup (""); -- -- if (file[0] == '/') -- { -- *path = grub_strdup (file+1); -- grub_free (file); -- } -- else -- *path = file; -- } -- else if (num == GRUB_NET_DHCP6_IA_NA) -- { -- const grub_net_dhcpv6_option_t *ia_na_opt; -- const grub_net_dhcpv6_opt_ia_na_t *ia_na = -- (const grub_net_dhcpv6_opt_ia_na_t *)opt; -- unsigned int left = len - OFFSET_OF (options, ia_na); -- unsigned int j; -- -- if ((grub_uint8_t *)ia_na + left > -- (grub_uint8_t *)options + option_max) -- left -= ((grub_uint8_t *)ia_na + left) -- - ((grub_uint8_t *)options + option_max); -- -- if (len < OFFSET_OF (option_data, opt) -- + sizeof (grub_net_dhcpv6_option_t)) -- { -- grub_dprintf ("net", -- "found dhcpv6 ia_na option with no address\n"); -- continue; -- } -- -- for (j = 0; left > sizeof (grub_net_dhcpv6_option_t); ) -- { -- ia_na_opt = (const grub_net_dhcpv6_option_t *) -- (ia_na->options + j); -- grub_uint16_t ia_na_opt_num, ia_na_opt_len; -- -- ia_na_opt_num = grub_be_to_cpu16 (ia_na_opt->option_num); -- ia_na_opt_len = grub_be_to_cpu16 (ia_na_opt->option_len); -- if (ia_na_opt_len == 0) -- break; -- if (j + ia_na_opt_len > left) -- break; -- if (ia_na_opt_num == GRUB_NET_DHCP6_IA_ADDRESS) -- { -- const grub_net_dhcpv6_opt_ia_address_t *ia_addr; -- -- ia_addr = (const grub_net_dhcpv6_opt_ia_address_t *) -- ia_na_opt; -- addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -- grub_memcpy(addr.ipv6, ia_addr->ipv6_address, -- sizeof (ia_addr->ipv6_address)); -- inter = grub_net_add_addr (name, card, &addr, hwaddr, 0); -- } -- -- j += ia_na_opt_len; -- left -= ia_na_opt_len; -- } -- } -- -- i += len + 4; -- } -- -- grub_print_error (); ++ { + int done = 1; + + FOR_DHCP6_SESSIONS (se) -+ { -+ struct grub_net_buff *nb; -+ struct grub_net_dhcp6_option *opt; -+ struct grub_net_dhcp6_packet *v6h; -+ struct grub_net_dhcp6_option_duid_ll *duid; -+ struct grub_net_dhcp6_option_iana *ia_na; -+ grub_net_network_level_address_t multicast; -+ grub_net_link_level_address_t ll_multicast; -+ struct udphdr *udph; -+ -+ multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -+ multicast.ipv6[0] = grub_cpu_to_be64_compile_time (0xff02ULL << 48); -+ multicast.ipv6[1] = grub_cpu_to_be64_compile_time (0x10002ULL); -+ -+ err = grub_net_link_layer_resolve (se->iface, -+ &multicast, &ll_multicast); -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ return err; -+ } -+ -+ nb = grub_netbuff_alloc (GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE); -+ -+ if (!nb) -+ { -+ grub_dhcp6_session_remove_all (); -+ return grub_errno; -+ } -+ -+ err = grub_netbuff_reserve (nb, GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE); -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (grub_uint16_t)); -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ opt = (struct grub_net_dhcp6_option *)nb->data; -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_ELAPSED_TIME); -+ opt->len = grub_cpu_to_be16_compile_time (sizeof (grub_uint16_t)); -+ grub_set_unaligned16 (opt->data, 0); -+ -+ err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (*duid)); -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ opt = (struct grub_net_dhcp6_option *)nb->data; -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_CLIENTID); -+ opt->len = grub_cpu_to_be16 (sizeof (*duid)); -+ -+ duid = (struct grub_net_dhcp6_option_duid_ll *) opt->data; -+ grub_memcpy (duid, &se->duid, sizeof (*duid)); -+ -+ err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (*ia_na)); -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ opt = (struct grub_net_dhcp6_option *)nb->data; -+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IA_NA); -+ opt->len = grub_cpu_to_be16 (sizeof (*ia_na)); -+ ia_na = (struct grub_net_dhcp6_option_iana *)opt->data; -+ ia_na->iaid = grub_cpu_to_be32 (se->iaid); -+ ia_na->t1 = 0; -+ ia_na->t2 = 0; -+ -+ err = grub_netbuff_push (nb, sizeof (*v6h)); -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ grub_netbuff_free (nb); -+ return err; -+ } -+ -+ v6h = (struct grub_net_dhcp6_packet *)nb->data; -+ v6h->message_type = GRUB_NET_DHCP6_SOLICIT; -+ v6h->transaction_id = se->transaction_id; -+ -+ grub_netbuff_push (nb, sizeof (*udph)); -+ -+ udph = (struct udphdr *) nb->data; -+ udph->src = grub_cpu_to_be16_compile_time (DHCP6_CLIENT_PORT); -+ udph->dst = grub_cpu_to_be16_compile_time (DHCP6_SERVER_PORT); -+ udph->chksum = 0; -+ udph->len = grub_cpu_to_be16 (nb->tail - nb->data); -+ -+ udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP, -+ &se->iface->address, &multicast); -+ -+ err = grub_net_send_ip_packet (se->iface, &multicast, -+ &ll_multicast, nb, GRUB_NET_IP_UDP); -+ done = 0; -+ grub_netbuff_free (nb); -+ -+ if (err) -+ { -+ grub_dhcp6_session_remove_all (); -+ return err; -+ } -+ } ++ { ++ struct grub_net_buff *nb; ++ struct grub_net_dhcp6_option *opt; ++ struct grub_net_dhcp6_packet *v6h; ++ struct grub_net_dhcp6_option_duid_ll *duid; ++ struct grub_net_dhcp6_option_iana *ia_na; ++ grub_net_network_level_address_t multicast; ++ grub_net_link_level_address_t ll_multicast; ++ struct udphdr *udph; ++ ++ multicast.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; ++ multicast.ipv6[0] = grub_cpu_to_be64_compile_time (0xff02ULL << 48); ++ multicast.ipv6[1] = grub_cpu_to_be64_compile_time (0x10002ULL); ++ ++ err = grub_net_link_layer_resolve (se->iface, ++ &multicast, &ll_multicast); ++ if (err) ++ { ++ grub_dhcp6_session_remove_all (); ++ return err; ++ } ++ ++ nb = grub_netbuff_alloc (GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE); ++ ++ if (!nb) ++ { ++ grub_dhcp6_session_remove_all (); ++ return grub_errno; ++ } ++ ++ err = grub_netbuff_reserve (nb, GRUB_DHCP6_DEFAULT_NETBUFF_ALLOC_SIZE); ++ if (err) ++ { ++ grub_dhcp6_session_remove_all (); ++ grub_netbuff_free (nb); ++ return err; ++ } ++ ++ err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (grub_uint16_t)); ++ if (err) ++ { ++ grub_dhcp6_session_remove_all (); ++ grub_netbuff_free (nb); ++ return err; ++ } ++ ++ opt = (struct grub_net_dhcp6_option *)nb->data; ++ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_ELAPSED_TIME); ++ opt->len = grub_cpu_to_be16_compile_time (sizeof (grub_uint16_t)); ++ grub_set_unaligned16 (opt->data, 0); ++ ++ err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (*duid)); ++ if (err) ++ { ++ grub_dhcp6_session_remove_all (); ++ grub_netbuff_free (nb); ++ return err; ++ } ++ ++ opt = (struct grub_net_dhcp6_option *)nb->data; ++ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_CLIENTID); ++ opt->len = grub_cpu_to_be16 (sizeof (*duid)); ++ ++ duid = (struct grub_net_dhcp6_option_duid_ll *) opt->data; ++ grub_memcpy (duid, &se->duid, sizeof (*duid)); ++ ++ err = grub_netbuff_push (nb, sizeof (*opt) + sizeof (*ia_na)); ++ if (err) ++ { ++ grub_dhcp6_session_remove_all (); ++ grub_netbuff_free (nb); ++ return err; ++ } ++ ++ opt = (struct grub_net_dhcp6_option *)nb->data; ++ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IA_NA); ++ opt->len = grub_cpu_to_be16 (sizeof (*ia_na)); ++ ia_na = (struct grub_net_dhcp6_option_iana *)opt->data; ++ ia_na->iaid = grub_cpu_to_be32 (se->iaid); ++ ia_na->t1 = 0; ++ ia_na->t2 = 0; ++ ++ err = grub_netbuff_push (nb, sizeof (*v6h)); ++ if (err) ++ { ++ grub_dhcp6_session_remove_all (); ++ grub_netbuff_free (nb); ++ return err; ++ } ++ ++ v6h = (struct grub_net_dhcp6_packet *)nb->data; ++ v6h->message_type = GRUB_NET_DHCP6_SOLICIT; ++ v6h->transaction_id = se->transaction_id; ++ ++ grub_netbuff_push (nb, sizeof (*udph)); ++ ++ udph = (struct udphdr *) nb->data; ++ udph->src = grub_cpu_to_be16_compile_time (DHCP6_CLIENT_PORT); ++ udph->dst = grub_cpu_to_be16_compile_time (DHCP6_SERVER_PORT); ++ udph->chksum = 0; ++ udph->len = grub_cpu_to_be16 (nb->tail - nb->data); ++ ++ udph->chksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_UDP, ++ &se->iface->address, &multicast); ++ ++ err = grub_net_send_ip_packet (se->iface, &multicast, ++ &ll_multicast, nb, GRUB_NET_IP_UDP); ++ done = 0; ++ grub_netbuff_free (nb); ++ ++ if (err) ++ { ++ grub_dhcp6_session_remove_all (); ++ return err; ++ } ++ } + if (!done) -+ grub_net_poll_cards (interval, 0); - } - -- if (is_def) ++ grub_net_poll_cards (interval, 0); ++ } ++ + FOR_DHCP6_SESSIONS (se) - { -- grub_env_set ("net_default_interface", name); -- grub_env_export ("net_default_interface"); ++ { + grub_error_push (); + err = grub_error (GRUB_ERR_FILE_NOT_FOUND, -+ N_("couldn't autoconfigure %s"), -+ se->iface->card->name); - } - -- if (inter) -- grub_net_add_ipv6_local (inter, mask); -- return inter; ++ N_("couldn't autoconfigure %s"), ++ se->iface->card->name); ++ } ++ + grub_dhcp6_session_remove_all (); + + return err; - } - ++} ++ +static grub_command_t cmd_getdhcp, cmd_bootp, cmd_dhcp, cmd_bootp6; void grub_bootp_init (void) -@@ -1084,11 +1819,15 @@ grub_bootp_init (void) +@@ -917,6 +1819,9 @@ cmd_getdhcp = grub_register_command ("net_get_dhcp_option", grub_cmd_dhcpopt, N_("VAR INTERFACE NUMBER DESCRIPTION"), N_("retrieve DHCP option and save it into VAR. If VAR is - then print the value.")); @@ -1129,55 +963,15 @@ index 08b6b2b5d6c..fe93b80f1cf 100644 } void - grub_bootp_fini (void) - { -+ grub_unregister_command (cmd_bootp6); +@@ -925,4 +1830,5 @@ grub_unregister_command (cmd_getdhcp); grub_unregister_command (cmd_bootp); grub_unregister_command (cmd_dhcp); -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index a673bea807a..8e25680db0c 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -393,9 +393,6 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - pxe_mode = pxe->mode; - if (pxe_mode->using_ipv6) - { -- grub_net_link_level_address_t hwaddr; -- struct grub_net_network_level_interface *intf; -- - grub_dprintf ("efinet", "using ipv6 and dhcpv6\n"); - grub_dprintf ("efinet", "dhcp_ack_received: %s%s\n", - pxe_mode->dhcp_ack_received ? "yes" : "no", -@@ -403,15 +400,14 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - if (!pxe_mode->dhcp_ack_received) - continue; - -- hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (hwaddr.mac, -- card->efi_net->mode->current_address, -- sizeof (hwaddr.mac)); -- -- intf = grub_net_configure_by_dhcpv6_ack (card->name, card, 0, &hwaddr, -- (const struct grub_net_dhcpv6_packet *)&pxe_mode->dhcp_ack.dhcpv6, -- 1, device, path); -- if (intf && device && path) -+ grub_net_configure_by_dhcpv6_reply (card->name, card, 0, -+ (struct grub_net_dhcp6_packet *) -+ &pxe_mode->dhcp_ack, -+ sizeof (pxe_mode->dhcp_ack), -+ 1, device, path); -+ if (grub_errno) -+ grub_print_error (); -+ if (device && path) - grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); - } - else -diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c -index a5896f6dc26..ce6bdc75c6d 100644 ++ grub_unregister_command (cmd_bootp6); + } --- a/grub-core/net/ip.c +++ b/grub-core/net/ip.c -@@ -239,6 +239,45 @@ handle_dgram (struct grub_net_buff *nb, +@@ -240,6 +240,45 @@ { struct udphdr *udph; udph = (struct udphdr *) nb->data; @@ -1223,50 +1017,19 @@ index a5896f6dc26..ce6bdc75c6d 100644 if (proto == GRUB_NET_IP_UDP && grub_be_to_cpu16 (udph->dst) == 68) { const struct grub_net_bootp_packet *bootp; -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 99628801478..7614b58dca8 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -1532,7 +1532,7 @@ typedef struct grub_efi_pxe_ip_filter - { - grub_efi_uint8_t filters; - grub_efi_uint8_t ip_count; -- grub_efi_uint8_t reserved; -+ grub_efi_uint16_t reserved; - grub_efi_ip_address_t ip_list[GRUB_EFI_PXE_MAX_IPCNT]; - } grub_efi_pxe_ip_filter_t; - -diff --git a/include/grub/net.h b/include/grub/net.h -index d55d505a03a..543251f7273 100644 --- a/include/grub/net.h +++ b/include/grub/net.h -@@ -451,50 +451,65 @@ struct grub_net_bootp_packet +@@ -450,6 +450,66 @@ grub_uint8_t vendor[0]; } GRUB_PACKED; --enum -- { -- GRUB_NET_DHCP6_IA_NA = 3, -- GRUB_NET_DHCP6_IA_ADDRESS = 5, -- GRUB_NET_DHCP6_BOOTFILE_URL = 59, -- }; -- --struct grub_net_dhcpv6_option +struct grub_net_dhcp6_packet - { -- grub_uint16_t option_num; -- grub_uint16_t option_len; -- grub_uint8_t option_data[]; ++{ + grub_uint32_t message_type:8; + grub_uint32_t transaction_id:24; + grub_uint8_t dhcp_options[0]; - } GRUB_PACKED; --typedef struct grub_net_dhcpv6_option grub_net_dhcpv6_option_t; - --struct grub_net_dhcpv6_opt_ia_na --{ -- grub_uint16_t option_num; -- grub_uint16_t option_len; ++} GRUB_PACKED; ++ +struct grub_net_dhcp6_option { + grub_uint16_t code; + grub_uint16_t len; @@ -1274,39 +1037,25 @@ index d55d505a03a..543251f7273 100644 +} GRUB_PACKED; + +struct grub_net_dhcp6_option_iana { - grub_uint32_t iaid; - grub_uint32_t t1; - grub_uint32_t t2; -- grub_uint8_t options[]; ++ grub_uint32_t iaid; ++ grub_uint32_t t1; ++ grub_uint32_t t2; + grub_uint8_t data[0]; - } GRUB_PACKED; --typedef struct grub_net_dhcpv6_opt_ia_na grub_net_dhcpv6_opt_ia_na_t; - --struct grub_net_dhcpv6_opt_ia_address --{ -- grub_uint16_t option_num; -- grub_uint16_t option_len; -- grub_uint64_t ipv6_address[2]; ++} GRUB_PACKED; ++ +struct grub_net_dhcp6_option_iaaddr { + grub_uint8_t addr[16]; - grub_uint32_t preferred_lifetime; - grub_uint32_t valid_lifetime; -- grub_uint8_t options[]; ++ grub_uint32_t preferred_lifetime; ++ grub_uint32_t valid_lifetime; + grub_uint8_t data[0]; - } GRUB_PACKED; --typedef struct grub_net_dhcpv6_opt_ia_address grub_net_dhcpv6_opt_ia_address_t; - --struct grub_net_dhcpv6_packet ++} GRUB_PACKED; ++ +struct grub_net_dhcp6_option_duid_ll - { -- grub_uint32_t message_type:8; -- grub_uint32_t transaction_id:24; -- grub_uint8_t dhcp_options[1024]; ++{ + grub_uint16_t type; + grub_uint16_t hw_type; + grub_uint8_t hwaddr[6]; - } GRUB_PACKED; --typedef struct grub_net_dhcpv6_packet grub_net_dhcpv6_packet_t; ++} GRUB_PACKED; + +enum + { @@ -1333,29 +1082,26 @@ index d55d505a03a..543251f7273 100644 + GRUB_NET_DHCP6_OPTION_DNS_SERVERS = 23, + GRUB_NET_DHCP6_OPTION_BOOTFILE_URL = 59 + }; - ++ #define GRUB_NET_BOOTP_RFC1048_MAGIC_0 0x63 #define GRUB_NET_BOOTP_RFC1048_MAGIC_1 0x82 -@@ -532,12 +547,12 @@ grub_net_configure_by_dhcp_ack (const char *name, + #define GRUB_NET_BOOTP_RFC1048_MAGIC_2 0x53 +@@ -485,6 +545,14 @@ + grub_size_t size, int is_def, char **device, char **path); - struct grub_net_network_level_interface * --grub_net_configure_by_dhcpv6_ack (const char *name, -- struct grub_net_card *card, -- grub_net_interface_flags_t flags, -- const grub_net_link_level_address_t *hwaddr, -- const struct grub_net_dhcpv6_packet *packet, -- int is_def, char **device, char **path); ++struct grub_net_network_level_interface * +grub_net_configure_by_dhcpv6_reply (const char *name, + struct grub_net_card *card, + grub_net_interface_flags_t flags, + const struct grub_net_dhcp6_packet *v6, + grub_size_t size, + int is_def, char **device, char **path); - - int - grub_ipv6_get_masksize(grub_uint16_t *mask); -@@ -554,6 +569,10 @@ void ++ + grub_err_t + grub_net_add_ipv4_local (struct grub_net_network_level_interface *inf, + int mask); +@@ -493,6 +561,10 @@ grub_net_process_dhcp (struct grub_net_buff *nb, struct grub_net_network_level_interface *iface); diff --git a/0003-cryptodisk-wipe-out-the-cached-keys-from-protectors.patch b/0003-cryptodisk-wipe-out-the-cached-keys-from-protectors.patch new file mode 100644 index 0000000000000000000000000000000000000000..5180f345bfd45aac81f3c03e5cd3f25c0f314758 --- /dev/null +++ b/0003-cryptodisk-wipe-out-the-cached-keys-from-protectors.patch @@ -0,0 +1,36 @@ +From 64494ffc442a5de05b237ad48d27c70d22849a44 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Thu, 3 Aug 2023 15:52:52 +0800 +Subject: [PATCH 3/4] cryptodisk: wipe out the cached keys from protectors + +An attacker may insert a malicious disk with the same crypto UUID and +trick grub2 to mount the fake root. Even though the key from the key +protector fails to unlock the fake root, it's not wiped out cleanly so +the attacker could dump the memory to retrieve the secret key. To defend +such attack, wipe out the cached key when we don't need it. + +Signed-off-by: Gary Lin +--- + grub-core/disk/cryptodisk.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c +index cf37a0934..f42437f4e 100644 +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -1348,7 +1348,11 @@ grub_cryptodisk_clear_key_cache (struct grub_cryptomount_args *cargs) + return; + + for (i = 0; cargs->protectors[i]; i++) +- grub_free (cargs->key_cache[i].key); ++ { ++ if (cargs->key_cache[i].key) ++ grub_memset (cargs->key_cache[i].key, 0, cargs->key_cache[i].key_len); ++ grub_free (cargs->key_cache[i].key); ++ } + + grub_free (cargs->key_cache); + } +-- +2.35.3 + diff --git a/0003-grub-install-support-prep-environment-block.patch b/0003-grub-install-support-prep-environment-block.patch new file mode 100644 index 0000000000000000000000000000000000000000..78601aa3f0ec70ce96551964d741ef5c2ff474fc --- /dev/null +++ b/0003-grub-install-support-prep-environment-block.patch @@ -0,0 +1,137 @@ +From c31fc5aa0ded9ce1e774d0a3526cfee19be1b77f Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Mon, 7 Feb 2022 20:49:01 +0800 +Subject: [PATCH 3/5] grub-install: support prep environment block + +The grub-install can be instructed to create environment block at end of +PReP paritition with probed device identities and properties in +variables to facilitate root device discovery. So far these variables +are defined for this purpose: + +ENV_FS_UUID - The filesystem uuid for the grub root device +ENV_CRYPTO_UUID - The crytodisk uuid for the grub root device separated +by space +ENV_GRUB_DIR - The path to grub prefix directory +ENV_HINT - The recommended hint string for searching root device + +The size of environment block is defined in GRUB_ENVBLK_PREP_SIZE which +is 4096 bytes and can be extended in the future. + +v2: Improve detection of ENV_CRYPTO_UUID by traversing all members of +the logical disk and utilize a space as a separator when multiple UUIDs +are found (bsc#1216075). + +Signed-off-by: Michael Chang +--- + include/grub/lib/envblk.h | 3 +++ + util/grub-install.c | 38 ++++++++++++++++++++++++++++++++++++++ + 2 files changed, 41 insertions(+) + +--- a/include/grub/lib/envblk.h ++++ b/include/grub/lib/envblk.h +@@ -24,6 +24,9 @@ + + #ifndef ASM_FILE + ++#include ++#define GRUB_ENVBLK_PREP_SIZE (GRUB_DISK_SECTOR_SIZE << 3) ++ + struct grub_envblk + { + char *buf; +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -43,6 +43,7 @@ + #include + #include + #include ++#include + + #include + +@@ -609,6 +610,41 @@ + } + } + ++static char * ++cryptodisk_uuids (grub_disk_t disk, int in_recurse) ++{ ++ grub_disk_memberlist_t list = NULL, tmp; ++ static char *ret; ++ ++ if (!in_recurse) ++ ret = NULL; ++ ++ if (disk->dev->disk_memberlist) ++ list = disk->dev->disk_memberlist (disk); ++ ++ while (list) ++ { ++ ret = cryptodisk_uuids (list->disk, 1); ++ tmp = list->next; ++ free (list); ++ list = tmp; ++ } ++ ++ if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) ++ { ++ if (!ret) ++ ret = grub_strdup (grub_util_cryptodisk_get_uuid (disk)); ++ else ++ { ++ char *s = grub_xasprintf ("%s %s", grub_util_cryptodisk_get_uuid (disk), ret); ++ grub_free (ret); ++ ret = s; ++ } ++ } ++ ++ return ret; ++} ++ + static int + is_same_disk (const char *a, const char *b) + { +@@ -2138,6 +2174,43 @@ + if (write_to_disk (ins_dev, imgfile)) + grub_util_error ("%s", _("failed to copy Grub to the PReP partition")); + grub_set_install_backup_ponr (); ++ ++ if ((signed_grub_mode >= SIGNED_GRUB_FORCE) || ((signed_grub_mode == SIGNED_GRUB_AUTO) && (ppc_sb_state > 0))) ++ { ++ char *uuid = NULL; ++ grub_envblk_t envblk = NULL; ++ char *buf; ++ char *cryptouuid = NULL; ++ ++ if (grub_dev->disk) ++ cryptouuid = cryptodisk_uuids (grub_dev->disk, 0); ++ ++ if (grub_fs->fs_uuid && grub_fs->fs_uuid (grub_dev, &uuid)) ++ { ++ grub_print_error (); ++ grub_errno = 0; ++ uuid = NULL; ++ } ++ buf = grub_envblk_buf (GRUB_ENVBLK_PREP_SIZE); ++ envblk = grub_envblk_open (buf, GRUB_ENVBLK_PREP_SIZE); ++ if (uuid) ++ grub_envblk_set (envblk, "ENV_FS_UUID", uuid); ++ if (cryptouuid) ++ grub_envblk_set (envblk, "ENV_CRYPTO_UUID", cryptouuid); ++ if (relative_grubdir) ++ grub_envblk_set (envblk, "ENV_GRUB_DIR", relative_grubdir); ++ if (have_abstractions) ++ grub_envblk_set (envblk, "ENV_HINT", grub_dev->disk->name); ++ if (use_relative_path_on_btrfs) ++ grub_envblk_set (envblk, "btrfs_relative_path", "1"); ++ if (envblk) ++ { ++ fprintf (stderr, _("Write environment block to PReP.\n")); ++ if (grub_disk_write_tail (ins_dev->disk, envblk->size, envblk->buf)) ++ grub_util_error ("%s", _("failed to write environment block to the PReP partition")); ++ } ++ grub_envblk_close (envblk); ++ } + grub_device_close (ins_dev); + if (update_nvram) + grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device), diff --git a/0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch b/0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch new file mode 100644 index 0000000000000000000000000000000000000000..6317601be88e5c4ffcf85349b8c862eec99f46c2 --- /dev/null +++ b/0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch @@ -0,0 +1,62 @@ +From 1729400ab816804a28ebf50cb1310607b2c4b75e Mon Sep 17 00:00:00 2001 +From: Diego Domingos +Date: Fri, 25 Feb 2022 12:49:51 -0500 +Subject: [PATCH 3/4] ieee1275: change the logic of ieee1275_get_devargs() + +Usually grub will parse the PFW arguments by searching for the first occurence of the character ':'. +However, we can have this char more than once on NQN. +This patch changes the logic to find the last occurence of this char so we can get the proper values +for NVMeoFC +--- + grub-core/kern/ieee1275/openfw.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c +index f819bd106..655a71310 100644 +--- a/grub-core/kern/ieee1275/openfw.c ++++ b/grub-core/kern/ieee1275/openfw.c +@@ -354,6 +354,13 @@ static char * + grub_ieee1275_get_devargs (const char *path) + { + char *colon = grub_strchr (path, ':'); ++ char *colon_check = colon; ++ ++ /* Find the last occurence of colon */ ++ while(colon_check){ ++ colon = colon_check; ++ colon_check = grub_strchr (colon+1, ':'); ++ } + + if (! colon) + return 0; +@@ -368,6 +375,18 @@ grub_ieee1275_get_devname (const char *path) + char *colon = grub_strchr (path, ':'); + int pathlen = grub_strlen (path); + struct grub_ieee1275_devalias curalias; ++ ++ /* Check some special cases */ ++ if(grub_strstr(path, "nvme-of")){ ++ char *namespace_split = grub_strstr(path,"/namespace@"); ++ if(namespace_split){ ++ colon = grub_strchr (namespace_split, ':'); ++ } else { ++ colon = NULL; ++ } ++ ++ } ++ + if (colon) + pathlen = (int)(colon - path); + +@@ -693,7 +712,7 @@ grub_ieee1275_get_boot_dev (void) + return NULL; + } + +- bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64); ++ bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64 + 256); + if (! bootpath) + { + grub_print_error (); +-- +2.35.3 + diff --git a/0003-protectors-Add-TPM2-Key-Protector.patch b/0003-protectors-Add-TPM2-Key-Protector.patch new file mode 100644 index 0000000000000000000000000000000000000000..cd66fae6c30f5b87159fcb16c2d389e430c3c733 --- /dev/null +++ b/0003-protectors-Add-TPM2-Key-Protector.patch @@ -0,0 +1,2052 @@ +From 2a63876ca714d177f919b2392d8efa0e3bd3ebe2 Mon Sep 17 00:00:00 2001 +From: Hernan Gatta +Date: Tue, 1 Feb 2022 05:02:55 -0800 +Subject: [PATCH v7 10/20] protectors: Add TPM2 Key Protector + +The TPM2 key protector is a module that enables the automatic retrieval +of a fully-encrypted disk's unlocking key from a TPM 2.0. + +The theory of operation is such that the module accepts various +arguments, most of which are optional and therefore possess reasonable +defaults. One of these arguments is the keyfile/tpm2key parameter, which +is mandatory. There are two supported key formats: + +1. Raw Sealed Key (--keyfile) + When sealing a key with TPM2_Create, the public portion of the sealed + key is stored in TPM2B_PUBLIC, and the private portion is in + TPM2B_PRIVATE. The raw sealed key glues the fully marshalled + TPM2B_PUBLIC and TPM2B_PRIVATE into one file. + +2. TPM 2.0 Key (--tpm2key) + The following is the ASN.1 definition of TPM 2.0 Key File: + + TPMPolicy ::= SEQUENCE { + CommandCode [0] EXPLICIT INTEGER + CommandPolicy [1] EXPLICIT OCTET STRING + } + + TPMAuthPolicy ::= SEQUENCE { + Name [0] EXPLICIT UTF8STRING OPTIONAL + Policy [1] EXPLICIT SEQUENCE OF TPMPolicy + } + + TPMKey ::= SEQUENCE { + type OBJECT IDENTIFIER + emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL + policy [1] EXPLICIT SEQUENCE OF TPMPolicy OPTIONAL + secret [2] EXPLICIT OCTET STRING OPTIONAL + authPolicy [3] EXPLICIT SEQUENCE OF TPMAuthPolicy OPTIONAL + parent INTEGER + pubkey OCTET STRING + privkey OCTET STRING + } + + The TPM2 key protector only expects a "sealed" key in DER encoding, + so 'type' is always 2.23.133.10.1.5, 'emptyAuth' is 'TRUE', and + 'secret' is empty. 'policy' and 'authPolicy' are the possible policy + command sequences to construst the policy digest to unseal the key. + Similar to the raw sealed key, the public portion (TPM2B_PUBLIC) of + the sealed key is stored in 'pubkey', and the private portion + (TPM2B_PRIVATE) is in 'privkey'. + + For more details: https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html + +This sealed key file is created via the grub-protect tool. The tool +utilizes the TPM's sealing functionality to seal (i.e., encrypt) an +unlocking key using a Storage Root Key (SRK) to the values of various +Platform Configuration Registers (PCRs). These PCRs reflect the state +of the system as it boots. If the values are as expected, the system +may be considered trustworthy, at which point the TPM allows for a +caller to utilize the private component of the SRK to unseal (i.e., +decrypt) the sealed key file. The caller, in this case, is this key +protector. + +The TPM2 key protector registers two commands: + +- tpm2_key_protector_init: Initializes the state of the TPM2 key + protector for later usage, clearing any + previous state, too, if any. + +- tpm2_key_protector_clear: Clears any state set by tpm2_key_protector_init. + +The way this is expected to be used requires the user to, either +interactively or, normally, via a boot script, initialize/configure +the key protector and then specify that it be used by the 'cryptomount' +command (modifications to this command are in a different patch). + +For instance, to unseal the raw sealed key file: + +tpm2_key_protector_init --keyfile=(hd0,gpt1)/efi/grub2/sealed-1.key +cryptomount -u -P tpm2 + +tpm2_key_protector_init --keyfile=(hd0,gpt1)/efi/grub2/sealed-2.key --pcrs=7,11 +cryptomount -u -P tpm2 + +Or, to unseal the TPM 2.0 Key file: + +tpm2_key_protector_init --tpm2key=(hd0,gpt1)/efi/grub2/sealed-1.tpm +cryptomount -u -P tpm2 + +tpm2_key_protector_init --tpm2key=(hd0,gpt1)/efi/grub2/sealed-2.tpm --pcrs=7,11 +cryptomount -u -P tpm2 + +If a user does not initialize the key protector and attempts to use it +anyway, the protector returns an error. + +Before unsealing the key, the TPM2 key protector follows the "TPMPolicy" +sequences to enforce the TPM policy commands to construct a valid policy +digest to unseal the key. + +For the TPM 2.0 Key files, 'authPolicy' may contain multiple "TPMPolicy" +sequences, the TPM2 key protector iterates 'authPolicy' to find a valid +sequence to unseal key. If 'authPolicy' is empty or all sequences in +'authPolicy' fail, the protector tries the one from 'policy'. In case +'policy' is also empty, the protector creates a "TPMPolicy" sequence +based on the given PCR selection. + +For the raw sealed key, the TPM2 key protector treats the key file as a +TPM 2.0 Key file without 'authPolicy' and 'policy', so the "TPMPolicy" +sequence is always based on the PCR selection from the command +parameters. + +Currently, there is only one supported policy command: TPM2_PolicyPCR. +The command set can be extended to support advanced features, such as +authorized policy, in the future. + +Signed-off-by: Hernan Gatta +Signed-off-by: Gary Lin +--- + grub-core/Makefile.core.def | 13 + + grub-core/tpm2/args.c | 177 +++++ + grub-core/tpm2/module.c | 1028 +++++++++++++++++++++++++++++ + grub-core/tpm2/tpm2key.asn | 31 + + grub-core/tpm2/tpm2key.c | 447 +++++++++++++ + grub-core/tpm2/tpm2key_asn1_tab.c | 41 ++ + include/grub/tpm2/internal/args.h | 41 ++ + include/grub/tpm2/tpm2key.h | 83 +++ + 8 files changed, 1861 insertions(+) + create mode 100644 grub-core/tpm2/args.c + create mode 100644 grub-core/tpm2/module.c + create mode 100644 grub-core/tpm2/tpm2key.asn + create mode 100644 grub-core/tpm2/tpm2key.c + create mode 100644 grub-core/tpm2/tpm2key_asn1_tab.c + create mode 100644 include/grub/tpm2/internal/args.h + create mode 100644 include/grub/tpm2/tpm2key.h + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 5831d4265..38571119e 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -2553,6 +2553,19 @@ module = { + enable = efi; + }; + ++module = { ++ name = tpm2; ++ common = tpm2/args.c; ++ common = tpm2/buffer.c; ++ common = tpm2/module.c; ++ common = tpm2/mu.c; ++ common = tpm2/tpm2.c; ++ common = tpm2/tpm2key.c; ++ common = tpm2/tpm2key_asn1_tab.c; ++ efi = tpm2/tcg2.c; ++ enable = efi; ++}; ++ + module = { + name = tr; + common = commands/tr.c; +diff --git a/grub-core/tpm2/args.c b/grub-core/tpm2/args.c +new file mode 100644 +index 000000000..274f4fef0 +--- /dev/null ++++ b/grub-core/tpm2/args.c +@@ -0,0 +1,177 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++ ++grub_err_t ++grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs, ++ grub_uint8_t *pcr_count) ++{ ++ char *current_pcr = value; ++ char *next_pcr; ++ unsigned long pcr; ++ grub_uint8_t i; ++ ++ if (grub_strlen (value) == 0) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ *pcr_count = 0; ++ for (i = 0; i < TPM_MAX_PCRS; i++) ++ { ++ next_pcr = grub_strchr (current_pcr, ','); ++ if (next_pcr == current_pcr) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Empty entry in PCR list")); ++ if (next_pcr) ++ *next_pcr = '\0'; ++ ++ grub_errno = GRUB_ERR_NONE; ++ pcr = grub_strtoul (current_pcr, NULL, 10); ++ if (grub_errno != GRUB_ERR_NONE) ++ return grub_error (grub_errno, ++ N_("Entry '%s' in PCR list is not a number"), ++ current_pcr); ++ ++ if (pcr > TPM_MAX_PCRS) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("Entry %lu in PCR list is too large to be a PCR " ++ "number, PCR numbers range from 0 to %u"), ++ pcr, TPM_MAX_PCRS); ++ ++ pcrs[i] = (grub_uint8_t)pcr; ++ *pcr_count += 1; ++ ++ if (next_pcr == NULL) ++ break; ++ ++ current_pcr = next_pcr + 1; ++ if (*current_pcr == '\0') ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Trailing comma at the end of PCR list")); ++ } ++ ++ if (i == TPM_MAX_PCRS) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("Too many PCRs in PCR list, the maximum number of " ++ "PCRs is %u"), TPM_MAX_PCRS); ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_tpm2_protector_parse_asymmetric (const char *value, ++ TPM_ALG_ID *asymmetric, ++ TPM_KEY_BITS *rsa_bits, ++ TPM_ECC_CURVE *ecc_curve) ++{ ++ if (grub_strcasecmp (value, "ECC") == 0 || ++ grub_strcasecmp (value, "ECC_NIST_P256") == 0) ++ { ++ *asymmetric = TPM_ALG_ECC; ++ *ecc_curve = TPM_ECC_NIST_P256; ++ } ++ else if (grub_strcasecmp (value, "RSA") == 0 || ++ grub_strcasecmp (value, "RSA2048") == 0) ++ { ++ *asymmetric = TPM_ALG_RSA; ++ *rsa_bits = 2048; ++ } ++ else if (grub_strcasecmp (value, "RSA3072") == 0) ++ { ++ *asymmetric = TPM_ALG_RSA; ++ *rsa_bits = 3072; ++ } ++ else if (grub_strcasecmp (value, "RSA4096") == 0) ++ { ++ *asymmetric = TPM_ALG_RSA; ++ *rsa_bits = 4096; ++ } ++ else if (grub_strcasecmp (value, "ECC_NIST_P384") == 0) ++ { ++ *asymmetric = TPM_ALG_ECC; ++ *ecc_curve = TPM_ECC_NIST_P384; ++ } ++ else if (grub_strcasecmp (value, "ECC_NIST_P521") == 0) ++ { ++ *asymmetric = TPM_ALG_ECC; ++ *ecc_curve = TPM_ECC_NIST_P521; ++ } ++ else if (grub_strcasecmp (value, "ECC_BN_P256") == 0) ++ { ++ *asymmetric = TPM_ALG_ECC; ++ *ecc_curve = TPM_ECC_BN_P256; ++ } ++ else if (grub_strcasecmp (value, "ECC_BN_P638") == 0) ++ { ++ *asymmetric = TPM_ALG_ECC; ++ *ecc_curve = TPM_ECC_BN_P638; ++ } ++ else if (grub_strcasecmp (value, "ECC_SM2_P256") == 0) ++ { ++ *asymmetric = TPM_ALG_ECC; ++ *ecc_curve = TPM_ECC_SM2_P256; ++ } ++ else ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("Value '%s' is not a valid asymmetric key type"), ++ value); ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID *bank) ++{ ++ if (grub_strcasecmp (value, "SHA1") == 0) ++ *bank = TPM_ALG_SHA1; ++ else if (grub_strcasecmp (value, "SHA256") == 0) ++ *bank = TPM_ALG_SHA256; ++ else if (grub_strcasecmp (value, "SHA384") == 0) ++ *bank = TPM_ALG_SHA384; ++ else if (grub_strcasecmp (value, "SHA512") == 0) ++ *bank = TPM_ALG_SHA512; ++ else ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("Value '%s' is not a valid PCR bank"), value); ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE *handle) ++{ ++ unsigned long num; ++ ++ grub_errno = GRUB_ERR_NONE; ++ num = grub_strtoul (value, NULL, 0); ++ if (grub_errno != GRUB_ERR_NONE) ++ return grub_error (grub_errno, N_("TPM handle value '%s' is not a number"), ++ value); ++ ++ if (num > GRUB_UINT_MAX) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("Value %lu is too large to be a TPM handle, TPM " ++ "handles are unsigned 32-bit integers"), num); ++ ++ *handle = (TPM_HANDLE)num; ++ ++ return GRUB_ERR_NONE; ++} +diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c +new file mode 100644 +index 000000000..df0727215 +--- /dev/null ++++ b/grub-core/tpm2/module.c +@@ -0,0 +1,1028 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++typedef enum grub_tpm2_protector_mode ++{ ++ GRUB_TPM2_PROTECTOR_MODE_UNSET, ++ GRUB_TPM2_PROTECTOR_MODE_SRK, ++ GRUB_TPM2_PROTECTOR_MODE_NV ++} grub_tpm2_protector_mode_t; ++ ++enum grub_tpm2_protector_options ++{ ++ OPTION_MODE, ++ OPTION_PCRS, ++ OPTION_BANK, ++ OPTION_TPM2KEY, ++ OPTION_KEYFILE, ++ OPTION_SRK, ++ OPTION_ASYMMETRIC, ++ OPTION_NVINDEX ++}; ++ ++struct grub_tpm2_protector_context ++{ ++ grub_tpm2_protector_mode_t mode; ++ grub_uint8_t pcrs[TPM_MAX_PCRS]; ++ grub_uint8_t pcr_count; ++ TPM_ALG_ID asymmetric; ++ TPM_KEY_BITS rsa_bits; ++ TPM_ECC_CURVE ecc_curve; ++ TPM_ALG_ID bank; ++ const char *tpm2key; ++ const char *keyfile; ++ TPM_HANDLE srk; ++ TPM_HANDLE nv; ++}; ++ ++static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] = ++ { ++ /* Options for all modes */ ++ { ++ .longarg = "mode", ++ .shortarg = 'm', ++ .flags = 0, ++ .arg = NULL, ++ .type = ARG_TYPE_STRING, ++ .doc = ++ N_("Unseal key using SRK ('srk') (default) or retrieve it from an NV " ++ "Index ('nv')."), ++ }, ++ { ++ .longarg = "pcrs", ++ .shortarg = 'p', ++ .flags = 0, ++ .arg = NULL, ++ .type = ARG_TYPE_STRING, ++ .doc = ++ N_("Comma-separated list of PCRs used to authorize key release " ++ "(e.g., '7,11', default is 7."), ++ }, ++ { ++ .longarg = "bank", ++ .shortarg = 'b', ++ .flags = 0, ++ .arg = NULL, ++ .type = ARG_TYPE_STRING, ++ .doc = ++ N_("Bank of PCRs used to authorize key release: " ++ "SHA1, SHA256 (default), SHA384 or SHA512."), ++ }, ++ /* SRK-mode options */ ++ { ++ .longarg = "tpm2key", ++ .shortarg = 'T', ++ .flags = 0, ++ .arg = NULL, ++ .type = ARG_TYPE_STRING, ++ .doc = ++ N_("Required in SRK mode, path to the key file in TPM 2.0 Key File Format " ++ "to unseal using the TPM (e.g., (hd0,gpt1)/boot/grub2/secret.tpm)."), ++ }, ++ { ++ .longarg = "keyfile", ++ .shortarg = 'k', ++ .flags = 0, ++ .arg = NULL, ++ .type = ARG_TYPE_STRING, ++ .doc = ++ N_("Required in SRK mode, path to the sealed key file to unseal using " ++ "the TPM (e.g., (hd0,gpt1)/boot/grub2/sealed_key). " ++ "Use '-tpm2key' instead"), ++ }, ++ { ++ .longarg = "srk", ++ .shortarg = 's', ++ .flags = 0, ++ .arg = NULL, ++ .type = ARG_TYPE_STRING, ++ .doc = ++ N_("In SRK mode, the SRK handle if the SRK is persistent."), ++ }, ++ { ++ .longarg = "asymmetric", ++ .shortarg = 'a', ++ .flags = 0, ++ .arg = NULL, ++ .type = ARG_TYPE_STRING, ++ .doc = ++ N_("In SRK mode, the type of SRK: RSA (RSA2048), RSA3072, " ++ "RSA4096, ECC (ECC_NIST_P256), ECC_NIST_P384, " ++ "ECC_NIST_P521, ECC_BN_P256, ECC_BN_P638, and ECC_SM2_P256. " ++ "(default is RSA2048)"), ++ }, ++ /* NV Index-mode options */ ++ { ++ .longarg = "nvindex", ++ .shortarg = 'n', ++ .flags = 0, ++ .arg = NULL, ++ .type = ARG_TYPE_STRING, ++ .doc = ++ N_("Required in NV Index mode, the NV handle to read which must " ++ "readily exist on the TPM and which contains the key."), ++ }, ++ /* End of list */ ++ {0, 0, 0, 0, 0, 0} ++ }; ++ ++static grub_extcmd_t grub_tpm2_protector_init_cmd; ++static grub_extcmd_t grub_tpm2_protector_clear_cmd; ++static struct grub_tpm2_protector_context grub_tpm2_protector_ctx = { 0 }; ++ ++static grub_err_t ++grub_tpm2_protector_srk_read_file (const char *filepath, void **buffer, ++ grub_size_t *buffer_size) ++{ ++ grub_file_t file; ++ grub_off_t file_size; ++ void *read_buffer; ++ grub_off_t read_n; ++ grub_err_t err; ++ ++ /* Using GRUB_FILE_TYPE_SIGNATURE ensures we do not hash the keyfile into PCR9 ++ * otherwise we'll never be able to predict the value of PCR9 at unseal time */ ++ file = grub_file_open (filepath, GRUB_FILE_TYPE_SIGNATURE); ++ if (file == NULL) ++ { ++ /* Push errno from grub_file_open() into the error message stack */ ++ grub_error_push(); ++ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, ++ N_("Could not open file: %s\n"), ++ filepath); ++ goto error; ++ } ++ ++ file_size = grub_file_size (file); ++ if (file_size == 0) ++ { ++ err = grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("Could not read file size: %s"), ++ filepath); ++ goto error; ++ } ++ ++ read_buffer = grub_malloc (file_size); ++ if (read_buffer == NULL) ++ { ++ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ N_("Could not allocate buffer for %s"), ++ filepath); ++ goto error; ++ } ++ ++ read_n = grub_file_read (file, read_buffer, file_size); ++ if (read_n != file_size) ++ { ++ grub_free (read_buffer); ++ err = grub_error (GRUB_ERR_FILE_READ_ERROR, ++ N_("Could not retrieve file contents: %s"), ++ filepath); ++ goto error; ++ } ++ ++ *buffer = read_buffer; ++ *buffer_size = file_size; ++ ++ err = GRUB_ERR_NONE; ++ ++error: ++ grub_file_close (file); ++ ++ return err; ++} ++ ++static grub_err_t ++grub_tpm2_protector_srk_unmarshal_keyfile (void *sealed_key, ++ grub_size_t sealed_key_size, ++ TPM2_SEALED_KEY *sk) ++{ ++ struct grub_tpm2_buffer buf; ++ ++ grub_tpm2_buffer_init (&buf); ++ if (sealed_key_size > buf.cap) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Sealed key larger than %" PRIuGRUB_SIZE " bytes"), ++ buf.cap); ++ ++ grub_memcpy (buf.data, sealed_key, sealed_key_size); ++ buf.size = sealed_key_size; ++ ++ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public); ++ grub_tpm2_mu_TPM2B_Unmarshal (&buf, (TPM2B *)&sk->private); ++ ++ if (buf.error) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Malformed TPM wire key file")); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm2_protector_srk_unmarshal_tpm2key (void *sealed_key, ++ grub_size_t sealed_key_size, ++ tpm2key_policy_t *policy_seq, ++ tpm2key_authpolicy_t *authpol_seq, ++ grub_uint32_t *parent, ++ TPM2_SEALED_KEY *sk) ++{ ++ asn1_node tpm2key = NULL; ++ grub_uint32_t parent_tmp; ++ void *sealed_pub = NULL; ++ grub_size_t sealed_pub_size; ++ void *sealed_priv = NULL; ++ grub_size_t sealed_priv_size; ++ struct grub_tpm2_buffer buf; ++ grub_err_t err; ++ ++ /* ++ * Start to parse the tpm2key file ++ * TPMKey ::= SEQUENCE { ++ * type OBJECT IDENTIFIER, ++ * emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL, ++ * policy [1] EXPLICIT SEQUENCE OF TPMPolicy OPTIONAL, ++ * secret [2] EXPLICIT OCTET STRING OPTIONAL, ++ * authPolicy [3] EXPLICIT SEQUENCE OF TPMAuthPolicy OPTIONAL, ++ * parent INTEGER, ++ * pubkey OCTET STRING, ++ * privkey OCTET STRING ++ * } ++ */ ++ err = grub_tpm2key_start_parsing (&tpm2key, sealed_key, sealed_key_size); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ /* ++ * Retrieve the policy sequence from 'policy' ++ * policy_seq will be NULL when 'policy' is not available ++ */ ++ err = grub_tpm2key_get_policy_seq (tpm2key, policy_seq); ++ if (err != GRUB_ERR_NONE) ++ goto error; ++ ++ /* ++ * Retrieve the authpolicy sequence from 'authPolicy' ++ * authpol_seq will be NULL when 'authPolicy' is not available ++ */ ++ err = grub_tpm2key_get_authpolicy_seq (tpm2key, authpol_seq); ++ if (err != GRUB_ERR_NONE) ++ goto error; ++ ++ /* Retrieve the parent handle */ ++ err = grub_tpm2key_get_parent (tpm2key, &parent_tmp); ++ if (err != GRUB_ERR_NONE) ++ goto error; ++ *parent = parent_tmp; ++ ++ /* Retrieve the public part of the sealed key */ ++ err = grub_tpm2key_get_pubkey (tpm2key, &sealed_pub, &sealed_pub_size); ++ if (err != GRUB_ERR_NONE) ++ goto error; ++ ++ /* Retrieve the private part of the sealed key */ ++ err = grub_tpm2key_get_privkey (tpm2key, &sealed_priv, &sealed_priv_size); ++ if (err != GRUB_ERR_NONE) ++ goto error; ++ ++ /* Unmarshal the sealed key */ ++ grub_tpm2_buffer_init (&buf); ++ if (sealed_pub_size + sealed_priv_size > buf.cap) ++ { ++ err = grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Sealed key larger than %" PRIuGRUB_SIZE " bytes"), ++ buf.cap); ++ goto error; ++ } ++ ++ grub_tpm2_buffer_pack (&buf, sealed_pub, sealed_pub_size); ++ grub_tpm2_buffer_pack (&buf, sealed_priv, sealed_priv_size); ++ ++ buf.offset = 0; ++ ++ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (&buf, &sk->public); ++ grub_tpm2_mu_TPM2B_Unmarshal (&buf, (TPM2B *)&sk->private); ++ ++ if (buf.error) ++ { ++ err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Malformed TPM 2.0 key file")); ++ goto error; ++ } ++ ++ err = GRUB_ERR_NONE; ++ ++error: ++ /* End the parsing */ ++ grub_tpm2key_end_parsing (tpm2key); ++ grub_free (sealed_pub); ++ grub_free (sealed_priv); ++ ++ return err; ++} ++ ++static grub_err_t ++grub_tpm2_protector_srk_get (const struct grub_tpm2_protector_context *ctx, ++ TPM_HANDLE parent, TPM_HANDLE *srk) ++{ ++ TPM_RC rc; ++ TPM2B_PUBLIC public; ++ TPMS_AUTH_COMMAND authCommand = { 0 }; ++ TPM2B_SENSITIVE_CREATE inSensitive = { 0 }; ++ TPM2B_PUBLIC inPublic = { 0 }; ++ TPM2B_DATA outsideInfo = { 0 }; ++ TPML_PCR_SELECTION creationPcr = { 0 }; ++ TPM2B_PUBLIC outPublic = { 0 }; ++ TPM2B_CREATION_DATA creationData = { 0 }; ++ TPM2B_DIGEST creationHash = { 0 }; ++ TPMT_TK_CREATION creationTicket = { 0 }; ++ TPM2B_NAME srkName = { 0 }; ++ TPM_HANDLE srkHandle; ++ ++ if (ctx->srk != 0) ++ { ++ /* Find SRK */ ++ rc = TPM2_ReadPublic (ctx->srk, NULL, &public); ++ if (rc == TPM_RC_SUCCESS) ++ { ++ *srk = ctx->srk; ++ return GRUB_ERR_NONE; ++ } ++ ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("Failed to retrieve SRK (TPM2_ReadPublic: 0x%x)"), ++ rc); ++ } ++ ++ /* Create SRK */ ++ authCommand.sessionHandle = TPM_RS_PW; ++ inPublic.publicArea.type = ctx->asymmetric; ++ inPublic.publicArea.nameAlg = TPM_ALG_SHA256; ++ inPublic.publicArea.objectAttributes.restricted = 1; ++ inPublic.publicArea.objectAttributes.userWithAuth = 1; ++ inPublic.publicArea.objectAttributes.decrypt = 1; ++ inPublic.publicArea.objectAttributes.fixedTPM = 1; ++ inPublic.publicArea.objectAttributes.fixedParent = 1; ++ inPublic.publicArea.objectAttributes.sensitiveDataOrigin = 1; ++ inPublic.publicArea.objectAttributes.noDA = 1; ++ ++ if (ctx->asymmetric == TPM_ALG_RSA) ++ { ++ inPublic.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES; ++ inPublic.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128; ++ inPublic.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CFB; ++ inPublic.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL; ++ inPublic.publicArea.parameters.rsaDetail.keyBits = ctx->rsa_bits; ++ inPublic.publicArea.parameters.rsaDetail.exponent = 0; ++ } ++ else if (ctx->asymmetric == TPM_ALG_ECC) ++ { ++ inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_AES; ++ inPublic.publicArea.parameters.eccDetail.symmetric.keyBits.aes = 128; ++ inPublic.publicArea.parameters.eccDetail.symmetric.mode.aes = TPM_ALG_CFB; ++ inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_NULL; ++ inPublic.publicArea.parameters.eccDetail.curveID = ctx->ecc_curve; ++ inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL; ++ } ++ else ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Unknown SRK algorithm")); ++ ++ rc = TPM2_CreatePrimary (parent, &authCommand, &inSensitive, &inPublic, ++ &outsideInfo, &creationPcr, &srkHandle, &outPublic, ++ &creationData, &creationHash, &creationTicket, ++ &srkName, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("Could not create SRK (TPM2_CreatePrimary: 0x%x)"), ++ rc); ++ ++ *srk = srkHandle; ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION session, ++ struct grub_tpm2_buffer *cmd_buf) ++{ ++ TPM2B_DIGEST pcr_digest; ++ TPML_PCR_SELECTION pcr_sel; ++ TPM_RC rc; ++ ++ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (cmd_buf, &pcr_digest); ++ grub_tpm2_mu_TPML_PCR_SELECTION_Unmarshal (cmd_buf, &pcr_sel); ++ if (cmd_buf->error) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Failed to unmarshal CommandPolicy for TPM2_PolicyPCR")); ++ ++ rc = TPM2_PolicyPCR (session, NULL, &pcr_digest, &pcr_sel, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("Failed to submit PCR policy (TPM2_PolicyPCR: 0x%x)"), ++ rc); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION session) ++{ ++ struct grub_tpm2_buffer buf; ++ grub_err_t err; ++ ++ grub_tpm2_buffer_init (&buf); ++ if (policy->cmd_policy_len > buf.cap) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("CommandPolicy larger than TPM buffer")); ++ ++ grub_memcpy (buf.data, policy->cmd_policy, policy->cmd_policy_len); ++ buf.size = policy->cmd_policy_len; ++ ++ switch (policy->cmd_code) ++ { ++ case TPM_CC_PolicyPCR: ++ err = grub_tpm2_protector_policypcr (session, &buf); ++ break; ++ default: ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Unknown TPM Command: 0x%x"), policy->cmd_code); ++ } ++ ++ return err; ++} ++ ++static grub_err_t ++grub_tpm2_protector_enforce_policy_seq (tpm2key_policy_t policy_seq, ++ TPMI_SH_AUTH_SESSION session) ++{ ++ tpm2key_policy_t policy; ++ grub_err_t err; ++ ++ FOR_LIST_ELEMENTS (policy, policy_seq) ++ { ++ err = grub_tpm2_protector_enforce_policy (policy, session); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm2_protector_simple_policy_seq (const struct grub_tpm2_protector_context *ctx, ++ tpm2key_policy_t *policy_seq) ++{ ++ tpm2key_policy_t policy = NULL; ++ struct grub_tpm2_buffer buf; ++ TPML_PCR_SELECTION pcr_sel = { ++ .count = 1, ++ .pcrSelections = { ++ { ++ .hash = ctx->bank, ++ .sizeOfSelect = 3, ++ .pcrSelect = { 0 } ++ }, ++ } ++ }; ++ grub_uint8_t i; ++ grub_err_t err; ++ ++ if (policy_seq == NULL) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ grub_tpm2_buffer_init (&buf); ++ ++ for (i = 0; i < ctx->pcr_count; i++) ++ TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], ctx->pcrs[i]); ++ ++ grub_tpm2_buffer_pack_u16 (&buf, 0); ++ grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&buf, &pcr_sel); ++ ++ if (buf.error) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ policy = grub_malloc (sizeof(struct tpm2key_policy)); ++ if (policy == NULL) ++ { ++ err = GRUB_ERR_OUT_OF_MEMORY; ++ goto error; ++ } ++ policy->cmd_code = TPM_CC_PolicyPCR; ++ policy->cmd_policy = grub_malloc (buf.size); ++ if (policy->cmd_policy == NULL) ++ { ++ err = GRUB_ERR_OUT_OF_MEMORY; ++ goto error; ++ } ++ grub_memcpy (policy->cmd_policy, buf.data, buf.size); ++ policy->cmd_policy_len = buf.size; ++ ++ grub_list_push (GRUB_AS_LIST_P (policy_seq), GRUB_AS_LIST (policy)); ++ ++ return GRUB_ERR_NONE; ++ ++error: ++ grub_free (policy); ++ ++ return err; ++} ++ ++static grub_err_t ++grub_tpm2_protector_unseal (tpm2key_policy_t policy_seq, TPM_HANDLE sealed_handle, ++ grub_uint8_t **key, grub_size_t *key_size) ++{ ++ TPMS_AUTH_COMMAND authCmd = { 0 }; ++ TPM2B_SENSITIVE_DATA data; ++ TPM2B_NONCE nonceCaller = { 0 }; ++ TPMT_SYM_DEF symmetric = { 0 }; ++ TPMI_SH_AUTH_SESSION session; ++ grub_uint8_t *key_out; ++ TPM_RC rc; ++ grub_err_t err; ++ ++ /* Start Auth Session */ ++ nonceCaller.size = TPM_SHA256_DIGEST_SIZE; ++ symmetric.algorithm = TPM_ALG_NULL; ++ rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, NULL, &nonceCaller, NULL, ++ TPM_SE_POLICY, &symmetric, TPM_ALG_SHA256, ++ &session, NULL, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("Failed to start auth session (TPM2_StartAuthSession: 0x%x)"), ++ rc); ++ ++ /* Enforce the policy command sequence */ ++ err = grub_tpm2_protector_enforce_policy_seq (policy_seq, session); ++ if (err != GRUB_ERR_NONE) ++ goto error; ++ ++ /* Unseal Sealed Key */ ++ authCmd.sessionHandle = session; ++ rc = TPM2_Unseal (sealed_handle, &authCmd, &data, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ err = grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("Failed to unseal sealed key (TPM2_Unseal: 0x%x)"), ++ rc); ++ goto error; ++ } ++ ++ /* Epilogue */ ++ key_out = grub_malloc (data.size); ++ if (key_out == NULL) ++ { ++ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ N_("No memory left to allocate unlock key buffer")); ++ goto error; ++ } ++ ++ grub_memcpy (key_out, data.buffer, data.size); ++ ++ *key = key_out; ++ *key_size = data.size; ++ ++ err = GRUB_ERR_NONE; ++ ++error: ++ TPM2_FlushContext (session); ++ ++ return err; ++} ++ ++static grub_err_t ++grub_tpm2_protector_srk_recover (const struct grub_tpm2_protector_context *ctx, ++ grub_uint8_t **key, grub_size_t *key_size) ++{ ++ TPMS_AUTH_COMMAND authCmd = { 0 }; ++ TPM2_SEALED_KEY sealed_key = { 0 }; ++ TPM2B_NAME name = { 0 }; ++ void *file_bytes = NULL; ++ grub_size_t file_size = 0; ++ TPM_HANDLE parent_handle = 0; ++ TPM_HANDLE srk_handle = 0; ++ TPM_HANDLE sealed_handle = 0; ++ tpm2key_policy_t policy_seq = NULL; ++ tpm2key_authpolicy_t authpol = NULL; ++ tpm2key_authpolicy_t authpol_seq = NULL; ++ TPM_RC rc; ++ grub_err_t err; ++ ++ /* ++ * Retrieve sealed key, parent handle, policy sequence, and authpolicy ++ * sequence from the key file ++ */ ++ if (ctx->tpm2key) ++ { ++ err = grub_tpm2_protector_srk_read_file (ctx->tpm2key, &file_bytes, ++ &file_size); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ err = grub_tpm2_protector_srk_unmarshal_tpm2key (file_bytes, ++ file_size, ++ &policy_seq, ++ &authpol_seq, ++ &parent_handle, ++ &sealed_key); ++ if (err != GRUB_ERR_NONE) ++ goto exit1; ++ } ++ else ++ { ++ err = grub_tpm2_protector_srk_read_file (ctx->keyfile, &file_bytes, ++ &file_size); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ parent_handle = TPM_RH_OWNER; ++ err = grub_tpm2_protector_srk_unmarshal_keyfile (file_bytes, ++ file_size, ++ &sealed_key); ++ if (err != GRUB_ERR_NONE) ++ goto exit1; ++ } ++ ++ /* Get the SRK to unseal the sealed key */ ++ err = grub_tpm2_protector_srk_get (ctx, parent_handle, &srk_handle); ++ if (err != GRUB_ERR_NONE) ++ goto exit1; ++ ++ /* Load the sealed key and associate it with the SRK */ ++ authCmd.sessionHandle = TPM_RS_PW; ++ rc = TPM2_Load (srk_handle, &authCmd, &sealed_key.private, &sealed_key.public, ++ &sealed_handle, &name, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ err = grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("Failed to load sealed key (TPM2_Load: 0x%x)"), ++ rc); ++ goto exit2; ++ } ++ ++ /* ++ * Set err to an error code to trigger the standalone policy sequence ++ * if there is no authpolicy sequence ++ */ ++ err = GRUB_ERR_READ_ERROR; ++ ++ /* Iterate the authpolicy sequence to find one that unseals the key */ ++ FOR_LIST_ELEMENTS (authpol, authpol_seq) ++ { ++ err = grub_tpm2_protector_unseal (authpol->policy_seq, sealed_handle, ++ key, key_size); ++ if (err == GRUB_ERR_NONE) ++ break; ++ ++ /* ++ * Push the error message into the grub_error stack ++ * Note: The grub_error stack may overflow if there are too many policy ++ * sequences. Anyway, we still can keep the error messages from ++ * the first few policy sequences which are usually most likely to ++ * unseal the key. ++ */ ++ grub_error_push(); ++ } ++ ++ /* Give the standalone policy sequence a try */ ++ if (err != GRUB_ERR_NONE) ++ { ++ /* ++ * Create a basic policy sequence based on the given PCR selection if the ++ * key file doesn't provide one ++ */ ++ if (policy_seq == NULL) ++ { ++ err = grub_tpm2_protector_simple_policy_seq (ctx, &policy_seq); ++ if (err != GRUB_ERR_NONE) ++ goto exit3; ++ } ++ ++ err = grub_tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size); ++ } ++ ++ /* Pop error messages on success */ ++ if (err == GRUB_ERR_NONE) ++ while (grub_error_pop ()); ++ ++exit3: ++ TPM2_FlushContext (sealed_handle); ++ ++exit2: ++ TPM2_FlushContext (srk_handle); ++ ++exit1: ++ grub_tpm2key_free_policy_seq (policy_seq); ++ grub_tpm2key_free_authpolicy_seq (authpol_seq); ++ grub_free (file_bytes); ++ return err; ++} ++ ++static grub_err_t ++grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context *ctx, ++ grub_uint8_t **key, grub_size_t *key_size) ++{ ++ (void)ctx; ++ (void)key; ++ (void)key_size; ++ ++ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, ++ N_("NV Index mode is not implemented yet")); ++} ++ ++static grub_err_t ++grub_tpm2_protector_recover (const struct grub_tpm2_protector_context *ctx, ++ grub_uint8_t **key, grub_size_t *key_size) ++{ ++ switch (ctx->mode) ++ { ++ case GRUB_TPM2_PROTECTOR_MODE_SRK: ++ return grub_tpm2_protector_srk_recover (ctx, key, key_size); ++ case GRUB_TPM2_PROTECTOR_MODE_NV: ++ return grub_tpm2_protector_nv_recover (ctx, key, key_size); ++ default: ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++} ++ ++static grub_err_t ++grub_tpm2_protector_recover_key (grub_uint8_t **key, grub_size_t *key_size) ++{ ++ /* Expect a call to tpm2_protector_init before anybody tries to use us */ ++ if (grub_tpm2_protector_ctx.mode == GRUB_TPM2_PROTECTOR_MODE_UNSET) ++ return grub_error (GRUB_ERR_INVALID_COMMAND, ++ N_("Cannot use TPM2 key protector without initializing " ++ "it, call tpm2_protector_init first")); ++ ++ if (key == NULL || key_size == NULL) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ return grub_tpm2_protector_recover (&grub_tpm2_protector_ctx, key, key_size); ++} ++ ++static grub_err_t ++grub_tpm2_protector_check_args (struct grub_tpm2_protector_context *ctx) ++{ ++ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_UNSET) ++ ctx->mode = GRUB_TPM2_PROTECTOR_MODE_SRK; ++ ++ /* Checks for SRK mode */ ++ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ctx->keyfile == NULL ++ && ctx->tpm2key == NULL) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("In SRK mode, a key file must be specified: " ++ "--tpm2key/-T or --keyfile/-k")); ++ ++ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ctx->keyfile ++ && ctx->tpm2key) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("In SRK mode, please specify a key file with " ++ "only --tpm2key/-T or --keyfile/-k")); ++ ++ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK && ctx->nv) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("In SRK mode, an NV Index cannot be specified")); ++ ++ /* Checks for NV mode */ ++ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->nv == 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("In NV Index mode, an NV Index must be specified: " ++ "--nvindex or -n")); ++ ++ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ++ (ctx->tpm2key || ctx->keyfile)) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("In NV Index mode, a keyfile cannot be specified")); ++ ++ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->srk) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("In NV Index mode, an SRK cannot be specified")); ++ ++ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_NV && ctx->asymmetric) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("In NV Index mode, an asymmetric key type cannot be " ++ "specified")); ++ ++ /* Defaults assignment */ ++ if (ctx->bank == TPM_ALG_ERROR) ++ ctx->bank = TPM_ALG_SHA256; ++ ++ if (ctx->pcr_count == 0) ++ { ++ ctx->pcrs[0] = 7; ++ ctx->pcr_count = 1; ++ } ++ ++ if (ctx->mode == GRUB_TPM2_PROTECTOR_MODE_SRK) ++ { ++ if (!ctx->asymmetric) ++ { ++ ctx->asymmetric = TPM_ALG_RSA; ++ ctx->rsa_bits = 2048; ++ } ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm2_protector_parse_file (const char *value, const char **file) ++{ ++ if (grub_strlen (value) == 0) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ *file = grub_strdup (value); ++ if (*file == NULL) ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ N_("No memory to duplicate file path")); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm2_protector_parse_mode (const char *value, ++ grub_tpm2_protector_mode_t *mode) ++{ ++ if (grub_strcmp (value, "srk") == 0) ++ *mode = GRUB_TPM2_PROTECTOR_MODE_SRK; ++ else if (grub_strcmp (value, "nv") == 0) ++ *mode = GRUB_TPM2_PROTECTOR_MODE_NV; ++ else ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("Value '%s' is not a valid TPM2 key protector mode"), ++ value); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm2_protector_init_cmd_handler (grub_extcmd_context_t ctxt, int argc, ++ char **args __attribute__ ((unused))) ++{ ++ struct grub_arg_list *state = ctxt->state; ++ grub_err_t err; ++ ++ if (argc) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("The TPM2 key protector does not accept any " ++ "non-option arguments (i.e., like -o and/or --option " ++ "only)")); ++ ++ grub_free ((void *) grub_tpm2_protector_ctx.keyfile); ++ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx)); ++ ++ if (state[OPTION_MODE].set) /* mode */ ++ { ++ err = grub_tpm2_protector_parse_mode (state[OPTION_MODE].arg, ++ &grub_tpm2_protector_ctx.mode); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ } ++ ++ if (state[OPTION_PCRS].set) /* pcrs */ ++ { ++ err = grub_tpm2_protector_parse_pcrs (state[OPTION_PCRS].arg, ++ grub_tpm2_protector_ctx.pcrs, ++ &grub_tpm2_protector_ctx.pcr_count); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ } ++ ++ if (state[OPTION_BANK].set) /* bank */ ++ { ++ err = grub_tpm2_protector_parse_bank (state[OPTION_BANK].arg, ++ &grub_tpm2_protector_ctx.bank); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ } ++ ++ if (state[OPTION_TPM2KEY].set) /* tpm2key */ ++ { ++ err = grub_tpm2_protector_parse_file (state[OPTION_TPM2KEY].arg, ++ &grub_tpm2_protector_ctx.tpm2key); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ } ++ ++ if (state[OPTION_KEYFILE].set) /* keyfile */ ++ { ++ err = grub_tpm2_protector_parse_file (state[OPTION_KEYFILE].arg, ++ &grub_tpm2_protector_ctx.keyfile); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ } ++ ++ if (state[OPTION_SRK].set) /* srk */ ++ { ++ err = grub_tpm2_protector_parse_tpm_handle (state[OPTION_SRK].arg, ++ &grub_tpm2_protector_ctx.srk); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ } ++ ++ if (state[OPTION_ASYMMETRIC].set) /* asymmetric */ ++ { ++ err = grub_tpm2_protector_parse_asymmetric (state[OPTION_ASYMMETRIC].arg, ++ &grub_tpm2_protector_ctx.asymmetric, ++ &grub_tpm2_protector_ctx.rsa_bits, ++ &grub_tpm2_protector_ctx.ecc_curve); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ } ++ ++ if (state[OPTION_NVINDEX].set) /* nvindex */ ++ { ++ err = grub_tpm2_protector_parse_tpm_handle (state[OPTION_NVINDEX].arg, ++ &grub_tpm2_protector_ctx.nv); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ } ++ ++ err = grub_tpm2_protector_check_args (&grub_tpm2_protector_ctx); ++ ++ /* This command only initializes the protector, so nothing else to do. */ ++ ++ return err; ++} ++ ++static grub_err_t ++grub_tpm2_protector_clear_cmd_handler (grub_extcmd_context_t ctxt __attribute__ ((unused)), ++ int argc, ++ char **args __attribute__ ((unused))) ++{ ++ if (argc) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("tpm2_key_protector_clear accepts no arguments")); ++ ++ grub_free ((void *) grub_tpm2_protector_ctx.keyfile); ++ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx)); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static struct grub_key_protector grub_tpm2_key_protector = ++ { ++ .name = "tpm2", ++ .recover_key = grub_tpm2_protector_recover_key ++ }; ++ ++GRUB_MOD_INIT (tpm2) ++{ ++ grub_tpm2_protector_init_cmd = ++ grub_register_extcmd ("tpm2_key_protector_init", ++ grub_tpm2_protector_init_cmd_handler, 0, ++ N_("[-m mode] " ++ "[-p pcr_list] " ++ "[-b pcr_bank] " ++ "[-T tpm2_key_file_path] " ++ "[-k sealed_key_file_path] " ++ "[-s srk_handle] " ++ "[-a asymmetric_key_type] " ++ "[-n nv_index]"), ++ N_("Initialize the TPM2 key protector."), ++ grub_tpm2_protector_init_cmd_options); ++ grub_tpm2_protector_clear_cmd = ++ grub_register_extcmd ("tpm2_key_protector_clear", ++ grub_tpm2_protector_clear_cmd_handler, 0, NULL, ++ N_("Clear the TPM2 key protector if previously initialized."), ++ NULL); ++ grub_key_protector_register (&grub_tpm2_key_protector); ++} ++ ++GRUB_MOD_FINI (tpm2) ++{ ++ grub_free ((void *) grub_tpm2_protector_ctx.keyfile); ++ grub_memset (&grub_tpm2_protector_ctx, 0, sizeof (grub_tpm2_protector_ctx)); ++ ++ grub_key_protector_unregister (&grub_tpm2_key_protector); ++ grub_unregister_extcmd (grub_tpm2_protector_clear_cmd); ++ grub_unregister_extcmd (grub_tpm2_protector_init_cmd); ++} +diff --git a/grub-core/tpm2/tpm2key.asn b/grub-core/tpm2/tpm2key.asn +new file mode 100644 +index 000000000..e3b6a03e0 +--- /dev/null ++++ b/grub-core/tpm2/tpm2key.asn +@@ -0,0 +1,31 @@ ++-- ++-- TPM 2.0 key file format ++-- To generate tpm2key_asn1_tab.c: asn1Parser tpm2key.asn ++-- ++TPM2KEY {} ++DEFINITIONS IMPLICIT TAGS ::= ++ ++BEGIN ++ ++TPMPolicy ::= SEQUENCE { ++ CommandCode [0] EXPLICIT INTEGER, ++ CommandPolicy [1] EXPLICIT OCTET STRING ++} ++ ++TPMAuthPolicy ::= SEQUENCE { ++ Name [0] EXPLICIT UTF8String OPTIONAL, ++ Policy [1] EXPLICIT SEQUENCE OF TPMPolicy ++} ++ ++TPMKey ::= SEQUENCE { ++ type OBJECT IDENTIFIER, ++ emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL, ++ policy [1] EXPLICIT SEQUENCE OF TPMPolicy OPTIONAL, ++ secret [2] EXPLICIT OCTET STRING OPTIONAL, ++ authPolicy [3] EXPLICIT SEQUENCE OF TPMAuthPolicy OPTIONAL, ++ parent INTEGER, ++ pubkey OCTET STRING, ++ privkey OCTET STRING ++} ++ ++END +diff --git a/grub-core/tpm2/tpm2key.c b/grub-core/tpm2/tpm2key.c +new file mode 100644 +index 000000000..a26c287c9 +--- /dev/null ++++ b/grub-core/tpm2/tpm2key.c +@@ -0,0 +1,447 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2023 SUSE LLC ++ * ++ * 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern asn1_static_node tpm2key_asn1_tab[]; ++const char *sealed_key_oid = "2.23.133.10.1.5"; ++ ++static int ++asn1_allocate_and_read (asn1_node node, const char *name, void **content, grub_size_t *content_size) ++{ ++ grub_uint8_t *tmpstr = NULL; ++ int tmpstr_size = 0; ++ int ret; ++ ++ if (content == NULL) ++ return ASN1_MEM_ERROR; ++ ++ ret = asn1_read_value (node, name, NULL, &tmpstr_size); ++ if (ret != ASN1_MEM_ERROR) ++ return ret; ++ ++ tmpstr = grub_malloc (tmpstr_size); ++ if (tmpstr == NULL) ++ return ASN1_MEM_ERROR; ++ ++ ret = asn1_read_value (node, name, tmpstr, &tmpstr_size); ++ if (ret != ASN1_SUCCESS) ++ return ret; ++ ++ *content = tmpstr; ++ *content_size = tmpstr_size; ++ ++ return ASN1_SUCCESS; ++} ++ ++static int ++asn1_read_uint32 (asn1_node node, const char *name, grub_uint32_t *out) ++{ ++ grub_uint32_t tmp = 0; ++ grub_uint8_t *ptr; ++ void *data = NULL; ++ grub_size_t data_size; ++ int ret; ++ ++ ret = asn1_allocate_and_read (node, name, &data, &data_size); ++ if (ret != ASN1_SUCCESS) ++ return ret; ++ ++ if (data_size > 4) ++ { ++ ret = ASN1_MEM_ERROR; ++ goto error; ++ } ++ ++ /* convert the big-endian integer to host uint32 */ ++ ptr = (grub_uint8_t *)&tmp + (4 - data_size); ++ grub_memcpy (ptr, data, data_size); ++ tmp = grub_be_to_cpu32 (tmp); ++ ++ *out = tmp; ++error: ++ if (data) ++ grub_free (data); ++ return ret; ++} ++ ++grub_err_t ++grub_tpm2key_start_parsing (asn1_node *parsed_tpm2key, void *data, grub_size_t size) ++{ ++ asn1_node tpm2key; ++ asn1_node tpm2key_asn1 = NULL; ++ void *type_oid = NULL; ++ grub_size_t type_oid_size = 0; ++ void *empty_auth = NULL; ++ grub_size_t empty_auth_size = 0; ++ int tmp_size = 0; ++ int ret; ++ grub_err_t err; ++ ++ /* ++ TPMKey ::= SEQUENCE { ++ type OBJECT IDENTIFIER, ++ emptyAuth [0] EXPLICIT BOOLEAN OPTIONAL, ++ policy [1] EXPLICIT SEQUENCE OF TPMPolicy OPTIONAL, ++ secret [2] EXPLICIT OCTET STRING OPTIONAL, ++ authPolicy [3] EXPLICIT SEQUENCE OF TPMAuthPolicy OPTIONAL, ++ parent INTEGER, ++ pubkey OCTET STRING, ++ privkey OCTET STRING ++ } ++ */ ++ ret = asn1_array2tree (tpm2key_asn1_tab, &tpm2key_asn1, NULL); ++ if (ret != ASN1_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Failed to parse TPM2KEY ASN.1 array")); ++ ++ ret = asn1_create_element (tpm2key_asn1, "TPM2KEY.TPMKey", &tpm2key); ++ if (ret != ASN1_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Failed to create TPM2KEY.TPMKey")); ++ ++ ret = asn1_der_decoding (&tpm2key, data, size, NULL); ++ if (ret != ASN1_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Failed to decode TPM2KEY DER")); ++ ++ /* Check if 'type' is Sealed Key or not */ ++ ret = asn1_allocate_and_read (tpm2key, "type", &type_oid, &type_oid_size); ++ if (ret != ASN1_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ N_("Not a valid TPM2KEY file")); ++ ++ if (grub_memcmp (sealed_key_oid, type_oid, type_oid_size) != 0) ++ { ++ err = grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ N_("Not a valid TPM2KEY file")); ++ goto error; ++ } ++ ++ /* 'emptyAuth' must be 'TRUE' since we don't support password authorization */ ++ ret = asn1_allocate_and_read (tpm2key, "emptyAuth", &empty_auth, &empty_auth_size); ++ if (ret != ASN1_SUCCESS || grub_strncmp ("TRUE", empty_auth, empty_auth_size) != 0) ++ { ++ err = grub_error (GRUB_ERR_BAD_ARGUMENT, N_("emptyAuth not TRUE")); ++ goto error; ++ } ++ ++ /* 'secret' should not be in a sealed key */ ++ ret = asn1_read_value (tpm2key, "secret", NULL, &tmp_size); ++ if (ret != ASN1_ELEMENT_NOT_FOUND) ++ { ++ err = grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("\"secret\" not allowed for Sealed Key")); ++ goto error; ++ } ++ ++ *parsed_tpm2key = tpm2key; ++ ++ err = GRUB_ERR_NONE; ++ ++error: ++ if (type_oid) ++ grub_free (type_oid); ++ ++ if (empty_auth) ++ grub_free (empty_auth); ++ ++ return err; ++} ++ ++void ++grub_tpm2key_end_parsing (asn1_node tpm2key) ++{ ++ if (tpm2key) ++ asn1_delete_structure (&tpm2key); ++ tpm2key = NULL; ++} ++ ++grub_err_t ++grub_tpm2key_get_parent (asn1_node tpm2key, grub_uint32_t *parent) ++{ ++ int ret; ++ ++ if (parent == NULL) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("NULL pointer detected")); ++ ++ if (tpm2key == NULL) ++ return grub_error (GRUB_ERR_READ_ERROR, N_("Invalid parent node")); ++ ++ ret = asn1_read_uint32 (tpm2key, "parent", parent); ++ if (ret != ASN1_SUCCESS) ++ return grub_error (GRUB_ERR_READ_ERROR, N_("Failed to retrieve parent")); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++tpm2key_get_octstring (asn1_node tpm2key, const char *name, void **data, grub_size_t *size) ++{ ++ int ret; ++ ++ if (name == NULL || data == NULL || size == NULL) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Invalid parameter(s)")); ++ ++ if (tpm2key == NULL) ++ return grub_error (GRUB_ERR_READ_ERROR, N_("Invalid %s node"), name); ++ ++ ret = asn1_allocate_and_read (tpm2key, name, data, size); ++ if (ret != ASN1_SUCCESS) ++ return grub_error (GRUB_ERR_READ_ERROR, ++ N_("Failed to retrieve %s"), ++ name); ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_tpm2key_get_pubkey (asn1_node tpm2key, void **data, grub_size_t *size) ++{ ++ return tpm2key_get_octstring (tpm2key, "pubkey", data, size); ++} ++ ++grub_err_t ++grub_tpm2key_get_privkey (asn1_node tpm2key, void **data, grub_size_t *size) ++{ ++ return tpm2key_get_octstring (tpm2key, "privkey", data, size); ++} ++ ++/* ++ * The string to fetch 'Policy' from 'authPolicy': ++ * authPolicy.?XX.Policy ++ */ ++#define AUTHPOLICY_POL_MAX_STR "authPolicy.?XX.Policy" ++#define AUTHPOLICY_POL_MAX (sizeof (AUTHPOLICY_POL_MAX_STR)) ++ ++/* ++ * Expected strings for CommandCode and CommandPolicy: ++ * policy.?XX.CommandCode ++ * policy.?XX.CommandPolicy ++ * authPolicy.?XX.Policy.?YY.CommandCode ++ * authPolicy.?XX.Policy.?YY.CommandPolicy ++ */ ++#define CMD_CODE_MAX_STR AUTHPOLICY_POL_MAX_STR".?YY.CommandCode" ++#define CMD_POL_MAX_STR AUTHPOLICY_POL_MAX_STR".?YY.CommandPolicy" ++#define CMD_CODE_MAX (sizeof (CMD_CODE_MAX_STR)) ++#define CMD_POL_MAX (sizeof (CMD_POL_MAX_STR)) ++ ++static int ++tpm2key_get_policy_seq (asn1_node tpm2key, const char *prefix, ++ tpm2key_policy_t *policy_seq) ++{ ++ tpm2key_policy_t tmp_seq = NULL; ++ tpm2key_policy_t policy = NULL; ++ int policy_n; ++ char cmd_code[CMD_CODE_MAX]; ++ char cmd_pol[CMD_POL_MAX]; ++ grub_size_t cmd_policy_len; ++ int i; ++ int ret; ++ ++ ret = asn1_number_of_elements (tpm2key, prefix, &policy_n); ++ if (ret != ASN1_SUCCESS) ++ return ret; ++ ++ /* ++ * Limit the number of policy commands to two digits (99) ++ * Although there is no upper bound for the number of policy commands, ++ * in practice, it takes one or two policy commands to unseal the key, ++ * so the 99 commands limit is more than enough. ++ */ ++ if (policy_n > 100 || policy_n < 1) ++ return ASN1_VALUE_NOT_VALID; ++ ++ /* ++ * Iterate the policy commands backwards since grub_list_push() prepends ++ * the item into the list. ++ */ ++ for (i = policy_n; i >= 1; i--) { ++ policy = grub_zalloc (sizeof (struct tpm2key_policy)); ++ if (policy == NULL) ++ { ++ ret = ASN1_MEM_ALLOC_ERROR; ++ goto error; ++ } ++ grub_snprintf (cmd_code, CMD_CODE_MAX, "%s.?%d.CommandCode", prefix, i); ++ grub_snprintf (cmd_pol, CMD_POL_MAX, "%s.?%d.CommandPolicy", prefix, i); ++ ++ /* CommandCode [0] EXPLICIT INTEGER */ ++ ret = asn1_read_uint32 (tpm2key, cmd_code, &policy->cmd_code); ++ if (ret != ASN1_SUCCESS) ++ return ret; ++ ++ /* CommandPolicy [1] EXPLICIT OCTET STRING */ ++ ret = tpm2key_get_octstring (tpm2key, cmd_pol, &policy->cmd_policy, ++ &cmd_policy_len); ++ if (ret != ASN1_SUCCESS) ++ { ++ goto error; ++ } ++ else if (cmd_policy_len > GRUB_TPM2_BUFFER_CAPACITY) ++ { ++ /* ++ * CommandPolicy is the marshalled parameters for the TPM command so ++ * it should not be larger than the maximum TPM2 buffer. ++ */ ++ ret = ASN1_VALUE_NOT_VALID; ++ goto error; ++ } ++ policy->cmd_policy_len = (grub_uint16_t)cmd_policy_len; ++ ++ /* Prepend the policy command into the sequence */ ++ grub_list_push (GRUB_AS_LIST_P (&tmp_seq), GRUB_AS_LIST (policy)); ++ } ++ ++ *policy_seq = tmp_seq; ++ ++ return ASN1_SUCCESS; ++ ++error: ++ if (policy) ++ { ++ grub_free (policy->cmd_policy); ++ grub_free (policy); ++ } ++ grub_tpm2key_free_policy_seq (tmp_seq); ++ ++ return ret; ++} ++ ++grub_err_t ++grub_tpm2key_get_policy_seq (asn1_node tpm2key, tpm2key_policy_t *policy_seq) ++{ ++ int ret; ++ ++ ret = tpm2key_get_policy_seq (tpm2key, "policy", policy_seq); ++ if (ret == ASN1_ELEMENT_NOT_FOUND) ++ { ++ /* "policy" is optional, so it may not be available */ ++ *policy_seq = NULL; ++ return GRUB_ERR_NONE; ++ } ++ else if (ret != ASN1_SUCCESS) ++ return grub_error (GRUB_ERR_READ_ERROR, N_("Failed to retrieve policy")); ++ ++ return GRUB_ERR_NONE; ++} ++ ++void ++grub_tpm2key_free_policy_seq (tpm2key_policy_t policy_seq) ++{ ++ tpm2key_policy_t policy; ++ tpm2key_policy_t next; ++ ++ if (policy_seq == NULL) ++ return; ++ ++ FOR_LIST_ELEMENTS_SAFE (policy, next, policy_seq) ++ { ++ grub_free (policy->cmd_policy); ++ grub_free (policy); ++ } ++} ++ ++grub_err_t ++grub_tpm2key_get_authpolicy_seq (asn1_node tpm2key, tpm2key_authpolicy_t *authpol_seq) ++{ ++ tpm2key_authpolicy_t tmp_seq = NULL; ++ tpm2key_authpolicy_t authpol = NULL; ++ int authpol_n; ++ char authpol_pol[AUTHPOLICY_POL_MAX]; ++ int i; ++ int ret; ++ grub_err_t err; ++ ++ ret = asn1_number_of_elements (tpm2key, "authPolicy", &authpol_n); ++ if (ret == ASN1_ELEMENT_NOT_FOUND) ++ { ++ /* "authPolicy" is optional, so it may not be available */ ++ *authpol_seq = NULL; ++ return GRUB_ERR_NONE; ++ } ++ else if (ret != ASN1_SUCCESS) ++ return grub_error (GRUB_ERR_READ_ERROR, N_("Failed to retrieve authPolicy")); ++ ++ /* Limit the number of authPolicy elements to two digits (99) */ ++ if (authpol_n > 100 || authpol_n < 1) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("Invalid number of autoPolicy elements")); ++ ++ /* ++ * Iterate the authPolicy elements backwards since grub_list_push() prepends ++ * the item into the list. ++ */ ++ for (i = authpol_n; i >= 1; i--) { ++ authpol = grub_zalloc (sizeof (struct tpm2key_authpolicy)); ++ if (authpol == NULL) ++ { ++ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ N_("Failed to allocate memory for authPolicy")); ++ goto error; ++ } ++ grub_snprintf (authpol_pol, AUTHPOLICY_POL_MAX, "authPolicy.?%d.Policy", i); ++ ++ ret = tpm2key_get_policy_seq (tpm2key, authpol_pol, &authpol->policy_seq); ++ if (ret != ASN1_SUCCESS) ++ { ++ err = grub_error (GRUB_ERR_READ_ERROR, ++ N_("Failed to retrieve policy from authPolicy")); ++ goto error; ++ } ++ ++ /* Prepend the authPolicy element into the sequence */ ++ grub_list_push (GRUB_AS_LIST_P (&tmp_seq), GRUB_AS_LIST (authpol)); ++ } ++ ++ *authpol_seq = tmp_seq; ++ ++ return GRUB_ERR_NONE; ++ ++error: ++ if (authpol) ++ { ++ grub_tpm2key_free_policy_seq (authpol->policy_seq); ++ grub_free (authpol); ++ } ++ ++ grub_tpm2key_free_authpolicy_seq (tmp_seq); ++ ++ return err; ++} ++ ++void ++grub_tpm2key_free_authpolicy_seq (tpm2key_authpolicy_t authpol_seq) ++{ ++ tpm2key_authpolicy_t authpol; ++ tpm2key_authpolicy_t next; ++ ++ if (authpol_seq == NULL) ++ return; ++ ++ FOR_LIST_ELEMENTS_SAFE (authpol, next, authpol_seq) ++ { ++ grub_tpm2key_free_policy_seq (authpol->policy_seq); ++ grub_free (authpol); ++ } ++} +diff --git a/grub-core/tpm2/tpm2key_asn1_tab.c b/grub-core/tpm2/tpm2key_asn1_tab.c +new file mode 100644 +index 000000000..551fc46ec +--- /dev/null ++++ b/grub-core/tpm2/tpm2key_asn1_tab.c +@@ -0,0 +1,41 @@ ++/* ++ * This file is generated by 'asn1Parser tpm2key.asn' and the '#include' ++ * headers are replaced with the ones in grub2. ++ * - 'grub/mm.h' for the definition of 'NULL' ++ * - 'grub/libtasn1.h' for the definition of 'asn1_static_node' ++ */ ++ ++#include ++#include ++ ++const asn1_static_node tpm2key_asn1_tab[] = { ++ { "TPM2KEY", 536875024, NULL }, ++ { NULL, 1073741836, NULL }, ++ { "TPMPolicy", 1610612741, NULL }, ++ { "CommandCode", 1610620931, NULL }, ++ { NULL, 2056, "0"}, ++ { "CommandPolicy", 536879111, NULL }, ++ { NULL, 2056, "1"}, ++ { "TPMAuthPolicy", 1610612741, NULL }, ++ { "Name", 1610637346, NULL }, ++ { NULL, 2056, "0"}, ++ { "Policy", 536879115, NULL }, ++ { NULL, 1073743880, "1"}, ++ { NULL, 2, "TPMPolicy"}, ++ { "TPMKey", 536870917, NULL }, ++ { "type", 1073741836, NULL }, ++ { "emptyAuth", 1610637316, NULL }, ++ { NULL, 2056, "0"}, ++ { "policy", 1610637323, NULL }, ++ { NULL, 1073743880, "1"}, ++ { NULL, 2, "TPMPolicy"}, ++ { "secret", 1610637319, NULL }, ++ { NULL, 2056, "2"}, ++ { "authPolicy", 1610637323, NULL }, ++ { NULL, 1073743880, "3"}, ++ { NULL, 2, "TPMAuthPolicy"}, ++ { "parent", 1073741827, NULL }, ++ { "pubkey", 1073741831, NULL }, ++ { "privkey", 7, NULL }, ++ { NULL, 0, NULL } ++}; +diff --git a/include/grub/tpm2/internal/args.h b/include/grub/tpm2/internal/args.h +new file mode 100644 +index 000000000..58d13e031 +--- /dev/null ++++ b/include/grub/tpm2/internal/args.h +@@ -0,0 +1,41 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_TPM2_INTERNAL_ARGS_HEADER ++#define GRUB_TPM2_INTERNAL_ARGS_HEADER 1 ++ ++#include ++#include ++ ++grub_err_t ++grub_tpm2_protector_parse_pcrs (char *value, grub_uint8_t *pcrs, ++ grub_uint8_t *pcr_count); ++ ++grub_err_t ++grub_tpm2_protector_parse_asymmetric (const char *value, ++ TPM_ALG_ID *asymmetric, ++ TPM_KEY_BITS *rsa_bits, ++ TPM_ECC_CURVE *ecc_curve); ++ ++grub_err_t ++grub_tpm2_protector_parse_bank (const char *value, TPM_ALG_ID *bank); ++ ++grub_err_t ++grub_tpm2_protector_parse_tpm_handle (const char *value, TPM_HANDLE *handle); ++ ++#endif /* ! GRUB_TPM2_INTERNAL_ARGS_HEADER */ +diff --git a/include/grub/tpm2/tpm2key.h b/include/grub/tpm2/tpm2key.h +new file mode 100644 +index 000000000..df46203e3 +--- /dev/null ++++ b/include/grub/tpm2/tpm2key.h +@@ -0,0 +1,83 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2023 SUSE LLC ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_TPM2_TPM2KEY_HEADER ++#define GRUB_TPM2_TPM2KEY_HEADER 1 ++ ++#include ++#include ++ ++/* ++ * TPMPolicy ::= SEQUENCE { ++ * CommandCode [0] EXPLICIT INTEGER, ++ * CommandPolicy [1] EXPLICIT OCTET STRING ++ * } ++ */ ++struct tpm2key_policy { ++ struct tpm2key_policy *next; ++ struct tpm2key_policy **prev; ++ grub_uint32_t cmd_code; ++ void *cmd_policy; ++ grub_uint16_t cmd_policy_len; ++}; ++typedef struct tpm2key_policy *tpm2key_policy_t; ++ ++/* ++ * TPMAuthPolicy ::= SEQUENCE { ++ * Name [0] EXPLICIT UTF8String OPTIONAL, ++ * Policy [1] EXPLICIT SEQUENCE OF TPMPolicy ++ * } ++ * ++ * Name is not a necessary part to unseal the key. Ignore it. ++ */ ++struct tpm2key_authpolicy { ++ struct tpm2key_authpolicy *next; ++ struct tpm2key_authpolicy **prev; ++ /* char *name; */ ++ tpm2key_policy_t policy_seq; ++}; ++typedef struct tpm2key_authpolicy *tpm2key_authpolicy_t; ++ ++grub_err_t ++grub_tpm2key_start_parsing (asn1_node *parsed_tpm2key, void *data, grub_size_t size); ++ ++void ++grub_tpm2key_end_parsing (asn1_node tpm2key); ++ ++grub_err_t ++grub_tpm2key_get_parent (asn1_node tpm2key, grub_uint32_t *parent); ++ ++grub_err_t ++grub_tpm2key_get_pubkey (asn1_node tpm2key, void **data, grub_size_t *size); ++ ++grub_err_t ++grub_tpm2key_get_privkey (asn1_node tpm2key, void **data, grub_size_t *size); ++ ++grub_err_t ++grub_tpm2key_get_policy_seq (asn1_node tpm2key, tpm2key_policy_t *policy_seq); ++ ++void ++grub_tpm2key_free_policy_seq (tpm2key_policy_t policy_seq); ++ ++grub_err_t ++grub_tpm2key_get_authpolicy_seq (asn1_node tpm2key, tpm2key_authpolicy_t *authpol_seq); ++ ++void ++grub_tpm2key_free_authpolicy_seq (tpm2key_authpolicy_t authpol_seq); ++ ++#endif /* GRUB_TPM2_TPM2KEY_HEADER */ +-- +2.35.3 + diff --git a/0003-tpm2-Implement-more-TPM2-commands.patch b/0003-tpm2-Implement-more-TPM2-commands.patch new file mode 100644 index 0000000000000000000000000000000000000000..7880b03278ad06390d7227d550b330d557424efc --- /dev/null +++ b/0003-tpm2-Implement-more-TPM2-commands.patch @@ -0,0 +1,543 @@ +From a49c4dcbcb04078434f461ed3356c04042be461a Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Wed, 8 Feb 2023 10:30:55 +0800 +Subject: [PATCH 3/4] tpm2: Implement more TPM2 commands + +This commit implements a few more TPM2 commands as the preparation for +the authorized policy support. + +* TPM2_LoadExternal + This command is added to load the external public key to verify the + signed policy digest +* TPM2_HashSequenceStart, TPM2_SequenceUpdate, TPM2_SequenceComplete, + and TPM2_Hash + With those commands, we can use the TPM as a coprocessor to calculate + the hash of a given binary blob. +* TPM2_VerifySignature + This command verifies the given signature with the given public key + and returns the validation ticket to authorize the policy. +* TPM2_PolicyAuthorize + This command approves the given policy digest so that we can unseal + the key with the newly authorized policy. + +Signed-off-by: Gary Lin +--- + grub-core/tpm2/tpm2.c | 424 +++++++++++++++++++++++++ + include/grub/tpm2/internal/functions.h | 57 ++++ + 2 files changed, 481 insertions(+) + +diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c +index d67699a24..159353b08 100644 +--- a/grub-core/tpm2/tpm2.c ++++ b/grub-core/tpm2/tpm2.c +@@ -427,6 +427,73 @@ TPM2_Load (const TPMI_DH_OBJECT parent_handle, + return TPM_RC_SUCCESS; + } + ++TPM_RC ++TPM2_LoadExternal (const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_SENSITIVE *inPrivate, ++ const TPM2B_PUBLIC *inPublic, ++ const TPMI_RH_HIERARCHY hierarchy, ++ TPM_HANDLE *objectHandle, ++ TPM2B_NAME *name, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM_HANDLE objectHandleTmp; ++ TPM2B_NAME nameTmp; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ grub_uint32_t param_size; ++ ++ if (!inPublic) ++ return TPM_RC_VALUE; ++ ++ if (!objectHandle) ++ objectHandle = &objectHandleTmp; ++ if (!name) ++ name = &nameTmp; ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (objectHandle, 0, sizeof (*objectHandle)); ++ grub_memset (name, 0, sizeof (*name)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ if (authCommand) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ if (inPrivate) ++ grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (&in, inPrivate); ++ else ++ grub_tpm2_buffer_pack_u16 (&in, 0); ++ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic); ++ grub_tpm2_buffer_pack_u32 (&in, hierarchy); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_LoadExternal, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ grub_tpm2_buffer_unpack_u32 (&out, objectHandle); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)name); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ + TPM_RC + TPM2_Unseal (const TPMI_DH_OBJECT itemHandle, + const TPMS_AUTH_COMMAND *authCommand, +@@ -759,3 +826,360 @@ TPM2_EvictControl (const TPMI_RH_PROVISION auth, + + return TPM_RC_SUCCESS; + } ++ ++TPM_RC ++TPM2_HashSequenceStart (const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_AUTH *auth, ++ const TPMI_ALG_HASH hashAlg, ++ TPMI_DH_OBJECT *sequenceHandle, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMI_DH_OBJECT sequenceHandleTmp; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ TPM_RC rc; ++ grub_uint32_t parameterSize; ++ ++ if (!auth) ++ return TPM_RC_VALUE; ++ ++ if (!sequenceHandle) ++ sequenceHandle = &sequenceHandleTmp; ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (sequenceHandle, 0, sizeof (*sequenceHandle)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ if (authCommand) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_tpm2_mu_TPM2B_Marshal (&in, auth->size, auth->buffer); ++ grub_tpm2_buffer_pack_u16 (&in, hashAlg); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_HashSequenceStart, &responseCode, &in, ++ &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ grub_tpm2_buffer_unpack_u32 (&out, sequenceHandle); ++ if (tag == TPM_ST_SESSIONS) ++ { ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); ++ } ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_SequenceUpdate (const TPMI_DH_OBJECT sequenceHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_MAX_BUFFER *buffer, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPM_RC responseCode; ++ TPM_RC rc; ++ grub_uint32_t parameterSize; ++ ++ if (!authCommand) ++ return TPM_RC_VALUE; ++ ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, sequenceHandle); ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ if (buffer) ++ grub_tpm2_mu_TPM2B_Marshal (&in, buffer->size, buffer->buffer); ++ else ++ grub_tpm2_buffer_pack_u16 (&in, 0); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (TPM_ST_SESSIONS, TPM_CC_SequenceUpdate, ++ &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_SequenceComplete (const TPMI_DH_OBJECT sequenceHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_MAX_BUFFER *buffer, ++ const TPMI_RH_HIERARCHY hierarchy, ++ TPM2B_DIGEST *result, ++ TPMT_TK_HASHCHECK *validation, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPM2B_DIGEST resultTmp; ++ TPMT_TK_HASHCHECK validationTmp; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPM_RC responseCode; ++ TPM_RC rc; ++ grub_uint32_t parameterSize; ++ ++ if (!authCommand) ++ return TPM_RC_VALUE; ++ ++ if (!result) ++ result = &resultTmp; ++ if (!validation) ++ validation = &validationTmp; ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (result, 0, sizeof (*result)); ++ grub_memset (validation, 0, sizeof (*validation)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, sequenceHandle); ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ if (buffer) ++ grub_tpm2_mu_TPM2B_Marshal (&in, buffer->size, buffer->buffer); ++ else ++ grub_tpm2_buffer_pack_u16 (&in, 0); ++ grub_tpm2_buffer_pack_u32 (&in, hierarchy); ++ ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (TPM_ST_SESSIONS, TPM_CC_SequenceComplete, ++ &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal */ ++ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize); ++ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (&out, result); ++ grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (&out, validation); ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_Hash (const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_MAX_BUFFER *data, ++ const TPMI_ALG_HASH hashAlg, ++ const TPMI_RH_HIERARCHY hierarchy, ++ TPM2B_DIGEST *outHash, ++ TPMT_TK_HASHCHECK *validation, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPM2B_DIGEST outHashTmp; ++ TPMT_TK_HASHCHECK validationTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ grub_uint32_t param_size; ++ ++ if (hashAlg == TPM_ALG_NULL) ++ return TPM_RC_VALUE; ++ ++ if (!outHash) ++ outHash = &outHashTmp; ++ if (!validation) ++ validation = &validationTmp; ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (outHash, 0, sizeof (*outHash)); ++ grub_memset (validation, 0, sizeof (*validation)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ if (authCommand) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ if (data) ++ grub_tpm2_mu_TPM2B_Marshal (&in, data->size, data->buffer); ++ else ++ grub_tpm2_buffer_pack_u16 (&in, 0); ++ grub_tpm2_buffer_pack_u16 (&in, hashAlg); ++ grub_tpm2_buffer_pack_u32 (&in, hierarchy); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_Hash, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (&out, outHash); ++ grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (&out, validation); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_VerifySignature (const TPMI_DH_OBJECT keyHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_DIGEST *digest, ++ const TPMT_SIGNATURE *signature, ++ TPMT_TK_VERIFIED *validation, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPMT_TK_VERIFIED validationTmp; ++ TPM_RC responseCode; ++ grub_uint32_t param_size; ++ ++ if (!digest || !signature) ++ return TPM_RC_VALUE; ++ ++ if (!validation) ++ validation = &validationTmp; ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (validation, 0, sizeof (*validation)); ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ if (authCommand) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_tpm2_buffer_pack_u32 (&in, keyHandle); ++ grub_tpm2_mu_TPM2B_Marshal (&in, digest->size, digest->buffer); ++ grub_tpm2_mu_TPMT_SIGNATURE_Marshal (&in, signature); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_VerifySignature, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (&out, validation); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} ++ ++TPM_RC ++TPM2_PolicyAuthorize (const TPMI_SH_POLICY policySession, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_DIGEST *approvedPolicy, ++ const TPM2B_NONCE *policyRef, ++ const TPM2B_NAME *keySign, ++ const TPMT_TK_VERIFIED *checkTicket, ++ TPMS_AUTH_RESPONSE *authResponse) ++{ ++ TPM_RC rc; ++ struct grub_tpm2_buffer in; ++ struct grub_tpm2_buffer out; ++ TPMS_AUTH_RESPONSE authResponseTmp; ++ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS; ++ TPM_RC responseCode; ++ grub_uint32_t param_size; ++ ++ if (!approvedPolicy || !keySign || !checkTicket) ++ return TPM_RC_VALUE; ++ ++ if (!authResponse) ++ authResponse = &authResponseTmp; ++ ++ grub_memset (authResponse, 0, sizeof (*authResponse)); ++ ++ /* Marshal */ ++ grub_tpm2_buffer_init (&in); ++ grub_tpm2_buffer_pack_u32 (&in, policySession); ++ if (authCommand) ++ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand); ++ grub_tpm2_mu_TPM2B_Marshal (&in, approvedPolicy->size, approvedPolicy->buffer); ++ if (policyRef) ++ grub_tpm2_mu_TPM2B_Marshal (&in, policyRef->size, policyRef->buffer); ++ else ++ grub_tpm2_buffer_pack_u16 (&in, 0); ++ grub_tpm2_mu_TPM2B_Marshal (&in, keySign->size, keySign->name); ++ grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (&in, checkTicket); ++ if (in.error) ++ return TPM_RC_FAILURE; ++ ++ /* Submit */ ++ grub_tpm2_buffer_init (&out); ++ rc = grub_tpm2_submit_command (tag, TPM_CC_PolicyAuthorize, &responseCode, &in, &out); ++ if (rc != TPM_RC_SUCCESS) ++ return rc; ++ if (responseCode != TPM_RC_SUCCESS) ++ return responseCode; ++ ++ /* Unmarshal*/ ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size); ++ if (tag == TPM_ST_SESSIONS) ++ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse); ++ if (out.error) ++ return TPM_RC_FAILURE; ++ ++ return TPM_RC_SUCCESS; ++} +diff --git a/include/grub/tpm2/internal/functions.h b/include/grub/tpm2/internal/functions.h +index 9380f26a2..67b78fab8 100644 +--- a/include/grub/tpm2/internal/functions.h ++++ b/include/grub/tpm2/internal/functions.h +@@ -70,6 +70,15 @@ TPM2_Load (const TPMI_DH_OBJECT parent_handle, + TPM2B_NAME *name, + TPMS_AUTH_RESPONSE *authResponse); + ++TPM_RC ++TPM2_LoadExternal (const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_SENSITIVE *inPrivate, ++ const TPM2B_PUBLIC *inPublic, ++ const TPMI_RH_HIERARCHY hierarchy, ++ TPM_HANDLE *objectHandle, ++ TPM2B_NAME *name, ++ TPMS_AUTH_RESPONSE *authResponse); ++ + TPM_RC + TPM2_Unseal (const TPMI_DH_OBJECT item_handle, + const TPMS_AUTH_COMMAND *authCommand, +@@ -114,4 +123,52 @@ TPM2_EvictControl (const TPMI_RH_PROVISION auth, + const TPMI_DH_PERSISTENT persistentHandle, + TPMS_AUTH_RESPONSE *authResponse); + ++TPM_RC ++TPM2_HashSequenceStart (const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_AUTH *auth, ++ const TPMI_ALG_HASH hashAlg, ++ TPMI_DH_OBJECT *sequenceHandle, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_SequenceUpdate (const TPMI_DH_OBJECT sequenceHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_MAX_BUFFER *buffer, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_SequenceComplete (const TPMI_DH_OBJECT sequenceHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_MAX_BUFFER *buffer, ++ const TPMI_RH_HIERARCHY hierarchy, ++ TPM2B_DIGEST *result, ++ TPMT_TK_HASHCHECK *validation, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_Hash (const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_MAX_BUFFER *data, ++ const TPMI_ALG_HASH hashAlg, ++ const TPMI_RH_HIERARCHY hierarchy, ++ TPM2B_DIGEST *outHash, ++ TPMT_TK_HASHCHECK *validation, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_VerifySignature (const TPMI_DH_OBJECT keyHandle, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_DIGEST *digest, ++ const TPMT_SIGNATURE *signature, ++ TPMT_TK_VERIFIED *validation, ++ TPMS_AUTH_RESPONSE *authResponse); ++ ++TPM_RC ++TPM2_PolicyAuthorize (const TPMI_SH_POLICY policySession, ++ const TPMS_AUTH_COMMAND *authCommand, ++ const TPM2B_DIGEST *approvedPolicy, ++ const TPM2B_NONCE *policyRef, ++ const TPM2B_NAME *keySign, ++ const TPMT_TK_VERIFIED *checkTicket, ++ TPMS_AUTH_RESPONSE *authResponse); ++ + #endif /* ! GRUB_TPM2_INTERNAL_FUNCTIONS_HEADER */ +-- +2.35.3 + diff --git a/0160-Add-suport-for-signing-grub-with-an-appended-signatu.patch b/0004-Add-suport-for-signing-grub-with-an-appended-signatu.patch similarity index 75% rename from 0160-Add-suport-for-signing-grub-with-an-appended-signatu.patch rename to 0004-Add-suport-for-signing-grub-with-an-appended-signatu.patch index ef6441492f7d3eb7e9af62a29a83579da98cbbd5..584dbfe90a09755224279de102599d7fbc43d0d7 100644 --- a/0160-Add-suport-for-signing-grub-with-an-appended-signatu.patch +++ b/0004-Add-suport-for-signing-grub-with-an-appended-signatu.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From cf6b16f113b1b5e6efce79b569be1de3e504de8f Mon Sep 17 00:00:00 2001 From: Rashmica Gupta Date: Thu, 11 Jun 2020 11:26:23 +1000 -Subject: [PATCH] Add suport for signing grub with an appended signature +Subject: [PATCH 04/23] Add suport for signing grub with an appended signature Add infrastructure to allow firmware to verify the integrity of grub by use of a Linux-kernel-module-style appended signature. We initially @@ -43,19 +43,65 @@ that verifies these signatures. You can find one at: I will be proposing this for inclusion in a future Power Architecture Platform Reference (PAPR). --- - util/grub-install-common.c | 18 ++++++++++++++---- - util/grub-mkimage.c | 15 +++++++++++++-- - util/grub-mkimagexx.c | 39 ++++++++++++++++++++++++++++++++++++++- - util/mkimage.c | 13 +++++++------ include/grub/util/install.h | 8 ++++++-- include/grub/util/mkimage.h | 4 ++-- - 6 files changed, 80 insertions(+), 17 deletions(-) + util/grub-install-common.c | 15 +++++++++++--- + util/grub-mkimage.c | 11 +++++++++++ + util/grub-mkimagexx.c | 39 ++++++++++++++++++++++++++++++++++++- + util/mkimage.c | 13 +++++++------ + 6 files changed, 76 insertions(+), 14 deletions(-) -diff --git a/util/grub-install-common.c b/util/grub-install-common.c -index 4e212e690c5..a74fee16e22 100644 +--- a/include/grub/util/install.h ++++ b/include/grub/util/install.h +@@ -67,6 +67,9 @@ + N_("SBAT metadata"), 0 }, \ + { "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \ + N_("disable shim_lock verifier"), 0 }, \ ++ { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\ ++ "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \ ++ 1}, \ + { "verbose", 'v', 0, 0, \ + N_("print verbose messages."), 1 } + +@@ -130,7 +133,8 @@ + GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, + GRUB_INSTALL_OPTIONS_DTB, + GRUB_INSTALL_OPTIONS_SBAT, +- GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK ++ GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, ++ GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE + }; + + extern char *grub_install_source_directory; +@@ -190,7 +194,7 @@ + size_t npubkeys, + char *config_path, + const struct grub_install_image_target_desc *image_target, +- int note, ++ int note, size_t appsig_size, + grub_compression_t comp, const char *dtb_file, + const char *sbat_path, const int disable_shim_lock); + +--- a/include/grub/util/mkimage.h ++++ b/include/grub/util/mkimage.h +@@ -51,12 +51,12 @@ + const struct grub_install_image_target_desc *image_target); + void + grub_mkimage_generate_elf32 (const struct grub_install_image_target_desc *image_target, +- int note, char **core_img, size_t *core_size, ++ int note, size_t appsig_size, char **core_img, size_t *core_size, + Elf32_Addr target_addr, + struct grub_mkimage_layout *layout); + void + grub_mkimage_generate_elf64 (const struct grub_install_image_target_desc *image_target, +- int note, char **core_img, size_t *core_size, ++ int note, size_t appsig_size, char **core_img, size_t *core_size, + Elf64_Addr target_addr, + struct grub_mkimage_layout *layout); + --- a/util/grub-install-common.c +++ b/util/grub-install-common.c -@@ -461,10 +461,12 @@ static size_t npubkeys; +@@ -466,10 +466,12 @@ static char *sbat; static int disable_shim_lock; static grub_compression_t compression; @@ -67,8 +113,8 @@ index 4e212e690c5..a74fee16e22 100644 + const char *end; switch (key) { - case 'C': -@@ -562,6 +564,12 @@ grub_install_parse (int key, char *arg) + case GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS: +@@ -567,6 +569,12 @@ grub_util_error (_("Unrecognized compression `%s'"), arg); case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE: return 1; @@ -81,24 +127,20 @@ index 4e212e690c5..a74fee16e22 100644 default: return 0; } -@@ -661,11 +669,13 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, - " --output '%s' " - " --dtb '%s' " - "--sbat '%s' " -- "--format '%s' --compression '%s' %s %s %s\n", -+ "--format '%s' --compression '%s' " -+ "--appended-signature-size %zu %s %s %s\n", - dir, prefix, - outname, dtb ? : "", sbat ? : "", mkimage_target, -- compnames[compression], note ? "--note" : "", -- disable_shim_lock ? "--disable-shim-lock" : "", s); -+ compnames[compression], appsig_size, -+ disable_shim_lock ? "--disable-shim-lock" : "", -+ note ? "--note" : "", s); - free (s); +@@ -679,9 +687,11 @@ + *p = '\0'; - tgt = grub_install_get_image_target (mkimage_target); -@@ -675,7 +685,7 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, + grub_util_info ("grub-mkimage --directory '%s' --prefix '%s' --output '%s'" +- " --format '%s' --compression '%s'%s%s%s\n", ++ " --format '%s' --compression '%s'" ++ " --appended-signature-size %zu%s%s%s\n", + dir, prefix, outname, + mkimage_target, compnames[compression], ++ appsig_size, + note ? " --note" : "", + disable_shim_lock ? " --disable-shim-lock" : "", s); + free (s); +@@ -693,7 +703,7 @@ grub_install_generate_image (dir, prefix, fp, outname, modules.entries, memdisk_path, pubkeys, npubkeys, config_path, tgt, @@ -107,11 +149,9 @@ index 4e212e690c5..a74fee16e22 100644 disable_shim_lock); while (dc--) grub_install_pop_module (); -diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c -index c0d55993702..8a53310548b 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c -@@ -84,6 +84,7 @@ static struct argp_option options[] = { +@@ -84,6 +84,7 @@ {"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0}, {"disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, N_("disable shim_lock verifier"), 0}, {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, @@ -119,7 +159,7 @@ index c0d55993702..8a53310548b 100644 { 0, 0, 0, 0, 0, 0 } }; -@@ -128,6 +129,7 @@ struct arguments +@@ -128,6 +129,7 @@ char *sbat; int note; int disable_shim_lock; @@ -127,7 +167,7 @@ index c0d55993702..8a53310548b 100644 const struct grub_install_image_target_desc *image_target; grub_compression_t comp; }; -@@ -138,6 +140,7 @@ argp_parser (int key, char *arg, struct argp_state *state) +@@ -138,6 +140,7 @@ /* Get the input argument from argp_parse, which we know is a pointer to our arguments structure. */ struct arguments *arguments = state->input; @@ -135,7 +175,7 @@ index c0d55993702..8a53310548b 100644 switch (key) { -@@ -170,6 +173,13 @@ argp_parser (int key, char *arg, struct argp_state *state) +@@ -170,6 +173,13 @@ arguments->note = 1; break; @@ -149,23 +189,17 @@ index c0d55993702..8a53310548b 100644 case 'm': if (arguments->memdisk) free (arguments->memdisk); -@@ -324,8 +334,9 @@ main (int argc, char *argv[]) +@@ -324,6 +334,7 @@ arguments.memdisk, arguments.pubkeys, arguments.npubkeys, arguments.config, arguments.image_target, arguments.note, -- arguments.comp, arguments.dtb, -- arguments.sbat, arguments.disable_shim_lock); -+ arguments.appsig_size, arguments.comp, -+ arguments.dtb, arguments.sbat, -+ arguments.disable_shim_lock); ++ arguments.appsig_size, + arguments.comp, arguments.dtb, + arguments.sbat, arguments.disable_shim_lock); - if (grub_util_file_sync (fp) < 0) - grub_util_error (_("cannot sync `%s': %s"), arguments.output ? : "stdout", -diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c -index d78fa3e5330..393119486d3 100644 --- a/util/grub-mkimagexx.c +++ b/util/grub-mkimagexx.c -@@ -84,6 +84,15 @@ struct grub_ieee1275_note +@@ -85,6 +85,15 @@ struct grub_ieee1275_note_desc descriptor; }; @@ -181,7 +215,7 @@ index d78fa3e5330..393119486d3 100644 #define GRUB_XEN_NOTE_NAME "Xen" struct fixup_block_list -@@ -207,7 +216,7 @@ grub_arm_reloc_jump24 (grub_uint32_t *target, Elf32_Addr sym_addr) +@@ -208,7 +217,7 @@ void SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target, @@ -190,7 +224,7 @@ index d78fa3e5330..393119486d3 100644 Elf_Addr target_addr, struct grub_mkimage_layout *layout) { -@@ -221,6 +230,12 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc +@@ -222,6 +231,12 @@ int shnum = 4; int string_size = sizeof (".text") + sizeof ("mods") + 1; @@ -203,7 +237,7 @@ index d78fa3e5330..393119486d3 100644 if (image_target->id != IMAGE_LOONGSON_ELF) phnum += 2; -@@ -484,6 +499,28 @@ SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc +@@ -485,6 +500,28 @@ phdr->p_offset = grub_host_to_target32 (header_size + program_size); } @@ -232,23 +266,21 @@ index d78fa3e5330..393119486d3 100644 { char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr) + shnum * sizeof (*shdr)); -diff --git a/util/mkimage.c b/util/mkimage.c -index a26cf76f72f..bab12276010 100644 --- a/util/mkimage.c +++ b/util/mkimage.c -@@ -869,8 +869,9 @@ grub_install_generate_image (const char *dir, const char *prefix, +@@ -885,8 +885,9 @@ char *memdisk_path, char **pubkey_paths, size_t npubkeys, char *config_path, const struct grub_install_image_target_desc *image_target, - int note, grub_compression_t comp, const char *dtb_path, - const char *sbat_path, int disable_shim_lock) + int note, size_t appsig_size, grub_compression_t comp, -+ const char *dtb_path, const char *sbat_path, ++ const char *dtb_path, const char *sbat_path, + int disable_shim_lock) { char *kernel_img, *core_img; size_t total_module_size, core_size; -@@ -1773,11 +1774,11 @@ grub_install_generate_image (const char *dir, const char *prefix, +@@ -1810,11 +1811,11 @@ else target_addr = image_target->link_addr; if (image_target->voidp_sizeof == 4) @@ -264,55 +296,3 @@ index a26cf76f72f..bab12276010 100644 } break; } -diff --git a/include/grub/util/install.h b/include/grub/util/install.h -index 7df3191f47e..cf4531e02b6 100644 ---- a/include/grub/util/install.h -+++ b/include/grub/util/install.h -@@ -67,6 +67,9 @@ - N_("SBAT metadata"), 0 }, \ - { "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \ - N_("disable shim_lock verifier"), 0 }, \ -+ { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\ -+ "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \ -+ 1}, \ - { "verbose", 'v', 0, 0, \ - N_("print verbose messages."), 1 } - -@@ -128,7 +131,8 @@ enum grub_install_options { - GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS, - GRUB_INSTALL_OPTIONS_DTB, - GRUB_INSTALL_OPTIONS_SBAT, -- GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK -+ GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, -+ GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE - }; - - extern char *grub_install_source_directory; -@@ -188,7 +192,7 @@ grub_install_generate_image (const char *dir, const char *prefix, - size_t npubkeys, - char *config_path, - const struct grub_install_image_target_desc *image_target, -- int note, -+ int note, size_t appsig_size, - grub_compression_t comp, const char *dtb_file, - const char *sbat_path, const int disable_shim_lock); - -diff --git a/include/grub/util/mkimage.h b/include/grub/util/mkimage.h -index 3819a67441c..6f1da89b9b6 100644 ---- a/include/grub/util/mkimage.h -+++ b/include/grub/util/mkimage.h -@@ -51,12 +51,12 @@ grub_mkimage_load_image64 (const char *kernel_path, - const struct grub_install_image_target_desc *image_target); - void - grub_mkimage_generate_elf32 (const struct grub_install_image_target_desc *image_target, -- int note, char **core_img, size_t *core_size, -+ int note, size_t appsig_size, char **core_img, size_t *core_size, - Elf32_Addr target_addr, - struct grub_mkimage_layout *layout); - void - grub_mkimage_generate_elf64 (const struct grub_install_image_target_desc *image_target, -- int note, char **core_img, size_t *core_size, -+ int note, size_t appsig_size, char **core_img, size_t *core_size, - Elf64_Addr target_addr, - struct grub_mkimage_layout *layout); - diff --git a/0004-Add-support-for-Linux-EFI-stub-loading.patch b/0004-Add-support-for-Linux-EFI-stub-loading.patch deleted file mode 100644 index 73d231a266b93cd52db2c667279f01c3559f764a..0000000000000000000000000000000000000000 --- a/0004-Add-support-for-Linux-EFI-stub-loading.patch +++ /dev/null @@ -1,983 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Tue, 10 Jul 2012 11:58:52 -0400 -Subject: [PATCH] Add support for Linux EFI stub loading. - -Also: - -commit 71c843745f22f81e16d259e2e19c99bf3c1855c1 -Author: Colin Watson -Date: Tue Oct 23 10:40:49 2012 -0400 - -Don't allow insmod when secure boot is enabled. - -Hi, - -Fedora's patch to forbid insmod in UEFI Secure Boot environments is fine -as far as it goes. However, the insmod command is not the only way that -modules can be loaded. In particular, the 'normal' command, which -implements the usual GRUB menu and the fully-featured command prompt, -will implicitly load commands not currently loaded into memory. This -permits trivial Secure Boot violations by writing commands implementing -whatever you want to do and pointing $prefix at the malicious code. - -I'm currently test-building this patch (replacing your current -grub-2.00-no-insmod-on-sb.patch), but this should be more correct. It -moves the check into grub_dl_load_file. ---- - grub-core/Makefile.core.def | 16 +- - grub-core/kern/dl.c | 21 +++ - grub-core/kern/efi/efi.c | 28 ++++ - grub-core/kern/efi/mm.c | 32 ++++ - grub-core/loader/arm64/linux.c | 118 +++++++------- - grub-core/loader/arm64/xen_boot.c | 1 - - grub-core/loader/efi/linux.c | 70 ++++++++ - grub-core/loader/i386/efi/linux.c | 335 ++++++++++++++++++++++++++++++++++++++ - grub-core/loader/i386/pc/linux.c | 10 +- - include/grub/arm/linux.h | 9 + - include/grub/arm64/linux.h | 9 + - include/grub/efi/efi.h | 7 +- - include/grub/efi/linux.h | 31 ++++ - 13 files changed, 618 insertions(+), 69 deletions(-) - create mode 100644 grub-core/loader/efi/linux.c - create mode 100644 grub-core/loader/i386/efi/linux.c - create mode 100644 include/grub/efi/linux.h - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 8022e1c0a79..45d3edaa4dc 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -1734,13 +1734,6 @@ module = { - enable = i386_pc; - }; - -- --module = { -- name = linux16; -- common = loader/i386/pc/linux.c; -- enable = x86; --}; -- - module = { - name = ntldr; - i386_pc = loader/i386/pc/ntldr.c; -@@ -1796,7 +1789,9 @@ module = { - - module = { - name = linux; -- x86 = loader/i386/linux.c; -+ i386_pc = loader/i386/pc/linux.c; -+ x86_64_efi = loader/i386/efi/linux.c; -+ i386_efi = loader/i386/efi/linux.c; - i386_xen_pvh = loader/i386/linux.c; - xen = loader/i386/xen.c; - i386_pc = lib/i386/pc/vesa_modes_table.c; -@@ -1811,9 +1806,14 @@ module = { - arm64 = loader/arm64/linux.c; - riscv32 = loader/riscv/linux.c; - riscv64 = loader/riscv/linux.c; -+ emu = loader/emu/linux.c; -+ fdt = lib/fdt.c; -+ - common = loader/linux.c; - common = lib/cmdline.c; - enable = noemu; -+ -+ efi = loader/efi/linux.c; - }; - - module = { -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index 48f8a79073d..b7149370950 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -38,6 +38,14 @@ - #define GRUB_MODULES_MACHINE_READONLY - #endif - -+#ifdef GRUB_MACHINE_EMU -+#include -+#endif -+ -+#ifdef GRUB_MACHINE_EFI -+#include -+#endif -+ - - - #pragma GCC diagnostic ignored "-Wcast-align" -@@ -695,6 +703,19 @@ grub_dl_load_file (const char *filename) - void *core = 0; - grub_dl_t mod = 0; - -+#ifdef GRUB_MACHINE_EFI -+ if (grub_efi_secure_boot ()) -+ { -+#if 0 -+ /* This is an error, but grub2-mkconfig still generates a pile of -+ * insmod commands, so emitting it would be mostly just obnoxious. */ -+ grub_error (GRUB_ERR_ACCESS_DENIED, -+ "Secure Boot forbids loading module from %s", filename); -+#endif -+ return 0; -+ } -+#endif -+ - grub_boot_time ("Loading module %s", filename); - - file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE); -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 8cff7be0289..35b8f670602 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -286,6 +286,34 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, - return grub_efi_get_variable_with_attributes (var, guid, datasize_out, data_out, NULL); - } - -+grub_efi_boolean_t -+grub_efi_secure_boot (void) -+{ -+ grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; -+ grub_size_t datasize; -+ char *secure_boot = NULL; -+ char *setup_mode = NULL; -+ grub_efi_boolean_t ret = 0; -+ -+ secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize); -+ -+ if (datasize != 1 || !secure_boot) -+ goto out; -+ -+ setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize); -+ -+ if (datasize != 1 || !setup_mode) -+ goto out; -+ -+ if (*secure_boot && !*setup_mode) -+ ret = 1; -+ -+ out: -+ grub_free (secure_boot); -+ grub_free (setup_mode); -+ return ret; -+} -+ - #pragma GCC diagnostic ignored "-Wcast-align" - - /* Search the mods section from the PE32/PE32+ image. This code uses -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index 9838fb2f50d..f6aef0ef649 100644 ---- a/grub-core/kern/efi/mm.c -+++ b/grub-core/kern/efi/mm.c -@@ -113,6 +113,38 @@ grub_efi_drop_alloc (grub_efi_physical_address_t address, - } - } - -+/* Allocate pages below a specified address */ -+void * -+grub_efi_allocate_pages_max (grub_efi_physical_address_t max, -+ grub_efi_uintn_t pages) -+{ -+ grub_efi_status_t status; -+ grub_efi_boot_services_t *b; -+ grub_efi_physical_address_t address = max; -+ -+ if (max > 0xffffffff) -+ return 0; -+ -+ b = grub_efi_system_table->boot_services; -+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); -+ -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ -+ if (address == 0) -+ { -+ /* Uggh, the address 0 was allocated... This is too annoying, -+ so reallocate another one. */ -+ address = max; -+ status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); -+ grub_efi_free_pages (0, pages); -+ if (status != GRUB_EFI_SUCCESS) -+ return 0; -+ } -+ -+ return (void *) ((grub_addr_t) address); -+} -+ - /* Allocate pages. Return the pointer to the first of allocated pages. */ - void * - grub_efi_allocate_pages_real (grub_efi_physical_address_t address, -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index ef3e9f9444c..a312c668685 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -41,6 +42,7 @@ 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; -@@ -67,7 +69,8 @@ grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh) - static grub_err_t - finalize_params_linux (void) - { -- int node, retval; -+ grub_efi_loaded_image_t *loaded_image = NULL; -+ int node, retval, len; - - void *fdt; - -@@ -102,79 +105,70 @@ finalize_params_linux (void) - if (grub_fdt_install() != GRUB_ERR_NONE) - goto failure; - -- return GRUB_ERR_NONE; -- --failure: -- grub_fdt_unload(); -- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); --} -- --grub_err_t --grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args) --{ -- grub_efi_memory_mapped_device_path_t *mempath; -- grub_efi_handle_t image_handle; -- grub_efi_boot_services_t *b; -- grub_efi_status_t status; -- grub_efi_loaded_image_t *loaded_image; -- int len; -- -- mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t)); -- if (!mempath) -- return grub_errno; -- -- mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE; -- mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE; -- mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath)); -- mempath[0].memory_type = GRUB_EFI_LOADER_DATA; -- mempath[0].start_address = addr; -- mempath[0].end_address = addr + size; -- -- mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE; -- mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -- mempath[1].header.length = sizeof (grub_efi_device_path_t); -- -- b = grub_efi_system_table->boot_services; -- status = b->load_image (0, grub_efi_image_handle, -- (grub_efi_device_path_t *) mempath, -- (void *) addr, size, &image_handle); -- if (status != GRUB_EFI_SUCCESS) -- return grub_error (GRUB_ERR_BAD_OS, "cannot load image"); -- -- grub_dprintf ("linux", "linux command line: '%s'\n", args); -+ grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n", -+ fdt); - - /* Convert command line to UCS-2 */ -- loaded_image = grub_efi_get_loaded_image (image_handle); -+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); -+ if (!loaded_image) -+ goto failure; -+ - loaded_image->load_options_size = len = -- (grub_strlen (args) + 1) * sizeof (grub_efi_char16_t); -+ (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_errno; -+ 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 *) args, len, NULL); -+ (grub_uint8_t *) linux_args, len, NULL); - -- grub_dprintf ("linux", "starting image %p\n", image_handle); -- status = b->start_image (image_handle, 0, NULL); -+ return GRUB_ERR_NONE; - -- /* When successful, not reached */ -- b->unload_image (image_handle); -- grub_efi_free_pages ((grub_addr_t) loaded_image->load_options, -- GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); -+failure: -+ grub_fdt_unload(); -+ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); -+} - -- return grub_errno; -+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, 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) - { -- if (finalize_params_linux () != GRUB_ERR_NONE) -- return grub_errno; -- -- return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr, -- kernel_size, linux_args)); -+ return (grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr, linux_args)); - } - - static grub_err_t -@@ -288,6 +282,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - { - 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); -@@ -333,6 +328,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)) -+ { -+ 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) -diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c -index 22cc25eccd9..d9b7a9ba400 100644 ---- a/grub-core/loader/arm64/xen_boot.c -+++ b/grub-core/loader/arm64/xen_boot.c -@@ -266,7 +266,6 @@ xen_boot (void) - return err; - - return grub_arch_efi_linux_boot_image (xen_hypervisor->start, -- xen_hypervisor->size, - xen_hypervisor->cmdline); - } - -diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c -new file mode 100644 -index 00000000000..c24202a5dd1 ---- /dev/null -+++ b/grub-core/loader/efi/linux.c -@@ -0,0 +1,70 @@ -+/* -+ * 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#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; -+ -+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 *); -+ -+grub_err_t -+grub_efi_linux_boot (void *kernel_addr, grub_off_t offset, -+ void *kernel_params) -+{ -+ handover_func hf; -+ -+ 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 -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -new file mode 100644 -index 00000000000..bb2616a8092 ---- /dev/null -+++ b/grub-core/loader/i386/efi/linux.c -@@ -0,0 +1,335 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2012 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static grub_dl_t my_mod; -+static int loaded; -+static void *kernel_mem; -+static grub_uint64_t kernel_size; -+static grub_uint8_t *initrd_mem; -+static grub_uint32_t handover_offset; -+struct linux_kernel_params *params; -+static char *linux_cmdline; -+ -+#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) -+ -+static grub_err_t -+grub_linuxefi_boot (void) -+{ -+ int offset = 0; -+ -+#ifdef __x86_64__ -+ offset = 512; -+#endif -+ asm volatile ("cli"); -+ -+ return grub_efi_linux_boot ((char *)kernel_mem, handover_offset + offset, -+ params); -+} -+ -+static grub_err_t -+grub_linuxefi_unload (void) -+{ -+ grub_dl_unref (my_mod); -+ loaded = 0; -+ if (initrd_mem) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, -+ BYTES_TO_PAGES(params->ramdisk_size)); -+ if (linux_cmdline) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) -+ linux_cmdline, -+ BYTES_TO_PAGES(params->cmdline_size + 1)); -+ if (kernel_mem) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, -+ BYTES_TO_PAGES(kernel_size)); -+ if (params) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params, -+ BYTES_TO_PAGES(16384)); -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[]) -+{ -+ grub_file_t *files = 0; -+ int i, nfiles = 0; -+ grub_size_t size = 0; -+ grub_uint8_t *ptr; -+ -+ 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; -+ } -+ -+ files = grub_zalloc (argc * sizeof (files[0])); -+ if (!files) -+ goto fail; -+ -+ for (i = 0; i < argc; i++) -+ { -+ files[i] = grub_file_open (argv[i], GRUB_FILE_TYPE_LINUX_INITRD | GRUB_FILE_TYPE_NO_DECOMPRESS); -+ if (! files[i]) -+ goto fail; -+ nfiles++; -+ size += ALIGN_UP (grub_file_size (files[i]), 4); -+ } -+ -+ initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); -+ if (!initrd_mem) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); -+ goto fail; -+ } -+ -+ params->ramdisk_size = size; -+ params->ramdisk_image = (grub_uint32_t)(grub_addr_t) initrd_mem; -+ -+ ptr = initrd_mem; -+ -+ for (i = 0; i < nfiles; i++) -+ { -+ grub_ssize_t cursize = grub_file_size (files[i]); -+ if (grub_file_read (files[i], ptr, cursize) != cursize) -+ { -+ if (!grub_errno) -+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), -+ argv[i]); -+ goto fail; -+ } -+ ptr += cursize; -+ grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); -+ ptr += ALIGN_UP_OVERHEAD (cursize, 4); -+ } -+ -+ params->ramdisk_size = size; -+ -+ fail: -+ for (i = 0; i < nfiles; i++) -+ grub_file_close (files[i]); -+ grub_free (files); -+ -+ if (initrd_mem && grub_errno) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, -+ BYTES_TO_PAGES(size)); -+ -+ 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_i386_kernel_header lh; -+ grub_ssize_t len, start, filelen; -+ void *kernel = NULL; -+ -+ 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; -+ -+ filelen = grub_file_size (file); -+ -+ kernel = grub_malloc(filelen); -+ -+ if (!kernel) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); -+ goto fail; -+ } -+ -+ if (grub_file_read (file, kernel, filelen) != filelen) -+ { -+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]); -+ goto fail; -+ } -+ -+ if (! grub_linuxefi_secure_validate (kernel, filelen)) -+ { -+ grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), -+ argv[0]); -+ goto fail; -+ } -+ -+ params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); -+ -+ if (! params) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); -+ goto fail; -+ } -+ -+ grub_memset (params, 0, 16384); -+ -+ grub_memcpy (&lh, kernel, sizeof (lh)); -+ -+ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number")); -+ goto fail; -+ } -+ -+ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors")); -+ goto fail; -+ } -+ -+ if (lh.version < grub_cpu_to_le16 (0x020b)) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old")); -+ goto fail; -+ } -+ -+ if (!lh.handover_offset) -+ { -+ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover")); -+ goto fail; -+ } -+ -+ grub_dprintf ("linux", "setting up cmdline\n"); -+ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, -+ BYTES_TO_PAGES(lh.cmdline_size + 1)); -+ -+ if (!linux_cmdline) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); -+ goto fail; -+ } -+ -+ grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); -+ grub_create_loader_cmdline (argc, argv, -+ linux_cmdline + sizeof (LINUX_IMAGE) - 1, -+ lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1), -+ GRUB_VERIFY_KERNEL_CMDLINE); -+ -+ lh.cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline; -+ -+ handover_offset = lh.handover_offset; -+ -+ start = (lh.setup_sects + 1) * 512; -+ len = grub_file_size(file) - start; -+ -+ kernel_mem = grub_efi_allocate_pages_max(lh.pref_address, -+ BYTES_TO_PAGES(lh.init_size)); -+ -+ if (!kernel_mem) -+ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, -+ BYTES_TO_PAGES(lh.init_size)); -+ -+ if (!kernel_mem) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); -+ goto fail; -+ } -+ -+ grub_memcpy (kernel_mem, (char *)kernel + start, len); -+ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); -+ loaded=1; -+ -+ lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem; -+ grub_memcpy (params, &lh, 2 * 512); -+ -+ params->type_of_loader = 0x21; -+ -+ fail: -+ -+ if (file) -+ grub_file_close (file); -+ -+ if (kernel) -+ grub_free (kernel); -+ -+ if (grub_errno != GRUB_ERR_NONE) -+ { -+ grub_dl_unref (my_mod); -+ loaded = 0; -+ } -+ -+ if (linux_cmdline && !loaded) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) -+ linux_cmdline, -+ BYTES_TO_PAGES(lh.cmdline_size + 1)); -+ -+ if (kernel_mem && !loaded) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, -+ BYTES_TO_PAGES(kernel_size)); -+ -+ if (params && !loaded) -+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params, -+ BYTES_TO_PAGES(16384)); -+ -+ return grub_errno; -+} -+ -+static grub_command_t cmd_linux, cmd_initrd; -+static grub_command_t cmd_linuxefi, cmd_initrdefi; -+ -+GRUB_MOD_INIT(linux) -+{ -+ cmd_linux = -+ grub_register_command ("linux", grub_cmd_linux, -+ 0, N_("Load Linux.")); -+ cmd_linuxefi = -+ grub_register_command ("linuxefi", grub_cmd_linux, -+ 0, N_("Load Linux.")); -+ cmd_initrd = -+ grub_register_command ("initrd", grub_cmd_initrd, -+ 0, N_("Load initrd.")); -+ cmd_initrdefi = -+ 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_linuxefi); -+ grub_unregister_command (cmd_initrd); -+ grub_unregister_command (cmd_initrdefi); -+} -diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c -index 2a299520160..8be4c3b3f48 100644 ---- a/grub-core/loader/i386/pc/linux.c -+++ b/grub-core/loader/i386/pc/linux.c -@@ -474,14 +474,20 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - return grub_errno; - } - --static grub_command_t cmd_linux, cmd_initrd; -+static grub_command_t cmd_linux, cmd_linux16, cmd_initrd, cmd_initrd16; - - GRUB_MOD_INIT(linux16) - { - cmd_linux = -+ grub_register_command ("linux", grub_cmd_linux, -+ 0, N_("Load Linux.")); -+ cmd_linux16 = - grub_register_command ("linux16", grub_cmd_linux, - 0, N_("Load Linux.")); - cmd_initrd = -+ grub_register_command ("initrd", grub_cmd_initrd, -+ 0, N_("Load initrd.")); -+ cmd_initrd16 = - grub_register_command ("initrd16", grub_cmd_initrd, - 0, N_("Load initrd.")); - my_mod = mod; -@@ -490,5 +496,7 @@ GRUB_MOD_INIT(linux16) - GRUB_MOD_FINI(linux16) - { - grub_unregister_command (cmd_linux); -+ grub_unregister_command (cmd_linux16); - grub_unregister_command (cmd_initrd); -+ grub_unregister_command (cmd_initrd16); - } -diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h -index bcd5a7eb186..b582f67f661 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 - #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 7e22b4ab699..ea030312df3 100644 ---- a/include/grub/arm64/linux.h -+++ b/include/grub/arm64/linux.h -@@ -19,6 +19,7 @@ - #ifndef GRUB_ARM64_LINUX_HEADER - #define GRUB_ARM64_LINUX_HEADER 1 - -+#include - #include - - #define GRUB_LINUX_ARM64_MAGIC_SIGNATURE 0x644d5241 /* 'ARM\x64' */ -@@ -38,9 +39,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 */ -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 83d958f9945..6295df85f3f 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -47,6 +47,9 @@ EXPORT_FUNC(grub_efi_allocate_fixed) (grub_efi_physical_address_t address, - grub_efi_uintn_t pages); - void * - EXPORT_FUNC(grub_efi_allocate_any_pages) (grub_efi_uintn_t pages); -+void * -+EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max, -+ grub_efi_uintn_t pages); - void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, - grub_efi_uintn_t pages); - grub_efi_uintn_t EXPORT_FUNC(grub_efi_find_mmap_size) (void); -@@ -88,6 +91,7 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, - const grub_efi_guid_t *guid, - void *data, - grub_size_t datasize); -+grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); - int - EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, - const grub_efi_device_path_t *dp2); -@@ -101,8 +105,7 @@ void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); - grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *); - #include - grub_err_t grub_arch_efi_linux_check_image(struct linux_arch_kernel_header *lh); --grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size, -- char *args); -+grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, char *args); - #endif - - grub_addr_t grub_efi_modules_addr (void); -diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h -new file mode 100644 -index 00000000000..d9ede36773b ---- /dev/null -+++ b/include/grub/efi/linux.h -@@ -0,0 +1,31 @@ -+/* -+ * 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 . -+ */ -+#ifndef GRUB_EFI_LINUX_HEADER -+#define GRUB_EFI_LINUX_HEADER 1 -+ -+#include -+#include -+#include -+ -+grub_efi_boolean_t -+EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size); -+grub_err_t -+EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset, -+ void *kernel_param); -+ -+#endif /* ! GRUB_EFI_LINUX_HEADER */ diff --git a/0004-Introduce-prep_load_env-command.patch b/0004-Introduce-prep_load_env-command.patch new file mode 100644 index 0000000000000000000000000000000000000000..f0a23d92d985e15aabf7178a58ad1963a166bfad --- /dev/null +++ b/0004-Introduce-prep_load_env-command.patch @@ -0,0 +1,279 @@ +From 3cf4fdf8d17423dea4e5913ab14fb6305f3c2571 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Fri, 18 Feb 2022 21:43:38 +0800 +Subject: [PATCH 4/5] Introduce prep_load_env command + +This command will accept grub disk device and perform load_env for +environment block located at end of PReP partition which belongs to that +input disk device. All variables read from that environment block are +exported to grub as environment variables. + +Please note there's no support for whitelist variables and also +--skip-sig option compared to ordinary load_env command. + +v2: +To avoid disrupting the boot process with errors, it's important to log +any errors that may occur and always return GRUB_ERR_NONE. + +v3: +Making the new module powerpc_ieee1275 specific. + +Signed-off-by: Michael Chang +--- + grub-core/Makefile.core.def | 5 + + grub-core/commands/prep_loadenv.c | 227 ++++++++++++++++++++++++++++++ + 2 files changed, 232 insertions(+) + create mode 100644 grub-core/commands/prep_loadenv.c + +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -2679,3 +2679,9 @@ + common = lib/libtasn1_wrap/tests/Test_strings.c; + common = lib/libtasn1_wrap/wrap_tests.c; + }; ++ ++module = { ++ name = prep_loadenv; ++ common = commands/prep_loadenv.c; ++ enable = powerpc_ieee1275; ++}; +--- /dev/null ++++ b/grub-core/commands/prep_loadenv.c +@@ -0,0 +1,237 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static char * ++match_substr (regmatch_t *match, const char *str) ++{ ++ if (match->rm_so != -1) ++ { ++ char *substr; ++ regoff_t sz = match->rm_eo - match->rm_so; ++ ++ if (!sz) ++ return NULL; ++ substr = grub_malloc (1 + sz); ++ if (!substr) ++ { ++ grub_print_error (); ++ return NULL; ++ } ++ grub_memcpy (substr, str + match->rm_so, sz); ++ substr[sz] = '\0'; ++ return substr; ++ } ++ ++ return NULL; ++} ++ ++static int ++is_prep_partition (grub_device_t dev) ++{ ++ if (!dev->disk) ++ return 0; ++ if (!dev->disk->partition) ++ return 0; ++ if (grub_strcmp (dev->disk->partition->partmap->name, "msdos") == 0) ++ return (dev->disk->partition->msdostype == 0x41); ++ ++ if (grub_strcmp (dev->disk->partition->partmap->name, "gpt") == 0) ++ { ++ struct grub_gpt_partentry gptdata; ++ grub_partition_t p = dev->disk->partition; ++ int ret = 0; ++ dev->disk->partition = dev->disk->partition->parent; ++ ++ if (grub_disk_read (dev->disk, p->offset, p->index, ++ sizeof (gptdata), &gptdata) == 0) ++ { ++ const grub_guid_t template = { ++ grub_cpu_to_le32_compile_time (0x9e1a2d38), ++ grub_cpu_to_le16_compile_time (0xc612), ++ grub_cpu_to_le16_compile_time (0x4316), ++ { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b } ++ }; ++ ++ ret = grub_memcmp (&template, &gptdata.type, ++ sizeof (template)) == 0; ++ } ++ dev->disk->partition = p; ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int ++part_hook (grub_disk_t disk, const grub_partition_t partition, void *data) ++{ ++ char **ret = data; ++ char *partition_name, *devname; ++ grub_device_t dev; ++ ++ partition_name = grub_partition_get_name (partition); ++ if (! partition_name) ++ return 2; ++ ++ devname = grub_xasprintf ("%s,%s", disk->name, partition_name); ++ grub_free (partition_name); ++ if (!devname) ++ return 2; ++ ++ dev = grub_device_open (devname); ++ if (!dev) ++ { ++ grub_free (devname); ++ return 2; ++ } ++ if (is_prep_partition (dev)) ++ { ++ *ret = devname; ++ return 1; ++ } ++ grub_free (devname); ++ grub_device_close (dev); ++ return 0; ++} ++ ++static int ++set_var (const char *name, const char *value, ++ void *hook_data __attribute__ ((unused))) ++{ ++ grub_env_set (name, value); ++ grub_env_export (name); ++ return 0; ++} ++ ++static grub_err_t ++prep_read_envblk (const char *devname) ++{ ++ char *buf = NULL; ++ grub_device_t dev = NULL; ++ grub_envblk_t envblk = NULL; ++ ++ dev = grub_device_open (devname); ++ if (!dev) ++ return grub_errno; ++ ++ if (!dev->disk || !dev->disk->partition) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, "disk device required"); ++ goto fail; ++ } ++ ++ buf = grub_malloc (GRUB_ENVBLK_PREP_SIZE); ++ if (!buf) ++ goto fail; ++ ++ if (grub_disk_read (dev->disk, dev->disk->partition->len - (GRUB_ENVBLK_PREP_SIZE >> GRUB_DISK_SECTOR_BITS), 0, GRUB_ENVBLK_PREP_SIZE, buf)) ++ goto fail; ++ ++ envblk = grub_envblk_open (buf, GRUB_ENVBLK_PREP_SIZE); ++ if (!envblk) ++ { ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block"); ++ goto fail; ++ } ++ grub_envblk_iterate (envblk, NULL, set_var); ++ ++ fail: ++ if (envblk) ++ grub_envblk_close (envblk); ++ else ++ grub_free (buf); ++ if (dev) ++ grub_device_close (dev); ++ return grub_errno; ++} ++ ++static grub_err_t ++prep_partname (const char *devname, char **prep) ++{ ++ grub_device_t dev = NULL; ++ grub_err_t err; ++ int ret; ++ ++ dev = grub_device_open (devname); ++ if (!dev) ++ return grub_errno; ++ ++ /* Only needed for disk device */ ++ if (!dev->disk) ++ { ++ err = GRUB_ERR_NONE; ++ goto out; ++ } ++ ++ ret = grub_partition_iterate (dev->disk, part_hook, prep); ++ if (ret == 1 && *prep) ++ { ++ err = GRUB_ERR_NONE; ++ goto out; ++ } ++ else if (ret == 0 && grub_errno == GRUB_ERR_NONE) ++ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "no prep partition"); ++ else ++ err = grub_errno; ++ ++ out: ++ grub_device_close (dev); ++ return err; ++} ++ ++static grub_err_t ++grub_cmd_prep_loadenv (grub_command_t cmd __attribute__ ((unused)), ++ int argc, ++ char **argv) ++{ ++ char *devname, *prep = NULL; ++ grub_err_t err; ++ ++ if (argc < 1) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); ++ ++ devname = grub_file_get_device_name(argv[0]); ++ if (!devname) ++ return grub_errno; ++ ++ err = prep_partname (devname, &prep); ++ if (prep == NULL || err != GRUB_ERR_NONE) ++ goto out; ++ ++ err = prep_read_envblk (prep); ++ ++ out: ++ grub_free (devname); ++ grub_free (prep); ++ ++ if (err) ++ grub_print_error (); ++ return GRUB_ERR_NONE; ++} ++ ++static grub_command_t cmd_prep_load; ++ ++GRUB_MOD_INIT(prep_loadenv) ++{ ++ cmd_prep_load = ++ grub_register_command("prep_load_env", grub_cmd_prep_loadenv, ++ "DEVICE", ++ N_("Load variables from environment block file.")); ++} ++ ++GRUB_MOD_FINI(prep_loadenv) ++{ ++ grub_unregister_command (cmd_prep_load); ++} diff --git a/0004-Key-revocation-on-out-of-bound-file-access.patch b/0004-Key-revocation-on-out-of-bound-file-access.patch new file mode 100644 index 0000000000000000000000000000000000000000..b314f6e8302abac5043979012b54cf9ee3ece1f4 --- /dev/null +++ b/0004-Key-revocation-on-out-of-bound-file-access.patch @@ -0,0 +1,91 @@ +From 6547d22fc9e20720d1a896be82b2d50d842f86b0 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Mon, 20 Nov 2023 09:25:53 +0800 +Subject: [PATCH 4/4] Key revocation on out of bound file access + +After successful disk unlocking, grub now takes on the responsibility of +safeguarding passwords or TPM keys exclusively within authenticated +cryptodisk files. Any attempt to access boot-related files outside this +trust realm triggers immediate key revocation, preventing potential +compromise by out of bound access. + +This patch strengthens security measures by restricting grub's access to +system boot files, except for essential internal processes like memdisk +and procfs, ensuring key protection against potential breaches due to +inadvertent customizations in grub.cfg. + +Signed-Off-by Michael Chang +--- + grub-core/commands/crypttab.c | 36 +++++++++++++++++++++++++++++++++++ + include/grub/file.h | 1 + + 2 files changed, 37 insertions(+) + +diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c +index d3acc4b59..e09296c57 100644 +--- a/grub-core/commands/crypttab.c ++++ b/grub-core/commands/crypttab.c +@@ -121,6 +121,41 @@ grub_cryptokey_tpmkey_discard (void) + grub_cryptokey_discard(); + } + ++static grub_file_t ++grub_distrust_open (grub_file_t io, ++ enum grub_file_type type __attribute__ ((unused))) ++{ ++ grub_disk_t disk = io->device->disk; ++ ++ if (io->device->disk && ++ (io->device->disk->dev->id == GRUB_DISK_DEVICE_MEMDISK_ID ++ || io->device->disk->dev->id == GRUB_DISK_DEVICE_PROCFS_ID)) ++ return io; ++ ++ /* Ensure second stage files is in a protected location or grub won't hand ++ * over the key and discards it */ ++ switch (type & GRUB_FILE_TYPE_MASK) ++ { ++ case GRUB_FILE_TYPE_ACPI_TABLE: ++ case GRUB_FILE_TYPE_CONFIG: ++ case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE: ++ case GRUB_FILE_TYPE_FONT: ++ case GRUB_FILE_TYPE_GRUB_MODULE: ++ case GRUB_FILE_TYPE_GRUB_MODULE_LIST: ++ case GRUB_FILE_TYPE_LINUX_KERNEL: ++ case GRUB_FILE_TYPE_LINUX_INITRD: ++ case GRUB_FILE_TYPE_LOADENV: ++ case GRUB_FILE_TYPE_THEME: ++ if (!disk || !grub_disk_is_crypto (disk)) ++ grub_cryptokey_discard (); ++ break; ++ default: ++ break; ++ } ++ ++ return io; ++} ++ + static grub_err_t + grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)), + int argc, char **argv) +@@ -153,6 +188,7 @@ GRUB_MOD_INIT(crypttab) + { + cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry, + N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description")); ++ grub_file_filter_register (GRUB_FILE_FILTER_DISTRUST, grub_distrust_open); + grub_dl_set_persistent (mod); + } + +diff --git a/include/grub/file.h b/include/grub/file.h +index fcfd32ce2..daf23a9c9 100644 +--- a/include/grub/file.h ++++ b/include/grub/file.h +@@ -185,6 +185,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook); + /* Filters with lower ID are executed first. */ + typedef enum grub_file_filter_id + { ++ GRUB_FILE_FILTER_DISTRUST, + GRUB_FILE_FILTER_NOCAT, + GRUB_FILE_FILTER_VERIFY, + GRUB_FILE_FILTER_GZIO, +-- +2.42.1 + diff --git a/0102-Try-to-pick-better-locations-for-kernel-and-initrd.patch b/0004-Try-to-pick-better-locations-for-kernel-and-initrd.patch similarity index 73% rename from 0102-Try-to-pick-better-locations-for-kernel-and-initrd.patch rename to 0004-Try-to-pick-better-locations-for-kernel-and-initrd.patch index 06329b9cf31d76e1f7181ccf1462b3481ecb57b8..ffa150e6d3757c0e405719a47313eaee7c2816ee 100644 --- a/0102-Try-to-pick-better-locations-for-kernel-and-initrd.patch +++ b/0004-Try-to-pick-better-locations-for-kernel-and-initrd.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 384763d7990f769839ca74d6756fbd85580873d4 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 11 Jul 2019 17:17:02 +0200 -Subject: [PATCH] Try to pick better locations for kernel and initrd +Subject: [PATCH 04/11] Try to pick better locations for kernel and initrd - Don't limit allocations on 64-bit platforms to < 0x[37f]fffffff if we're using the "large" code model ; use __UINTPTR_MAX__. @@ -23,25 +23,19 @@ Additionally, we now try to locate kernel+initrd+cmdline+etc below we try a higher address. Signed-off-by: Peter Jones -[david.abdurachmanov: fix macro for riscv64] -Signed-off-by: David Abdurachmanov -Signed-off-by: Robbie Harwood --- grub-core/kern/efi/mm.c | 8 ++++---- - grub-core/loader/i386/efi/linux.c | 24 +++++++++++++++++------- + grub-core/loader/i386/efi/linux.c | 25 +++++++++++++++++-------- include/grub/arm/efi/memory.h | 1 + include/grub/arm64/efi/memory.h | 1 + include/grub/i386/efi/memory.h | 1 + include/grub/ia64/efi/memory.h | 1 + - include/grub/riscv64/efi/memory.h | 1 + include/grub/x86_64/efi/memory.h | 4 +++- - 8 files changed, 29 insertions(+), 12 deletions(-) + 7 files changed, 28 insertions(+), 13 deletions(-) -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index 85ad4b4494c..e84961d078c 100644 --- a/grub-core/kern/efi/mm.c +++ b/grub-core/kern/efi/mm.c -@@ -122,7 +122,7 @@ grub_efi_allocate_pages_max (grub_efi_physical_address_t max, +@@ -121,7 +121,7 @@ grub_efi_boot_services_t *b; grub_efi_physical_address_t address = max; @@ -50,7 +44,7 @@ index 85ad4b4494c..e84961d078c 100644 return 0; b = grub_efi_system_table->boot_services; -@@ -480,7 +480,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, +@@ -481,7 +481,7 @@ { if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY #if 1 @@ -59,7 +53,7 @@ index 85ad4b4494c..e84961d078c 100644 #endif && desc->physical_start + PAGES_TO_BYTES (desc->num_pages) > 0x100000 && desc->num_pages != 0) -@@ -498,9 +498,9 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map, +@@ -499,9 +499,9 @@ #if 1 if (BYTES_TO_PAGES (filtered_desc->physical_start) + filtered_desc->num_pages @@ -71,8 +65,6 @@ index 85ad4b4494c..e84961d078c 100644 - BYTES_TO_PAGES (filtered_desc->physical_start)); #endif -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 3017d0f3e52..33e981e76e7 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -27,6 +27,7 @@ @@ -83,18 +75,19 @@ index 3017d0f3e52..33e981e76e7 100644 GRUB_MOD_LICENSE ("GPLv3+"); -@@ -106,7 +107,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), +@@ -102,8 +103,9 @@ size += ALIGN_UP (grub_file_size (files[i]), 4); } - initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); +- + initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, BYTES_TO_PAGES(size)); + if (!initrd_mem) + initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, BYTES_TO_PAGES(size)); if (!initrd_mem) { grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); -@@ -202,8 +205,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -187,8 +189,11 @@ goto fail; } @@ -107,7 +100,7 @@ index 3017d0f3e52..33e981e76e7 100644 if (! params) { grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); -@@ -273,8 +279,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -258,8 +263,11 @@ #endif grub_dprintf ("linux", "setting up cmdline\n"); @@ -121,7 +114,7 @@ index 3017d0f3e52..33e981e76e7 100644 if (!linux_cmdline) { grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); -@@ -301,11 +310,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -285,11 +293,12 @@ kernel_mem = grub_efi_allocate_pages_max(lh->pref_address, BYTES_TO_PAGES(lh->init_size)); @@ -137,8 +130,6 @@ index 3017d0f3e52..33e981e76e7 100644 if (!kernel_mem) { grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); -diff --git a/include/grub/arm/efi/memory.h b/include/grub/arm/efi/memory.h -index 2c64918e3f7..a4c2ec83502 100644 --- a/include/grub/arm/efi/memory.h +++ b/include/grub/arm/efi/memory.h @@ -2,5 +2,6 @@ @@ -148,8 +139,6 @@ index 2c64918e3f7..a4c2ec83502 100644 +#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS #endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/arm64/efi/memory.h b/include/grub/arm64/efi/memory.h -index c6cb3241714..acb61dca44b 100644 --- a/include/grub/arm64/efi/memory.h +++ b/include/grub/arm64/efi/memory.h @@ -2,5 +2,6 @@ @@ -159,8 +148,6 @@ index c6cb3241714..acb61dca44b 100644 +#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS #endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/i386/efi/memory.h b/include/grub/i386/efi/memory.h -index 2c64918e3f7..a4c2ec83502 100644 --- a/include/grub/i386/efi/memory.h +++ b/include/grub/i386/efi/memory.h @@ -2,5 +2,6 @@ @@ -170,8 +157,6 @@ index 2c64918e3f7..a4c2ec83502 100644 +#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS #endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/ia64/efi/memory.h b/include/grub/ia64/efi/memory.h -index 2c64918e3f7..a4c2ec83502 100644 --- a/include/grub/ia64/efi/memory.h +++ b/include/grub/ia64/efi/memory.h @@ -2,5 +2,6 @@ @@ -181,19 +166,6 @@ index 2c64918e3f7..a4c2ec83502 100644 +#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS #endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/riscv64/efi/memory.h b/include/grub/riscv64/efi/memory.h -index c6cb3241714..acb61dca44b 100644 ---- a/include/grub/riscv64/efi/memory.h -+++ b/include/grub/riscv64/efi/memory.h -@@ -2,5 +2,6 @@ - #include - - #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL -+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS - - #endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/x86_64/efi/memory.h b/include/grub/x86_64/efi/memory.h -index 46e9145a308..e81cfb32213 100644 --- a/include/grub/x86_64/efi/memory.h +++ b/include/grub/x86_64/efi/memory.h @@ -2,9 +2,11 @@ diff --git a/0101-arm-arm64-loader-Better-memory-allocation-and-error-.patch b/0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch similarity index 82% rename from 0101-arm-arm64-loader-Better-memory-allocation-and-error-.patch rename to 0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch index 1fdc552897eee214fbb25892f9ee82c97765d3d0..f8a3796cf58be2781b01deb3dd2d7184dac37931 100644 --- a/0101-arm-arm64-loader-Better-memory-allocation-and-error-.patch +++ b/0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 5d417346956bc3108183020a8a9f20ddda034b48 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 11 Jul 2019 14:38:57 +0200 -Subject: [PATCH] arm/arm64 loader: Better memory allocation and error +Subject: [PATCH 4/9] arm/arm64 loader: Better memory allocation and error messages. On mustang, our memory map looks like: @@ -65,16 +65,21 @@ 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 + +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 --- - grub-core/kern/efi/mm.c | 33 +++++++++++++++----- - grub-core/loader/arm64/linux.c | 68 +++++++++++++++++++++++++++++++----------- - 2 files changed, 76 insertions(+), 25 deletions(-) + 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 f6aef0ef649..85ad4b4494c 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, +@@ -153,6 +153,7 @@ { grub_efi_status_t status; grub_efi_boot_services_t *b; @@ -82,16 +87,16 @@ index f6aef0ef649..85ad4b4494c 100644 /* Limit the memory access to less than 4GB for 32-bit platforms. */ if (address > GRUB_EFI_MAX_USABLE_ADDRESS) -@@ -170,19 +171,22 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, +@@ -169,19 +170,22 @@ } 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); +- status = b->allocate_pages (alloctype, memtype, pages, &address); ++ status = b->allocate_pages (alloctype, memtype, pages, &ret); if (status != GRUB_EFI_SUCCESS) { + grub_dprintf ("efi", -+ "allocate_pages(%d, %d, 0x%0lx, 0x%016lx) = 0x%016lx\n", ++ "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; @@ -103,13 +108,13 @@ index f6aef0ef649..85ad4b4494c 100644 /* 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); +- status = b->allocate_pages (alloctype, memtype, pages, &address); + ret = address; -+ status = efi_call_4 (b->allocate_pages, alloctype, memtype, pages, &ret); ++ status = b->allocate_pages (alloctype, memtype, pages, &ret); grub_efi_free_pages (0, pages); if (status != GRUB_EFI_SUCCESS) { -@@ -191,9 +195,9 @@ grub_efi_allocate_pages_real (grub_efi_physical_address_t address, +@@ -190,9 +194,9 @@ } } @@ -121,7 +126,7 @@ index f6aef0ef649..85ad4b4494c 100644 } void * -@@ -713,8 +717,21 @@ grub_efi_get_ram_base(grub_addr_t *base_addr) +@@ -711,8 +715,21 @@ 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)) @@ -132,24 +137,22 @@ index f6aef0ef649..85ad4b4494c 100644 + (desc->attribute & GRUB_EFI_MEMORY_WB)) + { + *base_addr = grub_min (*base_addr, desc->physical_start); -+ grub_dprintf ("efi", "setting base_addr=0x%016lx\n", *base_addr); ++ grub_dprintf ("efi", "setting base_addr=0x%016" PRIxGRUB_ADDR "\n", *base_addr); + } + else + { -+ grub_dprintf ("efi", "ignoring address 0x%016lx\n", desc->physical_start); ++ 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%016lx is probably wrong.\n", *base_addr); ++ 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/linux.c b/grub-core/loader/arm64/linux.c -index 04994d5c67d..70a0075ec5e 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -71,20 +71,25 @@ finalize_params_linux (void) +--- a/grub-core/loader/arm64/efi/linux.c ++++ b/grub-core/loader/arm64/efi/linux.c +@@ -89,13 +89,15 @@ { grub_efi_loaded_image_t *loaded_image = NULL; int node, retval, len; @@ -168,7 +171,26 @@ index 04994d5c67d..70a0075ec5e 100644 node = grub_fdt_find_subnode (fdt, 0, "chosen"); if (node < 0) - node = grub_fdt_add_subnode (fdt, 0, "chosen"); +@@ -106,17 +108,26 @@ + */ + 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; @@ -179,7 +201,7 @@ index 04994d5c67d..70a0075ec5e 100644 /* Set initrd info */ if (initrd_start && initrd_end > initrd_start) -@@ -95,15 +100,26 @@ finalize_params_linux (void) +@@ -127,15 +138,26 @@ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", initrd_start); if (retval) @@ -209,8 +231,8 @@ index 04994d5c67d..70a0075ec5e 100644 + } grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n", - fdt); -@@ -111,14 +127,20 @@ finalize_params_linux (void) + fdt); +@@ -143,14 +165,20 @@ /* Convert command line to UCS-2 */ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle); if (!loaded_image) @@ -233,7 +255,7 @@ index 04994d5c67d..70a0075ec5e 100644 loaded_image->load_options_size = 2 * grub_utf8_to_utf16 (loaded_image->load_options, len, -@@ -128,7 +150,7 @@ finalize_params_linux (void) +@@ -160,7 +188,7 @@ failure: grub_fdt_unload(); @@ -242,7 +264,7 @@ index 04994d5c67d..70a0075ec5e 100644 } static void -@@ -212,16 +234,28 @@ grub_linux_unload (void) +@@ -246,16 +274,28 @@ static void * allocate_initrd_mem (int initrd_pages) { @@ -250,16 +272,16 @@ index 04994d5c67d..70a0075ec5e 100644 + grub_addr_t max_addr = 0; + grub_err_t err; + void *ret; - -- if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE) -- return NULL; ++ + 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); diff --git a/0004-cryptodisk-Support-key-protectors.patch b/0004-cryptodisk-Support-key-protectors.patch new file mode 100644 index 0000000000000000000000000000000000000000..571a9f363c3001cdefc8fa2f6429b0c15f7e99ba --- /dev/null +++ b/0004-cryptodisk-Support-key-protectors.patch @@ -0,0 +1,342 @@ +From 9888bf40d960339a59dc18fb6e1df5f65b4668e3 Mon Sep 17 00:00:00 2001 +From: Hernan Gatta +Date: Tue, 1 Feb 2022 05:02:56 -0800 +Subject: [PATCH 13/14] cryptodisk: Support key protectors + +Add a new parameter to cryptomount to support the key protectors framework: -k. +The parameter is used to automatically retrieve a key from specified key +protectors. The parameter may be repeated to specify any number of key +protectors. These are tried in order until one provides a usable key for any +given disk. + +Signed-off-by: +--- + Makefile.util.def | 1 + + grub-core/disk/cryptodisk.c | 166 +++++++++++++++++++++++++++++------- + include/grub/cryptodisk.h | 14 +++ + 3 files changed, 151 insertions(+), 30 deletions(-) + +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -35,6 +35,7 @@ + common = grub-core/kern/list.c; + common = grub-core/kern/misc.c; + common = grub-core/kern/partition.c; ++ common = grub-core/kern/protectors.c; + common = grub-core/lib/crypto.c; + common = grub-core/lib/json/json.c; + common = grub-core/disk/luks.c; +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #ifdef GRUB_UTIL + #include +@@ -44,7 +45,8 @@ + OPTION_KEYFILE, + OPTION_KEYFILE_OFFSET, + OPTION_KEYFILE_SIZE, +- OPTION_HEADER ++ OPTION_HEADER, ++ OPTION_PROTECTOR + }; + + static const struct grub_arg_option options[] = +@@ -58,6 +60,8 @@ + {"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT}, + {"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT}, + {"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING}, ++ {"protector", 'P', GRUB_ARG_OPTION_REPEATABLE, ++ N_("Unlock volume(s) using key protector(s)."), 0, ARG_TYPE_STRING}, + {0, 0, 0, 0, 0, 0} + }; + +@@ -1061,6 +1065,7 @@ + grub_err_t ret = GRUB_ERR_NONE; + grub_cryptodisk_t dev; + grub_cryptodisk_dev_t cr; ++ int i; + struct cryptodisk_read_hook_ctx read_hook_data = {0}; + int askpass = 0; + char *part = NULL; +@@ -1113,41 +1118,112 @@ + goto error_no_close; + if (!dev) + continue; ++ break; ++ } + +- if (!cargs->key_len) +- { +- /* Get the passphrase from the user, if no key data. */ +- askpass = 1; +- part = grub_partition_get_name (source->partition); +- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, +- source->partition != NULL ? "," : "", +- part != NULL ? part : N_("UNKNOWN"), +- dev->uuid); +- grub_free (part); +- +- cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE); +- if (cargs->key_data == NULL) +- goto error_no_close; ++ if (dev == NULL) ++ { ++ grub_error (GRUB_ERR_BAD_MODULE, ++ "no cryptodisk module can handle this device"); ++ goto error_no_close; ++ } + +- if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE)) +- { +- grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied"); +- goto error; +- } +- cargs->key_len = grub_strlen ((char *) cargs->key_data); +- } ++ if (cargs->protectors) ++ { ++ for (i = 0; cargs->protectors[i]; i++) ++ { ++ if (cargs->key_cache[i].invalid) ++ continue; + +- ret = cr->recover_key (source, dev, cargs); +- if (ret != GRUB_ERR_NONE) +- goto error; ++ if (cargs->key_cache[i].key == NULL) ++ { ++ ret = grub_key_protector_recover_key (cargs->protectors[i], ++ &cargs->key_cache[i].key, ++ &cargs->key_cache[i].key_len); ++ if (ret != GRUB_ERR_NONE) ++ { ++ if (grub_errno) ++ { ++ grub_print_error (); ++ grub_errno = GRUB_ERR_NONE; ++ } ++ ++ grub_dprintf ("cryptodisk", ++ "failed to recover a key from key protector " ++ "%s, will not try it again for any other " ++ "disks, if any, during this invocation of " ++ "cryptomount\n", ++ cargs->protectors[i]); ++ ++ cargs->key_cache[i].invalid = 1; ++ continue; ++ } ++ } ++ ++ cargs->key_data = cargs->key_cache[i].key; ++ cargs->key_len = cargs->key_cache[i].key_len; ++ ++ ret = cr->recover_key (source, dev, cargs); ++ if (ret != GRUB_ERR_NONE) ++ { ++ part = grub_partition_get_name (source->partition); ++ grub_dprintf ("cryptodisk", ++ "recovered a key from key protector %s but it " ++ "failed to unlock %s%s%s (%s)\n", ++ cargs->protectors[i], source->name, ++ source->partition != NULL ? "," : "", ++ part != NULL ? part : N_("UNKNOWN"), dev->uuid); ++ grub_free (part); ++ continue; ++ } ++ else ++ { ++ ret = grub_cryptodisk_insert (dev, name, source); ++ if (ret != GRUB_ERR_NONE) ++ goto error; ++ goto cleanup; ++ } ++ } + +- ret = grub_cryptodisk_insert (dev, name, source); +- if (ret != GRUB_ERR_NONE) ++ part = grub_partition_get_name (source->partition); ++ grub_error (GRUB_ERR_ACCESS_DENIED, ++ N_("no key protector provided a usable key for %s%s%s (%s)"), ++ source->name, source->partition != NULL ? "," : "", ++ part != NULL ? part : N_("UNKNOWN"), dev->uuid); ++ grub_free (part); + goto error; ++ } ++ ++ if (!cargs->key_len) ++ { ++ /* Get the passphrase from the user, if no key data. */ ++ askpass = 1; ++ part = grub_partition_get_name (source->partition); ++ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name, ++ source->partition != NULL ? "," : "", ++ part != NULL ? part : N_("UNKNOWN"), dev->uuid); ++ grub_free (part); ++ ++ cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE); ++ if (cargs->key_data == NULL) ++ goto error; ++ ++ if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE)) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied"); ++ goto error; ++ } ++ cargs->key_len = grub_strlen ((char *) cargs->key_data); ++ } ++ ++ ret = cr->recover_key (source, dev, cargs); ++ if (ret != GRUB_ERR_NONE) ++ goto error; ++ ++ ret = grub_cryptodisk_insert (dev, name, source); ++ if (ret != GRUB_ERR_NONE) ++ goto error; + +- goto cleanup; +- } +- grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device"); + goto cleanup; + + error: +@@ -1258,6 +1334,20 @@ + return ret; + } + ++static void ++grub_cryptodisk_clear_key_cache (struct grub_cryptomount_args *cargs) ++{ ++ int i; ++ ++ if (cargs->key_cache == NULL || cargs->protectors == NULL) ++ return; ++ ++ for (i = 0; cargs->protectors[i]; i++) ++ grub_free (cargs->key_cache[i].key); ++ ++ grub_free (cargs->key_cache); ++} ++ + static grub_err_t + grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args) + { +@@ -1270,6 +1360,10 @@ + if (grub_cryptodisk_list == NULL) + return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded"); + ++ if (state[OPTION_PASSWORD].set && state[OPTION_PROTECTOR].set) /* password and key protector */ ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ "a password and a key protector cannot both be set"); ++ + if (state[OPTION_PASSWORD].set) /* password */ + { + cargs.key_data = (grub_uint8_t *) state[OPTION_PASSWORD].arg; +@@ -1362,6 +1456,15 @@ + return grub_errno; + } + ++ if (state[OPTION_PROTECTOR].set) /* key protector(s) */ ++ { ++ cargs.key_cache = grub_zalloc (state[OPTION_PROTECTOR].set * sizeof (*cargs.key_cache)); ++ if (cargs.key_cache == NULL) ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "no memory for key protector key cache"); ++ cargs.protectors = state[OPTION_PROTECTOR].args; ++ } ++ + if (state[OPTION_UUID].set) /* uuid */ + { + int found_uuid; +@@ -1370,6 +1473,7 @@ + dev = grub_cryptodisk_get_by_uuid (args[0]); + if (dev) + { ++ grub_cryptodisk_clear_key_cache (&cargs); + grub_dprintf ("cryptodisk", + "already mounted as crypto%lu\n", dev->id); + return GRUB_ERR_NONE; +@@ -1378,6 +1482,7 @@ + cargs.check_boot = state[OPTION_BOOT].set; + cargs.search_uuid = args[0]; + found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); ++ grub_cryptodisk_clear_key_cache (&cargs); + + if (found_uuid) + return GRUB_ERR_NONE; +@@ -1397,6 +1502,7 @@ + { + cargs.check_boot = state[OPTION_BOOT].set; + grub_device_iterate (&grub_cryptodisk_scan_device, &cargs); ++ grub_cryptodisk_clear_key_cache (&cargs); + return GRUB_ERR_NONE; + } + else +@@ -1420,6 +1526,7 @@ + disk = grub_disk_open (diskname); + if (!disk) + { ++ grub_cryptodisk_clear_key_cache (&cargs); + if (disklast) + *disklast = ')'; + return grub_errno; +@@ -1430,12 +1537,14 @@ + { + grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id); + grub_disk_close (disk); ++ grub_cryptodisk_clear_key_cache (&cargs); + if (disklast) + *disklast = ')'; + return GRUB_ERR_NONE; + } + + dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs); ++ grub_cryptodisk_clear_key_cache (&cargs); + + grub_disk_close (disk); + if (disklast) +@@ -1576,6 +1685,7 @@ + cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0, + N_("[ [-p password] | [-k keyfile" + " [-O keyoffset] [-S keysize] ] ] [-H file]" ++ " [-P protector [-P protector ...]]" + " "), + N_("Mount a crypto device."), options); + grub_procfs_register ("luks_script", &luks_script); +--- a/include/grub/cryptodisk.h ++++ b/include/grub/cryptodisk.h +@@ -70,6 +70,18 @@ + (*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev, + grub_uint64_t zoneno); + ++struct grub_cryptomount_cached_key ++{ ++ grub_uint8_t *key; ++ grub_size_t key_len; ++ ++ /* ++ * The key protector associated with this cache entry failed, so avoid it ++ * even if the cached entry (an instance of this structure) is empty. ++ */ ++ int invalid; ++}; ++ + struct grub_cryptomount_args + { + /* scan: Flag to indicate that only bootable volumes should be decrypted */ +@@ -81,6 +93,10 @@ + /* recover_key: Length of key_data */ + grub_size_t key_len; + grub_file_t hdr_file; ++ /* recover_key: Names of the key protectors to use (NULL-terminated) */ ++ char **protectors; ++ /* recover_key: Key cache to avoid invoking the same key protector twice */ ++ struct grub_cryptomount_cached_key *key_cache; + }; + typedef struct grub_cryptomount_args *grub_cryptomount_args_t; + diff --git a/0004-diskfilter-look-up-cryptodisk-devices-first.patch b/0004-diskfilter-look-up-cryptodisk-devices-first.patch new file mode 100644 index 0000000000000000000000000000000000000000..d4329161ebb1a5de2ad2af6eb51457d19c31a554 --- /dev/null +++ b/0004-diskfilter-look-up-cryptodisk-devices-first.patch @@ -0,0 +1,89 @@ +From b7e2fb6a680447b7bb7eb18bb7570afa8d2b7f09 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Thu, 10 Aug 2023 10:19:29 +0800 +Subject: [PATCH 4/4] diskfilter: look up cryptodisk devices first + +When using disk auto-unlocking with TPM 2.0, the typical grub.cfg may +look like this: + + tpm2_key_protector_init --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm + cryptomount -u -P tpm2 + search --fs-uuid --set=root + +Since the disk search order is based on the order of module loading, the +attacker could insert a malicious disk with the same FS-UUID root to +trick grub2 to boot into th malicious root and further dump memory to +steal the unsealed key. + +To defend such attack, we can specify the hint provided by 'grub-probe' +to search the encrypted partition first: + +search --fs-uuid --set=root --hint='cryptouuid/' + +However, for LVM on a encrypted partition, the search hint provided by +'grub-probe' is: + + --hint='lvmid//' + +It doesn't guarantee to look up the logical volume from the encrypted +partition, so the attacker may have the chance to fool grub2 to boot +into the malicious disk. + +To mininize the attack surface, this commit tweaks the disk device search +in diskfilter to look up cryptodisk devices first and then others, so +that the auto-unlocked disk will be found first, not the attacker's disk. + +Signed-off-by: Gary Lin +--- + grub-core/disk/diskfilter.c | 35 ++++++++++++++++++++++++++--------- + 1 file changed, 26 insertions(+), 9 deletions(-) + +diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c +index 61a311efd..94832c8dd 100644 +--- a/grub-core/disk/diskfilter.c ++++ b/grub-core/disk/diskfilter.c +@@ -226,15 +226,32 @@ scan_devices (const char *arname) + int need_rescan; + + for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++) +- for (p = grub_disk_dev_list; p; p = p->next) +- if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID +- && p->disk_iterate) +- { +- if ((p->disk_iterate) (scan_disk_hook, NULL, pull)) +- return; +- if (arname && is_lv_readable (find_lv (arname), 1)) +- return; +- } ++ { ++ /* look up the crytodisk devices first */ ++ for (p = grub_disk_dev_list; p; p = p->next) ++ if (p->id == GRUB_DISK_DEVICE_CRYPTODISK_ID ++ && p->disk_iterate) ++ { ++ if ((p->disk_iterate) (scan_disk_hook, NULL, pull)) ++ return; ++ if (arname && is_lv_readable (find_lv (arname), 1)) ++ return; ++ break; ++ } ++ ++ /* check the devices other than crytodisk */ ++ for (p = grub_disk_dev_list; p; p = p->next) ++ if (p->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) ++ continue; ++ else if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID ++ && p->disk_iterate) ++ { ++ if ((p->disk_iterate) (scan_disk_hook, NULL, pull)) ++ return; ++ if (arname && is_lv_readable (find_lv (arname), 1)) ++ return; ++ } ++ } + + scan_depth = 0; + need_rescan = 1; +-- +2.35.3 + diff --git a/0077-efinet-UEFI-IPv6-PXE-support.patch b/0004-efinet-UEFI-IPv6-PXE-support.patch similarity index 35% rename from 0077-efinet-UEFI-IPv6-PXE-support.patch rename to 0004-efinet-UEFI-IPv6-PXE-support.patch index d8b22b8c94a3535b1782a86f62c0955971b7d2a1..e5d8be3120bbf253ccaa8ab0ca37f4f4f56eea15 100644 --- a/0077-efinet-UEFI-IPv6-PXE-support.patch +++ b/0004-efinet-UEFI-IPv6-PXE-support.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From ca482c7c1efe5faf792bf0912a116ea8e0642e24 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Wed, 15 Apr 2015 14:48:30 +0800 -Subject: [PATCH] efinet: UEFI IPv6 PXE support +Subject: [PATCH 4/8] efinet: UEFI IPv6 PXE support When grub2 image is booted from UEFI IPv6 PXE, the DHCPv6 Reply packet is cached in firmware buffer which can be obtained by PXE Base Code protocol. The @@ -10,62 +10,44 @@ network interface can be setup through the parameters in that obtained packet. Signed-off-by: Michael Chang Signed-off-by: Ken Lin --- - grub-core/net/drivers/efi/efinet.c | 2 ++ - include/grub/efi/api.h | 71 +++++++++++++++++++++++--------------- - 2 files changed, 46 insertions(+), 27 deletions(-) + grub-core/net/drivers/efi/efinet.c | 24 +++++++++++++---- + include/grub/efi/api.h | 55 +++++++++++++++++++++++++++++++++++++- + 2 files changed, 73 insertions(+), 6 deletions(-) -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 8e25680db0c..014e5bf9802 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c -@@ -409,6 +409,8 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - grub_print_error (); - if (device && path) - grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); +@@ -400,6 +400,18 @@ + continue; + pxe_mode = pxe->mode; + ++ if (pxe_mode->using_ipv6) ++ { ++ grub_net_configure_by_dhcpv6_reply (card->name, card, 0, ++ (struct grub_net_dhcp6_packet *) ++ &pxe_mode->dhcp_ack, ++ sizeof (pxe_mode->dhcp_ack), ++ 1, device, path); + if (grub_errno) + grub_print_error (); ++ } ++ else ++ { + inter = grub_net_configure_by_dhcp_ack (card->name, card, 0, + (struct grub_net_bootp_packet *) + &pxe_mode->dhcp_ack, +@@ -428,6 +440,7 @@ + vlan_dp = (grub_efi_device_path_t *) ((grub_efi_uint8_t *) vlan_dp + vlan_dp_len); + } } - else - { -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 7614b58dca8..91ab528e4d0 100644 ++ } + return; + } + } --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h -@@ -1524,31 +1524,6 @@ typedef union - grub_efi_pxe_dhcpv6_packet_t dhcpv6; - } grub_efi_pxe_packet_t; +@@ -1523,14 +1523,67 @@ --#define GRUB_EFI_PXE_MAX_IPCNT 8 --#define GRUB_EFI_PXE_MAX_ARP_ENTRIES 8 --#define GRUB_EFI_PXE_MAX_ROUTE_ENTRIES 8 -- --typedef struct grub_efi_pxe_ip_filter --{ -- grub_efi_uint8_t filters; -- grub_efi_uint8_t ip_count; -- grub_efi_uint16_t reserved; -- grub_efi_ip_address_t ip_list[GRUB_EFI_PXE_MAX_IPCNT]; --} grub_efi_pxe_ip_filter_t; -- --typedef struct grub_efi_pxe_arp_entry --{ -- grub_efi_ip_address_t ip_addr; -- grub_efi_mac_address_t mac_addr; --} grub_efi_pxe_arp_entry_t; -- --typedef struct grub_efi_pxe_route_entry --{ -- grub_efi_ip_address_t ip_addr; -- grub_efi_ip_address_t subnet_mask; -- grub_efi_ip_address_t gateway_addr; --} grub_efi_pxe_route_entry_t; -- - typedef struct grub_efi_pxe_icmp_error - { - grub_efi_uint8_t type; -@@ -1574,6 +1549,48 @@ typedef struct grub_efi_pxe_tftp_error - grub_efi_char8_t error_string[127]; - } grub_efi_pxe_tftp_error_t; + typedef grub_uint8_t grub_efi_pxe_packet_t[1472]; +typedef struct { + grub_uint8_t addr[4]; @@ -80,29 +62,28 @@ index 7614b58dca8..91ab528e4d0 100644 +} grub_efi_pxe_mac_address_t; + +typedef union { -+ grub_uint32_t addr[4]; -+ grub_efi_pxe_ipv4_address_t v4; -+ grub_efi_pxe_ipv6_address_t v6; ++ grub_uint32_t addr[4]; ++ grub_efi_pxe_ipv4_address_t v4; ++ grub_efi_pxe_ipv6_address_t v6; +} grub_efi_pxe_ip_address_t; + +#define GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT 8 -+typedef struct grub_efi_pxe_ip_filter -+{ -+ grub_efi_uint8_t filters; -+ grub_efi_uint8_t ip_count; -+ grub_efi_uint16_t reserved; -+ grub_efi_ip_address_t ip_list[GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT]; ++typedef struct { ++ grub_uint8_t filters; ++ grub_uint8_t ip_cnt; ++ grub_uint16_t reserved; ++ grub_efi_pxe_ip_address_t ip_list[GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT]; +} grub_efi_pxe_ip_filter_t; + +typedef struct { -+ grub_efi_pxe_ip_address_t ip_addr; -+ grub_efi_pxe_mac_address_t mac_addr; ++ grub_efi_pxe_ip_address_t ip_addr; ++ grub_efi_pxe_mac_address_t mac_addr; +} grub_efi_pxe_arp_entry_t; + +typedef struct { -+ grub_efi_pxe_ip_address_t ip_addr; -+ grub_efi_pxe_ip_address_t subnet_mask; -+ grub_efi_pxe_ip_address_t gw_addr; ++ grub_efi_pxe_ip_address_t ip_addr; ++ grub_efi_pxe_ip_address_t subnet_mask; ++ grub_efi_pxe_ip_address_t gw_addr; +} grub_efi_pxe_route_entry_t; + + @@ -111,16 +92,25 @@ index 7614b58dca8..91ab528e4d0 100644 + typedef struct grub_efi_pxe_mode { - grub_efi_boolean_t started; -@@ -1605,9 +1622,9 @@ typedef struct grub_efi_pxe_mode - grub_efi_pxe_packet_t pxe_bis_reply; - grub_efi_pxe_ip_filter_t ip_filter; - grub_efi_uint32_t arp_cache_entries; -- grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_MAX_ARP_ENTRIES]; +- grub_uint8_t unused[52]; ++ grub_uint8_t started; ++ grub_uint8_t ipv6_available; ++ grub_uint8_t ipv6_supported; ++ grub_uint8_t using_ipv6; ++ grub_uint8_t unused[16]; ++ grub_efi_pxe_ip_address_t station_ip; ++ grub_efi_pxe_ip_address_t subnet_mask; + grub_efi_pxe_packet_t dhcp_discover; + grub_efi_pxe_packet_t dhcp_ack; + grub_efi_pxe_packet_t proxy_offer; + grub_efi_pxe_packet_t pxe_discover; + grub_efi_pxe_packet_t pxe_reply; ++ grub_efi_pxe_packet_t pxe_bis_reply; ++ grub_efi_pxe_ip_filter_t ip_filter; ++ grub_uint32_t arp_cache_entries; + grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES]; - grub_efi_uint32_t route_table_entries; -- grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_MAX_ROUTE_ENTRIES]; ++ grub_uint32_t route_table_entries; + grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES]; - grub_efi_pxe_icmp_error_t icmp_error; - grub_efi_pxe_tftp_error_t tftp_error; } grub_efi_pxe_mode_t; + + typedef struct grub_efi_pxe diff --git a/0004-ofpath-controller-name-update.patch b/0004-ofpath-controller-name-update.patch new file mode 100644 index 0000000000000000000000000000000000000000..baea1660283828b51b8900dbbbc1da7772ef2a89 --- /dev/null +++ b/0004-ofpath-controller-name-update.patch @@ -0,0 +1,28 @@ +From 7717cd9c27f18703287403af1a955588e3d0261f Mon Sep 17 00:00:00 2001 +From: mamatha +Date: Sat, 24 Sep 2022 11:22:39 +0530 +Subject: [PATCH 4/4] ofpath controller name update + +patch to update ofpath controller name + +Signed-off-by: mamatha +--- + grub-core/osdep/linux/ofpath.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c +index 212782d3f..7d31cfd0f 100644 +--- a/grub-core/osdep/linux/ofpath.c ++++ b/grub-core/osdep/linux/ofpath.c +@@ -483,6 +483,8 @@ of_path_get_nvmeof_adapter_info(char* sysfs_path, + buf3=strchr(buf2,'-')+1; + buf3=strchr(buf3,'-')+1; + nvmeof_info->target_wwpn = buf3; ++ buf3=strchr(buf3,'x')+1; ++ nvmeof_info->target_wwpn = buf3; + buf3 = strchr(nvmeof_info->target_wwpn,','); + *buf3 = '\0'; + +-- +2.35.3 + diff --git a/0004-tpm2-Support-authorized-policy.patch b/0004-tpm2-Support-authorized-policy.patch new file mode 100644 index 0000000000000000000000000000000000000000..bed4531c7fe7f0acec5743e7092799e9dff1e934 --- /dev/null +++ b/0004-tpm2-Support-authorized-policy.patch @@ -0,0 +1,170 @@ +From 542c4fc6e067e04e8b96f798882ae968c59f4948 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Thu, 6 Apr 2023 16:00:25 +0800 +Subject: [PATCH v7 16/20] tpm2: Support authorized policy + +This commit handles the TPM2_PolicyAuthorize command from the key file +in TPM 2.0 Key File format. + +TPM2_PolicyAuthorize is the essential command to support authorized +policy which allows the users to sign TPM policies with their own keys. +Per TPM 2.0 Key File(*1), CommandPolicy for TPM2_PolicyAuthorize +comprises 'TPM2B_PUBLIC pubkey', 'TPM2B_DIGEST policy_ref', and +'TPMT_SIGNATURE signature'. To verify the signature, the current policy +digest is hashed with the hash algorithm written in 'signature', and then +'signature' is verified with the hashed policy digest and 'pubkey'. Once +TPM accepts 'signature', TPM2_PolicyAuthorize is invoked to authorize the +signed policy. + +To create the key file with authorized policy, here are the pcr-oracle(*2) +commands: + + # Generate the RSA key and create the authorized policy file + $ pcr-oracle \ + --rsa-generate-key \ + --private-key policy-key.pem \ + --auth authorized.policy \ + create-authorized-policy 0,2,4,7,9 + + # Seal the secret with the authorized policy + $ pcr-oracle \ + --key-format tpm2.0 \ + --auth authorized.policy \ + --input disk-secret.txt \ + --output sealed.key \ + seal-secret + + # Sign the predicted PCR policy + $ pcr-oracle \ + --key-format tpm2.0 \ + --private-key policy-key.pem \ + --from eventlog \ + --stop-event "grub-file=grub.cfg" \ + --after \ + --input sealed.key \ + --output sealed.tpm \ + sign 0,2,4,7.9 + +Then specify the key file and the key protector to grub.cfg in the EFI +system partition: + +tpm2_key_protector_init --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm +cryptomount -u -P tpm2 + +For any change in the boot components, just run the 'sign' command again +to update the signature in sealed.tpm, and TPM can unseal the key file +with the updated PCR policy. + +(*1) https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html +(*2) https://github.com/okirch/pcr-oracle + +Signed-off-by: Gary Lin +--- + grub-core/tpm2/module.c | 84 +++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 84 insertions(+) + +diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c +index df0727215..0cbfd06e8 100644 +--- a/grub-core/tpm2/module.c ++++ b/grub-core/tpm2/module.c +@@ -453,6 +453,87 @@ grub_tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION session, + return GRUB_ERR_NONE; + } + ++static grub_err_t ++grub_tpm2_protector_policyauthorize (TPMI_SH_AUTH_SESSION session, ++ struct grub_tpm2_buffer *cmd_buf) ++{ ++ TPM2B_PUBLIC pubkey; ++ TPM2B_DIGEST policy_ref; ++ TPMT_SIGNATURE signature; ++ TPM2B_DIGEST pcr_policy; ++ TPM2B_DIGEST pcr_policy_hash; ++ TPMI_ALG_HASH sig_hash; ++ TPMT_TK_VERIFIED verification_ticket; ++ TPM_HANDLE pubkey_handle = 0; ++ TPM2B_NAME pubname; ++ TPM_RC rc; ++ grub_err_t err; ++ ++ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey); ++ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref); ++ grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature); ++ if (cmd_buf->error != 0) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Failed to unmarshal the buffer for TPM2_PolicyAuthorize")); ++ ++ /* Retrieve Policy Digest */ ++ rc = TPM2_PolicyGetDigest (session, NULL, &pcr_policy, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("Failed to get policy digest (TPM2_PolicyGetDigest: 0x%x)."), ++ rc); ++ ++ /* Calculate the digest of the polcy for VerifySignature */ ++ sig_hash = TPMT_SIGNATURE_get_hash_alg (&signature); ++ if (sig_hash == TPM_ALG_NULL) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, ++ N_("Failed to get the hash algorithm of the signature")); ++ ++ rc = TPM2_Hash (NULL, (TPM2B_MAX_BUFFER *)&pcr_policy, sig_hash, ++ TPM_RH_NULL, &pcr_policy_hash, NULL, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("Failed to create PCR policy hash (TPM2_Hash: 0x%x)"), ++ rc); ++ ++ /* Load the public key */ ++ rc = TPM2_LoadExternal (NULL, NULL, &pubkey, TPM_RH_OWNER, ++ &pubkey_handle, &pubname, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ return grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("Failed to load public key (TPM2_LoadExternal: 0x%x)"), ++ rc); ++ ++ /* Verify the signature against the public key and the policy digest */ ++ rc = TPM2_VerifySignature (pubkey_handle, NULL, &pcr_policy_hash, &signature, ++ &verification_ticket, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ err = grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("Failed to verify signature (TPM2_VerifySignature: 0x%x)"), ++ rc); ++ goto error; ++ } ++ ++ /* Authorize the signed policy with the public key and the verification ticket */ ++ rc = TPM2_PolicyAuthorize (session, NULL, &pcr_policy, &policy_ref, &pubname, ++ &verification_ticket, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ err = grub_error (GRUB_ERR_BAD_DEVICE, ++ N_("Failed to authorize PCR policy (TPM2_PolicyAuthorize: 0x%x)"), ++ rc); ++ goto error; ++ } ++ ++ err = GRUB_ERR_NONE; ++ ++error: ++ TPM2_FlushContext (pubkey_handle); ++ ++ return err; ++} ++ + static grub_err_t + grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION session) + { +@@ -472,6 +553,9 @@ grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSIO + case TPM_CC_PolicyPCR: + err = grub_tpm2_protector_policypcr (session, &buf); + break; ++ case TPM_CC_PolicyAuthorize: ++ err = grub_tpm2_protector_policyauthorize (session, &buf); ++ break; + default: + return grub_error (GRUB_ERR_BAD_ARGUMENT, + N_("Unknown TPM Command: 0x%x"), policy->cmd_code); +-- +2.35.3 + diff --git a/0005-Rework-linux-command.patch b/0005-Rework-linux-command.patch deleted file mode 100644 index 9954dd0a61c6f3dcbb997241ac69e293bf3f0138..0000000000000000000000000000000000000000 --- a/0005-Rework-linux-command.patch +++ /dev/null @@ -1,109 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Sun, 9 Aug 2015 16:12:39 -0700 -Subject: [PATCH] Rework linux command - -We want a single buffer that contains the entire kernel image in order to -perform a TPM measurement. Allocate one and copy the entire kernel into it -before pulling out the individual blocks later on. - -Signed-off-by: Matthew Garrett ---- - grub-core/loader/i386/linux.c | 35 +++++++++++++++++++++++------------ - 1 file changed, 23 insertions(+), 12 deletions(-) - -diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index 9f74a96b19a..dccf3bb3005 100644 ---- a/grub-core/loader/i386/linux.c -+++ b/grub-core/loader/i386/linux.c -@@ -649,13 +649,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - { - grub_file_t file = 0; - struct linux_i386_kernel_header lh; -+ grub_uint8_t *linux_params_ptr; - grub_uint8_t setup_sects; -- grub_size_t real_size, prot_size, prot_file_size; -+ grub_size_t real_size, prot_size, prot_file_size, kernel_offset; - grub_ssize_t len; - int i; - grub_size_t align, min_align; - int relocatable; - grub_uint64_t preferred_address = GRUB_LINUX_BZIMAGE_ADDR; -+ grub_uint8_t *kernel = NULL; - - grub_dl_ref (my_mod); - -@@ -669,7 +671,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - if (! file) - goto fail; - -- if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) -+ len = grub_file_size (file); -+ kernel = grub_malloc (len); -+ if (!kernel) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); -+ goto fail; -+ } -+ -+ if (grub_file_read (file, kernel, len) != len) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -@@ -677,6 +687,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -+ grub_memcpy (&lh, kernel, sizeof (lh)); -+ kernel_offset = sizeof (lh); -+ - if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55)) - { - grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); -@@ -784,13 +797,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - /* We've already read lh so there is no need to read it second time. */ - len -= sizeof(lh); - -- if ((len > 0) && -- (grub_file_read (file, (char *) &linux_params + sizeof (lh), len) != len)) -+ linux_params_ptr = (void *)&linux_params; -+ if (len > 0) - { -- if (!grub_errno) -- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -- argv[0]); -- goto fail; -+ grub_memcpy (linux_params_ptr + sizeof (lh), kernel + kernel_offset, len); -+ kernel_offset += len; - } - - linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR; -@@ -853,7 +864,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - /* The other parameters are filled when booting. */ - -- grub_file_seek (file, real_size + GRUB_DISK_SECTOR_SIZE); -+ kernel_offset = real_size + GRUB_DISK_SECTOR_SIZE; - - grub_dprintf ("linux", "bzImage, setup=0x%x, size=0x%x\n", - (unsigned) real_size, (unsigned) prot_size); -@@ -1007,9 +1018,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - - len = prot_file_size; -- if (grub_file_read (file, prot_mode_mem, len) != len && !grub_errno) -- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -- argv[0]); -+ grub_memcpy (prot_mode_mem, kernel + kernel_offset, len); - - if (grub_errno == GRUB_ERR_NONE) - { -@@ -1020,6 +1029,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - fail: - -+ grub_free (kernel); -+ - if (file) - grub_file_close (file); - diff --git a/0161-docs-grub-Document-signing-grub-under-UEFI.patch b/0005-docs-grub-Document-signing-grub-under-UEFI.patch similarity index 84% rename from 0161-docs-grub-Document-signing-grub-under-UEFI.patch rename to 0005-docs-grub-Document-signing-grub-under-UEFI.patch index 9b9b19a718dfbb331b8af80c9c8bf0bd7100c3b7..dfed6c11e60cd25a839c216f7f1ed971bf6aabf2 100644 --- a/0161-docs-grub-Document-signing-grub-under-UEFI.patch +++ b/0005-docs-grub-Document-signing-grub-under-UEFI.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From f7b9580133cf346d77f345d175fa5cb8a591be16 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Sat, 15 Aug 2020 02:00:57 +1000 -Subject: [PATCH] docs/grub: Document signing grub under UEFI +Subject: [PATCH 05/23] docs/grub: Document signing grub under UEFI Before adding information about how grub is signed with an appended signature scheme, it's worth adding some information about how it @@ -12,11 +12,9 @@ Signed-off-by: Daniel Axtens docs/grub.texi | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) -diff --git a/docs/grub.texi b/docs/grub.texi -index 4870faaa00a..365d1d6931b 100644 --- a/docs/grub.texi +++ b/docs/grub.texi -@@ -5817,6 +5817,7 @@ environment variables and commands are listed in the same order. +@@ -6345,6 +6345,7 @@ * Secure Boot Advanced Targeting:: Embedded information for generation number based revocation * Measured Boot:: Measuring boot components * Lockdown:: Lockdown when booting on a secure setup @@ -24,7 +22,7 @@ index 4870faaa00a..365d1d6931b 100644 @end menu @node Authentication and authorisation -@@ -5895,7 +5896,7 @@ commands. +@@ -6423,7 +6424,7 @@ GRUB's @file{core.img} can optionally provide enforcement that all files subsequently read from disk are covered by a valid digital signature. @@ -33,7 +31,7 @@ index 4870faaa00a..365d1d6931b 100644 platform's firmware (e.g., Coreboot) validates @file{core.img}. If environment variable @code{check_signatures} -@@ -6067,6 +6068,25 @@ be restricted and some operations/commands cannot be executed. +@@ -6586,6 +6587,25 @@ The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down. Otherwise it does not exit. diff --git a/0005-export-environment-at-start-up.patch b/0005-export-environment-at-start-up.patch new file mode 100644 index 0000000000000000000000000000000000000000..9cea3b7b069fc18b82a55e5315a7c02fba751f32 --- /dev/null +++ b/0005-export-environment-at-start-up.patch @@ -0,0 +1,164 @@ +From 496b6b20cbce3fc27228d1d8290089fb7107b8de Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Fri, 18 Feb 2022 21:51:16 +0800 +Subject: [PATCH 5/5] export environment at start up + +If the prep_loadenv module is built into the core image, it will read +the environment block automatically during start up and export all +variables. The will ease integration with those without early scripts to +running the command. + +Signed-off-by: Michael Chang +--- + grub-core/Makefile.core.def | 2 + + grub-core/commands/prep_loadenv.c | 77 +++++++++++++++++++++++++++++++ + grub-core/kern/env.c | 2 + + grub-core/kern/main.c | 3 ++ + include/grub/env.h | 1 + + 5 files changed, 85 insertions(+) + +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -2678,4 +2678,6 @@ + name = prep_loadenv; + common = commands/prep_loadenv.c; + enable = powerpc_ieee1275; ++ cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; ++ cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)'; + }; +--- a/grub-core/commands/prep_loadenv.c ++++ b/grub-core/commands/prep_loadenv.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -185,6 +186,65 @@ + } + + static grub_err_t ++boot_disk_prep_partname (char **name) ++{ ++ regex_t regex; ++ int ret; ++ grub_size_t s; ++ char *comperr; ++ const char *cmdpath; ++ regmatch_t *matches = NULL; ++ grub_err_t err = GRUB_ERR_NONE; ++ ++ *name = NULL; ++ ++ cmdpath = grub_env_get ("cmdpath"); ++ if (!cmdpath) ++ return GRUB_ERR_NONE; ++ ++ ret = regcomp (®ex, "\\(([^,]+)(,?.*)?\\)(.*)", REG_EXTENDED); ++ if (ret) ++ goto fail; ++ ++ matches = grub_calloc (regex.re_nsub + 1, sizeof (*matches)); ++ if (! matches) ++ goto fail; ++ ++ ret = regexec (®ex, cmdpath, regex.re_nsub + 1, matches, 0); ++ if (!ret) ++ { ++ char *devname = devname = match_substr (matches + 1, cmdpath); ++ if (!devname) ++ { ++ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "%s contains no disk name", cmdpath); ++ goto out; ++ } ++ ++ err = prep_partname (devname, name); ++ out: ++ grub_free (devname); ++ regfree (®ex); ++ grub_free (matches); ++ return err; ++ } ++ ++ fail: ++ grub_free (matches); ++ s = regerror (ret, ®ex, 0, 0); ++ comperr = grub_malloc (s); ++ if (!comperr) ++ { ++ regfree (®ex); ++ return grub_errno; ++ } ++ regerror (ret, ®ex, comperr, s); ++ err = grub_error (GRUB_ERR_TEST_FAILURE, "%s", comperr); ++ regfree (®ex); ++ grub_free (comperr); ++ return err; ++} ++ ++static grub_err_t + grub_cmd_prep_loadenv (grub_command_t cmd __attribute__ ((unused)), + int argc, + char **argv) +@@ -214,10 +274,27 @@ + return GRUB_ERR_NONE; + } + ++static void ++early_prep_loadenv (void) ++{ ++ grub_err_t err; ++ char *prep; ++ ++ err = boot_disk_prep_partname (&prep); ++ if (err == GRUB_ERR_NONE && prep) ++ err = prep_read_envblk (prep); ++ if (err == GRUB_ERR_BAD_FILE_TYPE || err == GRUB_ERR_FILE_NOT_FOUND) ++ grub_error_pop (); ++ if (err != GRUB_ERR_NONE) ++ grub_print_error (); ++ grub_free (prep); ++} ++ + static grub_command_t cmd_prep_load; + + GRUB_MOD_INIT(prep_loadenv) + { ++ early_env_hook = early_prep_loadenv; + cmd_prep_load = + grub_register_command("prep_load_env", grub_cmd_prep_loadenv, + "DEVICE", +--- a/grub-core/kern/env.c ++++ b/grub-core/kern/env.c +@@ -28,6 +28,8 @@ + /* The current context. */ + struct grub_env_context *grub_current_context = &initial_context; + ++void (*early_env_hook) (void) = NULL; ++ + /* Return the hash representation of the string S. */ + static unsigned int + grub_env_hashval (const char *s) +--- a/grub-core/kern/main.c ++++ b/grub-core/kern/main.c +@@ -309,6 +309,9 @@ + + grub_boot_time ("Before execution of embedded config."); + ++ if (early_env_hook != NULL) ++ early_env_hook (); ++ + if (load_config) + grub_parser_execute (load_config); + +--- a/include/grub/env.h ++++ b/include/grub/env.h +@@ -69,5 +69,6 @@ + grub_err_t + grub_env_extractor_close (int source); + ++extern void (*EXPORT_VAR (early_env_hook)) (void); + + #endif /* ! GRUB_ENV_HEADER */ diff --git a/0078-grub.texi-Add-net_bootp6-doument.patch b/0005-grub.texi-Add-net_bootp6-doument.patch similarity index 75% rename from 0078-grub.texi-Add-net_bootp6-doument.patch rename to 0005-grub.texi-Add-net_bootp6-doument.patch index 3f8ec97a685181b0e3489e5c97d998349d1b6421..9c323f41fe50c638ff9bbec8173ca2a244dab4ca 100644 --- a/0078-grub.texi-Add-net_bootp6-doument.patch +++ b/0005-grub.texi-Add-net_bootp6-doument.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 2c997c8c058b41d3a59a81f2bf654288b7cdf8f2 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Tue, 5 May 2015 14:19:24 +0800 -Subject: [PATCH] grub.texi: Add net_bootp6 doument +Subject: [PATCH 5/8] grub.texi: Add net_bootp6 doument Update grub documentation for net_bootp6 command. @@ -11,11 +11,9 @@ Signed-off-by: Ken Lin docs/grub.texi | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) -diff --git a/docs/grub.texi b/docs/grub.texi -index 0615d0ed97e..04ed6ac1f07 100644 --- a/docs/grub.texi +++ b/docs/grub.texi -@@ -5487,6 +5487,7 @@ This command is only available on AArch64 systems. +@@ -5894,6 +5894,7 @@ * net_add_dns:: Add a DNS server * net_add_route:: Add routing entry * net_bootp:: Perform a bootp/DHCP autoconfiguration @@ -23,10 +21,11 @@ index 0615d0ed97e..04ed6ac1f07 100644 * net_del_addr:: Remove IP address from interface * net_del_dns:: Remove a DNS server * net_del_route:: Remove a route entry -@@ -5611,6 +5612,22 @@ Sets environment variable @samp{net_}@var{}@samp{_boot_file} +@@ -5951,6 +5952,24 @@ @end deffn ++ +@node net_bootp6 +@subsection net_bootp6 + @@ -43,6 +42,7 @@ index 0615d0ed97e..04ed6ac1f07 100644 +@end table + +@end deffn ++ - @node net_get_dhcp_option - @subsection net_get_dhcp_option + @node net_del_addr + @subsection net_del_addr diff --git a/0005-util-grub-protect-Add-new-tool.patch b/0005-util-grub-protect-Add-new-tool.patch new file mode 100644 index 0000000000000000000000000000000000000000..61a68b09f1b178016fc2f3c5a440465a644eaf01 --- /dev/null +++ b/0005-util-grub-protect-Add-new-tool.patch @@ -0,0 +1,1620 @@ +From 1116bc4b9a27aceaec53421e89eb887e6ad3aef8 Mon Sep 17 00:00:00 2001 +From: Hernan Gatta +Date: Tue, 1 Feb 2022 05:02:57 -0800 +Subject: [PATCH v7 12/20] util/grub-protect: Add new tool + +To utilize the key protectors framework, there must be a way to protect +full-disk encryption keys in the first place. The grub-protect tool +includes support for the TPM2 key protector but other protectors that +require setup ahead of time can be supported in the future. + +For the TPM2 key protector, the intended flow is for a user to have a +LUKS 1 or LUKS 2-protected fully-encrypted disk. The user then creates a +new LUKS key file, say by reading /dev/urandom into a file, and creates +a new LUKS key slot for this key. Then, the user invokes the grub-protect +tool to seal this key file to a set of PCRs using the system's TPM 2.0. +The resulting sealed key file is stored in an unencrypted partition such +as the EFI System Partition (ESP) so that GRUB may read it. The user also +has to ensure the cryptomount command is included in GRUB's boot script +and that it carries the requisite key protector (-P) parameter. + +Sample usage: + +$ dd if=/dev/urandom of=luks-key bs=1 count=32 +$ sudo cryptsetup luksAddKey /dev/sdb1 luks-key --pbkdf=pbkdf2 --hash=sha512 + +To seal the key with TPM 2.0 Key File (recommended): + +$ sudo grub-protect --action=add \ + --protector=tpm2 \ + --tpm2key \ + --tpm2-keyfile=luks-key \ + --tpm2-outfile=/boot/efi/boot/grub2/sealed.tpm + +Or, to seal the key with the raw sealed key: + +$ sudo grub-protect --action=add \ + --protector=tpm2 \ + --tpm2-keyfile=luks-key \ + --tpm2-outfile=/boot/efi/boot/grub2/sealed.key + +Then, in the boot script, for TPM 2.0 Key File: + +tpm2_key_protector_init --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm +cryptomount -u -P tpm2 + +Or, for the raw sealed key: + +tpm2_key_protector_init --keyfile=(hd0,gpt1)/boot/grub2/sealed.key +cryptomount -u -P tpm2 + +Signed-off-by: Hernan Gatta +Signed-off-by: Gary Lin +--- + Makefile.util.def | 22 + + configure.ac | 9 + + util/grub-protect.c | 1492 +++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 1525 insertions(+) + create mode 100644 util/grub-protect.c + +diff --git a/Makefile.util.def b/Makefile.util.def +index e89abb38f..f43c223b9 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -207,6 +207,28 @@ program = { + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + }; + ++program = { ++ name = grub-protect; ++ ++ common = grub-core/osdep/init.c; ++ common = grub-core/tpm2/args.c; ++ common = grub-core/tpm2/buffer.c; ++ common = grub-core/tpm2/mu.c; ++ common = grub-core/tpm2/tpm2.c; ++ common = grub-core/tpm2/tpm2key_asn1_tab.c; ++ common = util/grub-protect.c; ++ common = util/probe.c; ++ ++ ldadd = libgrubmods.a; ++ ldadd = libgrubgcry.a; ++ ldadd = libgrubkern.a; ++ ldadd = grub-core/lib/gnulib/libgnu.a; ++ ldadd = '$(LIBTASN1)'; ++ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; ++ ++ enable = efi; ++}; ++ + program = { + name = grub-mkrelpath; + mansection = 1; +diff --git a/configure.ac b/configure.ac +index c19779c14..9796e5f9b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -76,6 +76,7 @@ grub_TRANSFORM([grub-mkpasswd-pbkdf2]) + grub_TRANSFORM([grub-mkrelpath]) + grub_TRANSFORM([grub-mkrescue]) + grub_TRANSFORM([grub-probe]) ++grub_TRANSFORM([grub-protect]) + grub_TRANSFORM([grub-reboot]) + grub_TRANSFORM([grub-script-check]) + grub_TRANSFORM([grub-set-default]) +@@ -2018,6 +2019,14 @@ fi + AC_SUBST([LIBZFS]) + AC_SUBST([LIBNVPAIR]) + ++LIBTASN1= ++if test x"$platform" = xefi; then ++ AC_CHECK_LIB([tasn1], [asn1_write_value], [], ++ [AC_MSG_ERROR([Your platform requires libtasn1])]) ++ LIBTASN1="-ltasn1" ++fi ++AC_SUBST([LIBTASN1]) ++ + LIBS="" + + AC_SUBST([FONT_SOURCE]) +diff --git a/util/grub-protect.c b/util/grub-protect.c +new file mode 100644 +index 000000000..c6d41ea40 +--- /dev/null ++++ b/util/grub-protect.c +@@ -0,0 +1,1492 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2022 Microsoft Corporation ++ * Copyright (C) 2023 SUSE LLC ++ * ++ * 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 . ++ */ ++ ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#pragma GCC diagnostic ignored "-Wmissing-prototypes" ++#pragma GCC diagnostic ignored "-Wmissing-declarations" ++#include ++#pragma GCC diagnostic error "-Wmissing-prototypes" ++#pragma GCC diagnostic error "-Wmissing-declarations" ++ ++#include "progname.h" ++ ++/* Unprintable option keys for argp */ ++typedef enum grub_protect_opt ++{ ++ /* General */ ++ GRUB_PROTECT_OPT_ACTION = 'a', ++ GRUB_PROTECT_OPT_PROTECTOR = 'p', ++ /* TPM2 */ ++ GRUB_PROTECT_OPT_TPM2_DEVICE = 0x100, ++ GRUB_PROTECT_OPT_TPM2_PCRS, ++ GRUB_PROTECT_OPT_TPM2_ASYMMETRIC, ++ GRUB_PROTECT_OPT_TPM2_BANK, ++ GRUB_PROTECT_OPT_TPM2_SRK, ++ GRUB_PROTECT_OPT_TPM2_KEYFILE, ++ GRUB_PROTECT_OPT_TPM2_OUTFILE, ++ GRUB_PROTECT_OPT_TPM2_EVICT, ++ GRUB_PROTECT_OPT_TPM2_TPM2KEY ++} grub_protect_opt; ++ ++/* Option flags to keep track of specified arguments */ ++typedef enum grub_protect_arg ++{ ++ /* General */ ++ GRUB_PROTECT_ARG_ACTION = 1 << 0, ++ GRUB_PROTECT_ARG_PROTECTOR = 1 << 1, ++ /* TPM2 */ ++ GRUB_PROTECT_ARG_TPM2_DEVICE = 1 << 2, ++ GRUB_PROTECT_ARG_TPM2_PCRS = 1 << 3, ++ GRUB_PROTECT_ARG_TPM2_ASYMMETRIC = 1 << 4, ++ GRUB_PROTECT_ARG_TPM2_BANK = 1 << 5, ++ GRUB_PROTECT_ARG_TPM2_SRK = 1 << 6, ++ GRUB_PROTECT_ARG_TPM2_KEYFILE = 1 << 7, ++ GRUB_PROTECT_ARG_TPM2_OUTFILE = 1 << 8, ++ GRUB_PROTECT_ARG_TPM2_EVICT = 1 << 9, ++ GRUB_PROTECT_ARG_TPM2_TPM2KEY = 1 << 10 ++} grub_protect_arg_t; ++ ++typedef enum grub_protect_protector ++{ ++ GRUB_PROTECT_TYPE_ERROR, ++ GRUB_PROTECT_TYPE_TPM2 ++} grub_protect_protector_t; ++ ++typedef enum grub_protect_action ++{ ++ GRUB_PROTECT_ACTION_ERROR, ++ GRUB_PROTECT_ACTION_ADD, ++ GRUB_PROTECT_ACTION_REMOVE ++} grub_protect_action_t; ++ ++struct grub_protect_args ++{ ++ grub_protect_arg_t args; ++ grub_protect_action_t action; ++ grub_protect_protector_t protector; ++ ++ const char *tpm2_device; ++ grub_uint8_t tpm2_pcrs[TPM_MAX_PCRS]; ++ grub_uint8_t tpm2_pcr_count; ++ TPM_ALG_ID tpm2_asymmetric; ++ TPM_KEY_BITS rsa_bits; ++ TPM_ECC_CURVE ecc_curve; ++ TPM_ALG_ID tpm2_bank; ++ TPM_HANDLE tpm2_srk; ++ const char *tpm2_keyfile; ++ const char *tpm2_outfile; ++ int tpm2_evict; ++ int tpm2_tpm2key; ++}; ++ ++static struct argp_option grub_protect_options[] = ++ { ++ /* Top-level options */ ++ { ++ .name = "action", ++ .key = 'a', ++ .arg = "add|remove", ++ .flags = 0, ++ .doc = ++ N_("Add or remove a key protector to or from a key."), ++ .group = 0 ++ }, ++ { ++ .name = "protector", ++ .key = 'p', ++ .arg = "tpm2", ++ .flags = 0, ++ .doc = ++ N_("Key protector to use (only tpm2 is currently supported)."), ++ .group = 0 ++ }, ++ /* TPM2 key protector options */ ++ { ++ .name = "tpm2-device", ++ .key = GRUB_PROTECT_OPT_TPM2_DEVICE, ++ .arg = "FILE", ++ .flags = 0, ++ .doc = ++ N_("Path to the TPM2 device (default is /dev/tpm0)."), ++ .group = 0 ++ }, ++ { ++ .name = "tpm2-pcrs", ++ .key = GRUB_PROTECT_OPT_TPM2_PCRS, ++ .arg = "0[,1]...", ++ .flags = 0, ++ .doc = ++ N_("Comma-separated list of PCRs used to authorize key release " ++ "(e.g., '7,11', default is 7."), ++ .group = 0 ++ }, ++ { ++ .name = "tpm2-bank", ++ .key = GRUB_PROTECT_OPT_TPM2_BANK, ++ .arg = "ALG", ++ .flags = 0, ++ .doc = ++ N_("Bank of PCRs used to authorize key release: " ++ "SHA1, SHA256 (default), or SHA512."), ++ .group = 0 ++ }, ++ { ++ .name = "tpm2-keyfile", ++ .key = GRUB_PROTECT_OPT_TPM2_KEYFILE, ++ .arg = "FILE", ++ .flags = 0, ++ .doc = ++ N_("Path to a file that contains the cleartext key to protect."), ++ .group = 0 ++ }, ++ { ++ .name = "tpm2-outfile", ++ .key = GRUB_PROTECT_OPT_TPM2_OUTFILE, ++ .arg = "FILE", ++ .flags = 0, ++ .doc = ++ N_("Path to the file that will contain the key after sealing (must be " ++ "accessible to GRUB during boot)."), ++ .group = 0 ++ }, ++ { ++ .name = "tpm2-srk", ++ .key = GRUB_PROTECT_OPT_TPM2_SRK, ++ .arg = "NUM", ++ .flags = 0, ++ .doc = ++ N_("The SRK handle if the SRK is to be made persistent."), ++ .group = 0 ++ }, ++ { ++ .name = "tpm2-asymmetric", ++ .key = GRUB_PROTECT_OPT_TPM2_ASYMMETRIC, ++ .arg = "TYPE", ++ .flags = 0, ++ .doc = ++ N_("The type of SRK: RSA (RSA2048), RSA3072, RSA4096, " ++ "ECC (ECC_NIST_P256), ECC_NIST_P384, ECC_NIST_P521, " ++ "ECC_BN_P256, ECC_BN_P638, and ECC_SM2_P256. " ++ "(default is RSA2048)"), ++ .group = 0 ++ }, ++ { ++ .name = "tpm2-evict", ++ .key = GRUB_PROTECT_OPT_TPM2_EVICT, ++ .arg = NULL, ++ .flags = 0, ++ .doc = ++ N_("Evict a previously persisted SRK from the TPM, if any."), ++ .group = 0 ++ }, ++ { ++ .name = "tpm2key", ++ .key = GRUB_PROTECT_OPT_TPM2_TPM2KEY, ++ .arg = NULL, ++ .flags = 0, ++ .doc = ++ N_("Use TPM 2.0 Key File format instead of the raw format."), ++ .group = 0 ++ }, ++ /* End of list */ ++ { 0, 0, 0, 0, 0, 0 } ++ }; ++ ++static int grub_protector_tpm2_fd = -1; ++ ++static grub_err_t ++grub_protect_read_file (const char *filepath, void **buffer, ++ size_t *buffer_size) ++{ ++ grub_err_t err; ++ FILE *f; ++ long len; ++ void *buf; ++ ++ f = fopen (filepath, "rb"); ++ if (f == NULL) ++ return GRUB_ERR_FILE_NOT_FOUND; ++ ++ if (fseek (f, 0, SEEK_END)) ++ { ++ err = GRUB_ERR_FILE_READ_ERROR; ++ goto exit1; ++ } ++ ++ len = ftell (f); ++ if (len == 0) ++ { ++ err = GRUB_ERR_FILE_READ_ERROR; ++ goto exit1; ++ } ++ ++ rewind (f); ++ ++ buf = grub_malloc (len); ++ if (buf == NULL) ++ { ++ err = GRUB_ERR_OUT_OF_MEMORY; ++ goto exit1; ++ } ++ ++ if (fread (buf, len, 1, f) != 1) ++ { ++ err = GRUB_ERR_FILE_READ_ERROR; ++ goto exit2; ++ } ++ ++ *buffer = buf; ++ *buffer_size = len; ++ ++ buf = NULL; ++ err = GRUB_ERR_NONE; ++ ++exit2: ++ grub_free (buf); ++ ++exit1: ++ fclose (f); ++ ++ return err; ++} ++ ++static grub_err_t ++grub_protect_write_file (const char *filepath, void *buffer, size_t buffer_size) ++{ ++ grub_err_t err; ++ FILE *f; ++ ++ f = fopen (filepath, "wb"); ++ if (f == NULL) ++ return GRUB_ERR_FILE_NOT_FOUND; ++ ++ if (fwrite (buffer, buffer_size, 1, f) != 1) ++ { ++ err = GRUB_ERR_WRITE_ERROR; ++ goto exit1; ++ } ++ ++ err = GRUB_ERR_NONE; ++ ++exit1: ++ fclose (f); ++ ++ return err; ++} ++ ++static grub_err_t ++grub_protect_get_grub_drive_for_file (const char *filepath, char **drive) ++{ ++ grub_err_t err = GRUB_ERR_IO; ++ char *disk; ++ char **devices; ++ char *grub_dev; ++ char *grub_path; ++ char *efi_drive; ++ char *partition; ++ char *grub_drive; ++ grub_device_t dev; ++ grub_size_t grub_drive_len; ++ int n; ++ ++ grub_path = grub_canonicalize_file_name (filepath); ++ if (grub_path == NULL) ++ goto exit1; ++ ++ devices = grub_guess_root_devices (grub_path); ++ if (devices == NULL || devices[0] == NULL) ++ goto exit2; ++ ++ disk = devices[0]; ++ ++ grub_util_pull_device (disk); ++ ++ grub_dev = grub_util_get_grub_dev (disk); ++ if (grub_dev == NULL) ++ goto exit3; ++ ++ dev = grub_device_open (grub_dev); ++ if (dev == NULL) ++ goto exit4; ++ ++ efi_drive = grub_util_guess_efi_drive (disk); ++ if (efi_drive == NULL) ++ goto exit5; ++ ++ partition = grub_partition_get_name (dev->disk->partition); ++ if (partition == NULL) ++ goto exit6; ++ ++ grub_drive_len = grub_strlen (efi_drive) + grub_strlen (partition) + 3; ++ grub_drive = grub_malloc (grub_drive_len + 1); ++ if (grub_drive == NULL) ++ goto exit7; ++ ++ n = grub_snprintf (grub_drive, grub_drive_len + 1, "(%s,%s)", efi_drive, ++ partition); ++ if (n != grub_drive_len) ++ goto exit8; ++ ++ *drive = grub_drive; ++ grub_drive = NULL; ++ err = GRUB_ERR_NONE; ++ ++exit8: ++ grub_free (grub_drive); ++ ++exit7: ++ grub_free (partition); ++ ++exit6: ++ grub_free (efi_drive); ++ ++exit5: ++ grub_device_close (dev); ++ ++exit4: ++ grub_free (grub_dev); ++ ++exit3: ++ grub_free (devices); ++ ++exit2: ++ grub_free (grub_path); ++ ++exit1: ++ return err; ++} ++ ++grub_err_t ++grub_tcg2_get_max_output_size (grub_size_t *size) ++{ ++ if (size == NULL) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ *size = GRUB_TPM2_BUFFER_CAPACITY; ++ ++ return GRUB_ERR_NONE; ++} ++ ++grub_err_t ++grub_tcg2_submit_command (grub_size_t input_size, grub_uint8_t *input, ++ grub_size_t output_size, grub_uint8_t *output) ++{ ++ static const grub_size_t header_size = sizeof (grub_uint16_t) + ++ (2 * sizeof(grub_uint32_t)); ++ ++ if (write (grub_protector_tpm2_fd, input, input_size) != input_size) ++ return GRUB_ERR_BAD_DEVICE; ++ ++ if (read (grub_protector_tpm2_fd, output, output_size) < header_size) ++ return GRUB_ERR_BAD_DEVICE; ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_protect_tpm2_open_device (const char *dev_node) ++{ ++ if (grub_protector_tpm2_fd != -1) ++ return GRUB_ERR_NONE; ++ ++ grub_protector_tpm2_fd = open (dev_node, O_RDWR); ++ if (grub_protector_tpm2_fd == -1) ++ { ++ fprintf (stderr, _("Could not open TPM device (Error: %u).\n"), errno); ++ return GRUB_ERR_FILE_NOT_FOUND; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_protect_tpm2_close_device (void) ++{ ++ int err; ++ ++ if (grub_protector_tpm2_fd == -1) ++ return GRUB_ERR_NONE; ++ ++ err = close (grub_protector_tpm2_fd); ++ if (err != GRUB_ERR_NONE) ++ { ++ fprintf (stderr, _("Could not close TPM device (Error: %u).\n"), errno); ++ return GRUB_ERR_IO; ++ } ++ ++ grub_protector_tpm2_fd = -1; ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_protect_tpm2_get_policy_digest (struct grub_protect_args *args, ++ TPM2B_DIGEST *digest) ++{ ++ TPM_RC rc; ++ TPML_PCR_SELECTION pcr_sel = { ++ .count = 1, ++ .pcrSelections = { ++ { ++ .hash = args->tpm2_bank, ++ .sizeOfSelect = 3, ++ .pcrSelect = { 0 } ++ }, ++ } ++ }; ++ TPML_PCR_SELECTION pcr_sel_out = { 0 }; ++ TPML_DIGEST pcr_values = { 0 }; ++ grub_uint8_t *pcr_digest; ++ grub_size_t pcr_digest_len; ++ grub_uint8_t *pcr_concat; ++ grub_size_t pcr_concat_len; ++ grub_uint8_t *pcr_cursor; ++ const gcry_md_spec_t *hash_spec; ++ TPM2B_NONCE nonce = { 0 }; ++ TPM2B_ENCRYPTED_SECRET salt = { 0 }; ++ TPMT_SYM_DEF symmetric = { 0 }; ++ TPMI_SH_AUTH_SESSION session = 0; ++ TPM2B_DIGEST pcr_digest_in = { ++ .size = TPM_SHA256_DIGEST_SIZE, ++ .buffer = { 0 } ++ }; ++ TPM2B_DIGEST policy_digest = { 0 }; ++ grub_uint8_t i; ++ grub_err_t err; ++ ++ /* PCR Read */ ++ for (i = 0; i < args->tpm2_pcr_count; i++) ++ TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], args->tpm2_pcrs[i]); ++ ++ rc = TPM2_PCR_Read (NULL, &pcr_sel, NULL, &pcr_sel_out, &pcr_values, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ fprintf (stderr, _("Failed to read PCRs (TPM2_PCR_Read: 0x%x).\n"), rc); ++ return GRUB_ERR_BAD_DEVICE; ++ } ++ ++ if ((pcr_sel_out.count != pcr_sel.count) || ++ (pcr_sel.pcrSelections[0].sizeOfSelect != ++ pcr_sel_out.pcrSelections[0].sizeOfSelect)) ++ { ++ fprintf (stderr, _("Could not read all the specified PCRs.\n")); ++ return GRUB_ERR_BAD_DEVICE; ++ } ++ ++ /* Compute PCR Digest */ ++ switch (args->tpm2_bank) ++ { ++ case TPM_ALG_SHA1: ++ pcr_digest_len = TPM_SHA1_DIGEST_SIZE; ++ hash_spec = GRUB_MD_SHA1; ++ break; ++ case TPM_ALG_SHA256: ++ pcr_digest_len = TPM_SHA256_DIGEST_SIZE; ++ hash_spec = GRUB_MD_SHA256; ++ break; ++ case TPM_ALG_SHA512: ++ pcr_digest_len = TPM_SHA512_DIGEST_SIZE; ++ hash_spec = GRUB_MD_SHA512; ++ break; ++ /* Although SHA384 can be parsed by grub_tpm2_protector_parse_bank(), ++ it's not supported by the built-in libgcrypt, and we won't be able to ++ calculate the PCR digest, so SHA384 is marked as unsupported. */ ++ default: ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ pcr_digest = grub_malloc (pcr_digest_len); ++ if (!pcr_digest) ++ { ++ fprintf (stderr, _("Failed to allocate PCR digest buffer.\n")); ++ return GRUB_ERR_OUT_OF_MEMORY; ++ } ++ ++ pcr_concat_len = pcr_digest_len * args->tpm2_pcr_count; ++ pcr_concat = grub_malloc (pcr_concat_len); ++ if (pcr_concat == NULL) ++ { ++ err = GRUB_ERR_OUT_OF_MEMORY; ++ fprintf (stderr, _("Failed to allocate PCR concatenation buffer.\n")); ++ goto exit1; ++ } ++ ++ pcr_cursor = pcr_concat; ++ for (i = 0; i < args->tpm2_pcr_count; i++) ++ { ++ if (pcr_values.digests[i].size != pcr_digest_len) ++ { ++ fprintf (stderr, ++ _("Bad PCR value size: expected %" PRIuGRUB_SIZE " bytes but got %u bytes.\n"), ++ pcr_digest_len, pcr_values.digests[i].size); ++ goto exit2; ++ } ++ ++ grub_memcpy (pcr_cursor, pcr_values.digests[i].buffer, pcr_digest_len); ++ pcr_cursor += pcr_digest_len; ++ } ++ ++ grub_crypto_hash (hash_spec, pcr_digest, pcr_concat, pcr_concat_len); ++ ++ /* Start Trial Session */ ++ nonce.size = TPM_SHA256_DIGEST_SIZE; ++ symmetric.algorithm = TPM_ALG_NULL; ++ ++ rc = TPM2_StartAuthSession (TPM_RH_NULL, TPM_RH_NULL, 0, &nonce, &salt, ++ TPM_SE_TRIAL, &symmetric, TPM_ALG_SHA256, ++ &session, NULL, 0); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ fprintf (stderr, ++ _("Failed to start trial policy session (TPM2_StartAuthSession: 0x%x).\n"), ++ rc); ++ err = GRUB_ERR_BAD_DEVICE; ++ goto exit2; ++ } ++ ++ /* PCR Policy */ ++ memcpy (pcr_digest_in.buffer, pcr_digest, TPM_SHA256_DIGEST_SIZE); ++ ++ rc = TPM2_PolicyPCR (session, NULL, &pcr_digest_in, &pcr_sel, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ fprintf (stderr, _("Failed to submit PCR policy (TPM2_PolicyPCR: 0x%x).\n"), ++ rc); ++ err = GRUB_ERR_BAD_DEVICE; ++ goto exit3; ++ } ++ ++ /* Retrieve Policy Digest */ ++ rc = TPM2_PolicyGetDigest (session, NULL, &policy_digest, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ fprintf (stderr, _("Failed to get policy digest (TPM2_PolicyGetDigest: 0x%x).\n"), ++ rc); ++ err = GRUB_ERR_BAD_DEVICE; ++ goto exit3; ++ } ++ ++ /* Epilogue */ ++ *digest = policy_digest; ++ err = GRUB_ERR_NONE; ++ ++exit3: ++ TPM2_FlushContext (session); ++ ++exit2: ++ grub_free (pcr_concat); ++ ++exit1: ++ grub_free (pcr_digest); ++ ++ return err; ++} ++ ++static grub_err_t ++grub_protect_tpm2_get_srk (struct grub_protect_args *args, TPM_HANDLE *srk) ++{ ++ TPM_RC rc; ++ TPM2B_PUBLIC public; ++ TPMS_AUTH_COMMAND authCommand = { 0 }; ++ TPM2B_SENSITIVE_CREATE inSensitive = { 0 }; ++ TPM2B_PUBLIC inPublic = { 0 }; ++ TPM2B_DATA outsideInfo = { 0 }; ++ TPML_PCR_SELECTION creationPcr = { 0 }; ++ TPM2B_PUBLIC outPublic = { 0 }; ++ TPM2B_CREATION_DATA creationData = { 0 }; ++ TPM2B_DIGEST creationHash = { 0 }; ++ TPMT_TK_CREATION creationTicket = { 0 }; ++ TPM2B_NAME srkName = { 0 }; ++ TPM_HANDLE srkHandle; ++ ++ if (args->tpm2_srk != 0) ++ { ++ /* Find SRK */ ++ rc = TPM2_ReadPublic (args->tpm2_srk, NULL, &public); ++ if (rc == TPM_RC_SUCCESS) ++ { ++ printf (_("Read SRK from 0x%x\n"), args->tpm2_srk); ++ *srk = args->tpm2_srk; ++ return GRUB_ERR_NONE; ++ } ++ ++ /* The handle exists but its public area could not be read. */ ++ if ((rc & ~TPM_RC_N_MASK) != TPM_RC_HANDLE) ++ { ++ fprintf (stderr, ++ _("Failed to retrieve SRK from 0x%x (TPM2_ReadPublic: 0x%x).\n"), ++ args->tpm2_srk, rc); ++ return GRUB_ERR_BAD_DEVICE; ++ } ++ } ++ ++ /* Create SRK */ ++ authCommand.sessionHandle = TPM_RS_PW; ++ inPublic.publicArea.type = args->tpm2_asymmetric; ++ inPublic.publicArea.nameAlg = TPM_ALG_SHA256; ++ inPublic.publicArea.objectAttributes.restricted = 1; ++ inPublic.publicArea.objectAttributes.userWithAuth = 1; ++ inPublic.publicArea.objectAttributes.decrypt = 1; ++ inPublic.publicArea.objectAttributes.fixedTPM = 1; ++ inPublic.publicArea.objectAttributes.fixedParent = 1; ++ inPublic.publicArea.objectAttributes.sensitiveDataOrigin = 1; ++ inPublic.publicArea.objectAttributes.noDA = 1; ++ ++ switch (args->tpm2_asymmetric) ++ { ++ case TPM_ALG_RSA: ++ inPublic.publicArea.parameters.rsaDetail.symmetric.algorithm = TPM_ALG_AES; ++ inPublic.publicArea.parameters.rsaDetail.symmetric.keyBits.aes = 128; ++ inPublic.publicArea.parameters.rsaDetail.symmetric.mode.aes = TPM_ALG_CFB; ++ inPublic.publicArea.parameters.rsaDetail.scheme.scheme = TPM_ALG_NULL; ++ inPublic.publicArea.parameters.rsaDetail.keyBits = args->rsa_bits; ++ inPublic.publicArea.parameters.rsaDetail.exponent = 0; ++ break; ++ ++ case TPM_ALG_ECC: ++ inPublic.publicArea.parameters.eccDetail.symmetric.algorithm = TPM_ALG_AES; ++ inPublic.publicArea.parameters.eccDetail.symmetric.keyBits.aes = 128; ++ inPublic.publicArea.parameters.eccDetail.symmetric.mode.aes = TPM_ALG_CFB; ++ inPublic.publicArea.parameters.eccDetail.scheme.scheme = TPM_ALG_NULL; ++ inPublic.publicArea.parameters.eccDetail.curveID = args->ecc_curve; ++ inPublic.publicArea.parameters.eccDetail.kdf.scheme = TPM_ALG_NULL; ++ break; ++ ++ default: ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ rc = TPM2_CreatePrimary (TPM_RH_OWNER, &authCommand, &inSensitive, &inPublic, ++ &outsideInfo, &creationPcr, &srkHandle, &outPublic, ++ &creationData, &creationHash, &creationTicket, ++ &srkName, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ fprintf (stderr, _("Failed to create SRK (TPM2_CreatePrimary: 0x%x).\n"), rc); ++ return GRUB_ERR_BAD_DEVICE; ++ } ++ ++ /* Persist SRK */ ++ if (args->tpm2_srk != 0) ++ { ++ rc = TPM2_EvictControl (TPM_RH_OWNER, srkHandle, &authCommand, ++ args->tpm2_srk, NULL); ++ if (rc == TPM_RC_SUCCESS) ++ { ++ TPM2_FlushContext (srkHandle); ++ srkHandle = args->tpm2_srk; ++ } ++ else ++ fprintf (stderr, ++ _("Warning: Failed to persist SRK (0x%x) (TPM2_EvictControl: 0x%x\n). " ++ "Continuing anyway...\n"), args->tpm2_srk, rc); ++ } ++ ++ /* Epilogue */ ++ *srk = srkHandle; ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_protect_tpm2_seal (TPM2B_DIGEST *policyDigest, TPM_HANDLE srk, ++ grub_uint8_t *clearText, grub_size_t clearTextLength, ++ TPM2_SEALED_KEY *sealed_key) ++{ ++ TPM_RC rc; ++ TPMS_AUTH_COMMAND authCommand = { 0 }; ++ TPM2B_SENSITIVE_CREATE inSensitive = { 0 }; ++ TPM2B_PUBLIC inPublic = { 0 }; ++ TPM2B_DATA outsideInfo = { 0 }; ++ TPML_PCR_SELECTION pcr_sel = { 0 }; ++ TPM2B_PRIVATE outPrivate = { 0 }; ++ TPM2B_PUBLIC outPublic = { 0 }; ++ ++ /* Seal Data */ ++ authCommand.sessionHandle = TPM_RS_PW; ++ ++ inSensitive.sensitive.data.size = clearTextLength; ++ memcpy(inSensitive.sensitive.data.buffer, clearText, clearTextLength); ++ ++ inPublic.publicArea.type = TPM_ALG_KEYEDHASH; ++ inPublic.publicArea.nameAlg = TPM_ALG_SHA256; ++ inPublic.publicArea.parameters.keyedHashDetail.scheme.scheme = TPM_ALG_NULL; ++ inPublic.publicArea.authPolicy = *policyDigest; ++ ++ rc = TPM2_Create (srk, &authCommand, &inSensitive, &inPublic, &outsideInfo, ++ &pcr_sel, &outPrivate, &outPublic, NULL, NULL, NULL, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ fprintf (stderr, _("Failed to seal key (TPM2_Create: 0x%x).\n"), rc); ++ return GRUB_ERR_BAD_DEVICE; ++ } ++ ++ /* Epilogue */ ++ sealed_key->public = outPublic; ++ sealed_key->private = outPrivate; ++ ++ return GRUB_ERR_NONE; ++} ++ ++extern asn1_static_node tpm2key_asn1_tab[]; ++ ++static grub_err_t ++grub_protect_tpm2_export_tpm2key (const struct grub_protect_args *args, ++ TPM2_SEALED_KEY *sealed_key) ++{ ++ const char *sealed_key_oid = "2.23.133.10.1.5"; ++ asn1_node asn1_def = NULL; ++ asn1_node tpm2key = NULL; ++ grub_uint32_t parent; ++ grub_uint32_t cmd_code; ++ struct grub_tpm2_buffer pol_buf; ++ TPML_PCR_SELECTION pcr_sel = { ++ .count = 1, ++ .pcrSelections = { ++ { ++ .hash = args->tpm2_bank, ++ .sizeOfSelect = 3, ++ .pcrSelect = { 0 } ++ }, ++ } ++ }; ++ struct grub_tpm2_buffer pub_buf; ++ struct grub_tpm2_buffer priv_buf; ++ void *der_buf = NULL; ++ int der_buf_size = 0; ++ int i; ++ int ret; ++ grub_err_t err; ++ ++ for (i = 0; i < args->tpm2_pcr_count; i++) ++ TPMS_PCR_SELECTION_SelectPCR (&pcr_sel.pcrSelections[0], args->tpm2_pcrs[i]); ++ ++ /* ++ * Prepare the parameters for TPM_CC_PolicyPCR: ++ * empty pcrDigest and the user selected PCRs ++ */ ++ grub_tpm2_buffer_init (&pol_buf); ++ grub_tpm2_buffer_pack_u16 (&pol_buf, 0); ++ grub_tpm2_mu_TPML_PCR_SELECTION_Marshal (&pol_buf, &pcr_sel); ++ ++ grub_tpm2_buffer_init (&pub_buf); ++ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&pub_buf, &sealed_key->public); ++ grub_tpm2_buffer_init (&priv_buf); ++ grub_tpm2_mu_TPM2B_Marshal (&priv_buf, sealed_key->private.size, ++ sealed_key->private.buffer); ++ if (pub_buf.error != 0 || priv_buf.error != 0) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ ret = asn1_array2tree (tpm2key_asn1_tab, &asn1_def, NULL); ++ if (ret != ASN1_SUCCESS) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ ret = asn1_create_element (asn1_def, "TPM2KEY.TPMKey" , &tpm2key); ++ if (ret != ASN1_SUCCESS) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ /* Set 'type' to "sealed key" */ ++ ret = asn1_write_value (tpm2key, "type", sealed_key_oid, 1); ++ if (ret != ASN1_SUCCESS) ++ { ++ err = GRUB_ERR_BAD_ARGUMENT; ++ goto error; ++ } ++ ++ /* Set 'emptyAuth' to TRUE */ ++ ret = asn1_write_value (tpm2key, "emptyAuth", "TRUE", 1); ++ if (ret != ASN1_SUCCESS) ++ { ++ err = GRUB_ERR_BAD_ARGUMENT; ++ goto error; ++ } ++ ++ /* Set 'policy' */ ++ ret = asn1_write_value (tpm2key, "policy", "NEW", 1); ++ if (ret != ASN1_SUCCESS) ++ { ++ err = GRUB_ERR_BAD_ARGUMENT; ++ goto error; ++ } ++ cmd_code = grub_cpu_to_be32 (TPM_CC_PolicyPCR); ++ ret = asn1_write_value (tpm2key, "policy.?LAST.CommandCode", &cmd_code, ++ sizeof (cmd_code)); ++ if (ret != ASN1_SUCCESS) ++ { ++ err = GRUB_ERR_BAD_ARGUMENT; ++ goto error; ++ } ++ ret = asn1_write_value (tpm2key, "policy.?LAST.CommandPolicy", &pol_buf.data, ++ pol_buf.size); ++ if (ret != ASN1_SUCCESS) ++ { ++ err = GRUB_ERR_BAD_ARGUMENT; ++ goto error; ++ } ++ ++ /* Remove 'secret' */ ++ ret = asn1_write_value (tpm2key, "secret", NULL, 0); ++ if (ret != ASN1_SUCCESS) ++ { ++ err = GRUB_ERR_BAD_ARGUMENT; ++ goto error; ++ } ++ ++ /* Remove 'authPolicy' */ ++ ret = asn1_write_value (tpm2key, "authPolicy", NULL, 0); ++ if (ret != ASN1_SUCCESS) ++ { ++ err = GRUB_ERR_BAD_ARGUMENT; ++ goto error; ++ } ++ ++ /* Use TPM_RH_OWNER as the default parent handle */ ++ parent = grub_cpu_to_be32 (TPM_RH_OWNER); ++ ret = asn1_write_value (tpm2key, "parent", &parent, sizeof (parent)); ++ if (ret != ASN1_SUCCESS) ++ { ++ err = GRUB_ERR_BAD_ARGUMENT; ++ goto error; ++ } ++ ++ /* Set the pubkey */ ++ ret = asn1_write_value (tpm2key, "pubkey", pub_buf.data, pub_buf.size); ++ if (ret != ASN1_SUCCESS) ++ { ++ err = GRUB_ERR_BAD_ARGUMENT; ++ goto error; ++ } ++ ++ /* Set the privkey */ ++ ret = asn1_write_value (tpm2key, "privkey", priv_buf.data, priv_buf.size); ++ if (ret != ASN1_SUCCESS) ++ { ++ err = GRUB_ERR_BAD_ARGUMENT; ++ goto error; ++ } ++ ++ /* Create the DER binary */ ++ der_buf_size = 0; ++ ret = asn1_der_coding (tpm2key, "", NULL, &der_buf_size, NULL); ++ ++ der_buf = grub_malloc (der_buf_size); ++ if (der_buf == NULL) ++ { ++ err = GRUB_ERR_OUT_OF_MEMORY; ++ goto error; ++ } ++ ++ ret = asn1_der_coding (tpm2key, "", der_buf, &der_buf_size, NULL); ++ if (ret != ASN1_SUCCESS) ++ { ++ err = GRUB_ERR_BAD_ARGUMENT; ++ goto error; ++ } ++ ++ err = grub_protect_write_file (args->tpm2_outfile, der_buf, der_buf_size); ++ if (err != GRUB_ERR_NONE) ++ fprintf (stderr, _("Could not write tpm2key file (Error: %u).\n"), ++ errno); ++ ++error: ++ grub_free (der_buf); ++ ++ if (tpm2key) ++ asn1_delete_structure (&tpm2key); ++ ++ return err; ++} ++ ++static grub_err_t ++grub_protect_tpm2_export_sealed_key (const char *filepath, ++ TPM2_SEALED_KEY *sealed_key) ++{ ++ grub_err_t err; ++ struct grub_tpm2_buffer buf; ++ ++ grub_tpm2_buffer_init (&buf); ++ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&buf, &sealed_key->public); ++ grub_tpm2_mu_TPM2B_Marshal (&buf, sealed_key->private.size, ++ sealed_key->private.buffer); ++ if (buf.error != 0) ++ return GRUB_ERR_BAD_ARGUMENT; ++ ++ err = grub_protect_write_file (filepath, buf.data, buf.size); ++ if (err != GRUB_ERR_NONE) ++ fprintf (stderr, _("Could not write sealed key file (Error: %u).\n"), ++ errno); ++ ++ return err; ++} ++ ++static grub_err_t ++grub_protect_tpm2_add (struct grub_protect_args *args) ++{ ++ grub_err_t err; ++ grub_uint8_t *key; ++ grub_size_t key_size; ++ TPM_HANDLE srk; ++ TPM2B_DIGEST policy_digest; ++ TPM2_SEALED_KEY sealed_key; ++ char *grub_drive = NULL; ++ ++ grub_protect_get_grub_drive_for_file (args->tpm2_outfile, &grub_drive); ++ ++ err = grub_protect_tpm2_open_device (args->tpm2_device); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ err = grub_protect_read_file (args->tpm2_keyfile, (void **)&key, &key_size); ++ if (err != GRUB_ERR_NONE) ++ goto exit1; ++ ++ if (key_size > TPM_MAX_SYM_DATA) ++ { ++ fprintf (stderr, ++ _("Input key is too long, maximum allowed size is %u bytes.\n"), ++ TPM_MAX_SYM_DATA); ++ return GRUB_ERR_OUT_OF_RANGE; ++ } ++ ++ err = grub_protect_tpm2_get_srk (args, &srk); ++ if (err != GRUB_ERR_NONE) ++ goto exit2; ++ ++ err = grub_protect_tpm2_get_policy_digest (args, &policy_digest); ++ if (err != GRUB_ERR_NONE) ++ goto exit3; ++ ++ err = grub_protect_tpm2_seal (&policy_digest, srk, key, key_size, ++ &sealed_key); ++ if (err != GRUB_ERR_NONE) ++ goto exit3; ++ ++ if (args->tpm2_tpm2key) ++ err = grub_protect_tpm2_export_tpm2key (args, &sealed_key); ++ else ++ err = grub_protect_tpm2_export_sealed_key (args->tpm2_outfile, &sealed_key); ++ if (err != GRUB_ERR_NONE) ++ goto exit3; ++ ++ if (grub_drive) ++ { ++ printf (_("GRUB drive for the sealed key file: %s\n"), grub_drive); ++ grub_free (grub_drive); ++ } ++ else ++ { ++ fprintf (stderr, ++ _("Warning: Could not determine GRUB drive for sealed key " ++ "file.\n")); ++ err = GRUB_ERR_NONE; ++ } ++ ++exit3: ++ TPM2_FlushContext (srk); ++ ++exit2: ++ grub_free (key); ++ ++exit1: ++ grub_protect_tpm2_close_device (); ++ ++ return err; ++} ++ ++static grub_err_t ++grub_protect_tpm2_remove (struct grub_protect_args *args) ++{ ++ TPM_RC rc; ++ TPM2B_PUBLIC public; ++ TPMS_AUTH_COMMAND authCommand = { 0 }; ++ grub_err_t err; ++ ++ if (args->tpm2_evict == 0) ++ { ++ printf (_("--tpm2-evict not specified, nothing to do.\n")); ++ return GRUB_ERR_NONE; ++ } ++ ++ err = grub_protect_tpm2_open_device (args->tpm2_device); ++ if (err != GRUB_ERR_NONE) ++ return err; ++ ++ /* Find SRK */ ++ rc = TPM2_ReadPublic (args->tpm2_srk, NULL, &public); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ fprintf (stderr, _("SRK with handle 0x%x not found.\n"), args->tpm2_srk); ++ err = GRUB_ERR_BAD_ARGUMENT; ++ goto exit1; ++ } ++ ++ /* Evict SRK */ ++ authCommand.sessionHandle = TPM_RS_PW; ++ ++ rc = TPM2_EvictControl (TPM_RH_OWNER, args->tpm2_srk, &authCommand, ++ args->tpm2_srk, NULL); ++ if (rc != TPM_RC_SUCCESS) ++ { ++ fprintf (stderr, ++ _("Failed to evict SRK with handle 0x%x (TPM2_EvictControl: 0x%x).\n"), ++ args->tpm2_srk, rc); ++ err = GRUB_ERR_BAD_DEVICE; ++ goto exit2; ++ } ++ ++ err = GRUB_ERR_NONE; ++ ++exit2: ++ TPM2_FlushContext (args->tpm2_srk); ++ ++exit1: ++ grub_protect_tpm2_close_device (); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_protect_tpm2_run (struct grub_protect_args *args) ++{ ++ switch (args->action) ++ { ++ case GRUB_PROTECT_ACTION_ADD: ++ return grub_protect_tpm2_add (args); ++ ++ case GRUB_PROTECT_ACTION_REMOVE: ++ return grub_protect_tpm2_remove (args); ++ ++ default: ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++} ++ ++static grub_err_t ++grub_protect_tpm2_args_verify (struct grub_protect_args *args) ++{ ++ switch (args->action) ++ { ++ case GRUB_PROTECT_ACTION_ADD: ++ if (args->args & GRUB_PROTECT_ARG_TPM2_EVICT) ++ { ++ fprintf (stderr, ++ _("--tpm2-evict is invalid when --action is 'add'.\n")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ if (args->tpm2_keyfile == NULL) ++ { ++ fprintf (stderr, _("--tpm2-keyfile must be specified.\n")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ if (args->tpm2_outfile == NULL) ++ { ++ fprintf (stderr, _("--tpm2-outfile must be specified.\n")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ if (args->tpm2_device == NULL) ++ args->tpm2_device = "/dev/tpm0"; ++ ++ if (args->tpm2_pcr_count == 0) ++ { ++ args->tpm2_pcrs[0] = 7; ++ args->tpm2_pcr_count = 1; ++ } ++ ++ if (args->tpm2_asymmetric == TPM_ALG_ERROR) ++ { ++ args->tpm2_asymmetric = TPM_ALG_RSA; ++ args->rsa_bits = 2048; ++ } ++ ++ if (args->tpm2_bank == TPM_ALG_ERROR) ++ args->tpm2_bank = TPM_ALG_SHA256; ++ ++ break; ++ ++ case GRUB_PROTECT_ACTION_REMOVE: ++ if (args->args & GRUB_PROTECT_ARG_TPM2_ASYMMETRIC) ++ { ++ fprintf (stderr, ++ _("--tpm2-asymmetric is invalid when --action is 'remove'.\n")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ if (args->args & GRUB_PROTECT_ARG_TPM2_BANK) ++ { ++ fprintf (stderr, ++ _("--tpm2-bank is invalid when --action is 'remove'.\n")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ if (args->args & GRUB_PROTECT_ARG_TPM2_KEYFILE) ++ { ++ fprintf (stderr, ++ _("--tpm2-keyfile is invalid when --action is 'remove'.\n")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ if (args->args & GRUB_PROTECT_ARG_TPM2_OUTFILE) ++ { ++ fprintf (stderr, ++ _("--tpm2-outfile is invalid when --action is 'remove'.\n")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ if (args->args & GRUB_PROTECT_ARG_TPM2_PCRS) ++ { ++ fprintf (stderr, ++ _("--tpm2-pcrs is invalid when --action is 'remove'.\n")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ if (args->tpm2_srk == 0) ++ { ++ fprintf (stderr, ++ _("--tpm2-srk is not specified when --action is 'remove'.\n")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ if (args->tpm2_device == NULL) ++ args->tpm2_device = "/dev/tpm0"; ++ ++ break; ++ ++ default: ++ fprintf (stderr, ++ _("The TPM2 key protector only supports the following actions: " ++ "add, remove.\n")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static error_t ++grub_protect_argp_parser (int key, char *arg, struct argp_state *state) ++{ ++ grub_err_t err; ++ struct grub_protect_args *args = state->input; ++ ++ switch (key) ++ { ++ case GRUB_PROTECT_OPT_ACTION: ++ if (args->args & GRUB_PROTECT_ARG_ACTION) ++ { ++ fprintf (stderr, _("--action|-a can only be specified once.\n")); ++ return EINVAL; ++ } ++ ++ if (grub_strcmp (arg, "add") == 0) ++ args->action = GRUB_PROTECT_ACTION_ADD; ++ else if (grub_strcmp (arg, "remove") == 0) ++ args->action = GRUB_PROTECT_ACTION_REMOVE; ++ else ++ { ++ fprintf (stderr, _("'%s' is not a valid action.\n"), arg); ++ return EINVAL; ++ } ++ ++ args->args |= GRUB_PROTECT_ARG_ACTION; ++ break; ++ ++ case GRUB_PROTECT_OPT_PROTECTOR: ++ if (args->args & GRUB_PROTECT_ARG_PROTECTOR) ++ { ++ fprintf (stderr, _("--protector|-p can only be specified once.\n")); ++ return EINVAL; ++ } ++ ++ if (grub_strcmp (arg, "tpm2") == 0) ++ args->protector = GRUB_PROTECT_TYPE_TPM2; ++ else ++ { ++ fprintf (stderr, _("'%s' is not a valid protector.\n"), arg); ++ return EINVAL; ++ } ++ ++ args->args |= GRUB_PROTECT_ARG_PROTECTOR; ++ break; ++ ++ case GRUB_PROTECT_OPT_TPM2_DEVICE: ++ if (args->args & GRUB_PROTECT_ARG_TPM2_DEVICE) ++ { ++ fprintf (stderr, _("--tpm2-device can only be specified once.\n")); ++ return EINVAL; ++ } ++ ++ args->tpm2_device = xstrdup(arg); ++ args->args |= GRUB_PROTECT_ARG_TPM2_DEVICE; ++ break; ++ ++ case GRUB_PROTECT_OPT_TPM2_PCRS: ++ if (args->args & GRUB_PROTECT_ARG_TPM2_PCRS) ++ { ++ fprintf (stderr, _("--tpm2-pcrs can only be specified once.\n")); ++ return EINVAL; ++ } ++ ++ err = grub_tpm2_protector_parse_pcrs (arg, args->tpm2_pcrs, ++ &args->tpm2_pcr_count); ++ if (err != GRUB_ERR_NONE) ++ { ++ if (grub_errno != GRUB_ERR_NONE) ++ grub_print_error (); ++ return EINVAL; ++ } ++ ++ args->args |= GRUB_PROTECT_ARG_TPM2_PCRS; ++ break; ++ ++ case GRUB_PROTECT_OPT_TPM2_SRK: ++ if (args->args & GRUB_PROTECT_ARG_TPM2_SRK) ++ { ++ fprintf (stderr, _("--tpm2-srk can only be specified once.\n")); ++ return EINVAL; ++ } ++ ++ err = grub_tpm2_protector_parse_tpm_handle (arg, &args->tpm2_srk); ++ if (err != GRUB_ERR_NONE) ++ { ++ if (grub_errno != GRUB_ERR_NONE) ++ grub_print_error (); ++ return EINVAL; ++ } ++ ++ args->args |= GRUB_PROTECT_ARG_TPM2_SRK; ++ break; ++ ++ case GRUB_PROTECT_OPT_TPM2_ASYMMETRIC: ++ if (args->args & GRUB_PROTECT_ARG_TPM2_ASYMMETRIC) ++ { ++ fprintf (stderr, _("--tpm2-asymmetric can only be specified once.\n")); ++ return EINVAL; ++ } ++ ++ err = grub_tpm2_protector_parse_asymmetric (arg, &args->tpm2_asymmetric, ++ &args->rsa_bits, &args->ecc_curve); ++ if (err != GRUB_ERR_NONE) ++ { ++ if (grub_errno != GRUB_ERR_NONE) ++ grub_print_error (); ++ return EINVAL; ++ } ++ ++ args->args |= GRUB_PROTECT_ARG_TPM2_ASYMMETRIC; ++ break; ++ ++ case GRUB_PROTECT_OPT_TPM2_BANK: ++ if (args->args & GRUB_PROTECT_ARG_TPM2_BANK) ++ { ++ fprintf (stderr, _("--tpm2-bank can only be specified once.\n")); ++ return EINVAL; ++ } ++ ++ err = grub_tpm2_protector_parse_bank (arg, &args->tpm2_bank); ++ if (err != GRUB_ERR_NONE) ++ { ++ if (grub_errno != GRUB_ERR_NONE) ++ grub_print_error (); ++ return EINVAL; ++ } ++ ++ args->args |= GRUB_PROTECT_ARG_TPM2_BANK; ++ break; ++ ++ case GRUB_PROTECT_OPT_TPM2_KEYFILE: ++ if (args->args & GRUB_PROTECT_ARG_TPM2_KEYFILE) ++ { ++ fprintf (stderr, _("--tpm2-keyfile can only be specified once.\n")); ++ return EINVAL; ++ } ++ ++ args->tpm2_keyfile = xstrdup(arg); ++ args->args |= GRUB_PROTECT_ARG_TPM2_KEYFILE; ++ break; ++ ++ case GRUB_PROTECT_OPT_TPM2_OUTFILE: ++ if (args->args & GRUB_PROTECT_ARG_TPM2_OUTFILE) ++ { ++ fprintf (stderr, _("--tpm2-outfile can only be specified once.\n")); ++ return EINVAL; ++ } ++ ++ args->tpm2_outfile = xstrdup(arg); ++ args->args |= GRUB_PROTECT_ARG_TPM2_OUTFILE; ++ break; ++ ++ case GRUB_PROTECT_OPT_TPM2_EVICT: ++ if (args->args & GRUB_PROTECT_ARG_TPM2_EVICT) ++ { ++ fprintf (stderr, _("--tpm2-evict can only be specified once.\n")); ++ return EINVAL; ++ } ++ ++ args->tpm2_evict = 1; ++ args->args |= GRUB_PROTECT_ARG_TPM2_EVICT; ++ break; ++ ++ case GRUB_PROTECT_OPT_TPM2_TPM2KEY: ++ if (args->args & GRUB_PROTECT_ARG_TPM2_TPM2KEY) ++ { ++ fprintf (stderr, _("--tpm2-tpm2key can only be specified once.\n")); ++ return EINVAL; ++ } ++ ++ args->tpm2_tpm2key = 1; ++ args->args |= GRUB_PROTECT_ARG_TPM2_TPM2KEY; ++ break; ++ ++ default: ++ return ARGP_ERR_UNKNOWN; ++ } ++ ++ return 0; ++} ++ ++static grub_err_t ++grub_protect_args_verify (struct grub_protect_args *args) ++{ ++ if (args->action == GRUB_PROTECT_ACTION_ERROR) ++ { ++ fprintf (stderr, "--action is mandatory.\n"); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ /* At the moment, the only configurable key protector is the TPM2 one, so it ++ * is the only key protector supported by this tool. */ ++ if (args->protector != GRUB_PROTECT_TYPE_TPM2) ++ { ++ fprintf (stderr, ++ _("--protector is mandatory and only 'tpm2' is currently " ++ "supported.\n")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ switch (args->protector) ++ { ++ case GRUB_PROTECT_TYPE_TPM2: ++ return grub_protect_tpm2_args_verify (args); ++ default: ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_protect_dispatch (struct grub_protect_args *args) ++{ ++ switch (args->protector) ++ { ++ case GRUB_PROTECT_TYPE_TPM2: ++ return grub_protect_tpm2_run (args); ++ default: ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++} ++ ++static void ++grub_protect_init (int *argc, char **argv[]) ++{ ++ grub_util_host_init (argc, argv); ++ ++ grub_util_biosdisk_init (NULL); ++ ++ grub_init_all (); ++ grub_gcry_init_all (); ++ ++ grub_lvm_fini (); ++ grub_mdraid09_fini (); ++ grub_mdraid1x_fini (); ++ grub_diskfilter_fini (); ++ grub_diskfilter_init (); ++ grub_mdraid09_init (); ++ grub_mdraid1x_init (); ++ grub_lvm_init (); ++} ++ ++static void ++grub_protect_fini (void) ++{ ++ grub_gcry_fini_all (); ++ grub_fini_all (); ++ grub_util_biosdisk_fini (); ++} ++ ++static struct argp grub_protect_argp = ++{ ++ .options = grub_protect_options, ++ .parser = grub_protect_argp_parser, ++ .args_doc = NULL, ++ .doc = ++ N_("Protect a cleartext key using a GRUB key protector that can retrieve " ++ "the key during boot to unlock fully-encrypted disks automatically."), ++ .children = NULL, ++ .help_filter = NULL, ++ .argp_domain = NULL ++}; ++ ++int ++main (int argc, char *argv[]) ++{ ++ grub_err_t err; ++ struct grub_protect_args args = { 0 }; ++ ++ if (argp_parse (&grub_protect_argp, argc, argv, 0, 0, &args) != 0) ++ { ++ fprintf (stderr, _("Could not parse arguments.\n")); ++ return GRUB_ERR_BAD_ARGUMENT; ++ } ++ ++ grub_protect_init (&argc, &argv); ++ ++ err = grub_protect_args_verify (&args); ++ if (err != GRUB_ERR_NONE) ++ goto exit; ++ ++ err = grub_protect_dispatch (&args); ++ if (err != GRUB_ERR_NONE) ++ goto exit; ++ ++exit: ++ grub_protect_fini (); ++ ++ return err; ++} +-- +2.35.3 + diff --git a/0105-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch b/0005-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch similarity index 87% rename from 0105-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch rename to 0005-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch index fdd3096520fc796857e08439d9f54566aee1629d..9cbf61118ecbb8ad8b9d2d7050b39b7f6c698822 100644 --- a/0105-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch +++ b/0005-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch @@ -1,18 +1,19 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From a33acb675fe0d0464637175e4f06176e4c329025 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Fri, 12 Jul 2019 09:53:32 +0200 -Subject: [PATCH] x86-efi: Use bounce buffers for reading to addresses > 4GB +Subject: [PATCH 05/11] x86-efi: Use bounce buffers for reading to addresses > + 4GB Lots of machines apparently can't DMA correctly above 4GB during UEFI, so use bounce buffers for the initramfs read. Signed-off-by: Peter Jones --- - grub-core/loader/i386/efi/linux.c | 52 +++++++++++++++++++++++++++++++++------ + grub-core/loader/i386/efi/linux.c | 52 ++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 7 deletions(-) diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 33e981e76e7..2f0336809e7 100644 +index f3abbd025..d6bed4fb4 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -35,11 +35,16 @@ static grub_dl_t my_mod; @@ -33,7 +34,7 @@ index 33e981e76e7..2f0336809e7 100644 #define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12) static grub_err_t -@@ -73,6 +78,44 @@ grub_linuxefi_unload (void) +@@ -68,6 +73,44 @@ grub_linuxefi_unload (void) return GRUB_ERR_NONE; } @@ -78,7 +79,7 @@ index 33e981e76e7..2f0336809e7 100644 static grub_err_t grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) -@@ -126,7 +169,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), +@@ -120,7 +163,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), for (i = 0; i < nfiles; i++) { grub_ssize_t cursize = grub_file_size (files[i]); @@ -87,7 +88,7 @@ index 33e981e76e7..2f0336809e7 100644 { if (!grub_errno) grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), -@@ -152,11 +195,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), +@@ -145,11 +188,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), return grub_errno; } @@ -99,3 +100,6 @@ index 33e981e76e7..2f0336809e7 100644 static grub_err_t grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) +-- +2.31.1 + diff --git a/0006-Rework-linux16-command.patch b/0006-Rework-linux16-command.patch deleted file mode 100644 index 2c2d6f0ba6ccf41ad7df6f9e96fa054d3535baad..0000000000000000000000000000000000000000 --- a/0006-Rework-linux16-command.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett -Date: Sun, 9 Aug 2015 16:20:58 -0700 -Subject: [PATCH] Rework linux16 command - -We want a single buffer that contains the entire kernel image in order to -perform a TPM measurement. Allocate one and copy the entire kernel int it -before pulling out the individual blocks later on. - -Signed-off-by: Matthew Garrett ---- - grub-core/loader/i386/pc/linux.c | 33 +++++++++++++++++++++------------ - 1 file changed, 21 insertions(+), 12 deletions(-) - -diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c -index 8be4c3b3f48..4b1750e360e 100644 ---- a/grub-core/loader/i386/pc/linux.c -+++ b/grub-core/loader/i386/pc/linux.c -@@ -124,13 +124,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_file_t file = 0; - struct linux_i386_kernel_header lh; - grub_uint8_t setup_sects; -- grub_size_t real_size; -+ grub_size_t real_size, kernel_offset = 0; - grub_ssize_t len; - int i; - char *grub_linux_prot_chunk; - int grub_linux_is_bzimage; - grub_addr_t grub_linux_prot_target; - grub_err_t err; -+ grub_uint8_t *kernel = NULL; - - grub_dl_ref (my_mod); - -@@ -144,7 +145,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - if (! file) - goto fail; - -- if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) -+ len = grub_file_size (file); -+ kernel = grub_malloc (len); -+ if (!kernel) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); -+ goto fail; -+ } -+ -+ if (grub_file_read (file, kernel, len) != len) - { - if (!grub_errno) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -@@ -152,6 +161,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -+ grub_memcpy (&lh, kernel, sizeof (lh)); -+ kernel_offset = sizeof (lh); -+ - if (lh.boot_flag != grub_cpu_to_le16_compile_time (0xaa55)) - { - grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); -@@ -320,13 +332,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_memmove (grub_linux_real_chunk, &lh, sizeof (lh)); - - len = real_size + GRUB_DISK_SECTOR_SIZE - sizeof (lh); -- if (grub_file_read (file, grub_linux_real_chunk + sizeof (lh), len) != len) -- { -- if (!grub_errno) -- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -- argv[0]); -- goto fail; -- } -+ grub_memcpy (grub_linux_real_chunk + sizeof (lh), kernel + kernel_offset, -+ len); -+ kernel_offset += len; - - if (lh.header != grub_cpu_to_le32_compile_time (GRUB_LINUX_I386_MAGIC_SIGNATURE) - || grub_le_to_cpu16 (lh.version) < 0x0200) -@@ -364,9 +372,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - } - - len = grub_linux16_prot_size; -- if (grub_file_read (file, grub_linux_prot_chunk, len) != len && !grub_errno) -- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -- argv[0]); -+ grub_memcpy (grub_linux_prot_chunk, kernel + kernel_offset, len); -+ kernel_offset += len; - - if (grub_errno == GRUB_ERR_NONE) - { -@@ -376,6 +383,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - fail: - -+ grub_free (kernel); -+ - if (file) - grub_file_close (file); - diff --git a/0079-bootp-Add-processing-DHCPACK-packet-from-HTTP-Boot.patch b/0006-bootp-Add-processing-DHCPACK-packet-from-HTTP-Boot.patch similarity index 31% rename from 0079-bootp-Add-processing-DHCPACK-packet-from-HTTP-Boot.patch rename to 0006-bootp-Add-processing-DHCPACK-packet-from-HTTP-Boot.patch index e800dd236d9dede4e0c16f65ac307475a9df2f60..32504cee5e25ef8761c116321cc71669884bfd8f 100644 --- a/0079-bootp-Add-processing-DHCPACK-packet-from-HTTP-Boot.patch +++ b/0006-bootp-Add-processing-DHCPACK-packet-from-HTTP-Boot.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 8191aae462f8b755972a0a801f4adbdd6ecaa66c Mon Sep 17 00:00:00 2001 From: Michael Chang -Date: Wed, 10 Jul 2019 23:58:28 +0200 -Subject: [PATCH] bootp: Add processing DHCPACK packet from HTTP Boot +Date: Thu, 14 Jul 2016 18:45:14 +0800 +Subject: [PATCH 6/8] bootp: Add processing DHCPACK packet from HTTP Boot The vendor class identifier with the string "HTTPClient" is used to denote the packet as responding to HTTP boot request. In DHCP4 config, the filename for @@ -17,88 +17,78 @@ packet by treating it as HTTP format, not as the PXE format. Signed-off-by: Michael Chang Signed-off-by: Ken Lin --- - grub-core/net/bootp.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ + grub-core/net/bootp.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++-- include/grub/net.h | 1 + - 2 files changed, 56 insertions(+) + 2 files changed, 66 insertions(+), 2 deletions(-) -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index fe93b80f1cf..8fb8918ae7e 100644 --- a/grub-core/net/bootp.c +++ b/grub-core/net/bootp.c -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -500,6 +501,60 @@ grub_net_configure_by_dhcp_ack (const char *name, - if (opt && opt_len) - grub_env_set_net_property (name, "rootpath", (const char *) opt, opt_len); +@@ -352,6 +352,53 @@ + if (!inter) + return 0; -+ opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER, &opt_len); -+ if (opt && opt_len) ++ /* FIXME: Introduce new http flag for better synergy with existing tftp code base */ ++ if (size > OFFSET_OF (vendor, bp)) + { -+ grub_env_set_net_property (name, "vendor_class_identifier", (const char *) opt, opt_len); -+ if (opt && grub_strcmp (opt, "HTTPClient") == 0) -+ { -+ char *proto, *ip, *pa; ++ char *cidvar; ++ const char *cid; + -+ if (!dissect_url (bp->boot_file, &proto, &ip, &pa)) -+ return inter; ++ opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER, &opt_len); ++ if (opt && opt_len) ++ grub_env_set_net_property (name, "vendor_class_identifier", (const char *) opt, opt_len); ++ cidvar = grub_xasprintf ("net_%s_%s", name, "vendor_class_identifier"); ++ cid = grub_env_get (cidvar); ++ grub_free (cidvar); + -+ grub_env_set_net_property (name, "boot_file", pa, grub_strlen (pa)); -+ if (is_def) -+ { -+ grub_net_default_server = grub_strdup (ip); -+ grub_env_set ("net_default_interface", name); -+ grub_env_export ("net_default_interface"); -+ } -+ if (device && !*device) -+ { -+ *device = grub_xasprintf ("%s,%s", proto, ip); -+ grub_print_error (); -+ } -+ if (path) -+ { -+ *path = grub_strdup (pa); -+ grub_print_error (); -+ if (*path) -+ { -+ char *slash; -+ slash = grub_strrchr (*path, '/'); -+ if (slash) -+ *slash = 0; -+ else -+ **path = 0; -+ } -+ } -+ grub_net_add_ipv4_local (inter, mask); -+ inter->dhcp_ack = grub_malloc (size); -+ if (inter->dhcp_ack) -+ { -+ grub_memcpy (inter->dhcp_ack, bp, size); -+ inter->dhcp_acklen = size; -+ } -+ else -+ grub_errno = GRUB_ERR_NONE; ++ if (cid && grub_strcmp (cid, "HTTPClient") == 0) ++ { ++ char *proto, *ip, *pa; + -+ grub_free (proto); -+ grub_free (ip); -+ grub_free (pa); -+ return inter; -+ } ++ /* FIXME: Provide better URL function that returns in place pointers ++ * so that we don't have to free them. ++ */ ++ if (!dissect_url (bp->boot_file, &proto, &ip, &pa)) ++ return inter; ++ ++ if (is_def) ++ { ++ grub_net_default_server = grub_strdup (ip); ++ grub_env_set ("net_default_interface", name); ++ grub_env_export ("net_default_interface"); ++ } ++ if (device && !*device) ++ { ++ *device = grub_xasprintf ("%s,%s", proto, ip); ++ grub_print_error (); ++ } ++ ++ boot_file = pa; ++ boot_file_len = grub_strlen (pa); ++ ++ /* FIXME: Don't use malloc buffer here */ ++ grub_free (proto); ++ grub_free (ip); ++ ++ /* FIXME: NEED TO FREE boot_file */ ++ goto boot_file; ++ } + } + - opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_EXTENSIONS_PATH, &opt_len); - if (opt && opt_len) - grub_env_set_net_property (name, "extensionspath", (const char *) opt, opt_len); -diff --git a/include/grub/net.h b/include/grub/net.h -index 543251f7273..42af7de250a 100644 + opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_OVERLOAD, &opt_len); + if (opt && opt_len == 1) + overload = *opt; +@@ -428,6 +475,8 @@ + } + } + ++boot_file: ++ + if (boot_file) + { + grub_env_set_net_property (name, "boot_file", boot_file, boot_file_len); --- a/include/grub/net.h +++ b/include/grub/net.h -@@ -531,6 +531,7 @@ enum +@@ -530,6 +530,7 @@ GRUB_NET_DHCP_MESSAGE_TYPE = 53, GRUB_NET_DHCP_SERVER_IDENTIFIER = 54, GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55, diff --git a/0162-docs-grub-Document-signing-grub-with-an-appended-sig.patch b/0006-docs-grub-Document-signing-grub-with-an-appended-sig.patch similarity index 83% rename from 0162-docs-grub-Document-signing-grub-with-an-appended-sig.patch rename to 0006-docs-grub-Document-signing-grub-with-an-appended-sig.patch index 4d85d93822a8d109216b1730482e0695498c3810..5ace1a01b141d5ac87506893dfd23ea8a4464871 100644 --- a/0162-docs-grub-Document-signing-grub-with-an-appended-sig.patch +++ b/0006-docs-grub-Document-signing-grub-with-an-appended-sig.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From ac539a315495792cd75fe8ab1c474f26e0a78852 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Sat, 15 Aug 2020 02:19:36 +1000 -Subject: [PATCH] docs/grub: Document signing grub with an appended signature +Subject: [PATCH 06/23] docs/grub: Document signing grub with an appended + signature Signing grub for firmware that verifies an appended signature is a bit fiddly. I don't want people to have to figure it out from scratch @@ -12,21 +13,19 @@ Signed-off-by: Daniel Axtens docs/grub.texi | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) -diff --git a/docs/grub.texi b/docs/grub.texi -index 365d1d6931b..afbde7c1f7b 100644 --- a/docs/grub.texi +++ b/docs/grub.texi -@@ -6087,6 +6087,48 @@ image works under UEFI secure boot and can maintain the secure-boot chain. It +@@ -6606,6 +6606,48 @@ will also be necessary to enrol the public key used into a relevant firmware key database. +@section Signing GRUB with an appended signature + -+The @file{core.elf} itself can be signed with a Linux kernel module-style ++The @file{core.img} itself can be signed with a Linux kernel module-style +appended signature. + +To support IEEE1275 platforms where the boot image is often loaded directly -+from a disk partition rather than from a file system, the @file{core.elf} ++from a disk partition rather than from a file system, the @file{core.img} +can specify the size and location of the appended signature with an ELF +note added by @command{grub-install}. + diff --git a/0132-efi-Set-image-base-address-before-jumping-to-the-PE-.patch b/0006-efi-Set-image-base-address-before-jumping-to-the-PE-.patch similarity index 66% rename from 0132-efi-Set-image-base-address-before-jumping-to-the-PE-.patch rename to 0006-efi-Set-image-base-address-before-jumping-to-the-PE-.patch index 336bcf18b2f140ec4e1cbb0d8b1cb226d7e955b5..ad90fbb6772ccf9a83817dfac00caa5ae225ea20 100644 --- a/0132-efi-Set-image-base-address-before-jumping-to-the-PE-.patch +++ b/0006-efi-Set-image-base-address-before-jumping-to-the-PE-.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 3741c6807923ae97b0d87e61c59c8de8af544484 Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Thu, 23 Apr 2020 15:06:46 +0200 -Subject: [PATCH] efi: Set image base address before jumping to the PE/COFF +Subject: [PATCH 6/9] 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 @@ -21,28 +21,23 @@ and print the following warning message: EFI stub: ERROR: FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value -Resolves: rhbz#1814690 +Resolves: rhbz#1825411 Signed-off-by: Javier Martinez Canillas --- - grub-core/loader/efi/linux.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c -index 0622dfa48d4..e8b9ecb17f6 100644 ---- a/grub-core/loader/efi/linux.c -+++ b/grub-core/loader/efi/linux.c -@@ -72,6 +72,7 @@ grub_err_t - grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset, + grub-core/loader/arm64/efi/linux.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +Index: grub-2.06~rc1/grub-core/loader/arm64/efi/linux.c +=================================================================== +--- grub-2.06~rc1.orig/grub-core/loader/arm64/efi/linux.c ++++ grub-2.06~rc1/grub-core/loader/arm64/efi/linux.c +@@ -58,9 +58,24 @@ 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; - int offset = 0; - -@@ -79,6 +80,19 @@ grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset, - offset = 512; - #endif + /* + * Since the EFI loader is not calling the LoadImage() and StartImage() @@ -56,7 +51,9 @@ index 0622dfa48d4..e8b9ecb17f6 100644 + 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)handover_offset, kernel_params); - hf = (handover_func)((char *)kernel_addr + handover_offset + offset); ++ 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/0106-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch b/0006-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch similarity index 86% rename from 0106-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch rename to 0006-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch index f8284ec28a87c863b555d99766a590102167ca57..e37fa51d01806a868640d41aa85a280b3ecfe2c9 100644 --- a/0106-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch +++ b/0006-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch @@ -1,20 +1,20 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 24b5c0a3788c5c02b72ea61312f5cf8c39429db1 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Thu, 13 Sep 2018 14:42:34 -0400 -Subject: [PATCH] x86-efi: Re-arrange grub_cmd_linux() a little bit. +Subject: [PATCH 06/11] x86-efi: Re-arrange grub_cmd_linux() a little bit. This just helps the next patch be easier to read. Signed-off-by: Peter Jones --- - grub-core/loader/i386/efi/linux.c | 75 +++++++++++++++++++++------------------ - 1 file changed, 41 insertions(+), 34 deletions(-) + grub-core/loader/i386/efi/linux.c | 73 +++++++++++++++++-------------- + 1 file changed, 40 insertions(+), 33 deletions(-) diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 2f0336809e7..5f48fa55619 100644 +index d6bed4fb4..096a52eb5 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c -@@ -243,32 +243,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -227,32 +227,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } @@ -28,13 +28,13 @@ index 2f0336809e7..5f48fa55619 100644 - grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); - goto fail; - } -+ lh = (struct linux_i386_kernel_header *)kernel; -+ grub_dprintf ("linux", "original lh is at %p\n", kernel); - +- - grub_dprintf ("linux", "params = %p\n", params); - - grub_memset (params, 0, sizeof(*params)); -- ++ lh = (struct linux_i386_kernel_header *)kernel; ++ grub_dprintf ("linux", "original lh is at %p\n", kernel); + - setup_header_end_offset = *((grub_uint8_t *)kernel + 0x201); - grub_dprintf ("linux", "copying %lu bytes from %p to %p\n", - MIN((grub_size_t)0x202+setup_header_end_offset, @@ -49,7 +49,7 @@ index 2f0336809e7..5f48fa55619 100644 grub_dprintf ("linux", "checking lh->boot_flag\n"); if (lh->boot_flag != grub_cpu_to_le16 (0xaa55)) { -@@ -316,6 +293,34 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -300,6 +277,34 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), } #endif @@ -69,7 +69,7 @@ index 2f0336809e7..5f48fa55619 100644 + grub_memset (params, 0, sizeof(*params)); + + setup_header_end_offset = *((grub_uint8_t *)kernel + 0x201); -+ grub_dprintf ("linux", "copying %lu bytes from %p to %p\n", ++ grub_dprintf ("linux", "copying %" PRIuGRUB_SIZE " bytes from %p to %p\n", + MIN((grub_size_t)0x202+setup_header_end_offset, + sizeof (*params)) - 0x1f1, + (grub_uint8_t *)kernel + 0x1f1, @@ -84,7 +84,7 @@ index 2f0336809e7..5f48fa55619 100644 grub_dprintf ("linux", "setting up cmdline\n"); linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS, BYTES_TO_PAGES(lh->cmdline_size + 1)); -@@ -341,8 +346,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -324,8 +329,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_dprintf ("linux", "setting lh->cmd_line_ptr\n"); lh->cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline; @@ -94,7 +94,7 @@ index 2f0336809e7..5f48fa55619 100644 start = (lh->setup_sects + 1) * 512; -@@ -359,26 +364,28 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -342,24 +347,26 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); goto fail; } @@ -126,8 +126,8 @@ index 2f0336809e7..5f48fa55619 100644 + "setting lh->ext_loader_{type,ver} = {0x%02x,0x%02x}\n", + params->ext_loader_type, params->ext_loader_ver); -- fail: -+fail: - if (file) - grub_file_close (file); + fail: +-- +2.31.1 + diff --git a/0007-Add-secureboot-support-on-efi-chainloader.patch b/0007-Add-secureboot-support-on-efi-chainloader.patch deleted file mode 100644 index 6826cce1e3986691913aa31ce63dc5fec2a24e73..0000000000000000000000000000000000000000 --- a/0007-Add-secureboot-support-on-efi-chainloader.patch +++ /dev/null @@ -1,1401 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Raymund Will -Date: Mon, 8 Jul 2019 11:55:18 +0200 -Subject: [PATCH] Add secureboot support on efi chainloader - -Expand the chainloader to be able to verify the image by means of shim -lock protocol. The PE/COFF image is loaded and relocated by the -chainloader instead of calling LoadImage and StartImage UEFI boot -Service as they require positive verification result from keys enrolled -in KEK or DB. The shim will use MOK in addition to firmware enrolled -keys to verify the image. - -The chainloader module could be used to load other UEFI bootloaders, -such as xen.efi, and could be signed by any of MOK, KEK or DB. - -Based on https://build.opensuse.org/package/view_file/openSUSE:Factory/grub2/grub2-secureboot-chainloader.patch - -Signed-off-by: Peter Jones - -Also: - -commit cd7a8984d4fda905877b5bfe466339100156b3bc -Author: Raymund Will -Date: Fri Apr 10 01:45:02 2015 -0400 - -Use device part of chainloader target, if present. - -Otherwise chainloading is restricted to '$root', which might not even -be readable by EFI! - -v1. use grub_file_get_device_name() to get device name - -Signed-off-by: Michael Chang -Signed-off-by: Peter Jones - -Also: - -commit 0872a2310a0eeac4ecfe9e1b49dd2d72ab373039 -Author: Peter Jones -Date: Fri Jun 10 14:06:15 2016 -0400 - -Rework even more of efi chainload so non-sb cases work right. - -This ensures that if shim protocol is not loaded, or is loaded but shim -is disabled, we will fall back to a correct load method for the efi -chain loader. - -Here's what I tested with this version: - -results expected actual ------------------------------------------------------------- -sb + enabled + shim + fedora success success -sb + enabled + shim + win success success -sb + enabled + grub + fedora fail fail -sb + enabled + grub + win fail fail - -sb + mokdisabled + shim + fedora success success -sb + mokdisabled + shim + win success success -sb + mokdisabled + grub + fedora fail fail -sb + mokdisabled + grub + win fail fail - -sb disabled + shim + fedora success success* -sb disabled + shim + win success success* -sb disabled + grub + fedora success success -sb disabled + grub + win success success - -nosb + shim + fedora success success* -nosb + shim + win success success* -nosb + grub + fedora success success -nosb + grub + win success success - -* for some reason shim protocol is being installed in these cases, and I - can't see why, but I think it may be this firmware build returning an - erroneous value. But this effectively falls back to the mokdisabled - behavior, which works correctly, and the presence of the "grub" (i.e. - no shim) tests effectively tests the desired behavior here. - -Resolves: rhbz#1344512 - -Signed-off-by: Peter Jones - -Also: - -commit ff7b1cb7f69487870211aeb69ff4f54470fbcb58 -Author: Laszlo Ersek -Date: Mon Nov 21 15:34:00 2016 +0100 - -efi/chainloader: fix wrong sanity check in relocate_coff() - -In relocate_coff(), the relocation entries are parsed from the original -image (not the section-wise copied image). The original image is -pointed-to by the "orig" pointer. The current check - - (void *)reloc_end < data - -compares the addresses of independent memory allocations. "data" is a typo -here, it should be "orig". - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1347291 -Signed-off-by: Laszlo Ersek -Tested-by: Bogdan Costescu -Tested-by: Juan Orti - -Also: - -commit ab4ba9997ad4832449e54d930fa2aac6a160d0e9 -Author: Laszlo Ersek -Date: Wed Nov 23 06:27:09 2016 +0100 - -efi/chainloader: truncate overlong relocation section - -The UEFI Windows 7 boot loader ("EFI/Microsoft/Boot/bootmgfw.efi", SHA1 -31b410e029bba87d2068c65a80b88882f9f8ea25) has inconsistent headers. - -Compare: - -> The Data Directory -> ... -> Entry 5 00000000000d9000 00000574 Base Relocation Directory [.reloc] - -Versus: - -> Sections: -> Idx Name Size VMA LMA File off ... -> ... -> 10 .reloc 00000e22 00000000100d9000 00000000100d9000 000a1800 ... - -That is, the size reported by the RelocDir entry (0x574) is smaller than -the virtual size of the .reloc section (0xe22). - -Quoting the grub2 debug log for the same: - -> chainloader.c:595: reloc_dir: 0xd9000 reloc_size: 0x00000574 -> chainloader.c:603: reloc_base: 0x7d208000 reloc_base_end: 0x7d208573 -> ... -> chainloader.c:620: Section 10 ".reloc" at 0x7d208000..0x7d208e21 -> chainloader.c:661: section is not reloc section? -> chainloader.c:663: rds: 0x00001000, vs: 00000e22 -> chainloader.c:664: base: 0x7d208000 end: 0x7d208e21 -> chainloader.c:666: reloc_base: 0x7d208000 reloc_base_end: 0x7d208573 -> chainloader.c:671: Section characteristics are 42000040 -> chainloader.c:673: Section virtual size: 00000e22 -> chainloader.c:675: Section raw_data size: 00001000 -> chainloader.c:678: Discarding section - -After hexdumping "bootmgfw.efi" and manually walking its relocation blocks -(yes, really), I determined that the (smaller) RelocDir value is correct. -The remaining area that extends up to the .reloc section size (== 0xe22 - -0x574 == 0x8ae bytes) exists as zero padding in the file. - -This zero padding shouldn't be passed to relocate_coff() for parsing. In -order to cope with it, split the handling of .reloc sections into the -following branches: - -- original case (equal size): original behavior (--> relocation - attempted), - -- overlong .reloc section (longer than reported by RelocDir): truncate the - section to the RelocDir size for the purposes of relocate_coff(), and - attempt relocation, - -- .reloc section is too short, or other checks fail: original behavior - (--> relocation not attempted). - -Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1347291 -Signed-off-by: Laszlo Ersek - -Also: - -commit cc06f149fbd2d8c1da1e83173d21629ba97e0d92 -Author: Raymund Will - -chainloader: Define machine types for RISC-V - -The commit "Add secureboot support on efi chainloader" didn't add machine -types for RISC-V, so this patch adds them. - -Note, that grub-core/loader/riscv/linux.c is skipped because Linux is not -supported yet. This patch might need a new revision once that's the case. - -Signed-off-by: David Abdurachmanov ---- - grub-core/kern/efi/efi.c | 14 +- - grub-core/loader/arm64/linux.c | 4 +- - grub-core/loader/efi/chainloader.c | 820 +++++++++++++++++++++++++++++++++---- - grub-core/loader/efi/linux.c | 25 +- - grub-core/loader/i386/efi/linux.c | 17 +- - include/grub/efi/linux.h | 2 +- - include/grub/efi/pe32.h | 52 ++- - 7 files changed, 844 insertions(+), 90 deletions(-) - -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 35b8f670602..4a2259aa1c7 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -296,14 +296,20 @@ grub_efi_secure_boot (void) - grub_efi_boolean_t ret = 0; - - secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize); -- - if (datasize != 1 || !secure_boot) -- goto out; -+ { -+ grub_dprintf ("secureboot", "No SecureBoot variable\n"); -+ goto out; -+ } -+ grub_dprintf ("secureboot", "SecureBoot: %d\n", *secure_boot); - - setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize); -- - if (datasize != 1 || !setup_mode) -- goto out; -+ { -+ grub_dprintf ("secureboot", "No SetupMode variable\n"); -+ goto out; -+ } -+ grub_dprintf ("secureboot", "SetupMode: %d\n", *setup_mode); - - if (*secure_boot && !*setup_mode) - ret = 1; -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index a312c668685..04994d5c67d 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -284,6 +284,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); - -@@ -328,7 +329,8 @@ 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)) -+ 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; -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index 2bd80f4db3d..e6a8d4ad0e9 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -32,6 +32,8 @@ - #include - #include - #include -+#include -+#include - #include - #include - #include -@@ -46,9 +48,14 @@ static grub_dl_t my_mod; - - static grub_efi_physical_address_t address; - static grub_efi_uintn_t pages; -+static grub_ssize_t fsize; - static grub_efi_device_path_t *file_path; - static grub_efi_handle_t image_handle; - static grub_efi_char16_t *cmdline; -+static grub_ssize_t cmdline_len; -+static grub_efi_handle_t dev_handle; -+ -+static grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table); - - static grub_err_t - grub_chainloader_unload (void) -@@ -63,6 +70,7 @@ grub_chainloader_unload (void) - grub_free (cmdline); - cmdline = 0; - file_path = 0; -+ dev_handle = 0; - - grub_dl_unref (my_mod); - return GRUB_ERR_NONE; -@@ -213,20 +221,694 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename) - return file_path; - } - -+#define SHIM_LOCK_GUID \ -+ { 0x605dab50, 0xe046, 0x4300, { 0xab,0xb6,0x3d,0xd8,0x10,0xdd,0x8b,0x23 } } -+ -+typedef union -+{ -+ struct grub_pe32_header_32 pe32; -+ struct grub_pe32_header_64 pe32plus; -+} grub_pe_header_t; -+ -+struct pe_coff_loader_image_context -+{ -+ grub_efi_uint64_t image_address; -+ grub_efi_uint64_t image_size; -+ grub_efi_uint64_t entry_point; -+ grub_efi_uintn_t size_of_headers; -+ grub_efi_uint16_t image_type; -+ grub_efi_uint16_t number_of_sections; -+ grub_efi_uint32_t section_alignment; -+ struct grub_pe32_section_table *first_section; -+ struct grub_pe32_data_directory *reloc_dir; -+ struct grub_pe32_data_directory *sec_dir; -+ grub_efi_uint64_t number_of_rva_and_sizes; -+ grub_pe_header_t *pe_hdr; -+}; -+ -+typedef struct pe_coff_loader_image_context pe_coff_loader_image_context_t; -+ -+struct grub_efi_shim_lock -+{ -+ grub_efi_status_t (*verify)(void *buffer, -+ grub_efi_uint32_t size); -+ grub_efi_status_t (*hash)(void *data, -+ grub_efi_int32_t datasize, -+ pe_coff_loader_image_context_t *context, -+ grub_efi_uint8_t *sha256hash, -+ grub_efi_uint8_t *sha1hash); -+ grub_efi_status_t (*context)(void *data, -+ grub_efi_uint32_t size, -+ pe_coff_loader_image_context_t *context); -+}; -+ -+typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; -+ -+static grub_efi_boolean_t -+read_header (void *data, grub_efi_uint32_t size, -+ pe_coff_loader_image_context_t *context) -+{ -+ 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); -+ if (!shim_lock) -+ { -+ grub_dprintf ("chain", "no shim lock protocol"); -+ return 0; -+ } -+ -+ status = shim_lock->context (data, size, context); -+ -+ if (status == GRUB_EFI_SUCCESS) -+ { -+ grub_dprintf ("chain", "context success\n"); -+ return 1; -+ } -+ -+ switch (status) -+ { -+ case GRUB_EFI_UNSUPPORTED: -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error unsupported"); -+ break; -+ case GRUB_EFI_INVALID_PARAMETER: -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error invalid parameter"); -+ break; -+ default: -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error code"); -+ break; -+ } -+ -+ return -1; -+} -+ -+static void* -+image_address (void *image, grub_efi_uint64_t sz, grub_efi_uint64_t adr) -+{ -+ if (adr > sz) -+ return NULL; -+ -+ return ((grub_uint8_t*)image + adr); -+} -+ -+static int -+image_is_64_bit (grub_pe_header_t *pe_hdr) -+{ -+ /* .Magic is the same offset in all cases */ -+ if (pe_hdr->pe32plus.optional_header.magic == GRUB_PE32_PE64_MAGIC) -+ return 1; -+ return 0; -+} -+ -+static const grub_uint16_t machine_type __attribute__((__unused__)) = -+#if defined(__x86_64__) -+ GRUB_PE32_MACHINE_X86_64; -+#elif defined(__aarch64__) -+ GRUB_PE32_MACHINE_ARM64; -+#elif defined(__arm__) -+ GRUB_PE32_MACHINE_ARMTHUMB_MIXED; -+#elif defined(__i386__) || defined(__i486__) || defined(__i686__) -+ GRUB_PE32_MACHINE_I386; -+#elif defined(__ia64__) -+ GRUB_PE32_MACHINE_IA64; -+#elif defined(__riscv) && (__riscv_xlen == 32) -+ GRUB_PE32_MACHINE_RISCV32; -+#elif defined(__riscv) && (__riscv_xlen == 64) -+ GRUB_PE32_MACHINE_RISCV64; -+#else -+#error this architecture is not supported by grub2 -+#endif -+ -+static grub_efi_status_t -+relocate_coff (pe_coff_loader_image_context_t *context, -+ struct grub_pe32_section_table *section, -+ void *orig, void *data) -+{ -+ struct grub_pe32_data_directory *reloc_base, *reloc_base_end; -+ grub_efi_uint64_t adjust; -+ struct grub_pe32_fixup_block *reloc, *reloc_end; -+ char *fixup, *fixup_base, *fixup_data = NULL; -+ grub_efi_uint16_t *fixup_16; -+ grub_efi_uint32_t *fixup_32; -+ grub_efi_uint64_t *fixup_64; -+ grub_efi_uint64_t size = context->image_size; -+ void *image_end = (char *)orig + size; -+ int n = 0; -+ -+ if (image_is_64_bit (context->pe_hdr)) -+ context->pe_hdr->pe32plus.optional_header.image_base = -+ (grub_uint64_t)(unsigned long)data; -+ else -+ context->pe_hdr->pe32.optional_header.image_base = -+ (grub_uint32_t)(unsigned long)data; -+ -+ /* Alright, so here's how this works: -+ * -+ * context->reloc_dir gives us two things: -+ * - the VA the table of base relocation blocks are (maybe) to be -+ * mapped at (reloc_dir->rva) -+ * - the virtual size (reloc_dir->size) -+ * -+ * The .reloc section (section here) gives us some other things: -+ * - the name! kind of. (section->name) -+ * - the virtual size (section->virtual_size), which should be the same -+ * as RelocDir->Size -+ * - the virtual address (section->virtual_address) -+ * - the file section size (section->raw_data_size), which is -+ * a multiple of optional_header->file_alignment. Only useful for image -+ * validation, not really useful for iteration bounds. -+ * - the file address (section->raw_data_offset) -+ * - a bunch of stuff we don't use that's 0 in our binaries usually -+ * - Flags (section->characteristics) -+ * -+ * and then the thing that's actually at the file address is an array -+ * of struct grub_pe32_fixup_block structs with some values packed behind -+ * them. The block_size field of this structure includes the -+ * structure itself, and adding it to that structure's address will -+ * yield the next entry in the array. -+ */ -+ -+ reloc_base = image_address (orig, size, section->raw_data_offset); -+ reloc_base_end = image_address (orig, size, section->raw_data_offset -+ + section->virtual_size); -+ -+ grub_dprintf ("chain", "relocate_coff(): reloc_base %p reloc_base_end %p\n", -+ reloc_base, reloc_base_end); -+ -+ if (!reloc_base && !reloc_base_end) -+ return GRUB_EFI_SUCCESS; -+ -+ if (!reloc_base || !reloc_base_end) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc table overflows binary"); -+ return GRUB_EFI_UNSUPPORTED; -+ } -+ -+ adjust = (grub_uint64_t)(grub_efi_uintn_t)data - context->image_address; -+ if (adjust == 0) -+ return GRUB_EFI_SUCCESS; -+ -+ while (reloc_base < reloc_base_end) -+ { -+ grub_uint16_t *entry; -+ reloc = (struct grub_pe32_fixup_block *)((char*)reloc_base); -+ -+ if ((reloc_base->size == 0) || -+ (reloc_base->size > context->reloc_dir->size)) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ "Reloc %d block size %d is invalid\n", n, -+ reloc_base->size); -+ return GRUB_EFI_UNSUPPORTED; -+ } -+ -+ entry = &reloc->entries[0]; -+ reloc_end = (struct grub_pe32_fixup_block *) -+ ((char *)reloc_base + reloc_base->size); -+ -+ if ((void *)reloc_end < orig || (void *)reloc_end > image_end) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc entry %d overflows binary", -+ n); -+ return GRUB_EFI_UNSUPPORTED; -+ } -+ -+ fixup_base = image_address(data, size, reloc_base->rva); -+ -+ if (!fixup_base) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc %d Invalid fixupbase", n); -+ return GRUB_EFI_UNSUPPORTED; -+ } -+ -+ while ((void *)entry < (void *)reloc_end) -+ { -+ fixup = fixup_base + (*entry & 0xFFF); -+ switch ((*entry) >> 12) -+ { -+ case GRUB_PE32_REL_BASED_ABSOLUTE: -+ break; -+ case GRUB_PE32_REL_BASED_HIGH: -+ fixup_16 = (grub_uint16_t *)fixup; -+ *fixup_16 = (grub_uint16_t) -+ (*fixup_16 + ((grub_uint16_t)((grub_uint32_t)adjust >> 16))); -+ if (fixup_data != NULL) -+ { -+ *(grub_uint16_t *) fixup_data = *fixup_16; -+ fixup_data = fixup_data + sizeof (grub_uint16_t); -+ } -+ break; -+ case GRUB_PE32_REL_BASED_LOW: -+ fixup_16 = (grub_uint16_t *)fixup; -+ *fixup_16 = (grub_uint16_t) (*fixup_16 + (grub_uint16_t)adjust); -+ if (fixup_data != NULL) -+ { -+ *(grub_uint16_t *) fixup_data = *fixup_16; -+ fixup_data = fixup_data + sizeof (grub_uint16_t); -+ } -+ break; -+ case GRUB_PE32_REL_BASED_HIGHLOW: -+ fixup_32 = (grub_uint32_t *)fixup; -+ *fixup_32 = *fixup_32 + (grub_uint32_t)adjust; -+ if (fixup_data != NULL) -+ { -+ fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint32_t)); -+ *(grub_uint32_t *) fixup_data = *fixup_32; -+ fixup_data += sizeof (grub_uint32_t); -+ } -+ break; -+ case GRUB_PE32_REL_BASED_DIR64: -+ fixup_64 = (grub_uint64_t *)fixup; -+ *fixup_64 = *fixup_64 + (grub_uint64_t)adjust; -+ if (fixup_data != NULL) -+ { -+ fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint64_t)); -+ *(grub_uint64_t *) fixup_data = *fixup_64; -+ fixup_data += sizeof (grub_uint64_t); -+ } -+ break; -+ default: -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ "Reloc %d unknown relocation type %d", -+ n, (*entry) >> 12); -+ return GRUB_EFI_UNSUPPORTED; -+ } -+ entry += 1; -+ } -+ reloc_base = (struct grub_pe32_data_directory *)reloc_end; -+ n++; -+ } -+ -+ return GRUB_EFI_SUCCESS; -+} -+ -+static grub_efi_device_path_t * -+grub_efi_get_media_file_path (grub_efi_device_path_t *dp) -+{ -+ while (1) -+ { -+ grub_efi_uint8_t type = GRUB_EFI_DEVICE_PATH_TYPE (dp); -+ grub_efi_uint8_t subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); -+ -+ if (type == GRUB_EFI_END_DEVICE_PATH_TYPE) -+ break; -+ else if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE -+ && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) -+ return dp; -+ -+ dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); -+ } -+ -+ return NULL; -+} -+ -+static grub_efi_boolean_t -+handle_image (void *data, grub_efi_uint32_t datasize) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_loaded_image_t *li, li_bak; -+ grub_efi_status_t efi_status; -+ char *buffer = NULL; -+ char *buffer_aligned = NULL; -+ grub_efi_uint32_t i; -+ struct grub_pe32_section_table *section; -+ char *base, *end; -+ pe_coff_loader_image_context_t context; -+ grub_uint32_t section_alignment; -+ grub_uint32_t buffer_size; -+ int found_entry_point = 0; -+ int rc; -+ -+ b = grub_efi_system_table->boot_services; -+ -+ rc = read_header (data, datasize, &context); -+ if (rc < 0) -+ { -+ grub_dprintf ("chain", "Failed to read header\n"); -+ goto error_exit; -+ } -+ else if (rc == 0) -+ { -+ grub_dprintf ("chain", "Secure Boot is not enabled\n"); -+ return 0; -+ } -+ else -+ { -+ grub_dprintf ("chain", "Header read without error\n"); -+ } -+ -+ /* -+ * The spec says, uselessly, of SectionAlignment: -+ * ===== -+ * The alignment (in bytes) of sections when they are loaded into -+ * memory. It must be greater than or equal to FileAlignment. The -+ * default is the page size for the architecture. -+ * ===== -+ * Which doesn't tell you whose responsibility it is to enforce the -+ * "default", or when. It implies that the value in the field must -+ * be > FileAlignment (also poorly defined), but it appears visual -+ * studio will happily write 512 for FileAlignment (its default) and -+ * 0 for SectionAlignment, intending to imply PAGE_SIZE. -+ * -+ * We only support one page size, so if it's zero, nerf it to 4096. -+ */ -+ section_alignment = context.section_alignment; -+ if (section_alignment == 0) -+ section_alignment = 4096; -+ -+ buffer_size = context.image_size + section_alignment; -+ grub_dprintf ("chain", "image size is %08"PRIxGRUB_UINT64_T", datasize is %08x\n", -+ context.image_size, datasize); -+ -+ efi_status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA, -+ buffer_size, &buffer); -+ -+ if (efi_status != GRUB_EFI_SUCCESS) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto error_exit; -+ } -+ -+ buffer_aligned = (char *)ALIGN_UP ((grub_addr_t)buffer, section_alignment); -+ if (!buffer_aligned) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto error_exit; -+ } -+ -+ grub_memcpy (buffer_aligned, data, context.size_of_headers); -+ -+ entry_point = image_address (buffer_aligned, context.image_size, -+ context.entry_point); -+ -+ grub_dprintf ("chain", "entry_point: %p\n", entry_point); -+ if (!entry_point) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid entry point"); -+ goto error_exit; -+ } -+ -+ char *reloc_base, *reloc_base_end; -+ grub_dprintf ("chain", "reloc_dir: %p reloc_size: 0x%08x\n", -+ (void *)(unsigned long)context.reloc_dir->rva, -+ context.reloc_dir->size); -+ reloc_base = image_address (buffer_aligned, context.image_size, -+ context.reloc_dir->rva); -+ /* RelocBaseEnd here is the address of the last byte of the table */ -+ reloc_base_end = image_address (buffer_aligned, context.image_size, -+ context.reloc_dir->rva -+ + context.reloc_dir->size - 1); -+ grub_dprintf ("chain", "reloc_base: %p reloc_base_end: %p\n", -+ reloc_base, reloc_base_end); -+ -+ struct grub_pe32_section_table *reloc_section = NULL, fake_reloc_section; -+ -+ section = context.first_section; -+ for (i = 0; i < context.number_of_sections; i++, section++) -+ { -+ char name[9]; -+ -+ base = image_address (buffer_aligned, context.image_size, -+ section->virtual_address); -+ end = image_address (buffer_aligned, context.image_size, -+ section->virtual_address + section->virtual_size -1); -+ -+ grub_strncpy(name, section->name, 9); -+ name[8] = '\0'; -+ grub_dprintf ("chain", "Section %d \"%s\" at %p..%p\n", i, -+ name, base, end); -+ -+ if (end < base) -+ { -+ grub_dprintf ("chain", " base is %p but end is %p... bad.\n", -+ base, end); -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ "Image has invalid negative size"); -+ goto error_exit; -+ } -+ -+ if (section->virtual_address <= context.entry_point && -+ (section->virtual_address + section->raw_data_size - 1) -+ > context.entry_point) -+ { -+ found_entry_point++; -+ grub_dprintf ("chain", " section contains entry point\n"); -+ } -+ -+ /* We do want to process .reloc, but it's often marked -+ * discardable, so we don't want to memcpy it. */ -+ if (grub_memcmp (section->name, ".reloc\0\0", 8) == 0) -+ { -+ if (reloc_section) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ "Image has multiple relocation sections"); -+ goto error_exit; -+ } -+ -+ /* If it has nonzero sizes, and our bounds check -+ * made sense, and the VA and size match RelocDir's -+ * versions, then we believe in this section table. */ -+ if (section->raw_data_size && section->virtual_size && -+ base && end && reloc_base == base) -+ { -+ if (reloc_base_end == end) -+ { -+ grub_dprintf ("chain", " section is relocation section\n"); -+ reloc_section = section; -+ } -+ else if (reloc_base_end && reloc_base_end < end) -+ { -+ /* Bogus virtual size in the reloc section -- RelocDir -+ * reported a smaller Base Relocation Directory. Decrease -+ * the section's virtual size so that it equal RelocDir's -+ * idea, but only for the purposes of relocate_coff(). */ -+ grub_dprintf ("chain", -+ " section is (overlong) relocation section\n"); -+ grub_memcpy (&fake_reloc_section, section, sizeof *section); -+ fake_reloc_section.virtual_size -= (end - reloc_base_end); -+ reloc_section = &fake_reloc_section; -+ } -+ } -+ -+ if (!reloc_section) -+ { -+ grub_dprintf ("chain", " section is not reloc section?\n"); -+ grub_dprintf ("chain", " rds: 0x%08x, vs: %08x\n", -+ section->raw_data_size, section->virtual_size); -+ grub_dprintf ("chain", " base: %p end: %p\n", base, end); -+ grub_dprintf ("chain", " reloc_base: %p reloc_base_end: %p\n", -+ reloc_base, reloc_base_end); -+ } -+ } -+ -+ grub_dprintf ("chain", " Section characteristics are %08x\n", -+ section->characteristics); -+ grub_dprintf ("chain", " Section virtual size: %08x\n", -+ section->virtual_size); -+ grub_dprintf ("chain", " Section raw_data size: %08x\n", -+ section->raw_data_size); -+ if (section->characteristics & GRUB_PE32_SCN_MEM_DISCARDABLE) -+ { -+ grub_dprintf ("chain", " Discarding section\n"); -+ continue; -+ } -+ -+ if (!base || !end) -+ { -+ grub_dprintf ("chain", " section is invalid\n"); -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid section size"); -+ goto error_exit; -+ } -+ -+ if (section->characteristics & GRUB_PE32_SCN_CNT_UNINITIALIZED_DATA) -+ { -+ if (section->raw_data_size != 0) -+ grub_dprintf ("chain", " UNINITIALIZED_DATA section has data?\n"); -+ } -+ else if (section->virtual_address < context.size_of_headers || -+ section->raw_data_offset < context.size_of_headers) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ "Section %d is inside image headers", i); -+ goto error_exit; -+ } -+ -+ if (section->raw_data_size > 0) -+ { -+ grub_dprintf ("chain", " copying 0x%08x bytes to %p\n", -+ section->raw_data_size, base); -+ grub_memcpy (base, -+ (grub_efi_uint8_t*)data + section->raw_data_offset, -+ section->raw_data_size); -+ } -+ -+ if (section->raw_data_size < section->virtual_size) -+ { -+ grub_dprintf ("chain", " padding with 0x%08x bytes at %p\n", -+ section->virtual_size - section->raw_data_size, -+ base + section->raw_data_size); -+ grub_memset (base + section->raw_data_size, 0, -+ section->virtual_size - section->raw_data_size); -+ } -+ -+ grub_dprintf ("chain", " finished section %s\n", name); -+ } -+ -+ /* 5 == EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC */ -+ if (context.number_of_rva_and_sizes <= 5) -+ { -+ grub_dprintf ("chain", "image has no relocation entry\n"); -+ goto error_exit; -+ } -+ -+ if (context.reloc_dir->size && reloc_section) -+ { -+ /* run the relocation fixups */ -+ efi_status = relocate_coff (&context, reloc_section, data, -+ buffer_aligned); -+ -+ if (efi_status != GRUB_EFI_SUCCESS) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "relocation failed"); -+ goto error_exit; -+ } -+ } -+ -+ if (!found_entry_point) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "entry point is not within sections"); -+ goto error_exit; -+ } -+ if (found_entry_point > 1) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "%d sections contain entry point", -+ found_entry_point); -+ goto error_exit; -+ } -+ -+ li = grub_efi_get_loaded_image (grub_efi_image_handle); -+ if (!li) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, "no loaded image available"); -+ goto error_exit; -+ } -+ -+ grub_memcpy (&li_bak, li, sizeof (grub_efi_loaded_image_t)); -+ li->image_base = buffer_aligned; -+ li->image_size = context.image_size; -+ li->load_options = cmdline; -+ li->load_options_size = cmdline_len; -+ li->file_path = grub_efi_get_media_file_path (file_path); -+ li->device_handle = dev_handle; -+ if (!li->file_path) -+ { -+ grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file path found"); -+ goto error_exit; -+ } -+ -+ grub_dprintf ("chain", "booting via entry point\n"); -+ efi_status = efi_call_2 (entry_point, grub_efi_image_handle, -+ grub_efi_system_table); -+ -+ grub_dprintf ("chain", "entry_point returned %ld\n", efi_status); -+ grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t)); -+ efi_status = efi_call_1 (b->free_pool, buffer); -+ -+ return 1; -+ -+error_exit: -+ grub_dprintf ("chain", "error_exit: grub_errno: %d\n", grub_errno); -+ if (buffer) -+ efi_call_1 (b->free_pool, buffer); -+ -+ return 0; -+} -+ -+static grub_err_t -+grub_secureboot_chainloader_unload (void) -+{ -+ grub_efi_boot_services_t *b; -+ -+ b = grub_efi_system_table->boot_services; -+ efi_call_2 (b->free_pages, address, pages); -+ grub_free (file_path); -+ grub_free (cmdline); -+ cmdline = 0; -+ file_path = 0; -+ dev_handle = 0; -+ -+ grub_dl_unref (my_mod); -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_load_and_start_image(void *boot_image) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_status_t status; -+ grub_efi_loaded_image_t *loaded_image; -+ -+ b = grub_efi_system_table->boot_services; -+ -+ status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path, -+ boot_image, fsize, &image_handle); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ if (status == GRUB_EFI_OUT_OF_RESOURCES) -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); -+ else -+ grub_error (GRUB_ERR_BAD_OS, "cannot load image"); -+ return -1; -+ } -+ -+ /* LoadImage does not set a device handler when the image is -+ loaded from memory, so it is necessary to set it explicitly here. -+ This is a mess. */ -+ loaded_image = grub_efi_get_loaded_image (image_handle); -+ if (! loaded_image) -+ { -+ grub_error (GRUB_ERR_BAD_OS, "no loaded image available"); -+ return -1; -+ } -+ loaded_image->device_handle = dev_handle; -+ -+ if (cmdline) -+ { -+ loaded_image->load_options = cmdline; -+ loaded_image->load_options_size = cmdline_len; -+ } -+ -+ return 0; -+} -+ -+static grub_err_t -+grub_secureboot_chainloader_boot (void) -+{ -+ int rc; -+ rc = handle_image ((void *)(unsigned long)address, fsize); -+ if (rc == 0) -+ { -+ grub_load_and_start_image((void *)(unsigned long)address); -+ } -+ -+ grub_loader_unset (); -+ return grub_errno; -+} -+ - static grub_err_t - grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - int argc, char *argv[]) - { - grub_file_t file = 0; -- grub_ssize_t size; - grub_efi_status_t status; - grub_efi_boot_services_t *b; - grub_device_t dev = 0; - grub_efi_device_path_t *dp = 0; -- grub_efi_loaded_image_t *loaded_image; - char *filename; - void *boot_image = 0; -- grub_efi_handle_t dev_handle = 0; -+ int rc; - - if (argc == 0) - return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -@@ -238,15 +920,45 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - address = 0; - image_handle = 0; - file_path = 0; -+ dev_handle = 0; - - b = grub_efi_system_table->boot_services; - -+ if (argc > 1) -+ { -+ int i; -+ grub_efi_char16_t *p16; -+ -+ for (i = 1, cmdline_len = 0; i < argc; i++) -+ cmdline_len += grub_strlen (argv[i]) + 1; -+ -+ cmdline_len *= sizeof (grub_efi_char16_t); -+ cmdline = p16 = grub_malloc (cmdline_len); -+ if (! cmdline) -+ goto fail; -+ -+ for (i = 1; i < argc; i++) -+ { -+ char *p8; -+ -+ p8 = argv[i]; -+ while (*p8) -+ *(p16++) = *(p8++); -+ -+ *(p16++) = ' '; -+ } -+ *(--p16) = 0; -+ } -+ - file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE); - if (! file) - goto fail; - -- /* Get the root device's device path. */ -- dev = grub_device_open (0); -+ /* Get the device path from filename. */ -+ char *devname = grub_file_get_device_name (filename); -+ dev = grub_device_open (devname); -+ if (devname) -+ grub_free (devname); - if (! dev) - goto fail; - -@@ -283,17 +995,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - if (! file_path) - goto fail; - -- grub_printf ("file path: "); -- grub_efi_print_device_path (file_path); -- -- size = grub_file_size (file); -- if (!size) -+ fsize = grub_file_size (file); -+ if (!fsize) - { - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - goto fail; - } -- pages = (((grub_efi_uintn_t) size + ((1 << 12) - 1)) >> 12); -+ pages = (((grub_efi_uintn_t) fsize + ((1 << 12) - 1)) >> 12); - - status = efi_call_4 (b->allocate_pages, GRUB_EFI_ALLOCATE_ANY_PAGES, - GRUB_EFI_LOADER_CODE, -@@ -307,7 +1016,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - } - - boot_image = (void *) ((grub_addr_t) address); -- if (grub_file_read (file, boot_image, size) != size) -+ if (grub_file_read (file, boot_image, fsize) != fsize) - { - if (grub_errno == GRUB_ERR_NONE) - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -@@ -317,7 +1026,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - } - - #if defined (__i386__) || defined (__x86_64__) -- if (size >= (grub_ssize_t) sizeof (struct grub_macho_fat_header)) -+ if (fsize >= (grub_ssize_t) sizeof (struct grub_macho_fat_header)) - { - struct grub_macho_fat_header *head = boot_image; - if (head->magic -@@ -326,6 +1035,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - grub_uint32_t i; - struct grub_macho_fat_arch *archs - = (struct grub_macho_fat_arch *) (head + 1); -+ -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ { -+ grub_error (GRUB_ERR_BAD_OS, -+ "MACHO binaries are forbidden with Secure Boot"); -+ goto fail; -+ } -+ - for (i = 0; i < grub_cpu_to_le32 (head->nfat_arch); i++) - { - if (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT (archs[i].cputype)) -@@ -340,79 +1057,39 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - > ~grub_cpu_to_le32 (archs[i].size) - || grub_cpu_to_le32 (archs[i].offset) - + grub_cpu_to_le32 (archs[i].size) -- > (grub_size_t) size) -+ > (grub_size_t) fsize) - { - grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), - filename); - goto fail; - } - boot_image = (char *) boot_image + grub_cpu_to_le32 (archs[i].offset); -- size = grub_cpu_to_le32 (archs[i].size); -+ fsize = grub_cpu_to_le32 (archs[i].size); - } - } - #endif - -- status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path, -- boot_image, size, -- &image_handle); -- if (status != GRUB_EFI_SUCCESS) -+ rc = grub_linuxefi_secure_validate((void *)(unsigned long)address, fsize); -+ grub_dprintf ("chain", "linuxefi_secure_validate: %d\n", rc); -+ if (rc > 0) - { -- if (status == GRUB_EFI_OUT_OF_RESOURCES) -- grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of resources"); -- else -- grub_error (GRUB_ERR_BAD_OS, "cannot load image"); -- -- goto fail; -+ grub_file_close (file); -+ grub_device_close (dev); -+ grub_loader_set (grub_secureboot_chainloader_boot, -+ grub_secureboot_chainloader_unload, 0); -+ return 0; - } -- -- /* LoadImage does not set a device handler when the image is -- loaded from memory, so it is necessary to set it explicitly here. -- This is a mess. */ -- loaded_image = grub_efi_get_loaded_image (image_handle); -- if (! loaded_image) -+ else if (rc == 0) - { -- grub_error (GRUB_ERR_BAD_OS, "no loaded image available"); -- goto fail; -- } -- loaded_image->device_handle = dev_handle; -- -- if (argc > 1) -- { -- int i, len; -- grub_efi_char16_t *p16; -- -- for (i = 1, len = 0; i < argc; i++) -- len += grub_strlen (argv[i]) + 1; -- -- len *= sizeof (grub_efi_char16_t); -- cmdline = p16 = grub_malloc (len); -- if (! cmdline) -- goto fail; -+ grub_load_and_start_image(boot_image); -+ grub_file_close (file); -+ grub_device_close (dev); -+ grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); - -- for (i = 1; i < argc; i++) -- { -- char *p8; -- -- p8 = argv[i]; -- while (*p8) -- *(p16++) = *(p8++); -- -- *(p16++) = ' '; -- } -- *(--p16) = 0; -- -- loaded_image->load_options = cmdline; -- loaded_image->load_options_size = len; -+ return 0; - } - -- grub_file_close (file); -- grub_device_close (dev); -- -- grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0); -- return 0; -- -- fail: -- -+fail: - if (dev) - grub_device_close (dev); - -@@ -424,6 +1101,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - if (address) - efi_call_2 (b->free_pages, address, pages); - -+ if (cmdline) -+ grub_free (cmdline); -+ - grub_dl_unref (my_mod); - - return grub_errno; -diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c -index c24202a5dd1..c8ecce6dfd0 100644 ---- a/grub-core/loader/efi/linux.c -+++ b/grub-core/loader/efi/linux.c -@@ -33,21 +33,34 @@ struct grub_efi_shim_lock - }; - typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; - --grub_efi_boolean_t -+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 -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index bb2616a8092..6b24cbb9483 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -117,6 +117,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -+ grub_dprintf ("linux", "initrd_mem = %lx\n", (unsigned long) initrd_mem); -+ - params->ramdisk_size = size; - params->ramdisk_image = (grub_uint32_t)(grub_addr_t) initrd_mem; - -@@ -159,6 +161,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - struct linux_i386_kernel_header lh; - grub_ssize_t len, start, filelen; - void *kernel = NULL; -+ int rc; - - grub_dl_ref (my_mod); - -@@ -184,11 +187,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - if (grub_file_read (file, kernel, filelen) != filelen) - { -- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]); -+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), -+ argv[0]); - goto fail; - } - -- if (! grub_linuxefi_secure_validate (kernel, filelen)) -+ rc = grub_linuxefi_secure_validate (kernel, filelen); -+ if (rc < 0) - { - grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), - argv[0]); -@@ -203,6 +208,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -+ grub_dprintf ("linux", "params = %lx\n", (unsigned long) params); -+ - grub_memset (params, 0, 16384); - - grub_memcpy (&lh, kernel, sizeof (lh)); -@@ -241,6 +248,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -+ grub_dprintf ("linux", "linux_cmdline = %lx\n", -+ (unsigned long)linux_cmdline); -+ - grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, - linux_cmdline + sizeof (LINUX_IMAGE) - 1, -@@ -275,9 +285,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_memcpy (params, &lh, 2 * 512); - - params->type_of_loader = 0x21; -+ grub_dprintf("linux", "kernel_mem: %p handover_offset: %08x\n", -+ kernel_mem, handover_offset); - - fail: -- - if (file) - grub_file_close (file); - -diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h -index d9ede36773b..0033d9305a9 100644 ---- a/include/grub/efi/linux.h -+++ b/include/grub/efi/linux.h -@@ -22,7 +22,7 @@ - #include - #include - --grub_efi_boolean_t -+int - EXPORT_FUNC(grub_linuxefi_secure_validate) (void *data, grub_uint32_t size); - grub_err_t - EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset, -diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h -index 0ed8781f037..a43adf27464 100644 ---- a/include/grub/efi/pe32.h -+++ b/include/grub/efi/pe32.h -@@ -223,7 +223,11 @@ struct grub_pe64_optional_header - struct grub_pe32_section_table - { - char name[8]; -- grub_uint32_t virtual_size; -+ union -+ { -+ grub_uint32_t physical_address; -+ grub_uint32_t virtual_size; -+ }; - grub_uint32_t virtual_address; - grub_uint32_t raw_data_size; - grub_uint32_t raw_data_offset; -@@ -234,12 +238,18 @@ struct grub_pe32_section_table - grub_uint32_t characteristics; - }; - -+#define GRUB_PE32_SCN_TYPE_NO_PAD 0x00000008 - #define GRUB_PE32_SCN_CNT_CODE 0x00000020 - #define GRUB_PE32_SCN_CNT_INITIALIZED_DATA 0x00000040 --#define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000 --#define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000 --#define GRUB_PE32_SCN_MEM_READ 0x40000000 --#define GRUB_PE32_SCN_MEM_WRITE 0x80000000 -+#define GRUB_PE32_SCN_CNT_UNINITIALIZED_DATA 0x00000080 -+#define GRUB_PE32_SCN_LNK_OTHER 0x00000100 -+#define GRUB_PE32_SCN_LNK_INFO 0x00000200 -+#define GRUB_PE32_SCN_LNK_REMOVE 0x00000800 -+#define GRUB_PE32_SCN_LNK_COMDAT 0x00001000 -+#define GRUB_PE32_SCN_GPREL 0x00008000 -+#define GRUB_PE32_SCN_MEM_16BIT 0x00020000 -+#define GRUB_PE32_SCN_MEM_LOCKED 0x00040000 -+#define GRUB_PE32_SCN_MEM_PRELOAD 0x00080000 - - #define GRUB_PE32_SCN_ALIGN_1BYTES 0x00100000 - #define GRUB_PE32_SCN_ALIGN_2BYTES 0x00200000 -@@ -248,10 +258,28 @@ struct grub_pe32_section_table - #define GRUB_PE32_SCN_ALIGN_16BYTES 0x00500000 - #define GRUB_PE32_SCN_ALIGN_32BYTES 0x00600000 - #define GRUB_PE32_SCN_ALIGN_64BYTES 0x00700000 -+#define GRUB_PE32_SCN_ALIGN_128BYTES 0x00800000 -+#define GRUB_PE32_SCN_ALIGN_256BYTES 0x00900000 -+#define GRUB_PE32_SCN_ALIGN_512BYTES 0x00A00000 -+#define GRUB_PE32_SCN_ALIGN_1024BYTES 0x00B00000 -+#define GRUB_PE32_SCN_ALIGN_2048BYTES 0x00C00000 -+#define GRUB_PE32_SCN_ALIGN_4096BYTES 0x00D00000 -+#define GRUB_PE32_SCN_ALIGN_8192BYTES 0x00E00000 - - #define GRUB_PE32_SCN_ALIGN_SHIFT 20 - #define GRUB_PE32_SCN_ALIGN_MASK 7 - -+#define GRUB_PE32_SCN_LNK_NRELOC_OVFL 0x01000000 -+#define GRUB_PE32_SCN_MEM_DISCARDABLE 0x02000000 -+#define GRUB_PE32_SCN_MEM_NOT_CACHED 0x04000000 -+#define GRUB_PE32_SCN_MEM_NOT_PAGED 0x08000000 -+#define GRUB_PE32_SCN_MEM_SHARED 0x10000000 -+#define GRUB_PE32_SCN_MEM_EXECUTE 0x20000000 -+#define GRUB_PE32_SCN_MEM_READ 0x40000000 -+#define GRUB_PE32_SCN_MEM_WRITE 0x80000000 -+ -+ -+ - #define GRUB_PE32_SIGNATURE_SIZE 4 - - struct grub_pe32_header -@@ -274,6 +302,20 @@ struct grub_pe32_header - #endif - }; - -+struct grub_pe32_header_32 -+{ -+ char signature[GRUB_PE32_SIGNATURE_SIZE]; -+ struct grub_pe32_coff_header coff_header; -+ struct grub_pe32_optional_header optional_header; -+}; -+ -+struct grub_pe32_header_64 -+{ -+ char signature[GRUB_PE32_SIGNATURE_SIZE]; -+ struct grub_pe32_coff_header coff_header; -+ struct grub_pe64_optional_header optional_header; -+}; -+ - struct grub_pe32_fixup_block - { - grub_uint32_t page_rva; diff --git a/0163-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch b/0007-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch similarity index 76% rename from 0163-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch rename to 0007-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch index 6e46db010f1c517e287009efbc1147102de1879b..4760504c3ec01f7613a9d9a54dc5c6bf31160947 100644 --- a/0163-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch +++ b/0007-dl-provide-a-fake-grub_dl_set_persistent-for-the-emu.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 4773f90bdefb72dde55fb5961f7f37b467307016 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Thu, 30 Jul 2020 00:13:21 +1000 -Subject: [PATCH] dl: provide a fake grub_dl_set_persistent for the emu target +Subject: [PATCH 07/23] dl: provide a fake grub_dl_set_persistent for the emu + target Trying to start grub-emu with a module that calls grub_dl_set_persistent will crash because grub-emu fakes modules and passes NULL to the module @@ -15,11 +16,9 @@ Signed-off-by: Daniel Axtens include/grub/dl.h | 11 +++++++++++ 1 file changed, 11 insertions(+) -diff --git a/include/grub/dl.h b/include/grub/dl.h -index 2f76e6b0437..20d870f2a47 100644 --- a/include/grub/dl.h +++ b/include/grub/dl.h -@@ -245,11 +245,22 @@ grub_dl_get (const char *name) +@@ -242,11 +242,22 @@ return 0; } diff --git a/0080-efinet-Setting-network-from-UEFI-device-path.patch b/0007-efinet-Setting-network-from-UEFI-device-path.patch similarity index 83% rename from 0080-efinet-Setting-network-from-UEFI-device-path.patch rename to 0007-efinet-Setting-network-from-UEFI-device-path.patch index 11b2a724d656dc1c48f639f75e85239308c835b0..df16c70a23fa0ac3077008eac9bf77f64d237352 100644 --- a/0080-efinet-Setting-network-from-UEFI-device-path.patch +++ b/0007-efinet-Setting-network-from-UEFI-device-path.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 369df8e3006000a4acacc674f5882d8729781811 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Sun, 10 Jul 2016 23:46:31 +0800 -Subject: [PATCH] efinet: Setting network from UEFI device path +Subject: [PATCH 7/8] efinet: Setting network from UEFI device path The PXE Base Code protocol used to obtain cached PXE DHCPACK packet is no longer provided for HTTP Boot. Instead, we have to get the HTTP boot @@ -27,23 +27,21 @@ the same way it used to be. Signed-off-by: Michael Chang Signed-off-by: Ken Lin --- - grub-core/net/drivers/efi/efinet.c | 284 +++++++++++++++++++++++++++++++++++-- + grub-core/net/drivers/efi/efinet.c | 268 +++++++++++++++++++++++++++++++++++-- include/grub/efi/api.h | 11 ++ - 2 files changed, 280 insertions(+), 15 deletions(-) + 2 files changed, 270 insertions(+), 9 deletions(-) -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 014e5bf9802..8171ecaa5e4 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c -@@ -26,6 +26,7 @@ +@@ -23,6 +23,7 @@ + #include + #include #include - #include - #include +#include GRUB_MOD_LICENSE ("GPLv3+"); -@@ -331,6 +332,227 @@ grub_efinet_findcards (void) +@@ -341,6 +342,221 @@ grub_free (handles); } @@ -57,9 +55,6 @@ index 014e5bf9802..8171ecaa5e4 100644 + grub_err_t err; + + ddp = grub_efi_duplicate_device_path (dp); -+ if (!ddp) -+ return NULL; -+ + ldp = grub_efi_find_last_device_path (ddp); + + if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE @@ -95,10 +90,7 @@ index 014e5bf9802..8171ecaa5e4 100644 + + nb = grub_netbuff_alloc (512); + if (!nb) -+ { -+ grub_free (ddp); -+ return NULL; -+ } ++ return NULL; + + if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE) + { @@ -271,21 +263,20 @@ index 014e5bf9802..8171ecaa5e4 100644 static void grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, char **path) -@@ -346,7 +568,11 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - { +@@ -361,6 +577,11 @@ grub_efi_device_path_t *cdp; struct grub_efi_pxe *pxe; -- struct grub_efi_pxe_mode *pxe_mode; -+ struct grub_efi_pxe_mode *pxe_mode = NULL; + struct grub_efi_pxe_mode *pxe_mode; + grub_uint8_t *packet_buf; + grub_size_t packet_bufsz ; + int ipv6; + struct grub_net_buff *nb = NULL; - ++ if (card->driver != &efidriver) continue; -@@ -370,11 +596,21 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - */ + cdp = grub_efi_get_device_path (card->efi_handle); +@@ -380,11 +601,21 @@ + ldp = grub_efi_find_last_device_path (dp); if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE - && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) @@ -307,12 +298,13 @@ index 014e5bf9802..8171ecaa5e4 100644 dup_ldp = grub_efi_find_last_device_path (dup_dp); dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE; dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -@@ -387,23 +623,37 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - +@@ -396,16 +627,31 @@ + } pxe = grub_efi_open_protocol (hnd, &pxe_io_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (! pxe) - continue; +- pxe_mode = pxe->mode; + if (!pxe) + { + nb = grub_efinet_create_dhcp_ack_from_device_path (dp, &ipv6); @@ -332,21 +324,9 @@ index 014e5bf9802..8171ecaa5e4 100644 + ipv6 = pxe_mode->using_ipv6; + } -- pxe_mode = pxe->mode; - if (pxe_mode->using_ipv6) + if (ipv6) { - grub_dprintf ("efinet", "using ipv6 and dhcpv6\n"); -- grub_dprintf ("efinet", "dhcp_ack_received: %s%s\n", -- pxe_mode->dhcp_ack_received ? "yes" : "no", -- pxe_mode->dhcp_ack_received ? "" : " cannot continue"); -- if (!pxe_mode->dhcp_ack_received) -- continue; -+ if (pxe_mode) -+ grub_dprintf ("efinet", "dhcp_ack_received: %s%s\n", -+ pxe_mode->dhcp_ack_received ? "yes" : "no", -+ pxe_mode->dhcp_ack_received ? "" : " cannot continue"); - grub_net_configure_by_dhcpv6_reply (card->name, card, 0, (struct grub_net_dhcp6_packet *) - &pxe_mode->dhcp_ack, @@ -356,16 +336,20 @@ index 014e5bf9802..8171ecaa5e4 100644 1, device, path); if (grub_errno) grub_print_error (); -@@ -417,11 +667,15 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - grub_dprintf ("efinet", "using ipv4 and dhcp\n"); - grub_net_configure_by_dhcp_ack (card->name, card, 0, - (struct grub_net_bootp_packet *) -- &pxe_mode->dhcp_ack, -- sizeof (pxe_mode->dhcp_ack), -+ packet_buf, -+ packet_bufsz, - 1, device, path); - grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); +@@ -414,8 +660,8 @@ + { + inter = grub_net_configure_by_dhcp_ack (card->name, card, 0, + (struct grub_net_bootp_packet *) +- &pxe_mode->dhcp_ack, +- sizeof (pxe_mode->dhcp_ack), ++ packet_buf, ++ packet_bufsz, + 1, device, path); + + if (inter != NULL) +@@ -441,6 +687,10 @@ + } + } } + + if (nb) @@ -374,11 +358,9 @@ index 014e5bf9802..8171ecaa5e4 100644 return; } } -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 91ab528e4d0..4a51667adb1 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h -@@ -864,6 +864,8 @@ struct grub_efi_ipv4_device_path +@@ -876,6 +876,8 @@ grub_efi_uint16_t remote_port; grub_efi_uint16_t protocol; grub_efi_uint8_t static_ip_address; @@ -387,9 +369,9 @@ index 91ab528e4d0..4a51667adb1 100644 } GRUB_PACKED; typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t; -@@ -918,6 +920,15 @@ struct grub_efi_sata_device_path +@@ -939,6 +941,15 @@ } GRUB_PACKED; - typedef struct grub_efi_sata_device_path grub_efi_sata_device_path_t; + typedef struct grub_efi_vlan_device_path grub_efi_vlan_device_path_t; +#define GRUB_EFI_URI_DEVICE_PATH_SUBTYPE 24 + diff --git a/0107-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch b/0007-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch similarity index 79% rename from 0107-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch rename to 0007-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch index 4ad0696be43718b6e04fb3a4351e9807062020a7..21a1173fe102b0c93eed11ac27e87b3ad69e8ebb 100644 --- a/0107-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch +++ b/0007-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch @@ -1,17 +1,17 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 2a84f1a50c6f8770808fd4ec590eb8cff4228aed Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Wed, 12 Sep 2018 16:03:55 -0400 -Subject: [PATCH] x86-efi: Make our own allocator for kernel stuff +Subject: [PATCH 07/11] x86-efi: Make our own allocator for kernel stuff This helps enable allocations above 4GB. Signed-off-by: Peter Jones --- - grub-core/loader/i386/efi/linux.c | 167 +++++++++++++++++++++----------------- - 1 file changed, 94 insertions(+), 73 deletions(-) + grub-core/loader/i386/efi/linux.c | 155 ++++++++++++++++++------------ + 1 file changed, 94 insertions(+), 61 deletions(-) diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 5f48fa55619..3e4f7ef39f4 100644 +index 096a52eb5..d284db5d1 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -47,6 +47,65 @@ static char *linux_cmdline; @@ -55,8 +55,8 @@ index 5f48fa55619..3e4f7ef39f4 100644 + continue; + + pages = BYTES_TO_PAGES(size); -+ grub_dprintf ("linux", "Trying to allocate %lu pages from %p\n", -+ pages, (void *)max); ++ grub_dprintf ("linux", "Trying to allocate %" PRIuGRUB_SIZE" pages from %p\n", ++ pages, (void *)(grub_addr_t)max); + + prev_max = max; + addr = grub_efi_allocate_pages_real (max, pages, @@ -80,23 +80,18 @@ index 5f48fa55619..3e4f7ef39f4 100644 static grub_err_t grub_linuxefi_boot (void) { -@@ -62,19 +121,12 @@ grub_linuxefi_unload (void) +@@ -62,14 +121,12 @@ grub_linuxefi_unload (void) { grub_dl_unref (my_mod); loaded = 0; - if (initrd_mem) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, -- BYTES_TO_PAGES(params->ramdisk_size)); +- grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, BYTES_TO_PAGES(params->ramdisk_size)); - if (linux_cmdline) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) -- linux_cmdline, -- BYTES_TO_PAGES(params->cmdline_size + 1)); +- grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)linux_cmdline, BYTES_TO_PAGES(params->cmdline_size + 1)); - if (kernel_mem) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, -- BYTES_TO_PAGES(kernel_size)); +- grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); - if (params) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params, -- BYTES_TO_PAGES(16384)); +- grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)params, BYTES_TO_PAGES(16384)); + + kernel_free(initrd_mem, params->ramdisk_size); + kernel_free(linux_cmdline, params->cmdline_size + 1); @@ -106,7 +101,7 @@ index 5f48fa55619..3e4f7ef39f4 100644 return GRUB_ERR_NONE; } -@@ -150,19 +202,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), +@@ -146,17 +203,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), size += ALIGN_UP (grub_file_size (files[i]), 4); } @@ -118,8 +113,6 @@ index 5f48fa55619..3e4f7ef39f4 100644 - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); - goto fail; - } -- -- grub_dprintf ("linux", "initrd_mem = %lx\n", (unsigned long) initrd_mem); + initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); + if (initrd_mem == NULL) + goto fail; @@ -131,7 +124,7 @@ index 5f48fa55619..3e4f7ef39f4 100644 ptr = initrd_mem; -@@ -221,7 +267,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -214,7 +267,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), filelen = grub_file_size (file); kernel = grub_malloc(filelen); @@ -139,7 +132,7 @@ index 5f48fa55619..3e4f7ef39f4 100644 if (!kernel) { grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); -@@ -274,7 +319,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -258,7 +310,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), goto fail; } @@ -148,7 +141,7 @@ index 5f48fa55619..3e4f7ef39f4 100644 grub_dprintf ("linux", "checking lh->xloadflags\n"); if (!(lh->xloadflags & LINUX_XLF_KERNEL_64)) { -@@ -293,17 +338,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -277,17 +329,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), } #endif @@ -168,7 +161,7 @@ index 5f48fa55619..3e4f7ef39f4 100644 grub_dprintf ("linux", "params = %p\n", params); grub_memset (params, 0, sizeof(*params)); -@@ -322,19 +359,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -306,16 +350,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_dprintf ("linux", "new lh is at %p\n", lh); grub_dprintf ("linux", "setting up cmdline\n"); @@ -183,16 +176,13 @@ index 5f48fa55619..3e4f7ef39f4 100644 - grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); - goto fail; - } -- -- grub_dprintf ("linux", "linux_cmdline = %lx\n", -- (unsigned long)linux_cmdline); + goto fail; + grub_dprintf ("linux", "linux_cmdline = %p\n", linux_cmdline); grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); - grub_create_loader_cmdline (argc, argv, -@@ -343,27 +371,24 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - GRUB_VERIFY_KERNEL_CMDLINE); + err = grub_create_loader_cmdline (argc, argv, +@@ -326,27 +364,24 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + goto fail; grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline); - grub_dprintf ("linux", "setting lh->cmd_line_ptr\n"); @@ -230,7 +220,7 @@ index 5f48fa55619..3e4f7ef39f4 100644 grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem); grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); -@@ -398,18 +423,14 @@ fail: +@@ -382,16 +417,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), loaded = 0; } @@ -238,21 +228,22 @@ index 5f48fa55619..3e4f7ef39f4 100644 - grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t) - linux_cmdline, - BYTES_TO_PAGES(lh->cmdline_size + 1)); +- +- if (kernel_mem && !loaded) +- grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); + if (!loaded) + { + if (lh) + kernel_free (linux_cmdline, lh->cmdline_size + 1); -- if (kernel_mem && !loaded) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, -- BYTES_TO_PAGES(kernel_size)); -- - if (params && !loaded) -- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)params, -- BYTES_TO_PAGES(16384)); +- grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)params, BYTES_TO_PAGES(16384)); + kernel_free (kernel_mem, kernel_size); + kernel_free (params, sizeof(*params)); + } return grub_errno; } +-- +2.31.1 + diff --git a/0008-Make-any-of-the-loaders-that-link-in-efi-mode-honor-.patch b/0008-Make-any-of-the-loaders-that-link-in-efi-mode-honor-.patch deleted file mode 100644 index 030c71c9599a53ceb786186ee5ebe932649ed837..0000000000000000000000000000000000000000 --- a/0008-Make-any-of-the-loaders-that-link-in-efi-mode-honor-.patch +++ /dev/null @@ -1,390 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 6 Oct 2015 16:09:25 -0400 -Subject: [PATCH] Make any of the loaders that link in efi mode honor secure - boot. - -And in this case "honor" means "even if somebody does link this in, they -won't register commands if SB is enabled." - -Signed-off-by: Peter Jones ---- - grub-core/commands/iorw.c | 7 +++++++ - grub-core/commands/memrw.c | 7 +++++++ - grub-core/kern/dl.c | 3 ++- - grub-core/kern/efi/efi.c | 34 ---------------------------------- - grub-core/loader/efi/appleloader.c | 7 +++++++ - grub-core/loader/efi/chainloader.c | 1 + - grub-core/loader/i386/bsd.c | 7 +++++++ - grub-core/loader/i386/linux.c | 7 +++++++ - grub-core/loader/i386/pc/linux.c | 7 +++++++ - grub-core/loader/multiboot.c | 7 +++++++ - grub-core/loader/xnu.c | 7 +++++++ - include/grub/efi/efi.h | 1 - - include/grub/ia64/linux.h | 0 - include/grub/mips/linux.h | 0 - include/grub/powerpc/linux.h | 0 - include/grub/sparc64/linux.h | 0 - 16 files changed, 59 insertions(+), 36 deletions(-) - create mode 100644 include/grub/ia64/linux.h - create mode 100644 include/grub/mips/linux.h - create mode 100644 include/grub/powerpc/linux.h - create mode 100644 include/grub/sparc64/linux.h - -diff --git a/grub-core/commands/iorw.c b/grub-core/commands/iorw.c -index 584baec8f91..7b2999b14b5 100644 ---- a/grub-core/commands/iorw.c -+++ b/grub-core/commands/iorw.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -119,6 +120,9 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv) - - GRUB_MOD_INIT(memrw) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd_read_byte = - grub_register_extcmd ("inb", grub_cmd_read, 0, - N_("PORT"), N_("Read 8-bit value from PORT."), -@@ -147,6 +151,9 @@ GRUB_MOD_INIT(memrw) - - GRUB_MOD_FINI(memrw) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_extcmd (cmd_read_byte); - grub_unregister_extcmd (cmd_read_word); - grub_unregister_extcmd (cmd_read_dword); -diff --git a/grub-core/commands/memrw.c b/grub-core/commands/memrw.c -index d401a6db0ef..39cf3a06dbd 100644 ---- a/grub-core/commands/memrw.c -+++ b/grub-core/commands/memrw.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -121,6 +122,9 @@ grub_cmd_write (grub_command_t cmd, int argc, char **argv) - - GRUB_MOD_INIT(memrw) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd_read_byte = - grub_register_extcmd ("read_byte", grub_cmd_read, 0, - N_("ADDR"), N_("Read 8-bit value from ADDR."), -@@ -149,6 +153,9 @@ GRUB_MOD_INIT(memrw) - - GRUB_MOD_FINI(memrw) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_extcmd (cmd_read_byte); - grub_unregister_extcmd (cmd_read_word); - grub_unregister_extcmd (cmd_read_dword); -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index b7149370950..7afb9e6f724 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - - /* Platforms where modules are in a readonly area of memory. */ - #if defined(GRUB_MACHINE_QEMU) -@@ -704,7 +705,7 @@ grub_dl_load_file (const char *filename) - grub_dl_t mod = 0; - - #ifdef GRUB_MACHINE_EFI -- if (grub_efi_secure_boot ()) -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) - { - #if 0 - /* This is an error, but grub2-mkconfig still generates a pile of -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 4a2259aa1c7..8cff7be0289 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -286,40 +286,6 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, - return grub_efi_get_variable_with_attributes (var, guid, datasize_out, data_out, NULL); - } - --grub_efi_boolean_t --grub_efi_secure_boot (void) --{ -- grub_efi_guid_t efi_var_guid = GRUB_EFI_GLOBAL_VARIABLE_GUID; -- grub_size_t datasize; -- char *secure_boot = NULL; -- char *setup_mode = NULL; -- grub_efi_boolean_t ret = 0; -- -- secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize); -- if (datasize != 1 || !secure_boot) -- { -- grub_dprintf ("secureboot", "No SecureBoot variable\n"); -- goto out; -- } -- grub_dprintf ("secureboot", "SecureBoot: %d\n", *secure_boot); -- -- setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize); -- if (datasize != 1 || !setup_mode) -- { -- grub_dprintf ("secureboot", "No SetupMode variable\n"); -- goto out; -- } -- grub_dprintf ("secureboot", "SetupMode: %d\n", *setup_mode); -- -- if (*secure_boot && !*setup_mode) -- ret = 1; -- -- out: -- grub_free (secure_boot); -- grub_free (setup_mode); -- return ret; --} -- - #pragma GCC diagnostic ignored "-Wcast-align" - - /* Search the mods section from the PE32/PE32+ image. This code uses -diff --git a/grub-core/loader/efi/appleloader.c b/grub-core/loader/efi/appleloader.c -index 74888c463ba..585f2b57385 100644 ---- a/grub-core/loader/efi/appleloader.c -+++ b/grub-core/loader/efi/appleloader.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -227,6 +228,9 @@ static grub_command_t cmd; - - GRUB_MOD_INIT(appleloader) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd = grub_register_command ("appleloader", grub_cmd_appleloader, - N_("[OPTS]"), - /* TRANSLATORS: This command is used on EFI to -@@ -238,5 +242,8 @@ GRUB_MOD_INIT(appleloader) - - GRUB_MOD_FINI(appleloader) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_command (cmd); - } -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index e6a8d4ad0e9..07c4937898d 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c -index 5f3290ce17b..54befc26626 100644 ---- a/grub-core/loader/i386/bsd.c -+++ b/grub-core/loader/i386/bsd.c -@@ -40,6 +40,7 @@ - #ifdef GRUB_MACHINE_PCBIOS - #include - #endif -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -2137,6 +2138,9 @@ static grub_command_t cmd_netbsd_module_elf, cmd_openbsd_ramdisk; - - GRUB_MOD_INIT (bsd) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - /* Net and OpenBSD kernels are often compressed. */ - grub_dl_load ("gzio"); - -@@ -2176,6 +2180,9 @@ GRUB_MOD_INIT (bsd) - - GRUB_MOD_FINI (bsd) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_extcmd (cmd_freebsd); - grub_unregister_extcmd (cmd_openbsd); - grub_unregister_extcmd (cmd_netbsd); -diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c -index dccf3bb3005..4aeb0e4b9a6 100644 ---- a/grub-core/loader/i386/linux.c -+++ b/grub-core/loader/i386/linux.c -@@ -37,6 +37,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -1138,6 +1139,9 @@ static grub_command_t cmd_linux, cmd_initrd; - - GRUB_MOD_INIT(linux) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd_linux = grub_register_command ("linux", grub_cmd_linux, - 0, N_("Load Linux.")); - cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, -@@ -1147,6 +1151,9 @@ GRUB_MOD_INIT(linux) - - GRUB_MOD_FINI(linux) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_command (cmd_linux); - grub_unregister_command (cmd_initrd); - } -diff --git a/grub-core/loader/i386/pc/linux.c b/grub-core/loader/i386/pc/linux.c -index 4b1750e360e..e3fa1221e81 100644 ---- a/grub-core/loader/i386/pc/linux.c -+++ b/grub-core/loader/i386/pc/linux.c -@@ -36,6 +36,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -487,6 +488,9 @@ static grub_command_t cmd_linux, cmd_linux16, cmd_initrd, cmd_initrd16; - - GRUB_MOD_INIT(linux16) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd_linux = - grub_register_command ("linux", grub_cmd_linux, - 0, N_("Load Linux.")); -@@ -504,6 +508,9 @@ GRUB_MOD_INIT(linux16) - - GRUB_MOD_FINI(linux16) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_command (cmd_linux); - grub_unregister_command (cmd_linux16); - grub_unregister_command (cmd_initrd); -diff --git a/grub-core/loader/multiboot.c b/grub-core/loader/multiboot.c -index facb13f3d36..47e481f4576 100644 ---- a/grub-core/loader/multiboot.c -+++ b/grub-core/loader/multiboot.c -@@ -50,6 +50,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -444,6 +445,9 @@ static grub_command_t cmd_multiboot, cmd_module; - - GRUB_MOD_INIT(multiboot) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd_multiboot = - #ifdef GRUB_USE_MULTIBOOT2 - grub_register_command ("multiboot2", grub_cmd_multiboot, -@@ -464,6 +468,9 @@ GRUB_MOD_INIT(multiboot) - - GRUB_MOD_FINI(multiboot) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - grub_unregister_command (cmd_multiboot); - grub_unregister_command (cmd_module); - } -diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c -index 1c0cf6a430a..baa54e652ab 100644 ---- a/grub-core/loader/xnu.c -+++ b/grub-core/loader/xnu.c -@@ -35,6 +35,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -1497,6 +1498,9 @@ static grub_extcmd_t cmd_splash; - - GRUB_MOD_INIT(xnu) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - cmd_kernel = grub_register_command ("xnu_kernel", grub_cmd_xnu_kernel, 0, - N_("Load XNU image.")); - cmd_kernel64 = grub_register_command ("xnu_kernel64", grub_cmd_xnu_kernel64, -@@ -1540,6 +1544,9 @@ GRUB_MOD_INIT(xnu) - - GRUB_MOD_FINI(xnu) - { -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) -+ return; -+ - #ifndef GRUB_MACHINE_EMU - grub_unregister_command (cmd_resume); - #endif -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 6295df85f3f..585fa6662b6 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -91,7 +91,6 @@ EXPORT_FUNC (grub_efi_set_variable) (const char *var, - const grub_efi_guid_t *guid, - void *data, - grub_size_t datasize); --grub_efi_boolean_t EXPORT_FUNC (grub_efi_secure_boot) (void); - int - EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1, - const grub_efi_device_path_t *dp2); -diff --git a/include/grub/ia64/linux.h b/include/grub/ia64/linux.h -new file mode 100644 -index 00000000000..e69de29bb2d -diff --git a/include/grub/mips/linux.h b/include/grub/mips/linux.h -new file mode 100644 -index 00000000000..e69de29bb2d -diff --git a/include/grub/powerpc/linux.h b/include/grub/powerpc/linux.h -new file mode 100644 -index 00000000000..e69de29bb2d -diff --git a/include/grub/sparc64/linux.h b/include/grub/sparc64/linux.h -new file mode 100644 -index 00000000000..e69de29bb2d diff --git a/0081-efinet-Setting-DNS-server-from-UEFI-protocol.patch b/0008-efinet-Setting-DNS-server-from-UEFI-protocol.patch similarity index 76% rename from 0081-efinet-Setting-DNS-server-from-UEFI-protocol.patch rename to 0008-efinet-Setting-DNS-server-from-UEFI-protocol.patch index 1460c8a6f8617c05976451fbe99325b136a33de7..1151396e176bc8c17d56dc777ec650659059a25a 100644 --- a/0081-efinet-Setting-DNS-server-from-UEFI-protocol.patch +++ b/0008-efinet-Setting-DNS-server-from-UEFI-protocol.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 0c7ae6d7527d08e54a6eeebddb6c5c697c4b37d2 Mon Sep 17 00:00:00 2001 From: Michael Chang Date: Thu, 14 Jul 2016 17:48:45 +0800 -Subject: [PATCH] efinet: Setting DNS server from UEFI protocol +Subject: [PATCH 8/8] efinet: Setting DNS server from UEFI protocol In the URI device path node, any name rahter than address can be used for looking up the resources so that DNS service become needed to get answer of the @@ -29,23 +29,21 @@ Signed-off-by: Michael Chang Signed-off-by: Ken Lin --- grub-core/net/drivers/efi/efinet.c | 163 +++++++++++++++++++++++++++++++++++++ - include/grub/efi/api.h | 75 +++++++++++++++++ - 2 files changed, 238 insertions(+) + include/grub/efi/api.h | 76 +++++++++++++++++ + 2 files changed, 239 insertions(+) -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 8171ecaa5e4..715a6168d77 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c -@@ -33,6 +33,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); +@@ -30,6 +30,8 @@ /* GUID. */ - static grub_efi_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID; - static grub_efi_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID; -+static grub_efi_guid_t ip4_config_guid = GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID; -+static grub_efi_guid_t ip6_config_guid = GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID; + static grub_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID; + static grub_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID; ++static grub_guid_t ip4_config_guid = GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID; ++static grub_guid_t ip6_config_guid = GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID; static grub_err_t send_card_buffer (struct grub_net_card *dev, -@@ -332,6 +334,125 @@ grub_efinet_findcards (void) +@@ -342,6 +344,125 @@ grub_free (handles); } @@ -56,7 +54,7 @@ index 8171ecaa5e4..715a6168d77 100644 + grub_efi_handle_t handle; + grub_efi_status_t status; + -+ status = efi_call_3 (grub_efi_system_table->boot_services->locate_device_path, ++ status = grub_efi_system_table->boot_services->locate_device_path ( + protocol, &device_path, &handle); + + if (status != GRUB_EFI_SUCCESS) @@ -92,7 +90,7 @@ index 8171ecaa5e4..715a6168d77 100644 + if (!addrs) + return 0; + -+ status = efi_call_4 (conf->get_data, conf, ++ status = conf->get_data (conf, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, + &data_size, addrs); + @@ -103,7 +101,7 @@ index 8171ecaa5e4..715a6168d77 100644 + if (!addrs) + return 0; + -+ status = efi_call_4 (conf->get_data, conf, ++ status = conf->get_data (conf, + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER, + &data_size, addrs); + } @@ -142,7 +140,7 @@ index 8171ecaa5e4..715a6168d77 100644 + if (!addrs) + return 0; + -+ status = efi_call_4 (conf->get_data, conf, ++ status = conf->get_data (conf, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, + &data_size, addrs); + @@ -153,7 +151,7 @@ index 8171ecaa5e4..715a6168d77 100644 + if (!addrs) + return 0; + -+ status = efi_call_4 (conf->get_data, conf, ++ status = conf->get_data (conf, + GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER, + &data_size, addrs); + } @@ -171,7 +169,7 @@ index 8171ecaa5e4..715a6168d77 100644 static struct grub_net_buff * grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *use_ipv6) { -@@ -390,6 +511,8 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u +@@ -394,6 +515,8 @@ grub_efi_ipv4_device_path_t *ipv4 = (grub_efi_ipv4_device_path_t *) ldp; struct grub_net_bootp_packet *bp; grub_uint8_t *ptr; @@ -180,7 +178,7 @@ index 8171ecaa5e4..715a6168d77 100644 bp = (struct grub_net_bootp_packet *) nb->tail; err = grub_netbuff_put (nb, sizeof (*bp) + 4); -@@ -451,6 +574,25 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u +@@ -455,6 +578,25 @@ *ptr++ = sizeof ("HTTPClient") - 1; grub_memcpy (ptr, "HTTPClient", sizeof ("HTTPClient") - 1); @@ -206,7 +204,7 @@ index 8171ecaa5e4..715a6168d77 100644 ptr = nb->tail; err = grub_netbuff_put (nb, 1); if (err) -@@ -483,6 +625,8 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u +@@ -487,6 +629,8 @@ struct grub_net_dhcp6_option *opt; struct grub_net_dhcp6_option_iana *iana; struct grub_net_dhcp6_option_iaaddr *iaaddr; @@ -215,7 +213,7 @@ index 8171ecaa5e4..715a6168d77 100644 d6p = (struct grub_net_dhcp6_packet *)nb->tail; err = grub_netbuff_put (nb, sizeof(*d6p)); -@@ -546,6 +690,25 @@ grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *u +@@ -550,6 +694,25 @@ opt->len = grub_cpu_to_be16 (uri_len); grub_memcpy (opt->data, uri_dp->uri, uri_len); @@ -241,15 +239,12 @@ index 8171ecaa5e4..715a6168d77 100644 *use_ipv6 = 1; } -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 4a51667adb1..0b490195ad9 100644 --- a/include/grub/efi/api.h +++ b/include/grub/efi/api.h -@@ -352,6 +352,15 @@ - #define GRUB_EFI_RNG_PROTOCOL_GUID \ - { 0x3152bca5, 0xeade, 0x433d, \ - { 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \ -+ +@@ -379,6 +379,16 @@ + {0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } \ + } + +#define GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID \ + { 0x5b446ed1, 0xe30b, 0x4faa, \ + { 0x87, 0x1a, 0x36, 0x54, 0xec, 0xa3, 0x60, 0x80 } \ @@ -258,12 +253,14 @@ index 4a51667adb1..0b490195ad9 100644 +#define GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID \ + { 0x937fe521, 0x95ae, 0x4d1a, \ + { 0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \ - } - ++ } ++ struct grub_efi_sal_system_table -@@ -1883,6 +1892,72 @@ struct grub_efi_rng_protocol - }; - typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t; + { + grub_uint32_t signature; +@@ -1879,4 +1889,70 @@ + } GRUB_PACKED; + typedef struct initrd_media_device_path initrd_media_device_path_t; +enum grub_efi_ip4_config2_data_type { + GRUB_EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO, @@ -277,21 +274,21 @@ index 4a51667adb1..0b490195ad9 100644 + +struct grub_efi_ip4_config2_protocol +{ -+ grub_efi_status_t (*set_data) (struct grub_efi_ip4_config2_protocol *this, ++ grub_efi_status_t (__grub_efi_api *set_data) (struct grub_efi_ip4_config2_protocol *this, + grub_efi_ip4_config2_data_type_t data_type, + grub_efi_uintn_t data_size, + void *data); + -+ grub_efi_status_t (*get_data) (struct grub_efi_ip4_config2_protocol *this, ++ grub_efi_status_t (__grub_efi_api *get_data) (struct grub_efi_ip4_config2_protocol *this, + grub_efi_ip4_config2_data_type_t data_type, + grub_efi_uintn_t *data_size, + void *data); + -+ grub_efi_status_t (*register_data_notify) (struct grub_efi_ip4_config2_protocol *this, ++ grub_efi_status_t (__grub_efi_api *register_data_notify) (struct grub_efi_ip4_config2_protocol *this, + grub_efi_ip4_config2_data_type_t data_type, + grub_efi_event_t event); + -+ grub_efi_status_t (*unregister_datanotify) (struct grub_efi_ip4_config2_protocol *this, ++ grub_efi_status_t (__grub_efi_api *unregister_datanotify) (struct grub_efi_ip4_config2_protocol *this, + grub_efi_ip4_config2_data_type_t data_type, + grub_efi_event_t event); +}; @@ -311,26 +308,24 @@ index 4a51667adb1..0b490195ad9 100644 + +struct grub_efi_ip6_config_protocol +{ -+ grub_efi_status_t (*set_data) (struct grub_efi_ip6_config_protocol *this, ++ grub_efi_status_t (__grub_efi_api *set_data) (struct grub_efi_ip6_config_protocol *this, + grub_efi_ip6_config_data_type_t data_type, + grub_efi_uintn_t data_size, + void *data); + -+ grub_efi_status_t (*get_data) (struct grub_efi_ip6_config_protocol *this, ++ grub_efi_status_t (__grub_efi_api *get_data) (struct grub_efi_ip6_config_protocol *this, + grub_efi_ip6_config_data_type_t data_type, + grub_efi_uintn_t *data_size, + void *data); + -+ grub_efi_status_t (*register_data_notify) (struct grub_efi_ip6_config_protocol *this, ++ grub_efi_status_t (__grub_efi_api *register_data_notify) (struct grub_efi_ip6_config_protocol *this, + grub_efi_ip6_config_data_type_t data_type, + grub_efi_event_t event); + -+ grub_efi_status_t (*unregister_datanotify) (struct grub_efi_ip6_config_protocol *this, ++ grub_efi_status_t (__grub_efi_api *unregister_datanotify) (struct grub_efi_ip6_config_protocol *this, + grub_efi_ip6_config_data_type_t data_type, + grub_efi_event_t event); +}; +typedef struct grub_efi_ip6_config_protocol grub_efi_ip6_config_protocol_t; + - #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ - || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \ - || defined(__riscv) + #endif /* ! GRUB_EFI_API_HEADER */ diff --git a/0008-linuxefi-Use-common-grub_initrd_load.patch b/0008-linuxefi-Use-common-grub_initrd_load.patch new file mode 100644 index 0000000000000000000000000000000000000000..72ba70c8d0e21bd64e9c1200d8638cae2e1144d1 --- /dev/null +++ b/0008-linuxefi-Use-common-grub_initrd_load.patch @@ -0,0 +1,151 @@ +From adf486860fe0d395579be8b01d4fda8b93377768 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Wed, 8 Jun 2022 16:04:12 +0800 +Subject: [PATCH 08/10] linuxefi: Use common grub_initrd_load + +By using the common initrd loading routine factored out allows to share between +features like concatenating initramfs component. + +For eg. + + initrdefi /initrd-5.16.15-1-default newc:grub.cfg:/grub2/grub.cfg + +The file /grub2/grub.cfg read off from root disk will be available to use as +/grub.cfg in the target initramfs loaded by grub. + +Signed-off-by: Michael Chang +--- + grub-core/loader/i386/efi/linux.c | 87 ++++--------------------------- + 1 file changed, 10 insertions(+), 77 deletions(-) + +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -146,44 +147,6 @@ + return GRUB_ERR_NONE; + } + +-#define BOUNCE_BUFFER_MAX 0x1000000ull +- +-static grub_ssize_t +-read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len) +-{ +- grub_ssize_t bufpos = 0; +- static grub_size_t bbufsz = 0; +- static char *bbuf = NULL; +- +- if (bbufsz == 0) +- bbufsz = MIN(BOUNCE_BUFFER_MAX, len); +- +- while (!bbuf && bbufsz) +- { +- bbuf = grub_malloc(bbufsz); +- if (!bbuf) +- bbufsz >>= 1; +- } +- if (!bbuf) +- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate bounce buffer")); +- +- while (bufpos < (long long)len) +- { +- grub_ssize_t sz; +- +- sz = grub_file_read (file, bbuf, MIN(bbufsz, len - bufpos)); +- if (sz < 0) +- return sz; +- if (sz == 0) +- break; +- +- grub_memcpy(bufp + bufpos, bbuf, sz); +- bufpos += sz; +- } +- +- return bufpos; +-} +- + #define LOW_U32(val) ((grub_uint32_t)(((grub_addr_t)(val)) & 0xffffffffull)) + #define HIGH_U32(val) ((grub_uint32_t)(((grub_addr_t)(val) >> 32) & 0xffffffffull)) + +@@ -191,10 +154,8 @@ + grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { +- grub_file_t *files = 0; +- int i, nfiles = 0; ++ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; + grub_size_t size = 0; +- grub_uint8_t *ptr; + + if (argc == 0) + { +@@ -208,24 +169,10 @@ + goto fail; + } + +- files = grub_calloc (argc, sizeof (files[0])); +- if (!files) ++ if (grub_initrd_init (argc, argv, &initrd_ctx)) + goto fail; + +- for (i = 0; i < argc; i++) +- { +- files[i] = grub_file_open (argv[i], GRUB_FILE_TYPE_LINUX_INITRD +- | GRUB_FILE_TYPE_NO_DECOMPRESS); +- if (! files[i]) +- goto fail; +- nfiles++; +- if (grub_add (size, ALIGN_UP (grub_file_size (files[i]), 4), &size)) +- { +- grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); +- goto fail; +- } +- } +- ++ size = grub_get_initrd_size (&initrd_ctx); + initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); + if (initrd_mem == NULL) + goto fail; +@@ -238,30 +185,16 @@ + params->ext_ramdisk_image = HIGH_U32(initrd_mem); + #endif + +- ptr = initrd_mem; +- +- for (i = 0; i < nfiles; i++) +- { +- grub_ssize_t cursize = grub_file_size (files[i]); +- if (read (files[i], ptr, cursize) != cursize) +- { +- if (!grub_errno) +- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), +- argv[i]); +- goto fail; +- } +- ptr += cursize; +- grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); +- ptr += ALIGN_UP_OVERHEAD (cursize, 4); +- } ++ /* FIXME: Use bounce buffers as many UEFI machines apparently can't DMA ++ * correctly above 4GB ++ */ ++ if (grub_initrd_load (&initrd_ctx, initrd_mem)) ++ goto fail; + + params->ramdisk_size = size; + + fail: +- for (i = 0; i < nfiles; i++) +- grub_file_close (files[i]); +- grub_free (files); +- ++ grub_initrd_close (&initrd_ctx); + if (initrd_mem && grub_errno) + grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, BYTES_TO_PAGES(size)); + diff --git a/0164-pgp-factor-out-rsa_pad.patch b/0008-pgp-factor-out-rsa_pad.patch similarity index 86% rename from 0164-pgp-factor-out-rsa_pad.patch rename to 0008-pgp-factor-out-rsa_pad.patch index a8154e7496544e078887cdd3d1aee8c9ad274ddd..10fe4a32e1ea8018a71172595c20de99a46428b8 100644 --- a/0164-pgp-factor-out-rsa_pad.patch +++ b/0008-pgp-factor-out-rsa_pad.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 923c8f6807cbd93b72d4dcb16c213d0d2a6b5b9a Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Thu, 1 Oct 2020 20:23:48 +1000 -Subject: [PATCH] pgp: factor out rsa_pad +Subject: [PATCH 08/23] pgp: factor out rsa_pad rsa_pad does the PKCS#1 v1.5 padding for the RSA signature scheme. We want to use it in other RSA signature verification applications. @@ -18,23 +18,20 @@ PKCS#1 v1.5 module. Signed-off-by: Daniel Axtens --- - grub-core/Makefile.core.def | 8 ++++++ - grub-core/commands/pgp.c | 28 ++------------------- - grub-core/lib/pkcs1_v15.c | 59 +++++++++++++++++++++++++++++++++++++++++++++ - include/grub/pkcs1_v15.h | 27 +++++++++++++++++++++ + grub-core/Makefile.core.def | 8 +++++ + grub-core/commands/pgp.c | 28 ++---------------- + grub-core/lib/pkcs1_v15.c | 59 +++++++++++++++++++++++++++++++++++++ + include/grub/pkcs1_v15.h | 27 +++++++++++++++++ 4 files changed, 96 insertions(+), 26 deletions(-) create mode 100644 grub-core/lib/pkcs1_v15.c create mode 100644 include/grub/pkcs1_v15.h -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 81fc274148e..97347ae76f9 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -2510,6 +2510,14 @@ module = { - cppflags = '$(CPPFLAGS_GCRY)'; +@@ -2542,6 +2542,14 @@ }; -+module = { + module = { + name = pkcs1_v15; + common = lib/pkcs1_v15.c; + @@ -42,11 +39,10 @@ index 81fc274148e..97347ae76f9 100644 + cppflags = '$(CPPFLAGS_GCRY)'; +}; + - module = { ++module = { name = all_video; common = lib/fake_module.c; -diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c -index 5daa1e9d00c..2408db4994f 100644 + }; --- a/grub-core/commands/pgp.c +++ b/grub-core/commands/pgp.c @@ -24,6 +24,7 @@ @@ -57,7 +53,7 @@ index 5daa1e9d00c..2408db4994f 100644 #include #include #include -@@ -411,32 +412,7 @@ static int +@@ -411,32 +412,7 @@ rsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval, const gcry_md_spec_t *hash, struct grub_public_subkey *sk) { @@ -91,9 +87,6 @@ index 5daa1e9d00c..2408db4994f 100644 } struct grub_pubkey_context -diff --git a/grub-core/lib/pkcs1_v15.c b/grub-core/lib/pkcs1_v15.c -new file mode 100644 -index 00000000000..dbacd563d01 --- /dev/null +++ b/grub-core/lib/pkcs1_v15.c @@ -0,0 +1,59 @@ @@ -156,9 +149,6 @@ index 00000000000..dbacd563d01 + grub_free (em); + return ret; +} -diff --git a/include/grub/pkcs1_v15.h b/include/grub/pkcs1_v15.h -new file mode 100644 -index 00000000000..5c338c84a15 --- /dev/null +++ b/include/grub/pkcs1_v15.h @@ -0,0 +1,27 @@ diff --git a/0108-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch b/0008-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch similarity index 91% rename from 0108-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch rename to 0008-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch index b1233ce3ca2384b80b35089d8e437058fa6df087..c63d532ec8bc475864044db8ed9512586f87eb18 100644 --- a/0108-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch +++ b/0008-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 8fbcf9f2e97c98bdb63ae7d544aa9bb273022403 Mon Sep 17 00:00:00 2001 From: Peter Jones Date: Wed, 12 Sep 2018 16:12:27 -0400 -Subject: [PATCH] x86-efi: Allow initrd+params+cmdline allocations above 4GB. +Subject: [PATCH 08/11] x86-efi: Allow initrd+params+cmdline allocations above + 4GB. This enables everything except the kernel itself to be above 4GB. Putting the kernel up there still doesn't work, because of the way @@ -9,12 +10,12 @@ params->code32_start is used. Signed-off-by: Peter Jones --- - grub-core/loader/i386/efi/linux.c | 67 +++++++++++++++++++++++++++++++++++---- - include/grub/i386/linux.h | 6 +++- + grub-core/loader/i386/efi/linux.c | 67 +++++++++++++++++++++++++++---- + include/grub/i386/linux.h | 6 ++- 2 files changed, 65 insertions(+), 8 deletions(-) diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 3e4f7ef39f4..6bc18d5aef5 100644 +index d284db5d1..d49749269 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -52,13 +52,22 @@ struct allocation_choice { @@ -63,7 +64,7 @@ index 3e4f7ef39f4..6bc18d5aef5 100644 static grub_err_t grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) -@@ -207,8 +224,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), +@@ -208,8 +225,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), goto fail; grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem); @@ -78,7 +79,7 @@ index 3e4f7ef39f4..6bc18d5aef5 100644 ptr = initrd_mem; -@@ -338,6 +359,18 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -329,6 +350,18 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), } #endif @@ -97,7 +98,7 @@ index 3e4f7ef39f4..6bc18d5aef5 100644 params = kernel_alloc (sizeof(*params), "cannot allocate kernel parameters"); if (!params) goto fail; -@@ -372,21 +405,40 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -365,21 +398,40 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline); grub_dprintf ("linux", "setting lh->cmd_line_ptr to 0x%08x\n", @@ -140,7 +141,7 @@ index 3e4f7ef39f4..6bc18d5aef5 100644 if (!kernel_mem) goto fail; grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem); -@@ -395,8 +447,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), +@@ -388,8 +440,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), loaded = 1; @@ -153,7 +154,7 @@ index 3e4f7ef39f4..6bc18d5aef5 100644 grub_memcpy (kernel_mem, (char *)kernel + start, filelen - start); diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h -index 25ef52c04eb..fac22476cc5 100644 +index 25ef52c04..fac22476c 100644 --- a/include/grub/i386/linux.h +++ b/include/grub/i386/linux.h @@ -236,7 +236,11 @@ struct linux_kernel_params @@ -169,3 +170,6 @@ index 25ef52c04eb..fac22476cc5 100644 union { +-- +2.31.1 + diff --git a/0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch b/0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch new file mode 100644 index 0000000000000000000000000000000000000000..b69dd4804e2f3975cba1499a1659fc0d2677b42c --- /dev/null +++ b/0009-Add-crypttab_entry-to-obviate-the-need-to-input-pass.patch @@ -0,0 +1,327 @@ +From 749f7dee6f63217e536663aebb817aec72a65d5a Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Thu, 9 Jun 2022 21:06:00 +0800 +Subject: [PATCH 09/10] Add crypttab_entry to obviate the need to input + password twice + +This patch adds crypttab_entry command to hint grub where to put the key file +automatically loaded by linux cryptsetup. It's syntax is similar to +/etc/crypttab so that it is relatively straightforward to import. + + crypttab_entry + +For eg: + + crypttab_entry cr_root 5e1dd109e39343f984da57fd742d3f23 none + +Please note the "encrypted-device" only accepts UUID without dashes as it is +the only identification used by grub's cryptodisk device. The crypttab_entry +can also be used multiple times to specify encrypted volumes unlocked by +"cryptomount -a". + +Signed-off-by: Michael Chang +--- + grub-core/Makefile.core.def | 5 + + grub-core/commands/crypttab.c | 47 ++++++++++++++ + grub-core/disk/cryptodisk.c | 6 + + grub-core/loader/linux.c | 137 ++++++++++++++++++++++++++++++++++++++++-- + include/grub/linux.h | 3 + 5 files changed, 193 insertions(+), 5 deletions(-) + create mode 100644 grub-core/commands/crypttab.c + +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -2695,3 +2695,8 @@ + cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; + cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)'; + }; ++ ++module = { ++ name = crypttab; ++ common = commands/crypttab.c; ++}; +--- /dev/null ++++ b/grub-core/commands/crypttab.c +@@ -0,0 +1,47 @@ ++ ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static grub_err_t ++grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char **argv) ++{ ++ char buf[64]; ++ const char *path = NULL; ++ ++ if (argc == 2) ++ path = NULL; ++ else if (argc == 3) ++ path = argv[2]; ++ else ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("two or three arguments expected")); ++ ++ if (!path ++ || grub_strcmp (path, "none") == 0 ++ || grub_strcmp (path, "-") == 0) ++ { ++ grub_snprintf (buf, sizeof (buf), "/etc/cryptsetup-keys.d/%s.key", argv[0]); ++ path = buf; ++ } ++ ++ /*FIXME: Validate UUID string*/ ++ return grub_initrd_publish_key (argv[1], NULL, 0, path); ++} ++ ++static grub_command_t cmd; ++ ++GRUB_MOD_INIT(crypttab) ++{ ++ cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry, ++ N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description")); ++} ++ ++GRUB_MOD_FINI(crypttab) ++{ ++ grub_unregister_command (cmd); ++} +--- a/grub-core/disk/cryptodisk.c ++++ b/grub-core/disk/cryptodisk.c +@@ -30,6 +30,8 @@ + + #ifdef GRUB_UTIL + #include ++#else ++#include + #endif + + GRUB_MOD_LICENSE ("GPLv3+"); +@@ -1235,6 +1237,10 @@ + if (cargs->hdr_file != NULL) + source->read_hook = NULL; + ++#ifndef GRUB_UTIL ++ if (cargs->key_data && dev) ++ grub_initrd_publish_key (dev->uuid, (const char *)cargs->key_data, cargs->key_len, NULL); ++#endif + if (askpass) + { + cargs->key_len = 0; +--- a/grub-core/loader/linux.c ++++ b/grub-core/loader/linux.c +@@ -5,6 +5,7 @@ + #include + #include + #include ++#include + + struct newc_head + { +@@ -27,6 +28,7 @@ + struct grub_linux_initrd_component + { + grub_file_t file; ++ char *buf; + char *newc_name; + grub_off_t size; + }; +@@ -38,6 +40,18 @@ + struct dir *child; + }; + ++struct grub_key_publisher ++{ ++ struct grub_key_publisher *next; ++ struct grub_key_publisher **prev; ++ char *name; /* UUID */ ++ char *path; ++ char *key; ++ grub_size_t key_len; ++}; ++ ++static struct grub_key_publisher *kpuber; ++ + static char + hex (grub_uint8_t val) + { +@@ -162,6 +176,65 @@ + return GRUB_ERR_NONE; + } + ++static grub_err_t ++grub_initrd_component (const char *buf, int bufsz, const char *newc_name, ++ struct grub_linux_initrd_context *initrd_ctx) ++{ ++ struct dir *root = 0; ++ struct grub_linux_initrd_component *comp = initrd_ctx->components + initrd_ctx->nfiles; ++ grub_size_t dir_size, name_len; ++ ++ while (*newc_name == '/') ++ newc_name++; ++ ++ initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); ++ comp->newc_name = grub_strdup (newc_name); ++ if (!comp->newc_name || ++ insert_dir (comp->newc_name, &root, 0, &dir_size)) ++ { ++ /* FIXME: Check NULL file pointer before close */ ++ grub_initrd_close (initrd_ctx); ++ return grub_errno; ++ } ++ /* Should name_len count terminating null ? */ ++ name_len = grub_strlen (comp->newc_name) + 1; ++ if (grub_add (initrd_ctx->size, ++ ALIGN_UP (sizeof (struct newc_head) + name_len, 4), ++ &initrd_ctx->size) || ++ grub_add (initrd_ctx->size, dir_size, &initrd_ctx->size)) ++ goto overflow; ++ ++ comp->buf = grub_malloc (bufsz); ++ if (!comp->buf) ++ { ++ free_dir (root); ++ grub_initrd_close (initrd_ctx); ++ return grub_errno; ++ } ++ grub_memcpy (comp->buf, buf, bufsz); ++ initrd_ctx->nfiles++; ++ comp->size = bufsz; ++ if (grub_add (initrd_ctx->size, comp->size, ++ &initrd_ctx->size)) ++ goto overflow; ++ ++ initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); ++ if (grub_add (initrd_ctx->size, ++ ALIGN_UP (sizeof (struct newc_head) ++ + sizeof ("TRAILER!!!") - 1, 4), ++ &initrd_ctx->size)) ++ goto overflow; ++ ++ free_dir (root); ++ root = 0; ++ return GRUB_ERR_NONE; ++ ++ overflow: ++ free_dir (root); ++ grub_initrd_close (initrd_ctx); ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++} ++ + grub_err_t + grub_initrd_init (int argc, char *argv[], + struct grub_linux_initrd_context *initrd_ctx) +@@ -169,11 +242,17 @@ + int i; + int newc = 0; + struct dir *root = 0; ++ struct grub_key_publisher *pk; ++ int numkey = 0; + + initrd_ctx->nfiles = 0; + initrd_ctx->components = 0; + +- initrd_ctx->components = grub_calloc (argc, sizeof (initrd_ctx->components[0])); ++ FOR_LIST_ELEMENTS (pk, kpuber) ++ if (pk->key && pk->path) ++ numkey++; ++ ++ initrd_ctx->components = grub_calloc (argc + numkey, sizeof (initrd_ctx->components[0])); + if (!initrd_ctx->components) + return grub_errno; + +@@ -253,6 +332,10 @@ + root = 0; + } + ++ FOR_LIST_ELEMENTS (pk, kpuber) ++ if (pk->key && pk->path) ++ grub_initrd_component (pk->key, pk->key_len, pk->path, initrd_ctx); ++ + return GRUB_ERR_NONE; + + overflow: +@@ -276,7 +359,9 @@ + for (i = 0; i < initrd_ctx->nfiles; i++) + { + grub_free (initrd_ctx->components[i].newc_name); +- grub_file_close (initrd_ctx->components[i].file); ++ if (initrd_ctx->components[i].file) ++ grub_file_close (initrd_ctx->components[i].file); ++ grub_free (initrd_ctx->components[i].buf); + } + grub_free (initrd_ctx->components); + initrd_ctx->components = 0; +@@ -325,7 +410,12 @@ + } + + cursize = initrd_ctx->components[i].size; +- if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize) ++ if (initrd_ctx->components[i].buf) ++ { ++ grub_memcpy (ptr, initrd_ctx->components[i].buf, cursize); ++ newc = 1; ++ } ++ else if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize) + != cursize) + { + if (!grub_errno) +@@ -346,3 +436,45 @@ + root = 0; + return GRUB_ERR_NONE; + } ++ ++grub_err_t ++grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path) ++{ ++ struct grub_key_publisher *cur = NULL; ++ ++ FOR_LIST_ELEMENTS (cur, kpuber) ++ if (grub_uuidcasecmp (cur->name, uuid, sizeof (cur->name)) == 0) ++ break; ++ ++ if (!cur) ++ cur = grub_zalloc (sizeof (*cur)); ++ if (!cur) ++ return grub_errno; ++ ++ if (key && key_len) ++ { ++ grub_free (cur->key); ++ cur->key = grub_malloc (key_len); ++ if (!cur->key) ++ { ++ grub_free (cur); ++ return grub_errno; ++ } ++ grub_memcpy (cur->key, key, key_len); ++ cur->key_len = key_len; ++ } ++ ++ if (path) ++ { ++ grub_free (cur->path); ++ cur->path = grub_strdup (path); ++ } ++ ++ if (!cur->name) ++ { ++ cur->name = grub_strdup (uuid); ++ grub_list_push (GRUB_AS_LIST_P (&kpuber), GRUB_AS_LIST (cur)); ++ } ++ ++ return GRUB_ERR_NONE; ++} +--- a/include/grub/linux.h ++++ b/include/grub/linux.h +@@ -22,3 +22,6 @@ + grub_err_t + grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, + void *target); ++ ++grub_err_t ++grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path); diff --git a/0165-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch b/0009-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch similarity index 90% rename from 0165-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch rename to 0009-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch index 763cdc63f966e9045a2356c42e6bf5f1f8ff7fd4..1c5309bd1e30148d9b0892f8d620ca48e0d789c5 100644 --- a/0165-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch +++ b/0009-crypto-move-storage-for-grub_crypto_pk_-to-crypto.c.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From def9a985bdb1a12db49be42b748b646abc156411 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Fri, 2 Oct 2020 10:49:26 +1000 -Subject: [PATCH] crypto: move storage for grub_crypto_pk_* to crypto.c +Subject: [PATCH 09/23] crypto: move storage for grub_crypto_pk_* to crypto.c The way gcry_rsa and friends (the asymmetric ciphers) are loaded for the pgp module is a bit quirky. @@ -40,7 +40,7 @@ Signed-off-by: Daniel Axtens 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c -index 2408db4994f..355a43844ac 100644 +index 2408db499..355a43844 100644 --- a/grub-core/commands/pgp.c +++ b/grub-core/commands/pgp.c @@ -147,10 +147,6 @@ const char *hashes[] = { @@ -55,7 +55,7 @@ index 2408db4994f..355a43844ac 100644 dsa_pad (gcry_mpi_t *hmpi, grub_uint8_t *hval, const gcry_md_spec_t *hash, struct grub_public_subkey *sk); diff --git a/grub-core/lib/crypto.c b/grub-core/lib/crypto.c -index ca334d5a40e..c578128a59d 100644 +index ca334d5a4..c578128a5 100644 --- a/grub-core/lib/crypto.c +++ b/grub-core/lib/crypto.c @@ -121,6 +121,10 @@ grub_md_unregister (gcry_md_spec_t *cipher) @@ -69,3 +69,6 @@ index ca334d5a40e..c578128a59d 100644 void grub_crypto_hash (const gcry_md_spec_t *hash, void *out, const void *in, grub_size_t inlen) +-- +2.31.1 + diff --git a/0134-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch b/0009-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch similarity index 88% rename from 0134-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch rename to 0009-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch index 825d0f7c80a55f777445fcc6ab864ffe16a7d630..a2bd82f158eb6309f04d02b1aae555fb2ee1e451 100644 --- a/0134-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch +++ b/0009-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From a89b55330ff0930c998cf64ab534cd8ff7e3a74c Mon Sep 17 00:00:00 2001 From: Javier Martinez Canillas Date: Tue, 26 May 2020 16:59:28 +0200 -Subject: [PATCH] x86-efi: Reduce maximum bounce buffer size to 16 MiB +Subject: [PATCH 09/11] x86-efi: Reduce maximum bounce buffer size to 16 MiB The EFI linux loader allocates a bounce buffer to copy the initrd since in some machines doing DMA on addresses above 4GB is not possible during EFI. @@ -26,7 +26,7 @@ Signed-off-by: Javier Martinez Canillas 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 6bc18d5aef5..15d40d6e35b 100644 +index d49749269..652212227 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -144,7 +144,7 @@ grub_linuxefi_unload (void) @@ -38,3 +38,6 @@ index 6bc18d5aef5..15d40d6e35b 100644 static grub_ssize_t read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len) +-- +2.31.1 + diff --git a/0140-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch b/0010-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch similarity index 84% rename from 0140-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch rename to 0010-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch index 95f7e208dd83a16fb96519dd05ab09846ce9cc68..3a5e5c2126f9833631a7d1d791a2c3602e435cb7 100644 --- a/0140-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch +++ b/0010-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 1fc593b372bfe9bba82f4c59236d5a0cffebd8e2 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 24 Jul 2020 17:18:09 +0100 -Subject: [PATCH] efilinux: Fix integer overflows in grub_cmd_initrd +Subject: [PATCH 10/11] efilinux: Fix integer overflows in grub_cmd_initrd These could be triggered by an extremely large number of arguments to the initrd command on 32-bit architectures, or a crafted filesystem with @@ -13,7 +13,7 @@ Signed-off-by: Colin Watson 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index 15d40d6e35b..f992ceeef20 100644 +index 652212227..6b06a8f2f 100644 --- a/grub-core/loader/i386/efi/linux.c +++ b/grub-core/loader/i386/efi/linux.c @@ -28,6 +28,8 @@ @@ -34,7 +34,7 @@ index 15d40d6e35b..f992ceeef20 100644 if (!files) goto fail; -@@ -216,7 +218,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), +@@ -217,7 +219,11 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), if (! files[i]) goto fail; nfiles++; @@ -47,3 +47,6 @@ index 15d40d6e35b..f992ceeef20 100644 } initrd_mem = kernel_alloc(size, N_("can't allocate initrd")); +-- +2.31.1 + diff --git a/0166-posix_wrap-tweaks-in-preparation-for-libtasn1.patch b/0010-posix_wrap-tweaks-in-preparation-for-libtasn1.patch similarity index 70% rename from 0166-posix_wrap-tweaks-in-preparation-for-libtasn1.patch rename to 0010-posix_wrap-tweaks-in-preparation-for-libtasn1.patch index a09cab19833a92ac4b34a3464c5b6f0d41b4ab62..3a502cc8be54c802120d76781e6c3710993e605d 100644 --- a/0166-posix_wrap-tweaks-in-preparation-for-libtasn1.patch +++ b/0010-posix_wrap-tweaks-in-preparation-for-libtasn1.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From fa3436ad10a63d5ad3d27cc330fb2594e699cc34 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Sat, 2 May 2020 00:27:57 +1000 -Subject: [PATCH] posix_wrap: tweaks in preparation for libtasn1 +Subject: [PATCH 10/23] posix_wrap: tweaks in preparation for libtasn1 - Define SIZEOF_UNSIGNED_LONG_INT, it's the same as SIZEOF_UNSIGNED_LONG. @@ -22,23 +22,19 @@ Signed-off-by: Daniel Axtens grub-core/lib/posix_wrap/sys/types.h | 1 + 3 files changed, 10 insertions(+) -diff --git a/grub-core/lib/posix_wrap/limits.h b/grub-core/lib/posix_wrap/limits.h -index 7217138ffd6..591dbf3289d 100644 --- a/grub-core/lib/posix_wrap/limits.h +++ b/grub-core/lib/posix_wrap/limits.h -@@ -37,5 +37,6 @@ +@@ -41,5 +41,6 @@ #define LONG_MAX GRUB_LONG_MAX #define CHAR_BIT 8 +#define WORD_BIT 32 #endif -diff --git a/grub-core/lib/posix_wrap/stdlib.h b/grub-core/lib/posix_wrap/stdlib.h -index 7a8d385e973..4634db09f29 100644 --- a/grub-core/lib/posix_wrap/stdlib.h +++ b/grub-core/lib/posix_wrap/stdlib.h -@@ -58,4 +58,12 @@ abs (int c) - return (c >= 0) ? c : -c; +@@ -64,4 +64,12 @@ + grub_abort (); } +#define strtol grub_strtol @@ -50,11 +46,9 @@ index 7a8d385e973..4634db09f29 100644 +#define strtoull grub_strtoull + #endif -diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h -index 854eb0122ef..f63412c8da0 100644 --- a/grub-core/lib/posix_wrap/sys/types.h +++ b/grub-core/lib/posix_wrap/sys/types.h -@@ -51,6 +51,7 @@ typedef grub_uint8_t byte; +@@ -50,6 +50,7 @@ typedef grub_addr_t uintptr_t; #define SIZEOF_UNSIGNED_LONG GRUB_CPU_SIZEOF_LONG diff --git a/0010-templates-import-etc-crypttab-to-grub.cfg.patch b/0010-templates-import-etc-crypttab-to-grub.cfg.patch new file mode 100644 index 0000000000000000000000000000000000000000..74669606bee888bf0069999ca7a1f7ef8efc9523 --- /dev/null +++ b/0010-templates-import-etc-crypttab-to-grub.cfg.patch @@ -0,0 +1,87 @@ +From 2d3130c289b293269dcf558a26674f83f77729a6 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Tue, 14 Jun 2022 17:10:01 +0800 +Subject: [PATCH 10/10] templates: import /etc/crypttab to grub.cfg + +The /etc/crypptab is used to setup location of encryption key files during +boot, among other things. It is useful to make use the information by grub to +determine where keys are being looked up. + +This script can be used to import relevant /etc/crypptab entry to grub.cfg. + +Signed-off-by: Michael Chang +--- + Makefile.util.def | 7 ++++++ + util/grub.d/05_crypttab.in | 50 +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 57 insertions(+) + create mode 100644 util/grub.d/05_crypttab.in + +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -483,6 +483,13 @@ + }; + + script = { ++ name = '05_crypttab'; ++ common = util/grub.d/05_crypttab.in; ++ installdir = grubconf; ++ condition = COND_HOST_LINUX; ++}; ++ ++script = { + name = '10_windows'; + common = util/grub.d/10_windows.in; + installdir = grubconf; +--- /dev/null ++++ b/util/grub.d/05_crypttab.in +@@ -0,0 +1,50 @@ ++#! /bin/sh ++set -e ++ ++# grub-mkconfig helper script. ++# Copyright (C) 2022 Free Software Foundation, Inc. ++# ++# GRUB is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++# ++# GRUB is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GRUB. If not, see . ++ ++prefix="@prefix@" ++exec_prefix="@exec_prefix@" ++datarootdir="@datarootdir@" ++ ++export TEXTDOMAIN=@PACKAGE@ ++export TEXTDOMAINDIR="@localedir@" ++ ++. "$pkgdatadir/grub-mkconfig_lib" ++ ++CRYPTTAB=/etc/crypttab ++ ++if [ -r "$CRYPTTAB" ]; then ++ awk ' ++ /^\s*#/ || $3 ~ /(^\/dev\/|^\/proc\/|^\/sys\/|:)/ { next } ++ { key[0] = $3 } ++ $3 ~ /(^$|none|-)/ { ++ key[0] = "/etc/cryptsetup-keys.d/" $1 ".key" ++ key[1] = "/run/cryptsetup-keys.d/" $1 ".key" ++ } ++ { ++ for (d in key) ++ if (system("test -f " key[d]) == 0) ++ next ++ } ++ /UUID=/ { ++ sub(/UUID=/,"",$2); ++ gsub(/-/,"",$2); ++ printf("crypttab_entry %s %s %s\n",$1,$2,$3) ++ } ++ ' "$CRYPTTAB" ++fi diff --git a/0011-Also-define-GRUB_EFI_MAX_ALLOCATION_ADDRESS-for-RISC.patch b/0011-Also-define-GRUB_EFI_MAX_ALLOCATION_ADDRESS-for-RISC.patch new file mode 100644 index 0000000000000000000000000000000000000000..dc84300153f0442881015c81e4c0c885fa01b530 --- /dev/null +++ b/0011-Also-define-GRUB_EFI_MAX_ALLOCATION_ADDRESS-for-RISC.patch @@ -0,0 +1,27 @@ +From 76caed15754338f7261b2a95a3c7cc15a25f6a01 Mon Sep 17 00:00:00 2001 +From: David Abdurachmanov +Date: Thu, 16 Jan 2020 13:10:10 +0100 +Subject: [PATCH 11/11] Also define GRUB_EFI_MAX_ALLOCATION_ADDRESS for RISC-V + +The commit "Try to pick better locations for kernel and initrd" missed to +define this macro for the RISC-V (riscv64) architecture, so add it there. + +Signed-off-by: David Abdurachmanov +--- + include/grub/riscv64/efi/memory.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/include/grub/riscv64/efi/memory.h b/include/grub/riscv64/efi/memory.h +index c6cb32417..acb61dca4 100644 +--- a/include/grub/riscv64/efi/memory.h ++++ b/include/grub/riscv64/efi/memory.h +@@ -2,5 +2,6 @@ + #include + + #define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffffffffULL ++#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS + + #endif /* ! GRUB_MEMORY_CPU_HEADER */ +-- +2.31.1 + diff --git a/0167-libtasn1-import-libtasn1-4.16.0.patch b/0011-libtasn1-import-libtasn1-4.18.0.patch similarity index 84% rename from 0167-libtasn1-import-libtasn1-4.16.0.patch rename to 0011-libtasn1-import-libtasn1-4.18.0.patch index 89552c884536b70ec7b130ee81660c985908119c..1e3ab35e32e63e5b14b2edea5e156935368a8659 100644 --- a/0167-libtasn1-import-libtasn1-4.16.0.patch +++ b/0011-libtasn1-import-libtasn1-4.18.0.patch @@ -1,64 +1,183 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From c3a6fbeb436470aff90a63bb98444eb897fbe2f6 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Wed, 10 Jun 2020 16:31:22 +1000 -Subject: [PATCH] libtasn1: import libtasn1-4.16.0 +Subject: [PATCH 11/23] libtasn1: import libtasn1-4.18.0 Import a very trimmed-down set of libtasn1 files: pushd /tmp -wget https://ftp.gnu.org/gnu/libtasn1/libtasn1-4.16.0.tar.gz +wget https://ftp.gnu.org/gnu/libtasn1/libtasn1-4.18.0.tar.gz +tar -xf libtasn1-4.18.0.tar.gz popd pushd grub-core/lib +rm -rf libtasn1 mkdir libtasn1 -cp /tmp/libtasn1-4.16.0/{README.md,LICENSE} libtasn1/ +cp /tmp/libtasn1-4.18.0/{README.md,COPYING} libtasn1/ mkdir libtasn1/lib -cp /tmp/libtasn1-4.16.0/lib/{coding.c,decoding.c,element.c,element.h,errors.c,gstr.c,gstr.h,int.h,parser_aux.c,parser_aux.h,structure.c,structure.h} libtasn1/lib -cp /tmp/libtasn1-4.16.0/lib/includes/libtasn1.h ../../include/grub/ +cp /tmp/libtasn1-4.18.0/lib/{coding.c,decoding.c,element.c,element.h,errors.c,gstr.c,gstr.h,int.h,parser_aux.c,parser_aux.h,structure.c,structure.h} libtasn1/lib +cp /tmp/libtasn1-4.18.0/lib/includes/libtasn1.h ../../include/grub/ git add libtasn1/ ../../include/grub/libtasn1.h popd Signed-off-by: Daniel Axtens --- - grub-core/lib/libtasn1/lib/coding.c | 1415 ++++++++++++++++++ - grub-core/lib/libtasn1/lib/decoding.c | 2478 +++++++++++++++++++++++++++++++ - grub-core/lib/libtasn1/lib/element.c | 1111 ++++++++++++++ - grub-core/lib/libtasn1/lib/errors.c | 100 ++ + grub-core/lib/libtasn1/COPYING | 16 + + grub-core/lib/libtasn1/README.md | 98 + + grub-core/lib/libtasn1/lib/coding.c | 1425 +++++++++++++ + grub-core/lib/libtasn1/lib/decoding.c | 2501 +++++++++++++++++++++++ + grub-core/lib/libtasn1/lib/element.c | 1109 ++++++++++ + grub-core/lib/libtasn1/lib/element.h | 42 + + grub-core/lib/libtasn1/lib/errors.c | 100 + grub-core/lib/libtasn1/lib/gstr.c | 74 + - grub-core/lib/libtasn1/lib/parser_aux.c | 1173 +++++++++++++++ - grub-core/lib/libtasn1/lib/structure.c | 1220 +++++++++++++++ - grub-core/lib/libtasn1/lib/element.h | 40 + - grub-core/lib/libtasn1/lib/gstr.h | 47 + - grub-core/lib/libtasn1/lib/int.h | 221 +++ - grub-core/lib/libtasn1/lib/parser_aux.h | 172 +++ - grub-core/lib/libtasn1/lib/structure.h | 45 + - include/grub/libtasn1.h | 588 ++++++++ - grub-core/lib/libtasn1/LICENSE | 16 + - grub-core/lib/libtasn1/README.md | 91 ++ - 15 files changed, 8791 insertions(+) + grub-core/lib/libtasn1/lib/gstr.h | 50 + + grub-core/lib/libtasn1/lib/int.h | 221 ++ + grub-core/lib/libtasn1/lib/parser_aux.c | 1178 +++++++++++ + grub-core/lib/libtasn1/lib/parser_aux.h | 172 ++ + grub-core/lib/libtasn1/lib/structure.c | 1225 +++++++++++ + grub-core/lib/libtasn1/lib/structure.h | 46 + + include/grub/libtasn1.h | 639 ++++++ + 15 files changed, 8896 insertions(+) + create mode 100644 grub-core/lib/libtasn1/COPYING + create mode 100644 grub-core/lib/libtasn1/README.md create mode 100644 grub-core/lib/libtasn1/lib/coding.c create mode 100644 grub-core/lib/libtasn1/lib/decoding.c create mode 100644 grub-core/lib/libtasn1/lib/element.c + create mode 100644 grub-core/lib/libtasn1/lib/element.h create mode 100644 grub-core/lib/libtasn1/lib/errors.c create mode 100644 grub-core/lib/libtasn1/lib/gstr.c - create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.c - create mode 100644 grub-core/lib/libtasn1/lib/structure.c - create mode 100644 grub-core/lib/libtasn1/lib/element.h create mode 100644 grub-core/lib/libtasn1/lib/gstr.h create mode 100644 grub-core/lib/libtasn1/lib/int.h + create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.c create mode 100644 grub-core/lib/libtasn1/lib/parser_aux.h + create mode 100644 grub-core/lib/libtasn1/lib/structure.c create mode 100644 grub-core/lib/libtasn1/lib/structure.h create mode 100644 include/grub/libtasn1.h - create mode 100644 grub-core/lib/libtasn1/LICENSE - create mode 100644 grub-core/lib/libtasn1/README.md -diff --git a/grub-core/lib/libtasn1/lib/coding.c b/grub-core/lib/libtasn1/lib/coding.c -new file mode 100644 -index 00000000000..245ea64cf0a +--- /dev/null ++++ b/grub-core/lib/libtasn1/COPYING +@@ -0,0 +1,16 @@ ++LICENSING ++========= ++ ++The libtasn1 library is released under the GNU Lesser General Public ++License (LGPL) version 2.1 or later; see [COPYING.LESSER](doc/COPYING.LESSER) ++for the license terms. ++ ++The GNU LGPL applies to the main libtasn1 library, while the ++included applications library are under the GNU GPL version 3. ++The libtasn1 library is located in the lib directory, while the applications ++in src/. ++ ++The documentation in doc/ is under the GNU FDL license 1.3. ++ ++For any copyright year range specified as YYYY-ZZZZ in this package ++note that the range specifies every single year in that closed interval. +--- /dev/null ++++ b/grub-core/lib/libtasn1/README.md +@@ -0,0 +1,98 @@ ++# Libtasn1 README -- Introduction information ++ ++This is GNU Libtasn1, a small ASN.1 library. ++ ++The C library (libtasn1.*) is licensed under the GNU Lesser General ++Public License version 2.1 or later. See the file COPYING.LIB. ++ ++The command line tool, self tests, examples, and other auxilliary ++files, are licensed under the GNU General Public License version 3.0 ++or later. See the file COPYING. ++ ++## Building the library ++ ++We require several tools to build the software, including: ++ ++* [Make](https://www.gnu.org/software/make/) ++* [Automake](https://www.gnu.org/software/automake/) (use 1.11.3 or later) ++* [Autoconf](https://www.gnu.org/software/autoconf/) ++* [Libtool](https://www.gnu.org/software/libtool/) ++* [Texinfo](https://www.gnu.org/software/texinfo/) ++* [help2man](http://www.gnu.org/software/help2man/) ++* [Tar](https://www.gnu.org/software/tar/) ++* [Gzip](https://www.gnu.org/software/gzip/) ++* [bison](https://www.gnu.org/software/bison/) ++* [Texlive & epsf](https://www.tug.org/texlive/) (for PDF manual) ++* [GTK-DOC](https://www.gtk.org/gtk-doc/) (for API manual) ++* [Git](https://git-scm.com/) ++* [libabigail](https://pagure.io/libabigail/) (for abi comparison in make dist) ++* [Valgrind](https://valgrind.org/) (optional) ++ ++The required software is typically distributed with your operating ++system, and the instructions for installing them differ. Here are ++some hints: ++ ++Debian/Ubuntu: ++``` ++sudo apt-get install make git autoconf automake libtool bison ++sudo apt-get install texinfo help2man gtk-doc-tools valgrind abigail-tools ++``` ++ ++PDF manual - Debian <= stretch: ++``` ++sudo apt-get install texlive-generic-recommended texlive texlive-extra-utils ++``` ++ ++PDF manual - Debian >= buster: ++``` ++sudo apt-get install texlive-plain-generic texlive texlive-extra-utils ++``` ++ ++The next step is to run autoreconf, ./configure, etc: ++ ++``` ++$ ./bootstrap ++``` ++ ++Then build the project normally: ++ ++``` ++$ ./configure ++$ make check ++``` ++ ++Happy hacking! ++ ++ ++## Manual ++ ++The manual is in the `doc/` directory of the release. ++ ++You can also browse the manual online at: ++ ++ - https://www.gnu.org/software/libtasn1/manual/ ++ - https://gnutls.gitlab.io/libtasn1/manual/ ++ - https://gnutls.gitlab.io/libtasn1/manual/libtasn1.html ++ - https://gnutls.gitlab.io/libtasn1/manual/libtasn1.pdf ++ - https://gnutls.gitlab.io/libtasn1/reference/ ++ - https://gnutls.gitlab.io/libtasn1/reference/libtasn1.pdf ++ ++ ++## Code coverage report ++ ++The coverage report is at: ++ ++ - https://gnutls.gitlab.io/libtasn1/coverage ++ ++ ++## Issue trackers ++ ++ - [Main issue tracker](https://gitlab.com/gnutls/libtasn1/issues) ++ - [oss-fuzz found issues](https://bugs.chromium.org/p/oss-fuzz/issues/list?q=libtasn1&can=2) ++ ++ ++## Homepage ++ ++The project homepage at the gnu site is at: ++ ++https://www.gnu.org/software/libtasn1/ --- /dev/null +++ b/grub-core/lib/libtasn1/lib/coding.c -@@ -0,0 +1,1415 @@ +@@ -0,0 +1,1425 @@ +/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. ++ * Copyright (C) 2002-2021 Free Software Foundation, Inc. + * + * This file is part of LIBTASN1. + * @@ -324,9 +443,6 @@ index 00000000000..245ea64cf0a + int len_len; + int max_len; + -+ if (der == NULL) -+ return ASN1_VALUE_NOT_VALID; -+ + max_len = *der_len; + + asn1_length_der (str_len, (max_len > 0) ? der : NULL, &len_len); @@ -379,14 +495,14 @@ index 00000000000..245ea64cf0a +} +*/ + -+static -+void encode_val(uint64_t val, unsigned char *der, int max_len, int *der_len) ++static void ++encode_val (uint64_t val, unsigned char *der, int max_len, int *der_len) +{ + int first, k; + unsigned char bit7; + + first = 0; -+ for (k = sizeof(val); k >= 0; k--) ++ for (k = sizeof (val); k >= 0; k--) + { + bit7 = (val >> (k * 7)) & 0x7F; + if (bit7 || first || !k) @@ -447,30 +563,30 @@ index 00000000000..245ea64cf0a + counter++; + + if (counter == 1) -+ { ++ { + val1 = val; + } + else if (counter == 2) + { + uint64_t val0; + -+ if (val1 > 2) -+ { -+ free(temp); -+ return ASN1_VALUE_NOT_VALID; -+ } -+ else if ((val1 == 0 || val1 == 1) && val > 39) -+ { -+ free(temp); -+ return ASN1_VALUE_NOT_VALID; -+ } ++ if (val1 > 2) ++ { ++ free (temp); ++ return ASN1_VALUE_NOT_VALID; ++ } ++ else if ((val1 == 0 || val1 == 1) && val > 39) ++ { ++ free (temp); ++ return ASN1_VALUE_NOT_VALID; ++ } + + val0 = 40 * val1 + val; -+ encode_val(val0, der, max_len, der_len); ++ encode_val (val0, der, max_len, der_len); + } + else + { -+ encode_val(val, der, max_len, der_len); ++ encode_val (val, der, max_len, der_len); + } + n_start = n_end + 1; + } @@ -505,7 +621,9 @@ index 00000000000..245ea64cf0a + * vector isn't big enough and in this case @der_len will contain the + * length needed. + **/ -+int asn1_object_id_der(const char *str, unsigned char *der, int *der_len, unsigned flags) ++int ++asn1_object_id_der (const char *str, unsigned char *der, int *der_len, ++ unsigned flags) +{ + unsigned char tag_der[MAX_TAG_LEN]; + int tag_len = 0, r; @@ -513,12 +631,12 @@ index 00000000000..245ea64cf0a + + *der_len = 0; + -+ _asn1_tag_der (ETYPE_CLASS (ASN1_ETYPE_OBJECT_ID), ETYPE_TAG (ASN1_ETYPE_OBJECT_ID), -+ tag_der, &tag_len); ++ _asn1_tag_der (ETYPE_CLASS (ASN1_ETYPE_OBJECT_ID), ++ ETYPE_TAG (ASN1_ETYPE_OBJECT_ID), tag_der, &tag_len); + + if (max_len > tag_len) + { -+ memcpy(der, tag_der, tag_len); ++ memcpy (der, tag_der, tag_len); + } + max_len -= tag_len; + der += tag_len; @@ -610,7 +728,7 @@ index 00000000000..245ea64cf0a + { + p = node->down; + if (p == NULL) -+ return ASN1_DER_ERROR; ++ return ASN1_DER_ERROR; + /* When there are nested tags we must complete them reverse to + the order they were created. This is because completing a tag + modifies all data within it, including the incomplete tags @@ -728,7 +846,8 @@ index 00000000000..245ea64cf0a +{ + asn1_node p; + int tag_len, is_tag_implicit; -+ unsigned char class, class_implicit = 0, temp[MAX(SIZEOF_UNSIGNED_INT * 3 + 1, LTOSTR_MAX_SIZE)]; ++ unsigned char class, class_implicit = ++ 0, temp[MAX (SIZEOF_UNSIGNED_INT * 3 + 1, LTOSTR_MAX_SIZE)]; + unsigned long tag_implicit = 0; + unsigned char tag_der[MAX_TAG_LEN]; + @@ -858,7 +977,7 @@ index 00000000000..245ea64cf0a + + p = node->down; + while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) || -+ (type_field (p->type) == ASN1_ETYPE_SIZE))) ++ (type_field (p->type) == ASN1_ETYPE_SIZE))) + p = p->right; + + if ((p == NULL) || (p->right == NULL)) @@ -869,7 +988,7 @@ index 00000000000..245ea64cf0a + { + p_vet = malloc (sizeof (struct vet)); + if (p_vet == NULL) -+ { ++ { + err = ASN1_MEM_ALLOC_ERROR; + goto error; + } @@ -888,7 +1007,7 @@ index 00000000000..245ea64cf0a + if (err != ASN1_SUCCESS) + goto error; + -+ t = ((unsigned int)class) << 24; ++ t = ((unsigned int) class) << 24; + p_vet->value = t | tag; + counter += len2; + @@ -956,7 +1075,7 @@ index 00000000000..245ea64cf0a + { + p_vet = first; + first = first->next; -+ free(p_vet); ++ free (p_vet); + } + return err; +} @@ -967,7 +1086,8 @@ index 00000000000..245ea64cf0a + int size; +}; + -+static int setof_compar(const void *_e1, const void *_e2) ++static int ++setof_compar (const void *_e1, const void *_e2) +{ + unsigned length; + const struct vet *e1 = _e1, *e2 = _e2; @@ -980,15 +1100,15 @@ index 00000000000..245ea64cf0a + * The padding octets are for comparison purposes and + * do not appear in the encodings. + */ -+ length = MIN(e1->size, e2->size); ++ length = MIN (e1->size, e2->size); + -+ rval = memcmp(e1->ptr, e2->ptr, length); ++ rval = memcmp (e1->ptr, e2->ptr, length); + if (rval == 0 && e1->size != e2->size) + { + if (e1->size > e2->size) -+ rval = 1; ++ rval = 1; + else if (e2->size > e1->size) -+ rval = -1; ++ rval = -1; + } + + return rval; @@ -1018,9 +1138,6 @@ index 00000000000..245ea64cf0a + unsigned char *out = NULL; + int err; + -+ if (der == NULL) -+ return ASN1_VALUE_NOT_VALID; -+ + counter = 0; + + if (type_field (node->type) != ASN1_ETYPE_SET_OF) @@ -1028,7 +1145,7 @@ index 00000000000..245ea64cf0a + + p = node->down; + while (p && ((type_field (p->type) == ASN1_ETYPE_TAG) || -+ (type_field (p->type) == ASN1_ETYPE_SIZE))) ++ (type_field (p->type) == ASN1_ETYPE_SIZE))) + p = p->right; + if (p == NULL) + return ASN1_VALUE_NOT_VALID; @@ -1040,27 +1157,27 @@ index 00000000000..245ea64cf0a + while (p) + { + list_size++; -+ tlist = realloc (list, list_size*sizeof(struct vet)); ++ tlist = realloc (list, list_size * sizeof (struct vet)); + if (tlist == NULL) + { + err = ASN1_MEM_ALLOC_ERROR; + goto error; + } + list = tlist; -+ p_vet = &list[list_size-1]; ++ p_vet = &list[list_size - 1]; + -+ p_vet->ptr = der+counter; ++ p_vet->ptr = der + counter; + p_vet->size = 0; + + /* extraction of tag and length */ + if (der_len - counter > 0) + { + err = asn1_get_tag_der (der + counter, der_len - counter, &class, -+ &len, NULL); ++ &len, NULL); + if (err != ASN1_SUCCESS) + goto error; + counter += len; -+ p_vet->size += len; ++ p_vet->size += len; + + len2 = asn1_get_length_der (der + counter, der_len - counter, &len); + if (len2 < 0) @@ -1069,7 +1186,7 @@ index 00000000000..245ea64cf0a + goto error; + } + counter += len + len2; -+ p_vet->size += len + len2; ++ p_vet->size += len + len2; + + } + else @@ -1086,9 +1203,9 @@ index 00000000000..245ea64cf0a + goto error; + } + -+ qsort(list, list_size, sizeof(struct vet), setof_compar); ++ qsort (list, list_size, sizeof (struct vet), setof_compar); + -+ out = malloc(der_len); ++ out = malloc (der_len); + if (out == NULL) + { + err = ASN1_MEM_ERROR; @@ -1100,16 +1217,16 @@ index 00000000000..245ea64cf0a + for (i = 0; i < list_size; i++) + { + p_vet = &list[i]; -+ memcpy(out+counter, p_vet->ptr, p_vet->size); ++ memcpy (out + counter, p_vet->ptr, p_vet->size); + counter += p_vet->size; + } -+ memcpy(der, out, der_len); -+ free(out); ++ memcpy (der, out, der_len); ++ free (out); + + err = ASN1_SUCCESS; + +error: -+ free(list); ++ free (list); + return err; +} + @@ -1135,14 +1252,15 @@ index 00000000000..245ea64cf0a + * length needed. + **/ +int -+asn1_der_coding (asn1_node_const element, const char *name, void *ider, int *len, -+ char *ErrorDescription) ++asn1_der_coding (asn1_node_const element, const char *name, void *ider, ++ int *len, char *ErrorDescription) +{ + asn1_node node, p, p2; -+ unsigned char temp[MAX(LTOSTR_MAX_SIZE, SIZEOF_UNSIGNED_LONG_INT * 3 + 1)]; ++ unsigned char temp[MAX (LTOSTR_MAX_SIZE, SIZEOF_UNSIGNED_LONG_INT * 3 + 1)]; + int counter, counter_old, len2, len3, move, max_len, max_len_old; + int err; + unsigned char *der = ider; ++ unsigned char dummy; + + if (ErrorDescription) + ErrorDescription[0] = 0; @@ -1162,7 +1280,10 @@ index 00000000000..245ea64cf0a + max_len = *len; + + if (der == NULL && max_len > 0) -+ return ASN1_VALUE_NOT_VALID; ++ { ++ err = ASN1_VALUE_NOT_VALID; ++ goto error; ++ } + + counter = 0; + move = DOWN; @@ -1175,7 +1296,7 @@ index 00000000000..245ea64cf0a + max_len_old = max_len; + if (move != UP) + { -+ p->start = counter; ++ p->start = counter; + err = _asn1_insert_tag_der (p, der, &counter, &max_len); + if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) + goto error; @@ -1263,7 +1384,9 @@ index 00000000000..245ea64cf0a + goto error; + } + len2 = max_len; -+ err = _asn1_object_id_der ((char*)p->value, der + counter, &len2); ++ err = ++ _asn1_object_id_der ((char *) p->value, ++ der ? der + counter : &dummy, &len2); + if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) + goto error; + @@ -1281,7 +1404,9 @@ index 00000000000..245ea64cf0a + goto error; + } + len2 = max_len; -+ err = _asn1_time_der (p->value, p->value_len, der + counter, &len2); ++ err = ++ _asn1_time_der (p->value, p->value_len, ++ der ? der + counter : &dummy, &len2); + if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) + goto error; + @@ -1349,7 +1474,9 @@ index 00000000000..245ea64cf0a + p->tmp_ival = 0; + if ((type_field (p->type) == ASN1_ETYPE_SET) && (max_len >= 0)) + { -+ err = _asn1_ordering_set (der + len2, counter - len2, p); ++ err = ++ _asn1_ordering_set (der ? der + len2 : &dummy, ++ counter - len2, p); + if (err != ASN1_SUCCESS) + goto error; + } @@ -1390,7 +1517,9 @@ index 00000000000..245ea64cf0a + if ((type_field (p->type) == ASN1_ETYPE_SET_OF) + && (counter - len2 > 0) && (max_len >= 0)) + { -+ err = _asn1_ordering_set_of (der + len2, counter - len2, p); ++ err = ++ _asn1_ordering_set_of (der ? der + len2 : &dummy, ++ counter - len2, p); + if (err != ASN1_SUCCESS) + goto error; + } @@ -1431,7 +1560,7 @@ index 00000000000..245ea64cf0a + + if ((move != DOWN) && (counter != counter_old)) + { -+ p->end = counter - 1; ++ p->end = counter - 1; + err = _asn1_complete_explicit_tag (p, der, &counter, &max_len); + if (err != ASN1_SUCCESS && err != ASN1_MEM_ERROR) + goto error; @@ -1472,14 +1601,11 @@ index 00000000000..245ea64cf0a + asn1_delete_structure (&node); + return err; +} -diff --git a/grub-core/lib/libtasn1/lib/decoding.c b/grub-core/lib/libtasn1/lib/decoding.c -new file mode 100644 -index 00000000000..ff04eb778cb --- /dev/null +++ b/grub-core/lib/libtasn1/lib/decoding.c -@@ -0,0 +1,2478 @@ +@@ -0,0 +1,2501 @@ +/* -+ * Copyright (C) 2002-2016 Free Software Foundation, Inc. ++ * Copyright (C) 2002-2021 Free Software Foundation, Inc. + * + * This file is part of LIBTASN1. + * @@ -1512,7 +1638,7 @@ index 00000000000..ff04eb778cb +#include +#include +#include -+#include ++#include "c-ctype.h" + +#ifdef DEBUG +# define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__) @@ -1551,18 +1677,19 @@ index 00000000000..ff04eb778cb + } while (0) + +static int -+_asn1_get_indefinite_length_string (const unsigned char *der, int der_len, int *len); ++_asn1_get_indefinite_length_string (const unsigned char *der, int der_len, ++ int *len); + +static int +_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, -+ unsigned int _der_len, unsigned char **str, -+ unsigned int *str_len, unsigned int *ber_len, -+ unsigned dflags); ++ unsigned int _der_len, unsigned char **str, ++ unsigned int *str_len, unsigned int *ber_len, ++ unsigned dflags); + +static int +_asn1_decode_simple_der (unsigned int etype, const unsigned char *der, -+ unsigned int _der_len, const unsigned char **str, -+ unsigned int *str_len, unsigned dflags); ++ unsigned int _der_len, const unsigned char **str, ++ unsigned int *str_len, unsigned dflags); + +static void +_asn1_error_description_tag_error (asn1_node node, char *ErrorDescription) @@ -1609,7 +1736,7 @@ index 00000000000..ff04eb778cb + k = der[0] & 0x7F; + punt = 1; + if (k) -+ { /* definite length method */ ++ { /* definite length method */ + ans = 0; + while (punt <= k && punt < der_len) + { @@ -1735,7 +1862,7 @@ index 00000000000..ff04eb778cb + + if (ret == -1 && ber_len > 1) + { /* indefinite length method */ -+ err = _asn1_get_indefinite_length_string (ber + 1, ber_len-1, &ret); ++ err = _asn1_get_indefinite_length_string (ber + 1, ber_len - 1, &ret); + if (err != ASN1_SUCCESS) + return -3; + } @@ -1777,7 +1904,7 @@ index 00000000000..ff04eb778cb + if (str_size >= *str_len) + { + if (*str_len > 0 && str != NULL) -+ memcpy (str, der + len_len, *str_len); ++ memcpy (str, der + len_len, *str_len); + } + else + { @@ -1805,8 +1932,8 @@ index 00000000000..ff04eb778cb + * Returns: %ASN1_SUCCESS on success, or an error. + -*/ +static int -+_asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, int *ret_len, -+ char *str, int str_size, unsigned flags) ++_asn1_get_time_der (unsigned type, const unsigned char *der, int der_len, ++ int *ret_len, char *str, int str_size, unsigned flags) +{ + int len_len, str_len; + unsigned i; @@ -1824,46 +1951,47 @@ index 00000000000..ff04eb778cb + /* perform some sanity checks on the data */ + if (str_len < 8) + { -+ warn(); ++ warn (); + return ASN1_TIME_ENCODING_ERROR; + } + -+ if ((flags & ASN1_DECODE_FLAG_STRICT_DER) && !(flags & ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME)) ++ if ((flags & ASN1_DECODE_FLAG_STRICT_DER) ++ && !(flags & ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME)) + { + p = &der[len_len]; -+ for (i=0;i<(unsigned)(str_len-1);i++) -+ { -+ if (c_isdigit(p[i]) == 0) -+ { -+ if (type == ASN1_ETYPE_GENERALIZED_TIME) -+ { -+ /* tolerate lax encodings */ -+ if (p[i] == '.' && dot_count == 0) -+ { -+ dot_count++; -+ continue; -+ } -+ -+ /* This is not really valid DER, but there are -+ * structures using that */ -+ if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) && -+ (p[i] == '+' || p[i] == '-') && sign_count == 0) -+ { -+ sign_count++; -+ continue; -+ } -+ } -+ -+ warn(); -+ return ASN1_TIME_ENCODING_ERROR; -+ } -+ } -+ -+ if (sign_count == 0 && p[str_len-1] != 'Z') -+ { -+ warn(); -+ return ASN1_TIME_ENCODING_ERROR; -+ } ++ for (i = 0; i < (unsigned) (str_len - 1); i++) ++ { ++ if (c_isdigit (p[i]) == 0) ++ { ++ if (type == ASN1_ETYPE_GENERALIZED_TIME) ++ { ++ /* tolerate lax encodings */ ++ if (p[i] == '.' && dot_count == 0) ++ { ++ dot_count++; ++ continue; ++ } ++ ++ /* This is not really valid DER, but there are ++ * structures using that */ ++ if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) && ++ (p[i] == '+' || p[i] == '-') && sign_count == 0) ++ { ++ sign_count++; ++ continue; ++ } ++ } ++ ++ warn (); ++ return ASN1_TIME_ENCODING_ERROR; ++ } ++ } ++ ++ if (sign_count == 0 && p[str_len - 1] != 'Z') ++ { ++ warn (); ++ return ASN1_TIME_ENCODING_ERROR; ++ } + } + memcpy (str, der + len_len, str_len); + str[str_len] = 0; @@ -1934,11 +2062,11 @@ index 00000000000..ff04eb778cb + { + val = 1; + val1 = val0 - 40; -+ if (val1 > 39) -+ { -+ val = 2; -+ val1 = val0 - 80; -+ } ++ if (val1 > 39) ++ { ++ val = 2; ++ val1 = val0 - 80; ++ } + } + + _asn1_str_cpy (str, str_size, _asn1_ltostr (val, temp)); @@ -2015,7 +2143,7 @@ index 00000000000..ff04eb778cb + if (str_size >= len_byte) + { + if (len_byte > 0 && str) -+ memcpy (str, der + len_len + 1, len_byte); ++ memcpy (str, der + len_len + 1, len_byte); + } + else + { @@ -2066,21 +2194,19 @@ index 00000000000..ff04eb778cb + &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + -+ DECR_LEN(der_len, len2); ++ DECR_LEN (der_len, len2); + counter += len2; + + if (flags & ASN1_DECODE_FLAG_STRICT_DER) + len3 = -+ asn1_get_length_der (der + counter, der_len, -+ &len2); ++ asn1_get_length_der (der + counter, der_len, &len2); + else + len3 = -+ asn1_get_length_ber (der + counter, der_len, -+ &len2); ++ asn1_get_length_ber (der + counter, der_len, &len2); + if (len3 < 0) + return ASN1_DER_ERROR; + -+ DECR_LEN(der_len, len2); ++ DECR_LEN (der_len, len2); + counter += len2; + + if (!is_tag_implicit) @@ -2118,11 +2244,10 @@ index 00000000000..ff04eb778cb + if (is_tag_implicit) + { + if (asn1_get_tag_der -+ (der + counter, der_len, &class, &len2, -+ &tag) != ASN1_SUCCESS) ++ (der + counter, der_len, &class, &len2, &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + -+ DECR_LEN(der_len, len2); ++ DECR_LEN (der_len, len2); + + if ((class != class_implicit) || (tag != tag_implicit)) + { @@ -2148,11 +2273,10 @@ index 00000000000..ff04eb778cb + } + + if (asn1_get_tag_der -+ (der + counter, der_len, &class, &len2, -+ &tag) != ASN1_SUCCESS) ++ (der + counter, der_len, &class, &len2, &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + -+ DECR_LEN(der_len, len2); ++ DECR_LEN (der_len, len2); + + switch (type) + { @@ -2213,28 +2337,32 @@ index 00000000000..ff04eb778cb +} + +static int -+extract_tag_der_recursive(asn1_node node, const unsigned char *der, int der_len, -+ int *ret_len, int *inner_len, unsigned flags) ++extract_tag_der_recursive (asn1_node node, const unsigned char *der, ++ int der_len, int *ret_len, int *inner_len, ++ unsigned flags) +{ -+asn1_node p; -+int ris = ASN1_DER_ERROR; ++ asn1_node p; ++ int ris = ASN1_DER_ERROR; + + if (type_field (node->type) == ASN1_ETYPE_CHOICE) + { + p = node->down; + while (p) -+ { -+ ris = _asn1_extract_tag_der (p, der, der_len, ret_len, inner_len, flags); -+ if (ris == ASN1_SUCCESS) -+ break; -+ p = p->right; ++ { ++ ris = ++ _asn1_extract_tag_der (p, der, der_len, ret_len, inner_len, ++ flags); ++ if (ris == ASN1_SUCCESS) ++ break; ++ p = p->right; + } + + *ret_len = 0; + return ris; + } + else -+ return _asn1_extract_tag_der (node, der, der_len, ret_len, inner_len, flags); ++ return _asn1_extract_tag_der (node, der, der_len, ret_len, inner_len, ++ flags); +} + +static int @@ -2309,10 +2437,11 @@ index 00000000000..ff04eb778cb + + while (1) + { -+ if (HAVE_TWO(der_len) && (der[counter] == 0) && (der[counter + 1] == 0)) ++ if (HAVE_TWO (der_len) && (der[counter] == 0) ++ && (der[counter + 1] == 0)) + { + counter += 2; -+ DECR_LEN(der_len, 2); ++ DECR_LEN (der_len, 2); + + indefinite--; + if (indefinite <= 0) @@ -2322,11 +2451,10 @@ index 00000000000..ff04eb778cb + } + + if (asn1_get_tag_der -+ (der + counter, der_len, &class, &len2, -+ &tag) != ASN1_SUCCESS) ++ (der + counter, der_len, &class, &len2, &tag) != ASN1_SUCCESS) + return ASN1_DER_ERROR; + -+ DECR_LEN(der_len, len2); ++ DECR_LEN (der_len, len2); + counter += len2; + + len2 = asn1_get_length_der (der + counter, der_len, &len3); @@ -2337,12 +2465,12 @@ index 00000000000..ff04eb778cb + { + indefinite++; + counter += 1; -+ DECR_LEN(der_len, 1); ++ DECR_LEN (der_len, 1); + } + else + { + counter += len2 + len3; -+ DECR_LEN(der_len, len2+len3); ++ DECR_LEN (der_len, len2 + len3); + } + } + @@ -2353,7 +2481,8 @@ index 00000000000..ff04eb778cb + return result; +} + -+static void delete_unneeded_choice_fields(asn1_node p) ++static void ++delete_unneeded_choice_fields (asn1_node p) +{ + asn1_node p2; + @@ -2392,13 +2521,13 @@ index 00000000000..ff04eb778cb + * name (*@ELEMENT deleted). + **/ +int -+asn1_der_decoding2 (asn1_node *element, const void *ider, int *max_ider_len, ++asn1_der_decoding2 (asn1_node * element, const void *ider, int *max_ider_len, + unsigned int flags, char *errorDescription) +{ + asn1_node node, p, p2, p3; + char temp[128]; + int counter, len2, len3, len4, move, ris, tlen; -+ struct node_tail_cache_st tcache = {NULL, NULL}; ++ struct node_tail_cache_st tcache = { NULL, NULL }; + unsigned char class; + unsigned long tag; + int tag_len; @@ -2419,7 +2548,7 @@ index 00000000000..ff04eb778cb + if (node->type & CONST_OPTION) + { + result = ASN1_GENERIC_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + @@ -2439,12 +2568,13 @@ index 00000000000..ff04eb778cb + len2 = p2->tmp_ival; + if (len2 == -1) + { -+ if (HAVE_TWO(ider_len) && !der[counter] && !der[counter + 1]) ++ if (HAVE_TWO (ider_len) && !der[counter] ++ && !der[counter + 1]) + { + p = p2; + move = UP; + counter += 2; -+ DECR_LEN(ider_len, 2); ++ DECR_LEN (ider_len, 2); + continue; + } + } @@ -2457,7 +2587,7 @@ index 00000000000..ff04eb778cb + else if (counter > len2) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + p2 = p2->down; @@ -2466,8 +2596,9 @@ index 00000000000..ff04eb778cb + if ((p2->type & CONST_SET) && (p2->type & CONST_NOT_USED)) + { + ris = -+ extract_tag_der_recursive (p2, der + counter, -+ ider_len, &len2, NULL, flags); ++ extract_tag_der_recursive (p2, der + counter, ++ ider_len, &len2, NULL, ++ flags); + if (ris == ASN1_SUCCESS) + { + p2->type &= ~CONST_NOT_USED; @@ -2480,7 +2611,7 @@ index 00000000000..ff04eb778cb + if (p2 == NULL) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + } @@ -2516,18 +2647,18 @@ index 00000000000..ff04eb778cb + while (p->down) + { + ris = -+ extract_tag_der_recursive (p->down, der + counter, -+ ider_len, &len2, NULL, flags); ++ extract_tag_der_recursive (p->down, der + counter, ++ ider_len, &len2, NULL, flags); + + if (ris == ASN1_SUCCESS) + { -+ delete_unneeded_choice_fields(p->down); ++ delete_unneeded_choice_fields (p->down); + break; + } + else if (ris == ASN1_ERROR_TYPE_ANY) + { + result = ASN1_ERROR_TYPE_ANY; -+ warn(); ++ warn (); + goto cleanup; + } + else @@ -2542,7 +2673,7 @@ index 00000000000..ff04eb778cb + if (!(p->type & CONST_OPTION)) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + } @@ -2564,7 +2695,7 @@ index 00000000000..ff04eb778cb + if (ris == ASN1_SUCCESS) + ris = + extract_tag_der_recursive (p, der + counter, ider_len, -+ &tag_len, &inner_tag_len, flags); ++ &tag_len, &inner_tag_len, flags); + + if (ris != ASN1_SUCCESS) + { @@ -2584,13 +2715,13 @@ index 00000000000..ff04eb778cb + _asn1_error_description_tag_error (p, errorDescription); + + result = ASN1_TAG_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + } + else + { -+ DECR_LEN(ider_len, tag_len); ++ DECR_LEN (ider_len, tag_len); + counter += tag_len; + } + } @@ -2600,23 +2731,23 @@ index 00000000000..ff04eb778cb + switch (type_field (p->type)) + { + case ASN1_ETYPE_NULL: -+ DECR_LEN(ider_len, 1); ++ DECR_LEN (ider_len, 1); + if (der[counter]) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + counter++; + move = RIGHT; + break; + case ASN1_ETYPE_BOOLEAN: -+ DECR_LEN(ider_len, 2); ++ DECR_LEN (ider_len, 2); + + if (der[counter++] != 1) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + if (der[counter++] == 0) @@ -2627,16 +2758,15 @@ index 00000000000..ff04eb778cb + break; + case ASN1_ETYPE_INTEGER: + case ASN1_ETYPE_ENUMERATED: -+ len2 = -+ asn1_get_length_der (der + counter, ider_len, &len3); ++ len2 = asn1_get_length_der (der + counter, ider_len, &len3); + if (len2 < 0) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + -+ DECR_LEN(ider_len, len3+len2); ++ DECR_LEN (ider_len, len3 + len2); + + _asn1_set_value (p, der + counter, len3 + len2); + counter += len3 + len2; @@ -2647,12 +2777,12 @@ index 00000000000..ff04eb778cb + asn1_get_object_id_der (der + counter, ider_len, &len2, + temp, sizeof (temp)); + if (result != ASN1_SUCCESS) -+ { -+ warn(); ++ { ++ warn (); + goto cleanup; + } + -+ DECR_LEN(ider_len, len2); ++ DECR_LEN (ider_len, len2); + + tlen = strlen (temp); + if (tlen > 0) @@ -2664,15 +2794,16 @@ index 00000000000..ff04eb778cb + case ASN1_ETYPE_GENERALIZED_TIME: + case ASN1_ETYPE_UTC_TIME: + result = -+ _asn1_get_time_der (type_field (p->type), der + counter, ider_len, &len2, temp, -+ sizeof (temp) - 1, flags); ++ _asn1_get_time_der (type_field (p->type), der + counter, ++ ider_len, &len2, temp, sizeof (temp) - 1, ++ flags); + if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } ++ { ++ warn (); ++ goto cleanup; ++ } + -+ DECR_LEN(ider_len, len2); ++ DECR_LEN (ider_len, len2); + + tlen = strlen (temp); + if (tlen > 0) @@ -2683,57 +2814,60 @@ index 00000000000..ff04eb778cb + break; + case ASN1_ETYPE_OCTET_STRING: + if (counter < inner_tag_len) -+ { ++ { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; -+ } ++ } + -+ ptag = der + counter - inner_tag_len; -+ if ((flags & ASN1_DECODE_FLAG_STRICT_DER) || !(ptag[0] & ASN1_CLASS_STRUCTURED)) -+ { -+ if (ptag[0] & ASN1_CLASS_STRUCTURED) ++ ptag = der + counter - inner_tag_len; ++ if ((flags & ASN1_DECODE_FLAG_STRICT_DER) ++ || !(ptag[0] & ASN1_CLASS_STRUCTURED)) ++ { ++ if (ptag[0] & ASN1_CLASS_STRUCTURED) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + -+ len2 = -+ asn1_get_length_der (der + counter, ider_len, &len3); -+ if (len2 < 0) ++ len2 = asn1_get_length_der (der + counter, ider_len, &len3); ++ if (len2 < 0) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + -+ DECR_LEN(ider_len, len3+len2); ++ DECR_LEN (ider_len, len3 + len2); + -+ _asn1_set_value (p, der + counter, len3 + len2); -+ counter += len3 + len2; -+ } -+ else -+ { -+ unsigned dflags = 0, vlen, ber_len; ++ _asn1_set_value (p, der + counter, len3 + len2); ++ counter += len3 + len2; ++ } ++ else ++ { ++ unsigned dflags = 0, vlen, ber_len; + -+ if (ptag[0] & ASN1_CLASS_STRUCTURED) -+ dflags |= DECODE_FLAG_CONSTRUCTED; ++ if (ptag[0] & ASN1_CLASS_STRUCTURED) ++ dflags |= DECODE_FLAG_CONSTRUCTED; + -+ result = _asn1_decode_simple_ber(type_field (p->type), der+counter, ider_len, &ptmp, &vlen, &ber_len, dflags); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); ++ result = ++ _asn1_decode_simple_ber (type_field (p->type), ++ der + counter, ider_len, &ptmp, ++ &vlen, &ber_len, dflags); ++ if (result != ASN1_SUCCESS) ++ { ++ warn (); + goto cleanup; + } + -+ DECR_LEN(ider_len, ber_len); ++ DECR_LEN (ider_len, ber_len); + + _asn1_set_value_lv (p, ptmp, vlen); + -+ counter += ber_len; -+ free(ptmp); -+ } ++ counter += ber_len; ++ free (ptmp); ++ } + move = RIGHT; + break; + case ASN1_ETYPE_GENERALSTRING: @@ -2746,16 +2880,15 @@ index 00000000000..ff04eb778cb + case ASN1_ETYPE_UTF8_STRING: + case ASN1_ETYPE_VISIBLE_STRING: + case ASN1_ETYPE_BIT_STRING: -+ len2 = -+ asn1_get_length_der (der + counter, ider_len, &len3); ++ len2 = asn1_get_length_der (der + counter, ider_len, &len3); + if (len2 < 0) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + -+ DECR_LEN(ider_len, len3+len2); ++ DECR_LEN (ider_len, len3 + len2); + + _asn1_set_value (p, der + counter, len3 + len2); + counter += len3 + len2; @@ -2769,12 +2902,12 @@ index 00000000000..ff04eb778cb + p->tmp_ival = 0; + if (len2 == -1) + { /* indefinite length method */ -+ DECR_LEN(ider_len, 2); ++ DECR_LEN (ider_len, 2); + if ((der[counter]) || der[counter + 1]) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; ++ { ++ result = ASN1_DER_ERROR; ++ warn (); ++ goto cleanup; + } + counter += 2; + } @@ -2783,7 +2916,7 @@ index 00000000000..ff04eb778cb + if (len2 != counter) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + } @@ -2791,16 +2924,15 @@ index 00000000000..ff04eb778cb + } + else + { /* move==DOWN || move==RIGHT */ -+ len3 = -+ asn1_get_length_der (der + counter, ider_len, &len2); -+ if (IS_ERR(len3, flags)) ++ len3 = asn1_get_length_der (der + counter, ider_len, &len2); ++ if (IS_ERR (len3, flags)) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + -+ DECR_LEN(ider_len, len2); ++ DECR_LEN (ider_len, len2); + counter += len2; + + if (len3 > 0) @@ -2838,23 +2970,24 @@ index 00000000000..ff04eb778cb + len2 = p->tmp_ival; + if (len2 == -1) + { /* indefinite length method */ -+ if (!HAVE_TWO(ider_len) || ((der[counter]) || der[counter + 1])) ++ if (!HAVE_TWO (ider_len) ++ || ((der[counter]) || der[counter + 1])) + { + result = _asn1_append_sequence_set (p, &tcache); + if (result != 0) + { -+ warn(); -+ goto cleanup; -+ } ++ warn (); ++ goto cleanup; ++ } + p = tcache.tail; + move = RIGHT; + continue; + } + + p->tmp_ival = 0; -+ tcache.tail = NULL; /* finished decoding this structure */ ++ tcache.tail = NULL; /* finished decoding this structure */ + tcache.head = NULL; -+ DECR_LEN(ider_len, 2); ++ DECR_LEN (ider_len, 2); + counter += 2; + } + else @@ -2864,69 +2997,68 @@ index 00000000000..ff04eb778cb + result = _asn1_append_sequence_set (p, &tcache); + if (result != 0) + { -+ warn(); -+ goto cleanup; -+ } ++ warn (); ++ goto cleanup; ++ } + p = tcache.tail; + move = RIGHT; + continue; + } + + p->tmp_ival = 0; -+ tcache.tail = NULL; /* finished decoding this structure */ ++ tcache.tail = NULL; /* finished decoding this structure */ + tcache.head = NULL; + + if (len2 != counter) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + } + } + else + { /* move==DOWN || move==RIGHT */ -+ len3 = -+ asn1_get_length_der (der + counter, ider_len, &len2); -+ if (IS_ERR(len3, flags)) ++ len3 = asn1_get_length_der (der + counter, ider_len, &len2); ++ if (IS_ERR (len3, flags)) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + -+ DECR_LEN(ider_len, len2); ++ DECR_LEN (ider_len, len2); + counter += len2; + if (len3) + { + if (len3 > 0) + { /* definite length method */ -+ p->tmp_ival = counter + len3; ++ p->tmp_ival = counter + len3; + } + else + { /* indefinite length method */ -+ p->tmp_ival = -1; ++ p->tmp_ival = -1; + } + + p2 = p->down; -+ if (p2 == NULL) -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } ++ if (p2 == NULL) ++ { ++ result = ASN1_DER_ERROR; ++ warn (); ++ goto cleanup; ++ } + + while ((type_field (p2->type) == ASN1_ETYPE_TAG) + || (type_field (p2->type) == ASN1_ETYPE_SIZE)) + p2 = p2->right; + if (p2->right == NULL) -+ { ++ { + result = _asn1_append_sequence_set (p, &tcache); + if (result != 0) + { -+ warn(); -+ goto cleanup; -+ } ++ warn (); ++ goto cleanup; ++ } + } + p = p2; + } @@ -2936,81 +3068,82 @@ index 00000000000..ff04eb778cb + case ASN1_ETYPE_ANY: + /* Check indefinite lenth method in an EXPLICIT TAG */ + -+ if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) && (p->type & CONST_TAG) && -+ tag_len == 2 && (der[counter - 1] == 0x80)) ++ if (!(flags & ASN1_DECODE_FLAG_STRICT_DER) ++ && (p->type & CONST_TAG) && tag_len == 2 ++ && (der[counter - 1] == 0x80)) + indefinite = 1; + else -+ indefinite = 0; ++ indefinite = 0; + + if (asn1_get_tag_der + (der + counter, ider_len, &class, &len2, + &tag) != ASN1_SUCCESS) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + -+ DECR_LEN(ider_len, len2); ++ DECR_LEN (ider_len, len2); + + len4 = -+ asn1_get_length_der (der + counter + len2, -+ ider_len, &len3); -+ if (IS_ERR(len4, flags)) ++ asn1_get_length_der (der + counter + len2, ider_len, &len3); ++ if (IS_ERR (len4, flags)) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } -+ if (len4 != -1) /* definite */ ++ if (len4 != -1) /* definite */ + { + len2 += len4; + -+ DECR_LEN(ider_len, len4+len3); ++ DECR_LEN (ider_len, len4 + len3); + _asn1_set_value_lv (p, der + counter, len2 + len3); + counter += len2 + len3; + } -+ else /* == -1 */ ++ else /* == -1 */ + { /* indefinite length */ -+ ider_len += len2; /* undo DECR_LEN */ ++ ider_len += len2; /* undo DECR_LEN */ + + if (counter == 0) + { + result = ASN1_DER_ERROR; -+ warn(); ++ warn (); + goto cleanup; + } + + result = -+ _asn1_get_indefinite_length_string (der + counter, ider_len, &len2); ++ _asn1_get_indefinite_length_string (der + counter, ++ ider_len, &len2); + if (result != ASN1_SUCCESS) + { -+ warn(); -+ goto cleanup; -+ } ++ warn (); ++ goto cleanup; ++ } + -+ DECR_LEN(ider_len, len2); ++ DECR_LEN (ider_len, len2); + _asn1_set_value_lv (p, der + counter, len2); + counter += len2; + + } + -+ /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with -+ an indefinite length method. */ -+ if (indefinite) -+ { -+ DECR_LEN(ider_len, 2); -+ if (!der[counter] && !der[counter + 1]) -+ { -+ counter += 2; -+ } -+ else -+ { -+ result = ASN1_DER_ERROR; -+ warn(); -+ goto cleanup; -+ } -+ } ++ /* Check if a couple of 0x00 are present due to an EXPLICIT TAG with ++ an indefinite length method. */ ++ if (indefinite) ++ { ++ DECR_LEN (ider_len, 2); ++ if (!der[counter] && !der[counter + 1]) ++ { ++ counter += 2; ++ } ++ else ++ { ++ result = ASN1_DER_ERROR; ++ warn (); ++ goto cleanup; ++ } ++ } + + move = RIGHT; + break; @@ -3021,9 +3154,9 @@ index 00000000000..ff04eb778cb + } + + if (p) -+ { -+ p->end = counter - 1; -+ } ++ { ++ p->end = counter - 1; ++ } + + if (p == node && move != DOWN) + break; @@ -3051,7 +3184,7 @@ index 00000000000..ff04eb778cb + if ((ider_len < 0) || + (!(flags & ASN1_DECODE_FLAG_ALLOW_PADDING) && (ider_len != 0))) + { -+ warn(); ++ warn (); + result = ASN1_DER_ERROR; + goto cleanup; + } @@ -3121,7 +3254,7 @@ index 00000000000..ff04eb778cb +asn1_der_decoding_element (asn1_node * structure, const char *elementName, + const void *ider, int len, char *errorDescription) +{ -+ return asn1_der_decoding(structure, ider, len, errorDescription); ++ return asn1_der_decoding (structure, ider, len, errorDescription); +} + +/** @@ -3175,19 +3308,19 @@ index 00000000000..ff04eb778cb + if (*start == 0 && *end == 0) + { + if (ider == NULL || ider_len == 0) -+ return ASN1_GENERIC_ERROR; ++ return ASN1_GENERIC_ERROR; + + /* it seems asn1_der_decoding() wasn't called before. Do it now */ + result = asn1_der_decoding (&node, ider, ider_len, NULL); + if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ return result; -+ } ++ { ++ warn (); ++ return result; ++ } + + node_to_find = asn1_find_node (node, name_element); + if (node_to_find == NULL) -+ return ASN1_ELEMENT_NOT_FOUND; ++ return ASN1_ELEMENT_NOT_FOUND; + + *start = node_to_find->start; + *end = node_to_find->end; @@ -3218,8 +3351,7 @@ index 00000000000..ff04eb778cb +int +asn1_expand_any_defined_by (asn1_node_const definitions, asn1_node * element) +{ -+ char name[2 * ASN1_MAX_NAME_SIZE + 2], -+ value[ASN1_MAX_NAME_SIZE]; ++ char name[2 * ASN1_MAX_NAME_SIZE + 2], value[ASN1_MAX_NAME_SIZE]; + int retCode = ASN1_SUCCESS, result; + int len, len2, len3; + asn1_node_const p2; @@ -3305,7 +3437,8 @@ index 00000000000..ff04eb778cb + if ((type_field (p2->type) == ASN1_ETYPE_OBJECT_ID) && + (p2->type & CONST_ASSIGN)) + { -+ snprintf(name, sizeof(name), "%s.%s", definitionsName, p2->name); ++ snprintf (name, sizeof (name), "%s.%s", definitionsName, ++ p2->name); + + len = ASN1_MAX_NAME_SIZE; + result = @@ -3321,7 +3454,8 @@ index 00000000000..ff04eb778cb + + if (p2) + { -+ snprintf(name, sizeof(name), "%s.%s", definitionsName, p2->name); ++ snprintf (name, sizeof (name), "%s.%s", ++ definitionsName, p2->name); + + result = + asn1_create_element (definitions, name, &aux); @@ -3585,8 +3719,8 @@ index 00000000000..ff04eb778cb + -*/ +static int +_asn1_decode_simple_der (unsigned int etype, const unsigned char *der, -+ unsigned int _der_len, const unsigned char **str, -+ unsigned int *str_len, unsigned dflags) ++ unsigned int _der_len, const unsigned char **str, ++ unsigned int *str_len, unsigned dflags) +{ + int tag_len, len_len; + const unsigned char *p; @@ -3598,11 +3732,11 @@ index 00000000000..ff04eb778cb + if (der == NULL || der_len == 0) + return ASN1_VALUE_NOT_VALID; + -+ if (ETYPE_OK (etype) == 0 || ETYPE_IS_STRING(etype) == 0) ++ if (ETYPE_OK (etype) == 0 || ETYPE_IS_STRING (etype) == 0) + return ASN1_VALUE_NOT_VALID; + + /* doesn't handle constructed classes */ -+ class = ETYPE_CLASS(etype); ++ class = ETYPE_CLASS (etype); + if (class != ASN1_CLASS_UNIVERSAL) + return ASN1_VALUE_NOT_VALID; + @@ -3612,18 +3746,18 @@ index 00000000000..ff04eb778cb + { + ret = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag); + if (ret != ASN1_SUCCESS) -+ return ret; ++ return ret; + + if (class != ETYPE_CLASS (etype) || tag != ETYPE_TAG (etype)) -+ { -+ warn(); -+ return ASN1_DER_ERROR; -+ } ++ { ++ warn (); ++ return ASN1_DER_ERROR; ++ } + + p += tag_len; + der_len -= tag_len; + if (der_len <= 0) -+ return ASN1_DER_ERROR; ++ return ASN1_DER_ERROR; + } + + ret = asn1_get_length_der (p, der_len, &len_len); @@ -3659,18 +3793,21 @@ index 00000000000..ff04eb778cb + unsigned int _der_len, const unsigned char **str, + unsigned int *str_len) +{ -+ return _asn1_decode_simple_der(etype, der, _der_len, str, str_len, DECODE_FLAG_HAVE_TAG); ++ return _asn1_decode_simple_der (etype, der, _der_len, str, str_len, ++ DECODE_FLAG_HAVE_TAG); +} + -+static int append(uint8_t **dst, unsigned *dst_size, const unsigned char *src, unsigned src_size) ++static int ++append (uint8_t ** dst, unsigned *dst_size, const unsigned char *src, ++ unsigned src_size) +{ + if (src_size == 0) + return ASN1_SUCCESS; + -+ *dst = _asn1_realloc(*dst, *dst_size+src_size); ++ *dst = _asn1_realloc (*dst, *dst_size + src_size); + if (*dst == NULL) + return ASN1_MEM_ALLOC_ERROR; -+ memcpy(*dst + *dst_size, src, src_size); ++ memcpy (*dst + *dst_size, src, src_size); + *dst_size += src_size; + return ASN1_SUCCESS; +} @@ -3693,9 +3830,9 @@ index 00000000000..ff04eb778cb + -*/ +static int +_asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, -+ unsigned int _der_len, unsigned char **str, -+ unsigned int *str_len, unsigned int *ber_len, -+ unsigned dflags) ++ unsigned int _der_len, unsigned char **str, ++ unsigned int *str_len, unsigned int *ber_len, ++ unsigned dflags) +{ + int tag_len, len_len; + const unsigned char *p; @@ -3709,17 +3846,18 @@ index 00000000000..ff04eb778cb + unsigned out_len; + long result; + -+ if (ber_len) *ber_len = 0; ++ if (ber_len) ++ *ber_len = 0; + + if (der == NULL || der_len == 0) + { -+ warn(); ++ warn (); + return ASN1_VALUE_NOT_VALID; + } + + if (ETYPE_OK (etype) == 0) + { -+ warn(); ++ warn (); + return ASN1_VALUE_NOT_VALID; + } + @@ -3727,7 +3865,7 @@ index 00000000000..ff04eb778cb + class = ETYPE_CLASS (etype); + if (class != ASN1_CLASS_UNIVERSAL) + { -+ warn(); ++ warn (); + return ASN1_VALUE_NOT_VALID; + } + @@ -3736,191 +3874,201 @@ index 00000000000..ff04eb778cb + if (dflags & DECODE_FLAG_HAVE_TAG) + { + result = asn1_get_tag_der (p, der_len, &class, &tag_len, &tag); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ return result; -+ } ++ if (result != ASN1_SUCCESS) ++ { ++ warn (); ++ return result; ++ } + -+ if (tag != ETYPE_TAG (etype)) -+ { -+ warn(); -+ return ASN1_DER_ERROR; -+ } ++ if (tag != ETYPE_TAG (etype)) ++ { ++ warn (); ++ return ASN1_DER_ERROR; ++ } + -+ p += tag_len; ++ p += tag_len; + -+ DECR_LEN(der_len, tag_len); ++ DECR_LEN (der_len, tag_len); + -+ if (ber_len) *ber_len += tag_len; ++ if (ber_len) ++ *ber_len += tag_len; + } + + /* indefinite constructed */ -+ if ((((dflags & DECODE_FLAG_CONSTRUCTED) || class == ASN1_CLASS_STRUCTURED) && ETYPE_IS_STRING(etype)) && -+ !(dflags & DECODE_FLAG_LEVEL3)) ++ if ((((dflags & DECODE_FLAG_CONSTRUCTED) || class == ASN1_CLASS_STRUCTURED) ++ && ETYPE_IS_STRING (etype)) && !(dflags & DECODE_FLAG_LEVEL3)) + { + if (der_len == 0) -+ { -+ warn(); -+ result = ASN1_DER_ERROR; -+ goto cleanup; -+ } ++ { ++ warn (); ++ result = ASN1_DER_ERROR; ++ goto cleanup; ++ } + -+ if (der_len > 0 && p[0] == 0x80) /* indefinite */ -+ { -+ len_len = 1; -+ DECR_LEN(der_len, len_len); -+ p += len_len; -+ -+ if (ber_len) *ber_len += len_len; -+ -+ /* decode the available octet strings */ -+ do -+ { -+ unsigned tmp_len; -+ unsigned flags = DECODE_FLAG_HAVE_TAG; -+ -+ if (dflags & DECODE_FLAG_LEVEL1) -+ flags |= DECODE_FLAG_LEVEL2; -+ else if (dflags & DECODE_FLAG_LEVEL2) -+ flags |= DECODE_FLAG_LEVEL3; -+ else -+ flags |= DECODE_FLAG_LEVEL1; ++ if (der_len > 0 && p[0] == 0x80) /* indefinite */ ++ { ++ len_len = 1; ++ DECR_LEN (der_len, len_len); ++ p += len_len; + -+ result = _asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, &tmp_len, -+ flags); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ p += tmp_len; -+ DECR_LEN(der_len, tmp_len); -+ -+ if (ber_len) *ber_len += tmp_len; -+ -+ DECR_LEN(der_len, 2); /* we need the EOC */ -+ -+ result = append(&total, &total_size, out, out_len); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ free(out); -+ out = NULL; -+ -+ if (p[0] == 0 && p[1] == 0) /* EOC */ -+ { -+ if (ber_len) *ber_len += 2; -+ break; -+ } -+ -+ /* no EOC */ -+ der_len += 2; -+ -+ if (der_len == 2) -+ { -+ warn(); -+ result = ASN1_DER_ERROR; -+ goto cleanup; -+ } -+ } -+ while(1); -+ } -+ else /* constructed */ -+ { -+ long const_len; -+ -+ result = asn1_get_length_ber(p, der_len, &len_len); -+ if (result < 0) -+ { -+ warn(); -+ result = ASN1_DER_ERROR; -+ goto cleanup; -+ } -+ -+ DECR_LEN(der_len, len_len); -+ p += len_len; -+ -+ const_len = result; -+ -+ if (ber_len) *ber_len += len_len; -+ -+ /* decode the available octet strings */ -+ while(const_len > 0) -+ { -+ unsigned tmp_len; -+ unsigned flags = DECODE_FLAG_HAVE_TAG; -+ -+ if (dflags & DECODE_FLAG_LEVEL1) -+ flags |= DECODE_FLAG_LEVEL2; -+ else if (dflags & DECODE_FLAG_LEVEL2) -+ flags |= DECODE_FLAG_LEVEL3; -+ else ++ if (ber_len) ++ *ber_len += len_len; ++ ++ /* decode the available octet strings */ ++ do ++ { ++ unsigned tmp_len; ++ unsigned flags = DECODE_FLAG_HAVE_TAG; ++ ++ if (dflags & DECODE_FLAG_LEVEL1) ++ flags |= DECODE_FLAG_LEVEL2; ++ else if (dflags & DECODE_FLAG_LEVEL2) ++ flags |= DECODE_FLAG_LEVEL3; ++ else + flags |= DECODE_FLAG_LEVEL1; + -+ result = _asn1_decode_simple_ber(etype, p, der_len, &out, &out_len, &tmp_len, -+ flags); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ p += tmp_len; -+ DECR_LEN(der_len, tmp_len); -+ DECR_LEN(const_len, tmp_len); -+ -+ if (ber_len) *ber_len += tmp_len; -+ -+ result = append(&total, &total_size, out, out_len); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ -+ free(out); -+ out = NULL; -+ } -+ } -+ } -+ else if (class == ETYPE_CLASS(etype)) -+ { -+ if (ber_len) -+ { -+ result = asn1_get_length_der (p, der_len, &len_len); -+ if (result < 0) -+ { -+ warn(); -+ result = ASN1_DER_ERROR; -+ goto cleanup; -+ } -+ *ber_len += result + len_len; -+ } ++ result = ++ _asn1_decode_simple_ber (etype, p, der_len, &out, &out_len, ++ &tmp_len, flags); ++ if (result != ASN1_SUCCESS) ++ { ++ warn (); ++ goto cleanup; ++ } + -+ /* non-string values are decoded as DER */ -+ result = _asn1_decode_simple_der(etype, der, _der_len, &cout, &out_len, dflags); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } ++ p += tmp_len; ++ DECR_LEN (der_len, tmp_len); + -+ result = append(&total, &total_size, cout, out_len); -+ if (result != ASN1_SUCCESS) -+ { -+ warn(); -+ goto cleanup; -+ } -+ } -+ else -+ { -+ warn(); -+ result = ASN1_DER_ERROR; ++ if (ber_len) ++ *ber_len += tmp_len; ++ ++ DECR_LEN (der_len, 2); /* we need the EOC */ ++ ++ result = append (&total, &total_size, out, out_len); ++ if (result != ASN1_SUCCESS) ++ { ++ warn (); ++ goto cleanup; ++ } ++ ++ free (out); ++ out = NULL; ++ ++ if (p[0] == 0 && p[1] == 0) /* EOC */ ++ { ++ if (ber_len) ++ *ber_len += 2; ++ break; ++ } ++ ++ /* no EOC */ ++ der_len += 2; ++ ++ if (der_len == 2) ++ { ++ warn (); ++ result = ASN1_DER_ERROR; ++ goto cleanup; ++ } ++ } ++ while (1); ++ } ++ else /* constructed */ ++ { ++ long const_len; ++ ++ result = asn1_get_length_ber (p, der_len, &len_len); ++ if (result < 0) ++ { ++ warn (); ++ result = ASN1_DER_ERROR; ++ goto cleanup; ++ } ++ ++ DECR_LEN (der_len, len_len); ++ p += len_len; ++ ++ const_len = result; ++ ++ if (ber_len) ++ *ber_len += len_len; ++ ++ /* decode the available octet strings */ ++ while (const_len > 0) ++ { ++ unsigned tmp_len; ++ unsigned flags = DECODE_FLAG_HAVE_TAG; ++ ++ if (dflags & DECODE_FLAG_LEVEL1) ++ flags |= DECODE_FLAG_LEVEL2; ++ else if (dflags & DECODE_FLAG_LEVEL2) ++ flags |= DECODE_FLAG_LEVEL3; ++ else ++ flags |= DECODE_FLAG_LEVEL1; ++ ++ result = ++ _asn1_decode_simple_ber (etype, p, der_len, &out, &out_len, ++ &tmp_len, flags); ++ if (result != ASN1_SUCCESS) ++ { ++ warn (); ++ goto cleanup; ++ } ++ ++ p += tmp_len; ++ DECR_LEN (der_len, tmp_len); ++ DECR_LEN (const_len, tmp_len); ++ ++ if (ber_len) ++ *ber_len += tmp_len; ++ ++ result = append (&total, &total_size, out, out_len); ++ if (result != ASN1_SUCCESS) ++ { ++ warn (); ++ goto cleanup; ++ } ++ ++ free (out); ++ out = NULL; ++ } ++ } ++ } ++ else if (class == ETYPE_CLASS (etype)) ++ { ++ if (ber_len) ++ { ++ result = asn1_get_length_der (p, der_len, &len_len); ++ if (result < 0) ++ { ++ warn (); ++ result = ASN1_DER_ERROR; ++ goto cleanup; ++ } ++ *ber_len += result + len_len; ++ } ++ ++ /* non-string values are decoded as DER */ ++ result = ++ _asn1_decode_simple_der (etype, der, _der_len, &cout, &out_len, ++ dflags); ++ if (result != ASN1_SUCCESS) ++ { ++ warn (); ++ goto cleanup; ++ } ++ ++ result = append (&total, &total_size, cout, out_len); ++ if (result != ASN1_SUCCESS) ++ { ++ warn (); ++ goto cleanup; ++ } ++ } ++ else ++ { ++ warn (); ++ result = ASN1_DER_ERROR; + goto cleanup; + } + @@ -3929,8 +4077,8 @@ index 00000000000..ff04eb778cb + + return ASN1_SUCCESS; +cleanup: -+ free(out); -+ free(total); ++ free (out); ++ free (total); + return result; +} + @@ -3954,16 +4102,14 @@ index 00000000000..ff04eb778cb + unsigned int _der_len, unsigned char **str, + unsigned int *str_len, unsigned int *ber_len) +{ -+ return _asn1_decode_simple_ber(etype, der, _der_len, str, str_len, ber_len, DECODE_FLAG_HAVE_TAG); ++ return _asn1_decode_simple_ber (etype, der, _der_len, str, str_len, ber_len, ++ DECODE_FLAG_HAVE_TAG); +} -diff --git a/grub-core/lib/libtasn1/lib/element.c b/grub-core/lib/libtasn1/lib/element.c -new file mode 100644 -index 00000000000..997eb2725dc --- /dev/null +++ b/grub-core/lib/libtasn1/lib/element.c -@@ -0,0 +1,1111 @@ +@@ -0,0 +1,1109 @@ +/* -+ * Copyright (C) 2000-2014 Free Software Foundation, Inc. ++ * Copyright (C) 2000-2021 Free Software Foundation, Inc. + * + * This file is part of LIBTASN1. + * @@ -4079,7 +4225,7 @@ index 00000000000..997eb2725dc + if (value_out != NULL) + { + for (k2 = k; k2 < SIZEOF_UNSIGNED_LONG_INT; k2++) -+ value_out[k2 - k] = val[k2]; ++ value_out[k2 - k] = val[k2]; + } + +#if 0 @@ -4106,7 +4252,7 @@ index 00000000000..997eb2725dc +_asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache) +{ + asn1_node p, p2; -+ char temp[LTOSTR_MAX_SIZE]; ++ char temp[LTOSTR_MAX_SIZE + 1]; + long n; + + if (!node || !(node->down)) @@ -4124,9 +4270,9 @@ index 00000000000..997eb2725dc + if (pcache == NULL || pcache->tail == NULL || pcache->head != node) + { + while (p->right) -+ { -+ p = p->right; -+ } ++ { ++ p = p->right; ++ } + } + else + { @@ -4285,7 +4431,8 @@ index 00000000000..997eb2725dc + + type = type_field (node->type); + -+ if ((type == ASN1_ETYPE_SEQUENCE_OF || type == ASN1_ETYPE_SET_OF) && (value == NULL) && (len == 0)) ++ if ((type == ASN1_ETYPE_SEQUENCE_OF || type == ASN1_ETYPE_SET_OF) ++ && (value == NULL) && (len == 0)) + { + p = node->down; + while ((type_field (p->type) == ASN1_ETYPE_TAG) @@ -4721,7 +4868,8 @@ index 00000000000..997eb2725dc + * this function may return %ASN1_SUCCESS even if the provided @len is zero. + **/ +int -+asn1_read_value (asn1_node_const root, const char *name, void *ivalue, int *len) ++asn1_read_value (asn1_node_const root, const char *name, void *ivalue, ++ int *len) +{ + return asn1_read_value_type (root, name, ivalue, len, NULL); +} @@ -4858,8 +5006,8 @@ index 00000000000..997eb2725dc + || (p->value[0] == '+')) + { + result = _asn1_convert_integer -+ (p->value, value, value_size, len); -+ if (result != ASN1_SUCCESS) ++ (p->value, value, value_size, len); ++ if (result != ASN1_SUCCESS) + return result; + } + else @@ -4872,8 +5020,7 @@ index 00000000000..997eb2725dc + if (!_asn1_strcmp (p2->name, p->value)) + { + result = _asn1_convert_integer -+ (p2->value, value, value_size, -+ len); ++ (p2->value, value, value_size, len); + if (result != ASN1_SUCCESS) + return result; + break; @@ -4887,9 +5034,8 @@ index 00000000000..997eb2725dc + { + len2 = -1; + result = asn1_get_octet_der -+ (node->value, node->value_len, &len2, value, value_size, -+ len); -+ if (result != ASN1_SUCCESS) ++ (node->value, node->value_len, &len2, value, value_size, len); ++ if (result != ASN1_SUCCESS) + return result; + } + break; @@ -4942,16 +5088,14 @@ index 00000000000..997eb2725dc + case ASN1_ETYPE_VISIBLE_STRING: + len2 = -1; + result = asn1_get_octet_der -+ (node->value, node->value_len, &len2, value, value_size, -+ len); ++ (node->value, node->value_len, &len2, value, value_size, len); + if (result != ASN1_SUCCESS) + return result; + break; + case ASN1_ETYPE_BIT_STRING: + len2 = -1; + result = asn1_get_bit_der -+ (node->value, node->value_len, &len2, value, value_size, -+ len); ++ (node->value, node->value_len, &len2, value, value_size, len); + if (result != ASN1_SUCCESS) + return result; + break; @@ -5073,14 +5217,56 @@ index 00000000000..997eb2725dc + + return ASN1_SUCCESS; +} -diff --git a/grub-core/lib/libtasn1/lib/errors.c b/grub-core/lib/libtasn1/lib/errors.c -new file mode 100644 -index 00000000000..cee74daf795 +--- /dev/null ++++ b/grub-core/lib/libtasn1/lib/element.h +@@ -0,0 +1,42 @@ ++/* ++ * Copyright (C) 2000-2021 Free Software Foundation, Inc. ++ * ++ * This file is part of LIBTASN1. ++ * ++ * The LIBTASN1 library is free software; you can redistribute it ++ * and/or modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library 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 ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ */ ++ ++#ifndef _ELEMENT_H ++# define _ELEMENT_H ++ ++ ++struct node_tail_cache_st ++{ ++ asn1_node head; /* the first element of the sequence */ ++ asn1_node tail; ++}; ++ ++int _asn1_append_sequence_set (asn1_node node, ++ struct node_tail_cache_st *pcached); ++ ++int _asn1_convert_integer (const unsigned char *value, ++ unsigned char *value_out, ++ int value_out_size, int *len); ++ ++void _asn1_hierarchical_name (asn1_node_const node, char *name, ++ int name_size); ++ ++#endif --- /dev/null +++ b/grub-core/lib/libtasn1/lib/errors.c @@ -0,0 +1,100 @@ +/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. ++ * Copyright (C) 2002-2021 Free Software Foundation, Inc. + * + * This file is part of LIBTASN1. + * @@ -5102,7 +5288,7 @@ index 00000000000..cee74daf795 + +#include +#ifdef STDC_HEADERS -+#include ++# include +#endif + +#define LIBTASN1_ERROR_ENTRY(name) { #name, name } @@ -5179,14 +5365,11 @@ index 00000000000..cee74daf795 + + return NULL; +} -diff --git a/grub-core/lib/libtasn1/lib/gstr.c b/grub-core/lib/libtasn1/lib/gstr.c -new file mode 100644 -index 00000000000..e91a3a151c0 --- /dev/null +++ b/grub-core/lib/libtasn1/lib/gstr.c @@ -0,0 +1,74 @@ +/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. ++ * Copyright (C) 2002-2021 Free Software Foundation, Inc. + * + * This file is part of LIBTASN1. + * @@ -5227,7 +5410,7 @@ index 00000000000..e91a3a151c0 + } + else + { -+ if (dest_tot_size - dest_size > 0) ++ if (dest_tot_size > dest_size) + { + strncat (dest, src, (dest_tot_size - dest_size) - 1); + dest[dest_tot_size - 1] = 0; @@ -5259,14 +5442,11 @@ index 00000000000..e91a3a151c0 + return 0; + } +} -diff --git a/grub-core/lib/libtasn1/lib/parser_aux.c b/grub-core/lib/libtasn1/lib/parser_aux.c -new file mode 100644 -index 00000000000..d5dbbf8765d --- /dev/null -+++ b/grub-core/lib/libtasn1/lib/parser_aux.c -@@ -0,0 +1,1173 @@ ++++ b/grub-core/lib/libtasn1/lib/gstr.h +@@ -0,0 +1,50 @@ +/* -+ * Copyright (C) 2000-2016 Free Software Foundation, Inc. ++ * Copyright (C) 2002-2021 Free Software Foundation, Inc. + * + * This file is part of LIBTASN1. + * @@ -5286,129 +5466,404 @@ index 00000000000..d5dbbf8765d + * 02110-1301, USA + */ + -+#include // WORD_BIT -+ -+#include "int.h" -+#include "parser_aux.h" -+#include "gstr.h" -+#include "structure.h" -+#include "element.h" -+#include "c-ctype.h" -+ -+char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */ ++#ifndef GSTR_H ++# define GSTR_H + -+/* Return a hash of the N bytes of X using the method described by -+ Bruno Haible in https://www.haible.de/bruno/hashfunc.html. -+ Note that while many hash functions reduce their result via modulo -+ to a 0..table_size-1 range, this function does not do that. ++unsigned int _asn1_str_cpy (char *dest, size_t dest_tot_size, ++ const char *src); ++void _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src); + -+ This implementation has been changed from size_t -> unsigned int. */ ++# define Estrcpy(x,y) _asn1_str_cpy(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y) ++# define Estrcat(x,y) _asn1_str_cat(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y) + -+#ifdef __clang__ -+__attribute__((no_sanitize("integer"))) -+#endif -+_GL_ATTRIBUTE_PURE -+static unsigned int -+_asn1_hash_name (const char *x) ++inline static void ++safe_memset (void *data, int c, size_t size) +{ -+ const unsigned char *s = (unsigned char *) x; -+ unsigned h = 0; ++ volatile unsigned volatile_zero = 0; ++ volatile char *vdata = (volatile char *) data; + -+ while (*s) -+ h = (*s++) + ((h << 9) | (h >> (WORD_BIT - 9))); ++ /* This is based on a nice trick for safe memset, ++ * sent by David Jacobson in the openssl-dev mailing list. ++ */ + -+ return h; ++ if (size > 0) ++ do ++ { ++ memset (data, c, size); ++ } ++ while (vdata[volatile_zero] != c); +} + -+/******************************************************/ -+/* Function : _asn1_add_static_node */ -+/* Description: creates a new NODE_ASN element and */ -+/* puts it in the list pointed by e_list. */ -+/* Parameters: */ -+/* e_list: of type list_type; must be NULL initially */ -+/* type: type of the new element (see ASN1_ETYPE_ */ -+/* and CONST_ constants). */ -+/* Return: pointer to the new element. */ -+/******************************************************/ -+asn1_node -+_asn1_add_static_node (list_type **e_list, unsigned int type) -+{ -+ list_type *p; -+ asn1_node punt; -+ -+ punt = calloc (1, sizeof (struct asn1_node_st)); -+ if (punt == NULL) -+ return NULL; ++#endif /* GSTR_H */ +--- /dev/null ++++ b/grub-core/lib/libtasn1/lib/int.h +@@ -0,0 +1,221 @@ ++/* ++ * Copyright (C) 2002-2021 Free Software Foundation, Inc. ++ * ++ * This file is part of LIBTASN1. ++ * ++ * The LIBTASN1 library is free software; you can redistribute it ++ * and/or modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library 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 ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ */ + -+ p = malloc (sizeof (list_type)); -+ if (p == NULL) -+ { -+ free (punt); -+ return NULL; -+ } ++#ifndef INT_H ++# define INT_H + -+ p->node = punt; -+ p->next = *e_list; -+ *e_list = p; ++# ifdef HAVE_CONFIG_H ++# include ++# endif + -+ punt->type = type; ++# include ++# include ++# include ++# include + -+ return punt; -+} ++# ifdef HAVE_SYS_TYPES_H ++# include ++# endif + -+static -+int _asn1_add_static_node2 (list_type **e_list, asn1_node node) -+{ -+ list_type *p; ++# include + -+ p = malloc (sizeof (list_type)); -+ if (p == NULL) -+ { -+ return -1; -+ } ++# define ASN1_SMALL_VALUE_SIZE 16 + -+ p->node = node; -+ p->next = *e_list; -+ *e_list = p; ++/* This structure is also in libtasn1.h, but then contains less ++ fields. You cannot make any modifications to these first fields ++ without breaking ABI. */ ++struct asn1_node_st ++{ ++ /* public fields: */ ++ char name[ASN1_MAX_NAME_SIZE + 1]; /* Node name */ ++ unsigned int name_hash; ++ unsigned int type; /* Node type */ ++ unsigned char *value; /* Node value */ ++ int value_len; ++ asn1_node down; /* Pointer to the son node */ ++ asn1_node right; /* Pointer to the brother node */ ++ asn1_node left; /* Pointer to the next list element */ ++ /* private fields: */ ++ unsigned char small_value[ASN1_SMALL_VALUE_SIZE]; /* For small values */ + -+ return 0; -+} ++ /* values used during decoding/coding */ ++ int tmp_ival; ++ unsigned start; /* the start of the DER sequence - if decoded */ ++ unsigned end; /* the end of the DER sequence - if decoded */ ++}; + -+/** -+ * asn1_find_node: -+ * @pointer: NODE_ASN element pointer. -+ * @name: null terminated string with the element's name to find. -+ * -+ * Searches for an element called @name starting from @pointer. The -+ * name is composed by different identifiers separated by dots. When -+ * *@pointer has a name, the first identifier must be the name of -+ * *@pointer, otherwise it must be the name of one child of *@pointer. -+ * -+ * Returns: the search result, or %NULL if not found. -+ **/ -+asn1_node -+asn1_find_node (asn1_node_const pointer, const char *name) ++typedef struct tag_and_class_st +{ -+ asn1_node_const p; -+ char *n_end, n[ASN1_MAX_NAME_SIZE + 1]; -+ const char *n_start; -+ unsigned int nsize; -+ unsigned int nhash; -+ -+ if (pointer == NULL) -+ return NULL; ++ unsigned tag; ++ unsigned class; ++ const char *desc; ++} tag_and_class_st; + -+ if (name == NULL) -+ return NULL; ++/* the types that are handled in _asn1_tags */ ++# define CASE_HANDLED_ETYPES \ ++ case ASN1_ETYPE_NULL: \ ++ case ASN1_ETYPE_BOOLEAN: \ ++ case ASN1_ETYPE_INTEGER: \ ++ case ASN1_ETYPE_ENUMERATED: \ ++ case ASN1_ETYPE_OBJECT_ID: \ ++ case ASN1_ETYPE_OCTET_STRING: \ ++ case ASN1_ETYPE_GENERALSTRING: \ ++ case ASN1_ETYPE_NUMERIC_STRING: \ ++ case ASN1_ETYPE_IA5_STRING: \ ++ case ASN1_ETYPE_TELETEX_STRING: \ ++ case ASN1_ETYPE_PRINTABLE_STRING: \ ++ case ASN1_ETYPE_UNIVERSAL_STRING: \ ++ case ASN1_ETYPE_BMP_STRING: \ ++ case ASN1_ETYPE_UTF8_STRING: \ ++ case ASN1_ETYPE_VISIBLE_STRING: \ ++ case ASN1_ETYPE_BIT_STRING: \ ++ case ASN1_ETYPE_SEQUENCE: \ ++ case ASN1_ETYPE_SEQUENCE_OF: \ ++ case ASN1_ETYPE_SET: \ ++ case ASN1_ETYPE_UTC_TIME: \ ++ case ASN1_ETYPE_GENERALIZED_TIME: \ ++ case ASN1_ETYPE_SET_OF ++ ++# define ETYPE_TAG(etype) (_asn1_tags[etype].tag) ++# define ETYPE_CLASS(etype) (_asn1_tags[etype].class) ++# define ETYPE_OK(etype) (((etype) != ASN1_ETYPE_INVALID && \ ++ (etype) <= _asn1_tags_size && \ ++ _asn1_tags[(etype)].desc != NULL)?1:0) ++ ++# define ETYPE_IS_STRING(etype) ((etype == ASN1_ETYPE_GENERALSTRING || \ ++ etype == ASN1_ETYPE_NUMERIC_STRING || etype == ASN1_ETYPE_IA5_STRING || \ ++ etype == ASN1_ETYPE_TELETEX_STRING || etype == ASN1_ETYPE_PRINTABLE_STRING || \ ++ etype == ASN1_ETYPE_UNIVERSAL_STRING || etype == ASN1_ETYPE_BMP_STRING || \ ++ etype == ASN1_ETYPE_UTF8_STRING || etype == ASN1_ETYPE_VISIBLE_STRING || \ ++ etype == ASN1_ETYPE_OCTET_STRING)?1:0) ++ ++extern unsigned int _asn1_tags_size; ++extern const tag_and_class_st _asn1_tags[]; ++ ++# define _asn1_strlen(s) strlen((const char *) s) ++# define _asn1_strtol(n,e,b) strtol((const char *) n, e, b) ++# define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b) ++# define _asn1_strcmp(a,b) strcmp((const char *)a, (const char *)b) ++# define _asn1_strcpy(a,b) strcpy((char *)a, (const char *)b) ++# define _asn1_strcat(a,b) strcat((char *)a, (const char *)b) ++ ++# if SIZEOF_UNSIGNED_LONG_INT == 8 ++# define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b) ++# else ++# define _asn1_strtou64(n,e,b) strtoull((const char *) n, e, b) ++# endif ++ ++# define MAX_LOG_SIZE 1024 /* maximum number of characters of a log message */ ++ ++/* Define used for visiting trees. */ ++# define UP 1 ++# define RIGHT 2 ++# define DOWN 3 ++ ++/***********************************************************************/ ++/* List of constants to better specify the type of typedef asn1_node_st. */ ++/***********************************************************************/ ++/* Used with TYPE_TAG */ ++# define CONST_UNIVERSAL (1U<<8) ++# define CONST_PRIVATE (1U<<9) ++# define CONST_APPLICATION (1U<<10) ++# define CONST_EXPLICIT (1U<<11) ++# define CONST_IMPLICIT (1U<<12) ++ ++# define CONST_TAG (1U<<13) /* Used in ASN.1 assignement */ ++# define CONST_OPTION (1U<<14) ++# define CONST_DEFAULT (1U<<15) ++# define CONST_TRUE (1U<<16) ++# define CONST_FALSE (1U<<17) ++ ++# define CONST_LIST (1U<<18) /* Used with TYPE_INTEGER and TYPE_BIT_STRING */ ++# define CONST_MIN_MAX (1U<<19) ++ ++# define CONST_1_PARAM (1U<<20) ++ ++# define CONST_SIZE (1U<<21) ++ ++# define CONST_DEFINED_BY (1U<<22) ++ ++/* Those two are deprecated and used for backwards compatibility */ ++# define CONST_GENERALIZED (1U<<23) ++# define CONST_UTC (1U<<24) ++ ++/* #define CONST_IMPORTS (1U<<25) */ ++ ++# define CONST_NOT_USED (1U<<26) ++# define CONST_SET (1U<<27) ++# define CONST_ASSIGN (1U<<28) ++ ++# define CONST_DOWN (1U<<29) ++# define CONST_RIGHT (1U<<30) ++ ++ ++# define ASN1_ETYPE_TIME 17 ++/****************************************/ ++/* Returns the first 8 bits. */ ++/* Used with the field type of asn1_node_st */ ++/****************************************/ ++inline static unsigned int ++type_field (unsigned int ntype) ++{ ++ return (ntype & 0xff); ++} ++ ++/* To convert old types from a static structure */ ++inline static unsigned int ++convert_old_type (unsigned int ntype) ++{ ++ unsigned int type = ntype & 0xff; ++ if (type == ASN1_ETYPE_TIME) ++ { ++ if (ntype & CONST_UTC) ++ type = ASN1_ETYPE_UTC_TIME; ++ else ++ type = ASN1_ETYPE_GENERALIZED_TIME; ++ ++ ntype &= ~(CONST_UTC | CONST_GENERALIZED); ++ ntype &= 0xffffff00; ++ ntype |= type; ++ ++ return ntype; ++ } ++ else ++ return ntype; ++} ++ ++static inline void * ++_asn1_realloc (void *ptr, size_t size) ++{ ++ void *ret; ++ ++ if (size == 0) ++ return ptr; ++ ++ ret = realloc (ptr, size); ++ if (ret == NULL) ++ { ++ free (ptr); ++ } ++ return ret; ++} ++ ++#endif /* INT_H */ +--- /dev/null ++++ b/grub-core/lib/libtasn1/lib/parser_aux.c +@@ -0,0 +1,1178 @@ ++/* ++ * Copyright (C) 2000-2021 Free Software Foundation, Inc. ++ * ++ * This file is part of LIBTASN1. ++ * ++ * The LIBTASN1 library is free software; you can redistribute it ++ * and/or modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library 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 ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ */ ++ ++#include // WORD_BIT ++ ++#include "int.h" ++#include "parser_aux.h" ++#include "gstr.h" ++#include "structure.h" ++#include "element.h" ++#include "c-ctype.h" ++ ++char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not found */ ++ ++/* Return a hash of the N bytes of X using the method described by ++ Bruno Haible in https://www.haible.de/bruno/hashfunc.html. ++ Note that while many hash functions reduce their result via modulo ++ to a 0..table_size-1 range, this function does not do that. ++ ++ This implementation has been changed from size_t -> unsigned int. */ ++ ++#ifdef __clang__ ++__attribute__((no_sanitize ("integer"))) ++#endif ++ _GL_ATTRIBUTE_PURE static unsigned int _asn1_hash_name (const char *x) ++{ ++ const unsigned char *s = (unsigned char *) x; ++ unsigned h = 0; ++ ++ while (*s) ++ h = (*s++) + ((h << 9) | (h >> (WORD_BIT - 9))); ++ ++ return h; ++} ++ ++/******************************************************/ ++/* Function : _asn1_add_static_node */ ++/* Description: creates a new NODE_ASN element and */ ++/* puts it in the list pointed by e_list. */ ++/* Parameters: */ ++/* e_list: of type list_type; must be NULL initially */ ++/* type: type of the new element (see ASN1_ETYPE_ */ ++/* and CONST_ constants). */ ++/* Return: pointer to the new element. */ ++/******************************************************/ ++asn1_node ++_asn1_add_static_node (list_type ** e_list, unsigned int type) ++{ ++ list_type *p; ++ asn1_node punt; ++ ++ punt = calloc (1, sizeof (struct asn1_node_st)); ++ if (punt == NULL) ++ return NULL; ++ ++ p = malloc (sizeof (list_type)); ++ if (p == NULL) ++ { ++ free (punt); ++ return NULL; ++ } ++ ++ p->node = punt; ++ p->next = *e_list; ++ *e_list = p; ++ ++ punt->type = type; ++ ++ return punt; ++} ++ ++static int ++_asn1_add_static_node2 (list_type ** e_list, asn1_node node) ++{ ++ list_type *p; ++ ++ p = malloc (sizeof (list_type)); ++ if (p == NULL) ++ { ++ return -1; ++ } ++ ++ p->node = node; ++ p->next = *e_list; ++ *e_list = p; ++ ++ return 0; ++} ++ ++/** ++ * asn1_find_node: ++ * @pointer: NODE_ASN element pointer. ++ * @name: null terminated string with the element's name to find. ++ * ++ * Searches for an element called @name starting from @pointer. The ++ * name is composed by different identifiers separated by dots. When ++ * *@pointer has a name, the first identifier must be the name of ++ * *@pointer, otherwise it must be the name of one child of *@pointer. ++ * ++ * Returns: the search result, or %NULL if not found. ++ **/ ++asn1_node ++asn1_find_node (asn1_node_const pointer, const char *name) ++{ ++ asn1_node_const p; ++ char *n_end, n[ASN1_MAX_NAME_SIZE + 1]; ++ const char *n_start; ++ unsigned int nsize; ++ unsigned int nhash; ++ ++ if (pointer == NULL) ++ return NULL; ++ ++ if (name == NULL) ++ return NULL; + + p = pointer; + n_start = name; + + if (name[0] == '?' && name[1] == 'C' && p->name[0] == '?') -+ { /* ?CURRENT */ -+ n_start = strchr(n_start, '.'); ++ { /* ?CURRENT */ ++ n_start = strchr (n_start, '.'); + if (n_start) -+ n_start++; ++ n_start++; + } + else if (p->name[0] != 0) + { /* has *pointer got a name ? */ @@ -5416,8 +5871,8 @@ index 00000000000..d5dbbf8765d + if (n_end) + { + nsize = n_end - n_start; -+ if (nsize >= sizeof(n)) -+ return NULL; ++ if (nsize >= sizeof (n)) ++ return NULL; + + memcpy (n, n_start, nsize); + n[nsize] = 0; @@ -5457,8 +5912,8 @@ index 00000000000..d5dbbf8765d + if (n_end) + { + nsize = n_end - n_start; -+ if (nsize >= sizeof(n)) -+ return NULL; ++ if (nsize >= sizeof (n)) ++ return NULL; + + memcpy (n, n_start, nsize); + n[nsize] = 0; @@ -5479,11 +5934,11 @@ index 00000000000..d5dbbf8765d + + p = p->down; + if (p == NULL) -+ return NULL; ++ return NULL; + + /* The identifier "?LAST" indicates the last element + in the right chain. */ -+ if (n[0] == '?' && n[1] == 'L') /* ?LAST */ ++ if (n[0] == '?' && n[1] == 'L') /* ?LAST */ + { + while (p->right) + p = p->right; @@ -5499,7 +5954,7 @@ index 00000000000..d5dbbf8765d + } + } + if (p == NULL) -+ return NULL; ++ return NULL; + } /* while */ + + return (asn1_node) p; @@ -5638,13 +6093,13 @@ index 00000000000..d5dbbf8765d + } + + if (prev_len > 0) -+ memcpy (node->value, node->small_value, prev_len); ++ memcpy (node->value, node->small_value, prev_len); + + memcpy (&node->value[prev_len], value, len); + + return node; + } -+ else /* if (node->value != NULL && node->value != node->small_value) */ ++ else /* if (node->value != NULL && node->value != node->small_value) */ + { + /* value is allocated */ + int prev_len = node->value_len; @@ -5770,12 +6225,12 @@ index 00000000000..d5dbbf8765d + if (node->value != NULL) + { + if (flags & ASN1_DELETE_FLAG_ZEROIZE) -+ { -+ safe_memset(node->value, 0, node->value_len); -+ } ++ { ++ safe_memset (node->value, 0, node->value_len); ++ } + + if (node->value != node->small_value) -+ free (node->value); ++ free (node->value); + } + free (node); +} @@ -5803,8 +6258,8 @@ index 00000000000..d5dbbf8765d + return p->left; +} + -+static -+unsigned _asn1_is_up (asn1_node_const up_cand, asn1_node_const down) ++static unsigned ++_asn1_is_up (asn1_node_const up_cand, asn1_node_const down) +{ + asn1_node_const d, u; + @@ -5813,10 +6268,10 @@ index 00000000000..d5dbbf8765d + + d = down; + -+ while ((u = _asn1_find_up(d)) != NULL && u != d) ++ while ((u = _asn1_find_up (d)) != NULL && u != d) + { + if (u == up_cand) -+ return 1; ++ return 1; + d = u; + } + @@ -5828,14 +6283,14 @@ index 00000000000..d5dbbf8765d +/* Description: deletes the list element given */ +/******************************************************************/ +void -+_asn1_delete_node_from_list (list_type *list, asn1_node node) ++_asn1_delete_node_from_list (list_type * list, asn1_node node) +{ + list_type *p = list; + + while (p) + { + if (p->node == node) -+ p->node = NULL; ++ p->node = NULL; + p = p->next; + } +} @@ -5846,7 +6301,7 @@ index 00000000000..d5dbbf8765d +/* pointed by them). */ +/******************************************************************/ +void -+_asn1_delete_list (list_type *e_list) ++_asn1_delete_list (list_type * e_list) +{ + list_type *p; + @@ -5864,7 +6319,7 @@ index 00000000000..d5dbbf8765d +/* pointed by them. */ +/******************************************************************/ +void -+_asn1_delete_list_and_nodes (list_type *e_list) ++_asn1_delete_list_and_nodes (list_type * e_list) +{ + list_type *p; + @@ -5890,7 +6345,7 @@ index 00000000000..d5dbbf8765d + { + str[0] = '-'; + start = 1; -+ val = -((uint64_t)v); ++ val = -((uint64_t) v); + } + else + { @@ -5907,7 +6362,7 @@ index 00000000000..d5dbbf8765d + count++; + val = d; + } -+ while (val && ((start+count) < LTOSTR_MAX_SIZE-1)); ++ while (val && ((start + count) < LTOSTR_MAX_SIZE - 1)); + + for (k = 0; k < count; k++) + str[k + start] = temp[start + count - k - 1]; @@ -5996,7 +6451,7 @@ index 00000000000..d5dbbf8765d +/* otherwise ASN1_SUCCESS */ +/******************************************************************/ +int -+_asn1_expand_object_id (list_type **list, asn1_node node) ++_asn1_expand_object_id (list_type ** list, asn1_node node) +{ + asn1_node p, p2, p3, p4, p5; + char name_root[ASN1_MAX_NAME_SIZE], name2[2 * ASN1_MAX_NAME_SIZE + 1]; @@ -6026,9 +6481,10 @@ index 00000000000..d5dbbf8765d + { + _asn1_str_cpy (name2, sizeof (name2), name_root); + _asn1_str_cat (name2, sizeof (name2), "."); -+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); ++ _asn1_str_cat (name2, sizeof (name2), ++ (char *) p2->value); + p3 = asn1_find_node (node, name2); -+ if (!p3 || _asn1_is_up(p2, p3) || ++ if (!p3 || _asn1_is_up (p2, p3) || + (type_field (p3->type) != ASN1_ETYPE_OBJECT_ID) || + !(p3->type & CONST_ASSIGN)) + return ASN1_ELEMENT_NOT_FOUND; @@ -6036,7 +6492,7 @@ index 00000000000..d5dbbf8765d + _asn1_set_down (p, p2->right); + if (p2->down) + _asn1_delete_structure (*list, &p2->down, 0); -+ _asn1_delete_node_from_list(*list, p2); ++ _asn1_delete_node_from_list (*list, p2); + _asn1_remove_node (p2, 0); + p2 = p; + p4 = p3->down; @@ -6047,18 +6503,18 @@ index 00000000000..d5dbbf8765d + { + max_constants++; + if (max_constants == MAX_CONSTANTS) -+ return ASN1_RECURSION; ++ return ASN1_RECURSION; + + p5 = + _asn1_add_single_node (ASN1_ETYPE_CONSTANT); + _asn1_set_name (p5, p4->name); + if (p4->value) -+ { -+ tlen = _asn1_strlen (p4->value); -+ if (tlen > 0) -+ _asn1_set_value (p5, p4->value, tlen + 1); -+ } -+ _asn1_add_static_node2(list, p5); ++ { ++ tlen = _asn1_strlen (p4->value); ++ if (tlen > 0) ++ _asn1_set_value (p5, p4->value, tlen + 1); ++ } ++ _asn1_add_static_node2 (list, p5); + + if (p2 == p) + { @@ -6077,8 +6533,8 @@ index 00000000000..d5dbbf8765d + move = DOWN; + + tries++; -+ if (tries >= EXPAND_OBJECT_ID_MAX_RECURSION) -+ return ASN1_RECURSION; ++ if (tries >= EXPAND_OBJECT_ID_MAX_RECURSION) ++ return ASN1_RECURSION; + + continue; + } @@ -6298,7 +6754,9 @@ index 00000000000..d5dbbf8765d + if (p2 == NULL) + { + if (p->value) -+ _asn1_str_cpy (_asn1_identifierMissing, sizeof(_asn1_identifierMissing), (char*)p->value); ++ _asn1_str_cpy (_asn1_identifierMissing, ++ sizeof (_asn1_identifierMissing), ++ (char *) p->value); + else + _asn1_strcpy (_asn1_identifierMissing, "(null)"); + return ASN1_IDENTIFIER_NOT_FOUND; @@ -6312,11 +6770,13 @@ index 00000000000..d5dbbf8765d + { + _asn1_str_cpy (name2, sizeof (name2), node->name); + if (p2->value) -+ { -+ _asn1_str_cat (name2, sizeof (name2), "."); -+ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); -+ _asn1_str_cpy (_asn1_identifierMissing, sizeof(_asn1_identifierMissing), (char*)p2->value); -+ } ++ { ++ _asn1_str_cat (name2, sizeof (name2), "."); ++ _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); ++ _asn1_str_cpy (_asn1_identifierMissing, ++ sizeof (_asn1_identifierMissing), ++ (char *) p2->value); ++ } + else + _asn1_strcpy (_asn1_identifierMissing, "(null)"); + @@ -6339,7 +6799,9 @@ index 00000000000..d5dbbf8765d + _asn1_str_cpy (name2, sizeof (name2), node->name); + _asn1_str_cat (name2, sizeof (name2), "."); + _asn1_str_cat (name2, sizeof (name2), (char *) p2->value); -+ _asn1_str_cpy (_asn1_identifierMissing, sizeof(_asn1_identifierMissing), (char*)p2->value); ++ _asn1_str_cpy (_asn1_identifierMissing, ++ sizeof (_asn1_identifierMissing), ++ (char *) p2->value); + + p2 = asn1_find_node (node, name2); + if (!p2 || (type_field (p2->type) != ASN1_ETYPE_OBJECT_ID) @@ -6438,14 +6900,11 @@ index 00000000000..d5dbbf8765d + + return ASN1_SUCCESS; +} -diff --git a/grub-core/lib/libtasn1/lib/structure.c b/grub-core/lib/libtasn1/lib/structure.c -new file mode 100644 -index 00000000000..8189c56a4c9 --- /dev/null -+++ b/grub-core/lib/libtasn1/lib/structure.c -@@ -0,0 +1,1220 @@ ++++ b/grub-core/lib/libtasn1/lib/parser_aux.h +@@ -0,0 +1,172 @@ +/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. ++ * Copyright (C) 2000-2021 Free Software Foundation, Inc. + * + * This file is part of LIBTASN1. + * @@ -6465,15 +6924,190 @@ index 00000000000..8189c56a4c9 + * 02110-1301, USA + */ + ++#ifndef _PARSER_AUX_H ++# define _PARSER_AUX_H + -+/*****************************************************/ -+/* File: structure.c */ -+/* Description: Functions to create and delete an */ -+/* ASN1 tree. */ -+/*****************************************************/ -+ -+ -+#include ++/***********************************************/ ++/* Type: list_type */ ++/* Description: type used in the list during */ ++/* the structure creation. */ ++/***********************************************/ ++typedef struct list_struct ++{ ++ asn1_node node; ++ struct list_struct *next; ++} list_type; ++ ++/***************************************/ ++/* Functions used by ASN.1 parser */ ++/***************************************/ ++asn1_node _asn1_add_static_node (list_type ** e_list, unsigned int type); ++ ++void _asn1_delete_list (list_type * e_list); ++ ++void _asn1_delete_list_and_nodes (list_type * e_list); ++ ++void _asn1_delete_node_from_list (list_type * list, asn1_node node); ++ ++asn1_node ++_asn1_set_value (asn1_node node, const void *value, unsigned int len); ++ ++asn1_node _asn1_set_value_m (asn1_node node, void *value, unsigned int len); ++ ++asn1_node ++_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len); ++ ++asn1_node ++_asn1_append_value (asn1_node node, const void *value, unsigned int len); ++ ++asn1_node _asn1_set_name (asn1_node node, const char *name); ++ ++asn1_node _asn1_cpy_name (asn1_node dst, asn1_node_const src); ++ ++asn1_node _asn1_set_right (asn1_node node, asn1_node right); ++ ++asn1_node _asn1_get_last_right (asn1_node_const node); ++ ++void _asn1_remove_node (asn1_node node, unsigned int flags); ++ ++/* Max 64-bit integer length is 20 chars + 1 for sign + 1 for null termination */ ++# define LTOSTR_MAX_SIZE 22 ++char *_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]); ++ ++asn1_node _asn1_find_up (asn1_node_const node); ++ ++int _asn1_change_integer_value (asn1_node node); ++ ++# define EXPAND_OBJECT_ID_MAX_RECURSION 16 ++int _asn1_expand_object_id (list_type ** list, asn1_node node); ++ ++int _asn1_type_set_config (asn1_node node); ++ ++int _asn1_check_identifier (asn1_node_const node); ++ ++int _asn1_set_default_tag (asn1_node node); ++ ++/******************************************************************/ ++/* Function : _asn1_get_right */ ++/* Description: returns the element pointed by the RIGHT field of */ ++/* a NODE_ASN element. */ ++/* Parameters: */ ++/* node: NODE_ASN element pointer. */ ++/* Return: field RIGHT of NODE. */ ++/******************************************************************/ ++inline static asn1_node ++_asn1_get_right (asn1_node_const node) ++{ ++ if (node == NULL) ++ return NULL; ++ return node->right; ++} ++ ++/******************************************************************/ ++/* Function : _asn1_set_down */ ++/* Description: sets the field DOWN in a NODE_ASN element. */ ++/* Parameters: */ ++/* node: element pointer. */ ++/* down: pointer to a NODE_ASN element that you want be pointed */ ++/* by NODE. */ ++/* Return: pointer to *NODE. */ ++/******************************************************************/ ++inline static asn1_node ++_asn1_set_down (asn1_node node, asn1_node down) ++{ ++ if (node == NULL) ++ return node; ++ node->down = down; ++ if (down) ++ down->left = node; ++ return node; ++} ++ ++/******************************************************************/ ++/* Function : _asn1_get_down */ ++/* Description: returns the element pointed by the DOWN field of */ ++/* a NODE_ASN element. */ ++/* Parameters: */ ++/* node: NODE_ASN element pointer. */ ++/* Return: field DOWN of NODE. */ ++/******************************************************************/ ++inline static asn1_node ++_asn1_get_down (asn1_node_const node) ++{ ++ if (node == NULL) ++ return NULL; ++ return node->down; ++} ++ ++/******************************************************************/ ++/* Function : _asn1_get_name */ ++/* Description: returns the name of a NODE_ASN element. */ ++/* Parameters: */ ++/* node: NODE_ASN element pointer. */ ++/* Return: a null terminated string. */ ++/******************************************************************/ ++inline static char * ++_asn1_get_name (asn1_node_const node) ++{ ++ if (node == NULL) ++ return NULL; ++ return (char *) node->name; ++} ++ ++/******************************************************************/ ++/* Function : _asn1_mod_type */ ++/* Description: change the field TYPE of an NODE_ASN element. */ ++/* The new value is the old one | (bitwise or) the */ ++/* paramener VALUE. */ ++/* Parameters: */ ++/* node: NODE_ASN element pointer. */ ++/* value: the integer value that must be or-ed with the current */ ++/* value of field TYPE. */ ++/* Return: NODE pointer. */ ++/******************************************************************/ ++inline static asn1_node ++_asn1_mod_type (asn1_node node, unsigned int value) ++{ ++ if (node == NULL) ++ return node; ++ node->type |= value; ++ return node; ++} ++ ++#endif +--- /dev/null ++++ b/grub-core/lib/libtasn1/lib/structure.c +@@ -0,0 +1,1225 @@ ++/* ++ * Copyright (C) 2002-2021 Free Software Foundation, Inc. ++ * ++ * This file is part of LIBTASN1. ++ * ++ * The LIBTASN1 library is free software; you can redistribute it ++ * and/or modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * This library 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 ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with this library; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301, USA ++ */ ++ ++ ++/*****************************************************/ ++/* File: structure.c */ ++/* Description: Functions to create and delete an */ ++/* ASN1 tree. */ ++/*****************************************************/ ++ ++ ++#include +#include +#include "parser_aux.h" +#include @@ -6524,8 +7158,8 @@ index 00000000000..8189c56a4c9 + + +int -+_asn1_create_static_structure (asn1_node_const pointer, char *output_file_name, -+ char *vector_name) ++_asn1_create_static_structure (asn1_node_const pointer, ++ char *output_file_name, char *vector_name) +{ + FILE *file; + asn1_node_const p; @@ -6654,15 +7288,15 @@ index 00000000000..8189c56a4c9 + if (move == DOWN) + { + if (p_last && p_last->down) -+ _asn1_delete_structure (e_list, &p_last->down, 0); ++ _asn1_delete_structure (e_list, &p_last->down, 0); + _asn1_set_down (p_last, p); + } + else if (move == RIGHT) -+ { ++ { + if (p_last && p_last->right) -+ _asn1_delete_structure (e_list, &p_last->right, 0); ++ _asn1_delete_structure (e_list, &p_last->right, 0); + _asn1_set_right (p_last, p); -+ } ++ } + + p_last = p; + @@ -6745,7 +7379,7 @@ index 00000000000..8189c56a4c9 +/** + * asn1_delete_structure2: + * @structure: pointer to the structure that you want to delete. -+ * @flags: additional flags (see %ASN1_DELETE_FLAG) ++ * @flags: additional flags (see %ASN1_DELETE_FLAG_ZEROIZE) + * + * Deletes the structure *@structure. At the end, *@structure is set + * to NULL. @@ -6760,7 +7394,8 @@ index 00000000000..8189c56a4c9 +} + +int -+_asn1_delete_structure (list_type *e_list, asn1_node * structure, unsigned int flags) ++_asn1_delete_structure (list_type * e_list, asn1_node * structure, ++ unsigned int flags) +{ + asn1_node p, p2, p3; + @@ -6864,6 +7499,8 @@ index 00000000000..8189c56a4c9 + return NULL; + + dest_node = _asn1_add_single_node (source_node->type); ++ if (dest_node == NULL) ++ return dest_node; + + p_s = source_node; + p_d = dest_node; @@ -7336,7 +7973,8 @@ index 00000000000..8189c56a4c9 + fprintf (out, " value(%i):", + (len - 1) * 8 - (p->value[len2])); + for (k = 1; k < len; k++) -+ fprintf (out, "%02x", (unsigned) (p->value)[k + len2]); ++ fprintf (out, "%02x", ++ (unsigned) (p->value)[k + len2]); + } + } + break; @@ -7558,7 +8196,8 @@ index 00000000000..8189c56a4c9 + * the OID. + **/ +const char * -+asn1_find_structure_from_oid (asn1_node_const definitions, const char *oidValue) ++asn1_find_structure_from_oid (asn1_node_const definitions, ++ const char *oidValue) +{ + char name[2 * ASN1_MAX_NAME_SIZE + 2]; + char value[ASN1_MAX_NAME_SIZE]; @@ -7579,7 +8218,7 @@ index 00000000000..8189c56a4c9 + if ((type_field (p->type) == ASN1_ETYPE_OBJECT_ID) && + (p->type & CONST_ASSIGN)) + { -+ snprintf(name, sizeof(name), "%s.%s", definitionsName, p->name); ++ snprintf (name, sizeof (name), "%s.%s", definitionsName, p->name); + + len = ASN1_MAX_NAME_SIZE; + result = asn1_read_value (definitions, name, value, &len); @@ -7662,16 +8301,13 @@ index 00000000000..8189c56a4c9 +asn1_node +asn1_dup_node (asn1_node_const src, const char *src_name) +{ -+ return _asn1_copy_structure2(src, src_name); ++ return _asn1_copy_structure2 (src, src_name); +} -diff --git a/grub-core/lib/libtasn1/lib/element.h b/grub-core/lib/libtasn1/lib/element.h -new file mode 100644 -index 00000000000..440a33f4bb1 --- /dev/null -+++ b/grub-core/lib/libtasn1/lib/element.h -@@ -0,0 +1,40 @@ ++++ b/grub-core/lib/libtasn1/lib/structure.h +@@ -0,0 +1,46 @@ +/* -+ * Copyright (C) 2000-2014 Free Software Foundation, Inc. ++ * Copyright (C) 2002-2021 Free Software Foundation, Inc. + * + * This file is part of LIBTASN1. + * @@ -7691,720 +8327,210 @@ index 00000000000..440a33f4bb1 + * 02110-1301, USA + */ + -+#ifndef _ELEMENT_H -+#define _ELEMENT_H ++/*************************************************/ ++/* File: structure.h */ ++/* Description: list of exported object by */ ++/* "structure.c" */ ++/*************************************************/ + ++#ifndef _STRUCTURE_H ++# define _STRUCTURE_H + -+struct node_tail_cache_st -+{ -+ asn1_node head; /* the first element of the sequence */ -+ asn1_node tail; -+}; ++# include "parser_aux.h" // list_type + -+int _asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcached); ++int _asn1_create_static_structure (asn1_node_const pointer, ++ char *output_file_name, char *vector_name); + -+int _asn1_convert_integer (const unsigned char *value, -+ unsigned char *value_out, -+ int value_out_size, int *len); ++asn1_node _asn1_copy_structure3 (asn1_node_const source_node); ++ ++asn1_node _asn1_add_single_node (unsigned int type); + -+void _asn1_hierarchical_name (asn1_node_const node, char *name, int name_size); ++asn1_node _asn1_find_left (asn1_node_const node); ++ ++int ++_asn1_delete_structure (list_type * e_list, asn1_node * structure, ++ unsigned int flags); + +#endif -diff --git a/grub-core/lib/libtasn1/lib/gstr.h b/grub-core/lib/libtasn1/lib/gstr.h -new file mode 100644 -index 00000000000..48229844ff3 --- /dev/null -+++ b/grub-core/lib/libtasn1/lib/gstr.h -@@ -0,0 +1,47 @@ ++++ b/include/grub/libtasn1.h +@@ -0,0 +1,639 @@ +/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. ++ * Copyright (C) 2002-2021 Free Software Foundation, Inc. + * + * This file is part of LIBTASN1. + * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. ++ * LIBTASN1 is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU Lesser General Public License as ++ * published by the Free Software Foundation; either version 2.1 of ++ * the License, or (at your option) any later version. + * -+ * This library is distributed in the hope that it will be useful, but ++ * LIBTASN1 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software ++ * License along with LIBTASN1; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA ++ * + */ + -+#ifndef GSTR_H -+# define GSTR_H ++/** ++ * SECTION:libtasn1 ++ * @short_description: GNU ASN.1 library ++ * ++ * The Libtasn1 library provides Abstract Syntax Notation One (ASN.1, as ++ * specified by the X.680 ITU-T recommendation) parsing and structures ++ * management, and Distinguished Encoding Rules (DER, as per X.690) ++ * encoding and decoding functions. ++ */ + -+unsigned int _asn1_str_cpy (char *dest, size_t dest_tot_size, -+ const char *src); -+void _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src); + -+#define Estrcpy(x,y) _asn1_str_cpy(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y) -+#define Estrcat(x,y) _asn1_str_cat(x,ASN1_MAX_ERROR_DESCRIPTION_SIZE,y) ++#ifndef LIBTASN1_H ++# define LIBTASN1_H ++ ++# ifndef ASN1_API ++# if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY ++# define ASN1_API __attribute__((__visibility__("default"))) ++# elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC ++# define ASN1_API __declspec(dllexport) ++# elif defined _MSC_VER && ! defined ASN1_STATIC ++# define ASN1_API __declspec(dllimport) ++# else ++# define ASN1_API ++# endif ++# endif + -+inline static -+void safe_memset(void *data, int c, size_t size) -+{ -+ volatile unsigned volatile_zero = 0; -+ volatile char *vdata = (volatile char*)data; ++# ifdef __GNUC__ ++# define __LIBTASN1_CONST__ __attribute__((const)) ++# define __LIBTASN1_PURE__ __attribute__((pure)) ++# else ++# define __LIBTASN1_CONST__ ++# define __LIBTASN1_PURE__ ++# endif + -+ /* This is based on a nice trick for safe memset, -+ * sent by David Jacobson in the openssl-dev mailing list. -+ */ ++# include ++# include ++# include /* for FILE* */ + -+ if (size > 0) do { -+ memset(data, c, size); -+ } while(vdata[volatile_zero] != c); -+} ++# ifdef __cplusplus ++extern "C" ++{ ++# endif + -+#endif /* GSTR_H */ -diff --git a/grub-core/lib/libtasn1/lib/int.h b/grub-core/lib/libtasn1/lib/int.h -new file mode 100644 -index 00000000000..ea1625786c1 ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/int.h -@@ -0,0 +1,221 @@ -+/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. ++/** ++ * ASN1_VERSION: + * -+ * This file is part of LIBTASN1. ++ * Version of the library as a string. ++ */ ++# define ASN1_VERSION "4.18.0" ++ ++/** ++ * ASN1_VERSION_MAJOR: + * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library 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 -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+#ifndef INT_H -+#define INT_H -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+ -+#ifdef HAVE_SYS_TYPES_H -+#include -+#endif -+ -+#include -+ -+#define ASN1_SMALL_VALUE_SIZE 16 -+ -+/* This structure is also in libtasn1.h, but then contains less -+ fields. You cannot make any modifications to these first fields -+ without breaking ABI. */ -+struct asn1_node_st -+{ -+ /* public fields: */ -+ char name[ASN1_MAX_NAME_SIZE + 1]; /* Node name */ -+ unsigned int name_hash; -+ unsigned int type; /* Node type */ -+ unsigned char *value; /* Node value */ -+ int value_len; -+ asn1_node down; /* Pointer to the son node */ -+ asn1_node right; /* Pointer to the brother node */ -+ asn1_node left; /* Pointer to the next list element */ -+ /* private fields: */ -+ unsigned char small_value[ASN1_SMALL_VALUE_SIZE]; /* For small values */ -+ -+ /* values used during decoding/coding */ -+ int tmp_ival; -+ unsigned start; /* the start of the DER sequence - if decoded */ -+ unsigned end; /* the end of the DER sequence - if decoded */ -+}; -+ -+typedef struct tag_and_class_st -+{ -+ unsigned tag; -+ unsigned class; -+ const char *desc; -+} tag_and_class_st; -+ -+/* the types that are handled in _asn1_tags */ -+#define CASE_HANDLED_ETYPES \ -+ case ASN1_ETYPE_NULL: \ -+ case ASN1_ETYPE_BOOLEAN: \ -+ case ASN1_ETYPE_INTEGER: \ -+ case ASN1_ETYPE_ENUMERATED: \ -+ case ASN1_ETYPE_OBJECT_ID: \ -+ case ASN1_ETYPE_OCTET_STRING: \ -+ case ASN1_ETYPE_GENERALSTRING: \ -+ case ASN1_ETYPE_NUMERIC_STRING: \ -+ case ASN1_ETYPE_IA5_STRING: \ -+ case ASN1_ETYPE_TELETEX_STRING: \ -+ case ASN1_ETYPE_PRINTABLE_STRING: \ -+ case ASN1_ETYPE_UNIVERSAL_STRING: \ -+ case ASN1_ETYPE_BMP_STRING: \ -+ case ASN1_ETYPE_UTF8_STRING: \ -+ case ASN1_ETYPE_VISIBLE_STRING: \ -+ case ASN1_ETYPE_BIT_STRING: \ -+ case ASN1_ETYPE_SEQUENCE: \ -+ case ASN1_ETYPE_SEQUENCE_OF: \ -+ case ASN1_ETYPE_SET: \ -+ case ASN1_ETYPE_UTC_TIME: \ -+ case ASN1_ETYPE_GENERALIZED_TIME: \ -+ case ASN1_ETYPE_SET_OF -+ -+#define ETYPE_TAG(etype) (_asn1_tags[etype].tag) -+#define ETYPE_CLASS(etype) (_asn1_tags[etype].class) -+#define ETYPE_OK(etype) (((etype) != ASN1_ETYPE_INVALID && \ -+ (etype) <= _asn1_tags_size && \ -+ _asn1_tags[(etype)].desc != NULL)?1:0) -+ -+#define ETYPE_IS_STRING(etype) ((etype == ASN1_ETYPE_GENERALSTRING || \ -+ etype == ASN1_ETYPE_NUMERIC_STRING || etype == ASN1_ETYPE_IA5_STRING || \ -+ etype == ASN1_ETYPE_TELETEX_STRING || etype == ASN1_ETYPE_PRINTABLE_STRING || \ -+ etype == ASN1_ETYPE_UNIVERSAL_STRING || etype == ASN1_ETYPE_BMP_STRING || \ -+ etype == ASN1_ETYPE_UTF8_STRING || etype == ASN1_ETYPE_VISIBLE_STRING || \ -+ etype == ASN1_ETYPE_OCTET_STRING)?1:0) -+ -+extern unsigned int _asn1_tags_size; -+extern const tag_and_class_st _asn1_tags[]; -+ -+#define _asn1_strlen(s) strlen((const char *) s) -+#define _asn1_strtol(n,e,b) strtol((const char *) n, e, b) -+#define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b) -+#define _asn1_strcmp(a,b) strcmp((const char *)a, (const char *)b) -+#define _asn1_strcpy(a,b) strcpy((char *)a, (const char *)b) -+#define _asn1_strcat(a,b) strcat((char *)a, (const char *)b) -+ -+#if SIZEOF_UNSIGNED_LONG_INT == 8 -+# define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b) -+#else -+# define _asn1_strtou64(n,e,b) strtoull((const char *) n, e, b) -+#endif -+ -+#define MAX_LOG_SIZE 1024 /* maximum number of characters of a log message */ -+ -+/* Define used for visiting trees. */ -+#define UP 1 -+#define RIGHT 2 -+#define DOWN 3 -+ -+/***********************************************************************/ -+/* List of constants to better specify the type of typedef asn1_node_st. */ -+/***********************************************************************/ -+/* Used with TYPE_TAG */ -+#define CONST_UNIVERSAL (1U<<8) -+#define CONST_PRIVATE (1U<<9) -+#define CONST_APPLICATION (1U<<10) -+#define CONST_EXPLICIT (1U<<11) -+#define CONST_IMPLICIT (1U<<12) -+ -+#define CONST_TAG (1U<<13) /* Used in ASN.1 assignement */ -+#define CONST_OPTION (1U<<14) -+#define CONST_DEFAULT (1U<<15) -+#define CONST_TRUE (1U<<16) -+#define CONST_FALSE (1U<<17) -+ -+#define CONST_LIST (1U<<18) /* Used with TYPE_INTEGER and TYPE_BIT_STRING */ -+#define CONST_MIN_MAX (1U<<19) -+ -+#define CONST_1_PARAM (1U<<20) -+ -+#define CONST_SIZE (1U<<21) -+ -+#define CONST_DEFINED_BY (1U<<22) -+ -+/* Those two are deprecated and used for backwards compatibility */ -+#define CONST_GENERALIZED (1U<<23) -+#define CONST_UTC (1U<<24) -+ -+/* #define CONST_IMPORTS (1U<<25) */ -+ -+#define CONST_NOT_USED (1U<<26) -+#define CONST_SET (1U<<27) -+#define CONST_ASSIGN (1U<<28) -+ -+#define CONST_DOWN (1U<<29) -+#define CONST_RIGHT (1U<<30) -+ -+ -+#define ASN1_ETYPE_TIME 17 -+/****************************************/ -+/* Returns the first 8 bits. */ -+/* Used with the field type of asn1_node_st */ -+/****************************************/ -+inline static unsigned int -+type_field (unsigned int ntype) -+{ -+ return (ntype & 0xff); -+} -+ -+/* To convert old types from a static structure */ -+inline static unsigned int -+convert_old_type (unsigned int ntype) -+{ -+ unsigned int type = ntype & 0xff; -+ if (type == ASN1_ETYPE_TIME) -+ { -+ if (ntype & CONST_UTC) -+ type = ASN1_ETYPE_UTC_TIME; -+ else -+ type = ASN1_ETYPE_GENERALIZED_TIME; -+ -+ ntype &= ~(CONST_UTC | CONST_GENERALIZED); -+ ntype &= 0xffffff00; -+ ntype |= type; -+ -+ return ntype; -+ } -+ else -+ return ntype; -+} -+ -+static inline -+void *_asn1_realloc(void *ptr, size_t size) -+{ -+ void *ret; -+ -+ if (size == 0) -+ return ptr; -+ -+ ret = realloc(ptr, size); -+ if (ret == NULL) -+ { -+ free(ptr); -+ } -+ return ret; -+} -+ -+#endif /* INT_H */ -diff --git a/grub-core/lib/libtasn1/lib/parser_aux.h b/grub-core/lib/libtasn1/lib/parser_aux.h -new file mode 100644 -index 00000000000..598e684b355 ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/parser_aux.h -@@ -0,0 +1,172 @@ -+/* -+ * Copyright (C) 2000-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library 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 -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+#ifndef _PARSER_AUX_H -+#define _PARSER_AUX_H -+ -+/***********************************************/ -+/* Type: list_type */ -+/* Description: type used in the list during */ -+/* the structure creation. */ -+/***********************************************/ -+typedef struct list_struct -+{ -+ asn1_node node; -+ struct list_struct *next; -+} list_type; -+ -+/***************************************/ -+/* Functions used by ASN.1 parser */ -+/***************************************/ -+asn1_node _asn1_add_static_node (list_type **e_list, unsigned int type); -+ -+void _asn1_delete_list (list_type *e_list); -+ -+void _asn1_delete_list_and_nodes (list_type *e_list); -+ -+void _asn1_delete_node_from_list (list_type *list, asn1_node node); -+ -+asn1_node -+_asn1_set_value (asn1_node node, const void *value, unsigned int len); -+ -+asn1_node _asn1_set_value_m (asn1_node node, void *value, unsigned int len); -+ -+asn1_node -+_asn1_set_value_lv (asn1_node node, const void *value, unsigned int len); -+ -+asn1_node -+_asn1_append_value (asn1_node node, const void *value, unsigned int len); -+ -+asn1_node _asn1_set_name (asn1_node node, const char *name); -+ -+asn1_node _asn1_cpy_name (asn1_node dst, asn1_node_const src); -+ -+asn1_node _asn1_set_right (asn1_node node, asn1_node right); -+ -+asn1_node _asn1_get_last_right (asn1_node_const node); -+ -+void _asn1_remove_node (asn1_node node, unsigned int flags); -+ -+/* Max 64-bit integer length is 20 chars + 1 for sign + 1 for null termination */ -+#define LTOSTR_MAX_SIZE 22 -+char *_asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]); -+ -+asn1_node _asn1_find_up (asn1_node_const node); -+ -+int _asn1_change_integer_value (asn1_node node); -+ -+#define EXPAND_OBJECT_ID_MAX_RECURSION 16 -+int _asn1_expand_object_id (list_type **list, asn1_node node); -+ -+int _asn1_type_set_config (asn1_node node); -+ -+int _asn1_check_identifier (asn1_node_const node); -+ -+int _asn1_set_default_tag (asn1_node node); -+ -+/******************************************************************/ -+/* Function : _asn1_get_right */ -+/* Description: returns the element pointed by the RIGHT field of */ -+/* a NODE_ASN element. */ -+/* Parameters: */ -+/* node: NODE_ASN element pointer. */ -+/* Return: field RIGHT of NODE. */ -+/******************************************************************/ -+inline static asn1_node -+_asn1_get_right (asn1_node_const node) -+{ -+ if (node == NULL) -+ return NULL; -+ return node->right; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_set_down */ -+/* Description: sets the field DOWN in a NODE_ASN element. */ -+/* Parameters: */ -+/* node: element pointer. */ -+/* down: pointer to a NODE_ASN element that you want be pointed */ -+/* by NODE. */ -+/* Return: pointer to *NODE. */ -+/******************************************************************/ -+inline static asn1_node -+_asn1_set_down (asn1_node node, asn1_node down) -+{ -+ if (node == NULL) -+ return node; -+ node->down = down; -+ if (down) -+ down->left = node; -+ return node; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_get_down */ -+/* Description: returns the element pointed by the DOWN field of */ -+/* a NODE_ASN element. */ -+/* Parameters: */ -+/* node: NODE_ASN element pointer. */ -+/* Return: field DOWN of NODE. */ -+/******************************************************************/ -+inline static asn1_node -+_asn1_get_down (asn1_node_const node) -+{ -+ if (node == NULL) -+ return NULL; -+ return node->down; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_get_name */ -+/* Description: returns the name of a NODE_ASN element. */ -+/* Parameters: */ -+/* node: NODE_ASN element pointer. */ -+/* Return: a null terminated string. */ -+/******************************************************************/ -+inline static char * -+_asn1_get_name (asn1_node_const node) -+{ -+ if (node == NULL) -+ return NULL; -+ return (char *) node->name; -+} -+ -+/******************************************************************/ -+/* Function : _asn1_mod_type */ -+/* Description: change the field TYPE of an NODE_ASN element. */ -+/* The new value is the old one | (bitwise or) the */ -+/* paramener VALUE. */ -+/* Parameters: */ -+/* node: NODE_ASN element pointer. */ -+/* value: the integer value that must be or-ed with the current */ -+/* value of field TYPE. */ -+/* Return: NODE pointer. */ -+/******************************************************************/ -+inline static asn1_node -+_asn1_mod_type (asn1_node node, unsigned int value) -+{ -+ if (node == NULL) -+ return node; -+ node->type |= value; -+ return node; -+} -+ -+#endif -diff --git a/grub-core/lib/libtasn1/lib/structure.h b/grub-core/lib/libtasn1/lib/structure.h -new file mode 100644 -index 00000000000..99e685da07a ---- /dev/null -+++ b/grub-core/lib/libtasn1/lib/structure.h -@@ -0,0 +1,45 @@ -+/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * The LIBTASN1 library is free software; you can redistribute it -+ * and/or modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library 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 -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ */ -+ -+/*************************************************/ -+/* File: structure.h */ -+/* Description: list of exported object by */ -+/* "structure.c" */ -+/*************************************************/ -+ -+#ifndef _STRUCTURE_H -+#define _STRUCTURE_H -+ -+#include "parser_aux.h" // list_type -+ -+int _asn1_create_static_structure (asn1_node_const pointer, -+ char *output_file_name, char *vector_name); -+ -+asn1_node _asn1_copy_structure3 (asn1_node_const source_node); -+ -+asn1_node _asn1_add_single_node (unsigned int type); -+ -+asn1_node _asn1_find_left (asn1_node_const node); -+ -+int -+_asn1_delete_structure (list_type *e_list, asn1_node *structure, unsigned int flags); -+ -+#endif -diff --git a/include/grub/libtasn1.h b/include/grub/libtasn1.h -new file mode 100644 -index 00000000000..6fd7a30dc35 ---- /dev/null -+++ b/include/grub/libtasn1.h -@@ -0,0 +1,588 @@ -+/* -+ * Copyright (C) 2002-2014 Free Software Foundation, Inc. -+ * -+ * This file is part of LIBTASN1. -+ * -+ * LIBTASN1 is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU Lesser General Public License as -+ * published by the Free Software Foundation; either version 2.1 of -+ * the License, or (at your option) any later version. -+ * -+ * LIBTASN1 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 -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with LIBTASN1; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -+ * 02110-1301, USA -+ * -+ */ -+ -+/** -+ * libtasn1:Short_Description: -+ * -+ * GNU ASN.1 library -+ */ -+/** -+ * libtasn1:Long_Description: -+ * -+ * The Libtasn1 library provides Abstract Syntax Notation One (ASN.1, as -+ * specified by the X.680 ITU-T recommendation) parsing and structures -+ * management, and Distinguished Encoding Rules (DER, as per X.690) -+ * encoding and decoding functions. -+ */ -+ -+ -+#ifndef LIBTASN1_H -+#define LIBTASN1_H -+ -+#ifndef ASN1_API -+#if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY -+#define ASN1_API __attribute__((__visibility__("default"))) -+#elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC -+#define ASN1_API __declspec(dllexport) -+#elif defined _MSC_VER && ! defined ASN1_STATIC -+#define ASN1_API __declspec(dllimport) -+#else -+#define ASN1_API -+#endif -+#endif -+ -+#ifdef __GNUC__ -+# define __LIBTASN1_CONST__ __attribute__((const)) -+# define __LIBTASN1_PURE__ __attribute__((pure)) -+#else -+# define __LIBTASN1_CONST__ -+# define __LIBTASN1_PURE__ -+#endif -+ -+#include -+#include -+#include /* for FILE* */ -+ -+#ifdef __cplusplus -+extern "C" -+{ -+#endif -+ -+/** -+ * ASN1_VERSION: -+ * -+ * Version of the library as a string. -+ */ -+#define ASN1_VERSION "4.16.0" -+ -+/** -+ * ASN1_VERSION_MAJOR: -+ * -+ * Major version number of the library. -+ */ -+#define ASN1_VERSION_MAJOR 4 -+ -+/** -+ * ASN1_VERSION_MINOR: ++ * Major version number of the library. ++ */ ++# define ASN1_VERSION_MAJOR 4 ++ ++/** ++ * ASN1_VERSION_MINOR: + * + * Minor version number of the library. + */ -+#define ASN1_VERSION_MINOR 16 ++# define ASN1_VERSION_MINOR 18 + +/** + * ASN1_VERSION_PATCH: + * + * Patch version number of the library. + */ -+#define ASN1_VERSION_PATCH 0 ++# define ASN1_VERSION_PATCH 0 + +/** + * ASN1_VERSION_NUMBER: + * + * Version number of the library as a number. + */ -+#define ASN1_VERSION_NUMBER 0x041000 ++# define ASN1_VERSION_NUMBER 0x041200 + + -+#if defined __GNUC__ && !defined ASN1_INTERNAL_BUILD -+# define _ASN1_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -+# if _ASN1_GCC_VERSION >= 30100 -+# define _ASN1_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__)) ++# if defined __GNUC__ && !defined ASN1_INTERNAL_BUILD ++# define _ASN1_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) ++# if _ASN1_GCC_VERSION >= 30100 ++# define _ASN1_GCC_ATTR_DEPRECATED __attribute__ ((__deprecated__)) ++# endif +# endif -+#endif + -+#ifndef _ASN1_GCC_ATTR_DEPRECATED -+#define _ASN1_GCC_ATTR_DEPRECATED -+#endif ++# ifndef _ASN1_GCC_ATTR_DEPRECATED ++# define _ASN1_GCC_ATTR_DEPRECATED ++# endif + +/*****************************************/ +/* Errors returned by libtasn1 functions */ +/*****************************************/ -+#define ASN1_SUCCESS 0 -+#define ASN1_FILE_NOT_FOUND 1 -+#define ASN1_ELEMENT_NOT_FOUND 2 -+#define ASN1_IDENTIFIER_NOT_FOUND 3 -+#define ASN1_DER_ERROR 4 -+#define ASN1_VALUE_NOT_FOUND 5 -+#define ASN1_GENERIC_ERROR 6 -+#define ASN1_VALUE_NOT_VALID 7 -+#define ASN1_TAG_ERROR 8 -+#define ASN1_TAG_IMPLICIT 9 -+#define ASN1_ERROR_TYPE_ANY 10 -+#define ASN1_SYNTAX_ERROR 11 -+#define ASN1_MEM_ERROR 12 -+#define ASN1_MEM_ALLOC_ERROR 13 -+#define ASN1_DER_OVERFLOW 14 -+#define ASN1_NAME_TOO_LONG 15 -+#define ASN1_ARRAY_ERROR 16 -+#define ASN1_ELEMENT_NOT_EMPTY 17 -+#define ASN1_TIME_ENCODING_ERROR 18 -+#define ASN1_RECURSION 19 ++# define ASN1_SUCCESS 0 ++# define ASN1_FILE_NOT_FOUND 1 ++# define ASN1_ELEMENT_NOT_FOUND 2 ++# define ASN1_IDENTIFIER_NOT_FOUND 3 ++# define ASN1_DER_ERROR 4 ++# define ASN1_VALUE_NOT_FOUND 5 ++# define ASN1_GENERIC_ERROR 6 ++# define ASN1_VALUE_NOT_VALID 7 ++# define ASN1_TAG_ERROR 8 ++# define ASN1_TAG_IMPLICIT 9 ++# define ASN1_ERROR_TYPE_ANY 10 ++# define ASN1_SYNTAX_ERROR 11 ++# define ASN1_MEM_ERROR 12 ++# define ASN1_MEM_ALLOC_ERROR 13 ++# define ASN1_DER_OVERFLOW 14 ++# define ASN1_NAME_TOO_LONG 15 ++# define ASN1_ARRAY_ERROR 16 ++# define ASN1_ELEMENT_NOT_EMPTY 17 ++# define ASN1_TIME_ENCODING_ERROR 18 ++# define ASN1_RECURSION 19 + +/*************************************/ +/* Constants used in asn1_visit_tree */ +/*************************************/ -+#define ASN1_PRINT_NAME 1 -+#define ASN1_PRINT_NAME_TYPE 2 -+#define ASN1_PRINT_NAME_TYPE_VALUE 3 -+#define ASN1_PRINT_ALL 4 ++# define ASN1_PRINT_NAME 1 ++# define ASN1_PRINT_NAME_TYPE 2 ++# define ASN1_PRINT_NAME_TYPE_VALUE 3 ++# define ASN1_PRINT_ALL 4 + +/*****************************************/ +/* Constants returned by asn1_read_tag */ +/*****************************************/ -+#define ASN1_CLASS_UNIVERSAL 0x00 /* old: 1 */ -+#define ASN1_CLASS_APPLICATION 0x40 /* old: 2 */ -+#define ASN1_CLASS_CONTEXT_SPECIFIC 0x80 /* old: 3 */ -+#define ASN1_CLASS_PRIVATE 0xC0 /* old: 4 */ -+#define ASN1_CLASS_STRUCTURED 0x20 ++# define ASN1_CLASS_UNIVERSAL 0x00 /* old: 1 */ ++# define ASN1_CLASS_APPLICATION 0x40 /* old: 2 */ ++# define ASN1_CLASS_CONTEXT_SPECIFIC 0x80 /* old: 3 */ ++# define ASN1_CLASS_PRIVATE 0xC0 /* old: 4 */ ++# define ASN1_CLASS_STRUCTURED 0x20 + +/*****************************************/ +/* Constants returned by asn1_read_tag */ +/*****************************************/ -+#define ASN1_TAG_BOOLEAN 0x01 -+#define ASN1_TAG_INTEGER 0x02 -+#define ASN1_TAG_SEQUENCE 0x10 -+#define ASN1_TAG_SET 0x11 -+#define ASN1_TAG_OCTET_STRING 0x04 -+#define ASN1_TAG_BIT_STRING 0x03 -+#define ASN1_TAG_UTCTime 0x17 -+#define ASN1_TAG_GENERALIZEDTime 0x18 -+#define ASN1_TAG_OBJECT_ID 0x06 -+#define ASN1_TAG_ENUMERATED 0x0A -+#define ASN1_TAG_NULL 0x05 -+#define ASN1_TAG_GENERALSTRING 0x1B -+#define ASN1_TAG_NUMERIC_STRING 0x12 -+#define ASN1_TAG_IA5_STRING 0x16 -+#define ASN1_TAG_TELETEX_STRING 0x14 -+#define ASN1_TAG_PRINTABLE_STRING 0x13 -+#define ASN1_TAG_UNIVERSAL_STRING 0x1C -+#define ASN1_TAG_BMP_STRING 0x1E -+#define ASN1_TAG_UTF8_STRING 0x0C -+#define ASN1_TAG_VISIBLE_STRING 0x1A ++# define ASN1_TAG_BOOLEAN 0x01 ++# define ASN1_TAG_INTEGER 0x02 ++# define ASN1_TAG_SEQUENCE 0x10 ++# define ASN1_TAG_SET 0x11 ++# define ASN1_TAG_OCTET_STRING 0x04 ++# define ASN1_TAG_BIT_STRING 0x03 ++# define ASN1_TAG_UTCTime 0x17 ++# define ASN1_TAG_GENERALIZEDTime 0x18 ++# define ASN1_TAG_OBJECT_ID 0x06 ++# define ASN1_TAG_ENUMERATED 0x0A ++# define ASN1_TAG_NULL 0x05 ++# define ASN1_TAG_GENERALSTRING 0x1B ++# define ASN1_TAG_NUMERIC_STRING 0x12 ++# define ASN1_TAG_IA5_STRING 0x16 ++# define ASN1_TAG_TELETEX_STRING 0x14 ++# define ASN1_TAG_PRINTABLE_STRING 0x13 ++# define ASN1_TAG_UNIVERSAL_STRING 0x1C ++# define ASN1_TAG_BMP_STRING 0x1E ++# define ASN1_TAG_UTF8_STRING 0x0C ++# define ASN1_TAG_VISIBLE_STRING 0x1A + +/** + * asn1_node: @@ -8412,10 +8538,10 @@ index 00000000000..6fd7a30dc35 + * Structure definition used for the node of the tree + * that represents an ASN.1 DEFINITION. + */ -+typedef struct asn1_node_st asn1_node_st; ++ typedef struct asn1_node_st asn1_node_st; + -+typedef asn1_node_st *asn1_node; -+typedef const asn1_node_st *asn1_node_const; ++ typedef asn1_node_st *asn1_node; ++ typedef const asn1_node_st *asn1_node_const; + +/** + * ASN1_MAX_NAME_SIZE: @@ -8423,7 +8549,7 @@ index 00000000000..6fd7a30dc35 + * Maximum number of characters of a name + * inside a file with ASN1 definitions. + */ -+#define ASN1_MAX_NAME_SIZE 64 ++# define ASN1_MAX_NAME_SIZE 64 + + +/** @@ -8434,47 +8560,46 @@ index 00000000000..6fd7a30dc35 + * + * For the on-disk format of ASN.1 trees, created by asn1_parser2array(). + */ -+struct asn1_static_node_st -+{ -+ const char *name; /* Node name */ -+ unsigned int type; /* Node type */ -+ const void *value; /* Node value */ -+}; -+typedef struct asn1_static_node_st asn1_static_node; -+ -+/* List of constants for field type of node_asn */ -+#define ASN1_ETYPE_INVALID 0 -+#define ASN1_ETYPE_CONSTANT 1 -+#define ASN1_ETYPE_IDENTIFIER 2 -+#define ASN1_ETYPE_INTEGER 3 -+#define ASN1_ETYPE_BOOLEAN 4 -+#define ASN1_ETYPE_SEQUENCE 5 -+#define ASN1_ETYPE_BIT_STRING 6 -+#define ASN1_ETYPE_OCTET_STRING 7 -+#define ASN1_ETYPE_TAG 8 -+#define ASN1_ETYPE_DEFAULT 9 -+#define ASN1_ETYPE_SIZE 10 -+#define ASN1_ETYPE_SEQUENCE_OF 11 -+#define ASN1_ETYPE_OBJECT_ID 12 -+#define ASN1_ETYPE_ANY 13 -+#define ASN1_ETYPE_SET 14 -+#define ASN1_ETYPE_SET_OF 15 -+#define ASN1_ETYPE_DEFINITIONS 16 -+#define ASN1_ETYPE_CHOICE 18 -+#define ASN1_ETYPE_IMPORTS 19 -+#define ASN1_ETYPE_NULL 20 -+#define ASN1_ETYPE_ENUMERATED 21 -+#define ASN1_ETYPE_GENERALSTRING 27 -+#define ASN1_ETYPE_NUMERIC_STRING 28 -+#define ASN1_ETYPE_IA5_STRING 29 -+#define ASN1_ETYPE_TELETEX_STRING 30 -+#define ASN1_ETYPE_PRINTABLE_STRING 31 -+#define ASN1_ETYPE_UNIVERSAL_STRING 32 -+#define ASN1_ETYPE_BMP_STRING 33 -+#define ASN1_ETYPE_UTF8_STRING 34 -+#define ASN1_ETYPE_VISIBLE_STRING 35 -+#define ASN1_ETYPE_UTC_TIME 36 -+#define ASN1_ETYPE_GENERALIZED_TIME 37 ++ typedef struct asn1_static_node_st ++ { ++ const char *name; /* Node name */ ++ unsigned int type; /* Node type */ ++ const void *value; /* Node value */ ++ } asn1_static_node; ++ ++/* List of constants for field type of asn1_static_node */ ++# define ASN1_ETYPE_INVALID 0 ++# define ASN1_ETYPE_CONSTANT 1 ++# define ASN1_ETYPE_IDENTIFIER 2 ++# define ASN1_ETYPE_INTEGER 3 ++# define ASN1_ETYPE_BOOLEAN 4 ++# define ASN1_ETYPE_SEQUENCE 5 ++# define ASN1_ETYPE_BIT_STRING 6 ++# define ASN1_ETYPE_OCTET_STRING 7 ++# define ASN1_ETYPE_TAG 8 ++# define ASN1_ETYPE_DEFAULT 9 ++# define ASN1_ETYPE_SIZE 10 ++# define ASN1_ETYPE_SEQUENCE_OF 11 ++# define ASN1_ETYPE_OBJECT_ID 12 ++# define ASN1_ETYPE_ANY 13 ++# define ASN1_ETYPE_SET 14 ++# define ASN1_ETYPE_SET_OF 15 ++# define ASN1_ETYPE_DEFINITIONS 16 ++# define ASN1_ETYPE_CHOICE 18 ++# define ASN1_ETYPE_IMPORTS 19 ++# define ASN1_ETYPE_NULL 20 ++# define ASN1_ETYPE_ENUMERATED 21 ++# define ASN1_ETYPE_GENERALSTRING 27 ++# define ASN1_ETYPE_NUMERIC_STRING 28 ++# define ASN1_ETYPE_IA5_STRING 29 ++# define ASN1_ETYPE_TELETEX_STRING 30 ++# define ASN1_ETYPE_PRINTABLE_STRING 31 ++# define ASN1_ETYPE_UNIVERSAL_STRING 32 ++# define ASN1_ETYPE_BMP_STRING 33 ++# define ASN1_ETYPE_UTF8_STRING 34 ++# define ASN1_ETYPE_VISIBLE_STRING 35 ++# define ASN1_ETYPE_UTC_TIME 36 ++# define ASN1_ETYPE_GENERALIZED_TIME 37 + +/** + * ASN1_DELETE_FLAG_ZEROIZE: @@ -8483,7 +8608,7 @@ index 00000000000..6fd7a30dc35 + * + * Zeroize values prior to deinitialization. + */ -+#define ASN1_DELETE_FLAG_ZEROIZE 1 ++# define ASN1_DELETE_FLAG_ZEROIZE 1 + +/** + * ASN1_DECODE_FLAG_ALLOW_PADDING: @@ -8492,7 +8617,7 @@ index 00000000000..6fd7a30dc35 + * + * This flag would allow arbitrary data past the DER data. + */ -+#define ASN1_DECODE_FLAG_ALLOW_PADDING 1 ++# define ASN1_DECODE_FLAG_ALLOW_PADDING 1 +/** + * ASN1_DECODE_FLAG_STRICT_DER: + * @@ -8500,7 +8625,7 @@ index 00000000000..6fd7a30dc35 + * + * This flag would ensure that no BER decoding takes place. + */ -+#define ASN1_DECODE_FLAG_STRICT_DER (1<<1) ++# define ASN1_DECODE_FLAG_STRICT_DER (1<<1) +/** + * ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME: + * @@ -8508,7 +8633,7 @@ index 00000000000..6fd7a30dc35 + * + * This flag will tolerate Time encoding errors when in strict DER. + */ -+#define ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME (1<<2) ++# define ASN1_DECODE_FLAG_ALLOW_INCORRECT_TIME (1<<2) + + +/** @@ -8520,14 +8645,14 @@ index 00000000000..6fd7a30dc35 + * + * Data node inside a #asn1_node structure. + */ -+struct asn1_data_node_st -+{ -+ const char *name; /* Node name */ -+ const void *value; /* Node value */ -+ unsigned int value_len; /* Node value size */ -+ unsigned int type; /* Node value type (ASN1_ETYPE_*) */ -+}; -+typedef struct asn1_data_node_st asn1_data_node_st; ++ struct asn1_data_node_st ++ { ++ const char *name; /* Node name */ ++ const void *value; /* Node value */ ++ unsigned int value_len; /* Node value size */ ++ unsigned int type; /* Node value type (ASN1_ETYPE_*) */ ++ }; ++ typedef struct asn1_data_node_st asn1_data_node_st; + +/***********************************/ +/* Fixed constants */ @@ -8540,181 +8665,183 @@ index 00000000000..6fd7a30dc35 + * of a description message + * (null character included). + */ -+#define ASN1_MAX_ERROR_DESCRIPTION_SIZE 128 ++# define ASN1_MAX_ERROR_DESCRIPTION_SIZE 128 + +/***********************************/ +/* Functions definitions */ +/***********************************/ + -+extern ASN1_API int -+ asn1_parser2tree (const char *file, ++ extern ASN1_API int ++ asn1_parser2tree (const char *file, + asn1_node * definitions, char *error_desc); + -+extern ASN1_API int -+ asn1_parser2array (const char *inputFileName, ++ extern ASN1_API int ++ asn1_parser2array (const char *inputFileName, + const char *outputFileName, + const char *vectorName, char *error_desc); + -+extern ASN1_API int -+ asn1_array2tree (const asn1_static_node * array, ++ extern ASN1_API int ++ asn1_array2tree (const asn1_static_node * array, + asn1_node * definitions, char *errorDescription); + -+extern ASN1_API void -+ asn1_print_structure (FILE * out, asn1_node_const structure, ++ extern ASN1_API void ++ asn1_print_structure (FILE * out, asn1_node_const structure, + const char *name, int mode); + -+extern ASN1_API int -+ asn1_create_element (asn1_node_const definitions, ++ extern ASN1_API int ++ asn1_create_element (asn1_node_const definitions, + const char *source_name, asn1_node * element); + -+extern ASN1_API int asn1_delete_structure (asn1_node * structure); ++ extern ASN1_API int asn1_delete_structure (asn1_node * structure); + -+extern ASN1_API int asn1_delete_structure2 (asn1_node * structure, unsigned int flags); ++ extern ASN1_API int asn1_delete_structure2 (asn1_node * structure, ++ unsigned int flags); + -+extern ASN1_API int -+ asn1_delete_element (asn1_node structure, const char *element_name); ++ extern ASN1_API int ++ asn1_delete_element (asn1_node structure, const char *element_name); + -+extern ASN1_API int -+ asn1_write_value (asn1_node node_root, const char *name, ++ extern ASN1_API int ++ asn1_write_value (asn1_node node_root, const char *name, + const void *ivalue, int len); + -+extern ASN1_API int -+ asn1_read_value (asn1_node_const root, const char *name, ++ extern ASN1_API int ++ asn1_read_value (asn1_node_const root, const char *name, + void *ivalue, int *len); + -+extern ASN1_API int -+ asn1_read_value_type (asn1_node_const root, const char *name, ++ extern ASN1_API int ++ asn1_read_value_type (asn1_node_const root, const char *name, + void *ivalue, int *len, unsigned int *etype); + -+extern ASN1_API int -+ asn1_read_node_value (asn1_node_const node, asn1_data_node_st * data); ++ extern ASN1_API int ++ asn1_read_node_value (asn1_node_const node, asn1_data_node_st * data); + -+extern ASN1_API int -+ asn1_number_of_elements (asn1_node_const element, const char *name, int *num); ++ extern ASN1_API int ++ asn1_number_of_elements (asn1_node_const element, const char *name, ++ int *num); + -+extern ASN1_API int -+ asn1_der_coding (asn1_node_const element, const char *name, ++ extern ASN1_API int ++ asn1_der_coding (asn1_node_const element, const char *name, + void *ider, int *len, char *ErrorDescription); + -+extern ASN1_API int -+ asn1_der_decoding2 (asn1_node *element, const void *ider, ++ extern ASN1_API int ++ asn1_der_decoding2 (asn1_node * element, const void *ider, + int *max_ider_len, unsigned int flags, + char *errorDescription); + -+extern ASN1_API int -+ asn1_der_decoding (asn1_node * element, const void *ider, ++ extern ASN1_API int ++ asn1_der_decoding (asn1_node * element, const void *ider, + int ider_len, char *errorDescription); + +/* Do not use. Use asn1_der_decoding() instead. */ -+extern ASN1_API int -+ asn1_der_decoding_element (asn1_node * structure, ++ extern ASN1_API int ++ asn1_der_decoding_element (asn1_node * structure, + const char *elementName, + const void *ider, int len, -+ char *errorDescription) _ASN1_GCC_ATTR_DEPRECATED; ++ char *errorDescription) ++ _ASN1_GCC_ATTR_DEPRECATED; + -+extern ASN1_API int -+ asn1_der_decoding_startEnd (asn1_node element, ++ extern ASN1_API int ++ asn1_der_decoding_startEnd (asn1_node element, + const void *ider, int ider_len, + const char *name_element, + int *start, int *end); + -+extern ASN1_API int -+ asn1_expand_any_defined_by (asn1_node_const definitions, asn1_node * element); ++ extern ASN1_API int ++ asn1_expand_any_defined_by (asn1_node_const definitions, ++ asn1_node * element); + -+extern ASN1_API int -+ asn1_expand_octet_string (asn1_node_const definitions, ++ extern ASN1_API int ++ asn1_expand_octet_string (asn1_node_const definitions, + asn1_node * element, + const char *octetName, const char *objectName); + -+extern ASN1_API int -+ asn1_read_tag (asn1_node_const root, const char *name, ++ extern ASN1_API int ++ asn1_read_tag (asn1_node_const root, const char *name, + int *tagValue, int *classValue); + -+extern ASN1_API const char *asn1_find_structure_from_oid (asn1_node_const ++ extern ASN1_API const char *asn1_find_structure_from_oid (asn1_node_const + definitions, + const char + *oidValue); + -+__LIBTASN1_PURE__ -+extern ASN1_API const char *asn1_check_version (const char *req_version); ++ __LIBTASN1_PURE__ ++ extern ASN1_API const char *asn1_check_version (const char *req_version); + -+__LIBTASN1_PURE__ -+extern ASN1_API const char *asn1_strerror (int error); ++ __LIBTASN1_PURE__ extern ASN1_API const char *asn1_strerror (int error); + -+extern ASN1_API void asn1_perror (int error); ++ extern ASN1_API void asn1_perror (int error); + -+#define ASN1_MAX_TAG_SIZE 4 -+#define ASN1_MAX_LENGTH_SIZE 9 -+#define ASN1_MAX_TL_SIZE (ASN1_MAX_TAG_SIZE+ASN1_MAX_LENGTH_SIZE) -+extern ASN1_API long -+ asn1_get_length_der (const unsigned char *der, int der_len, int *len); ++# define ASN1_MAX_TAG_SIZE 4 ++# define ASN1_MAX_LENGTH_SIZE 9 ++# define ASN1_MAX_TL_SIZE (ASN1_MAX_TAG_SIZE+ASN1_MAX_LENGTH_SIZE) ++ extern ASN1_API long ++ asn1_get_length_der (const unsigned char *der, int der_len, int *len); + -+extern ASN1_API long -+ asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len); ++ extern ASN1_API long ++ asn1_get_length_ber (const unsigned char *ber, int ber_len, int *len); + -+extern ASN1_API void -+ asn1_length_der (unsigned long int len, unsigned char *der, int *der_len); ++ extern ASN1_API void ++ asn1_length_der (unsigned long int len, unsigned char *der, int *der_len); + +/* Other utility functions. */ + -+extern ASN1_API -+ int asn1_decode_simple_der (unsigned int etype, const unsigned char *der, ++ extern ASN1_API ++ int asn1_decode_simple_der (unsigned int etype, const unsigned char *der, + unsigned int _der_len, + const unsigned char **str, + unsigned int *str_len); + -+extern ASN1_API -+ int asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, ++ extern ASN1_API ++ int asn1_decode_simple_ber (unsigned int etype, const unsigned char *der, + unsigned int _der_len, + unsigned char **str, -+ unsigned int *str_len, -+ unsigned int *ber_len); ++ unsigned int *str_len, unsigned int *ber_len); + -+extern ASN1_API int -+ asn1_encode_simple_der (unsigned int etype, const unsigned char *str, ++ extern ASN1_API int ++ asn1_encode_simple_der (unsigned int etype, const unsigned char *str, + unsigned int str_len, unsigned char *tl, + unsigned int *tl_len); + -+extern ASN1_API asn1_node -+ asn1_find_node (asn1_node_const pointer, const char *name); ++ extern ASN1_API asn1_node ++ asn1_find_node (asn1_node_const pointer, const char *name); + -+extern ASN1_API int -+ asn1_copy_node (asn1_node dst, const char *dst_name, ++ extern ASN1_API int ++ asn1_copy_node (asn1_node dst, const char *dst_name, + asn1_node_const src, const char *src_name); -+extern ASN1_API asn1_node -+ asn1_dup_node (asn1_node_const src, const char *src_name); ++ extern ASN1_API asn1_node ++ asn1_dup_node (asn1_node_const src, const char *src_name); + +/* Internal and low-level DER utility functions. */ + -+extern ASN1_API int -+ asn1_get_tag_der (const unsigned char *der, int der_len, ++ extern ASN1_API int ++ asn1_get_tag_der (const unsigned char *der, int der_len, + unsigned char *cls, int *len, unsigned long *tag); + -+extern ASN1_API void -+ asn1_octet_der (const unsigned char *str, int str_len, ++ extern ASN1_API void ++ asn1_octet_der (const unsigned char *str, int str_len, + unsigned char *der, int *der_len); + -+extern ASN1_API int -+ asn1_get_octet_der (const unsigned char *der, int der_len, ++ extern ASN1_API int ++ asn1_get_octet_der (const unsigned char *der, int der_len, + int *ret_len, unsigned char *str, + int str_size, int *str_len); + -+extern ASN1_API void asn1_bit_der (const unsigned char *str, int bit_len, ++ extern ASN1_API void asn1_bit_der (const unsigned char *str, int bit_len, + unsigned char *der, int *der_len); + -+extern ASN1_API int -+ asn1_get_bit_der (const unsigned char *der, int der_len, ++ extern ASN1_API int ++ asn1_get_bit_der (const unsigned char *der, int der_len, + int *ret_len, unsigned char *str, + int str_size, int *bit_len); + -+extern ASN1_API int -+ asn1_get_object_id_der (const unsigned char *der, -+ int der_len, int *ret_len, -+ char *str, int str_size); ++ extern ASN1_API int ++ asn1_get_object_id_der (const unsigned char *der, ++ int der_len, int *ret_len, ++ char *str, int str_size); + -+extern ASN1_API int -+ asn1_object_id_der (const char *str, unsigned char *der, int *der_len, -+ unsigned flags); ++ extern ASN1_API int ++ asn1_object_id_der (const char *str, unsigned char *der, int *der_len, ++ unsigned flags); + +/* Compatibility types */ + @@ -8725,7 +8852,7 @@ index 00000000000..6fd7a30dc35 + * + * Deprecated: 3.0: Use int instead. + */ -+typedef int asn1_retCode; ++ typedef int asn1_retCode _ASN1_GCC_ATTR_DEPRECATED; + +/** + * node_asn_struct: @@ -8734,7 +8861,13 @@ index 00000000000..6fd7a30dc35 + * + * Deprecated: 3.0: Use #asn1_node instead. + */ -+#define node_asn_struct asn1_node_st ++# ifndef ASN1_DISABLE_DEPRECATED ++# if _ASN1_GCC_VERSION >= 30100 ++# define node_asn_struct _Pragma ("GCC warning \"'node_asn_struct' macro is deprecated, use 'asn1_node' instead.\"") asn1_node_st ++# else ++# define node_asn_struct asn1_node_st ++# endif ++# endif /* !ASN1_DISABLE_DEPRECATED */ + +/** + * node_asn: @@ -8743,7 +8876,13 @@ index 00000000000..6fd7a30dc35 + * + * Deprecated: 3.0: Use #asn1_node instead. + */ -+#define node_asn asn1_node_st ++# ifndef ASN1_DISABLE_DEPRECATED ++# if _ASN1_GCC_VERSION >= 30100 ++# define node_asn _Pragma ("GCC warning \"'node_asn' macro is deprecated, use 'asn1_node' instead.\"") asn1_node_st ++# else ++# define node_asn asn1_node_st ++# endif ++# endif /* !ASN1_DISABLE_DEPRECATED */ + +/** + * ASN1_TYPE: @@ -8752,7 +8891,13 @@ index 00000000000..6fd7a30dc35 + * + * Deprecated: 3.0: Use #asn1_node instead. + */ -+#define ASN1_TYPE asn1_node ++# ifndef ASN1_DISABLE_DEPRECATED ++# if _ASN1_GCC_VERSION >= 30100 ++# define ASN1_TYPE _Pragma ("GCC warning \"'ASN1_TYPE' macro is deprecated, use 'asn1_node' instead.\"") asn1_node ++# else ++# define ASN1_TYPE asn1_node ++# endif ++# endif /* !ASN1_DISABLE_DEPRECATED */ + +/** + * ASN1_TYPE_EMPTY: @@ -8761,7 +8906,13 @@ index 00000000000..6fd7a30dc35 + * + * Deprecated: 3.0: Use NULL instead. + */ -+#define ASN1_TYPE_EMPTY NULL ++# ifndef ASN1_DISABLE_DEPRECATED ++# if _ASN1_GCC_VERSION >= 30100 ++# define ASN1_TYPE_EMPTY _Pragma ("GCC warning \"'ASN1_TYPE_EMPTY' macro is deprecated, use 'NULL' instead.\"") NULL ++# else ++# define ASN1_TYPE_EMPTY NULL ++# endif ++# endif /* !ASN1_DISABLE_DEPRECATED */ + +/** + * static_struct_asn: @@ -8770,7 +8921,13 @@ index 00000000000..6fd7a30dc35 + * + * Deprecated: 3.0: Use #asn1_static_node instead. + */ -+#define static_struct_asn asn1_static_node_st ++# ifndef ASN1_DISABLE_DEPRECATED ++# if _ASN1_GCC_VERSION >= 30100 ++# define static_struct_asn _Pragma ("GCC warning \"'static_struct_asn' macro is deprecated, use 'asn1_static_node_st' instead.\"") asn1_static_node_st ++# else ++# define static_struct_asn asn1_static_node_st ++# endif ++# endif /* !ASN1_DISABLE_DEPRECATED */ + +/** + * ASN1_ARRAY_TYPE: @@ -8779,7 +8936,13 @@ index 00000000000..6fd7a30dc35 + * + * Deprecated: 3.0: Use #asn1_static_node instead. + */ -+#define ASN1_ARRAY_TYPE asn1_static_node ++# ifndef ASN1_DISABLE_DEPRECATED ++# if _ASN1_GCC_VERSION >= 30100 ++# define ASN1_ARRAY_TYPE _Pragma ("GCC warning \"'ASN1_ARRAY_TYPE' macro is deprecated, use 'asn1_static_node' instead.\"") asn1_static_node ++# else ++# define ASN1_ARRAY_TYPE asn1_static_node ++# endif ++# endif /* !ASN1_DISABLE_DEPRECATED */ + +/** + * asn1_static_node_t: @@ -8788,7 +8951,13 @@ index 00000000000..6fd7a30dc35 + * + * Deprecated: 3.0: Use #asn1_static_node instead. + */ -+#define asn1_static_node_t asn1_static_node ++# ifndef ASN1_DISABLE_DEPRECATED ++# if _ASN1_GCC_VERSION >= 30100 ++# define asn1_static_node_t _Pragma ("GCC warning \"'asn1_static_node_t' macro is deprecated, use 'asn1_static_node' instead.\"") asn1_static_node ++# else ++# define asn1_static_node_t asn1_static_node ++# endif ++# endif /* !ASN1_DISABLE_DEPRECATED */ + +/** + * node_data_struct: @@ -8797,7 +8966,13 @@ index 00000000000..6fd7a30dc35 + * + * Deprecated: 3.0: Use #asn1_data_node_st instead. + */ -+#define node_data_struct asn1_data_node_st ++# ifndef ASN1_DISABLE_DEPRECATED ++# if _ASN1_GCC_VERSION >= 30100 ++# define node_data_struct _Pragma ("GCC warning \"'node_data_struct' macro is deprecated, use 'asn1_data_node_st' instead.\"") asn1_data_node_st ++# else ++# define node_data_struct asn1_data_node_st ++# endif ++# endif /* !ASN1_DISABLE_DEPRECATED */ + +/** + * ASN1_DATA_NODE: @@ -8806,129 +8981,16 @@ index 00000000000..6fd7a30dc35 + * + * Deprecated: 3.0: Use #asn1_data_node_st instead. + */ -+#define ASN1_DATA_NODE asn1_data_node_st -+ -+#ifdef __cplusplus ++# ifndef ASN1_DISABLE_DEPRECATED ++# if _ASN1_GCC_VERSION >= 30100 ++# define ASN1_DATA_NODE _Pragma ("GCC warning \"'asn1_static_node_t' macro is deprecated, use 'asn1_static_node' instead.\"") asn1_data_node_st ++# else ++# define ASN1_DATA_NODE asn1_data_node_st ++# endif ++# endif /* !ASN1_DISABLE_DEPRECATED */ ++ ++# ifdef __cplusplus +} -+#endif ++# endif + +#endif /* LIBTASN1_H */ -diff --git a/grub-core/lib/libtasn1/LICENSE b/grub-core/lib/libtasn1/LICENSE -new file mode 100644 -index 00000000000..e8b3628db9b ---- /dev/null -+++ b/grub-core/lib/libtasn1/LICENSE -@@ -0,0 +1,16 @@ -+LICENSING -+========= -+ -+The libtasn1 library is released under the GNU Lesser General Public -+License (LGPL) version 2.1 or later; see [COPYING.LESSER](doc/COPYING.LESSER) -+for the license terms. -+ -+The GNU LGPL applies to the main libtasn1 library, while the -+included applications library are under the GNU GPL version 3. -+The libtasn1 library is located in the lib directory, while the applications -+in src/. -+ -+The documentation in doc/ is under the GNU FDL license 1.3. -+ -+For any copyright year range specified as YYYY-ZZZZ in this package -+note that the range specifies every single year in that closed interval. -diff --git a/grub-core/lib/libtasn1/README.md b/grub-core/lib/libtasn1/README.md -new file mode 100644 -index 00000000000..50a8642296c ---- /dev/null -+++ b/grub-core/lib/libtasn1/README.md -@@ -0,0 +1,91 @@ -+|Branch|CI system|Status| -+|:----:|:-------:|-----:| -+|Master|Gitlab|[![build status](https://gitlab.com/gnutls/libtasn1/badges/master/pipeline.svg)](https://gitlab.com/gnutls/libtasn1/commits/master)[![coverage report](https://gitlab.com/gnutls/libtasn1/badges/master/coverage.svg)](https://gnutls.gitlab.io/libtasn1/coverage)| -+ -+# libtasn1 -+ -+This is GNU Libtasn1, a small ASN.1 library. -+ -+The C library (libtasn1.*) is licensed under the GNU Lesser General -+Public License version 2.1 or later. See the file COPYING.LIB. -+ -+The command line tool, self tests, examples, and other auxilliary -+files, are licensed under the GNU General Public License version 3.0 -+or later. See the file COPYING. -+ -+## Building the library -+ -+We require several tools to build the software, including: -+ -+* [Make](https://www.gnu.org/software/make/) -+* [Automake](https://www.gnu.org/software/automake/) (use 1.11.3 or later) -+* [Autoconf](https://www.gnu.org/software/autoconf/) -+* [Libtool](https://www.gnu.org/software/libtool/) -+* [Texinfo](https://www.gnu.org/software/texinfo/) -+* [help2man](http://www.gnu.org/software/help2man/) -+* [Tar](https://www.gnu.org/software/tar/) -+* [Gzip](https://www.gnu.org/software/gzip/) -+* [bison](https://www.gnu.org/software/bison/) -+* [Texlive & epsf](https://www.tug.org/texlive/) (for PDF manual) -+* [GTK-DOC](https://www.gtk.org/gtk-doc/) (for API manual) -+* [Git](https://git-scm.com/) -+* [libabigail](https://pagure.io/libabigail/) (for abi comparison in make dist) -+* [Valgrind](https://valgrind.org/) (optional) -+ -+The required software is typically distributed with your operating -+system, and the instructions for installing them differ. Here are -+some hints: -+ -+gNewSense/Debian/Ubuntu: -+``` -+sudo apt-get install make git-core autoconf automake libtool -+sudo apt-get install texinfo texlive texlive-generic-recommended texlive-extra-utils -+sudo apt-get install help2man gtk-doc-tools valgrind abigail-tools -+``` -+ -+The next step is to run autoreconf, ./configure, etc: -+ -+``` -+$ ./bootstrap -+``` -+ -+Then build the project normally: -+ -+``` -+$ make -+$ make check -+``` -+ -+Happy hacking! -+ -+ -+## Manual -+ -+The manual is in the `doc/` directory of the release. You can also browse -+the manual online at: -+ -+ - https://gnutls.gitlab.io/libtasn1/ -+ -+ -+## Code coverage report -+ -+The coverage report is at: -+ -+ - https://gnutls.gitlab.io/libtasn1/coverage -+ -+ -+## Issue trackers -+ -+ - [Main issue tracker](https://gitlab.com/gnutls/libtasn1/issues) -+ - [oss-fuzz found issues](https://bugs.chromium.org/p/oss-fuzz/issues/list?q=libtasn1&can=2) -+ -+ -+## Homepage -+ -+The project homepage at the gnu site is at: -+ -+http://www.gnu.org/software/libtasn1/ -+ -+ -+For any copyright year range specified as YYYY-ZZZZ in this package -+note that the range specifies every single year in that closed interval. diff --git a/0012-for-ppc-reset-console-display-attr-when-clear-screen.patch b/0012-for-ppc-reset-console-display-attr-when-clear-screen.patch deleted file mode 100644 index c8ccc7e22eb7d6d76fb845064d34c9161d62c081..0000000000000000000000000000000000000000 --- a/0012-for-ppc-reset-console-display-attr-when-clear-screen.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Wed, 24 Apr 2013 10:51:48 -0300 -Subject: [PATCH] for ppc, reset console display attr when clear screen - -v2: Also use \x0c instead of a literal ^L to make future patches less -awkward. - -This should fix this bugzilla: -https://bugzilla.redhat.com/show_bug.cgi?id=908519 - -Signed-off-by: Peter Jones -Signed-off-by: Paulo Flabiano Smorigo -Signed-off-by: Robbie Harwood ---- - grub-core/term/terminfo.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/term/terminfo.c b/grub-core/term/terminfo.c -index 85ecf06b4df..05c88dcf49e 100644 ---- a/grub-core/term/terminfo.c -+++ b/grub-core/term/terminfo.c -@@ -151,7 +151,7 @@ grub_terminfo_set_current (struct grub_term_output *term, - /* Clear the screen. Using serial console, screen(1) only recognizes the - * ANSI escape sequence. Using video console, Apple Open Firmware - * (version 3.1.1) only recognizes the literal ^L. So use both. */ -- data->cls = grub_strdup (" \e[2J"); -+ data->cls = grub_strdup ("\x0c\e[2J\e[m"); - data->reverse_video_on = grub_strdup ("\e[7m"); - data->reverse_video_off = grub_strdup ("\e[m"); - if (grub_strcmp ("ieee1275", str) == 0) diff --git a/0168-libtasn1-disable-code-not-needed-in-grub.patch b/0012-libtasn1-disable-code-not-needed-in-grub.patch similarity index 63% rename from 0168-libtasn1-disable-code-not-needed-in-grub.patch rename to 0012-libtasn1-disable-code-not-needed-in-grub.patch index 00f55888d7e83c744e28b78c162d97169c1d324e..b2ee029a94beb61316dcefc4dc8dbdc41e76717c 100644 --- a/0168-libtasn1-disable-code-not-needed-in-grub.patch +++ b/0012-libtasn1-disable-code-not-needed-in-grub.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 40099cf0d4d68e79db9e71d78070f37c73f998a0 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Fri, 1 May 2020 17:12:23 +1000 -Subject: [PATCH] libtasn1: disable code not needed in grub +Subject: [PATCH 12/23] libtasn1: disable code not needed in grub We don't expect to be able to write ASN.1, only read it, so we can disable some code. @@ -25,7 +25,7 @@ Signed-off-by: Daniel Axtens 6 files changed, 38 insertions(+), 8 deletions(-) diff --git a/grub-core/lib/libtasn1/lib/coding.c b/grub-core/lib/libtasn1/lib/coding.c -index 245ea64cf0a..52def598368 100644 +index 671104f63..b3d826710 100644 --- a/grub-core/lib/libtasn1/lib/coding.c +++ b/grub-core/lib/libtasn1/lib/coding.c @@ -30,11 +30,11 @@ @@ -57,7 +57,7 @@ index 245ea64cf0a..52def598368 100644 /******************************************************/ /* Function : _asn1_time_der */ /* Description: creates the DER coding for a TIME */ -@@ -281,7 +283,7 @@ _asn1_time_der (unsigned char *str, int str_len, unsigned char *der, +@@ -278,7 +280,7 @@ _asn1_time_der (unsigned char *str, int str_len, unsigned char *der, return ASN1_SUCCESS; } @@ -66,7 +66,7 @@ index 245ea64cf0a..52def598368 100644 /* void -@@ -520,6 +522,7 @@ asn1_bit_der (const unsigned char *str, int bit_len, +@@ -519,6 +521,7 @@ asn1_bit_der (const unsigned char *str, int bit_len, } @@ -74,7 +74,7 @@ index 245ea64cf0a..52def598368 100644 /******************************************************/ /* Function : _asn1_complete_explicit_tag */ /* Description: add the length coding to the EXPLICIT */ -@@ -596,6 +599,7 @@ _asn1_complete_explicit_tag (asn1_node node, unsigned char *der, +@@ -595,6 +598,7 @@ _asn1_complete_explicit_tag (asn1_node node, unsigned char *der, return ASN1_SUCCESS; } @@ -82,7 +82,7 @@ index 245ea64cf0a..52def598368 100644 const tag_and_class_st _asn1_tags[] = { [ASN1_ETYPE_GENERALSTRING] = -@@ -648,6 +652,8 @@ const tag_and_class_st _asn1_tags[] = { +@@ -647,6 +651,8 @@ const tag_and_class_st _asn1_tags[] = { unsigned int _asn1_tags_size = sizeof (_asn1_tags) / sizeof (_asn1_tags[0]); @@ -91,7 +91,7 @@ index 245ea64cf0a..52def598368 100644 /******************************************************/ /* Function : _asn1_insert_tag_der */ /* Description: creates the DER coding of tags of one */ -@@ -1413,3 +1419,5 @@ error: +@@ -1423,3 +1429,5 @@ error: asn1_delete_structure (&node); return err; } @@ -99,10 +99,10 @@ index 245ea64cf0a..52def598368 100644 +#endif \ No newline at end of file diff --git a/grub-core/lib/libtasn1/lib/decoding.c b/grub-core/lib/libtasn1/lib/decoding.c -index ff04eb778cb..42f9a92b5d4 100644 +index b1a35356f..b8130b956 100644 --- a/grub-core/lib/libtasn1/lib/decoding.c +++ b/grub-core/lib/libtasn1/lib/decoding.c -@@ -1613,6 +1613,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, +@@ -1620,6 +1620,7 @@ asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, return asn1_der_decoding2 (element, ider, &ider_len, 0, errorDescription); } @@ -110,16 +110,16 @@ index ff04eb778cb..42f9a92b5d4 100644 /** * asn1_der_decoding_element: * @structure: pointer to an ASN1 structure -@@ -1643,6 +1644,7 @@ asn1_der_decoding_element (asn1_node * structure, const char *elementName, +@@ -1650,6 +1651,7 @@ asn1_der_decoding_element (asn1_node * structure, const char *elementName, { - return asn1_der_decoding(structure, ider, len, errorDescription); + return asn1_der_decoding (structure, ider, len, errorDescription); } +#endif /** * asn1_der_decoding_startEnd: diff --git a/grub-core/lib/libtasn1/lib/element.c b/grub-core/lib/libtasn1/lib/element.c -index 997eb2725dc..539008d8e94 100644 +index 86e64f2cf..8cd6b662c 100644 --- a/grub-core/lib/libtasn1/lib/element.c +++ b/grub-core/lib/libtasn1/lib/element.c @@ -191,7 +191,7 @@ _asn1_append_sequence_set (asn1_node node, struct node_tail_cache_st *pcache) @@ -131,7 +131,7 @@ index 997eb2725dc..539008d8e94 100644 /** * asn1_write_value: * @node_root: pointer to a structure -@@ -645,7 +645,7 @@ asn1_write_value (asn1_node node_root, const char *name, +@@ -646,7 +646,7 @@ asn1_write_value (asn1_node node_root, const char *name, return ASN1_SUCCESS; } @@ -141,7 +141,7 @@ index 997eb2725dc..539008d8e94 100644 #define PUT_VALUE( ptr, ptr_size, data, data_size) \ *len = data_size; \ diff --git a/grub-core/lib/libtasn1/lib/errors.c b/grub-core/lib/libtasn1/lib/errors.c -index cee74daf795..42785e8622b 100644 +index 4dadbd96d..41921d813 100644 --- a/grub-core/lib/libtasn1/lib/errors.c +++ b/grub-core/lib/libtasn1/lib/errors.c @@ -57,6 +57,8 @@ static const libtasn1_error_entry error_algorithms[] = { @@ -162,7 +162,7 @@ index cee74daf795..42785e8622b 100644 /** * asn1_strerror: diff --git a/grub-core/lib/libtasn1/lib/structure.c b/grub-core/lib/libtasn1/lib/structure.c -index 8189c56a4c9..fcfde01a393 100644 +index c0802202e..45435732c 100644 --- a/grub-core/lib/libtasn1/lib/structure.c +++ b/grub-core/lib/libtasn1/lib/structure.c @@ -76,7 +76,7 @@ _asn1_find_left (asn1_node_const node) @@ -172,9 +172,9 @@ index 8189c56a4c9..fcfde01a393 100644 - +#if 0 int - _asn1_create_static_structure (asn1_node_const pointer, char *output_file_name, - char *vector_name) -@@ -155,7 +155,7 @@ _asn1_create_static_structure (asn1_node_const pointer, char *output_file_name, + _asn1_create_static_structure (asn1_node_const pointer, + char *output_file_name, char *vector_name) +@@ -155,7 +155,7 @@ _asn1_create_static_structure (asn1_node_const pointer, return ASN1_SUCCESS; } @@ -183,7 +183,7 @@ index 8189c56a4c9..fcfde01a393 100644 /** * asn1_array2tree: -@@ -718,7 +718,7 @@ asn1_create_element (asn1_node_const definitions, const char *source_name, +@@ -721,7 +721,7 @@ asn1_create_element (asn1_node_const definitions, const char *source_name, return res; } @@ -192,7 +192,7 @@ index 8189c56a4c9..fcfde01a393 100644 /** * asn1_print_structure: * @out: pointer to the output file (e.g. stdout). -@@ -1058,7 +1058,7 @@ asn1_print_structure (FILE * out, asn1_node_const structure, const char *name, +@@ -1062,7 +1062,7 @@ asn1_print_structure (FILE * out, asn1_node_const structure, const char *name, } } } @@ -201,7 +201,7 @@ index 8189c56a4c9..fcfde01a393 100644 /** -@@ -1153,6 +1153,7 @@ asn1_find_structure_from_oid (asn1_node_const definitions, const char *oidValue) +@@ -1158,6 +1158,7 @@ asn1_find_structure_from_oid (asn1_node_const definitions, return NULL; /* ASN1_ELEMENT_NOT_FOUND; */ } @@ -209,7 +209,7 @@ index 8189c56a4c9..fcfde01a393 100644 /** * asn1_copy_node: * @dst: Destination asn1 node. -@@ -1202,6 +1203,7 @@ asn1_copy_node (asn1_node dst, const char *dst_name, +@@ -1207,6 +1208,7 @@ asn1_copy_node (asn1_node dst, const char *dst_name, return result; } @@ -218,90 +218,93 @@ index 8189c56a4c9..fcfde01a393 100644 /** * asn1_dup_node: diff --git a/include/grub/libtasn1.h b/include/grub/libtasn1.h -index 6fd7a30dc35..785eda2ae3f 100644 +index fc695a28a..0c3a44881 100644 --- a/include/grub/libtasn1.h +++ b/include/grub/libtasn1.h -@@ -319,6 +319,8 @@ typedef struct asn1_data_node_st asn1_data_node_st; +@@ -314,6 +314,8 @@ extern "C" /* Functions definitions */ /***********************************/ +/* These functions are not used in grub and should not be referenced. */ -+#if 0 - extern ASN1_API int - asn1_parser2tree (const char *file, ++# if 0 + extern ASN1_API int + asn1_parser2tree (const char *file, asn1_node * definitions, char *error_desc); -@@ -327,14 +329,17 @@ extern ASN1_API int - asn1_parser2array (const char *inputFileName, +@@ -322,14 +324,17 @@ extern "C" + asn1_parser2array (const char *inputFileName, const char *outputFileName, const char *vectorName, char *error_desc); -+#endif ++# endif - extern ASN1_API int - asn1_array2tree (const asn1_static_node * array, + extern ASN1_API int + asn1_array2tree (const asn1_static_node * array, asn1_node * definitions, char *errorDescription); -+#if 0 - extern ASN1_API void - asn1_print_structure (FILE * out, asn1_node_const structure, ++# if 0 + extern ASN1_API void + asn1_print_structure (FILE * out, asn1_node_const structure, const char *name, int mode); -+#endif ++# endif - extern ASN1_API int - asn1_create_element (asn1_node_const definitions, -@@ -347,9 +352,11 @@ extern ASN1_API int asn1_delete_structure2 (asn1_node * structure, unsigned int - extern ASN1_API int - asn1_delete_element (asn1_node structure, const char *element_name); + extern ASN1_API int + asn1_create_element (asn1_node_const definitions, +@@ -343,9 +348,11 @@ extern "C" + extern ASN1_API int + asn1_delete_element (asn1_node structure, const char *element_name); -+#if 0 - extern ASN1_API int - asn1_write_value (asn1_node node_root, const char *name, ++# if 0 + extern ASN1_API int + asn1_write_value (asn1_node node_root, const char *name, const void *ivalue, int len); -+#endif ++# endif - extern ASN1_API int - asn1_read_value (asn1_node_const root, const char *name, -@@ -365,9 +372,11 @@ extern ASN1_API int - extern ASN1_API int - asn1_number_of_elements (asn1_node_const element, const char *name, int *num); + extern ASN1_API int + asn1_read_value (asn1_node_const root, const char *name, +@@ -362,9 +369,11 @@ extern "C" + asn1_number_of_elements (asn1_node_const element, const char *name, + int *num); -+#if 0 - extern ASN1_API int - asn1_der_coding (asn1_node_const element, const char *name, ++# if 0 + extern ASN1_API int + asn1_der_coding (asn1_node_const element, const char *name, void *ider, int *len, char *ErrorDescription); -+#endif ++# endif - extern ASN1_API int - asn1_der_decoding2 (asn1_node *element, const void *ider, -@@ -378,12 +387,14 @@ extern ASN1_API int - asn1_der_decoding (asn1_node * element, const void *ider, + extern ASN1_API int + asn1_der_decoding2 (asn1_node * element, const void *ider, +@@ -375,6 +384,7 @@ extern "C" + asn1_der_decoding (asn1_node * element, const void *ider, int ider_len, char *errorDescription); -+#if 0 ++# if 0 /* Do not use. Use asn1_der_decoding() instead. */ - extern ASN1_API int - asn1_der_decoding_element (asn1_node * structure, - const char *elementName, + extern ASN1_API int + asn1_der_decoding_element (asn1_node * structure, +@@ -382,6 +392,7 @@ extern "C" const void *ider, int len, - char *errorDescription) _ASN1_GCC_ATTR_DEPRECATED; -+#endif + char *errorDescription) + _ASN1_GCC_ATTR_DEPRECATED; ++# endif - extern ASN1_API int - asn1_der_decoding_startEnd (asn1_node element, -@@ -408,13 +419,17 @@ extern ASN1_API const char *asn1_find_structure_from_oid (asn1_node_const + extern ASN1_API int + asn1_der_decoding_startEnd (asn1_node element, +@@ -407,12 +418,16 @@ extern "C" const char *oidValue); -+#if 0 - __LIBTASN1_PURE__ - extern ASN1_API const char *asn1_check_version (const char *req_version); -+#endif ++# if 0 + __LIBTASN1_PURE__ + extern ASN1_API const char *asn1_check_version (const char *req_version); ++# endif - __LIBTASN1_PURE__ - extern ASN1_API const char *asn1_strerror (int error); + __LIBTASN1_PURE__ extern ASN1_API const char *asn1_strerror (int error); -+#if 0 - extern ASN1_API void asn1_perror (int error); -+#endif ++# if 0 + extern ASN1_API void asn1_perror (int error); ++# endif - #define ASN1_MAX_TAG_SIZE 4 - #define ASN1_MAX_LENGTH_SIZE 9 + # define ASN1_MAX_TAG_SIZE 4 + # define ASN1_MAX_LENGTH_SIZE 9 +-- +2.31.1 + diff --git a/0012-tpm-Build-tpm-as-module.patch b/0012-tpm-Build-tpm-as-module.patch new file mode 100644 index 0000000000000000000000000000000000000000..d519bd4e6e9bafea661c9e89e51fa80a25008a4a --- /dev/null +++ b/0012-tpm-Build-tpm-as-module.patch @@ -0,0 +1,54 @@ +From 54b6ba5f27dd9eb9ec2f1a41e7160964ab94451c Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Wed, 23 Nov 2016 16:52:16 +0800 +Subject: Build tpm as module + +Add --suse-enable-tpm option to grub2-install. + +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -81,6 +81,7 @@ + static char *label_bgcolor; + static char *product_version; + static int add_rs_codes = 1; ++static int suse_enable_tpm = 0; + + enum + { +@@ -107,6 +108,7 @@ + OPTION_DISK_MODULE, + OPTION_NO_BOOTSECTOR, + OPTION_NO_RS_CODES, ++ OPTION_SUSE_ENABLE_TPM, + OPTION_MACPPC_DIRECTORY, + OPTION_ZIPL_DIRECTORY, + OPTION_LABEL_FONT, +@@ -232,6 +234,10 @@ + add_rs_codes = 0; + return 0; + ++ case OPTION_SUSE_ENABLE_TPM: ++ suse_enable_tpm = 1; ++ return 0; ++ + case OPTION_DEBUG: + verbosity++; + return 0; +@@ -293,6 +299,7 @@ + {"no-rs-codes", OPTION_NO_RS_CODES, 0, 0, + N_("Do not apply any reed-solomon codes when embedding core.img. " + "This option is only available on x86 BIOS targets."), 0}, ++ {"suse-enable-tpm", OPTION_SUSE_ENABLE_TPM, 0, 0, N_("install TPM modules"), 0}, + + {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, + {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2}, +@@ -1373,6 +1380,9 @@ + else if (disk_module && disk_module[0]) + grub_install_push_module (disk_module); + ++ if (suse_enable_tpm && platform == GRUB_INSTALL_PLATFORM_X86_64_EFI) ++ grub_install_push_module ("tpm"); ++ + relative_grubdir = grub_make_system_path_relative_to_its_root (grubdir); + if (relative_grubdir[0] == '\0') + { diff --git a/0169-libtasn1-changes-for-grub-compatibility.patch b/0013-libtasn1-changes-for-grub-compatibility.patch similarity index 57% rename from 0169-libtasn1-changes-for-grub-compatibility.patch rename to 0013-libtasn1-changes-for-grub-compatibility.patch index 9b2275cab19dc1ab55a3e30380e5c2654da263b9..097de0f94ccaf773b9f0356c84db069626d55682 100644 --- a/0169-libtasn1-changes-for-grub-compatibility.patch +++ b/0013-libtasn1-changes-for-grub-compatibility.patch @@ -1,12 +1,13 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From f05ba09c9adea447d3ca837c73498b9619306180 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Fri, 1 May 2020 20:44:29 +1000 -Subject: [PATCH] libtasn1: changes for grub compatibility +Subject: [PATCH 13/23] libtasn1: changes for grub compatibility Do a few things to make libtasn1 compile as part of grub: - - replace strcat. grub removed strcat so replace it with the appropriate - calls to memcpy and strlen. + - redefine _asn1_strcat. grub removed strcat so replace it with the + appropriate calls to memcpy and strlen. Use this internally where + strcat was used. - replace c_isdigit with grub_isdigit (and don't import c-ctype from gnulib) grub_isdigit provides the same functionality as c_isdigit: it @@ -25,53 +26,57 @@ Do a few things to make libtasn1 compile as part of grub: creation of __udivdi3 calls on 32 bit platforms. Signed-off-by: Daniel Axtens + +--- + +v2: Clean up strcat handling, thanks Stefan Berger. --- - grub-core/lib/libtasn1/lib/decoding.c | 11 ++++++----- + grub-core/lib/libtasn1/lib/decoding.c | 11 +++++----- grub-core/lib/libtasn1/lib/element.c | 3 ++- grub-core/lib/libtasn1/lib/gstr.c | 4 ++-- - grub-core/lib/libtasn1/lib/parser_aux.c | 7 ++++--- grub-core/lib/libtasn1/lib/int.h | 4 ++-- - include/grub/libtasn1.h | 26 ++++++-------------------- - 6 files changed, 22 insertions(+), 33 deletions(-) + grub-core/lib/libtasn1/lib/parser_aux.c | 7 +++--- + include/grub/libtasn1.h | 29 +++++++------------------ + 6 files changed, 24 insertions(+), 34 deletions(-) diff --git a/grub-core/lib/libtasn1/lib/decoding.c b/grub-core/lib/libtasn1/lib/decoding.c -index 42f9a92b5d4..7856858b272 100644 +index b8130b956..beeb6a176 100644 --- a/grub-core/lib/libtasn1/lib/decoding.c +++ b/grub-core/lib/libtasn1/lib/decoding.c @@ -32,7 +32,8 @@ #include #include #include --#include +-#include "c-ctype.h" + +#define c_isdigit grub_isdigit #ifdef DEBUG # define warn() fprintf(stderr, "%s: %d\n", __func__, __LINE__) -@@ -2008,8 +2009,8 @@ asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element, +@@ -2016,8 +2017,8 @@ asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element, (p2->type & CONST_ASSIGN)) { strcpy (name, definitions->name); - strcat (name, "."); - strcat (name, p2->name); -+ memcpy (name + strlen(name), ".", sizeof(" . ")); -+ memcpy (name + strlen(name), p2->name, strlen(p2->name) + 1); ++ _asn1_strcat (name, "."); ++ _asn1_strcat (name, p2->name); len = sizeof (value); result = asn1_read_value (definitions, name, value, &len); -@@ -2026,8 +2027,8 @@ asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element, +@@ -2034,8 +2035,8 @@ asn1_expand_octet_string (asn1_node_const definitions, asn1_node * element, if (p2) { strcpy (name, definitions->name); - strcat (name, "."); - strcat (name, p2->name); -+ memcpy (name + strlen(name), ".", sizeof(" . ")); -+ memcpy (name + strlen(name), p2->name, strlen(p2->name) + 1); ++ _asn1_strcat (name, "."); ++ _asn1_strcat (name, p2->name); result = asn1_create_element (definitions, name, &aux); if (result == ASN1_SUCCESS) diff --git a/grub-core/lib/libtasn1/lib/element.c b/grub-core/lib/libtasn1/lib/element.c -index 539008d8e94..ed761ff56bd 100644 +index 8cd6b662c..150b9b377 100644 --- a/grub-core/lib/libtasn1/lib/element.c +++ b/grub-core/lib/libtasn1/lib/element.c @@ -30,9 +30,10 @@ @@ -87,7 +92,7 @@ index 539008d8e94..ed761ff56bd 100644 _asn1_hierarchical_name (asn1_node_const node, char *name, int name_size) { diff --git a/grub-core/lib/libtasn1/lib/gstr.c b/grub-core/lib/libtasn1/lib/gstr.c -index e91a3a151c0..e33875c2c7c 100644 +index 1475ed51b..b729089db 100644 --- a/grub-core/lib/libtasn1/lib/gstr.c +++ b/grub-core/lib/libtasn1/lib/gstr.c @@ -36,13 +36,13 @@ _asn1_str_cat (char *dest, size_t dest_tot_size, const char *src) @@ -95,19 +100,41 @@ index e91a3a151c0..e33875c2c7c 100644 if (dest_tot_size - dest_size > str_size) { - strcat (dest, src); -+ memcpy (dest + dest_size, src, str_size + 1); ++ _asn1_strcat (dest, src); } else { - if (dest_tot_size - dest_size > 0) + if (dest_tot_size > dest_size) { - strncat (dest, src, (dest_tot_size - dest_size) - 1); + memcpy (dest + dest_size, src, (dest_tot_size - dest_size) - 1); dest[dest_tot_size - 1] = 0; } } +diff --git a/grub-core/lib/libtasn1/lib/int.h b/grub-core/lib/libtasn1/lib/int.h +index 404cd1562..edfe84a0e 100644 +--- a/grub-core/lib/libtasn1/lib/int.h ++++ b/grub-core/lib/libtasn1/lib/int.h +@@ -35,7 +35,7 @@ + # include + # endif + +-# include ++# include "grub/libtasn1.h" + + # define ASN1_SMALL_VALUE_SIZE 16 + +@@ -115,7 +115,7 @@ extern const tag_and_class_st _asn1_tags[]; + # define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b) + # define _asn1_strcmp(a,b) strcmp((const char *)a, (const char *)b) + # define _asn1_strcpy(a,b) strcpy((char *)a, (const char *)b) +-# define _asn1_strcat(a,b) strcat((char *)a, (const char *)b) ++# define _asn1_strcat(a,b) memcpy((char *)a + strlen((const char *)a), (const char *)b, strlen((const char *)b) + 1) + + # if SIZEOF_UNSIGNED_LONG_INT == 8 + # define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b) diff --git a/grub-core/lib/libtasn1/lib/parser_aux.c b/grub-core/lib/libtasn1/lib/parser_aux.c -index d5dbbf8765d..89c9be69dc2 100644 +index c99c5a4cb..a933f03ed 100644 --- a/grub-core/lib/libtasn1/lib/parser_aux.c +++ b/grub-core/lib/libtasn1/lib/parser_aux.c @@ -26,7 +26,8 @@ @@ -122,14 +149,14 @@ index d5dbbf8765d..89c9be69dc2 100644 @@ -40,7 +41,7 @@ char _asn1_identifierMissing[ASN1_MAX_NAME_SIZE + 1]; /* identifier name not fou #ifdef __clang__ - __attribute__((no_sanitize("integer"))) + __attribute__((no_sanitize ("integer"))) #endif --_GL_ATTRIBUTE_PURE -+__attribute__((__pure__)) - static unsigned int - _asn1_hash_name (const char *x) +- _GL_ATTRIBUTE_PURE static unsigned int _asn1_hash_name (const char *x) ++ __attribute__((__pure__)) static unsigned int _asn1_hash_name (const char *x) { -@@ -634,7 +635,7 @@ _asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]) + const unsigned char *s = (unsigned char *) x; + unsigned h = 0; +@@ -632,7 +633,7 @@ _asn1_ltostr (int64_t v, char str[LTOSTR_MAX_SIZE]) count = 0; do { @@ -138,65 +165,48 @@ index d5dbbf8765d..89c9be69dc2 100644 r = val - d * 10; temp[start + count] = '0' + (char) r; count++; -diff --git a/grub-core/lib/libtasn1/lib/int.h b/grub-core/lib/libtasn1/lib/int.h -index ea1625786c1..4a568efee9c 100644 ---- a/grub-core/lib/libtasn1/lib/int.h -+++ b/grub-core/lib/libtasn1/lib/int.h -@@ -35,7 +35,7 @@ - #include - #endif - --#include -+#include "grub/libtasn1.h" - - #define ASN1_SMALL_VALUE_SIZE 16 - -@@ -115,7 +115,7 @@ extern const tag_and_class_st _asn1_tags[]; - #define _asn1_strtoul(n,e,b) strtoul((const char *) n, e, b) - #define _asn1_strcmp(a,b) strcmp((const char *)a, (const char *)b) - #define _asn1_strcpy(a,b) strcpy((char *)a, (const char *)b) --#define _asn1_strcat(a,b) strcat((char *)a, (const char *)b) -+#define _asn1_strcat(a,b) memcpy((char *)a + strlen((const char *)a), (const char *)b, strlen((const char *)b) + 1) - - #if SIZEOF_UNSIGNED_LONG_INT == 8 - # define _asn1_strtou64(n,e,b) strtoul((const char *) n, e, b) diff --git a/include/grub/libtasn1.h b/include/grub/libtasn1.h -index 785eda2ae3f..28dbf16c4e0 100644 +index 0c3a44881..2ea058a3b 100644 --- a/include/grub/libtasn1.h +++ b/include/grub/libtasn1.h -@@ -38,29 +38,15 @@ +@@ -34,29 +34,16 @@ #ifndef LIBTASN1_H - #define LIBTASN1_H + # define LIBTASN1_H --#ifndef ASN1_API --#if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY --#define ASN1_API __attribute__((__visibility__("default"))) --#elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC --#define ASN1_API __declspec(dllexport) --#elif defined _MSC_VER && ! defined ASN1_STATIC --#define ASN1_API __declspec(dllimport) --#else +-# ifndef ASN1_API +-# if defined ASN1_BUILDING && defined HAVE_VISIBILITY && HAVE_VISIBILITY +-# define ASN1_API __attribute__((__visibility__("default"))) +-# elif defined ASN1_BUILDING && defined _MSC_VER && ! defined ASN1_STATIC +-# define ASN1_API __declspec(dllexport) +-# elif defined _MSC_VER && ! defined ASN1_STATIC +-# define ASN1_API __declspec(dllimport) +-# else +-# define ASN1_API +-# endif +-# endif +/* grub: ASN1_API is not used */ - #define ASN1_API --#endif --#endif - --#ifdef __GNUC__ --# define __LIBTASN1_CONST__ __attribute__((const)) --# define __LIBTASN1_PURE__ __attribute__((pure)) --#else --# define __LIBTASN1_CONST__ --# define __LIBTASN1_PURE__ --#endif ++# define ASN1_API ++ +/* grub: all our supported compilers support these attributes */ -+#define __LIBTASN1_CONST__ __attribute__((const)) -+#define __LIBTASN1_PURE__ __attribute__((pure)) ++# define __LIBTASN1_CONST__ __attribute__((const)) ++# define __LIBTASN1_PURE__ __attribute__((pure)) + +-# ifdef __GNUC__ +-# define __LIBTASN1_CONST__ __attribute__((const)) +-# define __LIBTASN1_PURE__ __attribute__((pure)) +-# else +-# define __LIBTASN1_CONST__ +-# define __LIBTASN1_PURE__ +-# endif --#include --#include --#include /* for FILE* */ -+#include -+#include +-# include +-# include +-# include /* for FILE* */ ++# include ++# include - #ifdef __cplusplus + # ifdef __cplusplus extern "C" +-- +2.31.1 + diff --git a/0014-Move-bash-completion-script-922997.patch b/0014-Move-bash-completion-script-922997.patch deleted file mode 100644 index 6bf0b4b9aeb1f09b932ea55125144c05274cb3d0..0000000000000000000000000000000000000000 --- a/0014-Move-bash-completion-script-922997.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 3 Apr 2013 14:35:34 -0400 -Subject: [PATCH] Move bash completion script (#922997) - -Apparently these go in a new place now. ---- - configure.ac | 11 +++++++++++ - util/bash-completion.d/Makefile.am | 1 - - 2 files changed, 11 insertions(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 7517fc49d98..8331f95b645 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -314,6 +314,14 @@ AC_SUBST(grubdirname) - AC_DEFINE_UNQUOTED(GRUB_DIR_NAME, "$grubdirname", - [Default grub directory name]) - -+PKG_PROG_PKG_CONFIG -+AS_IF([$($PKG_CONFIG --exists bash-completion)], [ -+ bashcompletiondir=$($PKG_CONFIG --variable=completionsdir bash-completion) -+] , [ -+ bashcompletiondir=${datadir}/bash-completion/completions -+]) -+AC_SUBST(bashcompletiondir) -+ - # - # Checks for build programs. - # -@@ -525,6 +533,9 @@ HOST_CFLAGS="$HOST_CFLAGS $grub_cv_cc_w_extra_flags" - # Check for target programs. - # - -+# This makes sure pkg.m4 is available. -+m4_pattern_forbid([^_?PKG_[A-Z_]+$],[*** pkg.m4 missing, please install pkg-config]) -+ - # Find tools for the target. - if test "x$target_alias" != x && test "x$host_alias" != "x$target_alias"; then - tmp_ac_tool_prefix="$ac_tool_prefix" -diff --git a/util/bash-completion.d/Makefile.am b/util/bash-completion.d/Makefile.am -index 136287cf1bf..61108f05429 100644 ---- a/util/bash-completion.d/Makefile.am -+++ b/util/bash-completion.d/Makefile.am -@@ -6,7 +6,6 @@ EXTRA_DIST = $(bash_completion_source) - - CLEANFILES = $(bash_completion_script) config.log - --bashcompletiondir = $(sysconfdir)/bash_completion.d - bashcompletion_DATA = $(bash_completion_script) - - $(bash_completion_script): $(bash_completion_source) $(top_builddir)/config.status diff --git a/0170-libtasn1-compile-into-asn1-module.patch b/0014-libtasn1-compile-into-asn1-module.patch similarity index 82% rename from 0170-libtasn1-compile-into-asn1-module.patch rename to 0014-libtasn1-compile-into-asn1-module.patch index 67be4e877eae6ed1503768ce0dfc9135c2dcd6d7..eb797843f8704cf88df7fb40bca53a0d82185a21 100644 --- a/0170-libtasn1-compile-into-asn1-module.patch +++ b/0014-libtasn1-compile-into-asn1-module.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From f3b818444fe8628d581f5efe23d55554f23718c8 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Fri, 5 Jun 2020 17:47:25 +1000 -Subject: [PATCH] libtasn1: compile into asn1 module +Subject: [PATCH 14/23] libtasn1: compile into asn1 module Create a wrapper file that specifies the module license. Set up the makefile so it is built. @@ -13,13 +13,11 @@ Signed-off-by: Daniel Axtens 2 files changed, 41 insertions(+) create mode 100644 grub-core/lib/libtasn1_wrap/wrap.c -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 97347ae76f9..21d2c541850 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -2576,3 +2576,18 @@ module = { - common = commands/i386/wrmsr.c; - enable = x86; +@@ -2624,3 +2624,18 @@ + name = cmdline; + common = lib/cmdline.c; }; + +module = { @@ -36,9 +34,6 @@ index 97347ae76f9..21d2c541850 100644 + // -Wno-type-limits comes from libtasn1's configure.ac + cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -I$(srcdir)/lib/libtasn1/lib -Wno-type-limits'; +}; -diff --git a/grub-core/lib/libtasn1_wrap/wrap.c b/grub-core/lib/libtasn1_wrap/wrap.c -new file mode 100644 -index 00000000000..622ba942e33 --- /dev/null +++ b/grub-core/lib/libtasn1_wrap/wrap.c @@ -0,0 +1,26 @@ diff --git a/0015-Allow-fallback-to-include-entries-by-title-not-just-.patch b/0015-Allow-fallback-to-include-entries-by-title-not-just-.patch deleted file mode 100644 index f2a4a82c1199a076368b6dbac4c7d6be4ad442c5..0000000000000000000000000000000000000000 --- a/0015-Allow-fallback-to-include-entries-by-title-not-just-.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 5 Sep 2014 10:07:04 -0400 -Subject: [PATCH] Allow "fallback" to include entries by title, not just - number. - -Resolves: rhbz#1026084 - -Signed-off-by: Peter Jones ---- - grub-core/normal/menu.c | 85 +++++++++++++++++++++++++++++++++---------------- - 1 file changed, 58 insertions(+), 27 deletions(-) - -diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c -index 8397886fa05..d7a222e681b 100644 ---- a/grub-core/normal/menu.c -+++ b/grub-core/normal/menu.c -@@ -163,15 +163,40 @@ grub_menu_set_timeout (int timeout) - } - } - -+static int -+menuentry_eq (const char *id, const char *spec) -+{ -+ const char *ptr1, *ptr2; -+ ptr1 = id; -+ ptr2 = spec; -+ while (1) -+ { -+ if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0) -+ return ptr2 - spec; -+ if (*ptr2 == '>' && ptr2[1] != '>') -+ return 0; -+ if (*ptr2 == '>') -+ ptr2++; -+ if (*ptr1 != *ptr2) -+ return 0; -+ if (*ptr1 == 0) -+ return ptr1 - id; -+ ptr1++; -+ ptr2++; -+ } -+ return 0; -+} -+ - /* Get the first entry number from the value of the environment variable NAME, - which is a space-separated list of non-negative integers. The entry number - which is returned is stripped from the value of NAME. If no entry number - can be found, -1 is returned. */ - static int --get_and_remove_first_entry_number (const char *name) -+get_and_remove_first_entry_number (grub_menu_t menu, const char *name) - { - const char *val, *tail; - int entry; -+ int sz = 0; - - val = grub_env_get (name); - if (! val) -@@ -181,9 +206,39 @@ get_and_remove_first_entry_number (const char *name) - - entry = (int) grub_strtoul (val, &tail, 0); - -+ if (grub_errno == GRUB_ERR_BAD_NUMBER) -+ { -+ /* See if the variable matches the title of a menu entry. */ -+ grub_menu_entry_t e = menu->entry_list; -+ int i; -+ -+ for (i = 0; e; i++) -+ { -+ sz = menuentry_eq (e->title, val); -+ if (sz < 1) -+ sz = menuentry_eq (e->id, val); -+ -+ if (sz >= 1) -+ { -+ entry = i; -+ break; -+ } -+ e = e->next; -+ } -+ -+ if (sz > 0) -+ grub_errno = GRUB_ERR_NONE; -+ -+ if (! e) -+ entry = -1; -+ } -+ - if (grub_errno == GRUB_ERR_NONE) - { -- /* Skip whitespace to find the next digit. */ -+ if (sz > 0) -+ tail += sz; -+ -+ /* Skip whitespace to find the next entry. */ - while (*tail && grub_isspace (*tail)) - tail++; - grub_env_set (name, tail); -@@ -346,7 +401,7 @@ grub_menu_execute_with_fallback (grub_menu_t menu, - grub_menu_execute_entry (entry, 1); - - /* Deal with fallback entries. */ -- while ((fallback_entry = get_and_remove_first_entry_number ("fallback")) -+ while ((fallback_entry = get_and_remove_first_entry_number (menu, "fallback")) - >= 0) - { - grub_print_error (); -@@ -464,30 +519,6 @@ grub_menu_register_viewer (struct grub_menu_viewer *viewer) - viewers = viewer; - } - --static int --menuentry_eq (const char *id, const char *spec) --{ -- const char *ptr1, *ptr2; -- ptr1 = id; -- ptr2 = spec; -- while (1) -- { -- if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0) -- return 1; -- if (*ptr2 == '>' && ptr2[1] != '>') -- return 0; -- if (*ptr2 == '>') -- ptr2++; -- if (*ptr1 != *ptr2) -- return 0; -- if (*ptr1 == 0) -- return 1; -- ptr1++; -- ptr2++; -- } --} -- -- - /* Get the entry number from the variable NAME. */ - static int - get_entry_number (grub_menu_t menu, const char *name) diff --git a/0171-test_asn1-test-module-for-libtasn1.patch b/0015-test_asn1-test-module-for-libtasn1.patch similarity index 97% rename from 0171-test_asn1-test-module-for-libtasn1.patch rename to 0015-test_asn1-test-module-for-libtasn1.patch index b659558b0273b1e0d47e3bdf85c0ca6e32404de8..af61571ed6f24212439fccf96b8a74e2330cf701 100644 --- a/0171-test_asn1-test-module-for-libtasn1.patch +++ b/0015-test_asn1-test-module-for-libtasn1.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 5fcbd6e61cd5390e3e0d0f65eb622761d23bab4e Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Wed, 10 Jun 2020 17:48:42 +1000 -Subject: [PATCH] test_asn1: test module for libtasn1 +Subject: [PATCH 15/23] test_asn1: test module for libtasn1 Import tests from libtasn1 that don't use functionality we don't import. I have put them here rather than in the libtasn1 directory @@ -19,23 +19,24 @@ test suites for coming patch sets. Signed-off-by: Daniel Axtens --- - Makefile.util.def | 6 + - grub-core/Makefile.core.def | 13 ++ - .../lib/libtasn1_wrap/tests/CVE-2018-1000654.c | 61 ++++++ - grub-core/lib/libtasn1_wrap/tests/Test_overflow.c | 138 ++++++++++++++ - grub-core/lib/libtasn1_wrap/tests/Test_simple.c | 207 ++++++++++++++++++++ - grub-core/lib/libtasn1_wrap/tests/Test_strings.c | 150 +++++++++++++++ - .../lib/libtasn1_wrap/tests/object-id-decoding.c | 116 +++++++++++ - .../lib/libtasn1_wrap/tests/object-id-encoding.c | 120 ++++++++++++ - grub-core/lib/libtasn1_wrap/tests/octet-string.c | 211 +++++++++++++++++++++ - grub-core/lib/libtasn1_wrap/tests/reproducers.c | 81 ++++++++ - grub-core/lib/libtasn1_wrap/wrap_tests.c | 75 ++++++++ - .../tests/CVE-2018-1000654-1_asn1_tab.h | 32 ++++ - .../tests/CVE-2018-1000654-2_asn1_tab.h | 36 ++++ - grub-core/lib/libtasn1_wrap/wrap_tests.h | 38 ++++ - .gitignore | 1 + - tests/test_asn1.in | 12 ++ - 16 files changed, 1297 insertions(+) + Makefile.util.def | 6 + + grub-core/Makefile.core.def | 13 ++ + .../tests/CVE-2018-1000654-1_asn1_tab.h | 32 +++ + .../tests/CVE-2018-1000654-2_asn1_tab.h | 36 +++ + .../libtasn1_wrap/tests/CVE-2018-1000654.c | 61 +++++ + .../lib/libtasn1_wrap/tests/Test_overflow.c | 138 ++++++++++++ + .../lib/libtasn1_wrap/tests/Test_simple.c | 207 +++++++++++++++++ + .../lib/libtasn1_wrap/tests/Test_strings.c | 150 +++++++++++++ + .../libtasn1_wrap/tests/object-id-decoding.c | 116 ++++++++++ + .../libtasn1_wrap/tests/object-id-encoding.c | 120 ++++++++++ + .../lib/libtasn1_wrap/tests/octet-string.c | 211 ++++++++++++++++++ + .../lib/libtasn1_wrap/tests/reproducers.c | 81 +++++++ + grub-core/lib/libtasn1_wrap/wrap_tests.c | 75 +++++++ + grub-core/lib/libtasn1_wrap/wrap_tests.h | 38 ++++ + tests/test_asn1.in | 12 + + 15 files changed, 1296 insertions(+) + create mode 100644 grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-1_asn1_tab.h + create mode 100644 grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-2_asn1_tab.h create mode 100644 grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654.c create mode 100644 grub-core/lib/libtasn1_wrap/tests/Test_overflow.c create mode 100644 grub-core/lib/libtasn1_wrap/tests/Test_simple.c @@ -45,33 +46,27 @@ Signed-off-by: Daniel Axtens create mode 100644 grub-core/lib/libtasn1_wrap/tests/octet-string.c create mode 100644 grub-core/lib/libtasn1_wrap/tests/reproducers.c create mode 100644 grub-core/lib/libtasn1_wrap/wrap_tests.c - create mode 100644 grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-1_asn1_tab.h - create mode 100644 grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-2_asn1_tab.h create mode 100644 grub-core/lib/libtasn1_wrap/wrap_tests.h create mode 100644 tests/test_asn1.in -diff --git a/Makefile.util.def b/Makefile.util.def -index 9927c2cfd6a..3f191aa8095 100644 --- a/Makefile.util.def +++ b/Makefile.util.def -@@ -1306,6 +1306,12 @@ script = { - common = tests/syslinux_test.in; +@@ -1304,6 +1304,12 @@ + common = tests/luks2_test.in; }; +script = { -+ testcase; ++ testcase = native; + name = test_asn1; + common = tests/test_asn1.in; +}; + program = { - testcase; + testcase = native; name = example_unit_test; -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 21d2c541850..b4aaccf7b57 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -2591,3 +2591,16 @@ module = { +@@ -2639,3 +2639,16 @@ // -Wno-type-limits comes from libtasn1's configure.ac cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB) -I$(srcdir)/lib/libtasn1/lib -Wno-type-limits'; }; @@ -88,9 +83,80 @@ index 21d2c541850..b4aaccf7b57 100644 + common = lib/libtasn1_wrap/tests/Test_strings.c; + common = lib/libtasn1_wrap/wrap_tests.c; +}; -diff --git a/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654.c b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654.c -new file mode 100644 -index 00000000000..534e304521e +--- /dev/null ++++ b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-1_asn1_tab.h +@@ -0,0 +1,32 @@ ++#if HAVE_CONFIG_H ++# include "config.h" ++#endif ++ ++#include ++ ++const asn1_static_node CVE_2018_1000654_1_asn1_tab[] = { ++ { "TEST_TREE", 536875024, NULL }, ++ { NULL, 1610612748, NULL }, ++ { "iso", 1073741825, "1"}, ++ { "identified-organization", 1073741825, "3"}, ++ { "dod", 1073741825, "6"}, ++ { "internet", 1073741825, "1"}, ++ { "security", 1073741825, "5"}, ++ { "mechanisms", 1073741825, "5"}, ++ { "pkix", 1073741825, "7"}, ++ { "id-mod", 1073741825, "0"}, ++ { "id-pkix1-implicit-88", 1, "2"}, ++ { "id-xnyTest", 1879048204, NULL }, ++ { NULL, 1073741825, "id-ix"}, ++ { NULL, 1073741825, "29"}, ++ { NULL, 1, "1"}, ++ { "id-ix", 1880096780, "OBJECR"}, ++ { NULL, 1073741825, "id-ix"}, ++ { NULL, 1073741825, "29"}, ++ { NULL, 1, "2"}, ++ { "id-xnyTest", 805306380, NULL }, ++ { NULL, 1073741825, "id-ix"}, ++ { NULL, 1073741825, "29"}, ++ { NULL, 1, "1"}, ++ { NULL, 0, NULL } ++}; +--- /dev/null ++++ b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-2_asn1_tab.h +@@ -0,0 +1,36 @@ ++#if HAVE_CONFIG_H ++# include "config.h" ++#endif ++ ++#include ++ ++const asn1_static_node CVE_2018_1000654_2_asn1_tab[] = { ++ { "TEST_TREE", 536875024, NULL }, ++ { NULL, 1610612748, NULL }, ++ { "iso", 1073741825, "1"}, ++ { "identified-organization", 1073741825, "3"}, ++ { "dod", 1073741825, "6"}, ++ { "internet", 1073741825, "1"}, ++ { "security", 1073741825, "5"}, ++ { "mechanisms", 1073741825, "5"}, ++ { "pkix", 1073741825, "7"}, ++ { "id-mod", 1073741825, "0"}, ++ { "id-pkix1-implicit-88", 1, "2"}, ++ { "id-oneTest", 1879048204, NULL }, ++ { NULL, 1073741825, "id-two"}, ++ { NULL, 1073741825, "9"}, ++ { NULL, 1, "1"}, ++ { "id-two", 1879048204, NULL }, ++ { NULL, 1073741825, "id-three"}, ++ { NULL, 1073741825, "2"}, ++ { NULL, 1, "2"}, ++ { "id-three", 1879048204, NULL }, ++ { NULL, 1073741825, "id-four"}, ++ { NULL, 1073741825, "3"}, ++ { NULL, 1, "3"}, ++ { "id-four", 805306380, NULL }, ++ { NULL, 1073741825, "id-two"}, ++ { NULL, 1073741825, "3"}, ++ { NULL, 1, "3"}, ++ { NULL, 0, NULL } ++}; --- /dev/null +++ b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654.c @@ -0,0 +1,61 @@ @@ -155,9 +221,6 @@ index 00000000000..534e304521e + + asn1_delete_structure (&definitions); +} -diff --git a/grub-core/lib/libtasn1_wrap/tests/Test_overflow.c b/grub-core/lib/libtasn1_wrap/tests/Test_overflow.c -new file mode 100644 -index 00000000000..f48aea0ef8b --- /dev/null +++ b/grub-core/lib/libtasn1_wrap/tests/Test_overflow.c @@ -0,0 +1,138 @@ @@ -299,9 +362,6 @@ index 00000000000..f48aea0ef8b + } + } +} -diff --git a/grub-core/lib/libtasn1_wrap/tests/Test_simple.c b/grub-core/lib/libtasn1_wrap/tests/Test_simple.c -new file mode 100644 -index 00000000000..9f01006ddf4 --- /dev/null +++ b/grub-core/lib/libtasn1_wrap/tests/Test_simple.c @@ -0,0 +1,207 @@ @@ -512,9 +572,6 @@ index 00000000000..9f01006ddf4 + return; + } +} -diff --git a/grub-core/lib/libtasn1_wrap/tests/Test_strings.c b/grub-core/lib/libtasn1_wrap/tests/Test_strings.c -new file mode 100644 -index 00000000000..dbe1474b204 --- /dev/null +++ b/grub-core/lib/libtasn1_wrap/tests/Test_strings.c @@ -0,0 +1,150 @@ @@ -668,9 +725,6 @@ index 00000000000..dbe1474b204 + grub_free(b); + } +} -diff --git a/grub-core/lib/libtasn1_wrap/tests/object-id-decoding.c b/grub-core/lib/libtasn1_wrap/tests/object-id-decoding.c -new file mode 100644 -index 00000000000..d367bbfb5a7 --- /dev/null +++ b/grub-core/lib/libtasn1_wrap/tests/object-id-decoding.c @@ -0,0 +1,116 @@ @@ -790,9 +844,6 @@ index 00000000000..d367bbfb5a7 + + } +} -diff --git a/grub-core/lib/libtasn1_wrap/tests/object-id-encoding.c b/grub-core/lib/libtasn1_wrap/tests/object-id-encoding.c -new file mode 100644 -index 00000000000..3a83b58c59f --- /dev/null +++ b/grub-core/lib/libtasn1_wrap/tests/object-id-encoding.c @@ -0,0 +1,120 @@ @@ -916,9 +967,6 @@ index 00000000000..3a83b58c59f + } + } +} -diff --git a/grub-core/lib/libtasn1_wrap/tests/octet-string.c b/grub-core/lib/libtasn1_wrap/tests/octet-string.c -new file mode 100644 -index 00000000000..d8a049e8df0 --- /dev/null +++ b/grub-core/lib/libtasn1_wrap/tests/octet-string.c @@ -0,0 +1,211 @@ @@ -1133,9 +1181,6 @@ index 00000000000..d8a049e8df0 + + } +} -diff --git a/grub-core/lib/libtasn1_wrap/tests/reproducers.c b/grub-core/lib/libtasn1_wrap/tests/reproducers.c -new file mode 100644 -index 00000000000..dc7268d4c6c --- /dev/null +++ b/grub-core/lib/libtasn1_wrap/tests/reproducers.c @@ -0,0 +1,81 @@ @@ -1220,9 +1265,6 @@ index 00000000000..dc7268d4c6c + + asn1_delete_structure (&definitions); +} -diff --git a/grub-core/lib/libtasn1_wrap/wrap_tests.c b/grub-core/lib/libtasn1_wrap/wrap_tests.c -new file mode 100644 -index 00000000000..75fcd21f0d5 --- /dev/null +++ b/grub-core/lib/libtasn1_wrap/wrap_tests.c @@ -0,0 +1,75 @@ @@ -1301,89 +1343,6 @@ index 00000000000..75fcd21f0d5 +{ + grub_unregister_command (cmd); +} -diff --git a/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-1_asn1_tab.h b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-1_asn1_tab.h -new file mode 100644 -index 00000000000..1e7d3d64f55 ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-1_asn1_tab.h -@@ -0,0 +1,32 @@ -+#if HAVE_CONFIG_H -+# include "config.h" -+#endif -+ -+#include -+ -+const asn1_static_node CVE_2018_1000654_1_asn1_tab[] = { -+ { "TEST_TREE", 536875024, NULL }, -+ { NULL, 1610612748, NULL }, -+ { "iso", 1073741825, "1"}, -+ { "identified-organization", 1073741825, "3"}, -+ { "dod", 1073741825, "6"}, -+ { "internet", 1073741825, "1"}, -+ { "security", 1073741825, "5"}, -+ { "mechanisms", 1073741825, "5"}, -+ { "pkix", 1073741825, "7"}, -+ { "id-mod", 1073741825, "0"}, -+ { "id-pkix1-implicit-88", 1, "2"}, -+ { "id-xnyTest", 1879048204, NULL }, -+ { NULL, 1073741825, "id-ix"}, -+ { NULL, 1073741825, "29"}, -+ { NULL, 1, "1"}, -+ { "id-ix", 1880096780, "OBJECR"}, -+ { NULL, 1073741825, "id-ix"}, -+ { NULL, 1073741825, "29"}, -+ { NULL, 1, "2"}, -+ { "id-xnyTest", 805306380, NULL }, -+ { NULL, 1073741825, "id-ix"}, -+ { NULL, 1073741825, "29"}, -+ { NULL, 1, "1"}, -+ { NULL, 0, NULL } -+}; -diff --git a/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-2_asn1_tab.h b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-2_asn1_tab.h -new file mode 100644 -index 00000000000..e2561e5ec6d ---- /dev/null -+++ b/grub-core/lib/libtasn1_wrap/tests/CVE-2018-1000654-2_asn1_tab.h -@@ -0,0 +1,36 @@ -+#if HAVE_CONFIG_H -+# include "config.h" -+#endif -+ -+#include -+ -+const asn1_static_node CVE_2018_1000654_2_asn1_tab[] = { -+ { "TEST_TREE", 536875024, NULL }, -+ { NULL, 1610612748, NULL }, -+ { "iso", 1073741825, "1"}, -+ { "identified-organization", 1073741825, "3"}, -+ { "dod", 1073741825, "6"}, -+ { "internet", 1073741825, "1"}, -+ { "security", 1073741825, "5"}, -+ { "mechanisms", 1073741825, "5"}, -+ { "pkix", 1073741825, "7"}, -+ { "id-mod", 1073741825, "0"}, -+ { "id-pkix1-implicit-88", 1, "2"}, -+ { "id-oneTest", 1879048204, NULL }, -+ { NULL, 1073741825, "id-two"}, -+ { NULL, 1073741825, "9"}, -+ { NULL, 1, "1"}, -+ { "id-two", 1879048204, NULL }, -+ { NULL, 1073741825, "id-three"}, -+ { NULL, 1073741825, "2"}, -+ { NULL, 1, "2"}, -+ { "id-three", 1879048204, NULL }, -+ { NULL, 1073741825, "id-four"}, -+ { NULL, 1073741825, "3"}, -+ { NULL, 1, "3"}, -+ { "id-four", 805306380, NULL }, -+ { NULL, 1073741825, "id-two"}, -+ { NULL, 1073741825, "3"}, -+ { NULL, 1, "3"}, -+ { NULL, 0, NULL } -+}; -diff --git a/grub-core/lib/libtasn1_wrap/wrap_tests.h b/grub-core/lib/libtasn1_wrap/wrap_tests.h -new file mode 100644 -index 00000000000..555e56dd202 --- /dev/null +++ b/grub-core/lib/libtasn1_wrap/wrap_tests.h @@ -0,0 +1,38 @@ @@ -1425,21 +1384,6 @@ index 00000000000..555e56dd202 +void test_strings (void); + +#endif -diff --git a/.gitignore b/.gitignore -index 594d0134d33..856e69bc5c1 100644 ---- a/.gitignore -+++ b/.gitignore -@@ -264,6 +264,7 @@ widthspec.bin - /stamp-h1 - /syslinux_test - /tar_test -+/test_asn1 - /test_sha512sum - /test_unset - /tests/syslinux/ubuntu10.04_grub.cfg -diff --git a/tests/test_asn1.in b/tests/test_asn1.in -new file mode 100644 -index 00000000000..8173c5c270e --- /dev/null +++ b/tests/test_asn1.in @@ -0,0 +1,12 @@ diff --git a/0016-Make-exit-take-a-return-code.patch b/0016-Make-exit-take-a-return-code.patch deleted file mode 100644 index 39d70573676e088028c053f8e5bdca2f6f2cb422..0000000000000000000000000000000000000000 --- a/0016-Make-exit-take-a-return-code.patch +++ /dev/null @@ -1,267 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 26 Feb 2014 21:49:12 -0500 -Subject: [PATCH] Make "exit" take a return code. - -This adds "exit" with a return code. With this patch, any "exit" -command /may/ include a return code, and on platforms that support -returning with an exit status, we will do so. By default we return the -same exit status we did before this patch. - -Signed-off-by: Peter Jones ---- - grub-core/commands/minicmd.c | 20 ++++++++++++++++---- - grub-core/kern/efi/efi.c | 9 +++++++-- - grub-core/kern/emu/main.c | 2 +- - grub-core/kern/emu/misc.c | 5 +++-- - grub-core/kern/i386/coreboot/init.c | 2 +- - grub-core/kern/i386/qemu/init.c | 2 +- - grub-core/kern/ieee1275/init.c | 2 +- - grub-core/kern/mips/arc/init.c | 2 +- - grub-core/kern/mips/loongson/init.c | 2 +- - grub-core/kern/mips/qemu_mips/init.c | 2 +- - grub-core/kern/misc.c | 11 ++++++++++- - grub-core/kern/uboot/init.c | 6 +++--- - grub-core/kern/xen/init.c | 2 +- - include/grub/misc.h | 2 +- - 14 files changed, 48 insertions(+), 21 deletions(-) - -diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c -index fa498931ed2..2bd3ac76f2d 100644 ---- a/grub-core/commands/minicmd.c -+++ b/grub-core/commands/minicmd.c -@@ -182,12 +182,24 @@ grub_mini_cmd_lsmod (struct grub_command *cmd __attribute__ ((unused)), - } - - /* exit */ --static grub_err_t __attribute__ ((noreturn)) -+static grub_err_t - grub_mini_cmd_exit (struct grub_command *cmd __attribute__ ((unused)), -- int argc __attribute__ ((unused)), -- char *argv[] __attribute__ ((unused))) -+ int argc, char *argv[]) - { -- grub_exit (); -+ int retval = -1; -+ unsigned long n; -+ -+ if (argc < 0 || argc > 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); -+ -+ if (argc == 1) -+ { -+ n = grub_strtoul (argv[0], 0, 10); -+ if (n != ~0UL) -+ retval = n; -+ } -+ -+ grub_exit (retval); - /* Not reached. */ - } - -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 8cff7be0289..05d8237a9b2 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -165,11 +165,16 @@ grub_reboot (void) - } - - void --grub_exit (void) -+grub_exit (int retval) - { -+ int rc = GRUB_EFI_LOAD_ERROR; -+ -+ if (retval == 0) -+ rc = GRUB_EFI_SUCCESS; -+ - grub_machine_fini (GRUB_LOADER_FLAG_NORETURN); - efi_call_4 (grub_efi_system_table->boot_services->exit, -- grub_efi_image_handle, GRUB_EFI_SUCCESS, 0, 0); -+ grub_efi_image_handle, rc, 0, 0); - for (;;) ; - } - -diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c -index 425bb960347..55ea5a11ccd 100644 ---- a/grub-core/kern/emu/main.c -+++ b/grub-core/kern/emu/main.c -@@ -67,7 +67,7 @@ grub_reboot (void) - } - - void --grub_exit (void) -+grub_exit (int retval __attribute__((unused))) - { - grub_reboot (); - } -diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c -index dfd8a8ec488..0ff13bcaf8c 100644 ---- a/grub-core/kern/emu/misc.c -+++ b/grub-core/kern/emu/misc.c -@@ -151,9 +151,10 @@ xasprintf (const char *fmt, ...) - - #if !defined (GRUB_MACHINE_EMU) || defined (GRUB_UTIL) - void --grub_exit (void) -+__attribute__ ((noreturn)) -+grub_exit (int rc) - { -- exit (1); -+ exit (rc < 0 ? 1 : rc); - } - #endif - -diff --git a/grub-core/kern/i386/coreboot/init.c b/grub-core/kern/i386/coreboot/init.c -index 3314f027fec..36f9134b7b7 100644 ---- a/grub-core/kern/i386/coreboot/init.c -+++ b/grub-core/kern/i386/coreboot/init.c -@@ -41,7 +41,7 @@ extern grub_uint8_t _end[]; - extern grub_uint8_t _edata[]; - - void __attribute__ ((noreturn)) --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - /* We can't use grub_fatal() in this function. This would create an infinite - loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit(). */ -diff --git a/grub-core/kern/i386/qemu/init.c b/grub-core/kern/i386/qemu/init.c -index 271b6fbfabd..9fafe98f015 100644 ---- a/grub-core/kern/i386/qemu/init.c -+++ b/grub-core/kern/i386/qemu/init.c -@@ -42,7 +42,7 @@ extern grub_uint8_t _end[]; - extern grub_uint8_t _edata[]; - - void __attribute__ ((noreturn)) --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - /* We can't use grub_fatal() in this function. This would create an infinite - loop, since grub_fatal() calls grub_abort() which in turn calls grub_exit(). */ -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index d483e35eed2..e71d1584164 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -71,7 +71,7 @@ grub_addr_t grub_ieee1275_original_stack; - #endif - - void --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - grub_ieee1275_exit (); - } -diff --git a/grub-core/kern/mips/arc/init.c b/grub-core/kern/mips/arc/init.c -index 2ed3ff3191e..5c40c34078d 100644 ---- a/grub-core/kern/mips/arc/init.c -+++ b/grub-core/kern/mips/arc/init.c -@@ -276,7 +276,7 @@ grub_halt (void) - } - - void --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - GRUB_ARC_FIRMWARE_VECTOR->exit (); - -diff --git a/grub-core/kern/mips/loongson/init.c b/grub-core/kern/mips/loongson/init.c -index 7b96531b983..dff598ca7b0 100644 ---- a/grub-core/kern/mips/loongson/init.c -+++ b/grub-core/kern/mips/loongson/init.c -@@ -304,7 +304,7 @@ grub_halt (void) - } - - void --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - grub_halt (); - } -diff --git a/grub-core/kern/mips/qemu_mips/init.c b/grub-core/kern/mips/qemu_mips/init.c -index be88b77d22d..8b6c55ffc01 100644 ---- a/grub-core/kern/mips/qemu_mips/init.c -+++ b/grub-core/kern/mips/qemu_mips/init.c -@@ -75,7 +75,7 @@ grub_machine_fini (int flags __attribute__ ((unused))) - } - - void --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - grub_halt (); - } -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 3af336ee227..63b586d09cb 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -1209,9 +1209,18 @@ grub_abort (void) - grub_getkey (); - } - -- grub_exit (); -+ grub_exit (1); - } - -+#if defined (__clang__) && !defined (GRUB_UTIL) -+/* clang emits references to abort(). */ -+void __attribute__ ((noreturn)) -+abort (void) -+{ -+ grub_abort (); -+} -+#endif -+ - void - grub_fatal (const char *fmt, ...) - { -diff --git a/grub-core/kern/uboot/init.c b/grub-core/kern/uboot/init.c -index 3e338645c57..be2a5be1d07 100644 ---- a/grub-core/kern/uboot/init.c -+++ b/grub-core/kern/uboot/init.c -@@ -39,9 +39,9 @@ extern grub_size_t grub_total_module_size; - static unsigned long timer_start; - - void --grub_exit (void) -+grub_exit (int rc) - { -- grub_uboot_return (0); -+ grub_uboot_return (rc < 0 ? 1 : rc); - } - - static grub_uint64_t -@@ -78,7 +78,7 @@ grub_machine_init (void) - if (!ver) - { - /* Don't even have a console to log errors to... */ -- grub_exit (); -+ grub_exit (-1); - } - else if (ver > API_SIG_VERSION) - { -diff --git a/grub-core/kern/xen/init.c b/grub-core/kern/xen/init.c -index 782ca72952a..708b060f324 100644 ---- a/grub-core/kern/xen/init.c -+++ b/grub-core/kern/xen/init.c -@@ -584,7 +584,7 @@ grub_machine_init (void) - } - - void --grub_exit (void) -+grub_exit (int rc __attribute__((unused))) - { - struct sched_shutdown arg; - -diff --git a/include/grub/misc.h b/include/grub/misc.h -index 7d2b5519690..fd18e6320b8 100644 ---- a/include/grub/misc.h -+++ b/include/grub/misc.h -@@ -353,7 +353,7 @@ int EXPORT_FUNC(grub_vsnprintf) (char *str, grub_size_t n, const char *fmt, - char *EXPORT_FUNC(grub_xasprintf) (const char *fmt, ...) - __attribute__ ((format (GNU_PRINTF, 1, 2))) WARN_UNUSED_RESULT; - char *EXPORT_FUNC(grub_xvasprintf) (const char *fmt, va_list args) WARN_UNUSED_RESULT; --void EXPORT_FUNC(grub_exit) (void) __attribute__ ((noreturn)); -+void EXPORT_FUNC(grub_exit) (int rc) __attribute__ ((noreturn)); - grub_uint64_t EXPORT_FUNC(grub_divmod64) (grub_uint64_t n, - grub_uint64_t d, - grub_uint64_t *r); diff --git a/0172-grub-install-support-embedding-x509-certificates.patch b/0016-grub-install-support-embedding-x509-certificates.patch similarity index 72% rename from 0172-grub-install-support-embedding-x509-certificates.patch rename to 0016-grub-install-support-embedding-x509-certificates.patch index 136d216547e91fb42e3c171d9cbda45db7af1222..06ba8fc3fe91b70c87abb11af0a2b0bead9e21c4 100644 --- a/0172-grub-install-support-embedding-x509-certificates.patch +++ b/0016-grub-install-support-embedding-x509-certificates.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From a0e17ba00ac128759d40e2bfc751716f45542ac0 Mon Sep 17 00:00:00 2001 From: Alastair D'Silva Date: Mon, 6 Jul 2020 13:33:04 +1000 -Subject: [PATCH] grub-install: support embedding x509 certificates +Subject: [PATCH 16/23] grub-install: support embedding x509 certificates To support verification of appended signatures, we need a way to embed the necessary public keys. Existing appended signature schemes @@ -12,18 +12,16 @@ Signed-off-by: Alastair D'Silva Signed-off-by: Daniel Axtens --- grub-core/commands/pgp.c | 2 +- - util/grub-install-common.c | 22 +++++++++++++++++++++- - util/grub-mkimage.c | 15 +++++++++++++-- - util/mkimage.c | 38 ++++++++++++++++++++++++++++++++++++-- - include/grub/kernel.h | 4 +++- + include/grub/kernel.h | 3 ++- include/grub/util/install.h | 7 +++++-- - 6 files changed, 79 insertions(+), 9 deletions(-) + util/grub-install-common.c | 22 +++++++++++++++++++- + util/grub-mkimage.c | 15 ++++++++++++-- + util/mkimage.c | 41 ++++++++++++++++++++++++++++++++++--- + 6 files changed, 80 insertions(+), 10 deletions(-) -diff --git a/grub-core/commands/pgp.c b/grub-core/commands/pgp.c -index 355a43844ac..b81ac0ae46c 100644 --- a/grub-core/commands/pgp.c +++ b/grub-core/commands/pgp.c -@@ -944,7 +944,7 @@ GRUB_MOD_INIT(pgp) +@@ -944,7 +944,7 @@ grub_memset (&pseudo_file, 0, sizeof (pseudo_file)); /* Not an ELF module, skip. */ @@ -32,11 +30,44 @@ index 355a43844ac..b81ac0ae46c 100644 continue; pseudo_file.fs = &pseudo_fs; -diff --git a/util/grub-install-common.c b/util/grub-install-common.c -index a74fee16e22..2d9693ffeb7 100644 +--- a/include/grub/kernel.h ++++ b/include/grub/kernel.h +@@ -28,7 +28,8 @@ + OBJ_TYPE_MEMDISK, + OBJ_TYPE_CONFIG, + OBJ_TYPE_PREFIX, +- OBJ_TYPE_PUBKEY, ++ OBJ_TYPE_GPG_PUBKEY, ++ OBJ_TYPE_X509_PUBKEY, + OBJ_TYPE_DTB, + OBJ_TYPE_DISABLE_SHIM_LOCK + }; +--- a/include/grub/util/install.h ++++ b/include/grub/util/install.h +@@ -67,6 +67,8 @@ + N_("SBAT metadata"), 0 }, \ + { "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \ + N_("disable shim_lock verifier"), 0 }, \ ++ { "x509key", 'x', N_("FILE"), 0, \ ++ N_("embed FILE as an x509 certificate for signature checking"), 0}, \ + { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\ + "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \ + 1}, \ +@@ -190,8 +192,9 @@ + grub_install_generate_image (const char *dir, const char *prefix, + FILE *out, + const char *outname, char *mods[], +- char *memdisk_path, char **pubkey_paths, +- size_t npubkeys, ++ char *memdisk_path, ++ char **pubkey_paths, size_t npubkeys, ++ char **x509key_paths, size_t nx509keys, + char *config_path, + const struct grub_install_image_target_desc *image_target, + int note, size_t appsig_size, --- a/util/grub-install-common.c +++ b/util/grub-install-common.c -@@ -460,6 +460,8 @@ static char **pubkeys; +@@ -465,6 +465,8 @@ static size_t npubkeys; static char *sbat; static int disable_shim_lock; @@ -45,30 +76,31 @@ index a74fee16e22..2d9693ffeb7 100644 static grub_compression_t compression; static size_t appsig_size; -@@ -500,6 +502,11 @@ grub_install_parse (int key, char *arg) - return 1; +@@ -506,6 +508,12 @@ case GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK: disable_shim_lock = 1; + return 1; + case 'x': + x509keys = xrealloc (x509keys, + sizeof (x509keys[0]) + * (nx509keys + 1)); + x509keys[nx509keys++] = xstrdup (arg); - return 1; ++ return 1; case GRUB_INSTALL_OPTIONS_VERBOSITY: -@@ -627,6 +634,9 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, + verbosity++; +@@ -636,6 +644,9 @@ for (pk = pubkeys; pk < pubkeys + npubkeys; pk++) - slen += 20 + grub_strlen (*pk); + slen += sizeof (" --pubkey ''") + grub_strlen (*pk); + for (pk = x509keys; pk < x509keys + nx509keys; pk++) + slen += 10 + grub_strlen (*pk); + for (md = modules.entries; *md; md++) - { - slen += 10 + grub_strlen (*md); -@@ -655,6 +665,14 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, - *p++ = ' '; + slen += sizeof (" ''") + grub_strlen (*md); + +@@ -676,6 +687,14 @@ + *p++ = '\''; } + for (pk = x509keys; pk < x509keys + nx509keys; pk++) @@ -81,23 +113,20 @@ index a74fee16e22..2d9693ffeb7 100644 + for (md = modules.entries; *md; md++) { - *p++ = '\''; -@@ -684,7 +702,9 @@ grub_install_make_image_wrap_file (const char *dir, const char *prefix, + *p++ = ' '; +@@ -702,7 +721,8 @@ grub_install_generate_image (dir, prefix, fp, outname, modules.entries, memdisk_path, - pubkeys, npubkeys, config_path, tgt, -+ pubkeys, npubkeys, -+ x509keys, nx509keys, ++ pubkeys, npubkeys, x509keys, nx509keys, + config_path, tgt, note, appsig_size, compression, dtb, sbat, disable_shim_lock); while (dc--) -diff --git a/util/grub-mkimage.c b/util/grub-mkimage.c -index 8a53310548b..e1f1112784a 100644 --- a/util/grub-mkimage.c +++ b/util/grub-mkimage.c -@@ -75,7 +75,8 @@ static struct argp_option options[] = { +@@ -75,7 +75,8 @@ /* TRANSLATORS: "embed" is a verb (command description). "*/ {"config", 'c', N_("FILE"), 0, N_("embed FILE as an early config"), 0}, /* TRANSLATORS: "embed" is a verb (command description). "*/ @@ -107,7 +136,7 @@ index 8a53310548b..e1f1112784a 100644 /* TRANSLATORS: NOTE is a name of segment. */ {"note", 'n', 0, 0, N_("add NOTE segment for CHRP IEEE1275"), 0}, {"output", 'o', N_("FILE"), 0, N_("output a generated image to FILE [default=stdout]"), 0}, -@@ -124,6 +125,8 @@ struct arguments +@@ -124,6 +125,8 @@ char *dtb; char **pubkeys; size_t npubkeys; @@ -116,7 +145,7 @@ index 8a53310548b..e1f1112784a 100644 char *font; char *config; char *sbat; -@@ -206,6 +209,13 @@ argp_parser (int key, char *arg, struct argp_state *state) +@@ -206,6 +209,13 @@ arguments->pubkeys[arguments->npubkeys++] = xstrdup (arg); break; @@ -130,7 +159,7 @@ index 8a53310548b..e1f1112784a 100644 case 'c': if (arguments->config) free (arguments->config); -@@ -332,7 +342,8 @@ main (int argc, char *argv[]) +@@ -332,7 +342,8 @@ grub_install_generate_image (arguments.dir, arguments.prefix, fp, arguments.output, arguments.modules, arguments.memdisk, arguments.pubkeys, @@ -138,23 +167,24 @@ index 8a53310548b..e1f1112784a 100644 + arguments.npubkeys, arguments.x509keys, + arguments.nx509keys, arguments.config, arguments.image_target, arguments.note, - arguments.appsig_size, arguments.comp, - arguments.dtb, arguments.sbat, -diff --git a/util/mkimage.c b/util/mkimage.c -index bab12276010..8319e8dfbde 100644 + arguments.appsig_size, + arguments.comp, arguments.dtb, --- a/util/mkimage.c +++ b/util/mkimage.c -@@ -867,7 +867,8 @@ void +@@ -882,8 +882,10 @@ + void grub_install_generate_image (const char *dir, const char *prefix, FILE *out, const char *outname, char *mods[], - char *memdisk_path, char **pubkey_paths, +- char *memdisk_path, char **pubkey_paths, - size_t npubkeys, char *config_path, -+ size_t npubkeys, char **x509key_paths, -+ size_t nx509keys, char *config_path, ++ char *memdisk_path, ++ char **pubkey_paths, size_t npubkeys, ++ char **x509key_paths, size_t nx509keys, ++ char *config_path, const struct grub_install_image_target_desc *image_target, int note, size_t appsig_size, grub_compression_t comp, - const char *dtb_path, const char *sbat_path, -@@ -913,6 +914,19 @@ grub_install_generate_image (const char *dir, const char *prefix, + const char *dtb_path, const char *sbat_path, +@@ -929,6 +931,19 @@ } } @@ -174,7 +204,7 @@ index bab12276010..8319e8dfbde 100644 if (memdisk_path) { memdisk_size = ALIGN_UP(grub_util_get_image_size (memdisk_path), 512); -@@ -1034,7 +1048,7 @@ grub_install_generate_image (const char *dir, const char *prefix, +@@ -1050,7 +1065,7 @@ curs = grub_util_get_image_size (pubkey_paths[i]); header = (struct grub_module_header *) (kernel_img + offset); @@ -183,7 +213,7 @@ index bab12276010..8319e8dfbde 100644 header->size = grub_host_to_target32 (curs + sizeof (*header)); offset += sizeof (*header); -@@ -1043,6 +1057,26 @@ grub_install_generate_image (const char *dir, const char *prefix, +@@ -1059,6 +1074,26 @@ } } @@ -210,43 +240,3 @@ index bab12276010..8319e8dfbde 100644 if (memdisk_path) { struct grub_module_header *header; -diff --git a/include/grub/kernel.h b/include/grub/kernel.h -index 55849777eaa..98edc0863f6 100644 ---- a/include/grub/kernel.h -+++ b/include/grub/kernel.h -@@ -30,7 +30,9 @@ enum - OBJ_TYPE_PREFIX, - OBJ_TYPE_PUBKEY, - OBJ_TYPE_DTB, -- OBJ_TYPE_DISABLE_SHIM_LOCK -+ OBJ_TYPE_DISABLE_SHIM_LOCK, -+ OBJ_TYPE_GPG_PUBKEY, -+ OBJ_TYPE_X509_PUBKEY, - }; - - /* The module header. */ -diff --git a/include/grub/util/install.h b/include/grub/util/install.h -index cf4531e02b6..51f3b13ac13 100644 ---- a/include/grub/util/install.h -+++ b/include/grub/util/install.h -@@ -67,6 +67,8 @@ - N_("SBAT metadata"), 0 }, \ - { "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \ - N_("disable shim_lock verifier"), 0 }, \ -+ { "x509key", 'x', N_("FILE"), 0, \ -+ N_("embed FILE as an x509 certificate for signature checking"), 0}, \ - { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\ - "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \ - 1}, \ -@@ -188,8 +190,9 @@ void - grub_install_generate_image (const char *dir, const char *prefix, - FILE *out, - const char *outname, char *mods[], -- char *memdisk_path, char **pubkey_paths, -- size_t npubkeys, -+ char *memdisk_path, -+ char **pubkey_paths, size_t npubkeys, -+ char **x509key_paths, size_t nx509keys, - char *config_path, - const struct grub_install_image_target_desc *image_target, - int note, size_t appsig_size, diff --git a/0017-Make-efi-machines-load-an-env-block-from-a-variable.patch b/0017-Make-efi-machines-load-an-env-block-from-a-variable.patch deleted file mode 100644 index d0614611df668de8ada17698ea556fe8cbac5a14..0000000000000000000000000000000000000000 --- a/0017-Make-efi-machines-load-an-env-block-from-a-variable.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 7 Dec 2015 14:20:49 -0500 -Subject: [PATCH] Make efi machines load an env block from a variable - -Signed-off-by: Peter Jones ---- - grub-core/Makefile.core.def | 1 + - grub-core/kern/efi/init.c | 36 +++++++++++++++++++++++++++++++++++- - 2 files changed, 36 insertions(+), 1 deletion(-) - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 45d3edaa4dc..c865a08b027 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -207,6 +207,7 @@ kernel = { - efi = kern/efi/acpi.c; - efi = kern/efi/sb.c; - efi = kern/lockdown.c; -+ efi = lib/envblk.c; - i386_coreboot = kern/i386/pc/acpi.c; - i386_multiboot = kern/i386/pc/acpi.c; - i386_coreboot = kern/acpi.c; -diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c -index 7facacf09c7..6d39bd3ad29 100644 ---- a/grub-core/kern/efi/init.c -+++ b/grub-core/kern/efi/init.c -@@ -27,8 +27,11 @@ - #include - #include - #include -+ - #include - -+#include -+ - #ifdef GRUB_STACK_PROTECTOR - - static grub_efi_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID; -@@ -82,6 +85,36 @@ stack_protector_init (void) - - grub_addr_t grub_modbase; - -+#define GRUB_EFI_GRUB_VARIABLE_GUID \ -+ { 0x91376aff, 0xcba6, 0x42be, \ -+ { 0x94, 0x9d, 0x06, 0xfd, 0xe8, 0x11, 0x28, 0xe8 } \ -+ } -+ -+/* Helper for grub_efi_env_init */ -+static int -+set_var (const char *name, const char *value, -+ void *whitelist __attribute__((__unused__))) -+{ -+ grub_env_set (name, value); -+ return 0; -+} -+ -+static void -+grub_efi_env_init (void) -+{ -+ grub_efi_guid_t efi_grub_guid = GRUB_EFI_GRUB_VARIABLE_GUID; -+ struct grub_envblk envblk_s = { NULL, 0 }; -+ grub_envblk_t envblk = &envblk_s; -+ -+ grub_efi_get_variable ("GRUB_ENV", &efi_grub_guid, &envblk_s.size, -+ (void **) &envblk_s.buf); -+ if (!envblk_s.buf || envblk_s.size < 1) -+ return; -+ -+ grub_envblk_iterate (envblk, NULL, set_var); -+ grub_free (envblk_s.buf); -+} -+ - void - grub_efi_init (void) - { -@@ -108,10 +141,11 @@ grub_efi_init (void) - efi_call_4 (grub_efi_system_table->boot_services->set_watchdog_timer, - 0, 0, 0, NULL); - -+ grub_efi_env_init (); - grub_efidisk_init (); - } - --void (*grub_efi_net_config) (grub_efi_handle_t hnd, -+void (*grub_efi_net_config) (grub_efi_handle_t hnd, - char **device, - char **path); - diff --git a/0173-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch b/0017-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch similarity index 97% rename from 0173-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch rename to 0017-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch index 7b7d70c48a5f2d9286e7c1afbe4cc44a7375ac94..61e68ea5d6a4735c9017006bf81305fa2777cee6 100644 --- a/0173-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch +++ b/0017-appended-signatures-import-GNUTLS-s-ASN.1-descriptio.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From f948da0bef477fe9d95fbcb13eb2c4f45f1b6ea0 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Thu, 30 Jul 2020 01:35:10 +1000 -Subject: [PATCH] appended signatures: import GNUTLS's ASN.1 description files +Subject: [PATCH 17/23] appended signatures: import GNUTLS's ASN.1 description + files In order to parse PKCS#7 messages and X.509 certificates with libtasn1, we need some information about how they are encoded. @@ -14,15 +15,12 @@ us to import it without issue. Signed-off-by: Daniel Axtens --- - grub-core/commands/appendedsig/gnutls_asn1_tab.c | 121 ++++++ - grub-core/commands/appendedsig/pkix_asn1_tab.c | 484 +++++++++++++++++++++++ + .../commands/appendedsig/gnutls_asn1_tab.c | 121 +++++ + .../commands/appendedsig/pkix_asn1_tab.c | 484 ++++++++++++++++++ 2 files changed, 605 insertions(+) create mode 100644 grub-core/commands/appendedsig/gnutls_asn1_tab.c create mode 100644 grub-core/commands/appendedsig/pkix_asn1_tab.c -diff --git a/grub-core/commands/appendedsig/gnutls_asn1_tab.c b/grub-core/commands/appendedsig/gnutls_asn1_tab.c -new file mode 100644 -index 00000000000..ddd1314e63b --- /dev/null +++ b/grub-core/commands/appendedsig/gnutls_asn1_tab.c @@ -0,0 +1,121 @@ @@ -147,9 +145,6 @@ index 00000000000..ddd1314e63b + { NULL, 4104, "0"}, + { NULL, 0, NULL } +}; -diff --git a/grub-core/commands/appendedsig/pkix_asn1_tab.c b/grub-core/commands/appendedsig/pkix_asn1_tab.c -new file mode 100644 -index 00000000000..adef69d95ce --- /dev/null +++ b/grub-core/commands/appendedsig/pkix_asn1_tab.c @@ -0,0 +1,484 @@ diff --git a/0174-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch b/0018-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch similarity index 74% rename from 0174-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch rename to 0018-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch index 04bf1df4523208fd8b3a2770aa114b34a129ed72..410fa2d8a259f295c944bbba9e193ad5f3da2850 100644 --- a/0174-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch +++ b/0018-appended-signatures-parse-PKCS-7-signedData-and-X.50.patch @@ -1,7 +1,7 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 7a583c9b29ffa6ac32e93b6b20054c0290521e82 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Thu, 30 Jul 2020 01:33:46 +1000 -Subject: [PATCH] appended signatures: parse PKCS#7 signedData and X.509 +Subject: [PATCH 18/23] appended signatures: parse PKCS#7 signedData and X.509 certificates This code allows us to parse: @@ -15,24 +15,168 @@ This code allows us to parse: PKCS#7 messages. We expect that the certificates embedded in grub will be leaf certificates, not CA certificates. The parser enforces this. + - X.509 certificates support the Extended Key Usage extension and handle + it by verifying that the certificate has a single purpose, that is code + signing. This is required because Red Hat certificates have both Key + Usage and Extended Key Usage extensions present. + +Signed-off-by: Javier Martinez Canillas # EKU support Signed-off-by: Daniel Axtens + +--- + +v3 changes: + - fixes for libtasn1-4.18.0 + +v2 changes: + + - Handle the Extended Key Usage extension + - Fix 2 leaks in x509 cert parsing + - Improve x509 parser function name + - Constify the data parameter in parser signatures + - Support multiple signers in a pkcs7 message. Accept any passing sig. + - Allow padding after a pkcs7 message in an appended signature, required + to support my model for signers separated in time. + - Fix a test that used GRUB_ERR_NONE rather than ASN1_SUCCESS. They're + both 0 so no harm was done, but better to be correct. + - Various code and comment cleanups. + +Thanks to Nayna Jain and Stefan Berger for their reviews. --- - grub-core/commands/appendedsig/asn1util.c | 102 +++ - grub-core/commands/appendedsig/pkcs7.c | 305 +++++++++ - grub-core/commands/appendedsig/x509.c | 958 +++++++++++++++++++++++++++ - grub-core/commands/appendedsig/appendedsig.h | 110 +++ - 4 files changed, 1475 insertions(+) + grub-core/commands/appendedsig/appendedsig.h | 118 ++ + grub-core/commands/appendedsig/asn1util.c | 103 ++ + grub-core/commands/appendedsig/pkcs7.c | 509 +++++++++ + grub-core/commands/appendedsig/x509.c | 1079 ++++++++++++++++++ + 4 files changed, 1809 insertions(+) + create mode 100644 grub-core/commands/appendedsig/appendedsig.h create mode 100644 grub-core/commands/appendedsig/asn1util.c create mode 100644 grub-core/commands/appendedsig/pkcs7.c create mode 100644 grub-core/commands/appendedsig/x509.c - create mode 100644 grub-core/commands/appendedsig/appendedsig.h -diff --git a/grub-core/commands/appendedsig/asn1util.c b/grub-core/commands/appendedsig/asn1util.c -new file mode 100644 -index 00000000000..eff095a9df2 +--- /dev/null ++++ b/grub-core/commands/appendedsig/appendedsig.h +@@ -0,0 +1,118 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2020 IBM Corporation. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#include ++#include ++ ++extern asn1_node _gnutls_gnutls_asn; ++extern asn1_node _gnutls_pkix_asn; ++ ++#define MAX_OID_LEN 32 ++ ++/* ++ * One or more x509 certificates. ++ * ++ * We do limited parsing: extracting only the serial, CN and RSA public key. ++ */ ++struct x509_certificate ++{ ++ struct x509_certificate *next; ++ ++ grub_uint8_t *serial; ++ grub_size_t serial_len; ++ ++ char *subject; ++ grub_size_t subject_len; ++ ++ /* We only support RSA public keys. This encodes [modulus, publicExponent] */ ++ gcry_mpi_t mpis[2]; ++}; ++ ++/* ++ * A PKCS#7 signedData signerInfo. ++ */ ++struct pkcs7_signerInfo ++{ ++ const gcry_md_spec_t *hash; ++ gcry_mpi_t sig_mpi; ++}; ++ ++/* ++ * A PKCS#7 signedData message. ++ * ++ * We make no attempt to match intelligently, so we don't save any info about ++ * the signer. ++ */ ++struct pkcs7_signedData ++{ ++ int signerInfo_count; ++ struct pkcs7_signerInfo *signerInfos; ++}; ++ ++ ++/* Do libtasn1 init */ ++int asn1_init (void); ++ ++/* ++ * Import a DER-encoded certificate at 'data', of size 'size'. ++ * ++ * Place the results into 'results', which must be already allocated. ++ */ ++grub_err_t ++parse_x509_certificate (const void *data, grub_size_t size, ++ struct x509_certificate *results); ++ ++/* ++ * Release all the storage associated with the x509 certificate. ++ * If the caller dynamically allocated the certificate, it must free it. ++ * The caller is also responsible for maintenance of the linked list. ++ */ ++void certificate_release (struct x509_certificate *cert); ++ ++/* ++ * Parse a PKCS#7 message, which must be a signedData message. ++ * ++ * The message must be in 'sigbuf' and of size 'data_size'. The result is ++ * placed in 'msg', which must already be allocated. ++ */ ++grub_err_t ++parse_pkcs7_signedData (const void *sigbuf, grub_size_t data_size, ++ struct pkcs7_signedData *msg); ++ ++/* ++ * Release all the storage associated with the PKCS#7 message. ++ * If the caller dynamically allocated the message, it must free it. ++ */ ++void pkcs7_signedData_release (struct pkcs7_signedData *msg); ++ ++/* ++ * Read a value from an ASN1 node, allocating memory to store it. ++ * ++ * It will work for anything where the size libtasn1 returns is right: ++ * - Integers ++ * - Octet strings ++ * - DER encoding of other structures ++ * It will _not_ work for things where libtasn1 size requires adjustment: ++ * - Strings that require an extra NULL byte at the end ++ * - Bit strings because libtasn1 returns the length in bits, not bytes. ++ * ++ * If the function returns a non-NULL value, the caller must free it. ++ */ ++void *grub_asn1_allocate_and_read (asn1_node node, const char *name, ++ const char *friendly_name, ++ int *content_size); --- /dev/null +++ b/grub-core/commands/appendedsig/asn1util.c -@@ -0,0 +1,102 @@ +@@ -0,0 +1,103 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 IBM Corporation. @@ -56,15 +200,16 @@ index 00000000000..eff095a9df2 +#include +#include +#include ++#include +#include + +#include "appendedsig.h" + -+asn1_node _gnutls_gnutls_asn = ASN1_TYPE_EMPTY; -+asn1_node _gnutls_pkix_asn = ASN1_TYPE_EMPTY; ++asn1_node _gnutls_gnutls_asn = NULL; ++asn1_node _gnutls_pkix_asn = NULL; + -+extern const ASN1_ARRAY_TYPE gnutls_asn1_tab[]; -+extern const ASN1_ARRAY_TYPE pkix_asn1_tab[]; ++extern const asn1_static_node gnutls_asn1_tab[]; ++extern const asn1_static_node pkix_asn1_tab[]; + +/* + * Read a value from an ASN1 node, allocating memory to store it. @@ -135,12 +280,9 @@ index 00000000000..eff095a9df2 + res = asn1_array2tree (pkix_asn1_tab, &_gnutls_pkix_asn, NULL); + return res; +} -diff --git a/grub-core/commands/appendedsig/pkcs7.c b/grub-core/commands/appendedsig/pkcs7.c -new file mode 100644 -index 00000000000..dc6afe203f7 --- /dev/null +++ b/grub-core/commands/appendedsig/pkcs7.c -@@ -0,0 +1,305 @@ +@@ -0,0 +1,509 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 IBM Corporation. @@ -163,7 +305,7 @@ index 00000000000..dc6afe203f7 +#include +#include +#include -+ ++#include + +static char asn1_error[ASN1_MAX_ERROR_DESCRIPTION_SIZE]; + @@ -188,12 +330,18 @@ index 00000000000..dc6afe203f7 + char algo_oid[MAX_OID_LEN]; + int algo_oid_size = sizeof (algo_oid); + int algo_count; ++ int signer_count; ++ int i; + char version; + int version_size = sizeof (version); + grub_uint8_t *result_buf; + int result_size = 0; + int crls_size = 0; + gcry_error_t gcry_err; ++ bool sha256_in_da, sha256_in_si, sha512_in_da, sha512_in_si; ++ char *da_path; ++ char *si_sig_path; ++ char *si_da_path; + + res = asn1_create_element (_gnutls_pkix_asn, "PKIX1.pkcs-7-SignedData", + &signed_part); @@ -265,51 +413,92 @@ index 00000000000..dc6afe203f7 + goto cleanup_signed_part; + } + -+ if (algo_count != 1) -+ { -+ err = -+ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ "Only 1 digest algorithm is supported"); -+ goto cleanup_signed_part; -+ } -+ -+ res = -+ asn1_read_value (signed_part, "digestAlgorithms.?1.algorithm", algo_oid, -+ &algo_oid_size); -+ if (res != ASN1_SUCCESS) ++ if (algo_count <= 0) + { + err = + grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Error reading digest algorithm: %s", -+ asn1_strerror (res)); ++ "A minimum of 1 digest algorithm is required"); + goto cleanup_signed_part; + } + -+ if (grub_strncmp (sha512_oid, algo_oid, algo_oid_size) == 0) -+ { -+ msg->hash = grub_crypto_lookup_md_by_name ("sha512"); -+ } -+ else if (grub_strncmp (sha256_oid, algo_oid, algo_oid_size) == 0) -+ { -+ msg->hash = grub_crypto_lookup_md_by_name ("sha256"); -+ } -+ else ++ if (algo_count > 2) + { + err = + grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ "Only SHA-256 and SHA-512 hashes are supported, found OID %s", -+ algo_oid); ++ "A maximum of 2 digest algorithms are supported"); + goto cleanup_signed_part; + } + -+ if (!msg->hash) ++ sha256_in_da = false; ++ sha512_in_da = false; ++ ++ for (i = 0; i < algo_count; i++) + { -+ err = -+ grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Hash algorithm for OID %s not loaded", algo_oid); -+ goto cleanup_signed_part; ++ da_path = grub_xasprintf ("digestAlgorithms.?%d.algorithm", i + 1); ++ if (!da_path) ++ { ++ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "Could not allocate path for digest algorithm parsing path"); ++ goto cleanup_signed_part; ++ } ++ ++ algo_oid_size = sizeof (algo_oid); ++ res = asn1_read_value (signed_part, da_path, algo_oid, &algo_oid_size); ++ if (res != ASN1_SUCCESS) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_SIGNATURE, ++ "Error reading digest algorithm: %s", ++ asn1_strerror (res)); ++ grub_free (da_path); ++ goto cleanup_signed_part; ++ } ++ ++ if (grub_strncmp (sha512_oid, algo_oid, algo_oid_size) == 0) ++ { ++ if (!sha512_in_da) ++ { ++ sha512_in_da = true; ++ } ++ else ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_SIGNATURE, ++ "SHA-512 specified twice in digest algorithm list"); ++ grub_free (da_path); ++ goto cleanup_signed_part; ++ } ++ } ++ else if (grub_strncmp (sha256_oid, algo_oid, algo_oid_size) == 0) ++ { ++ if (!sha256_in_da) ++ { ++ sha256_in_da = true; ++ } ++ else ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_SIGNATURE, ++ "SHA-256 specified twice in digest algorithm list"); ++ grub_free (da_path); ++ goto cleanup_signed_part; ++ } ++ } ++ else ++ { ++ err = ++ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, ++ "Only SHA-256 and SHA-512 hashes are supported, found OID %s", ++ algo_oid); ++ grub_free (da_path); ++ goto cleanup_signed_part; ++ } ++ ++ grub_free (da_path); + } + ++ /* at this point, at least one of sha{256,512}_in_da must be true */ ++ + /* + * We ignore the certificates, but we don't permit CRLs. + * A CRL entry might be revoking the certificate we're using, and we have @@ -324,38 +513,189 @@ index 00000000000..dc6afe203f7 + goto cleanup_signed_part; + } + -+ /* read the signature */ -+ result_buf = -+ grub_asn1_allocate_and_read (signed_part, "signerInfos.?1.signature", -+ "signature data", &result_size); -+ if (!result_buf) ++ /* read the signatures */ ++ ++ res = asn1_number_of_elements (signed_part, "signerInfos", &signer_count); ++ if (res != ASN1_SUCCESS) + { -+ err = grub_errno; ++ err = ++ grub_error (GRUB_ERR_BAD_SIGNATURE, ++ "Error counting number of signers: %s", ++ asn1_strerror (res)); + goto cleanup_signed_part; + } + -+ gcry_err = -+ gcry_mpi_scan (&(msg->sig_mpi), GCRYMPI_FMT_USG, result_buf, result_size, -+ NULL); -+ if (gcry_err != GPG_ERR_NO_ERROR) ++ if (signer_count <= 0) + { + err = + grub_error (GRUB_ERR_BAD_SIGNATURE, -+ "Error loading signature into MPI structure: %d", -+ gcry_err); -+ goto cleanup_result; ++ "A minimum of 1 signer is required"); ++ goto cleanup_signed_part; ++ } ++ ++ msg->signerInfos = grub_calloc (signer_count, ++ sizeof (struct pkcs7_signerInfo)); ++ if (!msg->signerInfos) ++ { ++ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "Could not allocate space for %d signers", ++ signer_count); ++ goto cleanup_signed_part; ++ } ++ ++ msg->signerInfo_count = 0; ++ for (i = 0; i < signer_count; i++) ++ { ++ si_da_path = ++ grub_xasprintf ("signerInfos.?%d.digestAlgorithm.algorithm", i + 1); ++ if (!si_da_path) ++ { ++ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "Could not allocate path for signer %d's digest algorithm parsing path", ++ i); ++ goto cleanup_signerInfos; ++ } ++ ++ algo_oid_size = sizeof (algo_oid); ++ res = ++ asn1_read_value (signed_part, si_da_path, algo_oid, &algo_oid_size); ++ if (res != ASN1_SUCCESS) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_SIGNATURE, ++ "Error reading signer %d's digest algorithm: %s", ++ i, asn1_strerror (res)); ++ grub_free (si_da_path); ++ goto cleanup_signerInfos; ++ } ++ ++ grub_free (si_da_path); ++ ++ if (grub_strncmp (sha512_oid, algo_oid, algo_oid_size) == 0) ++ { ++ if (!sha512_in_da) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_SIGNATURE, ++ "Signer %d claims a SHA-512 signature which was not specified in the outer DigestAlgorithms", ++ i); ++ goto cleanup_signerInfos; ++ } ++ else ++ { ++ sha512_in_si = true; ++ msg->signerInfos[i].hash = ++ grub_crypto_lookup_md_by_name ("sha512"); ++ } ++ } ++ else if (grub_strncmp (sha256_oid, algo_oid, algo_oid_size) == 0) ++ { ++ if (!sha256_in_da) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_SIGNATURE, ++ "Signer %d claims a SHA-256 signature which was not specified in the outer DigestAlgorithms", ++ i); ++ goto cleanup_signerInfos; ++ } ++ else ++ { ++ sha256_in_si = true; ++ msg->signerInfos[i].hash = ++ grub_crypto_lookup_md_by_name ("sha256"); ++ } ++ } ++ else ++ { ++ err = ++ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, ++ "Only SHA-256 and SHA-512 hashes are supported, found OID %s", ++ algo_oid); ++ goto cleanup_signerInfos; ++ } ++ ++ if (!msg->signerInfos[i].hash) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_SIGNATURE, ++ "Hash algorithm for signer %d (OID %s) not loaded", i, ++ algo_oid); ++ goto cleanup_signerInfos; ++ } ++ ++ si_sig_path = grub_xasprintf ("signerInfos.?%d.signature", i + 1); ++ if (!si_sig_path) ++ { ++ err = grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "Could not allocate path for signer %d's signature parsing path", ++ i); ++ goto cleanup_signerInfos; ++ } ++ ++ result_buf = ++ grub_asn1_allocate_and_read (signed_part, si_sig_path, ++ "signature data", &result_size); ++ if (!result_buf) ++ { ++ err = grub_errno; ++ grub_free (si_sig_path); ++ goto cleanup_signerInfos; ++ } ++ grub_free (si_sig_path); ++ ++ gcry_err = ++ gcry_mpi_scan (&(msg->signerInfos[i].sig_mpi), GCRYMPI_FMT_USG, ++ result_buf, result_size, NULL); ++ if (gcry_err != GPG_ERR_NO_ERROR) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_SIGNATURE, ++ "Error loading signature %d into MPI structure: %d", ++ i, gcry_err); ++ grub_free (result_buf); ++ goto cleanup_signerInfos; ++ } ++ ++ grub_free (result_buf); ++ ++ /* use msg->signerInfo_count to track fully populated signerInfos so we ++ know how many we need to clean up */ ++ msg->signerInfo_count++; ++ } ++ ++ /* Final consistency check of signerInfo.*.digestAlgorithm vs ++ digestAlgorithms.*.algorithm. An algorithm must be present in both ++ digestAlgorithms and signerInfo or in neither. We have already checked ++ for an algorithm in signerInfo that is not in digestAlgorithms, here we ++ check for algorithms in digestAlgorithms but not in signerInfos. */ ++ if (sha512_in_da && !sha512_in_si) ++ { ++ err = grub_error (GRUB_ERR_BAD_SIGNATURE, ++ "SHA-512 specified in DigestAlgorithms but did not appear in SignerInfos"); ++ goto cleanup_signerInfos; ++ } ++ ++ if (sha256_in_da && !sha256_in_si) ++ { ++ err = grub_error (GRUB_ERR_BAD_SIGNATURE, ++ "SHA-256 specified in DigestAlgorithms but did not appear in SignerInfos"); ++ goto cleanup_signerInfos; + } + -+cleanup_result: -+ grub_free (result_buf); -+cleanup_signed_part: + asn1_delete_structure (&signed_part); ++ return GRUB_ERR_NONE; + ++cleanup_signerInfos: ++ for (i = 0; i < msg->signerInfo_count; i++) ++ gcry_mpi_release (msg->signerInfos[i].sig_mpi); ++ grub_free (msg->signerInfos); ++cleanup_signed_part: ++ asn1_delete_structure (&signed_part); + return err; +} + +grub_err_t -+parse_pkcs7_signedData (void *sigbuf, grub_size_t data_size, ++parse_pkcs7_signedData (const void *sigbuf, grub_size_t data_size, + struct pkcs7_signedData *msg) +{ + int res; @@ -382,7 +722,8 @@ index 00000000000..dc6afe203f7 + } + + res = asn1_der_decoding2 (&content_info, sigbuf, &size, -+ ASN1_DECODE_FLAG_STRICT_DER, asn1_error); ++ ASN1_DECODE_FLAG_STRICT_DER | ++ ASN1_DECODE_FLAG_ALLOW_PADDING, asn1_error); + if (res != ASN1_SUCCESS) + { + err = @@ -444,14 +785,16 @@ index 00000000000..dc6afe203f7 +void +pkcs7_signedData_release (struct pkcs7_signedData *msg) +{ -+ gcry_mpi_release (msg->sig_mpi); ++ grub_ssize_t i; ++ for (i = 0; i < msg->signerInfo_count; i++) ++ { ++ gcry_mpi_release (msg->signerInfos[i].sig_mpi); ++ } ++ grub_free (msg->signerInfos); +} -diff --git a/grub-core/commands/appendedsig/x509.c b/grub-core/commands/appendedsig/x509.c -new file mode 100644 -index 00000000000..2b38b3670a2 --- /dev/null +++ b/grub-core/commands/appendedsig/x509.c -@@ -0,0 +1,958 @@ +@@ -0,0 +1,1079 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 IBM Corporation. @@ -475,6 +818,7 @@ index 00000000000..2b38b3670a2 +#include +#include +#include ++#include +#include + +#include "appendedsig.h" @@ -496,12 +840,20 @@ index 00000000000..2b38b3670a2 + */ +const char *keyUsage_oid = "2.5.29.15"; + ++const grub_uint8_t digitalSignatureUsage = 0x80; ++ +/* + * RFC 5280 4.2.1.9 Basic Constraints + */ +const char *basicConstraints_oid = "2.5.29.19"; + +/* ++ * RFC 5280 4.2.1.12 Extended Key Usage ++ */ ++const char *extendedKeyUsage_oid = "2.5.29.37"; ++const char *codeSigningUsage_oid = "1.3.6.1.5.5.7.3.3"; ++ ++/* + * RFC 3279 2.3.1 + * + * The RSA public key MUST be encoded using the ASN.1 type RSAPublicKey: @@ -514,11 +866,11 @@ index 00000000000..2b38b3670a2 + * exponent e. + */ +static grub_err_t -+grub_parse_rsa_pubkey (grub_uint8_t * der, int dersize, ++grub_parse_rsa_pubkey (grub_uint8_t *der, int dersize, + struct x509_certificate *certificate) +{ + int result; -+ asn1_node spk = ASN1_TYPE_EMPTY; ++ asn1_node spk = NULL; + grub_uint8_t *m_data, *e_data; + int m_size, e_size; + grub_err_t err = GRUB_ERR_NONE; @@ -720,7 +1072,7 @@ index 00000000000..2b38b3670a2 +/* Decode a string as defined in Appendix A */ +static grub_err_t +decode_string (char *der, int der_size, char **string, -+ grub_size_t * string_size) ++ grub_size_t *string_size) +{ + asn1_node strasn; + int result; @@ -758,22 +1110,36 @@ index 00000000000..2b38b3670a2 + goto cleanup; + } + -+ if (grub_strncmp ("utf8String", choice, choice_size)) ++ if (grub_strncmp ("utf8String", choice, choice_size) == 0) + { -+ err = -+ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ "Only UTF-8 DirectoryStrings are supported, got %s", -+ choice); -+ goto cleanup_choice; ++ result = asn1_read_value (strasn, "utf8String", NULL, &tmp_size); ++ if (result != ASN1_MEM_ERROR) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ "Error reading size of UTF-8 string: %s", ++ asn1_strerror (result)); ++ goto cleanup_choice; ++ } + } -+ -+ result = asn1_read_value (strasn, "utf8String", NULL, &tmp_size); -+ if (result != ASN1_MEM_ERROR) ++ else if (grub_strncmp ("printableString", choice, choice_size) == 0) ++ { ++ result = asn1_read_value (strasn, "printableString", NULL, &tmp_size); ++ if (result != ASN1_MEM_ERROR) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ "Error reading size of UTF-8 string: %s", ++ asn1_strerror (result)); ++ goto cleanup_choice; ++ } ++ } ++ else + { + err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading size of UTF-8 string: %s", -+ asn1_strerror (result)); ++ grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, ++ "Only UTF-8 and printable DirectoryStrings are supported, got %s", ++ choice); + goto cleanup_choice; + } + @@ -789,13 +1155,13 @@ index 00000000000..2b38b3670a2 + goto cleanup_choice; + } + -+ result = asn1_read_value (strasn, "utf8String", *string, &tmp_size); ++ result = asn1_read_value (strasn, choice, *string, &tmp_size); + if (result != ASN1_SUCCESS) + { + err = + grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading out UTF-8 string in DirectoryString: %s", -+ asn1_strerror (result)); ++ "Error reading out %s in DirectoryString: %s", ++ choice, asn1_strerror (result)); + grub_free (*string); + goto cleanup_choice; + } @@ -822,7 +1188,7 @@ index 00000000000..2b38b3670a2 + int rc; + const char *name = "tbsCertificate.version"; + grub_uint8_t version; -+ int len = 1; ++ int len = sizeof (version); + + rc = asn1_read_value (certificate, name, &version, &len); + @@ -846,7 +1212,7 @@ index 00000000000..2b38b3670a2 + */ +static grub_err_t +read_name (asn1_node asn, const char *name_path, char **name, -+ grub_size_t * name_size) ++ grub_size_t *name_size) +{ + int seq_components, set_components; + int result; @@ -959,6 +1325,8 @@ index 00000000000..2b38b3670a2 + break; + } + ++ grub_free (top_path); ++ + return GRUB_ERR_NONE; + +cleanup_string: @@ -975,16 +1343,17 @@ index 00000000000..2b38b3670a2 +} + +/* -+ * details here ++ * Verify the Key Usage extension. ++ * We only permit the Digital signature usage. + */ +static grub_err_t -+verify_key_usage (grub_uint8_t * value, int value_size) ++verify_key_usage (grub_uint8_t *value, int value_size) +{ + asn1_node usageasn; + int result; + grub_err_t err = GRUB_ERR_NONE; + grub_uint8_t usage = 0xff; -+ int usage_size = 1; ++ int usage_size = sizeof (usage_size); + + result = + asn1_create_element (_gnutls_pkix_asn, "PKIX1.KeyUsage", &usageasn); @@ -1014,8 +1383,7 @@ index 00000000000..2b38b3670a2 + goto cleanup; + } + -+ /* Only the first bit is permitted to be set */ -+ if (usage != 0x80) ++ if (usage != digitalSignatureUsage) + { + err = + grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unexpected Key Usage value: %x", @@ -1034,7 +1402,7 @@ index 00000000000..2b38b3670a2 + * pathLenConstraint INTEGER (0..MAX) OPTIONAL } + */ +static grub_err_t -+verify_basic_constraints (grub_uint8_t * value, int value_size) ++verify_basic_constraints (grub_uint8_t *value, int value_size) +{ + asn1_node basicasn; + int result; @@ -1091,6 +1459,85 @@ index 00000000000..2b38b3670a2 + return err; +} + ++/* ++ * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId ++ * ++ * KeyPurposeId ::= OBJECT IDENTIFIER ++ */ ++static grub_err_t ++verify_extended_key_usage (grub_uint8_t *value, int value_size) ++{ ++ asn1_node extendedasn; ++ int result, count; ++ grub_err_t err = GRUB_ERR_NONE; ++ char usage[MAX_OID_LEN]; ++ int usage_size = sizeof (usage); ++ ++ result = ++ asn1_create_element (_gnutls_pkix_asn, "PKIX1.ExtKeyUsageSyntax", ++ &extendedasn); ++ if (result != ASN1_SUCCESS) ++ { ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, ++ "Could not create ASN.1 structure for Extended Key Usage"); ++ } ++ ++ result = asn1_der_decoding2 (&extendedasn, value, &value_size, ++ ASN1_DECODE_FLAG_STRICT_DER, asn1_error); ++ if (result != ASN1_SUCCESS) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ "Error parsing DER for Extended Key Usage: %s", ++ asn1_error); ++ goto cleanup; ++ } ++ ++ /* ++ * If EKUs are present, there must be exactly 1 and it must be a ++ * codeSigning usage. ++ */ ++ result = asn1_number_of_elements (extendedasn, "", &count); ++ if (result != ASN1_SUCCESS) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ "Error counting number of Extended Key Usages: %s", ++ asn1_strerror (result)); ++ goto cleanup; ++ } ++ ++ if (count != 1) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ "Unexpected number of Extended Key Usages: %d, 1 expected", ++ count); ++ goto cleanup; ++ } ++ ++ result = asn1_read_value (extendedasn, "?1", usage, &usage_size); ++ if (result != ASN1_SUCCESS) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ "Error reading Extended Key Usage: %s", ++ asn1_strerror (result)); ++ goto cleanup; ++ } ++ ++ if (grub_strncmp (codeSigningUsage_oid, usage, usage_size) != 0) ++ { ++ err = ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ "Unexpected Extended Key Usage OID, got: %s", usage); ++ goto cleanup; ++ } ++ ++cleanup: ++ asn1_delete_structure (&extendedasn); ++ return err; ++} + +/* + * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension @@ -1104,17 +1551,18 @@ index 00000000000..2b38b3670a2 + * -- by extnID + * } + * -+ * We require that a certificate: ++ * A certificate must: + * - contain the Digital Signature usage only + * - not be a CA -+ * - MUST not contain any other critical extensions (RFC 5280 s 4.2) ++ * - contain no extended usages, or only a code signing extended usage ++ * - not contain any other critical extensions (RFC 5280 s 4.2) + */ +static grub_err_t +verify_extensions (asn1_node cert) +{ + int result; + int ext, num_extensions = 0; -+ int usage_present = 0, constraints_present = 0; ++ int usage_present = 0, constraints_present = 0, extended_usage_present = 0; + char *oid_path, *critical_path, *value_path; + char extnID[MAX_OID_LEN]; + int extnID_size; @@ -1147,7 +1595,7 @@ index 00000000000..2b38b3670a2 + + extnID_size = sizeof (extnID); + result = asn1_read_value (cert, oid_path, extnID, &extnID_size); -+ if (result != GRUB_ERR_NONE) ++ if (result != ASN1_SUCCESS) + { + err = + grub_error (GRUB_ERR_BAD_FILE_TYPE, @@ -1208,6 +1656,15 @@ index 00000000000..2b38b3670a2 + } + constraints_present++; + } ++ else if (grub_strncmp (extendedKeyUsage_oid, extnID, extnID_size) == 0) ++ { ++ err = verify_extended_key_usage (value, value_size); ++ if (err != GRUB_ERR_NONE) ++ { ++ goto cleanup_value; ++ } ++ extended_usage_present++; ++ } + else if (grub_strncmp ("TRUE", critical, critical_size) == 0) + { + /* @@ -1239,6 +1696,12 @@ index 00000000000..2b38b3670a2 + "Unexpected number of basic constraints extensions - expected 1, got %d", + constraints_present); + } ++ if (extended_usage_present > 1) ++ { ++ return grub_error (GRUB_ERR_BAD_FILE_TYPE, ++ "Unexpected number of Extended Key Usage extensions - expected 0 or 1, got %d", ++ extended_usage_present); ++ } + return GRUB_ERR_NONE; + +cleanup_value: @@ -1257,8 +1720,8 @@ index 00000000000..2b38b3670a2 + * Return the results in @results, which must point to an allocated x509 certificate. + */ +grub_err_t -+certificate_import (void *data, grub_size_t data_size, -+ struct x509_certificate *results) ++parse_x509_certificate (const void *data, grub_size_t data_size, ++ struct x509_certificate *results) +{ + int result = 0; + asn1_node cert; @@ -1375,8 +1838,7 @@ index 00000000000..2b38b3670a2 + + err = verify_extensions (cert); + if (err != GRUB_ERR_NONE) -+ goto cleanup_name; -+ ++ goto cleanup_mpis; + + /* + * We do not read or check the signature on the certificate: @@ -1387,7 +1849,9 @@ index 00000000000..2b38b3670a2 + asn1_delete_structure (&cert); + return GRUB_ERR_NONE; + -+ ++cleanup_mpis: ++ gcry_mpi_release (results->mpis[0]); ++ gcry_mpi_release (results->mpis[1]); +cleanup_name: + grub_free (results->subject); +cleanup_serial: @@ -1410,119 +1874,3 @@ index 00000000000..2b38b3670a2 + gcry_mpi_release (cert->mpis[0]); + gcry_mpi_release (cert->mpis[1]); +} -diff --git a/grub-core/commands/appendedsig/appendedsig.h b/grub-core/commands/appendedsig/appendedsig.h -new file mode 100644 -index 00000000000..9792ef3901e ---- /dev/null -+++ b/grub-core/commands/appendedsig/appendedsig.h -@@ -0,0 +1,110 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2020 IBM Corporation. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+ -+extern asn1_node _gnutls_gnutls_asn; -+extern asn1_node _gnutls_pkix_asn; -+ -+#define MAX_OID_LEN 32 -+ -+/* -+ * One or more x509 certificates. -+ * -+ * We do limited parsing: extracting only the serial, CN and RSA public key. -+ */ -+struct x509_certificate -+{ -+ struct x509_certificate *next; -+ -+ grub_uint8_t *serial; -+ grub_size_t serial_len; -+ -+ char *subject; -+ grub_size_t subject_len; -+ -+ /* We only support RSA public keys. This encodes [modulus, publicExponent] */ -+ gcry_mpi_t mpis[2]; -+}; -+ -+/* -+ * A PKCS#7 signedData message. -+ * -+ * We make no attempt to match intelligently, so we don't save any info about -+ * the signer. We also support only 1 signerInfo, so we only store a single -+ * MPI for the signature. -+ */ -+struct pkcs7_signedData -+{ -+ const gcry_md_spec_t *hash; -+ gcry_mpi_t sig_mpi; -+}; -+ -+ -+/* Do libtasn1 init */ -+int asn1_init (void); -+ -+/* -+ * Import a DER-encoded certificate at 'data', of size 'size'. -+ * -+ * Place the results into 'results', which must be already allocated. -+ */ -+grub_err_t -+certificate_import (void *data, grub_size_t size, -+ struct x509_certificate *results); -+ -+/* -+ * Release all the storage associated with the x509 certificate. -+ * If the caller dynamically allocated the certificate, it must free it. -+ * The caller is also responsible for maintenance of the linked list. -+ */ -+void certificate_release (struct x509_certificate *cert); -+ -+/* -+ * Parse a PKCS#7 message, which must be a signedData message. -+ * -+ * The message must be in 'sigbuf' and of size 'data_size'. The result is -+ * placed in 'msg', which must already be allocated. -+ */ -+grub_err_t -+parse_pkcs7_signedData (void *sigbuf, grub_size_t data_size, -+ struct pkcs7_signedData *msg); -+ -+/* -+ * Release all the storage associated with the PKCS#7 message. -+ * If the caller dynamically allocated the message, it must free it. -+ */ -+void pkcs7_signedData_release (struct pkcs7_signedData *msg); -+ -+/* -+ * Read a value from an ASN1 node, allocating memory to store it. -+ * -+ * It will work for anything where the size libtasn1 returns is right: -+ * - Integers -+ * - Octet strings -+ * - DER encoding of other structures -+ * It will _not_ work for things where libtasn1 size requires adjustment: -+ * - Strings that require an extra NULL byte at the end -+ * - Bit strings because libtasn1 returns the length in bits, not bytes. -+ * -+ * If the function returns a non-NULL value, the caller must free it. -+ */ -+void *grub_asn1_allocate_and_read (asn1_node node, const char *name, -+ const char *friendly_name, -+ int *content_size); diff --git a/0019-Add-fw_path-variable-revised.patch b/0019-Add-fw_path-variable-revised.patch deleted file mode 100644 index a8491e8c083d23bd27540ff1e5e16db2509a2579..0000000000000000000000000000000000000000 --- a/0019-Add-fw_path-variable-revised.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Wed, 19 Sep 2012 21:22:55 -0300 -Subject: [PATCH] Add fw_path variable (revised) - -This patch makes grub look for its config file on efi where the app was -found. It was originally written by Matthew Garrett, and adapted to fix the -"No modules are loaded on grub2 network boot" issue: - -https://bugzilla.redhat.com/show_bug.cgi?id=857936 - -Signed-off-by: Paulo Flabiano Smorigo -Signed-off-by: Robbie Harwood ---- - grub-core/kern/main.c | 13 ++++++------- - grub-core/normal/main.c | 25 ++++++++++++++++++++++++- - 2 files changed, 30 insertions(+), 8 deletions(-) - -diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c -index 73967e2f5b0..d1de9fa6873 100644 ---- a/grub-core/kern/main.c -+++ b/grub-core/kern/main.c -@@ -128,16 +128,15 @@ grub_set_prefix_and_root (void) - - grub_machine_get_bootlocation (&fwdevice, &fwpath); - -- if (fwdevice) -+ if (fwdevice && fwpath) - { -- char *cmdpath; -+ char *fw_path; - -- cmdpath = grub_xasprintf ("(%s)%s", fwdevice, fwpath ? : ""); -- if (cmdpath) -+ fw_path = grub_xasprintf ("(%s)/%s", fwdevice, fwpath); -+ if (fw_path) - { -- grub_env_set ("cmdpath", cmdpath); -- grub_env_export ("cmdpath"); -- grub_free (cmdpath); -+ grub_env_set ("fw_path", fw_path); -+ grub_free (fw_path); - } - } - -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 70614de1565..62571e6dfcc 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -339,7 +339,30 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - /* Guess the config filename. It is necessary to make CONFIG static, - so that it won't get broken by longjmp. */ - char *config; -- const char *prefix; -+ const char *prefix, *fw_path; -+ -+ fw_path = grub_env_get ("fw_path"); -+ if (fw_path) -+ { -+ config = grub_xasprintf ("%s/grub.cfg", fw_path); -+ if (config) -+ { -+ grub_file_t file; -+ -+ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); -+ if (file) -+ { -+ grub_file_close (file); -+ grub_enter_normal_mode (config); -+ } -+ else -+ { -+ /* Ignore all errors. */ -+ grub_errno = 0; -+ } -+ grub_free (config); -+ } -+ } - - prefix = grub_env_get ("prefix"); - if (prefix) diff --git a/0175-appended-signatures-support-verifying-appended-signa.patch b/0019-appended-signatures-support-verifying-appended-signa.patch similarity index 77% rename from 0175-appended-signatures-support-verifying-appended-signa.patch rename to 0019-appended-signatures-support-verifying-appended-signa.patch index 262efc0df50b414f27662b970c6bf841e2259e54..e90d62016a0405fd05e2557147cd89baf3aa5e14 100644 --- a/0175-appended-signatures-support-verifying-appended-signa.patch +++ b/0019-appended-signatures-support-verifying-appended-signa.patch @@ -1,7 +1,8 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 97104dbd207a07fa3759b23766fa60f7bb8d16b4 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Thu, 30 Jul 2020 01:35:43 +1000 -Subject: [PATCH] appended signatures: support verifying appended signatures +Subject: [PATCH 19/23] appended signatures: support verifying appended + signatures Building on the parsers and the ability to embed x509 certificates, as well as the existing gcrypt functionality, add a module for verifying @@ -20,22 +21,37 @@ other mechanisms, such as a password or lockdown, must be used to ensure that a user cannot drop to the grub shell and disable verification. Signed-off-by: Daniel Axtens + +--- + +v2 changes: + + - Improve x509 parser function name + - Constify data parameters in function signatures + - Support multiple signers + - Use an enum rather than 0, 1 and 2 for various signature + enforcement states. + - Spin out a file reading function that was duplicated. + - Fix some code style and clarity issues. + +Thanks to Nayna Jain and Stefan Berger for their reviews. + +Revert "fixups so that you can build pkcs7 without posixly" + +This reverts commit 676a19fa8a7f9cca7a58ce2180110f609185b2bd. --- - grub-core/Makefile.core.def | 12 + - grub-core/commands/appendedsig/appendedsig.c | 645 +++++++++++++++++++++++++++ + grub-core/Makefile.core.def | 14 + + grub-core/commands/appendedsig/appendedsig.c | 669 +++++++++++++++++++ include/grub/file.h | 2 + - 3 files changed, 659 insertions(+) + 3 files changed, 685 insertions(+) create mode 100644 grub-core/commands/appendedsig/appendedsig.c -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index b4aaccf7b57..77321d218c8 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -980,6 +980,18 @@ module = { - cppflags = '-I$(srcdir)/lib/posix_wrap'; +@@ -979,6 +979,21 @@ }; -+module = { + module = { + name = appendedsig; + common = commands/appendedsig/appendedsig.c; + common = commands/appendedsig/x509.c; @@ -43,19 +59,20 @@ index b4aaccf7b57..77321d218c8 100644 + common = commands/appendedsig/asn1util.c; + common = commands/appendedsig/gnutls_asn1_tab.c; + common = commands/appendedsig/pkix_asn1_tab.c; ++ ++ extra_dist = commands/appendedsig/appendedsig.h; ++ // posix wrapper required for gcry to get sys/types.h + cflags = '$(CFLAGS_POSIX)'; + cppflags = '-I$(srcdir)/lib/posix_wrap'; +}; + - module = { ++module = { name = hdparm; common = commands/hdparm.c; -diff --git a/grub-core/commands/appendedsig/appendedsig.c b/grub-core/commands/appendedsig/appendedsig.c -new file mode 100644 -index 00000000000..dc294cd339e + enable = pci; --- /dev/null +++ b/grub-core/commands/appendedsig/appendedsig.c -@@ -0,0 +1,645 @@ +@@ -0,0 +1,669 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020-2021 IBM Corporation. @@ -148,15 +165,19 @@ index 00000000000..dc294cd339e + */ +extern gcry_pk_spec_t _gcry_pubkey_spec_rsa; + -+static int check_sigs = 0; ++static enum ++{ check_sigs_no = 0, ++ check_sigs_enforce = 1, ++ check_sigs_forced = 2 ++} check_sigs = check_sigs_no; + +static const char * -+grub_env_read_sec (struct grub_env_var *var __attribute__ ((unused)), -+ const char *val __attribute__ ((unused))) ++grub_env_read_sec (struct grub_env_var *var __attribute__((unused)), ++ const char *val __attribute__((unused))) +{ -+ if (check_sigs == 2) ++ if (check_sigs == check_sigs_forced) + return "forced"; -+ else if (check_sigs == 1) ++ else if (check_sigs == check_sigs_enforce) + return "enforce"; + else + return "no"; @@ -167,71 +188,99 @@ index 00000000000..dc294cd339e + const char *val) +{ + /* Do not allow the value to be changed if set to forced */ -+ if (check_sigs == 2) ++ if (check_sigs == check_sigs_forced) + return grub_strdup ("forced"); + + if ((*val == '2') || (*val == 'f')) -+ check_sigs = 2; ++ check_sigs = check_sigs_forced; + else if ((*val == '1') || (*val == 'e')) -+ check_sigs = 1; ++ check_sigs = check_sigs_enforce; + else if ((*val == '0') || (*val == 'n')) -+ check_sigs = 0; ++ check_sigs = check_sigs_no; + + return grub_strdup (grub_env_read_sec (NULL, NULL)); +} + +static grub_err_t -+read_cert_from_file (grub_file_t f, struct x509_certificate *certificate) ++file_read_all (grub_file_t file, grub_uint8_t **buf, grub_size_t *len) +{ -+ grub_err_t err; -+ grub_uint8_t *buf = NULL; ++ grub_off_t full_file_size; ++ grub_size_t file_size, total_read_size = 0; + grub_ssize_t read_size; -+ grub_off_t total_read_size = 0; -+ grub_off_t file_size = grub_file_size (f); -+ + -+ if (file_size == GRUB_FILE_SIZE_UNKNOWN) ++ full_file_size = grub_file_size (file); ++ if (full_file_size == GRUB_FILE_SIZE_UNKNOWN) + return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Cannot parse a certificate file of unknown size")); ++ N_("Cannot read a file of unknown size into a buffer")); + -+ buf = grub_zalloc (file_size); -+ if (!buf) ++ if (full_file_size > GRUB_SIZE_MAX) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, ++ N_("File is too large to read: %" PRIuGRUB_UINT64_T ++ " bytes"), full_file_size); ++ ++ file_size = (grub_size_t) full_file_size; ++ ++ *buf = grub_malloc (file_size); ++ if (!*buf) + return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ N_("Could not allocate buffer for certificate file contents")); ++ N_("Could not allocate file data buffer size %" ++ PRIuGRUB_SIZE), file_size); + + while (total_read_size < file_size) + { + read_size = -+ grub_file_read (f, &buf[total_read_size], ++ grub_file_read (file, *buf + total_read_size, + file_size - total_read_size); ++ + if (read_size < 0) + { -+ err = grub_error (GRUB_ERR_READ_ERROR, -+ N_("Error reading certificate file")); -+ goto cleanup_buf; ++ grub_free (*buf); ++ return grub_errno; + } ++ else if (read_size == 0) ++ { ++ grub_free (*buf); ++ return grub_error (GRUB_ERR_IO, ++ N_("Could not read full file size (%" ++ PRIuGRUB_SIZE "), only %" PRIuGRUB_SIZE ++ " bytes read"), file_size, total_read_size); ++ } ++ + total_read_size += read_size; + } ++ *len = file_size; ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++read_cert_from_file (grub_file_t f, struct x509_certificate *certificate) ++{ ++ grub_err_t err; ++ grub_uint8_t *buf; ++ grub_size_t file_size; ++ ++ err = file_read_all (f, &buf, &file_size); ++ if (err != GRUB_ERR_NONE) ++ return err; + -+ err = certificate_import (buf, total_read_size, certificate); ++ err = parse_x509_certificate (buf, file_size, certificate); + if (err != GRUB_ERR_NONE) -+ goto cleanup_buf; ++ { ++ grub_free (buf); ++ return err; ++ } + + return GRUB_ERR_NONE; -+ -+cleanup_buf: -+ grub_free (buf); -+ return err; +} + +static grub_err_t -+extract_appended_signature (grub_uint8_t * buf, grub_size_t bufsize, ++extract_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize, + struct grub_appended_signature *sig) +{ + grub_err_t err; + grub_size_t pkcs7_size; + grub_size_t remaining_len; -+ grub_uint8_t *appsigdata = buf + bufsize - grub_strlen (magic); ++ const grub_uint8_t *appsigdata = buf + bufsize - grub_strlen (magic); + + if (bufsize < grub_strlen (magic)) + return grub_error (GRUB_ERR_BAD_SIGNATURE, @@ -258,11 +307,7 @@ index 00000000000..dc294cd339e + if (sig->sig_metadata.id_type != 2) + return grub_error (GRUB_ERR_BAD_SIGNATURE, N_("Wrong signature type")); + -+#ifdef GRUB_TARGET_WORDS_BIGENDIAN -+ pkcs7_size = sig->sig_metadata.sig_len; -+#else -+ pkcs7_size = __builtin_bswap32 (sig->sig_metadata.sig_len); -+#endif ++ pkcs7_size = grub_be_to_cpu32 (sig->sig_metadata.sig_len); + + if (pkcs7_size > remaining_len) + return grub_error (GRUB_ERR_BAD_SIGNATURE, @@ -284,7 +329,7 @@ index 00000000000..dc294cd339e +} + +static grub_err_t -+grub_verify_appended_signature (grub_uint8_t * buf, grub_size_t bufsize) ++grub_verify_appended_signature (const grub_uint8_t *buf, grub_size_t bufsize) +{ + grub_err_t err = GRUB_ERR_NONE; + grub_size_t datasize; @@ -294,6 +339,8 @@ index 00000000000..dc294cd339e + gcry_err_code_t rc; + struct x509_certificate *pk; + struct grub_appended_signature sig; ++ struct pkcs7_signerInfo *si; ++ int i; + + if (!grub_trusted_key) + return grub_error (GRUB_ERR_BAD_SIGNATURE, @@ -305,53 +352,70 @@ index 00000000000..dc294cd339e + + datasize = bufsize - sig.signature_len; + -+ context = grub_zalloc (sig.pkcs7.hash->contextsize); -+ if (!context) -+ return grub_errno; -+ -+ sig.pkcs7.hash->init (context); -+ sig.pkcs7.hash->write (context, buf, datasize); -+ sig.pkcs7.hash->final (context); -+ hash = sig.pkcs7.hash->read (context); -+ grub_dprintf ("appendedsig", -+ "data size %" PRIxGRUB_SIZE ", hash %02x%02x%02x%02x...\n", -+ datasize, hash[0], hash[1], hash[2], hash[3]); -+ -+ err = GRUB_ERR_BAD_SIGNATURE; -+ for (pk = grub_trusted_key; pk; pk = pk->next) ++ for (i = 0; i < sig.pkcs7.signerInfo_count; i++) + { -+ rc = grub_crypto_rsa_pad (&hashmpi, hash, sig.pkcs7.hash, pk->mpis[0]); -+ if (rc) ++ /* This could be optimised in a couple of ways: ++ - we could only compute hashes once per hash type ++ - we could track signer information and only verify where IDs match ++ For now we do the naive O(trusted keys * pkcs7 signers) approach. ++ */ ++ si = &sig.pkcs7.signerInfos[i]; ++ context = grub_zalloc (si->hash->contextsize); ++ if (!context) ++ return grub_errno; ++ ++ si->hash->init (context); ++ si->hash->write (context, buf, datasize); ++ si->hash->final (context); ++ hash = si->hash->read (context); ++ ++ grub_dprintf ("appendedsig", ++ "data size %" PRIxGRUB_SIZE ", signer %d hash %02x%02x%02x%02x...\n", ++ datasize, i, hash[0], hash[1], hash[2], hash[3]); ++ ++ err = GRUB_ERR_BAD_SIGNATURE; ++ for (pk = grub_trusted_key; pk; pk = pk->next) + { -+ err = grub_error (GRUB_ERR_BAD_SIGNATURE, -+ N_("Error padding hash for RSA verification: %d"), -+ rc); -+ goto cleanup; ++ rc = grub_crypto_rsa_pad (&hashmpi, hash, si->hash, pk->mpis[0]); ++ if (rc) ++ { ++ err = grub_error (GRUB_ERR_BAD_SIGNATURE, ++ N_("Error padding hash for RSA verification: %d"), ++ rc); ++ grub_free (context); ++ goto cleanup; ++ } ++ ++ rc = _gcry_pubkey_spec_rsa.verify (0, hashmpi, &si->sig_mpi, ++ pk->mpis, NULL, NULL); ++ gcry_mpi_release (hashmpi); ++ ++ if (rc == 0) ++ { ++ grub_dprintf ("appendedsig", ++ "verify signer %d with key '%s' succeeded\n", i, ++ pk->subject); ++ err = GRUB_ERR_NONE; ++ break; ++ } ++ ++ grub_dprintf ("appendedsig", ++ "verify signer %d with key '%s' failed with %d\n", i, ++ pk->subject, rc); + } + -+ rc = _gcry_pubkey_spec_rsa.verify (0, hashmpi, &sig.pkcs7.sig_mpi, -+ pk->mpis, NULL, NULL); -+ gcry_mpi_release (hashmpi); ++ grub_free (context); + -+ if (rc == 0) -+ { -+ grub_dprintf ("appendedsig", "verify with key '%s' succeeded\n", -+ pk->subject); -+ err = GRUB_ERR_NONE; -+ break; -+ } -+ -+ grub_dprintf ("appendedsig", "verify with key '%s' failed with %d\n", -+ pk->subject, rc); ++ if (err == GRUB_ERR_NONE) ++ break; + } + + /* If we didn't verify, provide a neat message */ + if (err != GRUB_ERR_NONE) -+ err = grub_error (GRUB_ERR_BAD_SIGNATURE, -+ N_("Failed to verify signature against a trusted key")); ++ err = grub_error (GRUB_ERR_BAD_SIGNATURE, ++ N_("Failed to verify signature against a trusted key")); + +cleanup: -+ grub_free (context); + pkcs7_signedData_release (&sig.pkcs7); + + return err; @@ -364,8 +428,7 @@ index 00000000000..dc294cd339e + grub_file_t f; + grub_err_t err = GRUB_ERR_NONE; + grub_uint8_t *data; -+ grub_ssize_t read_size; -+ grub_off_t file_size, total_read_size = 0; ++ grub_size_t file_size; + + if (argc < 1) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); @@ -379,35 +442,14 @@ index 00000000000..dc294cd339e + goto cleanup; + } + -+ file_size = grub_file_size (f); -+ if (file_size == GRUB_FILE_SIZE_UNKNOWN) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("Cannot verify the signature of a file of unknown size")); -+ -+ data = grub_malloc (file_size); -+ if (!data) -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ N_("Could not allocate data buffer size " -+ PRIuGRUB_UINT64_T " for verification"), file_size); -+ -+ while (total_read_size < file_size) -+ { -+ read_size = -+ grub_file_read (f, &data[total_read_size], -+ file_size - total_read_size); -+ if (read_size < 0) -+ { -+ err = grub_error (GRUB_ERR_READ_ERROR, -+ N_("Error reading file to verify")); -+ goto cleanup_data; -+ } -+ total_read_size += read_size; -+ } ++ err = file_read_all (f, &data, &file_size); ++ if (err != GRUB_ERR_NONE) ++ goto cleanup; + + err = grub_verify_appended_signature (data, file_size); + -+cleanup_data: + grub_free (data); ++ +cleanup: + if (f) + grub_file_close (f); @@ -460,7 +502,7 @@ index 00000000000..dc294cd339e + } + + return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("No certificate number %d found - only %d certificates in the store"), ++ N_("No certificate number %lu found - only %lu certificates in the store"), + cert_num, i - 1); +} + @@ -537,7 +579,7 @@ index 00000000000..dc294cd339e + void **context __attribute__((unused)), + enum grub_verify_flags *flags) +{ -+ if (!check_sigs) ++ if (check_sigs == check_sigs_no) + { + *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; + return GRUB_ERR_NONE; @@ -619,13 +661,12 @@ index 00000000000..dc294cd339e + + /* If in lockdown, immediately enter forced mode */ + if (grub_is_lockdown () == GRUB_LOCKDOWN_ENABLED) -+ check_sigs = 2; ++ check_sigs = check_sigs_forced; + + grub_trusted_key = NULL; + + grub_register_variable_hook ("check_appended_signatures", -+ grub_env_read_sec, -+ grub_env_write_sec); ++ grub_env_read_sec, grub_env_write_sec); + grub_env_export ("check_appended_signatures"); + + rc = asn1_init (); @@ -701,11 +742,9 @@ index 00000000000..dc294cd339e + grub_unregister_command (cmd_trust); + grub_unregister_command (cmd_distrust); +} -diff --git a/include/grub/file.h b/include/grub/file.h -index 31567483ccf..96827a4f896 100644 --- a/include/grub/file.h +++ b/include/grub/file.h -@@ -80,6 +80,8 @@ enum grub_file_type +@@ -80,6 +80,8 @@ GRUB_FILE_TYPE_PUBLIC_KEY, /* File holding public key to add to trused keys. */ GRUB_FILE_TYPE_PUBLIC_KEY_TRUST, diff --git a/0020-Pass-x-hex-hex-straight-through-unmolested.patch b/0020-Pass-x-hex-hex-straight-through-unmolested.patch deleted file mode 100644 index b81abb54583a157bcffbd037a88f4282f550001b..0000000000000000000000000000000000000000 --- a/0020-Pass-x-hex-hex-straight-through-unmolested.patch +++ /dev/null @@ -1,173 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 1 Oct 2012 13:24:37 -0400 -Subject: [PATCH] Pass "\x[[:hex:]][[:hex:]]" straight through unmolested. - -Don't munge raw spaces when we're doing our cmdline escaping (#923374) - -Signed-off-by: Peter Jones ---- - grub-core/commands/wildcard.c | 16 +++++++++++++++- - grub-core/lib/cmdline.c | 25 +++++++++++++++++++++++-- - grub-core/script/execute.c | 43 +++++++++++++++++++++++++++++++++++++------ - 3 files changed, 75 insertions(+), 9 deletions(-) - -diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c -index cc3290311f0..8f67a4be7f0 100644 ---- a/grub-core/commands/wildcard.c -+++ b/grub-core/commands/wildcard.c -@@ -488,6 +488,12 @@ check_file (const char *dir, const char *basename) - return ctx.found; - } - -+static int -+is_hex(char c) -+{ -+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); -+} -+ - static void - unescape (char *out, const char *in, const char *end) - { -@@ -496,7 +502,15 @@ unescape (char *out, const char *in, const char *end) - - for (optr = out, iptr = in; iptr < end;) - { -- if (*iptr == '\\' && iptr + 1 < end) -+ if (*iptr == '\\' && iptr + 3 < end && iptr[1] == 'x' && is_hex(iptr[2]) && is_hex(iptr[3])) -+ { -+ *optr++ = *iptr++; -+ *optr++ = *iptr++; -+ *optr++ = *iptr++; -+ *optr++ = *iptr++; -+ continue; -+ } -+ else if (*iptr == '\\' && iptr + 1 < end) - { - *optr++ = iptr[1]; - iptr += 2; -diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c -index ed0b149dca5..8e2294d8ff6 100644 ---- a/grub-core/lib/cmdline.c -+++ b/grub-core/lib/cmdline.c -@@ -20,6 +20,12 @@ - #include - #include - -+static int -+is_hex(char c) -+{ -+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); -+} -+ - static unsigned int check_arg (char *c, int *has_space) - { - int space = 0; -@@ -27,7 +33,13 @@ static unsigned int check_arg (char *c, int *has_space) - - while (*c) - { -- if (*c == '\\' || *c == '\'' || *c == '"') -+ if (*c == '\\' && *(c+1) == 'x' && is_hex(*(c+2)) && is_hex(*(c+3))) -+ { -+ size += 4; -+ c += 4; -+ continue; -+ } -+ else if (*c == '\\' || *c == '\'' || *c == '"') - size++; - else if (*c == ' ') - space = 1; -@@ -86,7 +98,16 @@ grub_create_loader_cmdline (int argc, char *argv[], char *buf, - - while (*c) - { -- if (*c == '\\' || *c == '\'' || *c == '"') -+ if (*c == '\\' && *(c+1) == 'x' && -+ is_hex(*(c+2)) && is_hex(*(c+3))) -+ { -+ *buf++ = *c++; -+ *buf++ = *c++; -+ *buf++ = *c++; -+ *buf++ = *c++; -+ continue; -+ } -+ else if (*c == '\\' || *c == '\'' || *c == '"') - *buf++ = '\\'; - - *buf++ = *c; -diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c -index ad80399246a..0c6dd9c5201 100644 ---- a/grub-core/script/execute.c -+++ b/grub-core/script/execute.c -@@ -56,6 +56,12 @@ static struct grub_script_scope *scope = 0; - /* Wildcard translator for GRUB script. */ - struct grub_script_wildcard_translator *grub_wildcard_translator; - -+static int -+is_hex(char c) -+{ -+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')); -+} -+ - static char* - wildcard_escape (const char *s) - { -@@ -72,7 +78,15 @@ wildcard_escape (const char *s) - i = 0; - while ((ch = *s++)) - { -- if (ch == '*' || ch == '\\' || ch == '?') -+ if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2])) -+ { -+ p[i++] = ch; -+ p[i++] = *s++; -+ p[i++] = *s++; -+ p[i++] = *s++; -+ continue; -+ } -+ else if (ch == '*' || ch == '\\' || ch == '?') - p[i++] = '\\'; - p[i++] = ch; - } -@@ -96,7 +110,14 @@ wildcard_unescape (const char *s) - i = 0; - while ((ch = *s++)) - { -- if (ch == '\\') -+ if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2])) -+ { -+ p[i++] = '\\'; -+ p[i++] = *s++; -+ p[i++] = *s++; -+ p[i++] = *s++; -+ } -+ else if (ch == '\\') - p[i++] = *s++; - else - p[i++] = ch; -@@ -398,10 +419,20 @@ parse_string (const char *str, - switch (*ptr) - { - case '\\': -- escaped = !escaped; -- if (!escaped && put) -- *(put++) = '\\'; -- ptr++; -+ if (!escaped && put && *(ptr+1) == 'x' && is_hex(*(ptr+2)) && is_hex(*(ptr+3))) -+ { -+ *(put++) = *ptr++; -+ *(put++) = *ptr++; -+ *(put++) = *ptr++; -+ *(put++) = *ptr++; -+ } -+ else -+ { -+ escaped = !escaped; -+ if (!escaped && put) -+ *(put++) = '\\'; -+ ptr++; -+ } - break; - case '$': - if (escaped) diff --git a/0176-appended-signatures-verification-tests.patch b/0020-appended-signatures-verification-tests.patch similarity index 42% rename from 0176-appended-signatures-verification-tests.patch rename to 0020-appended-signatures-verification-tests.patch index 9f6c3c62d250045d5d3ae9b7bfc175f6a90b205f..29ed126e3617c378054b72236d977c27922fa6dd 100644 --- a/0176-appended-signatures-verification-tests.patch +++ b/0020-appended-signatures-verification-tests.patch @@ -1,44 +1,50 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 221f2419c70cd953515562901b1e72946632cd13 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Thu, 30 Jul 2020 01:31:02 +1000 -Subject: [PATCH] appended signatures: verification tests +Subject: [PATCH 20/23] appended signatures: verification tests These tests are run through all_functional_test and test a range of commands and behaviours. Signed-off-by: Daniel Axtens + +--- + +v2 changes: + + - add a test for EKU + - add tests for files signed with multiple signers + - add a test of padded PKCS#7 messages + - use macros to reduce duplication for exposing certificate files + to the test via procfs + - more useful comments --- grub-core/Makefile.core.def | 6 + - grub-core/tests/appended_signature_test.c | 281 +++++++++++++++ + grub-core/tests/appended_signature_test.c | 273 ++++++ + grub-core/tests/appended_signatures.h | 975 ++++++++++++++++++++++ grub-core/tests/lib/functional_test.c | 1 + - grub-core/tests/appended_signatures.h | 557 ++++++++++++++++++++++++++++++ - 4 files changed, 845 insertions(+) + 4 files changed, 1255 insertions(+) create mode 100644 grub-core/tests/appended_signature_test.c create mode 100644 grub-core/tests/appended_signatures.h -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 77321d218c8..6bddc841b85 100644 --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -2161,6 +2161,12 @@ module = { - common = tests/setjmp_test.c; +@@ -2191,6 +2191,12 @@ }; -+module = { + module = { + name = appended_signature_test; + common = tests/appended_signature_test.c; + common = tests/appended_signatures.h; +}; + - module = { ++module = { name = signature_test; common = tests/signature_test.c; -diff --git a/grub-core/tests/appended_signature_test.c b/grub-core/tests/appended_signature_test.c -new file mode 100644 -index 00000000000..88a485200d8 + common = tests/signatures.h; --- /dev/null +++ b/grub-core/tests/appended_signature_test.c -@@ -0,0 +1,281 @@ +@@ -0,0 +1,273 @@ +/* + * GRUB -- GRand Unified Bootloader + * Copyright (C) 2020 IBM Corporation. @@ -71,23 +77,26 @@ index 00000000000..88a485200d8 + +GRUB_MOD_LICENSE ("GPLv3+"); + -+#define DEFINE_TEST_CASE(case_name) \ ++#define PROC_FILE(identifier, file_name) \ +static char * \ -+get_ ## case_name (grub_size_t *sz) \ ++get_ ## identifier (grub_size_t *sz) \ +{ \ + char *ret; \ -+ *sz = case_name ## _len; \ ++ \ ++ *sz = identifier ## _len; \ + ret = grub_malloc (*sz); \ + if (ret) \ -+ grub_memcpy (ret, case_name, *sz); \ ++ grub_memcpy (ret, identifier, *sz); \ + return ret; \ +} \ +\ -+static struct grub_procfs_entry case_name ## _entry = \ ++static struct grub_procfs_entry identifier ## _entry = \ +{ \ -+ .name = #case_name, \ -+ .get_contents = get_ ## case_name \ -+} ++ .name = file_name, \ ++ .get_contents = get_ ## identifier \ ++}; ++ ++#define DEFINE_TEST_CASE(case_name) PROC_FILE(case_name, #case_name) + +#define DO_TEST(case_name, is_valid) \ +{ \ @@ -103,55 +112,13 @@ index 00000000000..88a485200d8 +DEFINE_TEST_CASE (short_msg); +DEFINE_TEST_CASE (unsigned_msg); +DEFINE_TEST_CASE (hi_signed_2nd); ++DEFINE_TEST_CASE (hi_double); ++DEFINE_TEST_CASE (hi_double_extended); + -+static char * -+get_certificate_der (grub_size_t * sz) -+{ -+ char *ret; -+ *sz = certificate_der_len; -+ ret = grub_malloc (*sz); -+ if (ret) -+ grub_memcpy (ret, certificate_der, *sz); -+ return ret; -+} -+ -+static struct grub_procfs_entry certificate_der_entry = { -+ .name = "certificate.der", -+ .get_contents = get_certificate_der -+}; -+ -+static char * -+get_certificate2_der (grub_size_t * sz) -+{ -+ char *ret; -+ *sz = certificate2_der_len; -+ ret = grub_malloc (*sz); -+ if (ret) -+ grub_memcpy (ret, certificate2_der, *sz); -+ return ret; -+} -+ -+static struct grub_procfs_entry certificate2_der_entry = { -+ .name = "certificate2.der", -+ .get_contents = get_certificate2_der -+}; -+ -+static char * -+get_certificate_printable_der (grub_size_t * sz) -+{ -+ char *ret; -+ *sz = certificate_printable_der_len; -+ ret = grub_malloc (*sz); -+ if (ret) -+ grub_memcpy (ret, certificate_printable_der, *sz); -+ return ret; -+} -+ -+static struct grub_procfs_entry certificate_printable_der_entry = { -+ .name = "certificate_printable.der", -+ .get_contents = get_certificate_printable_der -+}; -+ ++PROC_FILE (certificate_der, "certificate.der") ++PROC_FILE (certificate2_der, "certificate2.der") ++PROC_FILE (certificate_printable_der, "certificate_printable.der") ++PROC_FILE (certificate_eku_der, "certificate_eku.der") + +static void +do_verify (const char *f, int is_valid) @@ -190,6 +157,7 @@ index 00000000000..88a485200d8 + char *trust_args2[] = { (char *) "(proc)/certificate2.der", NULL }; + char *trust_args_printable[] = { (char *) "(proc)/certificate_printable.der", + NULL }; ++ char *trust_args_eku[] = { (char *) "(proc)/certificate_eku.der", NULL }; + char *distrust_args[] = { (char *) "1", NULL }; + char *distrust2_args[] = { (char *) "2", NULL }; + grub_err_t err; @@ -198,6 +166,7 @@ index 00000000000..88a485200d8 + grub_procfs_register ("certificate2.der", &certificate2_der_entry); + grub_procfs_register ("certificate_printable.der", + &certificate_printable_der_entry); ++ grub_procfs_register ("certificate_eku.der", &certificate_eku_der_entry); + + cmd_trust = grub_command_find ("trust_certificate"); + if (!cmd_trust) @@ -224,12 +193,30 @@ index 00000000000..88a485200d8 + */ + cmd_trust = grub_command_find ("trust_certificate"); + ++ /* hi, signed with key 1, SHA-512 */ + DO_TEST (hi_signed, 1); ++ ++ /* hi, signed with key 1, SHA-256 */ + DO_TEST (hi_signed_sha256, 1); ++ ++ /* hi, key 1, SHA-512, second byte corrupted */ + DO_TEST (hj_signed, 0); ++ ++ /* message too short for a signature */ + DO_TEST (short_msg, 0); ++ ++ /* lorem ipsum */ + DO_TEST (unsigned_msg, 0); + ++ /* hi, signed with both keys, SHA-512 */ ++ DO_TEST (hi_double, 1); ++ ++ /* ++ * hi, signed with both keys and with empty space to test we haven't broken ++ * support for adding more signatures after the fact ++ */ ++ DO_TEST (hi_double_extended, 1); ++ + /* + * in enforcing mode, we shouldn't be able to load a certificate that isn't + * signed by an existing trusted key. @@ -254,6 +241,8 @@ index 00000000000..88a485200d8 + + DO_TEST (hi_signed_2nd, 1); + DO_TEST (hi_signed, 1); ++ DO_TEST (hi_double, 1); ++ DO_TEST (hi_double_extended, 1); + + /* + * Check certificate removal. They're added to the _top_ of the list and @@ -275,6 +264,7 @@ index 00000000000..88a485200d8 + grub_errmsg); + DO_TEST (hi_signed_2nd, 1); + DO_TEST (hi_signed, 0); ++ DO_TEST (hi_double, 1); + + /* + * Now reload certificate #1. This will make the list look like [#1, #2] @@ -304,257 +294,349 @@ index 00000000000..88a485200d8 + "distrusting certificate 1 (second time) failed: %d: %s", + grub_errno, grub_errmsg); + DO_TEST (hi_signed_2nd, 0); ++ DO_TEST (hi_double, 0); + + /* + * Lastly, check a certificate that uses printableString rather than -+ * utf8String loads properly. ++ * utf8String loads properly, and that a certificate with an appropriate ++ * extended key usage loads. + */ + err = (cmd_trust->func) (cmd_trust, 1, trust_args_printable); + grub_test_assert (err == GRUB_ERR_NONE, -+ "distrusting printable certificate failed: %d: %s", ++ "trusting printable certificate failed: %d: %s", ++ grub_errno, grub_errmsg); ++ ++ err = (cmd_trust->func) (cmd_trust, 1, trust_args_eku); ++ grub_test_assert (err == GRUB_ERR_NONE, ++ "trusting certificate with extended key usage failed: %d: %s", + grub_errno, grub_errmsg); + + grub_procfs_unregister (&certificate_der_entry); + grub_procfs_unregister (&certificate2_der_entry); + grub_procfs_unregister (&certificate_printable_der_entry); ++ grub_procfs_unregister (&certificate_eku_der_entry); +} + +GRUB_FUNCTIONAL_TEST (appended_signature_test, appended_signature_test); -diff --git a/grub-core/tests/lib/functional_test.c b/grub-core/tests/lib/functional_test.c -index 96781fb39b5..403fa5c789a 100644 ---- a/grub-core/tests/lib/functional_test.c -+++ b/grub-core/tests/lib/functional_test.c -@@ -73,6 +73,7 @@ grub_functional_all_tests (grub_extcmd_context_t ctxt __attribute__ ((unused)), - grub_dl_load ("xnu_uuid_test"); - grub_dl_load ("pbkdf2_test"); - grub_dl_load ("signature_test"); -+ grub_dl_load ("appended_signature_test"); - grub_dl_load ("sleep_test"); - grub_dl_load ("bswap_test"); - grub_dl_load ("ctz_test"); -diff --git a/grub-core/tests/appended_signatures.h b/grub-core/tests/appended_signatures.h -new file mode 100644 -index 00000000000..aa3dc6278e3 --- /dev/null +++ b/grub-core/tests/appended_signatures.h -@@ -0,0 +1,557 @@ +@@ -0,0 +1,975 @@ +unsigned char certificate_der[] = { -+ 0x30, 0x82, 0x03, 0x88, 0x30, 0x82, 0x02, 0x70, 0xa0, 0x03, 0x02, 0x01, -+ 0x02, 0x02, 0x14, 0x25, 0x2e, 0xb8, 0xfd, 0x12, 0x62, 0x2e, 0xcd, 0x5d, -+ 0xa7, 0x53, 0xd2, 0x0b, 0xc2, 0x61, 0x7c, 0x14, 0xe0, 0x0f, 0x5c, 0x30, ++ 0x30, 0x82, 0x05, 0x5d, 0x30, 0x82, 0x03, 0x45, 0xa0, 0x03, 0x02, 0x01, ++ 0x02, 0x02, 0x14, 0x5b, 0x5e, 0x59, 0xf2, 0x5f, 0x75, 0x4c, 0x8e, 0xc5, ++ 0x3a, 0x91, 0x07, 0xe9, 0xe7, 0x6d, 0x3c, 0xd0, 0x7f, 0x92, 0x03, 0x30, + 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, -+ 0x05, 0x00, 0x30, 0x49, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, -+ 0x03, 0x0c, 0x1f, 0x47, 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, ++ 0x05, 0x00, 0x30, 0x3d, 0x31, 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, ++ 0x03, 0x0c, 0x32, 0x47, 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, + 0x6e, 0x64, 0x65, 0x64, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, -+ 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1d, -+ 0x30, 0x1b, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, -+ 0x01, 0x16, 0x0e, 0x64, 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, -+ 0x73, 0x2e, 0x6e, 0x65, 0x74, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x30, 0x30, -+ 0x37, 0x30, 0x39, 0x30, 0x36, 0x32, 0x32, 0x30, 0x37, 0x5a, 0x18, 0x0f, -+ 0x32, 0x31, 0x32, 0x30, 0x30, 0x36, 0x31, 0x35, 0x30, 0x36, 0x32, 0x32, -+ 0x30, 0x37, 0x5a, 0x30, 0x52, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, ++ 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, ++ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, ++ 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x31, 0x30, ++ 0x36, 0x32, 0x39, 0x30, 0x38, 0x33, 0x36, 0x31, 0x33, 0x5a, 0x18, 0x0f, ++ 0x32, 0x31, 0x32, 0x31, 0x30, 0x36, 0x30, 0x35, 0x30, 0x38, 0x33, 0x36, ++ 0x31, 0x33, 0x5a, 0x30, 0x33, 0x31, 0x31, 0x30, 0x2f, 0x06, 0x03, 0x55, + 0x04, 0x03, 0x0c, 0x28, 0x47, 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, + 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, + 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x53, 0x69, 0x67, -+ 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x4b, 0x65, 0x79, 0x31, 0x1d, 0x30, 0x1b, -+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, -+ 0x0e, 0x64, 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x2e, -+ 0x6e, 0x65, 0x74, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, -+ 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, -+ 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, -+ 0xcd, 0xe8, 0x1c, 0x08, 0x68, 0x2e, 0xcb, 0xfe, 0x8c, 0x4b, 0x3b, 0x61, -+ 0xe7, 0x8e, 0x80, 0x58, 0x85, 0x85, 0xea, 0xc8, 0x3b, 0x42, 0xba, 0x72, -+ 0x84, 0x65, 0x20, 0xbc, 0x48, 0xa2, 0x25, 0x49, 0x6e, 0x1c, 0xb9, 0x7d, -+ 0xeb, 0xc1, 0x0c, 0xa8, 0xb7, 0xcc, 0x13, 0x78, 0xba, 0x11, 0xa4, 0x98, -+ 0xd7, 0xd0, 0x7c, 0xdd, 0xf5, 0x5a, 0xb7, 0xcd, 0x31, 0x0e, 0xcd, 0x9e, -+ 0xa7, 0x19, 0xf0, 0xbd, 0x0f, 0xa6, 0xfe, 0x8a, 0x11, 0x97, 0xed, 0x8b, -+ 0xe5, 0x16, 0xa6, 0x21, 0x13, 0x36, 0xad, 0x05, 0x49, 0xec, 0x29, 0x12, -+ 0x38, 0xa7, 0x4b, 0x0f, 0xa1, 0xfb, 0x72, 0xc0, 0xc0, 0x09, 0x67, 0x78, -+ 0xa8, 0xb6, 0xd6, 0x1a, 0x39, 0xc0, 0xa8, 0xbf, 0x5f, 0x14, 0x89, 0x5c, -+ 0xbc, 0x41, 0x0c, 0x0c, 0x5d, 0x42, 0x2e, 0x1c, 0xdf, 0x1f, 0x1d, 0xc9, -+ 0x43, 0x94, 0x5b, 0x6e, 0x8f, 0x15, 0x8c, 0x8f, 0x94, 0x73, 0x4f, 0x97, -+ 0x54, 0xf1, 0x86, 0x8a, 0xbc, 0xe4, 0xe4, 0x93, 0xc1, 0x5e, 0xc2, 0x3e, -+ 0x31, 0x5e, 0xd4, 0x85, 0x57, 0x14, 0xd0, 0x11, 0x07, 0x65, 0xf4, 0x7c, -+ 0x8f, 0x07, 0x57, 0xe1, 0x22, 0xd4, 0x78, 0x47, 0x65, 0x4e, 0xa9, 0xb3, -+ 0xaa, 0xce, 0xc7, 0x36, 0xfe, 0xda, 0x66, 0x02, 0xb6, 0x8d, 0x18, 0x2f, -+ 0x3b, 0x41, 0x8d, 0x02, 0x08, 0x72, 0x4b, 0x69, 0xbd, 0x1e, 0x58, 0xfc, -+ 0x1b, 0x64, 0x04, 0x52, 0x35, 0x35, 0xe2, 0x3d, 0x3e, 0xde, 0xd6, 0x64, -+ 0xf4, 0xec, 0x57, 0x7e, 0x65, 0x59, 0x00, 0xa6, 0xd3, 0x4b, 0x09, 0x93, -+ 0x2a, 0x95, 0x0f, 0x30, 0xb6, 0xa1, 0x8c, 0xe7, 0x8b, 0x49, 0xa4, 0x1d, -+ 0x25, 0x2d, 0x65, 0x48, 0x8a, 0x0f, 0xcf, 0x2a, 0xa2, 0xe1, 0xef, 0x72, -+ 0x92, 0xc3, 0xf5, 0x21, 0x37, 0x83, 0x9b, 0x6d, 0x0b, 0x1b, 0xb3, 0xa2, -+ 0x32, 0x38, 0x11, 0xb1, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x5d, 0x30, -+ 0x5b, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, -+ 0x02, 0x30, 0x00, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, -+ 0x03, 0x02, 0x07, 0x80, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, -+ 0x16, 0x04, 0x14, 0xe5, 0x2a, 0x4f, 0xf2, 0x84, 0x91, 0x57, 0x91, 0xaf, -+ 0x12, 0xd2, 0xf1, 0xa1, 0x87, 0x73, 0x0f, 0x90, 0x25, 0xa0, 0x7a, 0x30, -+ 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, -+ 0x56, 0xd1, 0xfd, 0xe2, 0x1e, 0x7e, 0x1c, 0x63, 0x4f, 0x47, 0xdb, 0xe4, -+ 0xc4, 0x51, 0x04, 0x03, 0x9a, 0x48, 0x35, 0x6e, 0x30, 0x0d, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, -+ 0x82, 0x01, 0x01, 0x00, 0x65, 0x82, 0xd5, 0x88, 0x30, 0xe2, 0x2c, 0x47, -+ 0xf3, 0x31, 0x39, 0xa1, 0x75, 0x9a, 0xb0, 0x8a, 0x6c, 0x4b, 0xac, 0xdf, -+ 0x09, 0x7b, 0x90, 0xb6, 0x9e, 0x76, 0x62, 0x94, 0xc1, 0x3a, 0x99, 0x49, -+ 0x68, 0x29, 0x47, 0x42, 0xc3, 0x06, 0xcb, 0x88, 0x75, 0xe6, 0x79, 0x13, -+ 0x8c, 0x4b, 0x49, 0x6a, 0xb5, 0x56, 0x95, 0xc0, 0x42, 0x21, 0x9b, 0xd4, -+ 0x61, 0xd0, 0x02, 0x41, 0xdd, 0x20, 0x61, 0xe5, 0x91, 0xdf, 0x75, 0x00, -+ 0x25, 0x0e, 0x99, 0x65, 0x5c, 0x54, 0x49, 0x32, 0xa3, 0xe2, 0xcd, 0xa1, -+ 0x5f, 0x40, 0xf3, 0xc5, 0x81, 0xd9, 0x3c, 0xa3, 0x63, 0x5a, 0x38, 0x79, -+ 0xab, 0x77, 0x98, 0xde, 0x8f, 0x4e, 0x9e, 0x26, 0xbc, 0x4e, 0x80, 0x9e, -+ 0x8f, 0xbe, 0xf1, 0x00, 0xb3, 0x78, 0xb9, 0x4b, 0x1d, 0xc7, 0xa4, 0x83, -+ 0x59, 0x56, 0x11, 0xd1, 0x11, 0x1e, 0x50, 0x39, 0xd5, 0x78, 0x14, 0xf3, -+ 0xb9, 0x1d, 0xda, 0xe4, 0xc4, 0x63, 0x74, 0x26, 0xab, 0xa3, 0xfd, 0x9d, -+ 0x58, 0xa2, 0xee, 0x7b, 0x28, 0x34, 0xa3, 0xbe, 0x85, 0x7e, 0xaa, 0x97, -+ 0xb7, 0x5b, 0x9d, 0xa9, 0x4d, 0x96, 0xdb, 0x6b, 0x21, 0xe1, 0x96, 0x5d, -+ 0xc7, 0xad, 0x23, 0x03, 0x9a, 0x16, 0xdb, 0xa4, 0x1f, 0x63, 0xef, 0xaf, -+ 0x1e, 0x4f, 0xf8, 0x27, 0xdc, 0x4b, 0xfc, 0x2b, 0x68, 0x2e, 0xa0, 0xd3, -+ 0xae, 0xf2, 0xce, 0xf5, 0xfc, 0x97, 0x92, 0xd2, 0x29, 0x0f, 0x4f, 0x4b, -+ 0x29, 0xeb, 0x06, 0xcb, 0xf8, 0x21, 0x6e, 0xbc, 0x8b, 0x5c, 0xc5, 0xc9, -+ 0xf7, 0xe2, 0x7c, 0x47, 0xcd, 0x43, 0x98, 0xc4, 0xa3, 0x9a, 0xd7, 0x3e, -+ 0xdc, 0x01, 0x13, 0x28, 0x96, 0xc4, 0x60, 0x83, 0xe2, 0x79, 0xa1, 0x46, -+ 0xef, 0xf5, 0xa4, 0x7b, 0x00, 0xe3, 0x3d, 0x7d, 0xbc, 0xa8, 0x98, 0x49, -+ 0xa8, 0xcf, 0x3b, 0x41, 0xb6, 0x09, 0x97, 0x07 ++ 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x4b, 0x65, 0x79, 0x30, 0x82, 0x02, 0x22, ++ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, ++ 0x01, 0x05, 0x00, 0x03, 0x82, 0x02, 0x0f, 0x00, 0x30, 0x82, 0x02, 0x0a, ++ 0x02, 0x82, 0x02, 0x01, 0x00, 0xb9, 0x09, 0xb2, 0xf6, 0x24, 0x34, 0xdc, ++ 0x62, 0xe6, 0x4e, 0xee, 0x04, 0xdb, 0x29, 0xdc, 0x94, 0xcc, 0xee, 0x8a, ++ 0x5b, 0xc3, 0x9e, 0x06, 0xba, 0xa7, 0x9b, 0xa4, 0x5f, 0x15, 0x59, 0x8e, ++ 0xb8, 0x6e, 0x3c, 0xeb, 0x2e, 0xf2, 0xac, 0x21, 0x42, 0xbd, 0x30, 0xa1, ++ 0x39, 0xe5, 0xb9, 0x4f, 0xa0, 0x53, 0xd5, 0x42, 0xdc, 0x8a, 0x87, 0x30, ++ 0x38, 0x93, 0x44, 0x80, 0x3b, 0x1a, 0x7e, 0x9e, 0x8e, 0x3e, 0xea, 0x45, ++ 0xa0, 0x11, 0x8b, 0xfb, 0x78, 0xe4, 0xbc, 0x65, 0x6b, 0x73, 0xea, 0x6e, ++ 0xdf, 0x7c, 0x5b, 0x63, 0x7e, 0x5b, 0x0a, 0x1c, 0xe6, 0x76, 0x19, 0xb5, ++ 0x01, 0xde, 0xf6, 0x65, 0x51, 0x30, 0x0a, 0x56, 0x69, 0x69, 0xe8, 0x20, ++ 0xf9, 0x13, 0xf1, 0xbf, 0x6f, 0xdd, 0xce, 0x94, 0x96, 0x6e, 0x63, 0xd6, ++ 0xfa, 0xa4, 0x91, 0x5f, 0xb3, 0x9c, 0xc7, 0xfa, 0xa9, 0xff, 0x66, 0x5f, ++ 0xf3, 0xab, 0x5e, 0xdf, 0x4e, 0xca, 0x11, 0xcf, 0xbf, 0xf8, 0xad, 0x65, ++ 0xb1, 0x49, 0x8b, 0xe9, 0x2a, 0xad, 0x7d, 0xf3, 0x0b, 0xfa, 0x5b, 0x6a, ++ 0x6a, 0x20, 0x12, 0x77, 0xef, 0x4b, 0xb6, 0xbe, 0x92, 0xba, 0x14, 0x9c, ++ 0x5e, 0xea, 0xdc, 0x56, 0x6d, 0x92, 0xd3, 0x64, 0x22, 0xf6, 0x12, 0xe8, ++ 0x7d, 0x5e, 0x9c, 0xd6, 0xf9, 0x75, 0x68, 0x7f, 0x8f, 0xd3, 0x6e, 0x05, ++ 0x94, 0x91, 0x4f, 0xa1, 0xd6, 0x50, 0x72, 0x3b, 0x11, 0x1f, 0x28, 0x13, ++ 0xe8, 0x25, 0x6b, 0xdf, 0xff, 0x72, 0x46, 0x25, 0xe9, 0x05, 0x6f, 0x02, ++ 0xc7, 0x1e, 0xc9, 0xcf, 0x99, 0xe9, 0xa7, 0xe2, 0xae, 0xbc, 0xc1, 0x22, ++ 0x32, 0x73, 0x2d, 0xa3, 0x70, 0x8f, 0xa7, 0x8d, 0xbf, 0x5f, 0x74, 0x05, ++ 0x1b, 0x5e, 0xfe, 0x97, 0x3c, 0xe7, 0x3b, 0x86, 0x0d, 0xf6, 0x38, 0xdb, ++ 0xd2, 0x39, 0x47, 0x82, 0x00, 0x44, 0x6c, 0x7b, 0x40, 0x24, 0x0b, 0x3a, ++ 0xd4, 0x19, 0x31, 0xba, 0x4e, 0x8e, 0xa3, 0x33, 0xa6, 0x78, 0xef, 0x72, ++ 0x9f, 0x06, 0x37, 0x01, 0x9b, 0x79, 0x0d, 0x04, 0xbf, 0xba, 0xd5, 0x1f, ++ 0x27, 0xdc, 0x85, 0xbb, 0xef, 0xd2, 0x60, 0xda, 0xa0, 0x3f, 0x66, 0xce, ++ 0x9f, 0xa2, 0x7e, 0xa8, 0x8d, 0xee, 0x14, 0x4b, 0xcb, 0x93, 0xf1, 0x38, ++ 0xac, 0x4f, 0xd8, 0x29, 0xf3, 0x6f, 0xd4, 0xfd, 0x4d, 0x34, 0x77, 0x58, ++ 0x99, 0xdb, 0x16, 0xc1, 0xd0, 0xc7, 0x43, 0x41, 0x70, 0xc4, 0xad, 0x01, ++ 0x29, 0x65, 0x22, 0x43, 0x00, 0x6f, 0xb3, 0x00, 0x27, 0x38, 0xc1, 0x4f, ++ 0xda, 0x28, 0x96, 0x42, 0xdc, 0xbc, 0x3e, 0x34, 0x8e, 0x14, 0xb8, 0xf3, ++ 0x86, 0x4a, 0xea, 0x16, 0x90, 0xf9, 0x0e, 0x9e, 0x8f, 0x66, 0x0c, 0xbf, ++ 0x29, 0xd3, 0x8f, 0xfc, 0x4d, 0x38, 0x68, 0xe2, 0xe7, 0x64, 0x32, 0x47, ++ 0xdd, 0x56, 0xc9, 0xe4, 0x47, 0x9f, 0x18, 0x89, 0xfc, 0x30, 0x7a, 0xae, ++ 0x63, 0xe4, 0xec, 0x93, 0x04, 0xd4, 0x61, 0xe7, 0xbf, 0x0a, 0x06, 0x29, ++ 0xc2, 0xa6, 0xd5, 0x53, 0x5d, 0x65, 0x6d, 0x4a, 0xd0, 0xb7, 0x68, 0x4d, ++ 0x46, 0x0a, 0xb5, 0xff, 0x52, 0x5e, 0x92, 0x7e, 0x75, 0x08, 0xa4, 0x63, ++ 0x0a, 0x6c, 0x31, 0x7a, 0xaa, 0x0c, 0x52, 0xf4, 0x2e, 0xcd, 0x08, 0xeb, ++ 0xb3, 0xbd, 0xad, 0x8b, 0x8b, 0x9b, 0x8d, 0x71, 0x42, 0x30, 0x8e, 0xc7, ++ 0xfd, 0xec, 0xb7, 0xe6, 0x26, 0x96, 0xf2, 0x74, 0x1b, 0x78, 0x95, 0x22, ++ 0x14, 0xf3, 0xc9, 0xd3, 0x79, 0x11, 0xd9, 0xb7, 0x4d, 0x0d, 0x61, 0x60, ++ 0x5c, 0x47, 0x50, 0xf3, 0xca, 0x84, 0x4c, 0x5c, 0x30, 0x2c, 0x6a, 0x18, ++ 0x26, 0xb0, 0xf3, 0xd1, 0x15, 0x19, 0x39, 0xc3, 0x23, 0x13, 0x0f, 0x9c, ++ 0x97, 0x2b, 0x97, 0x93, 0xf9, 0xf8, 0x18, 0x9b, 0x4a, 0x4d, 0xd6, 0xd3, ++ 0xf5, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x5d, 0x30, 0x5b, 0x30, 0x0c, ++ 0x06, 0x03, 0x55, 0x1d, 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, ++ 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x07, ++ 0x80, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, ++ 0x8f, 0xba, 0x8b, 0xf5, 0xf4, 0x77, 0xb2, 0xa4, 0x19, 0xef, 0x43, 0xb1, ++ 0x8b, 0x03, 0x4b, 0x45, 0x47, 0xb5, 0x2a, 0x48, 0x30, 0x1f, 0x06, 0x03, ++ 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x59, 0x1c, 0xb5, ++ 0x52, 0x62, 0x83, 0x05, 0x3b, 0x41, 0x4c, 0x63, 0x4d, 0x5b, 0xf4, 0x8c, ++ 0xe6, 0xd7, 0xda, 0x87, 0x54, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, ++ 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x02, 0x01, ++ 0x00, 0x36, 0x2d, 0x0a, 0xcb, 0x49, 0x54, 0x75, 0xd7, 0xca, 0x21, 0x86, ++ 0xae, 0x40, 0x0f, 0x63, 0x10, 0x35, 0xfd, 0xbc, 0xba, 0x28, 0x31, 0x33, ++ 0x07, 0x08, 0x64, 0x03, 0x6c, 0xd3, 0xd5, 0xf7, 0xb7, 0x79, 0x11, 0x0c, ++ 0xa8, 0x9e, 0xfd, 0x34, 0xa2, 0xba, 0x77, 0x15, 0x15, 0x2d, 0x2c, 0x96, ++ 0xae, 0x47, 0xbb, 0x82, 0x89, 0x09, 0x7f, 0xd1, 0x95, 0x69, 0x9b, 0xfe, ++ 0xd7, 0x6f, 0x4e, 0x68, 0xf6, 0xe7, 0x5f, 0x54, 0xa1, 0x3a, 0xeb, 0xa4, ++ 0xbf, 0x7a, 0xb6, 0x7f, 0xaa, 0xd8, 0xd7, 0x99, 0xcb, 0xae, 0x88, 0x6d, ++ 0x7a, 0xf3, 0xfa, 0x9e, 0x44, 0x2f, 0x30, 0xa8, 0xe6, 0xb9, 0x75, 0xa0, ++ 0x82, 0xd6, 0xb0, 0xe3, 0x03, 0xb3, 0x12, 0xa3, 0xdc, 0xb9, 0x4d, 0x93, ++ 0xd4, 0x30, 0xea, 0xce, 0x96, 0x92, 0x07, 0xf8, 0xba, 0xe4, 0x0f, 0x41, ++ 0xe3, 0x04, 0xaa, 0x8c, 0x07, 0x1a, 0x34, 0x60, 0xfc, 0xc0, 0x05, 0xd2, ++ 0x5a, 0xa8, 0x66, 0xef, 0xe0, 0x94, 0xc5, 0x2f, 0x0f, 0xff, 0xdc, 0x70, ++ 0xfb, 0xe2, 0x9d, 0x61, 0x51, 0x25, 0x02, 0xff, 0x4b, 0x69, 0xfd, 0x66, ++ 0xb9, 0xeb, 0x0c, 0xc8, 0x50, 0xd3, 0xb1, 0x08, 0x1e, 0x09, 0x54, 0x87, ++ 0xe8, 0xa3, 0x4b, 0xef, 0x0c, 0x32, 0x0a, 0x6c, 0xec, 0x27, 0x22, 0xba, ++ 0x7f, 0xdc, 0x52, 0x27, 0x31, 0x14, 0x9a, 0xa8, 0xf7, 0xf9, 0xeb, 0xc8, ++ 0xb5, 0x8d, 0x12, 0xed, 0x94, 0xab, 0x3d, 0x9a, 0xfb, 0x4e, 0x04, 0x05, ++ 0xd2, 0x3c, 0x7c, 0x8a, 0xed, 0x46, 0x1b, 0x7c, 0xb5, 0x6c, 0x40, 0xb8, ++ 0xc1, 0xbf, 0xb0, 0xd2, 0x93, 0x8e, 0xa8, 0x0f, 0xde, 0x78, 0xf3, 0x8c, ++ 0xd8, 0x9f, 0xf8, 0xdc, 0xa1, 0x23, 0x20, 0x40, 0x17, 0xb4, 0xdb, 0xb7, ++ 0x09, 0x74, 0xa7, 0x80, 0xc2, 0x12, 0xd9, 0x76, 0x79, 0x5b, 0x71, 0xa9, ++ 0x6c, 0xd4, 0x57, 0x48, 0xe8, 0xfe, 0xc5, 0xc2, 0x6e, 0xe7, 0x83, 0x5a, ++ 0x07, 0xf0, 0x33, 0xc1, 0xc1, 0x1d, 0x34, 0xd4, 0xc8, 0xb0, 0xb7, 0xdb, ++ 0xeb, 0xe9, 0xe3, 0x59, 0xdc, 0x7f, 0x36, 0x58, 0xa9, 0xb8, 0x52, 0xdd, ++ 0xf9, 0xfd, 0x1c, 0x22, 0x2f, 0x93, 0x3d, 0x53, 0x89, 0x80, 0xde, 0xa2, ++ 0xb5, 0xa5, 0x36, 0xbd, 0xc3, 0x92, 0x03, 0xf3, 0x93, 0xc8, 0xc7, 0x4a, ++ 0x0b, 0x8b, 0x62, 0xfe, 0xd0, 0xf8, 0x0d, 0x7a, 0x32, 0xb4, 0x39, 0x1a, ++ 0xb7, 0x4e, 0xaa, 0xc4, 0x33, 0x32, 0x90, 0x8c, 0xab, 0xd4, 0xae, 0xa5, ++ 0xa4, 0x85, 0xcf, 0xba, 0xe1, 0x1b, 0x26, 0x7f, 0x74, 0x02, 0x12, 0x09, ++ 0x89, 0x56, 0xe4, 0xe7, 0x9d, 0x91, 0xde, 0x88, 0xe7, 0x1c, 0xed, 0x80, ++ 0x05, 0xa8, 0x58, 0x9a, 0x3e, 0x16, 0x97, 0xd5, 0xbc, 0x54, 0xcc, 0xf0, ++ 0x32, 0xf2, 0x93, 0x09, 0x94, 0x9f, 0x3c, 0xd9, 0x58, 0xca, 0x68, 0x0b, ++ 0xde, 0x3f, 0x73, 0x64, 0xb7, 0xf4, 0xd7, 0x5f, 0x2b, 0xe7, 0x7b, 0x06, ++ 0xca, 0xb1, 0x3e, 0xed, 0xd2, 0xb9, 0x29, 0xc1, 0x95, 0x87, 0xad, 0xd6, ++ 0x63, 0x69, 0xb8, 0x1f, 0x70, 0xdb, 0xeb, 0xc7, 0x11, 0x7d, 0xe2, 0x99, ++ 0x64, 0x6a, 0xf5, 0x3f, 0x30, 0x74, 0x5f, 0x2a, 0x21, 0xda, 0xef, 0x44, ++ 0x1d, 0xad, 0x97, 0xa1, 0xfe, 0x14, 0xa7, 0x88, 0x99, 0xd0, 0x1e, 0xb0, ++ 0x61, 0x88, 0x09, 0xc9, 0xfa, 0xd1, 0xb3, 0xcb, 0x1d, 0x76, 0x04, 0xbe, ++ 0x06, 0x44, 0xd2, 0x30, 0x5e, 0x95, 0x4b, 0x96, 0xc0, 0xd6, 0xbe, 0xd0, ++ 0x4d, 0xf2, 0xf4, 0x71, 0x72, 0xa9, 0xbd, 0x07, 0x4f, 0xbc, 0xb3, 0x78, ++ 0xb4, 0x8a, 0x44, 0xbd, 0x58, 0xd5, 0x21, 0xb6, 0x47, 0x9c, 0x88, 0x1f, ++ 0xbc, 0xbd, 0x54, 0xfa, 0x1d, 0x49, 0xec, 0x51, 0xd9, 0x43, 0x49, 0x9c, ++ 0x0c, 0xfa, 0x18, 0xdb, 0xeb, 0x05, 0x77, 0xa2, 0x9a +}; -+unsigned int certificate_der_len = 908; ++unsigned int certificate_der_len = 1377; + +unsigned char hi_signed[] = { -+ 0x68, 0x69, 0x0a, 0x30, 0x82, 0x01, 0xc0, 0x06, 0x09, 0x2a, 0x86, 0x48, -+ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x01, 0xb1, 0x30, 0x82, -+ 0x01, 0xad, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, ++ 0x68, 0x69, 0x0a, 0x30, 0x82, 0x02, 0xb4, 0x06, 0x09, 0x2a, 0x86, 0x48, ++ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0xa5, 0x30, 0x82, ++ 0x02, 0xa1, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x01, -+ 0x8a, 0x30, 0x82, 0x01, 0x86, 0x02, 0x01, 0x01, 0x30, 0x61, 0x30, 0x49, -+ 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1f, 0x47, ++ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x02, ++ 0x7e, 0x30, 0x82, 0x02, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x55, 0x30, 0x3d, ++ 0x31, 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x32, 0x47, + 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64, + 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54, -+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0e, 0x64, -+ 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x2e, 0x6e, 0x65, -+ 0x74, 0x02, 0x14, 0x25, 0x2e, 0xb8, 0xfd, 0x12, 0x62, 0x2e, 0xcd, 0x5d, -+ 0xa7, 0x53, 0xd2, 0x0b, 0xc2, 0x61, 0x7c, 0x14, 0xe0, 0x0f, 0x5c, 0x30, ++ 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, ++ 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, ++ 0x79, 0x02, 0x14, 0x5b, 0x5e, 0x59, 0xf2, 0x5f, 0x75, 0x4c, 0x8e, 0xc5, ++ 0x3a, 0x91, 0x07, 0xe9, 0xe7, 0x6d, 0x3c, 0xd0, 0x7f, 0x92, 0x03, 0x30, + 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, -+ 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xc7, 0x69, 0x35, 0x21, 0x66, -+ 0x4d, 0x50, 0xd4, 0x73, 0xde, 0xbd, 0x3a, 0xf6, 0x45, 0xe3, 0xe4, 0xd0, -+ 0xb6, 0xa1, 0xe7, 0xc0, 0xa2, 0xc9, 0xf4, 0xf0, 0x05, 0x8c, 0xa4, 0x16, -+ 0x9e, 0x81, 0x0d, 0x21, 0x68, 0xf3, 0xfe, 0x03, 0x96, 0x77, 0x31, 0x69, -+ 0x01, 0xd8, 0x26, 0xd9, 0x48, 0x95, 0xcf, 0xd1, 0x17, 0xb1, 0x0b, 0x6b, -+ 0x2c, 0xf1, 0xb0, 0xab, 0x65, 0x65, 0x56, 0xf8, 0x0c, 0xa7, 0xf7, 0xbb, -+ 0xf6, 0x5a, 0x55, 0x98, 0x14, 0x07, 0x8d, 0x2a, 0xbc, 0x16, 0x48, 0x94, -+ 0xab, 0x2f, 0x85, 0x97, 0x90, 0x51, 0x78, 0xa0, 0xda, 0x60, 0xb5, 0x41, -+ 0x4b, 0xe8, 0x78, 0xc5, 0xa6, 0x04, 0x9d, 0x54, 0x2a, 0x85, 0xfd, 0x86, -+ 0x0b, 0x6d, 0xc2, 0xd2, 0xad, 0x07, 0xff, 0x16, 0x42, 0x82, 0xe3, 0x5c, -+ 0xaa, 0x22, 0x59, 0x78, 0x92, 0xea, 0x94, 0xc3, 0x41, 0xb7, 0xa1, 0x86, -+ 0x44, 0xea, 0xd1, 0xdb, 0xe5, 0xac, 0x30, 0x32, 0xfb, 0x7d, 0x3f, 0xf7, -+ 0x8b, 0x11, 0x7f, 0x80, 0x3b, 0xe5, 0xc7, 0x82, 0x0f, 0x92, 0x07, 0x14, -+ 0x66, 0x01, 0x6e, 0x85, 0xab, 0x3a, 0x14, 0xcf, 0x76, 0xd1, 0x7e, 0x14, -+ 0x85, 0xca, 0x01, 0x73, 0x72, 0x38, 0xdc, 0xde, 0x30, 0x5c, 0xfb, 0xc0, -+ 0x3d, 0x93, 0xef, 0x9c, 0xbc, 0xf8, 0xcc, 0xd2, 0xbf, 0x47, 0xec, 0xf8, -+ 0x88, 0x9b, 0xe1, 0x43, 0xbe, 0xa7, 0x47, 0x96, 0xb6, 0x5d, 0x46, 0x0e, -+ 0x7a, 0x78, 0x38, 0x19, 0xbc, 0xb5, 0xbc, 0x9b, 0x3c, 0x39, 0x92, 0x70, -+ 0x0d, 0x9d, 0x8a, 0x35, 0xaf, 0xb4, 0x9e, 0xf4, 0xef, 0xc1, 0xb8, 0x25, -+ 0xd0, 0x14, 0x91, 0xd6, 0xc2, 0xb6, 0xc7, 0x3c, 0x72, 0x91, 0x0f, 0xad, -+ 0xde, 0xb2, 0x36, 0xf8, 0x4e, 0x59, 0xd4, 0xa4, 0x21, 0x9f, 0x03, 0x95, -+ 0x48, 0x01, 0xb4, 0x05, 0xc3, 0x39, 0x60, 0x51, 0x08, 0xd0, 0xbe, 0x00, -+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc4, 0x7e, -+ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, -+ 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, -+ 0x64, 0x7e, 0x0a ++ 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0xa0, 0x83, 0x3f, 0xac, 0x77, ++ 0x97, 0x74, 0x9b, 0x4b, 0x25, 0xa1, 0x64, 0x09, 0x8d, 0x53, 0xa6, 0x03, ++ 0xdf, 0x9a, 0x10, 0x52, 0xe5, 0x3f, 0xd4, 0x72, 0x75, 0x30, 0xd4, 0x6e, ++ 0x77, 0x32, 0x49, 0x84, 0xe2, 0xbe, 0xef, 0xe4, 0xf3, 0xac, 0xb0, 0x52, ++ 0x55, 0xbf, 0xa9, 0x57, 0x12, 0x08, 0x7d, 0xb0, 0x86, 0xc0, 0x9d, 0x01, ++ 0xc2, 0x1a, 0x4a, 0x2e, 0x3d, 0xd5, 0xc8, 0x56, 0xac, 0xd1, 0x83, 0x75, ++ 0x88, 0xd4, 0xcc, 0x9f, 0x0d, 0xcf, 0xd3, 0xa6, 0x91, 0xb6, 0xb6, 0xb1, ++ 0xd1, 0x24, 0x9c, 0xd0, 0x13, 0xe8, 0x6b, 0x15, 0x9c, 0x62, 0x33, 0x8d, ++ 0xe3, 0x67, 0x9b, 0xb1, 0x8a, 0x72, 0x38, 0xf7, 0x48, 0x32, 0x2f, 0x1e, ++ 0x45, 0xa8, 0xc4, 0xa5, 0xae, 0xb1, 0xfc, 0x35, 0x25, 0xb5, 0xf9, 0x7f, ++ 0x86, 0xef, 0xa2, 0x6d, 0x78, 0xcc, 0xfd, 0x0c, 0xca, 0x8a, 0xe1, 0xae, ++ 0xcd, 0x0f, 0x58, 0x69, 0xf1, 0x8b, 0xcc, 0x22, 0x35, 0x6d, 0x1f, 0xd5, ++ 0x27, 0x87, 0x39, 0x62, 0x3f, 0xb2, 0x17, 0x3d, 0x5e, 0xb1, 0x32, 0x7a, ++ 0xf1, 0x70, 0xce, 0xfa, 0xab, 0x1c, 0x92, 0xa8, 0xe1, 0xc4, 0xb2, 0x33, ++ 0x1a, 0x16, 0xf3, 0x60, 0x39, 0xdf, 0xb8, 0x85, 0xe7, 0x5d, 0x4d, 0xc2, ++ 0x8d, 0x55, 0x00, 0x49, 0x94, 0x04, 0x17, 0x88, 0x7c, 0xf4, 0xac, 0xa9, ++ 0xc5, 0x3a, 0x09, 0xc4, 0xc2, 0xcd, 0x3d, 0xc3, 0xfc, 0x4e, 0xf3, 0x70, ++ 0xa1, 0xc1, 0x54, 0x36, 0x1f, 0x38, 0x6d, 0x7a, 0x6b, 0x6a, 0xd3, 0x67, ++ 0x04, 0xd5, 0x53, 0xd4, 0xa5, 0xad, 0x63, 0x55, 0x0e, 0x06, 0x06, 0x3a, ++ 0x9a, 0xc5, 0xfe, 0x38, 0xc9, 0xb0, 0x69, 0x42, 0x90, 0x35, 0x1f, 0xe3, ++ 0x1c, 0x57, 0xea, 0xdb, 0x51, 0x35, 0x53, 0xd3, 0x94, 0xfe, 0x72, 0x33, ++ 0xd6, 0x8a, 0x46, 0x74, 0xf9, 0x6e, 0x94, 0x40, 0x2f, 0xba, 0xa2, 0xc4, ++ 0xe9, 0xc9, 0x8a, 0xf4, 0xda, 0xe2, 0xca, 0x3e, 0x98, 0x85, 0xa5, 0xd1, ++ 0x60, 0x94, 0xc8, 0xdf, 0x82, 0xee, 0x5c, 0x0d, 0x2a, 0xa9, 0x8e, 0x26, ++ 0x83, 0x3f, 0x02, 0xa2, 0xaf, 0xb8, 0x3b, 0x83, 0xf2, 0x44, 0x46, 0x41, ++ 0xd7, 0x5c, 0xa1, 0x42, 0x17, 0xa2, 0xd0, 0x50, 0x42, 0xef, 0x66, 0xda, ++ 0x35, 0x03, 0xd1, 0x8e, 0x77, 0x22, 0x7d, 0x4e, 0xf7, 0x4e, 0x04, 0xe3, ++ 0x0f, 0x98, 0x7d, 0xaa, 0x58, 0xba, 0xef, 0x9a, 0xd0, 0x88, 0x7c, 0x98, ++ 0xa0, 0xc2, 0xff, 0xa6, 0xb1, 0xec, 0xbe, 0x6e, 0xb0, 0x7e, 0xc6, 0xe5, ++ 0xaa, 0xcf, 0x10, 0x73, 0xc9, 0x13, 0x1a, 0x20, 0x12, 0x5c, 0xd2, 0x0e, ++ 0xe2, 0x60, 0x17, 0xdf, 0x4a, 0x44, 0x08, 0x22, 0xbc, 0xcd, 0x75, 0xbe, ++ 0xc3, 0x7a, 0x12, 0x90, 0x90, 0xc7, 0x94, 0x4c, 0x98, 0x45, 0x02, 0x5c, ++ 0x24, 0xae, 0x82, 0x2f, 0xcd, 0x30, 0xa6, 0xf5, 0x3f, 0xd3, 0xa7, 0xa6, ++ 0xe6, 0xea, 0x11, 0x4e, 0x45, 0xb7, 0xc0, 0xe6, 0x24, 0x8b, 0x76, 0xc5, ++ 0x5e, 0xc1, 0xd8, 0x07, 0x1e, 0x26, 0x94, 0x7a, 0x80, 0xc6, 0x3b, 0x1f, ++ 0x74, 0xe6, 0xae, 0x43, 0x2d, 0x11, 0xee, 0x96, 0x56, 0x6c, 0xff, 0xcb, ++ 0x3b, 0xde, 0xcc, 0xb3, 0x7b, 0x08, 0xf5, 0x3e, 0x6e, 0x51, 0x71, 0xe0, ++ 0x8a, 0xfa, 0xdd, 0x19, 0x39, 0xcf, 0x3f, 0x29, 0x4f, 0x2d, 0xd2, 0xd4, ++ 0xdc, 0x5c, 0xc4, 0xd1, 0xa7, 0xf5, 0xbf, 0x4a, 0xc0, 0x9b, 0xb4, 0x2b, ++ 0x83, 0x7a, 0x63, 0x4d, 0x20, 0x40, 0x8b, 0x11, 0x5c, 0x53, 0xd4, 0x52, ++ 0x21, 0xe7, 0xe4, 0x1f, 0x01, 0xf6, 0xd1, 0x25, 0x28, 0xba, 0x51, 0x6f, ++ 0x51, 0x69, 0xf4, 0x41, 0x45, 0x75, 0x23, 0x25, 0x77, 0xef, 0xa8, 0x1c, ++ 0x19, 0x8a, 0x66, 0x8c, 0x61, 0x13, 0x37, 0x4f, 0xa3, 0xa1, 0x83, 0x17, ++ 0x35, 0x23, 0x2d, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x02, 0xb8, 0x7e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, ++ 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, ++ 0x65, 0x6e, 0x64, 0x65, 0x64, 0x7e, 0x0a +}; -+unsigned int hi_signed_len = 495; ++unsigned int hi_signed_len = 739; + +unsigned char hj_signed[] = { -+ 0x68, 0x6a, 0x0a, 0x30, 0x82, 0x01, 0xc0, 0x06, 0x09, 0x2a, 0x86, 0x48, -+ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x01, 0xb1, 0x30, 0x82, -+ 0x01, 0xad, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, ++ 0x68, 0x6a, 0x0a, 0x30, 0x82, 0x02, 0xb4, 0x06, 0x09, 0x2a, 0x86, 0x48, ++ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0xa5, 0x30, 0x82, ++ 0x02, 0xa1, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x01, -+ 0x8a, 0x30, 0x82, 0x01, 0x86, 0x02, 0x01, 0x01, 0x30, 0x61, 0x30, 0x49, -+ 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1f, 0x47, ++ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x02, ++ 0x7e, 0x30, 0x82, 0x02, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x55, 0x30, 0x3d, ++ 0x31, 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x32, 0x47, + 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64, + 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54, -+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0e, 0x64, -+ 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x2e, 0x6e, 0x65, -+ 0x74, 0x02, 0x14, 0x25, 0x2e, 0xb8, 0xfd, 0x12, 0x62, 0x2e, 0xcd, 0x5d, -+ 0xa7, 0x53, 0xd2, 0x0b, 0xc2, 0x61, 0x7c, 0x14, 0xe0, 0x0f, 0x5c, 0x30, ++ 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, ++ 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, ++ 0x79, 0x02, 0x14, 0x5b, 0x5e, 0x59, 0xf2, 0x5f, 0x75, 0x4c, 0x8e, 0xc5, ++ 0x3a, 0x91, 0x07, 0xe9, 0xe7, 0x6d, 0x3c, 0xd0, 0x7f, 0x92, 0x03, 0x30, + 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, -+ 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0xc7, 0x69, 0x35, 0x21, 0x66, -+ 0x4d, 0x50, 0xd4, 0x73, 0xde, 0xbd, 0x3a, 0xf6, 0x45, 0xe3, 0xe4, 0xd0, -+ 0xb6, 0xa1, 0xe7, 0xc0, 0xa2, 0xc9, 0xf4, 0xf0, 0x05, 0x8c, 0xa4, 0x16, -+ 0x9e, 0x81, 0x0d, 0x21, 0x68, 0xf3, 0xfe, 0x03, 0x96, 0x77, 0x31, 0x69, -+ 0x01, 0xd8, 0x26, 0xd9, 0x48, 0x95, 0xcf, 0xd1, 0x17, 0xb1, 0x0b, 0x6b, -+ 0x2c, 0xf1, 0xb0, 0xab, 0x65, 0x65, 0x56, 0xf8, 0x0c, 0xa7, 0xf7, 0xbb, -+ 0xf6, 0x5a, 0x55, 0x98, 0x14, 0x07, 0x8d, 0x2a, 0xbc, 0x16, 0x48, 0x94, -+ 0xab, 0x2f, 0x85, 0x97, 0x90, 0x51, 0x78, 0xa0, 0xda, 0x60, 0xb5, 0x41, -+ 0x4b, 0xe8, 0x78, 0xc5, 0xa6, 0x04, 0x9d, 0x54, 0x2a, 0x85, 0xfd, 0x86, -+ 0x0b, 0x6d, 0xc2, 0xd2, 0xad, 0x07, 0xff, 0x16, 0x42, 0x82, 0xe3, 0x5c, -+ 0xaa, 0x22, 0x59, 0x78, 0x92, 0xea, 0x94, 0xc3, 0x41, 0xb7, 0xa1, 0x86, -+ 0x44, 0xea, 0xd1, 0xdb, 0xe5, 0xac, 0x30, 0x32, 0xfb, 0x7d, 0x3f, 0xf7, -+ 0x8b, 0x11, 0x7f, 0x80, 0x3b, 0xe5, 0xc7, 0x82, 0x0f, 0x92, 0x07, 0x14, -+ 0x66, 0x01, 0x6e, 0x85, 0xab, 0x3a, 0x14, 0xcf, 0x76, 0xd1, 0x7e, 0x14, -+ 0x85, 0xca, 0x01, 0x73, 0x72, 0x38, 0xdc, 0xde, 0x30, 0x5c, 0xfb, 0xc0, -+ 0x3d, 0x93, 0xef, 0x9c, 0xbc, 0xf8, 0xcc, 0xd2, 0xbf, 0x47, 0xec, 0xf8, -+ 0x88, 0x9b, 0xe1, 0x43, 0xbe, 0xa7, 0x47, 0x96, 0xb6, 0x5d, 0x46, 0x0e, -+ 0x7a, 0x78, 0x38, 0x19, 0xbc, 0xb5, 0xbc, 0x9b, 0x3c, 0x39, 0x92, 0x70, -+ 0x0d, 0x9d, 0x8a, 0x35, 0xaf, 0xb4, 0x9e, 0xf4, 0xef, 0xc1, 0xb8, 0x25, -+ 0xd0, 0x14, 0x91, 0xd6, 0xc2, 0xb6, 0xc7, 0x3c, 0x72, 0x91, 0x0f, 0xad, -+ 0xde, 0xb2, 0x36, 0xf8, 0x4e, 0x59, 0xd4, 0xa4, 0x21, 0x9f, 0x03, 0x95, -+ 0x48, 0x01, 0xb4, 0x05, 0xc3, 0x39, 0x60, 0x51, 0x08, 0xd0, 0xbe, 0x00, -+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc4, 0x7e, -+ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, -+ 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, -+ 0x64, 0x7e, 0x0a ++ 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0xa0, 0x83, 0x3f, 0xac, 0x77, ++ 0x97, 0x74, 0x9b, 0x4b, 0x25, 0xa1, 0x64, 0x09, 0x8d, 0x53, 0xa6, 0x03, ++ 0xdf, 0x9a, 0x10, 0x52, 0xe5, 0x3f, 0xd4, 0x72, 0x75, 0x30, 0xd4, 0x6e, ++ 0x77, 0x32, 0x49, 0x84, 0xe2, 0xbe, 0xef, 0xe4, 0xf3, 0xac, 0xb0, 0x52, ++ 0x55, 0xbf, 0xa9, 0x57, 0x12, 0x08, 0x7d, 0xb0, 0x86, 0xc0, 0x9d, 0x01, ++ 0xc2, 0x1a, 0x4a, 0x2e, 0x3d, 0xd5, 0xc8, 0x56, 0xac, 0xd1, 0x83, 0x75, ++ 0x88, 0xd4, 0xcc, 0x9f, 0x0d, 0xcf, 0xd3, 0xa6, 0x91, 0xb6, 0xb6, 0xb1, ++ 0xd1, 0x24, 0x9c, 0xd0, 0x13, 0xe8, 0x6b, 0x15, 0x9c, 0x62, 0x33, 0x8d, ++ 0xe3, 0x67, 0x9b, 0xb1, 0x8a, 0x72, 0x38, 0xf7, 0x48, 0x32, 0x2f, 0x1e, ++ 0x45, 0xa8, 0xc4, 0xa5, 0xae, 0xb1, 0xfc, 0x35, 0x25, 0xb5, 0xf9, 0x7f, ++ 0x86, 0xef, 0xa2, 0x6d, 0x78, 0xcc, 0xfd, 0x0c, 0xca, 0x8a, 0xe1, 0xae, ++ 0xcd, 0x0f, 0x58, 0x69, 0xf1, 0x8b, 0xcc, 0x22, 0x35, 0x6d, 0x1f, 0xd5, ++ 0x27, 0x87, 0x39, 0x62, 0x3f, 0xb2, 0x17, 0x3d, 0x5e, 0xb1, 0x32, 0x7a, ++ 0xf1, 0x70, 0xce, 0xfa, 0xab, 0x1c, 0x92, 0xa8, 0xe1, 0xc4, 0xb2, 0x33, ++ 0x1a, 0x16, 0xf3, 0x60, 0x39, 0xdf, 0xb8, 0x85, 0xe7, 0x5d, 0x4d, 0xc2, ++ 0x8d, 0x55, 0x00, 0x49, 0x94, 0x04, 0x17, 0x88, 0x7c, 0xf4, 0xac, 0xa9, ++ 0xc5, 0x3a, 0x09, 0xc4, 0xc2, 0xcd, 0x3d, 0xc3, 0xfc, 0x4e, 0xf3, 0x70, ++ 0xa1, 0xc1, 0x54, 0x36, 0x1f, 0x38, 0x6d, 0x7a, 0x6b, 0x6a, 0xd3, 0x67, ++ 0x04, 0xd5, 0x53, 0xd4, 0xa5, 0xad, 0x63, 0x55, 0x0e, 0x06, 0x06, 0x3a, ++ 0x9a, 0xc5, 0xfe, 0x38, 0xc9, 0xb0, 0x69, 0x42, 0x90, 0x35, 0x1f, 0xe3, ++ 0x1c, 0x57, 0xea, 0xdb, 0x51, 0x35, 0x53, 0xd3, 0x94, 0xfe, 0x72, 0x33, ++ 0xd6, 0x8a, 0x46, 0x74, 0xf9, 0x6e, 0x94, 0x40, 0x2f, 0xba, 0xa2, 0xc4, ++ 0xe9, 0xc9, 0x8a, 0xf4, 0xda, 0xe2, 0xca, 0x3e, 0x98, 0x85, 0xa5, 0xd1, ++ 0x60, 0x94, 0xc8, 0xdf, 0x82, 0xee, 0x5c, 0x0d, 0x2a, 0xa9, 0x8e, 0x26, ++ 0x83, 0x3f, 0x02, 0xa2, 0xaf, 0xb8, 0x3b, 0x83, 0xf2, 0x44, 0x46, 0x41, ++ 0xd7, 0x5c, 0xa1, 0x42, 0x17, 0xa2, 0xd0, 0x50, 0x42, 0xef, 0x66, 0xda, ++ 0x35, 0x03, 0xd1, 0x8e, 0x77, 0x22, 0x7d, 0x4e, 0xf7, 0x4e, 0x04, 0xe3, ++ 0x0f, 0x98, 0x7d, 0xaa, 0x58, 0xba, 0xef, 0x9a, 0xd0, 0x88, 0x7c, 0x98, ++ 0xa0, 0xc2, 0xff, 0xa6, 0xb1, 0xec, 0xbe, 0x6e, 0xb0, 0x7e, 0xc6, 0xe5, ++ 0xaa, 0xcf, 0x10, 0x73, 0xc9, 0x13, 0x1a, 0x20, 0x12, 0x5c, 0xd2, 0x0e, ++ 0xe2, 0x60, 0x17, 0xdf, 0x4a, 0x44, 0x08, 0x22, 0xbc, 0xcd, 0x75, 0xbe, ++ 0xc3, 0x7a, 0x12, 0x90, 0x90, 0xc7, 0x94, 0x4c, 0x98, 0x45, 0x02, 0x5c, ++ 0x24, 0xae, 0x82, 0x2f, 0xcd, 0x30, 0xa6, 0xf5, 0x3f, 0xd3, 0xa7, 0xa6, ++ 0xe6, 0xea, 0x11, 0x4e, 0x45, 0xb7, 0xc0, 0xe6, 0x24, 0x8b, 0x76, 0xc5, ++ 0x5e, 0xc1, 0xd8, 0x07, 0x1e, 0x26, 0x94, 0x7a, 0x80, 0xc6, 0x3b, 0x1f, ++ 0x74, 0xe6, 0xae, 0x43, 0x2d, 0x11, 0xee, 0x96, 0x56, 0x6c, 0xff, 0xcb, ++ 0x3b, 0xde, 0xcc, 0xb3, 0x7b, 0x08, 0xf5, 0x3e, 0x6e, 0x51, 0x71, 0xe0, ++ 0x8a, 0xfa, 0xdd, 0x19, 0x39, 0xcf, 0x3f, 0x29, 0x4f, 0x2d, 0xd2, 0xd4, ++ 0xdc, 0x5c, 0xc4, 0xd1, 0xa7, 0xf5, 0xbf, 0x4a, 0xc0, 0x9b, 0xb4, 0x2b, ++ 0x83, 0x7a, 0x63, 0x4d, 0x20, 0x40, 0x8b, 0x11, 0x5c, 0x53, 0xd4, 0x52, ++ 0x21, 0xe7, 0xe4, 0x1f, 0x01, 0xf6, 0xd1, 0x25, 0x28, 0xba, 0x51, 0x6f, ++ 0x51, 0x69, 0xf4, 0x41, 0x45, 0x75, 0x23, 0x25, 0x77, 0xef, 0xa8, 0x1c, ++ 0x19, 0x8a, 0x66, 0x8c, 0x61, 0x13, 0x37, 0x4f, 0xa3, 0xa1, 0x83, 0x17, ++ 0x35, 0x23, 0x2d, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x02, 0xb8, 0x7e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, ++ 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, ++ 0x65, 0x6e, 0x64, 0x65, 0x64, 0x7e, 0x0a +}; -+unsigned int hj_signed_len = 495; ++unsigned int hj_signed_len = 739; + +unsigned char hi_signed_sha256[] = { -+ 0x68, 0x69, 0x0a, 0x30, 0x82, 0x01, 0xc0, 0x06, 0x09, 0x2a, 0x86, 0x48, -+ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x01, 0xb1, 0x30, 0x82, -+ 0x01, 0xad, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, ++ 0x68, 0x69, 0x0a, 0x30, 0x82, 0x02, 0xb4, 0x06, 0x09, 0x2a, 0x86, 0x48, ++ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0xa5, 0x30, 0x82, ++ 0x02, 0xa1, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, + 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x0b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x01, -+ 0x8a, 0x30, 0x82, 0x01, 0x86, 0x02, 0x01, 0x01, 0x30, 0x61, 0x30, 0x49, -+ 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1f, 0x47, ++ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x02, ++ 0x7e, 0x30, 0x82, 0x02, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x55, 0x30, 0x3d, ++ 0x31, 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x32, 0x47, + 0x72, 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64, + 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54, -+ 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x31, 0x1d, 0x30, 0x1b, 0x06, 0x09, -+ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x0e, 0x64, -+ 0x6a, 0x61, 0x40, 0x61, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x2e, 0x6e, 0x65, -+ 0x74, 0x02, 0x14, 0x25, 0x2e, 0xb8, 0xfd, 0x12, 0x62, 0x2e, 0xcd, 0x5d, -+ 0xa7, 0x53, 0xd2, 0x0b, 0xc2, 0x61, 0x7c, 0x14, 0xe0, 0x0f, 0x5c, 0x30, ++ 0x65, 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, ++ 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, ++ 0x79, 0x02, 0x14, 0x5b, 0x5e, 0x59, 0xf2, 0x5f, 0x75, 0x4c, 0x8e, 0xc5, ++ 0x3a, 0x91, 0x07, 0xe9, 0xe7, 0x6d, 0x3c, 0xd0, 0x7f, 0x92, 0x03, 0x30, + 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, + 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, -+ 0x01, 0x05, 0x00, 0x04, 0x82, 0x01, 0x00, 0x7b, 0x5e, 0x82, 0x1d, 0x21, -+ 0xb6, 0x40, 0xd3, 0x33, 0x79, 0xa7, 0x52, 0x2b, 0xfc, 0x46, 0x51, 0x26, -+ 0xfe, 0x0f, 0x81, 0x90, 0x81, 0xab, 0x57, 0x5e, 0xf6, 0x45, 0x41, 0xa3, -+ 0x7b, 0x48, 0xdd, 0xd6, 0x59, 0x60, 0x51, 0x31, 0x14, 0x14, 0x7b, 0xb4, -+ 0x55, 0x7b, 0x4d, 0xfe, 0x09, 0x7a, 0x5d, 0xae, 0xc4, 0x58, 0x50, 0x80, -+ 0x75, 0xf2, 0x23, 0x20, 0x62, 0xe3, 0x7c, 0x26, 0x1d, 0x2a, 0x4d, 0x9f, -+ 0x89, 0xf0, 0x4f, 0x95, 0x8a, 0x80, 0x6e, 0x1a, 0xea, 0x87, 0xdb, 0x1f, -+ 0xf3, 0xda, 0x04, 0x91, 0x37, 0xea, 0x0a, 0xfb, 0x6c, 0xc9, 0x3d, 0x73, -+ 0xf9, 0x58, 0x7c, 0x15, 0x6b, 0xa2, 0x52, 0x5a, 0x97, 0xff, 0xd6, 0xb0, -+ 0xf1, 0xbf, 0xa5, 0x04, 0x6d, 0x91, 0xc1, 0x54, 0x05, 0xdc, 0x7f, 0x5d, -+ 0x19, 0xaf, 0x55, 0xec, 0x51, 0xfb, 0x66, 0x0a, 0xa4, 0x4e, 0x96, 0x47, -+ 0x43, 0x54, 0x7c, 0x64, 0xa8, 0xaa, 0xb4, 0x90, 0x02, 0xf3, 0xa7, 0x0b, -+ 0xb7, 0xbf, 0x06, 0xdb, 0x5e, 0x9c, 0x32, 0x6d, 0x45, 0x14, 0x1c, 0xaf, -+ 0x46, 0x30, 0x08, 0x55, 0x49, 0x78, 0xfa, 0x57, 0xda, 0x3d, 0xf5, 0xa0, -+ 0xef, 0x11, 0x0a, 0x81, 0x0d, 0x82, 0xcd, 0xaf, 0xdb, 0xda, 0x0e, 0x1a, -+ 0x44, 0xd1, 0xee, 0xc4, 0xb8, 0xde, 0x97, 0xb4, 0xda, 0xb4, 0x8b, 0x4f, -+ 0x58, 0x24, 0x59, 0xc0, 0xe0, 0x08, 0x97, 0x14, 0x68, 0xbe, 0x31, 0x09, -+ 0x5e, 0x67, 0x45, 0xf0, 0xcb, 0x81, 0x4f, 0x17, 0x44, 0x61, 0xe0, 0xe2, -+ 0xf0, 0xfc, 0x1e, 0xb9, 0x73, 0xaf, 0x42, 0xff, 0x33, 0xde, 0x61, 0x6b, -+ 0x7f, 0xc2, 0x69, 0x0d, 0x66, 0x54, 0xae, 0xf6, 0xde, 0x20, 0x47, 0x44, -+ 0x9b, 0x73, 0xd1, 0x07, 0x6e, 0x77, 0x37, 0x0a, 0xbb, 0x7f, 0xa0, 0x93, -+ 0x2d, 0x8d, 0x44, 0xba, 0xe2, 0xdd, 0x34, 0x32, 0xd7, 0x56, 0x71, 0x00, -+ 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xc4, 0x7e, -+ 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x69, 0x67, 0x6e, 0x61, -+ 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, -+ 0x64, 0x7e, 0x0a ++ 0x01, 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0x96, 0x02, 0x7b, 0xa4, 0x07, ++ 0xa7, 0x39, 0x8d, 0xa6, 0x0b, 0xde, 0x33, 0xdd, 0xf8, 0xec, 0x24, 0x5d, ++ 0x06, 0x81, 0xe7, 0x3c, 0x2d, 0x0c, 0x53, 0xfb, 0x7e, 0x5a, 0xf3, 0xee, ++ 0xe5, 0x4c, 0x7c, 0xf7, 0xe7, 0x8f, 0x36, 0x62, 0x35, 0xb8, 0x99, 0xc3, ++ 0xeb, 0x85, 0x1d, 0x2e, 0x40, 0x6e, 0x2a, 0xb4, 0x3a, 0x76, 0x48, 0x4f, ++ 0x8b, 0x29, 0xd4, 0x9e, 0x5c, 0xd2, 0x41, 0x4d, 0xc1, 0x72, 0x0f, 0x97, ++ 0xe0, 0x7d, 0x88, 0xed, 0x1a, 0xb0, 0xde, 0x1b, 0x21, 0xa6, 0x0c, 0x19, ++ 0xd8, 0xb0, 0x12, 0x54, 0x7b, 0xd8, 0x19, 0x03, 0xbd, 0x77, 0x83, 0x23, ++ 0xeb, 0xeb, 0x68, 0x0a, 0x7b, 0x3a, 0x4d, 0x25, 0x44, 0xe1, 0x64, 0x8d, ++ 0x43, 0x5a, 0x1c, 0x9f, 0x74, 0x79, 0x31, 0x3f, 0xc7, 0x8e, 0xae, 0xe1, ++ 0xf9, 0x1e, 0x54, 0x12, 0x36, 0x85, 0xf2, 0x55, 0xba, 0x42, 0x60, 0x64, ++ 0x25, 0x9f, 0x73, 0x62, 0x42, 0xd2, 0x1c, 0x5e, 0x39, 0x4f, 0x7d, 0x91, ++ 0xb8, 0xf9, 0x59, 0x3c, 0x13, 0x6b, 0x84, 0x76, 0x6d, 0x8a, 0xc3, 0xcb, ++ 0x2d, 0x14, 0x27, 0x16, 0xdc, 0x20, 0x2c, 0xbc, 0x6b, 0xc9, 0xda, 0x9f, ++ 0xef, 0xe2, 0x2d, 0xc3, 0x83, 0xd8, 0xf9, 0x94, 0x18, 0xbc, 0xfe, 0x8f, ++ 0xa9, 0x44, 0xad, 0xff, 0x1b, 0xcb, 0x86, 0x30, 0x96, 0xa8, 0x3c, 0x7a, ++ 0x4b, 0x73, 0x1b, 0xa9, 0xc3, 0x3b, 0xaa, 0xd7, 0x44, 0xa8, 0x4d, 0xd6, ++ 0x92, 0xb6, 0x00, 0x04, 0x09, 0x05, 0x4a, 0x95, 0x02, 0x90, 0x19, 0x8c, ++ 0x9a, 0xa5, 0xee, 0x58, 0x24, 0xb0, 0xca, 0x5e, 0x6f, 0x73, 0xdb, 0xf5, ++ 0xa1, 0xf4, 0xf0, 0xa9, 0xeb, 0xe4, 0xdc, 0x55, 0x9f, 0x8f, 0x7a, 0xd0, ++ 0xf7, 0xb6, 0xaa, 0xa6, 0xb5, 0xb4, 0xab, 0xb8, 0x65, 0xad, 0x12, 0x32, ++ 0x1c, 0xe6, 0x99, 0x71, 0x93, 0xe8, 0xb4, 0x1e, 0x21, 0x27, 0x52, 0xea, ++ 0x8c, 0xc8, 0x79, 0x96, 0x2e, 0x48, 0x60, 0x57, 0x1c, 0x7d, 0x8c, 0x0d, ++ 0x07, 0xa7, 0x12, 0x83, 0x0a, 0x76, 0x6a, 0x64, 0xed, 0xbe, 0x8d, 0xaf, ++ 0xdf, 0x51, 0x05, 0xdd, 0xf2, 0xd3, 0xb8, 0x93, 0xa9, 0x13, 0xa5, 0x96, ++ 0xe8, 0xfa, 0x82, 0x02, 0x18, 0x71, 0x7a, 0x71, 0xbb, 0x39, 0x6f, 0x85, ++ 0xee, 0x16, 0x82, 0x27, 0x42, 0x9f, 0x83, 0xc8, 0xab, 0x6a, 0x3b, 0x99, ++ 0xba, 0x38, 0x92, 0x38, 0xae, 0x59, 0xfa, 0xaa, 0x40, 0x2b, 0x52, 0x95, ++ 0xca, 0x5e, 0xe1, 0x9b, 0x00, 0xbd, 0xb9, 0x63, 0x25, 0x8d, 0xc7, 0x22, ++ 0xaf, 0xe5, 0x67, 0x76, 0x91, 0xf4, 0xda, 0xc9, 0x7e, 0x9e, 0xec, 0x9b, ++ 0x1f, 0x7d, 0x3b, 0xfe, 0xa1, 0x20, 0x52, 0xac, 0xd0, 0xe5, 0xa6, 0xf1, ++ 0xfd, 0x4c, 0x08, 0x59, 0x7d, 0x50, 0xbb, 0x0c, 0xcf, 0xd8, 0xb6, 0x0f, ++ 0xc7, 0x19, 0xcb, 0x7a, 0x96, 0x6f, 0x0f, 0x6c, 0x71, 0x56, 0x72, 0xd1, ++ 0x06, 0x29, 0x0f, 0x08, 0xa2, 0x46, 0x3e, 0x58, 0x42, 0xc4, 0x8c, 0xe0, ++ 0x6e, 0xe9, 0x37, 0xd5, 0x2f, 0x74, 0x36, 0x1d, 0x14, 0xcb, 0x10, 0x0e, ++ 0x7d, 0x67, 0xbd, 0x38, 0x0e, 0xa4, 0x27, 0x1d, 0x3c, 0x78, 0x4d, 0x0d, ++ 0x15, 0x42, 0x70, 0x20, 0xe0, 0x1d, 0x83, 0x6c, 0x4d, 0xf1, 0x02, 0xa1, ++ 0x51, 0xc4, 0xc5, 0x5d, 0x69, 0x90, 0x58, 0x82, 0x94, 0x50, 0x36, 0x22, ++ 0xb3, 0xa4, 0x15, 0x77, 0xdc, 0x44, 0xb0, 0x50, 0xa2, 0x3f, 0xd0, 0x0e, ++ 0x1b, 0xfc, 0xf4, 0x5b, 0x3b, 0x7d, 0x63, 0x94, 0x22, 0xf3, 0x87, 0x0a, ++ 0x41, 0x8a, 0x27, 0x48, 0xcb, 0x6c, 0xfd, 0x70, 0x66, 0x5f, 0x11, 0x6f, ++ 0x74, 0x2c, 0x42, 0xaf, 0x74, 0x45, 0x3f, 0x0c, 0x03, 0xc8, 0x80, 0xe2, ++ 0x71, 0x08, 0x93, 0xbd, 0x4d, 0x18, 0x78, 0x1e, 0x8e, 0xb9, 0x3a, 0xd6, ++ 0x1a, 0xde, 0xf9, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x02, 0xb8, 0x7e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, ++ 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, ++ 0x65, 0x6e, 0x64, 0x65, 0x64, 0x7e, 0x0a +}; -+unsigned int hi_signed_sha256_len = 495; ++unsigned int hi_signed_sha256_len = 739; + +unsigned char short_msg[] = { + 0x68, 0x69, 0x0a @@ -822,6 +904,244 @@ index 00000000000..aa3dc6278e3 +}; +unsigned int hi_signed_2nd_len = 736; + ++unsigned char hi_double[] = { ++ 0x68, 0x69, 0x0a, 0x30, 0x82, 0x05, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, ++ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x05, 0x20, 0x30, 0x82, ++ 0x05, 0x1c, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, ++ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0b, 0x06, 0x09, ++ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x04, ++ 0xf9, 0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x01, 0x30, 0x52, 0x30, 0x3a, ++ 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2f, 0x47, ++ 0x72, 0x75, 0x62, 0x20, 0x32, 0x6e, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74, ++ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, ++ 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, ++ 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x02, 0x14, ++ 0x5b, 0x5e, 0x59, 0xf2, 0x5f, 0x75, 0x4c, 0x8e, 0xc5, 0x3a, 0x91, 0x07, ++ 0xe9, 0xe7, 0x6d, 0x3c, 0xd0, 0x7f, 0x91, 0xff, 0x30, 0x0b, 0x06, 0x09, ++ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0d, 0x06, ++ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, ++ 0x04, 0x82, 0x02, 0x00, 0x0e, 0xc2, 0x30, 0x38, 0x81, 0x23, 0x68, 0x90, ++ 0xae, 0x5f, 0xce, 0xf7, 0x27, 0xb1, 0x8c, 0x2e, 0x12, 0x10, 0xc6, 0x99, ++ 0xdc, 0x4d, 0x4b, 0x79, 0xda, 0xe4, 0x32, 0x10, 0x46, 0x1c, 0x16, 0x07, ++ 0x87, 0x66, 0x55, 0xff, 0x64, 0x1c, 0x61, 0x25, 0xd5, 0xb9, 0xe1, 0xfe, ++ 0xea, 0x5a, 0xcd, 0x56, 0xa5, 0xc3, 0xbe, 0xb1, 0x61, 0xc7, 0x6f, 0x5f, ++ 0x69, 0x20, 0x64, 0x50, 0x6f, 0x12, 0x78, 0xb6, 0x0c, 0x72, 0x44, 0x4f, ++ 0x60, 0x0f, 0x9f, 0xa2, 0x83, 0x3b, 0xc2, 0x83, 0xd5, 0x14, 0x1f, 0x6f, ++ 0x3e, 0xb2, 0x47, 0xb5, 0x58, 0xc5, 0xa7, 0xb4, 0x82, 0x53, 0x2e, 0x53, ++ 0x95, 0x4e, 0x3d, 0xe4, 0x62, 0xe8, 0xa1, 0xaf, 0xae, 0xbf, 0xa9, 0xd2, ++ 0x22, 0x07, 0xbe, 0x71, 0x37, 0x2c, 0x5a, 0xa7, 0x6c, 0xaf, 0x14, 0xc0, ++ 0x6c, 0x2f, 0xbf, 0x4f, 0x15, 0xc2, 0x0f, 0x8b, 0xdc, 0x68, 0x45, 0xdf, ++ 0xf3, 0xa5, 0x7f, 0x11, 0x6a, 0x54, 0xcd, 0x67, 0xb9, 0x2e, 0x7d, 0x05, ++ 0xe3, 0x1c, 0x1d, 0xcc, 0x77, 0x8e, 0x97, 0xb1, 0xa0, 0x11, 0x09, 0x3d, ++ 0x90, 0x54, 0xfc, 0x7e, 0xbb, 0xbb, 0x21, 0x23, 0x03, 0x44, 0xbf, 0x7d, ++ 0x2c, 0xc9, 0x15, 0x42, 0xe5, 0xa0, 0x3b, 0xa2, 0xd1, 0x5b, 0x73, 0x81, ++ 0xff, 0xfa, 0x90, 0xfc, 0x27, 0x7b, 0x2f, 0x86, 0x9c, 0x1d, 0x14, 0x36, ++ 0x94, 0xa2, 0x6e, 0xe8, 0x9d, 0xa0, 0x5f, 0xfc, 0x5a, 0x0d, 0xa4, 0xd5, ++ 0x2f, 0x8d, 0xd6, 0x00, 0xfa, 0x93, 0x5b, 0x09, 0x7f, 0x42, 0x78, 0xcc, ++ 0x8c, 0x49, 0xda, 0xd9, 0xf6, 0x43, 0xe7, 0xe1, 0x3c, 0xa2, 0xe2, 0x70, ++ 0xe2, 0x6a, 0x99, 0xc5, 0xd6, 0xa2, 0xe3, 0x0b, 0xd4, 0x09, 0xac, 0x94, ++ 0xaf, 0xb7, 0xf0, 0xb3, 0x0c, 0x1e, 0xf5, 0x16, 0x4f, 0x53, 0x9a, 0xe3, ++ 0xcc, 0xe2, 0x0c, 0x4a, 0xb9, 0xe6, 0x06, 0xbb, 0xf7, 0x41, 0x43, 0x20, ++ 0x04, 0xee, 0x99, 0x2f, 0xd8, 0x9f, 0xda, 0x3f, 0xfd, 0x49, 0xb8, 0xc2, ++ 0xbd, 0xd9, 0xc5, 0x72, 0xfd, 0xe3, 0xce, 0x1c, 0xbc, 0xe4, 0x39, 0xac, ++ 0x2a, 0x99, 0xe9, 0xb4, 0x3e, 0x74, 0x10, 0xeb, 0xd5, 0x14, 0xcc, 0xdb, ++ 0xf1, 0x04, 0x63, 0x36, 0xfb, 0x1f, 0x2b, 0xe2, 0x73, 0xd4, 0xd8, 0x49, ++ 0x31, 0xa8, 0x55, 0xcc, 0xa7, 0x76, 0x36, 0x6e, 0x18, 0xdc, 0xb9, 0xb0, ++ 0x29, 0x99, 0xcf, 0x49, 0xbf, 0xf9, 0xdb, 0x7f, 0x24, 0x42, 0x02, 0xcb, ++ 0xc1, 0xaa, 0xcb, 0xba, 0x18, 0x85, 0x86, 0xc7, 0xf4, 0x1c, 0x62, 0x76, ++ 0xbc, 0x73, 0xfb, 0xe4, 0x15, 0xb8, 0xdd, 0x5d, 0xa6, 0x68, 0x39, 0xa5, ++ 0x3d, 0x33, 0xaf, 0xd5, 0x92, 0x4d, 0x48, 0xdb, 0x22, 0xc0, 0xdc, 0x49, ++ 0x5f, 0x7b, 0xa8, 0xd2, 0x62, 0x2d, 0xa7, 0x39, 0x93, 0x48, 0xe7, 0x6b, ++ 0x23, 0xba, 0xd4, 0xe0, 0xc1, 0x29, 0x55, 0xc4, 0x34, 0xe3, 0xac, 0x25, ++ 0xa7, 0x15, 0xad, 0xab, 0xb3, 0xb7, 0x25, 0xca, 0x37, 0x88, 0x40, 0x2e, ++ 0x47, 0x6e, 0x92, 0x20, 0x09, 0x2e, 0x5a, 0xec, 0xf2, 0xfb, 0xb3, 0xa0, ++ 0x16, 0xb6, 0x93, 0xf2, 0xf5, 0x8b, 0xfe, 0xaf, 0x25, 0xee, 0x2e, 0x98, ++ 0x6c, 0x0a, 0xfe, 0xae, 0x0b, 0x57, 0xf5, 0x9f, 0x3c, 0x80, 0xe9, 0x8b, ++ 0xaf, 0x92, 0x8a, 0xad, 0xe7, 0xa0, 0xe4, 0xe6, 0x0a, 0xa0, 0xc7, 0x83, ++ 0xb5, 0x48, 0x58, 0x5f, 0x55, 0x9e, 0x9b, 0x27, 0xcd, 0x31, 0x1f, 0x3e, ++ 0x50, 0x5a, 0x91, 0xad, 0x21, 0x1b, 0x97, 0x5b, 0xe8, 0xfa, 0x29, 0x8a, ++ 0xa4, 0x17, 0xe8, 0xab, 0x87, 0x02, 0xd6, 0x18, 0x8c, 0x9f, 0x65, 0xb7, ++ 0x2a, 0xfa, 0xde, 0x5f, 0x77, 0x30, 0x6c, 0x04, 0x22, 0xe6, 0x58, 0x26, ++ 0x14, 0x0d, 0x9c, 0x41, 0x0a, 0x82, 0x77, 0xdb, 0x40, 0xa1, 0x58, 0xac, ++ 0x30, 0x82, 0x02, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x55, 0x30, 0x3d, 0x31, ++ 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x32, 0x47, 0x72, ++ 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, ++ 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, ++ 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, ++ 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, ++ 0x02, 0x14, 0x5b, 0x5e, 0x59, 0xf2, 0x5f, 0x75, 0x4c, 0x8e, 0xc5, 0x3a, ++ 0x91, 0x07, 0xe9, 0xe7, 0x6d, 0x3c, 0xd0, 0x7f, 0x92, 0x03, 0x30, 0x0b, ++ 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, ++ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, ++ 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0xa0, 0x83, 0x3f, 0xac, 0x77, 0x97, ++ 0x74, 0x9b, 0x4b, 0x25, 0xa1, 0x64, 0x09, 0x8d, 0x53, 0xa6, 0x03, 0xdf, ++ 0x9a, 0x10, 0x52, 0xe5, 0x3f, 0xd4, 0x72, 0x75, 0x30, 0xd4, 0x6e, 0x77, ++ 0x32, 0x49, 0x84, 0xe2, 0xbe, 0xef, 0xe4, 0xf3, 0xac, 0xb0, 0x52, 0x55, ++ 0xbf, 0xa9, 0x57, 0x12, 0x08, 0x7d, 0xb0, 0x86, 0xc0, 0x9d, 0x01, 0xc2, ++ 0x1a, 0x4a, 0x2e, 0x3d, 0xd5, 0xc8, 0x56, 0xac, 0xd1, 0x83, 0x75, 0x88, ++ 0xd4, 0xcc, 0x9f, 0x0d, 0xcf, 0xd3, 0xa6, 0x91, 0xb6, 0xb6, 0xb1, 0xd1, ++ 0x24, 0x9c, 0xd0, 0x13, 0xe8, 0x6b, 0x15, 0x9c, 0x62, 0x33, 0x8d, 0xe3, ++ 0x67, 0x9b, 0xb1, 0x8a, 0x72, 0x38, 0xf7, 0x48, 0x32, 0x2f, 0x1e, 0x45, ++ 0xa8, 0xc4, 0xa5, 0xae, 0xb1, 0xfc, 0x35, 0x25, 0xb5, 0xf9, 0x7f, 0x86, ++ 0xef, 0xa2, 0x6d, 0x78, 0xcc, 0xfd, 0x0c, 0xca, 0x8a, 0xe1, 0xae, 0xcd, ++ 0x0f, 0x58, 0x69, 0xf1, 0x8b, 0xcc, 0x22, 0x35, 0x6d, 0x1f, 0xd5, 0x27, ++ 0x87, 0x39, 0x62, 0x3f, 0xb2, 0x17, 0x3d, 0x5e, 0xb1, 0x32, 0x7a, 0xf1, ++ 0x70, 0xce, 0xfa, 0xab, 0x1c, 0x92, 0xa8, 0xe1, 0xc4, 0xb2, 0x33, 0x1a, ++ 0x16, 0xf3, 0x60, 0x39, 0xdf, 0xb8, 0x85, 0xe7, 0x5d, 0x4d, 0xc2, 0x8d, ++ 0x55, 0x00, 0x49, 0x94, 0x04, 0x17, 0x88, 0x7c, 0xf4, 0xac, 0xa9, 0xc5, ++ 0x3a, 0x09, 0xc4, 0xc2, 0xcd, 0x3d, 0xc3, 0xfc, 0x4e, 0xf3, 0x70, 0xa1, ++ 0xc1, 0x54, 0x36, 0x1f, 0x38, 0x6d, 0x7a, 0x6b, 0x6a, 0xd3, 0x67, 0x04, ++ 0xd5, 0x53, 0xd4, 0xa5, 0xad, 0x63, 0x55, 0x0e, 0x06, 0x06, 0x3a, 0x9a, ++ 0xc5, 0xfe, 0x38, 0xc9, 0xb0, 0x69, 0x42, 0x90, 0x35, 0x1f, 0xe3, 0x1c, ++ 0x57, 0xea, 0xdb, 0x51, 0x35, 0x53, 0xd3, 0x94, 0xfe, 0x72, 0x33, 0xd6, ++ 0x8a, 0x46, 0x74, 0xf9, 0x6e, 0x94, 0x40, 0x2f, 0xba, 0xa2, 0xc4, 0xe9, ++ 0xc9, 0x8a, 0xf4, 0xda, 0xe2, 0xca, 0x3e, 0x98, 0x85, 0xa5, 0xd1, 0x60, ++ 0x94, 0xc8, 0xdf, 0x82, 0xee, 0x5c, 0x0d, 0x2a, 0xa9, 0x8e, 0x26, 0x83, ++ 0x3f, 0x02, 0xa2, 0xaf, 0xb8, 0x3b, 0x83, 0xf2, 0x44, 0x46, 0x41, 0xd7, ++ 0x5c, 0xa1, 0x42, 0x17, 0xa2, 0xd0, 0x50, 0x42, 0xef, 0x66, 0xda, 0x35, ++ 0x03, 0xd1, 0x8e, 0x77, 0x22, 0x7d, 0x4e, 0xf7, 0x4e, 0x04, 0xe3, 0x0f, ++ 0x98, 0x7d, 0xaa, 0x58, 0xba, 0xef, 0x9a, 0xd0, 0x88, 0x7c, 0x98, 0xa0, ++ 0xc2, 0xff, 0xa6, 0xb1, 0xec, 0xbe, 0x6e, 0xb0, 0x7e, 0xc6, 0xe5, 0xaa, ++ 0xcf, 0x10, 0x73, 0xc9, 0x13, 0x1a, 0x20, 0x12, 0x5c, 0xd2, 0x0e, 0xe2, ++ 0x60, 0x17, 0xdf, 0x4a, 0x44, 0x08, 0x22, 0xbc, 0xcd, 0x75, 0xbe, 0xc3, ++ 0x7a, 0x12, 0x90, 0x90, 0xc7, 0x94, 0x4c, 0x98, 0x45, 0x02, 0x5c, 0x24, ++ 0xae, 0x82, 0x2f, 0xcd, 0x30, 0xa6, 0xf5, 0x3f, 0xd3, 0xa7, 0xa6, 0xe6, ++ 0xea, 0x11, 0x4e, 0x45, 0xb7, 0xc0, 0xe6, 0x24, 0x8b, 0x76, 0xc5, 0x5e, ++ 0xc1, 0xd8, 0x07, 0x1e, 0x26, 0x94, 0x7a, 0x80, 0xc6, 0x3b, 0x1f, 0x74, ++ 0xe6, 0xae, 0x43, 0x2d, 0x11, 0xee, 0x96, 0x56, 0x6c, 0xff, 0xcb, 0x3b, ++ 0xde, 0xcc, 0xb3, 0x7b, 0x08, 0xf5, 0x3e, 0x6e, 0x51, 0x71, 0xe0, 0x8a, ++ 0xfa, 0xdd, 0x19, 0x39, 0xcf, 0x3f, 0x29, 0x4f, 0x2d, 0xd2, 0xd4, 0xdc, ++ 0x5c, 0xc4, 0xd1, 0xa7, 0xf5, 0xbf, 0x4a, 0xc0, 0x9b, 0xb4, 0x2b, 0x83, ++ 0x7a, 0x63, 0x4d, 0x20, 0x40, 0x8b, 0x11, 0x5c, 0x53, 0xd4, 0x52, 0x21, ++ 0xe7, 0xe4, 0x1f, 0x01, 0xf6, 0xd1, 0x25, 0x28, 0xba, 0x51, 0x6f, 0x51, ++ 0x69, 0xf4, 0x41, 0x45, 0x75, 0x23, 0x25, 0x77, 0xef, 0xa8, 0x1c, 0x19, ++ 0x8a, 0x66, 0x8c, 0x61, 0x13, 0x37, 0x4f, 0xa3, 0xa1, 0x83, 0x17, 0x35, ++ 0x23, 0x2d, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x05, 0x33, 0x7e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, 0x69, ++ 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, 0x65, ++ 0x6e, 0x64, 0x65, 0x64, 0x7e, 0x0a ++}; ++unsigned int hi_double_len = 1374; ++ ++unsigned char hi_double_extended[] = { ++ 0x68, 0x69, 0x0a, 0x30, 0x82, 0x05, 0x2f, 0x06, 0x09, 0x2a, 0x86, 0x48, ++ 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x05, 0x20, 0x30, 0x82, ++ 0x05, 0x1c, 0x02, 0x01, 0x01, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, ++ 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0b, 0x06, 0x09, ++ 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0x31, 0x82, 0x04, ++ 0xf9, 0x30, 0x82, 0x02, 0x77, 0x02, 0x01, 0x01, 0x30, 0x52, 0x30, 0x3a, ++ 0x31, 0x38, 0x30, 0x36, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x2f, 0x47, ++ 0x72, 0x75, 0x62, 0x20, 0x32, 0x6e, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74, ++ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, ++ 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, ++ 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x02, 0x14, ++ 0x5b, 0x5e, 0x59, 0xf2, 0x5f, 0x75, 0x4c, 0x8e, 0xc5, 0x3a, 0x91, 0x07, ++ 0xe9, 0xe7, 0x6d, 0x3c, 0xd0, 0x7f, 0x91, 0xff, 0x30, 0x0b, 0x06, 0x09, ++ 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, 0x0d, 0x06, ++ 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, ++ 0x04, 0x82, 0x02, 0x00, 0x0e, 0xc2, 0x30, 0x38, 0x81, 0x23, 0x68, 0x90, ++ 0xae, 0x5f, 0xce, 0xf7, 0x27, 0xb1, 0x8c, 0x2e, 0x12, 0x10, 0xc6, 0x99, ++ 0xdc, 0x4d, 0x4b, 0x79, 0xda, 0xe4, 0x32, 0x10, 0x46, 0x1c, 0x16, 0x07, ++ 0x87, 0x66, 0x55, 0xff, 0x64, 0x1c, 0x61, 0x25, 0xd5, 0xb9, 0xe1, 0xfe, ++ 0xea, 0x5a, 0xcd, 0x56, 0xa5, 0xc3, 0xbe, 0xb1, 0x61, 0xc7, 0x6f, 0x5f, ++ 0x69, 0x20, 0x64, 0x50, 0x6f, 0x12, 0x78, 0xb6, 0x0c, 0x72, 0x44, 0x4f, ++ 0x60, 0x0f, 0x9f, 0xa2, 0x83, 0x3b, 0xc2, 0x83, 0xd5, 0x14, 0x1f, 0x6f, ++ 0x3e, 0xb2, 0x47, 0xb5, 0x58, 0xc5, 0xa7, 0xb4, 0x82, 0x53, 0x2e, 0x53, ++ 0x95, 0x4e, 0x3d, 0xe4, 0x62, 0xe8, 0xa1, 0xaf, 0xae, 0xbf, 0xa9, 0xd2, ++ 0x22, 0x07, 0xbe, 0x71, 0x37, 0x2c, 0x5a, 0xa7, 0x6c, 0xaf, 0x14, 0xc0, ++ 0x6c, 0x2f, 0xbf, 0x4f, 0x15, 0xc2, 0x0f, 0x8b, 0xdc, 0x68, 0x45, 0xdf, ++ 0xf3, 0xa5, 0x7f, 0x11, 0x6a, 0x54, 0xcd, 0x67, 0xb9, 0x2e, 0x7d, 0x05, ++ 0xe3, 0x1c, 0x1d, 0xcc, 0x77, 0x8e, 0x97, 0xb1, 0xa0, 0x11, 0x09, 0x3d, ++ 0x90, 0x54, 0xfc, 0x7e, 0xbb, 0xbb, 0x21, 0x23, 0x03, 0x44, 0xbf, 0x7d, ++ 0x2c, 0xc9, 0x15, 0x42, 0xe5, 0xa0, 0x3b, 0xa2, 0xd1, 0x5b, 0x73, 0x81, ++ 0xff, 0xfa, 0x90, 0xfc, 0x27, 0x7b, 0x2f, 0x86, 0x9c, 0x1d, 0x14, 0x36, ++ 0x94, 0xa2, 0x6e, 0xe8, 0x9d, 0xa0, 0x5f, 0xfc, 0x5a, 0x0d, 0xa4, 0xd5, ++ 0x2f, 0x8d, 0xd6, 0x00, 0xfa, 0x93, 0x5b, 0x09, 0x7f, 0x42, 0x78, 0xcc, ++ 0x8c, 0x49, 0xda, 0xd9, 0xf6, 0x43, 0xe7, 0xe1, 0x3c, 0xa2, 0xe2, 0x70, ++ 0xe2, 0x6a, 0x99, 0xc5, 0xd6, 0xa2, 0xe3, 0x0b, 0xd4, 0x09, 0xac, 0x94, ++ 0xaf, 0xb7, 0xf0, 0xb3, 0x0c, 0x1e, 0xf5, 0x16, 0x4f, 0x53, 0x9a, 0xe3, ++ 0xcc, 0xe2, 0x0c, 0x4a, 0xb9, 0xe6, 0x06, 0xbb, 0xf7, 0x41, 0x43, 0x20, ++ 0x04, 0xee, 0x99, 0x2f, 0xd8, 0x9f, 0xda, 0x3f, 0xfd, 0x49, 0xb8, 0xc2, ++ 0xbd, 0xd9, 0xc5, 0x72, 0xfd, 0xe3, 0xce, 0x1c, 0xbc, 0xe4, 0x39, 0xac, ++ 0x2a, 0x99, 0xe9, 0xb4, 0x3e, 0x74, 0x10, 0xeb, 0xd5, 0x14, 0xcc, 0xdb, ++ 0xf1, 0x04, 0x63, 0x36, 0xfb, 0x1f, 0x2b, 0xe2, 0x73, 0xd4, 0xd8, 0x49, ++ 0x31, 0xa8, 0x55, 0xcc, 0xa7, 0x76, 0x36, 0x6e, 0x18, 0xdc, 0xb9, 0xb0, ++ 0x29, 0x99, 0xcf, 0x49, 0xbf, 0xf9, 0xdb, 0x7f, 0x24, 0x42, 0x02, 0xcb, ++ 0xc1, 0xaa, 0xcb, 0xba, 0x18, 0x85, 0x86, 0xc7, 0xf4, 0x1c, 0x62, 0x76, ++ 0xbc, 0x73, 0xfb, 0xe4, 0x15, 0xb8, 0xdd, 0x5d, 0xa6, 0x68, 0x39, 0xa5, ++ 0x3d, 0x33, 0xaf, 0xd5, 0x92, 0x4d, 0x48, 0xdb, 0x22, 0xc0, 0xdc, 0x49, ++ 0x5f, 0x7b, 0xa8, 0xd2, 0x62, 0x2d, 0xa7, 0x39, 0x93, 0x48, 0xe7, 0x6b, ++ 0x23, 0xba, 0xd4, 0xe0, 0xc1, 0x29, 0x55, 0xc4, 0x34, 0xe3, 0xac, 0x25, ++ 0xa7, 0x15, 0xad, 0xab, 0xb3, 0xb7, 0x25, 0xca, 0x37, 0x88, 0x40, 0x2e, ++ 0x47, 0x6e, 0x92, 0x20, 0x09, 0x2e, 0x5a, 0xec, 0xf2, 0xfb, 0xb3, 0xa0, ++ 0x16, 0xb6, 0x93, 0xf2, 0xf5, 0x8b, 0xfe, 0xaf, 0x25, 0xee, 0x2e, 0x98, ++ 0x6c, 0x0a, 0xfe, 0xae, 0x0b, 0x57, 0xf5, 0x9f, 0x3c, 0x80, 0xe9, 0x8b, ++ 0xaf, 0x92, 0x8a, 0xad, 0xe7, 0xa0, 0xe4, 0xe6, 0x0a, 0xa0, 0xc7, 0x83, ++ 0xb5, 0x48, 0x58, 0x5f, 0x55, 0x9e, 0x9b, 0x27, 0xcd, 0x31, 0x1f, 0x3e, ++ 0x50, 0x5a, 0x91, 0xad, 0x21, 0x1b, 0x97, 0x5b, 0xe8, 0xfa, 0x29, 0x8a, ++ 0xa4, 0x17, 0xe8, 0xab, 0x87, 0x02, 0xd6, 0x18, 0x8c, 0x9f, 0x65, 0xb7, ++ 0x2a, 0xfa, 0xde, 0x5f, 0x77, 0x30, 0x6c, 0x04, 0x22, 0xe6, 0x58, 0x26, ++ 0x14, 0x0d, 0x9c, 0x41, 0x0a, 0x82, 0x77, 0xdb, 0x40, 0xa1, 0x58, 0xac, ++ 0x30, 0x82, 0x02, 0x7a, 0x02, 0x01, 0x01, 0x30, 0x55, 0x30, 0x3d, 0x31, ++ 0x3b, 0x30, 0x39, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x32, 0x47, 0x72, ++ 0x75, 0x62, 0x20, 0x41, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x64, 0x20, ++ 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, ++ 0x73, 0x74, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, ++ 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, ++ 0x02, 0x14, 0x5b, 0x5e, 0x59, 0xf2, 0x5f, 0x75, 0x4c, 0x8e, 0xc5, 0x3a, ++ 0x91, 0x07, 0xe9, 0xe7, 0x6d, 0x3c, 0xd0, 0x7f, 0x92, 0x03, 0x30, 0x0b, ++ 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, 0x30, ++ 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, ++ 0x05, 0x00, 0x04, 0x82, 0x02, 0x00, 0xa0, 0x83, 0x3f, 0xac, 0x77, 0x97, ++ 0x74, 0x9b, 0x4b, 0x25, 0xa1, 0x64, 0x09, 0x8d, 0x53, 0xa6, 0x03, 0xdf, ++ 0x9a, 0x10, 0x52, 0xe5, 0x3f, 0xd4, 0x72, 0x75, 0x30, 0xd4, 0x6e, 0x77, ++ 0x32, 0x49, 0x84, 0xe2, 0xbe, 0xef, 0xe4, 0xf3, 0xac, 0xb0, 0x52, 0x55, ++ 0xbf, 0xa9, 0x57, 0x12, 0x08, 0x7d, 0xb0, 0x86, 0xc0, 0x9d, 0x01, 0xc2, ++ 0x1a, 0x4a, 0x2e, 0x3d, 0xd5, 0xc8, 0x56, 0xac, 0xd1, 0x83, 0x75, 0x88, ++ 0xd4, 0xcc, 0x9f, 0x0d, 0xcf, 0xd3, 0xa6, 0x91, 0xb6, 0xb6, 0xb1, 0xd1, ++ 0x24, 0x9c, 0xd0, 0x13, 0xe8, 0x6b, 0x15, 0x9c, 0x62, 0x33, 0x8d, 0xe3, ++ 0x67, 0x9b, 0xb1, 0x8a, 0x72, 0x38, 0xf7, 0x48, 0x32, 0x2f, 0x1e, 0x45, ++ 0xa8, 0xc4, 0xa5, 0xae, 0xb1, 0xfc, 0x35, 0x25, 0xb5, 0xf9, 0x7f, 0x86, ++ 0xef, 0xa2, 0x6d, 0x78, 0xcc, 0xfd, 0x0c, 0xca, 0x8a, 0xe1, 0xae, 0xcd, ++ 0x0f, 0x58, 0x69, 0xf1, 0x8b, 0xcc, 0x22, 0x35, 0x6d, 0x1f, 0xd5, 0x27, ++ 0x87, 0x39, 0x62, 0x3f, 0xb2, 0x17, 0x3d, 0x5e, 0xb1, 0x32, 0x7a, 0xf1, ++ 0x70, 0xce, 0xfa, 0xab, 0x1c, 0x92, 0xa8, 0xe1, 0xc4, 0xb2, 0x33, 0x1a, ++ 0x16, 0xf3, 0x60, 0x39, 0xdf, 0xb8, 0x85, 0xe7, 0x5d, 0x4d, 0xc2, 0x8d, ++ 0x55, 0x00, 0x49, 0x94, 0x04, 0x17, 0x88, 0x7c, 0xf4, 0xac, 0xa9, 0xc5, ++ 0x3a, 0x09, 0xc4, 0xc2, 0xcd, 0x3d, 0xc3, 0xfc, 0x4e, 0xf3, 0x70, 0xa1, ++ 0xc1, 0x54, 0x36, 0x1f, 0x38, 0x6d, 0x7a, 0x6b, 0x6a, 0xd3, 0x67, 0x04, ++ 0xd5, 0x53, 0xd4, 0xa5, 0xad, 0x63, 0x55, 0x0e, 0x06, 0x06, 0x3a, 0x9a, ++ 0xc5, 0xfe, 0x38, 0xc9, 0xb0, 0x69, 0x42, 0x90, 0x35, 0x1f, 0xe3, 0x1c, ++ 0x57, 0xea, 0xdb, 0x51, 0x35, 0x53, 0xd3, 0x94, 0xfe, 0x72, 0x33, 0xd6, ++ 0x8a, 0x46, 0x74, 0xf9, 0x6e, 0x94, 0x40, 0x2f, 0xba, 0xa2, 0xc4, 0xe9, ++ 0xc9, 0x8a, 0xf4, 0xda, 0xe2, 0xca, 0x3e, 0x98, 0x85, 0xa5, 0xd1, 0x60, ++ 0x94, 0xc8, 0xdf, 0x82, 0xee, 0x5c, 0x0d, 0x2a, 0xa9, 0x8e, 0x26, 0x83, ++ 0x3f, 0x02, 0xa2, 0xaf, 0xb8, 0x3b, 0x83, 0xf2, 0x44, 0x46, 0x41, 0xd7, ++ 0x5c, 0xa1, 0x42, 0x17, 0xa2, 0xd0, 0x50, 0x42, 0xef, 0x66, 0xda, 0x35, ++ 0x03, 0xd1, 0x8e, 0x77, 0x22, 0x7d, 0x4e, 0xf7, 0x4e, 0x04, 0xe3, 0x0f, ++ 0x98, 0x7d, 0xaa, 0x58, 0xba, 0xef, 0x9a, 0xd0, 0x88, 0x7c, 0x98, 0xa0, ++ 0xc2, 0xff, 0xa6, 0xb1, 0xec, 0xbe, 0x6e, 0xb0, 0x7e, 0xc6, 0xe5, 0xaa, ++ 0xcf, 0x10, 0x73, 0xc9, 0x13, 0x1a, 0x20, 0x12, 0x5c, 0xd2, 0x0e, 0xe2, ++ 0x60, 0x17, 0xdf, 0x4a, 0x44, 0x08, 0x22, 0xbc, 0xcd, 0x75, 0xbe, 0xc3, ++ 0x7a, 0x12, 0x90, 0x90, 0xc7, 0x94, 0x4c, 0x98, 0x45, 0x02, 0x5c, 0x24, ++ 0xae, 0x82, 0x2f, 0xcd, 0x30, 0xa6, 0xf5, 0x3f, 0xd3, 0xa7, 0xa6, 0xe6, ++ 0xea, 0x11, 0x4e, 0x45, 0xb7, 0xc0, 0xe6, 0x24, 0x8b, 0x76, 0xc5, 0x5e, ++ 0xc1, 0xd8, 0x07, 0x1e, 0x26, 0x94, 0x7a, 0x80, 0xc6, 0x3b, 0x1f, 0x74, ++ 0xe6, 0xae, 0x43, 0x2d, 0x11, 0xee, 0x96, 0x56, 0x6c, 0xff, 0xcb, 0x3b, ++ 0xde, 0xcc, 0xb3, 0x7b, 0x08, 0xf5, 0x3e, 0x6e, 0x51, 0x71, 0xe0, 0x8a, ++ 0xfa, 0xdd, 0x19, 0x39, 0xcf, 0x3f, 0x29, 0x4f, 0x2d, 0xd2, 0xd4, 0xdc, ++ 0x5c, 0xc4, 0xd1, 0xa7, 0xf5, 0xbf, 0x4a, 0xc0, 0x9b, 0xb4, 0x2b, 0x83, ++ 0x7a, 0x63, 0x4d, 0x20, 0x40, 0x8b, 0x11, 0x5c, 0x53, 0xd4, 0x52, 0x21, ++ 0xe7, 0xe4, 0x1f, 0x01, 0xf6, 0xd1, 0x25, 0x28, 0xba, 0x51, 0x6f, 0x51, ++ 0x69, 0xf4, 0x41, 0x45, 0x75, 0x23, 0x25, 0x77, 0xef, 0xa8, 0x1c, 0x19, ++ 0x8a, 0x66, 0x8c, 0x61, 0x13, 0x37, 0x4f, 0xa3, 0xa1, 0x83, 0x17, 0x35, ++ 0x23, 0x2d, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x05, 0x34, 0x7e, 0x4d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x20, 0x73, ++ 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x20, 0x61, 0x70, 0x70, ++ 0x65, 0x6e, 0x64, 0x65, 0x64, 0x7e, 0x0a ++}; ++unsigned int hi_double_extended_len = 1375; ++ +unsigned char certificate_printable_der[] = { + 0x30, 0x82, 0x03, 0x39, 0x30, 0x82, 0x02, 0x21, 0xa0, 0x03, 0x02, 0x01, + 0x02, 0x02, 0x09, 0x00, 0xde, 0xf6, 0x22, 0xc4, 0xf2, 0xf1, 0x86, 0x02, @@ -895,3 +1215,94 @@ index 00000000000..aa3dc6278e3 + 0xd2 +}; +unsigned int certificate_printable_der_len = 829; ++ ++unsigned char certificate_eku_der[] = { ++ 0x30, 0x82, 0x03, 0x90, 0x30, 0x82, 0x02, 0x78, 0xa0, 0x03, 0x02, 0x01, ++ 0x02, 0x02, 0x09, 0x00, 0xd3, 0x9c, 0x41, 0x33, 0xdd, 0x6b, 0x5f, 0x45, ++ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, ++ 0x0b, 0x05, 0x00, 0x30, 0x47, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, ++ 0x04, 0x03, 0x0c, 0x18, 0x52, 0x65, 0x64, 0x20, 0x48, 0x61, 0x74, 0x20, ++ 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x20, ++ 0x43, 0x41, 0x20, 0x36, 0x31, 0x22, 0x30, 0x20, 0x06, 0x09, 0x2a, 0x86, ++ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x13, 0x73, 0x65, 0x63, ++ 0x61, 0x6c, 0x65, 0x72, 0x74, 0x40, 0x72, 0x65, 0x64, 0x68, 0x61, 0x74, ++ 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x32, ++ 0x31, 0x35, 0x31, 0x34, 0x30, 0x30, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x33, ++ 0x38, 0x30, 0x31, 0x31, 0x37, 0x31, 0x34, 0x30, 0x30, 0x34, 0x34, 0x5a, ++ 0x30, 0x4e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, ++ 0x1f, 0x52, 0x65, 0x64, 0x20, 0x48, 0x61, 0x74, 0x20, 0x53, 0x65, 0x63, ++ 0x75, 0x72, 0x65, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x20, 0x53, 0x69, 0x67, ++ 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x36, 0x30, 0x32, 0x31, 0x22, 0x30, 0x20, ++ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, ++ 0x13, 0x73, 0x65, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x40, 0x72, 0x65, ++ 0x64, 0x68, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, ++ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, ++ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, ++ 0x02, 0x82, 0x01, 0x01, 0x00, 0xaa, 0x6f, 0xbb, 0x92, 0x77, 0xd7, 0x15, ++ 0xef, 0x88, 0x80, 0x88, 0xc0, 0xe7, 0x89, 0xeb, 0x35, 0x76, 0xf4, 0x85, ++ 0x05, 0x0f, 0x19, 0xe4, 0x5f, 0x25, 0xdd, 0xc1, 0xa2, 0xe5, 0x5c, 0x06, ++ 0xfb, 0xf1, 0x06, 0xb5, 0x65, 0x45, 0xcb, 0xbd, 0x19, 0x33, 0x54, 0xb5, ++ 0x1a, 0xcd, 0xe4, 0xa8, 0x35, 0x2a, 0xfe, 0x9c, 0x53, 0xf4, 0xc6, 0x76, ++ 0xdb, 0x1f, 0x8a, 0xd4, 0x7b, 0x18, 0x11, 0xaf, 0xa3, 0x90, 0xd4, 0xdd, ++ 0x4d, 0xd5, 0x42, 0xcc, 0x14, 0x9a, 0x64, 0x6b, 0xc0, 0x7f, 0xaa, 0x1c, ++ 0x94, 0x47, 0x4d, 0x79, 0xbd, 0x57, 0x9a, 0xbf, 0x99, 0x4e, 0x96, 0xa9, ++ 0x31, 0x2c, 0xa9, 0xe7, 0x14, 0x65, 0x86, 0xc8, 0xac, 0x79, 0x5e, 0x78, ++ 0xa4, 0x3c, 0x00, 0x24, 0xd3, 0xf7, 0xe1, 0xf5, 0x12, 0xad, 0xa0, 0x29, ++ 0xe5, 0xfe, 0x80, 0xae, 0xf8, 0xaa, 0x60, 0x36, 0xe7, 0xe8, 0x94, 0xcb, ++ 0xe9, 0xd1, 0xcc, 0x0b, 0x4d, 0xf7, 0xde, 0xeb, 0x52, 0xd2, 0x73, 0x09, ++ 0x28, 0xdf, 0x48, 0x99, 0x53, 0x9f, 0xc5, 0x9a, 0xd4, 0x36, 0xa3, 0xc6, ++ 0x5e, 0x8d, 0xbe, 0xd5, 0xdc, 0x76, 0xb4, 0x74, 0xb8, 0x26, 0x18, 0x27, ++ 0xfb, 0xf2, 0xfb, 0xd0, 0x9b, 0x3d, 0x7f, 0x10, 0xe2, 0xab, 0x44, 0xc7, ++ 0x88, 0x7f, 0xb4, 0x3d, 0x3e, 0xa3, 0xff, 0x6d, 0x06, 0x4b, 0x3e, 0x55, ++ 0xb2, 0x84, 0xf4, 0xad, 0x54, 0x88, 0x81, 0xc3, 0x9c, 0xf8, 0xb6, 0x68, ++ 0x96, 0x38, 0x8b, 0xcd, 0x90, 0x6d, 0x25, 0x4b, 0xbf, 0x0c, 0x44, 0x90, ++ 0xa5, 0x5b, 0x98, 0xd0, 0x40, 0x2f, 0xbb, 0x0d, 0xa8, 0x4b, 0x8a, 0x62, ++ 0x82, 0x46, 0x46, 0x18, 0x38, 0xae, 0x82, 0x07, 0xd0, 0xb4, 0x2f, 0x16, ++ 0x79, 0x55, 0x9f, 0x1b, 0xc5, 0x08, 0x6d, 0x85, 0xdf, 0x3f, 0xa9, 0x9b, ++ 0x4b, 0xc6, 0x28, 0xd3, 0x58, 0x72, 0x3d, 0x37, 0x11, 0x02, 0x03, 0x01, ++ 0x00, 0x01, 0xa3, 0x78, 0x30, 0x76, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, ++ 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, ++ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, ++ 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, ++ 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, ++ 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6c, ++ 0xe4, 0x6c, 0x27, 0xaa, 0xcd, 0x0d, 0x4b, 0x74, 0x21, 0xa4, 0xf6, 0x5f, ++ 0x87, 0xb5, 0x31, 0xfe, 0x10, 0xbb, 0xa7, 0x30, 0x1f, 0x06, 0x03, 0x55, ++ 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe8, 0x6a, 0x1c, 0xab, ++ 0x2c, 0x48, 0xf9, 0x60, 0x36, 0xa2, 0xf0, 0x7b, 0x8e, 0xd2, 0x9d, 0xb4, ++ 0x2a, 0x28, 0x98, 0xc8, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, ++ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, ++ 0x55, 0x34, 0xe2, 0xfa, 0xf6, 0x89, 0x86, 0xad, 0x92, 0x21, 0xec, 0xb9, ++ 0x54, 0x0e, 0x18, 0x47, 0x0d, 0x1b, 0xa7, 0x58, 0xad, 0x69, 0xe4, 0xef, ++ 0x3b, 0xe6, 0x8d, 0xdd, 0xda, 0x0c, 0x45, 0xf6, 0xe8, 0x96, 0xa4, 0x29, ++ 0x0f, 0xbb, 0xcf, 0x16, 0xae, 0x93, 0xd0, 0xcb, 0x2a, 0x26, 0x1a, 0x7b, ++ 0xfc, 0x51, 0x22, 0x76, 0x98, 0x31, 0xa7, 0x0f, 0x29, 0x35, 0x79, 0xbf, ++ 0xe2, 0x4f, 0x0f, 0x14, 0xf5, 0x1f, 0xcb, 0xbf, 0x87, 0x65, 0x13, 0x32, ++ 0xa3, 0x19, 0x4a, 0xd1, 0x3f, 0x45, 0xd4, 0x4b, 0xe2, 0x00, 0x26, 0xa9, ++ 0x3e, 0xd7, 0xa5, 0x37, 0x9f, 0xf5, 0xad, 0x61, 0xe2, 0x40, 0xa9, 0x74, ++ 0x24, 0x53, 0xf2, 0x78, 0xeb, 0x10, 0x9b, 0x2c, 0x27, 0x88, 0x46, 0xcb, ++ 0xe4, 0x60, 0xca, 0xf5, 0x06, 0x24, 0x40, 0x2a, 0x97, 0x3a, 0xcc, 0xd0, ++ 0x81, 0xb1, 0x15, 0xa3, 0x4f, 0xd0, 0x2b, 0x4f, 0xca, 0x6e, 0xaa, 0x24, ++ 0x31, 0xb3, 0xac, 0xa6, 0x75, 0x05, 0xfe, 0x8a, 0xf4, 0x41, 0xc4, 0x06, ++ 0x8a, 0xc7, 0x0a, 0x83, 0x4e, 0x49, 0xd4, 0x3f, 0x83, 0x50, 0xec, 0x57, ++ 0x04, 0x97, 0x14, 0x49, 0xf5, 0xe1, 0xb1, 0x7a, 0x9c, 0x09, 0x4f, 0x61, ++ 0x87, 0xc3, 0x97, 0x22, 0x17, 0xc2, 0xeb, 0xcc, 0x32, 0x81, 0x31, 0x21, ++ 0x3f, 0x10, 0x57, 0x5b, 0x43, 0xbe, 0xcd, 0x68, 0x82, 0xbe, 0xe5, 0xc1, ++ 0x65, 0x94, 0x7e, 0xc2, 0x34, 0x76, 0x2b, 0xcf, 0x89, 0x3c, 0x2b, 0x81, ++ 0x23, 0x72, 0x95, 0xcf, 0xc9, 0x67, 0x19, 0x2a, 0xd5, 0x5c, 0xca, 0xa3, ++ 0x46, 0xbd, 0x48, 0x06, 0x0b, 0xa6, 0xa3, 0x96, 0x50, 0x28, 0xc7, 0x7e, ++ 0xcf, 0x62, 0xf2, 0xfa, 0xc4, 0xf2, 0x53, 0xe3, 0xc9, 0xe8, 0x2e, 0xdd, ++ 0x29, 0x37, 0x07, 0x47, 0xff, 0xff, 0x8a, 0x32, 0xbd, 0xa2, 0xb7, 0x21, ++ 0x89, 0xa0, 0x55, 0xf7 ++}; ++unsigned int certificate_eku_der_len = 916; +--- a/grub-core/tests/lib/functional_test.c ++++ b/grub-core/tests/lib/functional_test.c +@@ -73,6 +73,7 @@ + grub_dl_load ("xnu_uuid_test"); + grub_dl_load ("pbkdf2_test"); + grub_dl_load ("signature_test"); ++ grub_dl_load ("appended_signature_test"); + grub_dl_load ("sleep_test"); + grub_dl_load ("bswap_test"); + grub_dl_load ("ctz_test"); diff --git a/0177-appended-signatures-documentation.patch b/0021-appended-signatures-documentation.patch similarity index 73% rename from 0177-appended-signatures-documentation.patch rename to 0021-appended-signatures-documentation.patch index 864cfa3198e02b1ccfc59fd49cdbda13e7818035..a2709ac3c759029df7e45f2baa129aca5b610668 100644 --- a/0177-appended-signatures-documentation.patch +++ b/0021-appended-signatures-documentation.patch @@ -1,22 +1,24 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 4edb825a012e9e7b9ad08aa693cfdebf42ae40e6 Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Thu, 1 Oct 2020 13:02:09 +1000 -Subject: [PATCH] appended signatures: documentation +Subject: [PATCH 21/23] appended signatures: documentation This explains how appended signatures can be used to form part of a secure boot chain, and documents the commands and variables introduced. Signed-off-by: Daniel Axtens + +--- + +v2: fix a grammar issue, thanks Stefan Berger. --- - docs/grub.texi | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 182 insertions(+), 17 deletions(-) + docs/grub.texi | 193 +++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 176 insertions(+), 17 deletions(-) -diff --git a/docs/grub.texi b/docs/grub.texi -index afbde7c1f7b..4816be85611 100644 --- a/docs/grub.texi +++ b/docs/grub.texi -@@ -3214,6 +3214,7 @@ These variables have special meaning to GRUB. +@@ -3270,6 +3270,7 @@ @menu * biosnum:: @@ -24,7 +26,7 @@ index afbde7c1f7b..4816be85611 100644 * check_signatures:: * chosen:: * cmdpath:: -@@ -3273,11 +3274,18 @@ For an alternative approach which also changes BIOS drive mappings for the +@@ -3334,11 +3335,18 @@ chain-loaded system, @pxref{drivemap}. @@ -45,23 +47,23 @@ index afbde7c1f7b..4816be85611 100644 @node chosen @subsection chosen -@@ -3994,6 +4002,7 @@ you forget a command, you can run the command @command{help} +@@ -4357,6 +4365,7 @@ * date:: Display or set current date and time * devicetree:: Load a device tree blob * distrust:: Remove a pubkey from trusted keys +* distrust_certificate:: Remove a certificate from the list of trusted certificates * drivemap:: Map a drive to another * echo:: Display a line of text - * eval:: Evaluate agruments as GRUB commands -@@ -4010,6 +4019,7 @@ you forget a command, you can run the command @command{help} + * efitextmode:: Set/Get text output mode resolution +@@ -4373,6 +4382,7 @@ + * hexdump:: Show raw contents of a file or memory + * insmod:: Insert a module * keystatus:: Check key modifier status - * linux:: Load a Linux kernel - * linux16:: Load a Linux kernel (16-bit mode) +* list_certificates:: List trusted certificates * list_env:: List variables in environment block * list_trusted:: List trusted public keys * load_env:: Load variables from environment block -@@ -4047,8 +4057,10 @@ you forget a command, you can run the command @command{help} +@@ -4411,8 +4421,10 @@ * test:: Check file types and compare values * true:: Do nothing, successfully * trust:: Add public key to list of trusted keys @@ -71,15 +73,15 @@ index afbde7c1f7b..4816be85611 100644 +* verify_appended:: Verify appended digital signature * verify_detached:: Verify detached digital signature * videoinfo:: List available video modes - @comment * xen_*:: Xen boot commands for AArch64 -@@ -4376,9 +4388,28 @@ These keys are used to validate signatures when environment variable + * wrmsr:: Write values to model-specific registers +@@ -4752,9 +4764,28 @@ @code{check_signatures} is set to @code{enforce} (@pxref{check_signatures}), and by some invocations of @command{verify_detached} (@pxref{verify_detached}). @xref{Using -digital signatures}, for more information. +GPG-style digital signatures}, for more information. - @end deffn - ++@end deffn ++ + +@node distrust_certificate +@subsection distrust_certificate @@ -92,17 +94,17 @@ index afbde7c1f7b..4816be85611 100644 +@command{list_certificates} (@pxref{list_certificates}). + +These certificates are used to validate appended signatures when environment -+variable @code{check_appended_signatures} is set to @code{enforce} or -+@code{forced} (@pxref{check_appended_signatures}), and by -+@command{verify_appended} (@pxref{verify_appended}). See -+@xref{Using appended signatures} for more information. -+@end deffn -+ ++variable @code{check_appended_signatures} is set to @code{enforce} ++(@pxref{check_appended_signatures}), and by @command{verify_appended} ++(@pxref{verify_appended}). See @xref{Using appended signatures} for more ++information. + @end deffn + + @node drivemap @subsection drivemap -@@ -4636,6 +4667,21 @@ This command is only available on x86 systems. +@@ -5031,6 +5062,21 @@ @end deffn @@ -124,7 +126,7 @@ index afbde7c1f7b..4816be85611 100644 @node list_env @subsection list_env -@@ -4655,7 +4701,7 @@ The output is in GPG's v4 key fingerprint format (i.e., the output of +@@ -5050,7 +5096,7 @@ @code{gpg --fingerprint}). The least significant four bytes (last eight hexadecimal digits) can be used as an argument to @command{distrust} (@pxref{distrust}). @@ -133,7 +135,7 @@ index afbde7c1f7b..4816be85611 100644 these keys. @end deffn -@@ -4690,8 +4736,13 @@ When used with care, @option{--skip-sig} and the whitelist enable an +@@ -5085,8 +5131,12 @@ administrator to configure a system to boot only signed configurations, but to allow the user to select from among multiple configurations, and to enable ``one-shot'' boot attempts and @@ -143,12 +145,11 @@ index afbde7c1f7b..4816be85611 100644 + +Extra care should be taken when combining this command with appended signatures +(@pxref{Using appended signatures}), as this file is not validated by an -+appended signature and could set @code{check_appended_signatures=no} if GRUB is -+not in @pxref{Lockdown} mode. ++appended signature and could set @code{check_appended_signatures=no}. @end deffn -@@ -4987,7 +5038,7 @@ read. It is possible to modify a digitally signed environment block +@@ -5457,7 +5507,7 @@ file from within GRUB using this command, such that its signature will no longer be valid on subsequent boots. Care should be taken in such advanced configurations to avoid rendering the system @@ -157,7 +158,7 @@ index afbde7c1f7b..4816be85611 100644 @end deffn -@@ -5387,11 +5438,32 @@ signatures when environment variable @code{check_signatures} is set to +@@ -5873,11 +5923,31 @@ must itself be properly signed. The @option{--skip-sig} option can be used to disable signature-checking when reading @var{pubkey_file} itself. It is expected that @option{--skip-sig} is useful for testing @@ -171,18 +172,17 @@ index afbde7c1f7b..4816be85611 100644 +@subsection trust_certificate + +@deffn Command trust_certificate x509_certificate -+Read an DER-formatted x509 certificate from the file @var{x509_certificate} ++Read a DER-formatted x509 certificate from the file @var{x509_certificate} +and add it to GRUB's internal list of trusted x509 certificates. These +certificates are used to validate appended signatures when the environment -+variable @code{check_appended_signatures} is set to @code{enforce} or -+@code{forced}. ++variable @code{check_appended_signatures} is set to @code{enforce}. + -+Note that if @code{check_appended_signatures} is set to @code{enforce} or -+@code{forced} when @command{trust_certificate} is executed, then -+@var{x509_certificate} must itself bear an appended signature. (It is not -+sufficient that @var{x509_certificate} be signed by a trusted certificate -+according to the x509 rules: grub does not include support for validating -+signatures within x509 certificates themselves.) ++Note that if @code{check_appended_signatures} is set to @code{enforce} ++when @command{trust_certificate} is executed, then @var{x509_certificate} ++must itself bear an appended signature. (It is not sufficient that ++@var{x509_certificate} be signed by a trusted certificate according to the ++x509 rules: grub does not include support for validating signatures within x509 ++certificates themselves.) + +See @xref{Using appended signatures} for more information. +@end deffn @@ -191,7 +191,7 @@ index afbde7c1f7b..4816be85611 100644 @node unset @subsection unset -@@ -5410,6 +5482,18 @@ only on PC BIOS platforms. +@@ -5896,6 +5966,18 @@ @end deffn @end ignore @@ -210,7 +210,7 @@ index afbde7c1f7b..4816be85611 100644 @node verify_detached @subsection verify_detached -@@ -5428,7 +5512,7 @@ tried. +@@ -5914,7 +5996,7 @@ Exit code @code{$?} is set to 0 if the signature validates successfully. If validation fails, it is set to a non-zero value. @@ -219,7 +219,7 @@ index afbde7c1f7b..4816be85611 100644 @end deffn @node videoinfo -@@ -5811,13 +5895,14 @@ environment variables and commands are listed in the same order. +@@ -6394,13 +6476,14 @@ @chapter Security @menu @@ -241,7 +241,7 @@ index afbde7c1f7b..4816be85611 100644 @end menu @node Authentication and authorisation -@@ -5891,8 +5976,8 @@ generating configuration files with authentication. You can use +@@ -6474,8 +6557,8 @@ adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2} commands. @@ -252,7 +252,7 @@ index afbde7c1f7b..4816be85611 100644 GRUB's @file{core.img} can optionally provide enforcement that all files subsequently read from disk are covered by a valid digital signature. -@@ -5985,6 +6070,86 @@ or BIOS) configuration to cause the machine to boot from a different +@@ -6558,6 +6641,82 @@ (attacker-controlled) device. GRUB is at best only one link in a secure boot chain. @@ -268,7 +268,11 @@ index afbde7c1f7b..4816be85611 100644 +~Module signature appended~\n +@end example + -+where @code{\n} represents the line-feed character, @code{0x0a}. ++where @code{\n} represents the carriage-return character, @code{0x0a}. ++ ++To enable appended signature verification, load the appendedsig module and an ++x509 certificate for verification. Building the appendedsig module into the ++core grub image is recommended. + +Certificates can be managed at boot time using the @pxref{trust_certificate}, +@pxref{distrust_certificate} and @pxref{list_certificates} commands. @@ -289,32 +293,32 @@ index afbde7c1f7b..4816be85611 100644 +@end example + +Enforcement of signature verification is controlled by the -+@code{check_appended_signatures} variable. -+ -+@itemize -+@item @samp{no}: no verification is performed. This is the default when GRUB -+ is not in @pxref{Lockdown} mode. -+@item @samp{enforce}: verification is performed. Verification can be disabled -+ by setting the variable back to @samp{no}. -+@item @samp{forced}: verification is performed and cannot be disabled. This is -+ set when GRUB is in Lockdown when the appendedsig module is loaded. -+@end itemize ++@code{check_appended_signatures} variable. Verification will only take place ++when files are loaded if the variable is set to @code{enforce}. If a ++certificate is built into the grub core image with the @code{--x509} parameter, ++the variable will be automatically set to @code{enforce} when the appendedsig ++module is loaded. + +Unlike GPG-style signatures, not all files loaded by GRUB are required to be -+signed. Once verification is turned on, the following file types will have -+appended signatures verified: ++signed. Once verification is turned on, the following file types must carry ++appended signatures: + -+@itemize -+@item Linux kernels -+@item GRUB modules, except those built into the core image ++@enumerate ++@item Linux, Multiboot, BSD, XNU and Plan9 kernels ++@item Grub modules, except those built in to the core image +@item Any new certificate files to be trusted -+@end itemize ++@end enumerate + +ACPI tables and Device Tree images will not be checked for appended signatures +but must be verified by another mechanism such as GPG-style signatures before +they will be loaded. + -+Unless lockdown mode is enabled, signature checking does @strong{not} ++No attempt is made to validate any other file type. In particular, ++chain-loaded binaries are not verified - if your platform supports ++chain-loading and this cannot be disabled, consider an alternative secure ++boot mechanism. ++ ++As with GPG-style appended signatures, signature checking does @strong{not} +stop an attacker with console access from dropping manually to the GRUB +console and executing: + @@ -325,16 +329,8 @@ index afbde7c1f7b..4816be85611 100644 +Refer to the section on password-protecting GRUB (@pxref{Authentication +and authorisation}) for more information on preventing this. + -+Additionally, unless lockdown mode is enabled: -+ -+@itemize -+@item Special care must be taken around the @command{loadenv} command, which -+ can be used to turn off @code{check_appended_signature}. -+ -+@item If the grub configuration file is loaded from the disk, anyone who can -+ modify the file on disk can turn off @code{check_appended_signature}. -+ Consider embedding the configuration into the core grub image. -+@end itemize ++Additionally, special care must be taken around the @command{loadenv} command, ++which can be used to turn off @code{check_appended_signature}. + @node UEFI secure boot and shim @section UEFI secure boot and shim support diff --git a/0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch b/0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch deleted file mode 100644 index da65e1876863ad1c1066796714836ff9beb630b7..0000000000000000000000000000000000000000 --- a/0021-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch +++ /dev/null @@ -1,1609 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 22 Jan 2013 06:31:38 +0100 -Subject: [PATCH] blscfg: add blscfg module to parse Boot Loader Specification - snippets - -The BootLoaderSpec (BLS) defines a scheme where different bootloaders can -share a format for boot items and a configuration directory that accepts -these common configurations as drop-in files. - -Signed-off-by: Peter Jones -Signed-off-by: Javier Martinez Canillas -[wjt: some cleanups and fixes] -Signed-off-by: Will Thompson ---- - grub-core/Makefile.core.def | 11 + - grub-core/commands/blscfg.c | 1177 ++++++++++++++++++++++++++++++++++++++++ - grub-core/commands/legacycfg.c | 5 +- - grub-core/commands/loadenv.c | 77 +-- - grub-core/commands/menuentry.c | 20 +- - grub-core/normal/main.c | 6 + - grub-core/commands/loadenv.h | 93 ++++ - include/grub/compiler.h | 2 + - include/grub/menu.h | 13 + - include/grub/normal.h | 2 +- - 10 files changed, 1324 insertions(+), 82 deletions(-) - create mode 100644 grub-core/commands/blscfg.c - create mode 100644 grub-core/commands/loadenv.h - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index c865a08b027..c15e91943b9 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -814,6 +814,16 @@ module = { - common = commands/blocklist.c; - }; - -+module = { -+ name = blscfg; -+ common = commands/blscfg.c; -+ common = commands/loadenv.h; -+ enable = powerpc_ieee1275; -+ enable = efi; -+ enable = i386_pc; -+ enable = emu; -+}; -+ - module = { - name = boot; - common = commands/boot.c; -@@ -980,6 +990,7 @@ module = { - module = { - name = loadenv; - common = commands/loadenv.c; -+ common = commands/loadenv.h; - common = lib/envblk.c; - }; - -diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c -new file mode 100644 -index 00000000000..e907a6a5d28 ---- /dev/null -+++ b/grub-core/commands/blscfg.c -@@ -0,0 +1,1177 @@ -+/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/ -+ -+/* bls.c - implementation of the boot loader spec */ -+ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * -+ * 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+#include "loadenv.h" -+ -+#define GRUB_BLS_CONFIG_PATH "/loader/entries/" -+#ifdef GRUB_MACHINE_EMU -+#define GRUB_BOOT_DEVICE "/boot" -+#else -+#define GRUB_BOOT_DEVICE "($root)" -+#endif -+ -+struct keyval -+{ -+ const char *key; -+ char *val; -+}; -+ -+static struct bls_entry *entries = NULL; -+ -+#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries) -+ -+static int bls_add_keyval(struct bls_entry *entry, char *key, char *val) -+{ -+ char *k, *v; -+ struct keyval **kvs, *kv; -+ int new_n = entry->nkeyvals + 1; -+ -+ kvs = grub_realloc (entry->keyvals, new_n * sizeof (struct keyval *)); -+ if (!kvs) -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "couldn't find space for BLS entry"); -+ entry->keyvals = kvs; -+ -+ kv = grub_malloc (sizeof (struct keyval)); -+ if (!kv) -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "couldn't find space for BLS entry"); -+ -+ k = grub_strdup (key); -+ if (!k) -+ { -+ grub_free (kv); -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "couldn't find space for BLS entry"); -+ } -+ -+ v = grub_strdup (val); -+ if (!v) -+ { -+ grub_free (k); -+ grub_free (kv); -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "couldn't find space for BLS entry"); -+ } -+ -+ kv->key = k; -+ kv->val = v; -+ -+ entry->keyvals[entry->nkeyvals] = kv; -+ grub_dprintf("blscfg", "new keyval at %p:%s:%s\n", entry->keyvals[entry->nkeyvals], k, v); -+ entry->nkeyvals = new_n; -+ -+ return 0; -+} -+ -+/* Find they value of the key named by keyname. If there are allowed to be -+ * more than one, pass a pointer to an int set to -1 the first time, and pass -+ * the same pointer through each time after, and it'll return them in sorted -+ * order as defined in the BLS fragment file */ -+static char *bls_get_val(struct bls_entry *entry, const char *keyname, int *last) -+{ -+ int idx, start = 0; -+ struct keyval *kv = NULL; -+ -+ if (last) -+ start = *last + 1; -+ -+ for (idx = start; idx < entry->nkeyvals; idx++) { -+ kv = entry->keyvals[idx]; -+ -+ if (!grub_strcmp (keyname, kv->key)) -+ break; -+ } -+ -+ if (idx == entry->nkeyvals) { -+ if (last) -+ *last = -1; -+ return NULL; -+ } -+ -+ if (last) -+ *last = idx; -+ -+ return kv->val; -+} -+ -+#define goto_return(x) ({ ret = (x); goto finish; }) -+ -+/* compare alpha and numeric segments of two versions */ -+/* return 1: a is newer than b */ -+/* 0: a and b are the same version */ -+/* -1: b is newer than a */ -+static int vercmp(const char * a, const char * b) -+{ -+ char oldch1, oldch2; -+ char *abuf, *bbuf; -+ char *str1, *str2; -+ char * one, * two; -+ int rc; -+ int isnum; -+ int ret = 0; -+ -+ grub_dprintf("blscfg", "%s comparing %s and %s\n", __func__, a, b); -+ if (!grub_strcmp(a, b)) -+ return 0; -+ -+ abuf = grub_malloc(grub_strlen(a) + 1); -+ bbuf = grub_malloc(grub_strlen(b) + 1); -+ str1 = abuf; -+ str2 = bbuf; -+ grub_strcpy(str1, a); -+ grub_strcpy(str2, b); -+ -+ one = str1; -+ two = str2; -+ -+ /* loop through each version segment of str1 and str2 and compare them */ -+ while (*one || *two) { -+ while (*one && !grub_isalnum(*one) && *one != '~' && *one != '+') one++; -+ while (*two && !grub_isalnum(*two) && *two != '~' && *two != '+') two++; -+ -+ /* handle the tilde separator, it sorts before everything else */ -+ if (*one == '~' || *two == '~') { -+ if (*one != '~') goto_return (1); -+ if (*two != '~') goto_return (-1); -+ one++; -+ two++; -+ continue; -+ } -+ -+ /* -+ * Handle plus separator. Concept is the same as tilde, -+ * except that if one of the strings ends (base version), -+ * the other is considered as higher version. -+ */ -+ if (*one == '+' || *two == '+') { -+ if (!*one) return -1; -+ if (!*two) return 1; -+ if (*one != '+') goto_return (1); -+ if (*two != '+') goto_return (-1); -+ one++; -+ two++; -+ continue; -+ } -+ -+ /* If we ran to the end of either, we are finished with the loop */ -+ if (!(*one && *two)) break; -+ -+ str1 = one; -+ str2 = two; -+ -+ /* grab first completely alpha or completely numeric segment */ -+ /* leave one and two pointing to the start of the alpha or numeric */ -+ /* segment and walk str1 and str2 to end of segment */ -+ if (grub_isdigit(*str1)) { -+ while (*str1 && grub_isdigit(*str1)) str1++; -+ while (*str2 && grub_isdigit(*str2)) str2++; -+ isnum = 1; -+ } else { -+ while (*str1 && grub_isalpha(*str1)) str1++; -+ while (*str2 && grub_isalpha(*str2)) str2++; -+ isnum = 0; -+ } -+ -+ /* save character at the end of the alpha or numeric segment */ -+ /* so that they can be restored after the comparison */ -+ oldch1 = *str1; -+ *str1 = '\0'; -+ oldch2 = *str2; -+ *str2 = '\0'; -+ -+ /* this cannot happen, as we previously tested to make sure that */ -+ /* the first string has a non-null segment */ -+ if (one == str1) goto_return(-1); /* arbitrary */ -+ -+ /* take care of the case where the two version segments are */ -+ /* different types: one numeric, the other alpha (i.e. empty) */ -+ /* numeric segments are always newer than alpha segments */ -+ /* XXX See patch #60884 (and details) from bugzilla #50977. */ -+ if (two == str2) goto_return (isnum ? 1 : -1); -+ -+ if (isnum) { -+ grub_size_t onelen, twolen; -+ /* this used to be done by converting the digit segments */ -+ /* to ints using atoi() - it's changed because long */ -+ /* digit segments can overflow an int - this should fix that. */ -+ -+ /* throw away any leading zeros - it's a number, right? */ -+ while (*one == '0') one++; -+ while (*two == '0') two++; -+ -+ /* whichever number has more digits wins */ -+ onelen = grub_strlen(one); -+ twolen = grub_strlen(two); -+ if (onelen > twolen) goto_return (1); -+ if (twolen > onelen) goto_return (-1); -+ } -+ -+ /* grub_strcmp will return which one is greater - even if the two */ -+ /* segments are alpha or if they are numeric. don't return */ -+ /* if they are equal because there might be more segments to */ -+ /* compare */ -+ rc = grub_strcmp(one, two); -+ if (rc) goto_return (rc < 1 ? -1 : 1); -+ -+ /* restore character that was replaced by null above */ -+ *str1 = oldch1; -+ one = str1; -+ *str2 = oldch2; -+ two = str2; -+ } -+ -+ /* this catches the case where all numeric and alpha segments have */ -+ /* compared identically but the segment sepparating characters were */ -+ /* different */ -+ if ((!*one) && (!*two)) goto_return (0); -+ -+ /* whichever version still has characters left over wins */ -+ if (!*one) goto_return (-1); else goto_return (1); -+ -+finish: -+ grub_free (abuf); -+ grub_free (bbuf); -+ return ret; -+} -+ -+/* returns name/version/release */ -+/* NULL string pointer returned if nothing found */ -+static void -+split_package_string (char *package_string, char **name, -+ char **version, char **release) -+{ -+ char *package_version, *package_release; -+ -+ /* Release */ -+ package_release = grub_strrchr (package_string, '-'); -+ -+ if (package_release != NULL) -+ *package_release++ = '\0'; -+ -+ *release = package_release; -+ -+ if (name == NULL) -+ { -+ *version = package_string; -+ } -+ else -+ { -+ /* Version */ -+ package_version = grub_strrchr(package_string, '-'); -+ -+ if (package_version != NULL) -+ *package_version++ = '\0'; -+ -+ *version = package_version; -+ /* Name */ -+ *name = package_string; -+ } -+ -+ /* Bubble up non-null values from release to name */ -+ if (name != NULL && *name == NULL) -+ { -+ *name = (*version == NULL ? *release : *version); -+ *version = *release; -+ *release = NULL; -+ } -+ if (*version == NULL) -+ { -+ *version = *release; -+ *release = NULL; -+ } -+} -+ -+static int -+split_cmp(char *nvr0, char *nvr1, int has_name) -+{ -+ int ret = 0; -+ char *name0, *version0, *release0; -+ char *name1, *version1, *release1; -+ -+ split_package_string(nvr0, has_name ? &name0 : NULL, &version0, &release0); -+ split_package_string(nvr1, has_name ? &name1 : NULL, &version1, &release1); -+ -+ if (has_name) -+ { -+ ret = vercmp(name0 == NULL ? "" : name0, -+ name1 == NULL ? "" : name1); -+ if (ret != 0) -+ return ret; -+ } -+ -+ ret = vercmp(version0 == NULL ? "" : version0, -+ version1 == NULL ? "" : version1); -+ if (ret != 0) -+ return ret; -+ -+ ret = vercmp(release0 == NULL ? "" : release0, -+ release1 == NULL ? "" : release1); -+ return ret; -+} -+ -+/* return 1: e0 is newer than e1 */ -+/* 0: e0 and e1 are the same version */ -+/* -1: e1 is newer than e0 */ -+static int bls_cmp(const struct bls_entry *e0, const struct bls_entry *e1) -+{ -+ char *id0, *id1; -+ int r; -+ -+ id0 = grub_strdup(e0->filename); -+ id1 = grub_strdup(e1->filename); -+ -+ r = split_cmp(id0, id1, 1); -+ -+ grub_free(id0); -+ grub_free(id1); -+ -+ return r; -+} -+ -+static void list_add_tail(struct bls_entry *head, struct bls_entry *item) -+{ -+ item->next = head; -+ if (head->prev) -+ head->prev->next = item; -+ item->prev = head->prev; -+ head->prev = item; -+} -+ -+static int bls_add_entry(struct bls_entry *entry) -+{ -+ struct bls_entry *e, *last = NULL; -+ int rc; -+ -+ if (!entries) { -+ grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); -+ entries = entry; -+ return 0; -+ } -+ -+ FOR_BLS_ENTRIES(e) { -+ rc = bls_cmp(entry, e); -+ -+ if (!rc) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ if (rc == 1) { -+ grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); -+ list_add_tail (e, entry); -+ if (e == entries) { -+ entries = entry; -+ entry->prev = NULL; -+ } -+ return 0; -+ } -+ last = e; -+ } -+ -+ if (last) { -+ grub_dprintf ("blscfg", "Add entry with id \"%s\"\n", entry->filename); -+ last->next = entry; -+ entry->prev = last; -+ } -+ -+ return 0; -+} -+ -+struct read_entry_info { -+ const char *devid; -+ const char *dirname; -+ grub_file_t file; -+}; -+ -+static int read_entry ( -+ const char *filename, -+ const struct grub_dirhook_info *dirhook_info UNUSED, -+ void *data) -+{ -+ grub_size_t m = 0, n, clip = 0; -+ int rc = 0; -+ char *p = NULL; -+ grub_file_t f = NULL; -+ struct bls_entry *entry; -+ struct read_entry_info *info = (struct read_entry_info *)data; -+ -+ grub_dprintf ("blscfg", "filename: \"%s\"\n", filename); -+ -+ n = grub_strlen (filename); -+ -+ if (info->file) -+ { -+ f = info->file; -+ } -+ else -+ { -+ if (filename[0] == '.') -+ return 0; -+ -+ if (n <= 5) -+ return 0; -+ -+ if (grub_strcmp (filename + n - 5, ".conf") != 0) -+ return 0; -+ -+ p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename); -+ -+ f = grub_file_open (p, GRUB_FILE_TYPE_CONFIG); -+ if (!f) -+ goto finish; -+ } -+ -+ entry = grub_zalloc (sizeof (*entry)); -+ if (!entry) -+ goto finish; -+ -+ if (info->file) -+ { -+ char *slash; -+ -+ if (n > 5 && !grub_strcmp (filename + n - 5, ".conf") == 0) -+ clip = 5; -+ -+ slash = grub_strrchr (filename, '/'); -+ if (!slash) -+ slash = grub_strrchr (filename, '\\'); -+ -+ while (*slash == '/' || *slash == '\\') -+ slash++; -+ -+ m = slash ? slash - filename : 0; -+ } -+ else -+ { -+ m = 0; -+ clip = 5; -+ } -+ n -= m; -+ -+ entry->filename = grub_strndup(filename + m, n - clip); -+ if (!entry->filename) -+ goto finish; -+ -+ entry->filename[n - 5] = '\0'; -+ -+ for (;;) -+ { -+ char *buf; -+ char *separator; -+ -+ buf = grub_file_getline (f); -+ if (!buf) -+ break; -+ -+ while (buf && buf[0] && (buf[0] == ' ' || buf[0] == '\t')) -+ buf++; -+ if (buf[0] == '#') -+ continue; -+ -+ separator = grub_strchr (buf, ' '); -+ -+ if (!separator) -+ separator = grub_strchr (buf, '\t'); -+ -+ if (!separator || separator[1] == '\0') -+ { -+ grub_free (buf); -+ break; -+ } -+ -+ separator[0] = '\0'; -+ -+ do { -+ separator++; -+ } while (*separator == ' ' || *separator == '\t'); -+ -+ rc = bls_add_keyval (entry, buf, separator); -+ grub_free (buf); -+ if (rc < 0) -+ break; -+ } -+ -+ if (!rc) -+ bls_add_entry(entry); -+ -+finish: -+ if (p) -+ grub_free (p); -+ -+ if (f) -+ grub_file_close (f); -+ -+ return 0; -+} -+ -+static grub_envblk_t saved_env = NULL; -+ -+static int UNUSED -+save_var (const char *name, const char *value, void *whitelist UNUSED) -+{ -+ const char *val = grub_env_get (name); -+ grub_dprintf("blscfg", "saving \"%s\"\n", name); -+ -+ if (val) -+ grub_envblk_set (saved_env, name, value); -+ -+ return 0; -+} -+ -+static int UNUSED -+unset_var (const char *name, const char *value UNUSED, void *whitelist) -+{ -+ grub_dprintf("blscfg", "restoring \"%s\"\n", name); -+ if (! whitelist) -+ { -+ grub_env_unset (name); -+ return 0; -+ } -+ -+ if (test_whitelist_membership (name, -+ (const grub_env_whitelist_t *) whitelist)) -+ grub_env_unset (name); -+ -+ return 0; -+} -+ -+static char **bls_make_list (struct bls_entry *entry, const char *key, int *num) -+{ -+ int last = -1; -+ char *val; -+ -+ int nlist = 0; -+ char **list = NULL; -+ -+ list = grub_malloc (sizeof (char *)); -+ if (!list) -+ return NULL; -+ list[0] = NULL; -+ -+ while (1) -+ { -+ char **new; -+ -+ val = bls_get_val (entry, key, &last); -+ if (!val) -+ break; -+ -+ new = grub_realloc (list, (nlist + 2) * sizeof (char *)); -+ if (!new) -+ break; -+ -+ list = new; -+ list[nlist++] = val; -+ list[nlist] = NULL; -+ } -+ -+ if (!nlist) -+ { -+ grub_free (list); -+ return NULL; -+ } -+ -+ if (num) -+ *num = nlist; -+ -+ return list; -+} -+ -+static char *field_append(bool is_var, char *buffer, const char *start, const char *end) -+{ -+ char *tmp = grub_strndup(start, end - start + 1); -+ const char *field = tmp; -+ int term = is_var ? 2 : 1; -+ -+ if (is_var) { -+ field = grub_env_get (tmp); -+ if (!field) -+ return buffer; -+ } -+ -+ if (!buffer) -+ buffer = grub_zalloc (grub_strlen(field) + term); -+ else -+ buffer = grub_realloc (buffer, grub_strlen(buffer) + grub_strlen(field) + term); -+ -+ if (!buffer) -+ return NULL; -+ -+ tmp = buffer + grub_strlen(buffer); -+ tmp = grub_stpcpy (tmp, field); -+ -+ if (is_var) -+ tmp = grub_stpcpy (tmp, " "); -+ -+ return buffer; -+} -+ -+static char *expand_val(const char *value) -+{ -+ char *buffer = NULL; -+ const char *start = value; -+ const char *end = value; -+ bool is_var = false; -+ -+ if (!value) -+ return NULL; -+ -+ while (*value) { -+ if (*value == '$') { -+ if (start != end) { -+ buffer = field_append(is_var, buffer, start, end); -+ if (!buffer) -+ return NULL; -+ } -+ -+ is_var = true; -+ start = value + 1; -+ } else if (is_var) { -+ if (!grub_isalnum(*value) && *value != '_') { -+ buffer = field_append(is_var, buffer, start, end); -+ is_var = false; -+ start = value; -+ if (*start == ' ') -+ start++; -+ } -+ } -+ -+ end = value; -+ value++; -+ } -+ -+ if (start != end) { -+ buffer = field_append(is_var, buffer, start, end); -+ if (!buffer) -+ return NULL; -+ } -+ -+ return buffer; -+} -+ -+static char **early_initrd_list (const char *initrd) -+{ -+ int nlist = 0; -+ char **list = NULL; -+ char *separator; -+ -+ while ((separator = grub_strchr (initrd, ' '))) -+ { -+ list = grub_realloc (list, (nlist + 2) * sizeof (char *)); -+ if (!list) -+ return NULL; -+ -+ list[nlist++] = grub_strndup(initrd, separator - initrd); -+ list[nlist] = NULL; -+ initrd = separator + 1; -+ } -+ -+ list = grub_realloc (list, (nlist + 2) * sizeof (char *)); -+ if (!list) -+ return NULL; -+ -+ list[nlist++] = grub_strndup(initrd, grub_strlen(initrd)); -+ list[nlist] = NULL; -+ -+ return list; -+} -+ -+static void create_entry (struct bls_entry *entry) -+{ -+ int argc = 0; -+ const char **argv = NULL; -+ -+ char *title = NULL; -+ char *clinux = NULL; -+ char *options = NULL; -+ char **initrds = NULL; -+ char *initrd = NULL; -+ const char *early_initrd = NULL; -+ char **early_initrds = NULL; -+ char *initrd_prefix = NULL; -+ char *devicetree = NULL; -+ char *dt = NULL; -+ char *id = entry->filename; -+ char *dotconf = id; -+ char *hotkey = NULL; -+ -+ char *users = NULL; -+ char **classes = NULL; -+ -+ char **args = NULL; -+ -+ char *src = NULL; -+ int i, index; -+ bool add_dt_prefix = false; -+ -+ grub_dprintf("blscfg", "%s got here\n", __func__); -+ clinux = bls_get_val (entry, "linux", NULL); -+ if (!clinux) -+ { -+ grub_dprintf ("blscfg", "Skipping file %s with no 'linux' key.\n", entry->filename); -+ goto finish; -+ } -+ -+ /* -+ * strip the ".conf" off the end before we make it our "id" field. -+ */ -+ do -+ { -+ dotconf = grub_strstr(dotconf, ".conf"); -+ } while (dotconf != NULL && dotconf[5] != '\0'); -+ if (dotconf) -+ dotconf[0] = '\0'; -+ -+ title = bls_get_val (entry, "title", NULL); -+ options = expand_val (bls_get_val (entry, "options", NULL)); -+ -+ if (!options) -+ options = expand_val (grub_env_get("default_kernelopts")); -+ -+ initrds = bls_make_list (entry, "initrd", NULL); -+ -+ devicetree = expand_val (bls_get_val (entry, "devicetree", NULL)); -+ -+ if (!devicetree) -+ { -+ devicetree = expand_val (grub_env_get("devicetree")); -+ add_dt_prefix = true; -+ } -+ -+ hotkey = bls_get_val (entry, "grub_hotkey", NULL); -+ users = expand_val (bls_get_val (entry, "grub_users", NULL)); -+ classes = bls_make_list (entry, "grub_class", NULL); -+ args = bls_make_list (entry, "grub_arg", &argc); -+ -+ argc += 1; -+ argv = grub_malloc ((argc + 1) * sizeof (char *)); -+ argv[0] = title ? title : clinux; -+ for (i = 1; i < argc; i++) -+ argv[i] = args[i-1]; -+ argv[argc] = NULL; -+ -+ early_initrd = grub_env_get("early_initrd"); -+ -+ grub_dprintf ("blscfg", "adding menu entry for \"%s\" with id \"%s\"\n", -+ title, id); -+ if (early_initrd) -+ { -+ early_initrds = early_initrd_list(early_initrd); -+ if (!early_initrds) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto finish; -+ } -+ -+ if (initrds != NULL && initrds[0] != NULL) -+ { -+ initrd_prefix = grub_strrchr (initrds[0], '/'); -+ initrd_prefix = grub_strndup(initrds[0], initrd_prefix - initrds[0] + 1); -+ } -+ else -+ { -+ initrd_prefix = grub_strrchr (clinux, '/'); -+ initrd_prefix = grub_strndup(clinux, initrd_prefix - clinux + 1); -+ } -+ -+ if (!initrd_prefix) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto finish; -+ } -+ } -+ -+ if (early_initrds || initrds) -+ { -+ int initrd_size = sizeof ("initrd"); -+ char *tmp; -+ -+ for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++) -+ initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \ -+ + grub_strlen(initrd_prefix) \ -+ + grub_strlen (early_initrds[i]) + 1; -+ -+ for (i = 0; initrds != NULL && initrds[i] != NULL; i++) -+ initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \ -+ + grub_strlen (initrds[i]) + 1; -+ initrd_size += 1; -+ -+ initrd = grub_malloc (initrd_size); -+ if (!initrd) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto finish; -+ } -+ -+ tmp = grub_stpcpy(initrd, "initrd"); -+ for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++) -+ { -+ grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]); -+ tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE); -+ tmp = grub_stpcpy (tmp, initrd_prefix); -+ tmp = grub_stpcpy (tmp, early_initrds[i]); -+ grub_free(early_initrds[i]); -+ } -+ -+ for (i = 0; initrds != NULL && initrds[i] != NULL; i++) -+ { -+ grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]); -+ tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE); -+ tmp = grub_stpcpy (tmp, initrds[i]); -+ } -+ tmp = grub_stpcpy (tmp, "\n"); -+ } -+ -+ if (devicetree) -+ { -+ char *prefix = NULL; -+ int dt_size; -+ -+ if (add_dt_prefix) -+ { -+ prefix = grub_strrchr (clinux, '/'); -+ prefix = grub_strndup(clinux, prefix - clinux + 1); -+ if (!prefix) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto finish; -+ } -+ } -+ -+ dt_size = sizeof("devicetree " GRUB_BOOT_DEVICE) + grub_strlen(devicetree) + 1; -+ -+ if (add_dt_prefix) -+ { -+ dt_size += grub_strlen(prefix); -+ } -+ -+ dt = grub_malloc (dt_size); -+ if (!dt) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto finish; -+ } -+ char *tmp = dt; -+ tmp = grub_stpcpy (dt, "devicetree"); -+ tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE); -+ if (add_dt_prefix) -+ tmp = grub_stpcpy (tmp, prefix); -+ tmp = grub_stpcpy (tmp, devicetree); -+ tmp = grub_stpcpy (tmp, "\n"); -+ -+ grub_free(prefix); -+ } -+ -+ grub_dprintf ("blscfg2", "devicetree %s for id:\"%s\"\n", dt, id); -+ -+ const char *sdval = grub_env_get("save_default"); -+ bool savedefault = ((NULL != sdval) && (grub_strcmp(sdval, "true") == 0)); -+ src = grub_xasprintf ("%sload_video\n" -+ "set gfxpayload=keep\n" -+ "insmod gzio\n" -+ "linux %s%s%s%s\n" -+ "%s%s", -+ savedefault ? "savedefault\n" : "", -+ GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "", -+ initrd ? initrd : "", dt ? dt : ""); -+ -+ grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, &index, entry); -+ grub_dprintf ("blscfg", "Added entry %d id:\"%s\"\n", index, id); -+ -+finish: -+ grub_free (dt); -+ grub_free (initrd); -+ grub_free (initrd_prefix); -+ grub_free (early_initrds); -+ grub_free (devicetree); -+ grub_free (initrds); -+ grub_free (options); -+ grub_free (classes); -+ grub_free (args); -+ grub_free (argv); -+ grub_free (src); -+} -+ -+struct find_entry_info { -+ const char *dirname; -+ const char *devid; -+ grub_device_t dev; -+ grub_fs_t fs; -+}; -+ -+/* -+ * info: the filesystem object the file is on. -+ */ -+static int find_entry (struct find_entry_info *info) -+{ -+ struct read_entry_info read_entry_info; -+ grub_fs_t blsdir_fs = NULL; -+ grub_device_t blsdir_dev = NULL; -+ const char *blsdir = info->dirname; -+ int fallback = 0; -+ int r = 0; -+ -+ if (!blsdir) { -+ blsdir = grub_env_get ("blsdir"); -+ if (!blsdir) -+ blsdir = GRUB_BLS_CONFIG_PATH; -+ } -+ -+ read_entry_info.file = NULL; -+ read_entry_info.dirname = blsdir; -+ -+ grub_dprintf ("blscfg", "scanning blsdir: %s\n", blsdir); -+ -+ blsdir_dev = info->dev; -+ blsdir_fs = info->fs; -+ read_entry_info.devid = info->devid; -+ -+read_fallback: -+ r = blsdir_fs->fs_dir (blsdir_dev, read_entry_info.dirname, read_entry, -+ &read_entry_info); -+ if (r != 0) { -+ grub_dprintf ("blscfg", "read_entry returned error\n"); -+ grub_err_t e; -+ do -+ { -+ e = grub_error_pop(); -+ } while (e); -+ } -+ -+ if (r && !info->dirname && !fallback) { -+ read_entry_info.dirname = "/boot" GRUB_BLS_CONFIG_PATH; -+ grub_dprintf ("blscfg", "Entries weren't found in %s, fallback to %s\n", -+ blsdir, read_entry_info.dirname); -+ fallback = 1; -+ goto read_fallback; -+ } -+ -+ return 0; -+} -+ -+static grub_err_t -+bls_load_entries (const char *path) -+{ -+ grub_size_t len; -+ grub_fs_t fs; -+ grub_device_t dev; -+ static grub_err_t r; -+ const char *devid = NULL; -+ char *blsdir = NULL; -+ struct find_entry_info info = { -+ .dev = NULL, -+ .fs = NULL, -+ .dirname = NULL, -+ }; -+ struct read_entry_info rei = { -+ .devid = NULL, -+ .dirname = NULL, -+ }; -+ -+ if (path) { -+ len = grub_strlen (path); -+ if (grub_strcmp (path + len - 5, ".conf") == 0) { -+ rei.file = grub_file_open (path, GRUB_FILE_TYPE_CONFIG); -+ if (!rei.file) -+ return grub_errno; -+ /* -+ * read_entry() closes the file -+ */ -+ return read_entry(path, NULL, &rei); -+ } else if (path[0] == '(') { -+ devid = path + 1; -+ -+ blsdir = grub_strchr (path, ')'); -+ if (!blsdir) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Filepath isn't correct")); -+ -+ *blsdir = '\0'; -+ blsdir = blsdir + 1; -+ } -+ } -+ -+ if (!devid) { -+#ifdef GRUB_MACHINE_EMU -+ devid = "host"; -+#else -+ devid = grub_env_get ("root"); -+#endif -+ if (!devid) -+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, -+ N_("variable `%s' isn't set"), "root"); -+ } -+ -+ grub_dprintf ("blscfg", "opening %s\n", devid); -+ dev = grub_device_open (devid); -+ if (!dev) -+ return grub_errno; -+ -+ grub_dprintf ("blscfg", "probing fs\n"); -+ fs = grub_fs_probe (dev); -+ if (!fs) -+ { -+ r = grub_errno; -+ goto finish; -+ } -+ -+ info.dirname = blsdir; -+ info.devid = devid; -+ info.dev = dev; -+ info.fs = fs; -+ find_entry(&info); -+ -+finish: -+ if (dev) -+ grub_device_close (dev); -+ -+ return r; -+} -+ -+static bool -+is_default_entry(const char *def_entry, struct bls_entry *entry, int idx) -+{ -+ const char *title; -+ int def_idx; -+ -+ if (!def_entry) -+ return false; -+ -+ if (grub_strcmp(def_entry, entry->filename) == 0) -+ return true; -+ -+ title = bls_get_val(entry, "title", NULL); -+ -+ if (title && grub_strcmp(def_entry, title) == 0) -+ return true; -+ -+ def_idx = (int)grub_strtol(def_entry, NULL, 0); -+ if (grub_errno == GRUB_ERR_BAD_NUMBER) { -+ grub_errno = GRUB_ERR_NONE; -+ return false; -+ } -+ -+ if (def_idx == idx) -+ return true; -+ -+ return false; -+} -+ -+static grub_err_t -+bls_create_entries (bool show_default, bool show_non_default, char *entry_id) -+{ -+ const char *def_entry = NULL; -+ struct bls_entry *entry = NULL; -+ int idx = 0; -+ -+ def_entry = grub_env_get("default"); -+ -+ grub_dprintf ("blscfg", "%s Creating entries from bls\n", __func__); -+ FOR_BLS_ENTRIES(entry) { -+ if (entry->visible) { -+ idx++; -+ continue; -+ } -+ -+ if ((show_default && is_default_entry(def_entry, entry, idx)) || -+ (show_non_default && !is_default_entry(def_entry, entry, idx)) || -+ (entry_id && grub_strcmp(entry_id, entry->filename) == 0)) { -+ create_entry(entry); -+ entry->visible = 1; -+ } -+ idx++; -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED, -+ int argc, char **args) -+{ -+ grub_err_t r; -+ char *path = NULL; -+ char *entry_id = NULL; -+ bool show_default = true; -+ bool show_non_default = true; -+ -+ if (argc == 1) { -+ if (grub_strcmp (args[0], "default") == 0) { -+ show_non_default = false; -+ } else if (grub_strcmp (args[0], "non-default") == 0) { -+ show_default = false; -+ } else if (args[0][0] == '(') { -+ path = args[0]; -+ } else { -+ entry_id = args[0]; -+ show_default = false; -+ show_non_default = false; -+ } -+ } -+ -+ r = bls_load_entries(path); -+ if (r) -+ return r; -+ -+ return bls_create_entries(show_default, show_non_default, entry_id); -+} -+ -+static grub_extcmd_t cmd; -+static grub_extcmd_t oldcmd; -+ -+GRUB_MOD_INIT(blscfg) -+{ -+ grub_dprintf("blscfg", "%s got here\n", __func__); -+ cmd = grub_register_extcmd ("blscfg", -+ grub_cmd_blscfg, -+ 0, -+ NULL, -+ N_("Import Boot Loader Specification snippets."), -+ NULL); -+ oldcmd = grub_register_extcmd ("bls_import", -+ grub_cmd_blscfg, -+ 0, -+ NULL, -+ N_("Import Boot Loader Specification snippets."), -+ NULL); -+} -+ -+GRUB_MOD_FINI(blscfg) -+{ -+ grub_unregister_extcmd (cmd); -+ grub_unregister_extcmd (oldcmd); -+} -diff --git a/grub-core/commands/legacycfg.c b/grub-core/commands/legacycfg.c -index cc5971f4dbd..782761c31aa 100644 ---- a/grub-core/commands/legacycfg.c -+++ b/grub-core/commands/legacycfg.c -@@ -143,7 +143,7 @@ legacy_file (const char *filename) - args[0] = oldname; - grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy", - NULL, NULL, -- entrysrc, 0); -+ entrysrc, 0, NULL, NULL); - grub_free (args); - entrysrc[0] = 0; - grub_free (oldname); -@@ -205,7 +205,8 @@ legacy_file (const char *filename) - } - args[0] = entryname; - grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, -- NULL, NULL, entrysrc, 0); -+ NULL, NULL, entrysrc, 0, NULL, -+ NULL); - grub_free (args); - } - -diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c -index 3fd664aac33..163b9a09042 100644 ---- a/grub-core/commands/loadenv.c -+++ b/grub-core/commands/loadenv.c -@@ -28,6 +28,8 @@ - #include - #include - -+#include "loadenv.h" -+ - GRUB_MOD_LICENSE ("GPLv3+"); - - static const struct grub_arg_option options[] = -@@ -79,81 +81,6 @@ open_envblk_file (char *filename, - return file; - } - --static grub_envblk_t --read_envblk_file (grub_file_t file) --{ -- grub_off_t offset = 0; -- char *buf; -- grub_size_t size = grub_file_size (file); -- grub_envblk_t envblk; -- -- buf = grub_malloc (size); -- if (! buf) -- return 0; -- -- while (size > 0) -- { -- grub_ssize_t ret; -- -- ret = grub_file_read (file, buf + offset, size); -- if (ret <= 0) -- { -- grub_free (buf); -- return 0; -- } -- -- size -= ret; -- offset += ret; -- } -- -- envblk = grub_envblk_open (buf, offset); -- if (! envblk) -- { -- grub_free (buf); -- grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block"); -- return 0; -- } -- -- return envblk; --} -- --struct grub_env_whitelist --{ -- grub_size_t len; -- char **list; --}; --typedef struct grub_env_whitelist grub_env_whitelist_t; -- --static int --test_whitelist_membership (const char* name, -- const grub_env_whitelist_t* whitelist) --{ -- grub_size_t i; -- -- for (i = 0; i < whitelist->len; i++) -- if (grub_strcmp (name, whitelist->list[i]) == 0) -- return 1; /* found it */ -- -- return 0; /* not found */ --} -- --/* Helper for grub_cmd_load_env. */ --static int --set_var (const char *name, const char *value, void *whitelist) --{ -- if (! whitelist) -- { -- grub_env_set (name, value); -- return 0; -- } -- -- if (test_whitelist_membership (name, -- (const grub_env_whitelist_t *) whitelist)) -- grub_env_set (name, value); -- -- return 0; --} -- - static grub_err_t - grub_cmd_load_env (grub_extcmd_context_t ctxt, int argc, char **args) - { -diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c -index 720e6d8ea3b..b194123eb67 100644 ---- a/grub-core/commands/menuentry.c -+++ b/grub-core/commands/menuentry.c -@@ -78,7 +78,7 @@ grub_normal_add_menu_entry (int argc, const char **args, - char **classes, const char *id, - const char *users, const char *hotkey, - const char *prefix, const char *sourcecode, -- int submenu) -+ int submenu, int *index, struct bls_entry *bls) - { - int menu_hotkey = 0; - char **menu_args = NULL; -@@ -149,9 +149,12 @@ grub_normal_add_menu_entry (int argc, const char **args, - if (! menu_title) - goto fail; - -+ grub_dprintf ("menu", "id:\"%s\"\n", id); -+ grub_dprintf ("menu", "title:\"%s\"\n", menu_title); - menu_id = grub_strdup (id ? : menu_title); - if (! menu_id) - goto fail; -+ grub_dprintf ("menu", "menu_id:\"%s\"\n", menu_id); - - /* Save argc, args to pass as parameters to block arg later. */ - menu_args = grub_calloc (argc + 1, sizeof (char *)); -@@ -170,8 +173,12 @@ grub_normal_add_menu_entry (int argc, const char **args, - } - - /* Add the menu entry at the end of the list. */ -+ int ind=0; - while (*last) -- last = &(*last)->next; -+ { -+ ind++; -+ last = &(*last)->next; -+ } - - *last = grub_zalloc (sizeof (**last)); - if (! *last) -@@ -188,8 +195,11 @@ grub_normal_add_menu_entry (int argc, const char **args, - (*last)->args = menu_args; - (*last)->sourcecode = menu_sourcecode; - (*last)->submenu = submenu; -+ (*last)->bls = bls; - - menu->size++; -+ if (index) -+ *index = ind; - return GRUB_ERR_NONE; - - fail: -@@ -286,7 +296,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) - users, - ctxt->state[2].arg, 0, - ctxt->state[3].arg, -- ctxt->extcmd->cmd->name[0] == 's'); -+ ctxt->extcmd->cmd->name[0] == 's', -+ NULL, NULL); - - src = args[argc - 1]; - args[argc - 1] = NULL; -@@ -303,7 +314,8 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) - ctxt->state[0].args, ctxt->state[4].arg, - users, - ctxt->state[2].arg, prefix, src + 1, -- ctxt->extcmd->cmd->name[0] == 's'); -+ ctxt->extcmd->cmd->name[0] == 's', NULL, -+ NULL); - - src[len - 1] = ch; - args[argc - 1] = src; -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 62571e6dfcc..7ca2e5400b1 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -70,6 +71,11 @@ grub_normal_free_menu (grub_menu_t menu) - grub_free (entry->args); - } - -+ if (entry->bls) -+ { -+ entry->bls->visible = 0; -+ } -+ - grub_free ((void *) entry->id); - grub_free ((void *) entry->users); - grub_free ((void *) entry->title); -diff --git a/grub-core/commands/loadenv.h b/grub-core/commands/loadenv.h -new file mode 100644 -index 00000000000..952f46121bd ---- /dev/null -+++ b/grub-core/commands/loadenv.h -@@ -0,0 +1,93 @@ -+/* loadenv.c - command to load/save environment variable. */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2008,2009,2010 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 . -+ */ -+ -+static grub_envblk_t UNUSED -+read_envblk_file (grub_file_t file) -+{ -+ grub_off_t offset = 0; -+ char *buf; -+ grub_size_t size = grub_file_size (file); -+ grub_envblk_t envblk; -+ -+ buf = grub_malloc (size); -+ if (! buf) -+ return 0; -+ -+ while (size > 0) -+ { -+ grub_ssize_t ret; -+ -+ ret = grub_file_read (file, buf + offset, size); -+ if (ret <= 0) -+ { -+ grub_free (buf); -+ return 0; -+ } -+ -+ size -= ret; -+ offset += ret; -+ } -+ -+ envblk = grub_envblk_open (buf, offset); -+ if (! envblk) -+ { -+ grub_free (buf); -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block"); -+ return 0; -+ } -+ -+ return envblk; -+} -+ -+struct grub_env_whitelist -+{ -+ grub_size_t len; -+ char **list; -+}; -+typedef struct grub_env_whitelist grub_env_whitelist_t; -+ -+static int UNUSED -+test_whitelist_membership (const char* name, -+ const grub_env_whitelist_t* whitelist) -+{ -+ grub_size_t i; -+ -+ for (i = 0; i < whitelist->len; i++) -+ if (grub_strcmp (name, whitelist->list[i]) == 0) -+ return 1; /* found it */ -+ -+ return 0; /* not found */ -+} -+ -+/* Helper for grub_cmd_load_env. */ -+static int UNUSED -+set_var (const char *name, const char *value, void *whitelist) -+{ -+ if (! whitelist) -+ { -+ grub_env_set (name, value); -+ return 0; -+ } -+ -+ if (test_whitelist_membership (name, -+ (const grub_env_whitelist_t *) whitelist)) -+ grub_env_set (name, value); -+ -+ return 0; -+} -diff --git a/include/grub/compiler.h b/include/grub/compiler.h -index 8f3be3ae706..ebafec68957 100644 ---- a/include/grub/compiler.h -+++ b/include/grub/compiler.h -@@ -56,4 +56,6 @@ - # define CLANG_PREREQ(maj,min) 0 - #endif - -+#define UNUSED __attribute__((__unused__)) -+ - #endif /* ! GRUB_COMPILER_HEADER */ -diff --git a/include/grub/menu.h b/include/grub/menu.h -index ee2b5e91045..0acdc2aa6bf 100644 ---- a/include/grub/menu.h -+++ b/include/grub/menu.h -@@ -20,6 +20,16 @@ - #ifndef GRUB_MENU_HEADER - #define GRUB_MENU_HEADER 1 - -+struct bls_entry -+{ -+ struct bls_entry *next; -+ struct bls_entry *prev; -+ struct keyval **keyvals; -+ int nkeyvals; -+ char *filename; -+ int visible; -+}; -+ - struct grub_menu_entry_class - { - char *name; -@@ -60,6 +70,9 @@ struct grub_menu_entry - - /* The next element. */ - struct grub_menu_entry *next; -+ -+ /* BLS used to populate the entry */ -+ struct bls_entry *bls; - }; - typedef struct grub_menu_entry *grub_menu_entry_t; - -diff --git a/include/grub/normal.h b/include/grub/normal.h -index 218cbabccaf..8839ad85a19 100644 ---- a/include/grub/normal.h -+++ b/include/grub/normal.h -@@ -145,7 +145,7 @@ grub_normal_add_menu_entry (int argc, const char **args, char **classes, - const char *id, - const char *users, const char *hotkey, - const char *prefix, const char *sourcecode, -- int submenu); -+ int submenu, int *index, struct bls_entry *bls); - - grub_err_t - grub_normal_set_password (const char *user, const char *password); diff --git a/0022-Add-devicetree-loading.patch b/0022-Add-devicetree-loading.patch deleted file mode 100644 index c0728a9890ea370610275f3d83e61e635c393eab..0000000000000000000000000000000000000000 --- a/0022-Add-devicetree-loading.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 14 Jan 2014 13:12:23 -0500 -Subject: [PATCH] Add devicetree loading - -Signed-off-by: Peter Jones - -Switch to use APM Mustang device tree, for hardware testing. - -Signed-off-by: David A. Marlin - -Use the default device tree from the grub default file - -instead of hardcoding a value. - -Signed-off-by: David A. Marlin ---- - util/grub-mkconfig.in | 3 ++- - util/grub.d/10_linux.in | 15 +++++++++++++++ - 2 files changed, 17 insertions(+), 1 deletion(-) - -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index d3e879b8e5c..8ea2315ebc2 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -248,7 +248,8 @@ export GRUB_DEFAULT \ - GRUB_ENABLE_CRYPTODISK \ - GRUB_BADRAM \ - GRUB_OS_PROBER_SKIP_LIST \ -- GRUB_DISABLE_SUBMENU -+ GRUB_DISABLE_SUBMENU \ -+ GRUB_DEFAULT_DTB - - if test "x${grub_cfg}" != "x"; then - rm -f "${grub_cfg}.new" -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index e8b01c0d0c7..dc75a1c30bf 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -153,6 +153,13 @@ EOF - sed "s/^/$submenu_indentation/" << EOF - echo '$(echo "$message" | grub_quote)' - initrd $(echo $initrd_path) -+EOF -+ fi -+ if test -n "${fdt}" ; then -+ message="$(gettext_printf "Loading fdt ...")" -+ sed "s/^/$submenu_indentation/" << EOF -+ echo '$(echo "$message" | grub_quote)' -+ devicetree ${rel_dirname}/${fdt} - EOF - fi - sed "s/^/$submenu_indentation/" << EOF -@@ -236,6 +243,14 @@ while [ "x$list" != "x" ] ; do - gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 - fi - -+ fdt= -+ for i in "dtb-${version}" "dtb-${alt_version}"; do -+ if test -f "${dirname}/${i}/${GRUB_DEFAULT_DTB}" ; then -+ fdt="${i}/${GRUB_DEFAULT_DTB}" -+ break -+ fi -+ done -+ - config= - for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do - if test -e "${i}" ; then diff --git a/0178-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch b/0022-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch similarity index 72% rename from 0178-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch rename to 0022-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch index 40c3b3e843aeb8ae83d43012f63e5d9bae11606c..950d9abdf3a917fe848919478f6115cca2239c3f 100644 --- a/0178-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch +++ b/0022-ieee1275-enter-lockdown-based-on-ibm-secure-boot.patch @@ -1,24 +1,35 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 806bb18c3493537530b6b0387143752478078f5b Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Mon, 28 Sep 2020 11:11:17 +1000 -Subject: [PATCH] ieee1275: enter lockdown based on /ibm,secure-boot +Subject: [PATCH 22/23] ieee1275: enter lockdown based on /ibm,secure-boot If the 'ibm,secure-boot' property of the root node is 2 or greater, enter lockdown. Signed-off-by: Daniel Axtens --- + docs/grub.texi | 4 ++-- grub-core/Makefile.core.def | 1 + grub-core/kern/ieee1275/init.c | 27 +++++++++++++++++++++++++++ include/grub/lockdown.h | 3 ++- - docs/grub.texi | 4 ++-- 4 files changed, 32 insertions(+), 3 deletions(-) -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 6bddc841b85..3f3459b2c70 100644 +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -6795,8 +6795,8 @@ + @section Lockdown when booting on a secure setup + + The GRUB can be locked down when booted on a secure boot environment, for example +-if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will +-be restricted and some operations/commands cannot be executed. ++if UEFI or Power secure boot is enabled. On a locked down configuration, the ++GRUB will be restricted and some operations/commands cannot be executed. + + The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down. + Otherwise it does not exit. --- a/grub-core/Makefile.core.def +++ b/grub-core/Makefile.core.def -@@ -323,6 +323,7 @@ kernel = { +@@ -331,6 +331,7 @@ powerpc_ieee1275 = kern/powerpc/cache.S; powerpc_ieee1275 = kern/powerpc/dl.c; powerpc_ieee1275 = kern/powerpc/compiler-rt.S; @@ -26,19 +37,17 @@ index 6bddc841b85..3f3459b2c70 100644 sparc64_ieee1275 = kern/sparc64/cache.S; sparc64_ieee1275 = kern/sparc64/dl.c; -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index 937c1bc44cb..fc7d9712729 100644 --- a/grub-core/kern/ieee1275/init.c +++ b/grub-core/kern/ieee1275/init.c -@@ -44,6 +44,7 @@ - #ifdef __sparc__ - #include +@@ -49,6 +49,7 @@ + #if defined(__powerpc__) || defined(__i386__) + #include #endif +#include - /* The minimal heap size we can live with. */ - #define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) -@@ -271,6 +272,30 @@ grub_parse_cmdline (void) + /* The maximum heap size we're going to claim at boot. Not used by sparc. */ + #ifdef __i386__ +@@ -893,6 +894,30 @@ } } @@ -69,7 +78,7 @@ index 937c1bc44cb..fc7d9712729 100644 grub_addr_t grub_modbase; void -@@ -296,6 +321,8 @@ grub_machine_init (void) +@@ -918,6 +943,8 @@ #else grub_install_get_time_ms (grub_rtc_get_time_ms); #endif @@ -78,8 +87,6 @@ index 937c1bc44cb..fc7d9712729 100644 } void -diff --git a/include/grub/lockdown.h b/include/grub/lockdown.h -index 40531fa823b..ebfee4bf06e 100644 --- a/include/grub/lockdown.h +++ b/include/grub/lockdown.h @@ -24,7 +24,8 @@ @@ -92,18 +99,3 @@ index 40531fa823b..ebfee4bf06e 100644 extern void EXPORT_FUNC (grub_lockdown) (void); extern int -diff --git a/docs/grub.texi b/docs/grub.texi -index 4816be85611..a4da9c2a1b9 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -6227,8 +6227,8 @@ Measured boot is currently only supported on EFI platforms. - @section Lockdown when booting on a secure setup - - The GRUB can be locked down when booted on a secure boot environment, for example --if the UEFI secure boot is enabled. On a locked down configuration, the GRUB will --be restricted and some operations/commands cannot be executed. -+if UEFI or Power secure boot is enabled. On a locked down configuration, the -+GRUB will be restricted and some operations/commands cannot be executed. - - The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down. - Otherwise it does not exit. diff --git a/0023-Enable-pager-by-default.-985860.patch b/0023-Enable-pager-by-default.-985860.patch deleted file mode 100644 index d92fbcc79a6b59f5b28483289647757b5e880c5b..0000000000000000000000000000000000000000 --- a/0023-Enable-pager-by-default.-985860.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 28 Oct 2013 10:09:27 -0400 -Subject: [PATCH] Enable pager by default. (#985860) - -Signed-off-by: Peter Jones ---- - util/grub.d/00_header.in | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in -index 93a90233ead..858b526c925 100644 ---- a/util/grub.d/00_header.in -+++ b/util/grub.d/00_header.in -@@ -43,6 +43,8 @@ if [ "x${GRUB_DEFAULT_BUTTON}" = "xsaved" ] ; then GRUB_DEFAULT_BUTTON='${saved_ - if [ "x${GRUB_TIMEOUT_BUTTON}" = "x" ] ; then GRUB_TIMEOUT_BUTTON="$GRUB_TIMEOUT" ; fi - - cat << EOF -+set pager=1 -+ - if [ -s \$prefix/grubenv ]; then - load_env - fi diff --git a/0023-x509-allow-Digitial-Signature-plus-other-Key-Usages.patch b/0023-x509-allow-Digitial-Signature-plus-other-Key-Usages.patch new file mode 100644 index 0000000000000000000000000000000000000000..c335b3be5e0f02ef5559c1cb3aef12970f51c8a2 --- /dev/null +++ b/0023-x509-allow-Digitial-Signature-plus-other-Key-Usages.patch @@ -0,0 +1,48 @@ +From 5a690183091c2c161481123b17e1925148e516e4 Mon Sep 17 00:00:00 2001 +From: Daniel Axtens +Date: Tue, 30 Nov 2021 15:00:57 +1100 +Subject: [PATCH 23/23] x509: allow Digitial Signature plus other Key Usages + +Currently the x509 certificate parser for appended signature +verification requires that the certificate have the Digitial Signature +key usage and _only_ the Digitial Signature use. This is overly strict +and becomes policy enforcement rather than a security property. + +Require that the Digitial Signature usage is present, but do not +require that it is the only usage present. + +Reported-by: Michal Suchanek +Signed-off-by: Daniel Axtens +--- + grub-core/commands/appendedsig/x509.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/grub-core/commands/appendedsig/x509.c b/grub-core/commands/appendedsig/x509.c +index 70480aa73..6ae985b30 100644 +--- a/grub-core/commands/appendedsig/x509.c ++++ b/grub-core/commands/appendedsig/x509.c +@@ -547,7 +547,7 @@ cleanup: + + /* + * Verify the Key Usage extension. +- * We only permit the Digital signature usage. ++ * We require the Digital signature usage. + */ + static grub_err_t + verify_key_usage (grub_uint8_t *value, int value_size) +@@ -586,10 +586,10 @@ verify_key_usage (grub_uint8_t *value, int value_size) + goto cleanup; + } + +- if (usage != digitalSignatureUsage) ++ if (!(usage & digitalSignatureUsage)) + { + err = +- grub_error (GRUB_ERR_BAD_FILE_TYPE, "Unexpected Key Usage value: %x", ++ grub_error (GRUB_ERR_BAD_FILE_TYPE, "Key Usage (0x%x) missing Digital Signature usage", + usage); + goto cleanup; + } +-- +2.31.1 + diff --git a/0025-Add-.eh_frame-to-list-of-relocations-stripped.patch b/0025-Add-.eh_frame-to-list-of-relocations-stripped.patch deleted file mode 100644 index ed48c5c7fe0b41c4a00c7611109ec8ee91223f41..0000000000000000000000000000000000000000 --- a/0025-Add-.eh_frame-to-list-of-relocations-stripped.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fedora Ninjas -Date: Mon, 13 Jan 2014 21:50:59 -0500 -Subject: [PATCH] Add .eh_frame to list of relocations stripped - ---- - conf/Makefile.common | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 2a1a886f6d5..191b1a70c6b 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -38,7 +38,7 @@ CFLAGS_KERNEL = $(CFLAGS_PLATFORM) -ffreestanding - LDFLAGS_KERNEL = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) - CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1 - CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) --STRIPFLAGS_KERNEL = -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx -+STRIPFLAGS_KERNEL = -R .eh_frame -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx - - CFLAGS_MODULE = $(CFLAGS_PLATFORM) -ffreestanding - LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d diff --git a/0026-Don-t-require-a-password-to-boot-entries-generated-b.patch b/0026-Don-t-require-a-password-to-boot-entries-generated-b.patch deleted file mode 100644 index ac9475e3f469b43cd7826c1f55b19439b87067f2..0000000000000000000000000000000000000000 --- a/0026-Don-t-require-a-password-to-boot-entries-generated-b.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 11 Feb 2014 11:14:50 -0500 -Subject: [PATCH] Don't require a password to boot entries generated by - grub-mkconfig. - -When we set a password, we just want that to mean you can't /edit/ an entry. - -Resolves: rhbz#1030176 - -Signed-off-by: Peter Jones ---- - util/grub.d/10_linux.in | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 4a499c53a61..cf8d1186981 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -26,7 +26,7 @@ datarootdir="@datarootdir@" - export TEXTDOMAIN=@PACKAGE@ - export TEXTDOMAINDIR="@localedir@" - --CLASS="--class gnu-linux --class gnu --class os" -+CLASS="--class gnu-linux --class gnu --class os --unrestricted" - - if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then - OS="$(sed 's, release .*$,,g' /etc/system-release)" diff --git a/0027-Replace-a-lot-of-man-pages-with-slightly-nicer-ones.patch b/0027-Replace-a-lot-of-man-pages-with-slightly-nicer-ones.patch deleted file mode 100644 index daa6fae0742d89d1f4cd3c58f0b9c4a80dad388c..0000000000000000000000000000000000000000 --- a/0027-Replace-a-lot-of-man-pages-with-slightly-nicer-ones.patch +++ /dev/null @@ -1,1959 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 4 Mar 2014 11:00:23 -0500 -Subject: [PATCH] Replace a lot of man pages with slightly nicer ones. - -Replace a bunch of machine generated ones with ones that look nicer. ---- - configure.ac | 23 ++++++ - conf/Makefile.extra-dist | 1 - - docs/Makefile.am | 2 - - docs/man/grub-bios-setup.h2m | 6 -- - docs/man/grub-editenv.h2m | 5 -- - docs/man/grub-emu.h2m | 6 -- - docs/man/grub-file.h2m | 2 - - docs/man/grub-fstest.h2m | 4 - - docs/man/grub-glue-efi.h2m | 4 - - docs/man/grub-install.h2m | 6 -- - docs/man/grub-kbdcomp.h2m | 10 --- - docs/man/grub-macbless.h2m | 4 - - docs/man/grub-macho2img.h2m | 4 - - docs/man/grub-menulst2cfg.h2m | 4 - - docs/man/grub-mkconfig.h2m | 4 - - docs/man/grub-mkfont.h2m | 4 - - docs/man/grub-mkimage.h2m | 6 -- - docs/man/grub-mklayout.h2m | 10 --- - docs/man/grub-mknetdir.h2m | 4 - - docs/man/grub-mkpasswd-pbkdf2.h2m | 4 - - docs/man/grub-mkrelpath.h2m | 4 - - docs/man/grub-mkrescue.h2m | 4 - - docs/man/grub-mkstandalone.h2m | 4 - - docs/man/grub-mount.h2m | 2 - - docs/man/grub-ofpathname.h2m | 4 - - docs/man/grub-pe2elf.h2m | 4 - - docs/man/grub-probe.h2m | 4 - - docs/man/grub-reboot.h2m | 5 -- - docs/man/grub-render-label.h2m | 3 - - docs/man/grub-script-check.h2m | 4 - - docs/man/grub-set-default.h2m | 5 -- - docs/man/grub-sparc64-setup.h2m | 6 -- - docs/man/grub-syslinux2cfg.h2m | 4 - - gentpl.py | 5 +- - util/grub-bios-setup.8 | 54 +++++++++++++ - util/grub-editenv.1 | 46 +++++++++++ - util/grub-file.1 | 165 ++++++++++++++++++++++++++++++++++++++ - util/grub-fstest.1 | 99 +++++++++++++++++++++++ - util/grub-glue-efi.1 | 31 +++++++ - util/grub-install.8 | 128 +++++++++++++++++++++++++++++ - util/grub-kbdcomp.1 | 19 +++++ - util/grub-macbless.1 | 22 +++++ - util/grub-menulst2cfg.1 | 12 +++ - util/grub-mkconfig.8 | 17 ++++ - util/grub-mkfont.1 | 87 ++++++++++++++++++++ - util/grub-mkimage.1 | 95 ++++++++++++++++++++++ - util/grub-mklayout.1 | 27 +++++++ - util/grub-mknetdir.1 | 12 +++ - util/grub-mkpasswd-pbkdf2.1 | 27 +++++++ - util/grub-mkrelpath.1 | 12 +++ - util/grub-mkrescue.1 | 123 ++++++++++++++++++++++++++++ - util/grub-mkstandalone.1 | 100 +++++++++++++++++++++++ - util/grub-ofpathname.8 | 12 +++ - util/grub-probe.8 | 80 ++++++++++++++++++ - util/grub-reboot.8 | 21 +++++ - util/grub-render-label.1 | 51 ++++++++++++ - util/grub-script-check.1 | 21 +++++ - util/grub-set-default.8 | 21 +++++ - util/grub-sparc64-setup.8 | 12 +++ - 59 files changed, 1318 insertions(+), 147 deletions(-) - delete mode 100644 docs/man/grub-bios-setup.h2m - delete mode 100644 docs/man/grub-editenv.h2m - delete mode 100644 docs/man/grub-emu.h2m - delete mode 100644 docs/man/grub-file.h2m - delete mode 100644 docs/man/grub-fstest.h2m - delete mode 100644 docs/man/grub-glue-efi.h2m - delete mode 100644 docs/man/grub-install.h2m - delete mode 100644 docs/man/grub-kbdcomp.h2m - delete mode 100644 docs/man/grub-macbless.h2m - delete mode 100644 docs/man/grub-macho2img.h2m - delete mode 100644 docs/man/grub-menulst2cfg.h2m - delete mode 100644 docs/man/grub-mkconfig.h2m - delete mode 100644 docs/man/grub-mkfont.h2m - delete mode 100644 docs/man/grub-mkimage.h2m - delete mode 100644 docs/man/grub-mklayout.h2m - delete mode 100644 docs/man/grub-mknetdir.h2m - delete mode 100644 docs/man/grub-mkpasswd-pbkdf2.h2m - delete mode 100644 docs/man/grub-mkrelpath.h2m - delete mode 100644 docs/man/grub-mkrescue.h2m - delete mode 100644 docs/man/grub-mkstandalone.h2m - delete mode 100644 docs/man/grub-mount.h2m - delete mode 100644 docs/man/grub-ofpathname.h2m - delete mode 100644 docs/man/grub-pe2elf.h2m - delete mode 100644 docs/man/grub-probe.h2m - delete mode 100644 docs/man/grub-reboot.h2m - delete mode 100644 docs/man/grub-render-label.h2m - delete mode 100644 docs/man/grub-script-check.h2m - delete mode 100644 docs/man/grub-set-default.h2m - delete mode 100644 docs/man/grub-sparc64-setup.h2m - delete mode 100644 docs/man/grub-syslinux2cfg.h2m - create mode 100644 util/grub-bios-setup.8 - create mode 100644 util/grub-editenv.1 - create mode 100644 util/grub-file.1 - create mode 100644 util/grub-fstest.1 - create mode 100644 util/grub-glue-efi.1 - create mode 100644 util/grub-install.8 - create mode 100644 util/grub-kbdcomp.1 - create mode 100644 util/grub-macbless.1 - create mode 100644 util/grub-menulst2cfg.1 - create mode 100644 util/grub-mkconfig.8 - create mode 100644 util/grub-mkfont.1 - create mode 100644 util/grub-mkimage.1 - create mode 100644 util/grub-mklayout.1 - create mode 100644 util/grub-mknetdir.1 - create mode 100644 util/grub-mkpasswd-pbkdf2.1 - create mode 100644 util/grub-mkrelpath.1 - create mode 100644 util/grub-mkrescue.1 - create mode 100644 util/grub-mkstandalone.1 - create mode 100644 util/grub-ofpathname.8 - create mode 100644 util/grub-probe.8 - create mode 100644 util/grub-reboot.8 - create mode 100644 util/grub-render-label.1 - create mode 100644 util/grub-script-check.1 - create mode 100644 util/grub-set-default.8 - create mode 100644 util/grub-sparc64-setup.8 - -diff --git a/configure.ac b/configure.ac -index 8331f95b645..bec8535af70 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -77,6 +77,29 @@ grub_TRANSFORM([grub-set-default]) - grub_TRANSFORM([grub-sparc64-setup]) - grub_TRANSFORM([grub-render-label]) - grub_TRANSFORM([grub-file]) -+grub_TRANSFORM([grub-bios-setup.3]) -+grub_TRANSFORM([grub-editenv.1]) -+grub_TRANSFORM([grub-fstest.3]) -+grub_TRANSFORM([grub-glue-efi.3]) -+grub_TRANSFORM([grub-install.1]) -+grub_TRANSFORM([grub-kbdcomp.3]) -+grub_TRANSFORM([grub-menulst2cfg.1]) -+grub_TRANSFORM([grub-mkconfig.1]) -+grub_TRANSFORM([grub-mkfont.3]) -+grub_TRANSFORM([grub-mkimage.1]) -+grub_TRANSFORM([grub-mklayout.3]) -+grub_TRANSFORM([grub-mknetdir.3]) -+grub_TRANSFORM([grub-mkpasswd-pbkdf2.3]) -+grub_TRANSFORM([grub-mkrelpath.3]) -+grub_TRANSFORM([grub-mkrescue.1]) -+grub_TRANSFORM([grub-mkstandalone.3]) -+grub_TRANSFORM([grub-ofpathname.3]) -+grub_TRANSFORM([grub-probe.3]) -+grub_TRANSFORM([grub-reboot.3]) -+grub_TRANSFORM([grub-render-label.3]) -+grub_TRANSFORM([grub-script-check.3]) -+grub_TRANSFORM([grub-set-default.1]) -+grub_TRANSFORM([grub-sparc64-setup.3]) - - # Optimization flag. Allow user to override. - if test "x$TARGET_CFLAGS" = x; then -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index 8f1485d52a5..b909f2c073a 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -11,7 +11,6 @@ EXTRA_DIST += unicode - EXTRA_DIST += util/import_gcry.py - EXTRA_DIST += util/import_unicode.py - --EXTRA_DIST += docs/man - EXTRA_DIST += docs/autoiso.cfg - EXTRA_DIST += docs/grub.cfg - EXTRA_DIST += docs/osdetect.cfg -diff --git a/docs/Makefile.am b/docs/Makefile.am -index 93eb3962765..ab28f199694 100644 ---- a/docs/Makefile.am -+++ b/docs/Makefile.am -@@ -5,5 +5,3 @@ info_TEXINFOS = grub.texi grub-dev.texi - grub_TEXINFOS = fdl.texi - - EXTRA_DIST = font_char_metrics.png font_char_metrics.txt -- -- -diff --git a/docs/man/grub-bios-setup.h2m b/docs/man/grub-bios-setup.h2m -deleted file mode 100644 -index ac6ede36296..00000000000 ---- a/docs/man/grub-bios-setup.h2m -+++ /dev/null -@@ -1,6 +0,0 @@ --[NAME] --grub-bios-setup \- set up a device to boot using GRUB --[SEE ALSO] --.BR grub-install (8), --.BR grub-mkimage (1), --.BR grub-mkrescue (1) -diff --git a/docs/man/grub-editenv.h2m b/docs/man/grub-editenv.h2m -deleted file mode 100644 -index 3859d3d4c4f..00000000000 ---- a/docs/man/grub-editenv.h2m -+++ /dev/null -@@ -1,5 +0,0 @@ --[NAME] --grub-editenv \- edit GRUB environment block --[SEE ALSO] --.BR grub-reboot (8), --.BR grub-set-default (8) -diff --git a/docs/man/grub-emu.h2m b/docs/man/grub-emu.h2m -deleted file mode 100644 -index ef1c000656a..00000000000 ---- a/docs/man/grub-emu.h2m -+++ /dev/null -@@ -1,6 +0,0 @@ --[NAME] --grub-emu \- GRUB emulator --[SEE ALSO] --If you are trying to install GRUB, then you should use --.BR grub-install (8) --rather than this program. -diff --git a/docs/man/grub-file.h2m b/docs/man/grub-file.h2m -deleted file mode 100644 -index e09bb4d3101..00000000000 ---- a/docs/man/grub-file.h2m -+++ /dev/null -@@ -1,2 +0,0 @@ --[NAME] --grub-file \- check file type -diff --git a/docs/man/grub-fstest.h2m b/docs/man/grub-fstest.h2m -deleted file mode 100644 -index 9676b159afd..00000000000 ---- a/docs/man/grub-fstest.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-fstest \- debug tool for GRUB filesystem drivers --[SEE ALSO] --.BR grub-probe (8) -diff --git a/docs/man/grub-glue-efi.h2m b/docs/man/grub-glue-efi.h2m -deleted file mode 100644 -index c1c6ded49ff..00000000000 ---- a/docs/man/grub-glue-efi.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-glue-efi \- generate a fat binary for EFI --[DESCRIPTION] --grub-glue-efi processes ia32 and amd64 EFI images and glues them according to Apple format. -diff --git a/docs/man/grub-install.h2m b/docs/man/grub-install.h2m -deleted file mode 100644 -index 8cbbc87a0f2..00000000000 ---- a/docs/man/grub-install.h2m -+++ /dev/null -@@ -1,6 +0,0 @@ --[NAME] --grub-install \- install GRUB to a device --[SEE ALSO] --.BR grub-mkconfig (8), --.BR grub-mkimage (1), --.BR grub-mkrescue (1) -diff --git a/docs/man/grub-kbdcomp.h2m b/docs/man/grub-kbdcomp.h2m -deleted file mode 100644 -index d81f9157e01..00000000000 ---- a/docs/man/grub-kbdcomp.h2m -+++ /dev/null -@@ -1,10 +0,0 @@ --[NAME] --grub-kbdcomp \- generate a GRUB keyboard layout file --[DESCRIPTION] --grub-kbdcomp processes a X keyboard layout description in --.BR keymaps (5) --format into a format that can be used by GRUB's --.B keymap --command. --[SEE ALSO] --.BR grub-mklayout (8) -diff --git a/docs/man/grub-macbless.h2m b/docs/man/grub-macbless.h2m -deleted file mode 100644 -index 0197c0087d7..00000000000 ---- a/docs/man/grub-macbless.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-macbless \- bless a mac file/directory --[SEE ALSO] --.BR grub-install (1) -diff --git a/docs/man/grub-macho2img.h2m b/docs/man/grub-macho2img.h2m -deleted file mode 100644 -index d79aaeed8f9..00000000000 ---- a/docs/man/grub-macho2img.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-macho2img \- convert Mach-O to raw image --[SEE ALSO] --.BR grub-mkimage (1) -diff --git a/docs/man/grub-menulst2cfg.h2m b/docs/man/grub-menulst2cfg.h2m -deleted file mode 100644 -index c2e0055ed7e..00000000000 ---- a/docs/man/grub-menulst2cfg.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-menulst2cfg \- transform legacy menu.lst into grub.cfg --[SEE ALSO] --.BR grub-mkconfig (8) -diff --git a/docs/man/grub-mkconfig.h2m b/docs/man/grub-mkconfig.h2m -deleted file mode 100644 -index 9b42f813010..00000000000 ---- a/docs/man/grub-mkconfig.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mkconfig \- generate a GRUB configuration file --[SEE ALSO] --.BR grub-install (8) -diff --git a/docs/man/grub-mkfont.h2m b/docs/man/grub-mkfont.h2m -deleted file mode 100644 -index d46fe600eca..00000000000 ---- a/docs/man/grub-mkfont.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mkfont \- make GRUB font files --[SEE ALSO] --.BR grub-mkconfig (8) -diff --git a/docs/man/grub-mkimage.h2m b/docs/man/grub-mkimage.h2m -deleted file mode 100644 -index f0fbc2bb197..00000000000 ---- a/docs/man/grub-mkimage.h2m -+++ /dev/null -@@ -1,6 +0,0 @@ --[NAME] --grub-mkimage \- make a bootable image of GRUB --[SEE ALSO] --.BR grub-install (8), --.BR grub-mkrescue (1), --.BR grub-mknetdir (8) -diff --git a/docs/man/grub-mklayout.h2m b/docs/man/grub-mklayout.h2m -deleted file mode 100644 -index 1e43409c0ab..00000000000 ---- a/docs/man/grub-mklayout.h2m -+++ /dev/null -@@ -1,10 +0,0 @@ --[NAME] --grub-mklayout \- generate a GRUB keyboard layout file --[DESCRIPTION] --grub-mklayout processes a keyboard layout description in --.BR keymaps (5) --format into a format that can be used by GRUB's --.B keymap --command. --[SEE ALSO] --.BR grub-mkconfig (8) -diff --git a/docs/man/grub-mknetdir.h2m b/docs/man/grub-mknetdir.h2m -deleted file mode 100644 -index a2ef13ec111..00000000000 ---- a/docs/man/grub-mknetdir.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mknetdir \- prepare a GRUB netboot directory. --[SEE ALSO] --.BR grub-mkimage (1) -diff --git a/docs/man/grub-mkpasswd-pbkdf2.h2m b/docs/man/grub-mkpasswd-pbkdf2.h2m -deleted file mode 100644 -index 4d202f3da7e..00000000000 ---- a/docs/man/grub-mkpasswd-pbkdf2.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mkpasswd-pbkdf2 \- generate hashed password for GRUB --[SEE ALSO] --.BR grub-mkconfig (8) -diff --git a/docs/man/grub-mkrelpath.h2m b/docs/man/grub-mkrelpath.h2m -deleted file mode 100644 -index d01f3961e3f..00000000000 ---- a/docs/man/grub-mkrelpath.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mkrelpath \- make a system path relative to its root --[SEE ALSO] --.BR grub-probe (8) -diff --git a/docs/man/grub-mkrescue.h2m b/docs/man/grub-mkrescue.h2m -deleted file mode 100644 -index a427f02e3c6..00000000000 ---- a/docs/man/grub-mkrescue.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mkrescue \- make a GRUB rescue image --[SEE ALSO] --.BR grub-mkimage (1) -diff --git a/docs/man/grub-mkstandalone.h2m b/docs/man/grub-mkstandalone.h2m -deleted file mode 100644 -index c77313978ad..00000000000 ---- a/docs/man/grub-mkstandalone.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-mkstandalone \- make a memdisk-based GRUB image --[SEE ALSO] --.BR grub-mkimage (1) -diff --git a/docs/man/grub-mount.h2m b/docs/man/grub-mount.h2m -deleted file mode 100644 -index 8d168982d72..00000000000 ---- a/docs/man/grub-mount.h2m -+++ /dev/null -@@ -1,2 +0,0 @@ --[NAME] --grub-mount \- export GRUB filesystem with FUSE -diff --git a/docs/man/grub-ofpathname.h2m b/docs/man/grub-ofpathname.h2m -deleted file mode 100644 -index 74b43eea039..00000000000 ---- a/docs/man/grub-ofpathname.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-ofpathname \- find OpenBOOT path for a device --[SEE ALSO] --.BR grub-probe (8) -diff --git a/docs/man/grub-pe2elf.h2m b/docs/man/grub-pe2elf.h2m -deleted file mode 100644 -index 7ca29bd703c..00000000000 ---- a/docs/man/grub-pe2elf.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-pe2elf \- convert PE image to ELF --[SEE ALSO] --.BR grub-mkimage (1) -diff --git a/docs/man/grub-probe.h2m b/docs/man/grub-probe.h2m -deleted file mode 100644 -index 6e1ffdcf937..00000000000 ---- a/docs/man/grub-probe.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-probe \- probe device information for GRUB --[SEE ALSO] --.BR grub-fstest (1) -diff --git a/docs/man/grub-reboot.h2m b/docs/man/grub-reboot.h2m -deleted file mode 100644 -index e4acace65ce..00000000000 ---- a/docs/man/grub-reboot.h2m -+++ /dev/null -@@ -1,5 +0,0 @@ --[NAME] --grub-reboot \- set the default boot entry for GRUB, for the next boot only --[SEE ALSO] --.BR grub-set-default (8), --.BR grub-editenv (1) -diff --git a/docs/man/grub-render-label.h2m b/docs/man/grub-render-label.h2m -deleted file mode 100644 -index 50ae5247c05..00000000000 ---- a/docs/man/grub-render-label.h2m -+++ /dev/null -@@ -1,3 +0,0 @@ --[NAME] --grub-render-label \- generate a .disk_label for Apple Macs. -- -diff --git a/docs/man/grub-script-check.h2m b/docs/man/grub-script-check.h2m -deleted file mode 100644 -index 3653682671a..00000000000 ---- a/docs/man/grub-script-check.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-script-check \- check grub.cfg for syntax errors --[SEE ALSO] --.BR grub-mkconfig (8) -diff --git a/docs/man/grub-set-default.h2m b/docs/man/grub-set-default.h2m -deleted file mode 100644 -index 7945001c154..00000000000 ---- a/docs/man/grub-set-default.h2m -+++ /dev/null -@@ -1,5 +0,0 @@ --[NAME] --grub-set-default \- set the saved default boot entry for GRUB --[SEE ALSO] --.BR grub-reboot (8), --.BR grub-editenv (1) -diff --git a/docs/man/grub-sparc64-setup.h2m b/docs/man/grub-sparc64-setup.h2m -deleted file mode 100644 -index 18f803a50db..00000000000 ---- a/docs/man/grub-sparc64-setup.h2m -+++ /dev/null -@@ -1,6 +0,0 @@ --[NAME] --grub-sparc64-setup \- set up a device to boot using GRUB --[SEE ALSO] --.BR grub-install (8), --.BR grub-mkimage (1), --.BR grub-mkrescue (1) -diff --git a/docs/man/grub-syslinux2cfg.h2m b/docs/man/grub-syslinux2cfg.h2m -deleted file mode 100644 -index ad25c8ab753..00000000000 ---- a/docs/man/grub-syslinux2cfg.h2m -+++ /dev/null -@@ -1,4 +0,0 @@ --[NAME] --grub-syslinux2cfg \- transform syslinux config into grub.cfg --[SEE ALSO] --.BR grub-menulst2cfg (8) -diff --git a/gentpl.py b/gentpl.py -index c86550d4f9e..2cba0bbbd6f 100644 ---- a/gentpl.py -+++ b/gentpl.py -@@ -805,10 +805,7 @@ def manpage(defn, adddeps): - - output("if COND_MAN_PAGES\n") - gvar_add("man_MANS", name + "." + mansection) -- rule(name + "." + mansection, name + " " + adddeps, """ --chmod a+x """ + name + """ --PATH=$(builddir):$$PATH pkgdatadir=$(builddir) $(HELP2MAN) --section=""" + mansection + """ -i $(top_srcdir)/docs/man/""" + name + """.h2m -o $@ """ + name + """ --""") -+ rule(name + "." + mansection, name + " " + adddeps, "cat $(top_srcdir)/util/" + name + "." + mansection + " | $(top_builddir)/config.status --file=$@:-") - gvar_add("CLEANFILES", name + "." + mansection) - output("endif\n") - -diff --git a/util/grub-bios-setup.8 b/util/grub-bios-setup.8 -new file mode 100644 -index 00000000000..56f582b3d75 ---- /dev/null -+++ b/util/grub-bios-setup.8 -@@ -0,0 +1,54 @@ -+.TH GRUB-BIOS-SETUP 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-bios-setup\fR \(em Set up images to boot from a device. -+ -+.SH SYNOPSIS -+\fBgrub-bios-setup\fR [-a | --allow-floppy] [-b | --boot-image=\fIFILE\fR] -+.RS 17 -+[-c | --core-image=\fIFILE\fR] [-d | --directory=\fIDIR\fR] -+.RE -+.RS 17 -+[-f | --force] [-m | --device-map=\fIFILE\fR] -+.RE -+.RS 17 -+[-s | --skip-fs-probe] [-v | --verbose] \fIDEVICE\fR -+ -+.SH DESCRIPTION -+You should not normally run this program directly. Use grub-install instead. -+ -+.SH OPTIONS -+.TP -+\fB--allow-floppy\fR -+Make the device also bootable as a floppy. This option is the default for -+/dev/fdX devices. Some BIOSes will not boot images created with this option. -+ -+.TP -+\fB--boot-image\fR=\fIFILE\fR -+Use FILE as the boot image. The default value is \fBboot.img\fR. -+ -+.TP -+\fB--core-image\fR=\fIFILE\fR -+Use FILE as ther core image. The default value is \fBcore.img\fR. -+ -+.TP -+\fB--directory\fR=\fIDIR\fR -+Use GRUB files in the directory DIR. The default value is \fB/boot/grub\fR. -+ -+.TP -+\fB--force\fR -+Install even if problems are detected. -+ -+.TP -+\fB--device-map\fR=\fIFILE\fR -+Use FILE as the device map. The default value is /boot/grub/device.map . -+ -+.TP -+\fB--skip-fs-probe\fR -+Do not probe DEVICE for filesystems. -+ -+.TP -+\fB--verbose\fR -+Print verbose messages. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-editenv.1 b/util/grub-editenv.1 -new file mode 100644 -index 00000000000..d28ba03ba42 ---- /dev/null -+++ b/util/grub-editenv.1 -@@ -0,0 +1,46 @@ -+.TH GRUB-EDITENV 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-editenv\fR \(em Manage the GRUB environment block. -+ -+.SH SYNOPSIS -+\fBgrub-editenv\fR [-v | --verbose] [\fIFILE\fR] -+.RS 14 -+ -+ -+.SH DESCRIPTION -+\fBgrub-editenv\fR is a command line tool to manage GRUB's stored environment. -+ -+.SH OPTIONS -+.TP -+\fB--verbose\fR -+Print verbose messages. -+ -+.TP -+\fBFILE\fR -+.RS 7 -+File name to use for grub environment. Default is /boot/grub/grubenv . -+.RE -+ -+.SH COMMANDS -+.TP -+\fBcreate\fR -+.RS 7 -+Create a blank environment block file. -+.RE -+ -+.TP -+\fBlist\fR -+.RS 7 -+List the current variables. -+.RE -+ -+.TP -+\fBset\fR [\fINAME\fR=\fIVALUE\fR ...] -+Set variables. -+ -+.TP -+\fBunset [\fINAME\fR ...] -+Delete variables. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-file.1 b/util/grub-file.1 -new file mode 100644 -index 00000000000..b29cb327889 ---- /dev/null -+++ b/util/grub-file.1 -@@ -0,0 +1,165 @@ -+.TH GRUB-FILE 1 "Web Feb 26 2014" -+.SH NAME -+\fBgrub-file\fR \(em Check if FILE is of specified type. -+ -+.SH SYNOPSIS -+\fBgrub-file\fR (--is-i386-xen-pae-domu | --is-x86_64-xen-domu | -+.RS 11 -+--is-x86-xen-dom0 | --is-x86-multiboot | -+.RE -+.RS 11 -+--is-x86-multiboot2 | --is-arm-linux | --is-arm64-linux | -+.RE -+.RS 11 -+--is-ia64-linux | --is-mips-linux | --is-mipsel-linux | -+.RE -+.RS 11 -+--is-sparc64-linux | --is-powerpc-linux | --is-x86-linux | -+.RE -+.RS 11 -+--is-x86-linux32 | --is-x86-kfreebsd | --is-i386-kfreebsd | -+.RE -+.RS 11 -+--is-x86_64-kfreebsd | --is-x86-knetbsd | -+.RE -+.RS 11 -+--is-i386-knetbsd | --is-x86_64-knetbsd | --is-i386-efi | -+.RE -+.RS 11 -+--is-x86_64-efi | --is-ia64-efi | --is-arm64-efi | -+.RE -+.RS 11 -+--is-arm-efi | --is-hibernated-hiberfil | --is-x86_64-xnu | -+.RE -+.RS 11 -+--is-i386-xnu | --is-xnu-hibr | --is-x86-bios-bootsector) -+.RE -+.RS 11 -+\fIFILE\fR -+ -+.SH DESCRIPTION -+\fBgrub-file\fR is used to check if \fIFILE\fR is of a specified type. -+ -+.SH OPTIONS -+.TP -+--is-i386-xen-pae-domu -+Check if FILE can be booted as i386 PAE Xen unprivileged guest kernel -+ -+.TP -+--is-x86_64-xen-domu -+Check if FILE can be booted as x86_64 Xen unprivileged guest kernel -+ -+.TP -+--is-x86-xen-dom0 -+Check if FILE can be used as Xen x86 privileged guest kernel -+ -+.TP -+--is-x86-multiboot -+Check if FILE can be used as x86 multiboot kernel -+ -+.TP -+--is-x86-multiboot2 -+Check if FILE can be used as x86 multiboot2 kernel -+ -+.TP -+--is-arm-linux -+Check if FILE is ARM Linux -+ -+.TP -+--is-arm64-linux -+Check if FILE is ARM64 Linux -+ -+.TP -+--is-ia64-linux -+Check if FILE is IA64 Linux -+ -+.TP -+--is-mips-linux -+Check if FILE is MIPS Linux -+ -+.TP -+--is-mipsel-linux -+Check if FILE is MIPSEL Linux -+ -+.TP -+--is-sparc64-linux -+Check if FILE is SPARC64 Linux -+ -+.TP -+--is-powerpc-linux -+Check if FILE is POWERPC Linux -+ -+.TP -+--is-x86-linux -+Check if FILE is x86 Linux -+ -+.TP -+--is-x86-linux32 -+Check if FILE is x86 Linux supporting 32-bit protocol -+ -+.TP -+--is-x86-kfreebsd -+Check if FILE is x86 kFreeBSD -+ -+.TP -+--is-i386-kfreebsd -+Check if FILE is i386 kFreeBSD -+ -+.TP -+--is-x86_64-kfreebsd -+Check if FILE is x86_64 kFreeBSD -+ -+.TP -+--is-x86-knetbsd -+Check if FILE is x86 kNetBSD -+ -+.TP -+--is-i386-knetbsd -+Check if FILE is i386 kNetBSD -+ -+.TP -+--is-x86_64-knetbsd -+Check if FILE is x86_64 kNetBSD -+ -+.TP -+--is-i386-efi -+Check if FILE is i386 EFI file -+ -+.TP -+--is-x86_64-efi -+Check if FILE is x86_64 EFI file -+ -+.TP -+--is-ia64-efi -+Check if FILE is IA64 EFI file -+ -+.TP -+--is-arm64-efi -+Check if FILE is ARM64 EFI file -+ -+.TP -+--is-arm-efi -+Check if FILE is ARM EFI file -+ -+.TP -+--is-hibernated-hiberfil -+Check if FILE is hiberfil.sys in hibernated state -+ -+.TP -+--is-x86_64-xnu -+Check if FILE is x86_64 XNU (Mac OS X kernel) -+ -+.TP -+--is-i386-xnu -+Check if FILE is i386 XNU (Mac OS X kernel) -+ -+.TP -+--is-xnu-hibr -+Check if FILE is XNU (Mac OS X kernel) hibernated image -+ -+.TP -+--is-x86-bios-bootsector -+Check if FILE is BIOS bootsector -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-fstest.1 b/util/grub-fstest.1 -new file mode 100644 -index 00000000000..792fa78634c ---- /dev/null -+++ b/util/grub-fstest.1 -@@ -0,0 +1,99 @@ -+.TH GRUB-FSTEST 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-fstest\fR — Debug tool for GRUB's filesystem driver. -+ -+.SH SYNOPSIS -+\fBgrub-fstest\fR [-c | --diskcount=\fINUM\fR] [-C | --crypto] -+.RS 13 -+[-d | --debug=\fISTRING\fR] [-K | --zfs-key=\fIFILE\fR|\fIprompt\fR] -+.RE -+.RS 13 -+[-n | --length=\fINUM\fR] [-r | --root=\fIDEVICE_NAME\fR] -+.RE -+.RS 13 -+[-s | --skip=\fINUM\fR] [-u | --uncompress] [-v | --verbose] -+.RE -+.RS 13 -+\fIIMAGE_PATH\fR -+ -+.SH DESCRIPTION -+\fBgrub-fstest\fR is a tool for testing GRUB's filesystem drivers. You should not normally need to run this program. -+ -+.SH OPTIONS -+.TP -+\fB--diskcount\fR=\fINUM\fR -+Specify the number of input files. -+ -+.TP -+\fB--crypto\fR -+Mount cryptographic devices. -+ -+.TP -+\fB--debug\fR=\fISTRING\fR -+Set debug environment variable. -+ -+.TP -+\fB--zfs-key\fR=\fIFILE\fR|\fIprompt\fR -+Load ZFS cryptographic key. -+ -+.TP -+\fB--length\fR=\fINUM\fR -+Handle NUM bytes in output file. -+ -+.TP -+\fB--root\fR=\fIDEVICE_NAME\fR -+Set root device. -+ -+.TP -+\fB--skip\fR=\fINUM\fR -+Skip NUM bytes from output file. -+ -+.TP -+\fB--uncompress\fR -+Uncompress data. -+ -+.TP -+\fB--verbose\fR -+Print verbose messages. -+ -+.SH COMMANDS -+.TP -+\fBblocklist\fR \fIFILE\fR -+Display block list of \fIFILE\fR. -+ -+.TP -+\fBcat\fR \fIFILE\fR -+Display \fIFILE\fR on standard output. -+ -+.TP -+\fBcmp\fR \fIFILE\fR \fILOCAL\fR -+Compare \fIFILE\fR with local file \fILOCAL\fR. -+ -+.TP -+\fBcp\fR \fIFILE\fR \fILOCAL\fR -+Copy \fIFILE\fR to local file \fILOCAL\fR. -+ -+.TP -+\fBcrc\fR \fIFILE\fR -+Display the CRC-32 checksum of \fIFILE\fR. -+ -+.TP -+\fBhex\fR \fIFILE\fR -+Display contents of \fIFILE\fR in hexidecimal. -+ -+.TP -+\fBls\fR \fIPATH\fR -+List files at \fIPATH\fR. -+ -+.TP -+\fBxnu_uuid\fR \fIDEVICE\fR -+Display the XNU UUID of \fIDEVICE\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-glue-efi.1 b/util/grub-glue-efi.1 -new file mode 100644 -index 00000000000..72bd555d577 ---- /dev/null -+++ b/util/grub-glue-efi.1 -@@ -0,0 +1,31 @@ -+.TH GRUB-GLUE-EFI 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-glue-efi\fR \(em Create an Apple fat EFI binary. -+ -+.SH SYNOPSIS -+\fBgrub-glue-efi\fR <-3 | --input32=\fIFILE\fR> <-6 | --input64=\fIFILE\fR> -+.RS 15 -+<-o | --output=\fIFILE\fR> [-v | --verbose] -+ -+.SH DESCRIPTION -+\fBgrub-glue-efi\fR creates an Apple fat EFI binary from two EFI binaries. -+ -+.SH OPTIONS -+.TP -+\fB--input32\fR=\fIFILE\fR -+Read 32-bit binary from \fIFILE\fR. -+ -+.TP -+\fB--input64\fR=\fIFILE\fR -+Read 64-bit binary from \fIFILE\fR. -+ -+.TP -+\fB--output\fR=\fIFILE\fR -+Write resulting fat binary to \fIFILE\fR. -+ -+.TP -+\fB--verbose\fR -+Print verbose messages. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-install.8 b/util/grub-install.8 -new file mode 100644 -index 00000000000..1db89e94b3b ---- /dev/null -+++ b/util/grub-install.8 -@@ -0,0 +1,128 @@ -+.TH GRUB-INSTALL 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-install\fR \(em Install GRUB on a device. -+ -+.SH SYNOPSIS -+\fBgrub-install\fR [--modules=\fIMODULES\fR] [--install-modules=\fIMODULES\fR] -+.RS 14 -+[--themes=\fITHEMES\fR] [--fonts=\fIFONTS\fR] [--locales=\fILOCALES\fR] -+.RE -+.RS 14 -+[--compress[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR]] [-d | --directory=\fIDIR\fR] -+.RE -+.RS 14 -+[--grub-mkimage=\fIFILE\fR] [--boot-directory=\fIDIR\fR] -+.RE -+.RS 14 -+[--target=\fITARGET\fR] [--grub-setup=\fIFILE\fR] -+.RE -+.RS 14 -+[--grub-mkrelpath=\fIFILE\fR] [--grub-probe=\fIFILE\fR] -+.RE -+.RS 14 -+[--allow-floppy] [--recheck] [--force] [--force-file-id] -+.RE -+.RS 14 -+[--disk-module=\fIMODULE\fR] [--no-nvram] [--removable] -+.RE -+.RS 14 -+[--bootloader-id=\fIID\fR] [--efi-directory=\fIDIR\fR] \fIINSTALL_DEVICE\fR -+ -+.SH DESCRIPTION -+\fBgrub-install\fR installs GRUB onto a device. This includes copying GRUB images into the target directory (generally \fI/boot/grub\fR), and on some platforms may also include installing GRUB onto a boot sector. -+ -+.SH OPTIONS -+.TP -+\fB--modules\fR=\fIMODULES\fR\! -+Pre-load modules specified by \fIMODULES\fR. -+ -+.TP -+\fB--install-modules\fR=\fIMODULES\fR -+Install only \fIMODULES\fR and their dependencies. The default is to install all available modules. -+ -+.TP -+\fB--themes\fR=\fITHEMES\fR -+Install \fITHEMES\fR. The default is to install the \fIstarfield\fR theme, if available. -+ -+.TP -+\fB--fonts\fR=\fIFONTS\fR -+Install \fIFONTS\fR. The default is to install the \fIunicode\fR font. -+ -+.TP -+\fB--locales\fR=\fILOCALES\fR -+Install only locales listed in \fILOCALES\fR. The default is to install all available locales. -+ -+.TP -+\fB--compress\fR=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR -+Compress GRUB files using the specified compression algorithm. -+ -+.TP -+\fB--directory\fR=\fIDIR\fR -+Use images and modules in \fIDIR\fR. -+ -+.TP -+\fB--grub-mkimage\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-mkimage\fR. The default is \fI/usr/bin/grub-mkimage\fR. -+ -+.TP -+\fB--boot-directory\fR=\fIDIR\fR -+Use \fIDIR\fR as the boot directory. The default is \fI/boot\fR. GRUB will put its files in a subdirectory of this directory named \fIgrub\fR. -+ -+.TP -+\fB--target\fR=\fITARGET\fR -+Install GRUB for \fITARGET\fR platform. The default is the platform \fBgrub-install\fR is running on. -+ -+.TP -+\fB--grub-setup\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-setup\fR. The default is \fI/usr/bin/grub-setup\fR. -+ -+.TP -+\fB--grub-mkrelpath\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-mkrelpath\fR. The default is \fI/usr/bin/grub-mkrelpath\fR. -+ -+.TP -+\fB--grub-probe\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-probe\fR. The default is \fI/usr/bin/grub-mkrelpath\fR. -+ -+.TP -+\fB--allow-floppy -+Make the device also bootable as a floppy. This option is the default for /dev/fdX devices. Some BIOSes will not boot images created with this option. -+ -+.TP -+\fB--recheck -+Delete any existing device map and create a new one if necessary. -+ -+.TP -+\fB--force -+Install even if problems are detected. -+ -+.TP -+\fB--force-file-id -+Use identifier file even if UUID is available. -+ -+.TP -+\fB--disk-module\fR=\fIMODULE\fR -+Use \fIMODULE\fR for disk access. This allows you to manually specify either \fIbiosdisk\fR or \fInative\fR disk access. This option is only available on the BIOS target platform. -+ -+.TP -+\fB--no-nvram -+Do not update the \fIboot-device\fR NVRAM variable. This option is only available on IEEE1275 target platforms. -+ -+.TP -+\fB--removable -+Treat the target device as if it is removeable. This option is only available on the EFI target platform. -+ -+.TP -+\fB--bootloader-id\fR=\fIID\fR -+Use \fIID\fR as the bootloader ID. This option is only available on the EFI target platform. -+ -+.TP -+\fB--efi-directory\fR=\fIDIR\fR -+Use \fIDIR\fR as the EFI System Partition root. This option is only available on the EFI target platform. -+ -+.TP -+\fIINSTALL_DEVICE\fR -+Install GRUB to the block device \fIINSTALL_DEVICE\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-kbdcomp.1 b/util/grub-kbdcomp.1 -new file mode 100644 -index 00000000000..0bb969a5b43 ---- /dev/null -+++ b/util/grub-kbdcomp.1 -@@ -0,0 +1,19 @@ -+.TH GRUB-KBDCOMP 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-kbdcomp\fR \(em Generate a GRUB keyboard layout file. -+ -+.SH SYNOPSIS -+\fBgrub-kbdcomp\fR <-o | --output=\fIFILE\fR> \fICKBMAP_ARGUMENTS\fR -+ -+.SH DESCRIPTION -+\fBgrub-kbdcomp\fR processes an X keyboard layout description in -+\fBkeymaps\fR(5) format into a format that can be used by GRUB's \fBkeymap\fR -+command. -+ -+.SH OPTIONS -+.TP -+\fB--output\fR=\fIFILE\fR -+Write output to \fIFILE\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-macbless.1 b/util/grub-macbless.1 -new file mode 100644 -index 00000000000..41a96186f70 ---- /dev/null -+++ b/util/grub-macbless.1 -@@ -0,0 +1,22 @@ -+.TH GRUB-MACBLESS 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-macbless\fR \(em Mac-style bless on HFS or HFS+ -+ -+.SH SYNOPSIS -+\fBgrub-macbless\fR [-v | --verbose] [-p | --ppc] \fIFILE\fR | [-x | --x86] \fIFILE\fR -+ -+.SH OPTIONS -+.TP -+--x86 -+Bless for x86 based Macs. -+ -+.TP -+--ppc -+Bless for PPC based Macs. -+ -+.TP -+--verbose -+Print verbose messages. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-menulst2cfg.1 b/util/grub-menulst2cfg.1 -new file mode 100644 -index 00000000000..91e2ef87113 ---- /dev/null -+++ b/util/grub-menulst2cfg.1 -@@ -0,0 +1,12 @@ -+.TH GRUB-MENULST2CFG 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-menulst2cfg\fR \(em Convert a configuration file from GRUB 0.xx to GRUB 2.xx format. -+ -+.SH SYNOPSIS -+\fBgrub-menulst2cfg\fR [\fIINFILE\fR [\fIOUTFILE\fR]] -+ -+.SH DESCRIPTION -+\fBgrub-menulst2cfg\fR converts a configuration file from GRUB 0.xx to the current format. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkconfig.8 b/util/grub-mkconfig.8 -new file mode 100644 -index 00000000000..a2d1f577b9b ---- /dev/null -+++ b/util/grub-mkconfig.8 -@@ -0,0 +1,17 @@ -+.TH GRUB-MKCONFIG 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mkconfig\fR \(em Generate a GRUB configuration file. -+ -+.SH SYNOPSIS -+\fBgrub-mkconfig\fR [-o | --output=\fIFILE\fR] -+ -+.SH DESCRIPTION -+\fBgrub-mkconfig\fR generates a configuration file for GRUB. -+ -+.SH OPTIONS -+.TP -+\fB--output\fR=\fIFILE\fR -+Write generated output to \fIFILE\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkfont.1 b/util/grub-mkfont.1 -new file mode 100644 -index 00000000000..3494857987d ---- /dev/null -+++ b/util/grub-mkfont.1 -@@ -0,0 +1,87 @@ -+.TH GRUB-MKFONT 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mkfont\fR \(em Convert common font file formats into the PF2 format. -+ -+.SH SYNOPSIS -+\fBgrub-mkfont\fR [--ascii-bitmaps] [-a | --force-autohint] -+.RS 13 -+[-b | --bold] [-c | --asce=\fINUM\fR] [-d | --desc=\fINUM\fR] -+.RE -+.RS 13 -+[-i | --index=\fINUM\fR] [-n | --name=\fINAME\fR] [--no-bitmap] -+.RE -+.RS 13 -+[--no-hinting] <-o | --output=\fIFILE\fR> -+.RE -+.RS 13 -+[-r | --range=\fIFROM-TO\fR[\fI,FROM-TO\fR]] [-s | --size=\fISIZE\fR] -+.RE -+.RS 13 -+[-v | --verbose] [--width-spec] \fIFONT_FILES\fR -+ -+.SH DESCRIPTION -+\fBgrub-mkfont\fR converts font files from common formats into the PF2 format used by GRUB. -+ -+.SH OPTIONS -+.TP -+--ascii-bitmaps -+Save only bitmaps for ASCII characters. -+ -+.TP -+--force-autohint -+Force generation of automatic hinting. -+ -+.TP -+--bold -+Convert font to bold. -+ -+.TP -+--asce=\fINUM\fR -+Set font ascent to \fINUM\fR. -+ -+.TP -+--desc=\fINUM\fR -+Set font descent to \fINUM\fR. -+ -+.TP -+--index=\fINUM\fR -+Select face index \fINUM\fR. -+ -+.TP -+--name=\fINAME\fR -+Set font family to \fINAME\fR. -+ -+.TP -+--no-bitmap -+Ignore bitmap strikes when loading. -+ -+.TP -+--no-hinting -+Disable hinting. -+ -+.TP -+--output=\fIFILE\fR -+Save ouptut to \fIFILE\fR. This argument is required. -+ -+.TP -+--range=\fIFROM-TO\fR\fI,FROM-TO\fR -+Set the font ranges to each pair of \fIFROM\fR,\fITO\fR. -+ -+.TP -+--size=\fISIZE\fR -+Set font size to \fISIZE\fR. -+ -+.TP -+--verbose -+Print verbose messages. -+ -+.TP -+--width-spec -+Create a width summary file. -+ -+.TP -+\fIFONT_FILES\fR -+The input files to be converted. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkimage.1 b/util/grub-mkimage.1 -new file mode 100644 -index 00000000000..4dea4f54597 ---- /dev/null -+++ b/util/grub-mkimage.1 -@@ -0,0 +1,95 @@ -+.TH GRUB-MKIMAGE 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mkimage\fR \(em Make a bootable GRUB image. -+ -+.SH SYNOPSIS -+\fBgrub-mkimage\fR [-c | --config=\fRFILE\fI] [-C | --compression=(\fIxz\fR,\fInone\fR,\fIauto\fR)] -+.RS 14 -+[-d | --directory=\fRDIR\fR] [-k | --pubkey=\fIFILE\fR] -+.RE -+.RS 14 -+[-m | --memdisk=\fIFILE\fR] [-n | --note] [-o | --output=\fIFILE\fR] -+.RE -+.RS 14 -+[-O | --format=\fIFORMAT\fR] [-p | --prefix=\fIDIR\fR] -+.RE -+.RS 14 -+[-v | --verbose] \fIMODULES\fR -+ -+.SH DESCRIPTION -+\fBgrub-mkimage\fI builds a bootable image of GRUB. -+ -+.SH OPTIONS -+.TP -+--config=\fIFILE\fR -+Embed \fIFILE\fR as the image's initial configuration file. -+ -+.TP -+--compression=(\fIxz\fR,\fInone\fR,\fIauto\fR) -+Use one of \fIxz\fR, \fInone\fR, or \fIauto\fR as the compression method for the core image. -+ -+.TP -+--directory=\fIDIR\fR -+Use images and modules from \fIDIR\fR. The default value is \fB/usr/lib/grub/\fR. -+ -+.TP -+--pubkey=\fIFILE\fR -+Embed the public key \fIFILE\fR for signature checking. -+ -+.TP -+--memdisk=\fIFILE\fR -+Embed the memdisk image \fIFILE\fR. If no \fB-p\fR option is also specified, this implies \fI-p (memdisk)/boot/grub\fR. -+ -+.TP -+--note -+Add a CHRP \fINOTE\fR section. This option is only valid on IEEE1275 platforms. -+ -+.TP -+--output=\fIFILE\fR -+Write the generated file to \fIFILE\fR. The default is to write to standard output. -+ -+.TP -+--format=\fIFORMAT\fR -+Generate an image in the specified \fIFORMAT\fR. Valid values are: -+.RS -+.RS 4 -+.P -+i386-coreboot, -+i386-multiboot, -+i386-pc, -+i386-pc-pxe, -+i386-efi, -+i386-ieee1275, -+i386-qemu, -+x86_64-efi, -+mipsel-yeeloong-flash, -+mipsel-fuloong2f-flash, -+mipself-loongson-elf, -+powerpc-ieee1275, -+sparc64-ieee1275-raw, -+sparc64-ieee1275-cdcore, -+sparc64-ieee1275-aout, -+ia64-efi, -+mips-arc, -+mipsel-arc, -+mipsel-qemu_mips-elf, -+mips-qemu_mips-flash, -+mipsel-qemu_mips-flash, -+mips-qemu_mips-elf -+.RE -+.RE -+ -+.TP -+--prefix=\fIDIR\fR -+Set prefix directory. The default value is \fI/boot/grub\fR. -+ -+.TP -+--verbose -+Print verbose messages. -+ -+.TP -+\fIMODULES\fR -+Include \fIMODULES\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mklayout.1 b/util/grub-mklayout.1 -new file mode 100644 -index 00000000000..d1bbc2ec515 ---- /dev/null -+++ b/util/grub-mklayout.1 -@@ -0,0 +1,27 @@ -+.TH GRUB-MKLAYOUT 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mklayout\fR \(em Generate a GRUB keyboard layout file. -+ -+.SH SYNOPSIS -+\fBgrub-mklayout\fR [-i | --input=\fIFILE\fR] [-o | --output=\fIFILE\fR] -+.RS 15 -+[-v | --verbose] -+ -+.SH DESCRIPTION -+\fBgrub-mklayout\fR generates a GRUB keyboard layout description which corresponds with the Linux console layout description given as input. -+ -+.SH OPTIONS -+.TP -+--input=\fIFILE\fR -+Use \fIFILE\fR as the input. The default value is the standard input device. -+ -+.TP -+--output=\fIFILE\fR -+Use \fIFILE\fR as the output. The default value is the standard output device. -+ -+.TP -+--verbose -+Print verbose messages. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mknetdir.1 b/util/grub-mknetdir.1 -new file mode 100644 -index 00000000000..fa7e8d4ef0d ---- /dev/null -+++ b/util/grub-mknetdir.1 -@@ -0,0 +1,12 @@ -+.TH GRUB-MKNETDIR 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mknetdir\fR \(em Prepare a GRUB netboot directory. -+ -+.SH SYNOPSIS -+\fBgrub-mknetdir\fR -+ -+.SH DESCRIPTION -+\fBgrub-mknetdir\fR prepares a directory for GRUB to be netbooted from. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkpasswd-pbkdf2.1 b/util/grub-mkpasswd-pbkdf2.1 -new file mode 100644 -index 00000000000..73c437c15d8 ---- /dev/null -+++ b/util/grub-mkpasswd-pbkdf2.1 -@@ -0,0 +1,27 @@ -+.TH GRUB-MKPASSWD-PBKDF2 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mkpasswd-pbkdf2\fR \(em Generate a PBKDF2 password hash. -+ -+.SH SYNOPSIS -+\fBgrub-mkpasswd-pbkdf2\fR [-c | --iteration-count=\fINUM\fR] [-l | --buflen=\fINUM\fR] -+.RS 22 -+[-s | --salt=\fINUM\fR] -+ -+.SH DESCRIPTION -+\fBgrub-mkpasswd-pbkdf2\fR generates a PBKDF2 password string suitable for use in a GRUB configuration file. -+ -+.SH OPTIONS -+.TP -+--iteration-count=\fINUM\fR -+Number of PBKDF2 iterations. -+ -+.TP -+--buflen=\fINUM\fR -+Length of generated hash. -+ -+.TP -+--salt=\fINUM\fR -+Length of salt to use. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkrelpath.1 b/util/grub-mkrelpath.1 -new file mode 100644 -index 00000000000..85f1113621d ---- /dev/null -+++ b/util/grub-mkrelpath.1 -@@ -0,0 +1,12 @@ -+.TH GRUB-MKRELPATH 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mkrelpath\fR \(em Generate a relative GRUB path given an OS path. -+ -+.SH SYNOPSIS -+\fBgrub-mkrelpath\fR \fIFILE\fR -+ -+.SH DESCRIPTION -+\fBgrub-mkrelpath\fR takes an OS filesystem path for \fIFILE\fR and returns a relative path suitable for use in a GRUB configuration file. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkrescue.1 b/util/grub-mkrescue.1 -new file mode 100644 -index 00000000000..4ed9fc723fd ---- /dev/null -+++ b/util/grub-mkrescue.1 -@@ -0,0 +1,123 @@ -+.TH GRUB-MKRESCUE 3 "Wed Feb 26 2014" -+.SH NAME -+grub-mkrescue \(em Generate a GRUB rescue image using GNU Xorriso. -+ -+.SH SYNOPSIS -+\fBgrub-mkrescue\fR [-o | --output=\fIFILE\fR] [--modules=\fIMODULES\fR] -+.RS 15 -+[--install-modules=\fIMODULES\fR] [--themes=\fITHEMES\fR] -+.RE -+.RS 15 -+[--fonts=\fIFONTS\fR] [--locales=\fILOCALES\fR] -+.RE -+.RS 15 -+[--compress[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR]] [-d | --directory=\fIDIR\fR] -+.RE -+.RS 15 -+[--grub-mkimage=\fIFILE\fR] [--rom-directory=\fIDIR\fR] -+.RE -+.RS 15 -+[--xorriso=\fIFILE\fR] [--grub-glue-efi=\fIFILE\fR] -+.RE -+.RS 15 -+[--grub-render-label=\fIFILE\fR] [--label-font=\fIFILE\fR] -+.RE -+.RS 15 -+[--label-color=\fICOLOR\fR] [--label-bgcolor=\fIFILE\fR] -+.RE -+.RS 15 -+[--product-name=\fISTRING\fR] [--product-version=\fISTRING\fR] -+.RE -+.RS 15 -+[--sparc-boot] [--arcs-boot] -+ -+.SH DESCRIPTION -+\fBgrub-mkrescue\fR can be used to generate a rescue image with the GRUB bootloader. -+ -+.SH OPTIONS -+.TP -+\fB--output\fR=\fIFILE\fR -+Write the generated file to \fIFILE\fR. The default is to write to standard output. -+ -+.TP -+\fB--modules\fR=\fIMODULES\fR -+Pre-load modules specified by \fIMODULES\fR. -+ -+.TP -+\fB--install-modules\fR=\fIMODULES\fR -+Install only \fIMODULES\fR and their dependencies. The default is to install all available modules. -+ -+.TP -+\fB--themes\fR=\fITHEMES\fR -+Install \fITHEMES\fR. The default is to install the \fIstarfield\fR theme, if available. -+ -+.TP -+\fB--fonts\fR=\fIFONTS\fR -+Install \fIFONTS\fR. The default is to install the \fIunicode\fR font. -+ -+.TP -+\fB--locales\fR=\fILOCALES\fR -+Install only locales listed in \fILOCALES\fR. The default is to install all available locales. -+ -+.TP -+\fB--compress\fR[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR] -+Compress GRUB files using the specified compression algorithm. -+ -+.TP -+\fB--directory\fR=\fIDIR\fR -+Use images and modules in \fIDIR\fR. -+ -+.TP -+\fB--grub-mkimage\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-mkimage\fR(1). The default is \fI/usr/bin/grub-mkimage\fR. -+ -+.TP -+\fB--rom-directory\fR=\fIDIR\fR -+Save ROM images in \fIDIR\fR. -+ -+.TP -+\fB--xorriso\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBxorriso\fI. -+ -+.TP -+\fB--grub-glue-efi\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-glue-efi\fR(3). -+ -+.TP -+\fB--grub-render-label\fR=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-render-label\fR(3). -+ -+.TP -+\fB--label-font\fR=\fIFILE\fR -+Use \fIFILE\fR as the font file for generated labels. -+ -+.TP -+\fB--label-color\fR=\fICOLOR\fR -+Use \fICOLOR\fI as the color for generated labels. -+ -+.TP -+\fB--label-bgcolor\fR=\fICOLOR\fR -+Use \fICOLOR\fR as the background color for generated labels. -+ -+.TP -+\fB--product-name\fR=\fISTRING\fR -+Use \fISTRING\fR as the product name in generated labels. -+ -+.TP -+\fB--product-version\fR=\fISTRING\fR -+Use \fISTRING\fR as the product version in generated labels. -+ -+.TP -+\fB--sparc-boot\fR -+Enable booting the SPARC platform. This disables HFS+, APM, ARCS, and "boot as disk image" on the \fIi386-pc\fR target platform. -+ -+.TP -+\fB--arcs-boot\fR -+Enable ARCS booting. This is typically for big-endian MIPS machines, and disables HFS+, APM, sparc64, and "boot as disk image" on the \fIi386-pc\fR target platform. -+ -+.TP -+\fB--\fR -+All options after a \fB--\fR will be passed directly to xorriso's command line when generating the image. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkstandalone.1 b/util/grub-mkstandalone.1 -new file mode 100644 -index 00000000000..ba2d2bdf279 ---- /dev/null -+++ b/util/grub-mkstandalone.1 -@@ -0,0 +1,100 @@ -+.TH GRUB-MKSTANDALONE 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-mkstandalone\fR \(em Generate a standalone image in the selected format. -+ -+.SH SYNOPSIS -+\fBgrub-mkstandalone\fR [-o | --output=\fIFILE\fR] [-O | --format=\fIFORMAT\fR] -+.RS 19 -+[-C | --compression=(\fIxz\fR|\fInone\fR|\fIauto\fR)] -+.RE -+.RS 19 -+[--modules=\fIMODULES\fR] [--install-modules=\fIMODULES\fR] -+.RE -+.RS 19 -+[--themes=\fITHEMES\fR] [--fonts=\fIFONTS\fR] -+.RE -+.RS 19 -+[--locales=\fILOCALES\fR] [--compress[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR]] -+.RE -+.RS 19 -+[-d | --directory=\fIDIR\fR] [--grub-mkimage=\fIFILE\fR] -+.RE -+.RS 19 -+\fISOURCE...\fR -+ -+.SH DESCRIPTION -+ -+.SH OPTIONS -+.TP -+--output=\fIFILE\fR -+Write the generated file to \fIFILE\fR. The default is to write to standard output. -+ -+.TP -+--format=\fIFORMAT\fR -+Generate an image in the specified \fIFORMAT\fR. Valid values are: -+.RS -+.RS 4 -+.P -+i386-coreboot, -+i386-multiboot, -+i386-pc, -+i386-pc-pxe, -+i386-efi, -+i386-ieee1275, -+i386-qemu, -+x86_64-efi, -+mipsel-yeeloong-flash, -+mipsel-fuloong2f-flash, -+mipself-loongson-elf, -+powerpc-ieee1275, -+sparc64-ieee1275-raw, -+sparc64-ieee1275-cdcore, -+sparc64-ieee1275-aout, -+ia64-efi, -+mips-arc, -+mipsel-arc, -+mipsel-qemu_mips-elf, -+mips-qemu_mips-flash, -+mipsel-qemu_mips-flash, -+mips-qemu_mips-elf -+.RE -+.RE -+ -+.TP -+--compression=(\fIxz\fR|\fInone\fR|\fIauto\fR) -+Use one of \fIxz\fR, \fInone\fR, or \fIauto\fR as the compression method for the core image. -+ -+.TP -+--modules=\fIMODULES\fR -+Pre-load modules specified by \fIMODULES\fR. -+ -+.TP -+--install-modules=\fIMODULES\fR -+Install only \fIMODULES\fR and their dependencies. The default is to install all available modules. -+ -+.TP -+--themes=\fITHEMES\fR -+Install \fITHEMES\fR. The default is to install the \fIstarfield\fR theme, if available. -+ -+.TP -+--fonts=\fIFONTS\fR -+Install \fIFONTS\fR. The default is to install the \fIunicode\fR font. -+ -+.TP -+--locales=\fILOCALES\fR -+Install only locales listed in \fILOCALES\fR. The default is to install all available locales. -+ -+.TP -+--compress[=\fIno\fR,\fIxz\fR,\fIgz\fR,\fIlzo\fR] -+Compress GRUB files using the specified compression algorithm. -+ -+.TP -+--directory=\fIDIR\fR -+Use images and modules in \fIDIR\fR. -+ -+.TP -+--grub-mkimage=\fIFILE\fR -+Use \fIFILE\fR as \fBgrub-mkimage\fR. The default is \fI/usr/bin/grub-mkimage\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-ofpathname.8 b/util/grub-ofpathname.8 -new file mode 100644 -index 00000000000..bf3743aeba1 ---- /dev/null -+++ b/util/grub-ofpathname.8 -@@ -0,0 +1,12 @@ -+.TH GRUB-OFPATHNAME 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-ofpathname\fR \(em Generate an IEEE-1275 device path for a specified device. -+ -+.SH SYNOPSIS -+\fBgrub-ofpathname\fR \fIDEVICE\fR -+ -+.SH DESCRIPTION -+\fBgrub-ofpathname\fR generates an IEEE-1275 device path for the specified \fIDEVICE\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-probe.8 b/util/grub-probe.8 -new file mode 100644 -index 00000000000..04e26c832bb ---- /dev/null -+++ b/util/grub-probe.8 -@@ -0,0 +1,80 @@ -+.TH GRUB-PROBE 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-probe\fR \(em Probe device information for a given path. -+ -+.SH SYNOPSIS -+\fBgrub-probe\fR \[-d | --device] [-m | --device-map=\fIFILE\fR] -+.RS 12 -+[-t | --target=(fs|fs_uuid|fs_label|drive|device|partmap| -+.RE -+.RS 28 -+abstraction|cryptodisk_uuid| -+.RE -+.RS 28 -+msdos_parttype)] -+.RE -+.RS 12 -+[-v | --verbose] (PATH|DEVICE) -+ -+.SH DESCRIPTION -+\fBgrub-probe\fR probes a path or device for filesystem and related information. -+ -+.SH OPTIONS -+.TP -+--device -+Final option represents a \fIDEVICE\fR, rather than a filesystem \fIPATH\fR. -+.TP -+--device-map=\fIFILE\fR -+Use \fIFILE\fR as the device map. The default value is \fI/boot/grub/device.map\fR. -+ -+.TP -+--target=(fs|fs_uuid|fs_label|drive|device|partmap|msdos_parttype) -+Select among various output definitions. The default is \fIfs\fR. -+.RS -+.TP -+\fIfs\fR -+filesystem module -+ -+.TP -+\fIfs_uuid\fR -+filesystem UUID -+ -+.TP -+\fIfs_label\fR -+filesystem label -+ -+.TP -+\fIdrive\fR -+GRUB drive name -+ -+.TP -+\fIdevice\fR -+System device -+ -+.TP -+\fIpartmap\fR -+partition map module -+ -+.TP -+\fIabstraction\fR -+abstraction module -+ -+.TP -+\fIcryptodisk_uuid\fR -+cryptographic container -+ -+.TP -+\fImsdos_partmap\fR -+MS-DOS partition map -+.RE -+ -+.TP -+--verbose -+Print verbose output. -+ -+.TP -+(\fIPATH\fR|\fIDEVICE\fR) -+If --device is passed, a block \fIDEVICE\fR. Otherwise, the \fIPATH\fR of a file on the filesystem. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-reboot.8 b/util/grub-reboot.8 -new file mode 100644 -index 00000000000..faa5e4eece2 ---- /dev/null -+++ b/util/grub-reboot.8 -@@ -0,0 +1,21 @@ -+.TH GRUB-REBOOT 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-reboot\fR \(em Set the default boot menu entry for the next boot only. -+ -+.SH SYNOPSIS -+\fBgrub-reboot\fR [--boot-directory=\fIDIR\fR] \fIMENU_ENTRY\fR -+ -+.SH DESCRIPTION -+\fBgrub-reboot\fR sets the default boot menu entry for the next boot, but not further boots after that. This command only works for GRUB configuration files created with \fIGRUB_DEFAULT=saved\fR in \fI/etc/default/grub\fR. -+ -+.SH OPTIONS -+.TP -+--boot-directory=\fIDIR\fR -+Find GRUB images under \fIDIR/grub\fR. The default value is \fI/boot\fR, resulting in grub images being search for at \fI/boot/grub\fR. -+ -+.TP -+\fIMENU_ENTRY\fR -+A number, a menu item title or a menu item identifier. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-render-label.1 b/util/grub-render-label.1 -new file mode 100644 -index 00000000000..4d51c8abf01 ---- /dev/null -+++ b/util/grub-render-label.1 -@@ -0,0 +1,51 @@ -+.TH GRUB-RENDER-LABEL 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-render-label\fR \(em Render an Apple disk label. -+ -+.SH SYNOPSIS -+\fBgrub-render-label\fR [-b | --bgcolor=\fICOLOR\fR] [-c | --color=\fICOLOR\fR] -+.RS 19 -+[-f | --font=\fIFILE\fR] [-i | --input=\fIFILE\fR] -+.RE -+.RS 19 -+[-o | --output=\fIFILE\fR] [-t | --text=\fISTRING\fR] -+.RE -+.RS 19 -+[-v | --verbose] -+ -+.SH DESCRIPTION -+\fBgrub-render-label\fR renders an Apple disk label (.disk_label) file. -+ -+ -+.SH OPTIONS -+.TP -+\fB--color\fR=\fICOLOR\fR -+Use \fICOLOR\fI as the color for generated labels. -+ -+.TP -+\fB--bgcolor\fR=\fICOLOR\fR -+Use \fICOLOR\fR as the background color for generated labels. -+ -+.TP -+\fB--font\fR=\fIFILE\fR -+Use \fIFILE\fR as the font file for generated labels. -+ -+.TP -+--input=\fIFILE\fR -+Read input text from \fIFILE\fR. -+ -+.TP -+--output=\fIFILE\fR -+Render output to \fIFILE\fR. -+ -+.TP -+--text=\fISTRING\fR -+Use \fISTRING\fR as input text. -+ -+.TP -+--verbose -+Print verbose output. -+ -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-script-check.1 b/util/grub-script-check.1 -new file mode 100644 -index 00000000000..0f1f625b05d ---- /dev/null -+++ b/util/grub-script-check.1 -@@ -0,0 +1,21 @@ -+.TH GRUB-SCRIPT-CHECK 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-script-check\fR \(em Check GRUB configuration file for syntax errors. -+ -+.SH SYNOPSIS -+\fBgrub-script-check\fR [-v | --verbose] \fIPATH\fR -+ -+.SH DESCRIPTION -+\fBgrub-script-check\fR verifies that a specified GRUB configuration file does not contain syntax errors. -+ -+.SH OPTIONS -+.TP -+--verbose -+Print verbose output. -+ -+.TP -+\fIPATH\fR -+Path of the file to use as input. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-set-default.8 b/util/grub-set-default.8 -new file mode 100644 -index 00000000000..a96265a1509 ---- /dev/null -+++ b/util/grub-set-default.8 -@@ -0,0 +1,21 @@ -+.TH GRUB-SET-DEFAULT 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-set-default\fR \(em Set the default boot menu entry for GRUB. -+ -+.SH SYNOPSIS -+\fBgrub-set-default\fR [--boot-directory=\fIDIR\fR] \fIMENU_ENTRY\fR -+ -+.SH DESCRIPTION -+\fBgrub-set-default\fR sets the default boot menu entry for all subsequent boots. This command only works for GRUB configuration files created with \fIGRUB_DEFAULT=saved\fR in \fI/etc/default/grub\fR. -+ -+.SH OPTIONS -+.TP -+--boot-directory=\fIDIR\fR -+Find GRUB images under \fIDIR/grub\fR. The default value is \fI/boot\fR, resulting in grub images being search for at \fI/boot/grub\fR. -+ -+.TP -+\fIMENU_ENTRY\fR -+A number, a menu item title or a menu item identifier. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-sparc64-setup.8 b/util/grub-sparc64-setup.8 -new file mode 100644 -index 00000000000..37ea2dd5eaa ---- /dev/null -+++ b/util/grub-sparc64-setup.8 -@@ -0,0 +1,12 @@ -+.TH GRUB-SPARC64-SETUP 3 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-sparc64-setup\fR \(em Set up a device to boot a sparc64 GRUB image. -+ -+.SH SYNOPSIS -+\fBgrub-sparc64-setup\fR [OPTIONS]. -+ -+.SH DESCRIPTION -+You should not normally run this program directly. Use grub-install instead. -+ -+.SH SEE ALSO -+.BR "info grub" diff --git a/0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch b/0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch deleted file mode 100644 index 6b1580bb49c690b1ffa4aad1f94e3b1bc180bbed..0000000000000000000000000000000000000000 --- a/0028-use-fw_path-prefix-when-fallback-searching-for-grub-.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Fedora Ninjas -Date: Wed, 19 Feb 2014 15:58:43 -0500 -Subject: [PATCH] use fw_path prefix when fallback searching for grub config - -When PXE booting via UEFI firmware, grub was searching for grub.cfg -in the fw_path directory where the grub application was found. If -that didn't exist, a fallback search would look for config file names -based on MAC and IP address. However, the search would look in the -prefix directory which may not be the same fw_path. This patch -changes that behavior to use the fw_path directory for the fallback -search. Only if fw_path is NULL will the prefix directory be searched. - -Signed-off-by: Mark Salter ---- - grub-core/normal/main.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 7ca2e5400b1..02577502116 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -347,7 +347,7 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - char *config; - const char *prefix, *fw_path; - -- fw_path = grub_env_get ("fw_path"); -+ prefix = fw_path = grub_env_get ("fw_path"); - if (fw_path) - { - config = grub_xasprintf ("%s/grub.cfg", fw_path); -@@ -370,7 +370,8 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - } - } - -- prefix = grub_env_get ("prefix"); -+ if (! prefix) -+ prefix = grub_env_get ("prefix"); - if (prefix) - { - grub_size_t config_len; diff --git a/0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch b/0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch deleted file mode 100644 index ab49bb1919860b19c433734557991cf04e6cc75f..0000000000000000000000000000000000000000 --- a/0029-Try-mac-guid-etc-before-grub.cfg-on-tftp-config-file.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 8 Jul 2019 17:33:22 +0200 -Subject: [PATCH] Try mac/guid/etc before grub.cfg on tftp config files. - -Signed-off-by: Peter Jones ---- - grub-core/normal/main.c | 97 ++++++++++++++++++++++++++----------------------- - 1 file changed, 51 insertions(+), 46 deletions(-) - -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 02577502116..880d0ebd454 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -345,61 +345,66 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - /* Guess the config filename. It is necessary to make CONFIG static, - so that it won't get broken by longjmp. */ - char *config; -- const char *prefix, *fw_path; -- -- prefix = fw_path = grub_env_get ("fw_path"); -- if (fw_path) -- { -- config = grub_xasprintf ("%s/grub.cfg", fw_path); -- if (config) -- { -- grub_file_t file; -- -- file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); -- if (file) -- { -- grub_file_close (file); -- grub_enter_normal_mode (config); -- } -- else -- { -- /* Ignore all errors. */ -- grub_errno = 0; -- } -- grub_free (config); -- } -- } -+ const char *prefix; -+ const char *net_search_cfg; -+ int disable_net_search = 0; - -+ prefix = grub_env_get ("fw_path"); - if (! prefix) - prefix = grub_env_get ("prefix"); -+ -+ net_search_cfg = grub_env_get ("feature_net_search_cfg"); -+ if (net_search_cfg && net_search_cfg[0] == 'n') -+ disable_net_search = 1; -+ - if (prefix) - { -- grub_size_t config_len; -- int disable_net_search = 0; -- const char *net_search_cfg; -- -- config_len = grub_strlen (prefix) + -- sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); -- config = grub_malloc (config_len); -- -- if (!config) -- goto quit; -- -- grub_snprintf (config, config_len, "%s/grub.cfg", prefix); -- -- net_search_cfg = grub_env_get ("feature_net_search_cfg"); -- if (net_search_cfg && net_search_cfg[0] == 'n') -- disable_net_search = 1; -- - if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && - !disable_net_search) -- grub_net_search_config_file (config); -+ { -+ grub_size_t config_len; -+ config_len = grub_strlen (prefix) + -+ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); -+ config = grub_malloc (config_len); - -- grub_enter_normal_mode (config); -- grub_free (config); -- } -+ if (! config) -+ goto quit; -+ -+ grub_snprintf (config, config_len, "%s/grub.cfg", prefix); -+ -+ grub_net_search_configfile (config); -+ -+ grub_enter_normal_mode (config); -+ grub_free (config); -+ config = NULL; -+ } -+ -+ if (!config) -+ { -+ config = grub_xasprintf ("%s/grub.cfg", prefix); -+ if (config) -+ { -+ grub_file_t file; -+ -+ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); -+ if (file) -+ { -+ grub_file_close (file); -+ grub_enter_normal_mode (config); -+ } -+ else -+ { -+ /* Ignore all errors. */ -+ grub_errno = 0; -+ } -+ grub_free (config); -+ } -+ } -+ } - else -- grub_enter_normal_mode (0); -+ { -+ grub_enter_normal_mode (0); -+ } - } - else - grub_enter_normal_mode (argv[0]); diff --git a/0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch b/0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch deleted file mode 100644 index 245faf7ef547a9f0be5151acd58ba4bbe9fdd553..0000000000000000000000000000000000000000 --- a/0030-Generate-OS-and-CLASS-in-10_linux-from-etc-os-releas.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 4 Sep 2014 14:23:23 -0400 -Subject: [PATCH] Generate OS and CLASS in 10_linux from /etc/os-release - -This makes us use pretty names in the titles we generate in -grub2-mkconfig when GRUB_DISTRIBUTOR isn't set. - -Resolves: rhbz#996794 - -Signed-off-by: Peter Jones ---- - util/grub.d/10_linux.in | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index cf8d1186981..5f6d3c8d52d 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -29,7 +29,8 @@ export TEXTDOMAINDIR="@localedir@" - CLASS="--class gnu-linux --class gnu --class os --unrestricted" - - if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then -- OS="$(sed 's, release .*$,,g' /etc/system-release)" -+ OS="$(eval $(grep PRETTY_NAME /etc/os-release) ; echo ${PRETTY_NAME})" -+ CLASS="--class $(eval $(grep '^ID_LIKE=\|^ID=' /etc/os-release) ; [ -n "${ID_LIKE}" ] && echo ${ID_LIKE} || echo ${ID}) ${CLASS}" - else - OS="${GRUB_DISTRIBUTOR}" - CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" diff --git a/0031-Minimize-the-sort-ordering-for-.debug-and-rescue-ker.patch b/0031-Minimize-the-sort-ordering-for-.debug-and-rescue-ker.patch deleted file mode 100644 index 3e2d3ae5c821679b65918ca5cf2738d9fc0a3a8a..0000000000000000000000000000000000000000 --- a/0031-Minimize-the-sort-ordering-for-.debug-and-rescue-ker.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 4 Sep 2014 15:52:08 -0400 -Subject: [PATCH] Minimize the sort ordering for .debug and -rescue- kernels. - -Resolves: rhbz#1065360 -Signed-off-by: Peter Jones ---- - util/grub-mkconfig_lib.in | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in -index 301d1ac229a..0f6505bf3b6 100644 ---- a/util/grub-mkconfig_lib.in -+++ b/util/grub-mkconfig_lib.in -@@ -253,6 +253,14 @@ version_test_gt () - *.old:*.old) ;; - *.old:*) version_test_gt_a="`echo "$version_test_gt_a" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=gt ;; - *:*.old) version_test_gt_b="`echo "$version_test_gt_b" | sed -e 's/\.old$//'`" ; version_test_gt_cmp=ge ;; -+ *-rescue*:*-rescue*) ;; -+ *?debug:*?debug) ;; -+ *-rescue*:*?debug) return 1 ;; -+ *?debug:*-rescue*) return 0 ;; -+ *-rescue*:*) return 1 ;; -+ *:*-rescue*) return 0 ;; -+ *?debug:*) return 1 ;; -+ *:*?debug) return 0 ;; - esac - version_test_numeric "$version_test_gt_a" "$version_test_gt_cmp" "$version_test_gt_b" - return "$?" diff --git a/0032-Try-prefix-if-fw_path-doesn-t-work.patch b/0032-Try-prefix-if-fw_path-doesn-t-work.patch deleted file mode 100644 index 54a876ba87dec5a80a80d3c5906e17d4e99f585f..0000000000000000000000000000000000000000 --- a/0032-Try-prefix-if-fw_path-doesn-t-work.patch +++ /dev/null @@ -1,222 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 9 Jul 2019 10:35:16 +0200 -Subject: [PATCH] Try $prefix if $fw_path doesn't work. - -Related: rhbz#1148652 - -Signed-off-by: Peter Jones ---- - grub-core/kern/ieee1275/init.c | 28 +++++---- - grub-core/net/net.c | 2 +- - grub-core/normal/main.c | 134 ++++++++++++++++++++--------------------- - 3 files changed, 82 insertions(+), 82 deletions(-) - -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index e71d1584164..0cd2a627231 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -127,23 +127,25 @@ grub_machine_get_bootlocation (char **device, char **path) - grub_free (canon); - } - else -- *device = grub_ieee1275_encode_devname (bootpath); -- grub_free (type); -- -- filename = grub_ieee1275_get_filename (bootpath); -- if (filename) - { -- char *lastslash = grub_strrchr (filename, '\\'); -- -- /* Truncate at last directory. */ -- if (lastslash) -+ filename = grub_ieee1275_get_filename (bootpath); -+ if (filename) - { -- *lastslash = '\0'; -- grub_translate_ieee1275_path (filename); -+ char *lastslash = grub_strrchr (filename, '\\'); - -- *path = filename; -- } -+ /* Truncate at last directory. */ -+ if (lastslash) -+ { -+ *lastslash = '\0'; -+ grub_translate_ieee1275_path (filename); -+ -+ *path = filename; -+ } -+ } -+ *device = grub_ieee1275_encode_devname (bootpath); - } -+ -+ grub_free (type); - grub_free (bootpath); - } - -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 4d3eb5c1a52..0ef148f4adc 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -1869,7 +1869,7 @@ grub_net_search_config_file (char *config) - /* Remove the remaining minus sign at the end. */ - config[config_len] = '\0'; - -- return GRUB_ERR_NONE; -+ return GRUB_ERR_FILE_NOT_FOUND; - } - - static struct grub_preboot *fini_hnd; -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 880d0ebd454..d5df4f815b0 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -335,81 +335,79 @@ grub_enter_normal_mode (const char *config) - grub_boot_time ("Exiting normal mode"); - } - -+static grub_err_t -+grub_try_normal (const char *variable) -+{ -+ char *config; -+ const char *prefix; -+ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; -+ const char *net_search_cfg; -+ int disable_net_search = 0; -+ -+ prefix = grub_env_get (variable); -+ if (!prefix) -+ return GRUB_ERR_FILE_NOT_FOUND; -+ -+ net_search_cfg = grub_env_get ("feature_net_search_cfg"); -+ if (net_search_cfg && net_search_cfg[0] == 'n') -+ disable_net_search = 1; -+ -+ if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && -+ !disable_net_search) -+ { -+ grub_size_t config_len; -+ config_len = grub_strlen (prefix) + -+ sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); -+ config = grub_malloc (config_len); -+ -+ if (! config) -+ return GRUB_ERR_FILE_NOT_FOUND; -+ -+ grub_snprintf (config, config_len, "%s/grub.cfg", prefix); -+ err = grub_net_search_config_file (config); -+ } -+ -+ if (err != GRUB_ERR_NONE) -+ { -+ config = grub_xasprintf ("%s/grub.cfg", prefix); -+ if (config) -+ { -+ grub_file_t file; -+ file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); -+ if (file) -+ { -+ grub_file_close (file); -+ err = GRUB_ERR_NONE; -+ } -+ } -+ } -+ -+ if (err == GRUB_ERR_NONE) -+ grub_enter_normal_mode (config); -+ -+ grub_errno = 0; -+ grub_free (config); -+ return err; -+} -+ - /* Enter normal mode from rescue mode. */ - static grub_err_t - grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - int argc, char *argv[]) - { -- if (argc == 0) -- { -- /* Guess the config filename. It is necessary to make CONFIG static, -- so that it won't get broken by longjmp. */ -- char *config; -- const char *prefix; -- const char *net_search_cfg; -- int disable_net_search = 0; -- -- prefix = grub_env_get ("fw_path"); -- if (! prefix) -- prefix = grub_env_get ("prefix"); -- -- net_search_cfg = grub_env_get ("feature_net_search_cfg"); -- if (net_search_cfg && net_search_cfg[0] == 'n') -- disable_net_search = 1; -- -- if (prefix) -- { -- if (grub_strncmp (prefix + 1, "tftp", sizeof ("tftp") - 1) == 0 && -- !disable_net_search) -- { -- grub_size_t config_len; -- config_len = grub_strlen (prefix) + -- sizeof ("/grub.cfg-XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"); -- config = grub_malloc (config_len); -- -- if (! config) -- goto quit; -- -- grub_snprintf (config, config_len, "%s/grub.cfg", prefix); -- -- grub_net_search_configfile (config); -- -- grub_enter_normal_mode (config); -- grub_free (config); -- config = NULL; -- } -- -- if (!config) -- { -- config = grub_xasprintf ("%s/grub.cfg", prefix); -- if (config) -- { -- grub_file_t file; -- -- file = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); -- if (file) -- { -- grub_file_close (file); -- grub_enter_normal_mode (config); -- } -- else -- { -- /* Ignore all errors. */ -- grub_errno = 0; -- } -- grub_free (config); -- } -- } -- } -- else -- { -- grub_enter_normal_mode (0); -- } -- } -- else -+ if (argc) - grub_enter_normal_mode (argv[0]); -+ else -+ { -+ /* Guess the config filename. */ -+ grub_err_t err; -+ err = grub_try_normal ("fw_path"); -+ if (err == GRUB_ERR_FILE_NOT_FOUND) -+ err = grub_try_normal ("prefix"); -+ if (err == GRUB_ERR_FILE_NOT_FOUND) -+ grub_enter_normal_mode (0); -+ } - --quit: - return 0; - } - diff --git a/0033-Use-rpm-s-sort-for-grub2-mkconfig.patch b/0033-Use-rpm-s-sort-for-grub2-mkconfig.patch deleted file mode 100644 index ff1c13ecac512d2deee72476b941561256f6662b..0000000000000000000000000000000000000000 --- a/0033-Use-rpm-s-sort-for-grub2-mkconfig.patch +++ /dev/null @@ -1,475 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robert Marshall -Date: Mon, 16 Mar 2015 14:14:19 -0400 -Subject: [PATCH] Use rpm's sort for grub2-mkconfig - -Add an option for rpm-based systems to use the rpm-sort library to sort -kernels. This avoids problems due to discrepancies between `sort -V` -and rpm. - -Signed-off-by: Robert Marshall -[pjones: fix --enable-rpm-sort configure option] -Signed-off-by: Peter Jones -[thierry.vignaud: fix build with rpm-4.16] -Signed-off-by: Thierry Vignaud -[tim: fix disabling grub-rpm-sort by ./configure] -Signed-off-by: Tim Landscheidt -[javierm: don't check for rpmvercmp in librpm] -Signed-off-by: Javier Martinez Canillas -[rharwood: commit message] -Signed-off-by: Robbie Harwood ---- - configure.ac | 37 ++++++ - Makefile.util.def | 17 +++ - util/grub-rpm-sort.c | 281 ++++++++++++++++++++++++++++++++++++++++++++++ - util/grub-mkconfig_lib.in | 11 +- - util/grub-rpm-sort.8 | 12 ++ - 5 files changed, 357 insertions(+), 1 deletion(-) - create mode 100644 util/grub-rpm-sort.c - create mode 100644 util/grub-rpm-sort.8 - -diff --git a/configure.ac b/configure.ac -index bec8535af70..643a13f9147 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -72,6 +72,7 @@ grub_TRANSFORM([grub-mkrelpath]) - grub_TRANSFORM([grub-mkrescue]) - grub_TRANSFORM([grub-probe]) - grub_TRANSFORM([grub-reboot]) -+grub_TRANSFORM([grub-rpm-sort]) - grub_TRANSFORM([grub-script-check]) - grub_TRANSFORM([grub-set-default]) - grub_TRANSFORM([grub-sparc64-setup]) -@@ -95,6 +96,7 @@ grub_TRANSFORM([grub-mkrescue.1]) - grub_TRANSFORM([grub-mkstandalone.3]) - grub_TRANSFORM([grub-ofpathname.3]) - grub_TRANSFORM([grub-probe.3]) -+grub_TRANSFORM([grub-rpm-sort.8]) - grub_TRANSFORM([grub-reboot.3]) - grub_TRANSFORM([grub-render-label.3]) - grub_TRANSFORM([grub-script-check.3]) -@@ -1860,6 +1862,35 @@ fi - - AC_SUBST([LIBDEVMAPPER]) - -+AC_ARG_ENABLE([rpm-sort], -+ [AS_HELP_STRING([--enable-rpm-sort], -+ [enable native rpm sorting of kernels in grub (default=guessed)])]) -+if test x"$enable_rpm_sort" = xno ; then -+ rpm_sort_excuse="explicitly disabled" -+else -+ enable_rpm_sort=yes -+fi -+ -+if test x"$rpm_sort_excuse" = x ; then -+ # Check for rpmlib header. -+ AC_CHECK_HEADER([rpm/rpmlib.h], [], -+ [rpm_sort_excuse="need rpm/rpmlib header"]) -+fi -+ -+if test x"$rpm_sort_excuse" = x ; then -+ # Check for rpmio library. -+ AC_CHECK_LIB([rpmio], [rpmvercmp], [], -+ [rpm_sort_excuse="rpmio missing rpmvercmp"]) -+fi -+ -+if test x"$rpm_sort_excuse" = x ; then -+ LIBRPM="-lrpmio"; -+ AC_DEFINE([HAVE_RPMIO], [1], -+ [Define to 1 if you have the rpmio library.]) -+fi -+ -+AC_SUBST([LIBRPM]) -+ - LIBGEOM= - if test x$host_kernel = xkfreebsd; then - AC_CHECK_LIB([geom], [geom_gettree], [], -@@ -2047,6 +2078,7 @@ AM_CONDITIONAL([COND_GRUB_EMU_SDL], [test x$enable_grub_emu_sdl = xyes]) - AM_CONDITIONAL([COND_GRUB_EMU_PCI], [test x$enable_grub_emu_pci = xyes]) - AM_CONDITIONAL([COND_GRUB_MKFONT], [test x$enable_grub_mkfont = xyes]) - AM_CONDITIONAL([COND_GRUB_MOUNT], [test x$enable_grub_mount = xyes]) -+AM_CONDITIONAL([COND_GRUB_RPM_SORT], [test x$enable_rpm_sort = xyes]) - AM_CONDITIONAL([COND_HAVE_FONT_SOURCE], [test x$FONT_SOURCE != x]) - if test x$FONT_SOURCE != x ; then - HAVE_FONT_SOURCE=1 -@@ -2168,6 +2200,11 @@ echo grub-mount: Yes - else - echo grub-mount: No "($grub_mount_excuse)" - fi -+if [ x"$rpm_sort_excuse" = x ]; then -+echo grub-rpm-sort: Yes -+else -+echo grub-rpm-sort: No "($rpm_sort_excuse)" -+fi - if [ x"$starfield_excuse" = x ]; then - echo starfield theme: Yes - echo With DejaVuSans font from $DJVU_FONT_SOURCE -diff --git a/Makefile.util.def b/Makefile.util.def -index 2c9b283a230..bc10cc79722 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -703,6 +703,23 @@ program = { - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - }; - -+program = { -+ name = grub-rpm-sort; -+ mansection = 8; -+ installdir = sbin; -+ -+ common = grub-core/kern/emu/misc.c; -+ common = grub-core/kern/emu/argp_common.c; -+ common = grub-core/osdep/init.c; -+ common = util/misc.c; -+ common = util/grub-rpm-sort.c; -+ -+ ldadd = libgrubkern.a; -+ ldadd = grub-core/lib/gnulib/libgnu.a; -+ ldadd = '$(LIBDEVMAPPER) $(LIBRPM)'; -+ condition = COND_GRUB_RPM_SORT; -+}; -+ - script = { - name = grub-mkconfig; - common = util/grub-mkconfig.in; -diff --git a/util/grub-rpm-sort.c b/util/grub-rpm-sort.c -new file mode 100644 -index 00000000000..f33bd1ed568 ---- /dev/null -+++ b/util/grub-rpm-sort.c -@@ -0,0 +1,281 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static size_t -+read_file (const char *input, char **ret) -+{ -+ FILE *in; -+ size_t s; -+ size_t sz = 2048; -+ size_t offset = 0; -+ char *text; -+ -+ if (!strcmp(input, "-")) -+ in = stdin; -+ else -+ in = grub_util_fopen(input, "r"); -+ -+ text = xmalloc (sz); -+ -+ if (!in) -+ grub_util_error (_("cannot open `%s': %s"), input, strerror (errno)); -+ -+ while ((s = fread (text + offset, 1, sz - offset, in)) != 0) -+ { -+ offset += s; -+ if (sz - offset == 0) -+ { -+ sz += 2048; -+ text = xrealloc (text, sz); -+ } -+ } -+ -+ text[offset] = '\0'; -+ *ret = text; -+ -+ if (in != stdin) -+ fclose(in); -+ -+ return offset + 1; -+} -+ -+/* returns name/version/release */ -+/* NULL string pointer returned if nothing found */ -+static void -+split_package_string (char *package_string, char **name, -+ char **version, char **release) -+{ -+ char *package_version, *package_release; -+ -+ /* Release */ -+ package_release = strrchr (package_string, '-'); -+ -+ if (package_release != NULL) -+ *package_release++ = '\0'; -+ -+ *release = package_release; -+ -+ /* Version */ -+ package_version = strrchr(package_string, '-'); -+ -+ if (package_version != NULL) -+ *package_version++ = '\0'; -+ -+ *version = package_version; -+ /* Name */ -+ *name = package_string; -+ -+ /* Bubble up non-null values from release to name */ -+ if (*name == NULL) -+ { -+ *name = (*version == NULL ? *release : *version); -+ *version = *release; -+ *release = NULL; -+ } -+ if (*version == NULL) -+ { -+ *version = *release; -+ *release = NULL; -+ } -+} -+ -+/* -+ * package name-version-release comparator for qsort -+ * expects p, q which are pointers to character strings (char *) -+ * which will not be altered in this function -+ */ -+static int -+package_version_compare (const void *p, const void *q) -+{ -+ char *local_p, *local_q; -+ char *lhs_name, *lhs_version, *lhs_release; -+ char *rhs_name, *rhs_version, *rhs_release; -+ int vercmpflag = 0; -+ -+ local_p = alloca (strlen (*(char * const *)p) + 1); -+ local_q = alloca (strlen (*(char * const *)q) + 1); -+ -+ /* make sure these allocated */ -+ assert (local_p); -+ assert (local_q); -+ -+ strcpy (local_p, *(char * const *)p); -+ strcpy (local_q, *(char * const *)q); -+ -+ split_package_string (local_p, &lhs_name, &lhs_version, &lhs_release); -+ split_package_string (local_q, &rhs_name, &rhs_version, &rhs_release); -+ -+ /* Check Name and return if unequal */ -+ vercmpflag = rpmvercmp ((lhs_name == NULL ? "" : lhs_name), -+ (rhs_name == NULL ? "" : rhs_name)); -+ if (vercmpflag != 0) -+ return vercmpflag; -+ -+ /* Check version and return if unequal */ -+ vercmpflag = rpmvercmp ((lhs_version == NULL ? "" : lhs_version), -+ (rhs_version == NULL ? "" : rhs_version)); -+ if (vercmpflag != 0) -+ return vercmpflag; -+ -+ /* Check release and return the version compare value */ -+ vercmpflag = rpmvercmp ((lhs_release == NULL ? "" : lhs_release), -+ (rhs_release == NULL ? "" : rhs_release)); -+ -+ return vercmpflag; -+} -+ -+static void -+add_input (const char *filename, char ***package_names, size_t *n_package_names) -+{ -+ char *orig_input_buffer = NULL; -+ char *input_buffer; -+ char *position_of_newline; -+ char **names = *package_names; -+ char **new_names = NULL; -+ size_t n_names = *n_package_names; -+ -+ if (!*package_names) -+ new_names = names = xmalloc (sizeof (char *) * 2); -+ -+ if (read_file (filename, &orig_input_buffer) < 2) -+ { -+ if (new_names) -+ free (new_names); -+ if (orig_input_buffer) -+ free (orig_input_buffer); -+ return; -+ } -+ -+ input_buffer = orig_input_buffer; -+ while (input_buffer && *input_buffer && -+ (position_of_newline = strchrnul (input_buffer, '\n'))) -+ { -+ size_t sz = position_of_newline - input_buffer; -+ char *new; -+ -+ if (sz == 0) -+ { -+ input_buffer = position_of_newline + 1; -+ continue; -+ } -+ -+ new = xmalloc (sz+1); -+ strncpy (new, input_buffer, sz); -+ new[sz] = '\0'; -+ -+ names = xrealloc (names, sizeof (char *) * (n_names + 1)); -+ names[n_names] = new; -+ n_names++; -+ -+ /* move buffer ahead to next line */ -+ input_buffer = position_of_newline + 1; -+ if (*position_of_newline == '\0') -+ input_buffer = NULL; -+ } -+ -+ free (orig_input_buffer); -+ -+ *package_names = names; -+ *n_package_names = n_names; -+} -+ -+static char * -+help_filter (int key, const char *text, void *input __attribute__ ((unused))) -+{ -+ return (char *)text; -+} -+ -+static struct argp_option options[] = { -+ { 0, } -+}; -+ -+struct arguments -+{ -+ size_t ninputs; -+ size_t input_max; -+ char **inputs; -+}; -+ -+static error_t -+argp_parser (int key, char *arg, struct argp_state *state) -+{ -+ struct arguments *arguments = state->input; -+ switch (key) -+ { -+ case ARGP_KEY_ARG: -+ assert (arguments->ninputs < arguments->input_max); -+ arguments->inputs[arguments->ninputs++] = xstrdup (arg); -+ break; -+ default: -+ return ARGP_ERR_UNKNOWN; -+ } -+ return 0; -+} -+ -+static struct argp argp = { -+ options, argp_parser, N_("[INPUT_FILES]"), -+ N_("Sort a list of strings in RPM version sort order."), -+ NULL, help_filter, NULL -+}; -+ -+int -+main (int argc, char *argv[]) -+{ -+ struct arguments arguments; -+ char **package_names = NULL; -+ size_t n_package_names = 0; -+ int i; -+ -+ grub_util_host_init (&argc, &argv); -+ -+ memset (&arguments, 0, sizeof (struct arguments)); -+ arguments.input_max = argc+1; -+ arguments.inputs = xmalloc ((arguments.input_max + 1) -+ * sizeof (arguments.inputs[0])); -+ memset (arguments.inputs, 0, (arguments.input_max + 1) -+ * sizeof (arguments.inputs[0])); -+ -+ /* Parse our arguments */ -+ if (argp_parse (&argp, argc, argv, 0, 0, &arguments) != 0) -+ grub_util_error ("%s", _("Error in parsing command line arguments\n")); -+ -+ /* If there's no inputs in argv, add one for stdin */ -+ if (!arguments.ninputs) -+ { -+ arguments.ninputs = 1; -+ arguments.inputs[0] = xmalloc (2); -+ strcpy(arguments.inputs[0], "-"); -+ } -+ -+ for (i = 0; i < arguments.ninputs; i++) -+ add_input(arguments.inputs[i], &package_names, &n_package_names); -+ -+ if (package_names == NULL || n_package_names < 1) -+ grub_util_error ("%s", _("Invalid input\n")); -+ -+ qsort (package_names, n_package_names, sizeof (char *), -+ package_version_compare); -+ -+ /* send sorted list to stdout */ -+ for (i = 0; i < n_package_names; i++) -+ { -+ fprintf (stdout, "%s\n", package_names[i]); -+ free (package_names[i]); -+ } -+ -+ free (package_names); -+ for (i = 0; i < arguments.ninputs; i++) -+ free (arguments.inputs[i]); -+ -+ free (arguments.inputs); -+ -+ return 0; -+} -diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in -index 0f6505bf3b6..42c2ea9ba50 100644 ---- a/util/grub-mkconfig_lib.in -+++ b/util/grub-mkconfig_lib.in -@@ -33,6 +33,9 @@ fi - if test "x$grub_mkrelpath" = x; then - grub_mkrelpath="${bindir}/@grub_mkrelpath@" - fi -+if test "x$grub_rpm_sort" = x; then -+ grub_rpm_sort="${sbindir}/@grub_rpm_sort@" -+fi - - if command -v gettext >/dev/null; then - : -@@ -218,6 +221,12 @@ version_sort () - esac - } - -+if [ "x$grub_rpm_sort" != x -a -x "$grub_rpm_sort" ]; then -+ kernel_sort="$grub_rpm_sort" -+else -+ kernel_sort=version_sort -+fi -+ - version_test_numeric () - { - version_test_numeric_a="$1" -@@ -234,7 +243,7 @@ version_test_numeric () - version_test_numeric_a="$version_test_numeric_b" - version_test_numeric_b="$version_test_numeric_c" - fi -- if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | version_sort | head -n 1 | grep -qx "$version_test_numeric_b" ; then -+ if (echo "$version_test_numeric_a" ; echo "$version_test_numeric_b") | "$kernel_sort" | head -n 1 | grep -qx "$version_test_numeric_b" ; then - return 0 - else - return 1 -diff --git a/util/grub-rpm-sort.8 b/util/grub-rpm-sort.8 -new file mode 100644 -index 00000000000..8ce21488448 ---- /dev/null -+++ b/util/grub-rpm-sort.8 -@@ -0,0 +1,12 @@ -+.TH GRUB-RPM-SORT 8 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-rpm-sort\fR \(em Sort input according to RPM version compare. -+ -+.SH SYNOPSIS -+\fBgrub-rpm-sort\fR [OPTIONS]. -+ -+.SH DESCRIPTION -+You should not normally run this program directly. Use grub-mkconfig instead. -+ -+.SH SEE ALSO -+.BR "info grub" diff --git a/0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch b/0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch deleted file mode 100644 index 4eb37e1ed475938f4491959feae6650a5d4ab894..0000000000000000000000000000000000000000 --- a/0034-Make-grub2-mkconfig-construct-titles-that-look-like-.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 28 Apr 2015 11:15:03 -0400 -Subject: [PATCH] Make grub2-mkconfig construct titles that look like the ones - we want elsewhere. - -Resolves: rhbz#1215839 - -Signed-off-by: Peter Jones ---- - util/grub.d/10_linux.in | 34 +++++++++++++++++++++++++++------- - 1 file changed, 27 insertions(+), 7 deletions(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 5f6d3c8d52d..786dbabb4a8 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -78,6 +78,32 @@ case x"$GRUB_FS" in - ;; - esac - -+mktitle () -+{ -+ local title_type -+ local version -+ local OS_NAME -+ local OS_VERS -+ -+ title_type=$1 && shift -+ version=$1 && shift -+ -+ OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})" -+ OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})" -+ -+ case $title_type in -+ recovery) -+ title=$(printf '%s (%s) %s (recovery mode)' \ -+ "${OS_NAME}" "${version}" "${OS_VERS}") -+ ;; -+ *) -+ title=$(printf '%s (%s) %s' \ -+ "${OS_NAME}" "${version}" "${OS_VERS}") -+ ;; -+ esac -+ echo -n ${title} -+} -+ - title_correction_code= - - linux_entry () -@@ -91,17 +117,11 @@ linux_entry () - boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" - fi - if [ x$type != xsimple ] ; then -- case $type in -- recovery) -- title="$(gettext_printf "%s, with Linux %s (recovery mode)" "${os}" "${version}")" ;; -- *) -- title="$(gettext_printf "%s, with Linux %s" "${os}" "${version}")" ;; -- esac -+ title=$(mktitle "$type" "$version") - if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then - replacement_title="$(echo "Advanced options for ${OS}" | sed 's,>,>>,g')>$(echo "$title" | sed 's,>,>>,g')" - quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" - title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" -- grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")" - fi - echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" - else diff --git a/0035-Add-friendly-grub2-password-config-tool-985962.patch b/0035-Add-friendly-grub2-password-config-tool-985962.patch deleted file mode 100644 index 2d6f18a62096a733d4f8318e57ec77008fe14f98..0000000000000000000000000000000000000000 --- a/0035-Add-friendly-grub2-password-config-tool-985962.patch +++ /dev/null @@ -1,269 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robert Marshall -Date: Thu, 25 Jun 2015 11:13:11 -0400 -Subject: [PATCH] Add friendly grub2 password config tool (#985962) - -Provided a tool for users to reset the grub2 root user password -without having to alter the grub.cfg. The hashed password now -lives in a root-only-readable configuration file. - -Resolves: rhbz#985962 - -Signed-off-by: Robert Marshall -[pjones: fix the efidir in grub-setpassword and rename tool] -Signed-off-by: Peter Jones -[luto: fix grub-setpassword -o's output path] -Andy Lutomirski ---- - configure.ac | 1 + - Makefile.util.def | 13 +++++ - util/grub-mkconfig.in | 2 + - util/grub-set-password.8 | 28 ++++++++++ - util/grub-set-password.in | 128 ++++++++++++++++++++++++++++++++++++++++++++++ - util/grub.d/01_users.in | 11 ++++ - 6 files changed, 183 insertions(+) - create mode 100644 util/grub-set-password.8 - create mode 100644 util/grub-set-password.in - create mode 100644 util/grub.d/01_users.in - -diff --git a/configure.ac b/configure.ac -index 643a13f9147..25e1abb59b9 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -72,6 +72,7 @@ grub_TRANSFORM([grub-mkrelpath]) - grub_TRANSFORM([grub-mkrescue]) - grub_TRANSFORM([grub-probe]) - grub_TRANSFORM([grub-reboot]) -+grub_TRANSFORM([grub-set-password]) - grub_TRANSFORM([grub-rpm-sort]) - grub_TRANSFORM([grub-script-check]) - grub_TRANSFORM([grub-set-default]) -diff --git a/Makefile.util.def b/Makefile.util.def -index bc10cc79722..8ca4c14f0b9 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -452,6 +452,12 @@ script = { - installdir = grubconf; - }; - -+script = { -+ name = '01_users'; -+ common = util/grub.d/01_users.in; -+ installdir = grubconf; -+}; -+ - script = { - name = '10_windows'; - common = util/grub.d/10_windows.in; -@@ -741,6 +747,13 @@ script = { - installdir = sbin; - }; - -+script = { -+ name = grub-set-password; -+ common = util/grub-set-password.in; -+ mansection = 8; -+ installdir = sbin; -+}; -+ - script = { - name = grub-mkconfig_lib; - common = util/grub-mkconfig_lib.in; -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index 8ea2315ebc2..ba14cf6261c 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -276,6 +276,8 @@ for i in "${grub_mkconfig_dir}"/* ; do - *~) ;; - # emacsen autosave files. FIXME: support other editors - */\#*\#) ;; -+ # rpm config files of yore. -+ *.rpmsave|*.rpmnew|*.rpmorig) ;; - *) - if grub_file_is_not_garbage "$i" && test -x "$i" ; then - echo -diff --git a/util/grub-set-password.8 b/util/grub-set-password.8 -new file mode 100644 -index 00000000000..9646546e43d ---- /dev/null -+++ b/util/grub-set-password.8 -@@ -0,0 +1,28 @@ -+.TH GRUB-SET-PASSWORD 3 "Thu Jun 25 2015" -+.SH NAME -+\fBgrub-set-password\fR \(em Generate the user.cfg file containing the hashed grub bootloader password. -+ -+.SH SYNOPSIS -+\fBgrub-set-password\fR [OPTION] -+ -+.SH DESCRIPTION -+\fBgrub-set-password\fR outputs the user.cfg file which contains the hashed GRUB bootloader password. This utility only supports configurations where there is a single root user. -+ -+The file has the format: -+GRUB2_PASSWORD=<\fIhashed password\fR>. -+ -+.SH OPTIONS -+.TP -+-h, --help -+Display program usage and exit. -+.TP -+-v, --version -+Display the current version. -+.TP -+-o, --output=<\fIDIRECTORY\fR> -+Choose the file path to which user.cfg will be written. -+ -+.SH SEE ALSO -+.BR "info grub" -+ -+.BR "info grub2-mkpasswd-pbkdf2" -diff --git a/util/grub-set-password.in b/util/grub-set-password.in -new file mode 100644 -index 00000000000..5ebf50576d6 ---- /dev/null -+++ b/util/grub-set-password.in -@@ -0,0 +1,128 @@ -+#!/bin/sh -e -+ -+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/') -+if [ -d /sys/firmware/efi/efivars/ ]; then -+ grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` -+else -+ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` -+fi -+ -+PACKAGE_VERSION="@PACKAGE_VERSION@" -+PACKAGE_NAME="@PACKAGE_NAME@" -+self=`basename $0` -+bindir="@bindir@" -+grub_mkpasswd="${bindir}/@grub_mkpasswd_pbkdf2@" -+ -+# Usage: usage -+# Print the usage. -+usage () { -+ cat < put user.cfg in a user-selected directory -+ -+Report bugs at https://bugzilla.redhat.com. -+EOF -+} -+ -+argument () { -+ opt=$1 -+ shift -+ -+ if test $# -eq 0; then -+ gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 -+ exit 1 -+ fi -+ echo $1 -+} -+ -+# Ensure that it's the root user running this script -+if [ "${EUID}" -ne 0 ]; then -+ echo "The grub bootloader password may only be set by root." -+ usage -+ exit 2 -+fi -+ -+# Check the arguments. -+while test $# -gt 0 -+do -+ option=$1 -+ shift -+ -+ case "$option" in -+ -h | --help) -+ usage -+ exit 0 ;; -+ -v | --version) -+ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" -+ exit 0 ;; -+ -o | --output) -+ OUTPUT_PATH=`argument $option "$@"`; shift ;; -+ --output=*) -+ OUTPUT_PATH=`echo "$option" | sed 's/--output=//'` ;; -+ -o=*) -+ OUTPUT_PATH=`echo "$option" | sed 's/-o=//'` ;; -+ esac -+done -+ -+# set user input or default path for user.cfg file -+if [ -z "${OUTPUT_PATH}" ]; then -+ OUTPUT_PATH="${grubdir}" -+fi -+ -+if [ ! -d "${OUTPUT_PATH}" ]; then -+ echo "${OUTPUT_PATH} does not exist." -+ usage -+ exit 2; -+fi -+ -+ttyopt=$(stty -g) -+fixtty() { -+ stty ${ttyopt} -+} -+ -+trap fixtty EXIT -+stty -echo -+ -+# prompt & confirm new grub2 root user password -+echo -n "Enter password: " -+read PASSWORD -+echo -+echo -n "Confirm password: " -+read PASSWORD_CONFIRM -+echo -+stty ${ttyopt} -+ -+getpass() { -+ local P0 -+ local P1 -+ P0="$1" && shift -+ P1="$1" && shift -+ -+ ( echo ${P0} ; echo ${P1} ) | \ -+ LC_ALL=C ${grub_mkpasswd} | \ -+ grep -v '[eE]nter password:' | \ -+ sed -e "s/PBKDF2 hash of your password is //" -+} -+ -+MYPASS="$(getpass "${PASSWORD}" "${PASSWORD_CONFIRM}")" -+if [ -z "${MYPASS}" ]; then -+ echo "${self}: error: empty password" 1>&2 -+ exit 1 -+fi -+ -+# on the ESP, these will fail to set the permissions, but it's okay because -+# the directory is protected. -+install -m 0600 /dev/null "${OUTPUT_PATH}/user.cfg" 2>/dev/null || : -+chmod 0600 "${OUTPUT_PATH}/user.cfg" 2>/dev/null || : -+echo "GRUB2_PASSWORD=${MYPASS}" > "${OUTPUT_PATH}/user.cfg" -+ -+if ! grep -q "^### BEGIN /etc/grub.d/01_users ###$" "${OUTPUT_PATH}/grub.cfg"; then -+ echo "WARNING: The current configuration lacks password support!" -+ echo "Update your configuration with @grub_mkconfig@ to support this feature." -+fi -diff --git a/util/grub.d/01_users.in b/util/grub.d/01_users.in -new file mode 100644 -index 00000000000..db2f44bfb78 ---- /dev/null -+++ b/util/grub.d/01_users.in -@@ -0,0 +1,11 @@ -+#!/bin/sh -e -+cat << EOF -+if [ -f \${prefix}/user.cfg ]; then -+ source \${prefix}/user.cfg -+ if [ -n "\${GRUB2_PASSWORD}" ]; then -+ set superusers="root" -+ export superusers -+ password_pbkdf2 root \${GRUB2_PASSWORD} -+ fi -+fi -+EOF diff --git a/0036-tcp-add-window-scaling-support.patch b/0036-tcp-add-window-scaling-support.patch deleted file mode 100644 index 7d1996c8fc233ece5afa67588ee79e6f95bd45bd..0000000000000000000000000000000000000000 --- a/0036-tcp-add-window-scaling-support.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Josef Bacik -Date: Wed, 12 Aug 2015 08:57:55 -0700 -Subject: [PATCH] tcp: add window scaling support - -Sometimes we have to provision boxes across regions, such as California to -Sweden. The http server has a 10 minute timeout, so if we can't get our 250mb -image transferred fast enough our provisioning fails, which is not ideal. So -add tcp window scaling on open connections and set the window size to 1mb. With -this change we're able to get higher sustained transfers between regions and can -transfer our image in well below 10 minutes. Without this patch we'd time out -every time halfway through the transfer. Thanks, - -Signed-off-by: Josef Bacik ---- - grub-core/net/tcp.c | 42 +++++++++++++++++++++++++++++------------- - 1 file changed, 29 insertions(+), 13 deletions(-) - -diff --git a/grub-core/net/tcp.c b/grub-core/net/tcp.c -index e8ad34b84d4..7d4b822626d 100644 ---- a/grub-core/net/tcp.c -+++ b/grub-core/net/tcp.c -@@ -106,6 +106,18 @@ struct tcphdr - grub_uint16_t urgent; - } GRUB_PACKED; - -+struct tcp_scale_opt { -+ grub_uint8_t kind; -+ grub_uint8_t length; -+ grub_uint8_t scale; -+} GRUB_PACKED; -+ -+struct tcp_synhdr { -+ struct tcphdr tcphdr; -+ struct tcp_scale_opt scale_opt; -+ grub_uint8_t padding; -+}; -+ - struct tcp_pseudohdr - { - grub_uint32_t src; -@@ -566,7 +578,7 @@ grub_net_tcp_open (char *server, - grub_net_tcp_socket_t socket; - static grub_uint16_t in_port = 21550; - struct grub_net_buff *nb; -- struct tcphdr *tcph; -+ struct tcp_synhdr *tcph; - int i; - grub_uint8_t *nbd; - grub_net_link_level_address_t ll_target_addr; -@@ -635,20 +647,24 @@ grub_net_tcp_open (char *server, - } - - tcph = (void *) nb->data; -+ grub_memset(tcph, 0, sizeof (*tcph)); - socket->my_start_seq = grub_get_time_ms (); - socket->my_cur_seq = socket->my_start_seq + 1; -- socket->my_window = 8192; -- tcph->seqnr = grub_cpu_to_be32 (socket->my_start_seq); -- tcph->ack = grub_cpu_to_be32_compile_time (0); -- tcph->flags = grub_cpu_to_be16_compile_time ((5 << 12) | TCP_SYN); -- tcph->window = grub_cpu_to_be16 (socket->my_window); -- tcph->urgent = 0; -- tcph->src = grub_cpu_to_be16 (socket->in_port); -- tcph->dst = grub_cpu_to_be16 (socket->out_port); -- tcph->checksum = 0; -- tcph->checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP, -- &socket->inf->address, -- &socket->out_nla); -+ socket->my_window = 32768; -+ tcph->tcphdr.seqnr = grub_cpu_to_be32 (socket->my_start_seq); -+ tcph->tcphdr.ack = grub_cpu_to_be32_compile_time (0); -+ tcph->tcphdr.flags = grub_cpu_to_be16_compile_time ((6 << 12) | TCP_SYN); -+ tcph->tcphdr.window = grub_cpu_to_be16 (socket->my_window); -+ tcph->tcphdr.urgent = 0; -+ tcph->tcphdr.src = grub_cpu_to_be16 (socket->in_port); -+ tcph->tcphdr.dst = grub_cpu_to_be16 (socket->out_port); -+ tcph->tcphdr.checksum = 0; -+ tcph->scale_opt.kind = 3; -+ tcph->scale_opt.length = 3; -+ tcph->scale_opt.scale = 5; -+ tcph->tcphdr.checksum = grub_net_ip_transport_checksum (nb, GRUB_NET_IP_TCP, -+ &socket->inf->address, -+ &socket->out_nla); - - tcp_socket_register (socket); - diff --git a/0037-efinet-and-bootp-add-support-for-dhcpv6.patch b/0037-efinet-and-bootp-add-support-for-dhcpv6.patch deleted file mode 100644 index a9844b89c0caf2e3f0b25ec377f105ef9704fbed..0000000000000000000000000000000000000000 --- a/0037-efinet-and-bootp-add-support-for-dhcpv6.patch +++ /dev/null @@ -1,651 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 9 Jul 2019 11:47:37 +0200 -Subject: [PATCH] efinet and bootp: add support for dhcpv6 - -Signed-off-by: Peter Jones ---- - grub-core/net/bootp.c | 173 +++++++++++++++++++++++++++++++++++++ - grub-core/net/drivers/efi/efinet.c | 53 ++++++++++-- - grub-core/net/net.c | 72 +++++++++++++++ - grub-core/net/tftp.c | 4 + - include/grub/efi/api.h | 129 +++++++++++++++++++++++++-- - include/grub/net.h | 60 +++++++++++++ - 6 files changed, 477 insertions(+), 14 deletions(-) - -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index 6fb5627025d..e28fb6a09f9 100644 ---- a/grub-core/net/bootp.c -+++ b/grub-core/net/bootp.c -@@ -902,6 +902,179 @@ grub_cmd_bootp (struct grub_command *cmd __attribute__ ((unused)), - - static grub_command_t cmd_getdhcp, cmd_bootp, cmd_dhcp; - -+struct grub_net_network_level_interface * -+grub_net_configure_by_dhcpv6_ack (const char *name, -+ struct grub_net_card *card, -+ grub_net_interface_flags_t flags -+ __attribute__((__unused__)), -+ const grub_net_link_level_address_t *hwaddr, -+ const struct grub_net_dhcpv6_packet *packet, -+ int is_def, char **device, char **path) -+{ -+ struct grub_net_network_level_interface *inter = NULL; -+ struct grub_net_network_level_address addr; -+ int mask = -1; -+ -+ if (!device || !path) -+ return NULL; -+ -+ *device = 0; -+ *path = 0; -+ -+ grub_dprintf ("net", "mac address is %02x:%02x:%02x:%02x:%02x:%02x\n", -+ hwaddr->mac[0], hwaddr->mac[1], hwaddr->mac[2], -+ hwaddr->mac[3], hwaddr->mac[4], hwaddr->mac[5]); -+ -+ if (is_def) -+ grub_net_default_server = 0; -+ -+ if (is_def && !grub_net_default_server && packet) -+ { -+ const grub_uint8_t *options = packet->dhcp_options; -+ unsigned int option_max = 1024 - OFFSET_OF (dhcp_options, packet); -+ unsigned int i; -+ -+ for (i = 0; i < option_max - sizeof (grub_net_dhcpv6_option_t); ) -+ { -+ grub_uint16_t num, len; -+ grub_net_dhcpv6_option_t *opt = -+ (grub_net_dhcpv6_option_t *)(options + i); -+ -+ num = grub_be_to_cpu16(opt->option_num); -+ len = grub_be_to_cpu16(opt->option_len); -+ -+ grub_dprintf ("net", "got dhcpv6 option %d len %d\n", num, len); -+ -+ if (len == 0) -+ break; -+ -+ if (len + i > 1024) -+ break; -+ -+ if (num == GRUB_NET_DHCP6_BOOTFILE_URL) -+ { -+ char *scheme, *userinfo, *host, *file; -+ char *tmp; -+ int hostlen; -+ int port; -+ int rc = extract_url_info ((const char *)opt->option_data, -+ (grub_size_t)len, -+ &scheme, &userinfo, &host, &port, -+ &file); -+ if (rc < 0) -+ continue; -+ -+ /* right now this only handles tftp. */ -+ if (grub_strcmp("tftp", scheme)) -+ { -+ grub_free (scheme); -+ grub_free (userinfo); -+ grub_free (host); -+ grub_free (file); -+ continue; -+ } -+ grub_free (userinfo); -+ -+ hostlen = grub_strlen (host); -+ if (hostlen > 2 && host[0] == '[' && host[hostlen-1] == ']') -+ { -+ tmp = host+1; -+ host[hostlen-1] = '\0'; -+ } -+ else -+ tmp = host; -+ -+ *device = grub_xasprintf ("%s,%s", scheme, tmp); -+ grub_free (scheme); -+ grub_free (host); -+ -+ if (file && *file) -+ { -+ tmp = grub_strrchr (file, '/'); -+ if (tmp) -+ *(tmp+1) = '\0'; -+ else -+ file[0] = '\0'; -+ } -+ else if (!file) -+ file = grub_strdup (""); -+ -+ if (file[0] == '/') -+ { -+ *path = grub_strdup (file+1); -+ grub_free (file); -+ } -+ else -+ *path = file; -+ } -+ else if (num == GRUB_NET_DHCP6_IA_NA) -+ { -+ const grub_net_dhcpv6_option_t *ia_na_opt; -+ const grub_net_dhcpv6_opt_ia_na_t *ia_na = -+ (const grub_net_dhcpv6_opt_ia_na_t *)opt; -+ unsigned int left = len - OFFSET_OF (options, ia_na); -+ unsigned int j; -+ -+ if ((grub_uint8_t *)ia_na + left > -+ (grub_uint8_t *)options + option_max) -+ left -= ((grub_uint8_t *)ia_na + left) -+ - ((grub_uint8_t *)options + option_max); -+ -+ if (len < OFFSET_OF (option_data, opt) -+ + sizeof (grub_net_dhcpv6_option_t)) -+ { -+ grub_dprintf ("net", -+ "found dhcpv6 ia_na option with no address\n"); -+ continue; -+ } -+ -+ for (j = 0; left > sizeof (grub_net_dhcpv6_option_t); ) -+ { -+ ia_na_opt = (const grub_net_dhcpv6_option_t *) -+ (ia_na->options + j); -+ grub_uint16_t ia_na_opt_num, ia_na_opt_len; -+ -+ ia_na_opt_num = grub_be_to_cpu16 (ia_na_opt->option_num); -+ ia_na_opt_len = grub_be_to_cpu16 (ia_na_opt->option_len); -+ if (ia_na_opt_len == 0) -+ break; -+ if (j + ia_na_opt_len > left) -+ break; -+ if (ia_na_opt_num == GRUB_NET_DHCP6_IA_ADDRESS) -+ { -+ const grub_net_dhcpv6_opt_ia_address_t *ia_addr; -+ -+ ia_addr = (const grub_net_dhcpv6_opt_ia_address_t *) -+ ia_na_opt; -+ addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -+ grub_memcpy(addr.ipv6, ia_addr->ipv6_address, -+ sizeof (ia_addr->ipv6_address)); -+ inter = grub_net_add_addr (name, card, &addr, hwaddr, 0); -+ } -+ -+ j += ia_na_opt_len; -+ left -= ia_na_opt_len; -+ } -+ } -+ -+ i += len + 4; -+ } -+ -+ grub_print_error (); -+ } -+ -+ if (is_def) -+ { -+ grub_env_set ("net_default_interface", name); -+ grub_env_export ("net_default_interface"); -+ } -+ -+ if (inter) -+ grub_net_add_ipv6_local (inter, mask); -+ return inter; -+} -+ -+ - void - grub_bootp_init (void) - { -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 5388f952ba9..173fb63153c 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -18,11 +18,14 @@ - - #include - #include -+#include - #include - #include - #include - #include - #include -+#include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -329,7 +332,7 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - char **path) - { - struct grub_net_card *card; -- grub_efi_device_path_t *dp; -+ grub_efi_device_path_t *dp, *ldp = NULL; - - dp = grub_efi_get_device_path (hnd); - if (! dp) -@@ -340,14 +343,19 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - grub_efi_device_path_t *cdp; - struct grub_efi_pxe *pxe; - struct grub_efi_pxe_mode *pxe_mode; -+ - if (card->driver != &efidriver) - continue; -+ - cdp = grub_efi_get_device_path (card->efi_handle); - if (! cdp) - continue; -+ -+ ldp = grub_efi_find_last_device_path (dp); -+ - if (grub_efi_compare_device_paths (dp, cdp) != 0) - { -- grub_efi_device_path_t *ldp, *dup_dp, *dup_ldp; -+ grub_efi_device_path_t *dup_dp, *dup_ldp; - int match; - - /* EDK2 UEFI PXE driver creates pseudo devices with type IPv4/IPv6 -@@ -356,7 +364,6 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - devices. We skip them when enumerating cards, so here we need to - find matching MAC device. - */ -- ldp = grub_efi_find_last_device_path (dp); - if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE - || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE - && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE)) -@@ -373,16 +380,46 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - if (!match) - continue; - } -+ - pxe = grub_efi_open_protocol (hnd, &pxe_io_guid, - GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); - if (! pxe) - continue; -+ - pxe_mode = pxe->mode; -- grub_net_configure_by_dhcp_ack (card->name, card, 0, -- (struct grub_net_bootp_packet *) -- &pxe_mode->dhcp_ack, -- sizeof (pxe_mode->dhcp_ack), -- 1, device, path); -+ if (pxe_mode->using_ipv6) -+ { -+ grub_net_link_level_address_t hwaddr; -+ struct grub_net_network_level_interface *intf; -+ -+ grub_dprintf ("efinet", "using ipv6 and dhcpv6\n"); -+ grub_dprintf ("efinet", "dhcp_ack_received: %s%s\n", -+ pxe_mode->dhcp_ack_received ? "yes" : "no", -+ pxe_mode->dhcp_ack_received ? "" : " cannot continue"); -+ if (!pxe_mode->dhcp_ack_received) -+ continue; -+ -+ hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -+ grub_memcpy (hwaddr.mac, -+ card->efi_net->mode->current_address, -+ sizeof (hwaddr.mac)); -+ -+ intf = grub_net_configure_by_dhcpv6_ack (card->name, card, 0, &hwaddr, -+ (const struct grub_net_dhcpv6_packet *)&pxe_mode->dhcp_ack.dhcpv6, -+ 1, device, path); -+ if (intf && device && path) -+ grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); -+ } -+ else -+ { -+ grub_dprintf ("efinet", "using ipv4 and dhcp\n"); -+ grub_net_configure_by_dhcp_ack (card->name, card, 0, -+ (struct grub_net_bootp_packet *) -+ &pxe_mode->dhcp_ack, -+ sizeof (pxe_mode->dhcp_ack), -+ 1, device, path); -+ grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); -+ } - return; - } - } -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 0ef148f4adc..22f2689aaeb 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -960,6 +960,78 @@ grub_net_network_level_interface_register (struct grub_net_network_level_interfa - grub_net_network_level_interfaces = inter; - } - -+int -+grub_ipv6_get_masksize (grub_uint16_t be_mask[8]) -+{ -+ grub_uint8_t *mask; -+ grub_uint16_t mask16[8]; -+ int x, y; -+ int ret = 128; -+ -+ grub_memcpy (mask16, be_mask, sizeof (mask16)); -+ for (x = 0; x < 8; x++) -+ mask16[x] = grub_be_to_cpu16 (mask16[x]); -+ -+ mask = (grub_uint8_t *)mask16; -+ -+ for (x = 15; x >= 0; x--) -+ { -+ grub_uint8_t octet = mask[x]; -+ if (!octet) -+ { -+ ret -= 8; -+ continue; -+ } -+ for (y = 0; y < 8; y++) -+ { -+ if (octet & (1 << y)) -+ break; -+ else -+ ret--; -+ } -+ break; -+ } -+ -+ return ret; -+} -+ -+grub_err_t -+grub_net_add_ipv6_local (struct grub_net_network_level_interface *inter, -+ int mask) -+{ -+ struct grub_net_route *route; -+ -+ if (inter->address.type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6) -+ return 0; -+ -+ if (mask == -1) -+ mask = grub_ipv6_get_masksize ((grub_uint16_t *)inter->address.ipv6); -+ -+ if (mask == -1) -+ return 0; -+ -+ route = grub_zalloc (sizeof (*route)); -+ if (!route) -+ return grub_errno; -+ -+ route->name = grub_xasprintf ("%s:local", inter->name); -+ if (!route->name) -+ { -+ grub_free (route); -+ return grub_errno; -+ } -+ -+ route->target.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6; -+ grub_memcpy (route->target.ipv6.base, inter->address.ipv6, -+ sizeof (inter->address.ipv6)); -+ route->target.ipv6.masksize = mask; -+ route->is_gateway = 0; -+ route->interface = inter; -+ -+ grub_net_route_register (route); -+ -+ return 0; -+} - - grub_err_t - grub_net_add_ipv4_local (struct grub_net_network_level_interface *inter, -diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c -index 7f44b30f521..4ab2f5c7357 100644 ---- a/grub-core/net/tftp.c -+++ b/grub-core/net/tftp.c -@@ -358,18 +358,22 @@ tftp_open (struct grub_file *file, const char *filename) - file->not_easily_seekable = 1; - file->data = data; - -+ grub_dprintf("tftp", "resolving address for %s\n", file->device->net->server); - err = grub_net_resolve_address (file->device->net->server, &addr); - if (err) - { -+ grub_dprintf("tftp", "Address resolution failed: %d\n", err); - grub_free (data); - return err; - } - -+ grub_dprintf("tftp", "opening connection\n"); - data->sock = grub_net_udp_open (addr, - TFTP_SERVER_PORT, tftp_receive, - file); - if (!data->sock) - { -+ grub_dprintf("tftp", "connection failed\n"); - grub_free (data); - return grub_errno; - } -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index f1a52210c0c..117469450d3 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -592,10 +592,16 @@ typedef void *grub_efi_handle_t; - typedef void *grub_efi_event_t; - typedef grub_efi_uint64_t grub_efi_lba_t; - typedef grub_efi_uintn_t grub_efi_tpl_t; --typedef grub_uint8_t grub_efi_mac_address_t[32]; --typedef grub_uint8_t grub_efi_ipv4_address_t[4]; --typedef grub_uint16_t grub_efi_ipv6_address_t[8]; --typedef grub_uint8_t grub_efi_ip_address_t[8] __attribute__ ((aligned(4))); -+typedef grub_efi_uint8_t grub_efi_mac_address_t[32]; -+typedef grub_efi_uint8_t grub_efi_ipv4_address_t[4]; -+typedef grub_efi_uint8_t grub_efi_ipv6_address_t[16]; -+typedef union -+{ -+ grub_efi_uint32_t addr[4]; -+ grub_efi_ipv4_address_t v4; -+ grub_efi_ipv6_address_t v6; -+} grub_efi_ip_address_t __attribute__ ((aligned(4))); -+ - typedef grub_efi_uint64_t grub_efi_physical_address_t; - typedef grub_efi_uint64_t grub_efi_virtual_address_t; - -@@ -1474,16 +1480,127 @@ struct grub_efi_simple_text_output_interface - }; - typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t; - --typedef grub_uint8_t grub_efi_pxe_packet_t[1472]; -+typedef struct grub_efi_pxe_dhcpv4_packet -+{ -+ grub_efi_uint8_t bootp_opcode; -+ grub_efi_uint8_t bootp_hwtype; -+ grub_efi_uint8_t bootp_hwaddr_len; -+ grub_efi_uint8_t bootp_gate_hops; -+ grub_efi_uint32_t bootp_ident; -+ grub_efi_uint16_t bootp_seconds; -+ grub_efi_uint16_t bootp_flags; -+ grub_efi_uint8_t bootp_ci_addr[4]; -+ grub_efi_uint8_t bootp_yi_addr[4]; -+ grub_efi_uint8_t bootp_si_addr[4]; -+ grub_efi_uint8_t bootp_gi_addr[4]; -+ grub_efi_uint8_t bootp_hw_addr[16]; -+ grub_efi_uint8_t bootp_srv_name[64]; -+ grub_efi_uint8_t bootp_boot_file[128]; -+ grub_efi_uint32_t dhcp_magik; -+ grub_efi_uint8_t dhcp_options[56]; -+} grub_efi_pxe_dhcpv4_packet_t; -+ -+struct grub_efi_pxe_dhcpv6_packet -+{ -+ grub_efi_uint32_t message_type:8; -+ grub_efi_uint32_t transaction_id:24; -+ grub_efi_uint8_t dhcp_options[1024]; -+} GRUB_PACKED; -+typedef struct grub_efi_pxe_dhcpv6_packet grub_efi_pxe_dhcpv6_packet_t; -+ -+typedef union -+{ -+ grub_efi_uint8_t raw[1472]; -+ grub_efi_pxe_dhcpv4_packet_t dhcpv4; -+ grub_efi_pxe_dhcpv6_packet_t dhcpv6; -+} grub_efi_pxe_packet_t; -+ -+#define GRUB_EFI_PXE_MAX_IPCNT 8 -+#define GRUB_EFI_PXE_MAX_ARP_ENTRIES 8 -+#define GRUB_EFI_PXE_MAX_ROUTE_ENTRIES 8 -+ -+typedef struct grub_efi_pxe_ip_filter -+{ -+ grub_efi_uint8_t filters; -+ grub_efi_uint8_t ip_count; -+ grub_efi_uint8_t reserved; -+ grub_efi_ip_address_t ip_list[GRUB_EFI_PXE_MAX_IPCNT]; -+} grub_efi_pxe_ip_filter_t; -+ -+typedef struct grub_efi_pxe_arp_entry -+{ -+ grub_efi_ip_address_t ip_addr; -+ grub_efi_mac_address_t mac_addr; -+} grub_efi_pxe_arp_entry_t; -+ -+typedef struct grub_efi_pxe_route_entry -+{ -+ grub_efi_ip_address_t ip_addr; -+ grub_efi_ip_address_t subnet_mask; -+ grub_efi_ip_address_t gateway_addr; -+} grub_efi_pxe_route_entry_t; -+ -+typedef struct grub_efi_pxe_icmp_error -+{ -+ grub_efi_uint8_t type; -+ grub_efi_uint8_t code; -+ grub_efi_uint16_t checksum; -+ union -+ { -+ grub_efi_uint32_t reserved; -+ grub_efi_uint32_t mtu; -+ grub_efi_uint32_t pointer; -+ struct -+ { -+ grub_efi_uint16_t identifier; -+ grub_efi_uint16_t sequence; -+ } echo; -+ } u; -+ grub_efi_uint8_t data[494]; -+} grub_efi_pxe_icmp_error_t; -+ -+typedef struct grub_efi_pxe_tftp_error -+{ -+ grub_efi_uint8_t error_code; -+ grub_efi_char8_t error_string[127]; -+} grub_efi_pxe_tftp_error_t; - - typedef struct grub_efi_pxe_mode - { -- grub_uint8_t unused[52]; -+ grub_efi_boolean_t started; -+ grub_efi_boolean_t ipv6_available; -+ grub_efi_boolean_t ipv6_supported; -+ grub_efi_boolean_t using_ipv6; -+ grub_efi_boolean_t bis_supported; -+ grub_efi_boolean_t bis_detected; -+ grub_efi_boolean_t auto_arp; -+ grub_efi_boolean_t send_guid; -+ grub_efi_boolean_t dhcp_discover_valid; -+ grub_efi_boolean_t dhcp_ack_received; -+ grub_efi_boolean_t proxy_offer_received; -+ grub_efi_boolean_t pxe_discover_valid; -+ grub_efi_boolean_t pxe_reply_received; -+ grub_efi_boolean_t pxe_bis_reply_received; -+ grub_efi_boolean_t icmp_error_received; -+ grub_efi_boolean_t tftp_error_received; -+ grub_efi_boolean_t make_callbacks; -+ grub_efi_uint8_t ttl; -+ grub_efi_uint8_t tos; -+ grub_efi_ip_address_t station_ip; -+ grub_efi_ip_address_t subnet_mask; - grub_efi_pxe_packet_t dhcp_discover; - grub_efi_pxe_packet_t dhcp_ack; - grub_efi_pxe_packet_t proxy_offer; - grub_efi_pxe_packet_t pxe_discover; - grub_efi_pxe_packet_t pxe_reply; -+ grub_efi_pxe_packet_t pxe_bis_reply; -+ grub_efi_pxe_ip_filter_t ip_filter; -+ grub_efi_uint32_t arp_cache_entries; -+ grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_MAX_ARP_ENTRIES]; -+ grub_efi_uint32_t route_table_entries; -+ grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_MAX_ROUTE_ENTRIES]; -+ grub_efi_pxe_icmp_error_t icmp_error; -+ grub_efi_pxe_tftp_error_t tftp_error; - } grub_efi_pxe_mode_t; - - typedef struct grub_efi_pxe -diff --git a/include/grub/net.h b/include/grub/net.h -index 7ae4b6bd805..8a05ec4fe7a 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -447,6 +447,51 @@ struct grub_net_bootp_packet - grub_uint8_t vendor[0]; - } GRUB_PACKED; - -+enum -+ { -+ GRUB_NET_DHCP6_IA_NA = 3, -+ GRUB_NET_DHCP6_IA_ADDRESS = 5, -+ GRUB_NET_DHCP6_BOOTFILE_URL = 59, -+ }; -+ -+struct grub_net_dhcpv6_option -+{ -+ grub_uint16_t option_num; -+ grub_uint16_t option_len; -+ grub_uint8_t option_data[]; -+} GRUB_PACKED; -+typedef struct grub_net_dhcpv6_option grub_net_dhcpv6_option_t; -+ -+struct grub_net_dhcpv6_opt_ia_na -+{ -+ grub_uint16_t option_num; -+ grub_uint16_t option_len; -+ grub_uint32_t iaid; -+ grub_uint32_t t1; -+ grub_uint32_t t2; -+ grub_uint8_t options[]; -+} GRUB_PACKED; -+typedef struct grub_net_dhcpv6_opt_ia_na grub_net_dhcpv6_opt_ia_na_t; -+ -+struct grub_net_dhcpv6_opt_ia_address -+{ -+ grub_uint16_t option_num; -+ grub_uint16_t option_len; -+ grub_uint64_t ipv6_address[2]; -+ grub_uint32_t preferred_lifetime; -+ grub_uint32_t valid_lifetime; -+ grub_uint8_t options[]; -+} GRUB_PACKED; -+typedef struct grub_net_dhcpv6_opt_ia_address grub_net_dhcpv6_opt_ia_address_t; -+ -+struct grub_net_dhcpv6_packet -+{ -+ grub_uint32_t message_type:8; -+ grub_uint32_t transaction_id:24; -+ grub_uint8_t dhcp_options[1024]; -+} GRUB_PACKED; -+typedef struct grub_net_dhcpv6_packet grub_net_dhcpv6_packet_t; -+ - #define GRUB_NET_BOOTP_RFC1048_MAGIC_0 0x63 - #define GRUB_NET_BOOTP_RFC1048_MAGIC_1 0x82 - #define GRUB_NET_BOOTP_RFC1048_MAGIC_2 0x53 -@@ -482,6 +527,21 @@ grub_net_configure_by_dhcp_ack (const char *name, - grub_size_t size, - int is_def, char **device, char **path); - -+struct grub_net_network_level_interface * -+grub_net_configure_by_dhcpv6_ack (const char *name, -+ struct grub_net_card *card, -+ grub_net_interface_flags_t flags, -+ const grub_net_link_level_address_t *hwaddr, -+ const struct grub_net_dhcpv6_packet *packet, -+ int is_def, char **device, char **path); -+ -+int -+grub_ipv6_get_masksize(grub_uint16_t *mask); -+ -+grub_err_t -+grub_net_add_ipv6_local (struct grub_net_network_level_interface *inf, -+ int mask); -+ - grub_err_t - grub_net_add_ipv4_local (struct grub_net_network_level_interface *inf, - int mask); diff --git a/0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch b/0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch deleted file mode 100644 index bf78c8131abe6bc38d2f3d5630a1ff0abefcc74d..0000000000000000000000000000000000000000 --- a/0038-Add-grub-get-kernel-settings-and-use-it-in-10_linux.patch +++ /dev/null @@ -1,296 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 23 Jun 2016 11:01:39 -0400 -Subject: [PATCH] Add grub-get-kernel-settings and use it in 10_linux - -This patch adds grub-get-kernel-settings, which reads the system kernel -installation configuration from /etc/sysconfig/kernel, and outputs -${GRUB_...} variables suitable for evaluation by grub-mkconfig. Those -variables are then used by 10_linux to choose whether or not to create -debug stanzas. - -Resolves: rhbz#1226325 ---- - configure.ac | 2 + - Makefile.util.def | 7 ++ - util/bash-completion.d/grub-completion.bash.in | 22 +++++++ - util/grub-get-kernel-settings.3 | 20 ++++++ - util/grub-get-kernel-settings.in | 88 ++++++++++++++++++++++++++ - util/grub-mkconfig.in | 3 + - util/grub.d/10_linux.in | 23 +++++-- - 7 files changed, 160 insertions(+), 5 deletions(-) - create mode 100644 util/grub-get-kernel-settings.3 - create mode 100644 util/grub-get-kernel-settings.in - -diff --git a/configure.ac b/configure.ac -index 25e1abb59b9..58e57a745fa 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -65,6 +65,7 @@ grub_TRANSFORM([grub-install]) - grub_TRANSFORM([grub-mkconfig]) - grub_TRANSFORM([grub-mkfont]) - grub_TRANSFORM([grub-mkimage]) -+grub_TRANSFORM([grub-get-kernel-settings]) - grub_TRANSFORM([grub-glue-efi]) - grub_TRANSFORM([grub-mklayout]) - grub_TRANSFORM([grub-mkpasswd-pbkdf2]) -@@ -82,6 +83,7 @@ grub_TRANSFORM([grub-file]) - grub_TRANSFORM([grub-bios-setup.3]) - grub_TRANSFORM([grub-editenv.1]) - grub_TRANSFORM([grub-fstest.3]) -+grub_TRANSFORM([grub-get-kernel-settings.3]) - grub_TRANSFORM([grub-glue-efi.3]) - grub_TRANSFORM([grub-install.1]) - grub_TRANSFORM([grub-kbdcomp.3]) -diff --git a/Makefile.util.def b/Makefile.util.def -index 8ca4c14f0b9..43a1c7453b1 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -733,6 +733,13 @@ script = { - installdir = sbin; - }; - -+script = { -+ name = grub-get-kernel-settings; -+ common = util/grub-get-kernel-settings.in; -+ mansection = 3; -+ installdir = sbin; -+}; -+ - script = { - name = grub-set-default; - common = util/grub-set-default.in; -diff --git a/util/bash-completion.d/grub-completion.bash.in b/util/bash-completion.d/grub-completion.bash.in -index 44bf135b9f8..5c4acd496d4 100644 ---- a/util/bash-completion.d/grub-completion.bash.in -+++ b/util/bash-completion.d/grub-completion.bash.in -@@ -264,6 +264,28 @@ have ${__grub_sparc64_setup_program} && \ - unset __grub_sparc64_setup_program - - -+# -+# grub-get-kernel-settings -+# -+_grub_get_kernel_settings () { -+ local cur -+ -+ COMPREPLY=() -+ cur=`_get_cword` -+ -+ if [[ "$cur" == -* ]]; then -+ __grubcomp "$(__grub_get_options_from_help)" -+ else -+ # Default complete with a filename -+ _filedir -+ fi -+} -+__grub_get_kernel_settings_program="@grub_get_kernel_settings@" -+have ${__grub_get_kernel_settings_program} && \ -+ complete -F _grub_get_kernel_settings -o filenames ${__grub_get_kernel_settings_program} -+unset __grub_get_kernel_settings_program -+ -+ - # - # grub-install - # -diff --git a/util/grub-get-kernel-settings.3 b/util/grub-get-kernel-settings.3 -new file mode 100644 -index 00000000000..ba33330e28d ---- /dev/null -+++ b/util/grub-get-kernel-settings.3 -@@ -0,0 +1,20 @@ -+.TH GRUB-GET-KERNEL-SETTINGS 3 "Thu Jun 25 2015" -+.SH NAME -+\fBgrub-get-kernel-settings\fR \(em Evaluate the system's kernel installation settings for use while making a grub configuration file. -+ -+.SH SYNOPSIS -+\fBgrub-get-kernel-settings\fR [OPTION] -+ -+.SH DESCRIPTION -+\fBgrub-get-kernel-settings\fR reads the kernel installation settings on the host system, and emits a set of grub settings suitable for use when creating a grub configuration file. -+ -+.SH OPTIONS -+.TP -+-h, --help -+Display program usage and exit. -+.TP -+-v, --version -+Display the current version. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-get-kernel-settings.in b/util/grub-get-kernel-settings.in -new file mode 100644 -index 00000000000..7e87dfccc0e ---- /dev/null -+++ b/util/grub-get-kernel-settings.in -@@ -0,0 +1,88 @@ -+#!/bin/sh -+set -e -+ -+# Evaluate new-kernel-pkg's configuration file. -+# Copyright (C) 2016 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 . -+ -+PACKAGE_NAME=@PACKAGE_NAME@ -+PACKAGE_VERSION=@PACKAGE_VERSION@ -+datadir="@datadir@" -+if [ "x$pkgdatadir" = x ]; then -+ pkgdatadir="${datadir}/@PACKAGE@" -+fi -+ -+self=`basename $0` -+ -+export TEXTDOMAIN=@PACKAGE@ -+export TEXTDOMAINDIR="@localedir@" -+ -+. "${pkgdatadir}/grub-mkconfig_lib" -+ -+# Usage: usage -+# Print the usage. -+usage () { -+ gettext_printf "Usage: %s [OPTION]\n" "$self" -+ gettext "Evaluate new-kernel-pkg configuration"; echo -+ echo -+ print_option_help "-h, --help" "$(gettext "print this message and exit")" -+ print_option_help "-v, --version" "$(gettext "print the version information and exit")" -+ echo -+} -+ -+# Check the arguments. -+while test $# -gt 0 -+do -+ option=$1 -+ shift -+ -+ case "$option" in -+ -h | --help) -+ usage -+ exit 0 ;; -+ -v | --version) -+ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" -+ exit 0 ;; -+ -*) -+ gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 -+ usage -+ exit 1 -+ ;; -+ # Explicitly ignore non-option arguments, for compatibility. -+ esac -+done -+ -+if test -f /etc/sysconfig/kernel ; then -+ . /etc/sysconfig/kernel -+fi -+ -+if [ "$MAKEDEBUG" = "yes" ]; then -+ echo GRUB_LINUX_MAKE_DEBUG=true -+ echo export GRUB_LINUX_MAKE_DEBUG -+ echo GRUB_CMDLINE_LINUX_DEBUG=\"systemd.log_level=debug systemd.log_target=kmsg\" -+ echo export GRUB_CMDLINE_LINUX_DEBUG -+ echo GRUB_LINUX_DEBUG_TITLE_POSTFIX=\" with debugging\" -+ echo export GRUB_LINUX_DEBUG_TITLE_POSTFIX -+fi -+if [ "$DEFAULTDEBUG" = "yes" ]; then -+ echo GRUB_DEFAULT_TO_DEBUG=true -+else -+ echo GRUB_DEFAULT_TO_DEBUG=false -+fi -+echo export GRUB_DEFAULT_TO_DEBUG -+if [ "$UPDATEDEFAULT" = "yes" ]; then -+ echo GRUB_UPDATE_DEFAULT_KERNEL=true -+ echo export GRUB_UPDATE_DEFAULT_KERNEL -+fi -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index ba14cf6261c..005f093809b 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -45,6 +45,7 @@ grub_probe="${sbindir}/@grub_probe@" - grub_file="${bindir}/@grub_file@" - grub_editenv="${bindir}/@grub_editenv@" - grub_script_check="${bindir}/@grub_script_check@" -+grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" - - export TEXTDOMAIN=@PACKAGE@ - export TEXTDOMAINDIR="@localedir@" -@@ -158,6 +159,8 @@ if test -f ${sysconfdir}/default/grub ; then - . ${sysconfdir}/default/grub - fi - -+eval "$("${grub_get_kernel_settings}")" || true -+ - if [ "x${GRUB_DISABLE_UUID}" = "xtrue" ]; then - if [ -z "${GRUB_DISABLE_LINUX_UUID}" ]; then - GRUB_DISABLE_LINUX_UUID="true" -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 786dbabb4a8..292e333324b 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -111,7 +111,8 @@ linux_entry () - os="$1" - version="$2" - type="$3" -- args="$4" -+ isdebug="$4" -+ args="$5" - - if [ -z "$boot_device_id" ]; then - boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" -@@ -123,6 +124,9 @@ linux_entry () - quoted="$(echo "$GRUB_ACTUAL_DEFAULT" | grub_quote)" - title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" - fi -+ if [ x$isdebug = xdebug ]; then -+ title="$title${GRUB_LINUX_DEBUG_TITLE_POSTFIX}" -+ fi - echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" - else - echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/" -@@ -306,11 +310,15 @@ while [ "x$list" != "x" ] ; do - fi - - if [ "x$is_top_level" = xtrue ] && [ "x${GRUB_DISABLE_SUBMENU}" != xtrue ]; then -- linux_entry "${OS}" "${version}" simple \ -+ linux_entry "${OS}" "${version}" simple standard \ - "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then -+ linux_entry "${OS}" "${version}" simple debug \ -+ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} ${GRUB_CMDLINE_LINUX_DEBUG}" -+ fi - - submenu_indentation="$grub_tab" -- -+ - if [ -z "$boot_device_id" ]; then - boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" - fi -@@ -319,10 +327,15 @@ while [ "x$list" != "x" ] ; do - is_top_level=false - fi - -- linux_entry "${OS}" "${version}" advanced \ -+ linux_entry "${OS}" "${version}" advanced standard \ - "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then -+ linux_entry "${OS}" "${version}" advanced debug \ -+ "${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT} ${GRUB_CMDLINE_LINUX_DEBUG}" -+ fi -+ - if [ "x${GRUB_DISABLE_RECOVERY}" != "xtrue" ]; then -- linux_entry "${OS}" "${version}" recovery \ -+ linux_entry "${OS}" "${version}" recovery standard \ - "single ${GRUB_CMDLINE_LINUX}" - fi - diff --git a/0039-bz1374141-fix-incorrect-mask-for-ppc64.patch b/0039-bz1374141-fix-incorrect-mask-for-ppc64.patch deleted file mode 100644 index ef992f5dab33505802a3be9d76ef6476b566da70..0000000000000000000000000000000000000000 --- a/0039-bz1374141-fix-incorrect-mask-for-ppc64.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Masahiro Matsuya -Date: Sat, 29 Oct 2016 08:35:26 +0900 -Subject: [PATCH] bz1374141 fix incorrect mask for ppc64 - -The netmask configured in firmware is not respected on ppc64 (big endian). -When 255.255.252.0 is set as netmask in firmware, the following is the value of bootpath string in grub_ieee1275_parse_bootpath(). - - /vdevice/l-lan@30000002:speed=auto,duplex=auto,192.168.88.10,,192.168.89.113,192.168.88.1,5,5,255.255.252.0,512 - -The netmask in this bootpath is no problem, since it's a value specified in firmware. But, -The value of 'subnet_mask.ipv4' was set with 0xfffffc00, and __builtin_ctz (~grub_le_to_cpu32 (subnet_mask.ipv4)) returned 16 (not 22). -As a result, 16 was used for netmask wrongly. - -1111 1111 1111 1111 1111 1100 0000 0000 # subnet_mask.ipv4 (=0xfffffc00) -0000 0000 1111 1100 1111 1111 1111 1111 # grub_le_to_cpu32 (subnet_mask.ipv4) -1111 1111 0000 0011 0000 0000 0000 0000 # ~grub_le_to_cpu32 (subnet_mask.ipv4) - -And, the count of zero with __builtin_ctz can be 16. -This patch changes it as below. - -1111 1111 1111 1111 1111 1100 0000 0000 # subnet_mask.ipv4 (=0xfffffc00) -0000 0000 1111 1100 1111 1111 1111 1111 # grub_le_to_cpu32 (subnet_mask.ipv4) -1111 1111 1111 1111 1111 1100 0000 0000 # grub_swap_bytes32(grub_le_to_cpu32 (subnet_mask.ipv4)) -0000 0000 0000 0000 0000 0011 1111 1111 # ~grub_swap_bytes32(grub_le_to_cpu32 (subnet_mask.ipv4)) - -The count of zero with __builtin_clz can be 22. (clz counts the number of one bits preceding the most significant zero bit) - -Signed-off-by: Masahiro Matsuya -Signed-off-by: Robbie Harwood ---- - grub-core/net/drivers/ieee1275/ofnet.c | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c -index ac4e62a95c9..3860b6f78d8 100644 ---- a/grub-core/net/drivers/ieee1275/ofnet.c -+++ b/grub-core/net/drivers/ieee1275/ofnet.c -@@ -220,8 +220,7 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath, - flags); - inter->vlantag = vlantag; - grub_net_add_ipv4_local (inter, -- __builtin_ctz (~grub_le_to_cpu32 (subnet_mask.ipv4))); -- -+ __builtin_clz (~grub_swap_bytes32(grub_le_to_cpu32 (subnet_mask.ipv4)))); - } - - if (gateway_addr.ipv4 != 0) diff --git a/0040-Make-grub_fatal-also-backtrace.patch b/0040-Make-grub_fatal-also-backtrace.patch deleted file mode 100644 index 3534b05a046c0d2225eceaaef773bcfbbfa4f497..0000000000000000000000000000000000000000 --- a/0040-Make-grub_fatal-also-backtrace.patch +++ /dev/null @@ -1,172 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 27 Jan 2016 09:22:42 -0500 -Subject: [PATCH] Make grub_fatal() also backtrace. - ---- - grub-core/Makefile.core.def | 3 ++ - grub-core/kern/misc.c | 8 +++++- - grub-core/lib/arm64/backtrace.c | 62 +++++++++++++++++++++++++++++++++++++++++ - grub-core/lib/backtrace.c | 2 ++ - grub-core/lib/i386/backtrace.c | 14 +++++++++- - 5 files changed, 87 insertions(+), 2 deletions(-) - create mode 100644 grub-core/lib/arm64/backtrace.c - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index c15e91943b9..058c88ac3af 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -188,6 +188,9 @@ kernel = { - - softdiv = lib/division.c; - -+ x86 = lib/i386/backtrace.c; -+ x86 = lib/backtrace.c; -+ - i386 = kern/i386/dl.c; - i386_xen = kern/i386/dl.c; - i386_xen_pvh = kern/i386/dl.c; -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 63b586d09cb..a3e215155bd 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - union printf_arg - { -@@ -1199,8 +1200,13 @@ grub_printf_fmt_check (const char *fmt, const char *fmt_expected) - static void __attribute__ ((noreturn)) - grub_abort (void) - { -+#ifndef GRUB_UTIL -+#if defined(__i386__) || defined(__x86_64__) -+ grub_backtrace(); -+#endif -+#endif - grub_printf ("\nAborted."); -- -+ - #ifndef GRUB_UTIL - if (grub_term_inputs) - #endif -diff --git a/grub-core/lib/arm64/backtrace.c b/grub-core/lib/arm64/backtrace.c -new file mode 100644 -index 00000000000..1079b5380e1 ---- /dev/null -+++ b/grub-core/lib/arm64/backtrace.c -@@ -0,0 +1,62 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_STACK_FRAME 102400 -+ -+void -+grub_backtrace_pointer (int frame) -+{ -+ while (1) -+ { -+ void *lp = __builtin_return_address (frame); -+ if (!lp) -+ break; -+ -+ lp = __builtin_extract_return_addr (lp); -+ -+ grub_printf ("%p: ", lp); -+ grub_backtrace_print_address (lp); -+ grub_printf (" ("); -+ for (i = 0; i < 2; i++) -+ grub_printf ("%p,", ((void **)ptr) [i + 2]); -+ grub_printf ("%p)\n", ((void **)ptr) [i + 2]); -+ nptr = *(void **)ptr; -+ if (nptr < ptr || (void **) nptr - (void **) ptr > MAX_STACK_FRAME -+ || nptr == ptr) -+ { -+ grub_printf ("Invalid stack frame at %p (%p)\n", ptr, nptr); -+ break; -+ } -+ ptr = nptr; -+ } -+} -+ -+void -+grub_backtrace (void) -+{ -+ grub_backtrace_pointer (1); -+} -+ -diff --git a/grub-core/lib/backtrace.c b/grub-core/lib/backtrace.c -index 825a8800e25..c0ad6ab8be1 100644 ---- a/grub-core/lib/backtrace.c -+++ b/grub-core/lib/backtrace.c -@@ -29,6 +29,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); - void - grub_backtrace_print_address (void *addr) - { -+#ifndef GRUB_UTIL - grub_dl_t mod; - - FOR_DL_MODULES (mod) -@@ -44,6 +45,7 @@ grub_backtrace_print_address (void *addr) - } - } - -+#endif - grub_printf ("%p", addr); - } - -diff --git a/grub-core/lib/i386/backtrace.c b/grub-core/lib/i386/backtrace.c -index c3e03c7275c..c67273db3ae 100644 ---- a/grub-core/lib/i386/backtrace.c -+++ b/grub-core/lib/i386/backtrace.c -@@ -15,11 +15,23 @@ - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ -+#include -+#ifdef GRUB_UTIL -+#define REALLY_GRUB_UTIL GRUB_UTIL -+#undef GRUB_UTIL -+#endif -+ -+#include -+#include -+ -+#ifdef REALLY_GRUB_UTIL -+#define GRUB_UTIL REALLY_GRUB_UTIL -+#undef REALLY_GRUB_UTIL -+#endif - - #include - #include - #include --#include - #include - #include - #include diff --git a/0041-Fix-up-some-man-pages-rpmdiff-noticed.patch b/0041-Fix-up-some-man-pages-rpmdiff-noticed.patch deleted file mode 100644 index be5841754b5e021bbe42b7740e3b2e55945a5314..0000000000000000000000000000000000000000 --- a/0041-Fix-up-some-man-pages-rpmdiff-noticed.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 23 Sep 2014 09:58:49 -0400 -Subject: [PATCH] Fix up some man pages rpmdiff noticed. - ---- - configure.ac | 2 ++ - util/grub-macbless.8 | 26 +++++++++++++++++++ - util/grub-mkimage.1 | 2 +- - util/grub-syslinux2cfg.1 | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 94 insertions(+), 1 deletion(-) - create mode 100644 util/grub-macbless.8 - create mode 100644 util/grub-syslinux2cfg.1 - -diff --git a/configure.ac b/configure.ac -index 58e57a745fa..a0030632220 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -87,6 +87,7 @@ grub_TRANSFORM([grub-get-kernel-settings.3]) - grub_TRANSFORM([grub-glue-efi.3]) - grub_TRANSFORM([grub-install.1]) - grub_TRANSFORM([grub-kbdcomp.3]) -+grub_TRANSFORM([grub-macbless.8]) - grub_TRANSFORM([grub-menulst2cfg.1]) - grub_TRANSFORM([grub-mkconfig.1]) - grub_TRANSFORM([grub-mkfont.3]) -@@ -105,6 +106,7 @@ grub_TRANSFORM([grub-render-label.3]) - grub_TRANSFORM([grub-script-check.3]) - grub_TRANSFORM([grub-set-default.1]) - grub_TRANSFORM([grub-sparc64-setup.3]) -+grub_TRANSFORM([grub-syslinux2cfg.1]) - - # Optimization flag. Allow user to override. - if test "x$TARGET_CFLAGS" = x; then -diff --git a/util/grub-macbless.8 b/util/grub-macbless.8 -new file mode 100644 -index 00000000000..ae842f3a606 ---- /dev/null -+++ b/util/grub-macbless.8 -@@ -0,0 +1,26 @@ -+.TH GRUB-MACBLESS 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-macbless\fR \(em Mac-style bless utility for HFS or HFS+ -+ -+.SH SYNOPSIS -+\fBgrub-macbless\fR [-p | --ppc] [-v | --verbose] [-x | --x86] \fIFILE\fR -+ -+.SH DESCRIPTION -+\fBgrub-mkimage\fR blesses a file on an HFS or HFS+ file system, so that it -+can be used to boot a Mac. -+ -+.SH OPTIONS -+.TP -+--ppc -+Bless the file for use on PPC-based Macs. -+ -+.TP -+--verbose -+Print verbose messages. -+ -+.TP -+--x86 -+Bless the file for use on x86-based Macs. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-mkimage.1 b/util/grub-mkimage.1 -index 4dea4f54597..0eaaafe505b 100644 ---- a/util/grub-mkimage.1 -+++ b/util/grub-mkimage.1 -@@ -17,7 +17,7 @@ - [-v | --verbose] \fIMODULES\fR - - .SH DESCRIPTION --\fBgrub-mkimage\fI builds a bootable image of GRUB. -+\fBgrub-mkimage\fR builds a bootable image of GRUB. - - .SH OPTIONS - .TP -diff --git a/util/grub-syslinux2cfg.1 b/util/grub-syslinux2cfg.1 -new file mode 100644 -index 00000000000..85309482718 ---- /dev/null -+++ b/util/grub-syslinux2cfg.1 -@@ -0,0 +1,65 @@ -+.TH GRUB-SYSLINUX2CFG 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-syslinux2cfg\fR \(em Transform a syslinux config file into a GRUB config. -+ -+.SH SYNOPSIS -+\fBgrub-syslinux2cfg\fR [-c | --cwd=\fRDIR\fI] [-r | --root=\fIDIR\fR] [-v | --verbose] -+.RE -+.RS 25 -+[-t | --target-root=\fIDIR\fR] [-T | --target-cwd=\fIDIR\fR] -+.RE -+.RS 25 -+[-o | --output=\fIFILE\fR] [[-i | --isolinux] | -+.RE -+.RS 46 -+ [-s | --syslinux] | -+.RE -+.RS 46 -+ [-p | --pxelinux]] \fIFILE\fR -+ -+.SH DESCRIPTION -+\fBgrub-syslinux2cfg\fR builds a GRUB configuration file out of an existing -+syslinux configuration file. -+ -+.SH OPTIONS -+.TP -+--cwd=\fIDIR\fR -+Set \fIDIR\fR as syslinux's working directory. The default is to use the -+parent directory of the input file. -+ -+.TP -+--root=\fIDIR\fR -+Set \fIDIR\fR as the root directory of the syslinux disk. The default value -+is "/". -+ -+.TP -+--verbose -+Print verbose messages. -+ -+.TP -+--target-root=\fIDIR\fR -+Root directory as it will be seen at runtime. The default value is "/". -+ -+.TP -+--target-cwd=\fIDIR\fR -+Working directory of syslinux as it will be seen at runtime. The default -+value is the parent directory of the input file. -+ -+.TP -+--output=\fIFILE\fR -+Write the new config file to \fIFILE\fR. The default value is standard output. -+ -+.TP -+--isolinux -+Assume that the input file is an isolinux configuration file. -+ -+.TP -+--pxelinux -+Assume that the input file is a pxelinux configuration file. -+ -+.TP -+--syslinux -+Assume that the input file is a syslinux configuration file. -+ -+.SH SEE ALSO -+.BR "info grub" diff --git a/0042-Make-our-info-pages-say-grub2-where-appropriate.patch b/0042-Make-our-info-pages-say-grub2-where-appropriate.patch deleted file mode 100644 index be28efd517f3d379a1c3ce9775f917ce83cbfefb..0000000000000000000000000000000000000000 --- a/0042-Make-our-info-pages-say-grub2-where-appropriate.patch +++ /dev/null @@ -1,1008 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 9 Jul 2019 12:59:58 +0200 -Subject: [PATCH] Make our info pages say "grub2" where appropriate. - -This needs to be hooked up to --program-transform=, but I haven't had -time. - -Signed-off-by: Peter Jones ---- - docs/grub-dev.texi | 4 +- - docs/grub.texi | 321 ++++++++++++++++++++++++++++------------------------- - 2 files changed, 171 insertions(+), 154 deletions(-) - -diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi -index 6c629a23e2d..19f708ee662 100644 ---- a/docs/grub-dev.texi -+++ b/docs/grub-dev.texi -@@ -1,7 +1,7 @@ - \input texinfo - @c -*-texinfo-*- - @c %**start of header --@setfilename grub-dev.info -+@setfilename grub2-dev.info - @include version-dev.texi - @settitle GNU GRUB Developers Manual @value{VERSION} - @c Unify all our little indices for now. -@@ -32,7 +32,7 @@ Invariant Sections. - - @dircategory Kernel - @direntry --* grub-dev: (grub-dev). The GRand Unified Bootloader Dev -+* grub2-dev: (grub2-dev). The GRand Unified Bootloader Dev - @end direntry - - @setchapternewpage odd -diff --git a/docs/grub.texi b/docs/grub.texi -index 69f08d289f9..0615d0ed97e 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -1,7 +1,7 @@ - \input texinfo - @c -*-texinfo-*- - @c %**start of header --@setfilename grub.info -+@setfilename grub2.info - @include version.texi - @settitle GNU GRUB Manual @value{VERSION} - @c Unify all our little indices for now. -@@ -32,15 +32,15 @@ Invariant Sections. - - @dircategory Kernel - @direntry --* GRUB: (grub). The GRand Unified Bootloader --* grub-install: (grub)Invoking grub-install. Install GRUB on your drive --* grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration --* grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2. --* grub-mkrelpath: (grub)Invoking grub-mkrelpath. --* grub-mkrescue: (grub)Invoking grub-mkrescue. Make a GRUB rescue image --* grub-mount: (grub)Invoking grub-mount. Mount a file system using GRUB --* grub-probe: (grub)Invoking grub-probe. Probe device information --* grub-script-check: (grub)Invoking grub-script-check. -+* GRUB2: (grub2). The GRand Unified Bootloader -+* grub2-install: (grub2)Invoking grub2-install. Install GRUB on your drive -+* grub2-mkconfig: (grub2)Invoking grub2-mkconfig. Generate GRUB configuration -+* grub2-mkpasswd-pbkdf2: (grub2)Invoking grub2-mkpasswd-pbkdf2. -+* grub2-mkrelpath: (grub2)Invoking grub2-mkrelpath. -+* grub2-mkrescue: (grub2)Invoking grub2-mkrescue. Make a GRUB rescue image -+* grub2-mount: (grub2)Invoking grub2-mount. Mount a file system using GRUB -+* grub2-probe: (grub2)Invoking grub2-probe. Probe device information -+* grub2-script-check: (grub2)Invoking grub2-script-check. - @end direntry - - @setchapternewpage odd -@@ -103,15 +103,15 @@ This edition documents version @value{VERSION}. - * Platform-specific operations:: Platform-specific operations - * Supported kernels:: The list of supported kernels - * Troubleshooting:: Error messages produced by GRUB --* Invoking grub-install:: How to use the GRUB installer --* Invoking grub-mkconfig:: Generate a GRUB configuration file --* Invoking grub-mkpasswd-pbkdf2:: -+* Invoking grub2-install:: How to use the GRUB installer -+* Invoking grub2-mkconfig:: Generate a GRUB configuration file -+* Invoking grub2-mkpasswd-pbkdf2:: - Generate GRUB password hashes --* Invoking grub-mkrelpath:: Make system path relative to its root --* Invoking grub-mkrescue:: Make a GRUB rescue image --* Invoking grub-mount:: Mount a file system using GRUB --* Invoking grub-probe:: Probe device information for GRUB --* Invoking grub-script-check:: Check GRUB script file for syntax errors -+* Invoking grub2-mkrelpath:: Make system path relative to its root -+* Invoking grub2-mkrescue:: Make a GRUB rescue image -+* Invoking grub2-mount:: Mount a file system using GRUB -+* Invoking grub2-probe:: Probe device information for GRUB -+* Invoking grub2-script-check:: Check GRUB script file for syntax errors - * Obtaining and Building GRUB:: How to obtain and build GRUB - * Reporting bugs:: Where you should send a bug report - * Future:: Some future plans on GRUB -@@ -230,7 +230,7 @@ surprising. - - @item - @file{grub.cfg} is typically automatically generated by --@command{grub-mkconfig} (@pxref{Simple configuration}). This makes it -+@command{grub2-mkconfig} (@pxref{Simple configuration}). This makes it - easier to handle versioned kernel upgrades. - - @item -@@ -244,7 +244,7 @@ scripting language: variables, conditionals, and loops are available. - @item - A small amount of persistent storage is available across reboots, using the - @command{save_env} and @command{load_env} commands in GRUB and the --@command{grub-editenv} utility. This is not available in all configurations -+@command{grub2-editenv} utility. This is not available in all configurations - (@pxref{Environment block}). - - @item -@@ -549,7 +549,7 @@ On OS which have device nodes similar to Unix-like OS GRUB tools use the - OS name. E.g. for GNU/Linux: - - @example --# @kbd{grub-install /dev/sda} -+# @kbd{grub2-install /dev/sda} - @end example - - On AROS we use another syntax. For volumes: -@@ -572,7 +572,7 @@ For disks we use syntax: - E.g. - - @example --# @kbd{grub-install //:ata.device/0/0} -+# @kbd{grub2-install //:ata.device/0/0} - @end example - - On Windows we use UNC path. For volumes it's typically -@@ -599,7 +599,7 @@ For disks it's - E.g. - - @example --# @kbd{grub-install \\?\PhysicalDrive0} -+# @kbd{grub2-install \\?\PhysicalDrive0} - @end example - - Beware that you may need to further escape the backslashes depending on your -@@ -609,7 +609,7 @@ When compiled with cygwin support then cygwin drive names are automatically - when needed. E.g. - - @example --# @kbd{grub-install /dev/sda} -+# @kbd{grub2-install /dev/sda} - @end example - - @node Installation -@@ -622,7 +622,7 @@ from the source tarball, or as a package for your OS. - - After you have done that, you need to install the boot loader on a - drive (floppy or hard disk) by using the utility --@command{grub-install} (@pxref{Invoking grub-install}) on a UNIX-like OS. -+@command{grub2-install} (@pxref{Invoking grub2-install}) on a UNIX-like OS. - - GRUB comes with boot images, which are normally put in the directory - @file{/usr/lib/grub/-} (for BIOS-based machines -@@ -633,22 +633,22 @@ loader needs to find them (usually @file{/boot}) will be called - the @dfn{boot directory}. - - @menu --* Installing GRUB using grub-install:: -+* Installing GRUB using grub2-install:: - * Making a GRUB bootable CD-ROM:: - * Device map:: - * BIOS installation:: - @end menu - - --@node Installing GRUB using grub-install --@section Installing GRUB using grub-install -+@node Installing GRUB using grub2-install -+@section Installing GRUB using grub2-install - - For information on where GRUB should be installed on PC BIOS platforms, - @pxref{BIOS installation}. - - In order to install GRUB under a UNIX-like OS (such --as @sc{gnu}), invoke the program @command{grub-install} (@pxref{Invoking --grub-install}) as the superuser (@dfn{root}). -+as @sc{gnu}), invoke the program @command{grub2-install} (@pxref{Invoking -+grub2-install}) as the superuser (@dfn{root}). - - The usage is basically very simple. You only need to specify one - argument to the program, namely, where to install the boot loader. The -@@ -657,13 +657,13 @@ For example, under Linux the following will install GRUB into the MBR - of the first IDE disk: - - @example --# @kbd{grub-install /dev/sda} -+# @kbd{grub2-install /dev/sda} - @end example - - Likewise, under GNU/Hurd, this has the same effect: - - @example --# @kbd{grub-install /dev/hd0} -+# @kbd{grub2-install /dev/hd0} - @end example - - But all the above examples assume that GRUB should put images under -@@ -677,7 +677,7 @@ boot floppy with a filesystem. Here is an example: - # @kbd{mke2fs /dev/fd0} - # @kbd{mount -t ext2 /dev/fd0 /mnt} - # @kbd{mkdir /mnt/boot} --# @kbd{grub-install --boot-directory=/mnt/boot /dev/fd0} -+# @kbd{grub2-install --boot-directory=/mnt/boot /dev/fd0} - # @kbd{umount /mnt} - @end group - @end example -@@ -689,30 +689,37 @@ floppy instead of exposing the USB drive as a hard disk (they call it - @example - # @kbd{losetup /dev/loop0 /dev/sdb1} - # @kbd{mount /dev/loop0 /mnt/usb} --# @kbd{grub-install --boot-directory=/mnt/usb/bugbios --force --allow-floppy /dev/loop0} -+# @kbd{grub2-install --boot-directory=/mnt/usb/bugbios --force --allow-floppy /dev/loop0} - @end example - - This install doesn't conflict with standard install as long as they are in - separate directories. - -+Note that @command{grub2-install} is actually just a shell script and the -+real task is done by other tools such as @command{grub2-mkimage}. Therefore, -+you may run those commands directly to install GRUB, without using -+@command{grub2-install}. Don't do that, however, unless you are very familiar -+with the internals of GRUB. Installing a boot loader on a running OS may be -+extremely dangerous. -+ - On EFI systems for fixed disk install you have to mount EFI System Partition. - If you mount it at @file{/boot/efi} then you don't need any special arguments: - - @example --# @kbd{grub-install} -+# @kbd{grub2-install} - @end example - - Otherwise you need to specify where your EFI System partition is mounted: - - @example --# @kbd{grub-install --efi-directory=/mnt/efi} -+# @kbd{grub2-install --efi-directory=/mnt/efi} - @end example - - For removable installs you have to use @option{--removable} and specify both - @option{--boot-directory} and @option{--efi-directory}: - - @example --# @kbd{grub-install --efi-directory=/mnt/usb --boot-directory=/mnt/usb/boot --removable} -+# @kbd{grub2-install --efi-directory=/mnt/usb --boot-directory=/mnt/usb/boot --removable} - @end example - - @node Making a GRUB bootable CD-ROM -@@ -732,10 +739,10 @@ usually also need to include a configuration file @file{grub.cfg} and some - other GRUB modules. - - To make a simple generic GRUB rescue CD, you can use the --@command{grub-mkrescue} program (@pxref{Invoking grub-mkrescue}): -+@command{grub2-mkrescue} program (@pxref{Invoking grub2-mkrescue}): - - @example --$ @kbd{grub-mkrescue -o grub.iso} -+$ @kbd{grub2-mkrescue -o grub.iso} - @end example - - You will often need to include other files in your image. To do this, first -@@ -758,7 +765,7 @@ directory @file{iso/}. - Finally, make the image: - - @example --$ @kbd{grub-mkrescue -o grub.iso iso} -+$ @kbd{grub2-mkrescue -o grub.iso iso} - @end example - - This produces a file named @file{grub.iso}, which then can be burned -@@ -774,7 +781,7 @@ storage devices. - @node Device map - @section The map between BIOS drives and OS devices - --If the device map file exists, the GRUB utilities (@command{grub-probe}, -+If the device map file exists, the GRUB utilities (@command{grub2-probe}, - etc.) read it to map BIOS drives to OS devices. This file consists of lines - like this: - -@@ -1254,23 +1261,23 @@ need to write the whole thing by hand. - @node Simple configuration - @section Simple configuration handling - --The program @command{grub-mkconfig} (@pxref{Invoking grub-mkconfig}) -+The program @command{grub2-mkconfig} (@pxref{Invoking grub2-mkconfig}) - generates @file{grub.cfg} files suitable for most cases. It is suitable for - use when upgrading a distribution, and will discover available kernels and - attempt to generate menu entries for them. - --@command{grub-mkconfig} does have some limitations. While adding extra -+@command{grub2-mkconfig} does have some limitations. While adding extra - custom menu entries to the end of the list can be done by editing --@file{/etc/grub.d/40_custom} or creating @file{/boot/grub/custom.cfg}, -+@file{/etc/grub.d/40_custom} or creating @file{/boot/grub2/custom.cfg}, - changing the order of menu entries or changing their titles may require - making complex changes to shell scripts stored in @file{/etc/grub.d/}. This - may be improved in the future. In the meantime, those who feel that it - would be easier to write @file{grub.cfg} directly are encouraged to do so - (@pxref{Booting}, and @ref{Shell-like scripting}), and to disable any system --provided by their distribution to automatically run @command{grub-mkconfig}. -+provided by their distribution to automatically run @command{grub2-mkconfig}. - - The file @file{/etc/default/grub} controls the operation of --@command{grub-mkconfig}. It is sourced by a shell script, and so must be -+@command{grub2-mkconfig}. It is sourced by a shell script, and so must be - valid POSIX shell input; normally, it will just be a sequence of - @samp{KEY=value} lines, but if the value contains spaces or other special - characters then it must be quoted. For example: -@@ -1308,7 +1315,7 @@ works it's not recommended since titles often contain unstable device names - and may be translated - - If you set this to @samp{saved}, then the default menu entry will be that --saved by @samp{GRUB_SAVEDEFAULT} or @command{grub-set-default}. This relies on -+saved by @samp{GRUB_SAVEDEFAULT} or @command{grub2-set-default}. This relies on - the environment block, which may not be available in all situations - (@pxref{Environment block}). - -@@ -1319,7 +1326,7 @@ If this option is set to @samp{true}, then, when an entry is selected, save - it as a new default entry for use by future runs of GRUB. This is only - useful if @samp{GRUB_DEFAULT=saved}; it is a separate option because - @samp{GRUB_DEFAULT=saved} is useful without this option, in conjunction with --@command{grub-set-default}. Unset by default. -+@command{grub2-set-default}. Unset by default. - This option relies on the environment block, which may not be available in - all situations (@pxref{Environment block}). - -@@ -1449,7 +1456,7 @@ intel-uc.img intel-ucode.img amd-uc.img amd-ucode.img early_ucode.cpio microcode - @end example - - @item GRUB_DISABLE_LINUX_UUID --Normally, @command{grub-mkconfig} will generate menu entries that use -+Normally, @command{grub2-mkconfig} will generate menu entries that use - universally-unique identifiers (UUIDs) to identify the root filesystem to - the Linux kernel, using a @samp{root=UUID=...} kernel parameter. This is - usually more reliable, but in some cases it may not be appropriate. To -@@ -1471,7 +1478,7 @@ If this option is set to @samp{true}, disable the generation of recovery - mode menu entries. - - @item GRUB_DISABLE_UUID --Normally, @command{grub-mkconfig} will generate menu entries that use -+Normally, @command{grub2-mkconfig} will generate menu entries that use - universally-unique identifiers (UUIDs) to identify various filesystems to - search for files. This is usually more reliable, but in some cases it may - not be appropriate. To disable this use of UUIDs, set this option to -@@ -1482,12 +1489,12 @@ not be appropriate. To disable this use of UUIDs, set this option to - @item GRUB_VIDEO_BACKEND - If graphical video support is required, either because the @samp{gfxterm} - graphical terminal is in use or because @samp{GRUB_GFXPAYLOAD_LINUX} is set, --then @command{grub-mkconfig} will normally load all available GRUB video -+then @command{grub2-mkconfig} will normally load all available GRUB video - drivers and use the one most appropriate for your hardware. If you need to - override this for some reason, then you can set this option. - --After @command{grub-install} has been run, the available video drivers are --listed in @file{/boot/grub/video.lst}. -+After @command{grub2-install} has been run, the available video drivers are -+listed in @file{/boot/grub2/video.lst}. - - @item GRUB_GFXMODE - Set the resolution used on the @samp{gfxterm} graphical terminal. Note that -@@ -1519,7 +1526,7 @@ boot sequence. If you have problems, set this option to @samp{text} and - GRUB will tell Linux to boot in normal text mode. - - @item GRUB_DISABLE_OS_PROBER --Normally, @command{grub-mkconfig} will try to use the external -+Normally, @command{grub2-mkconfig} will try to use the external - @command{os-prober} program, if installed, to discover other operating - systems installed on the same system and generate appropriate menu entries - for them. Set this option to @samp{true} to disable this. -@@ -1529,7 +1536,7 @@ List of space-separated FS UUIDs of filesystems to be ignored from os-prober - output. For efi chainloaders it's @@ - - @item GRUB_DISABLE_SUBMENU --Normally, @command{grub-mkconfig} will generate top level menu entry for -+Normally, @command{grub2-mkconfig} will generate top level menu entry for - the kernel with highest version number and put all other found kernels - or alternative menu entries for recovery mode in submenu. For entries returned - by @command{os-prober} first entry will be put on top level and all others -@@ -1537,11 +1544,11 @@ in submenu. If this option is set to @samp{true}, flat menu with all entries - on top level will be generated instead. Changing this option will require - changing existing values of @samp{GRUB_DEFAULT}, @samp{fallback} (@pxref{fallback}) - and @samp{default} (@pxref{default}) environment variables as well as saved --default entry using @command{grub-set-default} and value used with --@command{grub-reboot}. -+default entry using @command{grub2-set-default} and value used with -+@command{grub2-reboot}. - - @item GRUB_ENABLE_CRYPTODISK --If set to @samp{y}, @command{grub-mkconfig} and @command{grub-install} will -+If set to @samp{y}, @command{grub2-mkconfig} and @command{grub2-install} will - check for encrypted disks and generate additional commands needed to access - them during boot. Note that in this case unattended boot is not possible - because GRUB will wait for passphrase to unlock encrypted container. -@@ -1600,7 +1607,7 @@ confusing @samp{GRUB_TIMEOUT_STYLE=countdown} or - - @end table - --For more detailed customisation of @command{grub-mkconfig}'s output, you may -+For more detailed customisation of @command{grub2-mkconfig}'s output, you may - edit the scripts in @file{/etc/grub.d} directly. - @file{/etc/grub.d/40_custom} is particularly useful for adding entire custom - menu entries; simply type the menu entries you want to add at the end of -@@ -1862,7 +1869,7 @@ images as well. - Mount this partition on/mnt/boot and disable GRUB in all OSes and manually - install self-compiled latest GRUB with: - --@code{grub-install --boot-directory=/mnt/boot /dev/sda} -+@code{grub2-install --boot-directory=/mnt/boot /dev/sda} - - In all the OSes install GRUB tools but disable installing GRUB in bootsector, - so you'll have menu.lst and grub.cfg available for use. Also disable os-prober -@@ -1872,20 +1879,20 @@ use by setting: - - in /etc/default/grub - --Then write a grub.cfg (/mnt/boot/grub/grub.cfg): -+Then write a grub.cfg (/mnt/boot/grub2/grub.cfg): - - @example - - menuentry "OS using grub2" @{ - insmod xfs - search --set=root --label OS1 --hint hd0,msdos8 -- configfile /boot/grub/grub.cfg -+ configfile /boot/grub2/grub.cfg - @} - - menuentry "OS using grub2-legacy" @{ - insmod ext2 - search --set=root --label OS2 --hint hd0,msdos6 -- legacy_configfile /boot/grub/menu.lst -+ legacy_configfile /boot/grub2/menu.lst - @} - - menuentry "Windows XP" @{ -@@ -1948,15 +1955,15 @@ GRUB supports embedding a configuration file directly into the core image, - so that it is loaded before entering normal mode. This is useful, for - example, when it is not straightforward to find the real configuration file, - or when you need to debug problems with loading that file. --@command{grub-install} uses this feature when it is not using BIOS disk -+@command{grub2-install} uses this feature when it is not using BIOS disk - functions or when installing to a different disk from the one containing - @file{/boot/grub}, in which case it needs to use the @command{search} - command (@pxref{search}) to find @file{/boot/grub}. - - To embed a configuration file, use the @option{-c} option to --@command{grub-mkimage}. The file is copied into the core image, so it may -+@command{grub2-mkimage}. The file is copied into the core image, so it may - reside anywhere on the file system, and may be removed after running --@command{grub-mkimage}. -+@command{grub2-mkimage}. - - After the embedded configuration file (if any) is executed, GRUB will load - the @samp{normal} module (@pxref{normal}), which will then read the real -@@ -1991,13 +1998,13 @@ included in the core image: - @example - @group - search.fs_label grub root --if [ -e /boot/grub/example/test1.cfg ]; then -+if [ -e /boot/grub2/example/test1.cfg ]; then - set prefix=($root)/boot/grub -- configfile /boot/grub/example/test1.cfg -+ configfile /boot/grub2/example/test1.cfg - else -- if [ -e /boot/grub/example/test2.cfg ]; then -+ if [ -e /boot/grub2/example/test2.cfg ]; then - set prefix=($root)/boot/grub -- configfile /boot/grub/example/test2.cfg -+ configfile /boot/grub2/example/test2.cfg - else - echo "Could not find an example configuration file!" - fi -@@ -2521,7 +2528,7 @@ grub-mknetdir --net-directory=/srv/tftp --subdir=/boot/grub -d /usr/lib/grub/i38 - @end group - @end example - --Then follow instructions printed out by grub-mknetdir on configuring your DHCP -+Then follow instructions printed out by grub2-mknetdir on configuring your DHCP - server. - - The grub.cfg file is placed in the same directory as the path output by -@@ -2715,7 +2722,7 @@ team are: - @end table - - To take full advantage of this function, install GRUB into the MBR --(@pxref{Installing GRUB using grub-install}). -+(@pxref{Installing GRUB using grub2-install}). - - If you have a laptop which has a similar feature and not in the above list - could you figure your address and contribute? -@@ -2776,7 +2783,7 @@ bytes. - The sole function of @file{boot.img} is to read the first sector of the core - image from a local disk and jump to it. Because of the size restriction, - @file{boot.img} cannot understand any file system structure, so --@command{grub-install} hardcodes the location of the first sector of the -+@command{grub2-install} hardcodes the location of the first sector of the - core image into @file{boot.img} when installing GRUB. - - @item diskboot.img -@@ -2806,7 +2813,7 @@ images. - - @item core.img - This is the core image of GRUB. It is built dynamically from the kernel --image and an arbitrary list of modules by the @command{grub-mkimage} -+image and an arbitrary list of modules by the @command{grub2-mkimage} - program. Usually, it contains enough modules to access @file{/boot/grub}, - and loads everything else (including menu handling, the ability to load - target operating systems, and so on) from the file system at run-time. The -@@ -2858,7 +2865,7 @@ GRUB 2 has no single Stage 2 image. Instead, it loads modules from - In GRUB 2, images for booting from CD-ROM drives are now constructed using - @file{cdboot.img} and @file{core.img}, making sure that the core image - contains the @samp{iso9660} module. It is usually best to use the --@command{grub-mkrescue} program for this. -+@command{grub2-mkrescue} program for this. - - @item nbgrub - There is as yet no equivalent for @file{nbgrub} in GRUB 2; it was used by -@@ -3014,8 +3021,8 @@ There are two ways to specify files, by @dfn{absolute file name} and by - - An absolute file name resembles a Unix absolute file name, using - @samp{/} for the directory separator (not @samp{\} as in DOS). One --example is @samp{(hd0,1)/boot/grub/grub.cfg}. This means the file --@file{/boot/grub/grub.cfg} in the first partition of the first hard -+example is @samp{(hd0,1)/boot/grub2/grub.cfg}. This means the file -+@file{/boot/grub2/grub.cfg} in the first partition of the first hard - disk. If you omit the device name in an absolute file name, GRUB uses - GRUB's @dfn{root device} implicitly. So if you set the root device to, - say, @samp{(hd1,1)} by the command @samp{set root=(hd1,1)} (@pxref{set}), -@@ -3023,8 +3030,8 @@ then @code{/boot/kernel} is the same as @code{(hd1,1)/boot/kernel}. - - On ZFS filesystem the first path component must be - @var{volume}@samp{@@}[@var{snapshot}]. --So @samp{/rootvol@@snap-129/boot/grub/grub.cfg} refers to file --@samp{/boot/grub/grub.cfg} in snapshot of volume @samp{rootvol} with name -+So @samp{/rootvol@@snap-129/boot/grub2/grub.cfg} refers to file -+@samp{/boot/grub2/grub.cfg} in snapshot of volume @samp{rootvol} with name - @samp{snap-129}. Trailing @samp{@@} after volume name is mandatory even if - snapshot name is omitted. - -@@ -3427,7 +3434,7 @@ The more recent release of Minix would then be identified as - @samp{other>minix>minix-3.4.0}. - - This variable is often set by @samp{GRUB_DEFAULT} (@pxref{Simple --configuration}), @command{grub-set-default}, or @command{grub-reboot}. -+configuration}), @command{grub2-set-default}, or @command{grub2-reboot}. - - - @node fallback -@@ -3517,7 +3524,7 @@ If this variable is set, it names the language code that the - example, French would be named as @samp{fr}, and Simplified Chinese as - @samp{zh_CN}. - --@command{grub-mkconfig} (@pxref{Simple configuration}) will try to set a -+@command{grub2-mkconfig} (@pxref{Simple configuration}) will try to set a - reasonable default for this variable based on the system locale. - - -@@ -3525,10 +3532,10 @@ reasonable default for this variable based on the system locale. - @subsection locale_dir - - If this variable is set, it names the directory where translation files may --be found (@pxref{gettext}), usually @file{/boot/grub/locale}. Otherwise, -+be found (@pxref{gettext}), usually @file{/boot/grub2/locale}. Otherwise, - internationalization is disabled. - --@command{grub-mkconfig} (@pxref{Simple configuration}) will set a reasonable -+@command{grub2-mkconfig} (@pxref{Simple configuration}) will set a reasonable - default for this variable if internationalization is needed and any - translation files are available. - -@@ -3646,7 +3653,7 @@ input. The default is not to pause output. - - The location of the @samp{/boot/grub} directory as an absolute file name - (@pxref{File name syntax}). This is normally set by GRUB at startup based --on information provided by @command{grub-install}. GRUB modules are -+on information provided by @command{grub2-install}. GRUB modules are - dynamically loaded from this directory, so it must be set correctly in order - for many parts of GRUB to work. - -@@ -3737,17 +3744,17 @@ GRUB provides an ``environment block'' which can be used to save a small - amount of state. - - The environment block is a preallocated 1024-byte file, which normally lives --in @file{/boot/grub/grubenv} (although you should not assume this). At boot -+in @file{/boot/grub2/grubenv} (although you should not assume this). At boot - time, the @command{load_env} command (@pxref{load_env}) loads environment - variables from it, and the @command{save_env} (@pxref{save_env}) command - saves environment variables to it. From a running system, the --@command{grub-editenv} utility can be used to edit the environment block. -+@command{grub2-editenv} utility can be used to edit the environment block. - - For safety reasons, this storage is only available when installed on a plain - disk (no LVM or RAID), using a non-checksumming filesystem (no ZFS), and - using BIOS or EFI functions (no ATA, USB or IEEE1275). - --@command{grub-mkconfig} uses this facility to implement -+@command{grub2-mkconfig} uses this facility to implement - @samp{GRUB_SAVEDEFAULT} (@pxref{Simple configuration}). - - -@@ -4476,7 +4483,7 @@ Translate @var{string} into the current language. - - The current language code is stored in the @samp{lang} variable in GRUB's - environment (@pxref{lang}). Translation files in MO format are read from --@samp{locale_dir} (@pxref{locale_dir}), usually @file{/boot/grub/locale}. -+@samp{locale_dir} (@pxref{locale_dir}), usually @file{/boot/grub2/locale}. - @end deffn - - -@@ -4871,7 +4878,7 @@ Define a user named @var{user} with password @var{clear-password}. - - @deffn Command password_pbkdf2 user hashed-password - Define a user named @var{user} with password hash @var{hashed-password}. --Use @command{grub-mkpasswd-pbkdf2} (@pxref{Invoking grub-mkpasswd-pbkdf2}) -+Use @command{grub2-mkpasswd-pbkdf2} (@pxref{Invoking grub2-mkpasswd-pbkdf2}) - to generate password hashes. @xref{Security}. - @end deffn - -@@ -5814,8 +5821,8 @@ The @samp{password} (@pxref{password}) and @samp{password_pbkdf2} - which has an associated password. @samp{password} sets the password in - plain text, requiring @file{grub.cfg} to be secure; @samp{password_pbkdf2} - sets the password hashed using the Password-Based Key Derivation Function --(RFC 2898), requiring the use of @command{grub-mkpasswd-pbkdf2} --(@pxref{Invoking grub-mkpasswd-pbkdf2}) to generate password hashes. -+(RFC 2898), requiring the use of @command{grub2-mkpasswd-pbkdf2} -+(@pxref{Invoking grub2-mkpasswd-pbkdf2}) to generate password hashes. - - In order to enable authentication support, the @samp{superusers} environment - variable must be set to a list of usernames, separated by any of spaces, -@@ -5860,7 +5867,7 @@ menuentry "May be run by user1 or a superuser" --users user1 @{ - @end group - @end example - --The @command{grub-mkconfig} program does not yet have built-in support for -+The @command{grub2-mkconfig} program does not yet have built-in support for - generating configuration files with authentication. You can use - @file{/etc/grub.d/40_custom} to add simple superuser authentication, by - adding @kbd{set superusers=} and @kbd{password} or @kbd{password_pbkdf2} -@@ -5887,7 +5894,17 @@ may halt or otherwise impact the boot process. - - An initial trusted public key can be embedded within the GRUB @file{core.img} - using the @code{--pubkey} option to @command{grub-install} --(@pxref{Invoking grub-install}). -+(@pxref{Invoking grub2-install}). -+ -+@comment Unfortunately --pubkey is not yet supported by grub2-install, -+@comment but we should not bring up internal detail grub2-mkimage here -+@comment in the user guide (as opposed to developer's manual). -+ -+@comment An initial trusted public key can be embedded within the GRUB -+@comment @file{core.img} using the @code{--pubkey} option to -+@comment @command{grub2-mkimage} (@pxref{Invoking grub2-install}). Presently it -+@comment is necessary to write a custom wrapper around @command{grub2-mkimage} -+@comment using the @code{--grub-mkimage} flag to @command{grub2-install}. - - GRUB uses GPG-style detached signatures (meaning that a file - @file{foo.sig} will be produced when file @file{foo} is signed), and -@@ -5907,8 +5924,8 @@ gpg --detach-sign /path/to/file - For successful validation of all of GRUB's subcomponents and the - loaded OS kernel, they must all be signed. One way to accomplish this - is the following (after having already produced the desired --@file{grub.cfg} file, e.g., by running @command{grub-mkconfig} --(@pxref{Invoking grub-mkconfig}): -+@file{grub.cfg} file, e.g., by running @command{grub2-mkconfig} -+(@pxref{Invoking grub2-mkconfig}): - - @example - @group -@@ -5930,7 +5947,7 @@ See also: @ref{check_signatures}, @ref{verify_detached}, @ref{trust}, - Note that internally signature enforcement is controlled by setting - the environment variable @code{check_signatures} equal to - @code{enforce}. Passing one or more @code{--pubkey} options to --@command{grub-mkimage} implicitly defines @code{check_signatures} -+@command{grub2-mkimage} implicitly defines @code{check_signatures} - equal to @code{enforce} in @file{core.img} prior to processing any - configuration files. - -@@ -6388,10 +6405,10 @@ Required files are: - - GRUB's normal start-up procedure involves setting the @samp{prefix} - environment variable to a value set in the core image by --@command{grub-install}, setting the @samp{root} variable to match, loading -+@command{grub2-install}, setting the @samp{root} variable to match, loading - the @samp{normal} module from the prefix, and running the @samp{normal} - command (@pxref{normal}). This command is responsible for reading --@file{/boot/grub/grub.cfg}, running the menu, and doing all the useful -+@file{/boot/grub2/grub.cfg}, running the menu, and doing all the useful - things GRUB is supposed to do. - - If, instead, you only get a rescue shell, this usually means that GRUB -@@ -6417,8 +6434,8 @@ normal - - However, any problem that leaves you in the rescue shell probably means that - GRUB was not correctly installed. It may be more useful to try to reinstall --it properly using @kbd{grub-install @var{device}} (@pxref{Invoking --grub-install}). When doing this, there are a few things to remember: -+it properly using @kbd{grub2-install @var{device}} (@pxref{Invoking -+grub2-install}). When doing this, there are a few things to remember: - - @itemize @bullet{} - @item -@@ -6430,7 +6447,7 @@ is usually better to use UUIDs or file system labels and avoid depending on - drive ordering entirely. - - @item --At least on BIOS systems, if you tell @command{grub-install} to install GRUB -+At least on BIOS systems, if you tell @command{grub2-install} to install GRUB - to a partition but GRUB has already been installed in the master boot - record, then the GRUB installation in the partition will be ignored. - -@@ -6461,21 +6478,21 @@ entry which claims partition start at block 0. This change will not hamper - bootability on other machines. - - --@node Invoking grub-install --@chapter Invoking grub-install -+@node Invoking grub2-install -+@chapter Invoking grub2-install - --The program @command{grub-install} generates a GRUB core image using --@command{grub-mkimage} and installs it on your system. You must specify the -+The program @command{grub2-install} generates a GRUB core image using -+@command{grub2-mkimage} and installs it on your system. You must specify the - device name on which you want to install GRUB, like this: - - @example --grub-install @var{install_device} -+grub2-install @var{install_device} - @end example - - The device name @var{install_device} is an OS device name or a GRUB - device name. - --@command{grub-install} accepts the following options: -+@command{grub2-install} accepts the following options: - - @table @option - @item --help -@@ -6491,13 +6508,13 @@ separate partition or a removable disk. - If this option is not specified then it defaults to @file{/boot}, so - - @example --@kbd{grub-install /dev/sda} -+@kbd{grub2-install /dev/sda} - @end example - - is equivalent to - - @example --@kbd{grub-install --boot-directory=/boot/ /dev/sda} -+@kbd{grub2-install --boot-directory=/boot/ /dev/sda} - @end example - - Here is an example in which you have a separate @dfn{boot} partition which is -@@ -6505,16 +6522,16 @@ mounted on - @file{/mnt/boot}: - - @example --@kbd{grub-install --boot-directory=/mnt/boot /dev/sdb} -+@kbd{grub2-install --boot-directory=/mnt/boot /dev/sdb} - @end example - - @item --recheck --Recheck the device map, even if @file{/boot/grub/device.map} already -+Recheck the device map, even if @file{/boot/grub2/device.map} already - exists. You should use this option whenever you add/remove a disk - into/from your computer. - - @item --no-rs-codes --By default on x86 BIOS systems, @command{grub-install} will use some -+By default on x86 BIOS systems, @command{grub2-install} will use some - extra space in the bootloader embedding area for Reed-Solomon - error-correcting codes. This enables GRUB to still boot successfully - if some blocks are corrupted. The exact amount of protection offered -@@ -6527,17 +6544,17 @@ installation}) where GRUB does not reside in any unpartitioned space - outside of the MBR. Disable the Reed-Solomon codes with this option. - @end table - --@node Invoking grub-mkconfig --@chapter Invoking grub-mkconfig -+@node Invoking grub2-mkconfig -+@chapter Invoking grub2-mkconfig - --The program @command{grub-mkconfig} generates a configuration file for GRUB -+The program @command{grub2-mkconfig} generates a configuration file for GRUB - (@pxref{Simple configuration}). - - @example --grub-mkconfig -o /boot/grub/grub.cfg -+grub-mkconfig -o /boot/grub2/grub.cfg - @end example - --@command{grub-mkconfig} accepts the following options: -+@command{grub2-mkconfig} accepts the following options: - - @table @option - @item --help -@@ -6553,17 +6570,17 @@ it to standard output. - @end table - - --@node Invoking grub-mkpasswd-pbkdf2 --@chapter Invoking grub-mkpasswd-pbkdf2 -+@node Invoking grub2-mkpasswd-pbkdf2 -+@chapter Invoking grub2-mkpasswd-pbkdf2 - --The program @command{grub-mkpasswd-pbkdf2} generates password hashes for -+The program @command{grub2-mkpasswd-pbkdf2} generates password hashes for - GRUB (@pxref{Security}). - - @example - grub-mkpasswd-pbkdf2 - @end example - --@command{grub-mkpasswd-pbkdf2} accepts the following options: -+@command{grub2-mkpasswd-pbkdf2} accepts the following options: - - @table @option - @item -c @var{number} -@@ -6581,23 +6598,23 @@ Length of the salt. Defaults to 64. - @end table - - --@node Invoking grub-mkrelpath --@chapter Invoking grub-mkrelpath -+@node Invoking grub2-mkrelpath -+@chapter Invoking grub2-mkrelpath - --The program @command{grub-mkrelpath} makes a file system path relative to -+The program @command{grub2-mkrelpath} makes a file system path relative to - the root of its containing file system. For instance, if @file{/usr} is a - mount point, then: - - @example --$ @kbd{grub-mkrelpath /usr/share/grub/unicode.pf2} -+$ @kbd{grub2-mkrelpath /usr/share/grub/unicode.pf2} - @samp{/share/grub/unicode.pf2} - @end example - - This is mainly used internally by other GRUB utilities such as --@command{grub-mkconfig} (@pxref{Invoking grub-mkconfig}), but may -+@command{grub2-mkconfig} (@pxref{Invoking grub2-mkconfig}), but may - occasionally also be useful for debugging. - --@command{grub-mkrelpath} accepts the following options: -+@command{grub2-mkrelpath} accepts the following options: - - @table @option - @item --help -@@ -6608,17 +6625,17 @@ Print the version number of GRUB and exit. - @end table - - --@node Invoking grub-mkrescue --@chapter Invoking grub-mkrescue -+@node Invoking grub2-mkrescue -+@chapter Invoking grub2-mkrescue - --The program @command{grub-mkrescue} generates a bootable GRUB rescue image -+The program @command{grub2-mkrescue} generates a bootable GRUB rescue image - (@pxref{Making a GRUB bootable CD-ROM}). - - @example - grub-mkrescue -o grub.iso - @end example - --All arguments not explicitly listed as @command{grub-mkrescue} options are -+All arguments not explicitly listed as @command{grub2-mkrescue} options are - passed on directly to @command{xorriso} in @command{mkisofs} emulation mode. - Options passed to @command{xorriso} will normally be interpreted as - @command{mkisofs} options; if the option @samp{--} is used, then anything -@@ -6633,7 +6650,7 @@ mkdir -p disk/boot/grub - grub-mkrescue -o grub.iso disk - @end example - --@command{grub-mkrescue} accepts the following options: -+@command{grub2-mkrescue} accepts the following options: - - @table @option - @item --help -@@ -6661,15 +6678,15 @@ Use @var{file} as the @command{xorriso} program, rather than the built-in - default. - - @item --grub-mkimage=@var{file} --Use @var{file} as the @command{grub-mkimage} program, rather than the -+Use @var{file} as the @command{grub2-mkimage} program, rather than the - built-in default. - @end table - - --@node Invoking grub-mount --@chapter Invoking grub-mount -+@node Invoking grub2-mount -+@chapter Invoking grub2-mount - --The program @command{grub-mount} performs a read-only mount of any file -+The program @command{grub2-mount} performs a read-only mount of any file - system or file system image that GRUB understands, using GRUB's file system - drivers via FUSE. (It is only available if FUSE development files were - present when GRUB was built.) This has a number of uses: -@@ -6701,13 +6718,13 @@ even if nobody has yet written a FUSE module specifically for that file - system type. - @end itemize - --Using @command{grub-mount} is normally as simple as: -+Using @command{grub2-mount} is normally as simple as: - - @example - grub-mount /dev/sda1 /mnt - @end example - --@command{grub-mount} must be given one or more images and a mount point as -+@command{grub2-mount} must be given one or more images and a mount point as - non-option arguments (if it is given more than one image, it will treat them - as a RAID set), and also accepts the following options: - -@@ -6729,13 +6746,13 @@ Show debugging output for conditions matching @var{string}. - @item -K prompt|@var{file} - @itemx --zfs-key=prompt|@var{file} - Load a ZFS encryption key. If you use @samp{prompt} as the argument, --@command{grub-mount} will read a passphrase from the terminal; otherwise, it -+@command{grub2-mount} will read a passphrase from the terminal; otherwise, it - will read key material from the specified file. - - @item -r @var{device} - @itemx --root=@var{device} - Set the GRUB root device to @var{device}. You do not normally need to set --this; @command{grub-mount} will automatically set the root device to the -+this; @command{grub2-mount} will automatically set the root device to the - root of the supplied file system. - - If @var{device} is just a number, then it will be treated as a partition -@@ -6753,10 +6770,10 @@ Print verbose messages. - @end table - - --@node Invoking grub-probe --@chapter Invoking grub-probe -+@node Invoking grub2-probe -+@chapter Invoking grub2-probe - --The program @command{grub-probe} probes device information for a given path -+The program @command{grub2-probe} probes device information for a given path - or device. - - @example -@@ -6764,7 +6781,7 @@ grub-probe --target=fs /boot/grub - grub-probe --target=drive --device /dev/sda1 - @end example - --@command{grub-probe} must be given a path or device as a non-option -+@command{grub2-probe} must be given a path or device as a non-option - argument, and also accepts the following options: - - @table @option -@@ -6777,16 +6794,16 @@ Print the version number of GRUB and exit. - @item -d - @itemx --device - If this option is given, then the non-option argument is a system device --name (such as @samp{/dev/sda1}), and @command{grub-probe} will print -+name (such as @samp{/dev/sda1}), and @command{grub2-probe} will print - information about that device. If it is not given, then the non-option - argument is a filesystem path (such as @samp{/boot/grub}), and --@command{grub-probe} will print information about the device containing that -+@command{grub2-probe} will print information about the device containing that - part of the filesystem. - - @item -m @var{file} - @itemx --device-map=@var{file} - Use @var{file} as the device map (@pxref{Device map}) rather than the --default, usually @samp{/boot/grub/device.map}. -+default, usually @samp{/boot/grub2/device.map}. - - @item -t @var{target} - @itemx --target=@var{target} -@@ -6839,19 +6856,19 @@ Print verbose messages. - @end table - - --@node Invoking grub-script-check --@chapter Invoking grub-script-check -+@node Invoking grub2-script-check -+@chapter Invoking grub2-script-check - --The program @command{grub-script-check} takes a GRUB script file -+The program @command{grub2-script-check} takes a GRUB script file - (@pxref{Shell-like scripting}) and checks it for syntax errors, similar to - commands such as @command{sh -n}. It may take a @var{path} as a non-option - argument; if none is supplied, it will read from standard input. - - @example --grub-script-check /boot/grub/grub.cfg -+grub-script-check /boot/grub2/grub.cfg - @end example - --@command{grub-script-check} accepts the following options: -+@command{grub2-script-check} accepts the following options: - - @table @option - @item --help diff --git a/0043-macos-just-build-chainloader-entries-don-t-try-any-x.patch b/0043-macos-just-build-chainloader-entries-don-t-try-any-x.patch deleted file mode 100644 index 574d1173538c9cd600aab0751594eb65a20ad5dd..0000000000000000000000000000000000000000 --- a/0043-macos-just-build-chainloader-entries-don-t-try-any-x.patch +++ /dev/null @@ -1,124 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 24 May 2017 12:42:32 -0400 -Subject: [PATCH] macos: just build chainloader entries, don't try any xnu xnu. - -Since our bugs tell us that the xnu boot entries really just don't work -most of the time, and they create piles of extra boot entries, because -they can't quite figure out 32-vs-64 and other stuff like that. - -It's rediculous, and we should just boot their bootloader through the -chainloader instead. - -So this patch does that. - -Resolves: rhbz#893179 - -Signed-off-by: Peter Jones ---- - util/grub.d/30_os-prober.in | 78 +++++++++++---------------------------------- - 1 file changed, 18 insertions(+), 60 deletions(-) - -diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in -index 1b91c102f35..4b27bd20153 100644 ---- a/util/grub.d/30_os-prober.in -+++ b/util/grub.d/30_os-prober.in -@@ -42,68 +42,25 @@ if [ -z "${OSPROBED}" ] ; then - fi - - osx_entry() { -- if [ x$2 = x32 ]; then -- # TRANSLATORS: it refers to kernel architecture (32-bit) -- bitstr="$(gettext "(32-bit)")" -- else -- # TRANSLATORS: it refers to kernel architecture (64-bit) -- bitstr="$(gettext "(64-bit)")" -- fi - # TRANSLATORS: it refers on the OS residing on device %s - onstr="$(gettext_printf "(on %s)" "${DEVICE}")" -- cat << EOF --menuentry '$(echo "${LONGNAME} $bitstr $onstr" | grub_quote)' --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${DEVICE}")' { -+ hints="" -+ for hint in `"${grub_probe}" --device ${device} --target=efi_hints 2> /dev/null` ; do -+ hints="${hints} --hint=${hint}" -+ done -+ cat << EOF -+menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class osx --class darwin --class os \$menuentry_id_option 'osprober-xnu-$2-$(grub_get_device_id "${DEVICE}")' { - EOF - save_default_entry | grub_add_tab - prepare_grub_to_access_device ${DEVICE} | grub_add_tab - cat << EOF -+ set gfxpayload=keep - load_video -- set do_resume=0 -- if [ /var/vm/sleepimage -nt10 / ]; then -- if xnu_resume /var/vm/sleepimage; then -- set do_resume=1 -- fi -- fi -- if [ \$do_resume = 0 ]; then -- xnu_uuid ${OSXUUID} uuid -- if [ -f /Extra/DSDT.aml ]; then -- acpi -e /Extra/DSDT.aml -- fi -- if [ /kernelcache -nt /System/Library/Extensions ]; then -- $1 /kernelcache boot-uuid=\${uuid} rd=*uuid -- elif [ -f /System/Library/Kernels/kernel ]; then -- $1 /System/Library/Kernels/kernel boot-uuid=\${uuid} rd=*uuid -- xnu_kextdir /System/Library/Extensions -- else -- $1 /mach_kernel boot-uuid=\${uuid} rd=*uuid -- if [ /System/Library/Extensions.mkext -nt /System/Library/Extensions ]; then -- xnu_mkext /System/Library/Extensions.mkext -- else -- xnu_kextdir /System/Library/Extensions -- fi -- fi -- if [ -f /Extra/Extensions.mkext ]; then -- xnu_mkext /Extra/Extensions.mkext -- fi -- if [ -d /Extra/Extensions ]; then -- xnu_kextdir /Extra/Extensions -- fi -- if [ -f /Extra/devprop.bin ]; then -- xnu_devprop_load /Extra/devprop.bin -- fi -- if [ -f /Extra/splash.jpg ]; then -- insmod jpeg -- xnu_splash /Extra/splash.jpg -- fi -- if [ -f /Extra/splash.png ]; then -- insmod png -- xnu_splash /Extra/splash.png -- fi -- if [ -f /Extra/splash.tga ]; then -- insmod tga -- xnu_splash /Extra/splash.tga -- fi -- fi -+ insmod part_gpt -+ insmod hfsplus -+ search --no-floppy --fs-uuid --set=root ${hints} $(grub_get_device_id "${DEVICE}") -+ chainloader (\$root)/System/Library/CoreServices/boot.efi -+ boot - } - EOF - } -@@ -292,11 +249,12 @@ EOF - echo "$title_correction_code" - ;; - macosx) -- if [ "${UUID}" ]; then -- OSXUUID="${UUID}" -- osx_entry xnu_kernel 32 -- osx_entry xnu_kernel64 64 -- fi -+ for subdevice in ${DEVICE%[[:digit:]]*}* ; do -+ parttype="`"${grub_probe}" --device ${device} --target=gpt_parttype "${subdevice}" 2> /dev/null`" -+ if [[ "$parttype" = "426f6f74-0000-11aa-aa11-00306543ecac" ]]; then -+ DEVICE="${subdevice}" osx_entry -+ fi -+ done - ;; - hurd) - onstr="$(gettext_printf "(on %s)" "${DEVICE}")" diff --git a/0044-squash-kern-Add-lockdown-support.patch b/0044-squash-kern-Add-lockdown-support.patch new file mode 100644 index 0000000000000000000000000000000000000000..281aacb0eb0ebae29dc4848c1fe4d9c4c53c43b0 --- /dev/null +++ b/0044-squash-kern-Add-lockdown-support.patch @@ -0,0 +1,115 @@ +From 3c612287086a5f590f80d874e8c5c6042bf7f6a0 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Wed, 24 Feb 2021 23:51:38 +0800 +Subject: [PATCH 44/46] squash! kern: Add lockdown support + +Since the lockdown feature is efi specific, the +grub_{command,extcmd}_lockdown functions can be removed from other +platform for not taking up space in kernel image. +--- + grub-core/commands/extcmd.c | 2 ++ + grub-core/kern/command.c | 2 ++ + include/grub/command.h | 11 +++++++++++ + include/grub/extcmd.h | 13 +++++++++++++ + 4 files changed, 28 insertions(+) + +diff --git a/grub-core/commands/extcmd.c b/grub-core/commands/extcmd.c +index 90a5ca24a..4ac111a99 100644 +--- a/grub-core/commands/extcmd.c ++++ b/grub-core/commands/extcmd.c +@@ -111,6 +111,7 @@ grub_register_extcmd (const char *name, grub_extcmd_func_t func, + summary, description, parser, 1); + } + ++#ifdef GRUB_MACHINE_EFI + static grub_err_t + grub_extcmd_lockdown (grub_extcmd_context_t ctxt __attribute__ ((unused)), + int argc __attribute__ ((unused)), +@@ -132,6 +133,7 @@ grub_register_extcmd_lockdown (const char *name, grub_extcmd_func_t func, + + return grub_register_extcmd (name, func, flags, summary, description, parser); + } ++#endif + + void + grub_unregister_extcmd (grub_extcmd_t ext) +diff --git a/grub-core/kern/command.c b/grub-core/kern/command.c +index 4aabcd4b5..17363af7b 100644 +--- a/grub-core/kern/command.c ++++ b/grub-core/kern/command.c +@@ -78,6 +78,7 @@ grub_register_command_prio (const char *name, + return cmd; + } + ++#ifdef GRUB_MACHINE_EFI + static grub_err_t + grub_cmd_lockdown (grub_command_t cmd __attribute__ ((unused)), + int argc __attribute__ ((unused)), +@@ -100,6 +101,7 @@ grub_register_command_lockdown (const char *name, + + return grub_register_command_prio (name, func, summary, description, 0); + } ++#endif + + void + grub_unregister_command (grub_command_t cmd) +diff --git a/include/grub/command.h b/include/grub/command.h +index 2a6f7f846..b518e262e 100644 +--- a/include/grub/command.h ++++ b/include/grub/command.h +@@ -86,11 +86,22 @@ EXPORT_FUNC(grub_register_command_prio) (const char *name, + const char *summary, + const char *description, + int prio); ++#ifdef GRUB_MACHINE_EFI + grub_command_t + EXPORT_FUNC(grub_register_command_lockdown) (const char *name, + grub_command_func_t func, + const char *summary, + const char *description); ++#else ++static inline grub_command_t ++grub_register_command_lockdown (const char *name, ++ grub_command_func_t func, ++ const char *summary, ++ const char *description) ++{ ++ return grub_register_command_prio (name, func, summary, description, 0); ++} ++#endif + void EXPORT_FUNC(grub_unregister_command) (grub_command_t cmd); + + static inline grub_command_t +diff --git a/include/grub/extcmd.h b/include/grub/extcmd.h +index fe9248b8b..fa1328ea5 100644 +--- a/include/grub/extcmd.h ++++ b/include/grub/extcmd.h +@@ -62,12 +62,25 @@ grub_extcmd_t EXPORT_FUNC(grub_register_extcmd) (const char *name, + const char *description, + const struct grub_arg_option *parser); + ++#ifdef GRUB_MACHINE_EFI + grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_lockdown) (const char *name, + grub_extcmd_func_t func, + grub_command_flags_t flags, + const char *summary, + const char *description, + const struct grub_arg_option *parser); ++#else ++static inline grub_extcmd_t ++grub_register_extcmd_lockdown (const char *name, ++ grub_extcmd_func_t func, ++ grub_command_flags_t flags, ++ const char *summary, ++ const char *description, ++ const struct grub_arg_option *parser) ++{ ++ return grub_register_extcmd (name, func, flags, summary, description, parser); ++} ++#endif + + grub_extcmd_t EXPORT_FUNC(grub_register_extcmd_prio) (const char *name, + grub_extcmd_func_t func, +-- +2.26.2 + diff --git a/0052-Add-grub_efi_allocate_pool-and-grub_efi_free_pool-wr.patch b/0052-Add-grub_efi_allocate_pool-and-grub_efi_free_pool-wr.patch deleted file mode 100644 index bde70969087d1b5d1951eb0fc631af3ec7caeca9..0000000000000000000000000000000000000000 --- a/0052-Add-grub_efi_allocate_pool-and-grub_efi_free_pool-wr.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 1 Jun 2017 09:59:56 -0400 -Subject: [PATCH] Add grub_efi_allocate_pool() and grub_efi_free_pool() - wrappers. - -Signed-off-by: Peter Jones ---- - include/grub/efi/efi.h | 36 ++++++++++++++++++++++++++++++++---- - 1 file changed, 32 insertions(+), 4 deletions(-) - -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 585fa6662b6..03f9a9d0118 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -24,6 +24,10 @@ - #include - #include - -+/* Variables. */ -+extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); -+extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); -+ - /* Functions. */ - void *EXPORT_FUNC(grub_efi_locate_protocol) (grub_efi_guid_t *protocol, - void *registration); -@@ -60,6 +64,33 @@ EXPORT_FUNC(grub_efi_get_memory_map) (grub_efi_uintn_t *memory_map_size, - grub_efi_uintn_t *descriptor_size, - grub_efi_uint32_t *descriptor_version); - void grub_efi_memory_fini (void); -+ -+static inline grub_efi_status_t -+__attribute__((__unused__)) -+grub_efi_allocate_pool (grub_efi_memory_type_t pool_type, -+ grub_efi_uintn_t buffer_size, -+ void **buffer) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_status_t status; -+ -+ b = grub_efi_system_table->boot_services; -+ status = efi_call_3 (b->allocate_pool, pool_type, buffer_size, buffer); -+ return status; -+} -+ -+static inline grub_efi_status_t -+__attribute__((__unused__)) -+grub_efi_free_pool (void *buffer) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_status_t status; -+ -+ b = grub_efi_system_table->boot_services; -+ status = efi_call_1 (b->free_pool, buffer); -+ return status; -+} -+ - grub_efi_loaded_image_t *EXPORT_FUNC(grub_efi_get_loaded_image) (grub_efi_handle_t image_handle); - void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp); - char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp); -@@ -115,10 +146,7 @@ void grub_efi_init (void); - void grub_efi_fini (void); - void grub_efi_set_prefix (void); - --/* Variables. */ --extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); --extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); -- -+/* More variables. */ - extern int EXPORT_VAR(grub_efi_is_finished); - - struct grub_net_card; diff --git a/0053-Use-grub_efi_.-memory-helpers-where-reasonable.patch b/0053-Use-grub_efi_.-memory-helpers-where-reasonable.patch deleted file mode 100644 index ccdf28298823bdb8e9f280bcdbdf052c7c88d256..0000000000000000000000000000000000000000 --- a/0053-Use-grub_efi_.-memory-helpers-where-reasonable.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 1 Jun 2017 10:06:38 -0400 -Subject: [PATCH] Use grub_efi_...() memory helpers where reasonable. - -This uses grub_efi_allocate_pool(), grub_efi_free_pool(), and -grub_efi_free_pages() instead of open-coded efi_call_N() calls, so we -get more reasonable type checking. - -Signed-off-by: Peter Jones ---- - grub-core/loader/efi/chainloader.c | 24 +++++++++--------------- - 1 file changed, 9 insertions(+), 15 deletions(-) - -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index 07c4937898d..89ac84cc663 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -65,7 +65,7 @@ grub_chainloader_unload (void) - - b = grub_efi_system_table->boot_services; - efi_call_1 (b->unload_image, image_handle); -- efi_call_2 (b->free_pages, address, pages); -+ grub_efi_free_pages (address, pages); - - grub_free (file_path); - grub_free (cmdline); -@@ -108,7 +108,7 @@ grub_chainloader_boot (void) - } - - if (exit_data) -- efi_call_1 (b->free_pool, exit_data); -+ grub_efi_free_pool (exit_data); - - grub_loader_unset (); - -@@ -527,10 +527,9 @@ grub_efi_get_media_file_path (grub_efi_device_path_t *dp) - static grub_efi_boolean_t - handle_image (void *data, grub_efi_uint32_t datasize) - { -- grub_efi_boot_services_t *b; - grub_efi_loaded_image_t *li, li_bak; - grub_efi_status_t efi_status; -- char *buffer = NULL; -+ void *buffer = NULL; - char *buffer_aligned = NULL; - grub_efi_uint32_t i; - struct grub_pe32_section_table *section; -@@ -541,8 +540,6 @@ handle_image (void *data, grub_efi_uint32_t datasize) - int found_entry_point = 0; - int rc; - -- b = grub_efi_system_table->boot_services; -- - rc = read_header (data, datasize, &context); - if (rc < 0) - { -@@ -582,8 +579,8 @@ handle_image (void *data, grub_efi_uint32_t datasize) - grub_dprintf ("chain", "image size is %08"PRIxGRUB_UINT64_T", datasize is %08x\n", - context.image_size, datasize); - -- efi_status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA, -- buffer_size, &buffer); -+ efi_status = grub_efi_allocate_pool (GRUB_EFI_LOADER_DATA, buffer_size, -+ &buffer); - - if (efi_status != GRUB_EFI_SUCCESS) - { -@@ -815,14 +812,14 @@ handle_image (void *data, grub_efi_uint32_t datasize) - - grub_dprintf ("chain", "entry_point returned %ld\n", efi_status); - grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t)); -- efi_status = efi_call_1 (b->free_pool, buffer); -+ efi_status = grub_efi_free_pool (buffer); - - return 1; - - error_exit: - grub_dprintf ("chain", "error_exit: grub_errno: %d\n", grub_errno); - if (buffer) -- efi_call_1 (b->free_pool, buffer); -+ grub_efi_free_pool (buffer); - - return 0; - } -@@ -830,10 +827,7 @@ error_exit: - static grub_err_t - grub_secureboot_chainloader_unload (void) - { -- grub_efi_boot_services_t *b; -- -- b = grub_efi_system_table->boot_services; -- efi_call_2 (b->free_pages, address, pages); -+ grub_efi_free_pages (address, pages); - grub_free (file_path); - grub_free (cmdline); - cmdline = 0; -@@ -1100,7 +1094,7 @@ fail: - grub_free (file_path); - - if (address) -- efi_call_2 (b->free_pages, address, pages); -+ grub_efi_free_pages (address, pages); - - if (cmdline) - grub_free (cmdline); diff --git a/0054-Add-PRIxGRUB_EFI_STATUS-and-use-it.patch b/0054-Add-PRIxGRUB_EFI_STATUS-and-use-it.patch deleted file mode 100644 index ef41fe1a5afed98119c2bafc069736ab5d58a87a..0000000000000000000000000000000000000000 --- a/0054-Add-PRIxGRUB_EFI_STATUS-and-use-it.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 1 Jun 2017 10:07:50 -0400 -Subject: [PATCH] Add PRIxGRUB_EFI_STATUS and use it. - -This avoids syntax checkers getting confused about if it's llx or lx. - -Signed-off-by: Peter Jones ---- - grub-core/loader/efi/chainloader.c | 3 ++- - include/grub/efi/api.h | 9 +++++++++ - 2 files changed, 11 insertions(+), 1 deletion(-) - -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index 89ac84cc663..ac8dfd40c61 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -810,7 +810,8 @@ handle_image (void *data, grub_efi_uint32_t datasize) - efi_status = efi_call_2 (entry_point, grub_efi_image_handle, - grub_efi_system_table); - -- grub_dprintf ("chain", "entry_point returned %ld\n", efi_status); -+ grub_dprintf ("chain", "entry_point returned 0x%"PRIxGRUB_EFI_STATUS"\n", -+ efi_status); - grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t)); - efi_status = grub_efi_free_pool (buffer); - -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index 117469450d3..99628801478 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -546,7 +546,16 @@ typedef grub_uint64_t grub_efi_uint64_t; - typedef grub_uint8_t grub_efi_char8_t; - typedef grub_uint16_t grub_efi_char16_t; - -+ - typedef grub_efi_uintn_t grub_efi_status_t; -+/* Make grub_efi_status_t reasonably printable. */ -+#if GRUB_CPU_SIZEOF_VOID_P == 8 -+#define PRIxGRUB_EFI_STATUS "lx" -+#define PRIdGRUB_EFI_STATUS "ld" -+#else -+#define PRIxGRUB_EFI_STATUS "llx" -+#define PRIdGRUB_EFI_STATUS "lld" -+#endif - - #define GRUB_EFI_ERROR_CODE(value) \ - ((((grub_efi_status_t) 1) << (sizeof (grub_efi_status_t) * 8 - 1)) | (value)) diff --git a/0055-don-t-use-int-for-efi-status.patch b/0055-don-t-use-int-for-efi-status.patch deleted file mode 100644 index 44d35554082705d6f432b9c42ad5499090816d71..0000000000000000000000000000000000000000 --- a/0055-don-t-use-int-for-efi-status.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 26 Jun 2017 12:44:59 -0400 -Subject: [PATCH] don't use int for efi status - ---- - grub-core/kern/efi/efi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 05d8237a9b2..ae9885edb84 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -167,7 +167,7 @@ grub_reboot (void) - void - grub_exit (int retval) - { -- int rc = GRUB_EFI_LOAD_ERROR; -+ grub_efi_status_t rc = GRUB_EFI_LOAD_ERROR; - - if (retval == 0) - rc = GRUB_EFI_SUCCESS; diff --git a/0056-make-GRUB_MOD_INIT-declare-its-function-prototypes.patch b/0056-make-GRUB_MOD_INIT-declare-its-function-prototypes.patch deleted file mode 100644 index 1014900c932c971116862e046ee81d379ad8355d..0000000000000000000000000000000000000000 --- a/0056-make-GRUB_MOD_INIT-declare-its-function-prototypes.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 26 Jun 2017 12:46:23 -0400 -Subject: [PATCH] make GRUB_MOD_INIT() declare its function prototypes. - ---- - include/grub/dl.h | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/include/grub/dl.h b/include/grub/dl.h -index b3753c9ca26..91933b85f2c 100644 ---- a/include/grub/dl.h -+++ b/include/grub/dl.h -@@ -54,6 +54,7 @@ grub_mod_fini (void) - - #define GRUB_MOD_INIT(name) \ - static void grub_mod_init (grub_dl_t mod __attribute__ ((unused))) __attribute__ ((used)); \ -+extern void grub_##name##_init (void); \ - void \ - grub_##name##_init (void) { grub_mod_init (0); } \ - static void \ -@@ -61,6 +62,7 @@ grub_mod_init (grub_dl_t mod __attribute__ ((unused))) - - #define GRUB_MOD_FINI(name) \ - static void grub_mod_fini (void) __attribute__ ((used)); \ -+extern void grub_##name##_fini (void); \ - void \ - grub_##name##_fini (void) { grub_mod_fini (); } \ - static void \ diff --git a/0057-Don-t-guess-boot-efi-as-HFS-on-ppc-machines-in-grub-.patch b/0057-Don-t-guess-boot-efi-as-HFS-on-ppc-machines-in-grub-.patch deleted file mode 100644 index 890aa34ce7905671c3ac931471ff05205e630c91..0000000000000000000000000000000000000000 --- a/0057-Don-t-guess-boot-efi-as-HFS-on-ppc-machines-in-grub-.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 20 Apr 2017 13:29:06 -0400 -Subject: [PATCH] Don't guess /boot/efi/ as HFS+ on ppc machines in - grub-install - -This should never be trying this, and since we've consolidated the -grubenv to always be on /boot/efi/EFI/fedora/, this code causes it to -always make the wrong decision. - -Resolves: rhbz#1484474 - -Signed-off-by: Peter Jones ---- - util/grub-install.c | 12 +----------- - 1 file changed, 1 insertion(+), 11 deletions(-) - -diff --git a/util/grub-install.c b/util/grub-install.c -index 84ed6e88ecb..a2bec7446cb 100644 ---- a/util/grub-install.c -+++ b/util/grub-install.c -@@ -1190,18 +1190,8 @@ main (int argc, char *argv[]) - char *d; - - is_guess = 1; -- d = grub_util_path_concat (2, bootdir, "macppc"); -- if (!grub_util_is_directory (d)) -- { -- free (d); -- d = grub_util_path_concat (2, bootdir, "efi"); -- } - /* Find the Mac HFS(+) System Partition. */ -- if (!grub_util_is_directory (d)) -- { -- free (d); -- d = grub_util_path_concat (2, bootdir, "EFI"); -- } -+ d = grub_util_path_concat (2, bootdir, "macppc"); - if (!grub_util_is_directory (d)) - { - free (d); diff --git a/0058-20_linux_xen-load-xen-or-multiboot-2-modules-as-need.patch b/0058-20_linux_xen-load-xen-or-multiboot-2-modules-as-need.patch deleted file mode 100644 index 3fd779f7dfbb5c6705302df146f71804afa79037..0000000000000000000000000000000000000000 --- a/0058-20_linux_xen-load-xen-or-multiboot-2-modules-as-need.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 9 Jul 2019 14:31:19 +0200 -Subject: [PATCH] 20_linux_xen: load xen or multiboot{,2} modules as needed. - -Signed-off-by: Peter Jones ---- - util/grub.d/20_linux_xen.in | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in -index e9e73b815fb..c23b064be6c 100644 ---- a/util/grub.d/20_linux_xen.in -+++ b/util/grub.d/20_linux_xen.in -@@ -153,6 +153,7 @@ linux_entry_xsm () - else - xen_rm_opts="no-real-mode edd=off" - fi -+ insmod ${xen_module} - ${xen_loader} ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts} - echo '$(echo "$lmessage" | grub_quote)' - ${module_loader} ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} -@@ -166,6 +167,7 @@ EOF - done - sed "s/^/$submenu_indentation/" << EOF - echo '$(echo "$message" | grub_quote)' -+ insmod ${xen_module} - ${module_loader} --nounzip $(echo $initrd_path) - EOF - fi -@@ -253,13 +255,16 @@ while [ "x${xen_list}" != "x" ] ; do - echo " submenu '$(gettext_printf "Xen hypervisor, version %s" "${xen_version}" | grub_quote)' \$menuentry_id_option 'xen-hypervisor-$xen_version-$boot_device_id' {" - fi - if ($grub_file --is-arm64-efi $current_xen); then -+ xen_module="xen_boot" - xen_loader="xen_hypervisor" - module_loader="xen_module" - else - if ($grub_file --is-x86-multiboot2 $current_xen); then -+ xen_module="multiboot2" - xen_loader="multiboot2" - module_loader="module2" - else -+ xen_module="multiboot" - xen_loader="multiboot" - module_loader="module" - fi diff --git a/0059-Make-pmtimer-tsc-calibration-not-take-51-seconds-to-.patch b/0059-Make-pmtimer-tsc-calibration-not-take-51-seconds-to-.patch deleted file mode 100644 index acfb116d74f35d92a98eea43dca2cf73ed2797ff..0000000000000000000000000000000000000000 --- a/0059-Make-pmtimer-tsc-calibration-not-take-51-seconds-to-.patch +++ /dev/null @@ -1,211 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 7 Nov 2017 17:12:17 -0500 -Subject: [PATCH] Make pmtimer tsc calibration not take 51 seconds to fail. - -On my laptop running at 2.4GHz, if I run a VM where tsc calibration -using pmtimer will fail presuming a broken pmtimer, it takes ~51 seconds -to do so (as measured with the stopwatch on my phone), with a tsc delta -of 0x1cd1c85300, or around 125 billion cycles. - -If instead of trying to wait for 5-200ms to show up on the pmtimer, we try -to wait for 5-200us, it decides it's broken in ~0x2626aa0 TSCs, aka ~2.4 -million cycles, or more or less instantly. - -Additionally, this reading the pmtimer was returning 0xffffffff anyway, -and that's obviously an invalid return. I've added a check for that and -0 so we don't bother waiting for the test if what we're seeing is dead -pins with no response at all. - -If "debug" is includes "pmtimer", you will see one of the following -three outcomes. If pmtimer gives all 0 or all 1 bits, you will see: - -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 1 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 2 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 3 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 4 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 5 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 6 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 7 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 8 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 9 -kern/i386/tsc_pmtimer.c:77: pmtimer: 0xffffff bad_reads: 10 -kern/i386/tsc_pmtimer.c:78: timer is broken; giving up. - -This outcome was tested using qemu+kvm with UEFI (OVMF) firmware and -these options: -machine pc-q35-2.10 -cpu Broadwell-noTSX - -If pmtimer gives any other bit patterns but is not actually marching -forward fast enough to use for clock calibration, you will see: - -kern/i386/tsc_pmtimer.c:121: pmtimer delta is 0x0 (1904 iterations) -kern/i386/tsc_pmtimer.c:124: tsc delta is implausible: 0x2626aa0 - -This outcome was tested using grub compiled with GRUB_PMTIMER_IGNORE_BAD_READS -defined (so as not to trip the bad read test) using qemu+kvm with UEFI -(OVMF) firmware, and these options: -machine pc-q35-2.10 -cpu Broadwell-noTSX - -If pmtimer actually works, you'll see something like: - -kern/i386/tsc_pmtimer.c:121: pmtimer delta is 0x0 (1904 iterations) -kern/i386/tsc_pmtimer.c:124: tsc delta is implausible: 0x2626aa0 - -This outcome was tested using qemu+kvm with UEFI (OVMF) firmware, and -these options: -machine pc-i440fx-2.4 -cpu Broadwell-noTSX - -I've also tested this outcome on a real Intel Xeon E3-1275v3 on an Intel -Server Board S1200V3RPS using the SDV.RP.B8 "Release" build here: -https://firmware.intel.com/sites/default/files/UEFIDevKit_S1200RP_vB8.zip - -Signed-off-by: Peter Jones ---- - grub-core/kern/i386/tsc_pmtimer.c | 109 +++++++++++++++++++++++++++++++------- - 1 file changed, 89 insertions(+), 20 deletions(-) - -diff --git a/grub-core/kern/i386/tsc_pmtimer.c b/grub-core/kern/i386/tsc_pmtimer.c -index c9c36169978..ca15c3aacd7 100644 ---- a/grub-core/kern/i386/tsc_pmtimer.c -+++ b/grub-core/kern/i386/tsc_pmtimer.c -@@ -28,40 +28,101 @@ - #include - #include - -+/* -+ * Define GRUB_PMTIMER_IGNORE_BAD_READS if you're trying to test a timer that's -+ * present but doesn't keep time well. -+ */ -+// #define GRUB_PMTIMER_IGNORE_BAD_READS -+ - grub_uint64_t - grub_pmtimer_wait_count_tsc (grub_port_t pmtimer, - grub_uint16_t num_pm_ticks) - { - grub_uint32_t start; -- grub_uint32_t last; -- grub_uint32_t cur, end; -+ grub_uint64_t cur, end; - grub_uint64_t start_tsc; - grub_uint64_t end_tsc; -- int num_iter = 0; -+ unsigned int num_iter = 0; -+#ifndef GRUB_PMTIMER_IGNORE_BAD_READS -+ int bad_reads = 0; -+#endif - -- start = grub_inl (pmtimer) & 0xffffff; -- last = start; -+ /* -+ * Some timers are 24-bit and some are 32-bit, but it doesn't make much -+ * difference to us. Caring which one we have isn't really worth it since -+ * the low-order digits will give us enough data to calibrate TSC. So just -+ * mask the top-order byte off. -+ */ -+ cur = start = grub_inl (pmtimer) & 0xffffffUL; - end = start + num_pm_ticks; - start_tsc = grub_get_tsc (); - while (1) - { -- cur = grub_inl (pmtimer) & 0xffffff; -- if (cur < last) -- cur |= 0x1000000; -- num_iter++; -+ cur &= 0xffffffffff000000ULL; -+ cur |= grub_inl (pmtimer) & 0xffffffUL; -+ -+ end_tsc = grub_get_tsc(); -+ -+#ifndef GRUB_PMTIMER_IGNORE_BAD_READS -+ /* -+ * If we get 10 reads in a row that are obviously dead pins, there's no -+ * reason to do this thousands of times. -+ */ -+ if (cur == 0xffffffUL || cur == 0) -+ { -+ bad_reads++; -+ grub_dprintf ("pmtimer", -+ "pmtimer: 0x%"PRIxGRUB_UINT64_T" bad_reads: %d\n", -+ cur, bad_reads); -+ grub_dprintf ("pmtimer", "timer is broken; giving up.\n"); -+ -+ if (bad_reads == 10) -+ return 0; -+ } -+#endif -+ -+ if (cur < start) -+ cur += 0x1000000; -+ - if (cur >= end) - { -- end_tsc = grub_get_tsc (); -+ grub_dprintf ("pmtimer", "pmtimer delta is 0x%"PRIxGRUB_UINT64_T"\n", -+ cur - start); -+ grub_dprintf ("pmtimer", "tsc delta is 0x%"PRIxGRUB_UINT64_T"\n", -+ end_tsc - start_tsc); - return end_tsc - start_tsc; - } -- /* Check for broken PM timer. -- 50000000 TSCs is between 5 ms (10GHz) and 200 ms (250 MHz) -- if after this time we still don't have 1 ms on pmtimer, then -- pmtimer is broken. -+ -+ /* -+ * Check for broken PM timer. 1ms at 10GHz should be 1E+7 TSCs; at -+ * 250MHz it should be 2.5E6. So if after 4E+7 TSCs on a 10GHz machine, -+ * we should have seen pmtimer show 4ms of change (i.e. cur =~ -+ * start+14320); on a 250MHz machine that should be 16ms (start+57280). -+ * If after this a time we still don't have 1ms on pmtimer, then pmtimer -+ * is broken. -+ * -+ * Likewise, if our code is perfectly efficient and introduces no delays -+ * whatsoever, on a 10GHz system we should see a TSC delta of 3580 in -+ * ~3580 iterations. On a 250MHz machine that should be ~900 iterations. -+ * -+ * With those factors in mind, there are two limits here. There's a hard -+ * limit here at 8x our desired pm timer delta, picked as an arbitrarily -+ * large value that's still not a lot of time to humans, because if we -+ * get that far this is either an implausibly fast machine or the pmtimer -+ * is not running. And there's another limit on 4x our 10GHz tsc delta -+ * without seeing cur converge on our target value. - */ -- if ((num_iter & 0xffffff) == 0 && grub_get_tsc () - start_tsc > 5000000) { -- return 0; -- } -+ if ((++num_iter > (grub_uint32_t)num_pm_ticks << 3UL) || -+ end_tsc - start_tsc > 40000000) -+ { -+ grub_dprintf ("pmtimer", -+ "pmtimer delta is 0x%"PRIxGRUB_UINT64_T" (%u iterations)\n", -+ cur - start, num_iter); -+ grub_dprintf ("pmtimer", -+ "tsc delta is implausible: 0x%"PRIxGRUB_UINT64_T"\n", -+ end_tsc - start_tsc); -+ return 0; -+ } - } - } - -@@ -74,12 +135,20 @@ grub_tsc_calibrate_from_pmtimer (void) - - fadt = grub_acpi_find_fadt (); - if (!fadt) -- return 0; -+ { -+ grub_dprintf ("pmtimer", "No FADT found; not using pmtimer.\n"); -+ return 0; -+ } - pmtimer = fadt->pmtimer; - if (!pmtimer) -- return 0; -+ { -+ grub_dprintf ("pmtimer", "FADT does not specify pmtimer; skipping.\n"); -+ return 0; -+ } - -- /* It's 3.579545 MHz clock. Wait 1 ms. */ -+ /* -+ * It's 3.579545 MHz clock. Wait 1 ms. -+ */ - tsc_diff = grub_pmtimer_wait_count_tsc (pmtimer, 3580); - if (tsc_diff == 0) - return 0; diff --git a/0060-align-struct-efi_variable-better.patch b/0060-align-struct-efi_variable-better.patch deleted file mode 100644 index ec26def52ed83b41947f594e209637e647ecb852..0000000000000000000000000000000000000000 --- a/0060-align-struct-efi_variable-better.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 27 Feb 2018 13:55:35 -0500 -Subject: [PATCH] align struct efi_variable better... - ---- - include/grub/efiemu/runtime.h | 2 +- - include/grub/types.h | 1 + - 2 files changed, 2 insertions(+), 1 deletion(-) - -diff --git a/include/grub/efiemu/runtime.h b/include/grub/efiemu/runtime.h -index 36d2dedf47e..9d93ba88bac 100644 ---- a/include/grub/efiemu/runtime.h -+++ b/include/grub/efiemu/runtime.h -@@ -33,5 +33,5 @@ struct efi_variable - grub_uint32_t namelen; - grub_uint32_t size; - grub_efi_uint32_t attributes; --} GRUB_PACKED; -+} GRUB_PACKED GRUB_ALIGNED(8); - #endif /* ! GRUB_EFI_EMU_RUNTIME_HEADER */ -diff --git a/include/grub/types.h b/include/grub/types.h -index 0a3ff159136..ba446d99040 100644 ---- a/include/grub/types.h -+++ b/include/grub/types.h -@@ -29,6 +29,7 @@ - #else - #define GRUB_PACKED __attribute__ ((packed)) - #endif -+#define GRUB_ALIGNED(x) __attribute__((aligned (x))) - - #ifdef GRUB_BUILD - # define GRUB_CPU_SIZEOF_VOID_P BUILD_SIZEOF_VOID_P diff --git a/0061-Add-BLS-support-to-grub-mkconfig.patch b/0061-Add-BLS-support-to-grub-mkconfig.patch deleted file mode 100644 index 7211afbaf571f8a7b59f2f4e11e72774d3959260..0000000000000000000000000000000000000000 --- a/0061-Add-BLS-support-to-grub-mkconfig.patch +++ /dev/null @@ -1,397 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 9 Dec 2016 15:40:29 -0500 -Subject: [PATCH] Add BLS support to grub-mkconfig - -GRUB now has BootLoaderSpec support, the user can choose to use this by -setting GRUB_ENABLE_BLSCFG to true in /etc/default/grub. On this setup, -the boot menu entries are not added to the grub.cfg, instead BLS config -files are parsed by blscfg command and the entries created dynamically. - -A 10_linux_bls grub.d snippet to generate menu entries from BLS files -is also added that can be used on platforms where the bootloader doesn't -have BLS support and only can parse a normal grub configuration file. - -Portions of the 10_linux_bls were taken from the ostree-grub-generator -script that's included in the OSTree project. - -Fixes to support multi-devices and generate a BLS section even if no -kernels are found in the boot directory were proposed by Yclept Nemo -and Tom Gundersen respectively. - -Signed-off-by: Peter Jones -[javierm: remove outdated URL for BLS document] -Signed-off-by: Javier Martinez Canillas -[iwienand@redhat.com: skip machine ID check when updating entries] -Signed-off-by: Ian Wienand -[rharwood: commit message composits] -Signed-off-by: Robbie Harwood ---- - util/grub-mkconfig.8 | 4 + - util/grub-mkconfig.in | 9 +- - util/grub-mkconfig_lib.in | 22 ++++- - util/grub.d/10_linux.in | 218 +++++++++++++++++++++++++++++++++++++++++++++- - 4 files changed, 247 insertions(+), 6 deletions(-) - -diff --git a/util/grub-mkconfig.8 b/util/grub-mkconfig.8 -index a2d1f577b9b..434fa4deda4 100644 ---- a/util/grub-mkconfig.8 -+++ b/util/grub-mkconfig.8 -@@ -13,5 +13,9 @@ - \fB--output\fR=\fIFILE\fR - Write generated output to \fIFILE\fR. - -+.TP -+\fB--no-grubenv-update\fR -+Do not update variables in the grubenv file. -+ - .SH SEE ALSO - .BR "info grub" -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index 535c0f02499..f55339a3f64 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -50,6 +50,8 @@ grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" - export TEXTDOMAIN=@PACKAGE@ - export TEXTDOMAINDIR="@localedir@" - -+export GRUB_GRUBENV_UPDATE="yes" -+ - . "${pkgdatadir}/grub-mkconfig_lib" - - # Usage: usage -@@ -59,6 +61,7 @@ usage () { - gettext "Generate a grub config file"; echo - echo - print_option_help "-o, --output=$(gettext FILE)" "$(gettext "output generated config to FILE [default=stdout]")" -+ print_option_help "--no-grubenv-update" "$(gettext "do not update variables in the grubenv file")" - print_option_help "-h, --help" "$(gettext "print this message and exit")" - print_option_help "-V, --version" "$(gettext "print the version information and exit")" - echo -@@ -94,6 +97,9 @@ do - --output=*) - grub_cfg=`echo "$option" | sed 's/--output=//'` - ;; -+ --no-grubenv-update) -+ GRUB_GRUBENV_UPDATE="no" -+ ;; - -*) - gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 - usage -@@ -253,7 +259,8 @@ export GRUB_DEFAULT \ - GRUB_OS_PROBER_SKIP_LIST \ - GRUB_DISABLE_SUBMENU \ - GRUB_DEFAULT_DTB \ -- SUSE_BTRFS_SNAPSHOT_BOOTING -+ SUSE_BTRFS_SNAPSHOT_BOOTING \ -+ GRUB_ENABLE_BLSCFG - - if test "x${grub_cfg}" != "x"; then - rm -f "${grub_cfg}.new" -diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in -index fafeac95061..d8bb4069360 100644 ---- a/util/grub-mkconfig_lib.in -+++ b/util/grub-mkconfig_lib.in -@@ -30,6 +30,9 @@ fi - if test "x$grub_file" = x; then - grub_file="${bindir}/@grub_file@" - fi -+if test "x$grub_editenv" = x; then -+ grub_editenv="${bindir}/@grub_editenv@" -+fi - if test "x$grub_mkrelpath" = x; then - grub_mkrelpath="${bindir}/@grub_mkrelpath@" - fi -@@ -125,8 +128,19 @@ EOF - fi - } - -+prepare_grub_to_access_device_with_variable () -+{ -+ device_variable="$1" -+ shift -+ prepare_grub_to_access_device "$@" -+ unset "device_variable" -+} -+ - prepare_grub_to_access_device () - { -+ if [ -z "$device_variable" ]; then -+ device_variable="root" -+ fi - old_ifs="$IFS" - IFS=' - ' -@@ -161,18 +175,18 @@ prepare_grub_to_access_device () - # otherwise set root as per value in device.map. - fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`" - if [ "x$fs_hint" != x ]; then -- echo "set root='$fs_hint'" -+ echo "set ${device_variable}='$fs_hint'" - fi - if [ "x${GRUB_DISABLE_UUID}" != "xtrue" ] && fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then - hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints= - if [ "x$hints" != x ]; then - echo "if [ x\$feature_platform_search_hint = xy ]; then" -- echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}" -+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${hints} ${fs_uuid}" - echo "else" -- echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}" -+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}" - echo "fi" - else -- echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}" -+ echo "search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}" - fi - fi - IFS="$old_ifs" -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 7bb3a211a7c..9fcd77cacc3 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -82,6 +82,218 @@ case x"$GRUB_FS" in - ;; - esac - -+populate_header_warn() -+{ -+if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then -+ bls_parser="10_linux script" -+else -+ bls_parser="blscfg command" -+fi -+cat </dev/null | tac)) || : -+ -+ echo "${files[@]}" -+} -+ -+update_bls_cmdline() -+{ -+ local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -+ local -a files=($(get_sorted_bls)) -+ -+ for bls in "${files[@]}"; do -+ local options="${cmdline}" -+ if [ -z "${bls##*debug*}" ]; then -+ options="${options} ${GRUB_CMDLINE_LINUX_DEBUG}" -+ fi -+ options="$(echo "${options}" | sed -e 's/\//\\\//g')" -+ sed -i -e "s/^options.*/options ${options}/" "${blsdir}/${bls}.conf" -+ done -+} -+ -+populate_menu() -+{ -+ local -a files=($(get_sorted_bls)) -+ -+ gettext_printf "Generating boot entries from BLS files...\n" >&2 -+ -+ for bls in "${files[@]}"; do -+ read_config "${blsdir}/${bls}.conf" -+ -+ menu="${menu}menuentry '${title}' ${grub_arg} --id=${bls} {\n" -+ menu="${menu}\t linux ${linux} ${options}\n" -+ if [ -n "${initrd}" ] ; then -+ menu="${menu}\t initrd ${boot_prefix}${initrd}\n" -+ fi -+ menu="${menu}}\n\n" -+ done -+ # The printf command seems to be more reliable across shells for special character (\n, \t) evaluation -+ printf "$menu" -+} -+ -+# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed. -+if [ -z "${GRUB_ENABLE_BLSCFG}" ] && [ -z "$(which new-kernel-pkg 2> /dev/null)" ]; then -+ GRUB_ENABLE_BLSCFG="true" -+fi -+ -+if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then -+ if [ x$dirname = x/ ]; then -+ if [ -z "${prepare_root_cache}" ]; then -+ prepare_grub_to_access_device ${GRUB_DEVICE} -+ fi -+ else -+ if [ -z "${prepare_boot_cache}" ]; then -+ prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} -+ fi -+ fi -+ -+ if [ -d /sys/firmware/efi ]; then -+ bootefi_device="`${grub_probe} --target=device /boot/efi/`" -+ prepare_grub_to_access_device_with_variable boot ${bootefi_device} -+ else -+ boot_device="`${grub_probe} --target=device /boot/`" -+ prepare_grub_to_access_device_with_variable boot ${boot_device} -+ fi -+ -+ arch="$(uname -m)" -+ if [ "x${arch}" = "xppc64le" ] && [ -d /sys/firmware/opal ]; then -+ -+ BLS_POPULATE_MENU="true" -+ petitboot_path="/sys/firmware/devicetree/base/ibm,firmware-versions/petitboot" -+ -+ if test -e ${petitboot_path}; then -+ read -r -d '' petitboot_version < ${petitboot_path} -+ petitboot_version="$(echo ${petitboot_version//v})" -+ -+ if test -n ${petitboot_version}; then -+ major_version="$(echo ${petitboot_version} | cut -d . -f1)" -+ minor_version="$(echo ${petitboot_version} | cut -d . -f2)" -+ -+ re='^[0-9]+$' -+ if [[ $major_version =~ $re ]] && [[ $minor_version =~ $re ]] && -+ ([[ ${major_version} -gt 1 ]] || -+ [[ ${major_version} -eq 1 && -+ ${minor_version} -ge 8 ]]); then -+ BLS_POPULATE_MENU="false" -+ fi -+ fi -+ fi -+ fi -+ -+ populate_header_warn -+ -+ cat << EOF -+# The kernelopts variable should be defined in the grubenv file. But to ensure that menu -+# entries populated from BootLoaderSpec files that use this variable work correctly even -+# without a grubenv file, define a fallback kernelopts variable if this has not been set. -+# -+# The kernelopts variable in the grubenv file can be modified using the grubby tool or by -+# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX -+# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both -+# the kernelopts variable in the grubenv file and the fallback kernelopts variable. -+if [ -z "\${kernelopts}" ]; then -+ set kernelopts="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" -+fi -+EOF -+ -+ update_bls_cmdline -+ -+ if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then -+ populate_menu -+ else -+ cat << EOF -+ -+insmod blscfg -+blscfg -+EOF -+ fi -+ -+ if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then -+ blsdir="/boot/loader/entries" -+ [ -d "${blsdir}" ] && GRUB_BLS_FS="$(${grub_probe} --target=fs ${blsdir})" -+ if [ "x${GRUB_BLS_FS}" = "xbtrfs" ] || [ "x${GRUB_BLS_FS}" = "xzfs" ]; then -+ blsdir=$(make_system_path_relative_to_its_root "${blsdir}") -+ if [ "x${blsdir}" != "x/loader/entries" ] && [ "x${blsdir}" != "x/boot/loader/entries" ]; then -+ ${grub_editenv} - set blsdir="${blsdir}" -+ fi -+ fi -+ -+ if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then -+ ${grub_editenv} - set early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}" -+ fi -+ -+ if [ -n "${GRUB_DEFAULT_DTB}" ]; then -+ ${grub_editenv} - set devicetree="${GRUB_DEFAULT_DTB}" -+ fi -+ -+ if [ -n "${GRUB_SAVEDEFAULT}" ]; then -+ ${grub_editenv} - set save_default="${GRUB_SAVEDEFAULT}" -+ fi -+ fi -+ -+ exit 0 -+fi -+ - mktitle () - { - local title_type -@@ -121,6 +333,7 @@ linux_entry () - if [ -z "$boot_device_id" ]; then - boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" - fi -+ - if [ x$type != xsimple ] ; then - title=$(mktitle "$type" "$version") - if [ x"$title" = x"$GRUB_ACTUAL_DEFAULT" ] || [ x"Previous Linux versions>$title" = x"$GRUB_ACTUAL_DEFAULT" ]; then -@@ -231,6 +444,7 @@ is_top_level=true - while [ "x$list" != "x" ] ; do - linux=`version_find_latest $list` - gettext_printf "Found linux image: %s\n" "$linux" >&2 -+ - basename=`basename $linux` - dirname=`dirname $linux` - rel_dirname=`make_system_path_relative_to_its_root $dirname` -@@ -269,7 +483,9 @@ while [ "x$list" != "x" ] ; do - for i in ${initrd}; do - initrd_display="${initrd_display} ${dirname}/${i}" - done -- gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 -+ if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then -+ gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2 -+ fi - fi - - fdt= diff --git a/0062-Don-t-attempt-to-backtrace-on-grub_abort-for-grub-em.patch b/0062-Don-t-attempt-to-backtrace-on-grub_abort-for-grub-em.patch deleted file mode 100644 index 9ff4c8b8694add91b6fde9d7e6355acb80b57919..0000000000000000000000000000000000000000 --- a/0062-Don-t-attempt-to-backtrace-on-grub_abort-for-grub-em.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 6 Feb 2018 11:16:28 +0100 -Subject: [PATCH] Don't attempt to backtrace on grub_abort() for grub-emu - -The emu platform doesn't have a grub_backtrace() implementation, so this -causes a build error. Don't attempt to call this when building grub-emu. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/kern/misc.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index a3e215155bd..c60601b699d 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -1201,7 +1201,7 @@ static void __attribute__ ((noreturn)) - grub_abort (void) - { - #ifndef GRUB_UTIL --#if defined(__i386__) || defined(__x86_64__) -+#if (defined(__i386__) || defined(__x86_64__)) && !defined(GRUB_MACHINE_EMU) - grub_backtrace(); - #endif - #endif diff --git a/0063-Add-linux-and-initrd-commands-for-grub-emu.patch b/0063-Add-linux-and-initrd-commands-for-grub-emu.patch deleted file mode 100644 index 2431a4d782e87a599c87b3609c3cab2037f5a41f..0000000000000000000000000000000000000000 --- a/0063-Add-linux-and-initrd-commands-for-grub-emu.patch +++ /dev/null @@ -1,350 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Raymund Will -Date: Tue, 6 Feb 2018 09:09:00 +0100 -Subject: [PATCH] Add linux and initrd commands for grub-emu - -When using grub-emu, the linux and initrd commands are used as arguments -to the kexec command line tool, to allow booting the selected menu entry. - -Signed-off-by: Raymund Will -Signed-off-by: Robbie Harwood ---- - grub-core/Makefile.core.def | 1 - - grub-core/kern/emu/main.c | 4 + - grub-core/kern/emu/misc.c | 18 ++++- - grub-core/loader/emu/linux.c | 172 +++++++++++++++++++++++++++++++++++++++++++ - include/grub/emu/exec.h | 4 +- - include/grub/emu/hostfile.h | 3 +- - include/grub/emu/misc.h | 3 + - grub-core/Makefile.am | 1 + - 8 files changed, 202 insertions(+), 4 deletions(-) - create mode 100644 grub-core/loader/emu/linux.c - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 058c88ac3af..5354f9613d3 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -1826,7 +1826,6 @@ module = { - - common = loader/linux.c; - common = lib/cmdline.c; -- enable = noemu; - - efi = loader/efi/linux.c; - }; -diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c -index 55ea5a11ccd..846fe9715ec 100644 ---- a/grub-core/kern/emu/main.c -+++ b/grub-core/kern/emu/main.c -@@ -107,6 +107,7 @@ static struct argp_option options[] = { - N_("use GRUB files in the directory DIR [default=%s]"), 0}, - {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, - {"hold", 'H', N_("SECS"), OPTION_ARG_OPTIONAL, N_("wait until a debugger will attach"), 0}, -+ {"kexec", 'X', 0, 0, N_("try the untryable."), 0}, - { 0, 0, 0, 0, 0, 0 } - }; - -@@ -164,6 +165,9 @@ argp_parser (int key, char *arg, struct argp_state *state) - case 'v': - verbosity++; - break; -+ case 'X': -+ grub_util_set_kexecute(); -+ break; - - case ARGP_KEY_ARG: - { -diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c -index 0ff13bcaf8c..eeea092752d 100644 ---- a/grub-core/kern/emu/misc.c -+++ b/grub-core/kern/emu/misc.c -@@ -39,6 +39,7 @@ - #include - - int verbosity; -+int kexecute; - - void - grub_util_warn (const char *fmt, ...) -@@ -82,7 +83,7 @@ grub_util_error (const char *fmt, ...) - vfprintf (stderr, fmt, ap); - va_end (ap); - fprintf (stderr, ".\n"); -- exit (1); -+ grub_exit (1); - } - - void * -@@ -154,6 +155,9 @@ void - __attribute__ ((noreturn)) - grub_exit (int rc) - { -+#if defined (GRUB_KERNEL) -+ grub_reboot(); -+#endif - exit (rc < 0 ? 1 : rc); - } - #endif -@@ -215,3 +219,15 @@ grub_util_load_image (const char *path, char *buf) - - fclose (fp); - } -+ -+void -+grub_util_set_kexecute(void) -+{ -+ kexecute++; -+} -+ -+int -+grub_util_get_kexecute(void) -+{ -+ return kexecute; -+} -diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c -new file mode 100644 -index 00000000000..fda9e00d24c ---- /dev/null -+++ b/grub-core/loader/emu/linux.c -@@ -0,0 +1,172 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2006,2007,2008,2009,2010 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static grub_dl_t my_mod; -+ -+static char *kernel_path; -+static char *initrd_path; -+static char *boot_cmdline; -+ -+static grub_err_t -+grub_linux_boot (void) -+{ -+ grub_err_t rc = GRUB_ERR_NONE; -+ char *initrd_param; -+ const char *kexec[] = { "kexec", "-l", kernel_path, boot_cmdline, NULL, NULL }; -+ const char *systemctl[] = { "systemctl", "kexec", NULL }; -+ int kexecute = grub_util_get_kexecute(); -+ -+ if (initrd_path) { -+ initrd_param = grub_xasprintf("--initrd=%s", initrd_path); -+ kexec[3] = initrd_param; -+ kexec[4] = boot_cmdline; -+ } else { -+ initrd_param = grub_xasprintf("%s", ""); -+ } -+ -+ grub_printf("%serforming 'kexec -l %s %s %s'\n", -+ (kexecute) ? "P" : "Not p", -+ kernel_path, initrd_param, boot_cmdline); -+ -+ if (kexecute) -+ rc = grub_util_exec(kexec); -+ -+ grub_free(initrd_param); -+ -+ if (rc != GRUB_ERR_NONE) { -+ grub_error (rc, N_("Error trying to perform kexec load operation.")); -+ grub_sleep (3); -+ return rc; -+ } -+ if (kexecute < 1) -+ grub_fatal (N_("Use '"PACKAGE"-emu --kexec' to force a system restart.")); -+ -+ grub_printf("Performing 'systemctl kexec' (%s) ", -+ (kexecute==1) ? "do-or-die" : "just-in-case"); -+ rc = grub_util_exec (systemctl); -+ -+ if (kexecute == 1) -+ grub_fatal (N_("Error trying to perform 'systemctl kexec'")); -+ -+ /* need to check read-only root before resetting hard!? */ -+ grub_printf("Performing 'kexec -e'"); -+ kexec[1] = "-e"; -+ kexec[2] = NULL; -+ rc = grub_util_exec(kexec); -+ if ( rc != GRUB_ERR_NONE ) -+ grub_fatal (N_("Error trying to directly perform 'kexec -e'.")); -+ -+ return rc; -+} -+ -+static grub_err_t -+grub_linux_unload (void) -+{ -+ grub_dl_unref (my_mod); -+ if ( boot_cmdline != NULL ) -+ grub_free (boot_cmdline); -+ boot_cmdline = NULL; -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) -+{ -+ int i; -+ char *tempstr; -+ -+ grub_dl_ref (my_mod); -+ -+ if (argc == 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ -+ if ( !grub_util_is_regular(argv[0]) ) -+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("Cannot find kernel file %s"), argv[0]); -+ -+ if ( kernel_path != NULL ) -+ grub_free(kernel_path); -+ -+ kernel_path = grub_xasprintf("%s", argv[0]); -+ -+ if ( boot_cmdline != NULL ) { -+ grub_free(boot_cmdline); -+ boot_cmdline = NULL; -+ } -+ -+ if ( argc > 1 ) -+ { -+ boot_cmdline = grub_xasprintf("--command-line=%s", argv[1]); -+ for ( i = 2; i < argc; i++ ) { -+ tempstr = grub_xasprintf("%s %s", boot_cmdline, argv[i]); -+ grub_free(boot_cmdline); -+ boot_cmdline = tempstr; -+ } -+ } -+ -+ grub_loader_set (grub_linux_boot, grub_linux_unload, 0); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), int argc, char *argv[]) -+{ -+ if (argc == 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ -+ if ( !grub_util_is_regular(argv[0]) ) -+ return grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("Cannot find initrd file %s"), argv[0]); -+ -+ if ( initrd_path != NULL ) -+ grub_free(initrd_path); -+ -+ initrd_path = grub_xasprintf("%s", argv[0]); -+ -+ grub_dl_unref (my_mod); -+ -+ return GRUB_ERR_NONE; -+} -+ -+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; -+ kernel_path = NULL; -+ initrd_path = NULL; -+ boot_cmdline = NULL; -+} -+ -+GRUB_MOD_FINI(linux) -+{ -+ grub_unregister_command (cmd_linux); -+ grub_unregister_command (cmd_initrd); -+} -diff --git a/include/grub/emu/exec.h b/include/grub/emu/exec.h -index d1073ef86af..1b61b4a2e5d 100644 ---- a/include/grub/emu/exec.h -+++ b/include/grub/emu/exec.h -@@ -23,6 +23,8 @@ - #include - - #include -+#include -+ - pid_t - grub_util_exec_pipe (const char *const *argv, int *fd); - pid_t -@@ -32,7 +34,7 @@ int - grub_util_exec_redirect_all (const char *const *argv, const char *stdin_file, - const char *stdout_file, const char *stderr_file); - int --grub_util_exec (const char *const *argv); -+EXPORT_FUNC(grub_util_exec) (const char *const *argv); - int - grub_util_exec_redirect (const char *const *argv, const char *stdin_file, - const char *stdout_file); -diff --git a/include/grub/emu/hostfile.h b/include/grub/emu/hostfile.h -index cfb1e2b5661..a61568e36e9 100644 ---- a/include/grub/emu/hostfile.h -+++ b/include/grub/emu/hostfile.h -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - #include - - int -@@ -29,7 +30,7 @@ grub_util_is_directory (const char *path); - int - grub_util_is_special_file (const char *path); - int --grub_util_is_regular (const char *path); -+EXPORT_FUNC(grub_util_is_regular) (const char *path); - - char * - grub_util_path_concat (size_t n, ...); -diff --git a/include/grub/emu/misc.h b/include/grub/emu/misc.h -index ff9c48a6490..01056954b96 100644 ---- a/include/grub/emu/misc.h -+++ b/include/grub/emu/misc.h -@@ -57,6 +57,9 @@ void EXPORT_FUNC(grub_util_warn) (const char *fmt, ...) __attribute__ ((format ( - void EXPORT_FUNC(grub_util_info) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2))); - void EXPORT_FUNC(grub_util_error) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2), noreturn)); - -+void EXPORT_FUNC(grub_util_set_kexecute) (void); -+int EXPORT_FUNC(grub_util_get_kexecute) (void) WARN_UNUSED_RESULT; -+ - grub_uint64_t EXPORT_FUNC (grub_util_get_cpu_time_ms) (void); - - #ifdef HAVE_DEVICE_MAPPER -diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index ee88e44e97a..80e7a83edf9 100644 ---- a/grub-core/Makefile.am -+++ b/grub-core/Makefile.am -@@ -307,6 +307,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/net.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostdisk.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/hostfile.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/exec.h - if COND_GRUB_EMU_SDL - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/sdl.h - endif diff --git a/0064-Add-grub2-switch-to-blscfg.patch b/0064-Add-grub2-switch-to-blscfg.patch deleted file mode 100644 index fca07e640e2d9a31ad63ce0b050c4e32f7d0b943..0000000000000000000000000000000000000000 --- a/0064-Add-grub2-switch-to-blscfg.patch +++ /dev/null @@ -1,426 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 15 Mar 2018 14:12:40 -0400 -Subject: [PATCH] Add grub2-switch-to-blscfg - -Signed-off-by: Peter Jones -Signed-off-by: Javier Martinez Canillas -[jhlavac: Use ${etcdefaultgrub} instead of /etc/default/grub] -Signed-off-by: Jan Hlavac -[rharwood: skip on ostree installations] -Signed-off-by: Robbie Harwood ---- - Makefile.util.def | 7 + - util/grub-set-password.in | 2 +- - util/grub-switch-to-blscfg.8 | 33 +++++ - util/grub-switch-to-blscfg.in | 317 ++++++++++++++++++++++++++++++++++++++++++ - util/grub.d/10_linux.in | 2 +- - 5 files changed, 359 insertions(+), 2 deletions(-) - create mode 100644 util/grub-switch-to-blscfg.8 - create mode 100644 util/grub-switch-to-blscfg.in - -diff --git a/Makefile.util.def b/Makefile.util.def -index 43a1c7453b1..a90879fa9ba 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -1365,6 +1365,13 @@ program = { - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - }; - -+script = { -+ name = grub-switch-to-blscfg; -+ common = util/grub-switch-to-blscfg.in; -+ mansection = 8; -+ installdir = sbin; -+}; -+ - program = { - name = grub-glue-efi; - mansection = 1; -diff --git a/util/grub-set-password.in b/util/grub-set-password.in -index 5ebf50576d6..c0b5ebbfdc5 100644 ---- a/util/grub-set-password.in -+++ b/util/grub-set-password.in -@@ -1,6 +1,6 @@ - #!/bin/sh -e - --EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/') -+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g') - if [ -d /sys/firmware/efi/efivars/ ]; then - grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` - else -diff --git a/util/grub-switch-to-blscfg.8 b/util/grub-switch-to-blscfg.8 -new file mode 100644 -index 00000000000..9a886282976 ---- /dev/null -+++ b/util/grub-switch-to-blscfg.8 -@@ -0,0 +1,33 @@ -+.TH GRUB-SWITCH-TO-BLSCFG 1 "Wed Feb 26 2014" -+.SH NAME -+\fBgrub-switch-to-blscfg\fR \(em Switch to using BLS config files. -+ -+.SH SYNOPSIS -+\fBgrub-switch-to-blscfg\fR [--grub-directory=\fIDIR\fR] [--config-file=\fIFILE\fR] [--grub-defaults=\fIFILE\fR] -+ -+.SH DESCRIPTION -+\fBgrub-switch-to-blscfg\fR reconfigures grub-mkconfig to use BLS-style config files, and then regenerates the GRUB configuration. -+ -+.SH OPTIONS -+.TP -+--grub-directory=\fIDIR\fR -+Search for grub.cfg under \fIDIR\fR. The default value is \fI/boot/efi/EFI/\fBVENDOR\fR on UEFI machines and \fI/boot/grub2\fR elsewhere. -+ -+.TP -+--config-file=\fIFILE\fR -+The grub config file to use. The default value is \fI/etc/grub2-efi.cfg\fR on UEFI machines and \fI/etc/grub2.cfg\fR elsewhere. Symbolic links will be followed. -+ -+.TP -+--grub-defaults=\fIFILE\fR -+The defaults file for grub-mkconfig. The default value is \fI/etc/default/grub\fR. -+ -+.TP -+--bls-directory=\fIDIR\fR -+Create BootLoaderSpec fragments in \fIDIR\fR. The default value is \fI/boot/loader/entries\fR. -+ -+.TP -+--backup-suffix=\fSUFFIX\fR -+The suffix to use for saved backup files. The default value is \fI.bak\fR. -+ -+.SH SEE ALSO -+.BR "info grub" -diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in -new file mode 100644 -index 00000000000..a851424beb2 ---- /dev/null -+++ b/util/grub-switch-to-blscfg.in -@@ -0,0 +1,317 @@ -+#! /bin/sh -+# -+# Set a default boot entry for GRUB. -+# Copyright (C) 2004,2009 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 . -+ -+#set -eu -+ -+# Initialize some variables. -+prefix=@prefix@ -+exec_prefix=@exec_prefix@ -+sbindir=@sbindir@ -+bindir=@bindir@ -+sysconfdir="@sysconfdir@" -+PACKAGE_NAME=@PACKAGE_NAME@ -+PACKAGE_VERSION=@PACKAGE_VERSION@ -+datarootdir="@datarootdir@" -+datadir="@datadir@" -+if [ ! -v pkgdatadir ]; then -+ pkgdatadir="${datadir}/@PACKAGE@" -+fi -+ -+self=`basename $0` -+ -+grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@" -+grub_editenv=${bindir}/@grub_editenv@ -+etcdefaultgrub=/etc/default/grub -+ -+eval "$("${grub_get_kernel_settings}")" || true -+ -+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g') -+if [ -d /sys/firmware/efi/efivars/ ]; then -+ startlink=/etc/grub2-efi.cfg -+ grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` -+else -+ startlink=/etc/grub2.cfg -+ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` -+fi -+ -+blsdir=`echo "/@bootdirname@/loader/entries" | sed 's,//*,/,g'` -+ -+backupsuffix=.bak -+ -+arch="$(uname -m)" -+ -+export TEXTDOMAIN=@PACKAGE@ -+export TEXTDOMAINDIR="@localedir@" -+ -+. "${pkgdatadir}/grub-mkconfig_lib" -+ -+# Usage: usage -+# Print the usage. -+usage () { -+ gettext_printf "Usage: %s\n" "$self" -+ gettext "Switch to BLS config files.\n"; echo -+ echo -+ print_option_help "-h, --help" "$(gettext "print this message and exit")" -+ print_option_help "-V, --version" "$(gettext "print the version information and exit")" -+ echo -+ print_option_help "--backup-suffix=$(gettext "SUFFIX")" "$backupsuffix" -+ print_option_help "--bls-directory=$(gettext "DIR")" "$blsdir" -+ print_option_help "--config-file=$(gettext "FILE")" "$startlink" -+ print_option_help "--grub-defaults=$(gettext "FILE")" "$etcdefaultgrub" -+ print_option_help "--grub-directory=$(gettext "DIR")" "$grubdir" -+ # echo -+ # gettext "Report bugs to ."; echo -+} -+ -+argument () { -+ opt=$1 -+ shift -+ -+ if test $# -eq 0; then -+ gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2 -+ exit 1 -+ fi -+ echo $1 -+} -+ -+# Check the arguments. -+while test $# -gt 0 -+do -+ option=$1 -+ shift -+ -+ case "$option" in -+ -h | --help) -+ usage -+ exit 0 ;; -+ -V | --version) -+ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}" -+ exit 0 ;; -+ -+ --backup-suffix) -+ backupsuffix=`argument $option "$@"` -+ shift -+ ;; -+ --backup-suffix=*) -+ backupsuffix=`echo "$option" | sed 's/--backup-suffix=//'` -+ ;; -+ -+ --bls-directory) -+ blsdir=`argument $option "$@"` -+ shift -+ ;; -+ --bls-directory=*) -+ blsdir=`echo "$option" | sed 's/--bls-directory=//'` -+ ;; -+ -+ --config-file) -+ startlink=`argument $option "$@"` -+ shift -+ ;; -+ --config-file=*) -+ startlink=`echo "$option" | sed 's/--config-file=//'` -+ ;; -+ -+ --grub-defaults) -+ etcdefaultgrub=`argument $option "$@"` -+ shift -+ ;; -+ --grub-defaults=*) -+ etcdefaultgrub=`echo "$option" | sed 's/--grub-defaults=//'` -+ ;; -+ -+ --grub-directory) -+ grubdir=`argument $option "$@"` -+ shift -+ ;; -+ --grub-directory=*) -+ grubdir=`echo "$option" | sed 's/--grub-directory=//'` -+ ;; -+ -+ *) -+ gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2 -+ usage -+ exit 1 -+ ;; -+ esac -+done -+ -+find_grub_cfg() { -+ local candidate="" -+ while [ -e "${candidate}" -o $# -gt 0 ] -+ do -+ if [ ! -e "${candidate}" ] ; then -+ candidate="$1" -+ shift -+ fi -+ -+ if [ -L "${candidate}" ]; then -+ candidate="$(realpath "${candidate}")" -+ fi -+ -+ if [ -f "${candidate}" ]; then -+ export GRUB_CONFIG_FILE="${candidate}" -+ return 0 -+ fi -+ done -+ return 1 -+} -+ -+if ! find_grub_cfg ${startlink} ${grubdir}/grub.cfg ; then -+ gettext_printf "Couldn't find config file\n" 1>&2 -+ exit 1 -+fi -+ -+if [ ! -d "${blsdir}" ]; then -+ install -m 700 -d "${blsdir}" -+fi -+ -+if [ -f /etc/machine-id ]; then -+ MACHINE_ID=$(cat /etc/machine-id) -+else -+ MACHINE_ID=$(dmesg | sha256sum) -+fi -+ -+mkbls() { -+ local kernelver=$1 && shift -+ local datetime=$1 && shift -+ local kernelopts=$1 && shift -+ -+ local debugname="" -+ local debugid="" -+ local flavor="" -+ -+ if [ "$kernelver" == *\+* ] ; then -+ local flavor=-"${kernelver##*+}" -+ if [ "${flavor}" == "-debug" ]; then -+ local debugname=" with debugging" -+ local debugid="-debug" -+ fi -+ fi -+ ( -+ source /etc/os-release -+ -+ cat <"${bls_target}" -+ -+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then -+ bls_debug="$(echo ${bls_target} | sed -e "s/${kernelver}/${kernelver}~debug/")" -+ cp -aT "${bls_target}" "${bls_debug}" -+ title="$(grep '^title[ \t]' "${bls_debug}" | sed -e 's/^title[ \t]*//')" -+ options="$(echo "${cmdline} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 's/\//\\\//g')" -+ sed -i -e "s/^title.*/title ${title}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${bls_debug}" -+ sed -i -e "s/^options.*/options ${options}/" "${bls_debug}" -+ fi -+ done -+ -+ if [ -f "/boot/vmlinuz-0-rescue-${MACHINE_ID}" ]; then -+ mkbls "0-rescue-${MACHINE_ID}" "0" "${bootprefix}" >"${blsdir}/${MACHINE_ID}-0-rescue.conf" -+ fi -+} -+ -+# The grub2 EFI binary is not copied to the ESP as a part of an ostree -+# transaction. Make sure a grub2 version with BLS support is installed -+# but only do this if the blsdir is not set, to make sure that the BLS -+# parsing module will search for the BLS snippets in the default path. -+if test -f /run/ostree-booted && test -d /sys/firmware/efi/efivars && \ -+ ! ${grub_editenv} - list | grep -q blsdir && \ -+ mountpoint -q /boot; then -+ grub_binary="$(find /usr/lib/ostree-boot/efi/EFI/${EFIDIR}/ -name grub*.efi)" -+ install -m 700 ${grub_binary} ${grubdir} || exit 1 -+ # Create a hidden file to indicate that grub2 now has BLS support. -+ touch /boot/grub2/.grub2-blscfg-supported -+fi -+ -+GENERATE=0 -+if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \ -+ | grep -vq '^GRUB_ENABLE_BLSCFG="*true"*\s*$' ; then -+ if ! sed -i"${backupsuffix}" \ -+ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=true,' \ -+ "${etcdefaultgrub}" ; then -+ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}" -+ exit 1 -+ fi -+ GENERATE=1 -+elif ! grep -q '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" ; then -+ if ! echo 'GRUB_ENABLE_BLSCFG=true' >> "${etcdefaultgrub}" ; then -+ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}" -+ exit 1 -+ fi -+ GENERATE=1 -+fi -+ -+if [ "${GENERATE}" -eq 1 ] ; then -+ copy_bls -+ -+ if [ $arch = "x86_64" ] && [ ! -d /sys/firmware/efi ]; then -+ mod_dir="i386-pc" -+ elif [ $arch = "ppc64" -o $arch = "ppc64le" ] && [ ! -d /sys/firmware/opal ]; then -+ mod_dir="powerpc-ieee1275" -+ fi -+ -+ if [ -n "${mod_dir}" ]; then -+ for mod in blscfg increment; do -+ install -m 700 ${prefix}/lib/grub/${mod_dir}/${mod}.mod ${grubdir}/$mod_dir/ || exit 1 -+ done -+ fi -+ -+ cp -af "${GRUB_CONFIG_FILE}" "${GRUB_CONFIG_FILE}${backupsuffix}" -+ if ! grub2-mkconfig -o "${GRUB_CONFIG_FILE}" ; then -+ install -m 700 "${GRUB_CONFIG_FILE}${backupsuffix}" "${GRUB_CONFIG_FILE}" -+ sed -i"${backupsuffix}" \ -+ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=false,' \ -+ "${etcdefaultgrub}" -+ gettext_printf "Updating %s failed\n" "${GRUB_CONFIG_FILE}" -+ exit 1 -+ fi -+fi -+ -+# Bye. -+exit 0 -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 9fcd77cacc3..81f35a2f3f0 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -138,7 +138,7 @@ blsdir="/boot/loader/entries" - - get_sorted_bls() - { -- if ! [ -d "${blsdir}" ]; then -+ if ! [ -d "${blsdir}" ] || [ -f /run/ostree-booted ]; then - return - fi - diff --git a/0065-make-better-backtraces.patch b/0065-make-better-backtraces.patch deleted file mode 100644 index 637656719b92e0b946b0eb0431ca4ee4a800e823..0000000000000000000000000000000000000000 --- a/0065-make-better-backtraces.patch +++ /dev/null @@ -1,910 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 9 Jul 2019 17:05:03 +0200 -Subject: [PATCH] make better backtraces - -Signed-off-by: Peter Jones ---- - Makefile.util.def | 6 ++ - grub-core/Makefile.core.def | 16 ++-- - grub-core/{lib => commands}/backtrace.c | 2 +- - grub-core/gdb/cstub.c | 1 - - grub-core/kern/arm64/backtrace.c | 94 ++++++++++++++++++++++++ - grub-core/kern/backtrace.c | 97 +++++++++++++++++++++++++ - grub-core/kern/dl.c | 45 ++++++++++++ - grub-core/kern/i386/backtrace.c | 125 ++++++++++++++++++++++++++++++++ - grub-core/kern/i386/pc/init.c | 4 +- - grub-core/kern/ieee1275/init.c | 1 - - grub-core/kern/misc.c | 13 ++-- - grub-core/kern/mm.c | 6 +- - grub-core/lib/arm64/backtrace.c | 62 ---------------- - grub-core/lib/i386/backtrace.c | 78 -------------------- - include/grub/backtrace.h | 10 ++- - include/grub/dl.h | 2 + - include/grub/kernel.h | 3 + - grub-core/kern/arm/efi/startup.S | 2 + - grub-core/kern/arm/startup.S | 2 + - grub-core/kern/arm64/efi/startup.S | 2 + - grub-core/kern/i386/qemu/startup.S | 3 +- - grub-core/kern/ia64/efi/startup.S | 3 +- - grub-core/kern/sparc64/ieee1275/crt0.S | 3 +- - grub-core/Makefile.am | 1 + - 24 files changed, 414 insertions(+), 167 deletions(-) - rename grub-core/{lib => commands}/backtrace.c (98%) - create mode 100644 grub-core/kern/arm64/backtrace.c - create mode 100644 grub-core/kern/backtrace.c - create mode 100644 grub-core/kern/i386/backtrace.c - delete mode 100644 grub-core/lib/arm64/backtrace.c - delete mode 100644 grub-core/lib/i386/backtrace.c - -diff --git a/Makefile.util.def b/Makefile.util.def -index a90879fa9ba..48512bc6311 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -51,6 +51,12 @@ library = { - common = grub-core/partmap/msdos.c; - common = grub-core/fs/proc.c; - common = grub-core/fs/archelp.c; -+ common = grub-core/kern/backtrace.c; -+ -+ x86 = grub-core/kern/i386/backtrace.c; -+ i386_xen = grub-core/kern/i386/backtrace.c; -+ x86_64_xen = grub-core/kern/i386/backtrace.c; -+ arm64 = grub-core/kern/arm64/backtrace.c; - }; - - library = { -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 5354f9613d3..4b7c45a7b06 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -142,6 +142,12 @@ kernel = { - common = kern/rescue_reader.c; - common = kern/term.c; - common = kern/verifiers.c; -+ common = kern/backtrace.c; -+ -+ x86 = kern/i386/backtrace.c; -+ i386_xen = kern/i386/backtrace.c; -+ x86_64_xen = kern/i386/backtrace.c; -+ arm64 = kern/arm64/backtrace.c; - - noemu = kern/compiler-rt.c; - noemu = kern/mm.c; -@@ -188,9 +194,6 @@ kernel = { - - softdiv = lib/division.c; - -- x86 = lib/i386/backtrace.c; -- x86 = lib/backtrace.c; -- - i386 = kern/i386/dl.c; - i386_xen = kern/i386/dl.c; - i386_xen_pvh = kern/i386/dl.c; -@@ -2398,15 +2401,12 @@ module = { - - module = { - name = backtrace; -- x86 = lib/i386/backtrace.c; -- i386_xen_pvh = lib/i386/backtrace.c; -- i386_xen = lib/i386/backtrace.c; -- x86_64_xen = lib/i386/backtrace.c; -- common = lib/backtrace.c; -+ common = commands/backtrace.c; - enable = x86; - enable = i386_xen_pvh; - enable = i386_xen; - enable = x86_64_xen; -+ enable = arm64; - }; - - module = { -diff --git a/grub-core/lib/backtrace.c b/grub-core/commands/backtrace.c -similarity index 98% -rename from grub-core/lib/backtrace.c -rename to grub-core/commands/backtrace.c -index c0ad6ab8be1..8b5ec3913b5 100644 ---- a/grub-core/lib/backtrace.c -+++ b/grub-core/commands/backtrace.c -@@ -54,7 +54,7 @@ grub_cmd_backtrace (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), - char **args __attribute__ ((unused))) - { -- grub_backtrace (); -+ grub_backtrace (1); - return 0; - } - -diff --git a/grub-core/gdb/cstub.c b/grub-core/gdb/cstub.c -index b64acd70fee..99281472d36 100644 ---- a/grub-core/gdb/cstub.c -+++ b/grub-core/gdb/cstub.c -@@ -215,7 +215,6 @@ grub_gdb_trap (int trap_no) - grub_printf ("Unhandled exception 0x%x at ", trap_no); - grub_backtrace_print_address ((void *) grub_gdb_regs[PC]); - grub_printf ("\n"); -- grub_backtrace_pointer ((void *) grub_gdb_regs[EBP]); - grub_fatal ("Unhandled exception"); - } - -diff --git a/grub-core/kern/arm64/backtrace.c b/grub-core/kern/arm64/backtrace.c -new file mode 100644 -index 00000000000..019c6fdfef2 ---- /dev/null -+++ b/grub-core/kern/arm64/backtrace.c -@@ -0,0 +1,94 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_STACK_FRAME 102400 -+ -+struct fplr -+{ -+ void *lr; -+ struct fplr *fp; -+}; -+ -+void -+grub_backtrace_pointer (void *frame, unsigned int skip) -+{ -+ unsigned int x = 0; -+ struct fplr *fplr = (struct fplr *)frame; -+ -+ while (fplr) -+ { -+ const char *name = NULL; -+ char *addr = NULL; -+ -+ grub_dprintf("backtrace", "fp is %p next_fp is %p\n", -+ fplr, fplr->fp); -+ -+ if (x >= skip) -+ { -+ name = grub_get_symbol_by_addr (fplr->lr, 1); -+ if (name) -+ addr = grub_resolve_symbol (name); -+ grub_backtrace_print_address (fplr->lr); -+ -+ if (addr && addr != fplr->lr) -+ grub_printf (" %s() %p+%p \n", name ? name : "unknown", addr, -+ (void *)((grub_uint64_t)fplr->lr - (grub_uint64_t)addr)); -+ else -+ grub_printf(" %s() %p \n", name ? name : "unknown", addr); -+ -+ } -+ -+ x += 1; -+ -+ if (fplr->fp < fplr || -+ (grub_uint64_t)fplr->fp - (grub_uint64_t)fplr > MAX_STACK_FRAME || -+ fplr->fp == fplr) -+ { -+ break; -+ } -+ fplr = fplr->fp; -+ } -+} -+ -+asm ("\t.global \"_text\"\n" -+ "_text:\n" -+ "\t.quad .text\n" -+ "\t.global \"_data\"\n" -+ "_data:\n" -+ "\t.quad .data\n" -+ ); -+ -+extern grub_uint64_t _text; -+extern grub_uint64_t _data; -+ -+void -+grub_backtrace_arch (unsigned int skip) -+{ -+ grub_printf ("Backtrace (.text %p .data %p):\n", -+ (void *)_text, (void *)_data); -+ skip += 1; -+ grub_backtrace_pointer(__builtin_frame_address(0), skip); -+} -diff --git a/grub-core/kern/backtrace.c b/grub-core/kern/backtrace.c -new file mode 100644 -index 00000000000..4a82e865cc6 ---- /dev/null -+++ b/grub-core/kern/backtrace.c -@@ -0,0 +1,97 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static void -+grub_backtrace_print_address_default (void *addr) -+{ -+#ifndef GRUB_UTIL -+ grub_dl_t mod; -+ void *start_addr; -+ -+ FOR_DL_MODULES (mod) -+ { -+ grub_dl_segment_t segment; -+ for (segment = mod->segment; segment; segment = segment->next) -+ if (segment->addr <= addr && (grub_uint8_t *) segment->addr -+ + segment->size > (grub_uint8_t *) addr) -+ { -+ grub_printf ("%s.%x+%" PRIxGRUB_SIZE, mod->name, -+ segment->section, -+ (grub_size_t) -+ ((grub_uint8_t *)addr - (grub_uint8_t *)segment->addr)); -+ return; -+ } -+ } -+ -+ start_addr = grub_resolve_symbol ("_start"); -+ if (start_addr && start_addr < addr) -+ grub_printf ("kernel+%" PRIxGRUB_SIZE, -+ (grub_size_t) -+ ((grub_uint8_t *)addr - (grub_uint8_t *)start_addr)); -+ else -+#endif -+ grub_printf ("%p", addr); -+} -+ -+static void -+grub_backtrace_pointer_default (void *frame __attribute__((__unused__)), -+ unsigned int skip __attribute__((__unused__))) -+{ -+ return; -+} -+ -+void -+grub_backtrace_pointer (void *frame, unsigned int skip) -+ __attribute__((__weak__, -+ __alias__(("grub_backtrace_pointer_default")))); -+ -+void -+grub_backtrace_print_address (void *addr) -+ __attribute__((__weak__, -+ __alias__(("grub_backtrace_print_address_default")))); -+ -+static void -+grub_backtrace_arch_default(unsigned int skip) -+{ -+ grub_backtrace_pointer(__builtin_frame_address(0), skip + 1); -+} -+ -+void grub_backtrace_arch (unsigned int skip) -+ __attribute__((__weak__, __alias__(("grub_backtrace_arch_default")))); -+ -+void grub_backtrace (unsigned int skip) -+{ -+ grub_backtrace_arch(skip + 1); -+} -+ -+void grub_debug_backtrace (const char * const debug, -+ unsigned int skip) -+{ -+ if (grub_debug_enabled (debug)) -+ grub_backtrace (skip + 1); -+} -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index 7afb9e6f724..88d2077709e 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -124,6 +124,50 @@ grub_dl_resolve_symbol (const char *name) - return 0; - } - -+void * -+grub_resolve_symbol (const char *name) -+{ -+ grub_symbol_t sym; -+ -+ sym = grub_dl_resolve_symbol (name); -+ if (sym) -+ return sym->addr; -+ return NULL; -+} -+ -+const char * -+grub_get_symbol_by_addr(const void *addr, int isfunc) -+{ -+ unsigned int i; -+ grub_symbol_t before = NULL, after = NULL; -+ for (i = 0; i < GRUB_SYMTAB_SIZE; i++) -+ { -+ grub_symbol_t sym; -+ for (sym = grub_symtab[i]; sym; sym = sym->next) -+ { -+ //grub_printf ("addr 0x%08llx symbol %s\n", (unsigned long long)sym->addr, sym->name); -+ if (sym->addr > addr) -+ { -+ if (!after || sym->addr > after->addr) -+ after = sym; -+ } -+ -+ if (isfunc != sym->isfunc) -+ continue; -+ if (sym->addr > addr) -+ continue; -+ -+ if ((!before && sym->addr <= addr) || (before && before->addr <= sym->addr)) -+ before = sym; -+ } -+ } -+ -+ if (before && addr < after->addr) -+ return before->name; -+ -+ return NULL; -+} -+ - /* Register a symbol with the name NAME and the address ADDR. */ - grub_err_t - grub_dl_register_symbol (const char *name, void *addr, int isfunc, -@@ -336,6 +380,7 @@ grub_dl_resolve_symbols (grub_dl_t mod, Elf_Ehdr *e) - const char *str; - Elf_Word size, entsize; - -+ grub_dprintf ("modules", "Resolving symbols for \"%s\"\n", mod->name); - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) -diff --git a/grub-core/kern/i386/backtrace.c b/grub-core/kern/i386/backtrace.c -new file mode 100644 -index 00000000000..2413f9a57db ---- /dev/null -+++ b/grub-core/kern/i386/backtrace.c -@@ -0,0 +1,125 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define MAX_STACK_FRAME 102400 -+ -+void -+grub_backtrace_pointer (void *frame, unsigned int skip) -+{ -+ void **ebp = (void **)frame; -+ unsigned long x = 0; -+ -+ while (ebp) -+ { -+ void **next_ebp = (void **)ebp[0]; -+ const char *name = NULL; -+ char *addr = NULL; -+ -+ grub_dprintf("backtrace", "ebp is %p next_ebp is %p\n", ebp, next_ebp); -+ -+ if (x >= skip) -+ { -+ name = grub_get_symbol_by_addr (ebp[1], 1); -+ if (name) -+ addr = grub_resolve_symbol (name); -+ grub_backtrace_print_address (ebp[1]); -+ -+ if (addr && addr != ebp[1]) -+ grub_printf (" %s() %p+%p \n", name ? name : "unknown", addr, -+ (char *)((char *)ebp[1] - addr)); -+ else -+ grub_printf(" %s() %p \n", name ? name : "unknown", addr); -+ -+#if 0 -+ grub_printf ("("); -+ for (i = 0, arg = ebp[2]; arg != next_ebp && i < 12; arg++, i++) -+ grub_printf ("%p,", arg); -+ grub_printf (")\n"); -+#endif -+ } -+ -+ x += 1; -+ -+ if (next_ebp < ebp || next_ebp - ebp > MAX_STACK_FRAME || next_ebp == ebp) -+ { -+ //grub_printf ("Invalid stack frame at %p (%p)\n", ebp, next_ebp); -+ break; -+ } -+ ebp = next_ebp; -+ } -+} -+ -+#if defined (__x86_64__) -+asm ("\t.global \"_text\"\n" -+ "_text:\n" -+ "\t.quad .text\n" -+ "\t.global \"_data\"\n" -+ "_data:\n" -+ "\t.quad .data\n" -+ ); -+#elif defined(__i386__) -+asm ("\t.global \"_text\"\n" -+ "_text:\n" -+ "\t.long .text\n" -+ "\t.global \"_data\"\n" -+ "_data:\n" -+ "\t.long .data\n" -+ ); -+#else -+#warning I dunno... -+#endif -+ -+extern unsigned long _text; -+extern unsigned long _data; -+ -+#ifdef GRUB_UTIL -+#define EXT_C(x) x -+#endif -+ -+void -+grub_backtrace_arch (unsigned int skip) -+{ -+ grub_printf ("Backtrace (.text %p .data %p):\n", -+ (void *)_text, (void *)_data); -+ skip += 1; -+#if defined (__x86_64__) -+ asm volatile ("movq %%rbp, %%rdi\n" -+ "movq 0, %%rsi\n" -+ "movl %0, %%esi\n" -+ "call " EXT_C("grub_backtrace_pointer") -+ : -+ : "r" (skip)); -+#elif defined(__i386__) -+ asm volatile ("addl $8, %%esp\n" -+ "pushl %0\n" -+ "pushl %%ebp\n" -+ "call " EXT_C("grub_backtrace_pointer") -+ : -+ : "r" (skip)); -+#else -+ grub_backtrace_pointer(__builtin_frame_address(0), skip); -+#endif -+} -diff --git a/grub-core/kern/i386/pc/init.c b/grub-core/kern/i386/pc/init.c -index 27bc68b8a53..b51d0abfa6e 100644 ---- a/grub-core/kern/i386/pc/init.c -+++ b/grub-core/kern/i386/pc/init.c -@@ -153,7 +153,7 @@ compact_mem_regions (void) - } - - grub_addr_t grub_modbase; --extern grub_uint8_t _start[], _edata[]; -+extern grub_uint8_t _edata[]; - - /* Helper for grub_machine_init. */ - static int -@@ -217,7 +217,7 @@ grub_machine_init (void) - /* This has to happen before any BIOS calls. */ - grub_via_workaround_init (); - -- grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - _start); -+ grub_modbase = GRUB_MEMORY_MACHINE_DECOMPRESSION_ADDR + (_edata - (grub_uint8_t *)_start); - - /* Initialize the console as early as possible. */ - grub_console_init (); -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index 0cd2a627231..937c1bc44cb 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -63,7 +63,6 @@ - #define HEAP_MAX_ADDR (unsigned long) (32 * 1024 * 1024) - #endif - --extern char _start[]; - extern char _end[]; - - #ifdef __sparc__ -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index c60601b699d..a432a6be54a 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -1197,15 +1197,15 @@ grub_printf_fmt_check (const char *fmt, const char *fmt_expected) - - - /* Abort GRUB. This function does not return. */ --static void __attribute__ ((noreturn)) -+static inline void __attribute__ ((noreturn)) - grub_abort (void) - { --#ifndef GRUB_UTIL --#if (defined(__i386__) || defined(__x86_64__)) && !defined(GRUB_MACHINE_EMU) -- grub_backtrace(); -+#if !defined(GRUB_MACHINE_EMU) && !defined(GRUB_UTIL) -+ grub_backtrace (1); -+#else -+ grub_printf ("\n"); - #endif --#endif -- grub_printf ("\nAborted."); -+ grub_printf ("Aborted."); - - #ifndef GRUB_UTIL - if (grub_term_inputs) -@@ -1232,6 +1232,7 @@ grub_fatal (const char *fmt, ...) - { - va_list ap; - -+ grub_printf ("\n"); - va_start (ap, fmt); - grub_vprintf (_(fmt), ap); - va_end (ap); -diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c -index c070afc621f..d8c8377578b 100644 ---- a/grub-core/kern/mm.c -+++ b/grub-core/kern/mm.c -@@ -97,13 +97,13 @@ get_header_from_pointer (void *ptr, grub_mm_header_t *p, grub_mm_region_t *r) - break; - - if (! *r) -- grub_fatal ("out of range pointer %p", ptr); -+ grub_fatal ("out of range pointer %p\n", ptr); - - *p = (grub_mm_header_t) ptr - 1; - if ((*p)->magic == GRUB_MM_FREE_MAGIC) -- grub_fatal ("double free at %p", *p); -+ grub_fatal ("double free at %p\n", *p); - if ((*p)->magic != GRUB_MM_ALLOC_MAGIC) -- grub_fatal ("alloc magic is broken at %p: %lx", *p, -+ grub_fatal ("alloc magic is broken at %p: %lx\n", *p, - (unsigned long) (*p)->magic); - } - -diff --git a/grub-core/lib/arm64/backtrace.c b/grub-core/lib/arm64/backtrace.c -deleted file mode 100644 -index 1079b5380e1..00000000000 ---- a/grub-core/lib/arm64/backtrace.c -+++ /dev/null -@@ -1,62 +0,0 @@ --/* -- * GRUB -- GRand Unified Bootloader -- * Copyright (C) 2009 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 . -- */ -- --#include --#include --#include --#include --#include --#include --#include -- --#define MAX_STACK_FRAME 102400 -- --void --grub_backtrace_pointer (int frame) --{ -- while (1) -- { -- void *lp = __builtin_return_address (frame); -- if (!lp) -- break; -- -- lp = __builtin_extract_return_addr (lp); -- -- grub_printf ("%p: ", lp); -- grub_backtrace_print_address (lp); -- grub_printf (" ("); -- for (i = 0; i < 2; i++) -- grub_printf ("%p,", ((void **)ptr) [i + 2]); -- grub_printf ("%p)\n", ((void **)ptr) [i + 2]); -- nptr = *(void **)ptr; -- if (nptr < ptr || (void **) nptr - (void **) ptr > MAX_STACK_FRAME -- || nptr == ptr) -- { -- grub_printf ("Invalid stack frame at %p (%p)\n", ptr, nptr); -- break; -- } -- ptr = nptr; -- } --} -- --void --grub_backtrace (void) --{ -- grub_backtrace_pointer (1); --} -- -diff --git a/grub-core/lib/i386/backtrace.c b/grub-core/lib/i386/backtrace.c -deleted file mode 100644 -index c67273db3ae..00000000000 ---- a/grub-core/lib/i386/backtrace.c -+++ /dev/null -@@ -1,78 +0,0 @@ --/* -- * GRUB -- GRand Unified Bootloader -- * Copyright (C) 2009 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 . -- */ --#include --#ifdef GRUB_UTIL --#define REALLY_GRUB_UTIL GRUB_UTIL --#undef GRUB_UTIL --#endif -- --#include --#include -- --#ifdef REALLY_GRUB_UTIL --#define GRUB_UTIL REALLY_GRUB_UTIL --#undef REALLY_GRUB_UTIL --#endif -- --#include --#include --#include --#include --#include --#include -- --#define MAX_STACK_FRAME 102400 -- --void --grub_backtrace_pointer (void *ebp) --{ -- void *ptr, *nptr; -- unsigned i; -- -- ptr = ebp; -- while (1) -- { -- grub_printf ("%p: ", ptr); -- grub_backtrace_print_address (((void **) ptr)[1]); -- grub_printf (" ("); -- for (i = 0; i < 2; i++) -- grub_printf ("%p,", ((void **)ptr) [i + 2]); -- grub_printf ("%p)\n", ((void **)ptr) [i + 2]); -- nptr = *(void **)ptr; -- if (nptr < ptr || (void **) nptr - (void **) ptr > MAX_STACK_FRAME -- || nptr == ptr) -- { -- grub_printf ("Invalid stack frame at %p (%p)\n", ptr, nptr); -- break; -- } -- ptr = nptr; -- } --} -- --void --grub_backtrace (void) --{ --#ifdef __x86_64__ -- asm volatile ("movq %%rbp, %%rdi\n" -- "callq *%%rax": :"a"(grub_backtrace_pointer)); --#else -- asm volatile ("movl %%ebp, %%eax\n" -- "calll *%%ecx": :"c"(grub_backtrace_pointer)); --#endif --} -- -diff --git a/include/grub/backtrace.h b/include/grub/backtrace.h -index 395519762f0..275cf85e2d3 100644 ---- a/include/grub/backtrace.h -+++ b/include/grub/backtrace.h -@@ -19,8 +19,14 @@ - #ifndef GRUB_BACKTRACE_HEADER - #define GRUB_BACKTRACE_HEADER 1 - --void grub_backtrace (void); --void grub_backtrace_pointer (void *ptr); -+#include -+#include -+ -+void EXPORT_FUNC(grub_debug_backtrace) (const char * const debug, -+ unsigned int skip); -+void EXPORT_FUNC(grub_backtrace) (unsigned int skip); -+void grub_backtrace_arch (unsigned int skip); -+void grub_backtrace_pointer (void *ptr, unsigned int skip); - void grub_backtrace_print_address (void *addr); - - #endif -diff --git a/include/grub/dl.h b/include/grub/dl.h -index 91933b85f2c..2f76e6b0437 100644 ---- a/include/grub/dl.h -+++ b/include/grub/dl.h -@@ -259,6 +259,8 @@ grub_dl_is_persistent (grub_dl_t mod) - - #endif - -+void * EXPORT_FUNC(grub_resolve_symbol) (const char *name); -+const char * EXPORT_FUNC(grub_get_symbol_by_addr) (const void *addr, int isfunc); - grub_err_t grub_dl_register_symbol (const char *name, void *addr, - int isfunc, grub_dl_t mod); - -diff --git a/include/grub/kernel.h b/include/grub/kernel.h -index abbca5ea335..300a9766cda 100644 ---- a/include/grub/kernel.h -+++ b/include/grub/kernel.h -@@ -111,6 +111,9 @@ grub_addr_t grub_modules_get_end (void); - - #endif - -+void EXPORT_FUNC(start) (void); -+void EXPORT_FUNC(_start) (void); -+ - /* The start point of the C code. */ - void grub_main (void) __attribute__ ((noreturn)); - -diff --git a/grub-core/kern/arm/efi/startup.S b/grub-core/kern/arm/efi/startup.S -index 9f8265315a9..f3bc41f9d0f 100644 ---- a/grub-core/kern/arm/efi/startup.S -+++ b/grub-core/kern/arm/efi/startup.S -@@ -23,6 +23,8 @@ - .file "startup.S" - .text - .arm -+ .globl start, _start -+FUNCTION(start) - FUNCTION(_start) - /* - * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in r1/r0. -diff --git a/grub-core/kern/arm/startup.S b/grub-core/kern/arm/startup.S -index 3946fe8e183..5679a1d00ad 100644 ---- a/grub-core/kern/arm/startup.S -+++ b/grub-core/kern/arm/startup.S -@@ -48,6 +48,8 @@ - - .text - .arm -+ .globl start, _start -+FUNCTION(start) - FUNCTION(_start) - b codestart - -diff --git a/grub-core/kern/arm64/efi/startup.S b/grub-core/kern/arm64/efi/startup.S -index 666a7ee3c92..41676bdb2b8 100644 ---- a/grub-core/kern/arm64/efi/startup.S -+++ b/grub-core/kern/arm64/efi/startup.S -@@ -19,7 +19,9 @@ - #include - - .file "startup.S" -+ .globl start, _start - .text -+FUNCTION(start) - FUNCTION(_start) - /* - * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in x1/x0. -diff --git a/grub-core/kern/i386/qemu/startup.S b/grub-core/kern/i386/qemu/startup.S -index 0d89858d9b3..939f182fc74 100644 ---- a/grub-core/kern/i386/qemu/startup.S -+++ b/grub-core/kern/i386/qemu/startup.S -@@ -24,7 +24,8 @@ - - .text - .code32 -- .globl _start -+ .globl start, _start -+start: - _start: - jmp codestart - -diff --git a/grub-core/kern/ia64/efi/startup.S b/grub-core/kern/ia64/efi/startup.S -index d75c6d7cc74..8f2a593e529 100644 ---- a/grub-core/kern/ia64/efi/startup.S -+++ b/grub-core/kern/ia64/efi/startup.S -@@ -24,8 +24,9 @@ - .psr lsb - .lsb - -- .global _start -+ .global start, _start - .proc _start -+start: - _start: - alloc loc0=ar.pfs,2,4,0,0 - mov loc1=rp -diff --git a/grub-core/kern/sparc64/ieee1275/crt0.S b/grub-core/kern/sparc64/ieee1275/crt0.S -index 03b916f0534..701bf63abcf 100644 ---- a/grub-core/kern/sparc64/ieee1275/crt0.S -+++ b/grub-core/kern/sparc64/ieee1275/crt0.S -@@ -22,7 +22,8 @@ - - .text - .align 4 -- .globl _start -+ .globl start, _start -+start: - _start: - ba codestart - mov %o4, %o0 -diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index 80e7a83edf9..f512573c0da 100644 ---- a/grub-core/Makefile.am -+++ b/grub-core/Makefile.am -@@ -66,6 +66,7 @@ CLEANFILES += grub_script.yy.c grub_script.yy.h - - include $(srcdir)/Makefile.core.am - -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/backtrace.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/cache.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/command.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/device.h diff --git a/0066-normal-don-t-draw-our-startup-message-if-debug-is-se.patch b/0066-normal-don-t-draw-our-startup-message-if-debug-is-se.patch deleted file mode 100644 index 9ebfc7ae01e3d4057d5879b7faf3f5e52bf176d4..0000000000000000000000000000000000000000 --- a/0066-normal-don-t-draw-our-startup-message-if-debug-is-se.patch +++ /dev/null @@ -1,23 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 9 Nov 2017 15:58:52 -0500 -Subject: [PATCH] normal: don't draw our startup message if debug is set - ---- - grub-core/normal/main.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index d5df4f815b0..1970e4816a8 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -430,6 +430,9 @@ grub_normal_reader_init (int nested) - const char *msg_esc = _("ESC at any time exits."); - char *msg_formatted; - -+ if (grub_env_get ("debug") != NULL) -+ return 0; -+ - msg_formatted = grub_xasprintf (_("Minimal BASH-like line editing is supported. For " - "the first word, TAB lists possible command completions. Anywhere " - "else TAB lists possible device or file completions. %s"), diff --git a/0068-Make-it-possible-to-enabled-build-id-sha1.patch b/0068-Make-it-possible-to-enabled-build-id-sha1.patch deleted file mode 100644 index f68fc58b8f4fa084d624f50f52dfca042084562f..0000000000000000000000000000000000000000 --- a/0068-Make-it-possible-to-enabled-build-id-sha1.patch +++ /dev/null @@ -1,61 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 25 Jun 2015 15:41:06 -0400 -Subject: [PATCH] Make it possible to enabled --build-id=sha1 - -Signed-off-by: Peter Jones ---- - configure.ac | 8 ++++++++ - acinclude.m4 | 19 +++++++++++++++++++ - 2 files changed, 27 insertions(+) - -diff --git a/configure.ac b/configure.ac -index a0030632220..b50fb2e9897 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1470,7 +1470,15 @@ grub_PROG_TARGET_CC - if test "x$TARGET_APPLE_LINKER" != x1 ; then - grub_PROG_OBJCOPY_ABSOLUTE - fi -+ -+AC_ARG_ENABLE([build-id], -+ [AS_HELP_STRING([--enable-build-id], -+ [ask the linker to supply build-id notes (default=no)])]) -+if test x$enable_build_id = xyes; then -+grub_PROG_LD_BUILD_ID_SHA1 -+else - grub_PROG_LD_BUILD_ID_NONE -+fi - if test "x$target_cpu" = xi386; then - if test "$platform" != emu && test "x$TARGET_APPLE_LINKER" != x1 ; then - if test ! -z "$TARGET_IMG_LDSCRIPT"; then -diff --git a/acinclude.m4 b/acinclude.m4 -index 6e14bb553c6..21238fcfd03 100644 ---- a/acinclude.m4 -+++ b/acinclude.m4 -@@ -136,6 +136,25 @@ if test "x$grub_cv_prog_ld_build_id_none" = xyes; then - fi - ]) - -+dnl Supply --build-id=sha1 to ld if building modules. -+dnl This suppresses warnings from ld on some systems -+AC_DEFUN([grub_PROG_LD_BUILD_ID_SHA1], -+[AC_MSG_CHECKING([whether linker accepts --build-id=sha1]) -+AC_CACHE_VAL(grub_cv_prog_ld_build_id_sha1, -+[save_LDFLAGS="$LDFLAGS" -+LDFLAGS="$LDFLAGS -Wl,--build-id=sha1" -+AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], -+ [grub_cv_prog_ld_build_id_sha1=yes], -+ [grub_cv_prog_ld_build_id_sha1=no]) -+LDFLAGS="$save_LDFLAGS" -+]) -+AC_MSG_RESULT([$grub_cv_prog_ld_build_id_sha1]) -+ -+if test "x$grub_cv_prog_ld_build_id_sha1" = xyes; then -+ TARGET_LDFLAGS="$TARGET_LDFLAGS -Wl,--build-id=sha1" -+fi -+]) -+ - dnl Check nm - AC_DEFUN([grub_PROG_NM_WORKS], - [AC_MSG_CHECKING([whether nm works]) diff --git a/0069-Add-grub_qdprintf-grub_dprintf-without-the-file-line.patch b/0069-Add-grub_qdprintf-grub_dprintf-without-the-file-line.patch deleted file mode 100644 index a8a757e5f5b9d178564c4471ae656e909532290a..0000000000000000000000000000000000000000 --- a/0069-Add-grub_qdprintf-grub_dprintf-without-the-file-line.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Sun, 28 Jun 2015 13:09:58 -0400 -Subject: [PATCH] Add grub_qdprintf() - grub_dprintf() without the file+line - number. - -This just makes copy+paste of our debug loading info easier. - -Signed-off-by: Peter Jones ---- - grub-core/kern/misc.c | 18 ++++++++++++++++++ - include/grub/misc.h | 2 ++ - 2 files changed, 20 insertions(+) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index a432a6be54a..9a2fae6398e 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -191,6 +191,24 @@ grub_real_dprintf (const char *file, const int line, const char *condition, - } - } - -+void -+grub_qdprintf (const char *condition, const char *fmt, ...) -+{ -+ va_list args; -+ const char *debug = grub_env_get ("debug"); -+ -+ if (! debug) -+ return; -+ -+ if (grub_strword (debug, "all") || grub_strword (debug, condition)) -+ { -+ va_start (args, fmt); -+ grub_vprintf (fmt, args); -+ va_end (args); -+ grub_refresh (); -+ } -+} -+ - #define PREALLOC_SIZE 255 - - int -diff --git a/include/grub/misc.h b/include/grub/misc.h -index fd18e6320b8..3adc4036e3b 100644 ---- a/include/grub/misc.h -+++ b/include/grub/misc.h -@@ -345,6 +345,8 @@ void EXPORT_FUNC(grub_real_dprintf) (const char *file, - const int line, - const char *condition, - const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 4, 5))); -+void EXPORT_FUNC(grub_qdprintf) (const char *condition, -+ const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 2, 3))); - int EXPORT_FUNC(grub_vprintf) (const char *fmt, va_list args); - int EXPORT_FUNC(grub_snprintf) (char *str, grub_size_t n, const char *fmt, ...) - __attribute__ ((format (GNU_PRINTF, 3, 4))); diff --git a/0070-Make-a-gdb-dprintf-that-tells-us-load-addresses.patch b/0070-Make-a-gdb-dprintf-that-tells-us-load-addresses.patch deleted file mode 100644 index 75de764ad4103b03e338d9ec8baa9189668e285b..0000000000000000000000000000000000000000 --- a/0070-Make-a-gdb-dprintf-that-tells-us-load-addresses.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 25 Jun 2015 15:11:36 -0400 -Subject: [PATCH] Make a "gdb" dprintf that tells us load addresses. - -This makes a grub_dprintf() call during platform init and during module -loading that tells us the virtual addresses of the .text and .data -sections of grub-core/kernel.exec and any modules it loads. - -Specifically, it displays them in the gdb "add-symbol-file" syntax, with -the presumption that there's a variable $grubdir that reflects the path -to any such binaries. - -Signed-off-by: Peter Jones ---- - grub-core/kern/dl.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ - grub-core/kern/efi/efi.c | 4 ++-- - grub-core/kern/efi/init.c | 26 +++++++++++++++++++++++- - include/grub/efi/efi.h | 2 +- - 4 files changed, 78 insertions(+), 4 deletions(-) - -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index 88d2077709e..9557254035e 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -501,6 +501,23 @@ grub_dl_find_section (Elf_Ehdr *e, const char *name) - return s; - return NULL; - } -+static long -+grub_dl_find_section_index (Elf_Ehdr *e, const char *name) -+{ -+ Elf_Shdr *s; -+ const char *str; -+ unsigned i; -+ -+ s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize); -+ str = (char *) e + s->sh_offset; -+ -+ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); -+ i < e->e_shnum; -+ i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) -+ if (grub_strcmp (str + s->sh_name, name) == 0) -+ return (long)i; -+ return -1; -+} - - /* Me, Vladimir Serbinenko, hereby I add this module check as per new - GNU module policy. Note that this license check is informative only. -@@ -653,6 +670,37 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr) - - return GRUB_ERR_NONE; - } -+static void -+grub_dl_print_gdb_info (grub_dl_t mod, Elf_Ehdr *e) -+{ -+ void *text, *data = NULL; -+ long idx; -+ -+ idx = grub_dl_find_section_index (e, ".text"); -+ if (idx < 0) -+ return; -+ -+ text = grub_dl_get_section_addr (mod, idx); -+ if (!text) -+ return; -+ -+ idx = grub_dl_find_section_index (e, ".data"); -+ if (idx >= 0) -+ data = grub_dl_get_section_addr (mod, idx); -+ -+ if (data) -+ grub_qdprintf ("gdb", "add-symbol-file \\\n" -+ "/usr/lib/debug/usr/lib/grub/%s-%s/%s.debug " -+ "\\\n %p -s .data %p\n", -+ GRUB_TARGET_CPU, GRUB_PLATFORM, -+ mod->name, text, data); -+ else -+ grub_qdprintf ("gdb", "add-symbol-file \\\n" -+ "/usr/lib/debug/usr/lib/grub/%s-%s/%s.debug " -+ "\\\n%p\n", -+ GRUB_TARGET_CPU, GRUB_PLATFORM, -+ mod->name, text); -+} - - /* Load a module from core memory. */ - grub_dl_t -@@ -712,6 +760,8 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) - grub_dprintf ("modules", "module name: %s\n", mod->name); - grub_dprintf ("modules", "init function: %p\n", mod->init); - -+ grub_dl_print_gdb_info (mod, e); -+ - if (grub_dl_add (mod)) - { - grub_dl_unload (mod); -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index ae9885edb84..d6a2fb57789 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -296,7 +296,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid, - /* Search the mods section from the PE32/PE32+ image. This code uses - a PE32 header, but should work with PE32+ as well. */ - grub_addr_t --grub_efi_modules_addr (void) -+grub_efi_section_addr (const char *section_name) - { - grub_efi_loaded_image_t *image; - struct grub_pe32_header *header; -@@ -321,7 +321,7 @@ grub_efi_modules_addr (void) - i < coff_header->num_sections; - i++, section++) - { -- if (grub_strcmp (section->name, "mods") == 0) -+ if (grub_strcmp (section->name, section_name) == 0) - break; - } - -diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c -index 6d39bd3ad29..2d12e6188fd 100644 ---- a/grub-core/kern/efi/init.c -+++ b/grub-core/kern/efi/init.c -@@ -115,10 +115,33 @@ grub_efi_env_init (void) - grub_free (envblk_s.buf); - } - -+static void -+grub_efi_print_gdb_info (void) -+{ -+ grub_addr_t text; -+ grub_addr_t data; -+ -+ text = grub_efi_section_addr (".text"); -+ if (!text) -+ return; -+ -+ data = grub_efi_section_addr (".data"); -+ if (data) -+ grub_qdprintf ("gdb", -+ "add-symbol-file /usr/lib/debug/usr/lib/grub/%s-%s/" -+ "kernel.exec %p -s .data %p\n", -+ GRUB_TARGET_CPU, GRUB_PLATFORM, (void *)text, (void *)data); -+ else -+ grub_qdprintf ("gdb", -+ "add-symbol-file /usr/lib/debug/usr/lib/grub/%s-%s/" -+ "kernel.exec %p\n", -+ GRUB_TARGET_CPU, GRUB_PLATFORM, (void *)text); -+} -+ - void - grub_efi_init (void) - { -- grub_modbase = grub_efi_modules_addr (); -+ grub_modbase = grub_efi_section_addr ("mods"); - /* First of all, initialize the console so that GRUB can display - messages. */ - grub_console_init (); -@@ -142,6 +165,7 @@ grub_efi_init (void) - 0, 0, 0, NULL); - - grub_efi_env_init (); -+ grub_efi_print_gdb_info (); - grub_efidisk_init (); - } - -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 03f9a9d0118..2e0691454b1 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -138,7 +138,7 @@ grub_err_t grub_arch_efi_linux_check_image(struct linux_arch_kernel_header *lh); - grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, char *args); - #endif - --grub_addr_t grub_efi_modules_addr (void); -+grub_addr_t grub_efi_section_addr (const char *section); - - void grub_efi_mm_init (void); - void grub_efi_mm_fini (void); diff --git a/0071-Fixup-for-newer-compiler.patch b/0071-Fixup-for-newer-compiler.patch deleted file mode 100644 index 12dd193e612d4eb766eca7f309ad1f8234db1a1d..0000000000000000000000000000000000000000 --- a/0071-Fixup-for-newer-compiler.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 10 May 2018 13:40:19 -0400 -Subject: [PATCH] Fixup for newer compiler - ---- - grub-core/fs/btrfs.c | 2 +- - include/grub/gpt_partition.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 2b21cbaa67e..4cc86e9b79e 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -218,7 +218,7 @@ struct grub_btrfs_inode - grub_uint64_t size; - grub_uint8_t dummy2[0x70]; - struct grub_btrfs_time mtime; --} GRUB_PACKED; -+} GRUB_PACKED __attribute__ ((aligned(8))); - - struct grub_btrfs_extent_data - { -diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h -index 7a93f43291c..8212697bf6b 100644 ---- a/include/grub/gpt_partition.h -+++ b/include/grub/gpt_partition.h -@@ -76,7 +76,7 @@ struct grub_gpt_partentry - grub_uint64_t end; - grub_uint64_t attrib; - char name[72]; --} GRUB_PACKED; -+} GRUB_PACKED __attribute__ ((aligned(8))); - - grub_err_t - grub_gpt_partition_map_iterate (grub_disk_t disk, diff --git a/0072-Don-t-attempt-to-export-the-start-and-_start-symbols.patch b/0072-Don-t-attempt-to-export-the-start-and-_start-symbols.patch deleted file mode 100644 index 0e925eef827e59cf9bd0f20211e89a626925b4f4..0000000000000000000000000000000000000000 --- a/0072-Don-t-attempt-to-export-the-start-and-_start-symbols.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Sat, 12 May 2018 11:29:07 +0200 -Subject: [PATCH] Don't attempt to export the start and _start symbols for - grub-emu - -Commit 318ee04aadc ("make better backtraces") reworked the backtrace logic -but the changes lead to the following build error on the grub-emu platform: - -grub_emu_lite-symlist.o:(.data+0xf08): undefined reference to `start' -collect2: error: ld returned 1 exit status -make[3]: *** [Makefile:25959: grub-emu-lite] Error 1 -make[3]: *** Waiting for unfinished jobs.... -cat kernel_syms.input | grep -v '^#' | sed -n \ - -e '/EXPORT_FUNC *([a-zA-Z0-9_]*)/{s/.*EXPORT_FUNC *(\([a-zA-Z0-9_]*\)).*/defined kernel '""'\1/;p;}' \ - -e '/EXPORT_VAR *([a-zA-Z0-9_]*)/{s/.*EXPORT_VAR *(\([a-zA-Z0-9_]*\)).*/defined kernel '""'\1/;p;}' \ - | sort -u >kernel_syms.lst - -The problem is that start and _start symbols are exported unconditionally, -but these aren't defined for grub-emu since is an emultaed platform so it -doesn't have a startup logic. Don't attempt to export those for grub-emu. - -Signed-off-by: Javier Martinez Canillas ---- - include/grub/kernel.h | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/include/grub/kernel.h b/include/grub/kernel.h -index 300a9766cda..55849777eaa 100644 ---- a/include/grub/kernel.h -+++ b/include/grub/kernel.h -@@ -111,8 +111,10 @@ grub_addr_t grub_modules_get_end (void); - - #endif - -+#if !defined(GRUB_MACHINE_EMU) - void EXPORT_FUNC(start) (void); - void EXPORT_FUNC(_start) (void); -+#endif - - /* The start point of the C code. */ - void grub_main (void) __attribute__ ((noreturn)); diff --git a/0073-Fixup-for-newer-compiler.patch b/0073-Fixup-for-newer-compiler.patch deleted file mode 100644 index 11ed6e52167e392c7d228ebf360e186ed7f5eb7f..0000000000000000000000000000000000000000 --- a/0073-Fixup-for-newer-compiler.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 10 May 2018 13:40:19 -0400 -Subject: [PATCH] Fixup for newer compiler - ---- - conf/Makefile.common | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 191b1a70c6b..5f0ef969857 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -38,7 +38,7 @@ CFLAGS_KERNEL = $(CFLAGS_PLATFORM) -ffreestanding - LDFLAGS_KERNEL = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) - CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1 - CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) --STRIPFLAGS_KERNEL = -R .eh_frame -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx -+STRIPFLAGS_KERNEL = -R .eh_frame -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx -R .note.gnu.property -R .gnu.build.attributes - - CFLAGS_MODULE = $(CFLAGS_PLATFORM) -ffreestanding - LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d diff --git a/0074-Add-support-for-non-Ethernet-network-cards.patch b/0074-Add-support-for-non-Ethernet-network-cards.patch deleted file mode 100644 index 02fb951f4750f649ad8dce02d39efa2df94b2df0..0000000000000000000000000000000000000000 --- a/0074-Add-support-for-non-Ethernet-network-cards.patch +++ /dev/null @@ -1,766 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Andrzej Kacprowski -Date: Wed, 10 Jul 2019 15:22:29 +0200 -Subject: [PATCH] Add support for non-Ethernet network cards - -This patch replaces fixed 6-byte link layer address with -up to 32-byte variable sized address. -This allows supporting Infiniband and Omni-Path fabric -which use 20-byte address, but other network card types -can also take advantage of this change. -The network card driver is responsible for replacing L2 -header provided by grub2 if needed. -This approach is compatible with UEFI network stack which -also allows up to 32-byte variable size link address. - -The BOOTP/DHCP packet format is limited to 16 byte client -hardware address, if link address is more that 16-bytes -then chaddr field in BOOTP it will be set to 0 as per rfc4390. - -Resolves: rhbz#1370642 - -Signed-off-by: Andrzej Kacprowski -[msalter: Fix max string calculation in grub_net_hwaddr_to_str] -Signed-off-by: Mark Salter ---- - grub-core/net/arp.c | 155 ++++++++++++++++++++++----------- - grub-core/net/bootp.c | 15 ++-- - grub-core/net/drivers/efi/efinet.c | 8 +- - grub-core/net/drivers/emu/emunet.c | 1 + - grub-core/net/drivers/i386/pc/pxe.c | 13 +-- - grub-core/net/drivers/ieee1275/ofnet.c | 2 + - grub-core/net/drivers/uboot/ubootnet.c | 1 + - grub-core/net/ethernet.c | 88 +++++++++---------- - grub-core/net/icmp6.c | 15 ++-- - grub-core/net/ip.c | 4 +- - grub-core/net/net.c | 50 ++++++----- - include/grub/net.h | 19 ++-- - 12 files changed, 219 insertions(+), 152 deletions(-) - -diff --git a/grub-core/net/arp.c b/grub-core/net/arp.c -index 54306e3b16d..67b409a8acc 100644 ---- a/grub-core/net/arp.c -+++ b/grub-core/net/arp.c -@@ -31,22 +31,12 @@ enum - ARP_REPLY = 2 - }; - --enum -- { -- /* IANA ARP constant to define hardware type as ethernet. */ -- GRUB_NET_ARPHRD_ETHERNET = 1 -- }; -- --struct arppkt { -+struct arphdr { - grub_uint16_t hrd; - grub_uint16_t pro; - grub_uint8_t hln; - grub_uint8_t pln; - grub_uint16_t op; -- grub_uint8_t sender_mac[6]; -- grub_uint32_t sender_ip; -- grub_uint8_t recv_mac[6]; -- grub_uint32_t recv_ip; - } GRUB_PACKED; - - static int have_pending; -@@ -57,12 +47,16 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf, - const grub_net_network_level_address_t *proto_addr) - { - struct grub_net_buff nb; -- struct arppkt *arp_packet; -+ struct arphdr *arp_header; - grub_net_link_level_address_t target_mac_addr; - grub_err_t err; - int i; - grub_uint8_t *nbd; - grub_uint8_t arp_data[128]; -+ grub_uint8_t hln; -+ grub_uint8_t pln; -+ grub_uint8_t arp_packet_len; -+ grub_uint8_t *tmp_ptr; - - if (proto_addr->type != GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4) - return grub_error (GRUB_ERR_BUG, "unsupported address family"); -@@ -73,23 +67,39 @@ grub_net_arp_send_request (struct grub_net_network_level_interface *inf, - grub_netbuff_clear (&nb); - grub_netbuff_reserve (&nb, 128); - -- err = grub_netbuff_push (&nb, sizeof (*arp_packet)); -+ hln = inf->card->default_address.len; -+ pln = sizeof (proto_addr->ipv4); -+ arp_packet_len = sizeof (*arp_header) + 2 * (hln + pln); -+ -+ err = grub_netbuff_push (&nb, arp_packet_len); - if (err) - return err; - -- arp_packet = (struct arppkt *) nb.data; -- arp_packet->hrd = grub_cpu_to_be16_compile_time (GRUB_NET_ARPHRD_ETHERNET); -- arp_packet->hln = 6; -- arp_packet->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP); -- arp_packet->pln = 4; -- arp_packet->op = grub_cpu_to_be16_compile_time (ARP_REQUEST); -- /* Sender hardware address. */ -- grub_memcpy (arp_packet->sender_mac, &inf->hwaddress.mac, 6); -- arp_packet->sender_ip = inf->address.ipv4; -- grub_memset (arp_packet->recv_mac, 0, 6); -- arp_packet->recv_ip = proto_addr->ipv4; -- /* Target protocol address */ -- grub_memset (&target_mac_addr.mac, 0xff, 6); -+ arp_header = (struct arphdr *) nb.data; -+ arp_header->hrd = grub_cpu_to_be16 (inf->card->default_address.type); -+ arp_header->hln = hln; -+ arp_header->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP); -+ arp_header->pln = pln; -+ arp_header->op = grub_cpu_to_be16_compile_time (ARP_REQUEST); -+ tmp_ptr = nb.data + sizeof (*arp_header); -+ -+ /* The source hardware address. */ -+ grub_memcpy (tmp_ptr, inf->hwaddress.mac, hln); -+ tmp_ptr += hln; -+ -+ /* The source protocol address. */ -+ grub_memcpy (tmp_ptr, &inf->address.ipv4, pln); -+ tmp_ptr += pln; -+ -+ /* The target hardware address. */ -+ grub_memset (tmp_ptr, 0, hln); -+ tmp_ptr += hln; -+ -+ /* The target protocol address */ -+ grub_memcpy (tmp_ptr, &proto_addr->ipv4, pln); -+ tmp_ptr += pln; -+ -+ grub_memset (&target_mac_addr.mac, 0xff, hln); - - nbd = nb.data; - send_ethernet_packet (inf, &nb, target_mac_addr, GRUB_NET_ETHERTYPE_ARP); -@@ -114,28 +124,53 @@ grub_err_t - grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, - grub_uint16_t *vlantag) - { -- struct arppkt *arp_packet = (struct arppkt *) nb->data; -+ struct arphdr *arp_header = (struct arphdr *) nb->data; - grub_net_network_level_address_t sender_addr, target_addr; - grub_net_link_level_address_t sender_mac_addr; - struct grub_net_network_level_interface *inf; -+ grub_uint16_t hw_type; -+ grub_uint8_t hln; -+ grub_uint8_t pln; -+ grub_uint8_t arp_packet_len; -+ grub_uint8_t *tmp_ptr; - -- if (arp_packet->pro != grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP) -- || arp_packet->pln != 4 || arp_packet->hln != 6 -- || nb->tail - nb->data < (int) sizeof (*arp_packet)) -+ hw_type = card->default_address.type; -+ hln = card->default_address.len; -+ pln = sizeof(sender_addr.ipv4); -+ arp_packet_len = sizeof (*arp_header) + 2 * (pln + hln); -+ -+ if (arp_header->pro != grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP) -+ || arp_header->hrd != grub_cpu_to_be16 (hw_type) -+ || arp_header->hln != hln || arp_header->pln != pln -+ || nb->tail - nb->data < (int) arp_packet_len) { - return GRUB_ERR_NONE; -+ } - -+ tmp_ptr = nb->data + sizeof (*arp_header); -+ -+ /* The source hardware address. */ -+ sender_mac_addr.type = hw_type; -+ sender_mac_addr.len = hln; -+ grub_memcpy (sender_mac_addr.mac, tmp_ptr, hln); -+ tmp_ptr += hln; -+ -+ /* The source protocol address. */ - sender_addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; -+ grub_memcpy(&sender_addr.ipv4, tmp_ptr, pln); -+ tmp_ptr += pln; -+ -+ grub_net_link_layer_add_address (card, &sender_addr, &sender_mac_addr, 1); -+ -+ /* The target hardware address. */ -+ tmp_ptr += hln; -+ -+ /* The target protocol address. */ - target_addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4; -- sender_addr.ipv4 = arp_packet->sender_ip; -- target_addr.ipv4 = arp_packet->recv_ip; -- if (arp_packet->sender_ip == pending_req) -+ grub_memcpy(&target_addr.ipv4, tmp_ptr, pln); -+ -+ if (sender_addr.ipv4 == pending_req) - have_pending = 1; - -- sender_mac_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (sender_mac_addr.mac, arp_packet->sender_mac, -- sizeof (sender_mac_addr.mac)); -- grub_net_link_layer_add_address (card, &sender_addr, &sender_mac_addr, 1); -- - FOR_NET_NETWORK_LEVEL_INTERFACES (inf) - { - /* Verify vlantag id */ -@@ -148,11 +183,11 @@ grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, - - /* Am I the protocol address target? */ - if (grub_net_addr_cmp (&inf->address, &target_addr) == 0 -- && arp_packet->op == grub_cpu_to_be16_compile_time (ARP_REQUEST)) -+ && arp_header->op == grub_cpu_to_be16_compile_time (ARP_REQUEST)) - { - grub_net_link_level_address_t target; - struct grub_net_buff nb_reply; -- struct arppkt *arp_reply; -+ struct arphdr *arp_reply; - grub_uint8_t arp_data[128]; - grub_err_t err; - -@@ -161,25 +196,39 @@ grub_net_arp_receive (struct grub_net_buff *nb, struct grub_net_card *card, - grub_netbuff_clear (&nb_reply); - grub_netbuff_reserve (&nb_reply, 128); - -- err = grub_netbuff_push (&nb_reply, sizeof (*arp_packet)); -+ err = grub_netbuff_push (&nb_reply, arp_packet_len); - if (err) - return err; - -- arp_reply = (struct arppkt *) nb_reply.data; -+ arp_reply = (struct arphdr *) nb_reply.data; - -- arp_reply->hrd = grub_cpu_to_be16_compile_time (GRUB_NET_ARPHRD_ETHERNET); -+ arp_reply->hrd = grub_cpu_to_be16 (hw_type); - arp_reply->pro = grub_cpu_to_be16_compile_time (GRUB_NET_ETHERTYPE_IP); -- arp_reply->pln = 4; -- arp_reply->hln = 6; -+ arp_reply->pln = pln; -+ arp_reply->hln = hln; - arp_reply->op = grub_cpu_to_be16_compile_time (ARP_REPLY); -- arp_reply->sender_ip = arp_packet->recv_ip; -- arp_reply->recv_ip = arp_packet->sender_ip; -- arp_reply->hln = 6; -- -- target.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (target.mac, arp_packet->sender_mac, 6); -- grub_memcpy (arp_reply->sender_mac, inf->hwaddress.mac, 6); -- grub_memcpy (arp_reply->recv_mac, arp_packet->sender_mac, 6); -+ -+ tmp_ptr = nb_reply.data + sizeof (*arp_reply); -+ -+ /* The source hardware address. */ -+ grub_memcpy (tmp_ptr, inf->hwaddress.mac, hln); -+ tmp_ptr += hln; -+ -+ /* The source protocol address. */ -+ grub_memcpy (tmp_ptr, &target_addr.ipv4, pln); -+ tmp_ptr += pln; -+ -+ /* The target hardware address. */ -+ grub_memcpy (tmp_ptr, sender_mac_addr.mac, hln); -+ tmp_ptr += hln; -+ -+ /* The target protocol address */ -+ grub_memcpy (tmp_ptr, &sender_addr.ipv4, pln); -+ tmp_ptr += pln; -+ -+ target.type = hw_type; -+ target.len = hln; -+ grub_memcpy (target.mac, sender_mac_addr.mac, hln); - - /* Change operation to REPLY and send packet */ - send_ethernet_packet (inf, &nb_reply, target, GRUB_NET_ETHERTYPE_ARP); -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index e28fb6a09f9..08b6b2b5d6c 100644 ---- a/grub-core/net/bootp.c -+++ b/grub-core/net/bootp.c -@@ -233,7 +233,6 @@ grub_net_configure_by_dhcp_ack (const char *name, - int is_def, char **device, char **path) - { - grub_net_network_level_address_t addr; -- grub_net_link_level_address_t hwaddr; - struct grub_net_network_level_interface *inter; - int mask = -1; - char server_ip[sizeof ("xxx.xxx.xxx.xxx")]; -@@ -250,12 +249,8 @@ grub_net_configure_by_dhcp_ack (const char *name, - if (path) - *path = 0; - -- grub_memcpy (hwaddr.mac, bp->mac_addr, -- bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len -- : sizeof (hwaddr.mac)); -- hwaddr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- -- inter = grub_net_add_addr (name, card, &addr, &hwaddr, flags); -+ grub_dprintf("dhcp", "configuring dhcp for %s\n", name); -+ inter = grub_net_add_addr (name, card, &addr, &card->default_address, flags); - if (!inter) - return 0; - -@@ -567,7 +562,9 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface) - grub_memset (pack, 0, sizeof (*pack)); - pack->opcode = 1; - pack->hw_type = 1; -- pack->hw_len = 6; -+ pack->hw_len = iface->hwaddress.len > 16 ? 0 -+ : iface->hwaddress.len; -+ - err = grub_get_datetime (&date); - if (err || !grub_datetime2unixtime (&date, &t)) - { -@@ -580,7 +577,7 @@ send_dhcp_packet (struct grub_net_network_level_interface *iface) - else - pack->ident = iface->xid; - -- grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, 6); -+ grub_memcpy (&pack->mac_addr, &iface->hwaddress.mac, pack->hw_len); - - grub_netbuff_push (nb, sizeof (*udph)); - -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index 173fb63153c..a673bea807a 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -279,6 +279,9 @@ grub_efinet_findcards (void) - /* This should not happen... Why? */ - continue; - -+ if (net->mode->hwaddr_size > GRUB_NET_MAX_LINK_ADDRESS_SIZE) -+ continue; -+ - if (net->mode->state == GRUB_EFI_NETWORK_STOPPED - && efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS) - continue; -@@ -315,10 +318,11 @@ grub_efinet_findcards (void) - card->name = grub_xasprintf ("efinet%d", i++); - card->driver = &efidriver; - card->flags = 0; -- card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -+ card->default_address.type = net->mode->if_type; -+ card->default_address.len = net->mode->hwaddr_size; - grub_memcpy (card->default_address.mac, - net->mode->current_address, -- sizeof (card->default_address.mac)); -+ net->mode->hwaddr_size); - card->efi_net = net; - card->efi_handle = *handle; - -diff --git a/grub-core/net/drivers/emu/emunet.c b/grub-core/net/drivers/emu/emunet.c -index b194920861f..5b6c5e16a6d 100644 ---- a/grub-core/net/drivers/emu/emunet.c -+++ b/grub-core/net/drivers/emu/emunet.c -@@ -46,6 +46,7 @@ static struct grub_net_card emucard = - .mtu = 1500, - .default_address = { - .type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET, -+ . len = 6, - {.mac = {0, 1, 2, 3, 4, 5}} - }, - .flags = 0 -diff --git a/grub-core/net/drivers/i386/pc/pxe.c b/grub-core/net/drivers/i386/pc/pxe.c -index 3f4152d036c..9f8fb4b6d2b 100644 ---- a/grub-core/net/drivers/i386/pc/pxe.c -+++ b/grub-core/net/drivers/i386/pc/pxe.c -@@ -386,20 +386,21 @@ GRUB_MOD_INIT(pxe) - grub_memset (ui, 0, sizeof (*ui)); - grub_pxe_call (GRUB_PXENV_UNDI_GET_INFORMATION, ui, pxe_rm_entry); - -+ grub_pxe_card.default_address.len = 6; - grub_memcpy (grub_pxe_card.default_address.mac, ui->current_addr, -- sizeof (grub_pxe_card.default_address.mac)); -- for (i = 0; i < sizeof (grub_pxe_card.default_address.mac); i++) -+ grub_pxe_card.default_address.len); -+ for (i = 0; i < grub_pxe_card.default_address.len; i++) - if (grub_pxe_card.default_address.mac[i] != 0) - break; -- if (i != sizeof (grub_pxe_card.default_address.mac)) -+ if (i != grub_pxe_card.default_address.len) - { -- for (i = 0; i < sizeof (grub_pxe_card.default_address.mac); i++) -+ for (i = 0; i < grub_pxe_card.default_address.len; i++) - if (grub_pxe_card.default_address.mac[i] != 0xff) - break; - } -- if (i == sizeof (grub_pxe_card.default_address.mac)) -+ if (i == grub_pxe_card.default_address.len) - grub_memcpy (grub_pxe_card.default_address.mac, ui->permanent_addr, -- sizeof (grub_pxe_card.default_address.mac)); -+ grub_pxe_card.default_address.len); - grub_pxe_card.mtu = ui->mtu; - - grub_pxe_card.default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c -index 3860b6f78d8..bcb3f9ea02d 100644 ---- a/grub-core/net/drivers/ieee1275/ofnet.c -+++ b/grub-core/net/drivers/ieee1275/ofnet.c -@@ -160,6 +160,7 @@ grub_ieee1275_parse_bootpath (const char *devpath, char *bootpath, - grub_uint16_t vlantag = 0; - - hw_addr.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -+ hw_addr.len = 6; - - args = bootpath + grub_strlen (devpath) + 1; - do -@@ -503,6 +504,7 @@ search_net_devices (struct grub_ieee1275_devalias *alias) - grub_memcpy (&lla.mac, pprop, 6); - - lla.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -+ lla.len = 6; - card->default_address = lla; - - card->txbufsize = ALIGN_UP (card->mtu, 64) + 256; -diff --git a/grub-core/net/drivers/uboot/ubootnet.c b/grub-core/net/drivers/uboot/ubootnet.c -index 056052e40d5..22ebcbf211e 100644 ---- a/grub-core/net/drivers/uboot/ubootnet.c -+++ b/grub-core/net/drivers/uboot/ubootnet.c -@@ -131,6 +131,7 @@ GRUB_MOD_INIT (ubootnet) - - grub_memcpy (&(card->default_address.mac), &devinfo->di_net.hwaddr, 6); - card->default_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -+ card->default_address.len = 6; - - card->txbufsize = ALIGN_UP (card->mtu, 64) + 256; - card->txbuf = grub_zalloc (card->txbufsize); -diff --git a/grub-core/net/ethernet.c b/grub-core/net/ethernet.c -index 4d7ceed6f93..9aae83a5eb4 100644 ---- a/grub-core/net/ethernet.c -+++ b/grub-core/net/ethernet.c -@@ -29,13 +29,6 @@ - - #define LLCADDRMASK 0x7f - --struct etherhdr --{ -- grub_uint8_t dst[6]; -- grub_uint8_t src[6]; -- grub_uint16_t type; --} GRUB_PACKED; -- - struct llchdr - { - grub_uint8_t dsap; -@@ -55,13 +48,15 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, - grub_net_link_level_address_t target_addr, - grub_net_ethertype_t ethertype) - { -- struct etherhdr *eth; -+ grub_uint8_t *eth; - grub_err_t err; -- grub_uint8_t etherhdr_size; -- grub_uint16_t vlantag_id = VLANTAG_IDENTIFIER; -+ grub_uint32_t vlantag = 0; -+ grub_uint8_t hw_addr_len = inf->card->default_address.len; -+ grub_uint8_t etherhdr_size = 2 * hw_addr_len + 2; - -- etherhdr_size = sizeof (*eth); -- COMPILE_TIME_ASSERT (sizeof (*eth) + 4 < GRUB_NET_MAX_LINK_HEADER_SIZE); -+ /* Source and destination link addresses + ethertype + vlan tag */ -+ COMPILE_TIME_ASSERT ((GRUB_NET_MAX_LINK_ADDRESS_SIZE * 2 + 2 + 4) < -+ GRUB_NET_MAX_LINK_HEADER_SIZE); - - /* Increase ethernet header in case of vlantag */ - if (inf->vlantag != 0) -@@ -70,11 +65,22 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, - err = grub_netbuff_push (nb, etherhdr_size); - if (err) - return err; -- eth = (struct etherhdr *) nb->data; -- grub_memcpy (eth->dst, target_addr.mac, 6); -- grub_memcpy (eth->src, inf->hwaddress.mac, 6); -+ eth = nb->data; -+ grub_memcpy (eth, target_addr.mac, hw_addr_len); -+ eth += hw_addr_len; -+ grub_memcpy (eth, inf->hwaddress.mac, hw_addr_len); -+ eth += hw_addr_len; -+ -+ /* Check if a vlan-tag is present. */ -+ if (vlantag != 0) -+ { -+ *((grub_uint32_t *)eth) = grub_cpu_to_be32 (vlantag); -+ eth += sizeof (vlantag); -+ } -+ -+ /* Write ethertype */ -+ *((grub_uint16_t*) eth) = grub_cpu_to_be16 (ethertype); - -- eth->type = grub_cpu_to_be16 (ethertype); - if (!inf->card->opened) - { - err = GRUB_ERR_NONE; -@@ -85,18 +91,6 @@ send_ethernet_packet (struct grub_net_network_level_interface *inf, - inf->card->opened = 1; - } - -- /* Check and add a vlan-tag if needed. */ -- if (inf->vlantag != 0) -- { -- /* Move eth type to the right */ -- grub_memcpy ((char *) nb->data + etherhdr_size - 2, -- (char *) nb->data + etherhdr_size - 6, 2); -- -- /* Add the tag in the middle */ -- grub_memcpy ((char *) nb->data + etherhdr_size - 6, &vlantag_id, 2); -- grub_memcpy ((char *) nb->data + etherhdr_size - 4, (char *) &(inf->vlantag), 2); -- } -- - return inf->card->driver->send (inf->card, nb); - } - -@@ -104,31 +98,40 @@ grub_err_t - grub_net_recv_ethernet_packet (struct grub_net_buff *nb, - struct grub_net_card *card) - { -- struct etherhdr *eth; -+ grub_uint8_t *eth; - struct llchdr *llch; - struct snaphdr *snaph; - grub_net_ethertype_t type; - grub_net_link_level_address_t hwaddress; - grub_net_link_level_address_t src_hwaddress; - grub_err_t err; -- grub_uint8_t etherhdr_size = sizeof (*eth); -+ grub_uint8_t hw_addr_len = card->default_address.len; -+ grub_uint8_t etherhdr_size = 2 * hw_addr_len + 2; - grub_uint16_t vlantag = 0; - -+ eth = nb->data; - -- /* Check if a vlan-tag is present. If so, the ethernet header is 4 bytes */ -- /* longer than the original one. The vlantag id is extracted and the header */ -- /* is reseted to the original size. */ -- if (grub_get_unaligned16 (nb->data + etherhdr_size - 2) == VLANTAG_IDENTIFIER) -+ hwaddress.type = card->default_address.type; -+ hwaddress.len = hw_addr_len; -+ grub_memcpy (hwaddress.mac, eth, hw_addr_len); -+ eth += hw_addr_len; -+ -+ src_hwaddress.type = card->default_address.type; -+ src_hwaddress.len = hw_addr_len; -+ grub_memcpy (src_hwaddress.mac, eth, hw_addr_len); -+ eth += hw_addr_len; -+ -+ type = grub_be_to_cpu16 (*(grub_uint16_t*)(eth)); -+ if (type == VLANTAG_IDENTIFIER) - { -- vlantag = grub_get_unaligned16 (nb->data + etherhdr_size); -+ /* Skip vlan tag */ -+ eth += 2; -+ vlantag = grub_be_to_cpu16 (*(grub_uint16_t*)(eth)); - etherhdr_size += 4; -- /* Move eth type to the original position */ -- grub_memcpy((char *) nb->data + etherhdr_size - 6, -- (char *) nb->data + etherhdr_size - 2, 2); -+ eth += 2; -+ type = grub_be_to_cpu16 (*(grub_uint16_t*)(eth)); - } - -- eth = (struct etherhdr *) nb->data; -- type = grub_be_to_cpu16 (eth->type); - err = grub_netbuff_pull (nb, etherhdr_size); - if (err) - return err; -@@ -148,11 +151,6 @@ grub_net_recv_ethernet_packet (struct grub_net_buff *nb, - } - } - -- hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (hwaddress.mac, eth->dst, sizeof (hwaddress.mac)); -- src_hwaddress.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (src_hwaddress.mac, eth->src, sizeof (src_hwaddress.mac)); -- - switch (type) - { - /* ARP packet. */ -diff --git a/grub-core/net/icmp6.c b/grub-core/net/icmp6.c -index 2cbd95dce25..56a3ec5c8e8 100644 ---- a/grub-core/net/icmp6.c -+++ b/grub-core/net/icmp6.c -@@ -231,8 +231,9 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, - && ohdr->len == 1) - { - grub_net_link_level_address_t ll_address; -- ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac)); -+ ll_address.type = card->default_address.type; -+ ll_address.len = card->default_address.len; -+ grub_memcpy (ll_address.mac, ohdr + 1, ll_address.len); - grub_net_link_layer_add_address (card, source, &ll_address, 0); - } - } -@@ -335,8 +336,9 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, - && ohdr->len == 1) - { - grub_net_link_level_address_t ll_address; -- ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac)); -+ ll_address.type = card->default_address.type; -+ ll_address.len = card->default_address.len; -+ grub_memcpy (ll_address.mac, ohdr + 1, ll_address.len); - grub_net_link_layer_add_address (card, source, &ll_address, 0); - } - } -@@ -384,8 +386,9 @@ grub_net_recv_icmp6_packet (struct grub_net_buff *nb, - && ohdr->len == 1) - { - grub_net_link_level_address_t ll_address; -- ll_address.type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memcpy (ll_address.mac, ohdr + 1, sizeof (ll_address.mac)); -+ ll_address.type = card->default_address.type; -+ ll_address.len = card->default_address.len; -+ grub_memcpy (ll_address.mac, ohdr + 1, ll_address.len); - grub_net_link_layer_add_address (card, source, &ll_address, 0); - } - if (ohdr->type == OPTION_PREFIX && ohdr->len == 4) -diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c -index ea5edf8f1f6..a5896f6dc26 100644 ---- a/grub-core/net/ip.c -+++ b/grub-core/net/ip.c -@@ -276,8 +276,8 @@ handle_dgram (struct grub_net_buff *nb, - if (inf->card == card - && inf->address.type == GRUB_NET_NETWORK_LEVEL_PROTOCOL_DHCP_RECV - && inf->hwaddress.type == GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET -- && grub_memcmp (inf->hwaddress.mac, &bootp->mac_addr, -- sizeof (inf->hwaddress.mac)) == 0) -+ && (grub_memcmp (inf->hwaddress.mac, &bootp->mac_addr, -+ bootp->hw_len) == 0 || bootp->hw_len == 0)) - { - grub_net_process_dhcp (nb, inf); - grub_netbuff_free (nb); -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 22f2689aaeb..a46f82362ed 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -133,8 +133,9 @@ grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf, - << 48) - && proto_addr->ipv6[1] == (grub_be_to_cpu64_compile_time (1)))) - { -- hw_addr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -- grub_memset (hw_addr->mac, -1, 6); -+ hw_addr->type = inf->card->default_address.type; -+ hw_addr->len = inf->card->default_address.len; -+ grub_memset (hw_addr->mac, -1, hw_addr->len); - return GRUB_ERR_NONE; - } - -@@ -142,6 +143,7 @@ grub_net_link_layer_resolve (struct grub_net_network_level_interface *inf, - && ((grub_be_to_cpu64 (proto_addr->ipv6[0]) >> 56) == 0xff)) - { - hw_addr->type = GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET; -+ hw_addr->len = inf->card->default_address.len; - hw_addr->mac[0] = 0x33; - hw_addr->mac[1] = 0x33; - hw_addr->mac[2] = ((grub_be_to_cpu64 (proto_addr->ipv6[1]) >> 24) & 0xff); -@@ -762,23 +764,23 @@ grub_net_addr_to_str (const grub_net_network_level_address_t *target, char *buf) - void - grub_net_hwaddr_to_str (const grub_net_link_level_address_t *addr, char *str) - { -- str[0] = 0; -- switch (addr->type) -+ char *ptr; -+ unsigned i; -+ int maxstr; -+ -+ if (addr->len > GRUB_NET_MAX_LINK_ADDRESS_SIZE) - { -- case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET: -- { -- char *ptr; -- unsigned i; -- for (ptr = str, i = 0; i < ARRAY_SIZE (addr->mac); i++) -- { -- grub_snprintf (ptr, GRUB_NET_MAX_STR_HWADDR_LEN - (ptr - str), -- "%02x:", addr->mac[i] & 0xff); -- ptr += (sizeof ("XX:") - 1); -- } -- return; -- } -+ str[0] = 0; -+ grub_printf (_("Unsupported hw address type %d len %d\n"), -+ addr->type, addr->len); -+ return; -+ } -+ maxstr = addr->len * grub_strlen ("XX:"); -+ for (ptr = str, i = 0; i < addr->len; i++) -+ { -+ ptr += grub_snprintf (ptr, maxstr - (ptr - str), -+ "%02x:", addr->mac[i] & 0xff); - } -- grub_printf (_("Unsupported hw address type %d\n"), addr->type); - } - - int -@@ -789,13 +791,17 @@ grub_net_hwaddr_cmp (const grub_net_link_level_address_t *a, - return -1; - if (a->type > b->type) - return +1; -- switch (a->type) -+ if (a->len < b->len) -+ return -1; -+ if (a->len > b->len) -+ return +1; -+ if (a->len > GRUB_NET_MAX_LINK_ADDRESS_SIZE) - { -- case GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET: -- return grub_memcmp (a->mac, b->mac, sizeof (a->mac)); -+ grub_printf (_("Unsupported hw address type %d len %d\n"), -+ a->type, a->len); -+ return + 1; - } -- grub_printf (_("Unsupported hw address type %d\n"), a->type); -- return 1; -+ return grub_memcmp (a->mac, b->mac, a->len); - } - - int -diff --git a/include/grub/net.h b/include/grub/net.h -index 8a05ec4fe7a..af0404db7e3 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -29,7 +29,8 @@ - - enum - { -- GRUB_NET_MAX_LINK_HEADER_SIZE = 64, -+ GRUB_NET_MAX_LINK_HEADER_SIZE = 96, -+ GRUB_NET_MAX_LINK_ADDRESS_SIZE = 32, - GRUB_NET_UDP_HEADER_SIZE = 8, - GRUB_NET_TCP_HEADER_SIZE = 20, - GRUB_NET_OUR_IPV4_HEADER_SIZE = 20, -@@ -42,15 +43,17 @@ enum - - typedef enum grub_link_level_protocol_id - { -- GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET -+ /* IANA ARP constant to define hardware type. */ -+ GRUB_NET_LINK_LEVEL_PROTOCOL_ETHERNET = 1, - } grub_link_level_protocol_id_t; - - typedef struct grub_net_link_level_address - { - grub_link_level_protocol_id_t type; -+ grub_uint8_t len; - union - { -- grub_uint8_t mac[6]; -+ grub_uint8_t mac[GRUB_NET_MAX_LINK_ADDRESS_SIZE]; - }; - } grub_net_link_level_address_t; - -@@ -566,11 +569,13 @@ grub_net_addr_cmp (const grub_net_network_level_address_t *a, - #define GRUB_NET_MAX_STR_ADDR_LEN sizeof ("XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX") - - /* -- Currently suppoerted adresses: -- ethernet: XX:XX:XX:XX:XX:XX -+ Up to 32 byte hardware address supported, see GRUB_NET_MAX_LINK_ADDRESS_SIZE - */ -- --#define GRUB_NET_MAX_STR_HWADDR_LEN (sizeof ("XX:XX:XX:XX:XX:XX")) -+#define GRUB_NET_MAX_STR_HWADDR_LEN (sizeof (\ -+ "XX:XX:XX:XX:XX:XX:XX:XX:"\ -+ "XX:XX:XX:XX:XX:XX:XX:XX:"\ -+ "XX:XX:XX:XX:XX:XX:XX:XX:"\ -+ "XX:XX:XX:XX:XX:XX:XX:XX")) - - void - grub_net_addr_to_str (const grub_net_network_level_address_t *target, diff --git a/0075-net-read-bracketed-ipv6-addrs-and-port-numbers.patch b/0075-net-read-bracketed-ipv6-addrs-and-port-numbers.patch deleted file mode 100644 index 834b96e28a7c14d92f80c7258b9a17cbb5b983cd..0000000000000000000000000000000000000000 --- a/0075-net-read-bracketed-ipv6-addrs-and-port-numbers.patch +++ /dev/null @@ -1,270 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Aaron Miller -Date: Fri, 29 Jul 2016 17:41:38 +0800 -Subject: [PATCH] net: read bracketed ipv6 addrs and port numbers - -Allow specifying port numbers for http and tftp paths, and allow ipv6 addresses -to be recognized with brackets around them, which is required to specify a port -number - -Signed-off-by: Aaron Miller -[pjones: various bug fixes] -Signed-off-by: Peter Jones ---- - grub-core/net/http.c | 25 ++++++++++++--- - grub-core/net/net.c | 87 +++++++++++++++++++++++++++++++++++++++++++++++++--- - grub-core/net/tftp.c | 8 +++-- - include/grub/net.h | 1 + - 4 files changed, 109 insertions(+), 12 deletions(-) - -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index b616cf40b1e..12a2632ea55 100644 ---- a/grub-core/net/http.c -+++ b/grub-core/net/http.c -@@ -289,7 +289,9 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)), - nb2 = grub_netbuff_alloc (data->chunk_rem); - if (!nb2) - return grub_errno; -- grub_netbuff_put (nb2, data->chunk_rem); -+ err = grub_netbuff_put (nb2, data->chunk_rem); -+ if (err) -+ return grub_errno; - grub_memcpy (nb2->data, nb->data, data->chunk_rem); - if (file->device->net->packs.count >= 20) - { -@@ -312,12 +314,14 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - int i; - struct grub_net_buff *nb; - grub_err_t err; -+ char* server = file->device->net->server; -+ int port = file->device->net->port; - - nb = grub_netbuff_alloc (GRUB_NET_TCP_RESERVE_SIZE - + sizeof ("GET ") - 1 - + grub_strlen (data->filename) - + sizeof (" HTTP/1.1\r\nHost: ") - 1 -- + grub_strlen (file->device->net->server) -+ + grub_strlen (server) + sizeof (":XXXXXXXXXX") - + sizeof ("\r\nUser-Agent: " PACKAGE_STRING - "\r\n") - 1 - + sizeof ("Range: bytes=XXXXXXXXXXXXXXXXXXXX" -@@ -356,7 +360,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - sizeof (" HTTP/1.1\r\nHost: ") - 1); - - ptr = nb->tail; -- err = grub_netbuff_put (nb, grub_strlen (file->device->net->server)); -+ err = grub_netbuff_put (nb, grub_strlen (server)); - if (err) - { - grub_netbuff_free (nb); -@@ -365,6 +369,15 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - grub_memcpy (ptr, file->device->net->server, - grub_strlen (file->device->net->server)); - -+ if (port) -+ { -+ ptr = nb->tail; -+ grub_snprintf ((char *) ptr, -+ sizeof (":XXXXXXXXXX"), -+ ":%d", -+ port); -+ } -+ - ptr = nb->tail; - err = grub_netbuff_put (nb, - sizeof ("\r\nUser-Agent: " PACKAGE_STRING "\r\n") -@@ -390,8 +403,10 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - grub_netbuff_put (nb, 2); - grub_memcpy (ptr, "\r\n", 2); - -- data->sock = grub_net_tcp_open (file->device->net->server, -- HTTP_PORT, http_receive, -+ grub_dprintf ("http", "opening path %s on host %s TCP port %d\n", -+ data->filename, server, port ? port : HTTP_PORT); -+ data->sock = grub_net_tcp_open (server, -+ port ? port : HTTP_PORT, http_receive, - http_err, NULL, - file); - if (!data->sock) -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index a46f82362ed..0ce5e675ed7 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -444,6 +444,13 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest) - grub_uint16_t newip[8]; - const char *ptr = val; - int word, quaddot = -1; -+ int bracketed = 0; -+ -+ if (ptr[0] == '[') -+ { -+ bracketed = 1; -+ ptr++; -+ } - - if (ptr[0] == ':' && ptr[1] != ':') - return 0; -@@ -482,6 +489,8 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest) - grub_memset (&newip[quaddot], 0, (7 - word) * sizeof (newip[0])); - } - grub_memcpy (ip, newip, 16); -+ if (bracketed && *ptr == ']') -+ ptr++; - if (rest) - *rest = ptr; - return 1; -@@ -1343,8 +1352,10 @@ grub_net_open_real (const char *name) - { - grub_net_app_level_t proto; - const char *protname, *server; -+ char *host; - grub_size_t protnamelen; - int try; -+ int port = 0; - - if (grub_strncmp (name, "pxe:", sizeof ("pxe:") - 1) == 0) - { -@@ -1382,6 +1393,72 @@ grub_net_open_real (const char *name) - return NULL; - } - -+ char* port_start; -+ /* ipv6 or port specified? */ -+ if ((port_start = grub_strchr (server, ':'))) -+ { -+ char* ipv6_begin; -+ if((ipv6_begin = grub_strchr (server, '['))) -+ { -+ char* ipv6_end = grub_strchr (server, ']'); -+ if(!ipv6_end) -+ { -+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, -+ N_("mismatched [ in address")); -+ return NULL; -+ } -+ /* port number after bracketed ipv6 addr */ -+ if(ipv6_end[1] == ':') -+ { -+ port = grub_strtoul (ipv6_end + 2, NULL, 10); -+ if(port > 65535) -+ { -+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, -+ N_("bad port number")); -+ return NULL; -+ } -+ } -+ host = grub_strndup (ipv6_begin, (ipv6_end - ipv6_begin) + 1); -+ } -+ else -+ { -+ if (grub_strchr (port_start + 1, ':')) -+ { -+ int iplen = grub_strlen (server); -+ /* bracket bare ipv6 addrs */ -+ host = grub_malloc (iplen + 3); -+ if(!host) -+ { -+ return NULL; -+ } -+ host[0] = '['; -+ grub_memcpy (host + 1, server, iplen); -+ host[iplen + 1] = ']'; -+ host[iplen + 2] = '\0'; -+ } -+ else -+ { -+ /* hostname:port or ipv4:port */ -+ port = grub_strtol (port_start + 1, NULL, 10); -+ if(port > 65535) -+ { -+ grub_error (GRUB_ERR_NET_BAD_ADDRESS, -+ N_("bad port number")); -+ return NULL; -+ } -+ host = grub_strndup (server, port_start - server); -+ } -+ } -+ } -+ else -+ { -+ host = grub_strdup (server); -+ } -+ if (!host) -+ { -+ return NULL; -+ } -+ - for (try = 0; try < 2; try++) - { - FOR_NET_APP_LEVEL (proto) -@@ -1391,14 +1468,13 @@ grub_net_open_real (const char *name) - { - grub_net_t ret = grub_zalloc (sizeof (*ret)); - if (!ret) -- return NULL; -- ret->protocol = proto; -- ret->server = grub_strdup (server); -- if (!ret->server) - { -- grub_free (ret); -+ grub_free (host); - return NULL; - } -+ ret->protocol = proto; -+ ret->port = port; -+ ret->server = host; - ret->fs = &grub_net_fs; - return ret; - } -@@ -1473,6 +1549,7 @@ grub_net_open_real (const char *name) - grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' not found"), - name); - -+ grub_free (host); - return NULL; - } - -diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c -index 4ab2f5c7357..d54b13f09ff 100644 ---- a/grub-core/net/tftp.c -+++ b/grub-core/net/tftp.c -@@ -295,6 +295,7 @@ tftp_open (struct grub_file *file, const char *filename) - grub_err_t err; - grub_uint8_t *nbd; - grub_net_network_level_address_t addr; -+ int port = file->device->net->port; - - data = grub_zalloc (sizeof (*data)); - if (!data) -@@ -362,14 +363,17 @@ tftp_open (struct grub_file *file, const char *filename) - err = grub_net_resolve_address (file->device->net->server, &addr); - if (err) - { -- grub_dprintf("tftp", "Address resolution failed: %d\n", err); -+ grub_dprintf ("tftp", "Address resolution failed: %d\n", err); -+ grub_dprintf ("tftp", "file_size is %llu, block_size is %llu\n", -+ (unsigned long long)data->file_size, -+ (unsigned long long)data->block_size); - grub_free (data); - return err; - } - - grub_dprintf("tftp", "opening connection\n"); - data->sock = grub_net_udp_open (addr, -- TFTP_SERVER_PORT, tftp_receive, -+ port ? port : TFTP_SERVER_PORT, tftp_receive, - file); - if (!data->sock) - { -diff --git a/include/grub/net.h b/include/grub/net.h -index af0404db7e3..d55d505a03a 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -273,6 +273,7 @@ typedef struct grub_net - { - char *server; - char *name; -+ int port; - grub_net_app_level_t protocol; - grub_net_packets_t packs; - grub_off_t offset; diff --git a/0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch b/0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch deleted file mode 100644 index f8de42a3d0c810726fc5888c41b7ba01b9849c46..0000000000000000000000000000000000000000 --- a/0084-grub-editenv-Add-incr-command-to-increment-integer-v.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Mon, 4 Jun 2018 19:49:47 +0200 -Subject: [PATCH] grub-editenv: Add "incr" command to increment integer value - env. variables - -To be able to automatically detect if the last boot was successful, -We want to keep count of succesful / failed boots in some integer -environment variable. - -This commit adds a grub-editenvt "incr" command to increment such -integer value env. variables by 1 for use from various boot scripts. - -Signed-off-by: Hans de Goede ---- - util/grub-editenv.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 50 insertions(+) - -diff --git a/util/grub-editenv.c b/util/grub-editenv.c -index db6f187cc63..948eec8a114 100644 ---- a/util/grub-editenv.c -+++ b/util/grub-editenv.c -@@ -53,6 +53,9 @@ static struct argp_option options[] = { - /* TRANSLATORS: "unset" is a keyword. It's a summary of "unset" subcommand. */ - {N_("unset [NAME ...]"), 0, 0, OPTION_DOC|OPTION_NO_USAGE, - N_("Delete variables."), 0}, -+ /* TRANSLATORS: "incr" is a keyword. It's a summary of "incr" subcommand. */ -+ {N_("incr [NAME ...]"), 0, 0, OPTION_DOC|OPTION_NO_USAGE, -+ N_("Increase value of integer variables."), 0}, - - {0, 0, 0, OPTION_DOC, N_("Options:"), -1}, - {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, -@@ -253,6 +256,51 @@ unset_variables (const char *name, int argc, char *argv[]) - grub_envblk_close (envblk); - } - -+struct get_int_value_params { -+ char *varname; -+ int value; -+}; -+ -+static int -+get_int_value (const char *varname, const char *value, void *hook_data) -+{ -+ struct get_int_value_params *params = hook_data; -+ -+ if (strcmp (varname, params->varname) == 0) { -+ params->value = strtol (value, NULL, 10); -+ return 1; -+ } -+ return 0; -+} -+ -+static void -+incr_variables (const char *name, int argc, char *argv[]) -+{ -+ grub_envblk_t envblk; -+ char buf[16]; -+ -+ envblk = open_envblk_file (name); -+ while (argc) -+ { -+ struct get_int_value_params params = { -+ .varname = argv[0], -+ .value = 0, /* Consider unset variables 0 */ -+ }; -+ -+ grub_envblk_iterate (envblk, ¶ms, get_int_value); -+ snprintf(buf, sizeof(buf), "%d", params.value + 1); -+ -+ if (! grub_envblk_set (envblk, argv[0], buf)) -+ grub_util_error ("%s", _("environment block too small")); -+ -+ argc--; -+ argv++; -+ } -+ -+ write_envblk (name, envblk); -+ grub_envblk_close (envblk); -+} -+ - int - main (int argc, char *argv[]) - { -@@ -292,6 +340,8 @@ main (int argc, char *argv[]) - set_variables (filename, argc - curindex, argv + curindex); - else if (strcmp (command, "unset") == 0) - unset_variables (filename, argc - curindex, argv + curindex); -+ else if (strcmp (command, "incr") == 0) -+ incr_variables (filename, argc - curindex, argv + curindex); - else - { - char *program = xstrdup(program_name); diff --git a/0085-Add-auto-hide-menu-support.patch b/0085-Add-auto-hide-menu-support.patch deleted file mode 100644 index 863cd053e0e69e31971e9e7dd55cd3ce6e64cd5a..0000000000000000000000000000000000000000 --- a/0085-Add-auto-hide-menu-support.patch +++ /dev/null @@ -1,189 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 6 Jun 2018 08:44:11 +0200 -Subject: [PATCH] Add auto-hide menu support - -On single-os systems we do not want to show the menu, unless something -went wrong with the previous boot, in which case the user may need the -menu to debug/fix the problem. - -This commit adds a new grub.d/00_menu_auto_hide file which emits a -config snippet implementing this. I've chosen to do this in a separate -grub.d file because chances of this going upstream are small and this way -it will be easier to rebase. - -Since auto-hiding the menu requires detecting the previous boot was ok, -we get fastboot support (where we don't check for a key at all) for free -so this commit also adds support for this. - -The new config-file code uses the following variables: - -menu_auto_hide Set this to "1" to activate the new auto-hide feature - Set this to "2" to auto-hide the menu even when multiple - operating systems are installed. Note the menu will still - auto show after booting an other os as that won't set - boot_success. -menu_show_once Set this to "1" to force showing the menu once. -boot_success The OS sets this to "1" to indicate a successful boot. -boot_indeterminate The OS increments this integer when rebooting after e.g. - installing updates or a selinux relabel. -fastboot If set to "1" and the conditions for auto-hiding the menu - are met, the menu is not shown and all checks for keypresses - are skipped, booting the default immediately. - -30_os-prober.in changes somewhat inspired by: -https://git.launchpad.net/~ubuntu-core-dev/grub/+git/ubuntu/tree/debian/patches/quick_boot.patch - -Signed-off-by: Hans de Goede ---- -Changes in v2: --Drop shutdown_success tests, there is no meaningful way for systemd to set - this flag (by the time it knows all filesystems are unmounted or read-only --Drop fwsetup_once support, systemd already supports booting directly into - the fwsetup by doing "systemctl reboot --firmware" ---- - Makefile.util.def | 6 +++++ - util/grub.d/01_menu_auto_hide.in | 48 ++++++++++++++++++++++++++++++++++++++++ - util/grub.d/30_os-prober.in | 18 +++++++++++++++ - 3 files changed, 72 insertions(+) - create mode 100644 util/grub.d/01_menu_auto_hide.in - -diff --git a/Makefile.util.def b/Makefile.util.def -index 48512bc6311..314e6f2acf8 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -458,6 +458,12 @@ script = { - installdir = grubconf; - }; - -+script = { -+ name = '01_menu_auto_hide'; -+ common = util/grub.d/01_menu_auto_hide.in; -+ installdir = grubconf; -+}; -+ - script = { - name = '01_users'; - common = util/grub.d/01_users.in; -diff --git a/util/grub.d/01_menu_auto_hide.in b/util/grub.d/01_menu_auto_hide.in -new file mode 100644 -index 00000000000..ad175870a54 ---- /dev/null -+++ b/util/grub.d/01_menu_auto_hide.in -@@ -0,0 +1,48 @@ -+#! /bin/sh -+ -+# Disable / skip generating menu-auto-hide config parts on serial terminals -+for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do -+ case "$x" in -+ serial*) -+ exit 0 -+ ;; -+ esac -+done -+ -+cat << EOF -+if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then -+ set last_boot_ok=1 -+else -+ set last_boot_ok=0 -+fi -+ -+# Reset boot_indeterminate after a successful boot -+if [ "\${boot_success}" = "1" ] ; then -+ set boot_indeterminate=0 -+# Avoid boot_indeterminate causing the menu to be hidden more then once -+elif [ "\${boot_indeterminate}" = "1" ]; then -+ set boot_indeterminate=2 -+fi -+set boot_success=0 -+save_env boot_success boot_indeterminate -+ -+if [ x\$feature_timeout_style = xy ] ; then -+ if [ "\${menu_show_once}" ]; then -+ unset menu_show_once -+ save_env menu_show_once -+ set timeout_style=menu -+ set timeout=60 -+ elif [ "\${menu_auto_hide}" -a "\${last_boot_ok}" = "1" ]; then -+ set orig_timeout_style=\${timeout_style} -+ set orig_timeout=\${timeout} -+ if [ "\${fastboot}" = "1" ]; then -+ # timeout_style=menu + timeout=0 avoids the countdown code keypress check -+ set timeout_style=menu -+ set timeout=0 -+ else -+ set timeout_style=hidden -+ set timeout=1 -+ fi -+ fi -+fi -+EOF -diff --git a/util/grub.d/30_os-prober.in b/util/grub.d/30_os-prober.in -index 4b27bd20153..3c9431cfcfb 100644 ---- a/util/grub.d/30_os-prober.in -+++ b/util/grub.d/30_os-prober.in -@@ -42,6 +42,7 @@ if [ -z "${OSPROBED}" ] ; then - fi - - osx_entry() { -+ found_other_os=1 - # TRANSLATORS: it refers on the OS residing on device %s - onstr="$(gettext_printf "(on %s)" "${DEVICE}")" - hints="" -@@ -102,6 +103,7 @@ for OS in ${OSPROBED} ; do - - case ${BOOT} in - chain) -+ found_other_os=1 - - onstr="$(gettext_printf "(on %s)" "${DEVICE}")" - cat << EOF -@@ -132,6 +134,7 @@ EOF - EOF - ;; - efi) -+ found_other_os=1 - - EFIPATH=${DEVICE#*@} - DEVICE=${DEVICE%@*} -@@ -176,6 +179,7 @@ EOF - LINITRD="${LINITRD#/boot}" - fi - -+ found_other_os=1 - onstr="$(gettext_printf "(on %s)" "${DEVICE}")" - recovery_params="$(echo "${LPARAMS}" | grep single)" || true - counter=1 -@@ -257,6 +261,7 @@ EOF - done - ;; - hurd) -+ found_other_os=1 - onstr="$(gettext_printf "(on %s)" "${DEVICE}")" - cat << EOF - menuentry '$(echo "${LONGNAME} $onstr" | grub_quote)' --class hurd --class gnu --class os \$menuentry_id_option 'osprober-gnuhurd-/boot/gnumach.gz-false-$(grub_get_device_id "${DEVICE}")' { -@@ -283,6 +288,7 @@ EOF - EOF - ;; - minix) -+ found_other_os=1 - cat << EOF - menuentry "${LONGNAME} (on ${DEVICE}, Multiboot)" { - EOF -@@ -299,3 +305,15 @@ EOF - ;; - esac - done -+ -+# We override the results of the menu_auto_hide code here, this is a bit ugly, -+# but grub-mkconfig writes out the file linearly, so this is the only way -+if [ "${found_other_os}" = "1" ]; then -+ cat << EOF -+# Other OS found, undo autohiding of menu unless menu_auto_hide=2 -+if [ "\${orig_timeout_style}" -a "\${menu_auto_hide}" != "2" ]; then -+ set timeout_style=\${orig_timeout_style} -+ set timeout=\${orig_timeout} -+fi -+EOF -+fi diff --git a/0086-Add-grub-set-bootflag-utility.patch b/0086-Add-grub-set-bootflag-utility.patch deleted file mode 100644 index e39f8bebb496a3315ab10090c10ecf7b3339fac0..0000000000000000000000000000000000000000 --- a/0086-Add-grub-set-bootflag-utility.patch +++ /dev/null @@ -1,295 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 12 Jun 2018 13:25:16 +0200 -Subject: [PATCH] Add grub-set-bootflag utility - -This commit adds a new grub-set-bootflag utility, which can be used -to set known bootflags in the grubenv: boot_success or menu_show_once. - -grub-set-bootflag is different from grub-editenv in 2 ways: - -1) It is intended to be executed by regular users so must be installed -as suid root. As such it is written to not use any existing grubenv -related code for easy auditing. - -It can't be executed through pkexec because we want to call it under gdm -and pkexec does not work under gdm due the gdm user having /sbin/nologin -as shell. - -2) Since it can be executed by regular users it only allows setting -(assigning a value of 1 to) bootflags which it knows about. Currently -those are just boot_success and menu_show_once. - -This commit also adds a couple of example systemd and files which show -how this can be used to set boot_success from a user-session: - -docs/grub-boot-success.service -docs/grub-boot-success.timer - -The 2 grub-boot-success.systemd files should be placed in /lib/systemd/user -and a symlink to grub-boot-success.timer should be added to -/lib/systemd/user/timers.target.wants. - -Signed-off-by: Hans de Goede -[makhomed: grub-boot-success.timer: Only run if not in a container] -Signed-off-by: Gena Makhomed -Signed-off-by: Robbie Harwood ---- - Makefile.util.def | 7 ++ - util/grub-set-bootflag.c | 160 +++++++++++++++++++++++++++++++++++++++++ - conf/Makefile.extra-dist | 3 + - docs/grub-boot-success.service | 6 ++ - docs/grub-boot-success.timer | 7 ++ - util/grub-set-bootflag.1 | 20 ++++++ - 6 files changed, 203 insertions(+) - create mode 100644 util/grub-set-bootflag.c - create mode 100644 docs/grub-boot-success.service - create mode 100644 docs/grub-boot-success.timer - create mode 100644 util/grub-set-bootflag.1 - -diff --git a/Makefile.util.def b/Makefile.util.def -index 314e6f2acf8..0b85a7fce4a 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -1446,3 +1446,10 @@ program = { - ldadd = grub-core/lib/gnulib/libgnu.a; - ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; - }; -+ -+program = { -+ name = grub-set-bootflag; -+ installdir = sbin; -+ mansection = 1; -+ common = util/grub-set-bootflag.c; -+}; -diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c -new file mode 100644 -index 00000000000..bb198f02351 ---- /dev/null -+++ b/util/grub-set-bootflag.c -@@ -0,0 +1,160 @@ -+/* grub-set-bootflag.c - tool to set boot-flags in the grubenv. */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2018 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 . -+ */ -+ -+/* -+ * NOTE this gets run by users as root (through pkexec), so this does not -+ * use any grub library / util functions to allow for easy auditing. -+ * The grub headers are only included to get certain defines. -+ */ -+ -+#include /* For *_DIR_NAME defines */ -+#include -+#include /* For GRUB_ENVBLK_DEFCFG define */ -+#include -+#include -+#include -+#include -+ -+#define GRUBENV "/" GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME "/" GRUB_ENVBLK_DEFCFG -+#define GRUBENV_SIZE 1024 -+ -+const char *bootflags[] = { -+ "boot_success", -+ "menu_show_once", -+ NULL -+}; -+ -+static void usage(void) -+{ -+ int i; -+ -+ fprintf (stderr, "Usage: 'grub-set-bootflag ', where is one of:\n"); -+ for (i = 0; bootflags[i]; i++) -+ fprintf (stderr, " %s\n", bootflags[i]); -+} -+ -+int main(int argc, char *argv[]) -+{ -+ /* NOTE buf must be at least the longest bootflag length + 4 bytes */ -+ char env[GRUBENV_SIZE + 1], buf[64], *s; -+ const char *bootflag; -+ int i, len, ret; -+ FILE *f; -+ -+ if (argc != 2) -+ { -+ usage(); -+ return 1; -+ } -+ -+ for (i = 0; bootflags[i]; i++) -+ if (!strcmp (argv[1], bootflags[i])) -+ break; -+ if (!bootflags[i]) -+ { -+ fprintf (stderr, "Invalid bootflag: '%s'\n", argv[1]); -+ usage(); -+ return 1; -+ } -+ -+ bootflag = bootflags[i]; -+ len = strlen (bootflag); -+ -+ f = fopen (GRUBENV, "r"); -+ if (!f) -+ { -+ perror ("Error opening " GRUBENV " for reading"); -+ return 1; -+ } -+ -+ ret = fread (env, 1, GRUBENV_SIZE, f); -+ fclose (f); -+ if (ret != GRUBENV_SIZE) -+ { -+ errno = EINVAL; -+ perror ("Error reading from " GRUBENV); -+ return 1; -+ } -+ -+ /* 0 terminate env */ -+ env[GRUBENV_SIZE] = 0; -+ -+ if (strncmp (env, GRUB_ENVBLK_SIGNATURE, strlen (GRUB_ENVBLK_SIGNATURE))) -+ { -+ fprintf (stderr, "Error invalid environment block\n"); -+ return 1; -+ } -+ -+ /* Find a pre-existing definition of the bootflag */ -+ s = strstr (env, bootflag); -+ while (s && s[len] != '=') -+ s = strstr (s + len, bootflag); -+ -+ if (s && ((s[len + 1] != '0' && s[len + 1] != '1') || s[len + 2] != '\n')) -+ { -+ fprintf (stderr, "Pre-existing bootflag '%s' has unexpected value\n", bootflag); -+ return 1; -+ } -+ -+ /* No pre-existing bootflag? -> find free space */ -+ if (!s) -+ { -+ for (i = 0; i < (len + 3); i++) -+ buf[i] = '#'; -+ buf[i] = 0; -+ s = strstr (env, buf); -+ } -+ -+ if (!s) -+ { -+ fprintf (stderr, "No space in grubenv to store bootflag '%s'\n", bootflag); -+ return 1; -+ } -+ -+ /* The grubenv is not 0 terminated, so memcpy the name + '=' , '1', '\n' */ -+ snprintf(buf, sizeof(buf), "%s=1\n", bootflag); -+ memcpy(s, buf, len + 3); -+ -+ /* "r+", don't truncate so that the diskspace stays reserved */ -+ f = fopen (GRUBENV, "r+"); -+ if (!f) -+ { -+ perror ("Error opening " GRUBENV " for writing"); -+ return 1; -+ } -+ -+ ret = fwrite (env, 1, GRUBENV_SIZE, f); -+ if (ret != GRUBENV_SIZE) -+ { -+ perror ("Error writing to " GRUBENV); -+ return 1; -+ } -+ -+ ret = fflush (f); -+ if (ret) -+ { -+ perror ("Error flushing " GRUBENV); -+ return 1; -+ } -+ -+ fsync (fileno (f)); -+ fclose (f); -+ -+ return 0; -+} -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index b909f2c073a..ea58362b555 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -14,6 +14,9 @@ EXTRA_DIST += util/import_unicode.py - EXTRA_DIST += docs/autoiso.cfg - EXTRA_DIST += docs/grub.cfg - EXTRA_DIST += docs/osdetect.cfg -+EXTRA_DIST += docs/org.gnu.grub.policy -+EXTRA_DIST += docs/grub-boot-success.service -+EXTRA_DIST += docs/grub-boot-success.timer - - EXTRA_DIST += conf/i386-cygwin-img-ld.sc - -diff --git a/docs/grub-boot-success.service b/docs/grub-boot-success.service -new file mode 100644 -index 00000000000..80e79584c91 ---- /dev/null -+++ b/docs/grub-boot-success.service -@@ -0,0 +1,6 @@ -+[Unit] -+Description=Mark boot as successful -+ -+[Service] -+Type=oneshot -+ExecStart=/usr/sbin/grub2-set-bootflag boot_success -diff --git a/docs/grub-boot-success.timer b/docs/grub-boot-success.timer -new file mode 100644 -index 00000000000..406f1720056 ---- /dev/null -+++ b/docs/grub-boot-success.timer -@@ -0,0 +1,7 @@ -+[Unit] -+Description=Mark boot as successful after the user session has run 2 minutes -+ConditionUser=!@system -+ConditionVirtualization=!container -+ -+[Timer] -+OnActiveSec=2min -diff --git a/util/grub-set-bootflag.1 b/util/grub-set-bootflag.1 -new file mode 100644 -index 00000000000..57801da22a0 ---- /dev/null -+++ b/util/grub-set-bootflag.1 -@@ -0,0 +1,20 @@ -+.TH GRUB-SET-BOOTFLAG 1 "Tue Jun 12 2018" -+.SH NAME -+\fBgrub-set-bootflag\fR \(em Set a bootflag in the GRUB environment block. -+ -+.SH SYNOPSIS -+\fBgrub-set-bootflag\fR <\fIBOOTFLAG\fR> -+ -+.SH DESCRIPTION -+\fBgrub-set-bootflag\fR is a command line to set bootflags in GRUB's -+stored environment. -+ -+.SH COMMANDS -+.TP -+\fBBOOTFLAG\fR -+.RS 7 -+Bootflag to set, one of \fIboot_success\fR or \fIshow_menu_once\fR. -+.RE -+ -+.SH SEE ALSO -+.BR "info grub" diff --git a/0087-docs-Add-grub-boot-indeterminate.service-example.patch b/0087-docs-Add-grub-boot-indeterminate.service-example.patch deleted file mode 100644 index 44f6ad3984b8dd0c9ab108d395e1a68934a831a2..0000000000000000000000000000000000000000 --- a/0087-docs-Add-grub-boot-indeterminate.service-example.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 19 Jun 2018 15:20:54 +0200 -Subject: [PATCH] docs: Add grub-boot-indeterminate.service example - -This is an example service file, for use from -/lib/systemd/system/system-update.target.wants -to increment the boot_indeterminate variable when -doing offline updates. - -Signed-off-by: Hans de Goede ---- - docs/grub-boot-indeterminate.service | 11 +++++++++++ - 1 file changed, 11 insertions(+) - create mode 100644 docs/grub-boot-indeterminate.service - -diff --git a/docs/grub-boot-indeterminate.service b/docs/grub-boot-indeterminate.service -new file mode 100644 -index 00000000000..6c8dcb186b6 ---- /dev/null -+++ b/docs/grub-boot-indeterminate.service -@@ -0,0 +1,11 @@ -+[Unit] -+Description=Mark boot as indeterminate -+DefaultDependencies=false -+Requires=sysinit.target -+After=sysinit.target -+Wants=system-update-pre.target -+Before=system-update-pre.target -+ -+[Service] -+Type=oneshot -+ExecStart=/usr/bin/grub2-editenv - incr boot_indeterminate diff --git a/0088-gentpl-add-disable-support.patch b/0088-gentpl-add-disable-support.patch deleted file mode 100644 index 2c3c998f505c768ce1538d996323e754fc34a932..0000000000000000000000000000000000000000 --- a/0088-gentpl-add-disable-support.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 11 Jul 2018 13:43:15 -0400 -Subject: [PATCH] gentpl: add 'disable = ' support - -Signed-off-by: Peter Jones ---- - gentpl.py | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/gentpl.py b/gentpl.py -index 2cba0bbbd6f..628e8bec1d7 100644 ---- a/gentpl.py -+++ b/gentpl.py -@@ -592,11 +592,21 @@ def platform_conditional(platform, closure): - # }; - # - def foreach_enabled_platform(defn, closure): -+ enabled = False -+ disabled = False - if 'enable' in defn: -+ enabled = True - for platform in GRUB_PLATFORMS: - if platform_tagged(defn, platform, "enable"): - platform_conditional(platform, closure) -- else: -+ -+ if 'disable' in defn: -+ disabled = True -+ for platform in GRUB_PLATFORMS: -+ if not platform_tagged(defn, platform, "disable"): -+ platform_conditional(platform, closure) -+ -+ if not enabled and not disabled: - for platform in GRUB_PLATFORMS: - platform_conditional(platform, closure) - -@@ -655,6 +665,8 @@ def first_time(defn, snippet): - def is_platform_independent(defn): - if 'enable' in defn: - return False -+ if 'disable' in defn: -+ return False - for suffix in [ "", "_nodist" ]: - template = platform_values(defn, GRUB_PLATFORMS[0], suffix) - for platform in GRUB_PLATFORMS[1:]: diff --git a/0089-gentpl-add-pc-firmware-type.patch b/0089-gentpl-add-pc-firmware-type.patch deleted file mode 100644 index 96dd2b8c623287deebd1198ec49d19395f66099f..0000000000000000000000000000000000000000 --- a/0089-gentpl-add-pc-firmware-type.patch +++ /dev/null @@ -1,22 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 11 Jul 2019 11:04:24 +0200 -Subject: [PATCH] gentpl: add 'pc' firmware type - -Signed-off-by: Peter Jones ---- - gentpl.py | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/gentpl.py b/gentpl.py -index 628e8bec1d7..34a4eba2b42 100644 ---- a/gentpl.py -+++ b/gentpl.py -@@ -51,6 +51,7 @@ GROUPS["riscv32"] = [ "riscv32_efi" ] - GROUPS["riscv64"] = [ "riscv64_efi" ] - - # Groups based on firmware -+GROUPS["pc"] = [ "i386_pc" ] - GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", - "riscv32_efi", "riscv64_efi" ] - GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] diff --git a/0090-efinet-also-use-the-firmware-acceleration-for-http.patch b/0090-efinet-also-use-the-firmware-acceleration-for-http.patch deleted file mode 100644 index 915b5aa161164b5725011f539c6b1bd942ca79ad..0000000000000000000000000000000000000000 --- a/0090-efinet-also-use-the-firmware-acceleration-for-http.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 30 Jul 2018 14:06:42 -0400 -Subject: [PATCH] efinet: also use the firmware acceleration for http - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/net.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -index 4bb308026ce..6603cd83edc 100644 ---- a/grub-core/net/efi/net.c -+++ b/grub-core/net/efi/net.c -@@ -1324,7 +1324,9 @@ grub_efi_net_boot_from_https (void) - && (subtype == GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)) - { - grub_efi_uri_device_path_t *uri_dp = (grub_efi_uri_device_path_t *) dp; -- return (grub_strncmp ((const char*)uri_dp->uri, "https://", sizeof ("https://") - 1) == 0) ? 1 : 0; -+ grub_dprintf ("efinet", "url:%s\n", (const char *)uri_dp->uri); -+ return (grub_strncmp ((const char *)uri_dp->uri, "https://", sizeof ("https://") - 1) == 0 || -+ grub_strncmp ((const char *)uri_dp->uri, "http://", sizeof ("http://") - 1) == 0); - } - - if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) diff --git a/0091-efi-http-Make-root_url-reflect-the-protocol-hostname.patch b/0091-efi-http-Make-root_url-reflect-the-protocol-hostname.patch deleted file mode 100644 index 985a037828bde8390cc4d84d0b395a133fcc0338..0000000000000000000000000000000000000000 --- a/0091-efi-http-Make-root_url-reflect-the-protocol-hostname.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 30 Jul 2018 16:39:57 -0400 -Subject: [PATCH] efi/http: Make root_url reflect the protocol+hostname of our - boot url. - -This lets you write config files that don't know urls. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/http.c | 19 +++++++++++++++++++ - 1 file changed, 19 insertions(+) - -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -index 3f61fd2fa5b..243acbaa35b 100644 ---- a/grub-core/net/efi/http.c -+++ b/grub-core/net/efi/http.c -@@ -4,6 +4,7 @@ - #include - #include - #include -+#include - - static void - http_configure (struct grub_efi_net_device *dev, int prefer_ip6) -@@ -351,6 +352,24 @@ grub_efihttp_open (struct grub_efi_net_device *dev, - grub_err_t err; - grub_off_t size; - char *buf; -+ char *root_url; -+ grub_efi_ipv6_address_t address; -+ const char *rest; -+ -+ if (grub_efi_string_to_ip6_address (file->device->net->server, &address, &rest) && *rest == 0) -+ root_url = grub_xasprintf ("%s://[%s]", type ? "https" : "http", file->device->net->server); -+ else -+ root_url = grub_xasprintf ("%s://%s", type ? "https" : "http", file->device->net->server); -+ if (root_url) -+ { -+ grub_env_unset ("root_url"); -+ grub_env_set ("root_url", root_url); -+ grub_free (root_url); -+ } -+ else -+ { -+ return grub_errno; -+ } - - err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 1, 0); - if (err != GRUB_ERR_NONE) diff --git a/0092-Make-it-so-we-can-tell-configure-which-cflags-utils-.patch b/0092-Make-it-so-we-can-tell-configure-which-cflags-utils-.patch deleted file mode 100644 index ee2216e514ec1d9db12487219790a04bf0f06ca8..0000000000000000000000000000000000000000 --- a/0092-Make-it-so-we-can-tell-configure-which-cflags-utils-.patch +++ /dev/null @@ -1,149 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 26 Jun 2018 17:16:06 -0400 -Subject: [PATCH] Make it so we can tell configure which cflags utils are built - with - -This lets us have kernel.img be built with TARGET_CFLAGS but grub-mkimage and -friends built with HOST_CFLAGS. That in turn lets us build with an ARM compiler -that only has hard-float ABI versions of crt*.o and libgcc*, but still use soft -float for grub.efi. - -Signed-off-by: Peter Jones ---- - configure.ac | 49 ++++++++++++++++++++++++++++++++++++++++++++++++- - conf/Makefile.common | 23 ++++++++++++----------- - gentpl.py | 8 ++++---- - 3 files changed, 64 insertions(+), 16 deletions(-) - -diff --git a/configure.ac b/configure.ac -index b50fb2e9897..b27573b3de5 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -877,11 +877,23 @@ if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ) && test "x$p - TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow" - fi - -+# Should grub utils get the host CFLAGS, or the target CFLAGS? -+AC_ARG_WITH([utils], -+ AS_HELP_STRING([--with-utils=host|target|build], -+ [choose which flags to build utilities with. (default=target)]), -+ [have_with_utils=y], -+ [have_with_utils=n]) -+if test x"$have_with_utils" = xy ; then -+ with_utils="$withval" -+else -+ with_utils=target -+fi -+ - # GRUB doesn't use float or doubles at all. Yet some toolchains may decide - # that floats are a good fit to run instead of what's written in the code. - # Given that floating point unit is disabled (if present to begin with) - # when GRUB is running which may result in various hard crashes. --if test x"$platform" != xemu ; then -+if test x"$platform" != xemu -a x"$with_utils" == xtarget ; then - AC_CACHE_CHECK([for options to get soft-float], grub_cv_target_cc_soft_float, [ - grub_cv_target_cc_soft_float=no - if test "x$target_cpu" = xarm64; then -@@ -2011,6 +2023,41 @@ HOST_CPPFLAGS="$HOST_CPPFLAGS -I\$(top_builddir)/include" - TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_srcdir)/include" - TARGET_CPPFLAGS="$TARGET_CPPFLAGS -I\$(top_builddir)/include" - -+case "$with_utils" in -+ host) -+ UTILS_CFLAGS=$HOST_CFLAGS -+ UTILS_CPPFLAGS=$HOST_CPPFLAGS -+ UTILS_CCASFLAGS=$HOST_CCASFLAGS -+ UTILS_LDFLAGS=$HOST_LDFLAGS -+ ;; -+ target) -+ UTILS_CFLAGS=$TARGET_CFLAGS -+ UTILS_CPPFLAGS=$TARGET_CPPFLAGS -+ UTILS_CCASFLAGS=$TARGET_CCASFLAGS -+ UTILS_LDFLAGS=$TARGET_LDFLAGS -+ ;; -+ build) -+ UTILS_CFLAGS=$BUILD_CFLAGS -+ UTILS_CPPFLAGS=$BUILD_CPPFLAGS -+ UTILS_CCASFLAGS=$BUILD_CCASFLAGS -+ UTILS_LDFLAGS=$BUILD_LDFLAGS -+ ;; -+ *) -+ AC_MSG_ERROR([--with-utils must be either host, target, or build]) -+ ;; -+esac -+AC_MSG_NOTICE([Using $with_utils flags for utilities.]) -+ -+unset CFLAGS -+unset CPPFLAGS -+unset CCASFLAGS -+unset LDFLAGS -+ -+AC_SUBST(UTILS_CFLAGS) -+AC_SUBST(UTILS_CPPFLAGS) -+AC_SUBST(UTILS_CCASFLAGS) -+AC_SUBST(UTILS_LDFLAGS) -+ - GRUB_TARGET_CPU="${target_cpu}" - GRUB_PLATFORM="${platform}" - -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 5f0ef969857..2ff9b39357c 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -40,24 +40,25 @@ CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -DGRUB_KERNEL=1 - CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) - STRIPFLAGS_KERNEL = -R .eh_frame -R .rel.dyn -R .reginfo -R .note -R .comment -R .drectve -R .note.gnu.gold-version -R .MIPS.abiflags -R .ARM.exidx -R .note.gnu.property -R .gnu.build.attributes - --CFLAGS_MODULE = $(CFLAGS_PLATFORM) -ffreestanding --LDFLAGS_MODULE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d --CPPFLAGS_MODULE = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) --CCASFLAGS_MODULE = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) -+CFLAGS_MODULE = $(TARGET_CFLAGS) $(CFLAGS_PLATFORM) -ffreestanding -+LDFLAGS_MODULE = $(TARGET_LDFLAGS) $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-r,-d -+CPPFLAGS_MODULE = $(TARGET_CPPFLAGS) $(CPPFLAGS_DEFAULT) $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) -+CCASFLAGS_MODULE = $(TARGET_CCASFLAGS) $(CCASFLAGS_DEFAULT) $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) - - CFLAGS_IMAGE = $(CFLAGS_PLATFORM) -fno-builtin - LDFLAGS_IMAGE = $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -Wl,-S - CPPFLAGS_IMAGE = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM) - CCASFLAGS_IMAGE = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM) - --CFLAGS_PROGRAM = --LDFLAGS_PROGRAM = --CPPFLAGS_PROGRAM = --CCASFLAGS_PROGRAM = -+CFLAGS_PROGRAM = $(UTILS_CFLAGS) -+LDFLAGS_PROGRAM = $(UTILS_LDFLAGS) -+CPPFLAGS_PROGRAM = $(UTILS_CPPFLAGS) -+CCASFLAGS_PROGRAM = $(UTILS_CCASFLAGS) - --CFLAGS_LIBRARY = --CPPFLAGS_LIBRARY = --CCASFLAGS_LIBRARY = -+CFLAGS_LIBRARY = $(UTILS_CFLAGS) -+LDFLAGS_LIBRARY = $(UTILS_LDFLAGS) -+CPPFLAGS_LIBRARY = $(UTILS_CPPFLAGS) -+CCASFLAGS_LIBRARY = $(UTILS_CCASFLAGS) - - # Other variables - -diff --git a/gentpl.py b/gentpl.py -index 34a4eba2b42..59f62ef9522 100644 ---- a/gentpl.py -+++ b/gentpl.py -@@ -697,10 +697,10 @@ def module(defn, platform): - var_set(cname(defn) + "_SOURCES", platform_sources(defn, platform) + " ## platform sources") - var_set("nodist_" + cname(defn) + "_SOURCES", platform_nodist_sources(defn, platform) + " ## platform nodist sources") - var_set(cname(defn) + "_LDADD", platform_ldadd(defn, platform)) -- var_set(cname(defn) + "_CFLAGS", "$(AM_CFLAGS) $(CFLAGS_MODULE) " + platform_cflags(defn, platform)) -- var_set(cname(defn) + "_LDFLAGS", "$(AM_LDFLAGS) $(LDFLAGS_MODULE) " + platform_ldflags(defn, platform)) -- var_set(cname(defn) + "_CPPFLAGS", "$(AM_CPPFLAGS) $(CPPFLAGS_MODULE) " + platform_cppflags(defn, platform)) -- var_set(cname(defn) + "_CCASFLAGS", "$(AM_CCASFLAGS) $(CCASFLAGS_MODULE) " + platform_ccasflags(defn, platform)) -+ var_set(cname(defn) + "_CFLAGS", "$(CFLAGS_MODULE) " + platform_cflags(defn, platform)) -+ var_set(cname(defn) + "_LDFLAGS", "$(LDFLAGS_MODULE) " + platform_ldflags(defn, platform)) -+ var_set(cname(defn) + "_CPPFLAGS", "$(CPPFLAGS_MODULE) " + platform_cppflags(defn, platform)) -+ var_set(cname(defn) + "_CCASFLAGS", "$(CCASFLAGS_MODULE) " + platform_ccasflags(defn, platform)) - var_set(cname(defn) + "_DEPENDENCIES", "$(TARGET_OBJ2ELF) " + platform_dependencies(defn, platform)) - - gvar_add("dist_noinst_DATA", extra_dist(defn)) diff --git a/0093-module-verifier-make-it-possible-to-run-checkers-on-.patch b/0093-module-verifier-make-it-possible-to-run-checkers-on-.patch deleted file mode 100644 index e31b38f6c86e7b8b693b9beaefa31c7d9080a08a..0000000000000000000000000000000000000000 --- a/0093-module-verifier-make-it-possible-to-run-checkers-on-.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 1 Aug 2018 10:24:52 -0400 -Subject: [PATCH] module-verifier: make it possible to run checkers on - grub-module-verifierxx.c - -This makes it so you can treat grub-module-verifierxx.c as a file you can -build directly, so syntax checkers like vim's "syntastic" plugin, which uses -"gcc -x c -fsyntax-only" to build it, will work. - -One still has to do whatever setup is required to make it pick the right -include dirs, which -W options we use, etc., but this makes it so you can do -the checking on the file you're editing, rather than on a different file. - -v2: fix the typo in the #else clause in util/grub-module-verifierXX.c - -Signed-off-by: Peter Jones ---- - util/grub-module-verifier32.c | 2 ++ - util/grub-module-verifier64.c | 2 ++ - util/grub-module-verifierXX.c | 9 +++++++++ - 3 files changed, 13 insertions(+) - -diff --git a/util/grub-module-verifier32.c b/util/grub-module-verifier32.c -index 257229f8f08..ba7d41aafea 100644 ---- a/util/grub-module-verifier32.c -+++ b/util/grub-module-verifier32.c -@@ -1,2 +1,4 @@ - #define MODULEVERIFIER_ELF32 1 -+#ifndef GRUB_MODULE_VERIFIERXX - #include "grub-module-verifierXX.c" -+#endif -diff --git a/util/grub-module-verifier64.c b/util/grub-module-verifier64.c -index 4db6b4bedd1..fc23ef800b3 100644 ---- a/util/grub-module-verifier64.c -+++ b/util/grub-module-verifier64.c -@@ -1,2 +1,4 @@ - #define MODULEVERIFIER_ELF64 1 -+#ifndef GRUB_MODULE_VERIFIERXX - #include "grub-module-verifierXX.c" -+#endif -diff --git a/util/grub-module-verifierXX.c b/util/grub-module-verifierXX.c -index ceb24309aec..a98e2f9b1ac 100644 ---- a/util/grub-module-verifierXX.c -+++ b/util/grub-module-verifierXX.c -@@ -1,3 +1,12 @@ -+#define GRUB_MODULE_VERIFIERXX -+#if !defined(MODULEVERIFIER_ELF32) && !defined(MODULEVERIFIER_ELF64) -+#if __SIZEOF_POINTER__ == 8 -+#include "grub-module-verifier64.c" -+#else -+#include "grub-module-verifier32.c" -+#endif -+#endif -+ - #include - - #include diff --git a/0094-Rework-how-the-fdt-command-builds.patch b/0094-Rework-how-the-fdt-command-builds.patch deleted file mode 100644 index e233067a3eaab09e616270c71a73d812a4c16c86..0000000000000000000000000000000000000000 --- a/0094-Rework-how-the-fdt-command-builds.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 11 Jul 2019 13:01:41 +0200 -Subject: [PATCH] Rework how the fdt command builds. - -Trying to avoid all variants of: -cat syminfo.lst | sort | gawk -f ../../grub-core/genmoddep.awk > moddep.lst || (rm -f moddep.lst; exit 1) -grub_fdt_install in linux is not defined -grub_fdt_load in linux is not defined -grub_fdt_unload in linux is not defined -grub_fdt_install in xen_boot is not defined -grub_fdt_load in xen_boot is not defined -grub_fdt_unload in xen_boot is not defined - -Signed-off-by: Peter Jones -[javierm: Fix build with platform emu, aarch64, and risc-v] -Signed-off-by: Javier Martinez Canillas -Signed-off-by: Robbie Harwood ---- - grub-core/Makefile.core.def | 5 ++--- - grub-core/lib/fdt.c | 2 -- - grub-core/loader/efi/fdt.c | 2 ++ - include/grub/fdt.h | 6 ++++++ - grub-core/Makefile.am | 1 + - 5 files changed, 11 insertions(+), 5 deletions(-) - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index c40170f2dd2..84a3d89de9a 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -177,7 +177,6 @@ kernel = { - arm_coreboot = kern/arm/coreboot/init.c; - arm_coreboot = kern/arm/coreboot/timer.c; - arm_coreboot = kern/arm/coreboot/coreboot.S; -- arm_coreboot = lib/fdt.c; - arm_coreboot = bus/fdt.c; - arm_coreboot = term/ps2.c; - arm_coreboot = term/arm/pl050.c; -@@ -351,6 +350,8 @@ kernel = { - riscv64 = kern/riscv/cache_flush.S; - riscv64 = kern/riscv/dl.c; - -+ fdt = lib/fdt.c; -+ - emu = disk/host.c; - emu = kern/emu/cache_s.S; - emu = kern/emu/hostdisk.c; -@@ -1825,7 +1826,6 @@ module = { - riscv32 = loader/riscv/linux.c; - riscv64 = loader/riscv/linux.c; - emu = loader/emu/linux.c; -- fdt = lib/fdt.c; - - common = loader/linux.c; - common = lib/cmdline.c; -@@ -1836,7 +1836,6 @@ module = { - module = { - name = fdt; - efi = loader/efi/fdt.c; -- common = lib/fdt.c; - enable = fdt; - }; - -diff --git a/grub-core/lib/fdt.c b/grub-core/lib/fdt.c -index 0d371c5633e..37e04bd69e7 100644 ---- a/grub-core/lib/fdt.c -+++ b/grub-core/lib/fdt.c -@@ -21,8 +21,6 @@ - #include - #include - --GRUB_MOD_LICENSE ("GPLv3+"); -- - #define FDT_SUPPORTED_VERSION 17 - - #define FDT_BEGIN_NODE 0x00000001 -diff --git a/grub-core/loader/efi/fdt.c b/grub-core/loader/efi/fdt.c -index c86f283d756..c572415d38a 100644 ---- a/grub-core/loader/efi/fdt.c -+++ b/grub-core/loader/efi/fdt.c -@@ -27,6 +27,8 @@ - #include - #include - -+GRUB_MOD_LICENSE ("GPLv3+"); -+ - static void *loaded_fdt; - static void *fdt; - -diff --git a/include/grub/fdt.h b/include/grub/fdt.h -index e609c7e4111..3514aa4a5b6 100644 ---- a/include/grub/fdt.h -+++ b/include/grub/fdt.h -@@ -19,6 +19,9 @@ - #ifndef GRUB_FDT_HEADER - #define GRUB_FDT_HEADER 1 - -+#if !defined(GRUB_MACHINE_EMU) && \ -+ (defined(__arm__) || defined(__aarch64__) || defined(__riscv)) -+ - #include - #include - -@@ -144,4 +147,7 @@ int EXPORT_FUNC(grub_fdt_set_prop) (void *fdt, unsigned int nodeoffset, const ch - grub_fdt_set_prop ((fdt), (nodeoffset), "reg", reg_64, 16); \ - }) - -+#endif /* !defined(GRUB_MACHINE_EMU) && \ -+ (defined(__arm__) || defined(__aarch64__) || defined(__riscv)) */ -+ - #endif /* ! GRUB_FDT_HEADER */ -diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index f512573c0da..dd49939aaa9 100644 ---- a/grub-core/Makefile.am -+++ b/grub-core/Makefile.am -@@ -76,6 +76,7 @@ KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/sb.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/env_private.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/err.h -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fdt.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/file.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/fs.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i18n.h diff --git a/0095-Disable-non-wordsize-allocations-on-arm.patch b/0095-Disable-non-wordsize-allocations-on-arm.patch deleted file mode 100644 index e28041a1a38cc308d3533b787691e43746acdba2..0000000000000000000000000000000000000000 --- a/0095-Disable-non-wordsize-allocations-on-arm.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 2 Aug 2018 10:56:38 -0400 -Subject: [PATCH] Disable non-wordsize allocations on arm - -Signed-off-by: Peter Jones ---- - configure.ac | 20 ++++++++++++++++++++ - 1 file changed, 20 insertions(+) - -diff --git a/configure.ac b/configure.ac -index b27573b3de5..bb4e05ceef3 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1288,6 +1288,26 @@ if test "x$target_cpu" = xarm; then - done - ]) - -+ AC_CACHE_CHECK([for options to disable movt and movw relocations], -+ grub_cv_target_cc_mword_relocations, -+ [grub_cv_target_cc_mword_relocations=no -+ for cand in "-mword-relocations" ; do -+ if test x"$grub_cv_target_cc_mword_relocations" != xno ; then -+ break -+ fi -+ CFLAGS="$TARGET_CFLAGS $cand -Werror" -+ CPPFLAGS="$TARGET_CPPFLAGS" -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], -+ [grub_cv_target_cc_mword_relocations="$cand"], -+ []) -+ done -+ ]) -+ if test x"$grub_cv_target_cc_mword_relocations" = xno ; then -+ AC_MSG_ERROR(["your compiler doesn't support disabling movw/movt relocations"]) -+ else -+ TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mword_relocations" -+ fi -+ - if test x"$grub_cv_target_cc_mno_movt" != xno ; then - # A trick so that clang doesn't see it on link stage - TARGET_CPPFLAGS="$TARGET_CPPFLAGS $grub_cv_target_cc_mno_movt" diff --git a/0096-Prepend-prefix-when-HTTP-path-is-relative.patch b/0096-Prepend-prefix-when-HTTP-path-is-relative.patch deleted file mode 100644 index d3e599d1a691e995b007c21e03eea4205037d11e..0000000000000000000000000000000000000000 --- a/0096-Prepend-prefix-when-HTTP-path-is-relative.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Stephen Benjamin -Date: Thu, 16 Aug 2018 16:58:51 -0400 -Subject: [PATCH] Prepend prefix when HTTP path is relative - -This sets a couple of variables. With the url http://www.example.com/foo/bar : -http_path: /foo/bar -http_url: http://www.example.com/foo/bar - -Signed-off-by: Peter Jones -Signed-off-by: Stephen Benjamin -Signed-off-by: Robbie Harwood ---- - grub-core/kern/main.c | 10 +++++- - grub-core/net/efi/http.c | 82 ++++++++++++++++++++++++++++++++++++------------ - 2 files changed, 71 insertions(+), 21 deletions(-) - -diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c -index d1de9fa6873..1c540fc8c26 100644 ---- a/grub-core/kern/main.c -+++ b/grub-core/kern/main.c -@@ -131,11 +131,19 @@ grub_set_prefix_and_root (void) - if (fwdevice && fwpath) - { - char *fw_path; -+ char separator[3] = ")"; - -- fw_path = grub_xasprintf ("(%s)/%s", fwdevice, fwpath); -+ grub_dprintf ("fw_path", "\n"); -+ grub_dprintf ("fw_path", "fwdevice:\"%s\" fwpath:\"%s\"\n", fwdevice, fwpath); -+ -+ if (!grub_strncmp(fwdevice, "http", 4) && fwpath[0] != '/') -+ grub_strcpy(separator, ")/"); -+ -+ fw_path = grub_xasprintf ("(%s%s%s", fwdevice, separator, fwpath); - if (fw_path) - { - grub_env_set ("fw_path", fw_path); -+ grub_dprintf ("fw_path", "fw_path:\"%s\"\n", fw_path); - grub_free (fw_path); - } - } -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -index 243acbaa35b..de351b2cd03 100644 ---- a/grub-core/net/efi/http.c -+++ b/grub-core/net/efi/http.c -@@ -9,10 +9,52 @@ - static void - http_configure (struct grub_efi_net_device *dev, int prefer_ip6) - { -+ grub_efi_ipv6_address_t address; - grub_efi_http_config_data_t http_config; - grub_efi_httpv4_access_point_t httpv4_node; - grub_efi_httpv6_access_point_t httpv6_node; - grub_efi_status_t status; -+ int https; -+ char *http_url; -+ const char *rest, *http_server, *http_path = NULL; -+ -+ http_server = grub_env_get ("root"); -+ https = (grub_strncmp (http_server, "https", 5) == 0) ? 1 : 0; -+ -+ /* extract http server + port */ -+ if (http_server) -+ { -+ http_server = grub_strchr (http_server, ','); -+ if (http_server) -+ http_server++; -+ } -+ -+ /* fw_path is like (http,192.168.1.1:8000)/httpboot, extract path part */ -+ http_path = grub_env_get ("fw_path"); -+ if (http_path) -+ { -+ http_path = grub_strchr (http_path, ')'); -+ if (http_path) -+ { -+ http_path++; -+ grub_env_unset ("http_path"); -+ grub_env_set ("http_path", http_path); -+ } -+ } -+ -+ if (http_server && http_path) -+ { -+ if (grub_efi_string_to_ip6_address (http_server, &address, &rest) && *rest == 0) -+ http_url = grub_xasprintf ("%s://[%s]%s", https ? "https" : "http", http_server, http_path); -+ else -+ http_url = grub_xasprintf ("%s://%s%s", https ? "https" : "http", http_server, http_path); -+ if (http_url) -+ { -+ grub_env_unset ("http_url"); -+ grub_env_set ("http_url", http_url); -+ grub_free (http_url); -+ } -+ } - - grub_efi_http_t *http = dev->http; - -@@ -352,32 +394,32 @@ grub_efihttp_open (struct grub_efi_net_device *dev, - grub_err_t err; - grub_off_t size; - char *buf; -- char *root_url; -- grub_efi_ipv6_address_t address; -- const char *rest; -+ char *file_name = NULL; -+ const char *http_path; - -- if (grub_efi_string_to_ip6_address (file->device->net->server, &address, &rest) && *rest == 0) -- root_url = grub_xasprintf ("%s://[%s]", type ? "https" : "http", file->device->net->server); -- else -- root_url = grub_xasprintf ("%s://%s", type ? "https" : "http", file->device->net->server); -- if (root_url) -- { -- grub_env_unset ("root_url"); -- grub_env_set ("root_url", root_url); -- grub_free (root_url); -- } -- else -- { -+ /* If path is relative, prepend http_path */ -+ http_path = grub_env_get ("http_path"); -+ if (http_path && file->device->net->name[0] != '/') { -+ file_name = grub_xasprintf ("%s/%s", http_path, file->device->net->name); -+ if (!file_name) - return grub_errno; -- } -+ } - -- err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 1, 0); -+ err = efihttp_request (dev->http, file->device->net->server, -+ file_name ? file_name : file->device->net->name, type, 1, 0); - if (err != GRUB_ERR_NONE) -- return err; -+ { -+ grub_free (file_name); -+ return err; -+ } - -- err = efihttp_request (dev->http, file->device->net->server, file->device->net->name, type, 0, &size); -+ err = efihttp_request (dev->http, file->device->net->server, -+ file_name ? file_name : file->device->net->name, type, 0, &size); -+ grub_free (file_name); - if (err != GRUB_ERR_NONE) -- return err; -+ { -+ return err; -+ } - - buf = grub_malloc (size); - efihttp_read (dev, buf, size); diff --git a/0098-Make-reset-an-alias-for-the-reboot-command.patch b/0098-Make-reset-an-alias-for-the-reboot-command.patch deleted file mode 100644 index c86acf18a627bd3725b89d2a816648fa252dead9..0000000000000000000000000000000000000000 --- a/0098-Make-reset-an-alias-for-the-reboot-command.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 31 Aug 2018 16:42:03 -0400 -Subject: [PATCH] Make "reset" an alias for the "reboot" command. - -I'm really tired of half the tools I get to use having one and the other half -having the other. - -Signed-off-by: Peter Jones ---- - grub-core/commands/reboot.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/grub-core/commands/reboot.c b/grub-core/commands/reboot.c -index 46d364c99a9..f5cc2283636 100644 ---- a/grub-core/commands/reboot.c -+++ b/grub-core/commands/reboot.c -@@ -32,15 +32,18 @@ grub_cmd_reboot (grub_command_t cmd __attribute__ ((unused)), - grub_reboot (); - } - --static grub_command_t cmd; -+static grub_command_t reboot_cmd, reset_cmd; - - GRUB_MOD_INIT(reboot) - { -- cmd = grub_register_command ("reboot", grub_cmd_reboot, -- 0, N_("Reboot the computer.")); -+ reboot_cmd = grub_register_command ("reboot", grub_cmd_reboot, -+ 0, N_("Reboot the computer.")); -+ reset_cmd = grub_register_command ("reset", grub_cmd_reboot, -+ 0, N_("Reboot the computer.")); - } - - GRUB_MOD_FINI(reboot) - { -- grub_unregister_command (cmd); -+ grub_unregister_command (reboot_cmd); -+ grub_unregister_command (reset_cmd); - } diff --git a/0099-Add-a-version-command.patch b/0099-Add-a-version-command.patch deleted file mode 100644 index bf3b4b80794aefacc18b53d758c3943b605ae3bc..0000000000000000000000000000000000000000 --- a/0099-Add-a-version-command.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 11 Sep 2018 14:20:37 -0400 -Subject: [PATCH] Add a "version" command. - -This adds a command that shows you info about grub's version, the grub target -platform, the compiler version, and if you built with ---with-rpm-version=, the rpm package version. - -Signed-off-by: Peter Jones ---- - configure.ac | 13 ++++++++++ - grub-core/Makefile.core.def | 5 ++++ - grub-core/commands/version.c | 56 ++++++++++++++++++++++++++++++++++++++++++++ - config.h.in | 1 + - 4 files changed, 75 insertions(+) - create mode 100644 grub-core/commands/version.c - -diff --git a/configure.ac b/configure.ac -index bb4e05ceef3..59ccda24475 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -312,6 +312,19 @@ AC_SUBST(target_cpu) - AC_SUBST(platform) - - # Define default variables -+have_with_rpm_version=n -+AC_ARG_WITH([rpm_version], -+ AS_HELP_STRING([--with-rpm-version=VERSION], -+ [set the rpm package version [[guessed]]]), -+ [have_with_rpm_version=y], -+ [have_with_rpm_version=n]) -+if test x$have_with_rpm_version = xy; then -+ rpm_version="$with_rpm_version" -+else -+ rpm_version="" -+fi -+GRUB_RPM_VERSION="$rpm_version" -+AC_SUBST(GRUB_RPM_VERSION) - - have_with_bootdir=n - AC_ARG_WITH([bootdir], -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 84a3d89de9a..498ca11762a 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -579,6 +579,11 @@ image = { - enable = mips_loongson; - }; - -+module = { -+ name = version; -+ common = commands/version.c; -+}; -+ - module = { - name = disk; - common = lib/disk.c; -diff --git a/grub-core/commands/version.c b/grub-core/commands/version.c -new file mode 100644 -index 00000000000..f0966a518f7 ---- /dev/null -+++ b/grub-core/commands/version.c -@@ -0,0 +1,56 @@ -+/* version.c - Command to print the grub version and build info. */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2006,2007,2008 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static grub_err_t -+grub_cmd_version (grub_command_t cmd UNUSED, int argc, char **args UNUSED) -+{ -+ if (argc != 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("no arguments expected")); -+ -+ grub_printf (_("GNU GRUB version %s\n"), PACKAGE_VERSION); -+ grub_printf (_("Platform %s-%s\n"), GRUB_TARGET_CPU, GRUB_PLATFORM); -+ if (grub_strlen(GRUB_RPM_VERSION) != 0) -+ grub_printf (_("RPM package version %s\n"), GRUB_RPM_VERSION); -+ grub_printf (_("Compiler version %s\n"), __VERSION__); -+ -+ return 0; -+} -+ -+static grub_command_t cmd; -+ -+GRUB_MOD_INIT(version) -+{ -+ cmd = grub_register_command ("version", grub_cmd_version, NULL, -+ N_("Print version and build information.")); -+} -+ -+GRUB_MOD_FINI(version) -+{ -+ grub_unregister_command (cmd); -+} -diff --git a/config.h.in b/config.h.in -index 9e8f9911b18..c7e316f0f1f 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -59,6 +59,7 @@ - - #define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@" - #define GRUB_PLATFORM "@GRUB_PLATFORM@" -+#define GRUB_RPM_VERSION "@GRUB_RPM_VERSION@" - - #define RE_ENABLE_I18N 1 - diff --git a/0100-Add-more-dprintf-and-nerf-dprintf-in-script.c.patch b/0100-Add-more-dprintf-and-nerf-dprintf-in-script.c.patch deleted file mode 100644 index 9afb315163fc653edba049d5855c497803351e24..0000000000000000000000000000000000000000 --- a/0100-Add-more-dprintf-and-nerf-dprintf-in-script.c.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 11 Sep 2018 15:58:29 -0400 -Subject: [PATCH] Add more dprintf, and nerf dprintf in script.c - -Signed-off-by: Peter Jones ---- - grub-core/disk/diskfilter.c | 3 +++ - grub-core/disk/efi/efidisk.c | 1 + - grub-core/kern/device.c | 1 + - grub-core/script/script.c | 5 +++++ - 4 files changed, 10 insertions(+) - -diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c -index 0320115662f..7cdffe3ebd5 100644 ---- a/grub-core/disk/diskfilter.c -+++ b/grub-core/disk/diskfilter.c -@@ -188,6 +188,8 @@ scan_disk (const char *name, int accept_diskfilter) - grub_disk_t disk; - static int scan_depth = 0; - -+ grub_dprintf ("diskfilter", "scanning %s\n", name); -+ - if (!accept_diskfilter && is_valid_diskfilter_name (name)) - return 0; - -@@ -1212,6 +1214,7 @@ insert_array (grub_disk_t disk, const struct grub_diskfilter_pv_id *id, - the same. */ - if (pv->disk && grub_disk_native_sectors (disk) >= pv->part_size) - return GRUB_ERR_NONE; -+ grub_dprintf ("diskfilter", "checking %s\n", disk->name); - pv->disk = grub_disk_open (disk->name); - if (!pv->disk) - return grub_errno; -diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c -index f077b5f5535..fe8ba6e6c93 100644 ---- a/grub-core/disk/efi/efidisk.c -+++ b/grub-core/disk/efi/efidisk.c -@@ -855,6 +855,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle) - return 0; - } - -+ grub_dprintf ("efidisk", "getting disk for %s\n", device_name); - parent = grub_disk_open (device_name); - grub_free (dup_dp); - -diff --git a/grub-core/kern/device.c b/grub-core/kern/device.c -index 73b8ecc0c09..f58b58c89d5 100644 ---- a/grub-core/kern/device.c -+++ b/grub-core/kern/device.c -@@ -34,6 +34,7 @@ grub_device_open (const char *name) - { - grub_device_t dev = 0; - -+ grub_dprintf ("device", "opening device %s\n", name); - if (! name) - { - name = grub_env_get ("root"); -diff --git a/grub-core/script/script.c b/grub-core/script/script.c -index ec4d4337c66..844e8343ca7 100644 ---- a/grub-core/script/script.c -+++ b/grub-core/script/script.c -@@ -22,6 +22,11 @@ - #include - #include - -+#ifdef grub_dprintf -+#undef grub_dprintf -+#endif -+#define grub_dprintf(no, fmt, ...) -+ - /* It is not possible to deallocate the memory when a syntax error was - found. Because of that it is required to keep track of all memory - allocations. The memory is freed in case of an error, or assigned diff --git a/0103-Attempt-to-fix-up-all-the-places-Wsign-compare-error.patch b/0103-Attempt-to-fix-up-all-the-places-Wsign-compare-error.patch deleted file mode 100644 index e6cd8b477ab779afedf7bcede2cc763d857f386e..0000000000000000000000000000000000000000 --- a/0103-Attempt-to-fix-up-all-the-places-Wsign-compare-error.patch +++ /dev/null @@ -1,213 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 11 Jul 2019 18:03:25 +0200 -Subject: [PATCH] Attempt to fix up all the places -Wsign-compare=error finds. - -Signed-off-by: Peter Jones ---- - grub-core/kern/emu/misc.c | 2 +- - grub-core/lib/reed_solomon.c | 4 ++-- - grub-core/osdep/linux/blocklist.c | 2 +- - grub-core/osdep/linux/getroot.c | 2 +- - grub-core/osdep/linux/hostdisk.c | 2 +- - util/grub-fstest.c | 2 +- - util/grub-menulst2cfg.c | 2 +- - util/grub-mkfont.c | 13 +++++++------ - util/grub-probe.c | 2 +- - util/grub-rpm-sort.c | 2 +- - util/setup.c | 2 +- - 11 files changed, 18 insertions(+), 17 deletions(-) - -diff --git a/grub-core/kern/emu/misc.c b/grub-core/kern/emu/misc.c -index eeea092752d..f08a1bb8415 100644 ---- a/grub-core/kern/emu/misc.c -+++ b/grub-core/kern/emu/misc.c -@@ -189,7 +189,7 @@ grub_util_get_image_size (const char *path) - sz = ftello (f); - if (sz < 0) - grub_util_error (_("cannot open `%s': %s"), path, strerror (errno)); -- if (sz != (size_t) sz) -+ if (sz > (off_t)(GRUB_SIZE_MAX >> 1)) - grub_util_error (_("file `%s' is too big"), path); - ret = (size_t) sz; - -diff --git a/grub-core/lib/reed_solomon.c b/grub-core/lib/reed_solomon.c -index 467305b46ab..79037c093f7 100644 ---- a/grub-core/lib/reed_solomon.c -+++ b/grub-core/lib/reed_solomon.c -@@ -157,7 +157,7 @@ static void - rs_encode (gf_single_t *data, grub_size_t s, grub_size_t rs) - { - gf_single_t *rs_polynomial; -- int i, j; -+ unsigned int i, j; - gf_single_t *m; - m = xcalloc (s + rs, sizeof (gf_single_t)); - grub_memcpy (m, data, s * sizeof (gf_single_t)); -@@ -324,7 +324,7 @@ static void - encode_block (gf_single_t *ptr, grub_size_t s, - gf_single_t *rptr, grub_size_t rs) - { -- int i, j; -+ unsigned int i, j; - for (i = 0; i < SECTOR_SIZE; i++) - { - grub_size_t ds = (s + SECTOR_SIZE - 1 - i) / SECTOR_SIZE; -diff --git a/grub-core/osdep/linux/blocklist.c b/grub-core/osdep/linux/blocklist.c -index c77d6085ccb..42a315031ff 100644 ---- a/grub-core/osdep/linux/blocklist.c -+++ b/grub-core/osdep/linux/blocklist.c -@@ -109,7 +109,7 @@ grub_install_get_blocklist (grub_device_t root_dev, - else - { - struct fiemap *fie2; -- int i; -+ unsigned int i; - fie2 = xmalloc (sizeof (*fie2) - + fie1.fm_mapped_extents - * sizeof (fie1.fm_extents[1])); -diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c -index 28790307e00..9f730b35189 100644 ---- a/grub-core/osdep/linux/getroot.c -+++ b/grub-core/osdep/linux/getroot.c -@@ -236,7 +236,7 @@ grub_find_root_devices_from_btrfs (const char *dir) - { - int fd; - struct btrfs_ioctl_fs_info_args fsi; -- int i, j = 0; -+ unsigned int i, j = 0; - char **ret; - - fd = open (dir, 0); -diff --git a/grub-core/osdep/linux/hostdisk.c b/grub-core/osdep/linux/hostdisk.c -index da62f924e35..7bc99ac1c1d 100644 ---- a/grub-core/osdep/linux/hostdisk.c -+++ b/grub-core/osdep/linux/hostdisk.c -@@ -83,7 +83,7 @@ grub_util_get_fd_size_os (grub_util_fd_t fd, const char *name, unsigned *log_sec - if (sector_size & (sector_size - 1) || !sector_size) - return -1; - for (log_sector_size = 0; -- (1 << log_sector_size) < sector_size; -+ (1U << log_sector_size) < sector_size; - log_sector_size++); - - if (log_secsize) -diff --git a/util/grub-fstest.c b/util/grub-fstest.c -index 83865642009..bfcef852d83 100644 ---- a/util/grub-fstest.c -+++ b/util/grub-fstest.c -@@ -323,7 +323,7 @@ cmd_cmp (char *src, char *dest) - read_file (src, cmp_hook, ff); - - { -- grub_uint64_t pre; -+ long long pre; - pre = ftell (ff); - fseek (ff, 0, SEEK_END); - if (pre != ftell (ff)) -diff --git a/util/grub-menulst2cfg.c b/util/grub-menulst2cfg.c -index a39f8693947..358d604210b 100644 ---- a/util/grub-menulst2cfg.c -+++ b/util/grub-menulst2cfg.c -@@ -34,7 +34,7 @@ main (int argc, char **argv) - char *buf = NULL; - size_t bufsize = 0; - char *suffix = xstrdup (""); -- int suffixlen = 0; -+ size_t suffixlen = 0; - const char *out_fname = 0; - - grub_util_host_init (&argc, &argv); -diff --git a/util/grub-mkfont.c b/util/grub-mkfont.c -index 0fe45a6103d..3e09240b99f 100644 ---- a/util/grub-mkfont.c -+++ b/util/grub-mkfont.c -@@ -138,7 +138,8 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, - int width, height; - int cuttop, cutbottom, cutleft, cutright; - grub_uint8_t *data; -- int mask, i, j, bitmap_size; -+ int mask, i, bitmap_size; -+ unsigned int j; - FT_GlyphSlot glyph; - int flag = FT_LOAD_RENDER | FT_LOAD_MONOCHROME; - FT_Error err; -@@ -183,7 +184,7 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, - cuttop = cutbottom = cutleft = cutright = 0; - else - { -- for (cuttop = 0; cuttop < glyph->bitmap.rows; cuttop++) -+ for (cuttop = 0; cuttop < (long)glyph->bitmap.rows; cuttop++) - { - for (j = 0; j < glyph->bitmap.width; j++) - if (glyph->bitmap.buffer[j / 8 + cuttop * glyph->bitmap.pitch] -@@ -203,10 +204,10 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, - break; - } - cutbottom = glyph->bitmap.rows - 1 - cutbottom; -- if (cutbottom + cuttop >= glyph->bitmap.rows) -+ if (cutbottom + cuttop >= (long)glyph->bitmap.rows) - cutbottom = 0; - -- for (cutleft = 0; cutleft < glyph->bitmap.width; cutleft++) -+ for (cutleft = 0; cutleft < (long)glyph->bitmap.width; cutleft++) - { - for (j = 0; j < glyph->bitmap.rows; j++) - if (glyph->bitmap.buffer[cutleft / 8 + j * glyph->bitmap.pitch] -@@ -225,7 +226,7 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, - break; - } - cutright = glyph->bitmap.width - 1 - cutright; -- if (cutright + cutleft >= glyph->bitmap.width) -+ if (cutright + cutleft >= (long)glyph->bitmap.width) - cutright = 0; - } - -@@ -262,7 +263,7 @@ add_glyph (struct grub_font_info *font_info, FT_UInt glyph_idx, FT_Face face, - - mask = 0; - data = &glyph_info->bitmap[0] - 1; -- for (j = cuttop; j < height + cuttop; j++) -+ for (j = cuttop; j < (long)height + cuttop; j++) - for (i = cutleft; i < width + cutleft; i++) - add_pixel (&data, &mask, - glyph->bitmap.buffer[i / 8 + j * glyph->bitmap.pitch] & -diff --git a/util/grub-probe.c b/util/grub-probe.c -index c08e46bbb40..c6fac732b40 100644 ---- a/util/grub-probe.c -+++ b/util/grub-probe.c -@@ -798,7 +798,7 @@ argp_parser (int key, char *arg, struct argp_state *state) - - case 't': - { -- int i; -+ unsigned int i; - - for (i = PRINT_FS; i < ARRAY_SIZE (targets); i++) - if (strcmp (arg, targets[i]) == 0) -diff --git a/util/grub-rpm-sort.c b/util/grub-rpm-sort.c -index f33bd1ed568..8345944105f 100644 ---- a/util/grub-rpm-sort.c -+++ b/util/grub-rpm-sort.c -@@ -232,7 +232,7 @@ main (int argc, char *argv[]) - struct arguments arguments; - char **package_names = NULL; - size_t n_package_names = 0; -- int i; -+ unsigned int i; - - grub_util_host_init (&argc, &argv); - -diff --git a/util/setup.c b/util/setup.c -index da5f2c07f50..8b22bb8ccac 100644 ---- a/util/setup.c -+++ b/util/setup.c -@@ -406,7 +406,7 @@ SETUP (const char *dir, - int is_ldm; - grub_err_t err; - grub_disk_addr_t *sectors; -- int i; -+ unsigned int i; - grub_fs_t fs; - unsigned int nsec, maxsec; - diff --git a/0104-Don-t-use-Wno-sign-compare-Wno-conversion-Wno-error-.patch b/0104-Don-t-use-Wno-sign-compare-Wno-conversion-Wno-error-.patch deleted file mode 100644 index 1fa705e68c8581cc2242a39b86766c5631b8e2d7..0000000000000000000000000000000000000000 --- a/0104-Don-t-use-Wno-sign-compare-Wno-conversion-Wno-error-.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 11 Jul 2019 18:20:37 +0200 -Subject: [PATCH] Don't use -Wno-sign-compare -Wno-conversion -Wno-error, do - use -Wextra. - -Signed-off-by: Peter Jones ---- - configure.ac | 14 +++++++++++--- - conf/Makefile.common | 2 +- - 2 files changed, 12 insertions(+), 4 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 59ccda24475..6eb297fdbf6 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1480,11 +1480,11 @@ fi - # Set them to their new values for the tests below. - CC="$TARGET_CC" - if test x"$platform" = xemu ; then --CFLAGS="$TARGET_CFLAGS -Wno-error" -+CFLAGS="$TARGET_CFLAGS" - elif test "x$TARGET_APPLE_LINKER" = x1 ; then --CFLAGS="$TARGET_CFLAGS -nostdlib -static -Wno-error" -+CFLAGS="$TARGET_CFLAGS -nostdlib -static" - else --CFLAGS="$TARGET_CFLAGS -nostdlib -Wno-error" -+CFLAGS="$TARGET_CFLAGS -nostdlib" - fi - CPPFLAGS="$TARGET_CPPFLAGS" - -@@ -2047,6 +2047,14 @@ if test x"$enable_werror" != xno ; then - HOST_CFLAGS="$HOST_CFLAGS -Werror" - fi - -+AC_ARG_ENABLE([wextra], -+ [AS_HELP_STRING([--disable-wextra], -+ [do not use -Wextra when building GRUB])]) -+if test x"$enable_wextra" != xno ; then -+ TARGET_CFLAGS="$TARGET_CFLAGS -Wextra" -+ HOST_CFLAGS="$HOST_CFLAGS -Wextra" -+fi -+ - TARGET_CPP="$TARGET_CC -E" - TARGET_CCAS=$TARGET_CC - -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 2ff9b39357c..35e14ff017e 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -66,7 +66,7 @@ grubconfdir = $(sysconfdir)/grub.d - platformdir = $(pkglibdir)/$(target_cpu)-$(platform) - starfielddir = $(pkgdatadir)/themes/starfield - --CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion -+CFLAGS_GNULIB = -Wno-undef -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code - CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/lib/gnulib -I$(top_srcdir)/grub-core/lib/gnulib - - CFLAGS_POSIX = -fno-builtin diff --git a/0109-Fix-getroot.c-s-trampolines.patch b/0109-Fix-getroot.c-s-trampolines.patch deleted file mode 100644 index 29ec44c9861955c3e1060409e2af923d4616e35c..0000000000000000000000000000000000000000 --- a/0109-Fix-getroot.c-s-trampolines.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 28 Sep 2018 15:42:19 -0400 -Subject: [PATCH] Fix getroot.c's trampolines. - -This makes the stack executable on most of the grub utilities, which is -bad, and rpmdiff complains about it. - -Signed-off-by: Peter Jones ---- - grub-core/osdep/linux/getroot.c | 16 +++++++--------- - 1 file changed, 7 insertions(+), 9 deletions(-) - -diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c -index 9f730b35189..f0c503f43d3 100644 ---- a/grub-core/osdep/linux/getroot.c -+++ b/grub-core/osdep/linux/getroot.c -@@ -1264,22 +1264,20 @@ grub_util_get_grub_dev_os (const char *os_dev) - return grub_dev; - } - -+static void *mp = NULL; -+static void -+btrfs_mount_path_hook(const char *m) -+{ -+ mp = strdup (m); -+} - - char * - grub_util_get_btrfs_subvol (const char *path, char **mount_path) - { -- char *mp = NULL; -- - if (mount_path) - *mount_path = NULL; - -- auto void -- mount_path_hook (const char *m) -- { -- mp = strdup (m); -- } -- -- grub_find_root_btrfs_mount_path_hook = mount_path_hook; -+ grub_find_root_btrfs_mount_path_hook = btrfs_mount_path_hook; - grub_free (grub_find_root_devices_from_mountinfo (path, NULL)); - grub_find_root_btrfs_mount_path_hook = NULL; - diff --git a/0110-Do-not-allow-stack-trampolines-anywhere.patch b/0110-Do-not-allow-stack-trampolines-anywhere.patch deleted file mode 100644 index 2a3247af9705fb621e66000060a03b126dbd34d3..0000000000000000000000000000000000000000 --- a/0110-Do-not-allow-stack-trampolines-anywhere.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 12 Jul 2019 10:06:50 +0200 -Subject: [PATCH] Do not allow stack trampolines, anywhere. - -Signed-off-by: Peter Jones ---- - configure.ac | 3 +++ - conf/Makefile.common | 2 +- - 2 files changed, 4 insertions(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 6eb297fdbf6..c6bd965f1f9 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -2055,6 +2055,9 @@ if test x"$enable_wextra" != xno ; then - HOST_CFLAGS="$HOST_CFLAGS -Wextra" - fi - -+TARGET_CFLAGS="$TARGET_CFLAGS -Werror=trampolines -fno-trampolines" -+HOST_CFLAGS="$HOST_CFLAGS -Werror=trampolines -fno-trampolines" -+ - TARGET_CPP="$TARGET_CC -E" - TARGET_CCAS=$TARGET_CC - -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 35e14ff017e..0647c53b916 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -66,7 +66,7 @@ grubconfdir = $(sysconfdir)/grub.d - platformdir = $(pkglibdir)/$(target_cpu)-$(platform) - starfielddir = $(pkgdatadir)/themes/starfield - --CFLAGS_GNULIB = -Wno-undef -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -+CFLAGS_GNULIB = -Wno-undef -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Werror=trampolines -fno-trampolines - CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/lib/gnulib -I$(top_srcdir)/grub-core/lib/gnulib - - CFLAGS_POSIX = -fno-builtin diff --git a/0111-Reimplement-boot_counter.patch b/0111-Reimplement-boot_counter.patch deleted file mode 100644 index a203929f1a193c0119330975e4529aaef818e54c..0000000000000000000000000000000000000000 --- a/0111-Reimplement-boot_counter.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 4 Oct 2018 14:22:09 -0400 -Subject: [PATCH] Reimplement boot_counter - -This adds "increment" and "decrement" commands, and uses them to maintain our -variables in 01_fallback_counter. It also simplifies the counter logic, so -that there are no nested tests that conflict with each other. - -Apparently, this *really* wasn't tested well enough. - -Resolves: rhbz#1614637 -Signed-off-by: Peter Jones -[lorbus: add comments and revert logic changes in 01_fallback_counting] -Signed-off-by: Christian Glombek ---- - Makefile.util.def | 6 +++ - grub-core/Makefile.core.def | 5 ++ - grub-core/commands/increment.c | 105 ++++++++++++++++++++++++++++++++++++ - util/grub.d/01_fallback_counting.in | 22 ++++++++ - 4 files changed, 138 insertions(+) - create mode 100644 grub-core/commands/increment.c - create mode 100644 util/grub.d/01_fallback_counting.in - -diff --git a/Makefile.util.def b/Makefile.util.def -index 0b85a7fce4a..27a13bc734e 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -458,6 +458,12 @@ script = { - installdir = grubconf; - }; - -+script = { -+ name = '01_fallback_counting'; -+ common = util/grub.d/01_fallback_counting.in; -+ installdir = grubconf; -+}; -+ - script = { - name = '01_menu_auto_hide'; - common = util/grub.d/01_menu_auto_hide.in; -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 498ca11762a..1e15345107e 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -398,6 +398,11 @@ kernel = { - extra_dist = kern/mips/cache_flush.S; - }; - -+module = { -+ name = increment; -+ common = commands/increment.c; -+}; -+ - program = { - name = grub-emu; - mansection = 1; -diff --git a/grub-core/commands/increment.c b/grub-core/commands/increment.c -new file mode 100644 -index 00000000000..79cf137656c ---- /dev/null -+++ b/grub-core/commands/increment.c -@@ -0,0 +1,105 @@ -+/* increment.c - Commands to increment and decrement variables. */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2006,2007,2008 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+typedef enum { -+ INCREMENT, -+ DECREMENT, -+} operation; -+ -+static grub_err_t -+incr_decr(operation op, int argc, char **args) -+{ -+ const char *old; -+ char *new; -+ long value; -+ -+ if (argc < 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("no variable specified")); -+ if (argc > 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_ ("too many arguments")); -+ -+ old = grub_env_get (*args); -+ if (!old) -+ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("No such variable \"%s\""), -+ *args); -+ -+ value = grub_strtol (old, NULL, 0); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; -+ -+ switch (op) -+ { -+ case INCREMENT: -+ value += 1; -+ break; -+ case DECREMENT: -+ value -= 1; -+ break; -+ } -+ -+ new = grub_xasprintf ("%ld", value); -+ if (!new) -+ return grub_errno; -+ -+ grub_env_set (*args, new); -+ grub_free (new); -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_cmd_incr(struct grub_command *cmd UNUSED, -+ int argc, char **args) -+{ -+ return incr_decr(INCREMENT, argc, args); -+} -+ -+static grub_err_t -+grub_cmd_decr(struct grub_command *cmd UNUSED, -+ int argc, char **args) -+{ -+ return incr_decr(DECREMENT, argc, args); -+} -+ -+static grub_command_t cmd_incr, cmd_decr; -+ -+GRUB_MOD_INIT(increment) -+{ -+ cmd_incr = grub_register_command ("increment", grub_cmd_incr, N_("VARIABLE"), -+ N_("increment VARIABLE")); -+ cmd_decr = grub_register_command ("decrement", grub_cmd_decr, N_("VARIABLE"), -+ N_("decrement VARIABLE")); -+} -+ -+GRUB_MOD_FINI(increment) -+{ -+ grub_unregister_command (cmd_incr); -+ grub_unregister_command (cmd_decr); -+} -diff --git a/util/grub.d/01_fallback_counting.in b/util/grub.d/01_fallback_counting.in -new file mode 100644 -index 00000000000..be0e770ea82 ---- /dev/null -+++ b/util/grub.d/01_fallback_counting.in -@@ -0,0 +1,22 @@ -+#! /bin/sh -e -+ -+# Boot Counting -+# The boot_counter env var can be used to count down boot attempts after an -+# OSTree upgrade and choose the rollback deployment when 0 is reached. Both -+# boot_counter and boot_success need to be (re-)set from userspace. -+cat << EOF -+insmod increment -+# Check if boot_counter exists and boot_success=0 to activate this behaviour. -+if [ -n "\${boot_counter}" -a "\${boot_success}" = "0" ]; then -+ # if countdown has ended, choose to boot rollback deployment (default=1 on -+ # OSTree-based systems) -+ if [ "\${boot_counter}" = "0" -o "\${boot_counter}" = "-1" ]; then -+ set default=1 -+ set boot_counter=-1 -+ # otherwise decrement boot_counter -+ else -+ decrement boot_counter -+ fi -+ save_env boot_counter -+fi -+EOF diff --git a/0112-Fix-menu-entry-selection-based-on-ID-and-title.patch b/0112-Fix-menu-entry-selection-based-on-ID-and-title.patch deleted file mode 100644 index 957fda38c2fc97a96d5422873c82b84983bc47dc..0000000000000000000000000000000000000000 --- a/0112-Fix-menu-entry-selection-based-on-ID-and-title.patch +++ /dev/null @@ -1,233 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 19 Oct 2018 10:57:52 -0400 -Subject: [PATCH] Fix menu entry selection based on ID and title - -Currently if grub_strtoul(saved_entry_value, NULL, 0) does not return an -error, we assume the value it has produced is a correct index into our -menu entry list, and do not try to interpret the value as the "id" or -"title" . In cases where "id" or "title" start with a numeral, this -makes them impossible to use as selection criteria. - -This patch splits the search into three phases - matching id, matching -title, and only once those have been exhausted, trying to interpret the -ID as a numeral. In that case, we also require that the entire string -is numeric, not merely a string with leading numeric characters. - -Resolves: rhbz#1640979 - -Signed-off-by: Peter Jones -[javierm: fix menu entry selection based on title] -Signed-off-by: Javier Martinez Canillas ---- - grub-core/normal/menu.c | 141 ++++++++++++++++++++++++------------------------ - 1 file changed, 71 insertions(+), 70 deletions(-) - -diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c -index d7a222e681b..4a02aadb01c 100644 ---- a/grub-core/normal/menu.c -+++ b/grub-core/normal/menu.c -@@ -164,12 +164,12 @@ grub_menu_set_timeout (int timeout) - } - - static int --menuentry_eq (const char *id, const char *spec) -+menuentry_eq (const char *id, const char *spec, int limit) - { - const char *ptr1, *ptr2; - ptr1 = id; - ptr2 = spec; -- while (1) -+ while (limit == -1 || ptr1 - id <= limit) - { - if (*ptr2 == '>' && ptr2[1] != '>' && *ptr1 == 0) - return ptr2 - spec; -@@ -178,7 +178,11 @@ menuentry_eq (const char *id, const char *spec) - if (*ptr2 == '>') - ptr2++; - if (*ptr1 != *ptr2) -- return 0; -+ { -+ if (limit > -1 && ptr1 - id == limit && !*ptr1 && grub_isspace(*ptr2)) -+ return ptr1 -id -1; -+ return 0; -+ } - if (*ptr1 == 0) - return ptr1 - id; - ptr1++; -@@ -187,6 +191,58 @@ menuentry_eq (const char *id, const char *spec) - return 0; - } - -+static int -+get_entry_number_helper(grub_menu_t menu, -+ const char * const val, const char ** const tail) -+{ -+ /* See if the variable matches the title of a menu entry. */ -+ int entry = -1; -+ grub_menu_entry_t e; -+ int i; -+ -+ for (i = 0, e = menu->entry_list; e; i++) -+ { -+ int l = 0; -+ while (val[l] && !grub_isspace(val[l])) -+ l++; -+ -+ if (menuentry_eq (e->id, val, l)) -+ { -+ if (tail) -+ *tail = val + l; -+ return i; -+ } -+ e = e->next; -+ } -+ -+ for (i = 0, e = menu->entry_list; e; i++) -+ { -+ -+ if (menuentry_eq (e->title, val, -1)) -+ { -+ if (tail) -+ *tail = NULL; -+ return i; -+ } -+ e = e->next; -+ } -+ -+ if (tail) -+ *tail = NULL; -+ -+ entry = (int) grub_strtoul (val, tail, 0); -+ if (grub_errno == GRUB_ERR_BAD_NUMBER || -+ (*tail && **tail && !grub_isspace(**tail))) -+ { -+ entry = -1; -+ if (tail) -+ *tail = NULL; -+ grub_errno = GRUB_ERR_NONE; -+ } -+ -+ return entry; -+} -+ - /* Get the first entry number from the value of the environment variable NAME, - which is a space-separated list of non-negative integers. The entry number - which is returned is stripped from the value of NAME. If no entry number -@@ -196,7 +252,6 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char *name) - { - const char *val, *tail; - int entry; -- int sz = 0; - - val = grub_env_get (name); - if (! val) -@@ -204,50 +259,24 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char *name) - - grub_error_push (); - -- entry = (int) grub_strtoul (val, &tail, 0); -+ entry = get_entry_number_helper(menu, val, &tail); -+ if (!(*tail == 0 || grub_isspace(*tail))) -+ entry = -1; - -- if (grub_errno == GRUB_ERR_BAD_NUMBER) -+ if (entry >= 0) - { -- /* See if the variable matches the title of a menu entry. */ -- grub_menu_entry_t e = menu->entry_list; -- int i; -- -- for (i = 0; e; i++) -- { -- sz = menuentry_eq (e->title, val); -- if (sz < 1) -- sz = menuentry_eq (e->id, val); -- -- if (sz >= 1) -- { -- entry = i; -- break; -- } -- e = e->next; -- } -- -- if (sz > 0) -- grub_errno = GRUB_ERR_NONE; -- -- if (! e) -- entry = -1; -- } -- -- if (grub_errno == GRUB_ERR_NONE) -- { -- if (sz > 0) -- tail += sz; -- - /* Skip whitespace to find the next entry. */ - while (*tail && grub_isspace (*tail)) - tail++; -- grub_env_set (name, tail); -+ if (*tail) -+ grub_env_set (name, tail); -+ else -+ grub_env_unset (name); - } - else - { - grub_env_unset (name); - grub_errno = GRUB_ERR_NONE; -- entry = -1; - } - - grub_error_pop (); -@@ -524,6 +553,7 @@ static int - get_entry_number (grub_menu_t menu, const char *name) - { - const char *val; -+ const char *tail; - int entry; - - val = grub_env_get (name); -@@ -531,38 +561,9 @@ get_entry_number (grub_menu_t menu, const char *name) - return -1; - - grub_error_push (); -- -- entry = (int) grub_strtoul (val, 0, 0); -- -- if (grub_errno == GRUB_ERR_BAD_NUMBER) -- { -- /* See if the variable matches the title of a menu entry. */ -- grub_menu_entry_t e = menu->entry_list; -- int i; -- -- grub_errno = GRUB_ERR_NONE; -- -- for (i = 0; e; i++) -- { -- if (menuentry_eq (e->title, val) -- || menuentry_eq (e->id, val)) -- { -- entry = i; -- break; -- } -- e = e->next; -- } -- -- if (! e) -- entry = -1; -- } -- -- if (grub_errno != GRUB_ERR_NONE) -- { -- grub_errno = GRUB_ERR_NONE; -- entry = -1; -- } -- -+ entry = get_entry_number_helper(menu, val, &tail); -+ if (tail && *tail != '\0') -+ entry = -1; - grub_error_pop (); - - return entry; diff --git a/0113-Make-the-menu-entry-users-option-argument-to-be-opti.patch b/0113-Make-the-menu-entry-users-option-argument-to-be-opti.patch deleted file mode 100644 index e0d36db797811eb41c4bc2607ab588d0c985ce38..0000000000000000000000000000000000000000 --- a/0113-Make-the-menu-entry-users-option-argument-to-be-opti.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Mon, 26 Nov 2018 10:06:42 +0100 -Subject: [PATCH] Make the menu entry users option argument to be optional - -The --users option is used to restrict the access to specific menu entries -only to a set of users. But the option requires an argument to either be a -constant or a variable that has been set. So for example the following: - - menuentry "May be run by superusers or users in $users" --users $users { - linux /vmlinuz - } - -Would fail if $users is not defined and grub would discard the menu entry. -Instead, allow the --users option to have an optional argument and ignore -the option if the argument was not set. - -Related: rhbz#1652434 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/commands/menuentry.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/commands/menuentry.c b/grub-core/commands/menuentry.c -index b194123eb67..b175a1b43b7 100644 ---- a/grub-core/commands/menuentry.c -+++ b/grub-core/commands/menuentry.c -@@ -29,7 +29,7 @@ static const struct grub_arg_option options[] = - { - {"class", 1, GRUB_ARG_OPTION_REPEATABLE, - N_("Menu entry type."), N_("STRING"), ARG_TYPE_STRING}, -- {"users", 2, 0, -+ {"users", 2, GRUB_ARG_OPTION_OPTIONAL, - N_("List of users allowed to boot this entry."), N_("USERNAME[,USERNAME]"), - ARG_TYPE_STRING}, - {"hotkey", 3, 0, -@@ -281,7 +281,7 @@ grub_cmd_menuentry (grub_extcmd_context_t ctxt, int argc, char **args) - if (! ctxt->state[3].set && ! ctxt->script) - return grub_error (GRUB_ERR_BAD_ARGUMENT, "no menuentry definition"); - -- if (ctxt->state[1].set) -+ if (ctxt->state[1].set && ctxt->state[1].arg) - users = ctxt->state[1].arg; - else if (ctxt->state[5].set) - users = NULL; diff --git a/0114-Add-efi-export-env-and-efi-load-env-commands.patch b/0114-Add-efi-export-env-and-efi-load-env-commands.patch deleted file mode 100644 index 73456bc94c8a9bd9191cb7664eaf6a9754fd8ce3..0000000000000000000000000000000000000000 --- a/0114-Add-efi-export-env-and-efi-load-env-commands.patch +++ /dev/null @@ -1,346 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 16 Jan 2019 13:21:46 -0500 -Subject: [PATCH] Add efi-export-env and efi-load-env commands - -This adds "efi-export-env VARIABLE" and "efi-load-env", which manipulate the -environment block stored in the EFI variable -GRUB_ENV-91376aff-cba6-42be-949d-06fde81128e8. - -Signed-off-by: Peter Jones ---- - grub-core/Makefile.core.def | 6 ++ - grub-core/commands/efi/env.c | 168 +++++++++++++++++++++++++++++++++++++++++++ - grub-core/kern/efi/efi.c | 3 + - grub-core/kern/efi/init.c | 5 -- - grub-core/lib/envblk.c | 43 +++++++++++ - util/grub-set-bootflag.c | 1 + - include/grub/efi/efi.h | 5 ++ - include/grub/lib/envblk.h | 3 + - 8 files changed, 229 insertions(+), 5 deletions(-) - create mode 100644 grub-core/commands/efi/env.c - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 1e15345107e..81fc274148e 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -820,6 +820,12 @@ module = { - enable = efi; - }; - -+module = { -+ name = efienv; -+ common = commands/efi/env.c; -+ enable = efi; -+}; -+ - module = { - name = efifwsetup; - efi = commands/efi/efifwsetup.c; -diff --git a/grub-core/commands/efi/env.c b/grub-core/commands/efi/env.c -new file mode 100644 -index 00000000000..cbd13e03e81 ---- /dev/null -+++ b/grub-core/commands/efi/env.c -@@ -0,0 +1,168 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2012 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 . -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+static const grub_efi_guid_t grub_env_guid = GRUB_EFI_GRUB_VARIABLE_GUID; -+ -+static grub_err_t -+grub_efi_export_env(grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[]) -+{ -+ const char *value; -+ char *old_value; -+ struct grub_envblk envblk_s = { NULL, 0 }; -+ grub_envblk_t envblk = &envblk_s; -+ grub_err_t err; -+ int changed = 1; -+ grub_efi_status_t status; -+ -+ grub_dprintf ("efienv", "argc:%d\n", argc); -+ for (int i = 0; i < argc; i++) -+ grub_dprintf ("efienv", "argv[%d]: %s\n", i, argv[i]); -+ -+ if (argc != 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("variable name expected")); -+ -+ grub_efi_get_variable ("GRUB_ENV", &grub_env_guid, &envblk_s.size, -+ (void **) &envblk_s.buf); -+ if (!envblk_s.buf || envblk_s.size < 1) -+ { -+ char *buf = grub_malloc (1025); -+ if (!buf) -+ return grub_errno; -+ -+ grub_memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1); -+ grub_memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', -+ DEFAULT_ENVBLK_SIZE - sizeof (GRUB_ENVBLK_SIGNATURE) + 1); -+ buf[1024] = '\0'; -+ -+ envblk_s.buf = buf; -+ envblk_s.size = 1024; -+ } -+ else -+ { -+ char *buf = grub_realloc (envblk_s.buf, envblk_s.size + 1); -+ if (!buf) -+ return grub_errno; -+ -+ envblk_s.buf = buf; -+ envblk_s.buf[envblk_s.size] = '\0'; -+ } -+ -+ err = grub_envblk_get(envblk, argv[0], &old_value); -+ if (err != GRUB_ERR_NONE) -+ { -+ grub_dprintf ("efienv", "grub_envblk_get returned %d\n", err); -+ return err; -+ } -+ -+ value = grub_env_get(argv[0]); -+ if ((!value && !old_value) || -+ (value && old_value && !grub_strcmp(old_value, value))) -+ changed = 0; -+ -+ if (old_value) -+ grub_free(old_value); -+ -+ if (changed == 0) -+ { -+ grub_dprintf ("efienv", "No changes necessary\n"); -+ return 0; -+ } -+ -+ if (value) -+ { -+ grub_dprintf ("efienv", "setting \"%s\" to \"%s\"\n", argv[0], value); -+ grub_envblk_set(envblk, argv[0], value); -+ } -+ else -+ { -+ grub_dprintf ("efienv", "deleting \"%s\" from envblk\n", argv[0]); -+ grub_envblk_delete(envblk, argv[0]); -+ } -+ -+ grub_dprintf ("efienv", "envblk is %lu bytes:\n\"%s\"\n", envblk_s.size, envblk_s.buf); -+ -+ grub_dprintf ("efienv", "removing GRUB_ENV\n"); -+ status = grub_efi_set_variable ("GRUB_ENV", &grub_env_guid, NULL, 0); -+ if (status != GRUB_EFI_SUCCESS) -+ grub_dprintf ("efienv", "removal returned %ld\n", status); -+ -+ grub_dprintf ("efienv", "setting GRUB_ENV\n"); -+ status = grub_efi_set_variable ("GRUB_ENV", &grub_env_guid, -+ envblk_s.buf, envblk_s.size); -+ if (status != GRUB_EFI_SUCCESS) -+ grub_dprintf ("efienv", "setting GRUB_ENV returned %ld\n", status); -+ -+ return 0; -+} -+ -+static int -+set_var (const char *name, const char *value, -+ void *whitelist __attribute__((__unused__))) -+{ -+ grub_env_set (name, value); -+ return 0; -+} -+ -+static grub_err_t -+grub_efi_load_env(grub_command_t cmd __attribute__ ((unused)), -+ int argc, char *argv[] __attribute__((__unused__))) -+{ -+ struct grub_envblk envblk_s = { NULL, 0 }; -+ grub_envblk_t envblk = &envblk_s; -+ -+ grub_efi_get_variable ("GRUB_ENV", &grub_env_guid, &envblk_s.size, -+ (void **) &envblk_s.buf); -+ if (!envblk_s.buf || envblk_s.size < 1) -+ return 0; -+ -+ if (argc > 0) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("unexpected argument")); -+ -+ grub_envblk_iterate (envblk, NULL, set_var); -+ grub_free (envblk_s.buf); -+} -+ -+static grub_command_t export_cmd, loadenv_cmd; -+ -+GRUB_MOD_INIT(lsefi) -+{ -+ export_cmd = grub_register_command ("efi-export-env", grub_efi_export_env, -+ N_("VARIABLE_NAME"), N_("Export environment variable to UEFI.")); -+ loadenv_cmd = grub_register_command ("efi-load-env", grub_efi_load_env, -+ NULL, N_("Load the grub environment from UEFI.")); -+} -+ -+GRUB_MOD_FINI(lsefi) -+{ -+ grub_unregister_command (export_cmd); -+ grub_unregister_command (loadenv_cmd); -+} -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 2a446f5031b..14bc10eb564 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -225,6 +225,9 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid, - if (status == GRUB_EFI_SUCCESS) - return GRUB_ERR_NONE; - -+ if (status == GRUB_EFI_NOT_FOUND && datasize == 0) -+ return GRUB_ERR_NONE; -+ - return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var); - } - -diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c -index 2d12e6188fd..0574d8d6217 100644 ---- a/grub-core/kern/efi/init.c -+++ b/grub-core/kern/efi/init.c -@@ -85,11 +85,6 @@ stack_protector_init (void) - - grub_addr_t grub_modbase; - --#define GRUB_EFI_GRUB_VARIABLE_GUID \ -- { 0x91376aff, 0xcba6, 0x42be, \ -- { 0x94, 0x9d, 0x06, 0xfd, 0xe8, 0x11, 0x28, 0xe8 } \ -- } -- - /* Helper for grub_efi_env_init */ - static int - set_var (const char *name, const char *value, -diff --git a/grub-core/lib/envblk.c b/grub-core/lib/envblk.c -index 2e4e78b132d..874506da169 100644 ---- a/grub-core/lib/envblk.c -+++ b/grub-core/lib/envblk.c -@@ -223,6 +223,49 @@ grub_envblk_delete (grub_envblk_t envblk, const char *name) - } - } - -+struct get_var_state { -+ const char * const name; -+ char * value; -+ int found; -+}; -+ -+static int -+get_var (const char * const name, const char * const value, void *statep) -+{ -+ struct get_var_state *state = (struct get_var_state *)statep; -+ -+ if (!grub_strcmp(state->name, name)) -+ { -+ state->found = 1; -+ state->value = grub_strdup(value); -+ if (!state->value) -+ grub_errno = grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ -+ return 1; -+ } -+ -+ return 0; -+} -+ -+grub_err_t -+grub_envblk_get (grub_envblk_t envblk, const char * const name, char ** const value) -+{ -+ struct get_var_state state = { -+ .name = name, -+ .value = NULL, -+ .found = 0, -+ }; -+ -+ grub_envblk_iterate(envblk, (void *)&state, get_var); -+ -+ *value = state.value; -+ -+ if (state.found && !state.value) -+ return grub_errno; -+ -+ return GRUB_ERR_NONE; -+} -+ - void - grub_envblk_iterate (grub_envblk_t envblk, - void *hook_data, -diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c -index bb198f02351..6a79ee67444 100644 ---- a/util/grub-set-bootflag.c -+++ b/util/grub-set-bootflag.c -@@ -25,6 +25,7 @@ - - #include /* For *_DIR_NAME defines */ - #include -+#include - #include /* For GRUB_ENVBLK_DEFCFG define */ - #include - #include -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 2e0691454b1..8dfc89a33b9 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -24,6 +24,11 @@ - #include - #include - -+#define GRUB_EFI_GRUB_VARIABLE_GUID \ -+ { 0x91376aff, 0xcba6, 0x42be, \ -+ { 0x94, 0x9d, 0x06, 0xfd, 0xe8, 0x11, 0x28, 0xe8 } \ -+ } -+ - /* Variables. */ - extern grub_efi_system_table_t *EXPORT_VAR(grub_efi_system_table); - extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); -diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h -index c3e65592170..ab969af2461 100644 ---- a/include/grub/lib/envblk.h -+++ b/include/grub/lib/envblk.h -@@ -22,6 +22,8 @@ - #define GRUB_ENVBLK_SIGNATURE "# GRUB Environment Block\n" - #define GRUB_ENVBLK_DEFCFG "grubenv" - -+#define DEFAULT_ENVBLK_SIZE 1024 -+ - #ifndef ASM_FILE - - struct grub_envblk -@@ -33,6 +35,7 @@ typedef struct grub_envblk *grub_envblk_t; - - 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); -+grub_err_t grub_envblk_get (grub_envblk_t envblk, const char * const name, char ** const value); - void grub_envblk_delete (grub_envblk_t envblk, const char *name); - void grub_envblk_iterate (grub_envblk_t envblk, - void *hook_data, diff --git a/0115-Make-it-possible-to-subtract-conditions-from-debug.patch b/0115-Make-it-possible-to-subtract-conditions-from-debug.patch deleted file mode 100644 index fce51eac8360f042579e9ff102632bfb3115d246..0000000000000000000000000000000000000000 --- a/0115-Make-it-possible-to-subtract-conditions-from-debug.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 17 Jan 2019 13:10:39 -0500 -Subject: [PATCH] Make it possible to subtract conditions from debug= - -This makes it so you can do set debug to "all,-scripting,-lexer" and get the -obvious outcome. Any negation present will take preference over that -conditional, so "all,-scripting,scripting" is the same thing as -"all,-scripting". - -Signed-off-by: Peter Jones ---- - grub-core/kern/misc.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 9a2fae6398e..578bf51a5fc 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -164,12 +164,24 @@ int - grub_debug_enabled (const char * condition) - { - const char *debug; -+ char *negcond; -+ int negated = 0; - - debug = grub_env_get ("debug"); - if (!debug) - return 0; - -- if (grub_strword (debug, "all") || grub_strword (debug, condition)) -+ negcond = grub_zalloc (grub_strlen (condition) + 2); -+ if (negcond) -+ { -+ grub_strcpy (negcond, "-"); -+ grub_strcpy (negcond+1, condition); -+ negated = grub_strword (debug, negcond); -+ grub_free (negcond); -+ } -+ -+ if (!negated && -+ (grub_strword (debug, "all") || grub_strword (debug, condition))) - return 1; - - return 0; diff --git a/0116-Export-all-variables-from-the-initial-context-when-c.patch b/0116-Export-all-variables-from-the-initial-context-when-c.patch deleted file mode 100644 index 4e32260ccada665fefa13ad61396c453217e4574..0000000000000000000000000000000000000000 --- a/0116-Export-all-variables-from-the-initial-context-when-c.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 22 Jan 2019 15:40:25 +0100 -Subject: [PATCH] Export all variables from the initial context when creating a - submenu - -When a submenu is created, only the exported variables are copied to the -new menu context. But we want the variables to be global, so export lets -export all variables to the new created submenu. - -Also, don't unset the default variable when a new submenu is created. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/normal/context.c | 2 +- - grub-core/normal/menu.c | 2 -- - 2 files changed, 1 insertion(+), 3 deletions(-) - -diff --git a/grub-core/normal/context.c b/grub-core/normal/context.c -index ee53d4a68e5..87edd254c44 100644 ---- a/grub-core/normal/context.c -+++ b/grub-core/normal/context.c -@@ -99,7 +99,7 @@ grub_env_new_context (int export_all) - grub_err_t - grub_env_context_open (void) - { -- return grub_env_new_context (0); -+ return grub_env_new_context (1); - } - - int grub_extractor_level = 0; -diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c -index 4a02aadb01c..fe2e77a43e2 100644 ---- a/grub-core/normal/menu.c -+++ b/grub-core/normal/menu.c -@@ -375,8 +375,6 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) - - if (ptr && ptr[0] && ptr[1]) - grub_env_set ("default", ptr + 1); -- else -- grub_env_unset ("default"); - - grub_script_execute_new_scope (entry->sourcecode, entry->argc, entry->args); - diff --git a/0117-grub.d-Split-out-boot-success-reset-from-menu-auto-h.patch b/0117-grub.d-Split-out-boot-success-reset-from-menu-auto-h.patch deleted file mode 100644 index 92f259dc3886aabe44acfdf1fcccfdb5c5d27dd0..0000000000000000000000000000000000000000 --- a/0117-grub.d-Split-out-boot-success-reset-from-menu-auto-h.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Christian Glombek -Date: Tue, 2 Apr 2019 16:22:21 +0200 -Subject: [PATCH] grub.d: Split out boot success reset from menu auto hide - script - -Also rename fallback and menu auto hide script to be executed -before and after boot success reset script. -In menu auto hide script, rename last_boot_ok var to menu_hide_ok - -Signed-off-by: Christian Glombek -Signed-off-by: Robbie Harwood ---- - Makefile.util.def | 14 ++++++++---- - ...allback_counting.in => 08_fallback_counting.in} | 14 ++++++------ - util/grub.d/10_reset_boot_success.in | 25 ++++++++++++++++++++++ - .../{01_menu_auto_hide.in => 12_menu_auto_hide.in} | 23 +++++--------------- - 4 files changed, 48 insertions(+), 28 deletions(-) - rename util/grub.d/{01_fallback_counting.in => 08_fallback_counting.in} (65%) - create mode 100644 util/grub.d/10_reset_boot_success.in - rename util/grub.d/{01_menu_auto_hide.in => 12_menu_auto_hide.in} (58%) - -diff --git a/Makefile.util.def b/Makefile.util.def -index 27a13bc734e..2e6ad979c3e 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -459,14 +459,14 @@ script = { - }; - - script = { -- name = '01_fallback_counting'; -- common = util/grub.d/01_fallback_counting.in; -+ name = '08_fallback_counting'; -+ common = util/grub.d/08_fallback_counting.in; - installdir = grubconf; - }; - - script = { -- name = '01_menu_auto_hide'; -- common = util/grub.d/01_menu_auto_hide.in; -+ name = '12_menu_auto_hide'; -+ common = util/grub.d/12_menu_auto_hide.in; - installdir = grubconf; - }; - -@@ -518,6 +518,12 @@ script = { - condition = COND_HOST_LINUX; - }; - -+script = { -+ name = '10_reset_boot_success'; -+ common = util/grub.d/10_reset_boot_success.in; -+ installdir = grubconf; -+}; -+ - script = { - name = '10_xnu'; - common = util/grub.d/10_xnu.in; -diff --git a/util/grub.d/01_fallback_counting.in b/util/grub.d/08_fallback_counting.in -similarity index 65% -rename from util/grub.d/01_fallback_counting.in -rename to util/grub.d/08_fallback_counting.in -index be0e770ea82..2e2c3ff7d31 100644 ---- a/util/grub.d/01_fallback_counting.in -+++ b/util/grub.d/08_fallback_counting.in -@@ -1,15 +1,17 @@ - #! /bin/sh -e -- --# Boot Counting -+# Fallback Countdown -+# -+# This snippet depends on 10_reset_boot_success and needs to be kept in sync. -+# - # The boot_counter env var can be used to count down boot attempts after an --# OSTree upgrade and choose the rollback deployment when 0 is reached. Both --# boot_counter and boot_success need to be (re-)set from userspace. -+# OSTree upgrade and choose the rollback deployment when 0 is reached. -+# Both boot_counter=X and boot_success=1 need to be set from userspace. - cat << EOF - insmod increment - # Check if boot_counter exists and boot_success=0 to activate this behaviour. - if [ -n "\${boot_counter}" -a "\${boot_success}" = "0" ]; then -- # if countdown has ended, choose to boot rollback deployment (default=1 on -- # OSTree-based systems) -+ # if countdown has ended, choose to boot rollback deployment, -+ # i.e. default=1 on OSTree-based systems. - if [ "\${boot_counter}" = "0" -o "\${boot_counter}" = "-1" ]; then - set default=1 - set boot_counter=-1 -diff --git a/util/grub.d/10_reset_boot_success.in b/util/grub.d/10_reset_boot_success.in -new file mode 100644 -index 00000000000..6c88d933dde ---- /dev/null -+++ b/util/grub.d/10_reset_boot_success.in -@@ -0,0 +1,25 @@ -+#! /bin/sh -e -+# Reset Boot Success -+# -+# The 08_fallback_counting and 12_menu_auto_hide snippets rely on this one -+# and need to be kept in sync. -+# -+# The boot_success var needs to be set to 1 from userspace to mark a boot successful. -+cat << EOF -+insmod increment -+# Hiding the menu is ok if last boot was ok or if this is a first boot attempt to boot the entry -+if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then -+ set menu_hide_ok=1 -+else -+ set menu_hide_ok=0 -+fi -+# Reset boot_indeterminate after a successful boot, increment otherwise -+if [ "\${boot_success}" = "1" ] ; then -+ set boot_indeterminate=0 -+else -+ increment boot_indeterminate -+fi -+# Reset boot_success for current boot -+set boot_success=0 -+save_env boot_success boot_indeterminate -+EOF -diff --git a/util/grub.d/01_menu_auto_hide.in b/util/grub.d/12_menu_auto_hide.in -similarity index 58% -rename from util/grub.d/01_menu_auto_hide.in -rename to util/grub.d/12_menu_auto_hide.in -index ad175870a54..6a7c0fa0d43 100644 ---- a/util/grub.d/01_menu_auto_hide.in -+++ b/util/grub.d/12_menu_auto_hide.in -@@ -1,5 +1,8 @@ - #! /bin/sh -- -+# Menu Auto Hide -+# -+# This snippet depends on 10_reset_boot_success and needs to be kept in sync. -+# - # Disable / skip generating menu-auto-hide config parts on serial terminals - for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do - case "$x" in -@@ -10,29 +13,13 @@ for x in ${GRUB_TERMINAL_INPUT} ${GRUB_TERMINAL_OUTPUT}; do - done - - cat << EOF --if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then -- set last_boot_ok=1 --else -- set last_boot_ok=0 --fi -- --# Reset boot_indeterminate after a successful boot --if [ "\${boot_success}" = "1" ] ; then -- set boot_indeterminate=0 --# Avoid boot_indeterminate causing the menu to be hidden more then once --elif [ "\${boot_indeterminate}" = "1" ]; then -- set boot_indeterminate=2 --fi --set boot_success=0 --save_env boot_success boot_indeterminate -- - if [ x\$feature_timeout_style = xy ] ; then - if [ "\${menu_show_once}" ]; then - unset menu_show_once - save_env menu_show_once - set timeout_style=menu - set timeout=60 -- elif [ "\${menu_auto_hide}" -a "\${last_boot_ok}" = "1" ]; then -+ elif [ "\${menu_auto_hide}" -a "\${menu_hide_ok}" = "1" ]; then - set orig_timeout_style=\${timeout_style} - set orig_timeout=\${timeout} - if [ "\${fastboot}" = "1" ]; then diff --git a/0118-Fix-systemctl-kexec-exit-status-check.patch b/0118-Fix-systemctl-kexec-exit-status-check.patch deleted file mode 100644 index 74ecedccb118eb3ee9753ef02183c533c0f6e1e3..0000000000000000000000000000000000000000 --- a/0118-Fix-systemctl-kexec-exit-status-check.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 9 Apr 2019 12:30:38 +0200 -Subject: [PATCH] Fix systemctl kexec exit status check - -There's always an error printed even when the systemctl kexec command does -succeed. That's because systemctl executes it asynchronously, but the emu -loader seems to expect it to be synchronous and that should never return. - -Also, it's wrong to test if kexecute == 1 since we already know that's the -case or otherwise the function wouldn't had called grub_fatal() earlier. - -Finally, systemctl kexec failing shouldn't be a fatal error since the emu -loader fallbacks to executing the kexec command in case of a failure. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/loader/emu/linux.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c -index fda9e00d24c..5b85b225eed 100644 ---- a/grub-core/loader/emu/linux.c -+++ b/grub-core/loader/emu/linux.c -@@ -71,8 +71,10 @@ grub_linux_boot (void) - (kexecute==1) ? "do-or-die" : "just-in-case"); - rc = grub_util_exec (systemctl); - -- if (kexecute == 1) -- grub_fatal (N_("Error trying to perform 'systemctl kexec'")); -+ if (rc == GRUB_ERR_NONE) -+ return rc; -+ -+ grub_error (rc, N_("Error trying to perform 'systemctl kexec'")); - - /* need to check read-only root before resetting hard!? */ - grub_printf("Performing 'kexec -e'"); diff --git a/0119-Print-grub-emu-linux-loader-messages-as-debug.patch b/0119-Print-grub-emu-linux-loader-messages-as-debug.patch deleted file mode 100644 index a49ec44c4981f22752e041cf9c4ce0461e076ad8..0000000000000000000000000000000000000000 --- a/0119-Print-grub-emu-linux-loader-messages-as-debug.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 9 Apr 2019 12:42:37 +0200 -Subject: [PATCH] Print grub-emu linux loader messages as debug - -They just polute the output and should better be debug messages instead. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/loader/emu/linux.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/loader/emu/linux.c b/grub-core/loader/emu/linux.c -index 5b85b225eed..22ab6af1727 100644 ---- a/grub-core/loader/emu/linux.c -+++ b/grub-core/loader/emu/linux.c -@@ -50,7 +50,7 @@ grub_linux_boot (void) - initrd_param = grub_xasprintf("%s", ""); - } - -- grub_printf("%serforming 'kexec -l %s %s %s'\n", -+ grub_dprintf ("linux", "%serforming 'kexec -l %s %s %s'\n", - (kexecute) ? "P" : "Not p", - kernel_path, initrd_param, boot_cmdline); - -@@ -67,7 +67,7 @@ grub_linux_boot (void) - if (kexecute < 1) - grub_fatal (N_("Use '"PACKAGE"-emu --kexec' to force a system restart.")); - -- grub_printf("Performing 'systemctl kexec' (%s) ", -+ grub_dprintf ("linux", "Performing 'systemctl kexec' (%s) ", - (kexecute==1) ? "do-or-die" : "just-in-case"); - rc = grub_util_exec (systemctl); - diff --git a/0120-Don-t-assume-that-boot-commands-will-only-return-on-.patch b/0120-Don-t-assume-that-boot-commands-will-only-return-on-.patch deleted file mode 100644 index bd7b2c1b509e7d46b608e65e92d6fa15a9147b9c..0000000000000000000000000000000000000000 --- a/0120-Don-t-assume-that-boot-commands-will-only-return-on-.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 9 Apr 2019 13:12:40 +0200 -Subject: [PATCH] Don't assume that boot commands will only return on fail - -While it's true that for most loaders the boot command never returns, it -may be the case that it does. For example the GRUB emulator boot command -calls to systemctl kexec which in turn does an asynchonous call to kexec. - -So in this case GRUB will wrongly assume that the boot command fails and -print a "Failed to boot both default and fallback entries" even when the -kexec call later succeeds. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/normal/menu.c | 23 +++++++++++++---------- - 1 file changed, 13 insertions(+), 10 deletions(-) - -diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c -index fe2e77a43e2..ec0c92bade0 100644 ---- a/grub-core/normal/menu.c -+++ b/grub-core/normal/menu.c -@@ -285,7 +285,7 @@ get_and_remove_first_entry_number (grub_menu_t menu, const char *name) - } - - /* Run a menu entry. */ --static void -+static grub_err_t - grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) - { - grub_err_t err = GRUB_ERR_NONE; -@@ -302,7 +302,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) - { - grub_print_error (); - grub_errno = GRUB_ERR_NONE; -- return; -+ return grub_errno; - } - - errs_before = grub_err_printed_errors; -@@ -315,7 +315,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) - grub_env_context_open (); - menu = grub_zalloc (sizeof (*menu)); - if (! menu) -- return; -+ return grub_errno; - grub_env_set_menu (menu); - if (auto_boot) - grub_env_set ("timeout", "0"); -@@ -385,7 +385,7 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) - - if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ()) - /* Implicit execution of boot, only if something is loaded. */ -- grub_command_execute ("boot", 0, 0); -+ err = grub_command_execute ("boot", 0, 0); - - if (errs_before != grub_err_printed_errors) - grub_wait_after_message (); -@@ -408,6 +408,8 @@ grub_menu_execute_entry(grub_menu_entry_t entry, int auto_boot) - else - grub_env_unset ("default"); - grub_env_unset ("timeout"); -+ -+ return err; - } - - /* Execute ENTRY from the menu MENU, falling back to entries specified -@@ -422,10 +424,13 @@ grub_menu_execute_with_fallback (grub_menu_t menu, - void *callback_data) - { - int fallback_entry; -+ grub_err_t err; - - callback->notify_booting (entry, callback_data); - -- grub_menu_execute_entry (entry, 1); -+ err = grub_menu_execute_entry (entry, 1); -+ if (err == GRUB_ERR_NONE) -+ return; - - /* Deal with fallback entries. */ - while ((fallback_entry = get_and_remove_first_entry_number (menu, "fallback")) -@@ -436,11 +441,9 @@ grub_menu_execute_with_fallback (grub_menu_t menu, - - entry = grub_menu_get_entry (menu, fallback_entry); - callback->notify_fallback (entry, callback_data); -- grub_menu_execute_entry (entry, 1); -- /* If the function call to execute the entry returns at all, then this is -- taken to indicate a boot failure. For menu entries that do something -- other than actually boot an operating system, this could assume -- incorrectly that something failed. */ -+ err = grub_menu_execute_entry (entry, 1); -+ if (err == GRUB_ERR_NONE) -+ return; - } - - if (!autobooted) diff --git a/0121-grub-set-bootflag-Update-comment-about-running-as-ro.patch b/0121-grub-set-bootflag-Update-comment-about-running-as-ro.patch deleted file mode 100644 index cd4ef77508ceaef567291cd93af9b66cfd6e6317..0000000000000000000000000000000000000000 --- a/0121-grub-set-bootflag-Update-comment-about-running-as-ro.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 13 Nov 2019 12:15:43 +0100 -Subject: [PATCH] grub-set-bootflag: Update comment about running as root - through pkexec - -We have stopped using pkexec for grub-set-bootflag, instead it is now -installed suid root, update the comment accordingly. - -Signed-off-by: Hans de Goede ---- - util/grub-set-bootflag.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c -index 6a79ee67444..65d74ce010f 100644 ---- a/util/grub-set-bootflag.c -+++ b/util/grub-set-bootflag.c -@@ -18,7 +18,7 @@ - */ - - /* -- * NOTE this gets run by users as root (through pkexec), so this does not -+ * NOTE this gets run by users as root (its suid root), so this does not - * use any grub library / util functions to allow for easy auditing. - * The grub headers are only included to get certain defines. - */ diff --git a/0122-grub-set-bootflag-Write-new-env-to-tmpfile-and-then-.patch b/0122-grub-set-bootflag-Write-new-env-to-tmpfile-and-then-.patch deleted file mode 100644 index 122bf68689a6ef1321d50c3f0b26442a50570e3e..0000000000000000000000000000000000000000 --- a/0122-grub-set-bootflag-Write-new-env-to-tmpfile-and-then-.patch +++ /dev/null @@ -1,152 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 13 Nov 2019 13:02:01 +0100 -Subject: [PATCH] grub-set-bootflag: Write new env to tmpfile and then rename - -Make the grubenv writing code in grub-set-bootflag more robust by -writing the modified grubenv to a tmpfile first and then renaming the -tmpfile over the old grubenv (following symlinks). - -Signed-off-by: Hans de Goede ---- - util/grub-set-bootflag.c | 87 +++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 78 insertions(+), 9 deletions(-) - -diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c -index 65d74ce010f..d1c5e28862b 100644 ---- a/util/grub-set-bootflag.c -+++ b/util/grub-set-bootflag.c -@@ -28,7 +28,9 @@ - #include - #include /* For GRUB_ENVBLK_DEFCFG define */ - #include -+#include - #include -+#include - #include - #include - -@@ -54,8 +56,10 @@ int main(int argc, char *argv[]) - { - /* NOTE buf must be at least the longest bootflag length + 4 bytes */ - char env[GRUBENV_SIZE + 1], buf[64], *s; -+ /* +1 for 0 termination, +6 for "XXXXXX" in tmp filename */ -+ char env_filename[PATH_MAX + 1], tmp_filename[PATH_MAX + 6 + 1]; - const char *bootflag; -- int i, len, ret; -+ int i, fd, len, ret; - FILE *f; - - if (argc != 2) -@@ -77,7 +81,32 @@ int main(int argc, char *argv[]) - bootflag = bootflags[i]; - len = strlen (bootflag); - -- f = fopen (GRUBENV, "r"); -+ /* -+ * Really become root. setuid avoids an user killing us, possibly leaking -+ * the tmpfile. setgid avoids the new grubenv's gid being that of the user. -+ */ -+ ret = setuid(0); -+ if (ret) -+ { -+ perror ("Error setuid(0) failed"); -+ return 1; -+ } -+ -+ ret = setgid(0); -+ if (ret) -+ { -+ perror ("Error setgid(0) failed"); -+ return 1; -+ } -+ -+ /* Canonicalize GRUBENV filename, resolving symlinks, etc. */ -+ if (!realpath(GRUBENV, env_filename)) -+ { -+ perror ("Error canonicalizing " GRUBENV " filename"); -+ return 1; -+ } -+ -+ f = fopen (env_filename, "r"); - if (!f) - { - perror ("Error opening " GRUBENV " for reading"); -@@ -132,30 +161,70 @@ int main(int argc, char *argv[]) - snprintf(buf, sizeof(buf), "%s=1\n", bootflag); - memcpy(s, buf, len + 3); - -- /* "r+", don't truncate so that the diskspace stays reserved */ -- f = fopen (GRUBENV, "r+"); -+ -+ /* -+ * Create a tempfile for writing the new env. Use the canonicalized filename -+ * for the template so that the tmpfile is in the same dir / on same fs. -+ */ -+ snprintf(tmp_filename, sizeof(tmp_filename), "%sXXXXXX", env_filename); -+ fd = mkstemp(tmp_filename); -+ if (fd == -1) -+ { -+ perror ("Creating tmpfile failed"); -+ return 1; -+ } -+ -+ f = fdopen (fd, "w"); - if (!f) - { -- perror ("Error opening " GRUBENV " for writing"); -+ perror ("Error fdopen of tmpfile failed"); -+ unlink(tmp_filename); - return 1; - } - - ret = fwrite (env, 1, GRUBENV_SIZE, f); - if (ret != GRUBENV_SIZE) - { -- perror ("Error writing to " GRUBENV); -+ perror ("Error writing tmpfile"); -+ unlink(tmp_filename); - return 1; - } - - ret = fflush (f); - if (ret) - { -- perror ("Error flushing " GRUBENV); -+ perror ("Error flushing tmpfile"); -+ unlink(tmp_filename); - return 1; - } - -- fsync (fileno (f)); -- fclose (f); -+ ret = fsync (fileno (f)); -+ if (ret) -+ { -+ perror ("Error syncing tmpfile"); -+ unlink(tmp_filename); -+ return 1; -+ } -+ -+ ret = fclose (f); -+ if (ret) -+ { -+ perror ("Error closing tmpfile"); -+ unlink(tmp_filename); -+ return 1; -+ } -+ -+ /* -+ * And finally rename the tmpfile with the new env over the old env, the -+ * linux kernel guarantees that this is atomic (from a syscall pov). -+ */ -+ ret = rename(tmp_filename, env_filename); -+ if (ret) -+ { -+ perror ("Error renaming tmpfile to " GRUBENV " failed"); -+ unlink(tmp_filename); -+ return 1; -+ } - - return 0; - } diff --git a/0123-grub.d-Fix-boot_indeterminate-getting-set-on-boot_su.patch b/0123-grub.d-Fix-boot_indeterminate-getting-set-on-boot_su.patch deleted file mode 100644 index a32c1465095b9fdbf423cca194bd87d2b17a8800..0000000000000000000000000000000000000000 --- a/0123-grub.d-Fix-boot_indeterminate-getting-set-on-boot_su.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 26 Nov 2019 09:51:41 +0100 -Subject: [PATCH] grub.d: Fix boot_indeterminate getting set on boot_success=0 - boot -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The "grub.d: Split out boot success reset from menu auto hide script" -not only moved the code to clear boot_success and boot_indeterminate -but for some reason also mixed in some broken changes to the -boot_indeterminate handling. - -The boot_indeterminate var is meant to suppress the boot menu after -a reboot from either a selinux-relabel or offline-updates. These -2 special boot scenarios do not set boot_success since there is no -successfull interaction with the user. Instead they increment -boot_indeterminate, and if it is 1 and only when it is 1, so the -first reboot after a "special" boot we suppress the menu. - -To ensure that we do show the menu if we somehow get stuck in a -"special" boot loop where we do special-boots without them -incrementing boot_indeterminate, the code before the -"grub.d: Split out boot success reset from menu auto hide script" -commit would increment boot_indeterminate once when it is 1, so that -even if the "special" boot reboot-loop immediately we would show the -menu on the next boot. - -That commit broke this however, because it not only moves the code, -it also changes it from only "incrementing" boot_indeterminate once to -always incrementing it, except when boot_success == 1 (and we reset it). - -This broken behavior causes the following problem: - -1. Boot a broken kernel, system hangs, power-cycle -2. boot_success now != 1, so we increment boot_indeterminate from 0 - (unset!) to 1. User either simply tries again, or makes some changes - but the end-result still is a system hang, power-cycle -3. Now boot_indeterminate==1 so we do not show the menu even though the - previous boot failed -> BAD - -This commit fixes this by restoring the behavior of setting -boot_indeterminate to 2 when it was 1 before. - -Fixes: "grub.d: Split out boot success reset from menu auto hide script" -Signed-off-by: Hans de Goede -[jpokorny: 01_menu_auto_hide.in: fix a then/than typo] -Signed-off-by: Jan Pokorný -Signed-off-by: Robbie Harwood ---- - util/grub.d/10_reset_boot_success.in | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/util/grub.d/10_reset_boot_success.in b/util/grub.d/10_reset_boot_success.in -index 6c88d933dde..e73f4137b36 100644 ---- a/util/grub.d/10_reset_boot_success.in -+++ b/util/grub.d/10_reset_boot_success.in -@@ -6,18 +6,18 @@ - # - # The boot_success var needs to be set to 1 from userspace to mark a boot successful. - cat << EOF --insmod increment - # Hiding the menu is ok if last boot was ok or if this is a first boot attempt to boot the entry - if [ "\${boot_success}" = "1" -o "\${boot_indeterminate}" = "1" ]; then - set menu_hide_ok=1 - else - set menu_hide_ok=0 - fi --# Reset boot_indeterminate after a successful boot, increment otherwise -+# Reset boot_indeterminate after a successful boot - if [ "\${boot_success}" = "1" ] ; then - set boot_indeterminate=0 --else -- increment boot_indeterminate -+# Avoid boot_indeterminate causing the menu to be hidden more than once -+elif [ "\${boot_indeterminate}" = "1" ]; then -+ set boot_indeterminate=2 - fi - # Reset boot_success for current boot - set boot_success=0 diff --git a/0124-Add-start-symbol-for-RISC-V.patch b/0124-Add-start-symbol-for-RISC-V.patch deleted file mode 100644 index 677efae016068e1094f52d0c1befc213b846e677..0000000000000000000000000000000000000000 --- a/0124-Add-start-symbol-for-RISC-V.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: David Abdurachmanov -Date: Sat, 9 Nov 2019 19:51:57 +0000 -Subject: [PATCH] Add start symbol for RISC-V - -All other architectures have start symbol. - -Hopefully this resolves: - - BUILDSTDERR: ././grub-mkimage: error: undefined symbol start. - -Signed-off-by: David Abdurachmanov ---- - grub-core/kern/riscv/efi/startup.S | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/grub-core/kern/riscv/efi/startup.S b/grub-core/kern/riscv/efi/startup.S -index f2a7b2b1ede..781773136e8 100644 ---- a/grub-core/kern/riscv/efi/startup.S -+++ b/grub-core/kern/riscv/efi/startup.S -@@ -29,6 +29,7 @@ - - .file "startup.S" - .text -+FUNCTION(start) - FUNCTION(_start) - /* - * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0. diff --git a/0125-bootstrap.conf-Force-autogen.sh-to-use-python3.patch b/0125-bootstrap.conf-Force-autogen.sh-to-use-python3.patch deleted file mode 100644 index 49c92b97db74fec845270cd7dbc965013355bf53..0000000000000000000000000000000000000000 --- a/0125-bootstrap.conf-Force-autogen.sh-to-use-python3.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Wed, 15 Jan 2020 12:47:46 +0100 -Subject: [PATCH] bootstrap.conf: Force autogen.sh to use python3 - -The python-unversioned-command package is not installed in the buildroot, -but the bootstrap script expects the python command to be present if one -is not defined. So building the package leads to the following error: - -./autogen.sh: line 20: python: command not found - -This is harmless since gnulib is included as a source anyways, because the -builders can't download. But still the issue should be fixed by forcing to -use python3 that's the default in Fedora now. - -Signed-off-by: Javier Martinez Canillas ---- - bootstrap.conf | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/bootstrap.conf b/bootstrap.conf -index 6b043fc354c..52d4af44bec 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -92,7 +92,7 @@ bootstrap_post_import_hook () { - patch -d po -p3 \ - < "po/gettext-patches/$patchname.patch" - done -- FROM_BOOTSTRAP=1 ./autogen.sh -+ PYTHON=python3 FROM_BOOTSTRAP=1 ./autogen.sh - set +e # bootstrap expects this - } - diff --git a/0126-efi-http-Export-fw-http-_path-variables-to-make-them.patch b/0126-efi-http-Export-fw-http-_path-variables-to-make-them.patch deleted file mode 100644 index 74183bc3fe99881989ab652053efb35367d91184..0000000000000000000000000000000000000000 --- a/0126-efi-http-Export-fw-http-_path-variables-to-make-them.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Thu, 5 Mar 2020 16:21:47 +0100 -Subject: [PATCH] efi/http: Export {fw,http}_path variables to make them global - -The fw_path environment variable is used by http_configure() function to -determine the HTTP path that should be used as prefix when using relative -HTTP paths. And this is stored in the http_path environment variable. - -Later, that variable is looked up by grub_efihttp_open() to generate the -complete path to be used in the HTTP request. - -But these variables are not exported, which means that are not global and -so are only found in the initial context. - -This can cause commands like configfile that create a new context to fail -because the fw_path and http_path variables will not be found. - -Resolves: rhbz#1616395 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/kern/main.c | 1 + - grub-core/net/efi/http.c | 1 + - 2 files changed, 2 insertions(+) - -diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c -index 1c540fc8c26..b573be6650d 100644 ---- a/grub-core/kern/main.c -+++ b/grub-core/kern/main.c -@@ -143,6 +143,7 @@ grub_set_prefix_and_root (void) - if (fw_path) - { - grub_env_set ("fw_path", fw_path); -+ grub_env_export ("fw_path"); - grub_dprintf ("fw_path", "fw_path:\"%s\"\n", fw_path); - grub_free (fw_path); - } -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -index de351b2cd03..755b7a6d054 100644 ---- a/grub-core/net/efi/http.c -+++ b/grub-core/net/efi/http.c -@@ -39,6 +39,7 @@ http_configure (struct grub_efi_net_device *dev, int prefer_ip6) - http_path++; - grub_env_unset ("http_path"); - grub_env_set ("http_path", http_path); -+ grub_env_export ("http_path"); - } - } - diff --git a/0127-efi-http-Enclose-literal-IPv6-addresses-in-square-br.patch b/0127-efi-http-Enclose-literal-IPv6-addresses-in-square-br.patch deleted file mode 100644 index c3945498a8b421325377b9d40b22a8899cef3552..0000000000000000000000000000000000000000 --- a/0127-efi-http-Enclose-literal-IPv6-addresses-in-square-br.patch +++ /dev/null @@ -1,114 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Thu, 5 Mar 2020 16:21:58 +0100 -Subject: [PATCH] efi/http: Enclose literal IPv6 addresses in square brackets - -According to RFC 2732 (https://www.ietf.org/rfc/rfc2732.txt), literal IPv6 -addresses must be enclosed in square brackets. But GRUB currently does not -do this and is causing HTTP servers to send Bad Request (400) responses. - -For example, the following is the HTTP stream when fetching a config file: - -HEAD /EFI/BOOT/grub.cfg HTTP/1.1 -Host: 2000:dead:beef:a::1 -Accept: */* -User-Agent: UefiHttpBoot/1.0 - -HTTP/1.1 400 Bad Request -Date: Thu, 05 Mar 2020 14:46:02 GMT -Server: Apache/2.4.41 (Fedora) OpenSSL/1.1.1d -Connection: close -Content-Type: text/html; charset=iso-8859-1 - -and after enclosing the IPv6 address the HTTP request is successful: - -HEAD /EFI/BOOT/grub.cfg HTTP/1.1 -Host: [2000:dead:beef:a::1] -Accept: */* -User-Agent: UefiHttpBoot/1.0 - -HTTP/1.1 200 OK -Date: Thu, 05 Mar 2020 14:48:04 GMT -Server: Apache/2.4.41 (Fedora) OpenSSL/1.1.1d -Last-Modified: Thu, 27 Feb 2020 17:45:58 GMT -ETag: "206-59f924b24b1da" -Accept-Ranges: bytes -Content-Length: 518 - -Resolves: rhbz#1732765 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/net/efi/http.c | 37 ++++++++++++++++++++++++++++--------- - 1 file changed, 28 insertions(+), 9 deletions(-) - -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -index 755b7a6d054..fc8cb25ae0a 100644 ---- a/grub-core/net/efi/http.c -+++ b/grub-core/net/efi/http.c -@@ -158,13 +158,7 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https, - grub_efi_status_t status; - grub_efi_boot_services_t *b = grub_efi_system_table->boot_services; - char *url = NULL; -- -- request_headers[0].field_name = (grub_efi_char8_t *)"Host"; -- request_headers[0].field_value = (grub_efi_char8_t *)server; -- request_headers[1].field_name = (grub_efi_char8_t *)"Accept"; -- request_headers[1].field_value = (grub_efi_char8_t *)"*/*"; -- request_headers[2].field_name = (grub_efi_char8_t *)"User-Agent"; -- request_headers[2].field_value = (grub_efi_char8_t *)"UefiHttpBoot/1.0"; -+ char *hostname = NULL; - - { - grub_efi_ipv6_address_t address; -@@ -174,9 +168,24 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https, - const char *protocol = (use_https == 1) ? "https" : "http"; - - if (grub_efi_string_to_ip6_address (server, &address, &rest) && *rest == 0) -- url = grub_xasprintf ("%s://[%s]%s", protocol, server, name); -+ { -+ hostname = grub_xasprintf ("[%s]", server); -+ if (!hostname) -+ return GRUB_ERR_OUT_OF_MEMORY; -+ -+ server = hostname; -+ -+ url = grub_xasprintf ("%s://%s%s", protocol, server, name); -+ if (!url) -+ { -+ grub_free (hostname); -+ return GRUB_ERR_OUT_OF_MEMORY; -+ } -+ } - else -- url = grub_xasprintf ("%s://%s%s", protocol, server, name); -+ { -+ url = grub_xasprintf ("%s://%s%s", protocol, server, name); -+ } - - if (!url) - { -@@ -199,6 +208,13 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https, - request_data.url = ucs2_url; - } - -+ request_headers[0].field_name = (grub_efi_char8_t *)"Host"; -+ request_headers[0].field_value = (grub_efi_char8_t *)server; -+ request_headers[1].field_name = (grub_efi_char8_t *)"Accept"; -+ request_headers[1].field_value = (grub_efi_char8_t *)"*/*"; -+ request_headers[2].field_name = (grub_efi_char8_t *)"User-Agent"; -+ request_headers[2].field_value = (grub_efi_char8_t *)"UefiHttpBoot/1.0"; -+ - request_data.method = (headeronly > 0) ? GRUB_EFI_HTTPMETHODHEAD : GRUB_EFI_HTTPMETHODGET; - - request_message.data.request = &request_data; -@@ -228,6 +244,9 @@ efihttp_request (grub_efi_http_t *http, char *server, char *name, int use_https, - - status = efi_call_2 (http->request, http, &request_token); - -+ if (hostname) -+ grub_free (hostname); -+ - if (status != GRUB_EFI_SUCCESS) - { - efi_call_1 (b->close_event, request_token.event); diff --git a/0128-efi-net-Allow-to-specify-a-port-number-in-addresses.patch b/0128-efi-net-Allow-to-specify-a-port-number-in-addresses.patch deleted file mode 100644 index 209aed80f66762662a2229f2da9bd087ed15c691..0000000000000000000000000000000000000000 --- a/0128-efi-net-Allow-to-specify-a-port-number-in-addresses.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Mon, 9 Mar 2020 15:29:45 +0100 -Subject: [PATCH] efi/net: Allow to specify a port number in addresses - -The grub_efi_net_parse_address() function is not covering the case where a -port number is specified in an IPv4 or IPv6 address, so will fail to parse -the network address. - -For most cases the issue is harmless, because the function is only used to -match an address with a network interface and if fails the default is used. - -But still is a bug that has to be fixed and it causes error messages to be -printed like the following: - -error: net/efi/net.c:782:unrecognised network address '192.168.122.1:8080' - -error: net/efi/net.c:781:unrecognised network address '[2000:dead:beef:a::1]:8080' - -Resolves: rhbz#1732765 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/net/efi/net.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -index 6603cd83edc..84573937b18 100644 ---- a/grub-core/net/efi/net.c -+++ b/grub-core/net/efi/net.c -@@ -742,7 +742,7 @@ grub_efi_net_parse_address (const char *address, - return GRUB_ERR_NONE; - } - } -- else if (*rest == 0) -+ else if (*rest == 0 || *rest == ':') - { - grub_uint32_t subnet_mask = 0xffffffffU; - grub_memcpy (ip4->subnet_mask, &subnet_mask, sizeof (ip4->subnet_mask)); -@@ -768,7 +768,7 @@ grub_efi_net_parse_address (const char *address, - return GRUB_ERR_NONE; - } - } -- else if (*rest == 0) -+ else if (*rest == 0 || *rest == ':') - { - ip6->prefix_length = 128; - ip6->is_anycast = 0; diff --git a/0129-efi-ip4_config-Improve-check-to-detect-literal-IPv6-.patch b/0129-efi-ip4_config-Improve-check-to-detect-literal-IPv6-.patch deleted file mode 100644 index f92dee4405006f948c00a232a334764d86986b7c..0000000000000000000000000000000000000000 --- a/0129-efi-ip4_config-Improve-check-to-detect-literal-IPv6-.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Mon, 9 Mar 2020 15:30:05 +0100 -Subject: [PATCH] efi/ip4_config: Improve check to detect literal IPv6 - addresses - -The grub_efi_string_to_ip4_address() function wrongly assumes that an IPv6 -address is an IPv4 address, because it doesn't take into account the case -of a caller passing an IPv6 address as a string. - -This leads to the grub_efi_net_parse_address() function to fail and print -the following error message: - -error: net/efi/net.c:785:unrecognised network address '2000:dead:beef:a::1' - -Resolves: rhbz#1732765 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/net/efi/ip4_config.c | 13 ++++++++++++- - 1 file changed, 12 insertions(+), 1 deletion(-) - -diff --git a/grub-core/net/efi/ip4_config.c b/grub-core/net/efi/ip4_config.c -index b711a5d9457..313c818b184 100644 ---- a/grub-core/net/efi/ip4_config.c -+++ b/grub-core/net/efi/ip4_config.c -@@ -56,9 +56,20 @@ int - grub_efi_string_to_ip4_address (const char *val, grub_efi_ipv4_address_t *address, const char **rest) - { - grub_uint32_t newip = 0; -- int i; -+ int i, ncolon = 0; - const char *ptr = val; - -+ /* Check that is not an IPv6 address */ -+ for (i = 0; i < grub_strlen(ptr); i++) -+ { -+ if (ptr[i] == '[' && i == 0) -+ return 0; -+ -+ if (ptr[i] == ':') -+ if (i == 0 || ++ncolon == 2) -+ return 0; -+ } -+ - for (i = 0; i < 4; i++) - { - unsigned long t; diff --git a/0130-efi-net-Print-a-debug-message-if-parsing-the-address.patch b/0130-efi-net-Print-a-debug-message-if-parsing-the-address.patch deleted file mode 100644 index 33d8f886f35036de92470024908af1e11ba260ce..0000000000000000000000000000000000000000 --- a/0130-efi-net-Print-a-debug-message-if-parsing-the-address.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 10 Mar 2020 11:23:49 +0100 -Subject: [PATCH] efi/net: Print a debug message if parsing the address fails - -Currently if parsing the address fails an error message is printed. But in -most cases this isn't a fatal error since the grub_efi_net_parse_address() -function is only used to match an address with a network interface to use. - -And if this fails, the default interface is used which is good enough for -most cases. So instead of printing an error that would pollute the console -just print a debug message if the address is not parsed correctly. - -A user can enable debug messages for the efinet driver to have information -about the failure and the fact that the default interface is being used. - -Related: rhbz#1732765 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/net/efi/net.c | 18 +++++++++++------- - 1 file changed, 11 insertions(+), 7 deletions(-) - -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -index 84573937b18..a3f0535d43c 100644 ---- a/grub-core/net/efi/net.c -+++ b/grub-core/net/efi/net.c -@@ -778,9 +778,9 @@ grub_efi_net_parse_address (const char *address, - } - } - -- return grub_error (GRUB_ERR_NET_BAD_ADDRESS, -- N_("unrecognised network address `%s'"), -- address); -+ grub_dprintf ("efinet", "unrecognised network address '%s'\n", address); -+ -+ return GRUB_ERR_NET_BAD_ADDRESS; - } - - static grub_efi_net_interface_t * -@@ -795,10 +795,7 @@ match_route (const char *server) - err = grub_efi_net_parse_address (server, &ip4, &ip6, &is_ip6, 0); - - if (err) -- { -- grub_print_error (); - return NULL; -- } - - if (is_ip6) - { -@@ -1233,8 +1230,15 @@ grub_net_open_real (const char *name __attribute__ ((unused))) - /*FIXME: Use DNS translate name to address */ - net_interface = match_route (server); - -+ if (!net_interface && net_default_interface) -+ { -+ net_interface = net_default_interface; -+ grub_dprintf ("efinet", "interface lookup failed, using default '%s'\n", -+ net_interface->name); -+ } -+ - /*XXX: should we check device with default gateway ? */ -- if (!net_interface && !(net_interface = net_default_interface)) -+ if (!net_interface) - { - grub_error (GRUB_ERR_UNKNOWN_DEVICE, N_("disk `%s' no route found"), - name); diff --git a/0131-kern-term-Also-accept-F8-as-a-user-interrupt-key.patch b/0131-kern-term-Also-accept-F8-as-a-user-interrupt-key.patch deleted file mode 100644 index 3dd525af8191a4c737c546212335b58353b98c3b..0000000000000000000000000000000000000000 --- a/0131-kern-term-Also-accept-F8-as-a-user-interrupt-key.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Wed, 22 Apr 2020 12:41:52 +0200 -Subject: [PATCH] kern/term: Also accept F8 as a user interrupt key - -Make F8, which used to be the hotkey to show the Windows boot menu during -boot for a long long time, also interrupt sleeps / stop the menu countdown. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/kern/term.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/grub-core/kern/term.c b/grub-core/kern/term.c -index 14d59649832..4d61f4e9790 100644 ---- a/grub-core/kern/term.c -+++ b/grub-core/kern/term.c -@@ -144,9 +144,10 @@ grub_key_is_interrupt (int key) - /* - * ESC sometimes is the BIOS setup hotkey and may be hard to discover, also - * check F4, which was chosen because is not used as a hotkey to enter the -- * BIOS setup by any vendor. -+ * BIOS setup by any vendor. Also, F8 which was the key to get the Windows -+ * bootmenu for a long time. - */ -- if (key == GRUB_TERM_ESC || key == GRUB_TERM_KEY_F4) -+ if (key == GRUB_TERM_ESC || key == GRUB_TERM_KEY_F4 || key == GRUB_TERM_KEY_F8) - return 1; - - /* diff --git a/0133-tpm-Don-t-propagate-TPM-measurement-errors-to-the-ve.patch b/0133-tpm-Don-t-propagate-TPM-measurement-errors-to-the-ve.patch deleted file mode 100644 index 747773d1d60d8d4e222b8685974e3801020480d2..0000000000000000000000000000000000000000 --- a/0133-tpm-Don-t-propagate-TPM-measurement-errors-to-the-ve.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Sat, 16 May 2020 11:33:18 +0200 -Subject: [PATCH] tpm: Don't propagate TPM measurement errors to the verifiers - layer - -Currently if the EFI firmware fails to do a TPM measurement for a file, -the error will be propagated to the verifiers framework and so opening -the file will not succeed. - -This mean that buggy firmwares will prevent the system to boot since the -loader won't be able to open any file. But failing to do TPM measurements -shouldn't be a fatal error and the system should still be able to boot. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/commands/tpm.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c -index 2052c36eaba..e287d042e6b 100644 ---- a/grub-core/commands/tpm.c -+++ b/grub-core/commands/tpm.c -@@ -42,7 +42,8 @@ grub_tpm_verify_init (grub_file_t io, - static grub_err_t - grub_tpm_verify_write (void *context, void *buf, grub_size_t size) - { -- return grub_tpm_measure (buf, size, GRUB_BINARY_PCR, context); -+ grub_tpm_measure (buf, size, GRUB_BINARY_PCR, context); -+ return GRUB_ERR_NONE; - } - - static grub_err_t -@@ -50,7 +51,6 @@ grub_tpm_verify_string (char *str, enum grub_verify_string_type type) - { - const char *prefix = NULL; - char *description; -- grub_err_t status; - - switch (type) - { -@@ -66,15 +66,15 @@ grub_tpm_verify_string (char *str, enum grub_verify_string_type type) - } - description = grub_malloc (grub_strlen (str) + grub_strlen (prefix) + 1); - if (!description) -- return grub_errno; -+ return GRUB_ERR_NONE; - grub_memcpy (description, prefix, grub_strlen (prefix)); - grub_memcpy (description + grub_strlen (prefix), str, - grub_strlen (str) + 1); -- status = -- grub_tpm_measure ((unsigned char *) str, grub_strlen (str), -- GRUB_STRING_PCR, description); -+ -+ grub_tpm_measure ((unsigned char *) str, grub_strlen (str), GRUB_STRING_PCR, -+ description); - grub_free (description); -- return status; -+ return GRUB_ERR_NONE; - } - - struct grub_file_verifier grub_tpm_verifier = { diff --git a/0135-http-Prepend-prefix-when-the-HTTP-path-is-relative-a.patch b/0135-http-Prepend-prefix-when-the-HTTP-path-is-relative-a.patch deleted file mode 100644 index 97d2e06ff840078efe4e932692586dfe88389811..0000000000000000000000000000000000000000 --- a/0135-http-Prepend-prefix-when-the-HTTP-path-is-relative-a.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 2 Jun 2020 13:25:01 +0200 -Subject: [PATCH] http: Prepend prefix when the HTTP path is relative as done - in efi/http - -There are two different HTTP drivers that can be used when requesting an -HTTP resource: the efi/http that uses the EFI_HTTP_PROTOCOL and the http -that uses GRUB's HTTP and TCP/IP implementation. - -The efi/http driver appends a prefix that is defined in the variable -http_path, but the http driver doesn't. - -So using this driver and attempting to fetch a resource using a relative -path fails. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/net/http.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index b52b558d631..7f878b56157 100644 ---- a/grub-core/net/http.c -+++ b/grub-core/net/http.c -@@ -501,13 +501,20 @@ http_open (struct grub_file *file, const char *filename) - { - grub_err_t err; - struct http_data *data; -+ const char *http_path; - - data = grub_zalloc (sizeof (*data)); - if (!data) - return grub_errno; - file->size = GRUB_FILE_SIZE_UNKNOWN; - -- data->filename = grub_strdup (filename); -+ /* If path is relative, prepend http_path */ -+ http_path = grub_env_get ("http_path"); -+ if (http_path && filename[0] != '/') -+ data->filename = grub_xasprintf ("%s/%s", http_path, filename); -+ else -+ data->filename = grub_strdup (filename); -+ - if (!data->filename) - { - grub_free (data); diff --git a/0136-Fix-a-missing-return-in-efi-export-env-and-efi-load-.patch b/0136-Fix-a-missing-return-in-efi-export-env-and-efi-load-.patch deleted file mode 100644 index 1657d7a8792fd27a03f1036bcab62a49eb74e53f..0000000000000000000000000000000000000000 --- a/0136-Fix-a-missing-return-in-efi-export-env-and-efi-load-.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Wed, 16 Jan 2019 13:21:46 -0500 -Subject: [PATCH] Fix a missing return in efi-export-env and efi-load-env - commands - -Somewhere along the way this got mis-merged to include a return without -a value. Fix it up. - -Signed-off-by: Peter Jones ---- - grub-core/commands/efi/env.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/commands/efi/env.c b/grub-core/commands/efi/env.c -index cbd13e03e81..977edb6b065 100644 ---- a/grub-core/commands/efi/env.c -+++ b/grub-core/commands/efi/env.c -@@ -149,6 +149,8 @@ grub_efi_load_env(grub_command_t cmd __attribute__ ((unused)), - - grub_envblk_iterate (envblk, NULL, set_var); - grub_free (envblk_s.buf); -+ -+ return GRUB_ERR_NONE; - } - - static grub_command_t export_cmd, loadenv_cmd; diff --git a/0137-efi-dhcp-fix-some-allocation-error-checking.patch b/0137-efi-dhcp-fix-some-allocation-error-checking.patch deleted file mode 100644 index 7549733862f45b4dc0ce2634558a54b5dcc5ac54..0000000000000000000000000000000000000000 --- a/0137-efi-dhcp-fix-some-allocation-error-checking.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Sun, 19 Jul 2020 17:11:06 -0400 -Subject: [PATCH] efi+dhcp: fix some allocation error checking. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/dhcp.c | 9 ++++++--- - 1 file changed, 6 insertions(+), 3 deletions(-) - -diff --git a/grub-core/net/efi/dhcp.c b/grub-core/net/efi/dhcp.c -index dbef63d8c08..e5c79b748b0 100644 ---- a/grub-core/net/efi/dhcp.c -+++ b/grub-core/net/efi/dhcp.c -@@ -80,7 +80,7 @@ grub_efi_dhcp4_parse_dns (grub_efi_dhcp4_protocol_t *dhcp4, grub_efi_dhcp4_packe - if (status != GRUB_EFI_BUFFER_TOO_SMALL) - return NULL; - -- option_list = grub_malloc (option_count * sizeof(*option_list)); -+ option_list = grub_calloc (option_count, sizeof(*option_list)); - if (!option_list) - return NULL; - -@@ -360,8 +360,11 @@ grub_cmd_efi_bootp6 (struct grub_command *cmd __attribute__ ((unused)), - - if (status == GRUB_EFI_BUFFER_TOO_SMALL && count) - { -- options = grub_malloc (count * sizeof(*options)); -- status = efi_call_4 (dev->dhcp6->parse, dev->dhcp6, mode.ia->reply_packet, &count, options); -+ options = grub_calloc (count, sizeof(*options)); -+ if (options) -+ status = efi_call_4 (dev->dhcp6->parse, dev->dhcp6, mode.ia->reply_packet, &count, options); -+ else -+ status = GRUB_EFI_OUT_OF_RESOURCES; - } - - if (status != GRUB_EFI_SUCCESS) diff --git a/0138-efi-http-fix-some-allocation-error-checking.patch b/0138-efi-http-fix-some-allocation-error-checking.patch deleted file mode 100644 index 4dffab9e398d8b625f91d9af9cd6b0d7ceb0f682..0000000000000000000000000000000000000000 --- a/0138-efi-http-fix-some-allocation-error-checking.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Sun, 19 Jul 2020 17:14:15 -0400 -Subject: [PATCH] efi+http: fix some allocation error checking. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/http.c | 11 +++++++---- - 1 file changed, 7 insertions(+), 4 deletions(-) - -diff --git a/grub-core/net/efi/http.c b/grub-core/net/efi/http.c -index fc8cb25ae0a..26647a50fa4 100644 ---- a/grub-core/net/efi/http.c -+++ b/grub-core/net/efi/http.c -@@ -412,8 +412,8 @@ grub_efihttp_open (struct grub_efi_net_device *dev, - int type) - { - grub_err_t err; -- grub_off_t size; -- char *buf; -+ grub_off_t size = 0; -+ char *buf = NULL; - char *file_name = NULL; - const char *http_path; - -@@ -441,8 +441,11 @@ grub_efihttp_open (struct grub_efi_net_device *dev, - return err; - } - -- buf = grub_malloc (size); -- efihttp_read (dev, buf, size); -+ if (size) -+ { -+ buf = grub_malloc (size); -+ efihttp_read (dev, buf, size); -+ } - - file->size = size; - file->data = buf; diff --git a/0139-efi-ip-46-_config.c-fix-some-potential-allocation-ov.patch b/0139-efi-ip-46-_config.c-fix-some-potential-allocation-ov.patch deleted file mode 100644 index 30c21a586bf41dc48fb44c45458e855c9b7e4d66..0000000000000000000000000000000000000000 --- a/0139-efi-ip-46-_config.c-fix-some-potential-allocation-ov.patch +++ /dev/null @@ -1,127 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Sun, 19 Jul 2020 17:27:00 -0400 -Subject: [PATCH] efi/ip[46]_config.c: fix some potential allocation overflows - -In theory all of this data comes from the firmware stack and it should -be safe, but it's better to be paranoid. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/ip4_config.c | 25 ++++++++++++++++++------- - grub-core/net/efi/ip6_config.c | 13 ++++++++++--- - 2 files changed, 28 insertions(+), 10 deletions(-) - -diff --git a/grub-core/net/efi/ip4_config.c b/grub-core/net/efi/ip4_config.c -index 313c818b184..9725e928f7e 100644 ---- a/grub-core/net/efi/ip4_config.c -+++ b/grub-core/net/efi/ip4_config.c -@@ -4,15 +4,20 @@ - #include - #include - #include -+#include - - char * - grub_efi_hw_address_to_string (grub_efi_uint32_t hw_address_size, grub_efi_mac_address_t hw_address) - { - char *hw_addr, *p; -- int sz, s; -- int i; -+ grub_size_t sz, s, i; - -- sz = (int)hw_address_size * (sizeof ("XX:") - 1) + 1; -+ if (grub_mul (hw_address_size, sizeof ("XX:") - 1, &sz) || -+ grub_add (sz, 1, &sz)) -+ { -+ grub_errno = GRUB_ERR_OUT_OF_RANGE; -+ return NULL; -+ } - - hw_addr = grub_malloc (sz); - if (!hw_addr) -@@ -20,7 +25,7 @@ grub_efi_hw_address_to_string (grub_efi_uint32_t hw_address_size, grub_efi_mac_a - - p = hw_addr; - s = sz; -- for (i = 0; i < (int)hw_address_size; i++) -+ for (i = 0; i < hw_address_size; i++) - { - grub_snprintf (p, sz, "%02x:", hw_address[i]); - p += sizeof ("XX:") - 1; -@@ -238,14 +243,20 @@ grub_efi_ip4_interface_route_table (struct grub_efi_net_device *dev) - { - grub_efi_ip4_config2_interface_info_t *interface_info; - char **ret; -- int i, id; -+ int id; -+ grub_size_t i, nmemb; - - interface_info = efi_ip4_config_interface_info (dev->ip4_config); - if (!interface_info) - return NULL; - -- ret = grub_malloc (sizeof (*ret) * (interface_info->route_table_size + 1)); -+ if (grub_add (interface_info->route_table_size, 1, &nmemb)) -+ { -+ grub_errno = GRUB_ERR_OUT_OF_RANGE; -+ return NULL; -+ } - -+ ret = grub_calloc (nmemb, sizeof (*ret)); - if (!ret) - { - grub_free (interface_info); -@@ -253,7 +264,7 @@ grub_efi_ip4_interface_route_table (struct grub_efi_net_device *dev) - } - - id = 0; -- for (i = 0; i < (int)interface_info->route_table_size; i++) -+ for (i = 0; i < interface_info->route_table_size; i++) - { - char *subnet, *gateway, *mask; - grub_uint32_t u32_subnet, u32_gateway; -diff --git a/grub-core/net/efi/ip6_config.c b/grub-core/net/efi/ip6_config.c -index 017c4d05bc7..a46f6f9b685 100644 ---- a/grub-core/net/efi/ip6_config.c -+++ b/grub-core/net/efi/ip6_config.c -@@ -3,6 +3,7 @@ - #include - #include - #include -+#include - - char * - grub_efi_ip6_address_to_string (grub_efi_pxe_ipv6_address_t *address) -@@ -228,14 +229,20 @@ grub_efi_ip6_interface_route_table (struct grub_efi_net_device *dev) - { - grub_efi_ip6_config_interface_info_t *interface_info; - char **ret; -- int i, id; -+ int id; -+ grub_size_t i, nmemb; - - interface_info = efi_ip6_config_interface_info (dev->ip6_config); - if (!interface_info) - return NULL; - -- ret = grub_malloc (sizeof (*ret) * (interface_info->route_count + 1)); -+ if (grub_add (interface_info->route_count, 1, &nmemb)) -+ { -+ grub_errno = GRUB_ERR_OUT_OF_RANGE; -+ return NULL; -+ } - -+ ret = grub_calloc (nmemb, sizeof (*ret)); - if (!ret) - { - grub_free (interface_info); -@@ -243,7 +250,7 @@ grub_efi_ip6_interface_route_table (struct grub_efi_net_device *dev) - } - - id = 0; -- for (i = 0; i < (int)interface_info->route_count ; i++) -+ for (i = 0; i < interface_info->route_count ; i++) - { - char *gateway, *destination; - grub_uint64_t u64_gateway[2]; diff --git a/0141-linuxefi-fail-kernel-validation-without-shim-protoco.patch b/0141-linuxefi-fail-kernel-validation-without-shim-protoco.patch deleted file mode 100644 index 20fc7869fd905eaee3638b632577d1589056b6ca..0000000000000000000000000000000000000000 --- a/0141-linuxefi-fail-kernel-validation-without-shim-protoco.patch +++ /dev/null @@ -1,130 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dimitri John Ledkov -Date: Wed, 22 Jul 2020 11:31:43 +0100 -Subject: [PATCH] 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 -Signed-off-by: Dimitri John Ledkov ---- - grub-core/loader/arm64/linux.c | 13 +++++++++---- - grub-core/loader/efi/chainloader.c | 1 + - grub-core/loader/efi/linux.c | 1 + - grub-core/loader/i386/efi/linux.c | 17 +++++++++++------ - 4 files changed, 22 insertions(+), 10 deletions(-) - -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index 70a0075ec5e..47f8cf0d84b 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -34,6 +34,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -363,11 +364,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - grub_dprintf ("linux", "kernel @ %p\n", kernel_addr); - -- rc = grub_linuxefi_secure_validate (kernel_addr, kernel_size); -- if (rc < 0) -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) - { -- 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); -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index ac8dfd40c61..d41e8ea14a8 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -1084,6 +1084,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - - return 0; - } -+ // -1 fall-through to fail - - fail: - if (dev) -diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c -index e8b9ecb17f6..9260731c107 100644 ---- a/grub-core/loader/efi/linux.c -+++ b/grub-core/loader/efi/linux.c -@@ -33,6 +33,7 @@ struct grub_efi_shim_lock - }; - typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; - -+// Returns 1 on success, -1 on error, 0 when not available - int - grub_linuxefi_secure_validate (void *data, grub_uint32_t size) - { -diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c -index f992ceeef20..3cf0f9b330b 100644 ---- a/grub-core/loader/i386/efi/linux.c -+++ b/grub-core/loader/i386/efi/linux.c -@@ -30,6 +30,7 @@ - #include - #include - #include -+#include - - GRUB_MOD_LICENSE ("GPLv3+"); - -@@ -101,7 +102,7 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg) - - pages = BYTES_TO_PAGES(size); - grub_dprintf ("linux", "Trying to allocate %lu pages from %p\n", -- pages, (void *)max); -+ (unsigned long)pages, (void *)(unsigned long)max); - - prev_max = max; - addr = grub_efi_allocate_pages_real (max, pages, -@@ -307,12 +308,15 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - goto fail; - } - -- rc = grub_linuxefi_secure_validate (kernel, filelen); -- if (rc < 0) -+ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) - { -- grub_error (GRUB_ERR_INVALID_COMMAND, N_("%s has invalid signature"), -- argv[0]); -- goto fail; -+ rc = grub_linuxefi_secure_validate (kernel, filelen); -+ if (rc <= 0) -+ { -+ grub_error (GRUB_ERR_INVALID_COMMAND, -+ N_("%s has invalid signature"), argv[0]); -+ goto fail; -+ } - } - - lh = (struct linux_i386_kernel_header *)kernel; -@@ -386,6 +390,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - - setup_header_end_offset = *((grub_uint8_t *)kernel + 0x201); - grub_dprintf ("linux", "copying %lu bytes from %p to %p\n", -+ (unsigned long) - MIN((grub_size_t)0x202+setup_header_end_offset, - sizeof (*params)) - 0x1f1, - (grub_uint8_t *)kernel + 0x1f1, diff --git a/0142-Fix-const-char-pointers-in-grub-core-net-bootp.c.patch b/0142-Fix-const-char-pointers-in-grub-core-net-bootp.c.patch deleted file mode 100644 index 9b0db5f9e1aa935a4367b7f5a8b16d3a862f2d53..0000000000000000000000000000000000000000 --- a/0142-Fix-const-char-pointers-in-grub-core-net-bootp.c.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 20 Jul 2020 12:24:02 -0400 -Subject: [PATCH] Fix const char ** pointers in grub-core/net/bootp.c - -This will need to get folded back in the right place on the next rebase, -but it's before "Make grub_strtol() "end" pointers have safer const -qualifiers" currently, so for now I'm leaving it here instead of merging -it back with the original patch. - -Signed-off-by: Peter Jones ---- - grub-core/net/bootp.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c -index 8fb8918ae7e..7baf3540c81 100644 ---- a/grub-core/net/bootp.c -+++ b/grub-core/net/bootp.c -@@ -329,7 +329,7 @@ grub_net_configure_by_dhcp_ack (const char *name, - struct grub_net_network_level_interface *inter; - int mask = -1; - char server_ip[sizeof ("xxx.xxx.xxx.xxx")]; -- const grub_uint8_t *opt; -+ const char *opt; - grub_uint8_t opt_len, overload = 0; - const char *boot_file = 0, *server_name = 0; - grub_size_t boot_file_len, server_name_len; -@@ -505,7 +505,7 @@ grub_net_configure_by_dhcp_ack (const char *name, - if (opt && opt_len) - { - grub_env_set_net_property (name, "vendor_class_identifier", (const char *) opt, opt_len); -- if (opt && grub_strcmp (opt, "HTTPClient") == 0) -+ if (opt && grub_strcmp ((char *)opt, "HTTPClient") == 0) - { - char *proto, *ip, *pa; - diff --git a/0143-Fix-const-char-pointers-in-grub-core-net-efi-ip4_con.patch b/0143-Fix-const-char-pointers-in-grub-core-net-efi-ip4_con.patch deleted file mode 100644 index 6c16e9efd8123dfef1edd25fae1ca237559f1251..0000000000000000000000000000000000000000 --- a/0143-Fix-const-char-pointers-in-grub-core-net-efi-ip4_con.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 20 Jul 2020 12:24:02 -0400 -Subject: [PATCH] Fix const char ** pointers in grub-core/net/efi/ip4_config.c - -This will need to get folded back in the right place on the next rebase, -but it's before "Make grub_strtol() "end" pointers have safer const -qualifiers" currently, so for now I'm leaving it here instead of merging -it back with the original patch. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/ip4_config.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/efi/ip4_config.c b/grub-core/net/efi/ip4_config.c -index 9725e928f7e..cb880fc3e8f 100644 ---- a/grub-core/net/efi/ip4_config.c -+++ b/grub-core/net/efi/ip4_config.c -@@ -61,7 +61,8 @@ int - grub_efi_string_to_ip4_address (const char *val, grub_efi_ipv4_address_t *address, const char **rest) - { - grub_uint32_t newip = 0; -- int i, ncolon = 0; -+ grub_size_t i; -+ int ncolon = 0; - const char *ptr = val; - - /* Check that is not an IPv6 address */ -@@ -78,7 +79,7 @@ grub_efi_string_to_ip4_address (const char *val, grub_efi_ipv4_address_t *addres - for (i = 0; i < 4; i++) - { - unsigned long t; -- t = grub_strtoul (ptr, (char **) &ptr, 0); -+ t = grub_strtoul (ptr, &ptr, 0); - if (grub_errno) - { - grub_errno = GRUB_ERR_NONE; diff --git a/0144-Fix-const-char-pointers-in-grub-core-net-efi-ip6_con.patch b/0144-Fix-const-char-pointers-in-grub-core-net-efi-ip6_con.patch deleted file mode 100644 index 7c29683eea176b76c6d2dcecd15e829e52442596..0000000000000000000000000000000000000000 --- a/0144-Fix-const-char-pointers-in-grub-core-net-efi-ip6_con.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 20 Jul 2020 12:24:02 -0400 -Subject: [PATCH] Fix const char ** pointers in grub-core/net/efi/ip6_config.c - -This will need to get folded back in the right place on the next rebase, -but it's before "Make grub_strtol() "end" pointers have safer const -qualifiers" currently, so for now I'm leaving it here instead of merging -it back with the original patch. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/ip6_config.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/net/efi/ip6_config.c b/grub-core/net/efi/ip6_config.c -index a46f6f9b685..1c5415d7185 100644 ---- a/grub-core/net/efi/ip6_config.c -+++ b/grub-core/net/efi/ip6_config.c -@@ -85,7 +85,7 @@ grub_efi_string_to_ip6_address (const char *val, grub_efi_ipv6_address_t *addres - ptr++; - continue; - } -- t = grub_strtoul (ptr, (char **) &ptr, 16); -+ t = grub_strtoul (ptr, &ptr, 16); - if (grub_errno) - { - grub_errno = GRUB_ERR_NONE; diff --git a/0145-Fix-const-char-pointers-in-grub-core-net-efi-net.c.patch b/0145-Fix-const-char-pointers-in-grub-core-net-efi-net.c.patch deleted file mode 100644 index 0fe90c8b0a0d4ec3b397db037236cf8bab467ad2..0000000000000000000000000000000000000000 --- a/0145-Fix-const-char-pointers-in-grub-core-net-efi-net.c.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 20 Jul 2020 12:24:02 -0400 -Subject: [PATCH] Fix const char ** pointers in grub-core/net/efi/net.c - -This will need to get folded back in the right place on the next rebase, -but it's before "Make grub_strtol() "end" pointers have safer const -qualifiers" currently, so for now I'm leaving it here instead of merging -it back with the original patch. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/net.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/efi/net.c b/grub-core/net/efi/net.c -index a3f0535d43c..78e5442fc52 100644 ---- a/grub-core/net/efi/net.c -+++ b/grub-core/net/efi/net.c -@@ -729,7 +729,7 @@ grub_efi_net_parse_address (const char *address, - { - grub_uint32_t subnet_mask_size; - -- subnet_mask_size = grub_strtoul (rest + 1, (char **) &rest, 0); -+ subnet_mask_size = grub_strtoul (rest + 1, &rest, 0); - - if (!grub_errno && subnet_mask_size <= 32 && *rest == 0) - { -@@ -758,7 +758,7 @@ grub_efi_net_parse_address (const char *address, - { - grub_efi_uint8_t prefix_length; - -- prefix_length = grub_strtoul (rest + 1, (char **) &rest, 0); -+ prefix_length = grub_strtoul (rest + 1, &rest, 0); - if (!grub_errno && prefix_length <= 128 && *rest == 0) - { - ip6->prefix_length = prefix_length; diff --git a/0146-Fix-const-char-pointers-in-grub-core-net-efi-pxe.c.patch b/0146-Fix-const-char-pointers-in-grub-core-net-efi-pxe.c.patch deleted file mode 100644 index 59f29e4f651ca6a4a55f3a4f5919e2e663bcdbf5..0000000000000000000000000000000000000000 --- a/0146-Fix-const-char-pointers-in-grub-core-net-efi-pxe.c.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 20 Jul 2020 12:24:02 -0400 -Subject: [PATCH] Fix const char ** pointers in grub-core/net/efi/pxe.c - -This will need to get folded back in the right place on the next rebase, -but it's before "Make grub_strtol() "end" pointers have safer const -qualifiers" currently, so for now I'm leaving it here instead of merging -it back with the original patch. - -Signed-off-by: Peter Jones ---- - grub-core/net/efi/pxe.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/grub-core/net/efi/pxe.c b/grub-core/net/efi/pxe.c -index 531949cba5c..73e2bb01c1b 100644 ---- a/grub-core/net/efi/pxe.c -+++ b/grub-core/net/efi/pxe.c -@@ -187,7 +187,7 @@ parse_ip6 (const char *val, grub_uint64_t *ip, const char **rest) - ptr++; - continue; - } -- t = grub_strtoul (ptr, (char **) &ptr, 16); -+ t = grub_strtoul (ptr, &ptr, 16); - if (grub_errno) - { - grub_errno = GRUB_ERR_NONE; -@@ -225,7 +225,7 @@ pxe_open (struct grub_efi_net_device *dev, - int type __attribute__((unused))) - { - int i; -- char *p; -+ const char *p; - grub_efi_status_t status; - grub_efi_pxe_ip_address_t server_ip; - grub_efi_uint64_t file_size = 0; -@@ -313,7 +313,7 @@ pxe_read (struct grub_efi_net_device *dev, - grub_size_t len) - { - int i; -- char *p; -+ const char *p; - grub_efi_status_t status; - grub_efi_pxe_t *pxe = (prefer_ip6) ? dev->ip6_pxe : dev->ip4_pxe; - grub_efi_uint64_t bufsz = len; diff --git a/0147-Add-systemd-integration-scripts-to-make-systemctl-re.patch b/0147-Add-systemd-integration-scripts-to-make-systemctl-re.patch deleted file mode 100644 index 8e2481e71d46bc3b8d74ea79054c818e9a6790a9..0000000000000000000000000000000000000000 --- a/0147-Add-systemd-integration-scripts-to-make-systemctl-re.patch +++ /dev/null @@ -1,190 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Wed, 22 Jul 2020 14:03:42 +0200 -Subject: [PATCH] Add systemd integration scripts to make "systemctl reboot - --boot-loader-menu=xxx" work with grub - -This commit adds a number of scripts / config files to make -"systemctl reboot --boot-loader-menu=xxx" work with grub: - -1. /lib/systemd/system/systemd-logind.service.d/10-grub.conf -This sets SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU in the env. for logind, -indicating that the boot-loader which is used supports this feature, see: -https://github.com/systemd/systemd/blob/master/docs/ENVIRONMENT.md - -2. /lib/systemd/system/grub-systemd-integration.service - /lib/systemd/system/reboot.target.wants/grub-systemd-integration.service -> - ../grub-systemd-integration.service - /usr/libexec/grub/grub-systemd-integration.sh - -The symlink in the .wants dir causes the added service file to be started -by systemd just before rebooting the system. -If /run/systemd/reboot-to-boot-loader-menu exist then the service will run -the grub-systemd-integration.sh script. -This script sets the new menu_show_once_timeout grubenv variable to the -requested timeout in seconds. - -3. /etc/grub.d/14_menu_show_once - -This new grub-mkconfig snippet adds the necessary code to the generated -grub.conf to honor the new menu_show_once_timeout variable, and to -automatically clear it after consuming it. - -Note the service and libexec script use grub-systemd-integration as name -because in the future they may be used to add further integration with -systemctl reboot --foo options, e.g. support for --boot-loader-entry=NAME. - -A few notes about upstreaming this patch from the rhboot grub2 fork: -1. I have deliberately put the grub.conf bits for this in a new / separate - grub-mkconfig snippet generator for easy upstreaming -2. Even though the commit message mentions the .wants symlink for the .service - I have been unable to come up with a clean way to do this at "make install" - time, this should be fixed before upstreaming. - -Downstream notes: -1. Since make install does not add the .wants symlink, this needs to be done - in grub2.spec %install -2. This is keeping support for the "old" Fedora specific menu_show_once env - variable, which has a hardcoded timeout of 60 sec in 12_menu_auto_hide in - place for now. This can be dropped (eventually) in a follow-up patch once - GNOME has been converted to use the systemd dbus API equivalent of - "systemctl reboot --boot-loader-menu=xxx". - -Signed-off-by: Hans de Goede ---- - Makefile.util.def | 27 ++++++++++++++++++++++++ - conf/Makefile.common | 6 ++++++ - util/grub.d/14_menu_show_once.in | 13 ++++++++++++ - util/systemd/10-grub-logind-service.conf.in | 2 ++ - util/systemd/grub-systemd-integration.service.in | 8 +++++++ - util/systemd/systemd-integration.sh.in | 6 ++++++ - 6 files changed, 62 insertions(+) - create mode 100755 util/grub.d/14_menu_show_once.in - create mode 100644 util/systemd/10-grub-logind-service.conf.in - create mode 100644 util/systemd/grub-systemd-integration.service.in - create mode 100644 util/systemd/systemd-integration.sh.in - -diff --git a/Makefile.util.def b/Makefile.util.def -index 2e6ad979c3e..9927c2cfd6a 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -470,6 +470,12 @@ script = { - installdir = grubconf; - }; - -+script = { -+ name = '14_menu_show_once'; -+ common = util/grub.d/14_menu_show_once.in; -+ installdir = grubconf; -+}; -+ - script = { - name = '01_users'; - common = util/grub.d/01_users.in; -@@ -569,6 +575,27 @@ script = { - installdir = grubconf; - }; - -+script = { -+ name = 'grub-systemd-integration.service'; -+ common = util/systemd/grub-systemd-integration.service.in; -+ installdir = systemdunit; -+ condition = COND_HOST_LINUX; -+}; -+ -+script = { -+ name = 'systemd-integration.sh'; -+ common = util/systemd/systemd-integration.sh.in; -+ installdir = grublibexec; -+ condition = COND_HOST_LINUX; -+}; -+ -+script = { -+ name = '10-grub-logind-service.conf'; -+ common = util/systemd/10-grub-logind-service.conf.in; -+ installdir = systemd_logind_service_d; -+ condition = COND_HOST_LINUX; -+}; -+ - program = { - mansection = 1; - name = grub-mkrescue; -diff --git a/conf/Makefile.common b/conf/Makefile.common -index 0647c53b916..9fe5863b2d9 100644 ---- a/conf/Makefile.common -+++ b/conf/Makefile.common -@@ -63,8 +63,11 @@ CCASFLAGS_LIBRARY = $(UTILS_CCASFLAGS) - # Other variables - - grubconfdir = $(sysconfdir)/grub.d -+grublibexecdir = $(libexecdir)/$(grubdirname) - platformdir = $(pkglibdir)/$(target_cpu)-$(platform) - starfielddir = $(pkgdatadir)/themes/starfield -+systemdunitdir = ${prefix}/lib/systemd/system -+systemd_logind_service_ddir = $(systemdunitdir)/systemd-logind.service.d - - CFLAGS_GNULIB = -Wno-undef -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Werror=trampolines -fno-trampolines - CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/lib/gnulib -I$(top_srcdir)/grub-core/lib/gnulib -@@ -121,6 +124,9 @@ noinst_LIBRARIES = - dist_noinst_DATA = - platform_SCRIPTS = - platform_PROGRAMS = -+grublibexec_SCRIPTS = -+systemdunit_SCRIPTS = -+systemd_logind_service_d_SCRIPTS = - - TESTS = - EXTRA_DIST = -diff --git a/util/grub.d/14_menu_show_once.in b/util/grub.d/14_menu_show_once.in -new file mode 100755 -index 00000000000..1cd7f36142b ---- /dev/null -+++ b/util/grub.d/14_menu_show_once.in -@@ -0,0 +1,13 @@ -+#! /bin/sh -+# Force the menu to be shown once, with a timeout of ${menu_show_once_timeout} -+# if requested by ${menu_show_once_timeout} being set in the env. -+cat << EOF -+if [ x\$feature_timeout_style = xy ]; then -+ if [ "\${menu_show_once_timeout}" ]; then -+ set timeout_style=menu -+ set timeout="\${menu_show_once_timeout}" -+ unset menu_show_once_timeout -+ save_env menu_show_once_timeout -+ fi -+fi -+EOF -diff --git a/util/systemd/10-grub-logind-service.conf.in b/util/systemd/10-grub-logind-service.conf.in -new file mode 100644 -index 00000000000..f2d4ac00732 ---- /dev/null -+++ b/util/systemd/10-grub-logind-service.conf.in -@@ -0,0 +1,2 @@ -+[Service] -+Environment=SYSTEMD_REBOOT_TO_BOOT_LOADER_MENU=true -diff --git a/util/systemd/grub-systemd-integration.service.in b/util/systemd/grub-systemd-integration.service.in -new file mode 100644 -index 00000000000..c81fb594ce1 ---- /dev/null -+++ b/util/systemd/grub-systemd-integration.service.in -@@ -0,0 +1,8 @@ -+[Unit] -+Description=Grub2 systemctl reboot --boot-loader-menu=... support -+Before=umount.target systemd-reboot.service -+DefaultDependencies=no -+ConditionPathExists=/run/systemd/reboot-to-boot-loader-menu -+ -+[Service] -+ExecStart=@libexecdir@/@grubdirname@/systemd-integration.sh -diff --git a/util/systemd/systemd-integration.sh.in b/util/systemd/systemd-integration.sh.in -new file mode 100644 -index 00000000000..dc1218597bc ---- /dev/null -+++ b/util/systemd/systemd-integration.sh.in -@@ -0,0 +1,6 @@ -+#!/bin/sh -+ -+TIMEOUT_USEC=$(cat /run/systemd/reboot-to-boot-loader-menu) -+TIMEOUT=$(((TIMEOUT_USEC + 500000) / 1000000)) -+ -+@grub_editenv@ - set menu_show_once_timeout=$TIMEOUT diff --git a/0148-systemd-integration.sh-Also-set-old-menu_show_once-g.patch b/0148-systemd-integration.sh-Also-set-old-menu_show_once-g.patch deleted file mode 100644 index 9021de505793c9dad90df26f5264c2979268c13b..0000000000000000000000000000000000000000 --- a/0148-systemd-integration.sh-Also-set-old-menu_show_once-g.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Thu, 23 Jul 2020 09:27:36 +0200 -Subject: [PATCH] systemd-integration.sh: Also set old menu_show_once grubenv - var - -Downstream RH / Fedora patch for compatibility with old, not (yet) -regenerated grub.cfg files which miss the menu_show_once_timeout check. -This older grubenv variable leads to a fixed timeout of 60 seconds. - -Note that the new menu_show_once_timeout will overrule these 60 seconds -if both are set and the grub.cfg does have the menu_show_once_timeout -check. - -Signed-off-by: Hans de Goede ---- - util/systemd/systemd-integration.sh.in | 5 +++++ - 1 file changed, 5 insertions(+) - -diff --git a/util/systemd/systemd-integration.sh.in b/util/systemd/systemd-integration.sh.in -index dc1218597bc..a4c071c5b0c 100644 ---- a/util/systemd/systemd-integration.sh.in -+++ b/util/systemd/systemd-integration.sh.in -@@ -4,3 +4,8 @@ TIMEOUT_USEC=$(cat /run/systemd/reboot-to-boot-loader-menu) - TIMEOUT=$(((TIMEOUT_USEC + 500000) / 1000000)) - - @grub_editenv@ - set menu_show_once_timeout=$TIMEOUT -+ -+# Downstream RH / Fedora patch for compatibility with old, not (yet) -+# regenerated grub.cfg files which miss the menu_show_once_timeout check -+# this older grubenv variable leads to a fixed timeout of 60 seconds -+@grub_editenv@ - set menu_show_once=1 diff --git a/0149-at_keyboard-use-set-1-when-keyboard-is-in-Translate-.patch b/0149-at_keyboard-use-set-1-when-keyboard-is-in-Translate-.patch deleted file mode 100644 index c3388409860f73d9656d4ec7eabd6d51db6379ff..0000000000000000000000000000000000000000 --- a/0149-at_keyboard-use-set-1-when-keyboard-is-in-Translate-.patch +++ /dev/null @@ -1,121 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Thu, 3 Dec 2020 09:13:24 +0100 -Subject: [PATCH] at_keyboard: use set 1 when keyboard is in Translate mode -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When keyboard controller acts in Translate mode (0x40 mask), then use -set 1 since translation is done. -Otherwise use the mode queried from the controller (usually set 2). - -Added "atkeyb" debugging messages in at_keyboard module as well. - -Resolves: rhbz#1897587 - -Tested on: -- Asus N53SN (set 1 used) -- Dell Precision (set 1 used) -- HP Elitebook (set 2 used) -- HP G5430 (set 1 used, keyboard in XT mode!) -- Lenovo P71 & Lenovo T460s (set 2 used) -- QEMU/KVM (set 1 used) - -Signed-off-by: Renaud Métrich ---- - grub-core/term/at_keyboard.c | 29 ++++++++++++++++++++++++----- - include/grub/at_keyboard.h | 4 ++++ - 2 files changed, 28 insertions(+), 5 deletions(-) - -diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c -index 597111077bd..26014382608 100644 ---- a/grub-core/term/at_keyboard.c -+++ b/grub-core/term/at_keyboard.c -@@ -135,20 +135,28 @@ query_mode (void) - int e; - - e = write_mode (0); -- if (!e) -+ if (!e) { -+ grub_dprintf("atkeyb", "query_mode: write_mode(0) failed\n"); - return 0; -+ } - - do { - keyboard_controller_wait_until_ready (); - ret = grub_inb (KEYBOARD_REG_DATA); - } while (ret == GRUB_AT_ACK); - /* QEMU translates the set even in no-translate mode. */ -- if (ret == 0x43 || ret == 1) -+ if (ret == 0x43 || ret == 1) { -+ grub_dprintf("atkeyb", "query_mode: returning 1 (ret=0x%x)\n", ret); - return 1; -- if (ret == 0x41 || ret == 2) -+ } -+ if (ret == 0x41 || ret == 2) { -+ grub_dprintf("atkeyb", "query_mode: returning 2 (ret=0x%x)\n", ret); - return 2; -- if (ret == 0x3f || ret == 3) -+ } -+ if (ret == 0x3f || ret == 3) { -+ grub_dprintf("atkeyb", "query_mode: returning 3 (ret=0x%x)\n", ret); - return 3; -+ } - return 0; - } - -@@ -165,7 +173,13 @@ set_scancodes (void) - } - - #if !USE_SCANCODE_SET -- ps2_state.current_set = 1; -+ if ((grub_keyboard_controller_orig & KEYBOARD_AT_TRANSLATE) == KEYBOARD_AT_TRANSLATE) { -+ grub_dprintf ("atkeyb", "queried set is %d but keyboard in Translate mode, so actually in set 1\n", grub_keyboard_orig_set); -+ ps2_state.current_set = 1; -+ } else { -+ grub_dprintf ("atkeyb", "using queried set %d\n", grub_keyboard_orig_set); -+ ps2_state.current_set = grub_keyboard_orig_set; -+ } - return; - #else - -@@ -266,6 +280,7 @@ grub_keyboard_controller_init (void) - grub_keyboard_orig_set = 2; - #else - grub_keyboard_controller_orig = grub_keyboard_controller_read (); -+ grub_dprintf ("atkeyb", "grub_keyboard_controller_orig = 0x%x\n", grub_keyboard_controller_orig); - grub_keyboard_orig_set = query_mode (); - #endif - set_scancodes (); -@@ -275,11 +290,15 @@ grub_keyboard_controller_init (void) - static grub_err_t - grub_keyboard_controller_fini (struct grub_term_input *term __attribute__ ((unused))) - { -+/* In !USE_SCANCODE_SET mode, we didn't change anything, so nothing to restore */ -+#if USE_SCANCODE_SET - if (ps2_state.current_set == 0) - return GRUB_ERR_NONE; -+ grub_dprintf ("atkeyb", "restoring set %d, controller 0x%x\n", grub_keyboard_orig_set, grub_keyboard_controller_orig); - if (grub_keyboard_orig_set) - write_mode (grub_keyboard_orig_set); - grub_keyboard_controller_write (grub_keyboard_controller_orig); -+#endif - return GRUB_ERR_NONE; - } - -diff --git a/include/grub/at_keyboard.h b/include/grub/at_keyboard.h -index bcb4d9ba78f..9414dc1b996 100644 ---- a/include/grub/at_keyboard.h -+++ b/include/grub/at_keyboard.h -@@ -19,6 +19,10 @@ - #ifndef GRUB_AT_KEYBOARD_HEADER - #define GRUB_AT_KEYBOARD_HEADER 1 - -+/* -+ * Refer to https://wiki.osdev.org/%228042%22_PS/2_Controller for details. -+ */ -+ - /* Used for sending commands to the controller. */ - #define KEYBOARD_COMMAND_ISREADY(x) !((x) & 0x02) - #define KEYBOARD_COMMAND_READ 0x20 diff --git a/0150-grub-install-disable-support-for-EFI-platforms.patch b/0150-grub-install-disable-support-for-EFI-platforms.patch deleted file mode 100644 index 41003e2548dac8d0a1adccd069388e3e2c1f61c3..0000000000000000000000000000000000000000 --- a/0150-grub-install-disable-support-for-EFI-platforms.patch +++ /dev/null @@ -1,120 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jan Hlavac -Date: Fri, 20 Nov 2020 23:51:47 +0100 -Subject: [PATCH] grub-install: disable support for EFI platforms - -For each platform, GRUB is shipped as a kernel image and a set of -modules. These files are then used by the grub-install utility to -install GRUB on a specific device. However, in order to support UEFI -Secure Boot, the resulting EFI binary must be signed by a recognized -private key. For this reason, for EFI platforms, most distributions also -ship prebuilt EFI binaries signed by a distribution-specific private -key. In this case, however, the grub-install utility should not be used -because it would overwrite the signed EFI binary. - -The current fix is suboptimal because it preserves all EFI-related code. -A better solution could be to modularize the code and provide a -build-time option. - -Resolves: rhbz#1737444 - -Signed-off-by: Jan Hlavac ---- - util/grub-install.c | 37 ++++++++++++++++--------------------- - docs/grub.texi | 7 +++++++ - util/grub-install.8 | 4 +++- - 3 files changed, 26 insertions(+), 22 deletions(-) - -diff --git a/util/grub-install.c b/util/grub-install.c -index a2bec7446cb..5babc7af551 100644 ---- a/util/grub-install.c -+++ b/util/grub-install.c -@@ -899,6 +899,22 @@ main (int argc, char *argv[]) - - platform = grub_install_get_target (grub_install_source_directory); - -+ switch (platform) -+ { -+ case GRUB_INSTALL_PLATFORM_ARM_EFI: -+ case GRUB_INSTALL_PLATFORM_ARM64_EFI: -+ case GRUB_INSTALL_PLATFORM_I386_EFI: -+ case GRUB_INSTALL_PLATFORM_IA64_EFI: -+ case GRUB_INSTALL_PLATFORM_X86_64_EFI: -+ is_efi = 1; -+ grub_util_error (_("this utility cannot be used for EFI platforms" -+ " because it does not support UEFI Secure Boot")); -+ break; -+ default: -+ is_efi = 0; -+ break; -+ } -+ - { - char *platname = grub_install_get_platform_name (platform); - fprintf (stderr, _("Installing for %s platform.\n"), platname); -@@ -1011,28 +1027,7 @@ main (int argc, char *argv[]) - grub_hostfs_init (); - grub_host_init (); - -- switch (platform) -- { -- case GRUB_INSTALL_PLATFORM_I386_EFI: -- case GRUB_INSTALL_PLATFORM_X86_64_EFI: -- case GRUB_INSTALL_PLATFORM_ARM_EFI: -- case GRUB_INSTALL_PLATFORM_ARM64_EFI: -- case GRUB_INSTALL_PLATFORM_RISCV32_EFI: -- case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -- case GRUB_INSTALL_PLATFORM_IA64_EFI: -- is_efi = 1; -- break; -- default: -- is_efi = 0; -- break; -- -- /* pacify warning. */ -- case GRUB_INSTALL_PLATFORM_MAX: -- break; -- } -- - /* Find the EFI System Partition. */ -- - if (is_efi) - { - grub_fs_t fs; -diff --git a/docs/grub.texi b/docs/grub.texi -index 04ed6ac1f07..4870faaa00a 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -6509,6 +6509,13 @@ grub2-install @var{install_device} - The device name @var{install_device} is an OS device name or a GRUB - device name. - -+In order to support UEFI Secure Boot, the resulting GRUB EFI binary must -+be signed by a recognized private key. For this reason, for EFI -+platforms, most distributions also ship prebuilt GRUB EFI binaries -+signed by a distribution-specific private key. In this case, however, -+@command{grub2-install} should not be used because it would overwrite -+the signed EFI binary. -+ - @command{grub2-install} accepts the following options: - - @table @option -diff --git a/util/grub-install.8 b/util/grub-install.8 -index 1db89e94b3b..811d441b16c 100644 ---- a/util/grub-install.8 -+++ b/util/grub-install.8 -@@ -1,4 +1,4 @@ --.TH GRUB-INSTALL 1 "Wed Feb 26 2014" -+.TH GRUB-INSTALL 1 "Fri Nov 20 2020" - .SH NAME - \fBgrub-install\fR \(em Install GRUB on a device. - -@@ -31,6 +31,8 @@ - .SH DESCRIPTION - \fBgrub-install\fR installs GRUB onto a device. This includes copying GRUB images into the target directory (generally \fI/boot/grub\fR), and on some platforms may also include installing GRUB onto a boot sector. - -+In order to support UEFI Secure Boot, the resulting GRUB EFI binary must be signed by a recognized private key. For this reason, for EFI platforms, most distributions also ship prebuilt GRUB EFI binaries signed by a distribution-specific private key. In this case, however, the \fBgrub-install\fR utility should not be used because it would overwrite the signed EFI binary. -+ - .SH OPTIONS - .TP - \fB--modules\fR=\fIMODULES\fR\! diff --git a/0151-New-with-debug-timestamps-configure-flag-to-prepend-.patch b/0151-New-with-debug-timestamps-configure-flag-to-prepend-.patch deleted file mode 100644 index d216284c1218f2bf5243ae1d2bac12302ca9fc60..0000000000000000000000000000000000000000 --- a/0151-New-with-debug-timestamps-configure-flag-to-prepend-.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Sat, 23 Nov 2019 14:57:41 +0100 -Subject: [PATCH] New --with-debug-timestamps configure flag to prepend debug - traces with absolute and relative timestamp -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Renaud Métrich ---- - configure.ac | 18 ++++++++++++++++++ - grub-core/kern/misc.c | 20 ++++++++++++++++++++ - config.h.in | 1 + - 3 files changed, 39 insertions(+) - -diff --git a/configure.ac b/configure.ac -index c6bd965f1f9..3c808a72230 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1613,6 +1613,17 @@ else - fi - AC_SUBST([BOOT_TIME_STATS]) - -+AC_ARG_WITH([debug-timestamps], -+ AS_HELP_STRING([--with-debug-timestamps], -+ [prepend debug traces with absolute and relative timestamps])) -+ -+if test x$with_debug_timestamps = xyes; then -+ DEBUG_WITH_TIMESTAMPS=1 -+else -+ DEBUG_WITH_TIMESTAMPS=0 -+fi -+AC_SUBST([DEBUG_WITH_TIMESTAMPS]) -+ - AC_ARG_ENABLE([grub-emu-sdl], - [AS_HELP_STRING([--enable-grub-emu-sdl], - [build and install the `grub-emu' debugging utility with SDL support (default=guessed)])]) -@@ -2194,6 +2205,7 @@ AM_CONDITIONAL([COND_APPLE_LINKER], [test x$TARGET_APPLE_LINKER = x1]) - AM_CONDITIONAL([COND_ENABLE_EFIEMU], [test x$enable_efiemu = xyes]) - AM_CONDITIONAL([COND_ENABLE_CACHE_STATS], [test x$DISK_CACHE_STATS = x1]) - AM_CONDITIONAL([COND_ENABLE_BOOT_TIME_STATS], [test x$BOOT_TIME_STATS = x1]) -+AM_CONDITIONAL([COND_DEBUG_WITH_TIMESTAMPS], [test x$DEBUG_WITH_TIMESTAMPS = x1]) - - AM_CONDITIONAL([COND_HAVE_CXX], [test x$HAVE_CXX = xyes]) - -@@ -2289,6 +2301,12 @@ else - echo With boot time statistics: No - fi - -+if [ x"$with_debug_timestamps" = xyes ]; then -+echo Debug traces with timestamps: Yes -+else -+echo Debug traces with timestamps: No -+fi -+ - if [ x"$efiemu_excuse" = x ]; then - echo efiemu runtime: Yes - else -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 578bf51a5fc..9f54b6b7d2d 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -25,6 +25,9 @@ - #include - #include - #include -+#if DEBUG_WITH_TIMESTAMPS -+#include -+#endif - - union printf_arg - { -@@ -192,9 +195,26 @@ grub_real_dprintf (const char *file, const int line, const char *condition, - const char *fmt, ...) - { - va_list args; -+#if DEBUG_WITH_TIMESTAMPS -+ static long unsigned int last_time = 0; -+ static int last_had_cr = 1; -+#endif - - if (grub_debug_enabled (condition)) - { -+#if DEBUG_WITH_TIMESTAMPS -+ /* Don't print timestamp if last printed message isn't terminated yet */ -+ if (last_had_cr) { -+ long unsigned int tmabs = (long unsigned int) grub_get_time_ms(); -+ long unsigned int tmrel = tmabs - last_time; -+ last_time = tmabs; -+ grub_printf ("%3lu.%03lus +%2lu.%03lus ", tmabs / 1000, tmabs % 1000, tmrel / 1000, tmrel % 1000); -+ } -+ if (fmt[grub_strlen(fmt)-1] == '\n') -+ last_had_cr = 1; -+ else -+ last_had_cr = 0; -+#endif - grub_printf ("%s:%d: ", file, line); - va_start (args, fmt); - grub_vprintf (fmt, args); -diff --git a/config.h.in b/config.h.in -index c7e316f0f1f..c80e3e0aba3 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -12,6 +12,7 @@ - /* Define to 1 to enable disk cache statistics. */ - #define DISK_CACHE_STATS @DISK_CACHE_STATS@ - #define BOOT_TIME_STATS @BOOT_TIME_STATS@ -+#define DEBUG_WITH_TIMESTAMPS @DEBUG_WITH_TIMESTAMPS@ - - /* We don't need those. */ - #define MINILZO_CFG_SKIP_LZO_PTR 1 diff --git a/0152-Added-debug-statements-to-grub_disk_open-and-grub_di.patch b/0152-Added-debug-statements-to-grub_disk_open-and-grub_di.patch deleted file mode 100644 index cbb1a38e3ab76bad82372262ee46967cf5888a39..0000000000000000000000000000000000000000 --- a/0152-Added-debug-statements-to-grub_disk_open-and-grub_di.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Sat, 23 Nov 2019 15:22:16 +0100 -Subject: [PATCH] Added debug statements to grub_disk_open() and - grub_disk_close() on success -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Renaud Métrich ---- - grub-core/kern/disk.c | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/grub-core/kern/disk.c b/grub-core/kern/disk.c -index e1b0e073e09..05a28ab1429 100644 ---- a/grub-core/kern/disk.c -+++ b/grub-core/kern/disk.c -@@ -285,6 +285,8 @@ grub_disk_open (const char *name) - return 0; - } - -+ grub_dprintf ("disk", "Opening `%s' succeeded.\n", name); -+ - return disk; - } - -@@ -292,7 +294,7 @@ void - grub_disk_close (grub_disk_t disk) - { - grub_partition_t part; -- grub_dprintf ("disk", "Closing `%s'.\n", disk->name); -+ grub_dprintf ("disk", "Closing `%s'...\n", disk->name); - - if (disk->dev && disk->dev->disk_close) - (disk->dev->disk_close) (disk); -@@ -306,8 +308,10 @@ grub_disk_close (grub_disk_t disk) - grub_free (disk->partition); - disk->partition = part; - } -+ grub_dprintf ("disk", "Closing `%s' succeeded.\n", disk->name); - grub_free ((void *) disk->name); - grub_free (disk); -+ - } - - /* Small read (less than cache size and not pass across cache unit boundaries). diff --git a/0153-Introduce-function-grub_debug_is_enabled-void-return.patch b/0153-Introduce-function-grub_debug_is_enabled-void-return.patch deleted file mode 100644 index 4e4718b7898a951a26d8ea939e0b681ab41c3795..0000000000000000000000000000000000000000 --- a/0153-Introduce-function-grub_debug_is_enabled-void-return.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Mon, 25 Nov 2019 09:29:53 +0100 -Subject: [PATCH] Introduce function grub_debug_is_enabled(void) returning 1 if - 'debug' is in the environment and not empty -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Renaud Métrich ---- - grub-core/kern/misc.c | 13 +++++++++++++ - include/grub/misc.h | 1 + - 2 files changed, 14 insertions(+) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index 9f54b6b7d2d..a186ad3dd41 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -163,6 +163,19 @@ int grub_err_printf (const char *fmt, ...) - __attribute__ ((alias("grub_printf"))); - #endif - -+/* Return 1 if 'debug' is set and not empty */ -+int -+grub_debug_is_enabled (void) -+{ -+ const char *debug; -+ -+ debug = grub_env_get ("debug"); -+ if (!debug || debug[0] == '\0') -+ return 0; -+ -+ return 1; -+} -+ - int - grub_debug_enabled (const char * condition) - { -diff --git a/include/grub/misc.h b/include/grub/misc.h -index 3adc4036e3b..6c4aa85ac50 100644 ---- a/include/grub/misc.h -+++ b/include/grub/misc.h -@@ -340,6 +340,7 @@ grub_puts (const char *s) - } - - int EXPORT_FUNC(grub_puts_) (const char *s); -+int EXPORT_FUNC(grub_debug_is_enabled) (void); - int EXPORT_FUNC(grub_debug_enabled) (const char *condition); - void EXPORT_FUNC(grub_real_dprintf) (const char *file, - const int line, diff --git a/0154-Don-t-clear-screen-when-debugging-is-enabled.patch b/0154-Don-t-clear-screen-when-debugging-is-enabled.patch deleted file mode 100644 index d17b080c5e02f587175459f019f0eace26eee521..0000000000000000000000000000000000000000 --- a/0154-Don-t-clear-screen-when-debugging-is-enabled.patch +++ /dev/null @@ -1,31 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Sat, 23 Nov 2019 16:23:54 +0100 -Subject: [PATCH] Don't clear screen when debugging is enabled -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Renaud Métrich -[rharwood@redhat.com: rebase fuzz] -Signed-off-by: Robbie Harwood ---- - grub-core/normal/main.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 1970e4816a8..4ebdbd228d4 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -215,8 +215,9 @@ grub_normal_init_page (struct grub_term_output *term, - char *msg_formatted; - grub_uint32_t *unicode_msg; - grub_uint32_t *last_position; -- -- grub_term_cls (term); -+ -+ if (! grub_debug_is_enabled ()) -+ grub_term_cls (term); - - msg_formatted = grub_xasprintf (_("GNU GRUB version %s"), PACKAGE_VERSION); - if (!msg_formatted) diff --git a/0155-grub_file_-instrumentation-new-file-debug-tag.patch b/0155-grub_file_-instrumentation-new-file-debug-tag.patch deleted file mode 100644 index 0cc6b8c98eafa150f85697d0172c22e8b713b6ff..0000000000000000000000000000000000000000 --- a/0155-grub_file_-instrumentation-new-file-debug-tag.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Fri, 29 Nov 2019 11:02:00 +0100 -Subject: [PATCH] grub_file_* instrumentation (new 'file' debug tag) -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Signed-off-by: Renaud Métrich ---- - grub-core/kern/file.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c -index 58454458c47..e19aea3e514 100644 ---- a/grub-core/kern/file.c -+++ b/grub-core/kern/file.c -@@ -66,6 +66,8 @@ grub_file_open (const char *name, enum grub_file_type type) - const char *file_name; - grub_file_filter_id_t filter; - -+ grub_dprintf ("file", "Opening `%s' ...\n", name); -+ - device_name = grub_file_get_device_name (name); - if (grub_errno) - goto fail; -@@ -128,6 +130,8 @@ grub_file_open (const char *name, enum grub_file_type type) - if (!file) - grub_file_close (last_file); - -+ grub_dprintf ("file", "Opening `%s' succeeded.\n", name); -+ - return file; - - fail: -@@ -138,6 +142,8 @@ grub_file_open (const char *name, enum grub_file_type type) - - grub_free (file); - -+ grub_dprintf ("file", "Opening `%s' failed.\n", name); -+ - return 0; - } - -@@ -169,6 +175,7 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) - - if (len == 0) - return 0; -+ - read_hook = file->read_hook; - read_hook_data = file->read_hook_data; - if (!file->read_hook) -@@ -189,11 +196,18 @@ grub_file_read (grub_file_t file, void *buf, grub_size_t len) - grub_err_t - grub_file_close (grub_file_t file) - { -+ grub_dprintf ("file", "Closing `%s' ...\n", file->name); - if (file->fs->fs_close) - (file->fs->fs_close) (file); - - if (file->device) - grub_device_close (file->device); -+ -+ if (grub_errno == GRUB_ERR_NONE) -+ grub_dprintf ("file", "Closing `%s' succeeded.\n", file->name); -+ else -+ grub_dprintf ("file", "Closing `%s' failed with %d.\n", file->name, grub_errno); -+ - grub_free (file->name); - grub_free (file); - return grub_errno; diff --git a/0159-Add-at_keyboard_fallback_set-var-to-force-the-set-ma.patch b/0159-Add-at_keyboard_fallback_set-var-to-force-the-set-ma.patch deleted file mode 100644 index 01e7e678065830fce114171c60706ea62bc4d9ba..0000000000000000000000000000000000000000 --- a/0159-Add-at_keyboard_fallback_set-var-to-force-the-set-ma.patch +++ /dev/null @@ -1,245 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Fri, 18 Dec 2020 15:39:26 +0100 -Subject: [PATCH] Add 'at_keyboard_fallback_set' var to force the set manually -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This seems required with HP DL380p Gen 8 systems. -Indeed, with this system, we can see the following sequence: - -1. controller is queried to get current configuration (returns 0x30 which is quite standard) -2. controller is queried to get the current keyboard set in used, using code 0xf0 (first part) -3. controller answers with 0xfa which means "ACK" (== ok) -4. then we send "0" to tell "we want to know which set your are supporting" -5. controller answers with 0xfa ("ACK") -6. controller should then give us 1, 2, 3 or 0x43, 0x41, 0x3f, but here it gives us 0xfe which means "NACK" - -Since there seems no way to determine the current set, and in fact the -controller expects set2 to be used, we need to rely on an environment -variable. -Everything has been tested on this system: using 0xFE (resend command), -making sure we wait for ACK in the 2 steps "write_mode", etc. - -Below is litterature I used to come up with "there is no other -solution": -- https://wiki.osdev.org/%228042%22_PS/2_Controller -- http://www-ug.eecg.toronto.edu/msl/nios_devices/datasheets/PS2%20Keyboard%20Protocol.htm -- http://www.s100computers.com/My%20System%20Pages/MSDOS%20Board/PC%20Keyboard.pdf - -Signed-off-by: Renaud Métrich -Signed-off-by: Robbie Harwood ---- - grub-core/term/at_keyboard.c | 121 ++++++++++++++++++++++++++++++++++--------- - 1 file changed, 96 insertions(+), 25 deletions(-) - -diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c -index 26014382608..dac0f946fe6 100644 ---- a/grub-core/term/at_keyboard.c -+++ b/grub-core/term/at_keyboard.c -@@ -31,6 +31,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); - static grub_uint8_t grub_keyboard_controller_orig; - static grub_uint8_t grub_keyboard_orig_set; - struct grub_ps2_state ps2_state; -+static int fallback_set; - - static int ping_sent; - -@@ -76,6 +77,8 @@ at_command (grub_uint8_t data) - break; - return 0; - } -+ if (i == GRUB_AT_TRIES) -+ grub_dprintf ("atkeyb", "at_command() timed out! (stopped after %d tries)\n", i); - return (i != GRUB_AT_TRIES); - } - -@@ -105,6 +108,21 @@ grub_keyboard_controller_read (void) - - #endif - -+static int -+resend_last_result (void) -+{ -+ grub_uint8_t ret; -+ keyboard_controller_wait_until_ready (); -+ grub_dprintf ("atkeyb", "resend_last_result: sending 0xfe\n"); -+ grub_outb (0xfe, KEYBOARD_REG_DATA); -+ ret = wait_ack (); -+ grub_dprintf ("atkeyb", "resend_last_result: wait_ack() returned 0x%x\n", ret); -+ keyboard_controller_wait_until_ready (); -+ ret = grub_inb (KEYBOARD_REG_DATA); -+ grub_dprintf ("atkeyb", "resend_last_result: read 0x%x from controller\n", ret); -+ return ret; -+} -+ - static int - write_mode (int mode) - { -@@ -113,11 +131,14 @@ write_mode (int mode) - { - grub_uint8_t ack; - keyboard_controller_wait_until_ready (); -+ grub_dprintf ("atkeyb", "write_mode: sending 0xf0\n"); - grub_outb (0xf0, KEYBOARD_REG_DATA); - keyboard_controller_wait_until_ready (); -+ grub_dprintf ("atkeyb", "write_mode: sending mode %d\n", mode); - grub_outb (mode, KEYBOARD_REG_DATA); - keyboard_controller_wait_until_ready (); - ack = wait_ack (); -+ grub_dprintf ("atkeyb", "write_mode: wait_ack() returned 0x%x\n", ack); - if (ack == GRUB_AT_NACK) - continue; - if (ack == GRUB_AT_ACK) -@@ -125,6 +146,9 @@ write_mode (int mode) - return 0; - } - -+ if (i == GRUB_AT_TRIES) -+ grub_dprintf ("atkeyb", "write_mode() timed out! (stopped after %d tries)\n", i); -+ - return (i != GRUB_AT_TRIES); - } - -@@ -132,31 +156,66 @@ static int - query_mode (void) - { - grub_uint8_t ret; -+ grub_uint64_t endtime; -+ unsigned i; - int e; -+ char *envvar; - -- e = write_mode (0); -- if (!e) { -- grub_dprintf("atkeyb", "query_mode: write_mode(0) failed\n"); -- return 0; -- } -+ for (i = 0; i < GRUB_AT_TRIES; i++) { -+ grub_dprintf ("atkeyb", "query_mode: sending command to controller\n"); -+ e = write_mode (0); -+ if (!e) { -+ grub_dprintf ("atkeyb", "query_mode: write_mode(0) failed\n"); -+ return 0; -+ } - -- do { -- keyboard_controller_wait_until_ready (); -- ret = grub_inb (KEYBOARD_REG_DATA); -- } while (ret == GRUB_AT_ACK); -- /* QEMU translates the set even in no-translate mode. */ -- if (ret == 0x43 || ret == 1) { -- grub_dprintf("atkeyb", "query_mode: returning 1 (ret=0x%x)\n", ret); -- return 1; -- } -- if (ret == 0x41 || ret == 2) { -- grub_dprintf("atkeyb", "query_mode: returning 2 (ret=0x%x)\n", ret); -- return 2; -+ endtime = grub_get_time_ms () + 20; -+ do { -+ keyboard_controller_wait_until_ready (); -+ ret = grub_inb (KEYBOARD_REG_DATA); -+ grub_dprintf ("atkeyb", "query_mode/loop: read 0x%x from controller\n", ret); -+ } while ((ret == GRUB_AT_ACK || ret == GRUB_AT_NACK) && grub_get_time_ms () < endtime); -+ if (ret == 0xfe) { -+ grub_dprintf ("atkeyb", "query_mode: asking controller to resend last result\n"); -+ ret = resend_last_result(); -+ grub_dprintf ("atkeyb", "query_mode: read 0x%x from controller\n", ret); -+ } -+ /* QEMU translates the set even in no-translate mode. */ -+ if (ret == 0x43 || ret == 1) { -+ grub_dprintf ("atkeyb", "query_mode: controller returned 0x%x, returning 1\n", ret); -+ return 1; -+ } -+ if (ret == 0x41 || ret == 2) { -+ grub_dprintf ("atkeyb", "query_mode: controller returned 0x%x, returning 2\n", ret); -+ return 2; -+ } -+ if (ret == 0x3f || ret == 3) { -+ grub_dprintf ("atkeyb", "query_mode: controller returned 0x%x, returning 3\n", ret); -+ return 3; -+ } -+ grub_dprintf ("atkeyb", "query_mode: controller returned unexpected value 0x%x, retrying\n", ret); - } -- if (ret == 0x3f || ret == 3) { -- grub_dprintf("atkeyb", "query_mode: returning 3 (ret=0x%x)\n", ret); -- return 3; -+ -+ /* -+ * Falling here means we tried querying and the controller returned something -+ * we don't understand, try to use 'at_keyboard_fallback_set' if it exists, -+ * otherwise return 0. -+ */ -+ envvar = grub_env_get ("at_keyboard_fallback_set"); -+ if (envvar) { -+ fallback_set = grub_strtoul (envvar, 0, 10); -+ if ((grub_errno) || (fallback_set < 1) || (fallback_set > 3)) { -+ grub_dprintf ("atkeyb", "WARNING: ignoring unexpected value '%s' for '%s' variable\n", -+ envvar, "at_keyboard_fallback_set"); -+ fallback_set = 0; -+ } else { -+ grub_dprintf ("atkeyb", "query_mode: '%s' specified in environment, returning %d\n", -+ "at_keyboard_fallback_set", fallback_set); -+ } -+ return fallback_set; - } -+ grub_dprintf ("atkeyb", "WARNING: no '%s' specified in environment, returning 0\n", -+ "at_keyboard_fallback_set"); - return 0; - } - -@@ -165,14 +224,25 @@ set_scancodes (void) - { - /* You must have visited computer museum. Keyboard without scancode set - knowledge. Assume XT. */ -- if (!grub_keyboard_orig_set) -- { -- grub_dprintf ("atkeyb", "No sets support assumed\n"); -- ps2_state.current_set = 1; -+ if (!grub_keyboard_orig_set) { -+ if (fallback_set) { -+ grub_dprintf ("atkeyb", "No sets support assumed but set forced to %d\n", fallback_set); -+ ps2_state.current_set = fallback_set; - return; - } -+ grub_dprintf ("atkeyb", "No sets support assumed, forcing to set 1\n"); -+ ps2_state.current_set = 1; -+ return; -+ } - - #if !USE_SCANCODE_SET -+ if (fallback_set) { -+ grub_dprintf ("atkeyb", "queried set is %d but set forced to %d\n", -+ grub_keyboard_orig_set, fallback_set); -+ ps2_state.current_set = fallback_set; -+ return; -+ } -+ - if ((grub_keyboard_controller_orig & KEYBOARD_AT_TRANSLATE) == KEYBOARD_AT_TRANSLATE) { - grub_dprintf ("atkeyb", "queried set is %d but keyboard in Translate mode, so actually in set 1\n", grub_keyboard_orig_set); - ps2_state.current_set = 1; -@@ -261,6 +331,7 @@ grub_at_keyboard_getkey (struct grub_term_input *term __attribute__ ((unused))) - static void - grub_keyboard_controller_init (void) - { -+ grub_dprintf ("atkeyb", "initializing the controller\n"); - ps2_state.at_keyboard_status = 0; - /* Drain input buffer. */ - while (1) -@@ -282,6 +353,7 @@ grub_keyboard_controller_init (void) - grub_keyboard_controller_orig = grub_keyboard_controller_read (); - grub_dprintf ("atkeyb", "grub_keyboard_controller_orig = 0x%x\n", grub_keyboard_controller_orig); - grub_keyboard_orig_set = query_mode (); -+ grub_dprintf ("atkeyb", "grub_keyboard_orig_set = %d\n", grub_keyboard_orig_set); - #endif - set_scancodes (); - keyboard_controller_led (ps2_state.led_status); -@@ -329,7 +401,6 @@ grub_at_restore_hw (void) - return GRUB_ERR_NONE; - } - -- - static struct grub_term_input grub_at_keyboard_term = - { - .name = "at_keyboard", diff --git a/0179-ieee1275-drop-HEAP_MAX_ADDR-HEAP_MIN_SIZE.patch b/0179-ieee1275-drop-HEAP_MAX_ADDR-HEAP_MIN_SIZE.patch deleted file mode 100644 index 52fa9d23ad87b40be5fd125a7df1ecac8726751c..0000000000000000000000000000000000000000 --- a/0179-ieee1275-drop-HEAP_MAX_ADDR-HEAP_MIN_SIZE.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Wed, 14 Apr 2021 20:10:23 +1000 -Subject: [PATCH] ieee1275: drop HEAP_MAX_ADDR, HEAP_MIN_SIZE - -HEAP_MAX_ADDR is confusing. Currently it is set to 32MB, except -on ieee1275 on x86, where it is 64MB. - -There is a comment which purports to explain it: - -/* If possible, we will avoid claiming heap above this address, because it - seems to cause relocation problems with OSes that link at 4 MiB */ - -This doesn't make a lot of sense when the constants are well above 4MB -already. It was not always this way. Prior to -commit 7b5d0fe4440c ("Increase heap limit") in 2010, HEAP_MAX_SIZE and -HEAP_MAX_ADDR were indeed 4MB. However, when the constants were increased -the comment was left unchanged. - -It's been over a decade. It doesn't seem like we have problems with -claims over 4MB on powerpc or x86 ieee1275. (sparc does things completely -differently and never used the constant.) - -Drop the constant and the check. - -The only use of HEAP_MIN_SIZE was to potentially override the -HEAP_MAX_ADDR check. It is now unused. Remove it. - -Signed-off-by: Daniel Axtens ---- - grub-core/kern/ieee1275/init.c | 17 ----------------- - 1 file changed, 17 deletions(-) - -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index fc7d9712729..0dcd114ce54 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -46,9 +46,6 @@ - #endif - #include - --/* The minimal heap size we can live with. */ --#define HEAP_MIN_SIZE (unsigned long) (2 * 1024 * 1024) -- - /* The maximum heap size we're going to claim */ - #ifdef __i386__ - #define HEAP_MAX_SIZE (unsigned long) (64 * 1024 * 1024) -@@ -56,14 +53,6 @@ - #define HEAP_MAX_SIZE (unsigned long) (32 * 1024 * 1024) - #endif - --/* If possible, we will avoid claiming heap above this address, because it -- seems to cause relocation problems with OSes that link at 4 MiB */ --#ifdef __i386__ --#define HEAP_MAX_ADDR (unsigned long) (64 * 1024 * 1024) --#else --#define HEAP_MAX_ADDR (unsigned long) (32 * 1024 * 1024) --#endif -- - extern char _end[]; - - #ifdef __sparc__ -@@ -185,12 +174,6 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - if (*total + len > HEAP_MAX_SIZE) - len = HEAP_MAX_SIZE - *total; - -- /* Avoid claiming anything above HEAP_MAX_ADDR, if possible. */ -- if ((addr < HEAP_MAX_ADDR) && /* if it's too late, don't bother */ -- (addr + len > HEAP_MAX_ADDR) && /* if it wasn't available anyway, don't bother */ -- (*total + (HEAP_MAX_ADDR - addr) > HEAP_MIN_SIZE)) /* only limit ourselves when we can afford to */ -- len = HEAP_MAX_ADDR - addr; -- - /* In theory, firmware should already prevent this from happening by not - listing our own image in /memory/available. The check below is intended - as a safeguard in case that doesn't happen. However, it doesn't protect diff --git a/0180-ieee1275-claim-more-memory.patch b/0180-ieee1275-claim-more-memory.patch deleted file mode 100644 index 001a9df04b0b8148294a459f0235ea83ae393d0d..0000000000000000000000000000000000000000 --- a/0180-ieee1275-claim-more-memory.patch +++ /dev/null @@ -1,252 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Wed, 15 Apr 2020 23:28:29 +1000 -Subject: [PATCH] ieee1275: claim more memory - -On powerpc-ieee1275, we are running out of memory trying to verify -anything. This is because: - - - we have to load an entire file into memory to verify it. This is - extremely difficult to change with appended signatures. - - We only have 32MB of heap. - - Distro kernels are now often around 30MB. - -So we want to claim more memory from OpenFirmware for our heap. - -There are some complications: - - - The grub mm code isn't the only thing that will make claims on - memory from OpenFirmware: - - * PFW/SLOF will have claimed some for their own use. - - * The ieee1275 loader will try to find other bits of memory that we - haven't claimed to place the kernel and initrd when we go to boot. - - * Once we load Linux, it will also try to claim memory. It claims - memory without any reference to /memory/available, it just starts - at min(top of RMO, 768MB) and works down. So we need to avoid this - area. See arch/powerpc/kernel/prom_init.c as of v5.11. - - - The smallest amount of memory a ppc64 KVM guest can have is 256MB. - It doesn't work with distro kernels but can work with custom kernels. - We should maintain support for that. (ppc32 can boot with even less, - and we shouldn't break that either.) - - - Even if a VM has more memory, the memory OpenFirmware makes available - as Real Memory Area can be restricted. A freshly created LPAR on a - PowerVM machine is likely to have only 256MB available to OpenFirmware - even if it has many gigabytes of memory allocated. - -EFI systems will attempt to allocate 1/4th of the available memory, -clamped to between 1M and 1600M. That seems like a good sort of -approach, we just need to figure out if 1/4 is the right fraction -for us. - -We don't know in advance how big the kernel and initrd are going to be, -which makes figuring out how much memory we can take a bit tricky. - -To figure out how much memory we should leave unused, I looked at: - - - an Ubuntu 20.04.1 ppc64le pseries KVM guest: - vmlinux: ~30MB - initrd: ~50MB - - - a RHEL8.2 ppc64le pseries KVM guest: - vmlinux: ~30MB - initrd: ~30MB - -Ubuntu VMs struggle to boot with just 256MB under SLOF. -RHEL likewise has a higher minimum supported memory figure. -So lets first consider a distro kernel and 512MB of addressible memory. -(This is the default case for anything booting under PFW.) Say we lose -131MB to PFW (based on some tests). This leaves us 381MB. 1/4 of 381MB -is ~95MB. That should be enough to verify a 30MB vmlinux and should -leave plenty of space to load Linux and the initrd. - -If we consider 256MB of RMA under PFW, we have just 125MB remaining. 1/4 -of that is a smidge under 32MB, which gives us very poor odds of verifying -a distro-sized kernel. However, if we need 80MB just to put the kernel -and initrd in memory, we can't claim any more than 45MB anyway. So 1/4 -will do. We'll come back to this later. - -grub is always built as a 32-bit binary, even if it's loading a ppc64 -kernel. So we can't address memory beyond 4GB. This gives a natural cap -of 1GB for powerpc-ieee1275. - -Also apply this 1/4 approach to i386-ieee1275, but keep the 32MB cap. - -make check still works for both i386 and powerpc and I've booted -powerpc grub with this change under SLOF and PFW. - -Signed-off-by: Daniel Axtens ---- - grub-core/kern/ieee1275/init.c | 81 +++++++++++++++++++++++++++++++++--------- - docs/grub-dev.texi | 6 ++-- - 2 files changed, 69 insertions(+), 18 deletions(-) - -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index 0dcd114ce54..c61d91a0285 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -46,11 +46,12 @@ - #endif - #include - --/* The maximum heap size we're going to claim */ -+/* The maximum heap size we're going to claim. Not used by sparc. -+ We allocate 1/4 of the available memory under 4G, up to this limit. */ - #ifdef __i386__ - #define HEAP_MAX_SIZE (unsigned long) (64 * 1024 * 1024) --#else --#define HEAP_MAX_SIZE (unsigned long) (32 * 1024 * 1024) -+#else // __powerpc__ -+#define HEAP_MAX_SIZE (unsigned long) (1 * 1024 * 1024 * 1024) - #endif - - extern char _end[]; -@@ -147,16 +148,45 @@ grub_claim_heap (void) - + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000); - } - #else --/* Helper for grub_claim_heap. */ -+/* Helper for grub_claim_heap on powerpc. */ -+static int -+heap_size (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, -+ void *data) -+{ -+ grub_uint32_t total = *(grub_uint32_t *)data; -+ -+ if (type != GRUB_MEMORY_AVAILABLE) -+ return 0; -+ -+ /* Do not consider memory beyond 4GB */ -+ if (addr > 0xffffffffUL) -+ return 0; -+ -+ if (addr + len > 0xffffffffUL) -+ len = 0xffffffffUL - addr; -+ -+ total += len; -+ *(grub_uint32_t *)data = total; -+ -+ return 0; -+} -+ - static int - heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - void *data) - { -- unsigned long *total = data; -+ grub_uint32_t total = *(grub_uint32_t *)data; - - if (type != GRUB_MEMORY_AVAILABLE) - return 0; - -+ /* Do not consider memory beyond 4GB */ -+ if (addr > 0xffffffffUL) -+ return 0; -+ -+ if (addr + len > 0xffffffffUL) -+ len = 0xffffffffUL - addr; -+ - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_NO_PRE1_5M_CLAIM)) - { - if (addr + len <= 0x180000) -@@ -170,10 +200,6 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - } - len -= 1; /* Required for some firmware. */ - -- /* Never exceed HEAP_MAX_SIZE */ -- if (*total + len > HEAP_MAX_SIZE) -- len = HEAP_MAX_SIZE - *total; -- - /* In theory, firmware should already prevent this from happening by not - listing our own image in /memory/available. The check below is intended - as a safeguard in case that doesn't happen. However, it doesn't protect -@@ -185,6 +211,18 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - len = 0; - } - -+ /* If this block contains 0x30000000 (768MB), do not claim below that. -+ Linux likes to claim memory at min(RMO top, 768MB) and works down -+ without reference to /memory/available. */ -+ if ((addr < 0x30000000) && ((addr + len) > 0x30000000)) -+ { -+ len = len - (0x30000000 - addr); -+ addr = 0x30000000; -+ } -+ -+ if (len > total) -+ len = total; -+ - if (len) - { - grub_err_t err; -@@ -193,10 +231,12 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - if (err) - return err; - grub_mm_init_region ((void *) (grub_addr_t) addr, len); -+ total -= len; - } - -- *total += len; -- if (*total >= HEAP_MAX_SIZE) -+ *(grub_uint32_t *)data = total; -+ -+ if (total == 0) - return 1; - - return 0; -@@ -205,13 +245,22 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - static void - grub_claim_heap (void) - { -- unsigned long total = 0; -+ grub_uint32_t total = 0; - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM)) -- heap_init (GRUB_IEEE1275_STATIC_HEAP_START, GRUB_IEEE1275_STATIC_HEAP_LEN, -- 1, &total); -- else -- grub_machine_mmap_iterate (heap_init, &total); -+ { -+ heap_init (GRUB_IEEE1275_STATIC_HEAP_START, GRUB_IEEE1275_STATIC_HEAP_LEN, -+ 1, &total); -+ return; -+ } -+ -+ grub_machine_mmap_iterate (heap_size, &total); -+ -+ total = total / 4; -+ if (total > HEAP_MAX_SIZE) -+ total = HEAP_MAX_SIZE; -+ -+ grub_machine_mmap_iterate (heap_init, &total); - } - #endif - -diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi -index 19f708ee662..90083772c8a 100644 ---- a/docs/grub-dev.texi -+++ b/docs/grub-dev.texi -@@ -1047,7 +1047,9 @@ space is limited to 4GiB. GRUB allocates pages from EFI for its heap, at most - 1.6 GiB. - - On i386-ieee1275 and powerpc-ieee1275 GRUB uses same stack as IEEE1275. --It allocates at most 32MiB for its heap. -+ -+On i386-ieee1275, GRUB allocates at most 32MiB for its heap. On -+powerpc-ieee1275, GRUB allocates up to 1GiB. - - On sparc64-ieee1275 stack is 256KiB and heap is 2MiB. - -@@ -1075,7 +1077,7 @@ In short: - @item i386-qemu @tab 60 KiB @tab < 4 GiB - @item *-efi @tab ? @tab < 1.6 GiB - @item i386-ieee1275 @tab ? @tab < 32 MiB --@item powerpc-ieee1275 @tab ? @tab < 32 MiB -+@item powerpc-ieee1275 @tab ? @tab < 1 GiB - @item sparc64-ieee1275 @tab 256KiB @tab 2 MiB - @item arm-uboot @tab 256KiB @tab 2 MiB - @item mips(el)-qemu_mips @tab 2MiB @tab 253 MiB diff --git a/0181-ieee1275-request-memory-with-ibm-client-architecture.patch b/0181-ieee1275-request-memory-with-ibm-client-architecture.patch deleted file mode 100644 index 6e6c1f0cf798dc4c9c7a5aca77cb1c9e6e26465f..0000000000000000000000000000000000000000 --- a/0181-ieee1275-request-memory-with-ibm-client-architecture.patch +++ /dev/null @@ -1,268 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 16 Apr 2021 11:48:46 +1000 -Subject: [PATCH] ieee1275: request memory with ibm,client-architecture-support - -On PowerVM, the first time we boot a Linux partition, we may only get -256MB of real memory area, even if the partition has more memory. - -This isn't really enough. Fortunately, the Power Architecture Platform -Reference (PAPR) defines a method we can call to ask for more memory. -This is part of the broad and powerful ibm,client-architecture-support -(CAS) method. - -CAS can do an enormous amount of things on a PAPR platform: as well as -asking for memory, you can set the supported processor level, the interrupt -controller, hash vs radix mmu, and so on. We want to touch as little of -this as possible because we don't want to step on the toes of the future OS. - -If: - - - we are running under what we think is PowerVM (compatible property of / - begins with "IBM"), and - - - the full amount of RMA is less than 512MB (as determined by the reg - property of /memory) - -then call CAS as follows: (refer to the Linux on Power Architecture -Reference, LoPAR, which is public, at B.5.2.3): - - - Use the "any" PVR value and supply 2 option vectors. - - - Set option vector 1 (PowerPC Server Processor Architecture Level) - to "ignore". - - - Set option vector 2 with default or Linux-like options, including a - min-rma-size of 512MB. - -This will cause a CAS reboot and the partition will restart with 512MB -of RMA. Grub will notice the 512MB and not call CAS again. - -(A partition can be configured with only 256MB of memory, which would -mean this request couldn't be satisfied, but PFW refuses to load with -only 256MB of memory, so it's a bit moot. SLOF will run fine with 256MB, -but we will never call CAS under qemu/SLOF because /compatible won't -begin with "IBM".) - -One of the first things Linux does while still running under OpenFirmware -is to call CAS with a much fuller set of options (including asking for -512MB of memory). This includes a much more restrictive set of PVR values -and processor support levels, and this will induce another reboot. On this -reboot grub will again notice the higher RMA, and not call CAS. We will get -to Linux, Linux will call CAS but because the values are now set for Linux -this will not induce another CAS reboot and we will finally boot. - -On all subsequent boots, everything will be configured with 512MB of RMA -and all the settings Linux likes, so there will be no further CAS reboots. - -(phyp is super sticky with the RMA size - it persists even on cold boots. -So if you've ever booted Linux in a partition, you'll probably never have -grub call CAS. It'll only ever fire the first time a partition loads grub, -or if you deliberately lower the amount of memory your partition has below -512MB.) - -Signed-off-by: Daniel Axtens ---- - grub-core/kern/ieee1275/cmain.c | 3 + - grub-core/kern/ieee1275/init.c | 144 ++++++++++++++++++++++++++++++++++++++- - include/grub/ieee1275/ieee1275.h | 8 ++- - 3 files changed, 152 insertions(+), 3 deletions(-) - -diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c -index 04df9d2c667..6435628ec57 100644 ---- a/grub-core/kern/ieee1275/cmain.c -+++ b/grub-core/kern/ieee1275/cmain.c -@@ -127,6 +127,9 @@ grub_ieee1275_find_options (void) - break; - } - } -+ -+ if (grub_strncmp (tmp, "IBM,", 4) == 0) -+ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY); - } - - if (is_smartfirmware) -diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c -index c61d91a0285..9704715c837 100644 ---- a/grub-core/kern/ieee1275/init.c -+++ b/grub-core/kern/ieee1275/init.c -@@ -242,6 +242,135 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type, - return 0; - } - -+/* How much memory does OF believe it has? (regardless of whether -+ it's accessible or not) */ -+static grub_err_t -+grub_ieee1275_total_mem (grub_uint64_t *total) -+{ -+ grub_ieee1275_phandle_t root; -+ grub_ieee1275_phandle_t memory; -+ grub_uint32_t reg[4]; -+ grub_ssize_t reg_size; -+ grub_uint32_t address_cells = 1; -+ grub_uint32_t size_cells = 1; -+ grub_uint64_t size; -+ -+ /* If we fail to get to the end, report 0. */ -+ *total = 0; -+ -+ /* Determine the format of each entry in `reg'. */ -+ grub_ieee1275_finddevice ("/", &root); -+ grub_ieee1275_get_integer_property (root, "#address-cells", &address_cells, -+ sizeof address_cells, 0); -+ grub_ieee1275_get_integer_property (root, "#size-cells", &size_cells, -+ sizeof size_cells, 0); -+ -+ if (size_cells > address_cells) -+ address_cells = size_cells; -+ -+ /* Load `/memory/reg'. */ -+ if (grub_ieee1275_finddevice ("/memory", &memory)) -+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, -+ "couldn't find /memory node"); -+ if (grub_ieee1275_get_integer_property (memory, "reg", reg, -+ sizeof reg, ®_size)) -+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, -+ "couldn't examine /memory/reg property"); -+ if (reg_size < 0 || (grub_size_t) reg_size > sizeof (reg)) -+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, -+ "/memory response buffer exceeded"); -+ -+ if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_BROKEN_ADDRESS_CELLS)) -+ { -+ address_cells = 1; -+ size_cells = 1; -+ } -+ -+ /* Decode only the size */ -+ size = reg[address_cells]; -+ if (size_cells == 2) -+ size = (size << 32) | reg[address_cells + 1]; -+ -+ *total = size; -+ -+ return grub_errno; -+} -+ -+/* Based on linux - arch/powerpc/kernel/prom_init.c */ -+struct option_vector2 { -+ grub_uint8_t byte1; -+ grub_uint16_t reserved; -+ grub_uint32_t real_base; -+ grub_uint32_t real_size; -+ grub_uint32_t virt_base; -+ grub_uint32_t virt_size; -+ grub_uint32_t load_base; -+ grub_uint32_t min_rma; -+ grub_uint32_t min_load; -+ grub_uint8_t min_rma_percent; -+ grub_uint8_t max_pft_size; -+} __attribute__((packed)); -+ -+struct pvr_entry { -+ grub_uint32_t mask; -+ grub_uint32_t entry; -+}; -+ -+struct cas_vector { -+ struct { -+ struct pvr_entry terminal; -+ } pvr_list; -+ grub_uint8_t num_vecs; -+ grub_uint8_t vec1_size; -+ grub_uint8_t vec1; -+ grub_uint8_t vec2_size; -+ struct option_vector2 vec2; -+} __attribute__((packed)); -+ -+/* Call ibm,client-architecture-support to try to get more RMA. -+ We ask for 512MB which should be enough to verify a distro kernel. -+ We ignore most errors: if we don't succeed we'll proceed with whatever -+ memory we have. */ -+static void -+grub_ieee1275_ibm_cas (void) -+{ -+ int rc; -+ grub_ieee1275_ihandle_t root; -+ struct cas_args { -+ struct grub_ieee1275_common_hdr common; -+ grub_ieee1275_cell_t method; -+ grub_ieee1275_ihandle_t ihandle; -+ grub_ieee1275_cell_t cas_addr; -+ grub_ieee1275_cell_t result; -+ } args; -+ struct cas_vector vector = { -+ .pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */ -+ .num_vecs = 2 - 1, -+ .vec1_size = 0, -+ .vec1 = 0x80, /* ignore */ -+ .vec2_size = 1 + sizeof(struct option_vector2) - 2, -+ .vec2 = { -+ 0, 0, -1, -1, -1, -1, -1, 512, -1, 0, 48 -+ }, -+ }; -+ -+ INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2); -+ args.method = (grub_ieee1275_cell_t)"ibm,client-architecture-support"; -+ rc = grub_ieee1275_open("/", &root); -+ if (rc) { -+ grub_error (GRUB_ERR_IO, "could not open root when trying to call CAS"); -+ return; -+ } -+ args.ihandle = root; -+ args.cas_addr = (grub_ieee1275_cell_t)&vector; -+ -+ grub_printf("Calling ibm,client-architecture-support..."); -+ IEEE1275_CALL_ENTRY_FN (&args); -+ grub_printf("done\n"); -+ -+ grub_ieee1275_close(root); -+} -+ - static void - grub_claim_heap (void) - { -@@ -249,11 +378,22 @@ grub_claim_heap (void) - - if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_FORCE_CLAIM)) - { -- heap_init (GRUB_IEEE1275_STATIC_HEAP_START, GRUB_IEEE1275_STATIC_HEAP_LEN, -- 1, &total); -+ heap_init (GRUB_IEEE1275_STATIC_HEAP_START, -+ GRUB_IEEE1275_STATIC_HEAP_LEN, 1, &total); - return; - } - -+ if (grub_ieee1275_test_flag (GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY)) -+ { -+ grub_uint64_t rma_size; -+ grub_err_t err; -+ -+ err = grub_ieee1275_total_mem (&rma_size); -+ /* if we have an error, don't call CAS, just hope for the best */ -+ if (!err && rma_size < (512 * 1024 * 1024)) -+ grub_ieee1275_ibm_cas(); -+ } -+ - grub_machine_mmap_iterate (heap_size, &total); - - total = total / 4; -diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h -index b5a1d49bbc3..e0a6c2ce1e6 100644 ---- a/include/grub/ieee1275/ieee1275.h -+++ b/include/grub/ieee1275/ieee1275.h -@@ -149,7 +149,13 @@ enum grub_ieee1275_flag - - GRUB_IEEE1275_FLAG_RAW_DEVNAMES, - -- GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT -+ GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT, -+ -+ /* On PFW, the first time we boot a Linux partition, we may only get 256MB -+ of real memory area, even if the partition has more memory. Set this flag -+ if we think we're running under PFW. Then, if this flag is set, and the -+ RMA is only 256MB in size, try asking for more with CAS. */ -+ GRUB_IEEE1275_FLAG_CAN_TRY_CAS_FOR_MORE_MEMORY, - }; - - extern int EXPORT_FUNC(grub_ieee1275_test_flag) (enum grub_ieee1275_flag flag); diff --git a/0182-appendedsig-x509-Also-handle-the-Extended-Key-Usage-.patch b/0182-appendedsig-x509-Also-handle-the-Extended-Key-Usage-.patch deleted file mode 100644 index a237a217af6c59c4de2a6f39131349acb18922d7..0000000000000000000000000000000000000000 --- a/0182-appendedsig-x509-Also-handle-the-Extended-Key-Usage-.patch +++ /dev/null @@ -1,315 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Sat, 8 May 2021 02:27:58 +0200 -Subject: [PATCH] appendedsig/x509: Also handle the Extended Key Usage - extension - -Red Hat certificates have both Key Usage and Extended Key Usage extensions -present, but the appended signatures x509 parser doesn't handle the latter -and so buils due finding an unrecognised critical extension: - -Error loading initial key: -../../grub-core/commands/appendedsig/x509.c:780:Unhandled critical x509 extension with OID 2.5.29.37 - -Fix this by also parsing the Extended Key Usage extension and handle it by -verifying that the certificate has a single purpose, that is code signing. - -Signed-off-by: Javier Martinez Canillas -Signed-off-by: Daniel Axtens ---- - grub-core/commands/appendedsig/x509.c | 94 ++++++++++++++++++++++++++++++- - grub-core/tests/appended_signature_test.c | 29 +++++++++- - grub-core/tests/appended_signatures.h | 81 ++++++++++++++++++++++++++ - 3 files changed, 201 insertions(+), 3 deletions(-) - -diff --git a/grub-core/commands/appendedsig/x509.c b/grub-core/commands/appendedsig/x509.c -index 2b38b3670a2..42ec65c54aa 100644 ---- a/grub-core/commands/appendedsig/x509.c -+++ b/grub-core/commands/appendedsig/x509.c -@@ -47,6 +47,12 @@ const char *keyUsage_oid = "2.5.29.15"; - */ - const char *basicConstraints_oid = "2.5.29.19"; - -+/* -+ * RFC 5280 4.2.1.12 Extended Key Usage -+ */ -+const char *extendedKeyUsage_oid = "2.5.29.37"; -+const char *codeSigningUsage_oid = "1.3.6.1.5.5.7.3.3"; -+ - /* - * RFC 3279 2.3.1 - * -@@ -637,6 +643,77 @@ cleanup: - return err; - } - -+/* -+ * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId -+ * -+ * KeyPurposeId ::= OBJECT IDENTIFIER -+ */ -+static grub_err_t -+verify_extended_key_usage (grub_uint8_t * value, int value_size) -+{ -+ asn1_node extendedasn; -+ int result, count; -+ grub_err_t err = GRUB_ERR_NONE; -+ char usage[MAX_OID_LEN]; -+ int usage_size = sizeof (usage); -+ -+ result = -+ asn1_create_element (_gnutls_pkix_asn, "PKIX1.ExtKeyUsageSyntax", -+ &extendedasn); -+ if (result != ASN1_SUCCESS) -+ { -+ return grub_error (GRUB_ERR_OUT_OF_MEMORY, -+ "Could not create ASN.1 structure for Extended Key Usage"); -+ } -+ -+ result = asn1_der_decoding2 (&extendedasn, value, &value_size, -+ ASN1_DECODE_FLAG_STRICT_DER, asn1_error); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error parsing DER for Extended Key Usage: %s", -+ asn1_error); -+ goto cleanup; -+ } -+ -+ /* -+ * If EKUs are present, there must be exactly 1 and it must be a -+ * codeSigning usage. -+ */ -+ result = asn1_number_of_elements(extendedasn, "", &count); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error counting number of Extended Key Usages: %s", -+ asn1_strerror (result)); -+ goto cleanup; -+ } -+ -+ result = asn1_read_value (extendedasn, "?1", usage, &usage_size); -+ if (result != ASN1_SUCCESS) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Error reading Extended Key Usage: %s", -+ asn1_strerror (result)); -+ goto cleanup; -+ } -+ -+ if (grub_strncmp (codeSigningUsage_oid, usage, usage_size) != 0) -+ { -+ err = -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Unexpected Extended Key Usage OID, got: %s", -+ usage); -+ goto cleanup; -+ } -+ -+cleanup: -+ asn1_delete_structure (&extendedasn); -+ return err; -+} - - /* - * Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension -@@ -660,7 +737,7 @@ verify_extensions (asn1_node cert) - { - int result; - int ext, num_extensions = 0; -- int usage_present = 0, constraints_present = 0; -+ int usage_present = 0, constraints_present = 0, extended_usage_present = 0; - char *oid_path, *critical_path, *value_path; - char extnID[MAX_OID_LEN]; - int extnID_size; -@@ -754,6 +831,15 @@ verify_extensions (asn1_node cert) - } - constraints_present++; - } -+ else if (grub_strncmp (extendedKeyUsage_oid, extnID, extnID_size) == 0) -+ { -+ err = verify_extended_key_usage (value, value_size); -+ if (err != GRUB_ERR_NONE) -+ { -+ goto cleanup_value; -+ } -+ extended_usage_present++; -+ } - else if (grub_strncmp ("TRUE", critical, critical_size) == 0) - { - /* -@@ -785,6 +871,12 @@ verify_extensions (asn1_node cert) - "Unexpected number of basic constraints extensions - expected 1, got %d", - constraints_present); - } -+ if (extended_usage_present > 1) -+ { -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "Unexpected number of Extended Key Usage extensions - expected 0 or 1, got %d", -+ extended_usage_present); -+ } - return GRUB_ERR_NONE; - - cleanup_value: -diff --git a/grub-core/tests/appended_signature_test.c b/grub-core/tests/appended_signature_test.c -index 88a485200d8..dbba0616621 100644 ---- a/grub-core/tests/appended_signature_test.c -+++ b/grub-core/tests/appended_signature_test.c -@@ -111,6 +111,22 @@ static struct grub_procfs_entry certificate_printable_der_entry = { - .get_contents = get_certificate_printable_der - }; - -+static char * -+get_certificate_eku_der (grub_size_t * sz) -+{ -+ char *ret; -+ *sz = certificate_eku_der_len; -+ ret = grub_malloc (*sz); -+ if (ret) -+ grub_memcpy (ret, certificate_eku_der, *sz); -+ return ret; -+} -+ -+static struct grub_procfs_entry certificate_eku_der_entry = { -+ .name = "certificate_eku.der", -+ .get_contents = get_certificate_eku_der -+}; -+ - - static void - do_verify (const char *f, int is_valid) -@@ -149,6 +165,7 @@ appended_signature_test (void) - char *trust_args2[] = { (char *) "(proc)/certificate2.der", NULL }; - char *trust_args_printable[] = { (char *) "(proc)/certificate_printable.der", - NULL }; -+ char *trust_args_eku[] = { (char *) "(proc)/certificate_eku.der", NULL }; - char *distrust_args[] = { (char *) "1", NULL }; - char *distrust2_args[] = { (char *) "2", NULL }; - grub_err_t err; -@@ -157,6 +174,7 @@ appended_signature_test (void) - grub_procfs_register ("certificate2.der", &certificate2_der_entry); - grub_procfs_register ("certificate_printable.der", - &certificate_printable_der_entry); -+ grub_procfs_register ("certificate_eku.der", &certificate_eku_der_entry); - - cmd_trust = grub_command_find ("trust_certificate"); - if (!cmd_trust) -@@ -266,16 +284,23 @@ appended_signature_test (void) - - /* - * Lastly, check a certificate that uses printableString rather than -- * utf8String loads properly. -+ * utf8String loads properly, and that a certificate with an appropriate -+ * extended key usage loads. - */ - err = (cmd_trust->func) (cmd_trust, 1, trust_args_printable); - grub_test_assert (err == GRUB_ERR_NONE, -- "distrusting printable certificate failed: %d: %s", -+ "trusting printable certificate failed: %d: %s", -+ grub_errno, grub_errmsg); -+ -+ err = (cmd_trust->func) (cmd_trust, 1, trust_args_eku); -+ grub_test_assert (err == GRUB_ERR_NONE, -+ "trusting certificate with extended key usage failed: %d: %s", - grub_errno, grub_errmsg); - - grub_procfs_unregister (&certificate_der_entry); - grub_procfs_unregister (&certificate2_der_entry); - grub_procfs_unregister (&certificate_printable_der_entry); -+ grub_procfs_unregister (&certificate_eku_der_entry); - } - - GRUB_FUNCTIONAL_TEST (appended_signature_test, appended_signature_test); -diff --git a/grub-core/tests/appended_signatures.h b/grub-core/tests/appended_signatures.h -index aa3dc6278e3..2e5ebd7d8bd 100644 ---- a/grub-core/tests/appended_signatures.h -+++ b/grub-core/tests/appended_signatures.h -@@ -555,3 +555,84 @@ unsigned char certificate_printable_der[] = { - 0xd2 - }; - unsigned int certificate_printable_der_len = 829; -+ -+unsigned char certificate_eku_der[] = { -+ 0x30, 0x82, 0x03, 0x90, 0x30, 0x82, 0x02, 0x78, 0xa0, 0x03, 0x02, 0x01, -+ 0x02, 0x02, 0x09, 0x00, 0xd3, 0x9c, 0x41, 0x33, 0xdd, 0x6b, 0x5f, 0x45, -+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, -+ 0x0b, 0x05, 0x00, 0x30, 0x47, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, -+ 0x04, 0x03, 0x0c, 0x18, 0x52, 0x65, 0x64, 0x20, 0x48, 0x61, 0x74, 0x20, -+ 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x20, -+ 0x43, 0x41, 0x20, 0x36, 0x31, 0x22, 0x30, 0x20, 0x06, 0x09, 0x2a, 0x86, -+ 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, 0x13, 0x73, 0x65, 0x63, -+ 0x61, 0x6c, 0x65, 0x72, 0x74, 0x40, 0x72, 0x65, 0x64, 0x68, 0x61, 0x74, -+ 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x32, 0x31, 0x30, 0x32, -+ 0x31, 0x35, 0x31, 0x34, 0x30, 0x30, 0x34, 0x34, 0x5a, 0x17, 0x0d, 0x33, -+ 0x38, 0x30, 0x31, 0x31, 0x37, 0x31, 0x34, 0x30, 0x30, 0x34, 0x34, 0x5a, -+ 0x30, 0x4e, 0x31, 0x28, 0x30, 0x26, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, -+ 0x1f, 0x52, 0x65, 0x64, 0x20, 0x48, 0x61, 0x74, 0x20, 0x53, 0x65, 0x63, -+ 0x75, 0x72, 0x65, 0x20, 0x42, 0x6f, 0x6f, 0x74, 0x20, 0x53, 0x69, 0x67, -+ 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x36, 0x30, 0x32, 0x31, 0x22, 0x30, 0x20, -+ 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, 0x16, -+ 0x13, 0x73, 0x65, 0x63, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x40, 0x72, 0x65, -+ 0x64, 0x68, 0x61, 0x74, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x82, 0x01, 0x22, -+ 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, -+ 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, -+ 0x02, 0x82, 0x01, 0x01, 0x00, 0xaa, 0x6f, 0xbb, 0x92, 0x77, 0xd7, 0x15, -+ 0xef, 0x88, 0x80, 0x88, 0xc0, 0xe7, 0x89, 0xeb, 0x35, 0x76, 0xf4, 0x85, -+ 0x05, 0x0f, 0x19, 0xe4, 0x5f, 0x25, 0xdd, 0xc1, 0xa2, 0xe5, 0x5c, 0x06, -+ 0xfb, 0xf1, 0x06, 0xb5, 0x65, 0x45, 0xcb, 0xbd, 0x19, 0x33, 0x54, 0xb5, -+ 0x1a, 0xcd, 0xe4, 0xa8, 0x35, 0x2a, 0xfe, 0x9c, 0x53, 0xf4, 0xc6, 0x76, -+ 0xdb, 0x1f, 0x8a, 0xd4, 0x7b, 0x18, 0x11, 0xaf, 0xa3, 0x90, 0xd4, 0xdd, -+ 0x4d, 0xd5, 0x42, 0xcc, 0x14, 0x9a, 0x64, 0x6b, 0xc0, 0x7f, 0xaa, 0x1c, -+ 0x94, 0x47, 0x4d, 0x79, 0xbd, 0x57, 0x9a, 0xbf, 0x99, 0x4e, 0x96, 0xa9, -+ 0x31, 0x2c, 0xa9, 0xe7, 0x14, 0x65, 0x86, 0xc8, 0xac, 0x79, 0x5e, 0x78, -+ 0xa4, 0x3c, 0x00, 0x24, 0xd3, 0xf7, 0xe1, 0xf5, 0x12, 0xad, 0xa0, 0x29, -+ 0xe5, 0xfe, 0x80, 0xae, 0xf8, 0xaa, 0x60, 0x36, 0xe7, 0xe8, 0x94, 0xcb, -+ 0xe9, 0xd1, 0xcc, 0x0b, 0x4d, 0xf7, 0xde, 0xeb, 0x52, 0xd2, 0x73, 0x09, -+ 0x28, 0xdf, 0x48, 0x99, 0x53, 0x9f, 0xc5, 0x9a, 0xd4, 0x36, 0xa3, 0xc6, -+ 0x5e, 0x8d, 0xbe, 0xd5, 0xdc, 0x76, 0xb4, 0x74, 0xb8, 0x26, 0x18, 0x27, -+ 0xfb, 0xf2, 0xfb, 0xd0, 0x9b, 0x3d, 0x7f, 0x10, 0xe2, 0xab, 0x44, 0xc7, -+ 0x88, 0x7f, 0xb4, 0x3d, 0x3e, 0xa3, 0xff, 0x6d, 0x06, 0x4b, 0x3e, 0x55, -+ 0xb2, 0x84, 0xf4, 0xad, 0x54, 0x88, 0x81, 0xc3, 0x9c, 0xf8, 0xb6, 0x68, -+ 0x96, 0x38, 0x8b, 0xcd, 0x90, 0x6d, 0x25, 0x4b, 0xbf, 0x0c, 0x44, 0x90, -+ 0xa5, 0x5b, 0x98, 0xd0, 0x40, 0x2f, 0xbb, 0x0d, 0xa8, 0x4b, 0x8a, 0x62, -+ 0x82, 0x46, 0x46, 0x18, 0x38, 0xae, 0x82, 0x07, 0xd0, 0xb4, 0x2f, 0x16, -+ 0x79, 0x55, 0x9f, 0x1b, 0xc5, 0x08, 0x6d, 0x85, 0xdf, 0x3f, 0xa9, 0x9b, -+ 0x4b, 0xc6, 0x28, 0xd3, 0x58, 0x72, 0x3d, 0x37, 0x11, 0x02, 0x03, 0x01, -+ 0x00, 0x01, 0xa3, 0x78, 0x30, 0x76, 0x30, 0x0c, 0x06, 0x03, 0x55, 0x1d, -+ 0x13, 0x01, 0x01, 0xff, 0x04, 0x02, 0x30, 0x00, 0x30, 0x0e, 0x06, 0x03, -+ 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, -+ 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff, 0x04, 0x0c, -+ 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, -+ 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x6c, -+ 0xe4, 0x6c, 0x27, 0xaa, 0xcd, 0x0d, 0x4b, 0x74, 0x21, 0xa4, 0xf6, 0x5f, -+ 0x87, 0xb5, 0x31, 0xfe, 0x10, 0xbb, 0xa7, 0x30, 0x1f, 0x06, 0x03, 0x55, -+ 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0xe8, 0x6a, 0x1c, 0xab, -+ 0x2c, 0x48, 0xf9, 0x60, 0x36, 0xa2, 0xf0, 0x7b, 0x8e, 0xd2, 0x9d, 0xb4, -+ 0x2a, 0x28, 0x98, 0xc8, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, -+ 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, -+ 0x55, 0x34, 0xe2, 0xfa, 0xf6, 0x89, 0x86, 0xad, 0x92, 0x21, 0xec, 0xb9, -+ 0x54, 0x0e, 0x18, 0x47, 0x0d, 0x1b, 0xa7, 0x58, 0xad, 0x69, 0xe4, 0xef, -+ 0x3b, 0xe6, 0x8d, 0xdd, 0xda, 0x0c, 0x45, 0xf6, 0xe8, 0x96, 0xa4, 0x29, -+ 0x0f, 0xbb, 0xcf, 0x16, 0xae, 0x93, 0xd0, 0xcb, 0x2a, 0x26, 0x1a, 0x7b, -+ 0xfc, 0x51, 0x22, 0x76, 0x98, 0x31, 0xa7, 0x0f, 0x29, 0x35, 0x79, 0xbf, -+ 0xe2, 0x4f, 0x0f, 0x14, 0xf5, 0x1f, 0xcb, 0xbf, 0x87, 0x65, 0x13, 0x32, -+ 0xa3, 0x19, 0x4a, 0xd1, 0x3f, 0x45, 0xd4, 0x4b, 0xe2, 0x00, 0x26, 0xa9, -+ 0x3e, 0xd7, 0xa5, 0x37, 0x9f, 0xf5, 0xad, 0x61, 0xe2, 0x40, 0xa9, 0x74, -+ 0x24, 0x53, 0xf2, 0x78, 0xeb, 0x10, 0x9b, 0x2c, 0x27, 0x88, 0x46, 0xcb, -+ 0xe4, 0x60, 0xca, 0xf5, 0x06, 0x24, 0x40, 0x2a, 0x97, 0x3a, 0xcc, 0xd0, -+ 0x81, 0xb1, 0x15, 0xa3, 0x4f, 0xd0, 0x2b, 0x4f, 0xca, 0x6e, 0xaa, 0x24, -+ 0x31, 0xb3, 0xac, 0xa6, 0x75, 0x05, 0xfe, 0x8a, 0xf4, 0x41, 0xc4, 0x06, -+ 0x8a, 0xc7, 0x0a, 0x83, 0x4e, 0x49, 0xd4, 0x3f, 0x83, 0x50, 0xec, 0x57, -+ 0x04, 0x97, 0x14, 0x49, 0xf5, 0xe1, 0xb1, 0x7a, 0x9c, 0x09, 0x4f, 0x61, -+ 0x87, 0xc3, 0x97, 0x22, 0x17, 0xc2, 0xeb, 0xcc, 0x32, 0x81, 0x31, 0x21, -+ 0x3f, 0x10, 0x57, 0x5b, 0x43, 0xbe, 0xcd, 0x68, 0x82, 0xbe, 0xe5, 0xc1, -+ 0x65, 0x94, 0x7e, 0xc2, 0x34, 0x76, 0x2b, 0xcf, 0x89, 0x3c, 0x2b, 0x81, -+ 0x23, 0x72, 0x95, 0xcf, 0xc9, 0x67, 0x19, 0x2a, 0xd5, 0x5c, 0xca, 0xa3, -+ 0x46, 0xbd, 0x48, 0x06, 0x0b, 0xa6, 0xa3, 0x96, 0x50, 0x28, 0xc7, 0x7e, -+ 0xcf, 0x62, 0xf2, 0xfa, 0xc4, 0xf2, 0x53, 0xe3, 0xc9, 0xe8, 0x2e, 0xdd, -+ 0x29, 0x37, 0x07, 0x47, 0xff, 0xff, 0x8a, 0x32, 0xbd, 0xa2, 0xb7, 0x21, -+ 0x89, 0xa0, 0x55, 0xf7 -+}; -+unsigned int certificate_eku_der_len = 916; diff --git a/0183-ieee1275-ofdisk-retry-on-open-failure.patch b/0183-ieee1275-ofdisk-retry-on-open-failure.patch deleted file mode 100644 index 275d14f45411b4273c85451f947e6b5855fc38d9..0000000000000000000000000000000000000000 --- a/0183-ieee1275-ofdisk-retry-on-open-failure.patch +++ /dev/null @@ -1,103 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Diego Domingos -Date: Wed, 10 Mar 2021 14:17:52 -0500 -Subject: [PATCH] ieee1275/ofdisk: retry on open failure - -This patch aims to make grub more robust when booting from SAN/Multipath disks. - -If a path is failing intermittently so grub will retry the OPEN and READ the -disk (grub_ieee1275_open and grub_ieee1275_read) until the total amount of times -specified in MAX_RETRIES. - -Signed-off-by: Diego Domingos ---- - grub-core/disk/ieee1275/ofdisk.c | 25 ++++++++++++++++++++----- - include/grub/ieee1275/ofdisk.h | 8 ++++++++ - 2 files changed, 28 insertions(+), 5 deletions(-) - -diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c -index ea7f78ac7d8..55346849d35 100644 ---- a/grub-core/disk/ieee1275/ofdisk.c -+++ b/grub-core/disk/ieee1275/ofdisk.c -@@ -225,7 +225,9 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) - char *buf, *bufptr; - unsigned i; - -- if (grub_ieee1275_open (alias->path, &ihandle)) -+ -+ RETRY_IEEE1275_OFDISK_OPEN(alias->path, &ihandle) -+ if (! ihandle) - return; - - /* This method doesn't need memory allocation for the table. Open -@@ -305,7 +307,9 @@ dev_iterate (const struct grub_ieee1275_devalias *alias) - return; - } - -- if (grub_ieee1275_open (alias->path, &ihandle)) -+ RETRY_IEEE1275_OFDISK_OPEN(alias->path, &ihandle); -+ -+ if (! ihandle) - { - grub_free (buf); - grub_free (table); -@@ -495,7 +499,7 @@ grub_ofdisk_open (const char *name, grub_disk_t disk) - last_ihandle = 0; - last_devpath = NULL; - -- grub_ieee1275_open (op->open_path, &last_ihandle); -+ RETRY_IEEE1275_OFDISK_OPEN(op->open_path, &last_ihandle); - if (! last_ihandle) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); - last_devpath = op->open_path; -@@ -571,7 +575,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector) - last_ihandle = 0; - last_devpath = NULL; - -- grub_ieee1275_open (disk->data, &last_ihandle); -+ RETRY_IEEE1275_OFDISK_OPEN(disk->data, &last_ihandle); - if (! last_ihandle) - return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device"); - last_devpath = disk->data; -@@ -598,12 +602,23 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector, - return err; - grub_ieee1275_read (last_ihandle, buf, size << disk->log_sector_size, - &actual); -- if (actual != (grub_ssize_t) (size << disk->log_sector_size)) -+ int i = 0; -+ while(actual != (grub_ssize_t) (size << disk->log_sector_size)){ -+ if (i>MAX_RETRIES){ - return grub_error (GRUB_ERR_READ_ERROR, N_("failure reading sector 0x%llx " - "from `%s'"), - (unsigned long long) sector, - disk->name); -+ } -+ last_devpath = NULL; -+ err = grub_ofdisk_prepare (disk, sector); -+ if (err) -+ return err; - -+ grub_ieee1275_read (last_ihandle, buf, size << disk->log_sector_size, -+ &actual); -+ i++; -+ } - return 0; - } - -diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h -index 2f69e3f191d..7d2d5409305 100644 ---- a/include/grub/ieee1275/ofdisk.h -+++ b/include/grub/ieee1275/ofdisk.h -@@ -22,4 +22,12 @@ - extern void grub_ofdisk_init (void); - extern void grub_ofdisk_fini (void); - -+#define MAX_RETRIES 20 -+ -+ -+#define RETRY_IEEE1275_OFDISK_OPEN(device, last_ihandle) unsigned retry_i=0;for(retry_i=0; retry_i < MAX_RETRIES; retry_i++){ \ -+ if(!grub_ieee1275_open(device, last_ihandle)) \ -+ break; \ -+ grub_dprintf("ofdisk","Opening disk %s failed. Retrying...\n",device); } -+ - #endif /* ! GRUB_INIT_HEADER */ diff --git a/0184-Allow-chainloading-EFI-apps-from-loop-mounts.patch b/0184-Allow-chainloading-EFI-apps-from-loop-mounts.patch deleted file mode 100644 index 66e61a7ec3d4d09b69934b7795aee7ad64f57a61..0000000000000000000000000000000000000000 --- a/0184-Allow-chainloading-EFI-apps-from-loop-mounts.patch +++ /dev/null @@ -1,138 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Dimitri John Ledkov -Date: Fri, 11 Jun 2021 13:51:20 +0200 -Subject: [PATCH] Allow chainloading EFI apps from loop mounts. - -Signed-off-by: Dimitri John Ledkov -Signed-off-by: Robbie Harwood ---- - grub-core/disk/loopback.c | 9 +-------- - grub-core/loader/efi/chainloader.c | 23 +++++++++++++++++++++++ - include/grub/loopback.h | 30 ++++++++++++++++++++++++++++++ - 3 files changed, 54 insertions(+), 8 deletions(-) - create mode 100644 include/grub/loopback.h - -diff --git a/grub-core/disk/loopback.c b/grub-core/disk/loopback.c -index 41bebd14fe3..99f47924ec2 100644 ---- a/grub-core/disk/loopback.c -+++ b/grub-core/disk/loopback.c -@@ -21,20 +21,13 @@ - #include - #include - #include -+#include - #include - #include - #include - - GRUB_MOD_LICENSE ("GPLv3+"); - --struct grub_loopback --{ -- char *devname; -- grub_file_t file; -- struct grub_loopback *next; -- unsigned long id; --}; -- - static struct grub_loopback *loopback_list; - static unsigned long last_id = 0; - -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index d41e8ea14a8..3af6b122926 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -901,6 +902,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - grub_efi_status_t status; - grub_efi_boot_services_t *b; - grub_device_t dev = 0; -+ grub_device_t orig_dev = 0; - grub_efi_device_path_t *dp = 0; - char *filename; - void *boot_image = 0; -@@ -958,6 +960,15 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - if (! dev) - goto fail; - -+ /* if device is loopback, use underlying dev */ -+ if (dev->disk->dev->id == GRUB_DISK_DEVICE_LOOPBACK_ID) -+ { -+ struct grub_loopback *d; -+ orig_dev = dev; -+ d = dev->disk->data; -+ dev = d->file->device; -+ } -+ - if (dev->disk) - dev_handle = grub_efidisk_get_device_handle (dev->disk); - else if (dev->net && dev->net->server) -@@ -1065,6 +1076,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - } - #endif - -+ if (orig_dev) -+ { -+ dev = orig_dev; -+ orig_dev = 0; -+ } -+ - rc = grub_linuxefi_secure_validate((void *)(unsigned long)address, fsize); - grub_dprintf ("chain", "linuxefi_secure_validate: %d\n", rc); - if (rc > 0) -@@ -1087,6 +1104,12 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), - // -1 fall-through to fail - - fail: -+ if (orig_dev) -+ { -+ dev = orig_dev; -+ orig_dev = 0; -+ } -+ - if (dev) - grub_device_close (dev); - -diff --git a/include/grub/loopback.h b/include/grub/loopback.h -new file mode 100644 -index 00000000000..3b9a9e32e80 ---- /dev/null -+++ b/include/grub/loopback.h -@@ -0,0 +1,30 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2019 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_LOOPBACK_HEADER -+#define GRUB_LOOPBACK_HEADER 1 -+ -+struct grub_loopback -+{ -+ char *devname; -+ grub_file_t file; -+ struct grub_loopback *next; -+ unsigned long id; -+}; -+ -+#endif /* ! GRUB_LOOPBACK_HEADER */ diff --git a/0185-efinet-Add-DHCP-proxy-support.patch b/0185-efinet-Add-DHCP-proxy-support.patch deleted file mode 100644 index dcaac6fb39cc5c82e7a1beff8be45c80a4a599a9..0000000000000000000000000000000000000000 --- a/0185-efinet-Add-DHCP-proxy-support.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Ian Page Hands -Date: Tue, 8 Jun 2021 13:48:56 -0400 -Subject: [PATCH] efinet: Add DHCP proxy support - -If a proxyDHCP configuration is used, the server name, server IP and boot -file values should be taken from the DHCP proxy offer instead of the DHCP -server ack packet. Currently that case is not handled, add support for it. - -Signed-off-by: Ian Page Hands -Signed-off-by: Robbie Harwood ---- - grub-core/net/drivers/efi/efinet.c | 25 +++++++++++++++++++++++-- - 1 file changed, 23 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c -index e11d759f19a..1a24f38a21a 100644 ---- a/grub-core/net/drivers/efi/efinet.c -+++ b/grub-core/net/drivers/efi/efinet.c -@@ -850,10 +850,31 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device, - else - { - grub_dprintf ("efinet", "using ipv4 and dhcp\n"); -+ -+ struct grub_net_bootp_packet *dhcp_ack = &pxe_mode->dhcp_ack; -+ -+ if (pxe_mode->proxy_offer_received) -+ { -+ grub_dprintf ("efinet", "proxy offer receive"); -+ struct grub_net_bootp_packet *proxy_offer = &pxe_mode->proxy_offer; -+ -+ if (proxy_offer && dhcp_ack->boot_file[0] == '\0') -+ { -+ grub_dprintf ("efinet", "setting values from proxy offer"); -+ /* Here we got a proxy offer and the dhcp_ack has a nil boot_file -+ * Copy the proxy DHCP offer details into the bootp_packet we are -+ * sending forward as they are the deatils we need. -+ */ -+ *dhcp_ack->server_name = *proxy_offer->server_name; -+ *dhcp_ack->boot_file = *proxy_offer->boot_file; -+ dhcp_ack->server_ip = proxy_offer->server_ip; -+ } -+ } -+ - grub_net_configure_by_dhcp_ack (card->name, card, 0, - (struct grub_net_bootp_packet *) -- packet_buf, -- packet_bufsz, -+ &pxe_mode->dhcp_ack, -+ sizeof (pxe_mode->dhcp_ack), - 1, device, path); - grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path); - } diff --git a/0186-fs-ext2-Ignore-checksum-seed-incompat-feature.patch b/0186-fs-ext2-Ignore-checksum-seed-incompat-feature.patch deleted file mode 100644 index b4a5fd4ddfd9c0cec1c37c7ca8dfdb59ce380fa4..0000000000000000000000000000000000000000 --- a/0186-fs-ext2-Ignore-checksum-seed-incompat-feature.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Fri, 11 Jun 2021 00:01:29 +0200 -Subject: [PATCH] fs/ext2: Ignore checksum seed incompat feature - -This incompat feature is used to denote that the filesystem stored its -metadata checksum seed in the superblock. This is used to allow tune2fs -to change the UUID on a mounted metadata_csum filesystem without having -to rewrite all the disk metadata. - -But GRUB doesn't use the metadata checksum in anyway, so can just ignore -this feature if is enabled. This is consistent with GRUB filesystem code -in general which just does a best effort to access the filesystem's data. - -It may be removed from the ignored list in the future if supports to do -metadata checksumming verification is added to the read-only FS driver. - -Suggested-by: Eric Sandeen -Suggested-by: Lukas Czerner -Signed-off-by: Javier Martinez Canillas ---- - grub-core/fs/ext2.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/grub-core/fs/ext2.c b/grub-core/fs/ext2.c -index e7dd78e6635..731d346f886 100644 ---- a/grub-core/fs/ext2.c -+++ b/grub-core/fs/ext2.c -@@ -103,6 +103,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); - #define EXT4_FEATURE_INCOMPAT_64BIT 0x0080 - #define EXT4_FEATURE_INCOMPAT_MMP 0x0100 - #define EXT4_FEATURE_INCOMPAT_FLEX_BG 0x0200 -+#define EXT4_FEATURE_INCOMPAT_CSUM_SEED 0x2000 - #define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 - - /* The set of back-incompatible features this driver DOES support. Add (OR) -@@ -123,9 +124,16 @@ GRUB_MOD_LICENSE ("GPLv3+"); - * mmp: Not really back-incompatible - was added as such to - * avoid multiple read-write mounts. Safe to ignore for this - * RO driver. -+ * checksum seed: Not really back-incompatible - was added to allow tools -+ * such as tune2fs to change the UUID on a mounted metadata -+ * checksummed filesystem. Safe to ignore for now since the -+ * driver doesn't support checksum verification. But it must -+ * be removed from this list if that support is added later. -+ * - */ - #define EXT2_DRIVER_IGNORED_INCOMPAT ( EXT3_FEATURE_INCOMPAT_RECOVER \ -- | EXT4_FEATURE_INCOMPAT_MMP) -+ | EXT4_FEATURE_INCOMPAT_MMP \ -+ | EXT4_FEATURE_INCOMPAT_CSUM_SEED) - - - #define EXT3_JOURNAL_MAGIC_NUMBER 0xc03b3998U diff --git a/0187-Don-t-update-the-cmdline-when-generating-legacy-menu.patch b/0187-Don-t-update-the-cmdline-when-generating-legacy-menu.patch deleted file mode 100644 index c4ce251e252542de8cbc3d8df878a4c3876c57ec..0000000000000000000000000000000000000000 --- a/0187-Don-t-update-the-cmdline-when-generating-legacy-menu.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Thu, 17 Jun 2021 14:31:42 +0200 -Subject: [PATCH] Don't update the cmdline when generating legacy menuentry - commands - -On OPAL ppc64le machines with an old petitboot version that doesn't have -support to parse BLS snippets, the grub2-mkconfig script is executed to -generate menuentry commands from the BLS snippets. - -In this case, the script is executed with the --no-grubenv-update option -that indicates that no side effects should happen when running the script. - -But the options field in the BLS snippets are updated regardless, only do -the update if --no-grubenv-update was not used. - -Signed-off-by: Javier Martinez Canillas ---- - util/grub.d/10_linux.in | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 81f35a2f3f0..98fd9da6610 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -256,7 +256,9 @@ if [ -z "\${kernelopts}" ]; then - fi - EOF - -- update_bls_cmdline -+ if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then -+ update_bls_cmdline -+ fi - - if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then - populate_menu diff --git a/0188-Suppress-gettext-error-message.patch b/0188-Suppress-gettext-error-message.patch deleted file mode 100644 index c42dd0d53118d24b9b4cea22f13e6b65584ea4ac..0000000000000000000000000000000000000000 --- a/0188-Suppress-gettext-error-message.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Tue, 29 Jun 2021 13:17:42 +0200 -Subject: [PATCH] Suppress gettext error message - -Colin Watson's patch from comment #11 on the upstream bug: -https://savannah.gnu.org/bugs/?35880#comment11 - -Resolves: rhbz#1592124 - -Signed-off-by: Paulo Flabiano Smorigo ---- - grub-core/gettext/gettext.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/grub-core/gettext/gettext.c b/grub-core/gettext/gettext.c -index 4d02e62c109..7ec81ca0b48 100644 ---- a/grub-core/gettext/gettext.c -+++ b/grub-core/gettext/gettext.c -@@ -424,6 +424,13 @@ grub_gettext_init_ext (struct grub_gettext_context *ctx, - grub_free (lang); - } - -+ /* If no translations are available, fall back to untranslated text. */ -+ if (err == GRUB_ERR_FILE_NOT_FOUND) -+ { -+ grub_errno = GRUB_ERR_NONE; -+ return 0; -+ } -+ - if (locale[0] == 'e' && locale[1] == 'n' - && (locale[2] == '\0' || locale[2] == '_')) - grub_errno = err = GRUB_ERR_NONE; diff --git a/0189-grub-set-password-Always-use-boot-grub2-user.cfg-as-.patch b/0189-grub-set-password-Always-use-boot-grub2-user.cfg-as-.patch deleted file mode 100644 index 7ecea22d697e8ec24ecde0c96d5bb4977a8163d4..0000000000000000000000000000000000000000 --- a/0189-grub-set-password-Always-use-boot-grub2-user.cfg-as-.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Mon, 5 Jul 2021 18:24:22 +0200 -Subject: [PATCH] grub-set-password: Always use /boot/grub2/user.cfg as - password default - -The GRUB configuration file is always placed in /boot/grub2/ now, even for -EFI. But the tool is still creating the user.cfg in the ESP and not there. - -Resolves: rhbz#1955294 - -Signed-off-by: Javier Martinez Canillas ---- - util/grub-set-password.in | 9 +-------- - 1 file changed, 1 insertion(+), 8 deletions(-) - -diff --git a/util/grub-set-password.in b/util/grub-set-password.in -index c0b5ebbfdc5..d8005e5a142 100644 ---- a/util/grub-set-password.in -+++ b/util/grub-set-password.in -@@ -1,11 +1,6 @@ - #!/bin/sh -e - --EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g') --if [ -d /sys/firmware/efi/efivars/ ]; then -- grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'` --else -- grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` --fi -+grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'` - - PACKAGE_VERSION="@PACKAGE_VERSION@" - PACKAGE_NAME="@PACKAGE_NAME@" -@@ -116,8 +111,6 @@ if [ -z "${MYPASS}" ]; then - exit 1 - fi - --# on the ESP, these will fail to set the permissions, but it's okay because --# the directory is protected. - install -m 0600 /dev/null "${OUTPUT_PATH}/user.cfg" 2>/dev/null || : - chmod 0600 "${OUTPUT_PATH}/user.cfg" 2>/dev/null || : - echo "GRUB2_PASSWORD=${MYPASS}" > "${OUTPUT_PATH}/user.cfg" diff --git a/0190-templates-Check-for-EFI-at-runtime-instead-of-config.patch b/0190-templates-Check-for-EFI-at-runtime-instead-of-config.patch deleted file mode 100644 index e36afa113d9eb7dc5615400dcf67facb14f93152..0000000000000000000000000000000000000000 --- a/0190-templates-Check-for-EFI-at-runtime-instead-of-config.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 6 Jul 2021 00:38:40 +0200 -Subject: [PATCH] templates: Check for EFI at runtime instead of config - generation time - -The 30_uefi-firmware template checks if an OsIndicationsSupported UEFI var -exists and EFI_OS_INDICATIONS_BOOT_TO_FW_UI bit is set, to decide whether -a "fwsetup" menu entry would be added or not to the GRUB menu. - -But this has the problem that it will only work if the configuration file -was created on an UEFI machine that supports booting to a firmware UI. - -This for example doesn't support creating GRUB config files when executing -on systems that support both UEFI and legacy BIOS booting. Since creating -the config file from legacy BIOS wouldn't allow to access the firmware UI. - -To prevent this, make the template to unconditionally create the grub.cfg -snippet but check at runtime if was booted through UEFI to decide if this -entry should be added. That way it won't be added when booting with BIOS. - -There's no need to check if EFI_OS_INDICATIONS_BOOT_TO_FW_UI bit is set, -since that's already done by the "fwsetup" command when is executed. - -Resolves: rhbz#1823864 - -Signed-off-by: Javier Martinez Canillas ---- - util/grub.d/30_uefi-firmware.in | 21 ++++++++------------- - 1 file changed, 8 insertions(+), 13 deletions(-) - -diff --git a/util/grub.d/30_uefi-firmware.in b/util/grub.d/30_uefi-firmware.in -index d344d3883d7..b6041b55e2a 100644 ---- a/util/grub.d/30_uefi-firmware.in -+++ b/util/grub.d/30_uefi-firmware.in -@@ -26,19 +26,14 @@ export TEXTDOMAINDIR="@localedir@" - - . "$pkgdatadir/grub-mkconfig_lib" - --EFI_VARS_DIR=/sys/firmware/efi/efivars --EFI_GLOBAL_VARIABLE=8be4df61-93ca-11d2-aa0d-00e098032b8c --OS_INDICATIONS="$EFI_VARS_DIR/OsIndicationsSupported-$EFI_GLOBAL_VARIABLE" -+LABEL="UEFI Firmware Settings" - --if [ -e "$OS_INDICATIONS" ] && \ -- [ "$(( $(printf 0x%x \'"$(cat $OS_INDICATIONS | cut -b5)"\') & 1 ))" = 1 ]; then -- LABEL="UEFI Firmware Settings" -+gettext_printf "Adding boot menu entry for UEFI Firmware Settings ...\n" >&2 - -- gettext_printf "Adding boot menu entry for UEFI Firmware Settings ...\n" >&2 -- -- cat << EOF --menuentry '$LABEL' \$menuentry_id_option 'uefi-firmware' { -- fwsetup --} --EOF -+cat << EOF -+if [ "\$grub_platform" = "efi" ]; then -+ menuentry '$LABEL' \$menuentry_id_option 'uefi-firmware' { -+ fwsetup -+ } - fi -+EOF diff --git a/0191-efi-Print-an-error-if-boot-to-firmware-setup-is-not-.patch b/0191-efi-Print-an-error-if-boot-to-firmware-setup-is-not-.patch deleted file mode 100644 index 65b4aec54b51585670ec186dbd795214baad484f..0000000000000000000000000000000000000000 --- a/0191-efi-Print-an-error-if-boot-to-firmware-setup-is-not-.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Tue, 6 Jul 2021 01:10:18 +0200 -Subject: [PATCH] efi: Print an error if boot to firmware setup is not - supported - -The "fwsetup" command is only registered if the firmware supports booting -to the firmware setup UI. But it could be possible that the GRUB config -already contains a "fwsetup" entry, because it was generated in a machine -that has support for this feature. - -To prevent users getting a "can't find command `fwsetup`" error if it is -not supported by the firmware, let's just always register the command but -print a more accurate message if the firmware doesn't support this option. - -Resolves: rhbz#1823864 - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/commands/efi/efifwsetup.c | 43 ++++++++++++++++++++----------------- - 1 file changed, 23 insertions(+), 20 deletions(-) - -diff --git a/grub-core/commands/efi/efifwsetup.c b/grub-core/commands/efi/efifwsetup.c -index eaca0328388..328c45e82e0 100644 ---- a/grub-core/commands/efi/efifwsetup.c -+++ b/grub-core/commands/efi/efifwsetup.c -@@ -27,6 +27,25 @@ - - GRUB_MOD_LICENSE ("GPLv3+"); - -+static grub_efi_boolean_t -+efifwsetup_is_supported (void) -+{ -+ grub_efi_uint64_t *os_indications_supported = NULL; -+ grub_size_t oi_size = 0; -+ grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; -+ -+ grub_efi_get_variable ("OsIndicationsSupported", &global, &oi_size, -+ (void **) &os_indications_supported); -+ -+ if (!os_indications_supported) -+ return 0; -+ -+ if (*os_indications_supported & GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI) -+ return 1; -+ -+ return 0; -+} -+ - static grub_err_t - grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)), - int argc __attribute__ ((unused)), -@@ -38,6 +57,10 @@ grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)), - grub_size_t oi_size; - grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; - -+ if (!efifwsetup_is_supported ()) -+ return grub_error (GRUB_ERR_INVALID_COMMAND, -+ N_("Reboot to firmware setup is not supported")); -+ - grub_efi_get_variable ("OsIndications", &global, &oi_size, - (void **) &old_os_indications); - -@@ -56,28 +79,8 @@ grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)), - - static grub_command_t cmd = NULL; - --static grub_efi_boolean_t --efifwsetup_is_supported (void) --{ -- grub_efi_uint64_t *os_indications_supported = NULL; -- grub_size_t oi_size = 0; -- grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID; -- -- grub_efi_get_variable ("OsIndicationsSupported", &global, &oi_size, -- (void **) &os_indications_supported); -- -- if (!os_indications_supported) -- return 0; -- -- if (*os_indications_supported & GRUB_EFI_OS_INDICATIONS_BOOT_TO_FW_UI) -- return 1; -- -- return 0; --} -- - GRUB_MOD_INIT (efifwsetup) - { -- if (efifwsetup_is_supported ()) - cmd = grub_register_command ("fwsetup", grub_cmd_fwsetup, NULL, - N_("Reboot into firmware setup menu.")); - diff --git a/0193-normal-main-Discover-the-device-to-read-the-config-f.patch b/0193-normal-main-Discover-the-device-to-read-the-config-f.patch deleted file mode 100644 index 800903884efbc16d89521bf248817a21f631b1ca..0000000000000000000000000000000000000000 --- a/0193-normal-main-Discover-the-device-to-read-the-config-f.patch +++ /dev/null @@ -1,123 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Javier Martinez Canillas -Date: Mon, 30 Aug 2021 12:31:18 +0200 -Subject: [PATCH] normal/main: Discover the device to read the config from as a - fallback - -The GRUB core.img is generated locally, when this is done the grub2-probe -tool figures out the device and partition that needs to be read to parse -the GRUB configuration file. - -But in some cases the core.img can't be generated on the host and instead -has to be done at package build time. For example, if needs to get signed -with a key that's only available on the package building infrastructure. - -If that's the case, the prefix variable won't have a device and partition -but only a directory path. So there's no way for GRUB to know from which -device has to read the configuration file. - -To allow GRUB to continue working on that scenario, fallback to iterating -over all the available devices, if reading the config failed when using -the prefix and fw_path variables. - -Signed-off-by: Javier Martinez Canillas ---- - grub-core/normal/main.c | 58 +++++++++++++++++++++++++++++++++++++++++++------ - 1 file changed, 51 insertions(+), 7 deletions(-) - -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index 4ebdbd228d4..b72fe3d653c 100644 ---- a/grub-core/normal/main.c -+++ b/grub-core/normal/main.c -@@ -337,18 +337,13 @@ grub_enter_normal_mode (const char *config) - } - - static grub_err_t --grub_try_normal (const char *variable) -+grub_try_normal_prefix (const char *prefix) - { - char *config; -- const char *prefix; - grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; - const char *net_search_cfg; - int disable_net_search = 0; - -- prefix = grub_env_get (variable); -- if (!prefix) -- return GRUB_ERR_FILE_NOT_FOUND; -- - net_search_cfg = grub_env_get ("feature_net_search_cfg"); - if (net_search_cfg && net_search_cfg[0] == 'n') - disable_net_search = 1; -@@ -362,7 +357,7 @@ grub_try_normal (const char *variable) - config = grub_malloc (config_len); - - if (! config) -- return GRUB_ERR_FILE_NOT_FOUND; -+ return err; - - grub_snprintf (config, config_len, "%s/grub.cfg", prefix); - err = grub_net_search_config_file (config); -@@ -391,6 +386,53 @@ grub_try_normal (const char *variable) - return err; - } - -+static int -+grub_try_normal_dev (const char *name, void *data) -+{ -+ grub_err_t err; -+ const char *prefix = grub_xasprintf ("(%s)%s", name, (char *)data); -+ -+ if (!prefix) -+ return 0; -+ -+ err = grub_try_normal_prefix (prefix); -+ if (err == GRUB_ERR_NONE) -+ return 1; -+ -+ return 0; -+} -+ -+static grub_err_t -+grub_try_normal_discover (void) -+{ -+ char *prefix = grub_env_get ("prefix"); -+ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; -+ -+ if (!prefix) -+ return err; -+ -+ if (grub_device_iterate (grub_try_normal_dev, (void *)prefix)) -+ return GRUB_ERR_NONE; -+ -+ return err; -+} -+ -+static grub_err_t -+grub_try_normal (const char *variable) -+{ -+ grub_err_t err = GRUB_ERR_FILE_NOT_FOUND; -+ const char *prefix; -+ -+ if (!variable) -+ return err; -+ -+ prefix = grub_env_get (variable); -+ if (!prefix) -+ return err; -+ -+ return grub_try_normal_prefix (prefix); -+} -+ - /* Enter normal mode from rescue mode. */ - static grub_err_t - grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), -@@ -405,6 +447,8 @@ grub_cmd_normal (struct grub_command *cmd __attribute__ ((unused)), - err = grub_try_normal ("fw_path"); - if (err == GRUB_ERR_FILE_NOT_FOUND) - err = grub_try_normal ("prefix"); -+ if (err == GRUB_ERR_FILE_NOT_FOUND) -+ err = grub_try_normal_discover (); - if (err == GRUB_ERR_FILE_NOT_FOUND) - grub_enter_normal_mode (0); - } diff --git a/0194-powerpc-adjust-setting-of-prefix-for-signed-binary-c.patch b/0194-powerpc-adjust-setting-of-prefix-for-signed-binary-c.patch deleted file mode 100644 index 7f3161e29b03ee56071298ef2d346b73181f4699..0000000000000000000000000000000000000000 --- a/0194-powerpc-adjust-setting-of-prefix-for-signed-binary-c.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 19 Jul 2021 14:35:55 +1000 -Subject: [PATCH] powerpc: adjust setting of prefix for signed binary case - -On RHEL-signed powerpc grub, we sign a grub with -p /grub2 and expect -that there's a boot partition. - -Unfortunately grub_set_prefix_and_root tries to convert this to -($fwdevice)/grub2. This ends up being (ieee1275/disk)/grub2 and that -falls apart pretty quickly - there's no file-system on ieee1275/disk, -and it makes the search routine try things like -(ieee1275/disk,msdos2)(ieee1275/disk)/grub2 which also doesn't work. - -Detect if we would be about to create (ieee1275/disk)/path and don't: -preserve a prefix of /path instead and hope the search later finds us. - -Related: rhbz#1899864 - -Signed-off-by: Daniel Axtens -[rharwood@redhat.com: squash in fixup commit] -Signed-off-by: Robbie Harwood ---- - grub-core/kern/main.c | 49 ++++++++++++++++++++++++++++++++++++++++++++----- - 1 file changed, 44 insertions(+), 5 deletions(-) - -diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c -index b573be6650d..3fc34014726 100644 ---- a/grub-core/kern/main.c -+++ b/grub-core/kern/main.c -@@ -216,13 +216,52 @@ grub_set_prefix_and_root (void) - if (device) - { - char *prefix_set; -- -- prefix_set = grub_xasprintf ("(%s)%s", device, path ? : ""); -- if (prefix_set) -+ -+#ifdef __powerpc__ -+ /* We have to be careful here on powerpc-ieee1275 + signed grub. We -+ will have signed something with a prefix that doesn't have a device -+ because we cannot know in advance what partition we're on. -+ -+ We will have had !device earlier, so we will have set device=fwdevice -+ However, we want to make sure we do not end up setting prefix to be -+ ($fwdevice)/path, because we will then end up trying to boot or search -+ based on a prefix of (ieee1275/disk)/path, which will not work because -+ it's missing a partition. -+ -+ Also: -+ - You can end up with a device with an FS directly on it, without -+ a partition, e.g. ieee1275/cdrom. -+ -+ - powerpc-ieee1275 + grub-install sets e.g. prefix=(,gpt2)/path, -+ which will have now been extended to device=$fwdisk,partition -+ and path=/path -+ -+ - PowerVM will give us device names like -+ ieee1275//vdevice/v-scsi@3000006c/disk@8100000000000000 -+ and we don't want to try to encode some sort of truth table about -+ what sorts of paths represent disks with partition tables and those -+ without partition tables. -+ -+ So we act unless there is a comma in the device, which would indicate -+ a partition has already been specified. -+ -+ (If we only have a path, the code in normal to discover config files -+ will try both without partitions and then with any partitions so we -+ will cover both CDs and HDs.) -+ */ -+ if (grub_strchr (device, ',') == NULL) -+ grub_env_set ("prefix", path); -+ else -+#endif - { -- grub_env_set ("prefix", prefix_set); -- grub_free (prefix_set); -+ prefix_set = grub_xasprintf ("(%s)%s", device, path ? : ""); -+ if (prefix_set) -+ { -+ grub_env_set ("prefix", prefix_set); -+ grub_free (prefix_set); -+ } - } -+ - grub_env_set ("root", device); - } - diff --git a/0195-fs-xfs-Fix-unreadable-filesystem-with-v4-superblock.patch b/0195-fs-xfs-Fix-unreadable-filesystem-with-v4-superblock.patch deleted file mode 100644 index 893d8b41ae9c07042910f48e22c628da99c8930b..0000000000000000000000000000000000000000 --- a/0195-fs-xfs-Fix-unreadable-filesystem-with-v4-superblock.patch +++ /dev/null @@ -1,118 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Erwan Velu -Date: Wed, 25 Aug 2021 15:31:52 +0200 -Subject: [PATCH] fs/xfs: Fix unreadable filesystem with v4 superblock - -The commit 8b1e5d193 (fs/xfs: Add bigtime incompat feature support) -introduced the bigtime support by adding some features in v3 inodes. -This change extended grub_xfs_inode struct by 76 bytes but also changed -the computation of XFS_V2_INODE_SIZE and XFS_V3_INODE_SIZE. Prior this -commit, XFS_V2_INODE_SIZE was 100 bytes. After the commit it's 84 bytes -XFS_V2_INODE_SIZE becomes 16 bytes too small. - -As a result, the data structures aren't properly aligned and the GRUB -generates "attempt to read or write outside of partition" errors when -trying to read the XFS filesystem: - - GNU GRUB version 2.11 - .... - grub> set debug=efi,gpt,xfs - grub> insmod part_gpt - grub> ls (hd0,gpt1)/ - partmap/gpt.c:93: Read a valid GPT header - partmap/gpt.c:115: GPT entry 0: start=4096, length=1953125 - fs/xfs.c:931: Reading sb - fs/xfs.c:270: Validating superblock - fs/xfs.c:295: XFS v4 superblock detected - fs/xfs.c:962: Reading root ino 128 - fs/xfs.c:515: Reading inode (128) - 64, 0 - fs/xfs.c:515: Reading inode (739521961424144223) - 344365866970255880, 3840 - error: attempt to read or write outside of partition. - -This commit change the XFS_V2_INODE_SIZE computation by subtracting 76 -bytes instead of 92 bytes from the actual size of grub_xfs_inode struct. -This 76 bytes value comes from added members: - 20 grub_uint8_t unused5 - 1 grub_uint64_t flags2 - 48 grub_uint8_t unused6 - -This patch explicitly splits the v2 and v3 parts of the structure. -The unused4 is still ending of the v2 structures and the v3 starts -at unused5. Thanks to this we will avoid future corruptions of v2 -or v3 inodes. - -The XFS_V2_INODE_SIZE is returning to its expected size and the -filesystem is back to a readable state: - - GNU GRUB version 2.11 - .... - grub> set debug=efi,gpt,xfs - grub> insmod part_gpt - grub> ls (hd0,gpt1)/ - partmap/gpt.c:93: Read a valid GPT header - partmap/gpt.c:115: GPT entry 0: start=4096, length=1953125 - fs/xfs.c:931: Reading sb - fs/xfs.c:270: Validating superblock - fs/xfs.c:295: XFS v4 superblock detected - fs/xfs.c:962: Reading root ino 128 - fs/xfs.c:515: Reading inode (128) - 64, 0 - fs/xfs.c:515: Reading inode (128) - 64, 0 - fs/xfs.c:931: Reading sb - fs/xfs.c:270: Validating superblock - fs/xfs.c:295: XFS v4 superblock detected - fs/xfs.c:962: Reading root ino 128 - fs/xfs.c:515: Reading inode (128) - 64, 0 - fs/xfs.c:515: Reading inode (128) - 64, 0 - fs/xfs.c:515: Reading inode (128) - 64, 0 - fs/xfs.c:515: Reading inode (131) - 64, 768 - efi/ fs/xfs.c:515: Reading inode (3145856) - 1464904, 0 - grub2/ fs/xfs.c:515: Reading inode (132) - 64, 1024 - grub/ fs/xfs.c:515: Reading inode (139) - 64, 2816 - grub> - -Fixes: 8b1e5d193 (fs/xfs: Add bigtime incompat feature support) - -Signed-off-by: Erwan Velu -Tested-by: Carlos Maiolino -Reviewed-by: Daniel Kiper -(cherry picked from commit a4b495520e4dc41a896a8b916a64eda9970c50ea) ---- - grub-core/fs/xfs.c | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c -index 0f524c3a8a6..e3816d1ec4a 100644 ---- a/grub-core/fs/xfs.c -+++ b/grub-core/fs/xfs.c -@@ -192,6 +192,11 @@ struct grub_xfs_time_legacy - grub_uint32_t nanosec; - } GRUB_PACKED; - -+/* -+ * The struct grub_xfs_inode layout was taken from the -+ * struct xfs_dinode_core which is described here: -+ * https://mirrors.edge.kernel.org/pub/linux/utils/fs/xfs/docs/xfs_filesystem_structure.pdf -+ */ - struct grub_xfs_inode - { - grub_uint8_t magic[2]; -@@ -208,14 +213,15 @@ struct grub_xfs_inode - grub_uint32_t nextents; - grub_uint16_t unused3; - grub_uint8_t fork_offset; -- grub_uint8_t unused4[37]; -+ grub_uint8_t unused4[17]; /* Last member of inode v2. */ -+ grub_uint8_t unused5[20]; /* First member of inode v3. */ - grub_uint64_t flags2; -- grub_uint8_t unused5[48]; -+ grub_uint8_t unused6[48]; /* Last member of inode v3. */ - } GRUB_PACKED; - - #define XFS_V3_INODE_SIZE sizeof(struct grub_xfs_inode) --/* Size of struct grub_xfs_inode until fork_offset (included). */ --#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 92) -+/* Size of struct grub_xfs_inode v2, up to unused4 member included. */ -+#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 76) - - struct grub_xfs_dirblock_tail - { diff --git a/0196-Print-module-name-on-license-check-failure.patch b/0196-Print-module-name-on-license-check-failure.patch deleted file mode 100644 index c4b9a134421e5169874b9aa25e036ed8fef6dab8..0000000000000000000000000000000000000000 --- a/0196-Print-module-name-on-license-check-failure.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Tue, 12 Oct 2021 12:34:23 -0400 -Subject: [PATCH] Print module name on license check failure - -At the very least, this will make it easier to track down the problem -module - or, if something else has gone wrong, provide more information -for debugging. - -Signed-off-by: Robbie Harwood ---- - grub-core/kern/dl.c | 10 ++++++---- - 1 file changed, 6 insertions(+), 4 deletions(-) - -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index 9557254035e..f3044945742 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -528,14 +528,16 @@ grub_dl_find_section_index (Elf_Ehdr *e, const char *name) - Be sure to understand your license obligations. - */ - static grub_err_t --grub_dl_check_license (Elf_Ehdr *e) -+grub_dl_check_license (grub_dl_t mod, Elf_Ehdr *e) - { - Elf_Shdr *s = grub_dl_find_section (e, ".module_license"); - if (s && (grub_strcmp ((char *) e + s->sh_offset, "LICENSE=GPLv3") == 0 - || grub_strcmp ((char *) e + s->sh_offset, "LICENSE=GPLv3+") == 0 - || grub_strcmp ((char *) e + s->sh_offset, "LICENSE=GPLv2+") == 0)) - return GRUB_ERR_NONE; -- return grub_error (GRUB_ERR_BAD_MODULE, "incompatible license"); -+ return grub_error (GRUB_ERR_BAD_MODULE, -+ "incompatible license in module %s: %s", mod->name, -+ (char *) e + s->sh_offset); - } - - static grub_err_t -@@ -743,8 +745,8 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) - constitutes linking) and GRUB core being licensed under GPLv3+. - Be sure to understand your license obligations. - */ -- if (grub_dl_check_license (e) -- || grub_dl_resolve_name (mod, e) -+ if (grub_dl_resolve_name (mod, e) -+ || grub_dl_check_license (mod, e) - || grub_dl_resolve_dependencies (mod, e) - || grub_dl_load_segments (mod, e) - || grub_dl_resolve_symbols (mod, e) diff --git a/0197-powerpc-ieee1275-load-grub-at-4MB-not-2MB.patch b/0197-powerpc-ieee1275-load-grub-at-4MB-not-2MB.patch deleted file mode 100644 index a80727e0bb16e2a24f1b006fb3d10300207996a3..0000000000000000000000000000000000000000 --- a/0197-powerpc-ieee1275-load-grub-at-4MB-not-2MB.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 22 Oct 2021 09:53:15 +1100 -Subject: [PATCH] powerpc-ieee1275: load grub at 4MB, not 2MB - -This was first reported under PFW but reproduces under SLOF. - - - The core.elf was 2126152 = 0x207148 bytes in size with the following - program headers (per readelf): - -Entry point 0x200000 -There are 4 program headers, starting at offset 52 - -Program Headers: - Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align - LOAD 0x000160 0x00200000 0x00200000 0x21f98 0x2971c RWE 0x8 - GNU_STACK 0x0220f8 0x00000000 0x00000000 0x00000 0x00000 RWE 0x4 - LOAD 0x0220f8 0x00232000 0x00232000 0x1e4e50 0x1e4e50 RWE 0x4 - NOTE 0x206f48 0x00000000 0x00000000 0x00200 0x00000 R 0x4 - - - SLOF places the ELF file at 0x4000 (after the reserved space for - interrupt handlers etc.) upwards. The image was 2126152 = 0x207148 - bytes in size, so it runs from 0x4000 - 0x20b148. We'll call 0x4000 the - load address. - -0x0 0x4000 0x20b148 - |----------|--------------| - | reserved | ELF contents | - - - SLOF then copies the first LOAD program header (for .text). That runs - for 0x21f98 bytes. It runs from - (load addr + 0x160) to (load addr + 0x160 + 0x21f98) - = 0x4160 to 0x260f8 - and we copy it to 0x200000 to 0x221f98. This overwrites the end of the - image: - -0x0 0x4000 0x200000 0x221f98 - |----------|------------|---------------| - | reserved | ELF cont.. | .text section | - - - SLOF zeros the bss up to PhysAddr + MemSize = 0x22971c - -0x0 0x4000 0x200000 0x221f98 0x22971c - |----------|------------|---------------|--------| - | reserved | ELF cont.. | .text section | bss 0s | - - - SLOF then goes to fulfil the next LOAD header (for mods), which is - for 0x1e4e50 bytes. We copy from - (load addr + 0x220f8) to (load addr + 0x220f8 + 0x1e4e50) - = 0x260f8 to 0x20af48 - and we copy it to 0x232000 to 0x416e50: - -0x0 0x4000 0x200000 0x221f98 0x22971c - |----------|------------|---------------|--------| - | reserved | ELF cont.. | .text section | bss 0s | - |-------------| - | copied area | - 0x260f8 0x20af48 - - This goes poorly: - -0x0 0x4000 0x200000 0x221f98 0x22971c 0x232000 0x40bf08 0x416e50 - |----------|------------|---------------|--------|-----|-----------|-------------| - | reserved | ELF cont.. | .text section | bss 0s | pad | some mods | .text start | - -This matches the observations on the running system - 0x40bf08 was where -the contents of memory no longer matched the contents of the ELF file. - -This was reported as a license verification failure on SLOF as the -last module's .module_license section fell past where the corruption -began. - -Signed-off-by: Daniel Axtens -[rharwood@redhat.com: trim very detailed commit message] -Signed-off-by: Robbie Harwood ---- - grub-core/Makefile.core.def | 2 +- - include/grub/offsets.h | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 3f3459b2c70..6b00eb55575 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -89,7 +89,7 @@ kernel = { - i386_xen_pvh_ldflags = '$(TARGET_IMG_BASE_LDOPT),0x100000'; - - mips_loongson_ldflags = '-Wl,-Ttext,0x80200000'; -- powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x200000'; -+ powerpc_ieee1275_ldflags = '-Wl,-Ttext,0x400000'; - sparc64_ieee1275_ldflags = '-Wl,-Ttext,0x4400'; - mips_arc_ldflags = '-Wl,-Ttext,$(TARGET_LINK_ADDR)'; - mips_qemu_mips_ldflags = '-Wl,-Ttext,0x80200000'; -diff --git a/include/grub/offsets.h b/include/grub/offsets.h -index 871e1cd4c38..69211aa798b 100644 ---- a/include/grub/offsets.h -+++ b/include/grub/offsets.h -@@ -63,7 +63,7 @@ - #define GRUB_KERNEL_SPARC64_IEEE1275_LINK_ADDR 0x4400 - - #define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ALIGN 4 --#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x200000 -+#define GRUB_KERNEL_POWERPC_IEEE1275_LINK_ADDR 0x400000 - - #define GRUB_KERNEL_MIPS_LOONGSON_LINK_ADDR 0x80200000 - diff --git a/0198-grub-mkconfig-restore-umask-for-grub.cfg.patch b/0198-grub-mkconfig-restore-umask-for-grub.cfg.patch deleted file mode 100644 index 7c7bee0e60f5eb8d1f55dccd2d0052aa7f672663..0000000000000000000000000000000000000000 --- a/0198-grub-mkconfig-restore-umask-for-grub.cfg.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang via Grub-devel -Date: Fri, 3 Dec 2021 16:13:28 +0800 -Subject: [PATCH] grub-mkconfig: restore umask for grub.cfg - -Since commit: - - ab2e53c8a grub-mkconfig: Honor a symlink when generating configuration -by grub-mkconfig - -has inadvertently discarded umask for creating grub.cfg in the process -of grub-mkconfig. The resulting wrong permission (0644) would allow -unprivileged users to read grub's configuration file content. This -presents a low confidentiality risk as grub.cfg may contain non-secured -plain-text passwords. - -This patch restores the missing umask and set the file mode of creation -to 0600 preventing unprivileged access. - -Fixes: CVE-2021-3981 - -Signed-off-by: Michael Chang ---- - util/grub-mkconfig.in | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index f55339a3f64..520a672cd2c 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -311,7 +311,9 @@ and /etc/grub.d/* files or please file a bug report with - exit 1 - else - # none of the children aborted with error, install the new grub.cfg -+ oldumask=$(umask); umask 077 - cat ${grub_cfg}.new > ${grub_cfg} -+ umask $oldumask - rm -f ${grub_cfg}.new - fi - fi diff --git a/0199-fs-btrfs-Use-full-btrfs-bootloader-area.patch b/0199-fs-btrfs-Use-full-btrfs-bootloader-area.patch deleted file mode 100644 index ecfc58cd684f5430edd68e7f3523da02fcbebcd9..0000000000000000000000000000000000000000 --- a/0199-fs-btrfs-Use-full-btrfs-bootloader-area.patch +++ /dev/null @@ -1,160 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Mon, 13 Dec 2021 14:25:49 +0800 -Subject: [PATCH] fs/btrfs: Use full btrfs bootloader area - -Up to now GRUB can only embed to the first 64 KiB before primary -superblock of btrfs, effectively limiting the GRUB core size. That -could consequently pose restrictions to feature enablement like -advanced zstd compression. - -This patch attempts to utilize full unused area reserved by btrfs for -the bootloader outlined in the document [1]: - - The first 1MiB on each device is unused with the exception of primary - superblock that is on the offset 64KiB and spans 4KiB. - -Apart from that, adjacent sectors to superblock and first block group -are not used for embedding in case of overflow and logged access to -adjacent sectors could be useful for tracing it up. - -This patch has been tested to provide out of the box support for btrfs -zstd compression with which GRUB has been installed to the partition. - -[1] https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs(5)#BOOTLOADER_SUPPORT - -Signed-off-by: Michael Chang -Reviewed-by: Daniel Kiper -(cherry picked from commit b0f06a81c6f31b6fa20be67a96b6683bba8210c9) ---- - grub-core/fs/btrfs.c | 90 ++++++++++++++++++++++++++++++++++++++++++++-------- - include/grub/disk.h | 2 ++ - 2 files changed, 79 insertions(+), 13 deletions(-) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 4cc86e9b79e..07c0ff874b8 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -2476,6 +2476,33 @@ grub_btrfs_label (grub_device_t device, char **label) - } - - #ifdef GRUB_UTIL -+ -+struct embed_region { -+ unsigned int start; -+ unsigned int secs; -+}; -+ -+/* -+ * https://btrfs.wiki.kernel.org/index.php/Manpage/btrfs(5)#BOOTLOADER_SUPPORT -+ * The first 1 MiB on each device is unused with the exception of primary -+ * superblock that is on the offset 64 KiB and spans 4 KiB. -+ */ -+ -+static const struct { -+ struct embed_region available; -+ struct embed_region used[6]; -+} btrfs_head = { -+ .available = {0, GRUB_DISK_KiB_TO_SECTORS (1024)}, /* The first 1 MiB. */ -+ .used = { -+ {0, 1}, /* boot.S. */ -+ {GRUB_DISK_KiB_TO_SECTORS (64) - 1, 1}, /* Overflow guard. */ -+ {GRUB_DISK_KiB_TO_SECTORS (64), GRUB_DISK_KiB_TO_SECTORS (4)}, /* 4 KiB superblock. */ -+ {GRUB_DISK_KiB_TO_SECTORS (68), 1}, /* Overflow guard. */ -+ {GRUB_DISK_KiB_TO_SECTORS (1024) - 1, 1}, /* Overflow guard. */ -+ {0, 0} /* Array terminator. */ -+ } -+}; -+ - static grub_err_t - grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), - unsigned int *nsectors, -@@ -2483,25 +2510,62 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), - grub_embed_type_t embed_type, - grub_disk_addr_t **sectors) - { -- unsigned i; -+ unsigned int i, j, n = 0; -+ const struct embed_region *u; -+ grub_disk_addr_t *map; - - if (embed_type != GRUB_EMBED_PCBIOS) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - "BtrFS currently supports only PC-BIOS embedding"); - -- if (64 * 2 - 1 < *nsectors) -- return grub_error (GRUB_ERR_OUT_OF_RANGE, -- N_("your core.img is unusually large. " -- "It won't fit in the embedding area")); -- -- *nsectors = 64 * 2 - 1; -- if (*nsectors > max_nsectors) -- *nsectors = max_nsectors; -- *sectors = grub_calloc (*nsectors, sizeof (**sectors)); -- if (!*sectors) -+ map = grub_calloc (btrfs_head.available.secs, sizeof (*map)); -+ if (map == NULL) - return grub_errno; -- for (i = 0; i < *nsectors; i++) -- (*sectors)[i] = i + 1; -+ -+ /* -+ * Populating the map array so that it can be used to index if a disk -+ * address is available to embed: -+ * - 0: available, -+ * - 1: unavailable. -+ */ -+ for (u = btrfs_head.used; u->secs; ++u) -+ { -+ unsigned int end = u->start + u->secs; -+ -+ if (end > btrfs_head.available.secs) -+ end = btrfs_head.available.secs; -+ for (i = u->start; i < end; ++i) -+ map[i] = 1; -+ } -+ -+ /* Adding up n until it matches total size of available embedding area. */ -+ for (i = 0; i < btrfs_head.available.secs; ++i) -+ if (map[i] == 0) -+ n++; -+ -+ if (n < *nsectors) -+ { -+ grub_free (map); -+ return grub_error (GRUB_ERR_OUT_OF_RANGE, -+ N_("your core.img is unusually large. " -+ "It won't fit in the embedding area")); -+ } -+ -+ if (n > max_nsectors) -+ n = max_nsectors; -+ -+ /* -+ * Populating the array so that it can used to index disk block address for -+ * an image file's offset to be embedded on disk (the unit is in sectors): -+ * - i: The disk block address relative to btrfs_head.available.start, -+ * - j: The offset in image file. -+ */ -+ for (i = 0, j = 0; i < btrfs_head.available.secs && j < n; ++i) -+ if (map[i] == 0) -+ map[j++] = btrfs_head.available.start + i; -+ -+ *nsectors = n; -+ *sectors = map; - - return GRUB_ERR_NONE; - } -diff --git a/include/grub/disk.h b/include/grub/disk.h -index f95aca929a6..06210a70492 100644 ---- a/include/grub/disk.h -+++ b/include/grub/disk.h -@@ -182,6 +182,8 @@ typedef struct grub_disk_memberlist *grub_disk_memberlist_t; - /* Return value of grub_disk_native_sectors() in case disk size is unknown. */ - #define GRUB_DISK_SIZE_UNKNOWN 0xffffffffffffffffULL - -+#define GRUB_DISK_KiB_TO_SECTORS(x) ((x) << (10 - GRUB_DISK_SECTOR_BITS)) -+ - /* Convert sector number from one sector size to another. */ - static inline grub_disk_addr_t - grub_convert_sector (grub_disk_addr_t sector, diff --git a/0200-Add-Fedora-location-of-DejaVu-SANS-font.patch b/0200-Add-Fedora-location-of-DejaVu-SANS-font.patch deleted file mode 100644 index eb76649eaececd027e870ceae2aea56c635669dd..0000000000000000000000000000000000000000 --- a/0200-Add-Fedora-location-of-DejaVu-SANS-font.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: fluteze -Date: Sat, 27 Nov 2021 10:54:44 -0600 -Subject: [PATCH] Add Fedora location of DejaVu SANS font - -In Fedora 35, and possibly earlier, grub would fail to configure with a -complaint about DejaVu being "not found" even though it was installed. -The DejaVu sans font search path is updated to reflect the -distribution's current install path. - -Signed-off-by: Erik Edwards -[rharwood@redhat.com: slight commit message edits] -Signed-off-by: Robbie Harwood ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index 3c808a72230..3527f069ab2 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1812,7 +1812,7 @@ fi - - if test x"$starfield_excuse" = x; then - for ext in pcf pcf.gz bdf bdf.gz ttf ttf.gz; do -- for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/truetype/ttf-dejavu /usr/share/fonts/dejavu /usr/share/fonts/truetype; do -+ for dir in . /usr/src /usr/share/fonts/X11/misc /usr/share/fonts/truetype/ttf-dejavu /usr/share/fonts/dejavu /usr/share/fonts/truetype /usr/share/fonts/dejavu-sans-fonts; do - if test -f "$dir/DejaVuSans.$ext"; then - DJVU_FONT_SOURCE="$dir/DejaVuSans.$ext" - break 2 diff --git a/0201-normal-menu-Don-t-show-Booting-s-msg-when-auto-booti.patch b/0201-normal-menu-Don-t-show-Booting-s-msg-when-auto-booti.patch deleted file mode 100644 index 531c4f5d1e43e98cb36a8ef1c4fd15c58b7c01d6..0000000000000000000000000000000000000000 --- a/0201-normal-menu-Don-t-show-Booting-s-msg-when-auto-booti.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 28 Jan 2022 11:30:32 +0100 -Subject: [PATCH] normal/menu: Don't show "Booting `%s'" msg when auto-booting - with TIMEOUT_STYLE_HIDDEN - -When the user has asked the menu code to be hidden/quiet and the current -entry is being autobooted because the timeout has expired don't show -the "Booting `%s'" msg. - -This is necessary to let flicker-free boots really be flicker free, -otherwise the "Booting `%s'" msg will kick the EFI fb into text mode -and show the msg, breaking the flicker-free experience. - -Signed-off-by: Hans de Goede ---- - grub-core/normal/menu.c | 24 ++++++++++++++++-------- - 1 file changed, 16 insertions(+), 8 deletions(-) - -diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c -index ec0c92bade0..c8516a5a080 100644 ---- a/grub-core/normal/menu.c -+++ b/grub-core/normal/menu.c -@@ -606,13 +606,15 @@ print_countdown (struct grub_term_coordinate *pos, int n) - entry to be executed is a result of an automatic default selection because - of the timeout. */ - static int --run_menu (grub_menu_t menu, int nested, int *auto_boot) -+run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot) - { - grub_uint64_t saved_time; - int default_entry, current_entry; - int timeout; - enum timeout_style timeout_style; - -+ *notify_boot = 1; -+ - default_entry = get_entry_number (menu, "default"); - - /* If DEFAULT_ENTRY is not within the menu entries, fall back to -@@ -687,6 +689,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) - if (timeout == 0) - { - *auto_boot = 1; -+ *notify_boot = timeout_style != TIMEOUT_STYLE_HIDDEN; - return default_entry; - } - -@@ -840,12 +843,16 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot) - - /* Callback invoked immediately before a menu entry is executed. */ - static void --notify_booting (grub_menu_entry_t entry, -- void *userdata __attribute__((unused))) -+notify_booting (grub_menu_entry_t entry, void *userdata) - { -- grub_printf (" "); -- grub_printf_ (N_("Booting `%s'"), entry->title); -- grub_printf ("\n\n"); -+ int *notify_boot = userdata; -+ -+ if (*notify_boot) -+ { -+ grub_printf (" "); -+ grub_printf_ (N_("Booting `%s'"), entry->title); -+ grub_printf ("\n\n"); -+ } - } - - /* Callback invoked when a default menu entry executed because of a timeout -@@ -893,8 +900,9 @@ show_menu (grub_menu_t menu, int nested, int autobooted) - int boot_entry; - grub_menu_entry_t e; - int auto_boot; -+ int notify_boot; - -- boot_entry = run_menu (menu, nested, &auto_boot); -+ boot_entry = run_menu (menu, nested, &auto_boot, ¬ify_boot); - if (boot_entry < 0) - break; - -@@ -906,7 +914,7 @@ show_menu (grub_menu_t menu, int nested, int autobooted) - - if (auto_boot) - grub_menu_execute_with_fallback (menu, e, autobooted, -- &execution_callback, 0); -+ &execution_callback, ¬ify_boot); - else - grub_menu_execute_entry (e, 0); - if (autobooted) diff --git a/0202-EFI-suppress-the-Welcome-to-GRUB-message-in-EFI-buil.patch b/0202-EFI-suppress-the-Welcome-to-GRUB-message-in-EFI-buil.patch deleted file mode 100644 index 8f34b74d13a699ce8d42f2681a6d1830e9d9b204..0000000000000000000000000000000000000000 --- a/0202-EFI-suppress-the-Welcome-to-GRUB-message-in-EFI-buil.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 28 Jan 2022 11:30:33 +0100 -Subject: [PATCH] EFI: suppress the "Welcome to GRUB!" message in EFI builds - -Grub EFI builds are now often used in combination with flicker-free -boot, but this breaks with upstream grub because the "Welcome to GRUB!" -message will kick the EFI fb into text mode and show the msg, -breaking the flicker-free experience. - -EFI systems are so fast, that when the menu or the countdown are enabled -the message will be immediately overwritten, so in these cases not -printing the message does not matter. - -And in case when the timeout_style is set to TIMEOUT_STYLE_HIDDEN, -the user has asked grub to be quiet (for example to allow flickfree -boot) annd thus the message should not be printed. - -Signed-off-by: Hans de Goede ---- - grub-core/kern/main.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c -index 3fc34014726..993b8a8598e 100644 ---- a/grub-core/kern/main.c -+++ b/grub-core/kern/main.c -@@ -317,10 +317,13 @@ grub_main (void) - - grub_boot_time ("After machine init."); - -+ /* This breaks flicker-free boot on EFI systems, so disable it there. */ -+#ifndef GRUB_MACHINE_EFI - /* Hello. */ - grub_setcolorstate (GRUB_TERM_COLOR_HIGHLIGHT); - grub_printf ("Welcome to GRUB!\n\n"); - grub_setcolorstate (GRUB_TERM_COLOR_STANDARD); -+#endif - - /* Init verifiers API. */ - grub_verifiers_init (); diff --git a/0203-EFI-console-Do-not-set-colorstate-until-the-first-te.patch b/0203-EFI-console-Do-not-set-colorstate-until-the-first-te.patch deleted file mode 100644 index cb430c02d97398321fdffaa11e03981d19ca432b..0000000000000000000000000000000000000000 --- a/0203-EFI-console-Do-not-set-colorstate-until-the-first-te.patch +++ /dev/null @@ -1,51 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 28 Jan 2022 12:43:48 +0100 -Subject: [PATCH] EFI: console: Do not set colorstate until the first text - output - -GRUB_MOD_INIT(normal) does an unconditional: - -grub_env_set ("color_normal", "light-gray/black"); - -which triggers a grub_term_setcolorstate() call. The original version -of the "efi/console: Do not set text-mode until we actually need it" patch: -https://lists.gnu.org/archive/html/grub-devel/2018-03/msg00125.html - -Protected against this by caching the requested state in -grub_console_setcolorstate () and then only applying it when the first -text output actually happens. During refactoring to move the -grub_console_setcolorstate () up higher in the grub-core/term/efi/console.c -file the code to cache the color-state + bail early was accidentally -dropped. - -Restore the cache the color-state + bail early behavior from the original. - -Cc: Javier Martinez Canillas -Fixes: 2d7c3abd871f ("efi/console: Do not set text-mode until we actually need it") -Signed-off-by: Hans de Goede ---- - grub-core/term/efi/console.c | 10 ++++++++++ - 1 file changed, 10 insertions(+) - -diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c -index 2f1ae85ba7d..c44b2ac318c 100644 ---- a/grub-core/term/efi/console.c -+++ b/grub-core/term/efi/console.c -@@ -82,6 +82,16 @@ grub_console_setcolorstate (struct grub_term_output *term - { - grub_efi_simple_text_output_interface_t *o; - -+ if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE) -+ { -+ /* -+ * Cache colorstate changes before the first text-output, this avoids -+ * "color_normal" environment writes causing a switch to textmode. -+ */ -+ text_colorstate = state; -+ return; -+ } -+ - if (grub_efi_is_finished) - return; - diff --git a/0204-EFI-console-Do-not-set-cursor-until-the-first-text-o.patch b/0204-EFI-console-Do-not-set-cursor-until-the-first-text-o.patch deleted file mode 100644 index e33d1f3727c7458ed0fea252339c3bde39f9792e..0000000000000000000000000000000000000000 --- a/0204-EFI-console-Do-not-set-cursor-until-the-first-text-o.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Fri, 28 Jan 2022 12:43:49 +0100 -Subject: [PATCH] EFI: console: Do not set cursor until the first text output - -To allow flickerfree boot the EFI console code does not call -grub_efi_set_text_mode (1) until some text is actually output. - -Depending on if the output text is because of an error loading -e.g. the .cfg file; or because of showing the menu the cursor needs -to be on or off when the first text is shown. - -So far the cursor was hardcoded to being on, but this is causing -drawing artifacts + slow drawing of the menu as reported here: -https://bugzilla.redhat.com/show_bug.cgi?id=1946969 - -Handle the cursorstate in the same way as the colorstate to fix this, -when no text has been output yet, just cache the cursorstate and -then use the last set value when the first text is output. - -Fixes: 2d7c3abd871f ("efi/console: Do not set text-mode until we actually need it") -Signed-off-by: Hans de Goede ---- - grub-core/term/efi/console.c | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/grub-core/term/efi/console.c b/grub-core/term/efi/console.c -index c44b2ac318c..a3622e4fe5f 100644 ---- a/grub-core/term/efi/console.c -+++ b/grub-core/term/efi/console.c -@@ -31,7 +31,15 @@ typedef enum { - } - grub_text_mode; - -+typedef enum { -+ GRUB_CURSOR_MODE_UNDEFINED = -1, -+ GRUB_CURSOR_MODE_OFF = 0, -+ GRUB_CURSUR_MODE_ON -+} -+grub_cursor_mode; -+ - static grub_text_mode text_mode = GRUB_TEXT_MODE_UNDEFINED; -+static grub_cursor_mode cursor_mode = GRUB_CURSOR_MODE_UNDEFINED; - static grub_term_color_state text_colorstate = GRUB_TERM_COLOR_UNDEFINED; - - static grub_uint32_t -@@ -119,8 +127,12 @@ grub_console_setcursor (struct grub_term_output *term __attribute__ ((unused)), - { - grub_efi_simple_text_output_interface_t *o; - -- if (grub_efi_is_finished) -- return; -+ if (grub_efi_is_finished || text_mode != GRUB_TEXT_MODE_AVAILABLE) -+ { -+ /* Cache cursor changes before the first text-output */ -+ cursor_mode = on; -+ return; -+ } - - o = grub_efi_system_table->con_out; - efi_call_2 (o->enable_cursor, o, on); -@@ -143,7 +155,8 @@ grub_prepare_for_text_output (struct grub_term_output *term) - return GRUB_ERR_BAD_DEVICE; - } - -- grub_console_setcursor (term, 1); -+ if (cursor_mode != GRUB_CURSOR_MODE_UNDEFINED) -+ grub_console_setcursor (term, cursor_mode); - if (text_colorstate != GRUB_TERM_COLOR_UNDEFINED) - grub_console_setcolorstate (term, text_colorstate); - text_mode = GRUB_TEXT_MODE_AVAILABLE; diff --git a/0205-Use-visual-indentation-in-config.h.in.patch b/0205-Use-visual-indentation-in-config.h.in.patch deleted file mode 100644 index 1acc33364e8fc8d26a037fe90c7650c876811990..0000000000000000000000000000000000000000 --- a/0205-Use-visual-indentation-in-config.h.in.patch +++ /dev/null @@ -1,93 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Wed, 15 Dec 2021 15:46:13 -0500 -Subject: [PATCH] Use visual indentation in config.h.in - -Signed-off-by: Robbie Harwood -(cherry picked from commit de8051f34de0aa55c921a510974e5bb27e39c17b) -[rharwood: GRUB_RPM_CONFIG presence] ---- - config.h.in | 58 +++++++++++++++++++++++++++++----------------------------- - 1 file changed, 29 insertions(+), 29 deletions(-) - -diff --git a/config.h.in b/config.h.in -index c80e3e0aba3..f2ed0066ec0 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -23,47 +23,47 @@ - #define MINILZO_CFG_SKIP_LZO1X_DECOMPRESS 1 - - #if defined (GRUB_BUILD) --#undef ENABLE_NLS --#define BUILD_SIZEOF_LONG @BUILD_SIZEOF_LONG@ --#define BUILD_SIZEOF_VOID_P @BUILD_SIZEOF_VOID_P@ --#if defined __APPLE__ --# if defined __BIG_ENDIAN__ --# define BUILD_WORDS_BIGENDIAN 1 --# else --# define BUILD_WORDS_BIGENDIAN 0 --# endif --#else --#define BUILD_WORDS_BIGENDIAN @BUILD_WORDS_BIGENDIAN@ --#endif -+# undef ENABLE_NLS -+# define BUILD_SIZEOF_LONG @BUILD_SIZEOF_LONG@ -+# define BUILD_SIZEOF_VOID_P @BUILD_SIZEOF_VOID_P@ -+# if defined __APPLE__ -+# if defined __BIG_ENDIAN__ -+# define BUILD_WORDS_BIGENDIAN 1 -+# else -+# define BUILD_WORDS_BIGENDIAN 0 -+# endif -+# else /* !defined __APPLE__ */ -+# define BUILD_WORDS_BIGENDIAN @BUILD_WORDS_BIGENDIAN@ -+# endif /* !defined __APPLE__ */ - #elif defined (GRUB_UTIL) || !defined (GRUB_MACHINE) --#include --#else --#define HAVE_FONT_SOURCE @HAVE_FONT_SOURCE@ -+# include -+#else /* !defined GRUB_UTIL && defined GRUB_MACHINE */ -+# define HAVE_FONT_SOURCE @HAVE_FONT_SOURCE@ - /* Define if C symbols get an underscore after compilation. */ --#define HAVE_ASM_USCORE @HAVE_ASM_USCORE@ -+# define HAVE_ASM_USCORE @HAVE_ASM_USCORE@ - /* Define it to one of __bss_start, edata and _edata. */ --#define BSS_START_SYMBOL @BSS_START_SYMBOL@ -+# define BSS_START_SYMBOL @BSS_START_SYMBOL@ - /* Define it to either end or _end. */ --#define END_SYMBOL @END_SYMBOL@ -+# define END_SYMBOL @END_SYMBOL@ - /* Name of package. */ --#define PACKAGE "@PACKAGE@" -+# define PACKAGE "@PACKAGE@" - /* Version number of package. */ --#define VERSION "@VERSION@" -+# define VERSION "@VERSION@" - /* Define to the full name and version of this package. */ --#define PACKAGE_STRING "@PACKAGE_STRING@" -+# define PACKAGE_STRING "@PACKAGE_STRING@" - /* Define to the version of this package. */ --#define PACKAGE_VERSION "@PACKAGE_VERSION@" -+# define PACKAGE_VERSION "@PACKAGE_VERSION@" - /* Define to the full name of this package. */ --#define PACKAGE_NAME "@PACKAGE_NAME@" -+# define PACKAGE_NAME "@PACKAGE_NAME@" - /* Define to the address where bug reports for this package should be sent. */ --#define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" -+# define PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" - --#define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@" --#define GRUB_PLATFORM "@GRUB_PLATFORM@" --#define GRUB_RPM_VERSION "@GRUB_RPM_VERSION@" -+# define GRUB_TARGET_CPU "@GRUB_TARGET_CPU@" -+# define GRUB_PLATFORM "@GRUB_PLATFORM@" -+# define GRUB_RPM_VERSION "@GRUB_RPM_VERSION@" - --#define RE_ENABLE_I18N 1 -+# define RE_ENABLE_I18N 1 - --#define _GNU_SOURCE 1 -+# define _GNU_SOURCE 1 - - #endif diff --git a/0206-Where-present-ensure-config-util.h-precedes-config.h.patch b/0206-Where-present-ensure-config-util.h-precedes-config.h.patch deleted file mode 100644 index 351d50f1177bb171e5efc792eaffa089e6bd2362..0000000000000000000000000000000000000000 --- a/0206-Where-present-ensure-config-util.h-precedes-config.h.patch +++ /dev/null @@ -1,275 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Tue, 22 Feb 2022 16:57:54 -0500 -Subject: [PATCH] Where present, ensure config-util.h precedes config.h - -gnulib defines go in config-util.h, and we need to know whether to -provide duplicates in config.h or not. - -Signed-off-by: Robbie Harwood -(cherry picked from commit 46e82b28e1a75703d0424c7e13d009171310c6cd) -[rharwood: gensymlist isn't part of tarballs] ---- - grub-core/disk/host.c | 2 +- - grub-core/kern/emu/argp_common.c | 2 +- - grub-core/kern/emu/main.c | 2 +- - grub-core/osdep/aros/config.c | 2 +- - grub-core/osdep/basic/emunet.c | 2 +- - grub-core/osdep/basic/init.c | 2 +- - grub-core/osdep/haiku/getroot.c | 2 +- - grub-core/osdep/linux/emunet.c | 2 +- - grub-core/osdep/unix/config.c | 2 +- - grub-core/osdep/unix/cputime.c | 2 +- - grub-core/osdep/unix/dl.c | 2 +- - grub-core/osdep/unix/emuconsole.c | 2 +- - grub-core/osdep/unix/getroot.c | 2 +- - grub-core/osdep/windows/config.c | 2 +- - grub-core/osdep/windows/cputime.c | 2 +- - grub-core/osdep/windows/dl.c | 2 +- - grub-core/osdep/windows/emuconsole.c | 2 +- - grub-core/osdep/windows/init.c | 2 +- - 18 files changed, 18 insertions(+), 18 deletions(-) - -diff --git a/grub-core/disk/host.c b/grub-core/disk/host.c -index c151d225df7..f34529f86ae 100644 ---- a/grub-core/disk/host.c -+++ b/grub-core/disk/host.c -@@ -20,8 +20,8 @@ - /* When using the disk, make a reference to this module. Otherwise - the user will end up with a useless module :-). */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/kern/emu/argp_common.c b/grub-core/kern/emu/argp_common.c -index 16688587037..8cb4608c3df 100644 ---- a/grub-core/kern/emu/argp_common.c -+++ b/grub-core/kern/emu/argp_common.c -@@ -17,8 +17,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #pragma GCC diagnostic ignored "-Wmissing-prototypes" - #pragma GCC diagnostic ignored "-Wmissing-declarations" -diff --git a/grub-core/kern/emu/main.c b/grub-core/kern/emu/main.c -index 846fe9715ec..3e7929cc4af 100644 ---- a/grub-core/kern/emu/main.c -+++ b/grub-core/kern/emu/main.c -@@ -16,8 +16,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/aros/config.c b/grub-core/osdep/aros/config.c -index c82d0ea8e76..55f5728efca 100644 ---- a/grub-core/osdep/aros/config.c -+++ b/grub-core/osdep/aros/config.c -@@ -16,8 +16,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/basic/emunet.c b/grub-core/osdep/basic/emunet.c -index 6362e5cfbb3..dbfd316d613 100644 ---- a/grub-core/osdep/basic/emunet.c -+++ b/grub-core/osdep/basic/emunet.c -@@ -16,8 +16,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/basic/init.c b/grub-core/osdep/basic/init.c -index c54c710dbcb..b104c7e162b 100644 ---- a/grub-core/osdep/basic/init.c -+++ b/grub-core/osdep/basic/init.c -@@ -16,8 +16,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/haiku/getroot.c b/grub-core/osdep/haiku/getroot.c -index 4e123c0903a..927a1ebc941 100644 ---- a/grub-core/osdep/haiku/getroot.c -+++ b/grub-core/osdep/haiku/getroot.c -@@ -1,5 +1,5 @@ --#include - #include -+#include - #include - #include - #include -diff --git a/grub-core/osdep/linux/emunet.c b/grub-core/osdep/linux/emunet.c -index 19b188f09ee..d5a6417355f 100644 ---- a/grub-core/osdep/linux/emunet.c -+++ b/grub-core/osdep/linux/emunet.c -@@ -16,8 +16,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c -index 46a881530c0..0ce0e309ac0 100644 ---- a/grub-core/osdep/unix/config.c -+++ b/grub-core/osdep/unix/config.c -@@ -16,8 +16,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/unix/cputime.c b/grub-core/osdep/unix/cputime.c -index cff359a3b94..fb6ff55a1a7 100644 ---- a/grub-core/osdep/unix/cputime.c -+++ b/grub-core/osdep/unix/cputime.c -@@ -1,5 +1,5 @@ --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/unix/dl.c b/grub-core/osdep/unix/dl.c -index 562b101a280..99b189bc1c9 100644 ---- a/grub-core/osdep/unix/dl.c -+++ b/grub-core/osdep/unix/dl.c -@@ -16,8 +16,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/unix/emuconsole.c b/grub-core/osdep/unix/emuconsole.c -index 7308798efe9..cac159424d8 100644 ---- a/grub-core/osdep/unix/emuconsole.c -+++ b/grub-core/osdep/unix/emuconsole.c -@@ -17,8 +17,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/unix/getroot.c b/grub-core/osdep/unix/getroot.c -index 46d7116c6e6..4f436284ce0 100644 ---- a/grub-core/osdep/unix/getroot.c -+++ b/grub-core/osdep/unix/getroot.c -@@ -16,8 +16,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/windows/config.c b/grub-core/osdep/windows/config.c -index 928ab1a49be..2bb8a2fd88e 100644 ---- a/grub-core/osdep/windows/config.c -+++ b/grub-core/osdep/windows/config.c -@@ -16,8 +16,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/windows/cputime.c b/grub-core/osdep/windows/cputime.c -index 3568aa2d359..5d06d79dd53 100644 ---- a/grub-core/osdep/windows/cputime.c -+++ b/grub-core/osdep/windows/cputime.c -@@ -1,5 +1,5 @@ --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/windows/dl.c b/grub-core/osdep/windows/dl.c -index eec6a24ad7f..8eab7057e4d 100644 ---- a/grub-core/osdep/windows/dl.c -+++ b/grub-core/osdep/windows/dl.c -@@ -16,8 +16,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/windows/emuconsole.c b/grub-core/osdep/windows/emuconsole.c -index 4fb3693cc01..17a44de4690 100644 ---- a/grub-core/osdep/windows/emuconsole.c -+++ b/grub-core/osdep/windows/emuconsole.c -@@ -16,8 +16,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - - #include - #include -diff --git a/grub-core/osdep/windows/init.c b/grub-core/osdep/windows/init.c -index 6297de6326a..51a9647dde4 100644 ---- a/grub-core/osdep/windows/init.c -+++ b/grub-core/osdep/windows/init.c -@@ -16,8 +16,8 @@ - * along with GRUB. If not, see . - */ - --#include - #include -+#include - #include - #include - #include diff --git a/0207-Drop-gnulib-fix-base64.patch.patch b/0207-Drop-gnulib-fix-base64.patch.patch deleted file mode 100644 index 1d26c57f72532450c7242e80c01ed70e209271d7..0000000000000000000000000000000000000000 --- a/0207-Drop-gnulib-fix-base64.patch.patch +++ /dev/null @@ -1,140 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Thu, 28 Oct 2021 15:07:50 -0400 -Subject: [PATCH] Drop gnulib fix-base64.patch - -Originally added in 9fbdec2f6b4fa8b549daa4d49134d1fe89d95ef9 and -subsequently modified in 552c9fd08122a3036c724ce96dfe68aa2f75705f, -fix-base64.patch handled two problems we have using gnulib, which are -exerciesd by the base64 module but not directly caused by it. - -First, grub2 defines its own bool type, while gnulib expects the -equivalent of stdbool.h to be present. Rather than patching gnulib, -instead use gnulib's stdbool module to provide a bool type if needed. -(Suggested by Simon Josefsson.) - -Second, our config.h doesn't always inherit config-util.h, which is -where gnulib-related options like _GL_ATTRIBUTE_CONST end up. -fix-base64.h worked around this by defining the attribute away, but this -workaround is better placed in config.h itself, not a gnulib patch. - -Signed-off-by: Robbie Harwood -(cherry picked from commit 54fd1c3301dd15f6b6212c12887265e8a6cbc076) ---- - grub-core/lib/posix_wrap/sys/types.h | 7 +++---- - grub-core/lib/xzembed/xz.h | 5 +---- - bootstrap.conf | 3 ++- - conf/Makefile.extra-dist | 1 - - config.h.in | 4 ++++ - grub-core/lib/gnulib-patches/fix-base64.patch | 21 --------------------- - 6 files changed, 10 insertions(+), 31 deletions(-) - delete mode 100644 grub-core/lib/gnulib-patches/fix-base64.patch - -diff --git a/grub-core/lib/posix_wrap/sys/types.h b/grub-core/lib/posix_wrap/sys/types.h -index f63412c8da0..2f3e865495a 100644 ---- a/grub-core/lib/posix_wrap/sys/types.h -+++ b/grub-core/lib/posix_wrap/sys/types.h -@@ -23,11 +23,10 @@ - - #include - -+/* Provided by gnulib if not present. */ -+#include -+ - typedef grub_ssize_t ssize_t; --#ifndef GRUB_POSIX_BOOL_DEFINED --typedef enum { false = 0, true = 1 } bool; --#define GRUB_POSIX_BOOL_DEFINED 1 --#endif - - typedef grub_uint8_t uint8_t; - typedef grub_uint16_t uint16_t; -diff --git a/grub-core/lib/xzembed/xz.h b/grub-core/lib/xzembed/xz.h -index f7b32d80032..d1417039aa4 100644 ---- a/grub-core/lib/xzembed/xz.h -+++ b/grub-core/lib/xzembed/xz.h -@@ -29,10 +29,7 @@ - #include - #include - #include -- --#ifndef GRUB_POSIX_BOOL_DEFINED --typedef enum { false = 0, true = 1 } bool; --#endif -+#include - - /** - * enum xz_ret - Return codes -diff --git a/bootstrap.conf b/bootstrap.conf -index 52d4af44bec..645e3a459ce 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -35,6 +35,7 @@ gnulib_modules=" - realloc-gnu - regex - save-cwd -+ stdbool - " - - gnulib_tool_option_extras="\ -@@ -79,7 +80,7 @@ cp -a INSTALL INSTALL.grub - - bootstrap_post_import_hook () { - set -e -- for patchname in fix-base64 fix-null-deref fix-null-state-deref fix-regcomp-uninit-token \ -+ for patchname in fix-null-deref fix-null-state-deref fix-regcomp-uninit-token \ - fix-regexec-null-deref fix-uninit-structure fix-unused-value fix-width no-abort; do - patch -d grub-core/lib/gnulib -p2 \ - < "grub-core/lib/gnulib-patches/$patchname.patch" -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index ea58362b555..ca6a50deca9 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -30,7 +30,6 @@ EXTRA_DIST += grub-core/gensymlist.sh - EXTRA_DIST += grub-core/genemuinit.sh - EXTRA_DIST += grub-core/genemuinitheader.sh - --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-base64.patch - EXTRA_DIST += grub-core/lib/gnulib-patches/fix-null-deref.patch - EXTRA_DIST += grub-core/lib/gnulib-patches/fix-null-state-deref.patch - EXTRA_DIST += grub-core/lib/gnulib-patches/fix-regcomp-uninit-token.patch -diff --git a/config.h.in b/config.h.in -index f2ed0066ec0..9c7b4afaaad 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -66,4 +66,8 @@ - - # define _GNU_SOURCE 1 - -+# ifndef _GL_INLINE_HEADER_BEGIN -+# define _GL_ATTRIBUTE_CONST __attribute__ ((const)) -+# endif /* !_GL_INLINE_HEADER_BEGIN */ -+ - #endif -diff --git a/grub-core/lib/gnulib-patches/fix-base64.patch b/grub-core/lib/gnulib-patches/fix-base64.patch -deleted file mode 100644 -index 985db127971..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-base64.patch -+++ /dev/null -@@ -1,21 +0,0 @@ --diff --git a/lib/base64.h b/lib/base64.h --index 9cd0183b8..185a2afa1 100644 ----- a/lib/base64.h --+++ b/lib/base64.h --@@ -21,8 +21,14 @@ -- /* Get size_t. */ -- # include -- ---/* Get bool. */ ---# include --+#ifndef GRUB_POSIX_BOOL_DEFINED --+typedef enum { false = 0, true = 1 } bool; --+#define GRUB_POSIX_BOOL_DEFINED 1 --+#endif --+ --+#ifndef _GL_ATTRIBUTE_CONST --+# define _GL_ATTRIBUTE_CONST /* empty */ --+#endif -- -- # ifdef __cplusplus -- extern "C" { diff --git a/0208-Drop-gnulib-no-abort.patch.patch b/0208-Drop-gnulib-no-abort.patch.patch deleted file mode 100644 index 79bcb03826532f5dd178e203446ac55170503b59..0000000000000000000000000000000000000000 --- a/0208-Drop-gnulib-no-abort.patch.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Wed, 5 Jan 2022 16:42:11 -0500 -Subject: [PATCH] Drop gnulib no-abort.patch - -Originally added in db7337a3d353a817ffe9eb4a3702120527100be9, this -patched out all relevant invocations of abort() in gnulib. While it was -not documented why at the time, testing suggests that there's no abort() -implementation available for gnulib to use. - -gnulib's position is that the use of abort() is correct here, since it -happens when input violates a "shall" from POSIX. Additionally, the -code in question is probably not reachable. Since abort() is more -friendly to user-space, they prefer to make no change, so we can just -carry a define instead. (Suggested by Paul Eggert.) - -Signed-off-by: Robbie Harwood -(cherry picked from commit 5137c8eb3ec11c3217acea1a93a3f88f3fa4cbca) ---- - bootstrap.conf | 2 +- - conf/Makefile.extra-dist | 1 - - config.h.in | 3 +++ - grub-core/lib/gnulib-patches/no-abort.patch | 26 -------------------------- - 4 files changed, 4 insertions(+), 28 deletions(-) - delete mode 100644 grub-core/lib/gnulib-patches/no-abort.patch - -diff --git a/bootstrap.conf b/bootstrap.conf -index 645e3a459ce..71ce943c7d4 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -81,7 +81,7 @@ cp -a INSTALL INSTALL.grub - bootstrap_post_import_hook () { - set -e - for patchname in fix-null-deref fix-null-state-deref fix-regcomp-uninit-token \ -- fix-regexec-null-deref fix-uninit-structure fix-unused-value fix-width no-abort; do -+ fix-regexec-null-deref fix-uninit-structure fix-unused-value fix-width; do - patch -d grub-core/lib/gnulib -p2 \ - < "grub-core/lib/gnulib-patches/$patchname.patch" - done -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index ca6a50deca9..16248ccf032 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -37,7 +37,6 @@ EXTRA_DIST += grub-core/lib/gnulib-patches/fix-regexec-null-deref.patch - EXTRA_DIST += grub-core/lib/gnulib-patches/fix-uninit-structure.patch - EXTRA_DIST += grub-core/lib/gnulib-patches/fix-unused-value.patch - EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/no-abort.patch - - EXTRA_DIST += grub-core/lib/libgcrypt - EXTRA_DIST += grub-core/lib/libgcrypt-grub/mpi/generic -diff --git a/config.h.in b/config.h.in -index 9c7b4afaaad..c3134309c63 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -68,6 +68,9 @@ - - # ifndef _GL_INLINE_HEADER_BEGIN - # define _GL_ATTRIBUTE_CONST __attribute__ ((const)) -+ -+/* We don't have an abort() for gnulib to call in regexp. */ -+# define abort __builtin_unreachable - # endif /* !_GL_INLINE_HEADER_BEGIN */ - - #endif -diff --git a/grub-core/lib/gnulib-patches/no-abort.patch b/grub-core/lib/gnulib-patches/no-abort.patch -deleted file mode 100644 -index e469c4762eb..00000000000 ---- a/grub-core/lib/gnulib-patches/no-abort.patch -+++ /dev/null -@@ -1,26 +0,0 @@ --diff --git a/lib/regcomp.c b/lib/regcomp.c --index cc85f35ac..de45ebb5c 100644 ----- a/lib/regcomp.c --+++ b/lib/regcomp.c --@@ -528,9 +528,9 @@ regerror (int errcode, const regex_t *__restrict preg, char *__restrict errbuf, -- to this routine. If we are given anything else, or if other regex -- code generates an invalid error code, then the program has a bug. -- Dump core so we can fix it. */ --- abort (); --- --- msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); --+ msg = gettext ("unknown regexp error"); --+ else --+ msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); -- -- msg_size = strlen (msg) + 1; /* Includes the null. */ -- --@@ -1136,7 +1136,7 @@ optimize_utf8 (re_dfa_t *dfa) -- } -- break; -- default: --- abort (); --+ break; -- } -- -- if (mb_chars || has_period) diff --git a/0209-Update-gnulib-version-and-drop-most-gnulib-patches.patch b/0209-Update-gnulib-version-and-drop-most-gnulib-patches.patch deleted file mode 100644 index 4b5a44c8c6d0d454d355069360879b3cc4e56191..0000000000000000000000000000000000000000 --- a/0209-Update-gnulib-version-and-drop-most-gnulib-patches.patch +++ /dev/null @@ -1,832 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Wed, 15 Dec 2021 15:07:50 -0500 -Subject: [PATCH] Update gnulib version and drop most gnulib patches - -In addition to the changes carried in our gnulib patches, several -Coverity and code hygiene fixes that were previously downstream are also -included in this 3-year gnulib increment. - -Unfortunately, fix-width.patch is retained. - -Bump minimum autoconf version from 2.63 to 2.64 and automake from 1.11 -to 1.14, as required by gnulib. - -Sync bootstrap script itself with gnulib. - -Update regexp module for new dynarray dependency. - -Fix various new warnings. - -Signed-off-by: Robbie Harwood -(cherry picked from commit deb18ff931c3133c2aa536a92bd92e50d6615303) -[rharwood: backport around requirements in INSTALL] ---- - configure.ac | 2 +- - grub-core/Makefile.core.def | 3 + - grub-core/disk/luks2.c | 4 +- - grub-core/lib/posix_wrap/limits.h | 6 +- - include/grub/compiler.h | 4 +- - include/grub/list.h | 2 +- - INSTALL | 2 +- - bootstrap | 291 ++++++++++++--------- - bootstrap.conf | 22 +- - conf/Makefile.extra-dist | 6 - - config.h.in | 68 +++++ - grub-core/lib/gnulib-patches/fix-null-deref.patch | 13 - - .../lib/gnulib-patches/fix-null-state-deref.patch | 12 - - .../gnulib-patches/fix-regcomp-uninit-token.patch | 15 -- - .../gnulib-patches/fix-regexec-null-deref.patch | 12 - - .../lib/gnulib-patches/fix-uninit-structure.patch | 11 - - .../lib/gnulib-patches/fix-unused-value.patch | 14 - - 17 files changed, 262 insertions(+), 225 deletions(-) - delete mode 100644 grub-core/lib/gnulib-patches/fix-null-deref.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-null-state-deref.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-regcomp-uninit-token.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-regexec-null-deref.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-uninit-structure.patch - delete mode 100644 grub-core/lib/gnulib-patches/fix-unused-value.patch - -diff --git a/configure.ac b/configure.ac -index 3527f069ab2..d04c94691ef 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -49,7 +49,7 @@ AC_CANONICAL_TARGET - program_prefix="${save_program_prefix}" - - AM_INIT_AUTOMAKE([1.11]) --AC_PREREQ(2.63) -+AC_PREREQ(2.64) - AC_CONFIG_SRCDIR([include/grub/dl.h]) - AC_CONFIG_HEADER([config-util.h]) - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 6b00eb55575..39233096f29 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -762,6 +762,9 @@ module = { - name = regexp; - common = commands/regexp.c; - common = commands/wildcard.c; -+ common = lib/gnulib/malloc/dynarray_finalize.c; -+ common = lib/gnulib/malloc/dynarray_emplace_enlarge.c; -+ common = lib/gnulib/malloc/dynarray_resize.c; - common = lib/gnulib/regex.c; - cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)'; - cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)'; -diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c -index 371a53b837d..c917a5f91e7 100644 ---- a/grub-core/disk/luks2.c -+++ b/grub-core/disk/luks2.c -@@ -389,7 +389,7 @@ luks2_verify_key (grub_luks2_digest_t *d, grub_uint8_t *candidate_key, - { - grub_uint8_t candidate_digest[GRUB_CRYPTODISK_MAX_KEYLEN]; - grub_uint8_t digest[GRUB_CRYPTODISK_MAX_KEYLEN], salt[GRUB_CRYPTODISK_MAX_KEYLEN]; -- grub_size_t saltlen = sizeof (salt), digestlen = sizeof (digest); -+ idx_t saltlen = sizeof (salt), digestlen = sizeof (digest); - const gcry_md_spec_t *hash; - gcry_err_code_t gcry_ret; - -@@ -428,7 +428,7 @@ luks2_decrypt_key (grub_uint8_t *out_key, - grub_uint8_t area_key[GRUB_CRYPTODISK_MAX_KEYLEN]; - grub_uint8_t salt[GRUB_CRYPTODISK_MAX_KEYLEN]; - grub_uint8_t *split_key = NULL; -- grub_size_t saltlen = sizeof (salt); -+ idx_t saltlen = sizeof (salt); - char cipher[32], *p; - const gcry_md_spec_t *hash; - gcry_err_code_t gcry_ret; -diff --git a/grub-core/lib/posix_wrap/limits.h b/grub-core/lib/posix_wrap/limits.h -index 591dbf3289d..4be7b408063 100644 ---- a/grub-core/lib/posix_wrap/limits.h -+++ b/grub-core/lib/posix_wrap/limits.h -@@ -25,7 +25,11 @@ - #define USHRT_MAX GRUB_USHRT_MAX - #define UINT_MAX GRUB_UINT_MAX - #define ULONG_MAX GRUB_ULONG_MAX --#define SIZE_MAX GRUB_SIZE_MAX -+ -+/* gnulib also defines this type */ -+#ifndef SIZE_MAX -+# define SIZE_MAX GRUB_SIZE_MAX -+#endif - - #define SCHAR_MIN GRUB_SCHAR_MIN - #define SCHAR_MAX GRUB_SCHAR_MAX -diff --git a/include/grub/compiler.h b/include/grub/compiler.h -index ebafec68957..441a9eca07c 100644 ---- a/include/grub/compiler.h -+++ b/include/grub/compiler.h -@@ -30,10 +30,10 @@ - - /* Does this compiler support compile-time error attributes? */ - #if GNUC_PREREQ(4,3) --# define ATTRIBUTE_ERROR(msg) \ -+# define GRUB_ATTRIBUTE_ERROR(msg) \ - __attribute__ ((__error__ (msg))) - #else --# define ATTRIBUTE_ERROR(msg) __attribute__ ((noreturn)) -+# define GRUB_ATTRIBUTE_ERROR(msg) __attribute__ ((noreturn)) - #endif - - #if GNUC_PREREQ(4,4) -diff --git a/include/grub/list.h b/include/grub/list.h -index b13acb96243..21f4b4b44a1 100644 ---- a/include/grub/list.h -+++ b/include/grub/list.h -@@ -40,7 +40,7 @@ void EXPORT_FUNC(grub_list_remove) (grub_list_t item); - - static inline void * - grub_bad_type_cast_real (int line, const char *file) -- ATTRIBUTE_ERROR ("bad type cast between incompatible grub types"); -+ GRUB_ATTRIBUTE_ERROR ("bad type cast between incompatible grub types"); - - static inline void * - grub_bad_type_cast_real (int line, const char *file) -diff --git a/INSTALL b/INSTALL -index 79a0af7d937..ee9f536f760 100644 ---- a/INSTALL -+++ b/INSTALL -@@ -42,7 +42,7 @@ If you use a development snapshot or want to hack on GRUB you may - need the following. - - * Python 2.6 or later --* Autoconf 2.63 or later -+* Autoconf 2.64 or later - * Automake 1.11 or later - - Prerequisites for make-check: -diff --git a/bootstrap b/bootstrap -index 5b08e7e2d42..dc2238f4adf 100755 ---- a/bootstrap -+++ b/bootstrap -@@ -1,10 +1,10 @@ - #! /bin/sh - # Print a version string. --scriptversion=2019-01-04.17; # UTC -+scriptversion=2022-01-26.05; # UTC - - # Bootstrap this package from checked-out sources. - --# Copyright (C) 2003-2019 Free Software Foundation, Inc. -+# Copyright (C) 2003-2022 Free Software Foundation, Inc. - - # This program is free software: you can redistribute it and/or modify - # it under the terms of the GNU General Public License as published by -@@ -47,7 +47,7 @@ PERL="${PERL-perl}" - - me=$0 - --default_gnulib_url=git://git.sv.gnu.org/gnulib -+default_gnulib_url=https://git.savannah.gnu.org/git/gnulib.git - - usage() { - cat </dev/null) -+if test -z "$package"; then -+ package=$(sed -n "$extract_package_name" configure.ac) \ -+ || die 'cannot find package name in configure.ac' -+fi - gnulib_name=lib$package - - build_aux=build-aux -@@ -290,6 +313,116 @@ find_tool () - eval "export $find_tool_envvar" - } - -+# Strip blank and comment lines to leave significant entries. -+gitignore_entries() { -+ sed '/^#/d; /^$/d' "$@" -+} -+ -+# If $STR is not already on a line by itself in $FILE, insert it at the start. -+# Entries are inserted at the start of the ignore list to ensure existing -+# entries starting with ! are not overridden. Such entries support -+# whitelisting exceptions after a more generic blacklist pattern. -+insert_if_absent() { -+ file=$1 -+ str=$2 -+ test -f $file || touch $file -+ test -r $file || die "Error: failed to read ignore file: $file" -+ duplicate_entries=$(gitignore_entries $file | sort | uniq -d) -+ if [ "$duplicate_entries" ] ; then -+ die "Error: Duplicate entries in $file: " $duplicate_entries -+ fi -+ linesold=$(gitignore_entries $file | wc -l) -+ linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l) -+ if [ $linesold != $linesnew ] ; then -+ { echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \ -+ || die "insert_if_absent $file $str: failed" -+ fi -+} -+ -+# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with -+# insert_if_absent. -+insert_vc_ignore() { -+ vc_ignore_file="$1" -+ pattern="$2" -+ case $vc_ignore_file in -+ *.gitignore) -+ # A .gitignore entry that does not start with '/' applies -+ # recursively to subdirectories, so prepend '/' to every -+ # .gitignore entry. -+ pattern=$(echo "$pattern" | sed s,^,/,);; -+ esac -+ insert_if_absent "$vc_ignore_file" "$pattern" -+} -+ -+symlink_to_dir() -+{ -+ src=$1/$2 -+ dst=${3-$2} -+ -+ test -f "$src" && { -+ -+ # If the destination directory doesn't exist, create it. -+ # This is required at least for "lib/uniwidth/cjk.h". -+ dst_dir=$(dirname "$dst") -+ if ! test -d "$dst_dir"; then -+ mkdir -p "$dst_dir" -+ -+ # If we've just created a directory like lib/uniwidth, -+ # tell version control system(s) it's ignorable. -+ # FIXME: for now, this does only one level -+ parent=$(dirname "$dst_dir") -+ for dot_ig in x $vc_ignore; do -+ test $dot_ig = x && continue -+ ig=$parent/$dot_ig -+ insert_vc_ignore $ig "${dst_dir##*/}" -+ done -+ fi -+ -+ if $copy; then -+ { -+ test ! -h "$dst" || { -+ echo "$me: rm -f $dst" && -+ rm -f "$dst" -+ } -+ } && -+ test -f "$dst" && -+ cmp -s "$src" "$dst" || { -+ echo "$me: cp -fp $src $dst" && -+ cp -fp "$src" "$dst" -+ } -+ else -+ # Leave any existing symlink alone, if it already points to the source, -+ # so that broken build tools that care about symlink times -+ # aren't confused into doing unnecessary builds. Conversely, if the -+ # existing symlink's timestamp is older than the source, make it afresh, -+ # so that broken tools aren't confused into skipping needed builds. See -+ # . -+ test -h "$dst" && -+ src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 && -+ dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 && -+ test "$src_i" = "$dst_i" && -+ both_ls=$(ls -dt "$src" "$dst") && -+ test "X$both_ls" = "X$dst$nl$src" || { -+ dot_dots= -+ case $src in -+ /*) ;; -+ *) -+ case /$dst/ in -+ *//* | */../* | */./* | /*/*/*/*/*/) -+ die "invalid symlink calculation: $src -> $dst";; -+ /*/*/*/*/) dot_dots=../../../;; -+ /*/*/*/) dot_dots=../../;; -+ /*/*/) dot_dots=../;; -+ esac;; -+ esac -+ -+ echo "$me: ln -fs $dot_dots$src $dst" && -+ ln -fs "$dot_dots$src" "$dst" -+ } -+ fi -+ } -+} -+ - # Override the default configuration, if necessary. - # Make sure that bootstrap.conf is sourced from the current directory - # if we were invoked as "sh bootstrap". -@@ -320,6 +453,12 @@ do - --help) - usage - exit;; -+ --version) -+ set -e -+ echo "bootstrap $scriptversion" -+ echo "$copyright" -+ exit 0 -+ ;; - --gnulib-srcdir=*) - GNULIB_SRCDIR=${option#--gnulib-srcdir=};; - --skip-po) -@@ -335,7 +474,7 @@ do - --no-git) - use_git=false;; - *) -- die "$option: unknown option";; -+ bootstrap_option_hook $option || die "$option: unknown option";; - esac - done - -@@ -346,47 +485,6 @@ if test -n "$checkout_only_file" && test ! -r "$checkout_only_file"; then - die "Bootstrapping from a non-checked-out distribution is risky." - fi - --# Strip blank and comment lines to leave significant entries. --gitignore_entries() { -- sed '/^#/d; /^$/d' "$@" --} -- --# If $STR is not already on a line by itself in $FILE, insert it at the start. --# Entries are inserted at the start of the ignore list to ensure existing --# entries starting with ! are not overridden. Such entries support --# whitelisting exceptions after a more generic blacklist pattern. --insert_if_absent() { -- file=$1 -- str=$2 -- test -f $file || touch $file -- test -r $file || die "Error: failed to read ignore file: $file" -- duplicate_entries=$(gitignore_entries $file | sort | uniq -d) -- if [ "$duplicate_entries" ] ; then -- die "Error: Duplicate entries in $file: " $duplicate_entries -- fi -- linesold=$(gitignore_entries $file | wc -l) -- linesnew=$( { echo "$str"; cat $file; } | gitignore_entries | sort -u | wc -l) -- if [ $linesold != $linesnew ] ; then -- { echo "$str" | cat - $file > $file.bak && mv $file.bak $file; } \ -- || die "insert_if_absent $file $str: failed" -- fi --} -- --# Adjust $PATTERN for $VC_IGNORE_FILE and insert it with --# insert_if_absent. --insert_vc_ignore() { -- vc_ignore_file="$1" -- pattern="$2" -- case $vc_ignore_file in -- *.gitignore) -- # A .gitignore entry that does not start with '/' applies -- # recursively to subdirectories, so prepend '/' to every -- # .gitignore entry. -- pattern=$(echo "$pattern" | sed s,^,/,);; -- esac -- insert_if_absent "$vc_ignore_file" "$pattern" --} -- - # Die if there is no AC_CONFIG_AUX_DIR($build_aux) line in configure.ac. - found_aux_dir=no - grep '^[ ]*AC_CONFIG_AUX_DIR(\['"$build_aux"'\])' configure.ac \ -@@ -665,9 +763,25 @@ if $use_gnulib; then - shallow= - if test -z "$GNULIB_REVISION"; then - git clone -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2' -+ git clone $shallow ${GNULIB_URL:-$default_gnulib_url} "$gnulib_path" \ -+ || cleanup_gnulib -+ else -+ git fetch -h 2>&1 | grep -- --depth > /dev/null && shallow='--depth 2' -+ mkdir -p "$gnulib_path" -+ # Only want a shallow checkout of $GNULIB_REVISION, but git does not -+ # support cloning by commit hash. So attempt a shallow fetch by commit -+ # hash to minimize the amount of data downloaded and changes needed to -+ # be processed, which can drastically reduce download and processing -+ # time for checkout. If the fetch by commit fails, a shallow fetch can -+ # not be performed because we do not know what the depth of the commit -+ # is without fetching all commits. So fallback to fetching all commits. -+ git -C "$gnulib_path" init -+ git -C "$gnulib_path" remote add origin ${GNULIB_URL:-$default_gnulib_url} -+ git -C "$gnulib_path" fetch $shallow origin "$GNULIB_REVISION" \ -+ || git -C "$gnulib_path" fetch origin \ -+ || cleanup_gnulib -+ git -C "$gnulib_path" reset --hard FETCH_HEAD - fi -- git clone $shallow ${GNULIB_URL:-$default_gnulib_url} "$gnulib_path" \ -- || cleanup_gnulib - - trap - 1 2 13 15 - fi -@@ -784,75 +898,6 @@ case $SKIP_PO in - fi;; - esac - --symlink_to_dir() --{ -- src=$1/$2 -- dst=${3-$2} -- -- test -f "$src" && { -- -- # If the destination directory doesn't exist, create it. -- # This is required at least for "lib/uniwidth/cjk.h". -- dst_dir=$(dirname "$dst") -- if ! test -d "$dst_dir"; then -- mkdir -p "$dst_dir" -- -- # If we've just created a directory like lib/uniwidth, -- # tell version control system(s) it's ignorable. -- # FIXME: for now, this does only one level -- parent=$(dirname "$dst_dir") -- for dot_ig in x $vc_ignore; do -- test $dot_ig = x && continue -- ig=$parent/$dot_ig -- insert_vc_ignore $ig "${dst_dir##*/}" -- done -- fi -- -- if $copy; then -- { -- test ! -h "$dst" || { -- echo "$me: rm -f $dst" && -- rm -f "$dst" -- } -- } && -- test -f "$dst" && -- cmp -s "$src" "$dst" || { -- echo "$me: cp -fp $src $dst" && -- cp -fp "$src" "$dst" -- } -- else -- # Leave any existing symlink alone, if it already points to the source, -- # so that broken build tools that care about symlink times -- # aren't confused into doing unnecessary builds. Conversely, if the -- # existing symlink's timestamp is older than the source, make it afresh, -- # so that broken tools aren't confused into skipping needed builds. See -- # . -- test -h "$dst" && -- src_ls=$(ls -diL "$src" 2>/dev/null) && set $src_ls && src_i=$1 && -- dst_ls=$(ls -diL "$dst" 2>/dev/null) && set $dst_ls && dst_i=$1 && -- test "$src_i" = "$dst_i" && -- both_ls=$(ls -dt "$src" "$dst") && -- test "X$both_ls" = "X$dst$nl$src" || { -- dot_dots= -- case $src in -- /*) ;; -- *) -- case /$dst/ in -- *//* | */../* | */./* | /*/*/*/*/*/) -- die "invalid symlink calculation: $src -> $dst";; -- /*/*/*/*/) dot_dots=../../../;; -- /*/*/*/) dot_dots=../../;; -- /*/*/) dot_dots=../;; -- esac;; -- esac -- -- echo "$me: ln -fs $dot_dots$src $dst" && -- ln -fs "$dot_dots$src" "$dst" -- } -- fi -- } --} -- - version_controlled_file() { - parent=$1 - file=$2 -@@ -970,7 +1015,7 @@ bootstrap_post_import_hook \ - # Uninitialized submodules are listed with an initial dash. - if $use_git && git submodule | grep '^-' >/dev/null; then - die "some git submodules are not initialized. " \ -- "Run 'git submodule init' and bootstrap again." -+ "Run 'git submodule update --init' and bootstrap again." - fi - - # Remove any dangling symlink matching "*.m4" or "*.[ch]" in some -@@ -1064,7 +1109,7 @@ bootstrap_epilogue - - echo "$0: done. Now you can run './configure'." - --# Local variables: -+# Local Variables: - # eval: (add-hook 'before-save-hook 'time-stamp) - # time-stamp-start: "scriptversion=" - # time-stamp-format: "%:y-%02m-%02d.%02H" -diff --git a/bootstrap.conf b/bootstrap.conf -index 71ce943c7d4..e4e5f3750ad 100644 ---- a/bootstrap.conf -+++ b/bootstrap.conf -@@ -1,6 +1,6 @@ - # Bootstrap configuration. - --# Copyright (C) 2006-2019 Free Software Foundation, Inc. -+# Copyright (C) 2006-2022 Free Software Foundation, Inc. - - # This program is free software: you can redistribute it and/or modify - # it under the terms of the GNU General Public License as published by -@@ -16,11 +16,10 @@ - # along with this program. If not, see . - - --GNULIB_REVISION=d271f868a8df9bbec29049d01e056481b7a1a263 -+GNULIB_REVISION=9f48fb992a3d7e96610c4ce8be969cff2d61a01b - - # gnulib modules used by this package. --# mbswidth is used by gnulib-fix-width.diff's changes to argp rather than --# directly. -+# mbswidth is used by fix-width.diff's changes to argp rather than directly. - gnulib_modules=" - argp - base64 -@@ -67,8 +66,8 @@ SKIP_PO=t - - # Build prerequisites - buildreq="\ --autoconf 2.63 --automake 1.11 -+autoconf 2.64 -+automake 1.14 - gettext 0.18.3 - git 1.5.5 - tar - -@@ -80,11 +79,12 @@ cp -a INSTALL INSTALL.grub - - bootstrap_post_import_hook () { - set -e -- for patchname in fix-null-deref fix-null-state-deref fix-regcomp-uninit-token \ -- fix-regexec-null-deref fix-uninit-structure fix-unused-value fix-width; do -- patch -d grub-core/lib/gnulib -p2 \ -- < "grub-core/lib/gnulib-patches/$patchname.patch" -- done -+ -+ # Instead of patching our gnulib and therefore maintaining a fork, submit -+ # changes to gnulib and update the hash above when they've merged. Do not -+ # add new patches here. -+ patch -d grub-core/lib/gnulib -p2 < grub-core/lib/gnulib-patches/fix-width.patch -+ - for patchname in \ - 0001-Support-POTFILES-shell \ - 0002-Handle-gettext_printf-shell-function \ -diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist -index 16248ccf032..5b9fda752b6 100644 ---- a/conf/Makefile.extra-dist -+++ b/conf/Makefile.extra-dist -@@ -30,12 +30,6 @@ EXTRA_DIST += grub-core/gensymlist.sh - EXTRA_DIST += grub-core/genemuinit.sh - EXTRA_DIST += grub-core/genemuinitheader.sh - --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-null-deref.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-null-state-deref.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-regcomp-uninit-token.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-regexec-null-deref.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-uninit-structure.patch --EXTRA_DIST += grub-core/lib/gnulib-patches/fix-unused-value.patch - EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch - - EXTRA_DIST += grub-core/lib/libgcrypt -diff --git a/config.h.in b/config.h.in -index c3134309c63..512d1bbe138 100644 ---- a/config.h.in -+++ b/config.h.in -@@ -67,10 +67,78 @@ - # define _GNU_SOURCE 1 - - # ifndef _GL_INLINE_HEADER_BEGIN -+/* gnulib gets configured against the host, not the target, and the rest of -+ * our buildsystem works around that. This is difficult to avoid as gnulib's -+ * detection requires a more capable system than our target. Instead, we -+ * reach in and set values appropriately - intentionally setting more than the -+ * bare minimum. If, when updating gnulib, something breaks, there's probably -+ * a change needed here or in grub-core/Makefile.core.def. */ -+# define SIZE_MAX ((size_t) -1) -+# define _GL_ATTRIBUTE_ALLOC_SIZE(args) \ -+ __attribute__ ((__alloc_size__ args)) -+# define _GL_ATTRIBUTE_ALWAYS_INLINE __attribute__ ((__always_inline__)) -+# define _GL_ATTRIBUTE_ARTIFICIAL __attribute__ ((__artificial__)) -+# define _GL_ATTRIBUTE_COLD __attribute__ ((cold)) - # define _GL_ATTRIBUTE_CONST __attribute__ ((const)) -+# define _GL_ATTRIBUTE_DEALLOC(f, i) __attribute ((__malloc__ (f, i))) -+# define _GL_ATTRIBUTE_DEALLOC_FREE _GL_ATTRIBUTE_DEALLOC (free, 1) -+# define _GL_ATTRIBUTE_DEPRECATED __attribute__ ((__deprecated__)) -+# define _GL_ATTRIBUTE_ERROR(msg) __attribute__ ((__error__ (msg))) -+# define _GL_ATTRIBUTE_EXTERNALLY_VISIBLE \ -+ __attribute__ ((externally_visible)) -+# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec)) -+# define _GL_ATTRIBUTE_LEAF __attribute__ ((__leaf__)) -+# define _GL_ATTRIBUTE_MALLOC __attribute__ ((malloc)) -+# define _GL_ATTRIBUTE_MAYBE_UNUSED _GL_ATTRIBUTE_UNUSED -+# define _GL_ATTRIBUTE_MAY_ALIAS __attribute__ ((__may_alias__)) -+# define _GL_ATTRIBUTE_NODISCARD __attribute__ ((__warn_unused_result__)) -+# define _GL_ATTRIBUTE_NOINLINE __attribute__ ((__noinline__)) -+# define _GL_ATTRIBUTE_NONNULL(args) __attribute__ ((__nonnull__ args)) -+# define _GL_ATTRIBUTE_NONSTRING __attribute__ ((__nonstring__)) -+# define _GL_ATTRIBUTE_PACKED __attribute__ ((__packed__)) -+# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__)) -+# define _GL_ATTRIBUTE_RETURNS_NONNULL \ -+ __attribute__ ((__returns_nonnull__)) -+# define _GL_ATTRIBUTE_SENTINEL(pos) __attribute__ ((__sentinel__ pos)) -+# define _GL_ATTRIBUTE_UNUSED __attribute__ ((__unused__)) -+# define _GL_ATTRIBUTE_WARNING(msg) __attribute__ ((__warning__ (msg))) -+# define _GL_CMP(n1, n2) (((n1) > (n2)) - ((n1) < (n2))) -+# define _GL_GNUC_PREREQ GNUC_PREREQ -+# define _GL_INLINE inline -+# define _GL_UNUSED_LABEL _GL_ATTRIBUTE_UNUSED -+ -+/* We can't use __has_attribute for these because gcc-5.1 is too old for -+ * that. Everything above is present in that version, though. */ -+# if __GNUC__ >= 7 -+# define _GL_ATTRIBUTE_FALLTHROUGH __attribute__ ((fallthrough)) -+# else -+# define _GL_ATTRIBUTE_FALLTHROUGH /* empty */ -+# endif -+ -+# ifndef ASM_FILE -+typedef __INT_FAST32_TYPE__ int_fast32_t; -+typedef __UINT_FAST32_TYPE__ uint_fast32_t; -+# endif -+ -+/* Ensure ialloc nests static/non-static inline properly. */ -+# define IALLOC_INLINE static inline -+ -+/* gnulib uses these for blocking out warnings they can't/won't fix. gnulib -+ * also makes the decision about whether to provide a declaration for -+ * reallocarray() at compile-time, so this is a convenient place to override - -+ * it's used by the ialloc module, which is used by base64. */ -+# define _GL_INLINE_HEADER_BEGIN _Pragma ("GCC diagnostic push") \ -+ void * \ -+ reallocarray (void *ptr, unsigned int nmemb, unsigned int size); -+# define _GL_INLINE_HEADER_END _Pragma ("GCC diagnostic pop") - - /* We don't have an abort() for gnulib to call in regexp. */ - # define abort __builtin_unreachable - # endif /* !_GL_INLINE_HEADER_BEGIN */ - -+/* gnulib doesn't build cleanly with older compilers. */ -+# if __GNUC__ < 11 -+_Pragma ("GCC diagnostic ignored \"-Wtype-limits\"") -+# endif -+ - #endif -diff --git a/grub-core/lib/gnulib-patches/fix-null-deref.patch b/grub-core/lib/gnulib-patches/fix-null-deref.patch -deleted file mode 100644 -index 8fafa153a47..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-null-deref.patch -+++ /dev/null -@@ -1,13 +0,0 @@ --diff --git a/lib/argp-parse.c b/lib/argp-parse.c --index 6dec57310..900adad54 100644 ----- a/lib/argp-parse.c --+++ b/lib/argp-parse.c --@@ -940,7 +940,7 @@ weak_alias (__argp_parse, argp_parse) -- void * -- __argp_input (const struct argp *argp, const struct argp_state *state) -- { --- if (state) --+ if (state && state->pstate) -- { -- struct group *group; -- struct parser *parser = state->pstate; -diff --git a/grub-core/lib/gnulib-patches/fix-null-state-deref.patch b/grub-core/lib/gnulib-patches/fix-null-state-deref.patch -deleted file mode 100644 -index 813ec09c8a1..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-null-state-deref.patch -+++ /dev/null -@@ -1,12 +0,0 @@ ----- a/lib/argp-help.c 2020-10-28 14:32:19.189215988 +0000 --+++ b/lib/argp-help.c 2020-10-28 14:38:21.204673940 +0000 --@@ -145,7 +145,8 @@ -- if (*(int *)((char *)upptr + up->uparams_offs) >= upptr->rmargin) -- { -- __argp_failure (state, 0, 0, --- dgettext (state->root_argp->argp_domain, --+ dgettext (state == NULL ? NULL --+ : state->root_argp->argp_domain, -- "\ -- ARGP_HELP_FMT: %s value is less than or equal to %s"), -- "rmargin", up->name); -diff --git a/grub-core/lib/gnulib-patches/fix-regcomp-uninit-token.patch b/grub-core/lib/gnulib-patches/fix-regcomp-uninit-token.patch -deleted file mode 100644 -index 02e06315dff..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-regcomp-uninit-token.patch -+++ /dev/null -@@ -1,15 +0,0 @@ ----- a/lib/regcomp.c 2020-11-24 17:06:08.159223858 +0000 --+++ b/lib/regcomp.c 2020-11-24 17:06:15.630253923 +0000 --@@ -3808,11 +3808,7 @@ -- create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, -- re_token_type_t type) -- { --- re_token_t t; ---#if defined GCC_LINT || defined lint --- memset (&t, 0, sizeof t); ---#endif --- t.type = type; --+ re_token_t t = { .type = type }; -- return create_token_tree (dfa, left, right, &t); -- } -- -diff --git a/grub-core/lib/gnulib-patches/fix-regexec-null-deref.patch b/grub-core/lib/gnulib-patches/fix-regexec-null-deref.patch -deleted file mode 100644 -index db6dac9c9e3..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-regexec-null-deref.patch -+++ /dev/null -@@ -1,12 +0,0 @@ ----- a/lib/regexec.c 2020-10-21 14:25:35.310195912 +0000 --+++ b/lib/regexec.c 2020-11-05 10:55:09.621542984 +0000 --@@ -1692,6 +1692,9 @@ -- { -- Idx top = mctx->state_log_top; -- --+ if (mctx->state_log == NULL) --+ return REG_NOERROR; --+ -- if ((next_state_log_idx >= mctx->input.bufs_len -- && mctx->input.bufs_len < mctx->input.len) -- || (next_state_log_idx >= mctx->input.valid_len -diff --git a/grub-core/lib/gnulib-patches/fix-uninit-structure.patch b/grub-core/lib/gnulib-patches/fix-uninit-structure.patch -deleted file mode 100644 -index 7b4d9f67af4..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-uninit-structure.patch -+++ /dev/null -@@ -1,11 +0,0 @@ ----- a/lib/regcomp.c 2020-10-22 13:49:06.770168928 +0000 --+++ b/lib/regcomp.c 2020-10-22 13:50:37.026528298 +0000 --@@ -3662,7 +3662,7 @@ -- Idx alloc = 0; -- #endif /* not RE_ENABLE_I18N */ -- reg_errcode_t ret; --- re_token_t br_token; --+ re_token_t br_token = {0}; -- bin_tree_t *tree; -- -- sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); -diff --git a/grub-core/lib/gnulib-patches/fix-unused-value.patch b/grub-core/lib/gnulib-patches/fix-unused-value.patch -deleted file mode 100644 -index ba51f1bf223..00000000000 ---- a/grub-core/lib/gnulib-patches/fix-unused-value.patch -+++ /dev/null -@@ -1,14 +0,0 @@ ----- a/lib/regexec.c 2020-10-21 14:25:35.310195912 +0000 --+++ b/lib/regexec.c 2020-10-21 14:32:07.961765604 +0000 --@@ -828,7 +828,11 @@ -- break; -- if (__glibc_unlikely (err != REG_NOMATCH)) -- goto free_return; --+#ifdef DEBUG --+ /* Only used for assertion below when DEBUG is set, otherwise --+ it will be over-written when we loop around. */ -- match_last = -1; --+#endif -- } -- else -- break; /* We found a match. */ diff --git a/0210-commands-search-Fix-bug-stopping-iteration-when-no-f.patch b/0210-commands-search-Fix-bug-stopping-iteration-when-no-f.patch deleted file mode 100644 index 388d3239488541b4cecdec379395acc4ee5ebc8c..0000000000000000000000000000000000000000 --- a/0210-commands-search-Fix-bug-stopping-iteration-when-no-f.patch +++ /dev/null @@ -1,33 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Tue, 8 Feb 2022 08:39:10 +0100 -Subject: [PATCH] commands/search: Fix bug stopping iteration when --no-floppy - is used -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When using --no-floppy and a floppy was encountered, iterate_device() -was returning 1, causing the iteration to stop instead of continuing. - -Signed-off-by: Renaud Métrich -Reviewed-by: Daniel Kiper -(cherry picked from commit 68ba54c2298604146be83cae144dafd1cfd1fe2d) -Signed-off-by: Robbie Harwood ---- - grub-core/commands/search.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c -index ed090b3af8b..51656e361cc 100644 ---- a/grub-core/commands/search.c -+++ b/grub-core/commands/search.c -@@ -64,7 +64,7 @@ iterate_device (const char *name, void *data) - /* Skip floppy drives when requested. */ - if (ctx->no_floppy && - name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') -- return 1; -+ return 0; - - #ifdef DO_SEARCH_FS_UUID - #define compare_fn grub_strcasecmp diff --git a/0211-search-new-efidisk-only-option-on-EFI-systems.patch b/0211-search-new-efidisk-only-option-on-EFI-systems.patch deleted file mode 100644 index 20ee9793b560c241ae965c7c87845e2284da2324..0000000000000000000000000000000000000000 --- a/0211-search-new-efidisk-only-option-on-EFI-systems.patch +++ /dev/null @@ -1,168 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Tue, 8 Feb 2022 08:39:11 +0100 -Subject: [PATCH] search: new --efidisk-only option on EFI systems -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When using 'search' on EFI systems, we sometimes want to exclude devices -that are not EFI disks (e.g. md, lvm). -This is typically used when wanting to chainload when having a software -raid (md) for EFI partition: -with no option, 'search --file /EFI/redhat/shimx64.efi' sets root envvar -to 'md/boot_efi' which cannot be used for chainloading since there is no -effective EFI device behind. - -This commit also refactors handling of --no-floppy option. - -Signed-off-by: Renaud Métrich -[rharwood: apply rmetrich's flags initialization fix] -Signed-off-by: Robbie Harwood ---- - grub-core/commands/search.c | 27 +++++++++++++++++++++++---- - grub-core/commands/search_wrap.c | 18 ++++++++++++------ - include/grub/search.h | 15 ++++++++++++--- - 3 files changed, 47 insertions(+), 13 deletions(-) - -diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c -index 51656e361cc..57d26ced8a8 100644 ---- a/grub-core/commands/search.c -+++ b/grub-core/commands/search.c -@@ -47,7 +47,7 @@ struct search_ctx - { - const char *key; - const char *var; -- int no_floppy; -+ enum search_flags flags; - char **hints; - unsigned nhints; - int count; -@@ -62,10 +62,29 @@ iterate_device (const char *name, void *data) - int found = 0; - - /* Skip floppy drives when requested. */ -- if (ctx->no_floppy && -+ if (ctx->flags & SEARCH_FLAGS_NO_FLOPPY && - name[0] == 'f' && name[1] == 'd' && name[2] >= '0' && name[2] <= '9') - return 0; - -+ /* Limit to EFI disks when requested. */ -+ if (ctx->flags & SEARCH_FLAGS_EFIDISK_ONLY) -+ { -+ grub_device_t dev; -+ dev = grub_device_open (name); -+ if (! dev) -+ { -+ grub_errno = GRUB_ERR_NONE; -+ return 0; -+ } -+ if (! dev->disk || dev->disk->dev->id != GRUB_DISK_DEVICE_EFIDISK_ID) -+ { -+ grub_device_close (dev); -+ grub_errno = GRUB_ERR_NONE; -+ return 0; -+ } -+ grub_device_close (dev); -+ } -+ - #ifdef DO_SEARCH_FS_UUID - #define compare_fn grub_strcasecmp - #else -@@ -261,13 +280,13 @@ try (struct search_ctx *ctx) - } - - void --FUNC_NAME (const char *key, const char *var, int no_floppy, -+FUNC_NAME (const char *key, const char *var, enum search_flags flags, - char **hints, unsigned nhints) - { - struct search_ctx ctx = { - .key = key, - .var = var, -- .no_floppy = no_floppy, -+ .flags = flags, - .hints = hints, - .nhints = nhints, - .count = 0, -diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c -index 47fc8eb9966..0b62acf8535 100644 ---- a/grub-core/commands/search_wrap.c -+++ b/grub-core/commands/search_wrap.c -@@ -40,6 +40,7 @@ static const struct grub_arg_option options[] = - N_("Set a variable to the first device found."), N_("VARNAME"), - ARG_TYPE_STRING}, - {"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0}, -+ {"efidisk-only", 0, 0, N_("Only probe EFI disks."), 0, 0}, - {"hint", 'h', GRUB_ARG_OPTION_REPEATABLE, - N_("First try the device HINT. If HINT ends in comma, " - "also try subpartitions"), N_("HINT"), ARG_TYPE_STRING}, -@@ -73,6 +74,7 @@ enum options - SEARCH_FS_UUID, - SEARCH_SET, - SEARCH_NO_FLOPPY, -+ SEARCH_EFIDISK_ONLY, - SEARCH_HINT, - SEARCH_HINT_IEEE1275, - SEARCH_HINT_BIOS, -@@ -89,6 +91,7 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) - const char *id = 0; - int i = 0, j = 0, nhints = 0; - char **hints = NULL; -+ enum search_flags flags = 0; - - if (state[SEARCH_HINT].set) - for (i = 0; state[SEARCH_HINT].args[i]; i++) -@@ -180,15 +183,18 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args) - goto out; - } - -+ if (state[SEARCH_NO_FLOPPY].set) -+ flags |= SEARCH_FLAGS_NO_FLOPPY; -+ -+ if (state[SEARCH_EFIDISK_ONLY].set) -+ flags |= SEARCH_FLAGS_EFIDISK_ONLY; -+ - if (state[SEARCH_LABEL].set) -- grub_search_label (id, var, state[SEARCH_NO_FLOPPY].set, -- hints, nhints); -+ grub_search_label (id, var, flags, hints, nhints); - else if (state[SEARCH_FS_UUID].set) -- grub_search_fs_uuid (id, var, state[SEARCH_NO_FLOPPY].set, -- hints, nhints); -+ grub_search_fs_uuid (id, var, flags, hints, nhints); - else if (state[SEARCH_FILE].set) -- grub_search_fs_file (id, var, state[SEARCH_NO_FLOPPY].set, -- hints, nhints); -+ grub_search_fs_file (id, var, flags, hints, nhints); - else - grub_error (GRUB_ERR_INVALID_COMMAND, "unspecified search type"); - -diff --git a/include/grub/search.h b/include/grub/search.h -index d80347df34b..4190aeb2cbf 100644 ---- a/include/grub/search.h -+++ b/include/grub/search.h -@@ -19,11 +19,20 @@ - #ifndef GRUB_SEARCH_HEADER - #define GRUB_SEARCH_HEADER 1 - --void grub_search_fs_file (const char *key, const char *var, int no_floppy, -+enum search_flags -+ { -+ SEARCH_FLAGS_NO_FLOPPY = 1, -+ SEARCH_FLAGS_EFIDISK_ONLY = 2 -+ }; -+ -+void grub_search_fs_file (const char *key, const char *var, -+ enum search_flags flags, - char **hints, unsigned nhints); --void grub_search_fs_uuid (const char *key, const char *var, int no_floppy, -+void grub_search_fs_uuid (const char *key, const char *var, -+ enum search_flags flags, - char **hints, unsigned nhints); --void grub_search_label (const char *key, const char *var, int no_floppy, -+void grub_search_label (const char *key, const char *var, -+ enum search_flags flags, - char **hints, unsigned nhints); - - #endif diff --git a/0212-efi-new-connectefi-command.patch b/0212-efi-new-connectefi-command.patch deleted file mode 100644 index a9d860ba22a051f5d27f19db5b37e0cc2770b860..0000000000000000000000000000000000000000 --- a/0212-efi-new-connectefi-command.patch +++ /dev/null @@ -1,395 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Renaud=20M=C3=A9trich?= -Date: Tue, 15 Feb 2022 14:05:22 +0100 -Subject: [PATCH] efi: new 'connectefi' command -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When efi.quickboot is enabled on VMWare (which is the default for -hardware release 16 and later), it may happen that not all EFI devices -are connected. Due to this, browsing the devices in make_devices() just -fails to find devices, in particular disks or partitions for a given -disk. -This typically happens when network booting, then trying to chainload to -local disk (this is used in deployment tools such as Red Hat Satellite), -which is done through using the following grub.cfg snippet: --------- 8< ---------------- 8< ---------------- 8< -------- -unset prefix -search --file --set=prefix /EFI/redhat/grubx64.efi -if [ -n "$prefix" ]; then - chainloader ($prefix)/EFI/redhat/grubx64/efi -... --------- 8< ---------------- 8< ---------------- 8< -------- - -With efi.quickboot, none of the devices are connected, causing "search" -to fail. Sometimes devices are connected but not the partition of the -disk matching $prefix, causing partition to not be found by -"chainloader". - -This patch introduces a new "connectefi pciroot|scsi" command which -recursively connects all EFI devices starting from a given controller -type: -- if 'pciroot' is specified, recursion is performed for all PCI root - handles -- if 'scsi' is specified, recursion is performed for all SCSI I/O - handles (recommended usage to avoid connecting unwanted handles which - may impact Grub performances) - -Typical grub.cfg snippet would then be: --------- 8< ---------------- 8< ---------------- 8< -------- -connectefi scsi -unset prefix -search --file --set=prefix /EFI/redhat/grubx64.efi -if [ -n "$prefix" ]; then - chainloader ($prefix)/EFI/redhat/grubx64/efi -... --------- 8< ---------------- 8< ---------------- 8< -------- - -The code is easily extensible to handle other arguments in the future if -needed. - -Signed-off-by: Renaud Métrich -Signed-off-by: Robbie Harwood ---- - grub-core/Makefile.core.def | 6 ++ - grub-core/commands/efi/connectefi.c | 205 ++++++++++++++++++++++++++++++++++++ - grub-core/commands/efi/lsefi.c | 1 + - grub-core/disk/efi/efidisk.c | 13 +++ - grub-core/kern/efi/efi.c | 13 +++ - include/grub/efi/disk.h | 2 + - include/grub/efi/efi.h | 5 + - NEWS | 2 +- - 8 files changed, 246 insertions(+), 1 deletion(-) - create mode 100644 grub-core/commands/efi/connectefi.c - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 39233096f29..3c0ac3b7bd0 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -836,6 +836,12 @@ module = { - enable = efi; - }; - -+module = { -+ name = connectefi; -+ common = commands/efi/connectefi.c; -+ enable = efi; -+}; -+ - module = { - name = blocklist; - common = commands/blocklist.c; -diff --git a/grub-core/commands/efi/connectefi.c b/grub-core/commands/efi/connectefi.c -new file mode 100644 -index 00000000000..8ab75bd51be ---- /dev/null -+++ b/grub-core/commands/efi/connectefi.c -@@ -0,0 +1,205 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+typedef struct handle_list -+{ -+ grub_efi_handle_t handle; -+ struct handle_list *next; -+} handle_list_t; -+ -+static handle_list_t *already_handled = NULL; -+ -+static grub_err_t -+add_handle (grub_efi_handle_t handle) -+{ -+ handle_list_t *e; -+ e = grub_malloc (sizeof (*e)); -+ if (! e) -+ return grub_errno; -+ e->handle = handle; -+ e->next = already_handled; -+ already_handled = e; -+ return GRUB_ERR_NONE; -+} -+ -+static int -+is_in_list (grub_efi_handle_t handle) -+{ -+ handle_list_t *e; -+ for (e = already_handled; e != NULL; e = e->next) -+ if (e->handle == handle) -+ return 1; -+ return 0; -+} -+ -+static void -+free_handle_list (void) -+{ -+ handle_list_t *e; -+ while ((e = already_handled) != NULL) -+ { -+ already_handled = already_handled->next; -+ grub_free (e); -+ } -+} -+ -+typedef enum searched_item_flag -+{ -+ SEARCHED_ITEM_FLAG_LOOP = 1, -+ SEARCHED_ITEM_FLAG_RECURSIVE = 2 -+} searched_item_flags; -+ -+typedef struct searched_item -+{ -+ grub_efi_guid_t guid; -+ const char *name; -+ searched_item_flags flags; -+} searched_items; -+ -+static grub_err_t -+grub_cmd_connectefi (grub_command_t cmd __attribute__ ((unused)), -+ int argc, char **args) -+{ -+ unsigned s; -+ searched_items pciroot_items[] = -+ { -+ { GRUB_EFI_PCI_ROOT_IO_GUID, "PCI root", SEARCHED_ITEM_FLAG_RECURSIVE } -+ }; -+ searched_items scsi_items[] = -+ { -+ { GRUB_EFI_PCI_ROOT_IO_GUID, "PCI root", 0 }, -+ { GRUB_EFI_PCI_IO_GUID, "PCI", SEARCHED_ITEM_FLAG_LOOP }, -+ { GRUB_EFI_SCSI_IO_PROTOCOL_GUID, "SCSI I/O", SEARCHED_ITEM_FLAG_RECURSIVE } -+ }; -+ searched_items *items = NULL; -+ unsigned nitems = 0; -+ grub_err_t grub_err = GRUB_ERR_NONE; -+ unsigned total_connected = 0; -+ -+ if (argc != 1) -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected")); -+ -+ if (grub_strcmp(args[0], N_("pciroot")) == 0) -+ { -+ items = pciroot_items; -+ nitems = ARRAY_SIZE (pciroot_items); -+ } -+ else if (grub_strcmp(args[0], N_("scsi")) == 0) -+ { -+ items = scsi_items; -+ nitems = ARRAY_SIZE (scsi_items); -+ } -+ else -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("unexpected argument `%s'"), args[0]); -+ -+ for (s = 0; s < nitems; s++) -+ { -+ grub_efi_handle_t *handles; -+ grub_efi_uintn_t num_handles; -+ unsigned i, connected = 0, loop = 0; -+ -+loop: -+ loop++; -+ grub_dprintf ("efi", "step '%s' loop %d:\n", items[s].name, loop); -+ -+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, -+ &items[s].guid, 0, &num_handles); -+ -+ if (!handles) -+ continue; -+ -+ for (i = 0; i < num_handles; i++) -+ { -+ grub_efi_handle_t handle = handles[i]; -+ grub_efi_status_t status; -+ unsigned j; -+ -+ /* Skip already handled handles */ -+ if (is_in_list (handle)) -+ { -+ grub_dprintf ("efi", " handle %p: already processed\n", -+ handle); -+ continue; -+ } -+ -+ status = grub_efi_connect_controller(handle, NULL, NULL, -+ items[s].flags & SEARCHED_ITEM_FLAG_RECURSIVE ? 1 : 0); -+ if (status == GRUB_EFI_SUCCESS) -+ { -+ connected++; -+ total_connected++; -+ grub_dprintf ("efi", " handle %p: connected\n", handle); -+ } -+ else -+ grub_dprintf ("efi", " handle %p: failed to connect (%d)\n", -+ handle, (grub_efi_int8_t) status); -+ -+ if ((grub_err = add_handle (handle)) != GRUB_ERR_NONE) -+ break; /* fatal */ -+ } -+ -+ grub_free (handles); -+ if (grub_err != GRUB_ERR_NONE) -+ break; /* fatal */ -+ -+ if (items[s].flags & SEARCHED_ITEM_FLAG_LOOP && connected) -+ { -+ connected = 0; -+ goto loop; -+ } -+ -+ free_handle_list (); -+ } -+ -+ free_handle_list (); -+ -+ if (total_connected) -+ grub_efidisk_reenumerate_disks (); -+ -+ return grub_err; -+} -+ -+static grub_command_t cmd; -+ -+GRUB_MOD_INIT(connectefi) -+{ -+ cmd = grub_register_command ("connectefi", grub_cmd_connectefi, -+ N_("pciroot|scsi"), -+ N_("Connect EFI handles." -+ " If 'pciroot' is specified, connect PCI" -+ " root EFI handles recursively." -+ " If 'scsi' is specified, connect SCSI" -+ " I/O EFI handles recursively.")); -+} -+ -+GRUB_MOD_FINI(connectefi) -+{ -+ grub_unregister_command (cmd); -+} -diff --git a/grub-core/commands/efi/lsefi.c b/grub-core/commands/efi/lsefi.c -index d1ce99af438..f2d2430e666 100644 ---- a/grub-core/commands/efi/lsefi.c -+++ b/grub-core/commands/efi/lsefi.c -@@ -19,6 +19,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c -index fe8ba6e6c93..062143dfffd 100644 ---- a/grub-core/disk/efi/efidisk.c -+++ b/grub-core/disk/efi/efidisk.c -@@ -396,6 +396,19 @@ enumerate_disks (void) - free_devices (devices); - } - -+void -+grub_efidisk_reenumerate_disks (void) -+{ -+ free_devices (fd_devices); -+ free_devices (hd_devices); -+ free_devices (cd_devices); -+ fd_devices = 0; -+ hd_devices = 0; -+ cd_devices = 0; -+ -+ enumerate_disks (); -+} -+ - static int - grub_efidisk_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, - grub_disk_pull_t pull) -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 14bc10eb564..7fcca69c17b 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -95,6 +95,19 @@ grub_efi_locate_handle (grub_efi_locate_search_type_t search_type, - return buffer; - } - -+grub_efi_status_t -+grub_efi_connect_controller (grub_efi_handle_t controller_handle, -+ grub_efi_handle_t *driver_image_handle, -+ grub_efi_device_path_protocol_t *remaining_device_path, -+ grub_efi_boolean_t recursive) -+{ -+ grub_efi_boot_services_t *b; -+ -+ b = grub_efi_system_table->boot_services; -+ return efi_call_4 (b->connect_controller, controller_handle, -+ driver_image_handle, remaining_device_path, recursive); -+} -+ - void * - grub_efi_open_protocol (grub_efi_handle_t handle, - grub_efi_guid_t *protocol, -diff --git a/include/grub/efi/disk.h b/include/grub/efi/disk.h -index 254475c8428..6845c2f1fd8 100644 ---- a/include/grub/efi/disk.h -+++ b/include/grub/efi/disk.h -@@ -27,6 +27,8 @@ grub_efi_handle_t - EXPORT_FUNC(grub_efidisk_get_device_handle) (grub_disk_t disk); - char *EXPORT_FUNC(grub_efidisk_get_device_name) (grub_efi_handle_t *handle); - -+void EXPORT_FUNC(grub_efidisk_reenumerate_disks) (void); -+ - void grub_efidisk_init (void); - void grub_efidisk_fini (void); - -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 8dfc89a33b9..ec52083c49f 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -41,6 +41,11 @@ EXPORT_FUNC(grub_efi_locate_handle) (grub_efi_locate_search_type_t search_type, - grub_efi_guid_t *protocol, - void *search_key, - grub_efi_uintn_t *num_handles); -+grub_efi_status_t -+EXPORT_FUNC(grub_efi_connect_controller) (grub_efi_handle_t controller_handle, -+ grub_efi_handle_t *driver_image_handle, -+ grub_efi_device_path_protocol_t *remaining_device_path, -+ grub_efi_boolean_t recursive); - void *EXPORT_FUNC(grub_efi_open_protocol) (grub_efi_handle_t handle, - grub_efi_guid_t *protocol, - grub_efi_uint32_t attributes); -diff --git a/NEWS b/NEWS -index 73b8492bc42..d7c1d23aed7 100644 ---- a/NEWS -+++ b/NEWS -@@ -98,7 +98,7 @@ New in 2.02: - * Prefer pmtimer for TSC calibration. - - * New/improved platform support: -- * New `efifwsetup' and `lsefi' commands on EFI platforms. -+ * New `efifwsetup', `lsefi' and `connectefi` commands on EFI platforms. - * New `cmosdump' and `cmosset' commands on platforms with CMOS support. - * New command `pcidump' for PCI platforms. - * Improve opcode parsing in ACPI halt implementation. diff --git a/0213-rpm-sort-add-prereqs-for-declaration-of-strchrnul.patch b/0213-rpm-sort-add-prereqs-for-declaration-of-strchrnul.patch deleted file mode 100644 index d2458d0066bb6dcd4fc1836a61752ca22dc72456..0000000000000000000000000000000000000000 --- a/0213-rpm-sort-add-prereqs-for-declaration-of-strchrnul.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Thu, 5 May 2022 18:01:05 -0400 -Subject: [PATCH] rpm-sort: add prereqs for declaration of strchrnul() - -Signed-off-by: Robbie Harwood ---- - util/grub-rpm-sort.c | 12 ++++++++---- - 1 file changed, 8 insertions(+), 4 deletions(-) - -diff --git a/util/grub-rpm-sort.c b/util/grub-rpm-sort.c -index 8345944105..71d038bb69 100644 ---- a/util/grub-rpm-sort.c -+++ b/util/grub-rpm-sort.c -@@ -1,13 +1,17 @@ -+#define _GNU_SOURCE 1 -+ - #include -+ -+#include -+#include -+#include - #include - #include -+#include - #include - #include -+#include - #include --#include --#include --#include --#include - - static size_t - read_file (const char *input, char **ret) diff --git a/0214-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch b/0214-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch deleted file mode 100644 index 3c73469d6eea59e121148ce18b05e829bb635e57..0000000000000000000000000000000000000000 --- a/0214-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch +++ /dev/null @@ -1,236 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Stefan Berger -Date: Sun, 15 Mar 2020 12:37:10 -0400 -Subject: [PATCH] ibmvtpm: Add support for trusted boot using a vTPM 2.0 - -Add support for trusted boot using a vTPM 2.0 on the IBM IEEE1275 -PowerPC platform. With this patch grub now measures text and binary data -into the TPM's PCRs 8 and 9 in the same way as the x86_64 platform -does. - -This patch requires Daniel Axtens's patches for claiming more memory. - -For vTPM support to work on PowerVM, system driver levels 1010.30 -or 1020.00 are required. - -Note: Previous versions of firmware levels with the 2hash-ext-log -API call have a bug that, once this API call is invoked, has the -effect of disabling the vTPM driver under Linux causing an error -message to be displayed in the Linux kernel log. Those users will -have to update their machines to the firmware levels mentioned -above. - -Cc: Eric Snowberg -Signed-off-by: Stefan Berger ---- - grub-core/Makefile.core.def | 7 ++ - grub-core/commands/ieee1275/ibmvtpm.c | 152 ++++++++++++++++++++++++++++++++++ - include/grub/ieee1275/ieee1275.h | 3 + - docs/grub.texi | 3 +- - 4 files changed, 164 insertions(+), 1 deletion(-) - create mode 100644 grub-core/commands/ieee1275/ibmvtpm.c - -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 3c0ac3b7bd..2c1608bca4 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -1175,6 +1175,13 @@ module = { - enable = powerpc_ieee1275; - }; - -+module = { -+ name = tpm; -+ common = commands/tpm.c; -+ ieee1275 = commands/ieee1275/ibmvtpm.c; -+ enable = powerpc_ieee1275; -+}; -+ - module = { - name = terminal; - common = commands/terminal.c; -diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c -new file mode 100644 -index 0000000000..e68b8448bc ---- /dev/null -+++ b/grub-core/commands/ieee1275/ibmvtpm.c -@@ -0,0 +1,152 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 Free Software Foundation, Inc. -+ * Copyright (C) 2021 IBM Corporation -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ * -+ * IBM vTPM support code. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static grub_ieee1275_ihandle_t tpm_ihandle; -+static grub_uint8_t tpm_version; -+ -+#define IEEE1275_IHANDLE_INVALID ((grub_ieee1275_ihandle_t)0) -+ -+static void -+tpm_get_tpm_version (void) -+{ -+ grub_ieee1275_phandle_t vtpm; -+ char buffer[20]; -+ -+ if (!grub_ieee1275_finddevice ("/vdevice/vtpm", &vtpm) && -+ !grub_ieee1275_get_property (vtpm, "compatible", buffer, -+ sizeof (buffer), NULL) && -+ !grub_strcmp (buffer, "IBM,vtpm20")) -+ tpm_version = 2; -+} -+ -+static grub_err_t -+tpm_init (void) -+{ -+ static int init_success = 0; -+ -+ if (!init_success) -+ { -+ if (grub_ieee1275_open ("/vdevice/vtpm", &tpm_ihandle) < 0) { -+ tpm_ihandle = IEEE1275_IHANDLE_INVALID; -+ return GRUB_ERR_UNKNOWN_DEVICE; -+ } -+ -+ init_success = 1; -+ -+ tpm_get_tpm_version (); -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static int -+ibmvtpm_2hash_ext_log (grub_uint8_t pcrindex, -+ grub_uint32_t eventtype, -+ const char *description, -+ grub_size_t description_size, -+ void *buf, grub_size_t size) -+{ -+ struct tpm_2hash_ext_log -+ { -+ struct grub_ieee1275_common_hdr common; -+ grub_ieee1275_cell_t method; -+ grub_ieee1275_cell_t ihandle; -+ grub_ieee1275_cell_t size; -+ grub_ieee1275_cell_t buf; -+ grub_ieee1275_cell_t description_size; -+ grub_ieee1275_cell_t description; -+ grub_ieee1275_cell_t eventtype; -+ grub_ieee1275_cell_t pcrindex; -+ grub_ieee1275_cell_t catch_result; -+ grub_ieee1275_cell_t rc; -+ } -+ args; -+ -+ INIT_IEEE1275_COMMON (&args.common, "call-method", 8, 2); -+ args.method = (grub_ieee1275_cell_t) "2hash-ext-log"; -+ args.ihandle = tpm_ihandle; -+ args.pcrindex = pcrindex; -+ args.eventtype = eventtype; -+ args.description = (grub_ieee1275_cell_t) description; -+ args.description_size = description_size; -+ args.buf = (grub_ieee1275_cell_t) buf; -+ args.size = (grub_ieee1275_cell_t) size; -+ -+ if (IEEE1275_CALL_ENTRY_FN (&args) == -1) -+ return -1; -+ -+ /* -+ * catch_result is set if firmware does not support 2hash-ext-log -+ * rc is GRUB_IEEE1275_CELL_FALSE (0) on failure -+ */ -+ if ((args.catch_result) || args.rc == GRUB_IEEE1275_CELL_FALSE) -+ return -1; -+ -+ return 0; -+} -+ -+static grub_err_t -+tpm2_log_event (unsigned char *buf, -+ grub_size_t size, grub_uint8_t pcr, -+ const char *description) -+{ -+ static int error_displayed = 0; -+ int err; -+ -+ err = ibmvtpm_2hash_ext_log (pcr, EV_IPL, -+ description, -+ grub_strlen(description) + 1, -+ buf, size); -+ if (err && !error_displayed) -+ { -+ error_displayed++; -+ return grub_error (GRUB_ERR_BAD_DEVICE, -+ "2HASH-EXT-LOG failed: Firmware is likely too old.\n"); -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+grub_err_t -+grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr, -+ const char *description) -+{ -+ grub_err_t err = tpm_init(); -+ -+ /* Absence of a TPM isn't a failure. */ -+ if (err != GRUB_ERR_NONE) -+ return GRUB_ERR_NONE; -+ -+ grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n", -+ pcr, size, description); -+ -+ if (tpm_version == 2) -+ return tpm2_log_event (buf, size, pcr, description); -+ -+ return GRUB_ERR_NONE; -+} -diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h -index e0a6c2ce1e..f4c85265fe 100644 ---- a/include/grub/ieee1275/ieee1275.h -+++ b/include/grub/ieee1275/ieee1275.h -@@ -24,6 +24,9 @@ - #include - #include - -+#define GRUB_IEEE1275_CELL_FALSE ((grub_ieee1275_cell_t) 0) -+#define GRUB_IEEE1275_CELL_TRUE ((grub_ieee1275_cell_t) -1) -+ - struct grub_ieee1275_mem_region - { - unsigned int start; -diff --git a/docs/grub.texi b/docs/grub.texi -index a4da9c2a1b..c433240f34 100644 ---- a/docs/grub.texi -+++ b/docs/grub.texi -@@ -6221,7 +6221,8 @@ tpm module is loaded. As such it is recommended that the tpm module be built - into @file{core.img} in order to avoid a potential gap in measurement between - @file{core.img} being loaded and the tpm module being loaded. - --Measured boot is currently only supported on EFI platforms. -+Measured boot is currently only supported on EFI and IBM IEEE1275 PowerPC -+platforms. - - @node Lockdown - @section Lockdown when booting on a secure setup diff --git a/0215-make-ofdisk_retries-optional.patch b/0215-make-ofdisk_retries-optional.patch deleted file mode 100644 index fce9702dfc76fa8b9e64d3178b853656ebac931b..0000000000000000000000000000000000000000 --- a/0215-make-ofdisk_retries-optional.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Diego Domingos -Date: Thu, 24 Mar 2022 13:14:42 -0400 -Subject: [PATCH] make ofdisk_retries optional - -The feature Retry on Fail added to GRUB can cause a LPM to take -longer if the SAN is slow. - -When a LPM to external site occur, the path of the disk can change -and thus the disk search function on grub can take some time since -it is used as a hint. This can cause the Retry on Fail feature to -try to access the disk 20x times (since this is hardcoded number) -and, if the SAN is slow, the boot time can increase a lot. -In some situations not acceptable. - -The following patch enables a configuration at user space of the -maximum number of retries we want for this feature. - -The variable ofdisk_retries should be set using grub2-editenv -and will be checked by retry function. If the variable is not set, -so the default number of retries will be used instead. ---- - include/grub/ieee1275/ofdisk.h | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/include/grub/ieee1275/ofdisk.h b/include/grub/ieee1275/ofdisk.h -index 7d2d540930..0074d55eee 100644 ---- a/include/grub/ieee1275/ofdisk.h -+++ b/include/grub/ieee1275/ofdisk.h -@@ -25,7 +25,12 @@ extern void grub_ofdisk_fini (void); - #define MAX_RETRIES 20 - - --#define RETRY_IEEE1275_OFDISK_OPEN(device, last_ihandle) unsigned retry_i=0;for(retry_i=0; retry_i < MAX_RETRIES; retry_i++){ \ -+#define RETRY_IEEE1275_OFDISK_OPEN(device, last_ihandle) \ -+ unsigned max_retries = MAX_RETRIES; \ -+ if(grub_env_get("ofdisk_retries") != NULL) \ -+ max_retries = grub_strtoul(grub_env_get("ofdisk_retries"), 0, 10)+1; \ -+ grub_dprintf("ofdisk","MAX_RETRIES set to %u\n",max_retries); \ -+ unsigned retry_i=0;for(retry_i=0; retry_i < max_retries; retry_i++){ \ - if(!grub_ieee1275_open(device, last_ihandle)) \ - break; \ - grub_dprintf("ofdisk","Opening disk %s failed. Retrying...\n",device); } diff --git a/0216-commands-boot-Add-API-to-pass-context-to-loader.patch b/0216-commands-boot-Add-API-to-pass-context-to-loader.patch deleted file mode 100644 index 63a2d76ebe89234f112dd2d794a95ad22e4154da..0000000000000000000000000000000000000000 --- a/0216-commands-boot-Add-API-to-pass-context-to-loader.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Chris Coulson -Date: Fri, 29 Apr 2022 21:16:02 +0100 -Subject: [PATCH] commands/boot: Add API to pass context to loader - -Loaders rely on global variables for saving context which is consumed -in the boot hook and freed in the unload hook. In the case where a loader -command is executed twice, calling grub_loader_set a second time executes -the unload hook, but in some cases this runs when the loader's global -context has already been updated, resulting in the updated context being -freed and potential use-after-free bugs when the boot hook is subsequently -called. - -This adds a new API (grub_loader_set_ex) which allows a loader to specify -context that is passed to its boot and unload hooks. This is an alternative -to requiring that loaders call grub_loader_unset before mutating their -global context. - -Signed-off-by: Chris Coulson -(cherry picked from commit 4322a64dde7e8fedb58e50b79408667129d45dd3) ---- - grub-core/commands/boot.c | 66 +++++++++++++++++++++++++++++++++++++++++------ - include/grub/loader.h | 5 ++++ - 2 files changed, 63 insertions(+), 8 deletions(-) - -diff --git a/grub-core/commands/boot.c b/grub-core/commands/boot.c -index bbca81e947..53691a62d9 100644 ---- a/grub-core/commands/boot.c -+++ b/grub-core/commands/boot.c -@@ -27,10 +27,20 @@ - - GRUB_MOD_LICENSE ("GPLv3+"); - --static grub_err_t (*grub_loader_boot_func) (void); --static grub_err_t (*grub_loader_unload_func) (void); -+static grub_err_t (*grub_loader_boot_func) (void *); -+static grub_err_t (*grub_loader_unload_func) (void *); -+static void *grub_loader_context; - static int grub_loader_flags; - -+struct grub_simple_loader_hooks -+{ -+ grub_err_t (*boot) (void); -+ grub_err_t (*unload) (void); -+}; -+ -+/* Don't heap allocate this to avoid making grub_loader_set fallible. */ -+static struct grub_simple_loader_hooks simple_loader_hooks; -+ - struct grub_preboot - { - grub_err_t (*preboot_func) (int); -@@ -44,6 +54,29 @@ static int grub_loader_loaded; - static struct grub_preboot *preboots_head = 0, - *preboots_tail = 0; - -+static grub_err_t -+grub_simple_boot_hook (void *context) -+{ -+ struct grub_simple_loader_hooks *hooks; -+ -+ hooks = (struct grub_simple_loader_hooks *) context; -+ return hooks->boot (); -+} -+ -+static grub_err_t -+grub_simple_unload_hook (void *context) -+{ -+ struct grub_simple_loader_hooks *hooks; -+ grub_err_t ret; -+ -+ hooks = (struct grub_simple_loader_hooks *) context; -+ -+ ret = hooks->unload (); -+ grub_memset (hooks, 0, sizeof (*hooks)); -+ -+ return ret; -+} -+ - int - grub_loader_is_loaded (void) - { -@@ -110,28 +143,45 @@ grub_loader_unregister_preboot_hook (struct grub_preboot *hnd) - } - - void --grub_loader_set (grub_err_t (*boot) (void), -- grub_err_t (*unload) (void), -- int flags) -+grub_loader_set_ex (grub_err_t (*boot) (void *), -+ grub_err_t (*unload) (void *), -+ void *context, -+ int flags) - { - if (grub_loader_loaded && grub_loader_unload_func) -- grub_loader_unload_func (); -+ grub_loader_unload_func (grub_loader_context); - - grub_loader_boot_func = boot; - grub_loader_unload_func = unload; -+ grub_loader_context = context; - grub_loader_flags = flags; - - grub_loader_loaded = 1; - } - -+void -+grub_loader_set (grub_err_t (*boot) (void), -+ grub_err_t (*unload) (void), -+ int flags) -+{ -+ grub_loader_set_ex (grub_simple_boot_hook, -+ grub_simple_unload_hook, -+ &simple_loader_hooks, -+ flags); -+ -+ simple_loader_hooks.boot = boot; -+ simple_loader_hooks.unload = unload; -+} -+ - void - grub_loader_unset(void) - { - if (grub_loader_loaded && grub_loader_unload_func) -- grub_loader_unload_func (); -+ grub_loader_unload_func (grub_loader_context); - - grub_loader_boot_func = 0; - grub_loader_unload_func = 0; -+ grub_loader_context = 0; - - grub_loader_loaded = 0; - } -@@ -158,7 +208,7 @@ grub_loader_boot (void) - return err; - } - } -- err = (grub_loader_boot_func) (); -+ err = (grub_loader_boot_func) (grub_loader_context); - - for (cur = preboots_tail; cur; cur = cur->prev) - if (! err) -diff --git a/include/grub/loader.h b/include/grub/loader.h -index b208642821..1846fa6c5f 100644 ---- a/include/grub/loader.h -+++ b/include/grub/loader.h -@@ -40,6 +40,11 @@ void EXPORT_FUNC (grub_loader_set) (grub_err_t (*boot) (void), - grub_err_t (*unload) (void), - int flags); - -+void EXPORT_FUNC (grub_loader_set_ex) (grub_err_t (*boot) (void *), -+ grub_err_t (*unload) (void *), -+ void *context, -+ int flags); -+ - /* Unset current loader, if any. */ - void EXPORT_FUNC (grub_loader_unset) (void); - diff --git a/0217-kern-efi-sb-Reject-non-kernel-files-in-the-shim_lock.patch b/0217-kern-efi-sb-Reject-non-kernel-files-in-the-shim_lock.patch deleted file mode 100644 index 715e6e1dc69beacf753b51fa6bc81e85ec0119b8..0000000000000000000000000000000000000000 --- a/0217-kern-efi-sb-Reject-non-kernel-files-in-the-shim_lock.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Julian Andres Klode -Date: Thu, 2 Dec 2021 15:03:53 +0100 -Subject: [PATCH] kern/efi/sb: Reject non-kernel files in the shim_lock - verifier - -We must not allow other verifiers to pass things like the GRUB modules. -Instead of maintaining a blocklist, maintain an allowlist of things -that we do not care about. - -This allowlist really should be made reusable, and shared by the -lockdown verifier, but this is the minimal patch addressing -security concerns where the TPM verifier was able to mark modules -as verified (or the OpenPGP verifier for that matter), when it -should not do so on shim-powered secure boot systems. - -Fixes: CVE-2022-28735 - -Signed-off-by: Julian Andres Klode -Reviewed-by: Daniel Kiper -(cherry picked from commit fa61ad69861c1cb3f68bf853d78fae7fd93986a0) ---- - grub-core/kern/efi/sb.c | 39 ++++++++++++++++++++++++++++++++++++--- - include/grub/verify.h | 1 + - 2 files changed, 37 insertions(+), 3 deletions(-) - -diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c -index c52ec6226a..89c4bb3fd1 100644 ---- a/grub-core/kern/efi/sb.c -+++ b/grub-core/kern/efi/sb.c -@@ -119,10 +119,11 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)), - void **context __attribute__ ((unused)), - enum grub_verify_flags *flags) - { -- *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; -+ *flags = GRUB_VERIFY_FLAGS_NONE; - - switch (type & GRUB_FILE_TYPE_MASK) - { -+ /* Files we check. */ - case GRUB_FILE_TYPE_LINUX_KERNEL: - case GRUB_FILE_TYPE_MULTIBOOT_KERNEL: - case GRUB_FILE_TYPE_BSD_KERNEL: -@@ -130,11 +131,43 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)), - case GRUB_FILE_TYPE_PLAN9_KERNEL: - case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE: - *flags = GRUB_VERIFY_FLAGS_SINGLE_CHUNK; -+ return GRUB_ERR_NONE; - -- /* Fall through. */ -+ /* Files that do not affect secureboot state. */ -+ case GRUB_FILE_TYPE_NONE: -+ case GRUB_FILE_TYPE_LOOPBACK: -+ case GRUB_FILE_TYPE_LINUX_INITRD: -+ case GRUB_FILE_TYPE_OPENBSD_RAMDISK: -+ case GRUB_FILE_TYPE_XNU_RAMDISK: -+ case GRUB_FILE_TYPE_SIGNATURE: -+ case GRUB_FILE_TYPE_PUBLIC_KEY: -+ case GRUB_FILE_TYPE_PUBLIC_KEY_TRUST: -+ case GRUB_FILE_TYPE_PRINT_BLOCKLIST: -+ case GRUB_FILE_TYPE_TESTLOAD: -+ case GRUB_FILE_TYPE_GET_SIZE: -+ case GRUB_FILE_TYPE_FONT: -+ case GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY: -+ case GRUB_FILE_TYPE_CAT: -+ case GRUB_FILE_TYPE_HEXCAT: -+ case GRUB_FILE_TYPE_CMP: -+ case GRUB_FILE_TYPE_HASHLIST: -+ case GRUB_FILE_TYPE_TO_HASH: -+ case GRUB_FILE_TYPE_KEYBOARD_LAYOUT: -+ case GRUB_FILE_TYPE_PIXMAP: -+ case GRUB_FILE_TYPE_GRUB_MODULE_LIST: -+ case GRUB_FILE_TYPE_CONFIG: -+ case GRUB_FILE_TYPE_THEME: -+ case GRUB_FILE_TYPE_GETTEXT_CATALOG: -+ case GRUB_FILE_TYPE_FS_SEARCH: -+ case GRUB_FILE_TYPE_LOADENV: -+ case GRUB_FILE_TYPE_SAVEENV: -+ case GRUB_FILE_TYPE_VERIFY_SIGNATURE: -+ *flags = GRUB_VERIFY_FLAGS_SKIP_VERIFICATION; -+ return GRUB_ERR_NONE; - -+ /* Other files. */ - default: -- return GRUB_ERR_NONE; -+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited by secure boot policy")); - } - } - -diff --git a/include/grub/verify.h b/include/grub/verify.h -index cd129c398f..672ae16924 100644 ---- a/include/grub/verify.h -+++ b/include/grub/verify.h -@@ -24,6 +24,7 @@ - - enum grub_verify_flags - { -+ GRUB_VERIFY_FLAGS_NONE = 0, - GRUB_VERIFY_FLAGS_SKIP_VERIFICATION = 1, - GRUB_VERIFY_FLAGS_SINGLE_CHUNK = 2, - /* Defer verification to another authority. */ diff --git a/0218-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch b/0218-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch deleted file mode 100644 index bcc5503d993af9fcebe2cc1c5b487f969ec19e07..0000000000000000000000000000000000000000 --- a/0218-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Fri, 25 Jun 2021 02:19:05 +1000 -Subject: [PATCH] kern/file: Do not leak device_name on error in - grub_file_open() - -If we have an error in grub_file_open() before we free device_name, we -will leak it. - -Free device_name in the error path and null out the pointer in the good -path once we free it there. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit 1499a5068839fa37cb77ecef4b5bdacbd1ed12ea) ---- - grub-core/kern/file.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c -index e19aea3e51..ed69fc0f0f 100644 ---- a/grub-core/kern/file.c -+++ b/grub-core/kern/file.c -@@ -81,6 +81,7 @@ grub_file_open (const char *name, enum grub_file_type type) - - device = grub_device_open (device_name); - grub_free (device_name); -+ device_name = NULL; - if (! device) - goto fail; - -@@ -135,6 +136,7 @@ grub_file_open (const char *name, enum grub_file_type type) - return file; - - fail: -+ grub_free (device_name); - if (device) - grub_device_close (device); - diff --git a/0219-video-readers-png-Abort-sooner-if-a-read-operation-f.patch b/0219-video-readers-png-Abort-sooner-if-a-read-operation-f.patch deleted file mode 100644 index 385d3ed0189dad5feab421b022700b1daf8bee52..0000000000000000000000000000000000000000 --- a/0219-video-readers-png-Abort-sooner-if-a-read-operation-f.patch +++ /dev/null @@ -1,198 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 6 Jul 2021 14:02:55 +1000 -Subject: [PATCH] video/readers/png: Abort sooner if a read operation fails - -Fuzzing revealed some inputs that were taking a long time, potentially -forever, because they did not bail quickly upon encountering an I/O error. - -Try to catch I/O errors sooner and bail out. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit 882be97d1df6449b9fd4d593f0cb70005fde3494) ---- - grub-core/video/readers/png.c | 55 ++++++++++++++++++++++++++++++++++++------- - 1 file changed, 47 insertions(+), 8 deletions(-) - -diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c -index 0157ff7420..e2a6b1cf3c 100644 ---- a/grub-core/video/readers/png.c -+++ b/grub-core/video/readers/png.c -@@ -142,6 +142,7 @@ static grub_uint8_t - grub_png_get_byte (struct grub_png_data *data) - { - grub_uint8_t r; -+ grub_ssize_t bytes_read = 0; - - if ((data->inside_idat) && (data->idat_remain == 0)) - { -@@ -175,7 +176,14 @@ grub_png_get_byte (struct grub_png_data *data) - } - - r = 0; -- grub_file_read (data->file, &r, 1); -+ bytes_read = grub_file_read (data->file, &r, 1); -+ -+ if (bytes_read != 1) -+ { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "png: unexpected end of data"); -+ return 0; -+ } - - if (data->inside_idat) - data->idat_remain--; -@@ -231,15 +239,16 @@ grub_png_decode_image_palette (struct grub_png_data *data, - if (len == 0) - return GRUB_ERR_NONE; - -- for (i = 0; 3 * i < len && i < 256; i++) -+ grub_errno = GRUB_ERR_NONE; -+ for (i = 0; 3 * i < len && i < 256 && grub_errno == GRUB_ERR_NONE; i++) - for (j = 0; j < 3; j++) - data->palette[i][j] = grub_png_get_byte (data); -- for (i *= 3; i < len; i++) -+ for (i *= 3; i < len && grub_errno == GRUB_ERR_NONE; i++) - grub_png_get_byte (data); - - grub_png_get_dword (data); - -- return GRUB_ERR_NONE; -+ return grub_errno; - } - - static grub_err_t -@@ -256,9 +265,13 @@ grub_png_decode_image_header (struct grub_png_data *data) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: invalid image size"); - - color_bits = grub_png_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - data->is_16bit = (color_bits == 16); - - color_type = grub_png_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - /* According to PNG spec, no other types are valid. */ - if ((color_type & ~(PNG_COLOR_MASK_ALPHA | PNG_COLOR_MASK_COLOR)) -@@ -340,14 +353,20 @@ grub_png_decode_image_header (struct grub_png_data *data) - if (grub_png_get_byte (data) != PNG_COMPRESSION_BASE) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "png: compression method not supported"); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - if (grub_png_get_byte (data) != PNG_FILTER_TYPE_BASE) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "png: filter method not supported"); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - if (grub_png_get_byte (data) != PNG_INTERLACE_NONE) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "png: interlace method not supported"); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - /* Skip crc checksum. */ - grub_png_get_dword (data); -@@ -449,7 +468,7 @@ grub_png_get_huff_code (struct grub_png_data *data, struct huff_table *ht) - int code, i; - - code = 0; -- for (i = 0; i < ht->max_length; i++) -+ for (i = 0; i < ht->max_length && grub_errno == GRUB_ERR_NONE; i++) - { - code = (code << 1) + grub_png_get_bits (data, 1); - if (code < ht->maxval[i]) -@@ -504,8 +523,14 @@ grub_png_init_dynamic_block (struct grub_png_data *data) - grub_uint8_t lens[DEFLATE_HCLEN_MAX]; - - nl = DEFLATE_HLIT_BASE + grub_png_get_bits (data, 5); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - nd = DEFLATE_HDIST_BASE + grub_png_get_bits (data, 5); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - nb = DEFLATE_HCLEN_BASE + grub_png_get_bits (data, 4); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - if ((nl > DEFLATE_HLIT_MAX) || (nd > DEFLATE_HDIST_MAX) || - (nb > DEFLATE_HCLEN_MAX)) -@@ -533,7 +558,7 @@ grub_png_init_dynamic_block (struct grub_png_data *data) - data->dist_offset); - - prev = 0; -- for (i = 0; i < nl + nd; i++) -+ for (i = 0; i < nl + nd && grub_errno == GRUB_ERR_NONE; i++) - { - int n, code; - struct huff_table *ht; -@@ -721,17 +746,21 @@ grub_png_read_dynamic_block (struct grub_png_data *data) - len = cplens[n]; - if (cplext[n]) - len += grub_png_get_bits (data, cplext[n]); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - n = grub_png_get_huff_code (data, &data->dist_table); - dist = cpdist[n]; - if (cpdext[n]) - dist += grub_png_get_bits (data, cpdext[n]); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - pos = data->wp - dist; - if (pos < 0) - pos += WSIZE; - -- while (len > 0) -+ while (len > 0 && grub_errno == GRUB_ERR_NONE) - { - data->slide[data->wp] = data->slide[pos]; - grub_png_output_byte (data, data->slide[data->wp]); -@@ -759,7 +788,11 @@ grub_png_decode_image_data (struct grub_png_data *data) - int final; - - cmf = grub_png_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - flg = grub_png_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - if ((cmf & 0xF) != Z_DEFLATED) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, -@@ -774,7 +807,11 @@ grub_png_decode_image_data (struct grub_png_data *data) - int block_type; - - final = grub_png_get_bits (data, 1); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - block_type = grub_png_get_bits (data, 2); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - switch (block_type) - { -@@ -790,7 +827,7 @@ grub_png_decode_image_data (struct grub_png_data *data) - grub_png_get_byte (data); - grub_png_get_byte (data); - -- for (i = 0; i < len; i++) -+ for (i = 0; i < len && grub_errno == GRUB_ERR_NONE; i++) - grub_png_output_byte (data, grub_png_get_byte (data)); - - break; -@@ -1045,6 +1082,8 @@ grub_png_decode_png (struct grub_png_data *data) - - len = grub_png_get_dword (data); - type = grub_png_get_dword (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ break; - data->next_offset = data->file->offset + len + 4; - - switch (type) diff --git a/0220-video-readers-png-Refuse-to-handle-multiple-image-he.patch b/0220-video-readers-png-Refuse-to-handle-multiple-image-he.patch deleted file mode 100644 index 9168fe58fec6248b06b225202da38e8fcf92bd6b..0000000000000000000000000000000000000000 --- a/0220-video-readers-png-Refuse-to-handle-multiple-image-he.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 6 Jul 2021 14:13:40 +1000 -Subject: [PATCH] video/readers/png: Refuse to handle multiple image headers - -This causes the bitmap to be leaked. Do not permit multiple image headers. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit 8ce433557adeadbc46429aabb9f850b02ad2bdfb) ---- - grub-core/video/readers/png.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c -index e2a6b1cf3c..8955b8ecfd 100644 ---- a/grub-core/video/readers/png.c -+++ b/grub-core/video/readers/png.c -@@ -258,6 +258,9 @@ grub_png_decode_image_header (struct grub_png_data *data) - int color_bits; - enum grub_video_blit_format blt; - -+ if (data->image_width || data->image_height) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "png: two image headers found"); -+ - data->image_width = grub_png_get_dword (data); - data->image_height = grub_png_get_dword (data); - diff --git a/0221-video-readers-png-Drop-greyscale-support-to-fix-heap.patch b/0221-video-readers-png-Drop-greyscale-support-to-fix-heap.patch deleted file mode 100644 index 4529cb8e3af8e6dba4d41ccaa9113b7788c4a6b7..0000000000000000000000000000000000000000 --- a/0221-video-readers-png-Drop-greyscale-support-to-fix-heap.patch +++ /dev/null @@ -1,170 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 6 Jul 2021 18:51:35 +1000 -Subject: [PATCH] video/readers/png: Drop greyscale support to fix heap - out-of-bounds write - -A 16-bit greyscale PNG without alpha is processed in the following loop: - - for (i = 0; i < (data->image_width * data->image_height); - i++, d1 += 4, d2 += 2) - { - d1[R3] = d2[1]; - d1[G3] = d2[1]; - d1[B3] = d2[1]; - } - -The increment of d1 is wrong. d1 is incremented by 4 bytes per iteration, -but there are only 3 bytes allocated for storage. This means that image -data will overwrite somewhat-attacker-controlled parts of memory - 3 bytes -out of every 4 following the end of the image. - -This has existed since greyscale support was added in 2013 in commit -3ccf16dff98f (grub-core/video/readers/png.c: Support grayscale). - -Saving starfield.png as a 16-bit greyscale image without alpha in the gimp -and attempting to load it causes grub-emu to crash - I don't think this code -has ever worked. - -Delete all PNG greyscale support. - -Fixes: CVE-2021-3695 - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit 0e1d163382669bd734439d8864ee969616d971d9) -[rharwood: context conflict] -Signed-off-by: Robbie Harwood ---- - grub-core/video/readers/png.c | 85 +++---------------------------------------- - 1 file changed, 6 insertions(+), 79 deletions(-) - -diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c -index 8955b8ecfd..a3161e25b6 100644 ---- a/grub-core/video/readers/png.c -+++ b/grub-core/video/readers/png.c -@@ -100,7 +100,7 @@ struct grub_png_data - - unsigned image_width, image_height; - int bpp, is_16bit; -- int raw_bytes, is_gray, is_alpha, is_palette; -+ int raw_bytes, is_alpha, is_palette; - int row_bytes, color_bits; - grub_uint8_t *image_data; - -@@ -296,13 +296,13 @@ grub_png_decode_image_header (struct grub_png_data *data) - data->bpp = 3; - else - { -- data->is_gray = 1; -- data->bpp = 1; -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "png: color type not supported"); - } - - if ((color_bits != 8) && (color_bits != 16) - && (color_bits != 4 -- || !(data->is_gray || data->is_palette))) -+ || !data->is_palette)) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "png: bit depth must be 8 or 16"); - -@@ -331,7 +331,7 @@ grub_png_decode_image_header (struct grub_png_data *data) - } - - #ifndef GRUB_CPU_WORDS_BIGENDIAN -- if (data->is_16bit || data->is_gray || data->is_palette) -+ if (data->is_16bit || data->is_palette) - #endif - { - data->image_data = grub_calloc (data->image_height, data->row_bytes); -@@ -899,27 +899,8 @@ grub_png_convert_image (struct grub_png_data *data) - int shift; - int mask = (1 << data->color_bits) - 1; - unsigned j; -- if (data->is_gray) -- { -- /* Generic formula is -- (0xff * i) / ((1U << data->color_bits) - 1) -- but for allowed bit depth of 1, 2 and for it's -- equivalent to -- (0xff / ((1U << data->color_bits) - 1)) * i -- Precompute the multipliers to avoid division. -- */ - -- const grub_uint8_t multipliers[5] = { 0xff, 0xff, 0x55, 0x24, 0x11 }; -- for (i = 0; i < (1U << data->color_bits); i++) -- { -- grub_uint8_t col = multipliers[data->color_bits] * i; -- palette[i][0] = col; -- palette[i][1] = col; -- palette[i][2] = col; -- } -- } -- else -- grub_memcpy (palette, data->palette, 3 << data->color_bits); -+ grub_memcpy (palette, data->palette, 3 << data->color_bits); - d1c = d1; - d2c = d2; - for (j = 0; j < data->image_height; j++, d1c += data->image_width * 3, -@@ -956,60 +937,6 @@ grub_png_convert_image (struct grub_png_data *data) - } - return; - } -- -- if (data->is_gray) -- { -- switch (data->bpp) -- { -- case 4: -- /* 16-bit gray with alpha. */ -- for (i = 0; i < (data->image_width * data->image_height); -- i++, d1 += 4, d2 += 4) -- { -- d1[R4] = d2[3]; -- d1[G4] = d2[3]; -- d1[B4] = d2[3]; -- d1[A4] = d2[1]; -- } -- break; -- case 2: -- if (data->is_16bit) -- /* 16-bit gray without alpha. */ -- { -- for (i = 0; i < (data->image_width * data->image_height); -- i++, d1 += 4, d2 += 2) -- { -- d1[R3] = d2[1]; -- d1[G3] = d2[1]; -- d1[B3] = d2[1]; -- } -- } -- else -- /* 8-bit gray with alpha. */ -- { -- for (i = 0; i < (data->image_width * data->image_height); -- i++, d1 += 4, d2 += 2) -- { -- d1[R4] = d2[1]; -- d1[G4] = d2[1]; -- d1[B4] = d2[1]; -- d1[A4] = d2[0]; -- } -- } -- break; -- /* 8-bit gray without alpha. */ -- case 1: -- for (i = 0; i < (data->image_width * data->image_height); -- i++, d1 += 3, d2++) -- { -- d1[R3] = d2[0]; -- d1[G3] = d2[0]; -- d1[B3] = d2[0]; -- } -- break; -- } -- return; -- } - - { - /* Only copy the upper 8 bit. */ diff --git a/0222-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch b/0222-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch deleted file mode 100644 index 51dddfe5f518c3a43eba5774e4ed9553b8873974..0000000000000000000000000000000000000000 --- a/0222-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 6 Jul 2021 23:25:07 +1000 -Subject: [PATCH] video/readers/png: Avoid heap OOB R/W inserting huff table - items - -In fuzzing we observed crashes where a code would attempt to be inserted -into a huffman table before the start, leading to a set of heap OOB reads -and writes as table entries with negative indices were shifted around and -the new code written in. - -Catch the case where we would underflow the array and bail. - -Fixes: CVE-2021-3696 - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit 1ae9a91d42cb40da8a6f11fac65541858e340afa) ---- - grub-core/video/readers/png.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c -index a3161e25b6..d7ed5aa6cf 100644 ---- a/grub-core/video/readers/png.c -+++ b/grub-core/video/readers/png.c -@@ -438,6 +438,13 @@ grub_png_insert_huff_item (struct huff_table *ht, int code, int len) - for (i = len; i < ht->max_length; i++) - n += ht->maxval[i]; - -+ if (n > ht->num_values) -+ { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "png: out of range inserting huffman table item"); -+ return; -+ } -+ - for (i = 0; i < n; i++) - ht->values[ht->num_values - i] = ht->values[ht->num_values - i - 1]; - diff --git a/0223-video-readers-png-Sanity-check-some-huffman-codes.patch b/0223-video-readers-png-Sanity-check-some-huffman-codes.patch deleted file mode 100644 index c9cef259be983100b9db4a0b80d7bcafecab7d35..0000000000000000000000000000000000000000 --- a/0223-video-readers-png-Sanity-check-some-huffman-codes.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 6 Jul 2021 19:19:11 +1000 -Subject: [PATCH] video/readers/png: Sanity check some huffman codes - -ASAN picked up two OOB global reads: we weren't checking if some code -values fit within the cplens or cpdext arrays. Check and throw an error -if not. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit c3a8ab0cbd24153ec7b1f84a96ddfdd72ef8d117) ---- - grub-core/video/readers/png.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/grub-core/video/readers/png.c b/grub-core/video/readers/png.c -index d7ed5aa6cf..7f2ba7849b 100644 ---- a/grub-core/video/readers/png.c -+++ b/grub-core/video/readers/png.c -@@ -753,6 +753,9 @@ grub_png_read_dynamic_block (struct grub_png_data *data) - int len, dist, pos; - - n -= 257; -+ if (((unsigned int) n) >= ARRAY_SIZE (cplens)) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "png: invalid huff code"); - len = cplens[n]; - if (cplext[n]) - len += grub_png_get_bits (data, cplext[n]); -@@ -760,6 +763,9 @@ grub_png_read_dynamic_block (struct grub_png_data *data) - return grub_errno; - - n = grub_png_get_huff_code (data, &data->dist_table); -+ if (((unsigned int) n) >= ARRAY_SIZE (cpdist)) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "png: invalid huff code"); - dist = cpdist[n]; - if (cpdext[n]) - dist += grub_png_get_bits (data, cpdext[n]); diff --git a/0224-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch b/0224-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch deleted file mode 100644 index 54918163af636a361dc0c7042bc429daed6d4e11..0000000000000000000000000000000000000000 --- a/0224-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch +++ /dev/null @@ -1,255 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 28 Jun 2021 14:16:14 +1000 -Subject: [PATCH] video/readers/jpeg: Abort sooner if a read operation fails - -Fuzzing revealed some inputs that were taking a long time, potentially -forever, because they did not bail quickly upon encountering an I/O error. - -Try to catch I/O errors sooner and bail out. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit ab2e5d2e4bff488bbb557ed435a61ae102ef9f0c) ---- - grub-core/video/readers/jpeg.c | 86 ++++++++++++++++++++++++++++++++++-------- - 1 file changed, 70 insertions(+), 16 deletions(-) - -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index e31602f766..10225abd53 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -109,9 +109,17 @@ static grub_uint8_t - grub_jpeg_get_byte (struct grub_jpeg_data *data) - { - grub_uint8_t r; -+ grub_ssize_t bytes_read; - - r = 0; -- grub_file_read (data->file, &r, 1); -+ bytes_read = grub_file_read (data->file, &r, 1); -+ -+ if (bytes_read != 1) -+ { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: unexpected end of data"); -+ return 0; -+ } - - return r; - } -@@ -120,9 +128,17 @@ static grub_uint16_t - grub_jpeg_get_word (struct grub_jpeg_data *data) - { - grub_uint16_t r; -+ grub_ssize_t bytes_read; - - r = 0; -- grub_file_read (data->file, &r, sizeof (grub_uint16_t)); -+ bytes_read = grub_file_read (data->file, &r, sizeof (grub_uint16_t)); -+ -+ if (bytes_read != sizeof (grub_uint16_t)) -+ { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: unexpected end of data"); -+ return 0; -+ } - - return grub_be_to_cpu16 (r); - } -@@ -135,6 +151,11 @@ grub_jpeg_get_bit (struct grub_jpeg_data *data) - if (data->bit_mask == 0) - { - data->bit_save = grub_jpeg_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: file read error"); -+ return 0; -+ } - if (data->bit_save == JPEG_ESC_CHAR) - { - if (grub_jpeg_get_byte (data) != 0) -@@ -143,6 +164,11 @@ grub_jpeg_get_bit (struct grub_jpeg_data *data) - "jpeg: invalid 0xFF in data stream"); - return 0; - } -+ if (grub_errno != GRUB_ERR_NONE) -+ { -+ grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: file read error"); -+ return 0; -+ } - } - data->bit_mask = 0x80; - } -@@ -161,7 +187,7 @@ grub_jpeg_get_number (struct grub_jpeg_data *data, int num) - return 0; - - msb = value = grub_jpeg_get_bit (data); -- for (i = 1; i < num; i++) -+ for (i = 1; i < num && grub_errno == GRUB_ERR_NONE; i++) - value = (value << 1) + (grub_jpeg_get_bit (data) != 0); - if (!msb) - value += 1 - (1 << num); -@@ -202,6 +228,8 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) - while (data->file->offset + sizeof (count) + 1 <= next_marker) - { - id = grub_jpeg_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - ac = (id >> 4) & 1; - id &= 0xF; - if (id > 1) -@@ -252,6 +280,8 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) - - next_marker = data->file->offset; - next_marker += grub_jpeg_get_word (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - - if (next_marker > data->file->size) - { -@@ -263,6 +293,8 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data) - <= next_marker) - { - id = grub_jpeg_get_byte (data); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - if (id >= 0x10) /* Upper 4-bit is precision. */ - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: only 8-bit precision is supported"); -@@ -294,6 +326,9 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) - next_marker = data->file->offset; - next_marker += grub_jpeg_get_word (data); - -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; -+ - if (grub_jpeg_get_byte (data) != 8) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: only 8-bit precision is supported"); -@@ -319,6 +354,8 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index"); - - ss = grub_jpeg_get_byte (data); /* Sampling factor. */ -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - if (!id) - { - grub_uint8_t vs, hs; -@@ -498,7 +535,7 @@ grub_jpeg_idct_transform (jpeg_data_unit_t du) - } - } - --static void -+static grub_err_t - grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) - { - int h1, h2, qt; -@@ -513,6 +550,9 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) - data->dc_value[id] += - grub_jpeg_get_number (data, grub_jpeg_get_huff_code (data, h1)); - -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; -+ - du[0] = data->dc_value[id] * (int) data->quan_table[qt][0]; - pos = 1; - while (pos < ARRAY_SIZE (data->quan_table[qt])) -@@ -527,11 +567,13 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) - num >>= 4; - pos += num; - -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; -+ - if (pos >= ARRAY_SIZE (jpeg_zigzag_order)) - { -- grub_error (GRUB_ERR_BAD_FILE_TYPE, -- "jpeg: invalid position in zigzag order!?"); -- return; -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: invalid position in zigzag order!?"); - } - - du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos]; -@@ -539,6 +581,7 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du) - } - - grub_jpeg_idct_transform (du); -+ return GRUB_ERR_NONE; - } - - static void -@@ -597,7 +640,8 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) - data_offset += grub_jpeg_get_word (data); - - cc = grub_jpeg_get_byte (data); -- -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - if (cc != 3 && cc != 1) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: component count must be 1 or 3"); -@@ -610,7 +654,8 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) - id = grub_jpeg_get_byte (data) - 1; - if ((id < 0) || (id >= 3)) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid index"); -- -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - ht = grub_jpeg_get_byte (data); - data->comp_index[id][1] = (ht >> 4); - data->comp_index[id][2] = (ht & 0xF) + 2; -@@ -618,11 +663,14 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) - if ((data->comp_index[id][1] < 0) || (data->comp_index[id][1] > 3) || - (data->comp_index[id][2] < 0) || (data->comp_index[id][2] > 3)) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid hufftable index"); -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - } - - grub_jpeg_get_byte (data); /* Skip 3 unused bytes. */ - grub_jpeg_get_word (data); -- -+ if (grub_errno != GRUB_ERR_NONE) -+ return grub_errno; - if (data->file->offset != data_offset) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos"); - -@@ -640,6 +688,7 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) - { - unsigned c1, vb, hb, nr1, nc1; - int rst = data->dri; -+ grub_err_t err = GRUB_ERR_NONE; - - vb = 8 << data->log_vs; - hb = 8 << data->log_hs; -@@ -660,17 +709,22 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) - - for (r2 = 0; r2 < (1U << data->log_vs); r2++) - for (c2 = 0; c2 < (1U << data->log_hs); c2++) -- grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]); -+ { -+ err = grub_jpeg_decode_du (data, 0, data->ydu[r2 * 2 + c2]); -+ if (err != GRUB_ERR_NONE) -+ return err; -+ } - - if (data->color_components >= 3) - { -- grub_jpeg_decode_du (data, 1, data->cbdu); -- grub_jpeg_decode_du (data, 2, data->crdu); -+ err = grub_jpeg_decode_du (data, 1, data->cbdu); -+ if (err != GRUB_ERR_NONE) -+ return err; -+ err = grub_jpeg_decode_du (data, 2, data->crdu); -+ if (err != GRUB_ERR_NONE) -+ return err; - } - -- if (grub_errno) -- return grub_errno; -- - nr2 = (data->r1 == nr1 - 1) ? (data->image_height - data->r1 * vb) : vb; - nc2 = (c1 == nc1 - 1) ? (data->image_width - c1 * hb) : hb; - diff --git a/0225-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch b/0225-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch deleted file mode 100644 index 199ec32cd18288b2f3302b7e34eff77dca601919..0000000000000000000000000000000000000000 --- a/0225-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 28 Jun 2021 14:16:58 +1000 -Subject: [PATCH] video/readers/jpeg: Do not reallocate a given huff table - -Fix a memory leak where an invalid file could cause us to reallocate -memory for a huffman table we had already allocated memory for. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit bc06e12b4de55cc6f926af9f064170c82b1403e9) ---- - grub-core/video/readers/jpeg.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index 10225abd53..caa211f06d 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -245,6 +245,9 @@ grub_jpeg_decode_huff_table (struct grub_jpeg_data *data) - n += count[i]; - - id += ac * 2; -+ if (data->huff_value[id] != NULL) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: attempt to reallocate huffman table"); - data->huff_value[id] = grub_malloc (n); - if (grub_errno) - return grub_errno; diff --git a/0226-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch b/0226-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch deleted file mode 100644 index 179238bec68c506adb1e810e6e2e232cd5b877ab..0000000000000000000000000000000000000000 --- a/0226-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 28 Jun 2021 14:25:17 +1000 -Subject: [PATCH] video/readers/jpeg: Refuse to handle multiple start of - streams - -An invalid file could contain multiple start of stream blocks, which -would cause us to reallocate and leak our bitmap. Refuse to handle -multiple start of streams. - -Additionally, fix a grub_error() call formatting. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit f3a854def3e281b7ad4bbea730cd3046de1da52f) ---- - grub-core/video/readers/jpeg.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index caa211f06d..1df1171d78 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -677,6 +677,9 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data) - if (data->file->offset != data_offset) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: extra byte in sos"); - -+ if (*data->bitmap) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: too many start of scan blocks"); -+ - if (grub_video_bitmap_create (data->bitmap, data->image_width, - data->image_height, - GRUB_VIDEO_BLIT_FORMAT_RGB_888)) -@@ -699,8 +702,8 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) - nc1 = (data->image_width + hb - 1) >> (3 + data->log_hs); - - if (data->bitmap_ptr == NULL) -- return grub_error(GRUB_ERR_BAD_FILE_TYPE, -- "jpeg: attempted to decode data before start of stream"); -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: attempted to decode data before start of stream"); - - for (; data->r1 < nr1 && (!data->dri || rst); - data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3) diff --git a/0227-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch b/0227-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch deleted file mode 100644 index 99eeb62109961af48de16dbdb80b1b59b4fb27b3..0000000000000000000000000000000000000000 --- a/0227-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Wed, 7 Jul 2021 15:38:19 +1000 -Subject: [PATCH] video/readers/jpeg: Block int underflow -> wild pointer write - -Certain 1 px wide images caused a wild pointer write in -grub_jpeg_ycrcb_to_rgb(). This was caused because in grub_jpeg_decode_data(), -we have the following loop: - -for (; data->r1 < nr1 && (!data->dri || rst); - data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3) - -We did not check if vb * width >= hb * nc1. - -On a 64-bit platform, if that turns out to be negative, it will underflow, -be interpreted as unsigned 64-bit, then be added to the 64-bit pointer, so -we see data->bitmap_ptr jump, e.g.: - -0x6180_0000_0480 to -0x6181_0000_0498 - ^ - ~--- carry has occurred and this pointer is now far away from - any object. - -On a 32-bit platform, it will decrement the pointer, creating a pointer -that won't crash but will overwrite random data. - -Catch the underflow and error out. - -Fixes: CVE-2021-3697 - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit 41aeb2004db9924fecd9f2dd64bc2a5a5594a4b5) ---- - grub-core/video/readers/jpeg.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c -index 1df1171d78..2da04094b3 100644 ---- a/grub-core/video/readers/jpeg.c -+++ b/grub-core/video/readers/jpeg.c -@@ -705,6 +705,10 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data) - return grub_error (GRUB_ERR_BAD_FILE_TYPE, - "jpeg: attempted to decode data before start of stream"); - -+ if (vb * data->image_width <= hb * nc1) -+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, -+ "jpeg: cannot decode image with these dimensions"); -+ - for (; data->r1 < nr1 && (!data->dri || rst); - data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3) - for (c1 = 0; c1 < nc1 && (!data->dri || rst); diff --git a/0228-normal-charset-Fix-array-out-of-bounds-formatting-un.patch b/0228-normal-charset-Fix-array-out-of-bounds-formatting-un.patch deleted file mode 100644 index 6e64ed86bff5b50e8653850375b9cf7f5eaff11c..0000000000000000000000000000000000000000 --- a/0228-normal-charset-Fix-array-out-of-bounds-formatting-un.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 13 Jul 2021 13:24:38 +1000 -Subject: [PATCH] normal/charset: Fix array out-of-bounds formatting unicode - for display - -In some cases attempting to display arbitrary binary strings leads -to ASAN splats reading the widthspec array out of bounds. - -Check the index. If it would be out of bounds, return a width of 1. -I don't know if that's strictly correct, but we're not really expecting -great display of arbitrary binary data, and it's certainly not worse than -an OOB read. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit fdf32abc7a3928852422c0f291d8cd1dd6b34a8d) ---- - grub-core/normal/charset.c | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c -index 4dfcc31078..7a5a7c153c 100644 ---- a/grub-core/normal/charset.c -+++ b/grub-core/normal/charset.c -@@ -395,6 +395,8 @@ grub_unicode_estimate_width (const struct grub_unicode_glyph *c) - { - if (grub_unicode_get_comb_type (c->base)) - return 0; -+ if (((unsigned long) (c->base >> 3)) >= ARRAY_SIZE (widthspec)) -+ return 1; - if (widthspec[c->base >> 3] & (1 << (c->base & 7))) - return 2; - else diff --git a/0229-net-netbuff-Block-overly-large-netbuff-allocs.patch b/0229-net-netbuff-Block-overly-large-netbuff-allocs.patch deleted file mode 100644 index 2e10d49e5f68dbc8b52274992d91bae0f6f314f8..0000000000000000000000000000000000000000 --- a/0229-net-netbuff-Block-overly-large-netbuff-allocs.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 8 Mar 2022 23:47:46 +1100 -Subject: [PATCH] net/netbuff: Block overly large netbuff allocs - -A netbuff shouldn't be too huge. It's bounded by MTU and TCP segment -reassembly. - -This helps avoid some bugs (and provides a spot to instrument to catch -them at their source). - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit ee9591103004cd13b4efadda671536090ca7fd57) ---- - grub-core/net/netbuff.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/grub-core/net/netbuff.c b/grub-core/net/netbuff.c -index dbeeefe478..d5e9e9a0d7 100644 ---- a/grub-core/net/netbuff.c -+++ b/grub-core/net/netbuff.c -@@ -79,10 +79,23 @@ grub_netbuff_alloc (grub_size_t len) - - COMPILE_TIME_ASSERT (NETBUFF_ALIGN % sizeof (grub_properly_aligned_t) == 0); - -+ /* -+ * The largest size of a TCP packet is 64 KiB, and everything else -+ * should be a lot smaller - most MTUs are 1500 or less. Cap data -+ * size at 64 KiB + a buffer. -+ */ -+ if (len > 0xffffUL + 0x1000UL) -+ { -+ grub_error (GRUB_ERR_BUG, -+ "attempted to allocate a packet that is too big"); -+ return NULL; -+ } -+ - if (len < NETBUFFMINLEN) - len = NETBUFFMINLEN; - - len = ALIGN_UP (len, NETBUFF_ALIGN); -+ - #ifdef GRUB_MACHINE_EMU - data = grub_malloc (len + sizeof (*nb)); - #else diff --git a/0230-net-ip-Do-IP-fragment-maths-safely.patch b/0230-net-ip-Do-IP-fragment-maths-safely.patch deleted file mode 100644 index 118448d15de0bddff01b6be14eb4ac539bb3fdf9..0000000000000000000000000000000000000000 --- a/0230-net-ip-Do-IP-fragment-maths-safely.patch +++ /dev/null @@ -1,44 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 20 Dec 2021 19:41:21 +1100 -Subject: [PATCH] net/ip: Do IP fragment maths safely - -This avoids an underflow and subsequent unpleasantness. - -Fixes: CVE-2022-28733 - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit eb74e5743ca7e18a5e75c392fe0b21d1549a1936) ---- - grub-core/net/ip.c | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c -index ce6bdc75c6..cf74f1f794 100644 ---- a/grub-core/net/ip.c -+++ b/grub-core/net/ip.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - - struct iphdr { -@@ -551,7 +552,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb, - { - rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK) - + (nb->tail - nb->data)); -- rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t)); -+ -+ if (grub_sub (rsm->total_len, (iph->verhdrlen & 0xf) * sizeof (grub_uint32_t), -+ &rsm->total_len)) -+ { -+ grub_dprintf ("net", "IP reassembly size underflow\n"); -+ return GRUB_ERR_NONE; -+ } -+ - rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len); - if (!rsm->asm_netbuff) - { diff --git a/0231-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch b/0231-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch deleted file mode 100644 index 19701b6aa5a51a1ef45c65391cec21c48849a2b2..0000000000000000000000000000000000000000 --- a/0231-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Thu, 16 Sep 2021 01:29:54 +1000 -Subject: [PATCH] net/dns: Fix double-free addresses on corrupt DNS response - -grub_net_dns_lookup() takes as inputs a pointer to an array of addresses -("addresses") for the given name, and pointer to a number of addresses -("naddresses"). grub_net_dns_lookup() is responsible for allocating -"addresses", and the caller is responsible for freeing it if -"naddresses" > 0. - -The DNS recv_hook will sometimes set and free the addresses array, -for example if the packet is too short: - - if (ptr + 10 >= nb->tail) - { - if (!*data->naddresses) - grub_free (*data->addresses); - grub_netbuff_free (nb); - return GRUB_ERR_NONE; - } - -Later on the nslookup command code unconditionally frees the "addresses" -array. Normally this is fine: the array is either populated with valid -data or is NULL. But in these sorts of error cases it is neither NULL -nor valid and we get a double-free. - -Only free "addresses" if "naddresses" > 0. - -It looks like the other use of grub_net_dns_lookup() is not affected. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit eb2e69fcf51307757e43f55ee8c9354d1ee42dd1) ---- - grub-core/net/dns.c | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c -index 906ec7d678..135faac035 100644 ---- a/grub-core/net/dns.c -+++ b/grub-core/net/dns.c -@@ -667,9 +667,11 @@ grub_cmd_nslookup (struct grub_command *cmd __attribute__ ((unused)), - grub_net_addr_to_str (&addresses[i], buf); - grub_printf ("%s\n", buf); - } -- grub_free (addresses); - if (naddresses) -- return GRUB_ERR_NONE; -+ { -+ grub_free (addresses); -+ return GRUB_ERR_NONE; -+ } - return grub_error (GRUB_ERR_NET_NO_DOMAIN, N_("no DNS record found")); - } - diff --git a/0232-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch b/0232-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch deleted file mode 100644 index ab0d4712ec9df899b58de29a8935aa1fe3cdd8cb..0000000000000000000000000000000000000000 --- a/0232-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch +++ /dev/null @@ -1,71 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 20 Dec 2021 21:55:43 +1100 -Subject: [PATCH] net/dns: Don't read past the end of the string we're checking - against - -I don't really understand what's going on here but fuzzing found -a bug where we read past the end of check_with. That's a C string, -so use grub_strlen() to make sure we don't overread it. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit 6a97b3f4b1d5173aa516edc6dedbc63de7306d21) ---- - grub-core/net/dns.c | 19 ++++++++++++++++--- - 1 file changed, 16 insertions(+), 3 deletions(-) - -diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c -index 135faac035..17961a9f18 100644 ---- a/grub-core/net/dns.c -+++ b/grub-core/net/dns.c -@@ -146,11 +146,18 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head, - int *length, char *set) - { - const char *readable_ptr = check_with; -+ int readable_len; - const grub_uint8_t *ptr; - char *optr = set; - int bytes_processed = 0; - if (length) - *length = 0; -+ -+ if (readable_ptr != NULL) -+ readable_len = grub_strlen (readable_ptr); -+ else -+ readable_len = 0; -+ - for (ptr = name_at; ptr < tail && bytes_processed < tail - head + 2; ) - { - /* End marker. */ -@@ -172,13 +179,16 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head, - ptr = head + (((ptr[0] & 0x3f) << 8) | ptr[1]); - continue; - } -- if (readable_ptr && grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0) -+ if (readable_ptr != NULL && (*ptr > readable_len || grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0)) - return 0; - if (grub_memchr (ptr + 1, 0, *ptr) - || grub_memchr (ptr + 1, '.', *ptr)) - return 0; - if (readable_ptr) -- readable_ptr += *ptr; -+ { -+ readable_ptr += *ptr; -+ readable_len -= *ptr; -+ } - if (readable_ptr && *readable_ptr != '.' && *readable_ptr != 0) - return 0; - bytes_processed += *ptr + 1; -@@ -192,7 +202,10 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head, - if (optr) - *optr++ = '.'; - if (readable_ptr && *readable_ptr) -- readable_ptr++; -+ { -+ readable_ptr++; -+ readable_len--; -+ } - ptr += *ptr + 1; - } - return 0; diff --git a/0233-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch b/0233-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch deleted file mode 100644 index 3ff7b6bb645096c5307ecab0c6c54e696bf90892..0000000000000000000000000000000000000000 --- a/0233-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch +++ /dev/null @@ -1,112 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Mon, 20 Sep 2021 01:12:24 +1000 -Subject: [PATCH] net/tftp: Prevent a UAF and double-free from a failed seek - -A malicious tftp server can cause UAFs and a double free. - -An attempt to read from a network file is handled by grub_net_fs_read(). If -the read is at an offset other than the current offset, grub_net_seek_real() -is invoked. - -In grub_net_seek_real(), if a backwards seek cannot be satisfied from the -currently received packets, and the underlying transport does not provide -a seek method, then grub_net_seek_real() will close and reopen the network -protocol layer. - -For tftp, the ->close() call goes to tftp_close() and frees the tftp_data_t -file->data. The file->data pointer is not nulled out after the free. - -If the ->open() call fails, the file->data will not be reallocated and will -continue point to a freed memory block. This could happen from a server -refusing to send the requisite ack to the new tftp request, for example. - -The seek and the read will then fail, but the grub_file continues to exist: -the failed seek does not necessarily cause the entire file to be thrown -away (e.g. where the file is checked to see if it is gzipped/lzio/xz/etc., -a read failure is interpreted as a decompressor passing on the file, not as -an invalidation of the entire grub_file_t structure). - -This means subsequent attempts to read or seek the file will use the old -file->data after free. Eventually, the file will be close()d again and -file->data will be freed again. - -Mark a net_fs file that doesn't reopen as broken. Do not permit read() or -close() on a broken file (seek is not exposed directly to the file API - -it is only called as part of read, so this blocks seeks as well). - -As an additional defence, null out the ->data pointer if tftp_open() fails. -That would have lead to a simple null pointer dereference rather than -a mess of UAFs. - -This may affect other protocols, I haven't checked. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit dada1dda695439bb55b2848dddc2d89843552f81) ---- - grub-core/net/net.c | 11 +++++++++-- - grub-core/net/tftp.c | 1 + - include/grub/net.h | 1 + - 3 files changed, 11 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/net.c b/grub-core/net/net.c -index 55aed92722..1001c611d1 100644 ---- a/grub-core/net/net.c -+++ b/grub-core/net/net.c -@@ -1625,7 +1625,8 @@ grub_net_fs_close (grub_file_t file) - grub_netbuff_free (file->device->net->packs.first->nb); - grub_net_remove_packet (file->device->net->packs.first); - } -- file->device->net->protocol->close (file); -+ if (!file->device->net->broken) -+ file->device->net->protocol->close (file); - grub_free (file->device->net->name); - return GRUB_ERR_NONE; - } -@@ -1847,7 +1848,10 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset) - file->device->net->stall = 0; - err = file->device->net->protocol->open (file, file->device->net->name); - if (err) -- return err; -+ { -+ file->device->net->broken = 1; -+ return err; -+ } - grub_net_fs_read_real (file, NULL, offset); - return grub_errno; - } -@@ -1856,6 +1860,9 @@ grub_net_seek_real (struct grub_file *file, grub_off_t offset) - static grub_ssize_t - grub_net_fs_read (grub_file_t file, char *buf, grub_size_t len) - { -+ if (file->device->net->broken) -+ return -1; -+ - if (file->offset != file->device->net->offset) - { - grub_err_t err; -diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c -index d54b13f09f..788ad1dc44 100644 ---- a/grub-core/net/tftp.c -+++ b/grub-core/net/tftp.c -@@ -408,6 +408,7 @@ tftp_open (struct grub_file *file, const char *filename) - { - grub_net_udp_close (data->sock); - grub_free (data); -+ file->data = NULL; - return grub_errno; - } - -diff --git a/include/grub/net.h b/include/grub/net.h -index 42af7de250..9e4898cc6b 100644 ---- a/include/grub/net.h -+++ b/include/grub/net.h -@@ -280,6 +280,7 @@ typedef struct grub_net - grub_fs_t fs; - int eof; - int stall; -+ int broken; - } *grub_net_t; - - extern grub_net_t (*EXPORT_VAR (grub_net_open)) (const char *name); diff --git a/0234-net-tftp-Avoid-a-trivial-UAF.patch b/0234-net-tftp-Avoid-a-trivial-UAF.patch deleted file mode 100644 index 4ec3b562813b26187622f58abaa3ae208f0d39c1..0000000000000000000000000000000000000000 --- a/0234-net-tftp-Avoid-a-trivial-UAF.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 18 Jan 2022 14:29:20 +1100 -Subject: [PATCH] net/tftp: Avoid a trivial UAF - -Under tftp errors, we print a tftp error message from the tftp header. -However, the tftph pointer is a pointer inside nb, the netbuff. Previously, -we were freeing the nb and then dereferencing it. Don't do that, use it -and then free it later. - -This isn't really _bad_ per se, especially as we're single-threaded, but -it trips up fuzzers. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit 956f4329cec23e4375182030ca9b2be631a61ba5) ---- - grub-core/net/tftp.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c -index 788ad1dc44..a95766dcbd 100644 ---- a/grub-core/net/tftp.c -+++ b/grub-core/net/tftp.c -@@ -251,9 +251,9 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)), - return GRUB_ERR_NONE; - case TFTP_ERROR: - data->have_oack = 1; -- grub_netbuff_free (nb); - grub_error (GRUB_ERR_IO, "%s", tftph->u.err.errmsg); - grub_error_save (&data->save_err); -+ grub_netbuff_free (nb); - return GRUB_ERR_NONE; - default: - grub_netbuff_free (nb); diff --git a/0235-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch b/0235-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch deleted file mode 100644 index 186f0c3d772648005616e55216e18d2c15e1f7e7..0000000000000000000000000000000000000000 --- a/0235-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 1 Mar 2022 23:14:15 +1100 -Subject: [PATCH] net/http: Do not tear down socket if it's already been torn - down - -It's possible for data->sock to get torn down in tcp error handling. -If we unconditionally tear it down again we will end up doing writes -to an offset of the NULL pointer when we go to tear it down again. - -Detect if it has been torn down and don't do it again. - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit ec233d3ecf995293304de443579aab5c46c49e85) ---- - grub-core/net/http.c | 5 +++-- - 1 file changed, 3 insertions(+), 2 deletions(-) - -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index 7f878b5615..19cb8768e3 100644 ---- a/grub-core/net/http.c -+++ b/grub-core/net/http.c -@@ -427,7 +427,7 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - return err; - } - -- for (i = 0; !data->headers_recv && i < 100; i++) -+ for (i = 0; data->sock && !data->headers_recv && i < 100; i++) - { - grub_net_tcp_retransmit (); - grub_net_poll_cards (300, &data->headers_recv); -@@ -435,7 +435,8 @@ http_establish (struct grub_file *file, grub_off_t offset, int initial) - - if (!data->headers_recv) - { -- grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); -+ if (data->sock) -+ grub_net_tcp_close (data->sock, GRUB_NET_TCP_ABORT); - if (data->err) - { - char *str = data->errmsg; diff --git a/0236-net-http-Fix-OOB-write-for-split-http-headers.patch b/0236-net-http-Fix-OOB-write-for-split-http-headers.patch deleted file mode 100644 index f22960b1de07e971bb5ac296191eb007554c696c..0000000000000000000000000000000000000000 --- a/0236-net-http-Fix-OOB-write-for-split-http-headers.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 8 Mar 2022 18:17:03 +1100 -Subject: [PATCH] net/http: Fix OOB write for split http headers - -GRUB has special code for handling an http header that is split -across two packets. - -The code tracks the end of line by looking for a "\n" byte. The -code for split headers has always advanced the pointer just past the -end of the line, whereas the code that handles unsplit headers does -not advance the pointer. This extra advance causes the length to be -one greater, which breaks an assumption in parse_line(), leading to -it writing a NUL byte one byte past the end of the buffer where we -reconstruct the line from the two packets. - -It's conceivable that an attacker controlled set of packets could -cause this to zero out the first byte of the "next" pointer of the -grub_mm_region structure following the current_line buffer. - -Do not advance the pointer in the split header case. - -Fixes: CVE-2022-28734 - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit e9fb459638811c12b0989dbf64e3e124974ef617) ---- - grub-core/net/http.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index 19cb8768e3..58546739a2 100644 ---- a/grub-core/net/http.c -+++ b/grub-core/net/http.c -@@ -193,9 +193,7 @@ http_receive (grub_net_tcp_socket_t sock __attribute__ ((unused)), - int have_line = 1; - char *t; - ptr = grub_memchr (nb->data, '\n', nb->tail - nb->data); -- if (ptr) -- ptr++; -- else -+ if (ptr == NULL) - { - have_line = 0; - ptr = (char *) nb->tail; diff --git a/0237-net-http-Error-out-on-headers-with-LF-without-CR.patch b/0237-net-http-Error-out-on-headers-with-LF-without-CR.patch deleted file mode 100644 index b73c1691570777e9b9c8692fb4be2598bc6391d3..0000000000000000000000000000000000000000 --- a/0237-net-http-Error-out-on-headers-with-LF-without-CR.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Daniel Axtens -Date: Tue, 8 Mar 2022 19:04:40 +1100 -Subject: [PATCH] net/http: Error out on headers with LF without CR - -In a similar vein to the previous patch, parse_line() would write -a NUL byte past the end of the buffer if there was an HTTP header -with a LF rather than a CRLF. - -RFC-2616 says: - - Many HTTP/1.1 header field values consist of words separated by LWS - or special characters. These special characters MUST be in a quoted - string to be used within a parameter value (as defined in section 3.6). - -We don't support quoted sections or continuation lines, etc. - -If we see an LF that's not part of a CRLF, bail out. - -Fixes: CVE-2022-28734 - -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit d232ad41ac4979a9de4d746e5fdff9caf0e303de) ---- - grub-core/net/http.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/grub-core/net/http.c b/grub-core/net/http.c -index 58546739a2..57d2721719 100644 ---- a/grub-core/net/http.c -+++ b/grub-core/net/http.c -@@ -69,7 +69,15 @@ parse_line (grub_file_t file, http_data_t data, char *ptr, grub_size_t len) - char *end = ptr + len; - while (end > ptr && *(end - 1) == '\r') - end--; -+ -+ /* LF without CR. */ -+ if (end == ptr + len) -+ { -+ data->errmsg = grub_strdup (_("invalid HTTP header - LF without CR")); -+ return GRUB_ERR_NONE; -+ } - *end = 0; -+ - /* Trailing CRLF. */ - if (data->in_chunk_len == 1) - { diff --git a/0238-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch b/0238-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch deleted file mode 100644 index 79df1c24997acbdabf666c016099a6d71d02bfe7..0000000000000000000000000000000000000000 --- a/0238-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch +++ /dev/null @@ -1,72 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sudhakar Kuppusamy -Date: Wed, 6 Apr 2022 18:03:37 +0530 -Subject: [PATCH] fs/f2fs: Do not read past the end of nat journal entries - -A corrupt f2fs file system could specify a nat journal entry count -that is beyond the maximum NAT_JOURNAL_ENTRIES. - -Check if the specified nat journal entry count before accessing the -array, and throw an error if it is too large. - -Signed-off-by: Sudhakar Kuppusamy -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit a3988cb3f0a108dd67ac127a79a4c8479d23334e) ---- - grub-core/fs/f2fs.c | 21 ++++++++++++++------- - 1 file changed, 14 insertions(+), 7 deletions(-) - -diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c -index 8a9992ca9e..63702214b0 100644 ---- a/grub-core/fs/f2fs.c -+++ b/grub-core/fs/f2fs.c -@@ -632,23 +632,27 @@ get_nat_journal (struct grub_f2fs_data *data) - return err; - } - --static grub_uint32_t --get_blkaddr_from_nat_journal (struct grub_f2fs_data *data, grub_uint32_t nid) -+static grub_err_t -+get_blkaddr_from_nat_journal (struct grub_f2fs_data *data, grub_uint32_t nid, -+ grub_uint32_t *blkaddr) - { - grub_uint16_t n = grub_le_to_cpu16 (data->nat_j.n_nats); -- grub_uint32_t blkaddr = 0; - grub_uint16_t i; - -+ if (n >= NAT_JOURNAL_ENTRIES) -+ return grub_error (GRUB_ERR_BAD_FS, -+ "invalid number of nat journal entries"); -+ - for (i = 0; i < n; i++) - { - if (grub_le_to_cpu32 (data->nat_j.entries[i].nid) == nid) - { -- blkaddr = grub_le_to_cpu32 (data->nat_j.entries[i].ne.block_addr); -+ *blkaddr = grub_le_to_cpu32 (data->nat_j.entries[i].ne.block_addr); - break; - } - } - -- return blkaddr; -+ return GRUB_ERR_NONE; - } - - static grub_uint32_t -@@ -656,10 +660,13 @@ get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid) - { - struct grub_f2fs_nat_block *nat_block; - grub_uint32_t seg_off, block_off, entry_off, block_addr; -- grub_uint32_t blkaddr; -+ grub_uint32_t blkaddr = 0; - grub_err_t err; - -- blkaddr = get_blkaddr_from_nat_journal (data, nid); -+ err = get_blkaddr_from_nat_journal (data, nid, &blkaddr); -+ if (err != GRUB_ERR_NONE) -+ return 0; -+ - if (blkaddr) - return blkaddr; - diff --git a/0239-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch b/0239-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch deleted file mode 100644 index 855e882670ccd0da8eb53a48cee0464dc508f6e9..0000000000000000000000000000000000000000 --- a/0239-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch +++ /dev/null @@ -1,132 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sudhakar Kuppusamy -Date: Wed, 6 Apr 2022 18:49:09 +0530 -Subject: [PATCH] fs/f2fs: Do not read past the end of nat bitmap - -A corrupt f2fs filesystem could have a block offset or a bitmap -offset that would cause us to read beyond the bounds of the nat -bitmap. - -Introduce the nat_bitmap_size member in grub_f2fs_data which holds -the size of nat bitmap. - -Set the size when loading the nat bitmap in nat_bitmap_ptr(), and -catch when an invalid offset would create a pointer past the end of -the allocated space. - -Check against the bitmap size in grub_f2fs_test_bit() test bit to avoid -reading past the end of the nat bitmap. - -Signed-off-by: Sudhakar Kuppusamy -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit 62d63d5e38c67a6e349148bf7cb87c560e935a7e) ---- - grub-core/fs/f2fs.c | 33 +++++++++++++++++++++++++++------ - 1 file changed, 27 insertions(+), 6 deletions(-) - -diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c -index 63702214b0..8898b235e0 100644 ---- a/grub-core/fs/f2fs.c -+++ b/grub-core/fs/f2fs.c -@@ -122,6 +122,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); - #define F2FS_INLINE_DOTS 0x10 /* File having implicit dot dentries. */ - - #define MAX_VOLUME_NAME 512 -+#define MAX_NAT_BITMAP_SIZE 3900 - - enum FILE_TYPE - { -@@ -183,7 +184,7 @@ struct grub_f2fs_checkpoint - grub_uint32_t checksum_offset; - grub_uint64_t elapsed_time; - grub_uint8_t alloc_type[MAX_ACTIVE_LOGS]; -- grub_uint8_t sit_nat_version_bitmap[3900]; -+ grub_uint8_t sit_nat_version_bitmap[MAX_NAT_BITMAP_SIZE]; - grub_uint32_t checksum; - } GRUB_PACKED; - -@@ -302,6 +303,7 @@ struct grub_f2fs_data - - struct grub_f2fs_nat_journal nat_j; - char *nat_bitmap; -+ grub_uint32_t nat_bitmap_size; - - grub_disk_t disk; - struct grub_f2fs_node *inode; -@@ -377,15 +379,20 @@ sum_blk_addr (struct grub_f2fs_data *data, int base, int type) - } - - static void * --nat_bitmap_ptr (struct grub_f2fs_data *data) -+nat_bitmap_ptr (struct grub_f2fs_data *data, grub_uint32_t *nat_bitmap_size) - { - struct grub_f2fs_checkpoint *ckpt = &data->ckpt; - grub_uint32_t offset; -+ *nat_bitmap_size = MAX_NAT_BITMAP_SIZE; - - if (grub_le_to_cpu32 (data->sblock.cp_payload) > 0) - return ckpt->sit_nat_version_bitmap; - - offset = grub_le_to_cpu32 (ckpt->sit_ver_bitmap_bytesize); -+ if (offset >= MAX_NAT_BITMAP_SIZE) -+ return NULL; -+ -+ *nat_bitmap_size = *nat_bitmap_size - offset; - - return ckpt->sit_nat_version_bitmap + offset; - } -@@ -438,11 +445,15 @@ grub_f2fs_crc_valid (grub_uint32_t blk_crc, void *buf, const grub_uint32_t len) - } - - static int --grub_f2fs_test_bit (grub_uint32_t nr, const char *p) -+grub_f2fs_test_bit (grub_uint32_t nr, const char *p, grub_uint32_t len) - { - int mask; -+ grub_uint32_t shifted_nr = (nr >> 3); - -- p += (nr >> 3); -+ if (shifted_nr >= len) -+ return -1; -+ -+ p += shifted_nr; - mask = 1 << (7 - (nr & 0x07)); - - return mask & *p; -@@ -662,6 +673,7 @@ get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid) - grub_uint32_t seg_off, block_off, entry_off, block_addr; - grub_uint32_t blkaddr = 0; - grub_err_t err; -+ int result_bit; - - err = get_blkaddr_from_nat_journal (data, nid, &blkaddr); - if (err != GRUB_ERR_NONE) -@@ -682,8 +694,15 @@ get_node_blkaddr (struct grub_f2fs_data *data, grub_uint32_t nid) - ((seg_off * data->blocks_per_seg) << 1) + - (block_off & (data->blocks_per_seg - 1)); - -- if (grub_f2fs_test_bit (block_off, data->nat_bitmap)) -+ result_bit = grub_f2fs_test_bit (block_off, data->nat_bitmap, -+ data->nat_bitmap_size); -+ if (result_bit > 0) - block_addr += data->blocks_per_seg; -+ else if (result_bit == -1) -+ { -+ grub_free (nat_block); -+ return 0; -+ } - - err = grub_f2fs_block_read (data, block_addr, nat_block); - if (err) -@@ -833,7 +852,9 @@ grub_f2fs_mount (grub_disk_t disk) - if (err) - goto fail; - -- data->nat_bitmap = nat_bitmap_ptr (data); -+ data->nat_bitmap = nat_bitmap_ptr (data, &data->nat_bitmap_size); -+ if (data->nat_bitmap == NULL) -+ goto fail; - - err = get_nat_journal (data); - if (err) diff --git a/0240-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch b/0240-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch deleted file mode 100644 index 0553d606fc22560b309bf665689541131b911a5c..0000000000000000000000000000000000000000 --- a/0240-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Sudhakar Kuppusamy -Date: Wed, 6 Apr 2022 18:17:43 +0530 -Subject: [PATCH] fs/f2fs: Do not copy file names that are too long - -A corrupt f2fs file system might specify a name length which is greater -than the maximum name length supported by the GRUB f2fs driver. - -We will allocate enough memory to store the overly long name, but there -are only F2FS_NAME_LEN bytes in the source, so we would read past the end -of the source. - -While checking directory entries, do not copy a file name with an invalid -length. - -Signed-off-by: Sudhakar Kuppusamy -Signed-off-by: Daniel Axtens -Reviewed-by: Daniel Kiper -(cherry picked from commit 9a891f638509e031d322c94e3cbcf38d36f3993a) ---- - grub-core/fs/f2fs.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c -index 8898b235e0..df6beb544c 100644 ---- a/grub-core/fs/f2fs.c -+++ b/grub-core/fs/f2fs.c -@@ -1003,6 +1003,10 @@ grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx) - - ftype = ctx->dentry[i].file_type; - name_len = grub_le_to_cpu16 (ctx->dentry[i].name_len); -+ -+ if (name_len >= F2FS_NAME_LEN) -+ return 0; -+ - filename = grub_malloc (name_len + 1); - if (!filename) - return 0; diff --git a/0241-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch b/0241-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch deleted file mode 100644 index 7ff58218a8303342e7d050b5fde1467d5b9c4162..0000000000000000000000000000000000000000 --- a/0241-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 29 Mar 2022 10:49:56 +0000 -Subject: [PATCH] fs/btrfs: Fix several fuzz issues with invalid dir item - sizing - -According to the btrfs code in Linux, the structure of a directory item -leaf should be of the form: - - |struct btrfs_dir_item|name|data| - -in GRUB the name len and data len are in the grub_btrfs_dir_item -structure's n and m fields respectively. - -The combined size of the structure, name and data should be less than -the allocated memory, a difference to the Linux kernel's struct -btrfs_dir_item is that the grub_btrfs_dir_item has an extra field for -where the name is stored, so we adjust for that too. - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper -(cherry picked from commit 6d3f06c0b6a8992b9b1bb0e62af93ac5ff2781f0) -[rharwood: we've an extra variable here] -Signed-off-by: Robbie Harwood ---- - grub-core/fs/btrfs.c | 26 ++++++++++++++++++++++++++ - 1 file changed, 26 insertions(+) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 07c0ff874b..2fcfb738fe 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -2254,6 +2254,7 @@ grub_btrfs_dir (grub_device_t device, const char *path, - grub_uint64_t tree; - grub_uint8_t type; - char *new_path = NULL; -+ grub_size_t est_size = 0; - - if (!data) - return grub_errno; -@@ -2320,6 +2321,18 @@ grub_btrfs_dir (grub_device_t device, const char *path, - break; - } - -+ if (direl == NULL || -+ grub_add (grub_le_to_cpu16 (direl->n), -+ grub_le_to_cpu16 (direl->m), &est_size) || -+ grub_add (est_size, sizeof (*direl), &est_size) || -+ grub_sub (est_size, sizeof (direl->name), &est_size) || -+ est_size > allocated) -+ { -+ grub_errno = GRUB_ERR_OUT_OF_RANGE; -+ r = -grub_errno; -+ goto out; -+ } -+ - for (cdirel = direl; - (grub_uint8_t *) cdirel - (grub_uint8_t *) direl - < (grub_ssize_t) elemsize; -@@ -2330,6 +2343,19 @@ grub_btrfs_dir (grub_device_t device, const char *path, - char c; - struct grub_btrfs_inode inode; - struct grub_dirhook_info info; -+ -+ if (cdirel == NULL || -+ grub_add (grub_le_to_cpu16 (cdirel->n), -+ grub_le_to_cpu16 (cdirel->m), &est_size) || -+ grub_add (est_size, sizeof (*cdirel), &est_size) || -+ grub_sub (est_size, sizeof (cdirel->name), &est_size) || -+ est_size > allocated) -+ { -+ grub_errno = GRUB_ERR_OUT_OF_RANGE; -+ r = -grub_errno; -+ goto out; -+ } -+ - err = grub_btrfs_read_inode (data, &inode, cdirel->key.object_id, - tree); - grub_memset (&info, 0, sizeof (info)); diff --git a/0242-fs-btrfs-Fix-more-ASAN-and-SEGV-issues-found-with-fu.patch b/0242-fs-btrfs-Fix-more-ASAN-and-SEGV-issues-found-with-fu.patch deleted file mode 100644 index d638c11754bd0bf78542a075cc0504e0c1d1c131..0000000000000000000000000000000000000000 --- a/0242-fs-btrfs-Fix-more-ASAN-and-SEGV-issues-found-with-fu.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Tue, 29 Mar 2022 15:52:46 +0000 -Subject: [PATCH] fs/btrfs: Fix more ASAN and SEGV issues found with fuzzing - -The fuzzer is generating btrfs file systems that have chunks with -invalid combinations of stripes and substripes for the given RAID -configurations. - -After examining the Linux kernel fs/btrfs/tree-checker.c code, it -appears that sub-stripes should only be applied to RAID10, and in that -case there should only ever be 2 of them. - -Similarly, RAID single should only have 1 stripe, and RAID1/1C3/1C4 -should have 2. 3 or 4 stripes respectively, which is what redundancy -corresponds. - -Some of the chunks ended up with a size of 0, which grub_malloc() still -returned memory for and in turn generated ASAN errors later when -accessed. - -While it would be possible to specifically limit the number of stripes, -a more correct test was on the combination of the chunk item, and the -number of stripes by the size of the chunk stripe structure in -comparison to the size of the chunk itself. - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper -(cherry picked from commit 3849647b4b98a4419366708fc4b7f339c6f55ec7) ---- - grub-core/fs/btrfs.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 55 insertions(+) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 2fcfb738fe..0e9b450413 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -941,6 +941,12 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, - return grub_error (GRUB_ERR_BAD_FS, - "couldn't find the chunk descriptor"); - -+ if (!chsize) -+ { -+ grub_dprintf ("btrfs", "zero-size chunk\n"); -+ return grub_error (GRUB_ERR_BAD_FS, -+ "got an invalid zero-size chunk"); -+ } - chunk = grub_malloc (chsize); - if (!chunk) - return grub_errno; -@@ -999,6 +1005,16 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, - stripe_length = grub_divmod64 (grub_le_to_cpu64 (chunk->size), - nstripes, - NULL); -+ -+ /* For single, there should be exactly 1 stripe. */ -+ if (grub_le_to_cpu16 (chunk->nstripes) != 1) -+ { -+ grub_dprintf ("btrfs", "invalid RAID_SINGLE: nstripes != 1 (%u)\n", -+ grub_le_to_cpu16 (chunk->nstripes)); -+ return grub_error (GRUB_ERR_BAD_FS, -+ "invalid RAID_SINGLE: nstripes != 1 (%u)", -+ grub_le_to_cpu16 (chunk->nstripes)); -+ } - if (stripe_length == 0) - stripe_length = 512; - stripen = grub_divmod64 (off, stripe_length, &stripe_offset); -@@ -1018,6 +1034,19 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, - stripen = 0; - stripe_offset = off; - csize = grub_le_to_cpu64 (chunk->size) - off; -+ -+ /* -+ * Redundancy, and substripes only apply to RAID10, and there -+ * should be exactly 2 sub-stripes. -+ */ -+ if (grub_le_to_cpu16 (chunk->nstripes) != redundancy) -+ { -+ grub_dprintf ("btrfs", "invalid RAID1: nstripes != %u (%u)\n", -+ redundancy, grub_le_to_cpu16 (chunk->nstripes)); -+ return grub_error (GRUB_ERR_BAD_FS, -+ "invalid RAID1: nstripes != %u (%u)", -+ redundancy, grub_le_to_cpu16 (chunk->nstripes)); -+ } - break; - } - case GRUB_BTRFS_CHUNK_TYPE_RAID0: -@@ -1054,6 +1083,20 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, - stripe_offset = low + chunk_stripe_length - * high; - csize = chunk_stripe_length - low; -+ -+ /* -+ * Substripes only apply to RAID10, and there -+ * should be exactly 2 sub-stripes. -+ */ -+ if (grub_le_to_cpu16 (chunk->nsubstripes) != 2) -+ { -+ grub_dprintf ("btrfs", "invalid RAID10: nsubstripes != 2 (%u)", -+ grub_le_to_cpu16 (chunk->nsubstripes)); -+ return grub_error (GRUB_ERR_BAD_FS, -+ "invalid RAID10: nsubstripes != 2 (%u)", -+ grub_le_to_cpu16 (chunk->nsubstripes)); -+ } -+ - break; - } - case GRUB_BTRFS_CHUNK_TYPE_RAID5: -@@ -1153,6 +1196,8 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, - - for (j = 0; j < 2; j++) - { -+ grub_size_t est_chunk_alloc = 0; -+ - grub_dprintf ("btrfs", "chunk 0x%" PRIxGRUB_UINT64_T - "+0x%" PRIxGRUB_UINT64_T - " (%d stripes (%d substripes) of %" -@@ -1165,6 +1210,16 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, - grub_dprintf ("btrfs", "reading laddr 0x%" PRIxGRUB_UINT64_T "\n", - addr); - -+ if (grub_mul (sizeof (struct grub_btrfs_chunk_stripe), -+ grub_le_to_cpu16 (chunk->nstripes), &est_chunk_alloc) || -+ grub_add (est_chunk_alloc, -+ sizeof (struct grub_btrfs_chunk_item), &est_chunk_alloc) || -+ est_chunk_alloc > chunk->size) -+ { -+ err = GRUB_ERR_BAD_FS; -+ break; -+ } -+ - if (is_raid56) - { - err = btrfs_read_from_chunk (data, chunk, stripen, diff --git a/0243-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch b/0243-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch deleted file mode 100644 index 2e5145fe7b4d506fde2d0bc451a9377100652d9e..0000000000000000000000000000000000000000 --- a/0243-fs-btrfs-Fix-more-fuzz-issues-related-to-chunks.patch +++ /dev/null @@ -1,75 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Darren Kenny -Date: Thu, 7 Apr 2022 15:18:12 +0000 -Subject: [PATCH] fs/btrfs: Fix more fuzz issues related to chunks - -The corpus we generating issues in grub_btrfs_read_logical() when -attempting to iterate over nstripes entries in the boot mapping. - -In most cases the reason for the failure was that the number of strips -exceeded the possible space statically allocated in superblock bootmapping -space. Each stripe entry in the bootmapping block consists of -a grub_btrfs_key followed by a grub_btrfs_chunk_stripe. - -Another issue that came up was that while calculating the chunk size, -in an earlier piece of code in that function, depending on the data -provided in the btrfs file system, it would end up calculating a size -that was too small to contain even 1 grub_btrfs_chunk_item, which is -obviously invalid too. - -Signed-off-by: Darren Kenny -Reviewed-by: Daniel Kiper -(cherry picked from commit e00cd76cbadcc897a9cc4087cb2fcb5dbe15e596) ---- - grub-core/fs/btrfs.c | 24 ++++++++++++++++++++++++ - 1 file changed, 24 insertions(+) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 0e9b450413..47325f6ad7 100644 ---- a/grub-core/fs/btrfs.c -+++ b/grub-core/fs/btrfs.c -@@ -947,6 +947,17 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, - return grub_error (GRUB_ERR_BAD_FS, - "got an invalid zero-size chunk"); - } -+ -+ /* -+ * The space being allocated for a chunk should at least be able to -+ * contain one chunk item. -+ */ -+ if (chsize < sizeof (struct grub_btrfs_chunk_item)) -+ { -+ grub_dprintf ("btrfs", "chunk-size too small\n"); -+ return grub_error (GRUB_ERR_BAD_FS, -+ "got an invalid chunk size"); -+ } - chunk = grub_malloc (chsize); - if (!chunk) - return grub_errno; -@@ -1194,6 +1205,13 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, - if (csize > (grub_uint64_t) size) - csize = size; - -+ /* -+ * The space for a chunk stripe is limited to the space provide in the super-block's -+ * bootstrap mapping with an initial btrfs key at the start of each chunk. -+ */ -+ grub_size_t avail_stripes = sizeof (data->sblock.bootstrap_mapping) / -+ (sizeof (struct grub_btrfs_key) + sizeof (struct grub_btrfs_chunk_stripe)); -+ - for (j = 0; j < 2; j++) - { - grub_size_t est_chunk_alloc = 0; -@@ -1220,6 +1238,12 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, - break; - } - -+ if (grub_le_to_cpu16 (chunk->nstripes) > avail_stripes) -+ { -+ err = GRUB_ERR_BAD_FS; -+ break; -+ } -+ - if (is_raid56) - { - err = btrfs_read_from_chunk (data, chunk, stripen, diff --git a/0244-misc-Make-grub_min-and-grub_max-more-resilient.patch b/0244-misc-Make-grub_min-and-grub_max-more-resilient.patch deleted file mode 100644 index eb2e8fda0a1f9f20a2fcb2e275f4aa14c47d726b..0000000000000000000000000000000000000000 --- a/0244-misc-Make-grub_min-and-grub_max-more-resilient.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 21 Mar 2022 16:06:10 -0400 -Subject: [PATCH] misc: Make grub_min() and grub_max() more resilient. - -grub_min(a,b) and grub_max(a,b) use a relatively naive implementation -which leads to several problems: -- they evaluate their parameters more than once -- the naive way to address this, to declare temporary variables in a - statement-expression, isn't resilient against nested uses, because - MIN(a,MIN(b,c)) results in the temporary variables being declared in - two nested scopes, which may result in a build warning depending on - your build options. - -This patch changes our implementation to use a statement-expression -inside a helper macro, and creates the symbols for the temporary -variables with __COUNTER__ (A GNU C cpp extension) and token pasting to -create uniquely named internal variables. - -Signed-off-by: Peter Jones ---- - grub-core/loader/multiboot_elfxx.c | 4 +--- - include/grub/misc.h | 25 +++++++++++++++++++++++-- - 2 files changed, 24 insertions(+), 5 deletions(-) - -diff --git a/grub-core/loader/multiboot_elfxx.c b/grub-core/loader/multiboot_elfxx.c -index f2318e0d16..87f6e31aa6 100644 ---- a/grub-core/loader/multiboot_elfxx.c -+++ b/grub-core/loader/multiboot_elfxx.c -@@ -35,9 +35,7 @@ - #endif - - #include -- --#define CONCAT(a,b) CONCAT_(a, b) --#define CONCAT_(a,b) a ## b -+#include - - #pragma GCC diagnostic ignored "-Wcast-align" - -diff --git a/include/grub/misc.h b/include/grub/misc.h -index 6c4aa85ac5..cf84aec1db 100644 ---- a/include/grub/misc.h -+++ b/include/grub/misc.h -@@ -35,6 +35,14 @@ - #define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) - #define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ; } - -+#ifndef CONCAT_ -+#define CONCAT_(a, b) a ## b -+#endif -+ -+#ifndef CONCAT -+#define CONCAT(a, b) CONCAT_(a, b) -+#endif -+ - #define grub_dprintf(condition, ...) grub_real_dprintf(GRUB_FILE, __LINE__, condition, __VA_ARGS__) - - void *EXPORT_FUNC(grub_memmove) (void *dest, const void *src, grub_size_t n); -@@ -498,8 +506,21 @@ void EXPORT_FUNC(grub_real_boot_time) (const char *file, - #define grub_boot_time(...) - #endif - --#define grub_max(a, b) (((a) > (b)) ? (a) : (b)) --#define grub_min(a, b) (((a) < (b)) ? (a) : (b)) -+#define _grub_min(a, b, _a, _b) \ -+ ({ typeof (a) _a = (a); \ -+ typeof (b) _b = (b); \ -+ _a < _b ? _a : _b; }) -+#define grub_min(a, b) _grub_min(a, b, \ -+ CONCAT(_a_,__COUNTER__), \ -+ CONCAT(_b_,__COUNTER__)) -+ -+#define _grub_max(a, b, _a, _b) \ -+ ({ typeof (a) _a = (a); \ -+ typeof (b) _b = (b); \ -+ _a > _b ? _a : _b; }) -+#define grub_max(a, b) _grub_max(a, b, \ -+ CONCAT(_a_,__COUNTER__), \ -+ CONCAT(_b_,__COUNTER__)) - - #define grub_log2ull(n) (GRUB_TYPE_BITS (grub_uint64_t) - __builtin_clzll (n) - 1) - diff --git a/0245-ReiserFS-switch-to-using-grub_min-grub_max.patch b/0245-ReiserFS-switch-to-using-grub_min-grub_max.patch deleted file mode 100644 index 0707af3e5801fd8557f1689adf4c247a141442a2..0000000000000000000000000000000000000000 --- a/0245-ReiserFS-switch-to-using-grub_min-grub_max.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 21 Apr 2022 16:31:17 -0400 -Subject: [PATCH] ReiserFS: switch to using grub_min()/grub_max() - -This is a minor cleanup patch to remove the bespoke MIN() and MAX() -definitions from the reiserfs driver, and uses grub_min() / grub_max() -instead. - -Signed-off-by: Peter Jones ---- - grub-core/fs/reiserfs.c | 28 +++++++++------------------- - 1 file changed, 9 insertions(+), 19 deletions(-) - -diff --git a/grub-core/fs/reiserfs.c b/grub-core/fs/reiserfs.c -index af6a226a7f..b8253da7fe 100644 ---- a/grub-core/fs/reiserfs.c -+++ b/grub-core/fs/reiserfs.c -@@ -42,16 +42,6 @@ - - GRUB_MOD_LICENSE ("GPLv3+"); - --#define MIN(a, b) \ -- ({ typeof (a) _a = (a); \ -- typeof (b) _b = (b); \ -- _a < _b ? _a : _b; }) -- --#define MAX(a, b) \ -- ({ typeof (a) _a = (a); \ -- typeof (b) _b = (b); \ -- _a > _b ? _a : _b; }) -- - #define REISERFS_SUPER_BLOCK_OFFSET 0x10000 - #define REISERFS_MAGIC_LEN 12 - #define REISERFS_MAGIC_STRING "ReIsEr" -@@ -1076,7 +1066,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node, - grub_reiserfs_set_key_type (&key, GRUB_REISERFS_ANY, 2); - initial_position = off; - current_position = 0; -- final_position = MIN (len + initial_position, node->size); -+ final_position = grub_min (len + initial_position, node->size); - grub_dprintf ("reiserfs", - "Reading from %lld to %lld (%lld instead of requested %ld)\n", - (unsigned long long) initial_position, -@@ -1115,8 +1105,8 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node, - grub_dprintf ("reiserfs_blocktype", "D: %u\n", (unsigned) block); - if (initial_position < current_position + item_size) - { -- offset = MAX ((signed) (initial_position - current_position), 0); -- length = (MIN (item_size, final_position - current_position) -+ offset = grub_max ((signed) (initial_position - current_position), 0); -+ length = (grub_min (item_size, final_position - current_position) - - offset); - grub_dprintf ("reiserfs", - "Reading direct block %u from %u to %u...\n", -@@ -1161,9 +1151,9 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node, - grub_dprintf ("reiserfs_blocktype", "I: %u\n", (unsigned) block); - if (current_position + block_size >= initial_position) - { -- offset = MAX ((signed) (initial_position - current_position), -- 0); -- length = (MIN (block_size, final_position - current_position) -+ offset = grub_max ((signed) (initial_position - current_position), -+ 0); -+ length = (grub_min (block_size, final_position - current_position) - - offset); - grub_dprintf ("reiserfs", - "Reading indirect block %u from %u to %u...\n", -@@ -1205,7 +1195,7 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node, - switch (found.type) - { - case GRUB_REISERFS_DIRECT: -- read_length = MIN (len, item_size - file->offset); -+ read_length = grub_min (len, item_size - file->offset); - grub_disk_read (found.data->disk, - (found.block_number * block_size) / GRUB_DISK_SECTOR_SIZE, - grub_le_to_cpu16 (found.header.item_location) + file->offset, -@@ -1224,12 +1214,12 @@ grub_reiserfs_read_real (struct grub_fshelp_node *node, - item_size, (char *) indirect_block_ptr); - if (grub_errno) - goto fail; -- len = MIN (len, file->size - file->offset); -+ len = grub_min (len, file->size - file->offset); - for (indirect_block = file->offset / block_size; - indirect_block < indirect_block_count && read_length < len; - indirect_block++) - { -- read = MIN (block_size, len - read_length); -+ read = grub_min (block_size, len - read_length); - grub_disk_read (found.data->disk, - (grub_le_to_cpu32 (indirect_block_ptr[indirect_block]) * block_size) / GRUB_DISK_SECTOR_SIZE, - file->offset % block_size, read, diff --git a/0246-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch b/0246-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch deleted file mode 100644 index a7ac6f2a40a62236cad575dca21e53384ec6be75..0000000000000000000000000000000000000000 --- a/0246-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 24 Mar 2022 14:40:01 -0400 -Subject: [PATCH] misc: make grub_boot_time() also call - grub_dprintf("boot",...) - -Currently grub_boot_time() includes valuable debugging messages, but if -you build without BOOT_TIME_STATS enabled, they are silently and -confusingly compiled away. - -This patch changes grub_boot_time() to also log when "boot" is enabled -in DEBUG, regardless of BOOT_TIME_STATS. - -Signed-off-by: Peter Jones ---- - grub-core/kern/misc.c | 3 ++- - include/grub/misc.h | 2 +- - 2 files changed, 3 insertions(+), 2 deletions(-) - -diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c -index a186ad3dd4..cb45461402 100644 ---- a/grub-core/kern/misc.c -+++ b/grub-core/kern/misc.c -@@ -1334,7 +1334,8 @@ grub_real_boot_time (const char *file, - n->next = 0; - - va_start (args, fmt); -- n->msg = grub_xvasprintf (fmt, args); -+ n->msg = grub_xvasprintf (fmt, args); -+ grub_dprintf ("boot", "%s\n", n->msg); - va_end (args); - - *boot_time_last = n; -diff --git a/include/grub/misc.h b/include/grub/misc.h -index cf84aec1db..faae0ae860 100644 ---- a/include/grub/misc.h -+++ b/include/grub/misc.h -@@ -503,7 +503,7 @@ void EXPORT_FUNC(grub_real_boot_time) (const char *file, - const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 3, 4))); - #define grub_boot_time(...) grub_real_boot_time(GRUB_FILE, __LINE__, __VA_ARGS__) - #else --#define grub_boot_time(...) -+#define grub_boot_time(fmt, ...) grub_dprintf("boot", fmt "\n", ##__VA_ARGS__) - #endif - - #define _grub_min(a, b, _a, _b) \ diff --git a/0247-modules-make-.module_license-read-only.patch b/0247-modules-make-.module_license-read-only.patch deleted file mode 100644 index ba3b31371a102225729f91326e2b2a9e25d1cbcd..0000000000000000000000000000000000000000 --- a/0247-modules-make-.module_license-read-only.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 24 Feb 2022 16:32:51 -0500 -Subject: [PATCH] modules: make .module_license read-only - -Currently .module_license is set writable (that is, the section has the -SHF_WRITE flag set) in the module's ELF headers. This probably never -actually matters, but it can't possibly be correct. - -This patch sets that data as "const", which causes that flag not to be -set. - -Signed-off-by: Peter Jones ---- - include/grub/dl.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/include/grub/dl.h b/include/grub/dl.h -index 20d870f2a4..618ae6f474 100644 ---- a/include/grub/dl.h -+++ b/include/grub/dl.h -@@ -121,7 +121,7 @@ grub_mod_fini (void) - #define ATTRIBUTE_USED __unused__ - #endif - #define GRUB_MOD_LICENSE(license) \ -- static char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license; -+ static const char grub_module_license[] __attribute__ ((section (GRUB_MOD_SECTION (module_license)), ATTRIBUTE_USED)) = "LICENSE=" license; - #define GRUB_MOD_DEP(name) \ - static const char grub_module_depend_##name[] \ - __attribute__((section(GRUB_MOD_SECTION(moddeps)), ATTRIBUTE_USED)) = #name diff --git a/0248-modules-strip-.llvm_addrsig-sections-and-similar.patch b/0248-modules-strip-.llvm_addrsig-sections-and-similar.patch deleted file mode 100644 index 9f26115d6fa542e237be63a503a816f93b0c9446..0000000000000000000000000000000000000000 --- a/0248-modules-strip-.llvm_addrsig-sections-and-similar.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Thu, 24 Feb 2022 16:40:11 -0500 -Subject: [PATCH] modules: strip .llvm_addrsig sections and similar. - -Currently grub modules built with clang or gcc have several sections -which we don't actually need or support. - -We already have a list of section to skip in genmod.sh, and this patch -adds the following sections to that list (as well as a few newlines): - -.note.gnu.property -.llvm* - -Note that the glob there won't work without a new enough linker, but the -failure is just reversion to the status quo, so that's not a big problem. - -Signed-off-by: Peter Jones ---- - grub-core/genmod.sh.in | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -diff --git a/grub-core/genmod.sh.in b/grub-core/genmod.sh.in -index 1250589b3f..c2c5280d75 100644 ---- a/grub-core/genmod.sh.in -+++ b/grub-core/genmod.sh.in -@@ -57,8 +57,11 @@ if test x@TARGET_APPLE_LINKER@ != x1; then - @TARGET_STRIP@ --strip-unneeded \ - -K grub_mod_init -K grub_mod_fini \ - -K _grub_mod_init -K _grub_mod_fini \ -- -R .note.gnu.gold-version -R .note.GNU-stack \ -+ -R .note.GNU-stack \ -+ -R .note.gnu.gold-version \ -+ -R .note.gnu.property \ - -R .gnu.build.attributes \ -+ -R '.llvm*' \ - -R .rel.gnu.build.attributes \ - -R .rela.gnu.build.attributes \ - -R .eh_frame -R .rela.eh_frame -R .rel.eh_frame \ diff --git a/0249-modules-Don-t-allocate-space-for-non-allocable-secti.patch b/0249-modules-Don-t-allocate-space-for-non-allocable-secti.patch deleted file mode 100644 index d07d8386c793c9513935e4e68bd4d3e05d48eeb4..0000000000000000000000000000000000000000 --- a/0249-modules-Don-t-allocate-space-for-non-allocable-secti.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 21 Mar 2022 16:56:10 -0400 -Subject: [PATCH] modules: Don't allocate space for non-allocable sections. - -Currently when loading grub modules, we allocate space for all sections, -including those without SHF_ALLOC set. We then copy the sections that -/do/ have SHF_ALLOC set into the allocated memory, leaving some of our -allocation untouched forever. Additionally, on platforms with GOT -fixups and trampolines, we currently compute alignment round-ups for the -sections and sections with sh_size = 0. - -This patch removes the extra space from the allocation computation, and -makes the allocation computation loop skip empty sections as the loading -loop does. - -Signed-off-by: Peter Jones ---- - grub-core/kern/dl.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index f304494574..aef8af8aa7 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -289,6 +289,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - i < e->e_shnum; - i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize)) - { -+ if (s->sh_size == 0 || !(s->sh_flags & SHF_ALLOC)) -+ continue; -+ - tsize = ALIGN_UP (tsize, s->sh_addralign) + s->sh_size; - if (talign < s->sh_addralign) - talign = s->sh_addralign; diff --git a/0250-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch b/0250-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch deleted file mode 100644 index ef51214fefe8ebdf7068e826e72128c15d275c7d..0000000000000000000000000000000000000000 --- a/0250-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 25 Mar 2022 15:40:12 -0400 -Subject: [PATCH] pe: add the DOS header struct and fix some bad naming. - -In order to properly validate a loaded kernel's support for being loaded -without a writable stack or executable, we need to be able to properly -parse arbitrary PE headers. - -Currently, pe32.h is written in such a way that the MS-DOS header that -tells us where to find the PE header in the binary can't be accessed. -Further, for some reason it calls the DOS MZ magic "GRUB_PE32_MAGIC". - -This patch adds the structure for the DOS header, renames the DOS magic -define, and adds defines for the actual PE magic. - -Signed-off-by: Peter Jones ---- - grub-core/loader/arm64/linux.c | 2 +- - include/grub/efi/pe32.h | 28 ++++++++++++++++++++++++++-- - 2 files changed, 27 insertions(+), 3 deletions(-) - -diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c -index d2af47c2c0..cc67f43906 100644 ---- a/grub-core/loader/arm64/linux.c -+++ b/grub-core/loader/arm64/linux.c -@@ -58,7 +58,7 @@ 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) -+ if ((lh->code0 & 0xffff) != GRUB_DOS_MAGIC) - return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, - N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled")); - -diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h -index a43adf2746..2a5e1ee003 100644 ---- a/include/grub/efi/pe32.h -+++ b/include/grub/efi/pe32.h -@@ -46,7 +46,30 @@ - - #define GRUB_PE32_MSDOS_STUB_SIZE 0x80 - --#define GRUB_PE32_MAGIC 0x5a4d -+#define GRUB_DOS_MAGIC 0x5a4d -+ -+struct grub_dos_header -+{ -+ grub_uint16_t magic; -+ grub_uint16_t cblp; -+ grub_uint16_t cp; -+ grub_uint16_t crlc; -+ grub_uint16_t cparhdr; -+ grub_uint16_t minalloc; -+ grub_uint16_t maxalloc; -+ grub_uint16_t ss; -+ grub_uint16_t sp; -+ grub_uint16_t csum; -+ grub_uint16_t ip; -+ grub_uint16_t cs; -+ grub_uint16_t lfarlc; -+ grub_uint16_t ovno; -+ grub_uint16_t res0[4]; -+ grub_uint16_t oemid; -+ grub_uint16_t oeminfo; -+ grub_uint16_t res1[10]; -+ grub_uint32_t lfanew; -+}; - - /* According to the spec, the minimal alignment is 512 bytes... - But some examples (such as EFI drivers in the Intel -@@ -280,7 +303,8 @@ struct grub_pe32_section_table - - - --#define GRUB_PE32_SIGNATURE_SIZE 4 -+#define GRUB_PE32_SIGNATURE_SIZE 4 -+#define GRUB_PE32_SIGNATURE "PE\0\0" - - struct grub_pe32_header - { diff --git a/0251-modules-load-module-sections-at-page-aligned-address.patch b/0251-modules-load-module-sections-at-page-aligned-address.patch deleted file mode 100644 index 9a5048ce90bae215cdd861b61d01e09c521fc94b..0000000000000000000000000000000000000000 --- a/0251-modules-load-module-sections-at-page-aligned-address.patch +++ /dev/null @@ -1,378 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 21 Mar 2022 17:45:40 -0400 -Subject: [PATCH] modules: load module sections at page-aligned addresses - -Currently we load module sections at whatever alignment gcc+ld happened -to dump into the ELF section header, which is often pretty useless. For -example, by default time.mod has these sections on a current x86_64 -build: - -$ eu-readelf -a grub-core/time.mod |& grep ^Section -A13 -Section Headers: -[Nr] Name Type Addr Off Size ES Flags Lk Inf Al -[ 0] NULL 0 00000000 00000000 0 0 0 0 -[ 1] .text PROGBITS 0 00000040 0000015e 0 AX 0 0 1 -[ 2] .rela.text RELA 0 00000458 000001e0 24 I 8 1 8 -[ 3] .rodata.str1.1 PROGBITS 0 0000019e 000000a1 1 AMS 0 0 1 -[ 4] .module_license PROGBITS 0 00000240 0000000f 0 A 0 0 8 -[ 5] .data PROGBITS 0 0000024f 00000000 0 WA 0 0 1 -[ 6] .bss NOBITS 0 00000250 00000008 0 WA 0 0 8 -[ 7] .modname PROGBITS 0 00000250 00000005 0 0 0 1 -[ 8] .symtab SYMTAB 0 00000258 00000150 24 9 6 8 -[ 9] .strtab STRTAB 0 000003a8 000000ab 0 0 0 1 -[10] .shstrtab STRTAB 0 00000638 00000059 0 0 0 1 - -With NX protections being page based, loading sections with either a 1 -or 8 *byte* alignment does absolutely nothing to help us out. - -This patch switches most EFI platforms to load module sections at 4kB -page-aligned addresses. To do so, it adds an new per-arch function, -grub_arch_dl_min_alignment(), which returns the alignment needed for -dynamically loaded sections (in bytes). Currently it sets it to 4096 -when GRUB_MACHINE_EFI is true on x86_64, i386, arm, arm64, and emu, and -1-byte alignment on everything else. - -It then changes the allocation size computation and the loader code in -grub_dl_load_segments() to align the locations and sizes up to these -boundaries, and fills any added padding with zeros. - -All of this happens before relocations are applied, so the relocations -factor that in with no change. - -As an aside, initially Daniel Kiper and I thought that it might be a -better idea to split the modules up into top-level sections as -.text.modules, .rodata.modules, .data.modules, etc., so that their page -permissions would get set by the loader that's loading grub itself. -This turns out to have two significant downsides: 1) either in mkimage -or in grub_dl_relocate_symbols(), you wind up having to dynamically -process the relocations to accommodate the moved module sections, and 2) -you then need to change the permissions on the modules and change them -back while relocating them in grub_dl_relocate_symbols(), which means -that any loader that /does/ honor the section flags but does /not/ -generally support NX with the memory attributes API will cause grub to -fail. - -Signed-off-by: Peter Jones ---- - grub-core/kern/arm/dl.c | 13 +++++++++++++ - grub-core/kern/arm64/dl.c | 13 +++++++++++++ - grub-core/kern/dl.c | 29 +++++++++++++++++++++-------- - grub-core/kern/emu/full.c | 13 +++++++++++++ - grub-core/kern/i386/dl.c | 13 +++++++++++++ - grub-core/kern/ia64/dl.c | 9 +++++++++ - grub-core/kern/mips/dl.c | 8 ++++++++ - grub-core/kern/powerpc/dl.c | 9 +++++++++ - grub-core/kern/riscv/dl.c | 13 +++++++++++++ - grub-core/kern/sparc64/dl.c | 9 +++++++++ - grub-core/kern/x86_64/dl.c | 13 +++++++++++++ - include/grub/dl.h | 2 ++ - docs/grub-dev.texi | 6 +++--- - 13 files changed, 139 insertions(+), 11 deletions(-) - -diff --git a/grub-core/kern/arm/dl.c b/grub-core/kern/arm/dl.c -index eab9d17ff2..9260737936 100644 ---- a/grub-core/kern/arm/dl.c -+++ b/grub-core/kern/arm/dl.c -@@ -278,3 +278,16 @@ grub_arch_dl_check_header (void *ehdr) - - return GRUB_ERR_NONE; - } -+ -+/* -+ * Tell the loader what our minimum section alignment is. -+ */ -+grub_size_t -+grub_arch_dl_min_alignment (void) -+{ -+#ifdef GRUB_MACHINE_EFI -+ return 4096; -+#else -+ return 1; -+#endif -+} -diff --git a/grub-core/kern/arm64/dl.c b/grub-core/kern/arm64/dl.c -index 512e5a80b0..0d4a26857f 100644 ---- a/grub-core/kern/arm64/dl.c -+++ b/grub-core/kern/arm64/dl.c -@@ -196,3 +196,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - - return GRUB_ERR_NONE; - } -+ -+/* -+ * Tell the loader what our minimum section alignment is. -+ */ -+grub_size_t -+grub_arch_dl_min_alignment (void) -+{ -+#ifdef GRUB_MACHINE_EFI -+ return 4096; -+#else -+ return 1; -+#endif -+} -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index aef8af8aa7..8c7aacef39 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -277,7 +277,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - { - unsigned i; - const Elf_Shdr *s; -- grub_size_t tsize = 0, talign = 1; -+ grub_size_t tsize = 0, talign = 1, arch_addralign = 1; - #if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) - grub_size_t tramp; - grub_size_t got; -@@ -285,16 +285,24 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - #endif - char *ptr; - -+ arch_addralign = grub_arch_dl_min_alignment (); -+ - for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize)) - { -+ grub_size_t sh_addralign; -+ grub_size_t sh_size; -+ - if (s->sh_size == 0 || !(s->sh_flags & SHF_ALLOC)) - continue; - -- tsize = ALIGN_UP (tsize, s->sh_addralign) + s->sh_size; -- if (talign < s->sh_addralign) -- talign = s->sh_addralign; -+ sh_addralign = ALIGN_UP(s->sh_addralign, arch_addralign); -+ sh_size = ALIGN_UP(s->sh_size, sh_addralign); -+ -+ tsize = ALIGN_UP (tsize, sh_addralign) + sh_size; -+ if (talign < sh_addralign) -+ talign = sh_addralign; - } - - #if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) -@@ -323,6 +331,9 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - i < e->e_shnum; - i++, s = (Elf_Shdr *)((char *) s + e->e_shentsize)) - { -+ grub_size_t sh_addralign = ALIGN_UP(s->sh_addralign, arch_addralign); -+ grub_size_t sh_size = ALIGN_UP(s->sh_size, sh_addralign); -+ - if (s->sh_flags & SHF_ALLOC) - { - grub_dl_segment_t seg; -@@ -335,17 +346,19 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - { - void *addr; - -- ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, s->sh_addralign); -+ ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, sh_addralign); - addr = ptr; -- ptr += s->sh_size; -+ ptr += sh_size; - - switch (s->sh_type) - { - case SHT_PROGBITS: - grub_memcpy (addr, (char *) e + s->sh_offset, s->sh_size); -+ grub_memset ((char *)addr + s->sh_size, 0, -+ sh_size - s->sh_size); - break; - case SHT_NOBITS: -- grub_memset (addr, 0, s->sh_size); -+ grub_memset (addr, 0, sh_size); - break; - } - -@@ -354,7 +367,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - else - seg->addr = 0; - -- seg->size = s->sh_size; -+ seg->size = sh_size; - seg->section = i; - seg->next = mod->segment; - mod->segment = seg; -diff --git a/grub-core/kern/emu/full.c b/grub-core/kern/emu/full.c -index e8d63b1f5f..1de1c28eb0 100644 ---- a/grub-core/kern/emu/full.c -+++ b/grub-core/kern/emu/full.c -@@ -67,3 +67,16 @@ grub_arch_dl_init_linker (void) - } - #endif - -+ -+/* -+ * Tell the loader what our minimum section alignment is. -+ */ -+grub_size_t -+grub_arch_dl_min_alignment (void) -+{ -+#ifdef GRUB_MACHINE_EFI -+ return 4096; -+#else -+ return 1; -+#endif -+} -diff --git a/grub-core/kern/i386/dl.c b/grub-core/kern/i386/dl.c -index 1346da5cc9..d6b4681fc9 100644 ---- a/grub-core/kern/i386/dl.c -+++ b/grub-core/kern/i386/dl.c -@@ -79,3 +79,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - - return GRUB_ERR_NONE; - } -+ -+/* -+ * Tell the loader what our minimum section alignment is. -+ */ -+grub_size_t -+grub_arch_dl_min_alignment (void) -+{ -+#ifdef GRUB_MACHINE_EFI -+ return 4096; -+#else -+ return 1; -+#endif -+} -diff --git a/grub-core/kern/ia64/dl.c b/grub-core/kern/ia64/dl.c -index db59300fea..92d82c5750 100644 ---- a/grub-core/kern/ia64/dl.c -+++ b/grub-core/kern/ia64/dl.c -@@ -148,3 +148,12 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - } - return GRUB_ERR_NONE; - } -+ -+/* -+ * Tell the loader what our minimum section alignment is. -+ */ -+grub_size_t -+grub_arch_dl_min_alignment (void) -+{ -+ return 1; -+} -diff --git a/grub-core/kern/mips/dl.c b/grub-core/kern/mips/dl.c -index 5d7d299c74..6d83bd71e9 100644 ---- a/grub-core/kern/mips/dl.c -+++ b/grub-core/kern/mips/dl.c -@@ -272,3 +272,11 @@ grub_arch_dl_init_linker (void) - grub_dl_register_symbol ("_gp_disp", &_gp_disp_dummy, 0, 0); - } - -+/* -+ * Tell the loader what our minimum section alignment is. -+ */ -+grub_size_t -+grub_arch_dl_min_alignment (void) -+{ -+ return 1; -+} -diff --git a/grub-core/kern/powerpc/dl.c b/grub-core/kern/powerpc/dl.c -index cdd61b305f..5d9ba2e158 100644 ---- a/grub-core/kern/powerpc/dl.c -+++ b/grub-core/kern/powerpc/dl.c -@@ -167,3 +167,12 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - - return GRUB_ERR_NONE; - } -+ -+/* -+ * Tell the loader what our minimum section alignment is. -+ */ -+grub_size_t -+grub_arch_dl_min_alignment (void) -+{ -+ return 1; -+} -diff --git a/grub-core/kern/riscv/dl.c b/grub-core/kern/riscv/dl.c -index f26b12aaa4..aa18f9e990 100644 ---- a/grub-core/kern/riscv/dl.c -+++ b/grub-core/kern/riscv/dl.c -@@ -343,3 +343,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - - return GRUB_ERR_NONE; - } -+ -+/* -+ * Tell the loader what our minimum section alignment is. -+ */ -+grub_size_t -+grub_arch_dl_min_alignment (void) -+{ -+#ifdef GRUB_MACHINE_EFI -+ return 4096; -+#else -+ return 1; -+#endif -+} -diff --git a/grub-core/kern/sparc64/dl.c b/grub-core/kern/sparc64/dl.c -index f3d960186b..f054f08241 100644 ---- a/grub-core/kern/sparc64/dl.c -+++ b/grub-core/kern/sparc64/dl.c -@@ -189,3 +189,12 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - - return GRUB_ERR_NONE; - } -+ -+/* -+ * Tell the loader what our minimum section alignment is. -+ */ -+grub_size_t -+grub_arch_dl_min_alignment (void) -+{ -+ return 1; -+} -diff --git a/grub-core/kern/x86_64/dl.c b/grub-core/kern/x86_64/dl.c -index e5a8bdcf4f..a105dc50ce 100644 ---- a/grub-core/kern/x86_64/dl.c -+++ b/grub-core/kern/x86_64/dl.c -@@ -119,3 +119,16 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - - return GRUB_ERR_NONE; - } -+ -+/* -+ * Tell the loader what our minimum section alignment is. -+ */ -+grub_size_t -+grub_arch_dl_min_alignment (void) -+{ -+#ifdef GRUB_MACHINE_EFI -+ return 4096; -+#else -+ return 1; -+#endif -+} -diff --git a/include/grub/dl.h b/include/grub/dl.h -index 618ae6f474..f36ed5cb17 100644 ---- a/include/grub/dl.h -+++ b/include/grub/dl.h -@@ -280,6 +280,8 @@ grub_err_t grub_arch_dl_check_header (void *ehdr); - grub_err_t - grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, - Elf_Shdr *s, grub_dl_segment_t seg); -+grub_size_t -+grub_arch_dl_min_alignment (void); - #endif - - #if defined (_mips) -diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi -index 90083772c8..c23ba313dc 100644 ---- a/docs/grub-dev.texi -+++ b/docs/grub-dev.texi -@@ -755,9 +755,9 @@ declare startup asm file ($cpu_$platform_startup) as well as any other files - (e.g. init.c and callwrap.S) (e.g. $cpu_$platform = kern/$cpu/$platform/init.c). - At this stage you will also need to add dummy dl.c and cache.S with functions - grub_err_t grub_arch_dl_check_header (void *ehdr), grub_err_t --grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) (dl.c) and --void grub_arch_sync_caches (void *address, grub_size_t len) (cache.S). They --won't be used for now. -+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr) (dl.c), grub_uint32_t -+grub_arch_dl_min_alignment (void), and void grub_arch_sync_caches (void -+*address, grub_size_t len) (cache.S). They won't be used for now. - - You will need to create directory include/$cpu/$platform and a file - include/$cpu/types.h. The later folowing this template: diff --git a/0252-nx-add-memory-attribute-get-set-API.patch b/0252-nx-add-memory-attribute-get-set-API.patch deleted file mode 100644 index 91c9d2f528a3b7056cf78f70df75ea621b821447..0000000000000000000000000000000000000000 --- a/0252-nx-add-memory-attribute-get-set-API.patch +++ /dev/null @@ -1,317 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Tue, 22 Mar 2022 10:56:21 -0400 -Subject: [PATCH] nx: add memory attribute get/set API - -For NX, we need to set the page access permission attributes for write -and execute permissions. - -This patch adds two new primitives, grub_set_mem_attrs() and -grub_clear_mem_attrs(), and associated constant definitions, to be used -for that purpose. - -For most platforms, it adds a dummy implementation that returns -GRUB_ERR_NONE. On EFI platforms, it adds a common helper function, -grub_efi_status_to_err(), which translates EFI error codes to grub error -codes, adds headers for the EFI Memory Attribute Protocol (still pending -standardization), and an implementation of the grub nx primitives using -it. - -Signed-off-by: Peter Jones -[rharwood: add pjones's none/nyi fixup] -Signed-off-by: Robbie Harwood ---- - grub-core/kern/efi/efi.c | 36 +++++++++++++ - grub-core/kern/efi/mm.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++ - include/grub/efi/api.h | 25 +++++++++ - include/grub/efi/efi.h | 2 + - include/grub/mm.h | 32 ++++++++++++ - 5 files changed, 226 insertions(+) - -diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c -index 7fcca69c17..4ac2b2754e 100644 ---- a/grub-core/kern/efi/efi.c -+++ b/grub-core/kern/efi/efi.c -@@ -1096,3 +1096,39 @@ grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1, - - return 0; - } -+ -+grub_err_t -+grub_efi_status_to_err (grub_efi_status_t status) -+{ -+ grub_err_t err; -+ switch (status) -+ { -+ case GRUB_EFI_SUCCESS: -+ err = GRUB_ERR_NONE; -+ break; -+ case GRUB_EFI_INVALID_PARAMETER: -+ default: -+ err = GRUB_ERR_BAD_ARGUMENT; -+ break; -+ case GRUB_EFI_OUT_OF_RESOURCES: -+ err = GRUB_ERR_OUT_OF_MEMORY; -+ break; -+ case GRUB_EFI_DEVICE_ERROR: -+ err = GRUB_ERR_IO; -+ break; -+ case GRUB_EFI_WRITE_PROTECTED: -+ err = GRUB_ERR_WRITE_ERROR; -+ break; -+ case GRUB_EFI_SECURITY_VIOLATION: -+ err = GRUB_ERR_ACCESS_DENIED; -+ break; -+ case GRUB_EFI_NOT_FOUND: -+ err = GRUB_ERR_FILE_NOT_FOUND; -+ break; -+ case GRUB_EFI_ABORTED: -+ err = GRUB_ERR_WAIT; -+ break; -+ } -+ -+ return err; -+} -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index e84961d078..2c33758ed7 100644 ---- a/grub-core/kern/efi/mm.c -+++ b/grub-core/kern/efi/mm.c -@@ -738,3 +738,134 @@ grub_efi_get_ram_base(grub_addr_t *base_addr) - return GRUB_ERR_NONE; - } - #endif -+ -+static inline grub_uint64_t -+grub_mem_attrs_to_uefi_mem_attrs (grub_uint64_t attrs) -+{ -+ grub_uint64_t ret = GRUB_EFI_MEMORY_RP | -+ GRUB_EFI_MEMORY_RO | -+ GRUB_EFI_MEMORY_XP; -+ -+ if (attrs & GRUB_MEM_ATTR_R) -+ ret &= ~GRUB_EFI_MEMORY_RP; -+ -+ if (attrs & GRUB_MEM_ATTR_W) -+ ret &= ~GRUB_EFI_MEMORY_RO; -+ -+ if (attrs & GRUB_MEM_ATTR_X) -+ ret &= ~GRUB_EFI_MEMORY_XP; -+ -+ return ret; -+} -+ -+static inline grub_uint64_t -+uefi_mem_attrs_to_grub_mem_attrs (grub_uint64_t attrs) -+{ -+ grub_uint64_t ret = GRUB_MEM_ATTR_R | -+ GRUB_MEM_ATTR_W | -+ GRUB_MEM_ATTR_X; -+ -+ if (attrs & GRUB_EFI_MEMORY_RP) -+ ret &= ~GRUB_MEM_ATTR_R; -+ -+ if (attrs & GRUB_EFI_MEMORY_RO) -+ ret &= ~GRUB_MEM_ATTR_W; -+ -+ if (attrs & GRUB_EFI_MEMORY_XP) -+ ret &= ~GRUB_MEM_ATTR_X; -+ -+ return ret; -+} -+ -+grub_err_t -+grub_get_mem_attrs (grub_addr_t addr, grub_size_t size, grub_uint64_t *attrs) -+{ -+ grub_efi_memory_attribute_protocol_t *proto; -+ grub_efi_physical_address_t physaddr = addr; -+ grub_efi_guid_t protocol_guid = GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID; -+ grub_efi_status_t efi_status; -+ -+ proto = grub_efi_locate_protocol (&protocol_guid, 0); -+ if (!proto) -+ return GRUB_ERR_NOT_IMPLEMENTED_YET; -+ -+ if (physaddr & 0xfff || size & 0xfff || size == 0 || attrs == NULL) -+ { -+ grub_dprintf ("nx", "%s called on 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" and attrs %p\n", -+ __func__, physaddr, physaddr+size-1, attrs); -+ return 0; -+ } -+ -+ efi_status = efi_call_4(proto->get_memory_attributes, -+ proto, physaddr, size, attrs); -+ *attrs = uefi_mem_attrs_to_grub_mem_attrs (*attrs); -+ -+ return grub_efi_status_to_err (efi_status); -+} -+ -+grub_err_t -+grub_update_mem_attrs (grub_addr_t addr, grub_size_t size, -+ grub_uint64_t set_attrs, grub_uint64_t clear_attrs) -+{ -+ grub_efi_memory_attribute_protocol_t *proto; -+ grub_efi_physical_address_t physaddr = addr; -+ grub_efi_guid_t protocol_guid = GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID; -+ grub_efi_status_t efi_status = GRUB_EFI_SUCCESS; -+ grub_uint64_t before = 0, after = 0, uefi_set_attrs, uefi_clear_attrs; -+ grub_err_t err; -+ -+ proto = grub_efi_locate_protocol (&protocol_guid, 0); -+ if (!proto) -+ return GRUB_ERR_NONE; -+ -+ err = grub_get_mem_attrs (addr, size, &before); -+ if (err) -+ grub_dprintf ("nx", "grub_get_mem_attrs(0x%"PRIxGRUB_ADDR", %"PRIuGRUB_SIZE", %p) -> 0x%x\n", -+ addr, size, &before, err); -+ -+ if (physaddr & 0xfff || size & 0xfff || size == 0) -+ { -+ grub_dprintf ("nx", "%s called on 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" +%s%s%s -%s%s%s\n", -+ __func__, physaddr, physaddr + size - 1, -+ (set_attrs & GRUB_MEM_ATTR_R) ? "r" : "", -+ (set_attrs & GRUB_MEM_ATTR_W) ? "w" : "", -+ (set_attrs & GRUB_MEM_ATTR_X) ? "x" : "", -+ (clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "", -+ (clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "", -+ (clear_attrs & GRUB_MEM_ATTR_X) ? "x" : ""); -+ return 0; -+ } -+ -+ uefi_set_attrs = grub_mem_attrs_to_uefi_mem_attrs (set_attrs); -+ grub_dprintf ("nx", "translating set_attrs from 0x%lx to 0x%lx\n", set_attrs, uefi_set_attrs); -+ uefi_clear_attrs = grub_mem_attrs_to_uefi_mem_attrs (clear_attrs); -+ grub_dprintf ("nx", "translating clear_attrs from 0x%lx to 0x%lx\n", clear_attrs, uefi_clear_attrs); -+ if (uefi_set_attrs) -+ efi_status = efi_call_4(proto->set_memory_attributes, -+ proto, physaddr, size, uefi_set_attrs); -+ if (efi_status == GRUB_EFI_SUCCESS && uefi_clear_attrs) -+ efi_status = efi_call_4(proto->clear_memory_attributes, -+ proto, physaddr, size, uefi_clear_attrs); -+ -+ err = grub_get_mem_attrs (addr, size, &after); -+ if (err) -+ grub_dprintf ("nx", "grub_get_mem_attrs(0x%"PRIxGRUB_ADDR", %"PRIuGRUB_SIZE", %p) -> 0x%x\n", -+ addr, size, &after, err); -+ -+ grub_dprintf ("nx", "set +%s%s%s -%s%s%s on 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" before:%c%c%c after:%c%c%c\n", -+ (set_attrs & GRUB_MEM_ATTR_R) ? "r" : "", -+ (set_attrs & GRUB_MEM_ATTR_W) ? "w" : "", -+ (set_attrs & GRUB_MEM_ATTR_X) ? "x" : "", -+ (clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "", -+ (clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "", -+ (clear_attrs & GRUB_MEM_ATTR_X) ? "x" : "", -+ addr, addr + size - 1, -+ (before & GRUB_MEM_ATTR_R) ? 'r' : '-', -+ (before & GRUB_MEM_ATTR_W) ? 'w' : '-', -+ (before & GRUB_MEM_ATTR_X) ? 'x' : '-', -+ (after & GRUB_MEM_ATTR_R) ? 'r' : '-', -+ (after & GRUB_MEM_ATTR_W) ? 'w' : '-', -+ (after & GRUB_MEM_ATTR_X) ? 'x' : '-'); -+ -+ return grub_efi_status_to_err (efi_status); -+} -diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h -index f431f49973..464842ba37 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -363,6 +363,11 @@ - { 0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \ - } - -+#define GRUB_EFI_MEMORY_ATTRIBUTE_PROTOCOL_GUID \ -+ { 0xf4560cf6, 0x40ec, 0x4b4a, \ -+ { 0xa1, 0x92, 0xbf, 0x1d, 0x57, 0xd0, 0xb1, 0x89 } \ -+ } -+ - struct grub_efi_sal_system_table - { - grub_uint32_t signature; -@@ -2102,6 +2107,26 @@ struct grub_efi_ip6_config_manual_address { - }; - typedef struct grub_efi_ip6_config_manual_address grub_efi_ip6_config_manual_address_t; - -+struct grub_efi_memory_attribute_protocol -+{ -+ grub_efi_status_t (*get_memory_attributes) ( -+ struct grub_efi_memory_attribute_protocol *this, -+ grub_efi_physical_address_t base_address, -+ grub_efi_uint64_t length, -+ grub_efi_uint64_t *attributes); -+ grub_efi_status_t (*set_memory_attributes) ( -+ struct grub_efi_memory_attribute_protocol *this, -+ grub_efi_physical_address_t base_address, -+ grub_efi_uint64_t length, -+ grub_efi_uint64_t attributes); -+ grub_efi_status_t (*clear_memory_attributes) ( -+ struct grub_efi_memory_attribute_protocol *this, -+ grub_efi_physical_address_t base_address, -+ grub_efi_uint64_t length, -+ grub_efi_uint64_t attributes); -+}; -+typedef struct grub_efi_memory_attribute_protocol grub_efi_memory_attribute_protocol_t; -+ - #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ - || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \ - || defined(__riscv) -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index ec52083c49..34825c4adc 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -164,4 +164,6 @@ struct grub_net_card; - grub_efi_handle_t - grub_efinet_get_device_handle (struct grub_net_card *card); - -+grub_err_t EXPORT_FUNC(grub_efi_status_to_err) (grub_efi_status_t status); -+ - #endif /* ! GRUB_EFI_EFI_HEADER */ -diff --git a/include/grub/mm.h b/include/grub/mm.h -index 9c38dd3ca5..d81623d226 100644 ---- a/include/grub/mm.h -+++ b/include/grub/mm.h -@@ -22,6 +22,7 @@ - - #include - #include -+#include - #include - - #ifndef NULL -@@ -38,6 +39,37 @@ void *EXPORT_FUNC(grub_realloc) (void *ptr, grub_size_t size); - void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size); - #endif - -+#define GRUB_MEM_ATTR_R 0x0000000000000004LLU -+#define GRUB_MEM_ATTR_W 0x0000000000000002LLU -+#define GRUB_MEM_ATTR_X 0x0000000000000001LLU -+ -+#ifdef GRUB_MACHINE_EFI -+grub_err_t EXPORT_FUNC(grub_get_mem_attrs) (grub_addr_t addr, -+ grub_size_t size, -+ grub_uint64_t *attrs); -+grub_err_t EXPORT_FUNC(grub_update_mem_attrs) (grub_addr_t addr, -+ grub_size_t size, -+ grub_uint64_t set_attrs, -+ grub_uint64_t clear_attrs); -+#else /* !GRUB_MACHINE_EFI */ -+static inline grub_err_t -+grub_get_mem_attrs (grub_addr_t addr __attribute__((__unused__)), -+ grub_size_t size __attribute__((__unused__)), -+ grub_uint64_t *attrs __attribute__((__unused__))) -+{ -+ return GRUB_ERR_NONE; -+} -+ -+static inline grub_err_t -+grub_update_mem_attrs (grub_addr_t addr __attribute__((__unused__)), -+ grub_size_t size __attribute__((__unused__)), -+ grub_uint64_t set_attrs __attribute__((__unused__)), -+ grub_uint64_t clear_attrs __attribute__((__unused__))) -+{ -+ return GRUB_ERR_NONE; -+} -+#endif /* GRUB_MACHINE_EFI */ -+ - void grub_mm_check_real (const char *file, int line); - #define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__); - diff --git a/0253-nx-set-page-permissions-for-loaded-modules.patch b/0253-nx-set-page-permissions-for-loaded-modules.patch deleted file mode 100644 index 9e0aebbcbc79586f3fcdc2d6662da90dcc9451a0..0000000000000000000000000000000000000000 --- a/0253-nx-set-page-permissions-for-loaded-modules.patch +++ /dev/null @@ -1,263 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 21 Mar 2022 17:46:35 -0400 -Subject: [PATCH] nx: set page permissions for loaded modules. - -For NX, we need to set write and executable permissions on the sections -of grub modules when we load them. - -On sections with SHF_ALLOC set, which is typically everything except -.modname and the symbol and string tables, this patch clears the Read -Only flag on sections that have the ELF flag SHF_WRITE set, and clears -the No eXecute flag on sections with SHF_EXECINSTR set. In all other -cases it sets both flags. - -Signed-off-by: Peter Jones -[rharwood: arm tgptr -> tgaddr] -Signed-off-by: Robbie Harwood ---- - grub-core/kern/dl.c | 120 +++++++++++++++++++++++++++++++++++++++------------- - include/grub/dl.h | 44 +++++++++++++++++++ - 2 files changed, 134 insertions(+), 30 deletions(-) - -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index 8c7aacef39..d5de80186f 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -285,6 +285,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - #endif - char *ptr; - -+ grub_dprintf ("modules", "loading segments for \"%s\"\n", mod->name); -+ - arch_addralign = grub_arch_dl_min_alignment (); - - for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff); -@@ -384,6 +386,7 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - ptr += got; - #endif - -+ grub_dprintf ("modules", "done loading segments for \"%s\"\n", mod->name); - return GRUB_ERR_NONE; - } - -@@ -517,23 +520,6 @@ grub_dl_find_section (Elf_Ehdr *e, const char *name) - return s; - return NULL; - } --static long --grub_dl_find_section_index (Elf_Ehdr *e, const char *name) --{ -- Elf_Shdr *s; -- const char *str; -- unsigned i; -- -- s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize); -- str = (char *) e + s->sh_offset; -- -- for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); -- i < e->e_shnum; -- i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) -- if (grub_strcmp (str + s->sh_name, name) == 0) -- return (long)i; -- return -1; --} - - /* Me, Vladimir Serbinenko, hereby I add this module check as per new - GNU module policy. Note that this license check is informative only. -@@ -662,6 +648,7 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr) - Elf_Shdr *s; - unsigned i; - -+ grub_dprintf ("modules", "relocating symbols for \"%s\"\n", mod->name); - for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); - i < e->e_shnum; - i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) -@@ -670,24 +657,95 @@ grub_dl_relocate_symbols (grub_dl_t mod, void *ehdr) - grub_dl_segment_t seg; - grub_err_t err; - -- /* Find the target segment. */ -- for (seg = mod->segment; seg; seg = seg->next) -- if (seg->section == s->sh_info) -- break; -+ seg = grub_dl_find_segment(mod, s->sh_info); -+ if (!seg) -+ continue; - -- if (seg) -- { -- if (!mod->symtab) -- return grub_error (GRUB_ERR_BAD_MODULE, "relocation without symbol table"); -+ if (!mod->symtab) -+ return grub_error (GRUB_ERR_BAD_MODULE, "relocation without symbol table"); - -- err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg); -- if (err) -- return err; -- } -+ err = grub_arch_dl_relocate_symbols (mod, ehdr, s, seg); -+ if (err) -+ return err; - } - -+ grub_dprintf ("modules", "done relocating symbols for \"%s\"\n", mod->name); - return GRUB_ERR_NONE; - } -+ -+static grub_err_t -+grub_dl_set_mem_attrs (grub_dl_t mod, void *ehdr) -+{ -+ unsigned i; -+ const Elf_Shdr *s; -+ const Elf_Ehdr *e = ehdr; -+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) -+ grub_size_t arch_addralign = grub_arch_dl_min_alignment (); -+ grub_addr_t tgaddr; -+ grub_uint64_t tgsz; -+#endif -+ -+ grub_dprintf ("modules", "updating memory attributes for \"%s\"\n", -+ mod->name); -+ for (i = 0, s = (const Elf_Shdr *)((const char *) e + e->e_shoff); -+ i < e->e_shnum; -+ i++, s = (const Elf_Shdr *)((const char *) s + e->e_shentsize)) -+ { -+ grub_dl_segment_t seg; -+ grub_uint64_t set_attrs = GRUB_MEM_ATTR_R; -+ grub_uint64_t clear_attrs = GRUB_MEM_ATTR_W|GRUB_MEM_ATTR_X; -+ -+ seg = grub_dl_find_segment(mod, i); -+ if (!seg) -+ continue; -+ -+ if (seg->size == 0 || !(s->sh_flags & SHF_ALLOC)) -+ continue; -+ -+ if (s->sh_flags & SHF_WRITE) -+ { -+ set_attrs |= GRUB_MEM_ATTR_W; -+ clear_attrs &= ~GRUB_MEM_ATTR_W; -+ } -+ -+ if (s->sh_flags & SHF_EXECINSTR) -+ { -+ set_attrs |= GRUB_MEM_ATTR_X; -+ clear_attrs &= ~GRUB_MEM_ATTR_X; -+ } -+ -+ grub_dprintf ("modules", "setting memory attrs for section \"%s\" to -%s%s%s+%s%s%s\n", -+ grub_dl_get_section_name(e, s), -+ (clear_attrs & GRUB_MEM_ATTR_R) ? "r" : "", -+ (clear_attrs & GRUB_MEM_ATTR_W) ? "w" : "", -+ (clear_attrs & GRUB_MEM_ATTR_X) ? "x" : "", -+ (set_attrs & GRUB_MEM_ATTR_R) ? "r" : "", -+ (set_attrs & GRUB_MEM_ATTR_W) ? "w" : "", -+ (set_attrs & GRUB_MEM_ATTR_X) ? "x" : ""); -+ grub_update_mem_attrs ((grub_addr_t)(seg->addr), seg->size, set_attrs, clear_attrs); -+ } -+ -+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) -+ tgaddr = grub_min((grub_addr_t)mod->tramp, (grub_addr_t)mod->got); -+ tgsz = grub_max((grub_addr_t)mod->trampptr, (grub_addr_t)mod->gotptr) - tgaddr; -+ -+ if (tgsz) -+ { -+ tgsz = ALIGN_UP(tgsz, arch_addralign); -+ -+ grub_dprintf ("modules", "updating attributes for GOT and trampolines\n", -+ mod->name); -+ grub_update_mem_attrs (tgaddr, tgsz, GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_X, -+ GRUB_MEM_ATTR_W); -+ } -+#endif -+ -+ grub_dprintf ("modules", "done updating module memory attributes for \"%s\"\n", -+ mod->name); -+ -+ return GRUB_ERR_NONE; -+} -+ - static void - grub_dl_print_gdb_info (grub_dl_t mod, Elf_Ehdr *e) - { -@@ -753,6 +811,7 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) - mod->ref_count = 1; - - grub_dprintf ("modules", "relocating to %p\n", mod); -+ - /* Me, Vladimir Serbinenko, hereby I add this module check as per new - GNU module policy. Note that this license check is informative only. - Modules have to be licensed under GPLv3 or GPLv3+ (optionally -@@ -766,7 +825,8 @@ grub_dl_load_core_noinit (void *addr, grub_size_t size) - || grub_dl_resolve_dependencies (mod, e) - || grub_dl_load_segments (mod, e) - || grub_dl_resolve_symbols (mod, e) -- || grub_dl_relocate_symbols (mod, e)) -+ || grub_dl_relocate_symbols (mod, e) -+ || grub_dl_set_mem_attrs (mod, e)) - { - mod->fini = 0; - grub_dl_unload (mod); -diff --git a/include/grub/dl.h b/include/grub/dl.h -index f36ed5cb17..45ac8e339f 100644 ---- a/include/grub/dl.h -+++ b/include/grub/dl.h -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #endif - - /* -@@ -268,6 +269,49 @@ grub_dl_is_persistent (grub_dl_t mod) - return mod->persistent; - } - -+static inline const char * -+grub_dl_get_section_name (const Elf_Ehdr *e, const Elf_Shdr *s) -+{ -+ Elf_Shdr *str_s; -+ const char *str; -+ -+ str_s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize); -+ str = (char *) e + str_s->sh_offset; -+ -+ return str + s->sh_name; -+} -+ -+static inline long -+grub_dl_find_section_index (Elf_Ehdr *e, const char *name) -+{ -+ Elf_Shdr *s; -+ const char *str; -+ unsigned i; -+ -+ s = (Elf_Shdr *) ((char *) e + e->e_shoff + e->e_shstrndx * e->e_shentsize); -+ str = (char *) e + s->sh_offset; -+ -+ for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff); -+ i < e->e_shnum; -+ i++, s = (Elf_Shdr *) ((char *) s + e->e_shentsize)) -+ if (grub_strcmp (str + s->sh_name, name) == 0) -+ return (long)i; -+ return -1; -+} -+ -+/* Return the segment for a section of index N */ -+static inline grub_dl_segment_t -+grub_dl_find_segment (grub_dl_t mod, unsigned n) -+{ -+ grub_dl_segment_t seg; -+ -+ for (seg = mod->segment; seg; seg = seg->next) -+ if (seg->section == n) -+ return seg; -+ -+ return NULL; -+} -+ - #endif - - void * EXPORT_FUNC(grub_resolve_symbol) (const char *name); diff --git a/0254-grub-probe-document-the-behavior-of-multiple-v.patch b/0254-grub-probe-document-the-behavior-of-multiple-v.patch deleted file mode 100644 index 4e9d7ccfeb8b542fc8a14b787adab975bdc05522..0000000000000000000000000000000000000000 --- a/0254-grub-probe-document-the-behavior-of-multiple-v.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Fri, 15 Jul 2022 15:49:25 -0400 -Subject: [PATCH] grub-probe: document the behavior of multiple -v - -Signed-off-by: Robbie Harwood -(cherry picked from commit 51a55233eed08f7f12276afd6b3724b807a0b680) ---- - util/grub-probe.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/util/grub-probe.c b/util/grub-probe.c -index c6fac732b4..ba867319a7 100644 ---- a/util/grub-probe.c -+++ b/util/grub-probe.c -@@ -732,7 +732,8 @@ static struct argp_option options[] = { - {"device-map", 'm', N_("FILE"), 0, - N_("use FILE as the device map [default=%s]"), 0}, - {"target", 't', N_("TARGET"), 0, 0, 0}, -- {"verbose", 'v', 0, 0, N_("print verbose messages."), 0}, -+ {"verbose", 'v', 0, 0, -+ N_("print verbose messages (pass twice to enable debug printing)."), 0}, - {0, '0', 0, 0, N_("separate items in output using ASCII NUL characters"), 0}, - { 0, 0, 0, 0, 0, 0 } - }; diff --git a/0255-grub_fs_probe-dprint-errors-from-filesystems.patch b/0255-grub_fs_probe-dprint-errors-from-filesystems.patch deleted file mode 100644 index 1455ae4bb4bafda446948c6db8737fa7990ce650..0000000000000000000000000000000000000000 --- a/0255-grub_fs_probe-dprint-errors-from-filesystems.patch +++ /dev/null @@ -1,43 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Fri, 15 Jul 2022 15:39:41 -0400 -Subject: [PATCH] grub_fs_probe(): dprint errors from filesystems - -When filesystem detection fails, all that's currently debug-logged is a -series of messages like: - - grub-core/kern/fs.c:56:fs: Detecting ntfs... - grub-core/kern/fs.c:76:fs: ntfs detection failed. - -repeated for each filesystem. Any messages provided to grub_error() by -the filesystem are lost, and one has to break out gdb to figure out what -went wrong. - -With this change, one instead sees: - - grub-core/kern/fs.c:56:fs: Detecting fat... - grub-core/osdep/hostdisk.c:357:hostdisk: reusing open device - `/path/to/device' - grub-core/kern/fs.c:77:fs: error: invalid modification timestamp for /. - grub-core/kern/fs.c:79:fs: fat detection failed. - -in the debug prints. - -Signed-off-by: Robbie Harwood -(cherry picked from commit 838c79d658797d0662ee7f9e033e38ee88059e02) ---- - grub-core/kern/fs.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/grub-core/kern/fs.c b/grub-core/kern/fs.c -index c698295bcb..b58e2ae1d2 100644 ---- a/grub-core/kern/fs.c -+++ b/grub-core/kern/fs.c -@@ -74,6 +74,7 @@ grub_fs_probe (grub_device_t device) - if (grub_errno == GRUB_ERR_NONE) - return p; - -+ grub_dprintf ("fs", _("error: %s.\n"), grub_errmsg); - grub_error_push (); - grub_dprintf ("fs", "%s detection failed.\n", p->name); - grub_error_pop (); diff --git a/0256-fs-fat-don-t-error-when-mtime-is-0.patch b/0256-fs-fat-don-t-error-when-mtime-is-0.patch deleted file mode 100644 index f014f6c9bbc38f0811bd788246ae0c0006abeeb7..0000000000000000000000000000000000000000 --- a/0256-fs-fat-don-t-error-when-mtime-is-0.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Fri, 15 Jul 2022 15:42:41 -0400 -Subject: [PATCH] fs/fat: don't error when mtime is 0 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In the wild, we occasionally see valid ESPs where some file modification times -are 0. For instance: - - ├── [Dec 31 1979] EFI - │ ├── [Dec 31 1979] BOOT - │ │ ├── [Dec 31 1979] BOOTX64.EFI - │ │ └── [Dec 31 1979] fbx64.efi - │ └── [Jun 27 02:41] fedora - │ ├── [Dec 31 1979] BOOTX64.CSV - │ ├── [Dec 31 1979] fonts - │ ├── [Mar 14 03:35] fw - │ │ ├── [Mar 14 03:35] fwupd-359c1169-abd6-4a0d-8bce-e4d4713335c1.cap - │ │ ├── [Mar 14 03:34] fwupd-9d255c4b-2d88-4861-860d-7ee52ade9463.cap - │ │ └── [Mar 14 03:34] fwupd-b36438d8-9128-49d2-b280-487be02d948b.cap - │ ├── [Dec 31 1979] fwupdx64.efi - │ ├── [May 10 10:47] grub.cfg - │ ├── [Jun 3 12:38] grub.cfg.new.new - │ ├── [May 10 10:41] grub.cfg.old - │ ├── [Jun 27 02:41] grubenv - │ ├── [Dec 31 1979] grubx64.efi - │ ├── [Dec 31 1979] mmx64.efi - │ ├── [Dec 31 1979] shim.efi - │ ├── [Dec 31 1979] shimx64.efi - │ └── [Dec 31 1979] shimx64-fedora.efi - └── [Dec 31 1979] FSCK0000.REC - - 5 directories, 17 files - -This causes grub-probe failure, which in turn causes grub-mkconfig -failure. They are valid filesystems that appear intact, and the Linux -FAT stack is able to mount and manipulate them without complaint. - -The check for mtime of 0 has been present since -20def1a3c3952982395cd7c3ea7e78638527962b ("fat: support file -modification times"). - -Signed-off-by: Robbie Harwood -(cherry picked from commit 0615c4887352e32d7bb7198e9ad0d695f9dc2c31) ---- - grub-core/fs/fat.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/grub-core/fs/fat.c b/grub-core/fs/fat.c -index dd82e4ee35..ff6200c5be 100644 ---- a/grub-core/fs/fat.c -+++ b/grub-core/fs/fat.c -@@ -1027,9 +1027,6 @@ grub_fat_dir (grub_device_t device, const char *path, grub_fs_dir_hook_t hook, - grub_le_to_cpu16 (ctxt.dir.w_date), - &info.mtime); - #endif -- if (info.mtimeset == 0) -- grub_error (GRUB_ERR_OUT_OF_RANGE, -- "invalid modification timestamp for %s", path); - - if (hook (ctxt.filename, &info, hook_data)) - break; diff --git a/0257-Make-debug-file-show-which-file-filters-get-run.patch b/0257-Make-debug-file-show-which-file-filters-get-run.patch deleted file mode 100644 index 4ac32cb4ac942c43b62bc5a72d47a882ec885cca..0000000000000000000000000000000000000000 --- a/0257-Make-debug-file-show-which-file-filters-get-run.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 29 Jul 2022 15:56:00 -0400 -Subject: [PATCH] Make debug=file show which file filters get run. - -If one of the file filters breaks things, it's hard to figure out where -it has happened. - -This makes grub log which filter is being run, which makes it easier to -figure out where you are in the sequence of events. - -Signed-off-by: Peter Jones ---- - grub-core/kern/file.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/grub-core/kern/file.c b/grub-core/kern/file.c -index ed69fc0f0f..20a4c839aa 100644 ---- a/grub-core/kern/file.c -+++ b/grub-core/kern/file.c -@@ -30,6 +30,14 @@ void (*EXPORT_VAR (grub_grubnet_fini)) (void); - - grub_file_filter_t grub_file_filters[GRUB_FILE_FILTER_MAX]; - -+static const char *filter_names[] = { -+ [GRUB_FILE_FILTER_VERIFY] = "GRUB_FILE_FILTER_VERIFY", -+ [GRUB_FILE_FILTER_GZIO] = "GRUB_FILE_FILTER_GZIO", -+ [GRUB_FILE_FILTER_XZIO] = "GRUB_FILE_FILTER_XZIO", -+ [GRUB_FILE_FILTER_LZOPIO] = "GRUB_FILE_FILTER_LZOPIO", -+ [GRUB_FILE_FILTER_MAX] = "GRUB_FILE_FILTER_MAX" -+}; -+ - /* Get the device part of the filename NAME. It is enclosed by parentheses. */ - char * - grub_file_get_device_name (const char *name) -@@ -121,6 +129,9 @@ grub_file_open (const char *name, enum grub_file_type type) - if (grub_file_filters[filter]) - { - last_file = file; -+ if (filter < GRUB_FILE_FILTER_MAX) -+ grub_dprintf ("file", "Running %s file filter\n", -+ filter_names[filter]); - file = grub_file_filters[filter] (file, type); - if (file && file != last_file) - { diff --git a/0258-BLS-create-etc-kernel-cmdline-during-mkconfig.patch b/0258-BLS-create-etc-kernel-cmdline-during-mkconfig.patch deleted file mode 100644 index 7080b6f6553766f342228ed39bf60c7bbce034aa..0000000000000000000000000000000000000000 --- a/0258-BLS-create-etc-kernel-cmdline-during-mkconfig.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Tue, 2 Aug 2022 15:56:28 -0400 -Subject: [PATCH] BLS: create /etc/kernel/cmdline during mkconfig - -Signed-off-by: Robbie Harwood ---- - util/grub.d/10_linux.in | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 6af84b44e1..950a92f5e8 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -161,6 +161,12 @@ update_bls_cmdline() - local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" - local -a files=($(get_sorted_bls)) - -+ if [[ ! -f /etc/kernel/cmdline ]]; then -+ # anaconda has the correct information to do this during install; -+ # afterward, grubby will take care of syncing on updates. -+ echo "$cmdline rhgb quiet" > /etc/kernel/cmdline -+ fi -+ - for bls in "${files[@]}"; do - local options="${cmdline}" - if [ -z "${bls##*debug*}" ]; then diff --git a/0259-squish-don-t-dup-rhgb-quiet-check-mtimes.patch b/0259-squish-don-t-dup-rhgb-quiet-check-mtimes.patch deleted file mode 100644 index 013b915e941b9ff0396fdc579758a9c74a3c0f98..0000000000000000000000000000000000000000 --- a/0259-squish-don-t-dup-rhgb-quiet-check-mtimes.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Wed, 17 Aug 2022 10:26:07 -0400 -Subject: [PATCH] squish: don't dup rhgb quiet, check mtimes - -Signed-off-by: Robbie Harwood ---- - util/grub.d/10_linux.in | 14 ++++++++++---- - 1 file changed, 10 insertions(+), 4 deletions(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 950a92f5e8..03f091a4dc 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -161,10 +161,16 @@ update_bls_cmdline() - local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" - local -a files=($(get_sorted_bls)) - -- if [[ ! -f /etc/kernel/cmdline ]]; then -- # anaconda has the correct information to do this during install; -- # afterward, grubby will take care of syncing on updates. -- echo "$cmdline rhgb quiet" > /etc/kernel/cmdline -+ if [[ ! -f /etc/kernel/cmdline ]] || -+ [[ /etc/kernel/cmdline -ot /etc/default/grub ]]; then -+ # anaconda has the correct information to create this during install; -+ # afterward, grubby will take care of syncing on updates. If the user -+ # has modified /etc/default/grub, try to cope. -+ if [[ ! "$cmdline" =~ "rhgb quiet" ]]; then -+ # ensure these only show up once -+ cmdline="$cmdline rhgb quiet" -+ fi -+ echo "$cmdline" > /etc/kernel/cmdline - fi - - for bls in "${files[@]}"; do diff --git a/0260-squish-give-up-on-rhgb-quiet.patch b/0260-squish-give-up-on-rhgb-quiet.patch deleted file mode 100644 index bbead5e97bcec34652b1b73f29f553e136f12e1e..0000000000000000000000000000000000000000 --- a/0260-squish-give-up-on-rhgb-quiet.patch +++ /dev/null @@ -1,25 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Wed, 17 Aug 2022 11:30:30 -0400 -Subject: [PATCH] squish: give up on rhgb quiet - -Signed-off-by: Robbie Harwood ---- - util/grub.d/10_linux.in | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 03f091a4dc..5ad624bfec 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -166,10 +166,6 @@ update_bls_cmdline() - # anaconda has the correct information to create this during install; - # afterward, grubby will take care of syncing on updates. If the user - # has modified /etc/default/grub, try to cope. -- if [[ ! "$cmdline" =~ "rhgb quiet" ]]; then -- # ensure these only show up once -- cmdline="$cmdline rhgb quiet" -- fi - echo "$cmdline" > /etc/kernel/cmdline - fi - diff --git a/0261-squish-BLS-only-write-etc-kernel-cmdline-if-writable.patch b/0261-squish-BLS-only-write-etc-kernel-cmdline-if-writable.patch deleted file mode 100644 index ed378b8996ac71950335a8d922a202bc070faf1b..0000000000000000000000000000000000000000 --- a/0261-squish-BLS-only-write-etc-kernel-cmdline-if-writable.patch +++ /dev/null @@ -1,57 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jonathan Lebon -Date: Wed, 17 Aug 2022 10:26:03 -0400 -Subject: [PATCH] squish: BLS: only write /etc/kernel/cmdline if writable - -On OSTree systems, `grub2-mkconfig` is run with `/etc` mounted read-only -because as part of the promise of transactional updates, we want to make -sure that we're not modifying the current deployment's state (`/etc` or -`/var`). - -This conflicts with 0837dcdf1 ("BLS: create /etc/kernel/cmdline during -mkconfig") which wants to write to `/etc/kernel/cmdline`. I'm not -exactly sure on the background there, but based on the comment I think -the intent is to fulfill grubby's expectation that the file exists. - -However, in systems like Silverblue, kernel arguments are managed by the -rpm-ostree stack and grubby is not shipped at all. - -Adjust the script slightly so that we only write `/etc/kernel/cmdline` -if the parent directory is writable. - -In the future, we're hoping to simplify things further on rpm-ostree -systems by not running `grub2-mkconfig` at all since libostree already -directly writes BLS entries. Doing that would also have avoided this, -but ratcheting it into existing systems needs more careful thought. - -Signed-off-by: Jonathan Lebon - -Fixes: https://github.com/fedora-silverblue/issue-tracker/issues/322 ---- - util/grub.d/10_linux.in | 13 +++++++------ - 1 file changed, 7 insertions(+), 6 deletions(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index 5ad624bfec..e5e87a6d80 100644 ---- a/util/grub.d/10_linux.in -+++ b/util/grub.d/10_linux.in -@@ -161,12 +161,13 @@ update_bls_cmdline() - local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}" - local -a files=($(get_sorted_bls)) - -- if [[ ! -f /etc/kernel/cmdline ]] || -- [[ /etc/kernel/cmdline -ot /etc/default/grub ]]; then -- # anaconda has the correct information to create this during install; -- # afterward, grubby will take care of syncing on updates. If the user -- # has modified /etc/default/grub, try to cope. -- echo "$cmdline" > /etc/kernel/cmdline -+ if [ -w /etc/kernel ] && -+ [[ ! -f /etc/kernel/cmdline || -+ /etc/kernel/cmdline -ot /etc/default/grub ]]; then -+ # anaconda has the correct information to create this during install; -+ # afterward, grubby will take care of syncing on updates. If the user -+ # has modified /etc/default/grub, try to cope. -+ echo "$cmdline" > /etc/kernel/cmdline - fi - - for bls in "${files[@]}"; do diff --git a/0262-blscfg-Don-t-root-device-in-emu-builds.patch b/0262-blscfg-Don-t-root-device-in-emu-builds.patch deleted file mode 100644 index 3fe8baf22f5bedf825921847588c374cccfde9c4..0000000000000000000000000000000000000000 --- a/0262-blscfg-Don-t-root-device-in-emu-builds.patch +++ /dev/null @@ -1,27 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Robbie Harwood -Date: Thu, 25 Aug 2022 17:57:55 -0400 -Subject: [PATCH] blscfg: Don't root device in emu builds - -Otherwise, we end up looking for kernel/initrd in /boot/boot which -doesn't work at all. Non-emu builds need to be looking in -($root)/boot/, which is what this is for. - -Signed-off-by: Robbie Harwood ---- - grub-core/commands/blscfg.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c -index e907a6a5d2..dbd0899acf 100644 ---- a/grub-core/commands/blscfg.c -+++ b/grub-core/commands/blscfg.c -@@ -41,7 +41,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); - - #define GRUB_BLS_CONFIG_PATH "/loader/entries/" - #ifdef GRUB_MACHINE_EMU --#define GRUB_BOOT_DEVICE "/boot" -+#define GRUB_BOOT_DEVICE "" - #else - #define GRUB_BOOT_DEVICE "($root)" - #endif diff --git a/0263-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch b/0263-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch deleted file mode 100644 index e264b0999c455242cc9070ba2dff31d476c3821e..0000000000000000000000000000000000000000 --- a/0263-font-Reject-glyphs-exceeds-font-max_glyph_width-or-f.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Wed, 3 Aug 2022 19:45:33 +0800 -Subject: [PATCH] font: Reject glyphs exceeds font->max_glyph_width or - font->max_glyph_height - -Check glyph's width and height against limits specified in font's -metadata. Reject the glyph (and font) if such limits are exceeded. - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit 5760fcfd466cc757540ea0d591bad6a08caeaa16) -(cherry picked from commit 3b410ef4bb95e607cadeba2193fa90ae9bddb98d) ---- - grub-core/font/font.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index d09bb38d89..2f09a4a55b 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -760,7 +760,9 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) - || read_be_uint16 (font->file, &height) != 0 - || read_be_int16 (font->file, &xoff) != 0 - || read_be_int16 (font->file, &yoff) != 0 -- || read_be_int16 (font->file, &dwidth) != 0) -+ || read_be_int16 (font->file, &dwidth) != 0 -+ || width > font->max_char_width -+ || height > font->max_char_height) - { - remove_font (font); - return 0; diff --git a/0264-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch b/0264-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch deleted file mode 100644 index 7ec23ab8cd1788f26029a3936fc77c4575a9f375..0000000000000000000000000000000000000000 --- a/0264-font-Fix-size-overflow-in-grub_font_get_glyph_intern.patch +++ /dev/null @@ -1,111 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Fri, 5 Aug 2022 00:51:20 +0800 -Subject: [PATCH] font: Fix size overflow in grub_font_get_glyph_internal() - -The length of memory allocation and file read may overflow. This patch -fixes the problem by using safemath macros. - -There is a lot of code repetition like "(x * y + 7) / 8". It is unsafe -if overflow happens. This patch introduces grub_video_bitmap_calc_1bpp_bufsz(). -It is safe replacement for such code. It has safemath-like prototype. - -This patch also introduces grub_cast(value, pointer), it casts value to -typeof(*pointer) then store the value to *pointer. It returns true when -overflow occurs or false if there is no overflow. The semantics of arguments -and return value are designed to be consistent with other safemath macros. - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit 941d10ad6f1dcbd12fb613002249e29ba035f985) -(cherry picked from commit 6bca9693878bdf61dd62b8c784862a48e75f569a) ---- - grub-core/font/font.c | 17 +++++++++++++---- - include/grub/bitmap.h | 18 ++++++++++++++++++ - include/grub/safemath.h | 2 ++ - 3 files changed, 33 insertions(+), 4 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 2f09a4a55b..6a3fbebbd8 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -739,7 +739,8 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) - grub_int16_t xoff; - grub_int16_t yoff; - grub_int16_t dwidth; -- int len; -+ grub_ssize_t len; -+ grub_size_t sz; - - if (index_entry->glyph) - /* Return cached glyph. */ -@@ -768,9 +769,17 @@ grub_font_get_glyph_internal (grub_font_t font, grub_uint32_t code) - return 0; - } - -- len = (width * height + 7) / 8; -- glyph = grub_malloc (sizeof (struct grub_font_glyph) + len); -- if (!glyph) -+ /* Calculate real struct size of current glyph. */ -+ if (grub_video_bitmap_calc_1bpp_bufsz (width, height, &len) || -+ grub_add (sizeof (struct grub_font_glyph), len, &sz)) -+ { -+ remove_font (font); -+ return 0; -+ } -+ -+ /* Allocate and initialize the glyph struct. */ -+ glyph = grub_malloc (sz); -+ if (glyph == NULL) - { - remove_font (font); - return 0; -diff --git a/include/grub/bitmap.h b/include/grub/bitmap.h -index 5728f8ca3a..0d9603f619 100644 ---- a/include/grub/bitmap.h -+++ b/include/grub/bitmap.h -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - struct grub_video_bitmap - { -@@ -79,6 +80,23 @@ grub_video_bitmap_get_height (struct grub_video_bitmap *bitmap) - return bitmap->mode_info.height; - } - -+/* -+ * Calculate and store the size of data buffer of 1bit bitmap in result. -+ * Equivalent to "*result = (width * height + 7) / 8" if no overflow occurs. -+ * Return true when overflow occurs or false if there is no overflow. -+ * This function is intentionally implemented as a macro instead of -+ * an inline function. Although a bit awkward, it preserves data types for -+ * safemath macros and reduces macro side effects as much as possible. -+ * -+ * XXX: Will report false overflow if width * height > UINT64_MAX. -+ */ -+#define grub_video_bitmap_calc_1bpp_bufsz(width, height, result) \ -+({ \ -+ grub_uint64_t _bitmap_pixels; \ -+ grub_mul ((width), (height), &_bitmap_pixels) ? 1 : \ -+ grub_cast (_bitmap_pixels / GRUB_CHAR_BIT + !!(_bitmap_pixels % GRUB_CHAR_BIT), (result)); \ -+}) -+ - void EXPORT_FUNC (grub_video_bitmap_get_mode_info) (struct grub_video_bitmap *bitmap, - struct grub_video_mode_info *mode_info); - -diff --git a/include/grub/safemath.h b/include/grub/safemath.h -index c17b89bba1..bb0f826de1 100644 ---- a/include/grub/safemath.h -+++ b/include/grub/safemath.h -@@ -30,6 +30,8 @@ - #define grub_sub(a, b, res) __builtin_sub_overflow(a, b, res) - #define grub_mul(a, b, res) __builtin_mul_overflow(a, b, res) - -+#define grub_cast(a, res) grub_add ((a), 0, (res)) -+ - #else - #error gcc 5.1 or newer or clang 3.8 or newer is required - #endif diff --git a/0265-font-Fix-several-integer-overflows-in-grub_font_cons.patch b/0265-font-Fix-several-integer-overflows-in-grub_font_cons.patch deleted file mode 100644 index fcc1d3c32277c0e16c73a7ac7cf398e569c39eed..0000000000000000000000000000000000000000 --- a/0265-font-Fix-several-integer-overflows-in-grub_font_cons.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Fri, 5 Aug 2022 01:58:27 +0800 -Subject: [PATCH] font: Fix several integer overflows in - grub_font_construct_glyph() - -This patch fixes several integer overflows in grub_font_construct_glyph(). -Glyphs of invalid size, zero or leading to an overflow, are rejected. -The inconsistency between "glyph" and "max_glyph_size" when grub_malloc() -returns NULL is fixed too. - -Fixes: CVE-2022-2601 - -Reported-by: Zhang Boyang -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit b1805f251b31a9d3cfae5c3572ddfa630145dbbf) -(cherry picked from commit b91eb9bd6c724339b7d7bb4765b9d36f1ee88b84) ---- - grub-core/font/font.c | 29 +++++++++++++++++------------ - 1 file changed, 17 insertions(+), 12 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 6a3fbebbd8..1fa181d4ca 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -1517,6 +1517,7 @@ grub_font_construct_glyph (grub_font_t hinted_font, - struct grub_video_signed_rect bounds; - static struct grub_font_glyph *glyph = 0; - static grub_size_t max_glyph_size = 0; -+ grub_size_t cur_glyph_size; - - ensure_comb_space (glyph_id); - -@@ -1533,29 +1534,33 @@ grub_font_construct_glyph (grub_font_t hinted_font, - if (!glyph_id->ncomb && !glyph_id->attributes) - return main_glyph; - -- if (max_glyph_size < sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) -+ if (grub_video_bitmap_calc_1bpp_bufsz (bounds.width, bounds.height, &cur_glyph_size) || -+ grub_add (sizeof (*glyph), cur_glyph_size, &cur_glyph_size)) -+ return main_glyph; -+ -+ if (max_glyph_size < cur_glyph_size) - { - grub_free (glyph); -- max_glyph_size = (sizeof (*glyph) + (bounds.width * bounds.height + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT) * 2; -- if (max_glyph_size < 8) -- max_glyph_size = 8; -- glyph = grub_malloc (max_glyph_size); -+ if (grub_mul (cur_glyph_size, 2, &max_glyph_size)) -+ max_glyph_size = 0; -+ glyph = max_glyph_size > 0 ? grub_malloc (max_glyph_size) : NULL; - } - if (!glyph) - { -+ max_glyph_size = 0; - grub_errno = GRUB_ERR_NONE; - return main_glyph; - } - -- grub_memset (glyph, 0, sizeof (*glyph) -- + (bounds.width * bounds.height -- + GRUB_CHAR_BIT - 1) / GRUB_CHAR_BIT); -+ grub_memset (glyph, 0, cur_glyph_size); - - glyph->font = main_glyph->font; -- glyph->width = bounds.width; -- glyph->height = bounds.height; -- glyph->offset_x = bounds.x; -- glyph->offset_y = bounds.y; -+ if (bounds.width == 0 || bounds.height == 0 || -+ grub_cast (bounds.width, &glyph->width) || -+ grub_cast (bounds.height, &glyph->height) || -+ grub_cast (bounds.x, &glyph->offset_x) || -+ grub_cast (bounds.y, &glyph->offset_y)) -+ return main_glyph; - - if (glyph_id->attributes & GRUB_UNICODE_GLYPH_ATTRIBUTE_MIRROR) - grub_font_blit_glyph_mirror (glyph, main_glyph, diff --git a/0266-font-Remove-grub_font_dup_glyph.patch b/0266-font-Remove-grub_font_dup_glyph.patch deleted file mode 100644 index a3493f6b22e8bf44dbc42d8ad6aee67647c7af04..0000000000000000000000000000000000000000 --- a/0266-font-Remove-grub_font_dup_glyph.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Fri, 5 Aug 2022 02:13:29 +0800 -Subject: [PATCH] font: Remove grub_font_dup_glyph() - -Remove grub_font_dup_glyph() since nobody is using it since 2013, and -I'm too lazy to fix the integer overflow problem in it. - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit 25ad31c19c331aaa2dbd9bd2b2e2655de5766a9d) -(cherry picked from commit ad950e1e033318bb50222ed268a6dcfb97389035) ---- - grub-core/font/font.c | 14 -------------- - 1 file changed, 14 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 1fa181d4ca..a115a63b0c 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -1055,20 +1055,6 @@ grub_font_get_glyph_with_fallback (grub_font_t font, grub_uint32_t code) - return best_glyph; - } - --#if 0 --static struct grub_font_glyph * --grub_font_dup_glyph (struct grub_font_glyph *glyph) --{ -- static struct grub_font_glyph *ret; -- ret = grub_malloc (sizeof (*ret) + (glyph->width * glyph->height + 7) / 8); -- if (!ret) -- return NULL; -- grub_memcpy (ret, glyph, sizeof (*ret) -- + (glyph->width * glyph->height + 7) / 8); -- return ret; --} --#endif -- - /* FIXME: suboptimal. */ - static void - grub_font_blit_glyph (struct grub_font_glyph *target, diff --git a/0267-font-Fix-integer-overflow-in-ensure_comb_space.patch b/0267-font-Fix-integer-overflow-in-ensure_comb_space.patch deleted file mode 100644 index af5eedbb393a0abef36cd589db7c472450ca9e1c..0000000000000000000000000000000000000000 --- a/0267-font-Fix-integer-overflow-in-ensure_comb_space.patch +++ /dev/null @@ -1,47 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Fri, 5 Aug 2022 02:27:05 +0800 -Subject: [PATCH] font: Fix integer overflow in ensure_comb_space() - -In fact it can't overflow at all because glyph_id->ncomb is only 8-bit -wide. But let's keep safe if somebody changes the width of glyph_id->ncomb -in the future. This patch also fixes the inconsistency between -render_max_comb_glyphs and render_combining_glyphs when grub_malloc() -returns NULL. - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit b2740b7e4a03bb8331d48b54b119afea76bb9d5f) -(cherry picked from commit f66ea1e60c347408e92b6695d5105c7e0f24d568) ---- - grub-core/font/font.c | 14 +++++++++----- - 1 file changed, 9 insertions(+), 5 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index a115a63b0c..d0e6340404 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -1468,14 +1468,18 @@ ensure_comb_space (const struct grub_unicode_glyph *glyph_id) - if (glyph_id->ncomb <= render_max_comb_glyphs) - return; - -- render_max_comb_glyphs = 2 * glyph_id->ncomb; -- if (render_max_comb_glyphs < 8) -+ if (grub_mul (glyph_id->ncomb, 2, &render_max_comb_glyphs)) -+ render_max_comb_glyphs = 0; -+ if (render_max_comb_glyphs > 0 && render_max_comb_glyphs < 8) - render_max_comb_glyphs = 8; - grub_free (render_combining_glyphs); -- render_combining_glyphs = grub_malloc (render_max_comb_glyphs -- * sizeof (render_combining_glyphs[0])); -+ render_combining_glyphs = (render_max_comb_glyphs > 0) ? -+ grub_calloc (render_max_comb_glyphs, sizeof (render_combining_glyphs[0])) : NULL; - if (!render_combining_glyphs) -- grub_errno = 0; -+ { -+ render_max_comb_glyphs = 0; -+ grub_errno = GRUB_ERR_NONE; -+ } - } - - int diff --git a/0268-font-Fix-integer-overflow-in-BMP-index.patch b/0268-font-Fix-integer-overflow-in-BMP-index.patch deleted file mode 100644 index bb227490d2bfd72c3b8b52f852fb38bfe42f7911..0000000000000000000000000000000000000000 --- a/0268-font-Fix-integer-overflow-in-BMP-index.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Mon, 15 Aug 2022 02:04:58 +0800 -Subject: [PATCH] font: Fix integer overflow in BMP index - -The BMP index (font->bmp_idx) is designed as a reverse lookup table of -char entries (font->char_index), in order to speed up lookups for BMP -chars (i.e. code < 0x10000). The values in BMP index are the subscripts -of the corresponding char entries, stored in grub_uint16_t, while 0xffff -means not found. - -This patch fixes the problem of large subscript truncated to grub_uint16_t, -leading BMP index to return wrong char entry or report false miss. The -code now checks for bounds and uses BMP index as a hint, and fallbacks -to binary-search if necessary. - -On the occasion add a comment about BMP index is initialized to 0xffff. - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit afda8b60ba0712abe01ae1e64c5f7a067a0e6492) -(cherry picked from commit 6d90568929e11739b56f09ebbce9185ca9c23519) ---- - grub-core/font/font.c | 13 +++++++++---- - 1 file changed, 9 insertions(+), 4 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index d0e6340404..b208a28717 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -300,6 +300,8 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct - font->bmp_idx = grub_malloc (0x10000 * sizeof (grub_uint16_t)); - if (!font->bmp_idx) - return 1; -+ -+ /* Init the BMP index array to 0xffff. */ - grub_memset (font->bmp_idx, 0xff, 0x10000 * sizeof (grub_uint16_t)); - - -@@ -328,7 +330,7 @@ load_font_index (grub_file_t file, grub_uint32_t sect_length, struct - return 1; - } - -- if (entry->code < 0x10000) -+ if (entry->code < 0x10000 && i < 0xffff) - font->bmp_idx[entry->code] = i; - - last_code = entry->code; -@@ -696,9 +698,12 @@ find_glyph (const grub_font_t font, grub_uint32_t code) - /* Use BMP index if possible. */ - if (code < 0x10000 && font->bmp_idx) - { -- if (font->bmp_idx[code] == 0xffff) -- return 0; -- return &table[font->bmp_idx[code]]; -+ if (font->bmp_idx[code] < 0xffff) -+ return &table[font->bmp_idx[code]]; -+ /* -+ * When we are here then lookup in BMP index result in miss, -+ * fallthough to binary-search. -+ */ - } - - /* Do a binary search in `char_index', which is ordered by code point. */ diff --git a/0269-font-Fix-integer-underflow-in-binary-search-of-char-.patch b/0269-font-Fix-integer-underflow-in-binary-search-of-char-.patch deleted file mode 100644 index 5c25e091927b07fec220f5ea3a82eda88ba057a9..0000000000000000000000000000000000000000 --- a/0269-font-Fix-integer-underflow-in-binary-search-of-char-.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Sun, 14 Aug 2022 18:09:38 +0800 -Subject: [PATCH] font: Fix integer underflow in binary search of char index - -If search target is less than all entries in font->index then "hi" -variable is set to -1, which translates to SIZE_MAX and leads to errors. - -This patch fixes the problem by replacing the entire binary search code -with the libstdc++'s std::lower_bound() implementation. - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit c140a086838e7c9af87842036f891b8393a8c4bc) -(cherry picked from commit e110997335b1744464ea232d57a7d86e16ca8dee) ---- - grub-core/font/font.c | 40 ++++++++++++++++++++++------------------ - 1 file changed, 22 insertions(+), 18 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index b208a28717..193dfec045 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -688,12 +688,12 @@ read_be_int16 (grub_file_t file, grub_int16_t * value) - static inline struct char_index_entry * - find_glyph (const grub_font_t font, grub_uint32_t code) - { -- struct char_index_entry *table; -- grub_size_t lo; -- grub_size_t hi; -- grub_size_t mid; -+ struct char_index_entry *table, *first, *end; -+ grub_size_t len; - - table = font->char_index; -+ if (table == NULL) -+ return NULL; - - /* Use BMP index if possible. */ - if (code < 0x10000 && font->bmp_idx) -@@ -706,25 +706,29 @@ find_glyph (const grub_font_t font, grub_uint32_t code) - */ - } - -- /* Do a binary search in `char_index', which is ordered by code point. */ -- lo = 0; -- hi = font->num_chars - 1; -+ /* -+ * Do a binary search in char_index which is ordered by code point. -+ * The code below is the same as libstdc++'s std::lower_bound(). -+ */ -+ first = table; -+ len = font->num_chars; -+ end = first + len; - -- if (!table) -- return 0; -- -- while (lo <= hi) -+ while (len > 0) - { -- mid = lo + (hi - lo) / 2; -- if (code < table[mid].code) -- hi = mid - 1; -- else if (code > table[mid].code) -- lo = mid + 1; -+ grub_size_t half = len >> 1; -+ struct char_index_entry *middle = first + half; -+ -+ if (middle->code < code) -+ { -+ first = middle + 1; -+ len = len - half - 1; -+ } - else -- return &table[mid]; -+ len = half; - } - -- return 0; -+ return (first < end && first->code == code) ? first : NULL; - } - - /* Get a glyph for the Unicode character CODE in FONT. The glyph is loaded diff --git a/0270-kern-efi-sb-Enforce-verification-of-font-files.patch b/0270-kern-efi-sb-Enforce-verification-of-font-files.patch deleted file mode 100644 index 42fea351e2a917b4ce7bb37a889dd7a646579180..0000000000000000000000000000000000000000 --- a/0270-kern-efi-sb-Enforce-verification-of-font-files.patch +++ /dev/null @@ -1,53 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Sun, 14 Aug 2022 15:51:54 +0800 -Subject: [PATCH] kern/efi/sb: Enforce verification of font files - -As a mitigation and hardening measure enforce verification of font -files. Then only trusted font files can be load. This will reduce the -attack surface at cost of losing the ability of end-users to customize -fonts if e.g. UEFI Secure Boot is enabled. Vendors can always customize -fonts because they have ability to pack fonts into their GRUB bundles. - -This goal is achieved by: - - * Removing GRUB_FILE_TYPE_FONT from shim lock verifier's - skip-verification list. - - * Adding GRUB_FILE_TYPE_FONT to lockdown verifier's defer-auth list, - so font files must be verified by a verifier before they can be loaded. - -Suggested-by: Daniel Kiper -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit 630deb8c0d8b02b670ced4b7030414bcf17aa080) -(cherry picked from commit 37257e0ee45b9029b62f4046c983481d063b821d) ---- - grub-core/kern/efi/sb.c | 1 - - grub-core/kern/lockdown.c | 1 + - 2 files changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c -index 89c4bb3fd1..db42c2539f 100644 ---- a/grub-core/kern/efi/sb.c -+++ b/grub-core/kern/efi/sb.c -@@ -145,7 +145,6 @@ shim_lock_verifier_init (grub_file_t io __attribute__ ((unused)), - case GRUB_FILE_TYPE_PRINT_BLOCKLIST: - case GRUB_FILE_TYPE_TESTLOAD: - case GRUB_FILE_TYPE_GET_SIZE: -- case GRUB_FILE_TYPE_FONT: - case GRUB_FILE_TYPE_ZFS_ENCRYPTION_KEY: - case GRUB_FILE_TYPE_CAT: - case GRUB_FILE_TYPE_HEXCAT: -diff --git a/grub-core/kern/lockdown.c b/grub-core/kern/lockdown.c -index 0bc70fd42d..af6d493cd3 100644 ---- a/grub-core/kern/lockdown.c -+++ b/grub-core/kern/lockdown.c -@@ -51,6 +51,7 @@ lockdown_verifier_init (grub_file_t io __attribute__ ((unused)), - case GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE: - case GRUB_FILE_TYPE_ACPI_TABLE: - case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE: -+ case GRUB_FILE_TYPE_FONT: - *flags = GRUB_VERIFY_FLAGS_DEFER_AUTH; - - /* Fall through. */ diff --git a/0271-fbutil-Fix-integer-overflow.patch b/0271-fbutil-Fix-integer-overflow.patch deleted file mode 100644 index f8e82e57fc84afa75a4efa5c402c3c48c7bf4a32..0000000000000000000000000000000000000000 --- a/0271-fbutil-Fix-integer-overflow.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Tue, 6 Sep 2022 03:03:21 +0800 -Subject: [PATCH] fbutil: Fix integer overflow - -Expressions like u64 = u32 * u32 are unsafe because their products are -truncated to u32 even if left hand side is u64. This patch fixes all -problems like that one in fbutil. - -To get right result not only left hand side have to be u64 but it's also -necessary to cast at least one of the operands of all leaf operators of -right hand side to u64, e.g. u64 = u32 * u32 + u32 * u32 should be -u64 = (u64)u32 * u32 + (u64)u32 * u32. - -For 1-bit bitmaps grub_uint64_t have to be used. It's safe because any -combination of values in (grub_uint64_t)u32 * u32 + u32 expression will -not overflow grub_uint64_t. - -Other expressions like ptr + u32 * u32 + u32 * u32 are also vulnerable. -They should be ptr + (grub_addr_t)u32 * u32 + (grub_addr_t)u32 * u32. - -This patch also adds a comment to grub_video_fb_get_video_ptr() which -says it's arguments must be valid and no sanity check is performed -(like its siblings in grub-core/video/fb/fbutil.c). - -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit 50a11a81bc842c58962244a2dc86bbd31a426e12) -(cherry picked from commit 8fa75d647362c938c4cc302cf5945b31fb92c078) ---- - grub-core/video/fb/fbutil.c | 4 ++-- - include/grub/fbutil.h | 13 +++++++++---- - 2 files changed, 11 insertions(+), 6 deletions(-) - -diff --git a/grub-core/video/fb/fbutil.c b/grub-core/video/fb/fbutil.c -index b98bb51fe8..25ef39f47d 100644 ---- a/grub-core/video/fb/fbutil.c -+++ b/grub-core/video/fb/fbutil.c -@@ -67,7 +67,7 @@ get_pixel (struct grub_video_fbblit_info *source, - case 1: - if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED) - { -- int bit_index = y * source->mode_info->width + x; -+ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x; - grub_uint8_t *ptr = source->data + bit_index / 8; - int bit_pos = 7 - bit_index % 8; - color = (*ptr >> bit_pos) & 0x01; -@@ -138,7 +138,7 @@ set_pixel (struct grub_video_fbblit_info *source, - case 1: - if (source->mode_info->blit_format == GRUB_VIDEO_BLIT_FORMAT_1BIT_PACKED) - { -- int bit_index = y * source->mode_info->width + x; -+ grub_uint64_t bit_index = (grub_uint64_t) y * source->mode_info->width + x; - grub_uint8_t *ptr = source->data + bit_index / 8; - int bit_pos = 7 - bit_index % 8; - *ptr = (*ptr & ~(1 << bit_pos)) | ((color & 0x01) << bit_pos); -diff --git a/include/grub/fbutil.h b/include/grub/fbutil.h -index 4205eb917f..78a1ab3b45 100644 ---- a/include/grub/fbutil.h -+++ b/include/grub/fbutil.h -@@ -31,14 +31,19 @@ struct grub_video_fbblit_info - grub_uint8_t *data; - }; - --/* Don't use for 1-bit bitmaps, addressing needs to be done at the bit level -- and it doesn't make sense, in general, to ask for a pointer -- to a particular pixel's data. */ -+/* -+ * Don't use for 1-bit bitmaps, addressing needs to be done at the bit level -+ * and it doesn't make sense, in general, to ask for a pointer -+ * to a particular pixel's data. -+ * -+ * This function assumes that bounds checking has been done in previous phase -+ * and they are opted out in here. -+ */ - static inline void * - grub_video_fb_get_video_ptr (struct grub_video_fbblit_info *source, - unsigned int x, unsigned int y) - { -- return source->data + y * source->mode_info->pitch + x * source->mode_info->bytes_per_pixel; -+ return source->data + (grub_addr_t) y * source->mode_info->pitch + (grub_addr_t) x * source->mode_info->bytes_per_pixel; - } - - /* Advance pointer by VAL bytes. If there is no unaligned access available, diff --git a/0272-font-Fix-an-integer-underflow-in-blit_comb.patch b/0272-font-Fix-an-integer-underflow-in-blit_comb.patch deleted file mode 100644 index b8a0e9e388566e78600c7a2ec5edb3f96ffa1e03..0000000000000000000000000000000000000000 --- a/0272-font-Fix-an-integer-underflow-in-blit_comb.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Mon, 24 Oct 2022 08:05:35 +0800 -Subject: [PATCH] font: Fix an integer underflow in blit_comb() - -The expression (ctx.bounds.height - combining_glyphs[i]->height) / 2 may -evaluate to a very big invalid value even if both ctx.bounds.height and -combining_glyphs[i]->height are small integers. For example, if -ctx.bounds.height is 10 and combining_glyphs[i]->height is 12, this -expression evaluates to 2147483647 (expected -1). This is because -coordinates are allowed to be negative but ctx.bounds.height is an -unsigned int. So, the subtraction operates on unsigned ints and -underflows to a very big value. The division makes things even worse. -The quotient is still an invalid value even if converted back to int. - -This patch fixes the problem by casting ctx.bounds.height to int. As -a result the subtraction will operate on int and grub_uint16_t which -will be promoted to an int. So, the underflow will no longer happen. Other -uses of ctx.bounds.height (and ctx.bounds.width) are also casted to int, -to ensure coordinates are always calculated on signed integers. - -Fixes: CVE-2022-3775 - -Reported-by: Daniel Axtens -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit 6d2668dea3774ed74c4cd1eadd146f1b846bc3d4) -(cherry picked from commit 05e532fb707bbf79aa4e1efbde4d208d7da89d6b) ---- - grub-core/font/font.c | 16 ++++++++-------- - 1 file changed, 8 insertions(+), 8 deletions(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 193dfec045..12a5f0d08c 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -1203,12 +1203,12 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, - ctx.bounds.height = main_glyph->height; - - above_rightx = main_glyph->offset_x + main_glyph->width; -- above_righty = ctx.bounds.y + ctx.bounds.height; -+ above_righty = ctx.bounds.y + (int) ctx.bounds.height; - - above_leftx = main_glyph->offset_x; -- above_lefty = ctx.bounds.y + ctx.bounds.height; -+ above_lefty = ctx.bounds.y + (int) ctx.bounds.height; - -- below_rightx = ctx.bounds.x + ctx.bounds.width; -+ below_rightx = ctx.bounds.x + (int) ctx.bounds.width; - below_righty = ctx.bounds.y; - - comb = grub_unicode_get_comb (glyph_id); -@@ -1221,7 +1221,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, - - if (!combining_glyphs[i]) - continue; -- targetx = (ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x; -+ targetx = ((int) ctx.bounds.width - combining_glyphs[i]->width) / 2 + ctx.bounds.x; - /* CGJ is to avoid diacritics reordering. */ - if (comb[i].code - == GRUB_UNICODE_COMBINING_GRAPHEME_JOINER) -@@ -1231,8 +1231,8 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, - case GRUB_UNICODE_COMB_OVERLAY: - do_blit (combining_glyphs[i], - targetx, -- (ctx.bounds.height - combining_glyphs[i]->height) / 2 -- - (ctx.bounds.height + ctx.bounds.y), &ctx); -+ ((int) ctx.bounds.height - combining_glyphs[i]->height) / 2 -+ - ((int) ctx.bounds.height + ctx.bounds.y), &ctx); - if (min_devwidth < combining_glyphs[i]->width) - min_devwidth = combining_glyphs[i]->width; - break; -@@ -1305,7 +1305,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, - /* Fallthrough. */ - case GRUB_UNICODE_STACK_ATTACHED_ABOVE: - do_blit (combining_glyphs[i], targetx, -- -(ctx.bounds.height + ctx.bounds.y + space -+ -((int) ctx.bounds.height + ctx.bounds.y + space - + combining_glyphs[i]->height), &ctx); - if (min_devwidth < combining_glyphs[i]->width) - min_devwidth = combining_glyphs[i]->width; -@@ -1313,7 +1313,7 @@ blit_comb (const struct grub_unicode_glyph *glyph_id, - - case GRUB_UNICODE_COMB_HEBREW_DAGESH: - do_blit (combining_glyphs[i], targetx, -- -(ctx.bounds.height / 2 + ctx.bounds.y -+ -((int) ctx.bounds.height / 2 + ctx.bounds.y - + combining_glyphs[i]->height / 2), &ctx); - if (min_devwidth < combining_glyphs[i]->width) - min_devwidth = combining_glyphs[i]->width; diff --git a/0273-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch b/0273-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch deleted file mode 100644 index 307572cb93a6ec7a25c8fcf6032eaceaf9b10849..0000000000000000000000000000000000000000 --- a/0273-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Mon, 24 Oct 2022 07:15:41 +0800 -Subject: [PATCH] font: Harden grub_font_blit_glyph() and - grub_font_blit_glyph_mirror() - -As a mitigation and hardening measure add sanity checks to -grub_font_blit_glyph() and grub_font_blit_glyph_mirror(). This patch -makes these two functions do nothing if target blitting area isn't fully -contained in target bitmap. Therefore, if complex calculations in caller -overflows and malicious coordinates are given, we are still safe because -any coordinates which result in out-of-bound-write are rejected. However, -this patch only checks for invalid coordinates, and doesn't provide any -protection against invalid source glyph or destination glyph, e.g. -mismatch between glyph size and buffer size. - -This hardening measure is designed to mitigate possible overflows in -blit_comb(). If overflow occurs, it may return invalid bounding box -during dry run and call grub_font_blit_glyph() with malicious -coordinates during actual blitting. However, we are still safe because -the scratch glyph itself is valid, although its size makes no sense, and -any invalid coordinates are rejected. - -It would be better to call grub_fatal() if illegal parameter is detected. -However, doing this may end up in a dangerous recursion because grub_fatal() -would print messages to the screen and we are in the progress of drawing -characters on the screen. - -Reported-by: Daniel Axtens -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit fcd7aa0c278f7cf3fb9f93f1a3966e1792339eb6) -(cherry picked from commit 1d37ec63a1c76a14fdf70f548eada92667b42ddb) ---- - grub-core/font/font.c | 14 ++++++++++++++ - 1 file changed, 14 insertions(+) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 12a5f0d08c..29fbb94294 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -1069,8 +1069,15 @@ static void - grub_font_blit_glyph (struct grub_font_glyph *target, - struct grub_font_glyph *src, unsigned dx, unsigned dy) - { -+ grub_uint16_t max_x, max_y; - unsigned src_bit, tgt_bit, src_byte, tgt_byte; - unsigned i, j; -+ -+ /* Harden against out-of-bound writes. */ -+ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) || -+ (grub_add (dy, src->height, &max_y) || max_y > target->height)) -+ return; -+ - for (i = 0; i < src->height; i++) - { - src_bit = (src->width * i) % 8; -@@ -1102,9 +1109,16 @@ grub_font_blit_glyph_mirror (struct grub_font_glyph *target, - struct grub_font_glyph *src, - unsigned dx, unsigned dy) - { -+ grub_uint16_t max_x, max_y; - unsigned tgt_bit, src_byte, tgt_byte; - signed src_bit; - unsigned i, j; -+ -+ /* Harden against out-of-bound writes. */ -+ if ((grub_add (dx, src->width, &max_x) || max_x > target->width) || -+ (grub_add (dy, src->height, &max_y) || max_y > target->height)) -+ return; -+ - for (i = 0; i < src->height; i++) - { - src_bit = (src->width * i + src->width - 1) % 8; diff --git a/0274-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch b/0274-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch deleted file mode 100644 index 368b9d061da8088846ec3d446da77636b9bdada8..0000000000000000000000000000000000000000 --- a/0274-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Fri, 28 Oct 2022 17:29:16 +0800 -Subject: [PATCH] font: Assign null_font to glyphs in ascii_font_glyph[] - -The calculations in blit_comb() need information from glyph's font, e.g. -grub_font_get_xheight(main_glyph->font). However, main_glyph->font is -NULL if main_glyph comes from ascii_font_glyph[]. Therefore -grub_font_get_*() crashes because of NULL pointer. - -There is already a solution, the null_font. So, assign it to those glyphs -in ascii_font_glyph[]. - -Reported-by: Daniel Axtens -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit dd539d695482069d28b40f2d3821f710cdcf6ee6) -(cherry picked from commit 87526376857eaceae474c9797e3cee5b50597332) ---- - grub-core/font/font.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/font/font.c b/grub-core/font/font.c -index 29fbb94294..e6616e610c 100644 ---- a/grub-core/font/font.c -+++ b/grub-core/font/font.c -@@ -137,7 +137,7 @@ ascii_glyph_lookup (grub_uint32_t code) - ascii_font_glyph[current]->offset_x = 0; - ascii_font_glyph[current]->offset_y = -2; - ascii_font_glyph[current]->device_width = 8; -- ascii_font_glyph[current]->font = NULL; -+ ascii_font_glyph[current]->font = &null_font; - - grub_memcpy (ascii_font_glyph[current]->bitmap, - &ascii_bitmaps[current * ASCII_BITMAP_SIZE], diff --git a/0275-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch b/0275-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch deleted file mode 100644 index 96f2f94d133725477f313064735a3b31f4362b3c..0000000000000000000000000000000000000000 --- a/0275-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch +++ /dev/null @@ -1,54 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Zhang Boyang -Date: Fri, 28 Oct 2022 21:31:39 +0800 -Subject: [PATCH] normal/charset: Fix an integer overflow in - grub_unicode_aglomerate_comb() - -The out->ncomb is a bit-field of 8 bits. So, the max possible value is 255. -However, code in grub_unicode_aglomerate_comb() doesn't check for an -overflow when incrementing out->ncomb. If out->ncomb is already 255, -after incrementing it will get 0 instead of 256, and cause illegal -memory access in subsequent processing. - -This patch introduces GRUB_UNICODE_NCOMB_MAX to represent the max -acceptable value of ncomb. The code now checks for this limit and -ignores additional combining characters when limit is reached. - -Reported-by: Daniel Axtens -Signed-off-by: Zhang Boyang -Reviewed-by: Daniel Kiper -(cherry picked from commit da90d62316a3b105d2fbd7334d6521936bd6dcf6) -(cherry picked from commit 26fafec86000b5322837722a115279ef03922ca6) ---- - grub-core/normal/charset.c | 3 +++ - include/grub/unicode.h | 2 ++ - 2 files changed, 5 insertions(+) - -diff --git a/grub-core/normal/charset.c b/grub-core/normal/charset.c -index 7a5a7c153c..c243ca6dae 100644 ---- a/grub-core/normal/charset.c -+++ b/grub-core/normal/charset.c -@@ -472,6 +472,9 @@ grub_unicode_aglomerate_comb (const grub_uint32_t *in, grub_size_t inlen, - if (!haveout) - continue; - -+ if (out->ncomb == GRUB_UNICODE_NCOMB_MAX) -+ continue; -+ - if (comb_type == GRUB_UNICODE_COMB_MC - || comb_type == GRUB_UNICODE_COMB_ME - || comb_type == GRUB_UNICODE_COMB_MN) -diff --git a/include/grub/unicode.h b/include/grub/unicode.h -index 4de986a857..c4f6fca043 100644 ---- a/include/grub/unicode.h -+++ b/include/grub/unicode.h -@@ -147,7 +147,9 @@ struct grub_unicode_glyph - grub_uint8_t bidi_level:6; /* minimum: 6 */ - enum grub_bidi_type bidi_type:5; /* minimum: :5 */ - -+#define GRUB_UNICODE_NCOMB_MAX ((1 << 8) - 1) - unsigned ncomb:8; -+ - /* Hint by unicode subsystem how wide this character usually is. - Real width is determined by font. Set only in UTF-8 stream. */ - int estimated_width:8; diff --git a/0276-port-Add-LoongArch-support.patch b/0276-port-Add-LoongArch-support.patch deleted file mode 100644 index 0dde2762e578dfc9b0b3c3dd42749a8834f4019e..0000000000000000000000000000000000000000 --- a/0276-port-Add-LoongArch-support.patch +++ /dev/null @@ -1,3571 +0,0 @@ -From 2bbda7ea6bb3b5d7da6484ddeec7b9e720faa312 Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Thu, 12 Jan 2023 14:44:13 +0800 -Subject: [PATCH] port: Add LoongArch support - -This patch adds support for LoongArch. From now on, we can boot up -grub as a UEFI application on LoongArch platform. - -Signed-off-by: yangqiming -Signed-off-by: mengyingkun ---- - Makefile.util.def | 1 + - configure.ac | 24 + - gentpl.py | 9 +- - grub-core/Makefile.am | 6 + - grub-core/Makefile.core.def | 23 + - grub-core/kern/dl.c | 9 +- - grub-core/kern/efi/mm.c | 3 +- - grub-core/kern/loongarch64/cache.S | 26 + - grub-core/kern/loongarch64/dl.c | 163 ++++++ - grub-core/kern/loongarch64/dl_helper.c | 264 +++++++++ - grub-core/kern/loongarch64/efi/init.c | 73 +++ - grub-core/kern/loongarch64/efi/startup.S | 45 ++ - grub-core/kern/loongarch64/init.c | 47 ++ - .../lib/gnulib-patches/fix-loongarch.patch | 26 + - grub-core/lib/loongarch64/relocator.c | 163 ++++++ - grub-core/lib/loongarch64/relocator_asm.S | 51 ++ - grub-core/lib/loongarch64/setjmp.S | 68 +++ - grub-core/lib/setjmp.S | 2 + - grub-core/loader/efi/chainloader.c | 2 + - grub-core/loader/loongarch64/linux-efi.c | 144 +++++ - grub-core/loader/loongarch64/linux-elf.c | 529 ++++++++++++++++++ - grub-core/loader/loongarch64/linux.c | 398 +++++++++++++ - include/grub/efi/api.h | 2 +- - include/grub/efi/efi.h | 6 +- - include/grub/efi/pe32.h | 4 + - include/grub/elf.h | 30 + - include/grub/fdt.h | 4 +- - include/grub/loongarch64/efi/loader.h | 25 + - include/grub/loongarch64/efi/memory.h | 15 + - include/grub/loongarch64/efi/time.h | 0 - include/grub/loongarch64/io.h | 62 ++ - include/grub/loongarch64/linux.h | 144 +++++ - include/grub/loongarch64/loongarch64.h | 30 + - include/grub/loongarch64/memory.h | 59 ++ - include/grub/loongarch64/reloc.h | 113 ++++ - include/grub/loongarch64/relocator.h | 38 ++ - include/grub/loongarch64/setjmp.h | 27 + - include/grub/loongarch64/time.h | 39 ++ - include/grub/loongarch64/types.h | 34 ++ - include/grub/util/install.h | 1 + - util/grub-install-common.c | 1 + - util/grub-install.c | 16 + - util/grub-mkimagexx.c | 99 +++- - util/grub-module-verifier.c | 15 + - util/mkimage.c | 16 + - 45 files changed, 2842 insertions(+), 14 deletions(-) - create mode 100644 grub-core/kern/loongarch64/cache.S - create mode 100644 grub-core/kern/loongarch64/dl.c - create mode 100644 grub-core/kern/loongarch64/dl_helper.c - create mode 100644 grub-core/kern/loongarch64/efi/init.c - create mode 100644 grub-core/kern/loongarch64/efi/startup.S - create mode 100644 grub-core/kern/loongarch64/init.c - create mode 100644 grub-core/lib/gnulib-patches/fix-loongarch.patch - create mode 100644 grub-core/lib/loongarch64/relocator.c - create mode 100644 grub-core/lib/loongarch64/relocator_asm.S - create mode 100644 grub-core/lib/loongarch64/setjmp.S - create mode 100644 grub-core/loader/loongarch64/linux-efi.c - create mode 100644 grub-core/loader/loongarch64/linux-elf.c - create mode 100644 grub-core/loader/loongarch64/linux.c - create mode 100644 include/grub/loongarch64/efi/loader.h - create mode 100644 include/grub/loongarch64/efi/memory.h - create mode 100644 include/grub/loongarch64/efi/time.h - create mode 100644 include/grub/loongarch64/io.h - create mode 100644 include/grub/loongarch64/linux.h - create mode 100644 include/grub/loongarch64/loongarch64.h - create mode 100644 include/grub/loongarch64/memory.h - create mode 100644 include/grub/loongarch64/reloc.h - create mode 100644 include/grub/loongarch64/relocator.h - create mode 100644 include/grub/loongarch64/setjmp.h - create mode 100644 include/grub/loongarch64/time.h - create mode 100644 include/grub/loongarch64/types.h - -diff --git a/Makefile.util.def b/Makefile.util.def -index 3f191aa80950..1a044a9df0a8 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -169,6 +169,7 @@ library = { - common = grub-core/kern/ia64/dl_helper.c; - common = grub-core/kern/arm/dl_helper.c; - common = grub-core/kern/arm64/dl_helper.c; -+ common = grub-core/kern/loongarch64/dl_helper.c; - common = grub-core/lib/minilzo/minilzo.c; - common = grub-core/lib/xzembed/xz_dec_bcj.c; - common = grub-core/lib/xzembed/xz_dec_lzma2.c; -diff --git a/configure.ac b/configure.ac -index d04c94691efe..dea4dfeda376 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -149,6 +149,10 @@ case "$target_cpu" in - riscv64*) - target_cpu=riscv64 - ;; -+ loongarch64) -+ target_cpu=loongarch64 -+ machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_LOONGARCH64=1" -+ ;; - esac - - # Specify the platform (such as firmware). -@@ -167,6 +171,7 @@ if test "x$with_platform" = x; then - powerpc64-*) platform=ieee1275 ;; - powerpc64le-*) platform=ieee1275 ;; - sparc64-*) platform=ieee1275 ;; -+ loongarch64-*) platform=efi ;; - mipsel-*) platform=loongson ;; - mips-*) platform=arc ;; - ia64-*) platform=efi ;; -@@ -218,6 +223,7 @@ case "$target_cpu"-"$platform" in - mipsel-yeeloong) platform=loongson ;; - mipsel-fuloong) platform=loongson ;; - mipsel-loongson) ;; -+ loongarch64-efi) ;; - arm-uboot) ;; - arm-coreboot) ;; - arm-efi) ;; -@@ -276,6 +282,7 @@ case "$platform" in - pc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_PCBIOS=1" ;; - emu) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;; - loongson) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_LOONGSON=1" ;; -+ loongson64) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_LOONARCH64=1" ;; - qemu_mips) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS_QEMU_MIPS=1" ;; - arc) machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARC=1" ;; - esac -@@ -890,6 +897,21 @@ if ( test "x$target_cpu" = xi386 || test "x$target_cpu" = xx86_64 ) && test "x$p - TARGET_CFLAGS="$TARGET_CFLAGS -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow" - fi - -+if test "x$target_cpu" = xloongarch64; then -+ AC_CACHE_CHECK([whether _mno_explicit_relocs works], [grub_cv_cc_mno_explicit_relocs], [ -+ CFLAGS="$TARGET_CFLAGS -mno-explicit-relocs -Werror" -+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], -+ [grub_cv_cc_mno_explicit_relocs=yes], -+ [grub_cv_cc_mno_explicit_relocs=no]) -+ ]) -+ if test "x$grub_cv_cc_mno_explicit_relocs" = xyes; then -+ TARGET_CFLAGS="$TARGET_CFLAGS -mno-explicit-relocs -fno-plt" -+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS -mno-explicit-relocs -fno-plt" -+ fi -+ TARGET_CFLAGS="$TARGET_CFLAGS -Wa,-mla-global-with-abs" -+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS -Wa,-mla-global-with-abs" -+fi -+ - # Should grub utils get the host CFLAGS, or the target CFLAGS? - AC_ARG_WITH([utils], - AS_HELP_STRING([--with-utils=host|target|build], -@@ -2166,6 +2188,8 @@ AM_CONDITIONAL([COND_mips_arc], [test "(" x$target_cpu = xmips -o x$target_cpu = - AM_CONDITIONAL([COND_sparc64_ieee1275], [test x$target_cpu = xsparc64 -a x$platform = xieee1275]) - AM_CONDITIONAL([COND_sparc64_emu], [test x$target_cpu = xsparc64 -a x$platform = xemu]) - AM_CONDITIONAL([COND_powerpc_ieee1275], [test x$target_cpu = xpowerpc -a x$platform = xieee1275]) -+AM_CONDITIONAL([COND_loongarch64_efi], [test x$target_cpu = xloongarch64 -a x$platform = xefi]) -+AM_CONDITIONAL([COND_loongarch64], [test x$target_cpu = xloongarch64]) - AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel]) - AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel]) - AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips]) -diff --git a/gentpl.py b/gentpl.py -index 59f62ef95229..f03aff85c2cd 100644 ---- a/gentpl.py -+++ b/gentpl.py -@@ -32,7 +32,8 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", - "mips_loongson", "sparc64_ieee1275", - "powerpc_ieee1275", "mips_arc", "ia64_efi", - "mips_qemu_mips", "arm_uboot", "arm_efi", "arm64_efi", -- "arm_coreboot", "riscv32_efi", "riscv64_efi" ] -+ "arm_coreboot", "riscv32_efi", "riscv64_efi", -+ "loongarch64_efi" ] - - GROUPS = {} - -@@ -49,11 +50,12 @@ GROUPS["arm"] = [ "arm_uboot", "arm_efi", "arm_coreboot" ] - GROUPS["arm64"] = [ "arm64_efi" ] - GROUPS["riscv32"] = [ "riscv32_efi" ] - GROUPS["riscv64"] = [ "riscv64_efi" ] -+GROUPS["loongarch64"] = [ "loongarch64_efi" ] - - # Groups based on firmware - GROUPS["pc"] = [ "i386_pc" ] - GROUPS["efi"] = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi", "arm64_efi", -- "riscv32_efi", "riscv64_efi" ] -+ "riscv32_efi", "riscv64_efi", "loongarch64_efi" ] - GROUPS["ieee1275"] = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ] - GROUPS["uboot"] = [ "arm_uboot" ] - GROUPS["xen"] = [ "i386_xen", "x86_64_xen" ] -@@ -80,7 +82,8 @@ GROUPS["terminfomodule"] = GRUB_PLATFORMS[:]; - for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i) - - # Flattened Device Trees (FDT) --GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "riscv32_efi", "riscv64_efi" ] -+GROUPS["fdt"] = [ "arm64_efi", "arm_uboot", "arm_efi", "riscv32_efi", -+ "riscv64_efi", "loongarch64_efi" ] - - # Needs software helpers for division - # Must match GRUB_DIVISION_IN_SOFTWARE in misc.h -diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am -index dd49939aaa98..6582f1630d4d 100644 ---- a/grub-core/Makefile.am -+++ b/grub-core/Makefile.am -@@ -240,6 +240,12 @@ KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/memory.h - KERNEL_HEADER_FILES += $(top_builddir)/include/grub/machine/kernel.h - endif - -+if COND_loongarch64_efi -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h -+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/acpi.h -+endif -+ - if COND_powerpc_ieee1275 - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/ieee1275/ieee1275.h - KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/terminfo.h -diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def -index 2c1608bca48b..d7c01a8adbd9 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -103,6 +103,9 @@ kernel = { - arm_coreboot_ldflags = '-Wl,-r,-d'; - arm_coreboot_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version'; - -+ loongarch64_efi_ldflags = '-Wl,-r,-d'; -+ loongarch64_efi_stripflags = '--strip-unneeded -K start -R .note -R .comment -R .note.gnu.gold-version -R .eh_frame'; -+ - i386_pc_startup = kern/i386/pc/startup.S; - i386_efi_startup = kern/i386/efi/startup.S; - x86_64_efi_startup = kern/x86_64/efi/startup.S; -@@ -122,6 +125,7 @@ kernel = { - arm64_efi_startup = kern/arm64/efi/startup.S; - riscv32_efi_startup = kern/riscv/efi/startup.S; - riscv64_efi_startup = kern/riscv/efi/startup.S; -+ loongarch64_efi_startup = kern/loongarch64/efi/startup.S; - - common = kern/buffer.c; - common = kern/command.c; -@@ -270,6 +274,9 @@ kernel = { - riscv64_efi = kern/riscv/efi/init.c; - riscv64_efi = kern/efi/fdt.c; - -+ loongarch64_efi = kern/loongarch64/efi/init.c; -+ loongarch64_efi = kern/efi/fdt.c; -+ - i386_pc = kern/i386/pc/init.c; - i386_pc = kern/i386/pc/mmap.c; - i386_pc = term/i386/pc/console.c; -@@ -351,6 +358,12 @@ kernel = { - riscv64 = kern/riscv/cache_flush.S; - riscv64 = kern/riscv/dl.c; - -+ loongarch64 = kern/loongarch64/init.c; -+ loongarch64 = kern/loongarch64/dl.c; -+ loongarch64 = kern/loongarch64/dl_helper.c; -+ loongarch64 = kern/loongarch64/cache.S; -+ loongarch64 = kern/generic/rtc_get_time_ms.c; -+ - fdt = lib/fdt.c; - - emu = disk/host.c; -@@ -873,6 +886,7 @@ module = { - enable = arm_coreboot; - enable = riscv32_efi; - enable = riscv64_efi; -+ enable = loongarch64_efi; - }; - - module = { -@@ -950,6 +964,7 @@ module = { - i386_multiboot = commands/acpihalt.c; - i386_efi = commands/acpihalt.c; - x86_64_efi = commands/acpihalt.c; -+ loongarch64_efi = commands/acpihalt.c; - i386_multiboot = lib/i386/halt.c; - i386_coreboot = lib/i386/halt.c; - i386_qemu = lib/i386/halt.c; -@@ -1731,6 +1746,8 @@ module = { - x86_64_xen = lib/x86_64/xen/relocator.S; - xen = lib/i386/relocator_common_c.c; - x86_64_efi = lib/x86_64/efi/relocator.c; -+ loongarch64 = lib/loongarch64/relocator_asm.S; -+ loongarch64 = lib/loongarch64/relocator.c; - - extra_dist = lib/i386/relocator_common.S; - extra_dist = kern/powerpc/cache_flush.S; -@@ -1740,6 +1757,7 @@ module = { - enable = x86; - enable = i386_xen_pvh; - enable = xen; -+ enable = loongarch64; - }; - - module = { -@@ -1772,6 +1790,7 @@ module = { - extra_dist = lib/arm/setjmp.S; - extra_dist = lib/arm64/setjmp.S; - extra_dist = lib/riscv/setjmp.S; -+ extra_dist = lib/loongarch64/setjmp.S; - }; - - module = { -@@ -1870,6 +1889,9 @@ module = { - arm64 = loader/arm64/linux.c; - riscv32 = loader/riscv/linux.c; - riscv64 = loader/riscv/linux.c; -+ loongarch64 = loader/loongarch64/linux.c; -+ loongarch64 = loader/loongarch64/linux-elf.c; -+ loongarch64 = loader/loongarch64/linux-efi.c; - emu = loader/emu/linux.c; - - common = loader/linux.c; -@@ -1969,6 +1991,7 @@ module = { - enable = riscv32_efi; - enable = riscv64_efi; - enable = mips; -+ enable = loongarch64_efi; - }; - - module = { -diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c -index d5de80186fa1..c60d49772bc3 100644 ---- a/grub-core/kern/dl.c -+++ b/grub-core/kern/dl.c -@@ -278,7 +278,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - unsigned i; - const Elf_Shdr *s; - grub_size_t tsize = 0, talign = 1, arch_addralign = 1; --#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) -+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ -+ !defined (__loongarch__) - grub_size_t tramp; - grub_size_t got; - grub_err_t err; -@@ -307,7 +308,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - talign = sh_addralign; - } - --#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) -+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ -+ !defined (__loongarch__) - err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got); - if (err) - return err; -@@ -375,7 +377,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e) - mod->segment = seg; - } - } --#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) -+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ -+ !defined (__loongarch__) - ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN); - mod->tramp = ptr; - mod->trampptr = ptr; -diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c -index 2c33758ed750..613a84488e75 100644 ---- a/grub-core/kern/efi/mm.c -+++ b/grub-core/kern/efi/mm.c -@@ -695,7 +695,8 @@ grub_efi_mm_init (void) - 2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE)); - } - --#if defined (__aarch64__) || defined (__arm__) || defined (__riscv) -+#if defined (__aarch64__) || defined (__arm__) || defined (__riscv) \ -+ || defined (__loongarch__) - grub_err_t - grub_efi_get_ram_base(grub_addr_t *base_addr) - { -diff --git a/grub-core/kern/loongarch64/cache.S b/grub-core/kern/loongarch64/cache.S -new file mode 100644 -index 000000000000..d291c6769c3c ---- /dev/null -+++ b/grub-core/kern/loongarch64/cache.S -@@ -0,0 +1,26 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009,2017 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 . -+ */ -+ -+#include -+ -+FUNCTION (grub_arch_sync_caches) -+ jr $ra -+ -+FUNCTION (grub_arch_sync_dma_caches) -+ jr $ra -+ -diff --git a/grub-core/kern/loongarch64/dl.c b/grub-core/kern/loongarch64/dl.c -new file mode 100644 -index 000000000000..5442ec875478 ---- /dev/null -+++ b/grub-core/kern/loongarch64/dl.c -@@ -0,0 +1,163 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Check if EHDR is a valid ELF header. */ -+grub_err_t -+grub_arch_dl_check_header (void *ehdr) -+{ -+ Elf_Ehdr *e = ehdr; -+ -+ /* Check the magic numbers. */ -+ if (e->e_ident[EI_CLASS] != ELFCLASS64 -+ || e->e_ident[EI_DATA] != ELFDATA2LSB || e->e_machine != EM_LOONGARCH) -+ return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); -+ -+ return GRUB_ERR_NONE; -+} -+ -+#pragma GCC diagnostic ignored "-Wcast-align" -+ -+/* -+ * Unified function for both REL and RELA. -+ */ -+grub_err_t -+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, -+ Elf_Shdr *s, grub_dl_segment_t seg) -+{ -+ Elf_Rel *rel, *max; -+ struct grub_loongarch64_stack stack; -+ grub_loongarch64_stack_init (&stack); -+ -+ for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset), -+ max = (Elf_Rel *) ((char *) rel + s->sh_size); -+ rel < max; -+ rel = (Elf_Rel *) ((char *) rel + s->sh_entsize)) -+ { -+ Elf_Sym *sym; -+ void *place; -+ grub_uint64_t sym_addr; -+ -+ if (rel->r_offset >= seg->size) -+ return grub_error (GRUB_ERR_BAD_MODULE, -+ "reloc offset is outside the segment"); -+ -+ sym = (Elf_Sym *) ((char*)mod->symtab -+ + mod->symsize * ELF_R_SYM (rel->r_info)); -+ -+ sym_addr = sym->st_value; -+ if (s->sh_type == SHT_RELA) -+ sym_addr += ((Elf_Rela *) rel)->r_addend; -+ -+ place = (void *) ((grub_addr_t)seg->addr + rel->r_offset); -+ -+ switch (ELF_R_TYPE (rel->r_info)) -+ { -+ case R_LARCH_64: -+ { -+ grub_uint64_t *abs_place = place; -+ -+ grub_dprintf ("dl", "reloc_abs64 %p => 0x%016llx, %p\n", -+ place, (unsigned long long) sym_addr, abs_place); -+ -+ *abs_place += (grub_uint64_t) sym_addr; -+ } -+ break; -+ case R_LARCH_MARK_LA: -+ break; -+ case R_LARCH_SOP_PUSH_PCREL: -+ case R_LARCH_SOP_PUSH_PLT_PCREL: -+ grub_loongarch64_sop_push (&stack, sym_addr - (grub_uint64_t)place); -+ break; -+ case R_LARCH_B26: -+ { -+ grub_uint32_t *abs_place = place; -+ grub_ssize_t off = sym_addr - (grub_addr_t) place; -+ -+ grub_loongarch64_b26 (abs_place, off); -+ } -+ break; -+ case R_LARCH_ABS_HI20: -+ { -+ grub_uint32_t *abs_place = place; -+ grub_loongarch64_xxx_hi20 (abs_place, sym_addr); -+ } -+ break; -+ case R_LARCH_ABS64_LO20: -+ { -+ grub_uint32_t *abs_place = place; -+ grub_loongarch64_xxx64_lo20 (abs_place, sym_addr); -+ } -+ break; -+ case R_LARCH_ABS64_HI12: -+ { -+ grub_uint32_t *abs_place = place; -+ grub_loongarch64_xxx64_hi12 (abs_place, sym_addr); -+ } -+ break; -+ case R_LARCH_PCALA_HI20: -+ { -+ grub_uint32_t *abs_place = place; -+ grub_int32_t off = (((sym_addr + 0x800) & ~0xfffULL) - ((grub_addr_t)place & ~0xfffULL)); -+ -+ grub_loongarch64_xxx_hi20 (abs_place, off); -+ } -+ break; -+ case R_LARCH_ABS_LO12: -+ case R_LARCH_PCALA_LO12: -+ { -+ grub_uint32_t *abs_place = place; -+ grub_loongarch64_xxx_lo12 (abs_place, sym_addr); -+ } -+ break; -+ GRUB_LOONGARCH64_RELOCATION (&stack, place, sym_addr) -+ default: -+ { -+ char rel_info[17]; /* log16(2^64) = 16, plus NUL. */ -+ -+ grub_snprintf (rel_info, sizeof (rel_info) - 1, "%" PRIxGRUB_UINT64_T, -+ (grub_uint64_t) ELF_R_TYPE (rel->r_info)); -+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, -+ N_("relocation 0x%s is not implemented yet"), rel_info); -+ } -+ break; -+ } -+ } -+ return GRUB_ERR_NONE; -+} -+ -+/* -+ * Tell the loader what our minimum section alignment is. -+ */ -+grub_size_t -+grub_arch_dl_min_alignment (void) -+{ -+#ifdef GRUB_MACHINE_EFI -+ return 4096; -+#else -+ return 1; -+#endif -+} -diff --git a/grub-core/kern/loongarch64/dl_helper.c b/grub-core/kern/loongarch64/dl_helper.c -new file mode 100644 -index 000000000000..68275fea3339 ---- /dev/null -+++ b/grub-core/kern/loongarch64/dl_helper.c -@@ -0,0 +1,264 @@ -+/* dl_helper.c - relocation helper functions for modules and grub-mkimage */ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static void grub_loongarch64_stack_push (grub_loongarch64_stack_t stack, grub_uint64_t x); -+static grub_uint64_t grub_loongarch64_stack_pop (grub_loongarch64_stack_t stack); -+ -+void -+grub_loongarch64_stack_init (grub_loongarch64_stack_t stack) -+{ -+ stack->top = -1; -+ stack->count = LOONGARCH64_STACK_MAX; -+} -+ -+static void -+grub_loongarch64_stack_push (grub_loongarch64_stack_t stack, grub_uint64_t x) -+{ -+ if (stack->top == stack->count) -+ return; -+ stack->data[++stack->top] = x; -+} -+ -+static grub_uint64_t -+grub_loongarch64_stack_pop (grub_loongarch64_stack_t stack) -+{ -+ if (stack->top == -1) -+ return -1; -+ return stack->data[stack->top--]; -+} -+ -+void -+grub_loongarch64_sop_push (grub_loongarch64_stack_t stack, grub_int64_t offset) -+{ -+ grub_loongarch64_stack_push (stack, offset); -+} -+ -+/* opr2 = pop (), opr1 = pop (), push (opr1 - opr2) */ -+void -+grub_loongarch64_sop_sub (grub_loongarch64_stack_t stack) -+{ -+ grub_uint64_t a, b; -+ b = grub_loongarch64_stack_pop (stack); -+ a = grub_loongarch64_stack_pop (stack); -+ grub_loongarch64_stack_push (stack, a - b); -+} -+ -+/* opr2 = pop (), opr1 = pop (), push (opr1 << opr2) */ -+void -+grub_loongarch64_sop_sl (grub_loongarch64_stack_t stack) -+{ -+ grub_uint64_t a, b; -+ b = grub_loongarch64_stack_pop (stack); -+ a = grub_loongarch64_stack_pop (stack); -+ grub_loongarch64_stack_push (stack, a << b); -+} -+ -+/* opr2 = pop (), opr1 = pop (), push (opr1 >> opr2) */ -+void -+grub_loongarch64_sop_sr (grub_loongarch64_stack_t stack) -+{ -+ grub_uint64_t a, b; -+ b = grub_loongarch64_stack_pop (stack); -+ a = grub_loongarch64_stack_pop (stack); -+ grub_loongarch64_stack_push (stack, a >> b); -+} -+ -+/* opr2 = pop (), opr1 = pop (), push (opr1 + opr2) */ -+void -+grub_loongarch64_sop_add (grub_loongarch64_stack_t stack) -+{ -+ grub_uint64_t a, b; -+ b = grub_loongarch64_stack_pop (stack); -+ a = grub_loongarch64_stack_pop (stack); -+ grub_loongarch64_stack_push (stack, a + b); -+} -+ -+/* opr2 = pop (), opr1 = pop (), push (opr1 & opr2) */ -+void -+grub_loongarch64_sop_and (grub_loongarch64_stack_t stack) -+{ -+ grub_uint64_t a, b; -+ b = grub_loongarch64_stack_pop (stack); -+ a = grub_loongarch64_stack_pop (stack); -+ grub_loongarch64_stack_push (stack, a & b); -+} -+ -+/* opr3 = pop (), opr2 = pop (), opr1 = pop (), push (opr1 ? opr2 : opr3) */ -+void -+grub_loongarch64_sop_if_else (grub_loongarch64_stack_t stack) -+{ -+ grub_uint64_t a, b, c; -+ c = grub_loongarch64_stack_pop (stack); -+ b = grub_loongarch64_stack_pop (stack); -+ a = grub_loongarch64_stack_pop (stack); -+ -+ if (a) { -+ grub_loongarch64_stack_push (stack, b); -+ } else { -+ grub_loongarch64_stack_push (stack, c); -+ } -+} -+ -+/* opr1 = pop (), (*(uint32_t *) PC) [14 ... 10] = opr1 [4 ... 0] */ -+void -+grub_loongarch64_sop_32_s_10_5 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place |= ((a & 0x1f) << 10); -+} -+ -+/* opr1 = pop (), (*(uint32_t *) PC) [21 ... 10] = opr1 [11 ... 0] */ -+void -+grub_loongarch64_sop_32_u_10_12 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place = *place | ((a & 0xfff) << 10); -+} -+ -+/* opr1 = pop (), (*(uint32_t *) PC) [21 ... 10] = opr1 [11 ... 0] */ -+void -+grub_loongarch64_sop_32_s_10_12 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place = (*place) | ((a & 0xfff) << 10); -+} -+ -+/* opr1 = pop (), (*(uint32_t *) PC) [25 ... 10] = opr1 [15 ... 0] */ -+void -+grub_loongarch64_sop_32_s_10_16 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place = (*place) | ((a & 0xffff) << 10); -+} -+ -+/* opr1 = pop (), (*(uint32_t *) PC) [25 ... 10] = opr1 [17 ... 2] */ -+void -+grub_loongarch64_sop_32_s_10_16_s2 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place = (*place) | (((a >> 2) & 0xffff) << 10); -+} -+ -+/* opr1 = pop (), (*(uint32_t *) PC) [24 ... 5] = opr1 [19 ... 0] */ -+void -+grub_loongarch64_sop_32_s_5_20 (grub_loongarch64_stack_t stack, grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place = (*place) | ((a & 0xfffff)<<5); -+} -+ -+/* opr1 = pop (), -+ (*(uint32_t *) PC) [4 ... 0] = opr1 [22 ... 18] -+ (*(uint32_t *) PC) [25 ...10] = opr1 [17 ... 2] -+ */ -+void -+grub_loongarch64_sop_32_s_0_5_10_16_s2 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ -+ *place =(*place) | (((a >> 2) & 0xffff) << 10); -+ *place =(*place) | ((a >> 18) & 0x1f); -+} -+ -+/* -+ opr1 = pop () -+ (*(uint32_t *) PC) [9 ... 0] = opr1 [27 ... 18], -+ (*(uint32_t *) PC) [25 ... 10] = opr1 [17 ... 2] -+*/ -+void -+grub_loongarch64_sop_32_s_0_10_10_16_s2 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place) -+{ -+ grub_uint64_t a = grub_loongarch64_stack_pop (stack); -+ *place =(*place) | (((a >> 2) & 0xffff) << 10); -+ *place =(*place) | ((a >> 18) & 0x3ff); -+} -+ -+void grub_loongarch64_b26 (grub_uint32_t *place, grub_int64_t offset) -+{ -+ grub_uint32_t val; -+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfc000000); -+ -+ grub_dprintf ("dl", " reloc_xxxx64 %p %c= 0x%llx\n", -+ place, offset > 0 ? '+' : '-', -+ offset < 0 ? (long long) -(unsigned long long) offset : offset); -+ -+ val = ((offset >> 18) & 0x3ff) | (((offset >> 2) & 0xffff) << 10); -+ -+ *place &= insmask; -+ *place |= grub_cpu_to_le32 (val) & ~insmask; -+} -+ -+void grub_loongarch64_xxx_hi20 (grub_uint32_t *place, grub_int64_t offset) -+{ -+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfe00001f); -+ grub_uint32_t val; -+ -+ offset >>= 12; -+ val = ((offset & 0xfffff) << 5); -+ -+ *place &= insmask; -+ *place |= grub_cpu_to_le32 (val) & ~insmask; -+} -+ -+void grub_loongarch64_xxx_lo12 (grub_uint32_t *place, grub_int64_t offset) -+{ -+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xffc003ff); -+ -+ *place &= insmask; -+ *place |= grub_cpu_to_le32 (offset << 10) & ~insmask; -+} -+ -+void grub_loongarch64_xxx64_hi12 (grub_uint32_t *place, grub_int64_t offset) -+{ -+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xffc003ff); -+ grub_uint32_t val; -+ -+ offset >>= 52; -+ val = ((offset & 0xfff) << 10); -+ -+ *place &= insmask; -+ *place |= grub_cpu_to_le32 (val) & ~insmask; -+} -+ -+void grub_loongarch64_xxx64_lo20 (grub_uint32_t *place, grub_int64_t offset) -+{ -+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfe00001f); -+ grub_uint32_t val; -+ -+ offset >>= 32; -+ val = ((offset & 0xfffff) << 5); -+ -+ *place &= insmask; -+ *place |= grub_cpu_to_le32 (val) & ~insmask; -+} -diff --git a/grub-core/kern/loongarch64/efi/init.c b/grub-core/kern/loongarch64/efi/init.c -new file mode 100644 -index 000000000000..7f7c86676029 ---- /dev/null -+++ b/grub-core/kern/loongarch64/efi/init.c -@@ -0,0 +1,73 @@ -+/* -+ * 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static grub_uint64_t tmr; -+static grub_efi_event_t tmr_evt; -+ -+static grub_uint64_t -+grub_efi_get_time_ms (void) -+{ -+ return tmr; -+} -+ -+static void -+grub_loongson_increment_timer (grub_efi_event_t event __attribute__ ((unused)), -+ void *context __attribute__ ((unused))) -+{ -+ tmr += 10; -+} -+ -+void -+grub_machine_init (void) -+{ -+ grub_efi_boot_services_t *b; -+ -+ grub_efi_init (); -+ -+ b = grub_efi_system_table->boot_services; -+ efi_call_5 (b->create_event, GRUB_EFI_EVT_TIMER | GRUB_EFI_EVT_NOTIFY_SIGNAL, -+ GRUB_EFI_TPL_CALLBACK, grub_loongson_increment_timer, NULL, &tmr_evt); -+ efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_PERIODIC, 100000); -+ -+ grub_install_get_time_ms (grub_efi_get_time_ms); -+} -+ -+void -+grub_machine_fini (int flags) -+{ -+ grub_efi_boot_services_t *b; -+ -+ if (!(flags & GRUB_LOADER_FLAG_NORETURN)) -+ return; -+ -+ b = grub_efi_system_table->boot_services; -+ -+ efi_call_3 (b->set_timer, tmr_evt, GRUB_EFI_TIMER_CANCEL, 0); -+ efi_call_1 (b->close_event, tmr_evt); -+ -+ grub_efi_fini (); -+} -diff --git a/grub-core/kern/loongarch64/efi/startup.S b/grub-core/kern/loongarch64/efi/startup.S -new file mode 100644 -index 000000000000..1ffff0867b6e ---- /dev/null -+++ b/grub-core/kern/loongarch64/efi/startup.S -@@ -0,0 +1,45 @@ -+/* -+ * 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 . -+ */ -+ -+#include -+ -+ .file "startup.S" -+ .text -+ .globl start, _start -+ .align 4 -+ -+FUNCTION(start) -+FUNCTION(_start) -+ /* -+ * EFI_SYSTEM_TABLE and EFI_HANDLE are passed in a1/a0. -+ */ -+ addi.d $sp, $sp, -16 -+ st.d $ra, $sp, 0 -+ -+ la $a2, grub_efi_image_handle -+ st.d $a0, $a2, 0 -+ la $a2, grub_efi_system_table -+ st.d $a1, $a2, 0 -+ -+ bl grub_main -+ -+1: -+ ld.d $ra, $sp, 0 -+ addi.d $sp, $sp, 16 -+ jr $ra -+ -diff --git a/grub-core/kern/loongarch64/init.c b/grub-core/kern/loongarch64/init.c -new file mode 100644 -index 000000000000..b2de9309c153 ---- /dev/null -+++ b/grub-core/kern/loongarch64/init.c -@@ -0,0 +1,47 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009,2017 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+ -+grub_uint32_t grub_arch_cpuclock; -+ -+/* FIXME: use interrupt to count high. */ -+grub_uint64_t -+grub_get_rtc (void) -+{ -+ static grub_uint32_t high = 0; -+ static grub_uint32_t last = 0; -+ grub_uint32_t low; -+ -+ asm volatile ("csrrd %0, " GRUB_CPU_LOONGARCH_COP0_TIMER_COUNT : "=r" (low)); -+ if (low < last) -+ high++; -+ last = low; -+ -+ return (((grub_uint64_t) high) << 32) | low; -+} -+ -+void -+grub_timer_init (grub_uint32_t cpuclock) -+{ -+ grub_arch_cpuclock = cpuclock; -+ grub_install_get_time_ms (grub_rtc_get_time_ms); -+} -diff --git a/grub-core/lib/gnulib-patches/fix-loongarch.patch b/grub-core/lib/gnulib-patches/fix-loongarch.patch -new file mode 100644 -index 000000000000..fa0b09ac52fd ---- /dev/null -+++ b/grub-core/lib/gnulib-patches/fix-loongarch.patch -@@ -0,0 +1,26 @@ -+diff --git a/build-aux/config.guess b/build-aux/config.guess -+index 8e2a58b..927581d 100755 -+--- a/build-aux/config.guess -++++ b/build-aux/config.guess -+@@ -990,6 +990,9 @@ EOF -+ k1om:Linux:*:*) -+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" -+ exit ;; -++ loongarch32:Linux:*:* | loongarch64:Linux:*:* | loongarchx32:Linux:*:*) -++ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" -++ exit ;; -+ m32r*:Linux:*:*) -+ echo "$UNAME_MACHINE"-unknown-linux-"$LIBC" -+ exit ;; -+diff --git a/build-aux/config.sub b/build-aux/config.sub -+index 1fc4cde..6303428 100755 -+--- a/build-aux/config.sub -++++ b/build-aux/config.sub -+@@ -1184,6 +1184,7 @@ case $cpu-$vendor in -+ | k1om \ -+ | le32 | le64 \ -+ | lm32 \ -++ | loongarch32 | loongarch64 | loongarchx32 \ -+ | m32c | m32r | m32rle \ -+ | m5200 | m68000 | m680[012346]0 | m68360 | m683?2 | m68k | v70 | w65 \ -+ | m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip \ -diff --git a/grub-core/lib/loongarch64/relocator.c b/grub-core/lib/loongarch64/relocator.c -new file mode 100644 -index 000000000000..faa4553a5232 ---- /dev/null -+++ b/grub-core/lib/loongarch64/relocator.c -@@ -0,0 +1,163 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+extern grub_uint8_t grub_relocator_forward_start; -+extern grub_uint8_t grub_relocator_forward_end; -+extern grub_uint8_t grub_relocator_backward_start; -+extern grub_uint8_t grub_relocator_backward_end; -+ -+#define REGW_SIZEOF (4 * sizeof (grub_uint32_t)) -+#define JUMP_SIZEOF (2 * sizeof (grub_uint32_t)) -+ -+#define RELOCATOR_SRC_SIZEOF(x) (&grub_relocator_##x##_end \ -+ - &grub_relocator_##x##_start) -+#define RELOCATOR_SIZEOF(x) (RELOCATOR_SRC_SIZEOF(x) \ -+ + REGW_SIZEOF * 3) -+grub_size_t grub_relocator_align = sizeof (grub_uint64_t); -+grub_size_t grub_relocator_forward_size; -+grub_size_t grub_relocator_backward_size; -+grub_size_t grub_relocator_jumper_size = JUMP_SIZEOF + REGW_SIZEOF; -+ -+void -+grub_cpu_relocator_init (void) -+{ -+ grub_relocator_forward_size = RELOCATOR_SIZEOF(forward); -+ grub_relocator_backward_size = RELOCATOR_SIZEOF(backward); -+} -+ -+static void -+write_reg (int regn, grub_uint64_t val, void **target) -+{ -+ grub_uint32_t lu12iw=0x14000000; -+ grub_uint32_t ori=0x03800000; -+ grub_uint32_t lu32id=0x16000000; -+ grub_uint32_t lu52id=0x03000000; -+ -+ *(grub_uint32_t *) *target = (lu12iw | (grub_uint32_t)((val & 0xfffff000)>>12<<5) | (grub_uint32_t)regn);; -+ *target = ((grub_uint32_t *) *target) + 1; -+ *(grub_uint32_t *) *target = (ori | (grub_uint32_t)((val & 0xfff)<<10) | (grub_uint32_t)(regn | regn<<5)); -+ *target = ((grub_uint32_t *) *target) + 1; -+ *(grub_uint32_t *) *target = (lu32id | (grub_uint32_t)((val & 0xfffff00000000)>>32<<5) | (grub_uint32_t)regn);; -+ *target = ((grub_uint32_t *) *target) + 1; -+ *(grub_uint32_t *) *target = (lu52id | (grub_uint32_t)((val & 0xfff0000000000000)>>52<<10) | (grub_uint32_t)(regn | regn<<5));; -+ *target = ((grub_uint32_t *) *target) + 1; -+} -+ -+static void -+write_jump (int regn, void **target) -+{ -+ grub_uint32_t jirl=0x4c000000; -+ -+ *(grub_uint32_t *) *target = (jirl | (grub_uint32_t)(regn<<5)); -+ *target = ((grub_uint32_t *) *target) + 1; -+} -+ -+void -+grub_cpu_relocator_jumper (void *rels, grub_addr_t addr) -+{ -+ write_reg (1, addr, &rels); -+ write_jump (1, &rels); -+} -+ -+void -+grub_cpu_relocator_backward (void *ptr0, void *src, void *dest, -+ grub_size_t size) -+{ -+ void *ptr = ptr0; -+ write_reg (8, (grub_uint64_t) src, &ptr); -+ write_reg (9, (grub_uint64_t) dest, &ptr); -+ write_reg (10, (grub_uint64_t) size, &ptr); -+ grub_memcpy (ptr, &grub_relocator_backward_start, -+ RELOCATOR_SRC_SIZEOF (backward)); -+} -+ -+void -+grub_cpu_relocator_forward (void *ptr0, void *src, void *dest, -+ grub_size_t size) -+{ -+ void *ptr = ptr0; -+ write_reg (8, (grub_uint64_t) src, &ptr); -+ write_reg (9, (grub_uint64_t) dest, &ptr); -+ write_reg (10, (grub_uint64_t) size, &ptr); -+ grub_memcpy (ptr, &grub_relocator_forward_start, -+ RELOCATOR_SRC_SIZEOF (forward)); -+} -+ -+grub_err_t -+grub_relocator64_boot (struct grub_relocator *rel, -+ struct grub_relocator64_state state) -+{ -+ grub_relocator_chunk_t ch; -+ void *ptr; -+ grub_err_t err; -+ void *relst; -+ grub_size_t relsize; -+ grub_size_t stateset_size = 31 * REGW_SIZEOF + JUMP_SIZEOF; -+ unsigned i; -+ grub_addr_t vtarget; -+ -+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0, -+ (0xffffffff - stateset_size) -+ + 1, stateset_size, -+ grub_relocator_align, -+ GRUB_RELOCATOR_PREFERENCE_NONE, 0); -+ if (err) -+ return err; -+ -+ ptr = get_virtual_current_address (ch); -+ for (i = 1; i < 32; i++) -+ write_reg (i, state.gpr[i], &ptr); -+ write_jump (state.jumpreg, &ptr); -+ -+ vtarget = (grub_addr_t) grub_map_memory (get_physical_target_address (ch), -+ stateset_size); -+ -+ err = grub_relocator_prepare_relocs (rel, vtarget, &relst, &relsize); -+ if (err) -+ return err; -+ -+ grub_arch_sync_caches ((void *) relst, relsize); -+ -+ asm volatile ( -+ "ibar 0 \n"); -+ -+ grub_uint64_t val; -+ __asm__ __volatile__( -+ "li.w %0, 0x4\n\t" -+ "csrxchg $r0, %0, 0x0\n\t" -+ : "=r"(val) -+ : -+ : -+ ); -+ -+ ((void (*) (void)) relst) (); -+ -+ /* Not reached. */ -+ return GRUB_ERR_NONE; -+} -diff --git a/grub-core/lib/loongarch64/relocator_asm.S b/grub-core/lib/loongarch64/relocator_asm.S -new file mode 100644 -index 000000000000..ffdccc903e5f ---- /dev/null -+++ b/grub-core/lib/loongarch64/relocator_asm.S -@@ -0,0 +1,51 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#include -+ -+ .p2align 4 /* force 16-byte alignment */ -+ -+VARIABLE (grub_relocator_forward_start) -+ -+copycont1: -+ ld.d $r11,$r8,0 -+ st.d $r11,$r9,0 -+ addi.d $r8, $r8, 8 -+ addi.d $r10, $r10, -8 -+ addi.d $r9, $r9, 8 -+ bne $r10, $r0, copycont1 -+ -+VARIABLE (grub_relocator_forward_end) -+ -+VARIABLE (grub_relocator_backward_start) -+ -+ add.d $r9, $r9, $r10 -+ add.d $r8, $r8, $r10 -+ /* Backward movsl is implicitly off-by-one. compensate that. */ -+ addi.d $r9, $r9, -8 -+ addi.d $r8, $r8, -8 -+copycont2: -+ ld.w $r11,$r8,0 -+ st.w $r11,$r9,0 -+ addi.d $r8, $r8, -8 -+ addi.d $r10, $r10, -8 -+ addi.d $r9, $r9, -8 -+ bne $r10, $r0, copycont2 -+ -+VARIABLE (grub_relocator_backward_end) -+ -diff --git a/grub-core/lib/loongarch64/setjmp.S b/grub-core/lib/loongarch64/setjmp.S -new file mode 100644 -index 000000000000..bb0995937ecf ---- /dev/null -+++ b/grub-core/lib/loongarch64/setjmp.S -@@ -0,0 +1,68 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 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 . -+ */ -+ -+#include -+ -+ .file "setjmp.S" -+ -+GRUB_MOD_LICENSE "GPLv3+" -+ -+ .text -+ -+/* -+ * int grub_setjmp (jmp_buf env) -+ */ -+FUNCTION(grub_setjmp) -+ st.d $s0, $a0, 0x0 -+ st.d $s1, $a0, 0x8 -+ st.d $s2, $a0, 0x10 -+ st.d $s3, $a0, 0x18 -+ st.d $s4, $a0, 0x20 -+ st.d $s5, $a0, 0x28 -+ st.d $s6, $a0, 0x30 -+ st.d $s7, $a0, 0x38 -+ st.d $s8, $a0, 0x40 -+ st.d $fp, $a0, 0x48 -+ st.d $sp, $a0, 0x50 -+ st.d $ra, $a0, 0x58 -+ -+ move $a0, $zero -+ jr $ra -+ -+/* -+ * void grub_longjmp (jmp_buf env, int val) -+ */ -+FUNCTION(grub_longjmp) -+ ld.d $s0, $a0, 0x0 -+ ld.d $s1, $a0, 0x8 -+ ld.d $s2, $a0, 0x10 -+ ld.d $s3, $a0, 0x18 -+ ld.d $s4, $a0, 0x20 -+ ld.d $s5, $a0, 0x28 -+ ld.d $s6, $a0, 0x30 -+ ld.d $s7, $a0, 0x38 -+ ld.d $s8, $a0, 0x40 -+ ld.d $fp, $a0, 0x48 -+ ld.d $sp, $a0, 0x50 -+ ld.d $ra, $a0, 0x58 -+ -+ li.w $a0, 1 -+ beqz $a1, .L0 -+ move $a0, $a1 -+.L0: -+ jr $ra -diff --git a/grub-core/lib/setjmp.S b/grub-core/lib/setjmp.S -index aa297ab0af2f..da71fc751871 100644 ---- a/grub-core/lib/setjmp.S -+++ b/grub-core/lib/setjmp.S -@@ -15,6 +15,8 @@ - #include "./arm/setjmp.S" - #elif defined(__aarch64__) - #include "./arm64/setjmp.S" -+#elif defined(__loongarch64) -+#include "./loongarch64/setjmp.S" - #elif defined(__riscv) - #include "./riscv/setjmp.S" - #else -diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c -index 3af6b1229269..985111cf458b 100644 ---- a/grub-core/loader/efi/chainloader.c -+++ b/grub-core/loader/efi/chainloader.c -@@ -334,6 +334,8 @@ static const grub_uint16_t machine_type __attribute__((__unused__)) = - GRUB_PE32_MACHINE_I386; - #elif defined(__ia64__) - GRUB_PE32_MACHINE_IA64; -+#elif defined(__loongarch64) -+ GRUB_PE32_MACHINE_LOONGARCH64; - #elif defined(__riscv) && (__riscv_xlen == 32) - GRUB_PE32_MACHINE_RISCV32; - #elif defined(__riscv) && (__riscv_xlen == 64) -diff --git a/grub-core/loader/loongarch64/linux-efi.c b/grub-core/loader/loongarch64/linux-efi.c -new file mode 100644 -index 000000000000..4dcefd9d9e27 ---- /dev/null -+++ b/grub-core/loader/loongarch64/linux-efi.c -@@ -0,0 +1,144 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 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 . -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define GRUB_EFI_PE_MAGIC 0x5A4D -+ -+grub_err_t -+finalize_efi_params_linux (struct linux_loongarch64_kernel_params *kernel_params) -+{ -+ int node, retval; -+ -+ 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 (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ { -+ grub_dprintf ("linux", "Initrd @ %p-%p\n", -+ (void *) kernel_params->ramdisk_addr, -+ (void *) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); -+ -+ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", -+ kernel_params->ramdisk_addr); -+ if (retval) -+ goto failure; -+ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", -+ kernel_params->ramdisk_addr + kernel_params->ramdisk_size); -+ if (retval) -+ goto failure; -+ } -+ -+ if (grub_fdt_install() != GRUB_ERR_NONE) -+ goto failure; -+ -+ return GRUB_ERR_NONE; -+ -+failure: -+ grub_fdt_unload(); -+ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); -+} -+ -+grub_err_t -+grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh) -+{ -+ if ((lh->code0 & 0xffff) == GRUB_EFI_PE_MAGIC) -+ return GRUB_ERR_NONE; -+ else -+ return 1; -+ -+ grub_dprintf ("linux", "UEFI stub kernel:\n"); -+ grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset); -+ -+ return GRUB_ERR_NONE; -+} -+ -+grub_err_t -+grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args) -+{ -+ grub_efi_memory_mapped_device_path_t *mempath; -+ grub_efi_handle_t image_handle; -+ grub_efi_boot_services_t *b; -+ grub_efi_status_t status; -+ grub_efi_loaded_image_t *loaded_image; -+ int len; -+ -+ mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t)); -+ if (!mempath) -+ return grub_errno; -+ -+ mempath[0].header.type = GRUB_EFI_HARDWARE_DEVICE_PATH_TYPE; -+ mempath[0].header.subtype = GRUB_EFI_MEMORY_MAPPED_DEVICE_PATH_SUBTYPE; -+ mempath[0].header.length = grub_cpu_to_le16_compile_time (sizeof (*mempath)); -+ mempath[0].memory_type = GRUB_EFI_LOADER_DATA; -+ mempath[0].start_address = addr; -+ mempath[0].end_address = addr + size; -+ -+ mempath[1].header.type = GRUB_EFI_END_DEVICE_PATH_TYPE; -+ mempath[1].header.subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE; -+ mempath[1].header.length = sizeof (grub_efi_device_path_t); -+ -+ b = grub_efi_system_table->boot_services; -+ status = b->load_image (0, grub_efi_image_handle, -+ (grub_efi_device_path_t *) mempath, -+ (void *) addr, size, &image_handle); -+ if (status != GRUB_EFI_SUCCESS) -+ return grub_error (GRUB_ERR_BAD_OS, "cannot load image"); -+ -+ grub_dprintf ("linux", "linux command line: '%s'\n", args); -+ -+ /* Convert command line to UCS-2 */ -+ loaded_image = grub_efi_get_loaded_image (image_handle); -+ loaded_image->load_options_size = len = -+ (grub_strlen (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_errno; -+ -+ loaded_image->load_options_size = -+ 2 * grub_utf8_to_utf16 (loaded_image->load_options, len, -+ (grub_uint8_t *) args, len, NULL); -+ -+ grub_dprintf ("linux", "starting image %p\n", image_handle); -+ status = b->start_image (image_handle, 0, NULL); -+ -+ /* When successful, not reached */ -+ b->unload_image (image_handle); -+ grub_efi_free_pages ((grub_addr_t) loaded_image->load_options, -+ GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size)); -+ -+ return grub_errno; -+} -diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c -new file mode 100644 -index 000000000000..85585b44f085 ---- /dev/null -+++ b/grub-core/loader/loongarch64/linux-elf.c -@@ -0,0 +1,529 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define GRUB_ADDRESS_TYPE_SYSRAM 1 -+#define GRUB_ADDRESS_TYPE_RESERVED 2 -+#define GRUB_ADDRESS_TYPE_ACPI 3 -+#define GRUB_ADDRESS_TYPE_NVS 4 -+#define GRUB_ADDRESS_TYPE_PMEM 5 -+#define GRUB_EFI_LOONGSON_BPI_TABLE_GUID \ -+ { 0x4660f721, 0x2ec5, 0x416a, \ -+ { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ -+ } -+ -+static struct grub_relocator *relocator; -+ -+void grub_linux_loongarch_elf_relocator_unload (void) -+{ -+ grub_relocator_unload (relocator); -+} -+ -+static grub_err_t -+allocate_fdt_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_params) -+{ -+ int node, retval; -+ grub_err_t err; -+ unsigned int size; -+ grub_efi_uintn_t mmap_size; -+ grub_efi_uintn_t desc_size; -+ grub_efi_uint32_t desc_version; -+ grub_efi_memory_descriptor_t *mmap_buf; -+ -+ size = GRUB_FDT_EMPTY_TREE_SZ + FDT_ADDR_SIZE_EXTRA + GRUB_EFI_LINUX_FDT_EXTRA_SPACE; -+ -+ kernel_params->fdt = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (size)); -+ if (!kernel_params->fdt) -+ return GRUB_ERR_OUT_OF_MEMORY; -+ -+ grub_fdt_create_empty_tree (kernel_params->fdt, size); -+ grub_fdt_set_prop32 (kernel_params->fdt, 0, FDT_ADDR_CELLS_STRING, 2); -+ grub_fdt_set_prop32 (kernel_params->fdt, 0, FDT_SIZE_CELLS_STRING, 2); -+ -+ node = grub_fdt_find_subnode (kernel_params->fdt, 0, "chosen"); -+ if (node < 0) -+ node = grub_fdt_add_subnode (kernel_params->fdt, 0, "chosen"); -+ if (node < 1) -+ goto failure; -+ -+ grub_dprintf ("loongson", "command_line %s, len %ld\n", -+ (char *)kernel_params->linux_args, -+ grub_strlen(kernel_params->linux_args) + 1); -+ if ((kernel_params->linux_args != NULL) && (grub_strlen(kernel_params->linux_args) > 0)) { -+ retval = grub_fdt_set_prop (kernel_params->fdt, node, "bootargs", kernel_params->linux_args, -+ grub_strlen(kernel_params->linux_args) + 1); -+ if (retval) -+ goto failure; -+ } -+ -+ /* Set initrd info */ -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ { -+ grub_dprintf ("linux", "Initrd @ %p-%p\n", -+ (void *) kernel_params->ramdisk_addr, -+ (void *) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); -+ -+ retval = grub_fdt_set_prop64 (kernel_params->fdt, node, "linux,initrd-start", -+ kernel_params->ramdisk_addr); -+ if (retval) -+ goto failure; -+ retval = grub_fdt_set_prop64 (kernel_params->fdt, node, "linux,initrd-end", -+ (grub_uint64_t) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); -+ if (retval) -+ goto failure; -+ } -+ -+ node = grub_fdt_find_subnode (kernel_params->fdt, 0, "chosen"); -+ retval = grub_fdt_set_prop64 (kernel_params->fdt, node, "linux,uefi-system-table", -+ (grub_uint64_t)grub_efi_system_table); -+ if (retval) -+ goto failure; -+ -+ mmap_size = grub_efi_find_mmap_size (); -+ if (! mmap_size) -+ return grub_errno; -+ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); -+ if (! mmap_buf) -+ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); -+ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, -+ &desc_size, &desc_version); -+ if (err) -+ return err; -+ -+ if (!mmap_buf || !mmap_size || !desc_size) -+ return GRUB_ERR_BAD_ARGUMENT; -+ -+ retval = grub_fdt_set_prop64 (kernel_params->fdt, node, "linux,uefi-mmap-start", -+ (grub_uint64_t)mmap_buf); -+ if (retval) -+ goto failure; -+ -+ retval = grub_fdt_set_prop32 (kernel_params->fdt, node, "linux,uefi-mmap-size", -+ mmap_size); -+ if (retval) -+ goto failure; -+ -+ retval = grub_fdt_set_prop32 (kernel_params->fdt, node, "linux,uefi-mmap-desc-size", -+ desc_size); -+ if (retval) -+ goto failure; -+ -+ retval = grub_fdt_set_prop32 (kernel_params->fdt, node, "linux,uefi-mmap-desc-ver", -+ desc_version); -+ if (retval) -+ goto failure; -+ -+ return GRUB_ERR_NONE; -+ -+failure: -+ if (!kernel_params->fdt) { -+ return GRUB_ERR_BAD_OS; -+ } -+ grub_efi_free_pages ((grub_addr_t) kernel_params->fdt, -+ GRUB_EFI_BYTES_TO_PAGES (grub_fdt_get_totalsize (kernel_params->fdt))); -+ kernel_params->fdt = NULL; -+ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); -+} -+ -+static void -+grub_linux_loongarch_elf_make_argv (struct linux_loongarch64_kernel_params *kernel_params) -+{ -+ static void* linux_args_addr; -+ int size; -+ grub_uint64_t *linux_argv; -+ char *args, *p, *linux_args; -+ int i, argc; -+ grub_err_t err; -+ -+ argc = kernel_params->linux_argc; -+ args = kernel_params->linux_args; -+ -+ /* new size */ -+ p = args; -+ size = (argc + 3 + 1) * sizeof (grub_uint64_t); /* orig arguments */ -+ for (i = 0; i < argc; i++) -+ { -+ size += ALIGN_UP (grub_strlen (p) + 1, 4); -+ p += grub_strlen (p) + 1; -+ } -+ -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ { -+ size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4) \ -+ + ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4) \ -+ + ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), -+ 4); -+ } -+ size = ALIGN_UP (size, 8); -+ -+ /* alloc memory */ -+ linux_args_addr = grub_linux_loongarch_alloc_virtual_mem_align (size, 8, &err); -+ -+ linux_argv = linux_args_addr; -+ linux_args = (char *)(linux_argv + (argc + 1 + 3)); -+ p = args; -+ for (i = 0; i < argc; i++) -+ { -+ grub_memcpy (linux_args, p, grub_strlen (p) + 1); -+ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; -+ linux_argv++; -+ linux_args += ALIGN_UP (grub_strlen (p) + 1, 4); -+ p += grub_strlen (p) + 1; -+ } -+ -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ { -+ /* rd_start */ -+ grub_snprintf (linux_args, -+ sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), -+ "rd_start=0x%lx", -+ (grub_uint64_t) kernel_params->ramdisk_addr); -+ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; -+ linux_argv++; -+ linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); -+ kernel_params->linux_argc++; -+ -+ /* rd_size */ -+ grub_snprintf (linux_args, -+ sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), -+ "rd_size=0x%lx", -+ (grub_uint64_t) kernel_params->ramdisk_size); -+ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; -+ linux_argv++; -+ linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); -+ kernel_params->linux_argc++; -+ -+ /* initrd */ -+ grub_snprintf (linux_args, -+ sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), -+ "initrd=0x%lx,0x%lx", -+ ((grub_uint64_t) kernel_params->ramdisk_addr & 0xffffffff), -+ (grub_uint64_t) kernel_params->ramdisk_size); -+ *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; -+ linux_argv++; -+ linux_args += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); -+ kernel_params->linux_argc++; -+ } -+ -+ /* Reserve space for initrd arguments. */ -+ *linux_argv = 0; -+ -+ grub_free (kernel_params->linux_args); -+ kernel_params->linux_argv = (grub_addr_t) linux_args_addr; -+} -+ -+grub_err_t -+grub_linux_loongarch_elf_linux_boot_image (struct linux_loongarch64_kernel_params -+ *kernel_params) -+{ -+ struct boot_params_interface *boot_params = NULL; -+ struct grub_relocator64_state state; -+ grub_err_t err; -+ -+ /* linux kernel type is ELF */ -+ grub_memset (&state, 0, sizeof (state)); -+ -+ state.jumpreg = 1; -+ state.gpr[1] = kernel_params->kernel_addr; /* ra */ -+ if (grub_linux_loongarch_elf_get_boot_params (&boot_params) == 0) -+ { -+ grub_printf("not find param, is fdt boot\n"); -+ if (allocate_fdt_and_exit_boot (kernel_params) != GRUB_ERR_NONE) -+ return grub_errno; -+ state.gpr[4] = 1 << FLAGS_EFI_SUPPORT_BIT; /* a0 = flag */ -+ state.gpr[5] = (grub_uint64_t)kernel_params->fdt; /* a1 = fdt */ -+ state.gpr[6] = 0; /* a2 = flag */ -+ } else { -+ grub_printf("find param, is bpi boot\n"); -+ grub_linux_loongarch_elf_make_argv (kernel_params); -+ state.gpr[4] = kernel_params->linux_argc; /* a0 = argc */ -+ state.gpr[5] = kernel_params->linux_argv; /* a1 = args */ -+ state.gpr[6] = (grub_uint64_t) boot_params; /* a2 = envp */ -+ err = grub_linux_loongarch_elf_boot_params (boot_params); -+ if (err) -+ return err; -+ } -+ -+ /* Boot the ELF kernel */ -+ grub_relocator64_boot (relocator, state); -+ -+ return GRUB_ERR_NONE; -+} -+ -+void* -+grub_linux_loongarch_alloc_virtual_mem_addr (grub_addr_t addr, -+ grub_size_t size, -+ grub_err_t *err) -+{ -+ relocator = grub_relocator_new (); -+ if (!relocator) -+ return NULL; -+ -+ grub_relocator_chunk_t ch; -+ *err = grub_relocator_alloc_chunk_addr (relocator, &ch, -+ grub_vtop ((void *) addr), -+ size); -+ if (*err) -+ return NULL; -+ return get_virtual_current_address (ch); -+} -+ -+void* -+grub_linux_loongarch_alloc_virtual_mem_align (grub_size_t size, -+ grub_size_t align, -+ grub_err_t *err) -+{ -+ grub_relocator_chunk_t ch; -+ -+ *err = grub_relocator_alloc_chunk_align (relocator, &ch, -+ 0, (0xffffffff - size) + 1, -+ size, align, -+ GRUB_RELOCATOR_PREFERENCE_LOW, 0); -+ return get_virtual_current_address (ch); -+} -+ -+int -+grub_linux_loongarch_elf_get_boot_params (struct boot_params_interface **boot_params) -+{ -+ grub_efi_configuration_table_t *tables; -+ grub_efi_guid_t bpi_guid = GRUB_EFI_LOONGSON_BPI_TABLE_GUID; -+ unsigned int i; -+ int found = 0; -+ -+ /* Look for Loongson BPI in UEFI config tables. */ -+ tables = grub_efi_system_table->configuration_table; -+ -+ for (i = 0; i < grub_efi_system_table->num_table_entries; i++) -+ if (grub_memcmp (&tables[i].vendor_guid, &bpi_guid, sizeof (bpi_guid)) == 0) -+ { -+ *boot_params = tables[i].vendor_table; -+ char *p = (char*) &((*boot_params)->signature); -+ if (grub_strncmp (p, "BPI", 3) == 0) -+ { -+ found = 1; -+ break; -+ } -+ } -+ return found; -+} -+ -+static grub_uint8_t -+grub_kernel_update_checksum (const grub_uint8_t *buffer, grub_efi_uintn_t length) -+{ -+ grub_uint8_t sum; -+ grub_efi_uintn_t count; -+ -+ for (sum = 0, count = 0; count < length; count++) -+ { -+ sum = (grub_uint8_t) (sum + *(buffer + count)); -+ } -+ -+ return (grub_uint8_t) (0x100 - sum); -+} -+ -+static grub_uint32_t -+grub_efi_loongarch64_memmap_sort (struct memmap array[], -+ grub_uint32_t length, -+ struct loongsonlist_mem_map* bpmem, -+ grub_uint32_t index, -+ grub_uint32_t memtype) -+{ -+ grub_uint64_t tempmemsize = 0; -+ grub_uint32_t j = 0; -+ grub_uint32_t t = 0; -+ -+ for(j = 0; j < length;) -+ { -+ tempmemsize = array[j].mem_size; -+ for(t = j + 1; t < length; t++) -+ { -+ if(array[j].mem_start + tempmemsize == array[t].mem_start) -+ { -+ tempmemsize += array[t].mem_size; -+ } -+ else -+ { -+ break; -+ } -+ } -+ bpmem->map[index].mem_type = memtype; -+ bpmem->map[index].mem_start = array[j].mem_start; -+ bpmem->map[index].mem_size = tempmemsize; -+ grub_printf("map[%d]:type %"PRIuGRUB_UINT32_T", start 0x%" -+ PRIxGRUB_UINT64_T", end 0x%"PRIxGRUB_UINT64_T"\n", -+ index, -+ bpmem->map[index].mem_type, -+ bpmem->map[index].mem_start, -+ bpmem->map[index].mem_start+ bpmem->map[index].mem_size -+ ); -+ j = t; -+ index++; -+ } -+ return index; -+} -+ -+grub_err_t -+grub_linux_loongarch_elf_boot_params (struct boot_params_interface *boot_params) -+{ -+ grub_int8_t checksum = 0; -+ grub_err_t err; -+ -+ struct loongsonlist_mem_map *loongson_mem_map = NULL; -+ struct _extention_list_hdr * listpointer = NULL; -+ grub_uint32_t tmp_index = 0; -+ grub_efi_memory_descriptor_t * lsdesc = NULL; -+ -+ grub_uint32_t free_index = 0; -+ grub_uint32_t reserve_index = 0; -+ grub_uint32_t acpi_table_index = 0; -+ grub_uint32_t acpi_nvs_index = 0; -+ -+ grub_efi_uintn_t mmap_size; -+ grub_efi_uintn_t desc_size; -+ grub_efi_memory_descriptor_t *mmap_buf; -+ -+ struct memmap reserve_mem[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; -+ struct memmap free_mem[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; -+ struct memmap acpi_table_mem[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; -+ struct memmap acpi_nvs_mem[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; -+ -+ grub_memset (reserve_mem, 0, sizeof(struct memmap) * GRUB_LOONGSON3_BOOT_MEM_MAP_MAX); -+ grub_memset (free_mem, 0, sizeof(struct memmap) * GRUB_LOONGSON3_BOOT_MEM_MAP_MAX); -+ grub_memset (acpi_table_mem, 0, sizeof(struct memmap) * GRUB_LOONGSON3_BOOT_MEM_MAP_MAX); -+ grub_memset (acpi_nvs_mem, 0, sizeof(struct memmap) * GRUB_LOONGSON3_BOOT_MEM_MAP_MAX); -+ -+ /* Check extlist headers */ -+ listpointer = boot_params->extlist; -+ for( ;listpointer != NULL; listpointer = listpointer->next) -+ { -+ char *pl= (char *)&(listpointer->signature); -+ if(grub_strncmp(pl, "MEM", 3) == 0) -+ { -+ loongson_mem_map = (struct loongsonlist_mem_map *)listpointer; -+ break; -+ } -+ } -+ -+ mmap_size = grub_efi_find_mmap_size (); -+ if (! mmap_size) -+ return grub_errno; -+ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); -+ if (! mmap_buf) -+ return grub_error (GRUB_ERR_IO, "cannot allocate memory map"); -+ -+ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, -+ &desc_size, NULL); -+ if (err) -+ return err; -+ -+ if (!mmap_buf || !mmap_size || !desc_size) -+ return -1; -+ -+ /* -+ According to UEFI SPEC,mmap_buf is the accurate Memory Map array \ -+ now we can fill platform specific memory structure. -+ */ -+ for (lsdesc = mmap_buf; lsdesc < (grub_efi_memory_descriptor_t *)((char *)mmap_buf + mmap_size); -+ lsdesc = (grub_efi_memory_descriptor_t *)((char *)lsdesc + desc_size)) -+ { -+ /* System RAM */ -+ if((lsdesc->type != GRUB_EFI_ACPI_RECLAIM_MEMORY) && \ -+ (lsdesc->type != GRUB_EFI_ACPI_MEMORY_NVS) && \ -+ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_DATA) && \ -+ (lsdesc->type != GRUB_EFI_RUNTIME_SERVICES_CODE) && \ -+ (lsdesc->type != GRUB_EFI_RESERVED_MEMORY_TYPE) && \ -+ (lsdesc->type != GRUB_EFI_PAL_CODE)) -+ { -+ free_mem[free_index].mem_type = GRUB_ADDRESS_TYPE_SYSRAM; -+ free_mem[free_index].mem_start = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; -+ free_mem[free_index].mem_size = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; -+ free_index++; -+ -+ /*ACPI*/ -+ }else if((lsdesc->type == GRUB_EFI_ACPI_RECLAIM_MEMORY)){ -+ acpi_table_mem[acpi_table_index].mem_type = GRUB_ADDRESS_TYPE_ACPI; -+ acpi_table_mem[acpi_table_index].mem_start = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; -+ acpi_table_mem[acpi_table_index].mem_size = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; -+ acpi_table_index++; -+ }else if((lsdesc->type == GRUB_EFI_ACPI_MEMORY_NVS)){ -+ acpi_nvs_mem[acpi_nvs_index].mem_type = GRUB_ADDRESS_TYPE_NVS; -+ acpi_nvs_mem[acpi_nvs_index].mem_start = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; -+ acpi_nvs_mem[acpi_nvs_index].mem_size = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; -+ acpi_nvs_index++; -+ -+ /* Reserve */ -+ }else{ -+ reserve_mem[reserve_index].mem_type = GRUB_ADDRESS_TYPE_RESERVED; -+ reserve_mem[reserve_index].mem_start = (lsdesc->physical_start) & GRUB_EFI_MAX_PHY_ADDRESS; -+ reserve_mem[reserve_index].mem_size = lsdesc->num_pages * GRUB_EFI_PAGE_SIZE; -+ reserve_index++; -+ } -+ } -+ -+ tmp_index = loongson_mem_map->map_count; -+ /*System RAM Sort*/ -+ tmp_index = grub_efi_loongarch64_memmap_sort(free_mem, -+ free_index, -+ loongson_mem_map, -+ tmp_index, -+ GRUB_ADDRESS_TYPE_SYSRAM); -+ /*ACPI Sort*/ -+ tmp_index = grub_efi_loongarch64_memmap_sort(acpi_table_mem, -+ acpi_table_index, -+ loongson_mem_map, -+ tmp_index, -+ GRUB_ADDRESS_TYPE_ACPI); -+ tmp_index = grub_efi_loongarch64_memmap_sort(acpi_nvs_mem, -+ acpi_nvs_index, -+ loongson_mem_map, -+ tmp_index, -+ GRUB_ADDRESS_TYPE_NVS); -+ -+ /*Reserve Sort*/ -+ { -+ grub_uint64_t loongarch_addr; -+ asm volatile ("csrrd %0, 0x181" : "=r" (loongarch_addr)); -+ if ((loongarch_addr & 0xff00000000000000) == 0x9000000000000000) -+ tmp_index = grub_efi_loongarch64_memmap_sort(reserve_mem, -+ reserve_index, -+ loongson_mem_map, -+ tmp_index, -+ GRUB_ADDRESS_TYPE_RESERVED); -+ else -+ tmp_index = grub_efi_loongarch64_memmap_sort(reserve_mem, -+ reserve_index, -+ loongson_mem_map, -+ tmp_index, -+ GRUB_ADDRESS_TYPE_RESERVED + 1); -+ } -+ loongson_mem_map->map_count = tmp_index; -+ loongson_mem_map->header.checksum = 0; -+ -+ checksum = grub_kernel_update_checksum ((grub_uint8_t *) loongson_mem_map, -+ loongson_mem_map->header.length); -+ loongson_mem_map->header.checksum = checksum; -+ -+ return grub_errno; -+} -diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c -new file mode 100644 -index 000000000000..783054be5100 ---- /dev/null -+++ b/grub-core/loader/loongarch64/linux.c -@@ -0,0 +1,398 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 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 . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+GRUB_MOD_LICENSE ("GPLv3+"); -+ -+#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024) -+ -+static struct linux_loongarch64_kernel_params kernel_params; -+ -+static grub_addr_t phys_addr; -+static grub_dl_t my_mod; -+static int loaded; -+static int is_bpi_boot; -+static int grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_BAD; -+ -+static grub_err_t -+grub_linux_boot (void) -+{ -+ -+ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_EFI) { -+ if (finalize_efi_params_linux (&kernel_params) != GRUB_ERR_NONE) -+ return grub_errno; -+ return (grub_arch_efi_linux_boot_image((grub_addr_t) kernel_params.kernel_addr, -+ kernel_params.kernel_size, -+ kernel_params.linux_args)); -+ } -+ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_ELF) { -+ return grub_linux_loongarch_elf_linux_boot_image (&kernel_params); -+ } -+ -+ return GRUB_ERR_NONE; -+} -+ -+static grub_err_t -+grub_linux_unload (void) -+{ -+ -+ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_EFI) { -+ if (kernel_params.ramdisk_addr) -+ grub_efi_free_pages ((grub_efi_physical_address_t) kernel_params.ramdisk_addr, -+ GRUB_EFI_BYTES_TO_PAGES (kernel_params.ramdisk_size)); -+ kernel_params.ramdisk_size = 0; -+ -+ if (kernel_params.kernel_addr) -+ grub_efi_free_pages ((grub_addr_t) kernel_params.kernel_addr, -+ GRUB_EFI_BYTES_TO_PAGES (kernel_params.kernel_size)); -+ kernel_params.kernel_addr = 0; -+ } -+ -+ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_ELF) { -+ grub_free (kernel_params.linux_args); -+ kernel_params.linux_args = 0; -+ grub_linux_loongarch_elf_relocator_unload (); -+ } -+ -+ grub_dl_unref (my_mod); -+ loaded = 0; -+ grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_BAD; -+ -+ return GRUB_ERR_NONE; -+} -+ -+grub_err_t -+grub_linux_loongarch_elf_load_kernel (grub_elf_t elf, const char *filename) -+{ -+ Elf64_Addr base; -+ grub_err_t err; -+ grub_uint8_t *playground; -+ grub_uint64_t addr; -+ int flag; -+ -+ /* Linux's entry point incorrectly contains a virtual address. */ -+ kernel_params.kernel_addr = elf->ehdr.ehdr64.e_entry; -+ kernel_params.kernel_size = grub_elf64_size (elf, &base, 0); -+ -+ if (kernel_params.kernel_size == 0) -+ return grub_errno; -+ -+ phys_addr = base; -+ kernel_params.kernel_size = ALIGN_UP (base + kernel_params.kernel_size - base, 8); -+ -+ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); -+ if (addr & 0x1) { -+ flag = GRUB_ELF_LOAD_FLAGS_NONE; -+ } else { -+ flag = GRUB_ELF_LOAD_FLAGS_30BITS; -+ base &= ~ELF64_LOADMASK; -+ kernel_params.kernel_addr &= ~ELF64_LOADMASK; -+ } -+ -+ playground = grub_linux_loongarch_alloc_virtual_mem_addr (phys_addr, -+ kernel_params.kernel_size, -+ &err); -+ if (playground == NULL) -+ return err; -+ -+ /* Now load the segments into the area we claimed. */ -+ return grub_elf64_load (elf, filename, playground - base, -+ flag, 0, 0); -+} -+ -+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 boot_params_interface *boot_params = NULL; -+ grub_elf_t elf = NULL; -+ grub_err_t err; -+ grub_size_t cmdline_size; -+ int i; -+ -+ grub_dl_ref (my_mod); -+ -+ /* Release the previously used memory. */ -+ grub_loader_unset (); -+ -+ 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_params.kernel_size = grub_file_size (file); -+ grub_dprintf ("linux", "kernel file size: %" PRIuGRUB_SIZE "\n", -+ kernel_params.kernel_size); -+ -+ 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) { -+ grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_EFI; -+ } -+ -+ if (grub_loongarch_linux_type != GRUB_LOONGARCH_LINUX_EFI) { -+ elf = grub_elf_file (file, argv[0]); -+ if (elf != NULL) -+ { -+ /* linux kernel type is ELF */ -+ grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_ELF; -+ if (elf->ehdr.ehdr64.e_type != ET_EXEC) -+ { -+ grub_error (GRUB_ERR_UNKNOWN_OS, -+ N_("this ELF file is not of the right type")); -+ goto fail; -+ } -+ if (elf->ehdr.ehdr64.e_machine != EM_LOONGARCH) -+ { -+ grub_error (GRUB_ERR_BAD_OS, "invalid magic number"); -+ goto fail; -+ } -+ -+ if (grub_elf_is_elf64 (elf)) -+ { -+ err = grub_linux_loongarch_elf_load_kernel (elf, argv[0]); -+ if (err) -+ goto fail; -+ } else { -+ grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF magic")); -+ goto fail; -+ } -+ grub_dprintf ("linux", "kernel @ %p\n", (void*) elf->ehdr.ehdr64.e_entry); -+ } -+ } else { -+ if (grub_file_seek (file, 0) == (grub_off_t) -1) -+ goto fail; -+ -+ if (grub_file_read (file, &lh, sizeof (lh)) < (grub_ssize_t) sizeof (lh)) -+ { -+ if (!grub_errno) -+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), -+ argv[0]); -+ goto fail; -+ } -+ -+ if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE) -+ { -+ goto fail; -+ } -+ /* linux kernel type is EFI */ -+ grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_EFI; -+ kernel_params.kernel_addr = (grub_addr_t) grub_efi_allocate_any_pages ( -+ GRUB_EFI_BYTES_TO_PAGES (kernel_params.kernel_size)); -+ grub_dprintf ("linux", "kernel numpages: %" PRIuGRUB_SIZE "\n", -+ GRUB_EFI_BYTES_TO_PAGES (kernel_params.kernel_size)); -+ if (!kernel_params.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, (void*) kernel_params.kernel_addr, kernel_params.kernel_size) -+ < (grub_int64_t) kernel_params.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", (void*) kernel_params.kernel_addr); -+ } -+ -+ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); -+ kernel_params.linux_argc = argc; -+ kernel_params.linux_args = grub_malloc (cmdline_size); -+ if (!kernel_params.linux_args) -+ { -+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); -+ goto fail; -+ } -+ -+ grub_memcpy (kernel_params.linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE)); -+ -+ if (grub_linux_loongarch_elf_get_boot_params (&boot_params) == 1) -+ is_bpi_boot = 1; -+ else -+ is_bpi_boot = 0; -+ -+ if (is_bpi_boot == 0) -+ { -+ err = grub_create_loader_cmdline (argc, argv, -+ (char*) ((grub_addr_t) kernel_params.linux_args + sizeof (LINUX_IMAGE) - 1), -+ cmdline_size, -+ GRUB_VERIFY_KERNEL_CMDLINE); -+ if (err) -+ goto fail; -+ } else { -+ /* save args from linux cmdline */ -+ char *p = kernel_params.linux_args; -+ -+ p += sizeof (LINUX_IMAGE) - 1; -+ for (i=0; i < argc; i++) -+ { -+ grub_memcpy (p, argv[i], grub_strlen(argv[i]) + 1); -+ p += grub_strlen(argv[i]) + 1; -+ } -+ } -+ -+ if (grub_errno == GRUB_ERR_NONE) -+ { -+ grub_loader_set (grub_linux_boot, grub_linux_unload, 0); -+ loaded = 1; -+ } -+ -+fail: -+ if (elf != NULL) { -+ /* grub_elf_close will call grub_file_close() */ -+ grub_elf_close (elf); -+ } else { -+ if (file) -+ grub_file_close (file); -+ } -+ -+ if (grub_errno != GRUB_ERR_NONE) -+ { -+ grub_dl_unref (my_mod); -+ loaded = 0; -+ } -+ -+ if (kernel_params.linux_args && !loaded) -+ grub_free (kernel_params.linux_args); -+ -+ if (grub_loongarch_linux_type == GRUB_LOONGARCH_LINUX_EFI) { -+ if (kernel_params.kernel_addr && !loaded) -+ grub_efi_free_pages ((grub_addr_t) kernel_params.kernel_addr, -+ GRUB_EFI_BYTES_TO_PAGES (kernel_params.kernel_size)); -+ } -+ -+ return grub_errno; -+} -+ -+/* -+ * 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 }; -+ grub_size_t initrd_size; -+ void *initrd_mem = NULL; -+ -+ if (argc == 0) -+ { -+ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); -+ goto fail; -+ } -+ -+ if (!loaded) -+ { -+ return 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"); -+ -+ if (is_bpi_boot == 0) { -+ grub_size_t initrd_pages; -+ initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size)); -+ initrd_mem = allocate_initrd_mem (initrd_pages); -+ } else { -+ grub_err_t err; -+ initrd_mem = grub_linux_loongarch_alloc_virtual_mem_align (initrd_size, 0x10000, &err); -+ if (err) -+ goto fail; -+ } -+ -+ 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; -+ -+ /* save ramdisk addr and size */ -+ kernel_params.ramdisk_addr = (grub_addr_t) initrd_mem; -+ kernel_params.ramdisk_size = initrd_size; -+ grub_dprintf ("linux", "ramdisk [addr=%p, size=0x%lx]\n", -+ (void *) initrd_mem, initrd_size); -+fail: -+ grub_initrd_close (&initrd_ctx); -+ if (is_bpi_boot == 0) { -+ if (initrd_mem && !kernel_params.ramdisk_addr) -+ grub_efi_free_pages ((grub_addr_t) initrd_mem, -+ GRUB_EFI_BYTES_TO_PAGES (initrd_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, -+ N_("FILE [ARGS...]"), N_("Load Linux.")); -+ cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, -+ N_("FILE"), 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/efi/api.h b/include/grub/efi/api.h -index 464842ba3705..66d20742b1fd 100644 ---- a/include/grub/efi/api.h -+++ b/include/grub/efi/api.h -@@ -2129,7 +2129,7 @@ typedef struct grub_efi_memory_attribute_protocol grub_efi_memory_attribute_prot - - #if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \ - || defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \ -- || defined(__riscv) -+ || defined(__riscv) || defined (__loongarch64) - - #define efi_call_0(func) func() - #define efi_call_1(func, a) func(a) -diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h -index 34825c4adc7f..789e0112b14a 100644 ---- a/include/grub/efi/efi.h -+++ b/include/grub/efi/efi.h -@@ -140,13 +140,17 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd, - char **device, - char **path); - --#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) -+#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) || defined(__loongarch__) - void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void); - grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *); - #include - grub_err_t grub_arch_efi_linux_check_image(struct linux_arch_kernel_header *lh); -+#if defined(__loongarch__) -+grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size, char *args); -+#else - grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, char *args); - #endif -+#endif - - grub_addr_t grub_efi_section_addr (const char *section); - -diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h -index 2a5e1ee003ed..f279d1dce0a5 100644 ---- a/include/grub/efi/pe32.h -+++ b/include/grub/efi/pe32.h -@@ -102,6 +102,8 @@ struct grub_pe32_coff_header - #define GRUB_PE32_MACHINE_ARM64 0xAA64 - #define GRUB_PE32_MACHINE_RISCV32 0x5032 - #define GRUB_PE32_MACHINE_RISCV64 0x5064 -+#define GRUB_PE32_MACHINE_LOONGARCH32 0x6232 -+#define GRUB_PE32_MACHINE_LOONGARCH64 0x6264 - - #define GRUB_PE32_RELOCS_STRIPPED 0x0001 - #define GRUB_PE32_EXECUTABLE_IMAGE 0x0002 -@@ -362,6 +364,8 @@ struct grub_pe32_fixup_block - #define GRUB_PE32_REL_BASED_ARM_MOV32T 7 - #define GRUB_PE32_REL_BASED_RISCV_LOW12I 7 - #define GRUB_PE32_REL_BASED_RISCV_LOW12S 8 -+#define GRUB_PE32_REL_BASED_LOONGARCH32_MARK_LA 8 -+#define GRUB_PE32_REL_BASED_LOONGARCH64_MARK_LA 8 - #define GRUB_PE32_REL_BASED_IA64_IMM64 9 - #define GRUB_PE32_REL_BASED_DIR64 10 - #define GRUB_PE32_REL_BASED_HIGH3ADJ 11 -diff --git a/include/grub/elf.h b/include/grub/elf.h -index c478933ee82f..73175bda02ac 100644 ---- a/include/grub/elf.h -+++ b/include/grub/elf.h -@@ -248,6 +248,7 @@ typedef struct - #define EM_NUM 95 - #define EM_AARCH64 183 /* ARM 64-bit architecture */ - #define EM_RISCV 243 /* RISC-V */ -+#define EM_LOONGARCH 258 /* LoongArch */ - - /* If it is necessary to assign new unofficial EM_* values, please - pick large random numbers (0x8523, 0xa7f2, etc.) to minimize the -@@ -2531,6 +2532,35 @@ typedef Elf32_Addr Elf32_Conflict; - #define R_RISCV_SET32 56 - #define R_RISCV_32_PCREL 57 - -+/* LoongArch relocations */ -+#define R_LARCH_NONE 0 -+#define R_LARCH_64 2 -+#define R_LARCH_MARK_LA 20 -+#define R_LARCH_SOP_PUSH_PCREL 22 -+#define R_LARCH_SOP_PUSH_ABSOLUTE 23 -+#define R_LARCH_SOP_PUSH_PLT_PCREL 29 -+#define R_LARCH_SOP_SUB 32 -+#define R_LARCH_SOP_SL 33 -+#define R_LARCH_SOP_SR 34 -+#define R_LARCH_SOP_ADD 35 -+#define R_LARCH_SOP_AND 36 -+#define R_LARCH_SOP_IF_ELSE 37 -+#define R_LARCH_SOP_POP_32_S_10_5 38 -+#define R_LARCH_SOP_POP_32_U_10_12 39 -+#define R_LARCH_SOP_POP_32_S_10_12 40 -+#define R_LARCH_SOP_POP_32_S_10_16 41 -+#define R_LARCH_SOP_POP_32_S_10_16_S2 42 -+#define R_LARCH_SOP_POP_32_S_5_20 43 -+#define R_LARCH_SOP_POP_32_S_0_5_10_16_S2 44 -+#define R_LARCH_SOP_POP_32_S_0_10_10_16_S2 45 -+#define R_LARCH_B26 66 -+#define R_LARCH_ABS_HI20 67 -+#define R_LARCH_ABS_LO12 68 -+#define R_LARCH_ABS64_LO20 69 -+#define R_LARCH_ABS64_HI12 70 -+#define R_LARCH_PCALA_HI20 71 -+#define R_LARCH_PCALA_LO12 72 -+ - #ifdef GRUB_TARGET_WORDSIZE - #if GRUB_TARGET_WORDSIZE == 32 - -diff --git a/include/grub/fdt.h b/include/grub/fdt.h -index 3514aa4a5b64..ba2f9a95c03e 100644 ---- a/include/grub/fdt.h -+++ b/include/grub/fdt.h -@@ -20,7 +20,7 @@ - #define GRUB_FDT_HEADER 1 - - #if !defined(GRUB_MACHINE_EMU) && \ -- (defined(__arm__) || defined(__aarch64__) || defined(__riscv)) -+ (defined(__arm__) || defined(__aarch64__) || defined(__riscv) || defined(__loongarch__)) - - #include - #include -@@ -148,6 +148,6 @@ int EXPORT_FUNC(grub_fdt_set_prop) (void *fdt, unsigned int nodeoffset, const ch - }) - - #endif /* !defined(GRUB_MACHINE_EMU) && \ -- (defined(__arm__) || defined(__aarch64__) || defined(__riscv)) */ -+ (defined(__arm__) || defined(__aarch64__) || defined(__riscv) || defined(__loongarch__)) */ - - #endif /* ! GRUB_FDT_HEADER */ -diff --git a/include/grub/loongarch64/efi/loader.h b/include/grub/loongarch64/efi/loader.h -new file mode 100644 -index 000000000000..71a0159771f6 ---- /dev/null -+++ b/include/grub/loongarch64/efi/loader.h -@@ -0,0 +1,25 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2003,2004,2006,2007,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_LOADER_MACHINE_HEADER -+#define GRUB_LOADER_MACHINE_HEADER 1 -+ -+#include -+#include -+ -+#endif /* ! GRUB_LOADER_MACHINE_HEADER */ -diff --git a/include/grub/loongarch64/efi/memory.h b/include/grub/loongarch64/efi/memory.h -new file mode 100644 -index 000000000000..2d3f36eb4f57 ---- /dev/null -+++ b/include/grub/loongarch64/efi/memory.h -@@ -0,0 +1,15 @@ -+#ifndef GRUB_MEMORY_CPU_HEADER -+#include -+ -+ -+static inline grub_uint64_t grub_efi_max_usable_address(void) -+{ -+ grub_uint64_t addr; -+ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); -+ return addr |= 0xffffffffffUL; -+} -+ -+#define GRUB_EFI_MAX_USABLE_ADDRESS (grub_efi_max_usable_address()) -+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS -+ -+#endif /* ! GRUB_MEMORY_CPU_HEADER */ -diff --git a/include/grub/loongarch64/efi/time.h b/include/grub/loongarch64/efi/time.h -new file mode 100644 -index 000000000000..e69de29bb2d1 -diff --git a/include/grub/loongarch64/io.h b/include/grub/loongarch64/io.h -new file mode 100644 -index 000000000000..5f341037a986 ---- /dev/null -+++ b/include/grub/loongarch64/io.h -@@ -0,0 +1,62 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2009,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_IO_H -+#define GRUB_IO_H 1 -+ -+#include -+ -+typedef grub_addr_t grub_port_t; -+ -+static __inline unsigned char -+grub_inb (grub_port_t port) -+{ -+ return *(volatile grub_uint8_t *) port; -+} -+ -+static __inline unsigned short int -+grub_inw (grub_port_t port) -+{ -+ return *(volatile grub_uint16_t *) port; -+} -+ -+static __inline unsigned int -+grub_inl (grub_port_t port) -+{ -+ return *(volatile grub_uint32_t *) port; -+} -+ -+static __inline void -+grub_outb (unsigned char value, grub_port_t port) -+{ -+ *(volatile grub_uint8_t *) port = value; -+} -+ -+static __inline void -+grub_outw (unsigned short int value, grub_port_t port) -+{ -+ *(volatile grub_uint16_t *) port = value; -+} -+ -+static __inline void -+grub_outl (unsigned int value, grub_port_t port) -+{ -+ *(volatile grub_uint32_t *) port = value; -+} -+ -+#endif /* _SYS_IO_H */ -diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h -new file mode 100644 -index 000000000000..af1f51dd7676 ---- /dev/null -+++ b/include/grub/loongarch64/linux.h -@@ -0,0 +1,144 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2021 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_LOONGARCH64_LINUX_HEADER -+#define GRUB_LOONGARCH64_LINUX_HEADER 1 -+ -+#include -+ -+/* LoongArch linux kernel type */ -+#define GRUB_LOONGARCH_LINUX_BAD 0 -+#define GRUB_LOONGARCH_LINUX_ELF 1 -+#define GRUB_LOONGARCH_LINUX_EFI 2 -+ -+#define GRUB_LOONGSON3_BOOT_MEM_MAP_MAX 128 -+ -+#define GRUB_LINUX_LOONGARCH_MAGIC_SIGNATURE 0x6E6F73676E6F6F4C /* 'Loongson' */ -+#define linux_arch_kernel_header linux_loongarch64_kernel_header -+ -+/* From linux/Documentation/loongarch/booting.txt -+ * -+ * 0-1: MZ -+ * 0x28: LoongArch\0 -+ * 0x3c: PE/COFF头偏移 -+ * 0x20e:内核版本号偏移-512 -+ * riscv的version字段在0x20偏移处,现在LoongArch没有使用,是0 -+ */ -+struct linux_loongarch64_kernel_header -+{ -+ grub_uint32_t code0; /* Executable code */ -+ grub_uint32_t code1; /* Executable code */ -+ grub_uint64_t text_offset; /* Image load offset */ -+ grub_uint64_t res0; /* reserved */ -+ grub_uint64_t res1; /* reserved */ -+ grub_uint64_t res2; /* reserved */ -+ grub_uint64_t magic; /* Magic number, little endian, "Loongson" */ -+ grub_uint64_t res3; /* reserved */ -+ grub_uint32_t res4; /* reserved */ -+ grub_uint32_t hdr_offset; /* Offset of PE/COFF header */ -+}; -+ -+struct linux_loongarch64_kernel_params -+{ -+ grub_addr_t kernel_addr; /* kernel entry address */ -+ grub_size_t kernel_size; /* kernel size */ -+ grub_addr_t ramdisk_addr; /* initrd load address */ -+ grub_size_t ramdisk_size; /* initrd size */ -+ int linux_argc; /* cmdline parameters number*/ -+ grub_addr_t linux_argv; /* cmdline parameters address*/ -+ void* linux_args; -+ void* fdt; -+}; -+ -+#include -+#include -+ -+#define GRUB_EFI_MAX_PHY_ADDRESS 0xffffffffffffULL -+#define ELF32_LOADMASK (0xf0000000UL) -+#define ELF64_LOADMASK (0xf000000000000000ULL) -+#define FLAGS_EFI_SUPPORT_BIT 0 -+ -+#define FDT_ADDR_CELLS_STRING "#address-cells" -+#define FDT_SIZE_CELLS_STRING "#size-cells" -+#define FDT_ADDR_SIZE_EXTRA ((2 * grub_fdt_prop_entry_size (sizeof(grub_uint32_t))) + \ -+ sizeof (FDT_ADDR_CELLS_STRING) + \ -+ sizeof (FDT_SIZE_CELLS_STRING)) -+ -+/* From arch/loongarch/include/asm/mach-loongson64/boot_param.h */ -+struct _extention_list_hdr { -+ grub_uint64_t signature; -+ grub_uint32_t length; -+ grub_uint8_t revision; -+ grub_uint8_t checksum; -+ union { -+ struct _extention_list_hdr *next; -+ grub_uint64_t next_offset; -+ }; -+ -+} GRUB_PACKED; -+ -+struct boot_params_interface { -+ grub_uint64_t signature; /* {"B", "P", "I", "0", "1", ... } */ -+ grub_efi_system_table_t *systemtable; -+ union { -+ struct _extention_list_hdr *extlist; -+ grub_uint64_t extlist_offset; -+ }; -+ grub_uint64_t flags; -+}GRUB_PACKED; -+ -+struct loongsonlist_mem_map { -+ struct _extention_list_hdr header; /* {"M", "E", "M"} */ -+ grub_uint8_t map_count; -+ struct memmap { -+ grub_uint32_t mem_type; -+ grub_uint64_t mem_start; -+ grub_uint64_t mem_size; -+ } GRUB_PACKED map[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; -+}GRUB_PACKED; -+ -+grub_err_t -+finalize_efi_params_linux (struct linux_loongarch64_kernel_params *kernel_params); -+ -+grub_err_t -+grub_linux_loongarch_elf_linux_boot_image (struct linux_loongarch64_kernel_params -+ *kernel_params); -+ -+void* -+grub_linux_loongarch_alloc_virtual_mem_addr (grub_addr_t addr, -+ grub_size_t size, -+ grub_err_t *err); -+ -+void* -+grub_linux_loongarch_alloc_virtual_mem_align (grub_size_t size, -+ grub_size_t align, -+ grub_err_t *err); -+ -+void -+grub_linux_loongarch_elf_relocator_unload (void); -+ -+int -+grub_linux_loongarch_elf_get_boot_params (struct boot_params_interface **boot_params); -+ -+grub_err_t -+grub_linux_loongarch_elf_boot_params (struct boot_params_interface *boot_params); -+ -+grub_err_t -+grub_linux_loongarch_elf_load_kernel (grub_elf_t elf, const char *filename); -+ -+#endif /* ! GRUB_LOONGARCH64_LINUX_HEADER */ -diff --git a/include/grub/loongarch64/loongarch64.h b/include/grub/loongarch64/loongarch64.h -new file mode 100644 -index 000000000000..ea3be3d788de ---- /dev/null -+++ b/include/grub/loongarch64/loongarch64.h -@@ -0,0 +1,30 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2010,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_REGISTERS_CPU_HEADER -+#define GRUB_REGISTERS_CPU_HEADER 1 -+ -+#ifdef ASM_FILE -+#define GRUB_CPU_REGISTER_WRAP(x) x -+#else -+#define GRUB_CPU_REGISTER_WRAP(x) #x -+#endif -+ -+#define GRUB_CPU_LOONGARCH_COP0_TIMER_COUNT GRUB_CPU_REGISTER_WRAP(9) -+ -+#endif -diff --git a/include/grub/loongarch64/memory.h b/include/grub/loongarch64/memory.h -new file mode 100644 -index 000000000000..cc9faefc1d9d ---- /dev/null -+++ b/include/grub/loongarch64/memory.h -@@ -0,0 +1,59 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_MEMORY_CPU_HEADER -+#define GRUB_MEMORY_CPU_HEADER 1 -+ -+#ifndef ASM_FILE -+#include -+#include -+#include -+#endif -+ -+#ifndef ASM_FILE -+ -+typedef grub_addr_t grub_phys_addr_t; -+ -+static inline grub_phys_addr_t -+grub_vtop (void *a) -+{ -+ if (-1 == ((grub_int64_t) a >> 32)) -+ return ((grub_phys_addr_t) a) & 0x1fffffffUL; -+ return ((grub_phys_addr_t) a) & 0xffffffffffffUL; -+} -+ -+static inline void * -+grub_map_memory (grub_phys_addr_t a, grub_size_t size) -+{ -+ grub_uint64_t addr; -+ asm volatile ("csrrd %0, 0x181" : "=r" (addr)); -+ if (addr & 0x1) -+ return (void *) (a | (addr & 0xffffffffffffff00UL)); -+ else -+ return (void *) a; -+} -+ -+static inline void -+grub_unmap_memory (void *a __attribute__ ((unused)), -+ grub_size_t size __attribute__ ((unused))) -+{ -+} -+ -+#endif -+ -+#endif -diff --git a/include/grub/loongarch64/reloc.h b/include/grub/loongarch64/reloc.h -new file mode 100644 -index 000000000000..2106ba22cd48 ---- /dev/null -+++ b/include/grub/loongarch64/reloc.h -@@ -0,0 +1,113 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_LOONGARCH64_RELOC_H -+#define GRUB_LOONGARCH64_RELOC_H 1 -+#include -+ -+#define LOONGARCH64_STACK_MAX 16 -+ -+struct grub_loongarch64_stack -+{ -+ grub_uint64_t data[LOONGARCH64_STACK_MAX]; -+ int count; -+ int top; -+}; -+ -+typedef struct grub_loongarch64_stack* grub_loongarch64_stack_t; -+ -+void grub_loongarch64_stack_init (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_push (grub_loongarch64_stack_t stack, -+ grub_int64_t offset); -+void grub_loongarch64_sop_sub (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_sl (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_sr (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_add (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_and (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_if_else (grub_loongarch64_stack_t stack); -+void grub_loongarch64_sop_32_s_10_5 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_u_10_12 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_s_10_12 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_s_10_16 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_s_10_16_s2 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_s_5_20 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_s_0_5_10_16_s2 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+void grub_loongarch64_sop_32_s_0_10_10_16_s2 (grub_loongarch64_stack_t stack, -+ grub_uint64_t *place); -+ -+void grub_loongarch64_b26 (grub_uint32_t *place, grub_int64_t offset); -+void grub_loongarch64_xxx_hi20 (grub_uint32_t *place, grub_int64_t offset); -+void grub_loongarch64_xxx_lo12 (grub_uint32_t *place, grub_int64_t offset); -+void grub_loongarch64_xxx64_hi12 (grub_uint32_t *place, grub_int64_t offset); -+void grub_loongarch64_xxx64_lo20 (grub_uint32_t *place, grub_int64_t offset); -+ -+#define GRUB_LOONGARCH64_RELOCATION(STACK, PLACE, OFFSET) \ -+ case R_LARCH_SOP_PUSH_ABSOLUTE: \ -+ grub_loongarch64_sop_push (STACK, OFFSET); \ -+ break; \ -+ case R_LARCH_SOP_SUB: \ -+ grub_loongarch64_sop_sub (STACK); \ -+ break; \ -+ case R_LARCH_SOP_SL: \ -+ grub_loongarch64_sop_sl (STACK); \ -+ break; \ -+ case R_LARCH_SOP_SR: \ -+ grub_loongarch64_sop_sr (STACK); \ -+ break; \ -+ case R_LARCH_SOP_ADD: \ -+ grub_loongarch64_sop_add (STACK); \ -+ break; \ -+ case R_LARCH_SOP_AND: \ -+ grub_loongarch64_sop_and (STACK); \ -+ break; \ -+ case R_LARCH_SOP_IF_ELSE: \ -+ grub_loongarch64_sop_if_else (STACK); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_10_5: \ -+ grub_loongarch64_sop_32_s_10_5 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_U_10_12: \ -+ grub_loongarch64_sop_32_u_10_12 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_10_12: \ -+ grub_loongarch64_sop_32_s_10_12 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_10_16: \ -+ grub_loongarch64_sop_32_s_10_16 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_10_16_S2: \ -+ grub_loongarch64_sop_32_s_10_16_s2 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_5_20: \ -+ grub_loongarch64_sop_32_s_5_20 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: \ -+ grub_loongarch64_sop_32_s_0_5_10_16_s2 (STACK, PLACE); \ -+ break; \ -+ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: \ -+ grub_loongarch64_sop_32_s_0_10_10_16_s2 (STACK, PLACE); \ -+ break; -+ -+#endif /* GRUB_LOONGARCH64_RELOC_H */ -diff --git a/include/grub/loongarch64/relocator.h b/include/grub/loongarch64/relocator.h -new file mode 100644 -index 000000000000..cef3aaaf77ba ---- /dev/null -+++ b/include/grub/loongarch64/relocator.h -@@ -0,0 +1,38 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2022 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_RELOCATOR_CPU_HEADER -+#define GRUB_RELOCATOR_CPU_HEADER 1 -+ -+#include -+#include -+#include -+ -+struct grub_relocator64_state -+{ -+ /* gpr[0] is ignored since it's hardwired to 0. */ -+ grub_uint64_t gpr[32]; -+ /* Register holding target $pc. */ -+ int jumpreg; -+}; -+ -+grub_err_t -+grub_relocator64_boot (struct grub_relocator *rel, -+ struct grub_relocator64_state state); -+ -+#endif /* ! GRUB_RELOCATOR_CPU_HEADER */ -diff --git a/include/grub/loongarch64/setjmp.h b/include/grub/loongarch64/setjmp.h -new file mode 100644 -index 000000000000..d9a0776b6a71 ---- /dev/null -+++ b/include/grub/loongarch64/setjmp.h -@@ -0,0 +1,27 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2004,2006,2007,2009,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_SETJMP_CPU_HEADER -+#define GRUB_SETJMP_CPU_HEADER 1 -+ -+typedef grub_uint64_t grub_jmp_buf[12]; -+ -+int grub_setjmp (grub_jmp_buf env) RETURNS_TWICE; -+void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); -+ -+#endif /* ! GRUB_SETJMP_CPU_HEADER */ -diff --git a/include/grub/loongarch64/time.h b/include/grub/loongarch64/time.h -new file mode 100644 -index 000000000000..c9a7334887e2 ---- /dev/null -+++ b/include/grub/loongarch64/time.h -@@ -0,0 +1,39 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2003,2004,2005,2007,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef KERNEL_CPU_TIME_HEADER -+#define KERNEL_CPU_TIME_HEADER 1 -+ -+#ifndef GRUB_UTIL -+ -+#define GRUB_TICKS_PER_SECOND (grub_arch_cpuclock / 2) -+ -+void grub_timer_init (grub_uint32_t cpuclock); -+ -+/* Return the real time in ticks. */ -+grub_uint64_t grub_get_rtc (void); -+ -+extern grub_uint32_t grub_arch_cpuclock; -+#endif -+ -+static inline void -+grub_cpu_idle(void) -+{ -+} -+ -+#endif -diff --git a/include/grub/loongarch64/types.h b/include/grub/loongarch64/types.h -new file mode 100644 -index 000000000000..2dbefbf603c2 ---- /dev/null -+++ b/include/grub/loongarch64/types.h -@@ -0,0 +1,34 @@ -+/* -+ * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2006,2007,2009,2017 Free Software Foundation, Inc. -+ * -+ * GRUB is free software: you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation, either version 3 of the License, or -+ * (at your option) any later version. -+ * -+ * GRUB is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with GRUB. If not, see . -+ */ -+ -+#ifndef GRUB_TYPES_CPU_HEADER -+#define GRUB_TYPES_CPU_HEADER 1 -+ -+/* The size of void *. */ -+#define GRUB_TARGET_SIZEOF_VOID_P 8 -+ -+/* The size of long. */ -+#define GRUB_TARGET_SIZEOF_LONG 8 -+ -+#ifdef GRUB_CPU_LOONGARCH -+/* loongarch is little-endian. */ -+#undef GRUB_TARGET_WORDS_BIGENDIAN -+ -+#endif /* ! GRUB_TYPES_CPU_HEADER */ -+ -+#endif -diff --git a/include/grub/util/install.h b/include/grub/util/install.h -index 51f3b13ac130..a728afc9b15b 100644 ---- a/include/grub/util/install.h -+++ b/include/grub/util/install.h -@@ -114,6 +114,7 @@ enum grub_install_plat - GRUB_INSTALL_PLATFORM_ARM_COREBOOT, - GRUB_INSTALL_PLATFORM_RISCV32_EFI, - GRUB_INSTALL_PLATFORM_RISCV64_EFI, -+ GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI, - GRUB_INSTALL_PLATFORM_MAX - }; - -diff --git a/util/grub-install-common.c b/util/grub-install-common.c -index 2d9693ffeb7b..19bd44515ebe 100644 ---- a/util/grub-install-common.c -+++ b/util/grub-install-common.c -@@ -932,6 +932,7 @@ static struct - [GRUB_INSTALL_PLATFORM_ARM_COREBOOT] = { "arm", "coreboot" }, - [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32", "efi" }, - [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64", "efi" }, -+ [GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI] = { "loongarch64", "efi" }, - }; - - char * -diff --git a/util/grub-install.c b/util/grub-install.c -index 5babc7af5518..c8f15df5917d 100644 ---- a/util/grub-install.c -+++ b/util/grub-install.c -@@ -332,6 +332,8 @@ get_default_platform (void) - #else - return NULL; - #endif -+#elif defined (__loongarch64) -+ return "loongarch64-efi"; - #else - return NULL; - #endif -@@ -487,6 +489,7 @@ have_bootdev (enum grub_install_plat pl) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_I386_IEEE1275: - case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: - case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275: -@@ -906,6 +909,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_I386_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - case GRUB_INSTALL_PLATFORM_X86_64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - is_efi = 1; - grub_util_error (_("this utility cannot be used for EFI platforms" - " because it does not support UEFI Secure Boot")); -@@ -933,6 +937,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - case GRUB_INSTALL_PLATFORM_I386_IEEE1275: - case GRUB_INSTALL_PLATFORM_SPARC64_IEEE1275: -@@ -980,6 +985,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - case GRUB_INSTALL_PLATFORM_I386_IEEE1275: - case GRUB_INSTALL_PLATFORM_ARM_UBOOT: -@@ -1133,6 +1139,9 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: - efi_file = "BOOTRISCV64.EFI"; - break; -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: -+ efi_file = "BOOTLOONGARCH64.EFI"; -+ break; - default: - grub_util_error ("%s", _("You've found a bug")); - break; -@@ -1166,6 +1175,9 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: - efi_file = "grubriscv64.efi"; - break; -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: -+ efi_file = "grubloongarch64.efi"; -+ break; - default: - efi_file = "grub.efi"; - break; -@@ -1470,6 +1482,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - g = grub_util_guess_efi_drive (*curdev); - break; -@@ -1614,6 +1627,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - core_name = "core.efi"; - snprintf (mkimage_target, sizeof (mkimage_target), -@@ -1719,6 +1733,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: - case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: -@@ -1973,6 +1988,7 @@ main (int argc, char *argv[]) - case GRUB_INSTALL_PLATFORM_ARM64_EFI: - case GRUB_INSTALL_PLATFORM_RISCV32_EFI: - case GRUB_INSTALL_PLATFORM_RISCV64_EFI: -+ case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: - case GRUB_INSTALL_PLATFORM_IA64_EFI: - { - char *dst = grub_util_path_concat (2, efidir, efi_file); -diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c -index 393119486d3f..cf582a95f043 100644 ---- a/util/grub-mkimagexx.c -+++ b/util/grub-mkimagexx.c -@@ -44,6 +44,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1160,7 +1161,60 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd, - } - break; - } --#endif -+ case EM_LOONGARCH: -+ { -+ grub_int64_t pc; -+ grub_uint32_t *t32 = (grub_uint32_t *) target; -+ -+ sym_addr += addend; -+ pc = offset + target_section_addr + image_target->vaddr_offset; -+ -+ switch (ELF_R_TYPE (info)) -+ { -+ case R_LARCH_64: -+ { -+ grub_uint64_t *t64 = (grub_uint64_t *) target; -+ *t64 = grub_host_to_target64 (grub_target_to_host64 (*t64) + sym_addr); -+ } -+ break; -+ case R_LARCH_MARK_LA: -+ break; -+ case R_LARCH_B26: -+ { -+ grub_int64_t off; -+ off = sym_addr - target_section_addr - offset -+ - image_target->vaddr_offset; -+ grub_loongarch64_b26 (t32, off); -+ } -+ break; -+ case R_LARCH_ABS_HI20: -+ grub_loongarch64_xxx_hi20 (t32, sym_addr); -+ break; -+ case R_LARCH_ABS64_LO20: -+ grub_loongarch64_xxx64_lo20 (t32, sym_addr); -+ break; -+ case R_LARCH_ABS64_HI12: -+ grub_loongarch64_xxx64_hi12 (t32, sym_addr); -+ break; -+ case R_LARCH_PCALA_HI20: -+ { -+ grub_int32_t hi20; -+ hi20 = (((sym_addr + 0x800) & ~0xfffULL) - (pc & ~0xfffULL)); -+ grub_loongarch64_xxx_hi20 (t32, hi20); -+ } -+ break; -+ case R_LARCH_ABS_LO12: -+ case R_LARCH_PCALA_LO12: -+ grub_loongarch64_xxx_lo12 (t32, sym_addr); -+ break; -+ default: -+ grub_util_error (_("relocation 0x%x is not implemented yet"), -+ (unsigned int) ELF_R_TYPE (info)); -+ break; -+ } -+ break; -+ } -+#endif /* defined(MKIMAGE_ELF64) */ - #if defined(MKIMAGE_ELF32) - case EM_ARM: - { -@@ -1538,7 +1592,10 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, - - /* The spec does not mention the requirement of a Page RVA. - Here, align the address with a 4K boundary for safety. */ -- b->page_rva = (addr & ~(0x1000 - 1)); -+#ifdef GRUB_CPU_LOONGARCH64 -+ if (type) -+#endif -+ b->page_rva = (addr & ~(0x1000 - 1)); - b->block_size = sizeof (*b); - } - -@@ -1548,7 +1605,11 @@ add_fixup_entry (struct fixup_block_list **cblock, grub_uint16_t type, - - /* Add a new entry. */ - cur_index = ((b->block_size - sizeof (*b)) >> 1); -+#ifdef GRUB_CPU_LOONGARCH64 -+ entry = GRUB_PE32_FIXUP_ENTRY (type, type ? (addr - b->page_rva) : addr); -+#else - entry = GRUB_PE32_FIXUP_ENTRY (type, addr - b->page_rva); -+#endif - b->entries[cur_index] = grub_host_to_target16 (entry); - b->block_size += 2; - } -@@ -1704,7 +1765,39 @@ translate_relocation_pe (struct translate_context *ctx, - break; - } - break; -- break; -+#if defined(MKIMAGE_ELF64) -+ case EM_LOONGARCH: -+ switch (ELF_R_TYPE (info)) -+ { -+ case R_LARCH_64: -+ ctx->current_address = add_fixup_entry (&ctx->lst, -+ GRUB_PE32_REL_BASED_DIR64, addr, 0, -+ ctx->current_address, image_target); -+ break; -+ case R_LARCH_MARK_LA: -+ ctx->current_address = add_fixup_entry (&ctx->lst, -+ GRUB_PE32_REL_BASED_LOONGARCH64_MARK_LA, -+ addr, 0, ctx->current_address, image_target); -+ break; -+ /* Relative relocations do not require fixup entries. */ -+ case R_LARCH_B26: -+ case R_LARCH_ABS_HI20: -+ case R_LARCH_ABS_LO12: -+ case R_LARCH_ABS64_LO20: -+ case R_LARCH_ABS64_HI12: -+ case R_LARCH_PCALA_HI20: -+ case R_LARCH_PCALA_LO12: -+ grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x", -+ __FUNCTION__, (unsigned int) addr, -+ (unsigned int) ctx->current_address); -+ break; -+ default: -+ grub_util_error (_("relocation 0x%x is not implemented yet"), -+ (unsigned int) ELF_R_TYPE (info)); -+ break; -+ } -+ break; -+#endif /* defined(MKIMAGE_ELF64) */ - #if defined(MKIMAGE_ELF32) - case EM_ARM: - switch (ELF_R_TYPE (info)) -diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c -index 163529ca9c25..071d1c31c91f 100644 ---- a/util/grub-module-verifier.c -+++ b/util/grub-module-verifier.c -@@ -176,6 +176,21 @@ struct grub_module_verifier_arch archs[] = { - -1 - } - }, -+ { "loongarch64", 8, 0, EM_LOONGARCH, GRUB_MODULE_VERIFY_SUPPORTS_REL | GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){ -+ R_LARCH_NONE, -+ R_LARCH_64, -+ R_LARCH_MARK_LA, -+ R_LARCH_B26, -+ R_LARCH_ABS_HI20, -+ R_LARCH_ABS_LO12, -+ R_LARCH_ABS64_LO20, -+ R_LARCH_ABS64_HI12, -+ R_LARCH_PCALA_HI20, -+ R_LARCH_PCALA_LO12, -+ -1 -+ }, (int[]){ -+ -1 -+ } }, - }; - - struct platform_whitelist { -diff --git a/util/mkimage.c b/util/mkimage.c -index 8319e8dfbde4..4e09dfc29f25 100644 ---- a/util/mkimage.c -+++ b/util/mkimage.c -@@ -654,6 +654,22 @@ static const struct grub_install_image_target_desc image_targets[] = - .pe_target = GRUB_PE32_MACHINE_RISCV64, - .elf_target = EM_RISCV, - }, -+ { -+ .dirname = "loongarch64-efi", -+ .names = { "loongarch64-efi", NULL }, -+ .voidp_sizeof = 8, -+ .bigendian = 0, -+ .id = IMAGE_EFI, -+ .flags = PLATFORM_FLAGS_NONE, -+ .total_module_size = TARGET_NO_FIELD, -+ .decompressor_compressed_size = TARGET_NO_FIELD, -+ .decompressor_uncompressed_size = TARGET_NO_FIELD, -+ .decompressor_uncompressed_addr = TARGET_NO_FIELD, -+ .section_align = GRUB_PE32_SECTION_ALIGNMENT, -+ .vaddr_offset = EFI64_HEADER_SIZE, -+ .pe_target = GRUB_PE32_MACHINE_LOONGARCH64, -+ .elf_target = EM_LOONGARCH, -+ }, - }; - - #include --- -2.33.0 - diff --git a/0277-loongarch-Modify-the-location-where-initrd-is-loaded.patch b/0277-loongarch-Modify-the-location-where-initrd-is-loaded.patch deleted file mode 100644 index 11513eb147130df94715ee1d50edb0bdadcb1924..0000000000000000000000000000000000000000 --- a/0277-loongarch-Modify-the-location-where-initrd-is-loaded.patch +++ /dev/null @@ -1,82 +0,0 @@ -From 8ed39fc6429ec659afa867e79364e9436a4a8242 Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Thu, 2 Feb 2023 20:32:17 +0800 -Subject: [PATCH 2/8] loongarch: Modify the location where initrd is loaded - into memory - -Try to allocate memory from higher than 256MB to -avoid kernel relocation overlaying initrd. If failed, -allocate memory in range 0~256MB, and high address -takes precedence. - -Signed-off-by: mengyingkun ---- - grub-core/loader/loongarch64/linux-elf.c | 21 +++++++++++++++++++++ - grub-core/loader/loongarch64/linux.c | 2 +- - include/grub/loongarch64/linux.h | 5 +++++ - 3 files changed, 27 insertions(+), 1 deletion(-) - -diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c -index 85585b44f085..8260e4c26fab 100644 ---- a/grub-core/loader/loongarch64/linux-elf.c -+++ b/grub-core/loader/loongarch64/linux-elf.c -@@ -304,6 +304,27 @@ grub_linux_loongarch_alloc_virtual_mem_align (grub_size_t size, - return get_virtual_current_address (ch); - } - -+void* -+grub_linux_loongarch_alloc_initrd_mem_align (grub_size_t size, -+ grub_size_t align, -+ grub_err_t *err) -+{ -+ grub_relocator_chunk_t ch; -+ -+ /* Firstly try to allocate from memory higher than 256MB */ -+ *err = grub_relocator_alloc_chunk_align (relocator, &ch, -+ 0x10000000, (0xffffffff - size) + 1, size, align, -+ GRUB_RELOCATOR_PREFERENCE_LOW, 0); -+ if (*err != GRUB_ERR_NONE) -+ { -+ /* Failed, try to allocate in range 0 ~ 256MB */ -+ *err = grub_relocator_alloc_chunk_align (relocator, &ch, -+ 0, (0xfffffff - size) + 1, size, align, -+ GRUB_RELOCATOR_PREFERENCE_HIGH, 0); -+ } -+ return get_virtual_current_address (ch); -+} -+ - int - grub_linux_loongarch_elf_get_boot_params (struct boot_params_interface **boot_params) - { -diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c -index 783054be5100..4c0219452a76 100644 ---- a/grub-core/loader/loongarch64/linux.c -+++ b/grub-core/loader/loongarch64/linux.c -@@ -351,7 +351,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - initrd_mem = allocate_initrd_mem (initrd_pages); - } else { - grub_err_t err; -- initrd_mem = grub_linux_loongarch_alloc_virtual_mem_align (initrd_size, 0x10000, &err); -+ initrd_mem = grub_linux_loongarch_alloc_initrd_mem_align (initrd_size, 0x10000, &err); - if (err) - goto fail; - } -diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h -index af1f51dd7676..f4b198ab7ad0 100644 ---- a/include/grub/loongarch64/linux.h -+++ b/include/grub/loongarch64/linux.h -@@ -129,6 +129,11 @@ grub_linux_loongarch_alloc_virtual_mem_align (grub_size_t size, - grub_size_t align, - grub_err_t *err); - -+void* -+grub_linux_loongarch_alloc_initrd_mem_align (grub_size_t size, -+ grub_size_t align, -+ grub_err_t *err); -+ - void - grub_linux_loongarch_elf_relocator_unload (void); - --- -2.33.0 - diff --git a/0278-loongarch-Add-EFI-frame-buffer-support.patch b/0278-loongarch-Add-EFI-frame-buffer-support.patch deleted file mode 100644 index 8fee3d629b20a36e250248dc5cb0418bde806d0c..0000000000000000000000000000000000000000 --- a/0278-loongarch-Add-EFI-frame-buffer-support.patch +++ /dev/null @@ -1,337 +0,0 @@ -From e496c2969905aa69406b67ed6df063aac2b3c33e Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Wed, 8 Feb 2023 09:24:05 +0800 -Subject: [PATCH 3/8] loongarch: Add EFI frame buffer support - -Signed-off-by: yangqiming -Signed-off-by: mengyingkun ---- - grub-core/loader/loongarch64/linux-elf.c | 232 +++++++++++++++++++++++ - include/grub/loongarch64/linux.h | 47 +++++ - 2 files changed, 279 insertions(+) - -diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c -index 8260e4c26fab..852e8f4b3ee8 100644 ---- a/grub-core/loader/loongarch64/linux-elf.c -+++ b/grub-core/loader/loongarch64/linux-elf.c -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - - #define GRUB_ADDRESS_TYPE_SYSRAM 1 - #define GRUB_ADDRESS_TYPE_RESERVED 2 -@@ -34,13 +35,242 @@ - { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ - } - -+#define GRUB_EFI_LARCH_SCREEN_INFO_GUID \ -+ { 0x07fd51a6, 0x9532, 0x926f, \ -+ { 0x51, 0xdc, 0x6a, 0x63, 0x60, 0x2f, 0x84, 0xb4 } \ -+ } -+ -+#define GRUB_EFI_LARCH_CONSOLE_OUT_DEVICE_GUID \ -+ { 0xd3b36f2c, 0xd551, 0x11d4, \ -+ { 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ -+ } -+ - static struct grub_relocator *relocator; -+static grub_efi_guid_t screen_info_guid = GRUB_EFI_LARCH_SCREEN_INFO_GUID; - - void grub_linux_loongarch_elf_relocator_unload (void) - { - grub_relocator_unload (relocator); - } - -+static void -+find_bits (unsigned long mask, grub_efi_uint8_t *pos, grub_efi_uint8_t *size) -+{ -+ grub_efi_uint8_t first, len; -+ -+ first = 0; -+ len = 0; -+ -+ if (mask) -+ { -+ while (!(mask & 0x1)) -+ { -+ mask = mask >> 1; -+ first++; -+ } -+ -+ while (mask & 0x1) -+ { -+ mask = mask >> 1; -+ len++; -+ } -+ } -+ -+ *pos = first; -+ *size = len; -+} -+ -+static void -+setup_pixel_info (struct screen_info *si, grub_efi_uint32_t pixels_per_scan_line, -+ struct grub_efi_gop_pixel_bitmask pixel_info, int pixel_format) -+{ -+ if (pixel_format == GRUB_EFI_GOT_RGBA8) -+ { -+ si->lfb_depth = 32; -+ si->lfb_linelength = pixels_per_scan_line * 4; -+ si->red_size = 8; -+ si->red_pos = 0; -+ si->green_size = 8; -+ si->green_pos = 8; -+ si->blue_size = 8; -+ si->blue_pos = 16; -+ si->rsvd_size = 8; -+ si->rsvd_pos = 24; -+ } -+ else if (pixel_format == GRUB_EFI_GOT_BGRA8) -+ { -+ si->lfb_depth = 32; -+ si->lfb_linelength = pixels_per_scan_line * 4; -+ si->red_size = 8; -+ si->red_pos = 16; -+ si->green_size = 8; -+ si->green_pos = 8; -+ si->blue_size = 8; -+ si->blue_pos = 0; -+ si->rsvd_size = 8; -+ si->rsvd_pos = 24; -+ } -+ else if (pixel_format == GRUB_EFI_GOT_BITMASK) -+ { -+ find_bits(pixel_info.r, &si->red_pos, &si->red_size); -+ find_bits(pixel_info.g, &si->green_pos, &si->green_size); -+ find_bits(pixel_info.b, &si->blue_pos, &si->blue_size); -+ find_bits(pixel_info.a, &si->rsvd_pos, &si->rsvd_size); -+ si->lfb_depth = si->red_size + si->green_size + -+ si->blue_size + si->rsvd_size; -+ si->lfb_linelength = (pixels_per_scan_line * si->lfb_depth) / 8; -+ } -+ else -+ { -+ si->lfb_depth = 4; -+ si->lfb_linelength = si->lfb_width / 2; -+ si->red_size = 0; -+ si->red_pos = 0; -+ si->green_size = 0; -+ si->green_pos = 0; -+ si->blue_size = 0; -+ si->blue_pos = 0; -+ si->rsvd_size = 0; -+ si->rsvd_pos = 0; -+ } -+} -+ -+static struct screen_info * -+alloc_screen_info (void) -+{ -+ grub_efi_status_t status; -+ grub_efi_boot_services_t *b; -+ struct screen_info *si; -+ -+ b = grub_efi_system_table->boot_services; -+ status = efi_call_3 (b->allocate_pool, GRUB_EFI_RUNTIME_SERVICES_DATA, -+ sizeof(*si), (void**)&si); -+ if (status != GRUB_EFI_SUCCESS) -+ return NULL; -+ -+ status = b->install_configuration_table (&screen_info_guid, si); -+ if (status == GRUB_EFI_SUCCESS) -+ return si; -+ -+ efi_call_1 (b->free_pool, si); -+ -+ return NULL; -+} -+ -+static struct screen_info * -+setup_screen_info (void) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_handle_t gop_handle; -+ struct screen_info *si = NULL; -+ struct grub_efi_gop *gop, *first_gop; -+ grub_efi_handle_t *handles; -+ grub_efi_uintn_t num_handles, i; -+ grub_efi_guid_t graphics_output_guid = GRUB_EFI_GOP_GUID; -+ grub_efi_uint16_t width, height; -+ grub_efi_uint32_t ext_lfb_base, pixels_per_scan_line; -+ grub_efi_uint64_t fb_base; -+ struct grub_efi_gop_pixel_bitmask pixel_info; -+ grub_efi_gop_pixel_format_t pixel_format; -+ -+ si = alloc_screen_info(); -+ if (!si) -+ return NULL; -+ -+ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, -+ &graphics_output_guid, NULL, &num_handles); -+ if (!handles || num_handles == 0) -+ goto free_screen_info; -+ -+ gop = NULL; -+ first_gop = NULL; -+ -+ for (i = 0; i < num_handles; i++) -+ { -+ struct grub_efi_gop_mode *mode; -+ struct grub_efi_gop_mode_info *info = NULL; -+ grub_efi_guid_t conout_proto = GRUB_EFI_LARCH_CONSOLE_OUT_DEVICE_GUID; -+ void *dummy = NULL; -+ grub_efi_uint8_t conout_found = 0; -+ grub_efi_uint64_t current_fb_base; -+ -+ gop_handle = handles[i]; -+ gop = grub_efi_open_protocol (gop_handle, &graphics_output_guid, -+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ -+ dummy = grub_efi_open_protocol (gop_handle, &conout_proto, -+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); -+ if (dummy != NULL) -+ conout_found = 1; -+ -+ mode = gop->mode; -+ info = mode->info; -+ current_fb_base = mode->fb_base; -+ -+ if ((!first_gop || conout_found) && -+ info->pixel_format != GRUB_EFI_GOT_BLT_ONLY) -+ { -+ /* -+ * Systems that use the UEFI Console Splitter may -+ * provide multiple GOP devices, not all of which are -+ * backed by real hardware. The workaround is to search -+ * for a GOP implementing the ConOut protocol, and if -+ * one isn't found, to just fall back to the first GOP. -+ */ -+ width = info->width; -+ height = info->height; -+ pixel_format = info->pixel_format; -+ pixel_info = info->pixel_bitmask; -+ pixels_per_scan_line = info->pixels_per_scanline; -+ fb_base = current_fb_base; -+ -+ /* -+ * Once we've found a GOP supporting ConOut, -+ * don't bother looking any further. -+ */ -+ first_gop = gop; -+ if (conout_found) -+ break; -+ } -+ } -+ -+ /* Did we find any GOPs? */ -+ if (!first_gop) -+ goto free_screen_info; -+ -+ /* EFI framebuffer */ -+ si->orig_video_isVGA = GRUB_VIDEO_TYPE_EFI; -+ -+ si->lfb_width = width; -+ si->lfb_height = height; -+ si->lfb_base = fb_base; -+ grub_dprintf ("loongson", "Screen info fb base: 0x%"PRIxGRUB_UINT32_T"\n", -+ si->lfb_base); -+ -+ ext_lfb_base = (grub_uint64_t)fb_base >> 32; -+ if (ext_lfb_base) { -+ si->capabilities |= GRUB_VIDEO_CAPABILITY_64BIT_BASE; -+ si->ext_lfb_base = ext_lfb_base; -+ } -+ si->pages = 1; -+ -+ setup_pixel_info(si, pixels_per_scan_line, pixel_info, pixel_format); -+ -+ si->lfb_size = si->lfb_linelength * si->lfb_height; -+ si->capabilities |= GRUB_VIDEO_CAPABILITY_SKIP_QUIRKS; -+ -+ return si; -+ -+free_screen_info: -+ b = grub_efi_system_table->boot_services; -+ b->install_configuration_table (&screen_info_guid, NULL); -+ if (si) -+ efi_call_1 (b->free_pool, si); -+ -+ grub_dprintf ("loongson", "No screen info\n"); -+ return NULL; -+} -+ - static grub_err_t - allocate_fdt_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_params) - { -@@ -242,6 +472,8 @@ grub_linux_loongarch_elf_linux_boot_image (struct linux_loongarch64_kernel_param - struct grub_relocator64_state state; - grub_err_t err; - -+ setup_screen_info (); -+ - /* linux kernel type is ELF */ - grub_memset (&state, 0, sizeof (state)); - -diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h -index f4b198ab7ad0..c010982b99b6 100644 ---- a/include/grub/loongarch64/linux.h -+++ b/include/grub/loongarch64/linux.h -@@ -79,6 +79,53 @@ struct linux_loongarch64_kernel_params - sizeof (FDT_ADDR_CELLS_STRING) + \ - sizeof (FDT_SIZE_CELLS_STRING)) - -+/* -+ * These are set up by the setup-routine at boot-time: -+ */ -+struct screen_info { -+ grub_efi_uint8_t orig_x; /* 0x00 */ -+ grub_efi_uint8_t orig_y; /* 0x01 */ -+ grub_efi_uint16_t ext_mem_k; /* 0x02 */ -+ grub_efi_uint16_t orig_video_page; /* 0x04 */ -+ grub_efi_uint8_t orig_video_mode; /* 0x06 */ -+ grub_efi_uint8_t orig_video_cols; /* 0x07 */ -+ grub_efi_uint8_t flags; /* 0x08 */ -+ grub_efi_uint8_t unused2; /* 0x09 */ -+ grub_efi_uint16_t orig_video_ega_bx;/* 0x0a */ -+ grub_efi_uint16_t unused3; /* 0x0c */ -+ grub_efi_uint8_t orig_video_lines; /* 0x0e */ -+ grub_efi_uint8_t orig_video_isVGA; /* 0x0f */ -+ grub_efi_uint16_t orig_video_points;/* 0x10 */ -+ -+ /* VESA graphic mode -- linear frame buffer */ -+ grub_efi_uint16_t lfb_width; /* 0x12 */ -+ grub_efi_uint16_t lfb_height; /* 0x14 */ -+ grub_efi_uint16_t lfb_depth; /* 0x16 */ -+ grub_efi_uint32_t lfb_base; /* 0x18 */ -+ grub_efi_uint32_t lfb_size; /* 0x1c */ -+ grub_efi_uint16_t cl_magic, cl_offset; /* 0x20 */ -+ grub_efi_uint16_t lfb_linelength; /* 0x24 */ -+ grub_efi_uint8_t red_size; /* 0x26 */ -+ grub_efi_uint8_t red_pos; /* 0x27 */ -+ grub_efi_uint8_t green_size; /* 0x28 */ -+ grub_efi_uint8_t green_pos; /* 0x29 */ -+ grub_efi_uint8_t blue_size; /* 0x2a */ -+ grub_efi_uint8_t blue_pos; /* 0x2b */ -+ grub_efi_uint8_t rsvd_size; /* 0x2c */ -+ grub_efi_uint8_t rsvd_pos; /* 0x2d */ -+ grub_efi_uint16_t vesapm_seg; /* 0x2e */ -+ grub_efi_uint16_t vesapm_off; /* 0x30 */ -+ grub_efi_uint16_t pages; /* 0x32 */ -+ grub_efi_uint16_t vesa_attributes; /* 0x34 */ -+ grub_efi_uint32_t capabilities; /* 0x36 */ -+ grub_efi_uint32_t ext_lfb_base; /* 0x3a */ -+ grub_efi_uint8_t _reserved[2]; /* 0x3e */ -+} __attribute__((packed)); -+ -+#define GRUB_VIDEO_TYPE_EFI 0x70 -+#define GRUB_VIDEO_CAPABILITY_SKIP_QUIRKS (1 << 0) -+#define GRUB_VIDEO_CAPABILITY_64BIT_BASE (1 << 1) /* Frame buffer base is 64-bit */ -+ - /* From arch/loongarch/include/asm/mach-loongson64/boot_param.h */ - struct _extention_list_hdr { - grub_uint64_t signature; --- -2.33.0 - diff --git a/0279-loongarch-Add-support-for-v4.0-interface.patch b/0279-loongarch-Add-support-for-v4.0-interface.patch deleted file mode 100644 index 8111a11a14e1dd0a7c173fd5504b78643f7afddc..0000000000000000000000000000000000000000 --- a/0279-loongarch-Add-support-for-v4.0-interface.patch +++ /dev/null @@ -1,434 +0,0 @@ -From 7883d8fafd9bbf3e2d7c2c01f0b314c25c6d60ea Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Mon, 13 Feb 2023 14:40:16 +0800 -Subject: [PATCH 4/8] loongarch: Add support for v4.0 interface - -This patch adds support for parameter passing converntion -between bootloader and kernel, defined in the document -"loongson devsys firmware kernel interface specification v4.0" - -Signed-off-by: yangqiming -Signed-off-by: mengyingkun ---- - grub-core/lib/loongarch64/relocator.c | 2 +- - grub-core/loader/loongarch64/linux-elf.c | 177 ++++++++++++++++++++--- - grub-core/loader/loongarch64/linux.c | 49 ++----- - include/grub/loongarch64/linux.h | 20 +++ - 4 files changed, 190 insertions(+), 58 deletions(-) - -diff --git a/grub-core/lib/loongarch64/relocator.c b/grub-core/lib/loongarch64/relocator.c -index faa4553a5232..587fc585ab7a 100644 ---- a/grub-core/lib/loongarch64/relocator.c -+++ b/grub-core/lib/loongarch64/relocator.c -@@ -122,7 +122,7 @@ grub_relocator64_boot (struct grub_relocator *rel, - unsigned i; - grub_addr_t vtarget; - -- err = grub_relocator_alloc_chunk_align (rel, &ch, 0, -+ err = grub_relocator_alloc_chunk_align (rel, &ch, 0x3000000, - (0xffffffff - stateset_size) - + 1, stateset_size, - grub_relocator_align, -diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c -index 852e8f4b3ee8..15f99849c4d1 100644 ---- a/grub-core/loader/loongarch64/linux-elf.c -+++ b/grub-core/loader/loongarch64/linux-elf.c -@@ -25,11 +25,14 @@ - #include - #include - -+#define GRUB_EFI_MMAP_NR_SLACK_SLOTS 8 -+ - #define GRUB_ADDRESS_TYPE_SYSRAM 1 - #define GRUB_ADDRESS_TYPE_RESERVED 2 - #define GRUB_ADDRESS_TYPE_ACPI 3 - #define GRUB_ADDRESS_TYPE_NVS 4 - #define GRUB_ADDRESS_TYPE_PMEM 5 -+ - #define GRUB_EFI_LOONGSON_BPI_TABLE_GUID \ - { 0x4660f721, 0x2ec5, 0x416a, \ - { 0x89, 0x9a, 0x43, 0x18, 0x02, 0x50, 0xa0, 0xc9 } \ -@@ -45,6 +48,16 @@ - { 0x9a, 0x46, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \ - } - -+#define GRUB_EFI_LARCH_BOOT_MEMMAP_GUID \ -+ { 0x800f683f, 0xd08b, 0x423a, \ -+ { 0xa2, 0x93, 0x96, 0x5c, 0x3c, 0x6f, 0xe2, 0xb4 } \ -+ } -+ -+#define GRUB_EFI_LARCH_INITRD_MEDIA_GUID \ -+ { 0x5568e427, 0x68fc, 0x4f3d, \ -+ { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \ -+ } -+ - static struct grub_relocator *relocator; - static grub_efi_guid_t screen_info_guid = GRUB_EFI_LARCH_SCREEN_INFO_GUID; - -@@ -271,6 +284,135 @@ free_screen_info: - return NULL; - } - -+static grub_err_t -+allocate_memmap_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_params) -+{ -+ grub_err_t err; -+ grub_efi_status_t status; -+ grub_efi_uintn_t mmap_size, desc_size, size; -+ grub_efi_uint32_t desc_version; -+ grub_efi_memory_descriptor_t *mmap_buf; -+ grub_efi_boot_services_t *b; -+ struct efi_boot_memmap *m, tmp; -+ struct efi_initrd *tbl = NULL; -+ grub_efi_guid_t boot_memmap_guid = GRUB_EFI_LARCH_BOOT_MEMMAP_GUID; -+ grub_efi_guid_t initrd_media_guid = GRUB_EFI_LARCH_INITRD_MEDIA_GUID; -+ -+ setup_screen_info(); -+ -+ b = grub_efi_system_table->boot_services; -+ -+ grub_dprintf ("loongson", "ramdisk_addr:0x%"PRIxGRUB_UINT64_T", \ -+ size:0x%"PRIxGRUB_UINT64_T"\n", -+ kernel_params->ramdisk_addr, -+ kernel_params->ramdisk_size); -+#if 0 -+ char string[64]; -+ -+ /* Set initrd info to cmdline*/ -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ { -+ grub_printf ( "Initrd @ %p-%p\n", -+ (void *) kernel_params->ramdisk_addr, -+ (void *) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); -+ /* initrd */ -+ grub_snprintf (string, -+ sizeof (GRUB_INITRD_STRING), -+ "initrd=0x%lx,0x%lx", -+ ((grub_uint64_t) kernel_params->ramdisk_addr & 0xffffffff), -+ (grub_uint64_t) kernel_params->ramdisk_size); -+ *(char*) ((grub_addr_t) kernel_params->linux_args + kernel_params->ramdisk_args_len - 2) = ' '; -+ grub_memcpy ((char*) ((grub_addr_t) kernel_params->linux_args + kernel_params->ramdisk_args_len - 1), -+ string, sizeof (GRUB_INITRD_STRING)); -+ } -+#else -+ /* Set initrd info to system table*/ -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ { -+ tbl = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -+ if (!tbl) -+ return grub_error (GRUB_ERR_IO, "cannot allocate tbl memory"); -+ tbl->base = kernel_params->ramdisk_addr; -+ tbl->size = kernel_params->ramdisk_size; -+ -+ status = b->install_configuration_table (&initrd_media_guid, tbl); -+ if (status != GRUB_EFI_SUCCESS) { -+ grub_error (GRUB_ERR_IO, "failed to install initrd media"); -+ goto free_tbl; -+ } -+ } -+#endif -+ -+ tmp.map_size = 0; -+ status = grub_efi_get_memory_map (&tmp.map_size, NULL, &tmp.map_key, -+ &tmp.desc_size, &tmp.desc_ver); -+ if (status != 0) { -+ grub_error (GRUB_ERR_IO, "cannot get memory map"); -+ goto uninstall_initrd_table; -+ } -+ size = tmp.map_size + tmp.desc_size * GRUB_EFI_MMAP_NR_SLACK_SLOTS; -+ m = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (sizeof(*m) + size)); -+ if (!m) { -+ grub_error (GRUB_ERR_IO, "cannot allocate m memory"); -+ goto uninstall_initrd_table; -+ } -+ -+ status = b->install_configuration_table (&boot_memmap_guid, m); -+ if (status != GRUB_EFI_SUCCESS) { -+ grub_error (GRUB_ERR_IO, "failed to install boot memmap"); -+ goto free_m; -+ } -+ -+ m->buff_size = m->map_size = size; -+ if (grub_efi_get_memory_map (&m->map_size, m->map, -+ &m->map_key, &m->desc_size, -+ &m->desc_ver) <= 0) -+ { -+ grub_error (GRUB_ERR_IO, "cannot get EFI memory map"); -+ goto uninstall_mem_table; -+ } -+ -+ mmap_size = grub_efi_find_mmap_size (); -+ if (! mmap_size) -+ goto uninstall_mem_table; -+ -+ mmap_buf = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (mmap_size)); -+ err = grub_efi_finish_boot_services (&mmap_size, mmap_buf, NULL, -+ &desc_size, &desc_version); -+ if (err) { -+ grub_error (GRUB_ERR_IO, "failed to finish boot services"); -+ goto free_map; -+ } -+ -+ return 0; -+ -+free_map: -+ if (mmap_buf) -+ grub_efi_free_pages ((grub_addr_t) mmap_buf, -+ GRUB_EFI_BYTES_TO_PAGES (mmap_size)); -+ -+uninstall_mem_table: -+ b->install_configuration_table (&boot_memmap_guid, NULL); -+ -+free_m: -+ if (m) -+ grub_efi_free_pages ((grub_addr_t) m, -+ GRUB_EFI_BYTES_TO_PAGES (sizeof(*m) + size)); -+ -+uninstall_initrd_table: -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -+ b->install_configuration_table (&initrd_media_guid, NULL); -+ -+free_tbl: -+ if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) { -+ if (tbl) -+ grub_efi_free_pages ((grub_addr_t) tbl, -+ GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -+ } -+ -+ return grub_error(GRUB_ERR_BAD_OS, "failed to V40 boot"); -+} -+ - static grub_err_t - allocate_fdt_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_params) - { -@@ -400,12 +542,11 @@ grub_linux_loongarch_elf_make_argv (struct linux_loongarch64_kernel_params *kern - } - - if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -- { -- size += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4) \ -- + ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4) \ -- + ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), -- 4); -- } -+ { -+ size += ALIGN_UP (sizeof (GRUB_RD_START_STRING), 4) -+ + ALIGN_UP (sizeof (GRUB_RD_SIZE_STRING), 4) -+ + ALIGN_UP (sizeof (GRUB_INITRD_STRING), 4); -+ } - size = ALIGN_UP (size, 8); - - /* alloc memory */ -@@ -427,33 +568,33 @@ grub_linux_loongarch_elf_make_argv (struct linux_loongarch64_kernel_params *kern - { - /* rd_start */ - grub_snprintf (linux_args, -- sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), -+ sizeof (GRUB_RD_START_STRING), - "rd_start=0x%lx", - (grub_uint64_t) kernel_params->ramdisk_addr); - *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; - linux_argv++; -- linux_args += ALIGN_UP (sizeof ("rd_start=0xXXXXXXXXXXXXXXXX"), 4); -+ linux_args += ALIGN_UP (sizeof (GRUB_RD_START_STRING), 4); - kernel_params->linux_argc++; - - /* rd_size */ - grub_snprintf (linux_args, -- sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), -+ sizeof (GRUB_RD_SIZE_STRING), - "rd_size=0x%lx", - (grub_uint64_t) kernel_params->ramdisk_size); - *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; - linux_argv++; -- linux_args += ALIGN_UP (sizeof ("rd_size=0xXXXXXXXXXXXXXXXX"), 4); -+ linux_args += ALIGN_UP (sizeof (GRUB_RD_SIZE_STRING), 4); - kernel_params->linux_argc++; - - /* initrd */ - grub_snprintf (linux_args, -- sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), -+ sizeof (GRUB_INITRD_STRING), - "initrd=0x%lx,0x%lx", - ((grub_uint64_t) kernel_params->ramdisk_addr & 0xffffffff), - (grub_uint64_t) kernel_params->ramdisk_size); - *linux_argv = (grub_uint64_t) (grub_addr_t) linux_args; - linux_argv++; -- linux_args += ALIGN_UP (sizeof ("initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX"), 4); -+ linux_args += ALIGN_UP (sizeof (GRUB_INITRD_STRING), 4); - kernel_params->linux_argc++; - } - -@@ -472,8 +613,6 @@ grub_linux_loongarch_elf_linux_boot_image (struct linux_loongarch64_kernel_param - struct grub_relocator64_state state; - grub_err_t err; - -- setup_screen_info (); -- - /* linux kernel type is ELF */ - grub_memset (&state, 0, sizeof (state)); - -@@ -481,14 +620,14 @@ grub_linux_loongarch_elf_linux_boot_image (struct linux_loongarch64_kernel_param - state.gpr[1] = kernel_params->kernel_addr; /* ra */ - if (grub_linux_loongarch_elf_get_boot_params (&boot_params) == 0) - { -- grub_printf("not find param, is fdt boot\n"); -- if (allocate_fdt_and_exit_boot (kernel_params) != GRUB_ERR_NONE) -+ grub_dprintf("loongson", "V4.0 boot\n"); -+ if (allocate_memmap_and_exit_boot (kernel_params) != GRUB_ERR_NONE) - return grub_errno; - state.gpr[4] = 1 << FLAGS_EFI_SUPPORT_BIT; /* a0 = flag */ -- state.gpr[5] = (grub_uint64_t)kernel_params->fdt; /* a1 = fdt */ -- state.gpr[6] = 0; /* a2 = flag */ -+ state.gpr[5] = (grub_uint64_t)kernel_params->linux_args; /* a1 = cmdline */ -+ state.gpr[6] = (grub_uint64_t)grub_efi_system_table; /* a2 = system_table */ - } else { -- grub_printf("find param, is bpi boot\n"); -+ grub_dprintf("loongson", "BPI boot\n"); - grub_linux_loongarch_elf_make_argv (kernel_params); - state.gpr[4] = kernel_params->linux_argc; /* a0 = argc */ - state.gpr[5] = kernel_params->linux_argv; /* a1 = args */ -diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c -index 4c0219452a76..03b7940526ee 100644 ---- a/grub-core/loader/loongarch64/linux.c -+++ b/grub-core/loader/loongarch64/linux.c -@@ -230,7 +230,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - grub_dprintf ("linux", "kernel @ %p\n", (void*) kernel_params.kernel_addr); - } - -- cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); -+ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE) -+ + sizeof (GRUB_INITRD_STRING); -+ kernel_params.ramdisk_args_len = grub_loader_cmdline_size (argc, argv) -+ + sizeof (LINUX_IMAGE); - kernel_params.linux_argc = argc; - kernel_params.linux_args = grub_malloc (cmdline_size); - if (!kernel_params.linux_args) -@@ -250,7 +253,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), - { - err = grub_create_loader_cmdline (argc, argv, - (char*) ((grub_addr_t) kernel_params.linux_args + sizeof (LINUX_IMAGE) - 1), -- cmdline_size, -+ kernel_params.ramdisk_args_len, - GRUB_VERIFY_KERNEL_CMDLINE); - if (err) - goto fail; -@@ -299,26 +302,6 @@ fail: - return grub_errno; - } - --/* -- * 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[]) -@@ -326,6 +309,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 }; - grub_size_t initrd_size; - void *initrd_mem = NULL; -+ grub_err_t err; - - if (argc == 0) - { -@@ -345,16 +329,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - initrd_size = grub_get_initrd_size (&initrd_ctx); - grub_dprintf ("linux", "Loading initrd\n"); - -- if (is_bpi_boot == 0) { -- grub_size_t initrd_pages; -- initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size)); -- initrd_mem = allocate_initrd_mem (initrd_pages); -- } else { -- grub_err_t err; -- initrd_mem = grub_linux_loongarch_alloc_initrd_mem_align (initrd_size, 0x10000, &err); -- if (err) -- goto fail; -- } -+ initrd_mem = grub_linux_loongarch_alloc_initrd_mem_align (initrd_size, 0x1000, &err); -+ if (err) -+ goto fail; - - if (!initrd_mem) - { -@@ -369,14 +346,10 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - kernel_params.ramdisk_addr = (grub_addr_t) initrd_mem; - kernel_params.ramdisk_size = initrd_size; - grub_dprintf ("linux", "ramdisk [addr=%p, size=0x%lx]\n", -- (void *) initrd_mem, initrd_size); -+ (void *) initrd_mem, initrd_size); - fail: - grub_initrd_close (&initrd_ctx); -- if (is_bpi_boot == 0) { -- if (initrd_mem && !kernel_params.ramdisk_addr) -- grub_efi_free_pages ((grub_addr_t) initrd_mem, -- GRUB_EFI_BYTES_TO_PAGES (initrd_size)); -- } -+ - return grub_errno; - } - -diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h -index c010982b99b6..f20a719b1386 100644 ---- a/include/grub/loongarch64/linux.h -+++ b/include/grub/loongarch64/linux.h -@@ -59,6 +59,7 @@ struct linux_loongarch64_kernel_params - grub_size_t kernel_size; /* kernel size */ - grub_addr_t ramdisk_addr; /* initrd load address */ - grub_size_t ramdisk_size; /* initrd size */ -+ int ramdisk_args_len; /* position of initrd in linux_args */ - int linux_argc; /* cmdline parameters number*/ - grub_addr_t linux_argv; /* cmdline parameters address*/ - void* linux_args; -@@ -73,12 +74,31 @@ struct linux_loongarch64_kernel_params - #define ELF64_LOADMASK (0xf000000000000000ULL) - #define FLAGS_EFI_SUPPORT_BIT 0 - -+/*initrd info*/ -+#define GRUB_RD_START_STRING "rd_start=0xXXXXXXXXXXXXXXXX" -+#define GRUB_RD_SIZE_STRING "rd_size=0xXXXXXXXXXXXXXXXX" -+#define GRUB_INITRD_STRING "initrd=0xXXXXXXXXXXXXXXXX,0xXXXXXXXXXXXXXXXX" -+ - #define FDT_ADDR_CELLS_STRING "#address-cells" - #define FDT_SIZE_CELLS_STRING "#size-cells" - #define FDT_ADDR_SIZE_EXTRA ((2 * grub_fdt_prop_entry_size (sizeof(grub_uint32_t))) + \ - sizeof (FDT_ADDR_CELLS_STRING) + \ - sizeof (FDT_SIZE_CELLS_STRING)) - -+struct efi_boot_memmap { -+ grub_efi_uintn_t map_size; -+ grub_efi_uintn_t desc_size; -+ grub_efi_uint32_t desc_ver; -+ grub_efi_uintn_t map_key; -+ grub_efi_uintn_t buff_size; -+ grub_efi_memory_descriptor_t map[]; -+}; -+ -+struct efi_initrd { -+ grub_efi_uintn_t base; -+ grub_efi_uintn_t size; -+}; -+ - /* - * These are set up by the setup-routine at boot-time: - */ --- -2.33.0 - diff --git a/0280-loongarch-Add-support-for-new-EFI-screen-info-GUID.patch b/0280-loongarch-Add-support-for-new-EFI-screen-info-GUID.patch deleted file mode 100644 index 8574c910e80b0ee49423efa9a620e1d86138e7fd..0000000000000000000000000000000000000000 --- a/0280-loongarch-Add-support-for-new-EFI-screen-info-GUID.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 70fd160eac36be8cb4441952a9e4cc77750bb05c Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Fri, 10 Mar 2023 11:00:51 +0800 -Subject: [PATCH 5/8] loongarch: Add support for new EFI screen info GUID - -Support new screen info GUID defined by upstream kernel, and -keep compatible with old GUID defined by loongson. - -Signed-off-by: mengyingkun ---- - grub-core/loader/loongarch64/linux-elf.c | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - -diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c -index 15f99849c4d1..86a90e76b4c3 100644 ---- a/grub-core/loader/loongarch64/linux-elf.c -+++ b/grub-core/loader/loongarch64/linux-elf.c -@@ -58,8 +58,14 @@ - { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \ - } - -+#define GRUB_EFI_SCREEN_INFO_GUID \ -+ { 0xe03fc20a, 0x85dc, 0x406e, \ -+ { 0xb9, 0x0e, 0x4a, 0xb5, 0x02, 0x37, 0x1d, 0x95 } \ -+ } -+ - static struct grub_relocator *relocator; --static grub_efi_guid_t screen_info_guid = GRUB_EFI_LARCH_SCREEN_INFO_GUID; -+static grub_efi_guid_t compat_screen_info_guid = GRUB_EFI_LARCH_SCREEN_INFO_GUID; -+static grub_efi_guid_t screen_info_guid = GRUB_EFI_SCREEN_INFO_GUID; - - void grub_linux_loongarch_elf_relocator_unload (void) - { -@@ -161,10 +167,17 @@ alloc_screen_info (void) - if (status != GRUB_EFI_SUCCESS) - return NULL; - -+ status = b->install_configuration_table (&compat_screen_info_guid, si); -+ if (status != GRUB_EFI_SUCCESS) -+ goto free_mem; -+ - status = b->install_configuration_table (&screen_info_guid, si); - if (status == GRUB_EFI_SUCCESS) - return si; - -+free_table: -+ b->install_configuration_table (&compat_screen_info_guid, NULL); -+free_mem: - efi_call_1 (b->free_pool, si); - - return NULL; -@@ -276,6 +289,7 @@ setup_screen_info (void) - - free_screen_info: - b = grub_efi_system_table->boot_services; -+ b->install_configuration_table (&compat_screen_info_guid, NULL); - b->install_configuration_table (&screen_info_guid, NULL); - if (si) - efi_call_1 (b->free_pool, si); --- -2.33.0 - diff --git a/0281-loongarch-Force-initrd-load-address-64KiB-alignment.patch b/0281-loongarch-Force-initrd-load-address-64KiB-alignment.patch deleted file mode 100644 index f62901bd6969258d6b2419fdcedd73647a1487c2..0000000000000000000000000000000000000000 --- a/0281-loongarch-Force-initrd-load-address-64KiB-alignment.patch +++ /dev/null @@ -1,26 +0,0 @@ -From d6efeb3425c32d6e24900b281e0c58403c5743a5 Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Sat, 18 Mar 2023 09:33:41 +0800 -Subject: [PATCH 6/8] loongarch: Force initrd load address 64KiB alignment - -Signed-off-by: mengyingkun ---- - grub-core/loader/loongarch64/linux.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c -index 03b7940526ee..5f1d8453b090 100644 ---- a/grub-core/loader/loongarch64/linux.c -+++ b/grub-core/loader/loongarch64/linux.c -@@ -329,7 +329,7 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), - initrd_size = grub_get_initrd_size (&initrd_ctx); - grub_dprintf ("linux", "Loading initrd\n"); - -- initrd_mem = grub_linux_loongarch_alloc_initrd_mem_align (initrd_size, 0x1000, &err); -+ initrd_mem = grub_linux_loongarch_alloc_initrd_mem_align (initrd_size, 0x10000, &err); - if (err) - goto fail; - --- -2.33.0 - diff --git a/0282-loongarch-Implement-cache-synchronization-operation.patch b/0282-loongarch-Implement-cache-synchronization-operation.patch deleted file mode 100644 index c97226844e93bc7fbe90d3f4447d35879d82979f..0000000000000000000000000000000000000000 --- a/0282-loongarch-Implement-cache-synchronization-operation.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 7b879fb103bbf09fca504db5b5fd5a52e1c0158a Mon Sep 17 00:00:00 2001 -From: mengyingkun -Date: Wed, 22 Mar 2023 09:29:42 +0800 -Subject: [PATCH 7/8] loongarch: Implement cache synchronization operation - -When the module is loaded, ICACHE and DCACHE need to flush -before calling init function. If the caches are not flushed, -loader will crash unexpectedly. - -Signed-off-by: mengyingkun ---- - grub-core/kern/loongarch64/cache.S | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/grub-core/kern/loongarch64/cache.S b/grub-core/kern/loongarch64/cache.S -index d291c6769c3c..6e32d37a9555 100644 ---- a/grub-core/kern/loongarch64/cache.S -+++ b/grub-core/kern/loongarch64/cache.S -@@ -19,6 +19,8 @@ - #include - - FUNCTION (grub_arch_sync_caches) -+ ibar 0 -+ dbar 0 - jr $ra - - FUNCTION (grub_arch_sync_dma_caches) --- -2.33.0 - diff --git a/0283-loongarch-Fix-the-initrd-parameter-passing.patch b/0283-loongarch-Fix-the-initrd-parameter-passing.patch deleted file mode 100644 index 51291fd01faea822522afca21a6e2785948a7a24..0000000000000000000000000000000000000000 --- a/0283-loongarch-Fix-the-initrd-parameter-passing.patch +++ /dev/null @@ -1,276 +0,0 @@ -From a4d6b98d10de59d9d12923d1a37b71b4703e4277 Mon Sep 17 00:00:00 2001 -From: Yingkun Meng -Date: Mon, 7 Aug 2023 11:47:54 +0800 -Subject: [PATCH 8/8] loongarch: Fix the initrd parameter passing - -When booting with EFI kernel, the kernel can't get -initrd parameter, resulting in the inability to -find the initrd. - -Change-Id: I61c6cee35853cd3ee5ce98a0bce949f6833d85b1 -Signed-off-by: Yingkun Meng ---- - grub-core/loader/loongarch64/linux-efi.c | 44 +--------------- - grub-core/loader/loongarch64/linux-elf.c | 53 +++---------------- - grub-core/loader/loongarch64/linux.c | 66 ++++++++++++++++++++++++ - include/grub/loongarch64/linux.h | 6 +++ - 4 files changed, 80 insertions(+), 89 deletions(-) - -diff --git a/grub-core/loader/loongarch64/linux-efi.c b/grub-core/loader/loongarch64/linux-efi.c -index 4dcefd9d9e27..8e2726163725 100644 ---- a/grub-core/loader/loongarch64/linux-efi.c -+++ b/grub-core/loader/loongarch64/linux-efi.c -@@ -16,11 +16,9 @@ - * along with GRUB. If not, see . - */ - #include --#include - #include - #include - #include --#include - #include - - #define GRUB_EFI_PE_MAGIC 0x5A4D -@@ -28,47 +26,7 @@ - grub_err_t - finalize_efi_params_linux (struct linux_loongarch64_kernel_params *kernel_params) - { -- int node, retval; -- -- 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 (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -- { -- grub_dprintf ("linux", "Initrd @ %p-%p\n", -- (void *) kernel_params->ramdisk_addr, -- (void *) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); -- -- retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start", -- kernel_params->ramdisk_addr); -- if (retval) -- goto failure; -- retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end", -- kernel_params->ramdisk_addr + kernel_params->ramdisk_size); -- if (retval) -- goto failure; -- } -- -- if (grub_fdt_install() != GRUB_ERR_NONE) -- goto failure; -- -- return GRUB_ERR_NONE; -- --failure: -- grub_fdt_unload(); -- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT"); -+ return grub_loongarch_setup_initrd_params(); - } - - grub_err_t -diff --git a/grub-core/loader/loongarch64/linux-elf.c b/grub-core/loader/loongarch64/linux-elf.c -index 86a90e76b4c3..28d3c90ad6e6 100644 ---- a/grub-core/loader/loongarch64/linux-elf.c -+++ b/grub-core/loader/loongarch64/linux-elf.c -@@ -308,54 +308,22 @@ allocate_memmap_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_pa - grub_efi_memory_descriptor_t *mmap_buf; - grub_efi_boot_services_t *b; - struct efi_boot_memmap *m, tmp; -- struct efi_initrd *tbl = NULL; - grub_efi_guid_t boot_memmap_guid = GRUB_EFI_LARCH_BOOT_MEMMAP_GUID; -- grub_efi_guid_t initrd_media_guid = GRUB_EFI_LARCH_INITRD_MEDIA_GUID; - - setup_screen_info(); - -- b = grub_efi_system_table->boot_services; -- - grub_dprintf ("loongson", "ramdisk_addr:0x%"PRIxGRUB_UINT64_T", \ - size:0x%"PRIxGRUB_UINT64_T"\n", - kernel_params->ramdisk_addr, - kernel_params->ramdisk_size); --#if 0 -- char string[64]; - -- /* Set initrd info to cmdline*/ -- if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -- { -- grub_printf ( "Initrd @ %p-%p\n", -- (void *) kernel_params->ramdisk_addr, -- (void *) (kernel_params->ramdisk_addr + kernel_params->ramdisk_size)); -- /* initrd */ -- grub_snprintf (string, -- sizeof (GRUB_INITRD_STRING), -- "initrd=0x%lx,0x%lx", -- ((grub_uint64_t) kernel_params->ramdisk_addr & 0xffffffff), -- (grub_uint64_t) kernel_params->ramdisk_size); -- *(char*) ((grub_addr_t) kernel_params->linux_args + kernel_params->ramdisk_args_len - 2) = ' '; -- grub_memcpy ((char*) ((grub_addr_t) kernel_params->linux_args + kernel_params->ramdisk_args_len - 1), -- string, sizeof (GRUB_INITRD_STRING)); -- } --#else - /* Set initrd info to system table*/ -- if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -- { -- tbl = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -- if (!tbl) -- return grub_error (GRUB_ERR_IO, "cannot allocate tbl memory"); -- tbl->base = kernel_params->ramdisk_addr; -- tbl->size = kernel_params->ramdisk_size; -- -- status = b->install_configuration_table (&initrd_media_guid, tbl); -- if (status != GRUB_EFI_SUCCESS) { -- grub_error (GRUB_ERR_IO, "failed to install initrd media"); -- goto free_tbl; -+ err = grub_loongarch_setup_initrd_params(); -+ if (err != GRUB_ERR_NONE) -+ { -+ grub_error(GRUB_ERR_IO, "failed to install initrd media"); -+ return err; - } -- } --#endif - - tmp.map_size = 0; - status = grub_efi_get_memory_map (&tmp.map_size, NULL, &tmp.map_key, -@@ -371,6 +339,7 @@ allocate_memmap_and_exit_boot (struct linux_loongarch64_kernel_params *kernel_pa - goto uninstall_initrd_table; - } - -+ b = grub_efi_system_table->boot_services; - status = b->install_configuration_table (&boot_memmap_guid, m); - if (status != GRUB_EFI_SUCCESS) { - grub_error (GRUB_ERR_IO, "failed to install boot memmap"); -@@ -414,15 +383,7 @@ free_m: - GRUB_EFI_BYTES_TO_PAGES (sizeof(*m) + size)); - - uninstall_initrd_table: -- if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) -- b->install_configuration_table (&initrd_media_guid, NULL); -- --free_tbl: -- if (kernel_params->ramdisk_addr && kernel_params->ramdisk_size) { -- if (tbl) -- grub_efi_free_pages ((grub_addr_t) tbl, -- GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -- } -+ grub_loongarch_remove_initrd_params(); - - return grub_error(GRUB_ERR_BAD_OS, "failed to V40 boot"); - } -diff --git a/grub-core/loader/loongarch64/linux.c b/grub-core/loader/loongarch64/linux.c -index 5f1d8453b090..0b65249e64d9 100644 ---- a/grub-core/loader/loongarch64/linux.c -+++ b/grub-core/loader/loongarch64/linux.c -@@ -29,6 +29,11 @@ GRUB_MOD_LICENSE ("GPLv3+"); - - #define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024) - -+#define GRUB_EFI_LARCH_INITRD_MEDIA_GUID \ -+ { 0x5568e427, 0x68fc, 0x4f3d, \ -+ { 0xac, 0x74, 0xca, 0x55, 0x52, 0x31, 0xcc, 0x68 } \ -+ } -+ - static struct linux_loongarch64_kernel_params kernel_params; - - static grub_addr_t phys_addr; -@@ -36,6 +41,67 @@ static grub_dl_t my_mod; - static int loaded; - static int is_bpi_boot; - static int grub_loongarch_linux_type = GRUB_LOONGARCH_LINUX_BAD; -+struct efi_initrd *initrd_tbl; -+ -+grub_err_t -+grub_loongarch_setup_initrd_params (void) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_guid_t initrd_media_guid = GRUB_EFI_LARCH_INITRD_MEDIA_GUID; -+ grub_efi_status_t status; -+ -+ if (!kernel_params.ramdisk_addr || !kernel_params.ramdisk_size) -+ { -+ grub_error (GRUB_ERR_BAD_ARGUMENT, -+ N_("you need to load the initrd first")); -+ return GRUB_ERR_BAD_ARGUMENT; -+ } -+ -+ /* Set initrd info to system table*/ -+ b = grub_efi_system_table->boot_services; -+ initrd_tbl = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -+ if (!initrd_tbl) -+ return grub_error (GRUB_ERR_IO, "cannot allocate tbl memory"); -+ -+ initrd_tbl->base = kernel_params.ramdisk_addr; -+ initrd_tbl->size = kernel_params.ramdisk_size; -+ status = b->install_configuration_table (&initrd_media_guid, initrd_tbl); -+ if (status != GRUB_EFI_SUCCESS) -+ { -+ grub_error (GRUB_ERR_IO, "failed to install initrd media"); -+ goto free_tbl; -+ } -+ -+ return GRUB_ERR_NONE; -+ -+free_tbl: -+ if (initrd_tbl) -+ { -+ grub_efi_free_pages ((grub_addr_t) initrd_tbl, -+ GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -+ } -+ -+ return GRUB_ERR_IO; -+} -+ -+void -+grub_loongarch_remove_initrd_params (void) -+{ -+ grub_efi_boot_services_t *b; -+ grub_efi_guid_t initrd_media_guid = GRUB_EFI_LARCH_INITRD_MEDIA_GUID; -+ -+ if (!initrd_tbl) -+ return; -+ -+ b = grub_efi_system_table->boot_services; -+ b->install_configuration_table (&initrd_media_guid, NULL); -+ -+ grub_efi_free_pages ((grub_addr_t) initrd_tbl, -+ GRUB_EFI_BYTES_TO_PAGES (sizeof(struct efi_initrd))); -+ -+ initrd_tbl = NULL; -+} -+ - - static grub_err_t - grub_linux_boot (void) -diff --git a/include/grub/loongarch64/linux.h b/include/grub/loongarch64/linux.h -index f20a719b1386..462ce69cabd4 100644 ---- a/include/grub/loongarch64/linux.h -+++ b/include/grub/loongarch64/linux.h -@@ -179,6 +179,12 @@ struct loongsonlist_mem_map { - } GRUB_PACKED map[GRUB_LOONGSON3_BOOT_MEM_MAP_MAX]; - }GRUB_PACKED; - -+grub_err_t -+grub_loongarch_setup_initrd_params (void); -+ -+void -+grub_loongarch_remove_initrd_params (void); -+ - grub_err_t - finalize_efi_params_linux (struct linux_loongarch64_kernel_params *kernel_params); - --- -2.33.0 - diff --git a/0284-loongarch-Disable-relaxation-relocations.patch b/0284-loongarch-Disable-relaxation-relocations.patch deleted file mode 100644 index bd7ce8dc5987cebac6e8af4ed98dad341242915b..0000000000000000000000000000000000000000 --- a/0284-loongarch-Disable-relaxation-relocations.patch +++ /dev/null @@ -1,64 +0,0 @@ -From 5cba5bf765c9fc417258f265979c6a7a795705bc Mon Sep 17 00:00:00 2001 -From: Xiaotian Wu -Date: Thu, 15 Jun 2023 20:10:38 +0800 -Subject: [PATCH] loongarch: Disable relaxation relocations - -commit 87247635c0d583cfbc1947107d23b40877d107b8 upstream. - -A working GRUB cannot be built with upcoming binutils and GCC, because linker -relaxation was added [1] causing new unsupported relocations to appear in modules. - -So we pass -mno-relax to GCC if it is supported, to disable relaxation and make -GRUB forward-compatible with new toolchains. - -While similar code already exists for sparc64 in configure.ac, sparc64 sets -LDFLAGS while LoongArch requires CFLAGS to be set. If we only set LDFLAGS on -LoongArch, GCC will still generate relaxation relocations in the .o files, so -the sparc64 code cannot be reused. - -[1] https://sourceware.org/git/?p=binutils-gdb.git;a=commit;h=56576f4a722b7398d35802ecf7d4185c27d6d69b - -Signed-off-by: Xiaotian Wu -Reviewed-by: Daniel Kiper -Signed-off-by: Yingkun Meng ---- - configure.ac | 23 +++++++++++++++++++++++ - 1 file changed, 23 insertions(+) - -diff --git a/configure.ac b/configure.ac -index dea4dfe..469e3ad 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -908,6 +908,29 @@ if test "x$target_cpu" = xloongarch64; then - TARGET_CFLAGS="$TARGET_CFLAGS -mno-explicit-relocs -fno-plt" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS -mno-explicit-relocs -fno-plt" - fi -+ -+ AC_CACHE_CHECK([for no-relax options], grub_cv_target_cc_mno_relax, [ -+ grub_cv_target_cc_mno_relax=no -+ for cand in "-mno-relax" "-Wa,-mno-relax"; do -+ if test x"$grub_cv_target_cc_mno_relax" != xno ; then -+ break -+ fi -+ CFLAGS="$TARGET_CFLAGS $cand -Werror" -+ AC_LINK_IFELSE([AC_LANG_PROGRAM([[ -+ asm (".globl start; start:"); -+ void __main (void); -+ void __main (void) {} -+ int main (void); -+ ]], [[]])], [grub_cv_target_cc_mno_relax="$cand"], []) -+ done -+ ]) -+ CFLAGS="$TARGET_CFLAGS" -+ -+ if test x"$grub_cv_target_cc_mno_relax" != xno ; then -+ TARGET_CFLAGS="$TARGET_CFLAGS $grub_cv_target_cc_mno_relax" -+ TARGET_CCASFLAGS="$TARGET_CCASFLAGS $grub_cv_target_cc_mno_relax" -+ fi -+ - TARGET_CFLAGS="$TARGET_CFLAGS -Wa,-mla-global-with-abs" - TARGET_CCASFLAGS="$TARGET_CCASFLAGS -Wa,-mla-global-with-abs" - fi --- -2.40.1 - diff --git a/1000-change-to-use-fuse3.patch b/1000-change-to-use-fuse3.patch deleted file mode 100644 index ca5d41ca4af51802e6cdd2bda504d2079865d0b2..0000000000000000000000000000000000000000 --- a/1000-change-to-use-fuse3.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 520f6df25b9643349c3a76ff197b967d3c2660c5 Mon Sep 17 00:00:00 2001 -From: Fedora Ninjas -Date: Tue, 22 Mar 2022 19:31:05 +0800 -Subject: [PATCH] change to use fuse3 - -Signed-off-by: Fedora Ninjas ---- - Makefile.util.def | 3 ++- - configure.ac | 10 +++++----- - util/grub-mount.c | 10 +++++----- - 3 files changed, 12 insertions(+), 11 deletions(-) - -diff --git a/Makefile.util.def b/Makefile.util.def -index 3f191aa..fa6e842 100644 ---- a/Makefile.util.def -+++ b/Makefile.util.def -@@ -315,11 +315,12 @@ program = { - common = grub-core/disk/host.c; - common = grub-core/osdep/init.c; - -+ cppflags = '-I/usr/include/fuse3'; - ldadd = libgrubmods.a; - ldadd = libgrubgcry.a; - ldadd = libgrubkern.a; - ldadd = grub-core/lib/gnulib/libgnu.a; -- ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM) -lfuse'; -+ ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM) -lfuse3'; - condition = COND_GRUB_MOUNT; - }; - -diff --git a/configure.ac b/configure.ac -index d04c946..878a54c 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1874,16 +1874,16 @@ if test x"$enable_grub_mount" = xno ; then - fi - - if test x"$grub_mount_excuse" = x ; then -- AC_CHECK_LIB([fuse], [fuse_main_real], [], -- [grub_mount_excuse="need FUSE library"]) -+ AC_CHECK_LIB([fuse3], [fuse_main_real], [], -+ [grub_mount_excuse="need FUSE3 library"]) - fi - - if test x"$grub_mount_excuse" = x ; then - # Check for fuse headers. - SAVED_CPPFLAGS="$CPPFLAGS" -- CPPFLAGS="$CPPFLAGS -DFUSE_USE_VERSION=26" -- AC_CHECK_HEADERS([fuse/fuse.h], [], -- [grub_mount_excuse=["need FUSE headers"]]) -+ CPPFLAGS="$CPPFLAGS -I/usr/include/fuse3 -DFUSE_USE_VERSION=30" -+ AC_CHECK_HEADERS([fuse3/fuse.h], [], -+ [grub_mount_excuse=["need FUSE3 headers"]]) - CPPFLAGS="$SAVED_CPPFLAGS" - fi - -diff --git a/util/grub-mount.c b/util/grub-mount.c -index d7be2a4..b7fd04d 100644 ---- a/util/grub-mount.c -+++ b/util/grub-mount.c -@@ -16,7 +16,7 @@ - * You should have received a copy of the GNU General Public License - * along with GRUB. If not, see . - */ --#define FUSE_USE_VERSION 26 -+#define FUSE_USE_VERSION 30 - #include - #include - #include -@@ -34,7 +34,7 @@ - #include - #include - #include --#include -+#include - - #include - #include -@@ -147,7 +147,7 @@ fuse_getattr_find_file (const char *cur_filename, - } - - static int --fuse_getattr (const char *path, struct stat *st) -+fuse_getattr (const char *path, struct stat *st, struct fuse_file_info *fi) - { - struct fuse_getattr_ctx ctx; - char *pathname, *path2; -@@ -330,13 +330,13 @@ fuse_readdir_call_fill (const char *filename, - st.st_blocks = (st.st_size + 511) >> 9; - st.st_atime = st.st_mtime = st.st_ctime - = info->mtimeset ? info->mtime : 0; -- ctx->fill (ctx->buf, filename, &st, 0); -+ ctx->fill (ctx->buf, filename, &st, 0, 0); - return 0; - } - - static int - fuse_readdir (const char *path, void *buf, -- fuse_fill_dir_t fill, off_t off, struct fuse_file_info *fi) -+ fuse_fill_dir_t fill, off_t off, struct fuse_file_info *fi, enum fuse_readdir_flags fl) - { - struct fuse_readdir_ctx ctx = { - .path = path, --- -2.34.1 - diff --git a/20-grub.install b/20-grub.install old mode 100755 new mode 100644 index 739191040221b01827743f718a46a36d74a7e304..8ae388530da12974996958e87554f00024152805 --- a/20-grub.install +++ b/20-grub.install @@ -46,7 +46,7 @@ initrd /initramfs-${kernelver}.img options ${kernelopts} grub_users \$grub_users grub_arg --unrestricted -grub_class ${ID} +grub_class kernel${flavor} EOF } @@ -62,7 +62,7 @@ case "$COMMAND" in "$KERNEL_DIR"/dtb do [[ -e "$i" ]] || continue - rm -rf "/boot/${i##*/}-${KERNEL_VERSION}" + rm -f "/boot/${i##*/}-${KERNEL_VERSION}" cp -aT "$i" "/boot/${i##*/}-${KERNEL_VERSION}" command -v restorecon &>/dev/null && \ restorecon -R "/boot/${i##*/}-${KERNEL_VERSION}" @@ -75,14 +75,6 @@ case "$COMMAND" in command -v restorecon &>/dev/null && \ restorecon "/boot/.${KERNEL_IMAGE##*/}-${KERNEL_VERSION}.hmac" fi - # symvers is symvers-.gz symlink, needs a special treatment - i="$KERNEL_DIR/symvers.gz" - if [[ -e "$i" ]]; then - rm -f "/boot/symvers-${KERNEL_VERSION}.gz" - ln -s "$i" "/boot/symvers-${KERNEL_VERSION}.gz" - command -v restorecon &>/dev/null && \ - restorecon "/boot/symvers-${KERNEL_VERSION}.gz" - fi fi if [[ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]] || [[ ! -f /sbin/new-kernel-pkg ]]; then @@ -112,12 +104,7 @@ case "$COMMAND" in LINUX="$(grep '^linux[ \t]' "${BLS_TARGET}" | sed -e 's,^linux[ \t]*,,')" INITRD="$(grep '^initrd[ \t]' "${BLS_TARGET}" | sed -e 's,^initrd[ \t]*,,')" - if [[ "$(grub2-probe --device $(grub2-probe --target=device /) --target=fs)" == "btrfs" && - "${SUSE_BTRFS_SNAPSHOT_BOOTING}" == "true" ]]; then - LINUX_RELPATH="$(grub2-mkrelpath -r /boot${LINUX})" - else - LINUX_RELPATH="$(grub2-mkrelpath /boot${LINUX})" - fi + LINUX_RELPATH="$(grub2-mkrelpath /boot${LINUX})" BOOTPREFIX="$(dirname ${LINUX_RELPATH})" ROOTPREFIX="$(dirname "/boot${LINUX}")" @@ -176,8 +163,6 @@ case "$COMMAND" in done # hmac is .vmlinuz-.hmac so needs a special treatment rm -f "/boot/.vmlinuz-${KERNEL_VERSION}.hmac" - # symvers is symvers-.gz symlink, needs a special treatment - rm -f "/boot/symvers-${KERNEL_VERSION}.gz" exit 0 fi diff --git a/99-grub-mkconfig.install b/99-grub-mkconfig.install index 0854b695160c52788b9c094385579f373f435c2e..d9686b51a22f01e8d2a3133e33373771d890543c 100755 --- a/99-grub-mkconfig.install +++ b/99-grub-mkconfig.install @@ -46,13 +46,6 @@ if [[ $RUN_MKCONFIG != "true" ]]; then exit 0 fi -if grep "crashkernel" /etc/default/grub; then - echo "crashkernel is done"; -else - grep "GRUB_CMDLINE_LINUX" /boot/grub2/grub.cfg && sed -i 's/GRUB_CMDLINE_LINUX="/GRUB_CMDLINE_LINUX="crashkernel=0M-2G:0M,2G-8G:192M,8G-128G:256M,128G-:384M /g' /etc/default/grub; - /usr/sbin/grub2-mkconfig -o /boot/grub2/grub.cfg -fi - [[ -f /etc/default/grub ]] && . /etc/default/grub COMMAND="$1" diff --git a/Fix-the-size-calculation-for-the-synthesized-initrd.patch b/Fix-the-size-calculation-for-the-synthesized-initrd.patch new file mode 100644 index 0000000000000000000000000000000000000000..9fff1a60865b28b8eae645f8d3df4a035261f0d6 --- /dev/null +++ b/Fix-the-size-calculation-for-the-synthesized-initrd.patch @@ -0,0 +1,86 @@ +From d441356c924102b43b303520cc1c62a624b014d6 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Thu, 26 Oct 2023 13:18:24 +0800 +Subject: [PATCH] Fix the size calculation for the synthesized initrd + +When calculating the size of the synthesized initrd in +grub_initrd_component(), the ending "TRAILER!!!" is counted in for every +synthesized initrd. However, in grub_initrd_load(), only one "TRAILER!!!" +will be appended for one group of consecutive synthesized initrds. The +additional size calculation for the ending "TRAILER!!!" could make the +linux kernel to read uninitialized bytes and result in the error message +like this: + +Initramfs unpacking failed: invalid magic at start of compressed archive + +To fit into the original 'newc' design, the ending "TRAILER!!!" is +removed from grub_initrd_component(). Instead, in grub_initrd_init(), +the 'newc' flag is set when calculating size of the synthesized initrd +to append the ending "TRAILER!!!" later. As for grub_initrd_load(), +since the path to the unsealed key is specified in 'newc_name', it's +unnecessary to set the 'newc' flag while copying the unsealed key +because the flag is already set when parsing the path name. + +Signed-off-by: Gary Lin +--- + grub-core/loader/linux.c | 23 ++++++++--------------- + 1 file changed, 8 insertions(+), 15 deletions(-) + +diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c +index 4e028f5..9ee8f37 100644 +--- a/grub-core/loader/linux.c ++++ b/grub-core/loader/linux.c +@@ -209,13 +209,6 @@ grub_initrd_component (const char *buf, int bufsz, const char *newc_name, + &initrd_ctx->size)) + goto overflow; + +- initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); +- if (grub_add (initrd_ctx->size, +- ALIGN_UP (sizeof (struct newc_head) +- + sizeof ("TRAILER!!!") - 1, 4), +- &initrd_ctx->size)) +- goto overflow; +- + free_dir (root); + root = 0; + return GRUB_ERR_NONE; +@@ -312,6 +305,13 @@ grub_initrd_init (int argc, char *argv[], + goto overflow; + } + ++ FOR_LIST_ELEMENTS (pk, kpuber) ++ if (pk->key && pk->path) ++ { ++ grub_initrd_component (pk->key, pk->key_len, pk->path, initrd_ctx); ++ newc = 1; ++ } ++ + if (newc) + { + initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); +@@ -324,10 +324,6 @@ grub_initrd_init (int argc, char *argv[], + root = 0; + } + +- FOR_LIST_ELEMENTS (pk, kpuber) +- if (pk->key && pk->path) +- grub_initrd_component (pk->key, pk->key_len, pk->path, initrd_ctx); +- + return GRUB_ERR_NONE; + + overflow: +@@ -404,10 +400,7 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, + + cursize = initrd_ctx->components[i].size; + if (initrd_ctx->components[i].buf) +- { +- grub_memcpy (ptr, initrd_ctx->components[i].buf, cursize); +- newc = 1; +- } ++ grub_memcpy (ptr, initrd_ctx->components[i].buf, cursize); + else if (grub_file_read (initrd_ctx->components[i].file, ptr, cursize) + != cursize) + { +-- +2.35.3 + diff --git a/add-TPCM-support-with-ipmi-channel.patch b/add-TPCM-support-with-ipmi-channel.patch new file mode 100644 index 0000000000000000000000000000000000000000..d1511d9a3aee9598b1adc9e855bfe03c3e89f9c9 --- /dev/null +++ b/add-TPCM-support-with-ipmi-channel.patch @@ -0,0 +1,773 @@ +From 2d7ef4b34427e1e1b2f55fdcc7868e7ce001a194 Mon Sep 17 00:00:00 2001 +From: "t.feng" +Date: Tue, 28 Feb 2023 16:25:30 +0800 +Subject: [PATCH] add tpcm support with ipmi channel + +t.feng(2): +add tpcm support with ipmi channel +use uefi hash interface + +zhangqiumiao(3): +reset response length when getting results failed +fix firmwarehash length and uiCmdLength error +clean code + +zhangqiumiao(4): +skip verification when just opening the grub.cfg without loading it +support control switch +modify GRUB_IPMI_TIMEOUT_MS from 7000 to 2000 + +Signed-off-by: "t.feng" +Signed-off-by: zhangqiumiao +--- + grub-core/Makefile.core.def | 6 + + grub-core/commands/efi/tpcm.c | 476 ++++++++++++++++++++++++++++++++++ + include/grub/efi/tpcm.h | 236 +++++++++++++++++ + 3 files changed, 718 insertions(+) + create mode 100644 grub-core/commands/efi/tpcm.c + create mode 100644 include/grub/efi/tpcm.h + +diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def +index 6b00eb5..ee6ff17 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -2564,6 +2564,12 @@ module = { + enable = efi; + }; + ++module = { ++ name = tpcm_kunpeng; ++ common = commands/efi/tpcm.c; ++ enable = efi; ++}; ++ + module = { + name = tr; + common = commands/tr.c; +diff --git a/grub-core/commands/efi/tpcm.c b/grub-core/commands/efi/tpcm.c +new file mode 100644 +index 0000000..57a4cea +--- /dev/null ++++ b/grub-core/commands/efi/tpcm.c +@@ -0,0 +1,476 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++#define TRANS(value) (((value << 24 ) & 0xFF000000) | \ ++ ((value << 8 ) & 0x00FF0000) | \ ++ ((value >> 8 ) & 0x0000FF00) | \ ++ ((value >> 24 ) & 0x000000FF)) ++ ++static grub_efi_guid_t gIpmiInterfaceProtocolGuid = EFI_TPCM_GUID; ++static grub_efi_guid_t hash2_service_binding_guid = GRUB_EFI_HASH2_SERVICE_BINDING_PROTOCOL_GUID; ++static grub_efi_guid_t hash2_guid = GRUB_EFI_HASH2_PROTOCOL_GUID; ++static grub_efi_guid_t sm3_guid = GRUB_HASH_ALGORITHM_SM3_GUID; ++ ++static grub_efi_ipmi_interface_protocol_t *tpcm_ipmi; ++static grub_efi_uint16_t grub_tcpm_file_type = GRUB_FILE_TYPE_NONE; ++ ++static grub_uint32_t bm_stage_base = 2000; ++static grub_efi_uint8_t permissive = 0; ++ ++static grub_efi_handle_t ++grub_efi_service_binding (grub_efi_guid_t *service_binding_guid) ++{ ++ grub_efi_service_binding_t *service; ++ grub_efi_status_t status; ++ grub_efi_handle_t child_dev = NULL; ++ grub_efi_handle_t *handles; ++ grub_efi_uintn_t num_handles; ++ ++ handles = grub_efi_locate_handle (GRUB_EFI_BY_PROTOCOL, service_binding_guid, 0, &num_handles); ++ if (!handles) ++ { ++ grub_printf ("couldn't locate service binding protocol handles\n"); ++ return NULL; ++ } ++ ++ service = grub_efi_open_protocol (handles[0], service_binding_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); ++ if (!service) ++ { ++ grub_printf ("couldn't open efi service binding protocol\n"); ++ return NULL; ++ } ++ ++ status = efi_call_2 (service->create_child, service, &child_dev); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ grub_printf ("Failed to create child device of efi service %x\n", status); ++ return NULL; ++ } ++ ++ return child_dev; ++} ++ ++static inline void ++util_dump_hex (const char *name, void *p, int bytes) ++{ ++ ++ int i = 0; ++ char *data = p; ++ int add_newline = 1; ++ grub_dprintf ("tpcm", "%s length=%d:\n", name, bytes); ++ if (bytes != 0) ++ { ++ grub_dprintf ("tpcm", "%02x ", (unsigned char)data[i]); ++ i++; ++ } ++ while (i < bytes) ++ { ++ grub_dprintf ("tpcm", "%02x ", (unsigned char)data[i]); ++ i++; ++ if (i % 16 == 0) ++ { ++ grub_dprintf("tpcm", "\n"); ++ add_newline = 0; ++ } ++ else ++ add_newline = 1; ++ } ++ if (add_newline) ++ grub_dprintf("tpcm", "\n"); ++} ++ ++static grub_efi_status_t ++grub_efi_hash (unsigned char *buf, grub_size_t size, unsigned char *content) ++{ ++ grub_efi_status_t status = GRUB_EFI_SUCCESS; ++ grub_efi_hash2_protocol_t *hash2; ++ grub_efi_handle_t hash_handle; ++ unsigned char output[DEFAULT_HASH_SIZE] = {0}; ++ grub_dprintf("tpcm", "grub_efi_hash binding service.\n"); ++ hash_handle = grub_efi_service_binding (&hash2_service_binding_guid); ++ if (!hash_handle) ++ { ++ grub_dprintf ("tpcm", "hash2 service binding failed.\n"); ++ status = GRUB_EFI_NOT_FOUND; ++ goto fail; ++ } ++ grub_dprintf("tpcm", "grub_efi_hash binding service success.\n"); ++ hash2 = grub_efi_open_protocol (hash_handle, &hash2_guid, GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL); ++ if (!hash2) ++ { ++ grub_dprintf ("tpcm", "hash2 protocol open failed.\n"); ++ status = GRUB_EFI_PROTOCOL_ERROR; ++ goto fail; ++ } ++ grub_dprintf("tpcm", "grub_efi_hash get protocol success.\n"); ++ status = hash2->hash_init(hash2, &sm3_guid); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ grub_dprintf("tpcm", "hash_init failed.\n"); ++ goto fail; ++ } ++ status = hash2->hash_update(hash2, buf, size); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ grub_dprintf("tpcm", "hash_update failed.\n"); ++ goto fail; ++ } ++ status = hash2->hash_final(hash2, output); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ grub_dprintf("tpcm", "hash_final failed.\n"); ++ goto fail; ++ } ++ util_dump_hex ("tpcm BIOS hash output: ", output, DEFAULT_HASH_SIZE); ++ grub_memcpy(content, output, DEFAULT_HASH_SIZE); ++ ++fail: ++ return status; ++} ++ ++static grub_err_t ++tpcm_ipmi_init (grub_file_t io, ++ enum grub_file_type type __attribute__ ((unused)), ++ void **context, enum grub_verify_flags *flags) ++{ ++ *context = io->name; ++ grub_tcpm_file_type = type & GRUB_FILE_TYPE_MASK; ++ *flags |= GRUB_VERIFY_FLAGS_SINGLE_CHUNK; ++ return GRUB_ERR_NONE; ++} ++ ++static grub_efi_uint8_t ++get_firmware_hash_content(unsigned char *buf, grub_size_t size, unsigned char *content) ++{ ++ grub_efi_status_t status; ++ ++ grub_dprintf ("tpcm", "grub_efi_hash:\n"); ++ status = grub_efi_hash (buf, size, content); ++ ++ return status; ++} ++ ++static grub_err_t ++grub_tpcm_set_firmware_detailtype (grub_efi_uint8_t *type) ++{ ++ switch (grub_tcpm_file_type) ++ { ++ case GRUB_FILE_TYPE_LINUX_KERNEL: ++ *type = IPMI_FW_DETAIL_KERNEL; ++ break; ++ case GRUB_FILE_TYPE_LINUX_INITRD: ++ *type = IPMI_FW_DETAIL_INITRD; ++ break; ++ case GRUB_FILE_TYPE_CONFIG: ++ *type = IPMI_FW_DETAIL_GRUB_CFG; ++ break; ++ default: ++ grub_dprintf ("tpcm", "%d is not a file type that TPCM cares about.\n", grub_tcpm_file_type); ++ grub_tcpm_file_type = GRUB_FILE_TYPE_NONE; ++ break; ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static void ++grub_tpcm_fillup_content (OEM_BMC_MEASURE_REQUSET *request_data, unsigned char *output) ++{ ++ grub_efi_uint32_t filename_len = 0; ++ switch (grub_tcpm_file_type) ++ { ++ case GRUB_FILE_TYPE_LINUX_KERNEL: ++ filename_len = grub_strlen("kernel"); ++ grub_memcpy ((grub_efi_uint8_t *)(request_data->FirmwareHashContent.uaObj), ++ "kernel", filename_len); ++ break; ++ case GRUB_FILE_TYPE_LINUX_INITRD: ++ filename_len = grub_strlen("initrd"); ++ grub_memcpy ((grub_efi_uint8_t *)(request_data->FirmwareHashContent.uaObj), ++ "initrd", filename_len); ++ break; ++ case GRUB_FILE_TYPE_CONFIG: ++ filename_len = grub_strlen("grub.cfg"); ++ grub_memcpy ((grub_efi_uint8_t *)(request_data->FirmwareHashContent.uaObj), ++ "grub.cfg", filename_len); ++ break; ++ default: ++ grub_dprintf ("tpcm", "%d is not a file type that TPCM cares about.\n", grub_tcpm_file_type); ++ break; ++ } ++ ++ request_data->FirmwareHashContent.uiCmdTag = TRANS (TPCM_TAG_REQ_COMMAND); ++ request_data->FirmwareHashContent.uiCmdLength = TRANS (sizeof (extern_simple_bmeasure_req_st)); ++ request_data->FirmwareHashContent.uiCmdCode = TRANS (TPCM_ORD_ExternSimpleBootMeasure); ++ request_data->FirmwareHashContent.uiPcr = TRANS (0); ++ ++ grub_uint32_t stage_base = bm_stage_base++; ++ request_data->FirmwareHashContent.uiStage = TRANS (stage_base); ++ ++ grub_memcpy ((grub_efi_uint8_t *)(request_data->FirmwareHashContent.uaDigest), ++ output, DEFAULT_HASH_SIZE); ++ request_data->FirmwareHashContent.uiObjLen = TRANS (filename_len); ++ ++ return; ++} ++ ++static grub_efi_status_t ++grub_tpcm_request_result (void) ++{ ++ grub_efi_status_t status = GRUB_EFI_SUCCESS; ++ grub_ipmi_cmd_header request = {IPMI_BMC_LUN, ++ IPMI_NETFN_OEM, ++ IPMI_CMD_GET_MEASURE_PARM}; ++ grub_efi_uint8_t response_length; ++ OEM_BMC_GET_RESULT_REQUSET get_result_request_data; ++ OEM_BMC_GET_RESULT_RESPONSE get_result_response_data; ++ ++ grub_efi_int16_t timeout_ms = GRUB_IPMI_TIMEOUT_MS; ++ ++ grub_memset (&get_result_request_data, 0, sizeof(get_result_request_data)); ++ grub_memset (&get_result_response_data, 0, sizeof(get_result_response_data)); ++ ++ get_result_request_data.OemSignature[0] = 0xDB; ++ get_result_request_data.OemSignature[1] = 0x07; ++ get_result_request_data.OemSignature[2] = 0x00; ++ get_result_request_data.SubCmd = IPMI_SUB_CMD_CONTROL_REQ; ++ get_result_request_data.FirmwareType = IPMI_FW_OS; ++ ++ // TODO: we should not load files expect: grub.cfg vmlinuz and initrd ++ grub_tpcm_set_firmware_detailtype (&(get_result_request_data.FirmwareDetailType)); ++ ++ while (timeout_ms > 0) ++ { ++ response_length = sizeof (OEM_BMC_GET_RESULT_RESPONSE); ++ grub_millisleep (200); ++ timeout_ms -= 200; ++ ++ grub_dprintf ("tpcm", "get result request: request_size[%lu], response_length[%d]\n", ++ sizeof(get_result_request_data), response_length); ++ ++ status = tpcm_ipmi->excute_ipmi_cmd (tpcm_ipmi, request, &get_result_request_data, ++ sizeof(get_result_request_data), &get_result_response_data, ++ &response_length, NULL); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ grub_dprintf ("tpcm", "excute_ipmi_cmd failed, request sub_cmd:%d, ret:%lu\n", ++ get_result_request_data.SubCmd, status); ++ continue; ++ } ++ ++ if (response_length == sizeof (OEM_BMC_GET_RESULT_RESPONSE) && \ ++ get_result_response_data.ControlResult != IPMI_MEASURE_UNKNOW) ++ { ++ grub_dprintf ("tpcm", "request ControlResult success, ControlResult:%d\n", ++ get_result_response_data.ControlResult); ++ break; ++ } ++ } ++ ++ if (get_result_response_data.ControlResult == IPMI_MEASURE_SUCCESS) ++ { ++ return GRUB_EFI_SUCCESS; ++ } ++ else if (timeout_ms <= 0) ++ { ++ grub_dprintf ("tpcm", "request TPCM constrol result timout"); ++ return GRUB_EFI_TIMEOUT; ++ } ++ ++ return GRUB_EFI_UNSUPPORTED; ++} ++ ++static grub_err_t ++grub_tpcm_log_event (unsigned char *buf, grub_size_t size, const char *description) ++{ ++ grub_err_t err = GRUB_ERR_NONE; ++ grub_efi_status_t status = GRUB_EFI_SUCCESS; ++ grub_ipmi_cmd_header request = {IPMI_BMC_LUN, ++ IPMI_NETFN_OEM, ++ IPMI_CMD_GET_MEASURE_PARM}; ++ OEM_BMC_MEASURE_REQUSET *request_data = NULL; ++ OEM_BMC_MEASURE_RESPONSE response_data; ++ ++ unsigned char output[DEFAULT_HASH_SIZE] = {0}; ++ grub_efi_uint8_t response_length = sizeof (OEM_BMC_MEASURE_RESPONSE); ++ ++ grub_memset (&response_data, 0, sizeof (response_data)); ++ ++ request_data = grub_calloc (1, sizeof (OEM_BMC_MEASURE_REQUSET)); ++ if (!request_data) ++ { ++ grub_dprintf ("tpcm", "malloc request_data failed.\n"); ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, "out of memory"); ++ return grub_errno; ++ } ++ ++ request_data->OemSignature[0] = 0xDB; ++ request_data->OemSignature[1] = 0x07; ++ request_data->OemSignature[2] = 0x00; ++ request_data->SubCmd = IPMI_SUB_CMD_MEASURE_REQ; ++ request_data->FirmwareType = IPMI_FW_OS; ++ request_data->FirmwareHashAlgoType = IPMI_FW_HASH_SM3; ++ ++ grub_tpcm_set_firmware_detailtype (&(request_data->FirmwareDetailType)); ++ ++ status = get_firmware_hash_content (buf, size, output); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ if (permissive) ++ grub_dprintf ("tpcm", "tpcm control switch turned off, ignore get firmware hash content failure.\n"); ++ else ++ { ++ grub_printf ("get firmware hash content failed\n"); ++ err = GRUB_ERR_BUG; ++ } ++ goto fail; ++ } ++ ++ request_data->FirmwareHashLen = sizeof(extern_simple_bmeasure_req_st); ++ grub_tpcm_fillup_content (request_data, output); ++ ++ status = tpcm_ipmi->excute_ipmi_cmd (tpcm_ipmi, request, request_data, ++ sizeof (OEM_BMC_MEASURE_REQUSET), &response_data, ++ &response_length, NULL); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ if (permissive) ++ grub_dprintf ("tpcm", "tpcm control switch turned off, ignore excute_ipmi_cmd failure.\n"); ++ else ++ { ++ err = grub_error (GRUB_ERR_BUG, ++ "excute_ipmi_cmd failed, request sub_cmd:0x%x, ret:%lu\n", ++ request_data->SubCmd, status); ++ } ++ goto fail; ++ } ++ grub_dprintf ("tpcm", "send tpcm measure request success\n"); ++ ++ status = grub_tpcm_request_result (); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ if (permissive) ++ grub_dprintf ("tpcm", "tpcm control switch turned off, ignore measurement failure.\n"); ++ else ++ { ++ err = grub_error (GRUB_ERR_BAD_SIGNATURE, "bad tpcm signature"); ++ goto fail; ++ } ++ } ++ else ++ grub_dprintf ("tpcm", "tpcm hash verify success, file:%s\n", description); ++ ++ fail: ++ if (request_data) ++ { ++ grub_free (request_data); ++ } ++ return err; ++} ++ ++static grub_efi_uint8_t ++tpcm_ipmi_get_switch (void) ++{ ++ grub_efi_status_t status = GRUB_EFI_SUCCESS; ++ grub_ipmi_cmd_header request = {IPMI_BMC_LUN, ++ IPMI_NETFN_OEM, ++ IPMI_CMD_GET_MEASURE_PARM}; ++ OEM_BMC_GET_SWITCH_REQUSET request_data; ++ OEM_BMC_GET_SWITCH_RESPONSE response_data; ++ grub_efi_uint8_t response_length; ++ ++ grub_memset (&request_data, 0, sizeof (request_data)); ++ grub_memset (&response_data, 0, sizeof (response_data)); ++ ++ request_data.OemSignature[0] = 0xDB; ++ request_data.OemSignature[1] = 0x07; ++ request_data.OemSignature[2] = 0x00; ++ request_data.SubCmd = IPMI_SUB_CMD_SWITCH_REQ; ++ request_data.FirmwareType = IPMI_FW_OS; ++ request_data.FirmwareDetailType = IPMI_FW_DETAIL_GRUB_CFG; ++ ++ response_length = sizeof (OEM_BMC_GET_SWITCH_RESPONSE); ++ ++ // TODO: 确认bios接口excute_ipmi_cmd, 请求开关控制结果这块代码是否需要轮询 ++ status = tpcm_ipmi->excute_ipmi_cmd (tpcm_ipmi, request, &request_data, ++ sizeof(request_data), &response_data, ++ &response_length, NULL); ++ if (status != GRUB_EFI_SUCCESS) ++ { ++ grub_printf ("excute_ipmi_cmd failed, request sub_cmd:%d, ret:%lu\n", ++ request_data.SubCmd, status); ++ /* if we excute_ipmi_cmd, it could be the fllowing results: ++ * 1. uefi have this interface, but did not implement it. ++ * 2. uefi have implemented, but bmc did not support TPCM ++ * All of these situation should booting normally. ++ */ ++ goto out; ++ } ++ ++ if (response_data.ControlResult == IPMI_TPCM_OPEN || response_data.ControlResult == IPMI_TPCM_PERMISSIVE) ++ { ++ permissive = (response_data.ControlResult == IPMI_TPCM_PERMISSIVE) ? 1 : 0; ++ grub_dprintf ("tpcm", "tpcm: Enabled, ControlResult: %d\n", response_data.ControlResult); ++ return 1; ++ } ++ ++ out: ++ grub_dprintf ("tpcm", "tpcm: Disabled or Unknown, ControlResult: %d\n", response_data.ControlResult); ++ return 0; ++} ++ ++static grub_err_t ++tpcm_ipmi_measure (unsigned char *buf, grub_size_t size, const char *description) ++{ ++ if (tpcm_ipmi_get_switch()) ++ { ++ grub_dprintf("tpcm", "hash file: %s\n", description); ++ return grub_tpcm_log_event(buf, size, description); ++ } ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++tpcm_ipmi_write (void *context __attribute__ ((unused)), void *buf, grub_size_t size) ++{ ++ grub_err_t err; ++ err = tpcm_ipmi_measure (buf, size, context); ++ grub_tcpm_file_type = GRUB_FILE_TYPE_NONE; ++ return err; ++} ++ ++struct grub_file_verifier tpcm = ++ { ++ .name = "tpcm", ++ .init = tpcm_ipmi_init, ++ .write = tpcm_ipmi_write ++ }; ++ ++ ++GRUB_MOD_INIT(tpcm) ++{ ++ tpcm_ipmi = grub_efi_locate_protocol (&gIpmiInterfaceProtocolGuid, 0); ++ if (!tpcm_ipmi) ++ { ++ grub_dprintf ("tpcm", "locate IpmiInterfaceProtocol failed, TPCM unsupported in the machine.\n"); ++ return; ++ } ++ grub_verifier_register (&tpcm); ++} ++ ++GRUB_MOD_FINI(tpcm) ++{ ++ grub_verifier_unregister (&tpcm); ++} ++ +diff --git a/include/grub/efi/tpcm.h b/include/grub/efi/tpcm.h +new file mode 100644 +index 0000000..d4cf93b +--- /dev/null ++++ b/include/grub/efi/tpcm.h +@@ -0,0 +1,236 @@ ++#ifndef GRUB_EFI_TPCM_HEADER ++#define GRUB_EFI_TPCM_HEADER 1 ++ ++#define GRUB_EFI_HASH2_SERVICE_BINDING_PROTOCOL_GUID \ ++ { \ ++ 0xda836f8d, 0x217f, 0x4ca0, { 0x99, 0xc2, 0x1c, 0xa4, 0xe1, 0x60, 0x77, 0xea } \ ++ } ++ ++#define GRUB_EFI_HASH2_PROTOCOL_GUID \ ++ { \ ++ 0x55b1d734, 0xc5e1, 0x49db, { 0x96, 0x47, 0xb1, 0x6a, 0xfb, 0xe, 0x30, 0x5b } \ ++ } ++ ++#define EFI_TPCM_GUID \ ++ { \ ++ 0xa37e200e, 0xda90, 0x473b, { 0x8b, 0xb5, 0x1d, 0x7b, 0x11, 0xba, 0x32, 0x33 } \ ++ } ++ ++#define GRUB_HASH_ALGORITHM_SM3_GUID \ ++ { \ ++ 0x9DCD754B, 0x3479, 0x27AD, { 0x56, 0x4C, 0x68, 0x7C, 0x68, 0xEC, 0xF9, 0xB9 } \ ++ } ++ ++ ++#define OEM_SIG_SIZE 3 ++#define FIRMWARE_VERSION_SIZE 32 ++#define FIRMWARE_HASH_CONTENT_SIZE 32 ++#define FIRMWARE_NAME_SIZE 32 ++#define GRUB_IPMI_TIMEOUT_MS 2000 ++ ++// LUN ++#define IPMI_BMC_LUN 0x00 ++// Net Function Definition ++#define IPMI_NETFN_OEM 0x30 ++ ++#define IPMI_CMD_GET_MEASURE_PARM 0x92 //change a name ++ ++#define IPMI_SUB_CMD_MEASURE_REQ 0x57 //change a name ++#define IPMI_SUB_CMD_CONTROL_REQ 0x58 ++#define IPMI_SUB_CMD_SWITCH_REQ 0x59 ++ ++//bmeasure ++#define DEFAULT_HASH_SIZE 32 ++#define MEASURE_DATA_MEM_SIZE 0x100000 ++ ++#define TPCM_TAG_REQ_COMMAND 0x000000C1 ++#define TPCM_ORD_ExternSimpleBootMeasure 0x00001053 ++ ++typedef struct { ++ grub_efi_uint32_t uiCmdTag; ++ grub_efi_uint32_t uiCmdLength; ++ grub_efi_uint32_t uiCmdCode; ++ grub_efi_uint32_t uiPcr; ++ grub_efi_uint32_t uiStage; ++ grub_efi_uint8_t uaDigest[DEFAULT_HASH_SIZE]; ++ grub_efi_uint32_t uiObjLen; ++ grub_efi_uint8_t uaObj[FIRMWARE_NAME_SIZE]; ++}extern_simple_bmeasure_req_st; ++ ++typedef struct { ++ grub_efi_uint8_t OemSignature[OEM_SIG_SIZE]; ++ grub_efi_uint8_t SubCmd; ++ grub_efi_uint8_t FirmwareType; ++ grub_efi_uint8_t FirmwareDetailType; ++ grub_efi_uint8_t FirmwareHashAlgoType; ++ grub_efi_uint8_t FirmwareHashLen; ++ extern_simple_bmeasure_req_st FirmwareHashContent; ++ // reserved for kernel and initrd's version ++ grub_efi_uint8_t FirmwareVerionLen; ++ grub_efi_uint8_t FirmwareVerion[0]; ++} OEM_BMC_MEASURE_REQUSET; ++ ++typedef struct { ++ grub_efi_uint8_t CompletionCode; ++ grub_efi_uint8_t OemSignature[OEM_SIG_SIZE]; ++} OEM_BMC_MEASURE_RESPONSE; ++ ++typedef struct { ++ grub_efi_uint8_t OemSignature[OEM_SIG_SIZE]; ++ grub_efi_uint8_t SubCmd; ++ grub_efi_uint8_t FirmwareType; ++ grub_efi_uint8_t FirmwareDetailType; ++} OEM_BMC_GET_RESULT_REQUSET; ++ ++typedef struct { ++ /* In the specification of BMC <--> BIOS(GRUB2), we need CompletionCode ++ * But, BIOS has pre-processed CompletionCode in function: excute_ipmi_cmd ++ * So, we delete the word: ++ * grub_efi_uint8_t CompletionCode; ++ */ ++ grub_efi_uint8_t OemSignature[OEM_SIG_SIZE]; ++ grub_efi_uint8_t ControlResult; ++} OEM_BMC_GET_RESULT_RESPONSE; ++ ++typedef struct { ++ grub_efi_uint8_t OemSignature[OEM_SIG_SIZE]; ++ grub_efi_uint8_t SubCmd; ++ grub_efi_uint8_t FirmwareType; ++ grub_efi_uint8_t FirmwareDetailType; ++} OEM_BMC_GET_SWITCH_REQUSET; ++ ++typedef struct { ++ /* In the specification of BMC <--> BIOS(GRUB2), we need CompletionCode ++ * But, BIOS has pre-processed CompletionCode in function: excute_ipmi_cmd ++ * So, we delete the word: ++ * grub_efi_uint8_t CompletionCode; ++ */ ++ grub_efi_uint8_t OemSignature[OEM_SIG_SIZE]; ++ grub_efi_uint8_t ControlResult; ++} OEM_BMC_GET_SWITCH_RESPONSE; ++ ++typedef enum { ++ IPMI_SYSTEM_INTERFACE_UNKNOWN, // IPMI_SYSTEM_INTERFACE_TYPE->UNKNOWN ++ IPMI_SYSTEM_INTERFACE_KCS, ++ IPMI_SYSTEM_INTERFACE_SMIC, ++ IPMI_SYSTEM_INTERFACE_BT, // IPMI_SYSTEM_INTERFACE_TYPE->BT ++ IPMI_SYSTEM_INTERFACE_SSIF, ++ IPMI_SYSTEM_INTERFACE_MAX_TYPE // IPMI_SYSTEM_INTERFACE_TYPE->MAX_TYPE ++} grub_ipmi_system_interface_type; ++ ++ ++typedef struct { ++ grub_efi_uint8_t lun : 2; ++ grub_efi_uint8_t net_fn : 6; ++ grub_efi_uint8_t cmd; ++} grub_ipmi_cmd_header; ++ ++typedef enum { ++ IPMI_MEMORY, ++ IPMI_IO, // IPMI_IO ++ IPMI_MAX_INTERFACE_ADDRESS_TYPE ++} grub_ipmi_interface_address_type; ++ ++typedef enum { ++ IPMI_FW_SHIM, ++ IPMI_FW_SHIM_GRUB, ++ IPMI_FW_OS ++} grub_ipmi_firmware_type; ++ ++typedef enum { ++ IPMI_FW_DETAIL_GRUB_CFG, ++ IPMI_FW_DETAIL_KERNEL, ++ IPMI_FW_DETAIL_INITRD ++} grub_ipmi_firmware_detail_type; ++ ++typedef enum { ++ IPMI_FW_HASH_SM3, ++ IPMI_FW_HASH_RESERVED1, ++ IPMI_FW_HASH_RESERVED2 ++} grub_ipmi_firmware_hash_algo_type; ++ ++typedef enum { ++ IPMI_MEASURE_UNKNOW, ++ IPMI_MEASURE_SUCCESS, ++ IPMI_MEASURE_FAIL ++} grub_ipmi_measure_result_type; ++ ++typedef enum { ++ IPMI_TPCM_UNKNOW, ++ IPMI_TPCM_OPEN, ++ IPMI_TPCM_CLOSE, ++ IPMI_TPCM_PERMISSIVE ++} grub_ipmi_tpcm_result_type; ++ ++ ++typedef grub_efi_uint8_t EFI_MD5_HASH2[16]; ++typedef grub_efi_uint8_t EFI_SHA1_HASH2[20]; ++typedef grub_efi_uint8_t EFI_SHA224_HASH2[28]; ++typedef grub_efi_uint8_t EFI_SHA256_HASH2[32]; ++typedef grub_efi_uint8_t EFI_SHA384_HASH2[48]; ++typedef grub_efi_uint8_t EFI_SHA512_HASH2[64]; ++typedef grub_efi_uint8_t EFI_SM3_HASH2[32]; ++ ++typedef union { ++ EFI_MD5_HASH2 Md5Hash; ++ EFI_SHA1_HASH2 Sha1Hash; ++ EFI_SHA224_HASH2 Sha224Hash; ++ EFI_SHA256_HASH2 Sha256Hash; ++ EFI_SHA384_HASH2 Sha384Hash; ++ EFI_SHA512_HASH2 Sha512Hash; ++ EFI_SM3_HASH2 Sm3Hash; ++} grub_efi_hash2_output; ++ ++struct grub_efi_hash2_protocol { ++ grub_efi_status_t ++ (*get_hash_size) (struct grub_efi_hash2_protocol *this, ++ grub_efi_guid_t *hash_algorithm, ++ grub_efi_uintn_t hash_size); ++ ++ grub_efi_status_t ++ (*hash) (struct grub_efi_hash2_protocol *this, ++ grub_efi_guid_t *hash_algorithm, ++ grub_efi_uint8_t *message, ++ grub_efi_uintn_t message_size, ++ grub_efi_hash2_output *hash); ++ ++ grub_efi_status_t ++ (*hash_init) (struct grub_efi_hash2_protocol *this, ++ grub_efi_guid_t *hash_algorithm); ++ ++ grub_efi_status_t ++ (*hash_update) (struct grub_efi_hash2_protocol *this, ++ grub_efi_uint8_t *message, ++ grub_efi_uintn_t message_size); ++ ++ grub_efi_status_t ++ (*hash_final) (struct grub_efi_hash2_protocol *this, ++ grub_efi_hash2_output *hash); ++}; ++typedef struct grub_efi_hash2_protocol grub_efi_hash2_protocol_t; ++ ++struct grub_efi_ipmi_interface_protocol { ++ grub_efi_status_t ++ (*excute_ipmi_cmd) (struct grub_efi_ipmi_interface_protocol *this, ++ grub_ipmi_cmd_header request, ++ void *send_data, ++ grub_efi_uint8_t send_length, ++ void *recv_data, ++ grub_efi_uint8_t *recv_length, ++ grub_efi_uint16_t *status_codes); ++ ++ grub_ipmi_system_interface_type ++ (*get_ipmi_interface_type) (struct grub_efi_ipmi_interface_protocol *this); ++ ++ grub_efi_uint16_t ++ (*get_ipmi_base_address) (struct grub_efi_ipmi_interface_protocol *this); ++ ++ grub_ipmi_interface_address_type ++ (*get_ipmi_base_address_type) (struct grub_efi_ipmi_interface_protocol *this); ++ ++ grub_efi_uint8_t ++ (*get_ipmi_version) (struct grub_efi_ipmi_interface_protocol *this); ++}; ++typedef struct grub_efi_ipmi_interface_protocol grub_efi_ipmi_interface_protocol_t; ++ ++#endif +-- +2.27.0 + diff --git a/arm64-Use-proper-memory-type-for-kernel-allocation.patch b/arm64-Use-proper-memory-type-for-kernel-allocation.patch new file mode 100644 index 0000000000000000000000000000000000000000..66a02c88e3825ffdbefb56aa2702d31c9f29cfe9 --- /dev/null +++ b/arm64-Use-proper-memory-type-for-kernel-allocation.patch @@ -0,0 +1,51 @@ +From 4f9d3f4f8d7866c69e52ba7d81562daea38b22e6 Mon Sep 17 00:00:00 2001 +From: Maximilian Luz +Date: Tue, 28 Jun 2022 23:06:46 +0200 +Subject: [PATCH] arm64: Use proper memory type for kernel allocation +References: bsc#1215151 +Patch-Mainline: no, it's a downstream fix based on Fedora/openSUSE grub2 + +Currently, the kernel pages are allocated with type EFI_LOADER_DATA. +While the vast majority of systems will happily execute code from those +pages (i.e. don't care about memory protection), the Microsoft Surface +Pro X stalls, as this memory is not designated as "executable". + +Therefore, allocate the kernel pages as EFI_LOADER_CODE to request +memory that is actually executable. + +Link: https://github.com/rhboot/grub2/commit/4f9d3f4f8d7866c69e52ba7d81562daea38b22e6 +Signed-off-by: Maximilian Luz +Signed-off-by: Chester Lin +--- + grub-core/loader/arm64/linux.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c +index 419f2201d..a3a193c25 100644 +--- a/grub-core/loader/arm64/efi/linux.c ++++ b/grub-core/loader/arm64/efi/linux.c +@@ -26,7 +26,9 @@ + #include + #include + #include ++#include + #include ++#include + #include + #include + #include +@@ -403,7 +405,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + grub_loader_unset(); + + kernel_alloc_pages = GRUB_EFI_BYTES_TO_PAGES (kernel_size + align - 1); +- kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages); ++ kernel_alloc_addr = grub_efi_allocate_pages_real (GRUB_EFI_MAX_USABLE_ADDRESS, ++ kernel_alloc_pages, ++ GRUB_EFI_ALLOCATE_MAX_ADDRESS, ++ GRUB_EFI_LOADER_CODE); + grub_dprintf ("linux", "kernel numpages: %d\n", kernel_alloc_pages); + if (!kernel_alloc_addr) + { +-- +2.40.0 + diff --git a/backport-Read-etc-default-grub.d-.cfg-after-etc-default-grub.patch b/backport-Read-etc-default-grub.d-.cfg-after-etc-default-grub.patch new file mode 100644 index 0000000000000000000000000000000000000000..f10323dfb4d1f245d760d7c8cf4ad8fc6a27b1a1 --- /dev/null +++ b/backport-Read-etc-default-grub.d-.cfg-after-etc-default-grub.patch @@ -0,0 +1,221 @@ +From c9198e80f1aa2e9ae9e2bdc8b6f9e9ef601f0971 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Mon, 13 Jan 2014 12:13:10 +0000 +Subject: [PATCH] Read /etc/default/grub.d/*.cfg after /etc/default/grub + +Bug-Ubuntu: https://bugs.launchpad.net/bugs/901600 +Forwarded: no +Last-Update: 2021-09-24 + +Reference:https://sources.debian.org/src/grub2/2.12-1/debian/patches/default-grub-d.patch/ +Conflict:NA +--- + grub-core/osdep/unix/config.c | 128 ++++++++++++++++++++++++++++------ + util/grub-mkconfig.in | 5 ++ + 2 files changed, 112 insertions(+), 21 deletions(-) + +diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c +index a84d022..5ee645d 100644 +--- a/grub-core/osdep/unix/config.c ++++ b/grub-core/osdep/unix/config.c +@@ -24,6 +24,9 @@ + #include + #include + #include ++#include ++#include ++#include + #include + #include + #include +@@ -186,13 +189,27 @@ grub_util_default_distributor (void) + } + #endif + ++struct cfglist ++{ ++ struct cfglist *next; ++ struct cfglist *prev; ++ char *path; ++}; ++ + void + grub_util_load_config (struct grub_util_config *cfg) + { + pid_t pid; + const char *argv[4]; +- char *script, *ptr; ++ char *script = NULL, *ptr; + const char *cfgfile, *iptr; ++ char *cfgdir; ++ grub_util_fd_dir_t d; ++ struct cfglist *cfgpaths = NULL, *cfgpath, *next_cfgpath; ++ int num_cfgpaths = 0; ++ size_t len_cfgpaths = 0; ++ char **sorted_cfgpaths = NULL; ++ int i; + FILE *f = NULL; + int fd; + const char *v; +@@ -221,29 +238,88 @@ grub_util_load_config (struct grub_util_config *cfg) + } + + cfgfile = grub_util_get_config_filename (); +- if (!grub_util_is_regular (cfgfile)) +- return; ++ if (grub_util_is_regular (cfgfile)) ++ { ++ size_t sz; ++ ++ ++num_cfgpaths; ++ sz = strlen (cfgfile); ++ if (grub_mul (sz, 4, &sz) || ++ grub_add (sz, sizeof (". ''; ") - 1, &sz) || ++ grub_add (len_cfgpaths, sz, &len_cfgpaths)) ++ grub_util_error ("%s", _("overflow is detected")); ++ } ++ ++ cfgdir = xasprintf ("%s.d", cfgfile); ++ d = grub_util_fd_opendir (cfgdir); ++ if (d) ++ { ++ grub_util_fd_dirent_t de; ++ ++ while ((de = grub_util_fd_readdir (d))) ++ { ++ const char *ext = strrchr (de->d_name, '.'); ++ size_t sz; ++ ++ if (!ext || strcmp (ext, ".cfg") != 0) ++ continue; ++ ++ cfgpath = xmalloc (sizeof (*cfgpath)); ++ cfgpath->path = grub_util_path_concat (2, cfgdir, de->d_name); ++ grub_list_push (GRUB_AS_LIST_P (&cfgpaths), GRUB_AS_LIST (cfgpath)); ++ ++num_cfgpaths; ++ sz = strlen (cfgpath->path); ++ if (grub_mul (sz, 4, &sz) || ++ grub_add (sz, sizeof (". ''; ") - 1, &sz) || ++ grub_add (len_cfgpaths, sz, &len_cfgpaths)) ++ grub_util_error ("%s", _("overflow is detected")); ++ } ++ grub_util_fd_closedir (d); ++ } ++ ++ if (num_cfgpaths == 0) ++ goto out; ++ ++ sorted_cfgpaths = xcalloc (num_cfgpaths, sizeof (*sorted_cfgpaths)); ++ i = 0; ++ if (grub_util_is_regular (cfgfile)) ++ sorted_cfgpaths[i++] = xstrdup (cfgfile); ++ FOR_LIST_ELEMENTS_SAFE (cfgpath, next_cfgpath, cfgpaths) ++ { ++ sorted_cfgpaths[i++] = cfgpath->path; ++ free (cfgpath); ++ } ++ assert (i == num_cfgpaths); ++ qsort (sorted_cfgpaths + 1, num_cfgpaths - 1, sizeof (*sorted_cfgpaths), ++ (int (*) (const void *, const void *)) strcmp); + + argv[0] = "sh"; + argv[1] = "-c"; + +- script = xcalloc (4, strlen (cfgfile) + 300); ++ if (grub_add (len_cfgpaths, 300, &len_cfgpaths)) ++ grub_util_error ("%s", _("overflow is detected")); ++ script = xmalloc (len_cfgpaths); + + ptr = script; +- memcpy (ptr, ". '", 3); +- ptr += 3; +- for (iptr = cfgfile; *iptr; iptr++) ++ for (i = 0; i < num_cfgpaths; i++) + { +- if (*iptr == '\\') ++ memcpy (ptr, ". '", 3); ++ ptr += 3; ++ for (iptr = sorted_cfgpaths[i]; *iptr; iptr++) + { +- memcpy (ptr, "'\\''", 4); +- ptr += 4; +- continue; ++ if (*iptr == '\\') ++ { ++ memcpy (ptr, "'\\''", 4); ++ ptr += 4; ++ continue; ++ } ++ *ptr++ = *iptr; + } +- *ptr++ = *iptr; ++ memcpy (ptr, "'; ", 3); ++ ptr += 3; + } + +- strcpy (ptr, "'; printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\nSUSE_BTRFS_SNAPSHOT_BOOTING=%s\\n\" " ++ strcpy (ptr, "printf \"GRUB_ENABLE_CRYPTODISK=%s\\nGRUB_DISTRIBUTOR=%s\\nSUSE_BTRFS_SNAPSHOT_BOOTING=%s\\n\" " + "\"$GRUB_ENABLE_CRYPTODISK\" \"$GRUB_DISTRIBUTOR\" \"$SUSE_BTRFS_SNAPSHOT_BOOTING\""); + + argv[2] = script; +@@ -272,18 +348,21 @@ grub_util_load_config (struct grub_util_config *cfg) + cfg->grub_distributor = grub_util_default_distributor (); + } + #endif +- return; ++ goto out; + } + +- f = grub_util_fopen (cfgfile, "r"); +- if (f) ++ for (i = 0; i < num_cfgpaths; i++) + { +- grub_util_parse_config (f, cfg, 0); +- fclose (f); ++ f = grub_util_fopen (sorted_cfgpaths[i], "r"); ++ if (f) ++ { ++ grub_util_parse_config (f, cfg, 0); ++ fclose (f); ++ } ++ else ++ grub_util_warn (_("cannot open configuration file `%s': %s"), ++ cfgfile, strerror (errno)); + } +- else +- grub_util_warn (_("cannot open configuration file `%s': %s"), +- cfgfile, strerror (errno)); + + #ifdef __linux__ + if (!cfg->grub_distributor || cfg->grub_distributor[0] == '\0') +@@ -293,4 +372,11 @@ grub_util_load_config (struct grub_util_config *cfg) + cfg->grub_distributor = grub_util_default_distributor (); + } + #endif ++ ++out: ++ free (script); ++ for (i = 0; i < num_cfgpaths; i++) ++ free (sorted_cfgpaths[i]); ++ free (sorted_cfgpaths); ++ free (cfgdir); + } +diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in +index cf5b793..4b3510a 100644 +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -188,6 +188,11 @@ fi + if test -f ${sysconfdir}/default/grub ; then + . ${sysconfdir}/default/grub + fi ++for x in ${sysconfdir}/default/grub.d/*.cfg ; do ++ if [ -e "${x}" ]; then ++ . "${x}" ++ fi ++done + + if [ "x${GRUB_DISABLE_UUID}" = "xtrue" ]; then + if [ -z "${GRUB_DISABLE_LINUX_UUID}" ]; then +-- +2.33.0 + diff --git a/bootstrap b/bootstrap old mode 100755 new mode 100644 index 5b08e7e2d421c0227598813ae65f35b9c22cfcb3..4e1e91f7176352e82832b9b4925022bc4915abc8 --- a/bootstrap +++ b/bootstrap @@ -1,4 +1,4 @@ -#! /bin/sh +#!/bin/sh # Print a version string. scriptversion=2019-01-04.17; # UTC diff --git a/bootstrap.conf b/bootstrap.conf index 6b043fc354c4347d992139e908a6a7b159e28114..ea401013f78c983cf9b0d2c0beabc1ff3b4832b1 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -79,11 +79,11 @@ cp -a INSTALL INSTALL.grub bootstrap_post_import_hook () { set -e - for patchname in fix-base64 fix-null-deref fix-null-state-deref fix-regcomp-uninit-token \ - fix-regexec-null-deref fix-uninit-structure fix-unused-value fix-width no-abort; do - patch -d grub-core/lib/gnulib -p2 \ - < "grub-core/lib/gnulib-patches/$patchname.patch" - done + #for patchname in fix-base64 fix-null-deref fix-null-state-deref fix-regcomp-uninit-token \ + # fix-regexec-null-deref fix-uninit-structure fix-unused-value fix-width no-abort; do + # patch -d grub-core/lib/gnulib -p2 \ + # < "grub-core/lib/gnulib-patches/$patchname.patch" + #done for patchname in \ 0001-Support-POTFILES-shell \ 0002-Handle-gettext_printf-shell-function \ diff --git a/config_for_secure b/config_for_secure new file mode 100644 index 0000000000000000000000000000000000000000..17428dda510124ba6e7dfacdfe68c061ab9f4bfe --- /dev/null +++ b/config_for_secure @@ -0,0 +1,3 @@ +rpm_name:grub2 +sec_opt:-fPIC -Wl,-z,relro -Wl,-z,now -Wl,-z,noexecstack -Wtrampolines +fs_opt: diff --git a/disable-some-unsupported-filesystems.patch b/disable-some-unsupported-filesystems.patch new file mode 100644 index 0000000000000000000000000000000000000000..5cf489ac472500980e9fea51272514829c3a37c7 --- /dev/null +++ b/disable-some-unsupported-filesystems.patch @@ -0,0 +1,53 @@ +From 5d3654738c78291a2252eec2fdee9cd4b6c9c2f4 Mon Sep 17 00:00:00 2001 +From: Qiumiao Zhang +Date: Thu, 2 Feb 2023 14:37:52 +0800 +Subject: [PATCH] disable some unsupported filesystems + +Signed-off-by: Qiumiao Zhang +--- + Makefile.util.def | 17 ----------------- + 1 file changed, 17 deletions(-) + +diff --git a/Makefile.util.def b/Makefile.util.def +index b7a6311..de156f9 100644 +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -95,9 +95,6 @@ library = { + common = grub-core/video/colors.c; + common = grub-core/unidata.c; + common = grub-core/io/bufio.c; +- common = grub-core/fs/affs.c; +- common = grub-core/fs/afs.c; +- common = grub-core/fs/bfs.c; + common = grub-core/fs/btrfs.c; + common = grub-core/fs/cbfs.c; + common = grub-core/fs/cpio.c; +@@ -113,25 +110,11 @@ library = { + common = grub-core/fs/hfsplus.c; + common = grub-core/fs/hfspluscomp.c; + common = grub-core/fs/iso9660.c; +- common = grub-core/fs/jfs.c; +- common = grub-core/fs/minix.c; +- common = grub-core/fs/minix2.c; +- common = grub-core/fs/minix3.c; +- common = grub-core/fs/minix_be.c; +- common = grub-core/fs/minix2_be.c; +- common = grub-core/fs/minix3_be.c; +- common = grub-core/fs/nilfs2.c; + common = grub-core/fs/ntfs.c; + common = grub-core/fs/ntfscomp.c; +- common = grub-core/fs/reiserfs.c; +- common = grub-core/fs/romfs.c; +- common = grub-core/fs/sfs.c; + common = grub-core/fs/squash4.c; + common = grub-core/fs/tar.c; + common = grub-core/fs/udf.c; +- common = grub-core/fs/ufs2.c; +- common = grub-core/fs/ufs.c; +- common = grub-core/fs/ufs_be.c; + common = grub-core/fs/xfs.c; + common = grub-core/fs/zfs/zfscrypt.c; + common = grub-core/fs/zfs/zfs.c; +-- +2.27.0 + diff --git a/fix_no_extra_deps_in_release_tarball.patch b/fix_no_extra_deps_in_release_tarball.patch new file mode 100644 index 0000000000000000000000000000000000000000..7393b7374414a92c5217bd41ba3e2de55bd0634f --- /dev/null +++ b/fix_no_extra_deps_in_release_tarball.patch @@ -0,0 +1,4 @@ +--- /dev/null ++++ b/grub-core/extra_deps.lst +@@ -0,0 +1 @@ ++depends bli part_gpt diff --git a/gnulib-9f48fb992a3d7e96610c4ce8be969cff2d61a01b.tar.gz b/gnulib-fixes.tar.gz similarity index 47% rename from gnulib-9f48fb992a3d7e96610c4ce8be969cff2d61a01b.tar.gz rename to gnulib-fixes.tar.gz index 1a0cf7dbaf75cfd6a60c5627f6b1a1845c8284eb..9b2472311a1a5a0a02b5d34e8e54000522f156f8 100644 Binary files a/gnulib-9f48fb992a3d7e96610c4ce8be969cff2d61a01b.tar.gz and b/gnulib-fixes.tar.gz differ diff --git a/grub-2.06.tar.xz b/grub-2.12.tar.xz similarity index 47% rename from grub-2.06.tar.xz rename to grub-2.12.tar.xz index a6a9c6dcb110f96560af778f89e7f64d67417679..9295544c27d42b29f1401817e4d045d7b4ba421f 100644 Binary files a/grub-2.06.tar.xz and b/grub-2.12.tar.xz differ diff --git a/grub-install-force-journal-draining-to-ensure-data-i.patch b/grub-install-force-journal-draining-to-ensure-data-i.patch new file mode 100644 index 0000000000000000000000000000000000000000..714e74804230f097482e2cfccd07ddb9b43e3e8d --- /dev/null +++ b/grub-install-force-journal-draining-to-ensure-data-i.patch @@ -0,0 +1,218 @@ +From 3085db0922a1d803d4a9dfe54daae6fef20e4340 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Mon, 13 Apr 2020 16:08:59 +0800 +Subject: [PATCH] grub-install: force journal draining to ensure data integrity + +In XFS, the system would end up in unbootable state if an abrupt power +off after grub-install is occuring. It can be easily reproduced with. + + grub-install /dev/vda; reboot -f + +The grub error would show many different kinds of corruption in +filesystem and the problem boils down to incompleted journal transaction +which would leave pending writes behind in the on-disk journal. It is +therefore necessary to recover the system via re-mounting the filesystem +from linux system that all pending journal log can be replayed. + +On the other hand if journal draining can be enforced by grub-install +then it can bring more resilience to such abrupt power loss. The fsync +is not enough here for XFS, because that only writes in-memory log to +on-disk (ie makes sure broken state can be repaired). Unfortunately +there's no designated system call to serve solely for the journal +draining, so it can only be achieved via fsfreeze system call that the +journal draining can happen as a byproduct during the process. + +This patch adds fsfreeze/unfreeze at the end of grub-install to induce +journal draining on journaled file system. However btrfs is excluded +from the list as it is using fsync to drain journal and also is not +desired as reportedly having negative side effect. With this patch +applied, the boot falilure can no longer be reproduced with above +procedure. + +v2: +Fix boot failure after kdump due to the content of grub.cfg is not +completed with pending modificaton in xfs journal (bsc#1186975) + +Signed-off-by: Michael Chang +--- + Makefile.util.def | 1 + + grub-core/osdep/basic/journaled_fs.c | 26 +++++++++++++++++++ + grub-core/osdep/journaled_fs.c | 5 ++++ + grub-core/osdep/linux/journaled_fs.c | 48 ++++++++++++++++++++++++++++++++++++ + include/grub/util/install.h | 2 ++ + util/grub-install.c | 20 +++++++++++++++ + 6 files changed, 102 insertions(+) + create mode 100644 grub-core/osdep/basic/journaled_fs.c + create mode 100644 grub-core/osdep/journaled_fs.c + create mode 100644 grub-core/osdep/linux/journaled_fs.c + +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -672,6 +672,9 @@ + emu_condition = COND_s390x; + common = grub-core/kern/emu/argp_common.c; + common = grub-core/osdep/init.c; ++ 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; + + ldadd = '$(LIBLZMA)'; + ldadd = libgrubmods.a; +--- /dev/null ++++ b/grub-core/osdep/basic/journaled_fs.c +@@ -0,0 +1,26 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2010,2011,2012,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 . ++ */ ++ ++#include ++ ++int ++grub_install_sync_fs_journal (const char *path) ++{ ++ return 1; ++} ++ +--- /dev/null ++++ b/grub-core/osdep/journaled_fs.c +@@ -0,0 +1,5 @@ ++#ifdef __linux__ ++#include "linux/journaled_fs.c" ++#else ++#include "basic/journaled_fs.c" ++#endif +--- /dev/null ++++ b/grub-core/osdep/linux/journaled_fs.c +@@ -0,0 +1,48 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2010,2011,2012,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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++int ++grub_install_sync_fs_journal (const char *path) ++{ ++ int fd, ret; ++ ++ fd = open (path, O_RDONLY); ++ ++ if (fd == -1) ++ return 1; ++ ++ if (ioctl (fd, FIFREEZE, 0) == 0) ++ { ++ ioctl(fd, FITHAW, 0); ++ ret = 1; ++ } ++ else if (errno == EOPNOTSUPP) ++ ret = 1; ++ else ++ ret = 0; ++ ++ close (fd); ++ return ret; ++} ++ +--- a/include/grub/util/install.h ++++ b/include/grub/util/install.h +@@ -301,4 +301,6 @@ + } + #endif + ++int ++grub_install_sync_fs_journal (const char *path); + #endif +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -42,6 +42,7 @@ + #include + #include + #include ++#include + + #include + +@@ -2074,6 +2075,24 @@ + break; + } + ++ { ++ const char *journaled_fs[] = {"xfs", "ext2", NULL}; ++ int i; ++ ++ for (i = 0; journaled_fs[i]; ++i) ++ if (grub_strcmp (grub_fs->name, journaled_fs[i]) == 0) ++ { ++ int retries = 10; ++ ++ /* If the fs is already frozen at that point, we could generally ++ * expected that it will be soon unfrozen again (assuming some other ++ * process has frozen it for snapshotting or something), so we may ++ * as well retry a few (limited) times in a delay loop. */ ++ while (retries-- && !grub_install_sync_fs_journal (grubdir)) ++ grub_sleep (1); ++ break; ++ } ++ } + /* + * Either there are no platform specific code, or it didn't raise + * ponr. Raise it here, because usually this is already past point +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -335,6 +335,15 @@ + esac + done + ++sync_fs_journal () { ++ if test "x$GRUB_DEVICE" = "x$GRUB_DEVICE_BOOT" && ++ test "x$GRUB_FS" = "xxfs" -o "x$GRUB_FS" = "xext2" && ++ test "x${grub_cfg}" != "x" -a "x`make_system_path_relative_to_its_root $grub_cfg`" = "x/boot/grub2/grub.cfg" && ++ test -x /usr/sbin/fsfreeze; then ++ /usr/sbin/fsfreeze --freeze / && /usr/sbin/fsfreeze --unfreeze / ++ fi ++} >&2 ++ + if test "x${grub_cfg}" != "x" ; then + if ! ${grub_script_check} ${grub_cfg}.new; then + # TRANSLATORS: %s is replaced by filename +@@ -351,6 +360,7 @@ + cat ${grub_cfg}.new > ${grub_cfg} + umask $oldumask + rm -f ${grub_cfg}.new ++ sync_fs_journal || true + fi + fi + diff --git a/grub-install-record-pcrs.patch b/grub-install-record-pcrs.patch new file mode 100644 index 0000000000000000000000000000000000000000..feb87fbd81735b2f6a8ea518ee96615a72ca2157 --- /dev/null +++ b/grub-install-record-pcrs.patch @@ -0,0 +1,16 @@ +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -1501,6 +1501,13 @@ + + grub_util_unlink (load_cfg); + ++ if (1) ++ { ++ load_cfg_f = grub_util_fopen (load_cfg, "wb"); ++ have_load_cfg = 1; ++ fprintf (load_cfg_f, "tpm_record_pcrs 0-9\n"); ++ } ++ + if (debug_image && debug_image[0]) + { + load_cfg_f = grub_util_fopen (load_cfg, "wb"); diff --git a/grub-read-pcr.patch b/grub-read-pcr.patch new file mode 100644 index 0000000000000000000000000000000000000000..8131cc9c948bf54eee3090aeaddf0d99273ebaf3 --- /dev/null +++ b/grub-read-pcr.patch @@ -0,0 +1,165 @@ +--- a/include/grub/tpm.h ++++ b/include/grub/tpm.h +@@ -36,6 +36,12 @@ + + #define EV_IPL 0x0d + ++struct grub_tpm_digest { ++ const char * algorithm; ++ unsigned int size; ++ unsigned char value[1]; /* variable length */ ++}; ++ + grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size, + grub_uint8_t pcr, const char *description); + int grub_tpm_present (void); +@@ -45,5 +51,7 @@ + { + return grub_env_get_bool ("tpm_fail_fatal", false); + } ++struct grub_tpm_digest *grub_tpm_read_pcr (grub_uint8_t index, const char *algo); ++void grub_tpm_digest_free (struct grub_tpm_digest *d); + + #endif +--- a/grub-core/commands/efi/tpm.c ++++ b/grub-core/commands/efi/tpm.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -186,6 +187,91 @@ + return grub_efi_log_event_status (status); + } + ++static void ++grub_tpm2_select_pcr(TPML_PCR_SELECTION *o, unsigned int pcrIndex, unsigned int algo) ++{ ++ TPMS_PCR_SELECTION *pcr; ++ ++ pcr = &o->pcrSelections[o->count++]; ++ pcr->hash = algo; ++ pcr->sizeOfSelect = 3; ++ pcr->pcrSelect[TPM2_PCR_TO_SELECT(pcrIndex)] |= TPM2_PCR_TO_BIT(pcrIndex); ++} ++ ++struct grub_tpm_hash_info { ++ const char *name; ++ grub_size_t size; ++ int id; ++}; ++ ++static const struct grub_tpm_hash_info * ++grub_tpm2_get_digest_info (const char *algo) ++{ ++ static struct grub_tpm_hash_info __hashes[] = { ++ { "sha256", 32, TPM_ALG_SHA256 }, /* first entry is the default */ ++ { "sha512", 64, TPM_ALG_SHA512 }, ++ { "sha1", 20, TPM_ALG_SHA1 }, ++ { NULL } ++ }; ++ struct grub_tpm_hash_info *h; ++ ++ if (algo == NULL) ++ return &__hashes[0]; ++ ++ for (h = __hashes; h->name; ++h) ++ if (!grub_strcmp(h->name, algo)) ++ return h; ++ ++ return NULL; ++} ++ ++static grub_err_t ++grub_tpm2_read_pcr (grub_int8_t pcrIndex, const char *algo, struct grub_tpm_digest **ret) ++{ ++ const struct grub_tpm_hash_info *info; ++ TPML_PCR_SELECTION inSelection, outSelection; ++ grub_uint32_t pcrUpdateCounter; ++ TPML_DIGEST digests = { 0 }; ++ TPM2B_DIGEST *d; ++ struct grub_tpm_digest *result; ++ int rc; ++ ++ info = grub_tpm2_get_digest_info (algo); ++ if (info == NULL) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("Unknown digest algorithm %s"), algo); ++ ++ grub_memset(&inSelection, 0, sizeof(inSelection)); ++ grub_memset(&outSelection, 0, sizeof(outSelection)); ++ grub_tpm2_select_pcr(&inSelection, pcrIndex, info->id); ++ ++ rc = TPM2_PCR_Read( ++ NULL, ++ &inSelection, ++ &pcrUpdateCounter, ++ &outSelection, ++ &digests, ++ NULL ++ ); ++ ++ if (rc != 0) ++ return grub_error (GRUB_ERR_BAD_DEVICE, "TPM2_PCR_Read failed, status=%d", rc); ++ ++ d = &digests.digests[0]; ++ ++ *ret = result = grub_malloc (sizeof (*result) + d->size); ++ grub_memcpy (result->value, d->buffer, d->size); ++ result->algorithm = info->name; ++ result->size = d->size; ++ ++ return GRUB_ERR_NONE; ++} ++ ++void ++grub_tpm_digest_free (struct grub_tpm_digest *d) ++{ ++ grub_free (d); ++} ++ + static grub_err_t + grub_tpm2_log_event (grub_efi_handle_t tpm_handle, unsigned char *buf, + grub_size_t size, grub_uint8_t pcr, +@@ -323,3 +409,26 @@ + return grub_tpm2_present (tpm); + } + } ++ ++struct grub_tpm_digest * ++grub_tpm_read_pcr (grub_uint8_t pcr, const char *algo) ++{ ++ grub_efi_handle_t tpm_handle; ++ grub_efi_uint8_t protocol_version; ++ struct grub_tpm_digest *result = NULL; ++ ++ ++ if (!grub_tpm_handle_find (&tpm_handle, &protocol_version)) ++ return 0; ++ ++ if (protocol_version != 2) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, N_("%s: TPM version %d not implemented"), __func__, protocol_version); ++ return NULL; ++ } ++ ++ if (grub_tpm2_read_pcr (pcr, algo, &result)) ++ return NULL; ++ ++ return result; ++} +--- a/include/grub/tpm2/tpm2.h ++++ b/include/grub/tpm2/tpm2.h +@@ -23,6 +23,10 @@ + #include + #include + ++/* Defined in: TCG TPM Specification, v1.59, Part 2, Section 10.6.1. */ ++#define TPM2_PCR_TO_SELECT(x) ((x) / 8) ++#define TPM2_PCR_TO_BIT(x) (1 << ((x) % 8)) ++ + /* Well-Known Windows SRK handle */ + #define TPM2_SRK_HANDLE 0x81000001 + diff --git a/grub.macros b/grub.macros index a960267a18e51fd8aa03f7b13b5ab62c7d380caf..05098f2cef440edad9d897c0dcbe07c41790db2b 100644 --- a/grub.macros +++ b/grub.macros @@ -14,15 +14,15 @@ %global ccpath %{__cc} %endif -# gnulib actively ignores CFLAGS because it's terrible -%global cc_equals "CC=%{ccpath} -fPIE" +%global cc_equals "CC=%{ccpath} -fPIE -Wl,-z,noexecstack" %global cflags_sed \\\ sed \\\ -e 's/-O. //g' \\\ - -e 's/-fplugin=annobin//g' \\\ - -e 's,-specs=[[:alnum:]/_-]*annobin[[:alnum:]_-]*,,g' \\\ - -e 's/-fstack-protector[[:alpha:]-]\\+//g' \\\ + -e 's/-g /-g3 /g' \\\ + -e 's/-fplugin=annobin //g' \\\ + -e 's,-specs=[[:alnum:]/_-]*annobin[[:alnum:]_-]* ,,g' \\\ + -e 's/-fstack-protector[[:alpha:]-]*//g' \\\ -e 's/-Wp,-D_FORTIFY_SOURCE=[[:digit:]]\\+//g' \\\ -e 's/--param=ssp-buffer-size=4//g' \\\ -e 's/-mregparm=3/-mregparm=4/g' \\\ @@ -52,7 +52,7 @@ %global ldflags_sed \\\ sed \\\ - -e 's,-specs=[[:alnum:]/_-]*annobin[[:alnum:]_-]*,,g' \\\ + -e 's,-specs=[[:alnum:]/_-]*annobin[[:alnum:]_-]* ,,g' \\\ -e 's/^$//' \\\ %{nil} @@ -118,9 +118,9 @@ ### fixme %ifarch aarch64 %{arm} riscv64 loongarch64 -%global efi_modules " " +%global efi_modules " tpm " %else -%global efi_modules " backtrace chain tpm usb usbserial_common usbserial_pl2303 usbserial_ftdi usbserial_usbdebug keylayouts at_keyboard connectefi " +%global efi_modules " backtrace chain tpm usb usbserial_common usbserial_pl2303 usbserial_ftdi usbserial_usbdebug keylayouts at_keyboard " %endif %ifarch aarch64 %{arm} riscv64 @@ -245,12 +245,14 @@ %define define_legacy_variant() \ %{expand:%%package %%{1}} \ Summary: Bootloader with support for Linux, Multiboot, and more \ +Group: System Environment/Base \ Provides: %{name} = %{evr} \ Obsoletes: %{name} < %{evr} \ Requires: %{name}-common = %{evr} \ Requires: %{name}-tools-minimal = %{evr} \ Requires: %{name}-%{1}-modules = %{evr} \ -Requires: gettext-runtime which file \ +Requires: gettext which file \ +Requires: %{name}-tools-extra = %{evr} \ Requires: %{name}-tools = %{evr} \ Requires(pre): dracut \ Requires(post): dracut \ @@ -262,6 +264,7 @@ This subpackage provides support for %{1} systems. \ %{expand:%%if 0%%{with_legacy_modules} \ %%package %%{1}-modules \ Summary: Modules used to build custom grub images \ +Group: System Environment/Base \ BuildArch: noarch \ Requires: %%{name}-common = %%{evr} \ %%description %%{1}-modules \ @@ -273,10 +276,12 @@ This subpackage provides support for rebuilding your own grub.efi. \ %{expand:%%{?!buildsubdir:%%define buildsubdir grub-%%{1}-%{tarversion}}}\ %{expand:%%package %%{1}-tools} \ Summary: Support tools for GRUB. \ -Requires: gettext-runtime os-prober which file system-logos \ +Group: System Environment/Base \ +Requires: gettext os-prober which file system-logos \ Requires: %{name}-common = %{evr} \ Requires: %{name}-tools-minimal = %{evr} \ Requires: os-prober >= 1.58-11 \ +Requires: gettext which file \ \ %{expand:%%description %%{1}-tools} \ %{desc} \ @@ -286,10 +291,14 @@ This subpackage provides tools for support of %%{1} platforms. \ %define define_efi_variant(o) \ %{expand:%%package %{1}} \ Summary: GRUB for EFI systems. \ +Group: System Environment/Base \ Requires: efi-filesystem \ Requires: %{name}-common = %{evr} \ Requires: %{name}-tools-minimal >= %{evr} \ +Requires: %{name}-tools-extra = %{evr} \ Requires: %{name}-tools = %{evr} \ +Requires(pre): %{name}-tools = %{evr} \ +Requires(postun): %{name}-tools = %{evr} \ Provides: %{name}-efi = %{evr} \ %{?legacy_provides:Provides: %{name} = %{evr}} \ %{-o:Obsoletes: %{name}-efi < %{evr}} \ @@ -297,11 +306,25 @@ Provides: %{name}-efi = %{evr} \ %{expand:%%description %{1}} \ %{desc} \ This subpackage provides support for %{1} systems. \ +%pre %{1} \ +res=$(grub2-probe /boot) \ +if [ "xvfat" != "x$res" -a "xfat" != "x$res" ]; then \ + ln -sf ../efi/EFI/%{efi_vendor}/grubenv /boot/grub2/grubenv \ +fi \ + \ +%postun %{1} \ +if [ "x0" == "x$1" ]; then \ + res=$(grub2-probe /boot) \ + if [ "xvfat" != "x$res" -a "xfat" != "x$res" ]; then \ + rm -f /boot/grub2/grubenv \ + fi \ +fi \ \ %{expand:%%{?!buildsubdir:%%define buildsubdir grub-%{1}-%{tarversion}}}\ %{expand:%if 0%{?with_efi_modules} \ %{expand:%%package %{1}-modules} \ Summary: Modules used to build custom grub.efi images \ +Group: System Environment/Base \ BuildArch: noarch \ Requires: %{name}-common = %{evr} \ Provides: %{name}-efi-modules = %{evr} \ @@ -313,6 +336,7 @@ This subpackage provides support for rebuilding your own grub.efi. \ \ %{expand:%%package %{1}-cdboot} \ Summary: Files used to boot removeable media with EFI \ +Group: System Environment/Base \ Requires: %{name}-common = %{evr} \ Provides: %{name}-efi-cdboot = %{evr} \ %{expand:%%description %{1}-cdboot} \ @@ -324,42 +348,49 @@ This subpackage provides optional components of grub used with removeable media %setup -q -n grub-%{tarversion} \ rm -fv docs/*.info \ cp %{SOURCE6} .gitignore \ -cp %{SOURCE7} bootstrap \ -cp %{SOURCE8} bootstrap.conf \ cp %{SOURCE9} ./grub-core/tests/strtoull_test.c \ -cp %{SOURCE2} gnulib-%{gnulibversion}.tar.gz \ -tar -zxf gnulib-%{gnulibversion}.tar.gz \ -mv gnulib-%{gnulibversion} gnulib \ +cp %{SOURCE11} bootstrap \ +cp %{SOURCE12} bootstrap.conf \ +#cp %{SOURCE8} gnulib-%{gnulibversion}.tar.gz \ +#tar -zxf gnulib-%{gnulibversion}.tar.gz \ +#mv gnulib-%{gnulibversion} gnulib \ git init \ echo '![[:digit:]][[:digit:]]_*.in' > util/grub.d/.gitignore \ echo '!*.[[:digit:]]' > util/.gitignore \ echo '!config.h' > include/grub/emu/.gitignore \ -git config user.email "%{name}-owner@fedoraproject.org" \ -git config user.name "Fedora Ninjas" \ +git config user.email "buildteam@%{efi_vendor}.org" \ +git config user.name "%{efi_vendor} Buildteam" \ git config gc.auto 0 \ rm -f configure \ git add . \ git commit -a -q -m "%{tarversion} baseline." \ -git am --whitespace=nowarn %%{patches} +Date: Tue, 26 Apr 2016 15:29:25 +0200 +Subject: [PATCH v3] Add hidden menu entries + +The menu infrastructure is quite powerful. It allows you to define menu +entries that can contain arbitrary grub commands that can do a lot more +than just boot kernel entries. + +For some of these it makes sense to hide them inside the normal menu +though and instead have them available through hotkeys that get advertised +differently. My main use case is to switch to the serial console when +gfxterm is loaded. + +So this patch adds support for hidden menu entries that are accessible +using hotkeys, but are not accessible in the grub menu. + +Signed-off-by: Alexander Graf + +--- + +v1 -> v2: + + - fix default entry selection + +v2 -> v3: + + - replace "--hidden" parameter with new command "hiddenentry" + +--- a/grub-core/commands/legacycfg.c ++++ b/grub-core/commands/legacycfg.c +@@ -143,7 +143,7 @@ + args[0] = oldname; + grub_normal_add_menu_entry (1, args, NULL, NULL, "legacy", + NULL, NULL, +- entrysrc, 0); ++ entrysrc, 0, 0); + grub_free (args); + entrysrc[0] = 0; + grub_free (oldname); +@@ -205,7 +205,7 @@ + } + args[0] = entryname; + grub_normal_add_menu_entry (1, args, NULL, NULL, NULL, +- NULL, NULL, entrysrc, 0); ++ NULL, NULL, entrysrc, 0, 0); + grub_free (args); + } + +--- a/grub-core/commands/menuentry.c ++++ b/grub-core/commands/menuentry.c +@@ -78,7 +78,7 @@ + char **classes, const char *id, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode, +- int submenu) ++ int submenu, int hidden) + { + int menu_hotkey = 0; + char **menu_args = NULL; +@@ -188,8 +188,11 @@ + (*last)->args = menu_args; + (*last)->sourcecode = menu_sourcecode; + (*last)->submenu = submenu; ++ (*last)->hidden = hidden; ++ ++ if (!hidden) ++ menu->size++; + +- menu->size++; + return GRUB_ERR_NONE; + + fail: +@@ -286,7 +289,8 @@ + users, + ctxt->state[2].arg, 0, + ctxt->state[3].arg, +- ctxt->extcmd->cmd->name[0] == 's'); ++ ctxt->extcmd->cmd->name[0] == 's', ++ ctxt->extcmd->cmd->name[0] == 'h'); + + src = args[argc - 1]; + args[argc - 1] = NULL; +@@ -303,7 +307,8 @@ + ctxt->state[0].args, ctxt->state[4].arg, + users, + ctxt->state[2].arg, prefix, src + 1, +- ctxt->extcmd->cmd->name[0] == 's'); ++ ctxt->extcmd->cmd->name[0] == 's', ++ ctxt->extcmd->cmd->name[0] == 'h'); + + src[len - 1] = ch; + args[argc - 1] = src; +@@ -311,7 +316,7 @@ + return r; + } + +-static grub_extcmd_t cmd, cmd_sub; ++static grub_extcmd_t cmd, cmd_sub, cmd_hidden; + + void + grub_menu_init (void) +@@ -327,6 +332,13 @@ + | GRUB_COMMAND_FLAG_EXTRACTOR, + N_("BLOCK"), N_("Define a submenu."), + options); ++ cmd_hidden = grub_register_extcmd ("hiddenentry", grub_cmd_menuentry, ++ GRUB_COMMAND_FLAG_BLOCKS ++ | GRUB_COMMAND_ACCEPT_DASH ++ | GRUB_COMMAND_FLAG_EXTRACTOR, ++ N_("BLOCK"), ++ N_("Define a hidden menu entry."), ++ options); + } + + void +--- a/grub-core/normal/menu.c ++++ b/grub-core/normal/menu.c +@@ -40,6 +40,8 @@ + grub_err_t (*grub_gfxmenu_try_hook) (int entry, grub_menu_t menu, + int nested) = NULL; + ++#define MENU_INCLUDE_HIDDEN 0x10000 ++ + enum timeout_style { + TIMEOUT_STYLE_MENU, + TIMEOUT_STYLE_COUNTDOWN, +@@ -80,8 +82,20 @@ + { + grub_menu_entry_t e; + +- for (e = menu->entry_list; e && no > 0; e = e->next, no--) +- ; ++ if (no & MENU_INCLUDE_HIDDEN) { ++ no &= ~MENU_INCLUDE_HIDDEN; ++ ++ for (e = menu->entry_list; e && no > 0; e = e->next, no--) ++ ; ++ } else { ++ for (e = menu->entry_list; e && no > 0; e = e->next, no--) { ++ /* Skip hidden entries */ ++ while (e && e->hidden) ++ e = e->next; ++ } ++ while (e && e->hidden) ++ e = e->next; ++ } + + return e; + } +@@ -93,10 +107,10 @@ + grub_menu_entry_t entry; + int i; + +- for (i = 0, entry = menu->entry_list; i < menu->size; ++ for (i = 0, entry = menu->entry_list; entry; + i++, entry = entry->next) + if (entry->hotkey == hotkey) +- return i; ++ return i | MENU_INCLUDE_HIDDEN; + + return -1; + } +@@ -519,6 +533,10 @@ + grub_menu_entry_t e = menu->entry_list; + int i; + ++ /* Skip hidden entries */ ++ while (e && e->hidden) ++ e = e->next; ++ + grub_errno = GRUB_ERR_NONE; + + for (i = 0; e; i++) +@@ -530,6 +548,10 @@ + break; + } + e = e->next; ++ ++ /* Skip hidden entries */ ++ while (e && e->hidden) ++ e = e->next; + } + + if (! e) +--- a/grub-core/normal/menu_text.c ++++ b/grub-core/normal/menu_text.c +@@ -318,6 +318,10 @@ + e, data); + if (e) + e = e->next; ++ ++ /* Skip hidden entries */ ++ while (e && e->hidden) ++ e = e->next; + } + + grub_term_gotoxy (data->term, +--- a/include/grub/menu.h ++++ b/include/grub/menu.h +@@ -58,6 +58,8 @@ + + int submenu; + ++ int hidden; ++ + /* The next element. */ + struct grub_menu_entry *next; + }; +--- a/include/grub/normal.h ++++ b/include/grub/normal.h +@@ -145,7 +145,7 @@ + const char *id, + const char *users, const char *hotkey, + const char *prefix, const char *sourcecode, +- int submenu); ++ int submenu, int hidden); + + grub_err_t + grub_normal_set_password (const char *user, const char *password); diff --git a/grub2-SUSE-Add-the-t-hotkey.patch b/grub2-SUSE-Add-the-t-hotkey.patch new file mode 100644 index 0000000000000000000000000000000000000000..58608d07673d63df64a16318bf068aaeb740ee3c --- /dev/null +++ b/grub2-SUSE-Add-the-t-hotkey.patch @@ -0,0 +1,66 @@ +From f6be3d41e24e685846dfc90ac1ca447501813687 Mon Sep 17 00:00:00 2001 +From: Alexander Graf +Date: Tue, 26 Apr 2016 15:59:03 +0200 +Subject: [PATCH] SUSE: Add the "t" hotkey + +While graphical output is fancy and nice, in some environments (EFI) we can +only have fancy graphical on frame buffer _or_ ugly serial on any output. + +To give the user a nicely graphical screen in the default case, but still +allow them to get their boot menu on the serial console, let's add a new +hidden option "t" that switches the output device back to the firmware default. + +Signed-off-by: Alexander Graf +--- + +v1 -> v2 + + - use hiddenentry instead of --hidden + +v2 -> v3 (by fvogt@suse.de) + + - make it a runtime decision (bsc#1164385) + +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -552,6 +552,12 @@ + installdir = grubconf; + }; + ++script = { ++ name = '95_textmode'; ++ common = util/grub.d/95_textmode.in; ++ installdir = grubconf; ++}; ++ + program = { + mansection = 1; + name = grub-mkrescue; +--- a/util/grub.d/00_header.in ++++ b/util/grub.d/00_header.in +@@ -247,6 +247,10 @@ + fi + + cat << EOF ++ if [ "\${grub_platform}" = "efi" ]; then ++ echo "Please press 't' to show the boot menu on this console" ++ fi ++ + set gfxmode=${GRUB_GFXMODE} + load_video + insmod gfxterm +--- /dev/null ++++ b/util/grub.d/95_textmode.in +@@ -0,0 +1,12 @@ ++#!/bin/sh ++ ++cat < +Date: Thu, 29 Feb 2024 10:07:58 +000 +Subject: Make bash completion work with version 2.12 and before 2.11 + +Note that the shell function have() had become deprecated with 2.11 +and had been removed from 2.12 which is now providing _comp_have_command() + +resolves boo#1220626 + +--- + util/bash-completion.d/grub-completion.bash.in | 38 ++++++++++++++++--------- + 1 file changed, 25 insertions(+), 13 deletions(-) + +--- a/util/bash-completion.d/grub-completion.bash.in ++++ b/util/bash-completion.d/grub-completion.bash.in 2024-02-29 10:04:52.197876569 +0000 +@@ -17,6 +17,18 @@ + # along with GRUB. If not, see . + # bash completion for grub + ++if test "$(type -t _comp_have_command)" = function ++then ++ _have() { ++ _comp_have_command $1 ++ } ++elif test "$(type -t have)" = function ++then ++ _have() { ++ have $1 ++ } ++fi ++ + __grub_dir() { + local i c=1 boot_dir + +@@ -177,12 +189,12 @@ _grub_set_entry () { + } + + __grub_set_default_program="@grub_set_default@" +-have ${__grub_set_default_program} && \ ++_have ${__grub_set_default_program} && \ + complete -F _grub_set_entry -o filenames ${__grub_set_default_program} + unset __grub_set_default_program + + __grub_reboot_program="@grub_reboot@" +-have ${__grub_reboot_program} && \ ++_have ${__grub_reboot_program} && \ + complete -F _grub_set_entry -o filenames ${__grub_reboot_program} + unset __grub_reboot_program + +@@ -209,7 +221,7 @@ _grub_editenv () { + } + + __grub_editenv_program="@grub_editenv@" +-have ${__grub_editenv_program} && \ ++_have ${__grub_editenv_program} && \ + complete -F _grub_editenv -o filenames ${__grub_editenv_program} + unset __grub_editenv_program + +@@ -230,7 +242,7 @@ _grub_mkconfig () { + fi + } + __grub_mkconfig_program="@grub_mkconfig@" +-have ${__grub_mkconfig_program} && \ ++_have ${__grub_mkconfig_program} && \ + complete -F _grub_mkconfig -o filenames ${__grub_mkconfig_program} + unset __grub_mkconfig_program + +@@ -265,12 +277,12 @@ _grub_setup () { + } + + __grub_bios_setup_program="@grub_bios_setup@" +-have ${__grub_bios_setup_program} && \ ++_have ${__grub_bios_setup_program} && \ + complete -F _grub_setup -o filenames ${__grub_bios_setup_program} + unset __grub_bios_setup_program + + __grub_sparc64_setup_program="@grub_sparc64_setup@" +-have ${__grub_sparc64_setup_program} && \ ++_have ${__grub_sparc64_setup_program} && \ + complete -F _grub_setup -o filenames ${__grub_sparc64_setup_program} + unset __grub_sparc64_setup_program + +@@ -316,7 +328,7 @@ _grub_install () { + fi + } + __grub_install_program="@grub_install@" +-have ${__grub_install_program} && \ ++_have ${__grub_install_program} && \ + complete -F _grub_install -o filenames ${__grub_install_program} + unset __grub_install_program + +@@ -338,7 +350,7 @@ _grub_mkfont () { + fi + } + __grub_mkfont_program="@grub_mkfont@" +-have ${__grub_mkfont_program} && \ ++_have ${__grub_mkfont_program} && \ + complete -F _grub_mkfont -o filenames ${__grub_mkfont_program} + unset __grub_mkfont_program + +@@ -369,7 +381,7 @@ _grub_mkrescue () { + fi + } + __grub_mkrescue_program="@grub_mkrescue@" +-have ${__grub_mkrescue_program} && \ ++_have ${__grub_mkrescue_program} && \ + complete -F _grub_mkrescue -o filenames ${__grub_mkrescue_program} + unset __grub_mkrescue_program + +@@ -411,7 +423,7 @@ _grub_mkimage () { + fi + } + __grub_mkimage_program="@grub_mkimage@" +-have ${__grub_mkimage_program} && \ ++_have ${__grub_mkimage_program} && \ + complete -F _grub_mkimage -o filenames ${__grub_mkimage_program} + unset __grub_mkimage_program + +@@ -433,7 +445,7 @@ _grub_mkpasswd_pbkdf2 () { + fi + } + __grub_mkpasswd_pbkdf2_program="@grub_mkpasswd_pbkdf2@" +-have ${__grub_mkpasswd_pbkdf2_program} && \ ++_have ${__grub_mkpasswd_pbkdf2_program} && \ + complete -F _grub_mkpasswd_pbkdf2 -o filenames ${__grub_mkpasswd_pbkdf2_program} + unset __grub_mkpasswd_pbkdf2_program + +@@ -471,7 +483,7 @@ _grub_probe () { + fi + } + __grub_probe_program="@grub_probe@" +-have ${__grub_probe_program} && \ ++_have ${__grub_probe_program} && \ + complete -F _grub_probe -o filenames ${__grub_probe_program} + unset __grub_probe_program + +@@ -493,7 +505,7 @@ _grub_script_check () { + fi + } + __grub_script_check_program="@grub_script_check@" +-have ${__grub_script_check_program} && \ ++_have ${__grub_script_check_program} && \ + complete -F _grub_script_check -o filenames ${__grub_script_check_program} + + diff --git a/0044-grub2-btrfs-Add-ability-to-boot-from-subvolumes.patch b/grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch similarity index 86% rename from 0044-grub2-btrfs-Add-ability-to-boot-from-subvolumes.patch rename to grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch index 68dfc1dc9badcb84c1357847b730a724afb39785..1579fa61a22ff73200b8efb27a2e67f841c2df84 100644 --- a/0044-grub2-btrfs-Add-ability-to-boot-from-subvolumes.patch +++ b/grub2-btrfs-01-add-ability-to-boot-from-subvolumes.patch @@ -1,7 +1,5 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Jeff Mahoney -Date: Tue, 9 Jul 2019 13:39:45 +0200 -Subject: [PATCH] grub2/btrfs: Add ability to boot from subvolumes +Subject: grub2/btrfs: Add ability to boot from subvolumes This patch adds the ability to specify a different root on a btrfs filesystem too boot from other than the default one. @@ -18,26 +16,34 @@ It is possible to boot into a separate GRUB instance by exporting the variable and loading the config file from the subvolume. Signed-off-by: Jeff Mahoney + +V1: + * Use overflow checking primitives where the arithmetic expression for + buffer allocations may include unvalidated data + +V2: + * Fix gcc-12 error: the comparison will always evaluate as 'true' for the + address of 'label' will never be NULL [-Werror=address] + --- - grub-core/fs/btrfs.c | 552 +++++++++++++++++++++++++++++++++++++++++++++++++-- - include/grub/btrfs.h | 1 + - 2 files changed, 533 insertions(+), 20 deletions(-) -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 63203034dfc..f1fff7385b5 100644 + grub-core/fs/btrfs.c | 561 +++++++++++++++++++++++++++++++++++++++++++++++++-- + include/grub/btrfs.h | 1 + 2 files changed, 544 insertions(+), 18 deletions(-) + --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c -@@ -38,6 +38,9 @@ - #include - #include - #include -+#include -+#include -+#include +@@ -41,6 +41,9 @@ #include #include #include -@@ -79,9 +82,11 @@ struct grub_btrfs_superblock ++#include ++#include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -79,9 +82,11 @@ grub_uint64_t generation; grub_uint64_t root_tree; grub_uint64_t chunk_tree; @@ -51,7 +57,7 @@ index 63203034dfc..f1fff7385b5 100644 struct grub_btrfs_device this_device; char label[0x100]; grub_uint8_t dummy4[0x100]; -@@ -121,6 +126,7 @@ struct grub_btrfs_data +@@ -121,6 +126,7 @@ grub_uint64_t exttree; grub_size_t extsize; struct grub_btrfs_extent_data *extent; @@ -59,7 +65,7 @@ index 63203034dfc..f1fff7385b5 100644 }; struct grub_btrfs_chunk_item -@@ -191,6 +197,14 @@ struct grub_btrfs_leaf_descriptor +@@ -191,6 +197,14 @@ } *data; }; @@ -74,7 +80,7 @@ index 63203034dfc..f1fff7385b5 100644 struct grub_btrfs_time { grub_int64_t sec; -@@ -236,6 +250,14 @@ struct grub_btrfs_extent_data +@@ -236,6 +250,14 @@ #define GRUB_BTRFS_OBJECT_ID_CHUNK 0x100 @@ -89,7 +95,7 @@ index 63203034dfc..f1fff7385b5 100644 static grub_disk_addr_t superblock_sectors[] = { 64 * 2, 64 * 1024 * 2, 256 * 1048576 * 2, 1048576ULL * 1048576ULL * 2 }; -@@ -1173,6 +1195,62 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, +@@ -1252,6 +1274,62 @@ return GRUB_ERR_NONE; } @@ -152,7 +158,7 @@ index 63203034dfc..f1fff7385b5 100644 static struct grub_btrfs_data * grub_btrfs_mount (grub_device_t dev) { -@@ -1208,6 +1286,13 @@ grub_btrfs_mount (grub_device_t dev) +@@ -1287,6 +1365,13 @@ data->devices_attached[0].dev = dev; data->devices_attached[0].id = data->sblock.this_device.device_id; @@ -166,11 +172,10 @@ index 63203034dfc..f1fff7385b5 100644 return data; } -@@ -1673,6 +1758,91 @@ get_root (struct grub_btrfs_data *data, struct grub_btrfs_key *key, - return GRUB_ERR_NONE; +@@ -1783,6 +1868,98 @@ } -+static grub_err_t + static grub_err_t +find_pathname(struct grub_btrfs_data *data, grub_uint64_t objectid, + grub_uint64_t fs_root, const char *name, char **pathname) +{ @@ -210,8 +215,12 @@ index 63203034dfc..f1fff7385b5 100644 + key_out.object_id != key_out.offset) { + struct grub_btrfs_inode_ref *inode_ref; + char *new; ++ grub_size_t sz; ++ ++ if (grub_add (elemsize, 1, &sz)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); + -+ inode_ref = grub_malloc(elemsize + 1); ++ inode_ref = grub_malloc(sz); + if (!inode_ref) + return grub_error(GRUB_ERR_OUT_OF_MEMORY, + "couldn't allocate memory for inode_ref (%"PRIuGRUB_SIZE")\n", elemsize); @@ -220,7 +229,10 @@ index 63203034dfc..f1fff7385b5 100644 + if (err) + return grub_error(err, "read_logical caught %d\n", err); + -+ alloc += grub_le_to_cpu16 (inode_ref->n) + 2; ++ if (grub_add (grub_le_to_cpu16 (inode_ref->n), 2, &sz) || ++ grub_add (alloc, sz, &alloc)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ + new = grub_malloc(alloc); + if (!new) + return grub_error(GRUB_ERR_OUT_OF_MEMORY, @@ -255,10 +267,11 @@ index 63203034dfc..f1fff7385b5 100644 + return 0; +} + - static grub_err_t ++static grub_err_t find_path (struct grub_btrfs_data *data, const char *path, struct grub_btrfs_key *key, -@@ -1691,14 +1861,26 @@ find_path (struct grub_btrfs_data *data, + grub_uint64_t *tree, grub_uint8_t *type) +@@ -1800,14 +1977,26 @@ char *origpath = NULL; unsigned symlinks_max = 32; @@ -289,15 +302,18 @@ index 63203034dfc..f1fff7385b5 100644 while (1) { while (path[0] == '/') -@@ -1871,9 +2053,21 @@ find_path (struct grub_btrfs_data *data, +@@ -1980,13 +2169,25 @@ path = path_alloc = tmp; if (path[0] == '/') { - err = get_root (data, key, tree, type); - if (err) -- return err; + if (data->fs_tree) -+ { + { +- grub_free (direl); +- grub_free (path_alloc); +- grub_free (origpath); +- return err; + *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; + *tree = data->fs_tree; + /* This is a tree root, so everything starts at objectid 256 */ @@ -309,55 +325,54 @@ index 63203034dfc..f1fff7385b5 100644 + { + err = get_root (data, key, tree, type); + if (err) -+ return err; -+ } ++ { ++ grub_free (direl); ++ grub_free (path_alloc); ++ grub_free (origpath); ++ return err; ++ } + } } continue; - } -@@ -2114,18 +2308,10 @@ grub_btrfs_read (grub_file_t file, char *buf, grub_size_t len) +@@ -2254,6 +2455,20 @@ data->tree, file->offset, buf, len); } --static grub_err_t --grub_btrfs_uuid (grub_device_t device, char **uuid) +static char * +btrfs_unparse_uuid(struct grub_btrfs_data *data) - { -- struct grub_btrfs_data *data; -- -- *uuid = NULL; -- -- data = grub_btrfs_mount (device); -- if (!data) -- return grub_errno; -- -- *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", ++{ + return grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", - grub_be_to_cpu16 (data->sblock.uuid[0]), - grub_be_to_cpu16 (data->sblock.uuid[1]), - grub_be_to_cpu16 (data->sblock.uuid[2]), -@@ -2134,6 +2320,20 @@ grub_btrfs_uuid (grub_device_t device, char **uuid) - grub_be_to_cpu16 (data->sblock.uuid[5]), - grub_be_to_cpu16 (data->sblock.uuid[6]), - grub_be_to_cpu16 (data->sblock.uuid[7])); ++ grub_be_to_cpu16 (data->sblock.uuid[0]), ++ grub_be_to_cpu16 (data->sblock.uuid[1]), ++ grub_be_to_cpu16 (data->sblock.uuid[2]), ++ grub_be_to_cpu16 (data->sblock.uuid[3]), ++ grub_be_to_cpu16 (data->sblock.uuid[4]), ++ grub_be_to_cpu16 (data->sblock.uuid[5]), ++ grub_be_to_cpu16 (data->sblock.uuid[6]), ++ grub_be_to_cpu16 (data->sblock.uuid[7])); +} + -+static grub_err_t -+grub_btrfs_uuid (grub_device_t device, char **uuid) -+{ -+ struct grub_btrfs_data *data; -+ -+ *uuid = NULL; -+ -+ data = grub_btrfs_mount (device); -+ if (!data) -+ return grub_errno; -+ + static grub_err_t + grub_btrfs_uuid (grub_device_t device, char **uuid) + { +@@ -2265,15 +2480,7 @@ + if (!data) + return grub_errno; + +- *uuid = grub_xasprintf ("%04x%04x-%04x-%04x-%04x-%04x%04x%04x", +- grub_be_to_cpu16 (data->sblock.uuid[0]), +- grub_be_to_cpu16 (data->sblock.uuid[1]), +- grub_be_to_cpu16 (data->sblock.uuid[2]), +- grub_be_to_cpu16 (data->sblock.uuid[3]), +- grub_be_to_cpu16 (data->sblock.uuid[4]), +- grub_be_to_cpu16 (data->sblock.uuid[5]), +- grub_be_to_cpu16 (data->sblock.uuid[6]), +- grub_be_to_cpu16 (data->sblock.uuid[7])); + *uuid = btrfs_unparse_uuid(data); grub_btrfs_unmount (data); -@@ -2190,6 +2390,242 @@ grub_btrfs_embed (grub_device_t device __attribute__ ((unused)), +@@ -2394,6 +2601,248 @@ } #endif @@ -390,7 +405,7 @@ index 63203034dfc..f1fff7385b5 100644 + return grub_error (GRUB_ERR_BAD_ARGUMENT, "failed to open fs"); + } + -+ if (data->sblock.label) ++ if (*data->sblock.label != '\0') + grub_printf("Label: '%s' ", data->sblock.label); + else + grub_printf("Label: none "); @@ -538,9 +553,15 @@ index 63203034dfc..f1fff7385b5 100644 + + if (elemsize > allocated) + { ++ grub_size_t sz; ++ + grub_free(buf); -+ allocated = 2 * elemsize; -+ buf = grub_malloc(allocated + 1); ++ ++ if (grub_mul (elemsize, 2, &allocated) || ++ grub_add (allocated, 1, &sz)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ ++ buf = grub_malloc(sz); + if (!buf) + { + r = -grub_errno; @@ -600,7 +621,7 @@ index 63203034dfc..f1fff7385b5 100644 static struct grub_fs grub_btrfs_fs = { .name = "btrfs", .fs_dir = grub_btrfs_dir, -@@ -2205,12 +2641,88 @@ static struct grub_fs grub_btrfs_fs = { +@@ -2409,12 +2858,88 @@ #endif }; @@ -689,11 +710,9 @@ index 63203034dfc..f1fff7385b5 100644 } + +// vim: si et sw=2: -diff --git a/include/grub/btrfs.h b/include/grub/btrfs.h -index 9d93fb6c182..234ad976771 100644 --- a/include/grub/btrfs.h +++ b/include/grub/btrfs.h -@@ -29,6 +29,7 @@ enum +@@ -29,6 +29,7 @@ GRUB_BTRFS_ITEM_TYPE_ROOT_ITEM = 0x84, GRUB_BTRFS_ITEM_TYPE_ROOT_BACKREF = 0x90, GRUB_BTRFS_ITEM_TYPE_DEVICE = 0xd8, diff --git a/0045-export-btrfs_subvol-and-btrfs_subvolid.patch b/grub2-btrfs-02-export-subvolume-envvars.patch similarity index 52% rename from 0045-export-btrfs_subvol-and-btrfs_subvolid.patch rename to grub2-btrfs-02-export-subvolume-envvars.patch index d38a6b878db3366d4236c37971d1561dd6b846e4..61a5e25381781545aaa3fb2b6595f55ade6510bc 100644 --- a/0045-export-btrfs_subvol-and-btrfs_subvolid.patch +++ b/grub2-btrfs-02-export-subvolume-envvars.patch @@ -1,21 +1,14 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Michael Chang -Date: Wed, 18 Dec 2013 09:57:04 +0000 -Subject: [PATCH] export btrfs_subvol and btrfs_subvolid +Subject: export btrfs_subvol and btrfs_subvolid -We should export btrfs_subvol and btrfs_subvolid to have both visible -to subsidiary configuration files loaded using configfile. +We should export btrfs_subvol and btrfs_subvolid to have both visible +to subsidiary configuration files loaded using configfile. Signed-off-by: Michael Chang ---- - grub-core/fs/btrfs.c | 2 ++ - 1 file changed, 2 insertions(+) -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index f1fff7385b5..ad1b56b716d 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c -@@ -2714,6 +2714,8 @@ GRUB_MOD_INIT (btrfs) +@@ -2931,6 +2931,8 @@ subvol_set_env); grub_register_variable_hook ("btrfs_subvolid", subvolid_get_env, subvolid_set_env); diff --git a/0046-grub2-btrfs-03-follow_default.patch b/grub2-btrfs-03-follow_default.patch similarity index 81% rename from 0046-grub2-btrfs-03-follow_default.patch rename to grub2-btrfs-03-follow_default.patch index ca203f4a423d9f2bedbf85d8fbd3337b723eed5c..8c644dbbdb6adcd9afe53a73e449590bb830fb3a 100644 --- a/0046-grub2-btrfs-03-follow_default.patch +++ b/grub2-btrfs-03-follow_default.patch @@ -1,19 +1,6 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Thu, 21 Aug 2014 03:39:11 +0000 -Subject: [PATCH] grub2-btrfs-03-follow_default - -Signed-off-by: Michael Chang -Signed-off-by: Robbie Harwood ---- - grub-core/fs/btrfs.c | 107 ++++++++++++++++++++++++++++++++++++--------------- - 1 file changed, 76 insertions(+), 31 deletions(-) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index ad1b56b716d..113c1f746c9 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c -@@ -1256,6 +1256,7 @@ grub_btrfs_mount (grub_device_t dev) +@@ -1335,6 +1335,7 @@ { struct grub_btrfs_data *data; grub_err_t err; @@ -21,7 +8,7 @@ index ad1b56b716d..113c1f746c9 100644 if (!dev->disk) { -@@ -1286,11 +1287,14 @@ grub_btrfs_mount (grub_device_t dev) +@@ -1365,11 +1366,14 @@ data->devices_attached[0].dev = dev; data->devices_attached[0].id = data->sblock.this_device.device_id; @@ -40,7 +27,7 @@ index ad1b56b716d..113c1f746c9 100644 } return data; -@@ -1855,24 +1859,39 @@ find_path (struct grub_btrfs_data *data, +@@ -1971,24 +1975,39 @@ grub_size_t allocated = 0; struct grub_btrfs_dir_item *direl = NULL; struct grub_btrfs_key key_out; @@ -87,7 +74,7 @@ index ad1b56b716d..113c1f746c9 100644 } else { -@@ -1883,15 +1902,23 @@ find_path (struct grub_btrfs_data *data, +@@ -1999,15 +2018,23 @@ while (1) { @@ -120,7 +107,7 @@ index ad1b56b716d..113c1f746c9 100644 if (*type != GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY) { -@@ -1902,7 +1929,9 @@ find_path (struct grub_btrfs_data *data, +@@ -2018,7 +2045,9 @@ if (ctokenlen == 1 && ctoken[0] == '.') { @@ -131,7 +118,7 @@ index ad1b56b716d..113c1f746c9 100644 continue; } if (ctokenlen == 2 && ctoken[0] == '.' && ctoken[1] == '.') -@@ -1933,8 +1962,9 @@ find_path (struct grub_btrfs_data *data, +@@ -2049,8 +2078,9 @@ *type = GRUB_BTRFS_DIR_ITEM_TYPE_DIRECTORY; key->object_id = key_out.offset; @@ -143,7 +130,7 @@ index ad1b56b716d..113c1f746c9 100644 continue; } -@@ -2003,7 +2033,9 @@ find_path (struct grub_btrfs_data *data, +@@ -2119,7 +2149,9 @@ return err; } @@ -154,7 +141,7 @@ index ad1b56b716d..113c1f746c9 100644 if (cdirel->type == GRUB_BTRFS_DIR_ITEM_TYPE_SYMLINK) { struct grub_btrfs_inode inode; -@@ -2053,14 +2085,26 @@ find_path (struct grub_btrfs_data *data, +@@ -2169,14 +2201,26 @@ path = path_alloc = tmp; if (path[0] == '/') { @@ -188,7 +175,7 @@ index ad1b56b716d..113c1f746c9 100644 } else { -@@ -2716,6 +2760,7 @@ GRUB_MOD_INIT (btrfs) +@@ -2933,6 +2977,7 @@ subvolid_set_env); grub_env_export ("btrfs_subvol"); grub_env_export ("btrfs_subvolid"); diff --git a/0047-grub2-btrfs-04-grub2-install.patch b/grub2-btrfs-04-grub2-install.patch similarity index 62% rename from 0047-grub2-btrfs-04-grub2-install.patch rename to grub2-btrfs-04-grub2-install.patch index 451f61d780cd7dfa8976bf4b7ae4611937b0f140..e676fdf12925ccec16064b1875890a506e87253a 100644 --- a/0047-grub2-btrfs-04-grub2-install.patch +++ b/grub2-btrfs-04-grub2-install.patch @@ -1,49 +1,6 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Thu, 21 Aug 2014 03:39:11 +0000 -Subject: [PATCH] grub2-btrfs-04-grub2-install - -Signed-off-by: Michael Chang -Signed-off-by: Robbie Harwood ---- - grub-core/osdep/linux/getroot.c | 7 +++++++ - grub-core/osdep/unix/config.c | 17 +++++++++++++++-- - util/config.c | 10 ++++++++++ - util/grub-install.c | 15 +++++++++++++++ - util/grub-mkrelpath.c | 6 ++++++ - include/grub/emu/config.h | 1 + - 6 files changed, 54 insertions(+), 2 deletions(-) - -diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c -index 001b818fe58..caf9b1ccd3f 100644 ---- a/grub-core/osdep/linux/getroot.c -+++ b/grub-core/osdep/linux/getroot.c -@@ -376,6 +376,7 @@ get_btrfs_fs_prefix (const char *mount_path) - return NULL; - } - -+int use_relative_path_on_btrfs = 0; - - char ** - grub_find_root_devices_from_mountinfo (const char *dir, char **relroot) -@@ -519,6 +520,12 @@ again: - { - ret = grub_find_root_devices_from_btrfs (dir); - fs_prefix = get_btrfs_fs_prefix (entries[i].enc_path); -+ if (use_relative_path_on_btrfs) -+ { -+ if (fs_prefix) -+ free (fs_prefix); -+ fs_prefix = xstrdup ("/"); -+ } - } - else if (!retry && grub_strcmp (entries[i].fstype, "autofs") == 0) - { -diff --git a/grub-core/osdep/unix/config.c b/grub-core/osdep/unix/config.c -index 7d6325138ce..46a881530c0 100644 --- a/grub-core/osdep/unix/config.c +++ b/grub-core/osdep/unix/config.c -@@ -82,6 +82,19 @@ grub_util_load_config (struct grub_util_config *cfg) +@@ -207,6 +207,19 @@ if (v) cfg->grub_distributor = xstrdup (v); @@ -63,7 +20,7 @@ index 7d6325138ce..46a881530c0 100644 cfgfile = grub_util_get_config_filename (); if (!grub_util_is_regular (cfgfile)) return; -@@ -105,8 +118,8 @@ grub_util_load_config (struct grub_util_config *cfg) +@@ -230,8 +243,8 @@ *ptr++ = *iptr; } @@ -74,11 +31,19 @@ index 7d6325138ce..46a881530c0 100644 argv[2] = script; argv[3] = '\0'; -diff --git a/util/config.c b/util/config.c -index ebcdd8f5e22..f044a880a76 100644 +--- a/include/grub/emu/config.h ++++ b/include/grub/emu/config.h +@@ -37,6 +37,7 @@ + { + int is_cryptodisk_enabled; + char *grub_distributor; ++ int is_suse_btrfs_snapshot_enabled; + }; + + void --- a/util/config.c +++ b/util/config.c -@@ -42,6 +42,16 @@ grub_util_parse_config (FILE *f, struct grub_util_config *cfg, int simple) +@@ -42,6 +42,16 @@ cfg->is_cryptodisk_enabled = 1; continue; } @@ -95,20 +60,18 @@ index ebcdd8f5e22..f044a880a76 100644 if (grub_strncmp (ptr, "GRUB_DISTRIBUTOR=", sizeof ("GRUB_DISTRIBUTOR=") - 1) == 0) { -diff --git a/util/grub-install.c b/util/grub-install.c -index 0fbe7f78c6d..0f66f36d23a 100644 --- a/util/grub-install.c +++ b/util/grub-install.c -@@ -827,6 +827,8 @@ fill_core_services (const char *core_services) - free (sysv_plist); +@@ -857,6 +857,8 @@ } + #endif +extern int use_relative_path_on_btrfs; + int main (int argc, char *argv[]) { -@@ -860,6 +862,9 @@ main (int argc, char *argv[]) +@@ -890,6 +892,9 @@ grub_util_load_config (&config); @@ -118,11 +81,10 @@ index 0fbe7f78c6d..0f66f36d23a 100644 if (!bootloader_id && config.grub_distributor) { char *ptr; -@@ -1352,6 +1357,16 @@ main (int argc, char *argv[]) - fprintf (load_cfg_f, "set debug='%s'\n", - debug_image); +@@ -1451,6 +1456,15 @@ + debug_image); } -+ + + if (config.is_suse_btrfs_snapshot_enabled + && grub_strncmp(grub_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0) + { @@ -132,14 +94,35 @@ index 0fbe7f78c6d..0f66f36d23a 100644 + fprintf (load_cfg_f, "set btrfs_relative_path='y'\n"); + } + - char *prefix_drive = NULL; - char *install_drive = NULL; + if (!have_abstractions) + { + if ((disk_module && grub_strcmp (disk_module, "biosdisk") != 0) +--- a/grub-core/osdep/linux/getroot.c ++++ b/grub-core/osdep/linux/getroot.c +@@ -373,6 +373,7 @@ + return NULL; + } + ++int use_relative_path_on_btrfs = 0; -diff --git a/util/grub-mkrelpath.c b/util/grub-mkrelpath.c -index 47a241a391b..5db7a9a7d97 100644 + char ** + grub_find_root_devices_from_mountinfo (const char *dir, char **relroot) +@@ -516,6 +517,12 @@ + { + ret = grub_find_root_devices_from_btrfs (dir); + fs_prefix = get_btrfs_fs_prefix (entries[i].enc_path); ++ if (use_relative_path_on_btrfs) ++ { ++ if (fs_prefix) ++ free (fs_prefix); ++ fs_prefix = xstrdup ("/"); ++ } + } + else if (!retry && grub_strcmp (entries[i].fstype, "autofs") == 0) + { --- a/util/grub-mkrelpath.c +++ b/util/grub-mkrelpath.c -@@ -40,9 +40,12 @@ struct arguments +@@ -40,9 +40,12 @@ }; static struct argp_option options[] = { @@ -152,7 +135,7 @@ index 47a241a391b..5db7a9a7d97 100644 static error_t argp_parser (int key, char *arg, struct argp_state *state) { -@@ -52,6 +55,9 @@ argp_parser (int key, char *arg, struct argp_state *state) +@@ -52,6 +55,9 @@ switch (key) { @@ -162,15 +145,3 @@ index 47a241a391b..5db7a9a7d97 100644 case ARGP_KEY_ARG: if (state->arg_num == 0) arguments->pathname = xstrdup (arg); -diff --git a/include/grub/emu/config.h b/include/grub/emu/config.h -index 875d5896ce1..c9a7e5f4ade 100644 ---- a/include/grub/emu/config.h -+++ b/include/grub/emu/config.h -@@ -37,6 +37,7 @@ struct grub_util_config - { - int is_cryptodisk_enabled; - char *grub_distributor; -+ int is_suse_btrfs_snapshot_enabled; - }; - - void diff --git a/0048-grub2-btrfs-05-grub2-mkconfig.patch b/grub2-btrfs-05-grub2-mkconfig.patch similarity index 64% rename from 0048-grub2-btrfs-05-grub2-mkconfig.patch rename to grub2-btrfs-05-grub2-mkconfig.patch index 5afd183c44202ee43274d1dbd83bc6d1f8396b45..9e660a14c17d76e698884b8821947c4257860421 100644 --- a/0048-grub2-btrfs-05-grub2-mkconfig.patch +++ b/grub2-btrfs-05-grub2-mkconfig.patch @@ -1,36 +1,18 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Thu, 21 Aug 2014 03:39:11 +0000 -Subject: [PATCH] grub2-btrfs-05-grub2-mkconfig -Signed-off-by: Michael Chang +Always declare path specification in case of inconsistent declaration +elsewhere. (bsc#1209165) + --- - util/grub-mkconfig.in | 3 ++- - util/grub-mkconfig_lib.in | 4 ++++ - util/grub.d/00_header.in | 25 ++++++++++++++++++++++++- - util/grub.d/10_linux.in | 4 ++++ - util/grub.d/20_linux_xen.in | 4 ++++ - 5 files changed, 38 insertions(+), 2 deletions(-) + util/grub-mkconfig.in | 3 ++- + util/grub-mkconfig_lib.in | 4 ++++ + util/grub.d/00_header.in | 23 ++++++++++++++++++++++- + util/grub.d/10_linux.in | 11 ++++++++++- + util/grub.d/20_linux_xen.in | 4 ++++ + 5 files changed, 42 insertions(+), 3 deletions(-) -diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in -index 005f093809b..535c0f02499 100644 ---- a/util/grub-mkconfig.in -+++ b/util/grub-mkconfig.in -@@ -252,7 +252,8 @@ export GRUB_DEFAULT \ - GRUB_BADRAM \ - GRUB_OS_PROBER_SKIP_LIST \ - GRUB_DISABLE_SUBMENU \ -- GRUB_DEFAULT_DTB -+ GRUB_DEFAULT_DTB \ -+ SUSE_BTRFS_SNAPSHOT_BOOTING - - if test "x${grub_cfg}" != "x"; then - rm -f "${grub_cfg}.new" -diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in -index 42c2ea9ba50..fafeac95061 100644 --- a/util/grub-mkconfig_lib.in +++ b/util/grub-mkconfig_lib.in -@@ -52,7 +52,11 @@ grub_warn () +@@ -49,7 +49,11 @@ make_system_path_relative_to_its_root () { @@ -42,11 +24,9 @@ index 42c2ea9ba50..fafeac95061 100644 } is_path_readable_by_grub () -diff --git a/util/grub.d/00_header.in b/util/grub.d/00_header.in -index 858b526c925..de727e6ee6b 100644 --- a/util/grub.d/00_header.in +++ b/util/grub.d/00_header.in -@@ -27,6 +27,14 @@ export TEXTDOMAINDIR="@localedir@" +@@ -27,6 +27,21 @@ . "$pkgdatadir/grub-mkconfig_lib" @@ -56,29 +36,35 @@ index 858b526c925..de727e6ee6b 100644 +set btrfs_relative_path="y" +export btrfs_relative_path +EOF ++else ++# Always declare path specification in case of inconsistent declaration ++# elsewhere. (bsc#1209165) ++ cat </dev/null || true` -diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in -index ada20775a14..e9e73b815fb 100644 +@@ -295,7 +299,12 @@ + if [ $PLATFORM != "emu" ]; then + hotkey=0 + else +- rel_dirname=$dirname ++ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] && ++ [ "x${GRUB_FS}" = "xbtrfs" ] ; then ++ rel_dirname="\${btrfs_subvol}$dirname" ++ else ++ rel_dirname="$dirname" ++ fi + fi + version=`echo $basename | sed -e "s,^[^0-9]*-,,g"` + alt_version=`echo $version | sed -e "s,\.old$,,g"` --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in -@@ -73,10 +73,14 @@ fi +@@ -81,10 +81,14 @@ case x"$GRUB_FS" in xbtrfs) diff --git a/0049-grub2-btrfs-06-subvol-mount.patch b/grub2-btrfs-06-subvol-mount.patch similarity index 79% rename from 0049-grub2-btrfs-06-subvol-mount.patch rename to grub2-btrfs-06-subvol-mount.patch index 14117ab41c518ee2c2e4ab2e159ea004c568904e..e36c3441a4c6fd3375638d7516d28d75b0702e31 100644 --- a/0049-grub2-btrfs-06-subvol-mount.patch +++ b/grub2-btrfs-06-subvol-mount.patch @@ -1,30 +1,23 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Tue, 9 Jul 2019 13:56:16 +0200 -Subject: [PATCH] grub2-btrfs-06-subvol-mount -Signed-off-by: Michael Chang -Signed-off-by: Robbie Harwood ---- - grub-core/fs/btrfs.c | 195 +++++++++++++++++++++++++++++++++++++++- - grub-core/osdep/linux/getroot.c | 148 +++++++++++++++++++++++++++++- - util/grub-install.c | 49 ++++++++++ - include/grub/emu/getroot.h | 5 ++ - 4 files changed, 392 insertions(+), 5 deletions(-) +V2: +* Fix grub2-install --root-directory does not work for /boot/grub2/ on + separate btrfs subvolume (boo#1098420) + +v3: +* Fix executable stack on which function trampoline is constructed to support + closure (nested function). The closure sematic is replaced. -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 113c1f746c9..d323746ecfa 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c -@@ -41,6 +41,7 @@ +@@ -44,6 +44,7 @@ #include #include #include +#include - #include - #include - #include -@@ -266,6 +267,12 @@ static grub_err_t + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -266,6 +267,12 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr, void *buf, grub_size_t size, int recursion_depth); @@ -37,7 +30,7 @@ index 113c1f746c9..d323746ecfa 100644 static grub_err_t read_sblock (grub_disk_t disk, struct grub_btrfs_superblock *sb) -@@ -1223,9 +1230,26 @@ lookup_root_by_name(struct grub_btrfs_data *data, const char *path) +@@ -1302,9 +1309,26 @@ grub_err_t err; grub_uint64_t tree = 0; grub_uint8_t type; @@ -64,10 +57,10 @@ index 113c1f746c9..d323746ecfa 100644 if (err) return grub_error(GRUB_ERR_FILE_NOT_FOUND, "couldn't locate %s\n", path); -@@ -2199,11 +2223,20 @@ grub_btrfs_dir (grub_device_t device, const char *path, - int r = 0; +@@ -2321,11 +2345,20 @@ grub_uint64_t tree; grub_uint8_t type; + grub_size_t est_size = 0; + char *new_path = NULL; if (!data) @@ -86,7 +79,7 @@ index 113c1f746c9..d323746ecfa 100644 if (err) { grub_btrfs_unmount (data); -@@ -2305,11 +2338,21 @@ grub_btrfs_open (struct grub_file *file, const char *name) +@@ -2452,11 +2485,21 @@ struct grub_btrfs_inode inode; grub_uint8_t type; struct grub_btrfs_key key_in; @@ -109,7 +102,7 @@ index 113c1f746c9..d323746ecfa 100644 if (err) { grub_btrfs_unmount (data); -@@ -2480,6 +2523,150 @@ grub_cmd_btrfs_info (grub_command_t cmd __attribute__ ((unused)), int argc, +@@ -2691,6 +2734,150 @@ return 0; } @@ -260,7 +253,7 @@ index 113c1f746c9..d323746ecfa 100644 static grub_err_t get_fs_root(struct grub_btrfs_data *data, grub_uint64_t tree, grub_uint64_t objectid, grub_uint64_t offset, -@@ -2686,6 +2873,7 @@ static struct grub_fs grub_btrfs_fs = { +@@ -2903,6 +3090,7 @@ }; static grub_command_t cmd_info; @@ -268,7 +261,7 @@ index 113c1f746c9..d323746ecfa 100644 static grub_extcmd_t cmd_list_subvols; static char * -@@ -2749,6 +2937,9 @@ GRUB_MOD_INIT (btrfs) +@@ -2966,6 +3154,9 @@ cmd_info = grub_register_command("btrfs-info", grub_cmd_btrfs_info, "DEVICE", "Print BtrFS info about DEVICE."); @@ -278,11 +271,9 @@ index 113c1f746c9..d323746ecfa 100644 cmd_list_subvols = grub_register_extcmd("btrfs-list-subvols", grub_cmd_btrfs_list_subvols, 0, "[-p|-n] [-o var] DEVICE", -diff --git a/grub-core/osdep/linux/getroot.c b/grub-core/osdep/linux/getroot.c -index caf9b1ccd3f..28790307e00 100644 --- a/grub-core/osdep/linux/getroot.c +++ b/grub-core/osdep/linux/getroot.c -@@ -107,6 +107,14 @@ struct btrfs_ioctl_search_key +@@ -103,6 +103,14 @@ grub_uint32_t unused[9]; }; @@ -297,7 +288,7 @@ index caf9b1ccd3f..28790307e00 100644 struct btrfs_ioctl_search_args { struct btrfs_ioctl_search_key key; grub_uint64_t buf[(4096 - sizeof(struct btrfs_ioctl_search_key)) -@@ -378,6 +386,109 @@ get_btrfs_fs_prefix (const char *mount_path) +@@ -375,6 +383,109 @@ int use_relative_path_on_btrfs = 0; @@ -402,12 +393,12 @@ index caf9b1ccd3f..28790307e00 100644 + return NULL; +} + -+void (*grub_find_root_btrfs_mount_path_hook)(const char *mount_path); ++static char *grub_btrfs_mount_path; + char ** grub_find_root_devices_from_mountinfo (const char *dir, char **relroot) { -@@ -519,12 +630,15 @@ again: +@@ -516,12 +627,17 @@ else if (grub_strcmp (entries[i].fstype, "btrfs") == 0) { ret = grub_find_root_devices_from_btrfs (dir); @@ -417,8 +408,10 @@ index caf9b1ccd3f..28790307e00 100644 - if (fs_prefix) - free (fs_prefix); fs_prefix = xstrdup ("/"); -+ if (grub_find_root_btrfs_mount_path_hook) -+ grub_find_root_btrfs_mount_path_hook (entries[i].enc_path); ++ ++ if (grub_btrfs_mount_path) ++ grub_free (grub_btrfs_mount_path); ++ grub_btrfs_mount_path = grub_strdup (entries[i].enc_path); + } + else + { @@ -426,7 +419,7 @@ index caf9b1ccd3f..28790307e00 100644 } } else if (!retry && grub_strcmp (entries[i].fstype, "autofs") == 0) -@@ -1150,6 +1264,34 @@ grub_util_get_grub_dev_os (const char *os_dev) +@@ -1202,6 +1318,24 @@ return grub_dev; } @@ -434,38 +427,26 @@ index caf9b1ccd3f..28790307e00 100644 +char * +grub_util_get_btrfs_subvol (const char *path, char **mount_path) +{ -+ char *mp = NULL; -+ + if (mount_path) + *mount_path = NULL; + -+ auto void -+ mount_path_hook (const char *m) -+ { -+ mp = strdup (m); -+ } -+ -+ grub_find_root_btrfs_mount_path_hook = mount_path_hook; + grub_free (grub_find_root_devices_from_mountinfo (path, NULL)); -+ grub_find_root_btrfs_mount_path_hook = NULL; + -+ if (!mp) ++ if (!grub_btrfs_mount_path) + return NULL; + + if (mount_path) -+ *mount_path = mp; ++ *mount_path = grub_strdup (grub_btrfs_mount_path); + -+ return get_btrfs_subvol (mp); ++ return get_btrfs_subvol (grub_btrfs_mount_path); +} + char * grub_make_system_path_relative_to_its_root_os (const char *path) { -diff --git a/util/grub-install.c b/util/grub-install.c -index 0f66f36d23a..84ed6e88ecb 100644 --- a/util/grub-install.c +++ b/util/grub-install.c -@@ -1569,6 +1569,55 @@ main (int argc, char *argv[]) +@@ -1645,6 +1645,58 @@ prefix_drive = xasprintf ("(%s)", grub_drives[0]); } @@ -477,13 +458,12 @@ index 0f66f36d23a..84ed6e88ecb 100644 + char *subvol = NULL; + char *mount_path = NULL; + char **rootdir_devices = NULL; -+ char *rootdir_path = grub_util_path_concat (2, "/", rootdir); ++ char *t = grub_util_path_concat (2, "/", rootdir); ++ char *rootdir_path = grub_canonicalize_file_name (t); + -+ if (grub_util_is_directory (rootdir_path)) ++ if (rootdir_path && grub_util_is_directory (rootdir_path)) + rootdir_devices = grub_guess_root_devices (rootdir_path); + -+ free (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); @@ -492,28 +472,32 @@ index 0f66f36d23a..84ed6e88ecb 100644 + { + char *def_subvol; + -+ def_subvol = grub_util_get_btrfs_subvol ("/", NULL); ++ def_subvol = grub_util_get_btrfs_subvol (rootdir_path, NULL); + + if (def_subvol) + { ++ char *rootdir_mount_path = NULL; + if (!load_cfg_f) + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + -+ if (grub_strcmp (subvol, def_subvol) != 0) -+ fprintf (load_cfg_f, "btrfs-mount-subvol ($root) %s %s\n", mount_path, subvol); ++ if (grub_strncmp (rootdir_path, mount_path, grub_strlen (rootdir_path)) == 0) ++ rootdir_mount_path = grub_util_path_concat (2, "/", mount_path + grub_strlen (rootdir_path)); ++ ++ if (grub_strcmp (subvol, def_subvol) != 0 && rootdir_mount_path) ++ fprintf (load_cfg_f, "btrfs-mount-subvol ($root) %s %s\n", rootdir_mount_path, subvol); ++ free (rootdir_mount_path); + free (def_subvol); + } + } + ++ free (t); ++ free (rootdir_path); + for (curdev = rootdir_devices; *curdev; curdev++) + free (*curdev); -+ if (rootdir_devices) -+ free (rootdir_devices); -+ if (subvol) -+ free (subvol); -+ if (mount_path) -+ free (mount_path); ++ free (rootdir_devices); ++ free (subvol); ++ free (mount_path); + } + +#endif @@ -521,11 +505,9 @@ index 0f66f36d23a..84ed6e88ecb 100644 char mkimage_target[200]; const char *core_name = NULL; -diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h -index 73fa2d34abb..9c642ae3fe3 100644 --- a/include/grub/emu/getroot.h +++ b/include/grub/emu/getroot.h -@@ -53,6 +53,11 @@ char ** +@@ -53,6 +53,11 @@ grub_find_root_devices_from_mountinfo (const char *dir, char **relroot); #endif diff --git a/0050-Fallback-to-old-subvol-name-scheme-to-support-old-sn.patch b/grub2-btrfs-07-subvol-fallback.patch similarity index 67% rename from 0050-Fallback-to-old-subvol-name-scheme-to-support-old-sn.patch rename to grub2-btrfs-07-subvol-fallback.patch index b02ab53fe8d4baa00e6eafc71f181591ec0c7cbd..d10c476315d2c8e8e381df14052e870d0eb2256f 100644 --- a/0050-Fallback-to-old-subvol-name-scheme-to-support-old-sn.patch +++ b/grub2-btrfs-07-subvol-fallback.patch @@ -1,23 +1,9 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Andrei Borzenkov -Date: Tue, 21 Jun 2016 16:44:17 +0000 -Subject: [PATCH] Fallback to old subvol name scheme to support old snapshot - config - -Ref: bsc#953538 ---- - grub-core/fs/btrfs.c | 32 +++++++++++++++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index d323746ecfa..673ded03522 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c -@@ -1260,11 +1260,41 @@ lookup_root_by_name(struct grub_btrfs_data *data, const char *path) - return GRUB_ERR_NONE; +@@ -1340,10 +1340,40 @@ } -+static grub_err_t + static grub_err_t +lookup_root_by_name_fallback(struct grub_btrfs_data *data, const char *path) +{ + grub_err_t err; @@ -36,7 +22,7 @@ index d323746ecfa..673ded03522 100644 + return GRUB_ERR_NONE; +} + - static grub_err_t ++static grub_err_t btrfs_handle_subvol(struct grub_btrfs_data *data __attribute__ ((unused))) { if (btrfs_default_subvol) diff --git a/grub2-btrfs-08-workaround-snapshot-menu-default-entry.patch b/grub2-btrfs-08-workaround-snapshot-menu-default-entry.patch new file mode 100644 index 0000000000000000000000000000000000000000..c1255aeea4bfe4fee78f283ae1a75826ac8e525f --- /dev/null +++ b/grub2-btrfs-08-workaround-snapshot-menu-default-entry.patch @@ -0,0 +1,58 @@ + +v2: Add menuentry "Help on bootable snapshot" to be excluded as default entry. + +--- a/grub-core/normal/menu.c ++++ b/grub-core/normal/menu.c +@@ -574,6 +574,43 @@ + grub_refresh (); + } + ++/* bsc#956046 - The first entry titled 'Bootable snapshot #$NUM' is inserted on ++ top at runtime to display current snapshot information. If default entry is ++ using number as key to index the entry, the result will be shifted so here we ++ add specical handling to shift it back. We apply this workaround until a better ++ solution can be found. */ ++static void ++workaround_snapshot_menu_default_entry (grub_menu_t menu, const char *name, int *default_entry) ++{ ++ grub_menu_entry_t entry; ++ if ((entry = grub_menu_get_entry (menu, 0)) && ++ ((entry->submenu && grub_strncmp (entry->title, "Bootable snapshot", sizeof("Bootable snapshot") - 1) == 0) || ++ (!entry->submenu && grub_strncmp (entry->title, "Help on bootable snapshot", sizeof("Help on bootable snapshot") - 1) == 0))) ++ { ++ const char *val; ++ ++ if (*default_entry == -1 && menu->size > 1) ++ { ++ *default_entry = 1; ++ return; ++ } ++ ++ val = grub_env_get (name); ++ ++ grub_error_push (); ++ ++ if (val) ++ grub_strtoul (val, 0, 0); ++ ++ if (*default_entry < (menu->size - 1) && grub_errno == GRUB_ERR_NONE) ++ ++(*default_entry); ++ ++ grub_error_pop (); ++ } ++ ++ return; ++} ++ + #define GRUB_MENU_PAGE_SIZE 10 + + /* Show the menu and handle menu entry selection. Returns the menu entry +@@ -594,6 +631,8 @@ + + default_entry = get_entry_number (menu, "default"); + ++ workaround_snapshot_menu_default_entry (menu, "default", &default_entry); ++ + /* If DEFAULT_ENTRY is not within the menu entries, fall back to + the first entry. */ + if (default_entry < 0 || default_entry >= menu->size) diff --git a/0051-Grub-not-working-correctly-with-btrfs-snapshots-bsc-.patch b/grub2-btrfs-09-get-default-subvolume.patch similarity index 90% rename from 0051-Grub-not-working-correctly-with-btrfs-snapshots-bsc-.patch rename to grub2-btrfs-09-get-default-subvolume.patch index b54b1960f4b8bcf4dabb0af37c969abc0f6bba5f..8106774b7cded1ecfc15d465df37b53fccdd40b7 100644 --- a/0051-Grub-not-working-correctly-with-btrfs-snapshots-bsc-.patch +++ b/grub2-btrfs-09-get-default-subvolume.patch @@ -1,19 +1,11 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Michael Chang -Date: Thu, 11 May 2017 08:56:57 +0000 -Subject: [PATCH] Grub not working correctly with btrfs snapshots (bsc#1026511) -Signed-off-by: Michael Chang -Signed-off-by: Robbie Harwood ---- - grub-core/fs/btrfs.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 238 insertions(+) +V1: + * Use overflow checking primitives where the arithmetic expression for + buffer allocations may include unvalidated data -diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c -index 673ded03522..2b21cbaa67e 100644 --- a/grub-core/fs/btrfs.c +++ b/grub-core/fs/btrfs.c -@@ -2887,6 +2887,238 @@ out: +@@ -3104,6 +3104,254 @@ return 0; } @@ -37,6 +29,7 @@ index 673ded03522..2b21cbaa67e 100644 + grub_disk_addr_t elemaddr; + grub_err_t err; + char *parent_path; ++ grub_size_t sz; + + *parent_id = 0; + *path_out = 0; @@ -55,7 +48,10 @@ index 673ded03522..2b21cbaa67e 100644 + return grub_error(GRUB_ERR_FILE_NOT_FOUND, N_("can't find root backrefs")); + } + -+ buf = grub_malloc(elemsize + 1); ++ if (grub_add (elemsize, 1, &sz)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ ++ buf = grub_malloc(sz); + if (!buf) + { + free_iterator(&desc); @@ -109,6 +105,7 @@ index 673ded03522..2b21cbaa67e 100644 + struct grub_btrfs_dir_item *direl = NULL; + const char *ctoken = "default"; + grub_size_t ctokenlen = sizeof ("default") - 1; ++ grub_size_t sz; + + *id = 0; + key.object_id = data->sblock.root_dir_objectid; @@ -123,7 +120,14 @@ index 673ded03522..2b21cbaa67e 100644 + return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("file not found")); + + struct grub_btrfs_dir_item *cdirel; -+ direl = grub_malloc (elemsize + 1); ++ ++ if (grub_add (elemsize, 1, &sz)) ++ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); ++ ++ direl = grub_malloc (sz); ++ if (!direl) ++ return grub_errno; ++ + err = grub_btrfs_read_logical (data, elemaddr, direl, elemsize, 0); + if (err) + { @@ -209,6 +213,10 @@ index 673ded03522..2b21cbaa67e 100644 + } + + id = subvolid; ++ ++ if (id == GRUB_BTRFS_ROOT_VOL_OBJECTID) ++ subvol = grub_strdup (""); ++ else + while (id != GRUB_BTRFS_ROOT_VOL_OBJECTID) + { + grub_uint64_t parent_id; @@ -252,7 +260,7 @@ index 673ded03522..2b21cbaa67e 100644 static struct grub_fs grub_btrfs_fs = { .name = "btrfs", .fs_dir = grub_btrfs_dir, -@@ -2905,6 +3137,7 @@ static struct grub_fs grub_btrfs_fs = { +@@ -3122,6 +3370,7 @@ static grub_command_t cmd_info; static grub_command_t cmd_mount_subvol; static grub_extcmd_t cmd_list_subvols; @@ -260,7 +268,7 @@ index 673ded03522..2b21cbaa67e 100644 static char * subvolid_set_env (struct grub_env_var *var __attribute__ ((unused)), -@@ -2975,6 +3208,11 @@ GRUB_MOD_INIT (btrfs) +@@ -3192,6 +3441,11 @@ "[-p|-n] [-o var] DEVICE", "Print list of BtrFS subvolumes on " "DEVICE.", options); diff --git a/grub2-btrfs-10-config-directory.patch b/grub2-btrfs-10-config-directory.patch new file mode 100644 index 0000000000000000000000000000000000000000..bcc157b22886a4906c639f5062e972ee49d3a739 --- /dev/null +++ b/grub2-btrfs-10-config-directory.patch @@ -0,0 +1,253 @@ +v1: +References: bsc#1063443 + +v2: +References: bsc#1106381 +Fix outputting invalid btrfs subvol path on non btrfs filesystem due to bogus +return code handling. + +--- a/grub-core/fs/btrfs.c ++++ b/grub-core/fs/btrfs.c +@@ -3260,8 +3260,7 @@ + } + + static grub_err_t +-grub_cmd_btrfs_get_default_subvol (struct grub_extcmd_context *ctxt, +- int argc, char **argv) ++grub_btrfs_get_default_subvol (const char *name, grub_uint64_t *ret_subvolid, char **ret_subvol) + { + char *devname; + grub_device_t dev; +@@ -3270,21 +3269,8 @@ + grub_uint64_t id; + char *subvol = NULL; + grub_uint64_t subvolid = 0; +- char *varname = NULL; +- char *output = NULL; +- int path_only = ctxt->state[1].set; +- int num_only = ctxt->state[2].set; +- +- if (ctxt->state[0].set) +- varname = ctxt->state[0].arg; +- +- if (argc < 1) +- return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); +- +- devname = grub_file_get_device_name(argv[0]); +- if (!devname) +- return grub_errno; + ++ devname = grub_file_get_device_name(name); + dev = grub_device_open (devname); + grub_free (devname); + if (!dev) +@@ -3295,8 +3281,7 @@ + { + grub_device_close (dev); + grub_dprintf ("btrfs", "failed to open fs\n"); +- grub_errno = GRUB_ERR_NONE; +- return 0; ++ return grub_errno; + } + + err = grub_btrfs_get_default_subvolume_id (data, &subvolid); +@@ -3325,12 +3310,47 @@ + return err; + } + +- if (subvol) +- grub_free (subvol); ++ grub_free (subvol); + subvol = path_out; + id = parent_id; + } + ++ if (ret_subvolid) ++ *ret_subvolid = subvolid; ++ if (ret_subvol) ++ *ret_subvol = subvol; ++ ++ grub_btrfs_unmount (data); ++ grub_device_close (dev); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_cmd_btrfs_get_default_subvol (struct grub_extcmd_context *ctxt, ++ int argc, char **argv) ++{ ++ grub_err_t err; ++ char *subvol = NULL; ++ grub_uint64_t subvolid = 0; ++ char *varname = NULL; ++ char *output = NULL; ++ int path_only = ctxt->state[1].set; ++ int num_only = ctxt->state[2].set; ++ ++ if (ctxt->state[0].set) ++ varname = ctxt->state[0].arg; ++ ++ if (argc < 1) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required"); ++ ++ if ((err = grub_btrfs_get_default_subvol (argv[0], &subvolid, &subvol)) != GRUB_ERR_NONE) ++ { ++ if (err == GRUB_ERR_BAD_FS) ++ err = grub_errno = GRUB_ERR_NONE; ++ return err; ++ } ++ + if (num_only && path_only) + output = grub_xasprintf ("%"PRIuGRUB_UINT64_T" /%s", subvolid, subvol); + else if (num_only) +@@ -3346,9 +3366,6 @@ + grub_free (output); + grub_free (subvol); + +- grub_btrfs_unmount (data); +- grub_device_close (dev); +- + return GRUB_ERR_NONE; + } + +@@ -3427,6 +3444,122 @@ + return ""; + } + ++ ++static char * ++grub_btrfs_path_to_abs (const char *path) ++{ ++ grub_err_t err; ++ char *device_name = NULL; ++ char *subvol = NULL; ++ const char *file_name; ++ char *ret; ++ ++ if (!path) ++ return NULL; ++ ++ if ((err = grub_btrfs_get_default_subvol (path, 0, &subvol)) != GRUB_ERR_NONE) ++ { ++ grub_errno = GRUB_ERR_NONE; ++ return NULL; ++ } ++ ++ if (!subvol || *subvol == '\0') ++ return NULL; ++ ++ file_name = (path[0] == '(') ? grub_strchr (path, ')') : NULL; ++ if (file_name) ++ file_name++; ++ else ++ file_name = path; ++ device_name = grub_file_get_device_name (path); ++ if (device_name) ++ ret = grub_xasprintf ("(%s)/%s%s", device_name, subvol, file_name); ++ else ++ ret = grub_xasprintf ("/%s%s", subvol, file_name); ++ ++ grub_free (device_name); ++ grub_free (subvol); ++ ++ return ret; ++} ++ ++static char * ++grub_btrfs_path_to_rel (const char *path) ++{ ++ grub_err_t err; ++ char *subvol = NULL; ++ const char *file_name; ++ ++ if (!path) ++ return NULL; ++ ++ if ((err = grub_btrfs_get_default_subvol (path, 0, &subvol)) != GRUB_ERR_NONE) ++ { ++ grub_errno = GRUB_ERR_NONE; ++ return NULL; ++ } ++ ++ if (!subvol || *subvol == '\0') ++ return NULL; ++ ++ file_name = (path[0] == '(') ? grub_strchr (path, ')') : NULL; ++ if (file_name) ++ file_name++; ++ else ++ file_name = path; ++ ++ if (*file_name == '/') ++ file_name++; ++ ++ if (grub_strncmp (file_name, subvol, grub_strlen (subvol)) == 0) ++ { ++ char *device_name; ++ char *ret; ++ ++ device_name = grub_file_get_device_name (path); ++ file_name += grub_strlen (subvol); ++ if (device_name) ++ ret = grub_xasprintf ("(%s)%s", device_name, file_name); ++ else ++ ret = grub_strdup (file_name); ++ grub_free (device_name); ++ grub_free (subvol); ++ return ret; ++ } ++ ++ grub_free (subvol); ++ return NULL; ++} ++ ++static char * ++relpath_set_env (struct grub_env_var *var, ++ const char *val) ++{ ++ int new_val, old_val; ++ new_val = (val[0] == '1' || val[0] == 'y') ? 1 : 0; ++ old_val = (var->value[0] == '1' || var->value[0] == 'y') ? 1 : 0; ++ ++ if (new_val != old_val) ++ { ++ const char **n; ++ char * (*path_to_xxx) (const char *); ++ const char *envname[] = {"config_file", "config_directory", NULL}; ++ ++ path_to_xxx = (new_val == 1) ? grub_btrfs_path_to_rel : grub_btrfs_path_to_abs; ++ for (n = envname; *n; n++) ++ { ++ char *ctmp = path_to_xxx (grub_env_get (*n)); ++ if (ctmp) ++ { ++ grub_env_set (*n, ctmp); ++ grub_free (ctmp); ++ } ++ } ++ } ++ ++ return grub_strdup (val); ++} ++ + GRUB_MOD_INIT (btrfs) + { + grub_fs_register (&grub_btrfs_fs); +@@ -3450,6 +3583,8 @@ + subvol_set_env); + grub_register_variable_hook ("btrfs_subvolid", subvolid_get_env, + subvolid_set_env); ++ grub_register_variable_hook ("btrfs_relative_path", NULL, ++ relpath_set_env); + grub_env_export ("btrfs_subvol"); + grub_env_export ("btrfs_subvolid"); + grub_env_export ("btrfs_relative_path"); +@@ -3459,6 +3594,7 @@ + { + grub_register_variable_hook ("btrfs_subvol", NULL, NULL); + grub_register_variable_hook ("btrfs_subvolid", NULL, NULL); ++ grub_register_variable_hook ("btrfs_relative_path", NULL, NULL); + grub_unregister_command (cmd_info); + grub_unregister_extcmd (cmd_list_subvols); + grub_fs_unregister (&grub_btrfs_fs); diff --git a/grub2-btrfs-help-on-snapper-rollback.patch b/grub2-btrfs-help-on-snapper-rollback.patch new file mode 100644 index 0000000000000000000000000000000000000000..679a9f4042dd67092a304855aa963fbb12bf3ee7 --- /dev/null +++ b/grub2-btrfs-help-on-snapper-rollback.patch @@ -0,0 +1,19 @@ +--- a/util/grub.d/00_header.in ++++ b/util/grub.d/00_header.in +@@ -428,8 +428,14 @@ + # Note: No $snapshot_num on *read-only* rollback! (bsc#901487) + cat < +Subject: Introduce a 'read_file' sub-command. +References: bsc#892852, bsc#891946 +Patch-Mainline: not yet + +Needed to allow s390x-emu to be telecontrolled via LOADPARM. + +v2: Added GRUB_FILE_TYPE_READ_ENVVAR as file type by read_file sub-command +tracked by verifier framework. + +--- + grub-core/commands/read.c | 34 ++++++++++++++++++++++++++++++++++ + 1 file changed, 34 insertions(+) + +--- a/grub-core/commands/read.c ++++ b/grub-core/commands/read.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -88,16 +89,49 @@ + return 0; + } + ++static grub_err_t ++grub_cmd_read_from_file (grub_command_t cmd __attribute__ ((unused)), int argc, char **args) ++{ ++ char *line; ++ int i = 0; ++ grub_file_t file; ++ ++ if (argc < 1) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("file name expected")); ++ if (argc < 2) ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("variable name expected")); ++ file = grub_file_open (args[i++], GRUB_FILE_TYPE_READ_ENVVAR); ++ if (! file) ++ return grub_errno; ++ while ( i < argc ) ++ { ++ line = grub_file_getline (file); ++ if ( !line ) ++ break; ++ grub_env_set (args[i++], line); ++ grub_free (line); ++ } ++ grub_file_close (file); ++ if (i != argc) ++ return GRUB_ERR_OUT_OF_RANGE; ++ return 0; ++} ++ + static grub_extcmd_t cmd; ++static grub_command_t cme; + + GRUB_MOD_INIT(read) + { + cmd = grub_register_extcmd ("read", grub_cmd_read, 0, + N_("[-s] [ENVVAR]"), + N_("Set variable with user input."), options); ++ cme = grub_register_command ("read_file", grub_cmd_read_from_file, ++ N_("FILE ENVVAR [...]"), ++ N_("Set variable(s) with line(s) from FILE.")); + } + + GRUB_MOD_FINI(read) + { + grub_unregister_extcmd (cmd); ++ grub_unregister_command (cme); + } +--- a/include/grub/file.h ++++ b/include/grub/file.h +@@ -126,6 +126,7 @@ + GRUB_FILE_TYPE_FS_SEARCH, + GRUB_FILE_TYPE_AUDIO, + GRUB_FILE_TYPE_VBE_DUMP, ++ GRUB_FILE_TYPE_READ_ENVVAR, + + GRUB_FILE_TYPE_LOADENV, + GRUB_FILE_TYPE_SAVEENV, diff --git a/grub2-default-distributor.patch b/grub2-default-distributor.patch new file mode 100644 index 0000000000000000000000000000000000000000..a882a34e8f2b1b816ceced6d46e8f202a5ee2a4d --- /dev/null +++ b/grub2-default-distributor.patch @@ -0,0 +1,201 @@ +v1: +As long as VERSION in /etc/os-release has been commented out for rolling +release, we can replace openSUSE Tumbleweed specific handling for grub +distributor with a generic one. + +v2: +Use /usr/lib/os-release as fallback to /etc/os-release + +Index: grub-2.06/grub-core/osdep/unix/config.c +=================================================================== +--- grub-2.06.orig/grub-core/osdep/unix/config.c ++++ grub-2.06/grub-core/osdep/unix/config.c +@@ -61,6 +61,131 @@ grub_util_get_localedir (void) + return LOCALEDIR; + } + ++#ifdef __linux__ ++static char * ++os_release_get_val (const char *buf, const char *key) ++{ ++ const char *ptr = buf; ++ char *ret; ++ ++ while (*ptr && grub_isspace(*ptr)) ++ ptr++; ++ ++ if (*ptr == '#') ++ return NULL; ++ ++ if (grub_strncmp (ptr, key, grub_strlen (key)) != 0) ++ return NULL; ++ ++ ptr += grub_strlen (key); ++ if (*ptr++ != '=' || *ptr == '\0') ++ return NULL; ++ ++ if (*ptr == '"' || *ptr == '\'') ++ { ++ char c = *ptr; ++ int i = 0; ++ char *tmp, *ptmp; ++ ++ if (*++ptr == '\0') ++ return NULL; ++ ++ tmp = grub_strdup (ptr); ++ if ((ptmp = grub_strrchr (tmp, c))) ++ *ptmp = '\0'; ++ ++ ret = malloc (grub_strlen (tmp) + 1); ++ ptmp = tmp; ++ while (*ptmp) ++ { ++ if (*ptmp != '\\' || *(ptmp + 1) != c) ++ ret[i++] = *ptmp; ++ ++ptmp; ++ } ++ ++ grub_free (tmp); ++ ret[i] = '\0'; ++ } ++ else ++ { ++ char *pret; ++ ++ ret = grub_strdup (ptr); ++ if ((pret = grub_strchr (ret, ' '))) ++ *pret = '\0'; ++ } ++ ++ return ret; ++} ++ ++static char* ++grub_util_default_distributor (void) ++{ ++ char *cfgfile; ++ char buf[1024]; ++ FILE *fp = NULL; ++ char *os_name = NULL; ++ char *os_version = NULL; ++ ++ cfgfile = grub_util_path_concat (2, GRUB_SYSCONFDIR, "os-release"); ++ if (!grub_util_is_regular (cfgfile)) ++ { ++ grub_free (cfgfile); ++ cfgfile = grub_util_path_concat (2, "/usr/lib", "os-release"); ++ if (!grub_util_is_regular (cfgfile)) ++ { ++ grub_free (cfgfile); ++ return NULL; ++ } ++ } ++ ++ fp = grub_util_fopen (cfgfile, "r"); ++ ++ if (!fp) ++ { ++ grub_util_warn (_("cannot open configuration file `%s': %s"), ++ cfgfile, strerror (errno)); ++ grub_free (cfgfile); ++ return NULL; ++ } ++ ++ grub_free (cfgfile); ++ ++ while (fgets (buf, sizeof (buf), fp)) ++ { ++ if (buf[grub_strlen(buf) - 1] == '\n') ++ buf[grub_strlen(buf) - 1] = '\0'; ++ ++ if (!os_name ++ && (os_name = os_release_get_val (buf, "NAME"))) ++ continue; ++ if (!os_version ++ && (os_version = os_release_get_val (buf, "VERSION"))) ++ continue; ++ if (os_name && os_version) ++ break; ++ } ++ ++ fclose (fp); ++ ++ if (os_name && os_version) ++ { ++ char *os_name_version; ++ ++ os_name_version = grub_xasprintf ("%s %s", os_name, os_version); ++ ++ grub_free (os_name); ++ grub_free (os_version); ++ ++ return os_name_version; ++ } ++ ++ grub_free (os_version); ++ ++ return os_name; ++} ++#endif ++ + void + grub_util_load_config (struct grub_util_config *cfg) + { +@@ -125,7 +250,17 @@ grub_util_load_config (struct grub_util_ + waitpid (pid, NULL, 0); + } + if (f) +- return; ++ { ++#ifdef __linux__ ++ if (!cfg->grub_distributor || cfg->grub_distributor[0] == '\0') ++ { ++ if (cfg->grub_distributor) ++ grub_free (cfg->grub_distributor); ++ cfg->grub_distributor = grub_util_default_distributor (); ++ } ++#endif ++ return; ++ } + + f = grub_util_fopen (cfgfile, "r"); + if (f) +@@ -136,4 +271,13 @@ grub_util_load_config (struct grub_util_ + else + grub_util_warn (_("cannot open configuration file `%s': %s"), + cfgfile, strerror (errno)); ++ ++#ifdef __linux__ ++ if (!cfg->grub_distributor || cfg->grub_distributor[0] == '\0') ++ { ++ if (cfg->grub_distributor) ++ grub_free (cfg->grub_distributor); ++ cfg->grub_distributor = grub_util_default_distributor (); ++ } ++#endif + } +Index: grub-2.06/util/grub-mkconfig.in +=================================================================== +--- grub-2.06.orig/util/grub-mkconfig.in ++++ grub-2.06/util/grub-mkconfig.in +@@ -225,6 +225,19 @@ GRUB_ACTUAL_DEFAULT="$GRUB_DEFAULT" + + if [ "x${GRUB_ACTUAL_DEFAULT}" = "xsaved" ] ; then GRUB_ACTUAL_DEFAULT="`"${grub_editenv}" - list | sed -n '/^saved_entry=/ s,^saved_entry=,,p'`" ; fi + ++if [ x"${GRUB_DISTRIBUTOR}" = x ] ; then ++ for i in "${sysconfdir}/os-release" "/usr/lib/os-release" ; do ++ if [ -f "$i" ] ; then ++ . "$i" ++ break ++ fi ++ done ++ if [ x"${NAME}" != x ] && [ x"${VERSION}" != x ] ; then ++ GRUB_DISTRIBUTOR="${NAME} ${VERSION}" ++ else ++ GRUB_DISTRIBUTOR="${NAME}" ++ fi ++fi + + # These are defined in this script, export them here so that user can + # override them. diff --git a/grub2-diskfilter-support-pv-without-metadatacopies.patch b/grub2-diskfilter-support-pv-without-metadatacopies.patch new file mode 100644 index 0000000000000000000000000000000000000000..2e58278a70ca84199f8f0cda94b4c4c34fc83994 --- /dev/null +++ b/grub2-diskfilter-support-pv-without-metadatacopies.patch @@ -0,0 +1,219 @@ +From a28bc19400b4e70725ce5532bc5e4c374c72d7a9 Mon Sep 17 00:00:00 2001 +From: Lidong Zhong +Date: Wed, 26 Apr 2017 15:52:40 +0800 +Subject: [PATCH] diskfilter: implementation of processing no metadata recorded + in PV + +If one PV underlying the root LV is created with no metadata, such as + +pvcreate --metadatacopies 0 /dev/sda + +then we could get a lot of error messages when generating a new +configuration file. + +Generating grub configuration file ... +error: unknown LVM metadata header. +error: unknown LVM metadata header. +/usr/sbin/grub2-probe: warning: Couldn't find physical volume `pv1'. +Some modules may be missing from core image.. +(For details, please refer to + https://bugzilla.suse.com/show_bug.cgi?id=1027526) + +When one labelled PV which dose not have any metadata is found, we put +it into a global grub_detached_pv list. and we search all the PVs in the +current array list to check if it is a member of grub_detached_pv list. +So we can know if the PV is really missing or just without metadata. + +Signed-off-by: Lidong Zhong +--- + grub-core/disk/diskfilter.c | 112 +++++++++++++++++++++++++++++++++++++++++++- + grub-core/disk/lvm.c | 15 ++++-- + 2 files changed, 121 insertions(+), 6 deletions(-) + +--- a/grub-core/disk/diskfilter.c ++++ b/grub-core/disk/diskfilter.c +@@ -28,6 +28,7 @@ + #include + #include + #endif ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -43,7 +44,17 @@ + find_lv (const char *name); + static int is_lv_readable (struct grub_diskfilter_lv *lv, int easily); + +- ++struct grub_detached_pv { ++ struct grub_detached_pv *next; ++ struct grub_detached_pv **prev; ++ struct grub_diskfilter_pv_id id; ++ grub_disk_t disk; ++ grub_diskfilter_t diskfilter; ++} ; ++ ++static struct grub_detached_pv *detached_pv_list; ++ ++#define FOR_DETACHED_PVS(var) for (var = detached_pv_list; var; var = var->next) + + static grub_err_t + is_node_readable (const struct grub_diskfilter_node *node, int easily) +@@ -132,6 +143,7 @@ + grub_disk_addr_t start_sector; + struct grub_diskfilter_pv_id id; + grub_diskfilter_t diskfilter; ++ struct grub_detached_pv *pv; + + grub_dprintf ("diskfilter", "Scanning for DISKFILTER devices on disk %s\n", + name); +@@ -168,6 +180,28 @@ + grub_free (id.uuid); + return 0; + } ++ /*insert the special LVM PV into detached_pv_list*/ ++ if (!arr && (id.uuidlen > 0) && (grub_strcmp(diskfilter->name, "lvm") == 0)) ++ { ++ pv = grub_zalloc(sizeof(*pv)); ++ if (!pv) ++ return 1; ++ pv->id.uuidlen = GRUB_LVM_ID_STRLEN; ++ pv->id.uuid = grub_malloc(GRUB_LVM_ID_STRLEN); ++ if (!pv->id.uuid) ++ goto fail_id; ++ grub_memcpy(pv->id.uuid, id.uuid, GRUB_LVM_ID_STRLEN); ++ /*It's safe to save disk into this standalone pv list*/ ++ pv->disk = grub_disk_open(name); ++ if (!pv->disk) ++ goto fail_id; ++ pv->diskfilter = diskfilter; ++ grub_list_push (GRUB_AS_LIST_P (&detached_pv_list), ++ GRUB_AS_LIST(pv)); ++#ifdef GRUB_UTIL ++ grub_util_info ("adding disk %s into detached pv list", name); ++#endif ++ } + if (arr && id.uuidlen) + grub_free (id.uuid); + +@@ -180,6 +214,65 @@ + } + + return 0; ++fail_id: ++ if (pv->id.uuidlen) ++ grub_free(pv->id.uuid); ++ grub_free(pv); ++ return 1; ++} ++ ++static int ++process_detached_pv_list(void) ++{ ++ struct grub_diskfilter_vg *arr; ++ struct grub_diskfilter_pv *pv1; ++ struct grub_detached_pv *pv2; ++ unsigned found = 0; ++ ++ for (arr = array_list; arr != NULL; arr = arr->next) ++ { ++ for (pv1 = arr->pvs; pv1; pv1 = pv1->next) ++ { ++ if (pv1->disk) ++ continue; ++ FOR_DETACHED_PVS(pv2) ++ { ++ if (pv2->id.uuidlen == pv1->id.uuidlen && ++ !grub_memcmp(pv2->id.uuid, pv1->id.uuid, pv1->id.uuidlen)) ++ { ++ if (insert_array(pv2->disk, &(pv2->id), arr, -1, pv2->diskfilter)) ++ return grub_errno; ++ else ++ { ++#ifdef GRUB_UTIL ++ grub_util_info ("found disk %s in detached pv list", pv1->disk->name); ++#endif ++ found = 1; ++ break; ++ } ++ } ++ } ++ /*remove pv2 from the list*/ ++ if (found) ++ { ++#ifdef GRUB_UTIL ++ grub_util_info ("removing disk %s from detached pv list", pv1->disk->name); ++#endif ++ grub_list_remove(GRUB_AS_LIST (pv2)); ++ if (pv2->id.uuidlen) ++ { ++ pv2->id.uuidlen = 0; ++ grub_free(pv2->id.uuid); ++ } ++ grub_disk_close(pv2->disk); ++ grub_free(pv2); ++ break; ++ } ++ } ++ if (found) ++ break; ++ } ++ return 0; + } + + static int +@@ -206,6 +299,9 @@ + grub_partition_iterate (disk, scan_disk_partition_iter, (void *) name); + grub_disk_close (disk); + scan_depth--; ++ ++ /*process the detached_pv_list*/ ++ process_detached_pv_list(); + return 0; + } + +@@ -1287,6 +1383,20 @@ + static void + free_array (void) + { ++ while(detached_pv_list) ++ { ++ struct grub_detached_pv *pv; ++ pv = detached_pv_list; ++ detached_pv_list = detached_pv_list->next; ++#ifdef GRUB_UTIL ++ grub_util_warn (_("Couldn't find disk for physical volume `%s'." ++ "Some LVs may not work normally."),pv->disk->name); ++#endif ++ if (pv->id.uuidlen) ++ grub_free(pv->id.uuid); ++ grub_disk_close(pv->disk); ++ grub_free(pv); ++ } + while (array_list) + { + struct grub_diskfilter_vg *vg; +--- a/grub-core/disk/lvm.c ++++ b/grub-core/disk/lvm.c +@@ -235,11 +235,16 @@ + sizeof (mdah->magic))) + || (grub_le_to_cpu32 (mdah->version) != GRUB_LVM_FMTT_VERSION)) + { +- grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET, +- "unknown LVM metadata header"); +-#ifdef GRUB_UTIL +- grub_util_info ("unknown LVM metadata header"); +-#endif ++ /* ++ * It's not necessarily an error. There is no metadata recorded when ++ * PV is created with pvmetadatacopies set to zero. We need to process ++ * this kind of PV seperately. ++ */ ++ id->uuid = grub_malloc(GRUB_LVM_ID_STRLEN); ++ if (!id->uuid) ++ goto fail; ++ grub_memcpy(id->uuid, pv_id, GRUB_LVM_ID_STRLEN); ++ id->uuidlen = GRUB_LVM_ID_STRLEN; + goto fail; + } + diff --git a/grub2-efi-HP-workaround.patch b/grub2-efi-HP-workaround.patch new file mode 100644 index 0000000000000000000000000000000000000000..550b23fe33e10fa9a337773eefcda6934a08b3a7 --- /dev/null +++ b/grub2-efi-HP-workaround.patch @@ -0,0 +1,95 @@ + +v2: Add GRUB_FILE_TYPE_CONFIG to grub_file_open, see also upstream commit +ca0a4f689 verifiers: File type for fine-grained signature-verification controlling + +--- a/grub-core/kern/efi/init.c ++++ b/grub-core/kern/efi/init.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + #include + + #ifdef GRUB_STACK_PROTECTOR +@@ -135,6 +136,67 @@ + void (*grub_efi_net_config) (grub_efi_handle_t hnd, + char **device, + char **path); ++static char * ++workaround_efi_firmware_path (const char *device, const char *path) ++{ ++ char *config = NULL;; ++ char *config_upper = NULL; ++ char *path_upper = NULL; ++ char *ret_path = NULL; ++ grub_file_t config_fd = NULL; ++ char *s; ++ ++ if (!device || !path) ++ return NULL; ++ ++ /* only workaround if booting off from cd device */ ++ if (grub_strncmp (device, "cd", 2) != 0) ++ goto quit; ++ ++ config = grub_xasprintf ("(%s)%s/grub.cfg", device, path); ++ config_fd = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); ++ ++ /* everything's fine, so quit the workaround */ ++ if (config_fd) ++ goto quit; ++ ++ /* reset grub error state because noone else does... */ ++ grub_errno = GRUB_ERR_NONE; ++ ++ /* try again, this time upper case path */ ++ path_upper = grub_strdup (path); ++ if (! path_upper) ++ goto quit; ++ ++ s = path_upper; ++ for (; *s; s++) *s = grub_toupper(*s); ++ ++ config_upper = grub_xasprintf ("(%s)%s/grub.cfg", device, path_upper); ++ if (! config_upper) ++ goto quit; ++ ++ config_fd = grub_file_open (config_upper, GRUB_FILE_TYPE_CONFIG); ++ ++ /* if config can be found by the upper case path, return it */ ++ if (config_fd) ++ ret_path = grub_strdup (path_upper); ++ ++quit: ++ ++ if (config_fd) ++ grub_file_close (config_fd); ++ ++ if (grub_errno) ++ grub_errno = GRUB_ERR_NONE; ++ ++ if (config) ++ grub_free (config); ++ ++ if (config_upper) ++ grub_free (config_upper); ++ ++ return ret_path; ++} + + void + grub_machine_get_bootlocation (char **device, char **path) +@@ -159,6 +221,12 @@ + p = grub_strrchr (*path, '/'); + if (p) + *p = '\0'; ++ ++ if ((p = workaround_efi_firmware_path (*device, *path))) ++ { ++ grub_free (*path); ++ *path = p; ++ } + } + } + diff --git a/grub2-efi-chainload-harder.patch b/grub2-efi-chainload-harder.patch new file mode 100644 index 0000000000000000000000000000000000000000..4793bae0620fa1d32d53f15a46e1f9615196caed --- /dev/null +++ b/grub2-efi-chainload-harder.patch @@ -0,0 +1,121 @@ + +v2: +Use grub_efi_get_secureboot to get secure boot status + +v3: +Fix null sb_context->file_path due to missing assignment of chainloaded image's +file_path (bsc#1216081) + +--- + grub-core/loader/efi/chainloader.c | 62 +++++++++++++++++++++---------------- + 1 file changed, 36 insertions(+), 26 deletions(-) + +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -305,40 +305,41 @@ + static grub_efi_boolean_t + read_header (void *data, grub_efi_uint32_t size, pe_coff_loader_image_context_t *context) + { +- 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); ++ char *msdos = (char *)data; ++ struct grub_pe32_header_no_msdos_stub *pe32 = (struct grub_pe32_header_no_msdos_stub *)data; + +- if (!shim_lock) ++ if (size < sizeof (*pe32)) + { +- grub_error (GRUB_ERR_BAD_ARGUMENT, "no shim lock protocol"); ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid image"); + return 0; + } + +- status = shim_lock->context (data, size, context); +- +- if (status == GRUB_EFI_SUCCESS) ++ if (grub_memcmp (msdos, "MZ", 2) == 0) + { +- grub_dprintf ("chain", "context success\n"); +- return 1; ++ grub_uint32_t off = *((grub_uint32_t *) (msdos + 0x3c)); ++ pe32 = (struct grub_pe32_header_no_msdos_stub *) ((char *)data + off); + } + +- switch (status) ++ if (grub_memcmp (pe32->signature, "PE\0\0", 4) != 0 || ++ pe32->coff_header.machine != GRUB_PE32_MACHINE_X86_64 || ++ pe32->optional_header.magic != GRUB_PE32_PE64_MAGIC) + { +- case GRUB_EFI_UNSUPPORTED: +- grub_error (GRUB_ERR_BAD_ARGUMENT, "context error unsupported"); +- break; +- case GRUB_EFI_INVALID_PARAMETER: +- grub_error (GRUB_ERR_BAD_ARGUMENT, "context error invalid parameter"); +- break; +- default: +- grub_error (GRUB_ERR_BAD_ARGUMENT, "context error code"); +- break; ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "Not supported image"); ++ return 0; + } + +- return 0; ++ context->number_of_rva_and_sizes = pe32->optional_header.num_data_directories; ++ context->size_of_headers = pe32->optional_header.header_size; ++ context->image_size = pe32->optional_header.image_size; ++ context->image_address = pe32->optional_header.image_base; ++ context->entry_point = pe32->optional_header.entry_addr; ++ context->reloc_dir = &pe32->optional_header.base_relocation_table; ++ context->sec_dir = &pe32->optional_header.certificate_table; ++ context->number_of_sections = pe32->coff_header.num_sections; ++ context->pe_hdr = pe32; ++ context->first_section = (struct grub_pe32_section_table *)((char *)(&pe32->optional_header) + pe32->coff_header.optional_header_size); ++ ++ return 1; + } + + static void* +@@ -607,6 +608,9 @@ + if (buffer) + b->free_pool (buffer); + ++ if (grub_errno) ++ grub_print_error (); ++ + return 0; + + } +@@ -825,6 +829,31 @@ + status = b->load_image (0, grub_efi_image_handle, file_path, + boot_image, size, + &image_handle); ++#ifdef SUPPORT_SECURE_BOOT ++ if (status == GRUB_EFI_SECURITY_VIOLATION && grub_efi_get_secureboot () != GRUB_EFI_SECUREBOOT_MODE_ENABLED) ++ { ++ /* If it failed with security violation while not in secure boot mode, ++ the firmware might be broken. We try to workaround on that by forcing ++ the SB method! (bsc#887793) */ ++ struct grub_secureboot_chainloader_context *sb_context; ++ ++ grub_dprintf ("chain", "Possible firmware flaw! Security violation while not in secure boot mode.\n"); ++ sb_context = grub_malloc (sizeof (*sb_context)); ++ if (!sb_context) ++ goto fail; ++ sb_context->cmdline = cmdline; ++ sb_context->cmdline_len = cmdline_len; ++ sb_context->fsize = size; ++ sb_context->dev_handle = dev_handle; ++ sb_context->address = address; ++ sb_context->pages = pages; ++ sb_context->file_path = file_path; ++ grub_file_close (file); ++ grub_loader_set_ex (grub_secureboot_chainloader_boot, ++ grub_secureboot_chainloader_unload, sb_context, 0); ++ return 0; ++ } ++#endif + if (status != GRUB_EFI_SUCCESS) + { + if (status == GRUB_EFI_OUT_OF_RESOURCES) diff --git a/grub2-efi-disable-video-cirrus-and-bochus.patch b/grub2-efi-disable-video-cirrus-and-bochus.patch new file mode 100644 index 0000000000000000000000000000000000000000..f1dc396f4fe6a0c0f1be137694ed943ca9a0433b --- /dev/null +++ b/grub2-efi-disable-video-cirrus-and-bochus.patch @@ -0,0 +1,31 @@ +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -2142,13 +2142,13 @@ + module = { + name = video_cirrus; + x86 = video/cirrus.c; +- enable = x86; ++ enable = x86_noefi; + }; + + module = { + name = video_bochs; + x86 = video/bochs.c; +- enable = x86; ++ enable = x86_noefi; + }; + + module = { +--- a/gentpl.py ++++ b/gentpl.py +@@ -92,6 +92,10 @@ + GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"] + GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc") + ++# x86 without efi ++GROUPS["x86_noefi"] = GROUPS["x86"][:] ++GROUPS["x86_noefi"].remove("i386_efi"); GROUPS["x86_noefi"].remove("x86_64_efi"); ++ + # + # Create platform => groups reverse map, where groups covering that + # platform are ordered by their sizes diff --git a/grub2-efi-xen-cfg-unquote.patch b/grub2-efi-xen-cfg-unquote.patch new file mode 100644 index 0000000000000000000000000000000000000000..73e6679333bf33f6252152ce8883e9521a624b70 --- /dev/null +++ b/grub2-efi-xen-cfg-unquote.patch @@ -0,0 +1,90 @@ +From: Petr Tesarik +Subject: Unquote parameters written to Xen EFI config file +References: bsc#900418 +Patch-mainline: not yet + +The GRUB_CMDLINE_* value is copied verbatim to grub.conf, so it is first +parsed by GRUB2 before being passed down to the kernel. OTOH Xen EFI loader +takes the config file options verbatim. This means that any special GRUB2 +syntax must be evaluated when generating that file. + +Of course, some things are not even possible (e.g. substituting GRUB runtime +variables), but let's call them known limitations. + +Signed-off-by: Petr Tesarik + +--- + util/grub.d/20_linux_xen.in | 54 ++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 52 insertions(+), 2 deletions(-) + +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -139,6 +139,52 @@ + is_efi=false + fi + ++grub2_unquote () ++{ ++ awk ' ++ BEGIN { ++ bare = "[^{}|&$;<> \t\n'\''\"\\\\]+" ++ esc = "\\\\." ++ id = "[[:alpha:]_][[:alnum:]_]*|[[:digit:]]+|[?#*@]" ++ var = "\\$("id")|\\$\\{("id")\\}" ++ dqesc = "\\\\[$\"\\\\]" ++ dqstr = "\\$?\"([^\"]|"var"|"dqesc")*\"" ++ sqstr = "'\''[^'\'']*'\''" ++ pat = bare"|"esc"|"var"|"dqstr"|"sqstr ++ ORS = "" ++ } ++ { ++ patsplit($0, words, pat, sep) ++ print sep[0] ++ for (i in words) { ++ w = words[i] ++ if (w ~ /^\$?"/) { ++ # Double-quoted string ++ patsplit(w, segs, var"|"dqesc, ssep) ++ print ssep[0] ++ for (j in segs) { ++ if (segs[j] ~ /^\\/) ++ print substr(segs[j], 2) ++ print ssep[j] ++ } ++ } else if (w ~ /^'\''/) { ++ # Single-quoted string ++ print substr(w, 2, length(w)-2) ++ } else if (w ~ /^\\/) { ++ # Escape sequence ++ print substr(w, 2) ++ } else if (w ~ /^\$/) { ++ # Variable expansion ++ } else { ++ # Bare word ++ print w ++ } ++ print sep[i] ++ } ++ print "\n" ++ }' ++} ++ + linux_entry () + { + linux_entry_xsm "$@" false +@@ -209,11 +255,13 @@ + else + section="failsafe.$section_count" + fi ++ xen_args_unq=$(echo $xen_args | grub2_unquote) ++ args_unq=$(echo $args | grub2_unquote) + cat <<-EOF >> $grub_dir/$xen_cfg + + [$section] +- options=${xen_args} +- kernel=${basename} root=${linux_root_device_thisversion} ${args} ++ options=${xen_args_unq} ++ kernel=${basename} root=${linux_root_device_thisversion} ${args_unq} + ramdisk=${initrd_real} + EOF + message="$(gettext_printf "Loading Xen %s with Linux %s ..." ${xen_version} ${version})" diff --git a/grub2-efi-xen-chainload.patch b/grub2-efi-xen-chainload.patch new file mode 100644 index 0000000000000000000000000000000000000000..8ef054f25a32862f8e2c4c717e6db886a919c498 --- /dev/null +++ b/grub2-efi-xen-chainload.patch @@ -0,0 +1,188 @@ +From: Raymund Will +Subject: Use chainloader to boot xen.efi under UEFI. +References: bnc#871857, bnc#879148 +Patch-Mainline: no + +As XEN on SLE12 is not multiboot2 ready, some very dirty hacking +is necessary to boot via xen.efi and separate configfile snippets +(as done in SLE11SP3 secureboot). + +To that end said configfile snippets, xen efi-binaries, kernels and initrds +need to copied to the EFI system partition during 'grub2-mkconfig'! + +V0: +- first, somewhat fragile version, without any sort of cleanup for ESP. +V1: +- add missing whitespace. (bnc879148) +V2: +- second, much less fragile version, using only one config file per + XEN hypervisor version with sections for different kernels, avoiding + useless duplicates for sym-linked hypervisors. and removing previously + installed files from ESP. +V3: +- support move to '/usr/share/efi/$machine' for EFI-binaries. (bsc#1122563) + +--- + util/grub.d/20_linux_xen.in | 109 +++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 97 insertions(+), 12 deletions(-) + +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -21,6 +21,8 @@ + exec_prefix="@exec_prefix@" + datarootdir="@datarootdir@" + ++ME=$(basename $0) ++ + . "$pkgdatadir/grub-mkconfig_lib" + + export TEXTDOMAIN=@PACKAGE@ +@@ -36,11 +38,23 @@ + + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then + OS=GNU/Linux ++ os=linux + else + OS="${GRUB_DISTRIBUTOR}" +- CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" ++ os="$(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1)" ++ CLASS="--class ${os} ${CLASS}" + fi + ++machine=`uname -m` ++ ++case "$machine" in ++ i?86) GENKERNEL_ARCH="x86" ;; ++ mips|mips64) GENKERNEL_ARCH="mips" ;; ++ mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;; ++ arm*) GENKERNEL_ARCH="arm" ;; ++ *) GENKERNEL_ARCH="$machine" ;; ++esac ++ + # loop-AES arranges things so that /dev/loop/X can be our root device, but + # the initrds that Linux uses don't like that. + case ${GRUB_DEVICE} in +@@ -99,6 +113,32 @@ + + title_correction_code= + ++if [ -d /sys/firmware/efi ]; then ++ is_efi=true ++ err_msg="" ++ efi_dir="/boot/efi/efi/${os}" ++ grub_dir=/boot/@PACKAGE@ ++ xen_dir=/usr/share/efi/$machine ++ [ -d $xen_dir ] || xen_dir=/usr/lib64/efi ++ for d in $grub_dir $efi_dir $xen_dir; do ++ [ ! -d "$d" ] || continue ++ err_msg="${err_msg}$ME: Essential directory '$d' not found!\n" ++ done ++ if ! [ -d "$efi_dir" -a -d "$grub_dir" -a -d "$xen_dir" ]; then ++ err_msg="${err_msg}$ME: XEN configuration skipped!\n" ++ else ++ rm -f $grub_dir/xen*.cfg ++ if [ -s $efi_dir/grub.xen-files ]; then ++ for f in $(sort $efi_dir/grub.xen-files| uniq); do ++ rm -f $efi_dir/$f ++ done ++ : > $efi_dir/grub.xen-files ++ fi ++ fi ++else ++ is_efi=false ++fi ++ + linux_entry () + { + linux_entry_xsm "$@" false +@@ -154,6 +194,40 @@ + save_default_entry | grub_add_tab | sed "s/^/$submenu_indentation/" + fi + ++ if $is_efi; then ++ xen_cfg=${xen_basename/.efi/.cfg} ++ if [ "$section_count" = 0 ]; then ++ cat <<-EOF > $grub_dir/$xen_cfg ++ # disclaimer ++ [global] ++ #default= ++ EOF ++ fi ++ section_count=$(expr $section_count + 1) ++ if [ x$type != xrecovery ] ; then ++ section="config.$section_count" ++ else ++ section="failsafe.$section_count" ++ fi ++ cat <<-EOF >> $grub_dir/$xen_cfg ++ ++ [$section] ++ options=${xen_args} ++ kernel=${basename} root=${linux_root_device_thisversion} ${args} ++ ramdisk=${initrd_real} ++ EOF ++ message="$(gettext_printf "Loading Xen %s with Linux %s ..." ${xen_version} ${version})" ++ sed "s/^/$submenu_indentation/" <<-EOF ++ echo '$(echo "$message" | grub_quote)' ++ chainloader \$cmdpath/${xen_basename} ${xen_basename} $section ++ } ++ EOF ++ for f in ${grub_dir}/$xen_cfg ${xen_dir}/${xen_basename} ${dirname}/${basename} ${dirname}/${initrd_real}; do ++ cp --preserve=timestamps $f $efi_dir ++ echo $(basename $f) >> $efi_dir/grub.xen-files ++ done ++ return ++ fi + if [ -z "${prepare_boot_cache}" ]; then + prepare_boot_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE_BOOT} | grub_add_tab)" + fi +@@ -245,16 +319,6 @@ + + title_correction_code= + +-machine=`uname -m` +- +-case "$machine" in +- i?86) GENKERNEL_ARCH="x86" ;; +- mips|mips64) GENKERNEL_ARCH="mips" ;; +- mipsel|mips64el) GENKERNEL_ARCH="mipsel" ;; +- arm*) GENKERNEL_ARCH="arm" ;; +- *) GENKERNEL_ARCH="$machine" ;; +-esac +- + # Extra indentation to add to menu entries in a submenu. We're not in a submenu + # yet, so it's empty. In a submenu it will be equal to '\t' (one tab). + submenu_indentation="" +@@ -325,6 +389,24 @@ + xen_dirname=`dirname ${current_xen}` + rel_xen_dirname=`make_system_path_relative_to_its_root $xen_dirname` + xen_version=`echo $xen_basename | sed -e "s,.gz$,,g;s,^xen-,,g"` ++ xen_list=`echo $xen_list | tr ' ' '\n' | grep -vx $current_xen | tr '\n' ' '` ++ if $is_efi; then ++ xen_basename=${xen_basename/.gz/.efi} ++ if ! [ -f ${xen_dir}/${xen_basename} ]; then ++ echo "Skip missing hypervisor $xen_dir/$xen_basename" >&2 ++ continue ++ elif [ -L ${xen_dir}/${xen_basename} ]; then ++ xen_target=$(basename $(readlink -e ${xen_dir}/${xen_basename})) ++ if [ -f ${efi_dir}/${xen_target} ]; then ++ echo "Skip duplicate $xen_dir/$xen_basename for $xen_target" >&2 ++ continue ++ fi ++ elif [ -n "$err_msg" ]; then ++ break ++ fi ++ gettext_printf "Found hypervisor: %s\n" "$current_xen" >&2 ++ section_count=0 ++ fi + if [ -z "$boot_device_id" ]; then + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" + fi +@@ -445,3 +527,7 @@ + fi + + echo "$title_correction_code" ++ ++if [ -n "$err_msg" ]; then ++ echo -en "$err_msg" >&2 ++fi diff --git a/grub2-efi-xen-cmdline.patch b/grub2-efi-xen-cmdline.patch new file mode 100644 index 0000000000000000000000000000000000000000..841f8866a672e00b7dba3485ddf56f4f7a45a345 --- /dev/null +++ b/grub2-efi-xen-cmdline.patch @@ -0,0 +1,23 @@ +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -298,7 +298,8 @@ + GRUB_BADRAM \ + GRUB_OS_PROBER_SKIP_LIST \ + GRUB_DISABLE_SUBMENU \ +- SUSE_BTRFS_SNAPSHOT_BOOTING ++ SUSE_BTRFS_SNAPSHOT_BOOTING \ ++ SUSE_CMDLINE_XENEFI + + if test "x${grub_cfg}" != "x"; then + rm -f "${grub_cfg}.new" +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -219,7 +219,7 @@ + message="$(gettext_printf "Loading Xen %s with Linux %s ..." ${xen_version} ${version})" + sed "s/^/$submenu_indentation/" <<-EOF + echo '$(echo "$message" | grub_quote)' +- chainloader \$cmdpath/${xen_basename} ${xen_basename} $section ++ chainloader \$cmdpath/${xen_basename} ${xen_basename} ${SUSE_CMDLINE_XENEFI} $section + } + EOF + for f in ${grub_dir}/$xen_cfg ${xen_dir}/${xen_basename} ${dirname}/${basename} ${dirname}/${initrd_real}; do diff --git a/grub2-efi-xen-removable.patch b/grub2-efi-xen-removable.patch new file mode 100644 index 0000000000000000000000000000000000000000..e65cce895ba8babcf641f1eb6ca7f6578b830e26 --- /dev/null +++ b/grub2-efi-xen-removable.patch @@ -0,0 +1,117 @@ +From: Michael Chang +References: bsc#1085842 +Patch-Mainline: no + +The grub can be installed with removable option to support booting from +removable media with standard UEFI default file path of the form: + \EFI\BOOT\BOOT{machine type short-name}.EFI + +It does not make use of distributor directory, which becomes a problem for UEFI +Xen installation as it requires that directory to be present for storing xen +stuff like chainloaded hypervisor, xen kernel and so on. Moreover it makes bad +assumption that hypervisor will be chainloaded by grub under the same +directory, which is also not always true. + +This patch fixes the problem by ensuring the directory available to Xen +installation if any Xen hypervisor found and independent to grub boot path +$cmdpath to work. + +--- + util/grub.d/20_linux_xen.in | 62 ++++++++++++++++++++++++-------------------- + 1 file changed, 35 insertions(+), 27 deletions(-) + +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -113,32 +113,6 @@ + + title_correction_code= + +-if [ -d /sys/firmware/efi ]; then +- is_efi=true +- err_msg="" +- efi_dir="/boot/efi/efi/${os}" +- grub_dir=/boot/@PACKAGE@ +- xen_dir=/usr/share/efi/$machine +- [ -d $xen_dir ] || xen_dir=/usr/lib64/efi +- for d in $grub_dir $efi_dir $xen_dir; do +- [ ! -d "$d" ] || continue +- err_msg="${err_msg}$ME: Essential directory '$d' not found!\n" +- done +- if ! [ -d "$efi_dir" -a -d "$grub_dir" -a -d "$xen_dir" ]; then +- err_msg="${err_msg}$ME: XEN configuration skipped!\n" +- else +- rm -f $grub_dir/xen*.cfg +- if [ -s $efi_dir/grub.xen-files ]; then +- for f in $(sort $efi_dir/grub.xen-files| uniq); do +- rm -f $efi_dir/$f +- done +- : > $efi_dir/grub.xen-files +- fi +- fi +-else +- is_efi=false +-fi +- + grub2_unquote () + { + awk ' +@@ -264,10 +238,15 @@ + kernel=${basename} root=${linux_root_device_thisversion} ${args_unq} + ramdisk=${initrd_real} + EOF ++ if [ -z "${prepare_efi_cache}" ]; then ++ grub_device_efi="`${grub_probe} --target=device /boot/efi`" ++ prepare_efi_cache="$(prepare_grub_to_access_device ${grub_device_efi} | grub_add_tab)" ++ fi ++ printf '%s\n' "${prepare_efi_cache}" | sed "s/^/$submenu_indentation/" + message="$(gettext_printf "Loading Xen %s with Linux %s ..." ${xen_version} ${version})" + sed "s/^/$submenu_indentation/" <<-EOF + echo '$(echo "$message" | grub_quote)' +- chainloader \$cmdpath/${xen_basename} ${xen_basename} ${SUSE_CMDLINE_XENEFI} $section ++ chainloader ${rel_efi_dir}/${xen_basename} ${xen_basename} ${SUSE_CMDLINE_XENEFI} $section + } + EOF + for f in ${grub_dir}/$xen_cfg ${xen_dir}/${xen_basename} ${dirname}/${basename} ${dirname}/${initrd_real}; do +@@ -363,6 +342,7 @@ + done + fi + prepare_boot_cache= ++prepare_efi_cache= + boot_device_id= + + title_correction_code= +@@ -432,6 +412,34 @@ + + is_top_level=true + ++if [ -d /sys/firmware/efi ] && [ "x${xen_list}" != "x" ]; then ++ is_efi=true ++ err_msg="" ++ efi_dir="/boot/efi/efi/${os}" ++ grub_dir=/boot/grub2 ++ xen_dir=/usr/share/efi/$machine ++ [ -d $xen_dir ] || xen_dir=/usr/lib64/efi ++ for d in $grub_dir $xen_dir; do ++ [ ! -d "$d" ] || continue ++ err_msg="${err_msg}$ME: Essential directory '$d' not found!\n" ++ done ++ if ! [ -d "$grub_dir" -a -d "$xen_dir" ]; then ++ err_msg="${err_msg}$ME: XEN configuration skipped!\n" ++ else ++ mkdir -p $efi_dir ++ rel_efi_dir=`make_system_path_relative_to_its_root $efi_dir` ++ rm -f $grub_dir/xen*.cfg ++ if [ -s $efi_dir/grub.xen-files ]; then ++ for f in $(sort $efi_dir/grub.xen-files| uniq); do ++ rm -f $efi_dir/$f ++ done ++ : > $efi_dir/grub.xen-files ++ fi ++ fi ++else ++ is_efi=false ++fi ++ + for current_xen in ${reverse_sorted_xen_list}; do + xen_basename=`basename ${current_xen}` + xen_dirname=`dirname ${current_xen}` diff --git a/grub2-efi_gop-avoid-low-resolution.patch b/grub2-efi_gop-avoid-low-resolution.patch new file mode 100644 index 0000000000000000000000000000000000000000..484cee1eddeac2e0cdec38c15e96686431eadaf2 --- /dev/null +++ b/grub2-efi_gop-avoid-low-resolution.patch @@ -0,0 +1,39 @@ +--- + grub-core/video/efi_gop.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) + +--- a/grub-core/video/efi_gop.c ++++ b/grub-core/video/efi_gop.c +@@ -358,6 +358,7 @@ grub_video_gop_setup (unsigned int width + grub_err_t err; + unsigned bpp; + int found = 0; ++ int avoid_low_resolution = 1; + unsigned long long best_volume = 0; + unsigned int preferred_width = 0, preferred_height = 0; + grub_uint8_t *buffer; +@@ -376,8 +377,11 @@ grub_video_gop_setup (unsigned int width + } + } + ++again: + /* Keep current mode if possible. */ +- if (gop->mode->info) ++ if (gop->mode->info && ++ (!avoid_low_resolution || ++ (gop->mode->info->width >= 800 && gop->mode->info->height >= 600))) + { + bpp = grub_video_gop_get_bpp (gop->mode->info); + if (bpp && ((width == gop->mode->info->width +@@ -450,6 +454,11 @@ grub_video_gop_setup (unsigned int width + + if (!found) + { ++ if (avoid_low_resolution && gop->mode->info) ++ { ++ avoid_low_resolution = 0; ++ goto again; ++ } + grub_dprintf ("video", "GOP: no mode found\n"); + return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching mode found"); + } diff --git a/grub2-emu-4-all.patch b/grub2-emu-4-all.patch new file mode 100644 index 0000000000000000000000000000000000000000..ad2526fef6797172bae0070ac67df5c6335f8679 --- /dev/null +++ b/grub2-emu-4-all.patch @@ -0,0 +1,162 @@ +--- + Makefile.util.def | 10 +++++----- + configure.ac | 1 + + grub-core/Makefile.core.def | 14 +++++--------- + grub-core/osdep/unix/emuconsole.c | 5 +++-- + 4 files changed, 14 insertions(+), 16 deletions(-) + +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -377,7 +377,7 @@ + ldadd = grub-core/lib/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + cppflags = '-DGRUB_SETUP_FUNC=grub_util_bios_setup'; +- emu_condition = COND_NOT_s390x; ++ emu_condition = COND_NOT_emu; + }; + + program = { +@@ -398,7 +398,7 @@ + ldadd = grub-core/lib/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + cppflags = '-DGRUB_SETUP_FUNC=grub_util_sparc_setup'; +- emu_condition = COND_NOT_s390x; ++ emu_condition = COND_NOT_emu; + }; + + program = { +@@ -414,7 +414,7 @@ + ldadd = libgrubkern.a; + ldadd = grub-core/lib/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; +- emu_condition = COND_NOT_s390x; ++ emu_condition = COND_NOT_emu; + }; + + program = { +@@ -445,7 +445,7 @@ + ldadd = libgrubkern.a; + ldadd = grub-core/lib/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; +- emu_condition = COND_NOT_s390x; ++ emu_condition = COND_NOT_emu; + }; + + data = { +@@ -1420,7 +1420,7 @@ + ldadd = libgrubkern.a; + ldadd = grub-core/lib/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; +- emu_condition = COND_NOT_s390x; ++ emu_condition = COND_NOT_emu; + }; + + program = { +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1183,7 +1183,7 @@ + module = { + name = videotest; + common = commands/videotest.c; +- emu_condition = COND_NOT_s390x; ++ emu_condition = COND_NOT_emu; + }; + + module = { +@@ -1638,7 +1638,7 @@ + common = gfxmenu/gui_progress_bar.c; + common = gfxmenu/gui_util.c; + common = gfxmenu/gui_string_util.c; +- emu_condition = COND_NOT_s390x; ++ emu_condition = COND_NOT_emu; + }; + + module = { +@@ -2077,13 +2077,13 @@ + name = gfxterm; + common = term/gfxterm.c; + enable = videomodules; +- emu_condition = COND_NOT_s390x; ++ emu_condition = COND_NOT_emu; + }; + + module = { + name = gfxterm_background; + common = term/gfxterm_background.c; +- emu_condition = COND_NOT_s390x; ++ emu_condition = COND_NOT_emu; + }; + + module = { +@@ -2204,9 +2204,7 @@ + enable = i386_xen_pvh; + enable = i386_efi; + enable = x86_64_efi; +- enable = emu; + enable = xen; +- emu_condition = COND_NOT_s390x; + }; + + module = { +@@ -2253,7 +2251,7 @@ + module = { + name = gfxterm_menu; + common = tests/gfxterm_menu.c; +- emu_condition = COND_NOT_s390x; ++ emu_condition = COND_NOT_emu; + }; + + module = { +@@ -2413,9 +2411,7 @@ + enable = i386_xen_pvh; + enable = i386_efi; + enable = x86_64_efi; +- enable = emu; + enable = xen; +- emu_condition = COND_NOT_s390x; + }; + + module = { +--- a/configure.ac ++++ b/configure.ac +@@ -2061,6 +2061,7 @@ + + AM_CONDITIONAL([COND_real_platform], [test x$platform != xnone]) + AM_CONDITIONAL([COND_emu], [test x$platform = xemu]) ++AM_CONDITIONAL([COND_NOT_emu], [test x$platform != xemu]) + AM_CONDITIONAL([COND_arm], [test x$target_cpu = xarm ]) + AM_CONDITIONAL([COND_arm_uboot], [test x$target_cpu = xarm -a x$platform = xuboot]) + AM_CONDITIONAL([COND_arm_coreboot], [test x$target_cpu = xarm -a x$platform = xcoreboot]) +--- a/grub-core/osdep/unix/emuconsole.c ++++ b/grub-core/osdep/unix/emuconsole.c +@@ -50,13 +50,12 @@ + static int console_mode = 0; + + #define MAX_LEN 1023 +-#if defined(__s390x__) ++ + static int + dummy (void) + { + return 0; + } +-#endif + #if 0 + static char msg[MAX_LEN+1]; + static void +@@ -128,6 +127,7 @@ + return -1; + } + ++#if defined(__s390x__) + #define NO_KEY ((grub_uint8_t)-1) + static int + readkey_dumb (struct grub_term_input *term) +@@ -158,6 +158,7 @@ + p = c; + return c; + } ++#endif + + static void + grub_dumb_putchar (struct grub_term_output *term, diff --git a/grub2-fix-error-terminal-gfxterm-isn-t-found.patch b/grub2-fix-error-terminal-gfxterm-isn-t-found.patch new file mode 100644 index 0000000000000000000000000000000000000000..b7ce5639030147474c1d4528c4efe9a72f16ae6b --- /dev/null +++ b/grub2-fix-error-terminal-gfxterm-isn-t-found.patch @@ -0,0 +1,34 @@ +From e2e0fe44cf2a03744e96f886f95ab2c2a8aed331 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Wed, 18 Jul 2012 14:54:32 +0800 +Subject: [PATCH] fix error: terminal 'gfxterm' isn't found + +References: bnc#771393 +Patch-Mainline: no + +If set GRUB_TERMINAL="gfxterm", the error message "terminal +'gfxterm' isn't found" will be logged to screen. This is caused +by GRUB_TERMINAL_INPUT erroneously set to gfxterm. This patch +fixes the issue by not setting it. + +v2: +Fix error gfxterm isn't found with multiple terminals (bsc#1187565) + +--- + util/grub-mkconfig.in | 6 +++++- + 1 files changed, 5 insertions(+), 1 deletions(-) + +Index: grub-2.06/util/grub-mkconfig.in +=================================================================== +--- grub-2.06.orig/util/grub-mkconfig.in ++++ grub-2.06/util/grub-mkconfig.in +@@ -172,7 +172,8 @@ fi + + # XXX: should this be deprecated at some point? + if [ "x${GRUB_TERMINAL}" != "x" ] ; then +- GRUB_TERMINAL_INPUT="${GRUB_TERMINAL}" ++# bnc#771393, bsc#1187565 - fix error: terminal 'gfxterm' isn't found. ++ GRUB_TERMINAL_INPUT="`echo ${GRUB_TERMINAL} | sed -e '/\bgfxterm\b/{s/\bconsole\b//g;s/\bgfxterm\b/console/}'`" + GRUB_TERMINAL_OUTPUT="${GRUB_TERMINAL}" + fi + diff --git a/grub2-fix-menu-in-xen-host-server.patch b/grub2-fix-menu-in-xen-host-server.patch new file mode 100644 index 0000000000000000000000000000000000000000..e0c7e78f2520a49c8c528a1b0cf83288e2c48b93 --- /dev/null +++ b/grub2-fix-menu-in-xen-host-server.patch @@ -0,0 +1,110 @@ +From b411dc88b46890400a2e1ba0aa8650e00f738c23 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Thu, 19 Jul 2012 18:43:55 +0800 +Subject: [PATCH] fix menu in xen host server + +References: bnc#771689, bnc#757895 +Patch-Mainline: no + +When system is configred as "Xen Virtual Machines Host Server", the +grub2 menu is not well organized. We could see some issues on it. + + - Many duplicated xen entries generated by links to xen hypervisor + - Non bootable kernel entries trying to boot xen kernel natively + - The -dbg xen hypervisor takes precedence over release version + +This patch fixes above three issues. + +v2: +References: bnc#877040 +Create only hypervisor pointed by /boot/xen.gz symlink to not clutter +the menu with multiple versions and also not include -dbg. Use custom.cfg +if you need any other custom entries. + +--- + util/grub-mkconfig_lib.in | 5 +++++ + util/grub.d/10_linux.in | 12 ++++++++++-- + util/grub.d/20_linux_xen.in | 6 ++++-- + 3 files changed, 19 insertions(+), 4 deletions(-) + +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -26,6 +26,12 @@ + export TEXTDOMAIN=@PACKAGE@ + export TEXTDOMAINDIR="@localedir@" + ++if [ ! -e /proc/xen/xsd_port -a -e /proc/xen ]; then ++# we're running on xen domU guest ++# prevent setting up nested virt on HVM or PV domU guest ++ exit 0 ++fi ++ + CLASS="--class gnu-linux --class gnu --class os --class xen" + + if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then +@@ -213,10 +219,18 @@ + esac + } + +-xen_list= +-for i in /boot/xen*; do +- if grub_file_is_not_garbage "$i" && file_is_not_xen_garbage "$i" ; then xen_list="$xen_list $i" ; fi +-done ++# bnc#877040 - Duplicate entries for boot menu created ++# only create /boot/xen.gz symlink boot entry ++if test -L /boot/xen.gz; then ++ xen_list=`readlink -f /boot/xen.gz` ++else ++ # bnc#757895 - Grub2 menu items incorrect when "Xen Virtual Machines Host Server" selected ++ # wildcard expasion with correct suffix (.gz) for not generating many duplicated menu entries ++ xen_list= ++ for i in /boot/xen*.gz; do ++ if grub_file_is_not_garbage "$i" && file_is_not_sym "$i" ; then xen_list="$xen_list $i" ; fi ++ done ++fi + prepare_boot_cache= + boot_device_id= + +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -258,6 +258,40 @@ + fi + done + ++ # try to get the kernel config if $linux is a symlink ++ if test -z "${config}" ; then ++ lnk_version=`basename \`readlink -f $linux\` | sed -e "s,^[^0-9]*-,,g"` ++ if (test -n ${lnk_version} && test -e "${dirname}/config-${lnk_version}") ; then ++ config="${dirname}/config-${lnk_version}" ++ fi ++ fi ++ ++ # check if we are in xen domU ++ if [ ! -e /proc/xen/xsd_port -a -e /proc/xen ]; then ++ # we're running on xen domU guest ++ dmi=/sys/class/dmi/id ++ if [ -r "${dmi}/product_name" -a -r "${dmi}/sys_vendor" ]; then ++ product_name=`cat ${dmi}/product_name` ++ sys_vendor=`cat ${dmi}/sys_vendor` ++ if test "${sys_vendor}" = "Xen" -a "${product_name}" = "HVM domU"; then ++ # xen HVM guest ++ xen_pv_domU=false ++ fi ++ fi ++ else ++ # we're running on baremetal or xen dom0 ++ xen_pv_domU=false ++ fi ++ ++ if test "$xen_pv_domU" = "false" ; then ++ # prevent xen kernel without pv_opt support from booting ++ if (grep -qx "CONFIG_XEN=y" "${config}" 2> /dev/null && ! grep -qx "CONFIG_PARAVIRT=y" "${config}" 2> /dev/null); then ++ echo "Skip xenlinux kernel $linux" >&2 ++ list=`echo $list | tr ' ' '\n' | grep -vx $linux | tr '\n' ' '` ++ continue ++ fi ++ fi ++ + initramfs= + if test -n "${config}" ; then + initramfs=`grep CONFIG_INITRAMFS_SOURCE= "${config}" | cut -f2 -d= | tr -d \"` diff --git a/grub2-getroot-scan-disk-pv.patch b/grub2-getroot-scan-disk-pv.patch new file mode 100644 index 0000000000000000000000000000000000000000..e32323847dae47a016cd16e99165c1a32f4659f6 --- /dev/null +++ b/grub2-getroot-scan-disk-pv.patch @@ -0,0 +1,43 @@ +From: Michael Chang +Subject: Fix grub2-mkconfig warning when disk is LVM PV +References: bsc#1071239 + +When a disk device was found in grub_util_biosdisk_get_grub_dev, its grub +hostdisk device name just returned. Since the disk could also be used as PV +disk, use grub_util_get_ldm to kick scanning of on disk metadata and adding it +to VG array. + +--- +Index: grub-2.02/util/getroot.c +=================================================================== +--- grub-2.02.orig/util/getroot.c ++++ grub-2.02/util/getroot.c +@@ -272,8 +272,28 @@ grub_util_biosdisk_get_grub_dev (const c + grub_util_info ("%s is a parent of %s", sys_disk, os_dev); + if (!is_part) + { ++#if defined(__APPLE__) + free (sys_disk); + return make_device_name (drive); ++#else ++ char *name, *ldm_name; ++ grub_disk_t disk; ++ ++ free (sys_disk); ++ name = make_device_name (drive); ++ disk = grub_disk_open (name); ++ if (!disk) ++ return name; ++ ldm_name = grub_util_get_ldm (disk, 0); ++ if (ldm_name) ++ { ++ grub_disk_close (disk); ++ grub_free (name); ++ return ldm_name; ++ } ++ grub_disk_close (disk); ++ return name; ++#endif + } + free (sys_disk); + diff --git a/grub2-getroot-support-nvdimm.patch b/grub2-getroot-support-nvdimm.patch new file mode 100644 index 0000000000000000000000000000000000000000..ed78ae5358ecfe3e87949f33d6eb2a78e75a6305 --- /dev/null +++ b/grub2-getroot-support-nvdimm.patch @@ -0,0 +1,66 @@ +From 889c0894d358e48c02f8225426893094f20004e5 Mon Sep 17 00:00:00 2001 +From: Gary Lin +Date: Thu, 4 Oct 2018 10:32:07 +0800 +Subject: [PATCH] linux/getroot: Support NVDIMM device names + +There are two types of NVDIMM block devices in linux: fsdax and blk. +For fsdax, the device name would be /dev/pmemXpY, /dev/pmemXsY, +/dev/pmemX.YpZ, or /dev/pmemX.YsZ. +For blk, the name would be /dev/ndblkX.YpZ or /dev/ndblkX.YsZ +--- + grub-core/osdep/linux/getroot.c | 44 +++++++++++++++++++++++++++++++++ + 1 file changed, 44 insertions(+) + +--- a/grub-core/osdep/linux/getroot.c ++++ b/grub-core/osdep/linux/getroot.c +@@ -971,6 +971,50 @@ + *pp = '\0'; + return path; + } ++ ++ /* If this is a NVDIMM device in fsdax mode */ ++ if (strncmp ("pmem", p, 4) == 0 && p[4] >= '0' && p[4] <= '9') ++ { ++ /* /dev/pmem[0-9]+(\.[0-9]+)?((p[0-9]+)?|s[0-9]*) */ ++ char *pp = strchr (p + 4, 'p'); ++ if (pp) ++ { ++ *is_part = 1; ++ *pp = '\0'; ++ } ++ else ++ { ++ pp = strchr (p + 4, 's'); ++ if (pp && pp[1] >= '0' && pp[1] <= '9') ++ { ++ *is_part = 1; ++ pp[1] = '\0'; ++ } ++ } ++ return path; ++ } ++ ++ /* If this is a NVDIMM device in block mode */ ++ if (strncmp ("ndblk", p, 5) == 0 && p[5] >= '0' && p[5] <= '9') ++ { ++ /* /dev/ndblk[0-9]+\.[0-9]+((p[0-9]+)?|s[0-9]*) */ ++ char *pp = strchr (p + 5, 'p'); ++ if (pp) ++ { ++ *is_part = 1; ++ *pp = '\0'; ++ } ++ else ++ { ++ pp = strchr (p + 5, 's'); ++ if (pp && pp[1] >= '0' && pp[1] <= '9') ++ { ++ *is_part = 1; ++ pp[1] = '\0'; ++ } ++ } ++ return path; ++ } + } + + return path; diff --git a/grub2-getroot-treat-mdadm-ddf-as-simple-device.patch b/grub2-getroot-treat-mdadm-ddf-as-simple-device.patch new file mode 100644 index 0000000000000000000000000000000000000000..3e36e521f3f58d11a9c67dae861dd976bdde150e --- /dev/null +++ b/grub2-getroot-treat-mdadm-ddf-as-simple-device.patch @@ -0,0 +1,66 @@ +From: Michael Chang +Subject: treat mdadm ddf fakeraid as simple device +References: bnc#872360 +Patch-Mainline: no + +--- a/grub-core/osdep/linux/getroot.c ++++ b/grub-core/osdep/linux/getroot.c +@@ -119,7 +119,7 @@ + struct btrfs_ioctl_fs_info_args) + + static int +-grub_util_is_imsm (const char *os_dev); ++grub_util_is_imsm_or_ddf (const char *os_dev); + + + #define ESCAPED_PATH_MAX (4 * PATH_MAX) +@@ -635,10 +635,10 @@ + } + + static int +-grub_util_is_imsm (const char *os_dev) ++grub_util_is_imsm_or_ddf (const char *os_dev) + { + int retry; +- int is_imsm = 0; ++ int is_imsm_or_ddf = 0; + int container_seen = 0; + const char *dev = os_dev; + +@@ -699,10 +699,17 @@ + if (strncmp (buf, "MD_METADATA=imsm", + sizeof ("MD_METADATA=imsm") - 1) == 0) + { +- is_imsm = 1; ++ is_imsm_or_ddf = 1; + grub_util_info ("%s is imsm", dev); + break; + } ++ if (strncmp (buf, "MD_METADATA=ddf", ++ sizeof ("MD_METADATA=ddf") - 1) == 0) ++ { ++ is_imsm_or_ddf = 1; ++ grub_util_info ("%s is ddf", dev); ++ break; ++ } + } + + free (buf); +@@ -713,7 +720,7 @@ + + if (dev != os_dev) + free ((void *) dev); +- return is_imsm; ++ return is_imsm_or_ddf; + } + + char * +@@ -1078,7 +1085,7 @@ + + /* Check for RAID. */ + if (!strncmp (os_dev, "/dev/md", 7) && ! grub_util_device_is_mapped (os_dev) +- && !grub_util_is_imsm (os_dev)) ++ && !grub_util_is_imsm_or_ddf (os_dev)) + return GRUB_DEV_ABSTRACTION_RAID; + return GRUB_DEV_ABSTRACTION_NONE; + } diff --git a/grub2-gfxmenu-support-scrolling-menu-entry-s-text.patch b/grub2-gfxmenu-support-scrolling-menu-entry-s-text.patch new file mode 100644 index 0000000000000000000000000000000000000000..61b8fed7dd97969293d73c7c0d2e7d472b7f116d --- /dev/null +++ b/grub2-gfxmenu-support-scrolling-menu-entry-s-text.patch @@ -0,0 +1,269 @@ +From b4c5f80fbfaf912553eca1b12da6fc49de4ae37f Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Mon, 7 Jan 2019 17:55:05 +0800 +Subject: [PATCH] gfxmenu: support scrolling menu entry's text + +If menu entry's title text is longer than its display width, the +overlong text simply get truncated. The only possible way to view the +full text is through the menu editing mode, but is a hassle switching +over the mode back and forth. Also menu editing mode could be password +protected which makes it not generally available to everyone. + +This patch implemented scrolling text support to the title of grub's +gfxmenu to make it convenient for viewing the truncated text by pressing +the ctrl+l and ctrl+r to scroll the highlighted text left and right. The +scrolled result will remain in place to help memorizing it after +changing highlight to other entry. + +V1: + * Use grub_calloc for overflow check and return NULL when it would + occur. +--- + grub-core/gfxmenu/gfxmenu.c | 3 +++ + grub-core/gfxmenu/gui_label.c | 2 ++ + grub-core/gfxmenu/gui_list.c | 38 ++++++++++++++++++++++++++++++++++ + grub-core/gfxmenu/view.c | 48 +++++++++++++++++++++++++++++++++++++++++++ + grub-core/normal/menu.c | 16 +++++++++++++++ + include/grub/gfxmenu_view.h | 4 ++++ + include/grub/menu_viewer.h | 1 + + 7 files changed, 112 insertions(+) + +--- a/grub-core/gfxmenu/gfxmenu.c ++++ b/grub-core/gfxmenu/gfxmenu.c +@@ -108,6 +108,15 @@ + view->menu = menu; + view->nested = nested; + view->first_timeout = -1; ++ if (menu->size) ++ { ++ view->menu_title_offset = grub_calloc (menu->size, sizeof (*view->menu_title_offset)); ++ if (!view->menu_title_offset) ++ { ++ grub_free (instance); ++ return grub_errno; ++ } ++ } + + grub_video_set_viewport (0, 0, mode_info.width, mode_info.height); + if (view->double_repaint) +@@ -123,6 +132,7 @@ + instance->fini = grub_gfxmenu_viewer_fini; + instance->print_timeout = grub_gfxmenu_print_timeout; + instance->clear_timeout = grub_gfxmenu_clear_timeout; ++ instance->scroll_chosen_entry = grub_gfxmenu_scroll_chosen_entry; + + grub_menu_register_viewer (instance); + +--- a/grub-core/gfxmenu/gui_label.c ++++ b/grub-core/gfxmenu/gui_label.c +@@ -192,6 +192,8 @@ + "or `c' for a command-line."); + else if (grub_strcmp (value, "@KEYMAP_SHORT@") == 0) + value = _("enter: boot, `e': options, `c': cmd-line"); ++ else if (grub_strcmp (value, "@SUSE_KEYMAP_SCROLL_ENTRY@") == 0) ++ value = _("ctrl+l: scroll entry left, ctrl+r: scroll entry right"); + /* FIXME: Add more templates here if needed. */ + + if (grub_printf_fmt_check(value, "%d") != GRUB_ERR_NONE) +--- a/grub-core/gfxmenu/gui_list.c ++++ b/grub-core/gfxmenu/gui_list.c +@@ -24,6 +24,7 @@ + #include + #include + #include ++#include + + enum scrollbar_slice_mode { + SCROLLBAR_SLICE_WEST, +@@ -314,6 +315,33 @@ + thumb->draw (thumb, thumbx, thumby); + } + ++static const char * ++grub_utf8_offset_code (const char *src, grub_size_t srcsize, int num) ++{ ++ int count = 0; ++ grub_uint32_t code = 0; ++ ++ while (srcsize && num) ++ { ++ if (srcsize != (grub_size_t)-1) ++ srcsize--; ++ if (!grub_utf8_process ((grub_uint8_t)*src++, &code, &count)) ++ return 0; ++ if (count != 0) ++ continue; ++ if (code == 0) ++ return 0; ++ if (code > GRUB_UNICODE_LAST_VALID) ++ return 0; ++ --num; ++ } ++ ++ if (!num) ++ return src; ++ ++ return 0; ++} ++ + /* Draw the list of items. */ + static void + draw_menu (list_impl_t self, int num_shown_items) +@@ -433,6 +461,16 @@ + const char *item_title = + grub_menu_get_entry (self->view->menu, menu_index)->title; + ++ { ++ int off = self->view->menu_title_offset[menu_index]; ++ const char *scrolled_title; ++ ++ scrolled_title = grub_utf8_offset_code (item_title, grub_strlen (item_title), off); ++ ++ if (scrolled_title) ++ item_title = scrolled_title; ++ } ++ + sviewport.y = item_top + top_pad; + sviewport.width = viewport_width; + grub_gui_set_viewport (&sviewport, &svpsave); +--- a/grub-core/gfxmenu/view.c ++++ b/grub-core/gfxmenu/view.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + + static void + init_terminal (grub_gfxmenu_view_t view); +@@ -103,6 +104,7 @@ + view->title_text = grub_strdup (_("GRUB Boot Menu")); + view->progress_message_text = 0; + view->theme_path = 0; ++ view->menu_title_offset = 0; + + /* Set the timeout bar's frame. */ + view->progress_message_frame.width = view->screen.width * 4 / 5; +@@ -142,6 +144,7 @@ + grub_free (view->title_text); + grub_free (view->progress_message_text); + grub_free (view->theme_path); ++ grub_free (view->menu_title_offset); + if (view->canvas) + view->canvas->component.ops->destroy (view->canvas); + grub_free (view); +@@ -410,6 +413,52 @@ + grub_gfxmenu_redraw_menu (view); + } + ++static int ++grub_utf8_get_num_code (const char *src, grub_size_t srcsize) ++{ ++ int count = 0; ++ grub_uint32_t code = 0; ++ int num = 0; ++ ++ while (srcsize) ++ { ++ if (srcsize != (grub_size_t)-1) ++ srcsize--; ++ if (!grub_utf8_process ((grub_uint8_t)*src++, &code, &count)) ++ return 0; ++ if (count != 0) ++ continue; ++ if (code == 0) ++ return num; ++ if (code > GRUB_UNICODE_LAST_VALID) ++ return 0; ++ ++num; ++ } ++ ++ return num; ++} ++ ++void ++grub_gfxmenu_scroll_chosen_entry (void *data, int diren) ++{ ++ grub_gfxmenu_view_t view = data; ++ const char *item_title; ++ int off; ++ ++ if (!view->menu->size) ++ return; ++ ++ item_title =grub_menu_get_entry (view->menu, view->selected)->title; ++ off = view->menu_title_offset[view->selected] + diren; ++ ++ if (off < 0 ++ || off > grub_utf8_get_num_code (item_title, grub_strlen(item_title))) ++ return; ++ ++ view->menu_title_offset[view->selected] = off; ++ grub_gfxmenu_redraw_menu (view); ++} ++ + static void + grub_gfxmenu_draw_terminal_box (void) + { +--- a/grub-core/normal/menu.c ++++ b/grub-core/normal/menu.c +@@ -400,6 +400,15 @@ + } + + static void ++menu_scroll_chosen_entry (int diren) ++{ ++ struct grub_menu_viewer *cur; ++ for (cur = viewers; cur; cur = cur->next) ++ if (cur->scroll_chosen_entry) ++ cur->scroll_chosen_entry (cur->data, diren); ++} ++ ++static void + menu_print_timeout (int timeout) + { + struct grub_menu_viewer *cur; +@@ -829,6 +838,13 @@ + menu_set_chosen_entry (current_entry); + break; + ++ case GRUB_TERM_CTRL | 'w': ++ menu_scroll_chosen_entry (1); ++ break; ++ case GRUB_TERM_CTRL | 'r': ++ menu_scroll_chosen_entry (-1); ++ break; ++ + case '\n': + case '\r': + case GRUB_TERM_KEY_RIGHT: +--- a/include/grub/gfxmenu_view.h ++++ b/include/grub/gfxmenu_view.h +@@ -61,6 +61,8 @@ + grub_gfxmenu_print_timeout (int timeout, void *data); + void + grub_gfxmenu_set_chosen_entry (int entry, void *data); ++void ++grub_gfxmenu_scroll_chosen_entry (void *data, int diren); + + grub_err_t grub_font_draw_string (const char *str, + grub_font_t font, +@@ -119,6 +121,8 @@ + int nested; + + int first_timeout; ++ ++ int *menu_title_offset; + }; + + #endif /* ! GRUB_GFXMENU_VIEW_HEADER */ +--- a/include/grub/menu_viewer.h ++++ b/include/grub/menu_viewer.h +@@ -33,6 +33,7 @@ + void (*set_chosen_entry) (int entry, void *data); + void (*print_timeout) (int timeout, void *data); + void (*clear_timeout) (void *data); ++ void (*scroll_chosen_entry) (void *data, int diren); + void (*fini) (void *fini); + }; + diff --git a/grub2-grubenv-in-btrfs-header.patch b/grub2-grubenv-in-btrfs-header.patch new file mode 100644 index 0000000000000000000000000000000000000000..cb1ac09e58cbc8b85acc23bea21d2f70758d23f0 --- /dev/null +++ b/grub2-grubenv-in-btrfs-header.patch @@ -0,0 +1,498 @@ +GRUB cannot write Btrfs file systems from the bootloader, so it cannot +modify values set from userspace (e.g. "next_entry" set by grub2-once). +As a workaround use the Btrfs header to store known data of the GRUB environment +block. + +v2: export env_block and make sure to use the device of grubenv + +v3: + * Use xcalloc for overflow check and return NULL when it would + occur. + +--- +--- a/grub-core/kern/fs.c ++++ b/grub-core/kern/fs.c +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + + grub_fs_t grub_fs_list = 0; + +@@ -236,6 +237,13 @@ + size, buf) != GRUB_ERR_NONE) + return -1; + ++ if (file->read_hook) ++ { ++ grub_disk_addr_t part_start; ++ ++ part_start = grub_partition_get_start (file->device->disk->partition); ++ file->read_hook (p->offset + sector + part_start, (unsigned)offset, (unsigned)size, NULL, file->read_hook_data); ++ } + ret += size; + len -= size; + sector -= ((size + offset) >> GRUB_DISK_SECTOR_BITS); +--- a/util/grub-editenv.c ++++ b/util/grub-editenv.c +@@ -23,8 +23,11 @@ + #include + #include + #include +-#include ++#include + #include ++#include ++#include ++#include + + #include + #include +@@ -120,6 +123,140 @@ + NULL, help_filter, NULL + }; + ++struct fs_envblk_spec { ++ const char *fs_name; ++ int offset; ++ int size; ++} fs_envblk_spec[] = { ++ { "btrfs", 256 * 1024, GRUB_DISK_SECTOR_SIZE }, ++ { NULL, 0, 0 } ++}; ++ ++struct fs_envblk { ++ struct fs_envblk_spec *spec; ++ const char *dev; ++}; ++ ++typedef struct fs_envblk_spec *fs_envblk_spec_t; ++typedef struct fs_envblk *fs_envblk_t; ++ ++fs_envblk_t fs_envblk = NULL; ++ ++static int ++read_envblk_fs (const char *varname, const char *value, void *hook_data) ++{ ++ grub_envblk_t *p_envblk = (grub_envblk_t *)hook_data; ++ ++ if (!p_envblk || !fs_envblk) ++ return 0; ++ ++ if (strcmp (varname, "env_block") == 0) ++ { ++ int off, sz; ++ char *p; ++ ++ off = strtol (value, &p, 10); ++ if (*p == '+') ++ sz = strtol (p+1, &p, 10); ++ ++ if (*p == '\0') ++ { ++ FILE *fp; ++ char *buf; ++ ++ off <<= GRUB_DISK_SECTOR_BITS; ++ sz <<= GRUB_DISK_SECTOR_BITS; ++ ++ fp = grub_util_fopen (fs_envblk->dev, "rb"); ++ if (! fp) ++ grub_util_error (_("cannot open `%s': %s"), fs_envblk->dev, ++ strerror (errno)); ++ ++ ++ if (fseek (fp, off, SEEK_SET) < 0) ++ grub_util_error (_("cannot seek `%s': %s"), fs_envblk->dev, ++ strerror (errno)); ++ ++ buf = xmalloc (sz); ++ if ((fread (buf, 1, sz, fp)) != sz) ++ grub_util_error (_("cannot read `%s': %s"), fs_envblk->dev, ++ strerror (errno)); ++ ++ fclose (fp); ++ ++ *p_envblk = grub_envblk_open (buf, sz); ++ } ++ } ++ ++ return 0; ++} ++ ++static void ++create_envblk_fs (void) ++{ ++ FILE *fp; ++ char *buf; ++ const char *device; ++ int offset, size; ++ ++ if (!fs_envblk) ++ return; ++ ++ device = fs_envblk->dev; ++ offset = fs_envblk->spec->offset; ++ size = fs_envblk->spec->size; ++ ++ fp = grub_util_fopen (device, "r+b"); ++ 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); ++ ++ if (fseek (fp, offset, SEEK_SET) < 0) ++ grub_util_error (_("cannot seek `%s': %s"), device, strerror (errno)); ++ ++ if (fwrite (buf, 1, size, fp) != size) ++ grub_util_error (_("cannot write to `%s': %s"), device, strerror (errno)); ++ ++ grub_util_file_sync (fp); ++ free (buf); ++ fclose (fp); ++} ++ ++static grub_envblk_t ++open_envblk_fs (grub_envblk_t envblk) ++{ ++ grub_envblk_t envblk_fs = NULL; ++ char *val; ++ int offset, size; ++ ++ if (!fs_envblk) ++ return NULL; ++ ++ offset = fs_envblk->spec->offset; ++ size = fs_envblk->spec->size; ++ ++ grub_envblk_iterate (envblk, &envblk_fs, read_envblk_fs); ++ ++ if (envblk_fs && grub_envblk_size (envblk_fs) == size) ++ return envblk_fs; ++ ++ create_envblk_fs (); ++ ++ offset = offset >> GRUB_DISK_SECTOR_BITS; ++ size = (size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS; ++ ++ val = xasprintf ("%d+%d", offset, size); ++ if (! grub_envblk_set (envblk, "env_block", val)) ++ grub_util_error ("%s", _("environment block too small")); ++ grub_envblk_iterate (envblk, &envblk_fs, read_envblk_fs); ++ free (val); ++ ++ return envblk_fs; ++} ++ + static grub_envblk_t + open_envblk_file (const char *name) + { +@@ -182,10 +319,17 @@ + list_variables (const char *name) + { + grub_envblk_t envblk; ++ grub_envblk_t envblk_fs = NULL; + + envblk = open_envblk_file (name); ++ grub_envblk_iterate (envblk, &envblk_fs, read_envblk_fs); + grub_envblk_iterate (envblk, NULL, print_var); + grub_envblk_close (envblk); ++ if (envblk_fs) ++ { ++ grub_envblk_iterate (envblk_fs, NULL, print_var); ++ grub_envblk_close (envblk_fs); ++ } + } + + static void +@@ -209,6 +353,38 @@ + } + + static void ++write_envblk_fs (grub_envblk_t envblk) ++{ ++ FILE *fp; ++ const char *device; ++ int offset, size; ++ ++ if (!fs_envblk) ++ return; ++ ++ device = fs_envblk->dev; ++ offset = fs_envblk->spec->offset; ++ size = fs_envblk->spec->size; ++ ++ if (grub_envblk_size (envblk) > size) ++ grub_util_error ("%s", _("environment block too small")); ++ ++ fp = grub_util_fopen (device, "r+b"); ++ ++ if (! fp) ++ grub_util_error (_("cannot open `%s': %s"), device, strerror (errno)); ++ ++ if (fseek (fp, offset, SEEK_SET) < 0) ++ grub_util_error (_("cannot seek `%s': %s"), device, strerror (errno)); ++ ++ if (fwrite (grub_envblk_buffer (envblk), 1, grub_envblk_size (envblk), fp) != grub_envblk_size (envblk)) ++ grub_util_error (_("cannot write to `%s': %s"), device, strerror (errno)); ++ ++ grub_util_file_sync (fp); ++ fclose (fp); ++} ++ ++static void + set_variables (const char *name, int argc, char *argv[]) + { + grub_envblk_t envblk; +@@ -224,8 +400,27 @@ + + *(p++) = 0; + +- if (! grub_envblk_set (envblk, argv[0], p)) +- grub_util_error ("%s", _("environment block too small")); ++ if ((strcmp (argv[0], "next_entry") == 0 || ++ strcmp (argv[0], "health_checker_flag") == 0) && fs_envblk) ++ { ++ grub_envblk_t envblk_fs; ++ envblk_fs = open_envblk_fs (envblk); ++ if (!envblk_fs) ++ grub_util_error ("%s", _("can't open fs environment block")); ++ if (! grub_envblk_set (envblk_fs, argv[0], p)) ++ grub_util_error ("%s", _("environment block too small")); ++ write_envblk_fs (envblk_fs); ++ grub_envblk_close (envblk_fs); ++ } ++ else if (strcmp (argv[0], "env_block") == 0) ++ { ++ grub_util_warn ("can't set env_block as it's read-only"); ++ } ++ else ++ { ++ if (! grub_envblk_set (envblk, argv[0], p)) ++ grub_util_error ("%s", _("environment block too small")); ++ } + + argc--; + argv++; +@@ -233,26 +428,158 @@ + + write_envblk (name, envblk); + grub_envblk_close (envblk); ++ + } + + static void + unset_variables (const char *name, int argc, char *argv[]) + { + grub_envblk_t envblk; ++ grub_envblk_t envblk_fs; + + envblk = open_envblk_file (name); ++ ++ envblk_fs = NULL; ++ if (fs_envblk) ++ envblk_fs = open_envblk_fs (envblk); ++ + while (argc) + { + grub_envblk_delete (envblk, argv[0]); + ++ if (envblk_fs) ++ grub_envblk_delete (envblk_fs, argv[0]); ++ + argc--; + argv++; + } + + write_envblk (name, envblk); + grub_envblk_close (envblk); ++ ++ if (envblk_fs) ++ { ++ write_envblk_fs (envblk_fs); ++ grub_envblk_close (envblk_fs); ++ } ++} ++ ++int have_abstraction = 0; ++static void ++probe_abstraction (grub_disk_t disk) ++{ ++ if (disk->partition == NULL) ++ grub_util_info ("no partition map found for %s", disk->name); ++ ++ if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID || ++ disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) ++ { ++ have_abstraction = 1; ++ } + } + ++static fs_envblk_t ++probe_fs_envblk (fs_envblk_spec_t spec) ++{ ++ char **grub_devices; ++ char **curdev, **curdrive; ++ size_t ndev = 0; ++ char **grub_drives; ++ grub_device_t grub_dev = NULL; ++ grub_fs_t grub_fs; ++ const char *fs_envblk_device; ++ ++#ifdef __s390x__ ++ return NULL; ++#endif ++ ++ grub_util_biosdisk_init (DEFAULT_DEVICE_MAP); ++ grub_init_all (); ++ grub_gcry_init_all (); ++ ++ grub_lvm_fini (); ++ grub_mdraid09_fini (); ++ grub_mdraid1x_fini (); ++ grub_diskfilter_fini (); ++ grub_diskfilter_init (); ++ grub_mdraid09_init (); ++ grub_mdraid1x_init (); ++ grub_lvm_init (); ++ ++ grub_devices = grub_guess_root_devices (DEFAULT_DIRECTORY); ++ ++ if (!grub_devices || !grub_devices[0]) ++ grub_util_error (_("cannot find a device for %s (is /dev mounted?)"), DEFAULT_DIRECTORY); ++ ++ fs_envblk_device = grub_devices[0]; ++ ++ for (curdev = grub_devices; *curdev; curdev++) ++ { ++ grub_util_pull_device (*curdev); ++ ndev++; ++ } ++ ++ grub_drives = xcalloc ((ndev + 1), sizeof (grub_drives[0])); ++ ++ for (curdev = grub_devices, curdrive = grub_drives; *curdev; curdev++, ++ curdrive++) ++ { ++ *curdrive = grub_util_get_grub_dev (*curdev); ++ if (! *curdrive) ++ grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"), ++ *curdev); ++ } ++ *curdrive = 0; ++ ++ grub_dev = grub_device_open (grub_drives[0]); ++ if (! grub_dev) ++ grub_util_error ("%s", grub_errmsg); ++ ++ grub_fs = grub_fs_probe (grub_dev); ++ if (! grub_fs) ++ grub_util_error ("%s", grub_errmsg); ++ ++ if (grub_dev->disk) ++ { ++ probe_abstraction (grub_dev->disk); ++ } ++ for (curdrive = grub_drives + 1; *curdrive; curdrive++) ++ { ++ grub_device_t dev = grub_device_open (*curdrive); ++ if (!dev) ++ continue; ++ if (dev->disk) ++ probe_abstraction (dev->disk); ++ grub_device_close (dev); ++ } ++ ++ free (grub_drives); ++ grub_device_close (grub_dev); ++ grub_gcry_fini_all (); ++ grub_fini_all (); ++ grub_util_biosdisk_fini (); ++ ++ fs_envblk_spec_t p; ++ ++ for (p = spec; p->fs_name; p++) ++ { ++ if (strcmp (grub_fs->name, p->fs_name) == 0 && !have_abstraction) ++ { ++ if (p->offset % GRUB_DISK_SECTOR_SIZE == 0 && ++ p->size % GRUB_DISK_SECTOR_SIZE == 0) ++ { ++ fs_envblk = xmalloc (sizeof (fs_envblk_t)); ++ fs_envblk->spec = p; ++ fs_envblk->dev = strdup(fs_envblk_device); ++ return fs_envblk; ++ } ++ } ++ } ++ ++ return NULL; ++} ++ ++ + int + main (int argc, char *argv[]) + { +@@ -284,6 +611,9 @@ + command = argv[curindex++]; + } + ++ if (strcmp (filename, DEFAULT_ENVBLK_PATH) == 0) ++ fs_envblk = probe_fs_envblk (fs_envblk_spec); ++ + if (strcmp (command, "create") == 0) + grub_util_create_envblk_file (filename); + else if (strcmp (command, "list") == 0) +--- a/util/grub.d/00_header.in ++++ b/util/grub.d/00_header.in +@@ -46,6 +46,13 @@ + if [ -s \$prefix/grubenv ]; then + load_env + fi ++ ++if [ "\${env_block}" ] ; then ++ set env_block="(\${root})\${env_block}" ++ export env_block ++ load_env -f "\${env_block}" ++fi ++ + EOF + if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then + cat < +Date: Fri, 16 Dec 2022 09:19:50 +0800 +Subject: [PATCH] commands/crypttab: increase the size of the path buffer + +Allocate a larger buffer for the cryptsetup.d path in case the system +uses a long volume name. + +Signed-off-by: Gary Lin +--- + grub-core/commands/crypttab.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: grub-2.06/grub-core/commands/crypttab.c +=================================================================== +--- grub-2.06.orig/grub-core/commands/crypttab.c ++++ grub-2.06/grub-core/commands/crypttab.c +@@ -11,7 +11,7 @@ static grub_err_t + grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)), + int argc, char **argv) + { +- char buf[64]; ++ char buf[256]; + const char *path = NULL; + + if (argc == 2) diff --git a/grub2-install-fix-not-a-directory-error.patch b/grub2-install-fix-not-a-directory-error.patch new file mode 100644 index 0000000000000000000000000000000000000000..fe75686e4cdb38de4400b54fd0a7f2cbdbe775a1 --- /dev/null +++ b/grub2-install-fix-not-a-directory-error.patch @@ -0,0 +1,38 @@ +From: Stefan Seyfried +Subject: Makefile.am: makes sure that ext2/3/4 is tried before minix +References: boo#1161641 + +I recently came across a strange grub2-install error when building kiwi images +in OBS. The reason is a bug in the minix file system detection. I filed +upstream bug [1]. + +Note I experienced this on SLES15-SP1. The bug is still present in current +Tumbleweed [2]. This bug thus needs fixing in all supported openSUSE releases. + +The reproducer-script is called as root like + + bash ./grub-bug-57652-reproduce-suse.sh /tmp/grub-test.img /mnt + +/tmp needs 1GB of free storage to store the image. + +Maybe this would be good enough as a minimal-intrusive fix. It does not fix the +minix detection code, but instead makes sure that ext[234] is tried before +minix. + +[1] https://savannah.gnu.org/bugs/index.php?57652 +[2] https://bugzilla.opensuse.org/attachment.cgi?id=828118 + +--- a/Makefile.am ++++ b/Makefile.am +@@ -51,8 +51,11 @@ + -D'GRUB_MOD_INIT(x)=@MARKER@x@' $^ > $@ || (rm -f $@; exit 1) + CLEANFILES += libgrub.pp + ++# the grep/sed ensures that ext2 gets initialized before minix* ++# see https://savannah.gnu.org/bugs/?57652 + libgrub_a_init.lst: libgrub.pp + cat $< | grep '^@MARKER@' | sed 's/@MARKER@\(.*\)@/\1/g' | sort -u > $@ || (rm -f $@; exit 1) ++ if grep ^ext2 $@ >/dev/null; then sed '/ext2/d;/newc/iext2' < $@ > $@.tmp && mv $@.tmp $@; fi + CLEANFILES += libgrub_a_init.lst + + libgrub_a_init.c: libgrub_a_init.lst $(top_srcdir)/geninit.sh diff --git a/grub2-install-remove-useless-check-PReP-partition-is-empty.patch b/grub2-install-remove-useless-check-PReP-partition-is-empty.patch new file mode 100644 index 0000000000000000000000000000000000000000..357797536947a2f7337cd3c3c13a896352ae2780 --- /dev/null +++ b/grub2-install-remove-useless-check-PReP-partition-is-empty.patch @@ -0,0 +1,77 @@ +From b57af595c94db6d7babb7623c1530ee4f5b956f0 Mon Sep 17 00:00:00 2001 +From: Michal Suchanek +Date: Tue, 31 Oct 2017 14:28:54 +0100 +Subject: [PATCH] grub-install: remove useless check PReP partition is empty. + +References: bsc#1065738 + +The grub-install rewrite in commit cd46aa6cefab checks that the PPeP +partition does not install an ELF binary before writing grub to it. This +causes regression in installer scripts that expect to be able to +reinstall bootloaders without first witping the partition by hand. + +Fixes: cd46aa6cefab ("Rewrite grub-install, grub-mkrescue, + grub-mkstandalone and grub-mknetdir ") +--- + util/grub-install.c | 39 ++------------------------------------- + 1 file changed, 2 insertions(+), 37 deletions(-) + +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -759,34 +759,6 @@ + return 0; + } + +-static int +-is_prep_empty (grub_device_t dev) +-{ +- grub_disk_addr_t dsize, addr; +- grub_uint32_t buffer[32768]; +- +- dsize = grub_disk_native_sectors (dev->disk); +- for (addr = 0; addr < dsize; +- addr += sizeof (buffer) / GRUB_DISK_SECTOR_SIZE) +- { +- grub_size_t sz = sizeof (buffer); +- grub_uint32_t *ptr; +- +- if (sizeof (buffer) / GRUB_DISK_SECTOR_SIZE > dsize - addr) +- sz = (dsize - addr) * GRUB_DISK_SECTOR_SIZE; +- grub_disk_read (dev->disk, addr, 0, sz, buffer); +- +- if (addr == 0 && grub_memcmp (buffer, ELFMAG, SELFMAG) == 0) +- return 1; +- +- for (ptr = buffer; ptr < buffer + sz / sizeof (*buffer); ptr++) +- if (*ptr) +- return 0; +- } +- +- return 1; +-} +- + static void + bless (grub_device_t dev, const char *path, int x86) + { +@@ -1980,18 +1952,9 @@ + { + grub_util_error ("%s", _("the chosen partition is not a PReP partition")); + } +- if (is_prep_empty (ins_dev)) +- { +- if (write_to_disk (ins_dev, imgfile)) +- grub_util_error ("%s", _("failed to copy Grub to the PReP partition")); +- grub_set_install_backup_ponr (); +- } +- else +- { +- char *s = xasprintf ("dd if=/dev/zero of=%s", install_device); +- grub_util_error (_("the PReP partition is not empty. If you are sure you want to use it, run dd to clear it: `%s'"), +- s); +- } ++ if (write_to_disk (ins_dev, imgfile)) ++ grub_util_error ("%s", _("failed to copy Grub to the PReP partition")); ++ grub_set_install_backup_ponr (); + grub_device_close (ins_dev); + if (update_nvram) + grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device), diff --git a/grub2-iterate-and-hook-for-extended-partition.patch b/grub2-iterate-and-hook-for-extended-partition.patch new file mode 100644 index 0000000000000000000000000000000000000000..73170c001bf603cef15493f5b8327850e21f4517 --- /dev/null +++ b/grub2-iterate-and-hook-for-extended-partition.patch @@ -0,0 +1,48 @@ +From: Michael Chang + +The same as in the previous patch, add a support for installing grub +into an extended partition. + +Here, we do not ignore extended partitions anymore. Instead we call a +hook that makes sure we have the partition when installing. + +Signed-off-by: Jiri Slaby +References: https://bugzilla.novell.com/show_bug.cgi?id=750897 + +From: Andrey Borzenkov + +Apply this logic only to primary extended partition. Ignore extended +partitions that are used to link together logical partitions. + +References: https://bugzilla.novell.com/show_bug.cgi?id=785341 +--- +Index: grub-2.00/grub-core/partmap/msdos.c +=================================================================== +--- grub-2.00.orig/grub-core/partmap/msdos.c ++++ grub-2.00/grub-core/partmap/msdos.c +@@ -188,13 +188,20 @@ grub_partition_msdos_iterate (grub_disk_ + (unsigned long long) p.len); + + /* If this partition is a normal one, call the hook. */ +- if (! grub_msdos_partition_is_empty (e->type) +- && ! grub_msdos_partition_is_extended (e->type)) ++ if (! grub_msdos_partition_is_empty (e->type)) + { +- p.number++; ++ if (!grub_msdos_partition_is_extended (e->type) || p.number < 3) ++ { ++ p.number++; + +- if (hook (disk, &p, hook_data)) +- return grub_errno; ++ /* prevent someone doing mkfs or mkswap on an ++ extended partition, but leave room for LILO */ ++ if (grub_msdos_partition_is_extended (e->type)) ++ p.len = 2; ++ ++ if (hook (disk, &p, hook_data)) ++ return grub_errno; ++ } + } + else if (p.number < 3) + /* If this partition is a logical one, shouldn't increase the diff --git a/grub2-linguas.sh-no-rsync.patch b/grub2-linguas.sh-no-rsync.patch new file mode 100644 index 0000000000000000000000000000000000000000..e63fe10ae6d3319f8b24fd10a441a0731e76f447 --- /dev/null +++ b/grub2-linguas.sh-no-rsync.patch @@ -0,0 +1,21 @@ +From: Andrey Borzenkov +Subject: disable rsync to make it possible to use in RPM build + +We need to create po/LINGUAS to generate message catalogs. Use +linguas.sh to ensure we always use the same rules as upstream, but +disable rsync. +Index: grub-2.02~rc2/linguas.sh +=================================================================== +--- grub-2.02~rc2.orig/linguas.sh ++++ grub-2.02~rc2/linguas.sh +@@ -1,8 +1,8 @@ + #!/bin/sh + +-rsync -Lrtvz translationproject.org::tp/latest/grub/ po ++#rsync -Lrtvz translationproject.org::tp/latest/grub/ po + +-autogenerated="en@quot en@hebrew de@hebrew en@cyrillic en@greek en@arabic en@piglatin de_CH" ++autogenerated="en@quot" # en@hebrew de@hebrew en@cyrillic en@greek en@arabic en@piglatin de_CH" + + + for x in $autogenerated; do diff --git a/0024-Don-t-say-GNU-Linux-in-generated-menus.patch b/grub2-linux.patch similarity index 38% rename from 0024-Don-t-say-GNU-Linux-in-generated-menus.patch rename to grub2-linux.patch index f28809503b8bb177aedd17918869258a62e1dc0e..0a76c46d15bf4b434f221810c0a68a0da30fc55b 100644 --- a/0024-Don-t-say-GNU-Linux-in-generated-menus.patch +++ b/grub2-linux.patch @@ -1,42 +1,40 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Mon, 14 Mar 2011 14:27:42 -0400 -Subject: [PATCH] Don't say "GNU/Linux" in generated menus. - ---- - util/grub.d/10_linux.in | 4 ++-- - util/grub.d/20_linux_xen.in | 4 ++-- - 2 files changed, 4 insertions(+), 4 deletions(-) - -diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in -index dc75a1c30bf..4a499c53a61 100644 --- a/util/grub.d/10_linux.in +++ b/util/grub.d/10_linux.in -@@ -29,9 +29,9 @@ export TEXTDOMAINDIR="@localedir@" - CLASS="--class gnu-linux --class gnu --class os" - +@@ -31,7 +31,7 @@ if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then -- OS=GNU/Linux -+ OS="$(sed 's, release .*$,,g' /etc/system-release)" + OS=GNU/Linux else - OS="${GRUB_DISTRIBUTOR} GNU/Linux" + OS="${GRUB_DISTRIBUTOR}" CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" fi -diff --git a/util/grub.d/20_linux_xen.in b/util/grub.d/20_linux_xen.in -index 3b1f4704921..ada20775a14 100644 +@@ -143,7 +143,7 @@ + message="$(gettext_printf "Loading Linux %s ..." ${version})" + sed "s/^/$submenu_indentation/" << EOF + echo '$(echo "$message" | grub_quote)' +- linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ro ${args} ++ linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ${args} + EOF + if test -n "${initrd}" ; then + # TRANSLATORS: ramdisk isn't identifier. Should be translated. --- a/util/grub.d/20_linux_xen.in +++ b/util/grub.d/20_linux_xen.in -@@ -29,9 +29,9 @@ export TEXTDOMAINDIR="@localedir@" - CLASS="--class gnu-linux --class gnu --class os --class xen" - +@@ -31,7 +31,7 @@ if [ "x${GRUB_DISTRIBUTOR}" = "x" ] ; then -- OS=GNU/Linux -+ OS="$(sed 's, release .*$,,g' /etc/system-release)" + OS=GNU/Linux else - OS="${GRUB_DISTRIBUTOR} GNU/Linux" + OS="${GRUB_DISTRIBUTOR}" CLASS="--class $(echo ${GRUB_DISTRIBUTOR} | tr 'A-Z' 'a-z' | cut -d' ' -f1|LC_ALL=C sed 's,[^[:alnum:]_],_,g') ${CLASS}" fi +@@ -154,7 +154,7 @@ + fi + ${xen_loader} ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts} + echo '$(echo "$lmessage" | grub_quote)' +- ${module_loader} ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ro ${args} ++ ${module_loader} ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ${args} + EOF + if test -n "${initrd}" ; then + # TRANSLATORS: ramdisk isn't identifier. Should be translated. diff --git a/grub2-linuxefi-fix-boot-params.patch b/grub2-linuxefi-fix-boot-params.patch new file mode 100644 index 0000000000000000000000000000000000000000..653eb527d691e613339d5c940d43efb93d4aba11 --- /dev/null +++ b/grub2-linuxefi-fix-boot-params.patch @@ -0,0 +1,18 @@ +--- a/grub-core/loader/i386/efi/linux.c ++++ b/grub-core/loader/i386/efi/linux.c +@@ -298,7 +298,14 @@ + lh.code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem; + } + +- grub_memcpy(params, &lh, 2 * 512); ++ /* Grub linuxefi erroneously initialize linux's boot_params with non-zero values. (bsc#1025563) ++ ++ From https://www.kernel.org/doc/Documentation/x86/boot.txt: ++ The memory for struct boot_params could be allocated anywhere (even above 4G) ++ and initialized to all zero. ++ Then, the setup header at offset 0x01f1 of kernel image on should be ++ loaded into struct boot_params and examined. */ ++ grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x01f1); + + params->type_of_loader = 0x21; + diff --git a/grub2-lvm-allocate-metadata-buffer-from-raw-contents.patch b/grub2-lvm-allocate-metadata-buffer-from-raw-contents.patch new file mode 100644 index 0000000000000000000000000000000000000000..f78bb767287b9b139a4c15cb8f71d4f296967e75 --- /dev/null +++ b/grub2-lvm-allocate-metadata-buffer-from-raw-contents.patch @@ -0,0 +1,148 @@ +From: Michael Chang +Date: Fri, 9 Apr 2021 19:58:24 +0800 +Subject: [PATCH] Allocate LVM metadata buffer from raw contents + +The size reserved for on disk LVM metadata area can be exceedingly large that +may trigger out of memory error for allocating buffer based on it. Refine the +buffer allocation to use size of raw LVM metadata contents and read them from +within the metadata area as we only need to parse the JSON formatted contents +rather than the entire metadata area. This reduced the size significantly and +the likelihood to out of memory error. +--- + grub-core/disk/lvm.c | 79 ++++++++++++++++++++++++-------------------- + 1 file changed, 43 insertions(+), 36 deletions(-) + +diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c +index 8257159b3..1d1a3dcad 100644 +--- a/grub-core/disk/lvm.c ++++ b/grub-core/disk/lvm.c +@@ -140,9 +140,11 @@ grub_lvm_detect (grub_disk_t disk, + grub_err_t err; + grub_uint64_t mda_offset, mda_size; + grub_size_t ptr; ++ grub_uint64_t mda_raw_offset, mda_raw_size; + char buf[GRUB_LVM_LABEL_SIZE]; + char vg_id[GRUB_LVM_ID_STRLEN+1]; + char pv_id[GRUB_LVM_ID_STRLEN+1]; ++ char mdah_buf[sizeof (struct grub_lvm_mda_header) + sizeof (struct grub_lvm_raw_locn)]; + char *metadatabuf, *mda_end, *vgname; + const char *p, *q; + struct grub_lvm_label_header *lh = (struct grub_lvm_label_header *) buf; +@@ -220,21 +222,15 @@ grub_lvm_detect (grub_disk_t disk, + + dlocn++; + mda_offset = grub_le_to_cpu64 (dlocn->offset); +- mda_size = grub_le_to_cpu64 (dlocn->size); + + /* It's possible to have multiple copies of metadata areas, we just use the + first one. */ +- +- /* Allocate buffer space for the circular worst-case scenario. */ +- metadatabuf = grub_calloc (2, mda_size); +- if (! metadatabuf) ++ err = grub_disk_read (disk, 0, mda_offset, sizeof (mdah_buf), mdah_buf); ++ if (err) + goto fail; + +- err = grub_disk_read (disk, 0, mda_offset, mda_size, metadatabuf); +- if (err) +- goto fail2; ++ mdah = (struct grub_lvm_mda_header *) mdah_buf; + +- mdah = (struct grub_lvm_mda_header *) metadatabuf; + if ((grub_strncmp ((char *)mdah->magic, GRUB_LVM_FMTT_MAGIC, + sizeof (mdah->magic))) + || (grub_le_to_cpu32 (mdah->version) != GRUB_LVM_FMTT_VERSION)) +@@ -244,42 +240,58 @@ grub_lvm_detect (grub_disk_t disk, + #ifdef GRUB_UTIL + grub_util_info ("unknown LVM metadata header"); + #endif +- goto fail2; ++ goto fail; + } + + rlocn = mdah->raw_locns; +- if (grub_le_to_cpu64 (rlocn->offset) >= grub_le_to_cpu64 (mda_size)) ++ ++ mda_size = grub_le_to_cpu64 (mdah->size); ++ mda_raw_size = grub_le_to_cpu64 (rlocn->size); ++ mda_raw_offset = grub_le_to_cpu64 (rlocn->offset); ++ ++ if (mda_raw_offset >= mda_size) + { + #ifdef GRUB_UTIL + grub_util_info ("metadata offset is beyond end of metadata area"); + #endif +- goto fail2; ++ goto fail; + } + +- if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) > +- grub_le_to_cpu64 (mdah->size)) ++ metadatabuf = grub_malloc (mda_raw_size); ++ ++ if (! metadatabuf) ++ goto fail; ++ ++ if (mda_raw_offset + mda_raw_size > mda_size) + { +- if (2 * mda_size < GRUB_LVM_MDA_HEADER_SIZE || +- (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) - +- grub_le_to_cpu64 (mdah->size) > mda_size - GRUB_LVM_MDA_HEADER_SIZE)) +- { +-#ifdef GRUB_UTIL +- grub_util_info ("cannot copy metadata wrap in circular buffer"); +-#endif +- goto fail2; +- } ++ err = grub_disk_read (disk, 0, ++ mda_offset + mda_raw_offset, ++ mda_size - mda_raw_offset, ++ metadatabuf); ++ if (err) ++ goto fail2; + + /* Metadata is circular. Copy the wrap in place. */ +- grub_memcpy (metadatabuf + mda_size, +- metadatabuf + GRUB_LVM_MDA_HEADER_SIZE, +- grub_le_to_cpu64 (rlocn->offset) + +- grub_le_to_cpu64 (rlocn->size) - +- grub_le_to_cpu64 (mdah->size)); ++ err = grub_disk_read (disk, 0, ++ mda_offset + GRUB_LVM_MDA_HEADER_SIZE, ++ mda_raw_offset + mda_raw_size - mda_size, ++ metadatabuf + mda_size - mda_raw_offset); ++ if (err) ++ goto fail2; ++ } ++ else ++ { ++ err = grub_disk_read (disk, 0, ++ mda_offset + mda_raw_offset, ++ mda_raw_size, ++ metadatabuf); ++ if (err) ++ goto fail2; + } + +- if (grub_add ((grub_size_t)metadatabuf, +- (grub_size_t)grub_le_to_cpu64 (rlocn->offset), +- &ptr)) ++ p = q = metadatabuf; ++ ++ if (grub_add ((grub_size_t)metadatabuf, (grub_size_t)mda_raw_size, &ptr)) + { + error_parsing_metadata: + #ifdef GRUB_UTIL +@@ -288,11 +300,6 @@ grub_lvm_detect (grub_disk_t disk, + goto fail2; + } + +- p = q = (char *)ptr; +- +- if (grub_add ((grub_size_t)metadatabuf, (grub_size_t)mda_size, &ptr)) +- goto error_parsing_metadata; +- + mda_end = (char *)ptr; + + while (*q != ' ' && q < mda_end) diff --git a/grub2-menu-unrestricted.patch b/grub2-menu-unrestricted.patch new file mode 100644 index 0000000000000000000000000000000000000000..825f65631fd80efd0acd6da8ce2e237b105117ad --- /dev/null +++ b/grub2-menu-unrestricted.patch @@ -0,0 +1,21 @@ +--- a/grub-core/normal/menu.c ++++ b/grub-core/normal/menu.c +@@ -212,7 +212,17 @@ + grub_size_t sz = 0; + + if (entry->restricted) +- err = grub_auth_check_authentication (entry->users); ++ { ++ int auth_check = 1; ++ if (entry->users && entry->users[0] == 0) ++ { ++ const char *unr = grub_env_get ("unrestricted_menu"); ++ if (unr && (unr[0] == '1' || unr[0] == 'y')) ++ auth_check = 0; ++ } ++ if (auth_check) ++ err = grub_auth_check_authentication (entry->users); ++ } + + if (err) + { diff --git a/grub2-mkconfig-aarch64.patch b/grub2-mkconfig-aarch64.patch new file mode 100644 index 0000000000000000000000000000000000000000..49a2626d2bfafe790afad1028537d19bfc0378f5 --- /dev/null +++ b/grub2-mkconfig-aarch64.patch @@ -0,0 +1,12 @@ +grub-mkonfig: Look for Image-* on aarch64 + +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -194,6 +194,7 @@ + machine=`uname -m` + case "x$machine" in + xi?86 | xx86_64) klist="/boot/vmlinuz-* /vmlinuz-* /boot/kernel-*" ;; ++ xaarch64) klist="/boot/Image-* /Image-* /boot/kernel-*" ;; + xs390 | xs390x) klist="/boot/image-* /boot/kernel-*" ;; + *) klist="/boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* \ + /boot/kernel-*" ;; diff --git a/grub2-mkconfig-arm.patch b/grub2-mkconfig-arm.patch new file mode 100644 index 0000000000000000000000000000000000000000..cd18dbd9ae937d4da5333e648624b478b2905d37 --- /dev/null +++ b/grub2-mkconfig-arm.patch @@ -0,0 +1,10 @@ +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -195,6 +195,7 @@ + case "x$machine" in + xi?86 | xx86_64) klist="/boot/vmlinuz-* /vmlinuz-* /boot/kernel-*" ;; + xaarch64) klist="/boot/Image-* /Image-* /boot/kernel-*" ;; ++ xarm*) klist="/boot/zImage-* /zImage-* /boot/kernel-*" ;; + xs390 | xs390x) klist="/boot/image-* /boot/kernel-*" ;; + *) klist="/boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* \ + /boot/kernel-*" ;; diff --git a/grub2-mkconfig-default-entry-correction.patch b/grub2-mkconfig-default-entry-correction.patch new file mode 100644 index 0000000000000000000000000000000000000000..e1dd1b8971a67767938f2353626e497cdbddc5e2 --- /dev/null +++ b/grub2-mkconfig-default-entry-correction.patch @@ -0,0 +1,14 @@ +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -363,6 +363,11 @@ + cat ${grub_cfg}.new > ${grub_cfg} + umask $oldumask + rm -f ${grub_cfg}.new ++ # check if default entry need to be corrected for updated distributor version ++ # and/or use fallback entry if default kernel entry removed ++ if test -x /usr/sbin/grub2-check-default; then ++ /usr/sbin/grub2-check-default >&2 ++ fi + sync_fs_journal || true + fi + fi diff --git a/grub2-mkconfig-riscv64.patch b/grub2-mkconfig-riscv64.patch new file mode 100644 index 0000000000000000000000000000000000000000..80ffaf50ecf90e53f121061609042b78184574b5 --- /dev/null +++ b/grub2-mkconfig-riscv64.patch @@ -0,0 +1,12 @@ +Index: grub-2.04/util/grub.d/10_linux.in +=================================================================== +--- grub-2.04.orig/util/grub.d/10_linux.in ++++ grub-2.04/util/grub.d/10_linux.in +@@ -216,6 +216,7 @@ case "x$machine" in + xi?86 | xx86_64) klist="/boot/vmlinuz-* /vmlinuz-* /boot/kernel-*" ;; + xaarch64) klist="/boot/Image-* /Image-* /boot/kernel-*" ;; + xarm*) klist="/boot/zImage-* /zImage-* /boot/kernel-*" ;; ++ xriscv64) klist="/boot/Image-* /Image-* /boot/kernel-*" ;; + xs390 | xs390x) klist="/boot/image-* /boot/kernel-*" ;; + *) klist="/boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* \ + /boot/kernel-*" ;; diff --git a/grub2-pass-corret-root-for-nfsroot.patch b/grub2-pass-corret-root-for-nfsroot.patch new file mode 100644 index 0000000000000000000000000000000000000000..7f0d90afc84bf1b2cd6e4f45a885aadcd19715e8 --- /dev/null +++ b/grub2-pass-corret-root-for-nfsroot.patch @@ -0,0 +1,135 @@ +From 340fd0c8717c2bf33163a18bfec72243b0e51862 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Thu, 30 Aug 2012 15:43:17 +0800 +Subject: [PATCH] Pass corret root= for nfsroot + +References: bnc#774548, bsc#1069094 +Patch-Mainline: no + +Fix / is mounted on nfs. The fix is to pass kernel parameters +with correct root= for nfs. However since grub2 doesn't support +nfs file system module, the /boot on nfs is not possible and +grub2-probe not work in probing nfs mounted path. The fix is merely +on the script level and not use grub2-probe for above reasons. + +v2: Filter out autofs and securityfs from /proc/self/mountinfo (bsc#1069094) + +--- + util/grub-mkconfig.in | 37 ++++++++++++++++++++++++++++++------- + 1 files changed, 30 insertions(+), 7 deletions(-) + +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -131,26 +131,54 @@ + exit 1 + fi + +-# Device containing our userland. Typically used for root= parameter. +-GRUB_DEVICE="`${grub_probe} --target=device /`" +-GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true +-GRUB_DEVICE_PARTUUID="`${grub_probe} --device ${GRUB_DEVICE} --target=partuuid 2> /dev/null`" || true ++probe_nfsroot_device () { ++ while read line ; do ++ part1=`echo $line | sed -e 's! - .*$!!'` ++ part2=`echo $line | sed -n -e 's! - \(.*\)$!\n\1!p' | sed 1d` ++ ++ set -- $part1 ++ path=$5 ++ ++ set -- $part2 ++ fstype=$1 ++ device=$2 ++ ++ if [ "x${path}" = "x/" ] && ++ [ "x${fstype}" = "xnfs" -o "x${fstype}" = "xnfs4" ] ; then ++ echo "${fstype}:$device" ++ return ++ fi ++ done ++} + +-# Device containing our /boot partition. Usually the same as GRUB_DEVICE. +-GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`" +-GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true ++NFSROOT_DEVICE="`awk '($9!="autofs")&&($9!="securityfs")' /proc/self/mountinfo | probe_nfsroot_device`" + + # Disable os-prober by default due to security reasons. + GRUB_DISABLE_OS_PROBER="true" + +-# Filesystem for the device containing our userland. Used for stuff like +-# choosing Hurd filesystem module. +-GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`" ++if [ "x${NFSROOT_DEVICE}" != "x" ]; then ++ GRUB_DEVICE="" ++ GRUB_DEVICE_UUID="" ++ GRUB_DEVICE_PARTUUID="" ++ GRUB_FS="unknown" ++else ++ # Filesystem for the device containing our userland. Used for stuff like ++ # choosing Hurd filesystem module. ++ GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`" ++ # Device containing our userland. Typically used for root= parameter. ++ GRUB_DEVICE="`${grub_probe} --target=device /`" ++ GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true ++ GRUB_DEVICE_PARTUUID="`${grub_probe} --device ${GRUB_DEVICE} --target=partuuid 2> /dev/null`" || true ++fi + +-if [ x"$GRUB_FS" = xunknown ]; then ++if [ x"$GRUB_FS" = x ] || [ x"$GRUB_FS" = xunknown ]; then + GRUB_FS="$(stat -f -c %T / || echo unknown)" + fi + ++# Device containing our /boot partition. Usually the same as GRUB_DEVICE. ++GRUB_DEVICE_BOOT="`${grub_probe} --target=device /boot`" ++GRUB_DEVICE_BOOT_UUID="`${grub_probe} --device ${GRUB_DEVICE_BOOT} --target=fs_uuid 2> /dev/null`" || true ++ + # Provide a default set of stock linux early initrd images. + # Define here so the list can be modified in the sourced config file. + if [ "x${GRUB_EARLY_INITRD_LINUX_STOCK}" = "x" ]; then +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -88,6 +88,12 @@ + type="$3" + args="$4" + ++ if [ -n "${linux_root_device_thisversion}" ]; then ++ root_device="root=${linux_root_device_thisversion}" ++ else ++ root_device="" ++ fi ++ + if [ -z "$boot_device_id" ]; then + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" + fi +@@ -143,7 +149,7 @@ + message="$(gettext_printf "Loading Linux %s ..." ${version})" + sed "s/^/$submenu_indentation/" << EOF + echo '$(echo "$message" | grub_quote)' +- linux ${rel_dirname}/${basename} root=${linux_root_device_thisversion} ${args} ++ linux ${rel_dirname}/${basename} ${root_device} ${args} + EOF + if test -n "${initrd}" ; then + # TRANSLATORS: ramdisk isn't identifier. Should be translated. +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -109,6 +109,11 @@ + args="$5" + xen_args="$6" + xsm="$7" ++ if [ -n "${linux_root_device_thisversion}" ]; then ++ root_device="root=${linux_root_device_thisversion}" ++ else ++ root_device="" ++ fi + # If user wants to enable XSM support, make sure there's + # corresponding policy file. + xenpolicy= +@@ -160,7 +165,7 @@ + fi + ${xen_loader} ${rel_xen_dirname}/${xen_basename} placeholder ${xen_args} \${xen_rm_opts} + echo '$(echo "$lmessage" | grub_quote)' +- ${module_loader} ${rel_dirname}/${basename} placeholder root=${linux_root_device_thisversion} ${args} ++ ${module_loader} ${rel_dirname}/${basename} placeholder ${root_device} ${args} + EOF + if test -n "${initrd}" ; then + # TRANSLATORS: ramdisk isn't identifier. Should be translated. diff --git a/0018-Migrate-PPC-from-Yaboot-to-Grub2.patch b/grub2-ppc-terminfo.patch similarity index 81% rename from 0018-Migrate-PPC-from-Yaboot-to-Grub2.patch rename to grub2-ppc-terminfo.patch index 5cbe731bc19d9ab85e9b79613dcc82761cb14765..7574a69b12c2f1aab9fb74039c1fa06306e7b521 100644 --- a/0018-Migrate-PPC-from-Yaboot-to-Grub2.patch +++ b/grub2-ppc-terminfo.patch @@ -1,40 +1,33 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From e263907f50e496e602edd9bd846ccb6e0565a085 Mon Sep 17 00:00:00 2001 From: Mark Hamzy Date: Wed, 28 Mar 2012 14:46:41 -0500 Subject: [PATCH] Migrate PPC from Yaboot to Grub2 -Add configuration support for serial terminal consoles. This will set -the maximum screen size so that text is not overwritten. +Add configuration support for serial terminal consoles. This will set the +maximum screen size so that text is not overwritten. -Signed-off-by: Mark Hamzy -Signed-off-by: Robbie Harwood --- - Makefile.util.def | 7 +++ - util/grub.d/20_ppc_terminfo.in | 114 +++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 121 insertions(+) + Makefile.util.def | 7 +++ + util/grub.d/20_ppc_terminfo.in | 114 ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 121 insertions(+), 0 deletions(-) create mode 100644 util/grub.d/20_ppc_terminfo.in -diff --git a/Makefile.util.def b/Makefile.util.def -index f8b356cc1fa..2c9b283a230 100644 --- a/Makefile.util.def +++ b/Makefile.util.def -@@ -508,6 +508,13 @@ script = { - condition = COND_HOST_LINUX; +@@ -512,6 +512,13 @@ }; -+script = { + script = { + name = '20_ppc_terminfo'; + common = util/grub.d/20_ppc_terminfo.in; + installdir = grubconf; + condition = COND_HOST_LINUX; +}; + - script = { - name = '30_os-prober'; - common = util/grub.d/30_os-prober.in; -diff --git a/util/grub.d/20_ppc_terminfo.in b/util/grub.d/20_ppc_terminfo.in -new file mode 100644 -index 00000000000..10d66586820 ++script = { + name = '25_bli'; + common = util/grub.d/25_bli.in; + installdir = grubconf; --- /dev/null +++ b/util/grub.d/20_ppc_terminfo.in @@ -0,0 +1,114 @@ diff --git a/grub2-ppc64-cas-fix-double-free.patch b/grub2-ppc64-cas-fix-double-free.patch new file mode 100644 index 0000000000000000000000000000000000000000..4eb36d5996ea4a98c98d85a43a716ca63eb7dc45 --- /dev/null +++ b/grub2-ppc64-cas-fix-double-free.patch @@ -0,0 +1,94 @@ +--- a/grub-core/kern/ieee1275/openfw.c ++++ b/grub-core/kern/ieee1275/openfw.c +@@ -595,7 +595,7 @@ + + /* Check if it's a CAS reboot. If so, set the script to be executed. */ + int +-grub_ieee1275_cas_reboot (char *script) ++grub_ieee1275_cas_reboot (char **script) + { + grub_uint32_t ibm_ca_support_reboot; + grub_uint32_t ibm_fw_nbr_reboots; +@@ -628,16 +628,37 @@ + + if (ibm_ca_support_reboot || ibm_fw_nbr_reboots) + { +- if (! grub_ieee1275_get_property_length (options, "boot-last-label", &actual)) +- { +- if (actual > 1024) +- script = grub_realloc (script, actual + 1); +- grub_ieee1275_get_property (options, "boot-last-label", script, actual, +- &actual); +- return 0; +- } ++ grub_ssize_t len; ++ char *buf; ++ ++ if (grub_ieee1275_get_property_length (options, "boot-last-label", &len) ++ || len <= 0) ++ { ++ grub_dprintf ("ieee1275", "boot-last-label missing or invalid\n"); ++ goto out; ++ } ++ /* The returned property string length may not include terminating null byte, and in ++ a bid to avoid out of bound access we allocate one more byte to add it back */ ++ buf = grub_malloc ((grub_size_t)len + 1); ++ if (!buf) ++ { ++ grub_print_error (); ++ goto out; ++ } ++ if (grub_ieee1275_get_property (options, "boot-last-label", buf, (grub_size_t)len + 1, &actual) ++ || actual < 0) ++ { ++ grub_dprintf ("ieee1275", "error while get boot-last-label property\n"); ++ grub_free (buf); ++ goto out; ++ } ++ /* Add terminating null byte */ ++ buf[len] = '\0'; ++ *script = buf; ++ return 0; + } + ++out: + grub_ieee1275_set_boot_last_label (""); + + return -1; +@@ -651,8 +672,9 @@ + grub_dprintf("ieee1275", "set boot_last_label (size: %" PRIxGRUB_SIZE ")\n", grub_strlen(text)); + if (! grub_ieee1275_finddevice ("/options", &options) && + options != (grub_ieee1275_ihandle_t) -1) ++ /* To be on the safe side, set the property string with terminating null byte */ + grub_ieee1275_set_property (options, "boot-last-label", text, +- grub_strlen (text), &actual); ++ grub_strlen (text) + 1, &actual); + return 0; + } + +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -282,10 +282,9 @@ + #ifdef GRUB_MACHINE_IEEE1275 + int boot; + boot = 0; +- char *script; ++ char *script = NULL; + char *dummy[1] = { NULL }; +- script = grub_malloc (1024); +- if (! grub_ieee1275_cas_reboot (script)) ++ if (! grub_ieee1275_cas_reboot (&script) && script) + { + if (! grub_script_execute_new_scope (script, 0, dummy)) + boot = 1; +--- a/include/grub/ieee1275/ieee1275.h ++++ b/include/grub/ieee1275/ieee1275.h +@@ -256,7 +256,7 @@ + void EXPORT_FUNC(grub_ieee1275_children_peer) (struct grub_ieee1275_devalias *alias); + void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath, + struct grub_ieee1275_devalias *alias); +-int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char *script); ++int EXPORT_FUNC(grub_ieee1275_cas_reboot) (char **script); + int EXPORT_FUNC(grub_ieee1275_set_boot_last_label) (const char *text); + + char *EXPORT_FUNC(grub_ieee1275_get_boot_dev) (void); diff --git a/grub2-ppc64-cas-new-scope.patch b/grub2-ppc64-cas-new-scope.patch new file mode 100644 index 0000000000000000000000000000000000000000..44de4b8a3f36ac0597f2ba0c59dca13dd8462a94 --- /dev/null +++ b/grub2-ppc64-cas-new-scope.patch @@ -0,0 +1,15 @@ +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -283,10 +283,11 @@ + int boot; + boot = 0; + char *script; ++ char *dummy[1] = { NULL }; + script = grub_malloc (1024); + if (! grub_ieee1275_cas_reboot (script)) + { +- if (! grub_script_execute_sourcecode (script)) ++ if (! grub_script_execute_new_scope (script, 0, dummy)) + boot = 1; + } + grub_free (script); diff --git a/0011-IBM-client-architecture-CAS-reboot-support.patch b/grub2-ppc64-cas-reboot-support.patch similarity index 77% rename from 0011-IBM-client-architecture-CAS-reboot-support.patch rename to grub2-ppc64-cas-reboot-support.patch index 431a443b46db46845bbe2aff100f6f5e7cccfc10..f7b41647621f8d1ec1d97eca0970dedcf01ef1af 100644 --- a/0011-IBM-client-architecture-CAS-reboot-support.patch +++ b/grub2-ppc64-cas-reboot-support.patch @@ -1,42 +1,35 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From 9d1411ffa7290c1cbdc9ee95bb5fcc5506e63e0f Mon Sep 17 00:00:00 2001 From: Paulo Flabiano Smorigo Date: Thu, 20 Sep 2012 18:07:39 -0300 -Subject: [PATCH] IBM client architecture (CAS) reboot support +Subject: [PATCH 096/152] IBM client architecture (CAS) reboot support This is an implementation of IBM client architecture (CAS) reboot for GRUB. There are cases where the POWER firmware must reboot in order to support specific features requested by a kernel. The kernel calls -ibm,client-architecture-support and it may either return or reboot with -the new feature set. eg: +ibm,client-architecture-support and it may either return or reboot with the new +feature set. eg: Calling ibm,client-architecture-support.../ Elapsed time since release of system processors: 70959 mins 50 secs Welcome to GRUB! -Instead of return to the GRUB menu, it will check if the flag for CAS -reboot is set. If so, grub will automatically boot the last booted -kernel using the same parameters - -Signed-off-by: Paulo Flabiano Smorigo -[rharwood@redhat.com: commit message rewrap] -Signed-off-by: Robbie Harwood +Instead of return to the GRUB menu, it will check if the flag for CAS reboot is +set. If so, grub will automatically boot the last booted kernel using the same +parameters --- - grub-core/kern/ieee1275/openfw.c | 63 ++++++++++++++++++++++++++++++++++++++++ + grub-core/kern/ieee1275/openfw.c | 62 ++++++++++++++++++++++++++++++++++++++++ grub-core/normal/main.c | 19 ++++++++++++ grub-core/script/execute.c | 7 +++++ include/grub/ieee1275/ieee1275.h | 2 ++ - 4 files changed, 91 insertions(+) + 4 files changed, 90 insertions(+) -diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c -index 4d493ab7661..3a6689abb11 100644 --- a/grub-core/kern/ieee1275/openfw.c +++ b/grub-core/kern/ieee1275/openfw.c -@@ -591,3 +591,66 @@ grub_ieee1275_get_boot_dev (void) - - return bootpath; +@@ -593,6 +593,69 @@ + return NULL; } -+ + +/* Check if it's a CAS reboot. If so, set the script to be executed. */ +int +grub_ieee1275_cas_reboot (char *script) @@ -92,15 +85,17 @@ index 4d493ab7661..3a6689abb11 100644 + grub_ieee1275_ihandle_t options; + grub_ssize_t actual; + -+ grub_dprintf("ieee1275", "set boot_last_label (size: %u)\n", grub_strlen(text)); ++ grub_dprintf("ieee1275", "set boot_last_label (size: %" PRIxGRUB_SIZE ")\n", grub_strlen(text)); + if (! grub_ieee1275_finddevice ("/options", &options) && + options != (grub_ieee1275_ihandle_t) -1) + grub_ieee1275_set_property (options, "boot-last-label", text, + grub_strlen (text), &actual); + return 0; +} -diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c -index c4ebe9e22ad..70614de1565 100644 ++ + char * + grub_ieee1275_get_boot_dev (void) + { --- a/grub-core/normal/main.c +++ b/grub-core/normal/main.c @@ -34,6 +34,9 @@ @@ -113,7 +108,7 @@ index c4ebe9e22ad..70614de1565 100644 GRUB_MOD_LICENSE ("GPLv3+"); -@@ -276,6 +279,22 @@ grub_normal_execute (const char *config, int nested, int batch) +@@ -276,6 +279,21 @@ { menu = read_config_file (config); @@ -124,7 +119,6 @@ index c4ebe9e22ad..70614de1565 100644 + script = grub_malloc (1024); + if (! grub_ieee1275_cas_reboot (script)) + { -+ char *dummy[1] = { NULL }; + if (! grub_script_execute_sourcecode (script)) + boot = 1; + } @@ -136,8 +130,6 @@ index c4ebe9e22ad..70614de1565 100644 /* Ignore any error. */ grub_errno = GRUB_ERR_NONE; } -diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c -index 25158407dd8..ad80399246a 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -28,6 +28,9 @@ @@ -150,7 +142,7 @@ index 25158407dd8..ad80399246a 100644 /* Max digits for a char is 3 (0xFF is 255), similarly for an int it is sizeof (int) * 3, and one extra for a possible -ve sign. */ -@@ -883,6 +886,10 @@ grub_script_execute_sourcecode (const char *source) +@@ -883,6 +886,10 @@ grub_err_t ret = 0; struct grub_script *parsed_script; @@ -161,11 +153,9 @@ index 25158407dd8..ad80399246a 100644 while (source) { char *line; -diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h -index 73e2f464475..0a599607f31 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h -@@ -254,6 +254,8 @@ int EXPORT_FUNC(grub_ieee1275_devalias_next) (struct grub_ieee1275_devalias *ali +@@ -256,6 +256,8 @@ void EXPORT_FUNC(grub_ieee1275_children_peer) (struct grub_ieee1275_devalias *alias); void EXPORT_FUNC(grub_ieee1275_children_first) (const char *devpath, struct grub_ieee1275_devalias *alias); diff --git a/0013-Disable-GRUB-video-support-for-IBM-power-machines.patch b/grub2-ppc64le-disable-video.patch similarity index 42% rename from 0013-Disable-GRUB-video-support-for-IBM-power-machines.patch rename to grub2-ppc64le-disable-video.patch index e8aa3678c386011b42e82c429c2a16af07930c4a..f9ea610c562e4f05762ea151796de981663cb576 100644 --- a/0013-Disable-GRUB-video-support-for-IBM-power-machines.patch +++ b/grub2-ppc64le-disable-video.patch @@ -1,40 +1,20 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Paulo Flabiano Smorigo -Date: Tue, 11 Jun 2013 15:14:05 -0300 -Subject: [PATCH] Disable GRUB video support for IBM power machines - -Should fix the problem in bugzilla: -https://bugzilla.redhat.com/show_bug.cgi?id=973205 - -Signed-off-by: Paulo Flabiano Smorigo -Signed-off-by: Robbie Harwood ---- - grub-core/kern/ieee1275/cmain.c | 5 ++++- - grub-core/video/ieee1275.c | 9 ++++++--- - include/grub/ieee1275/ieee1275.h | 2 ++ - 3 files changed, 12 insertions(+), 4 deletions(-) - -diff --git a/grub-core/kern/ieee1275/cmain.c b/grub-core/kern/ieee1275/cmain.c -index 20cbbd761ec..04df9d2c667 100644 --- a/grub-core/kern/ieee1275/cmain.c +++ b/grub-core/kern/ieee1275/cmain.c -@@ -90,7 +90,10 @@ grub_ieee1275_find_options (void) +@@ -89,7 +89,10 @@ } if (rc >= 0 && grub_strncmp (tmp, "IBM", 3) == 0) - grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS); + { -+ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS); -+ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT); ++ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_NO_TREE_SCANNING_FOR_DISKS); ++ grub_ieee1275_set_flag (GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT); + } /* Old Macs have no key repeat, newer ones have fully working one. The ones inbetween when repeated key generates an escaoe sequence -diff --git a/grub-core/video/ieee1275.c b/grub-core/video/ieee1275.c -index 17a3dbbb575..b8e4b3feb32 100644 --- a/grub-core/video/ieee1275.c +++ b/grub-core/video/ieee1275.c -@@ -352,9 +352,12 @@ static struct grub_video_adapter grub_video_ieee1275_adapter = +@@ -351,9 +351,12 @@ GRUB_MOD_INIT(ieee1275_fb) { @@ -50,15 +30,13 @@ index 17a3dbbb575..b8e4b3feb32 100644 } GRUB_MOD_FINI(ieee1275_fb) -diff --git a/include/grub/ieee1275/ieee1275.h b/include/grub/ieee1275/ieee1275.h -index 0a599607f31..b5a1d49bbc3 100644 --- a/include/grub/ieee1275/ieee1275.h +++ b/include/grub/ieee1275/ieee1275.h -@@ -148,6 +148,8 @@ enum grub_ieee1275_flag - GRUB_IEEE1275_FLAG_CURSORONOFF_ANSI_BROKEN, +@@ -145,6 +145,8 @@ + GRUB_IEEE1275_FLAG_POWER_VM, - GRUB_IEEE1275_FLAG_RAW_DEVNAMES, -+ + GRUB_IEEE1275_FLAG_POWER_KVM, ++ + GRUB_IEEE1275_FLAG_DISABLE_VIDEO_SUPPORT }; diff --git a/grub2-ppc64le-memory-map.patch b/grub2-ppc64le-memory-map.patch new file mode 100644 index 0000000000000000000000000000000000000000..5202d2072f871c70359d9bb6a507ca1ea5361b09 --- /dev/null +++ b/grub2-ppc64le-memory-map.patch @@ -0,0 +1,78 @@ +--- a/grub-core/kern/ieee1275/openfw.c ++++ b/grub-core/kern/ieee1275/openfw.c +@@ -302,6 +302,34 @@ + return args.catch_result; + } + ++/* Preallocate IEEE1275_MAX_MAP_RESOURCE map tracks to track the ++ * map regions allocated to us by the firmware. Cannot ++ * dynamically allocate them, since the heap is not set ++ * yet. ++ */ ++struct grub_map_track grub_map_track[IEEE1275_MAX_MAP_RESOURCE]; ++int grub_map_track_index=0; ++ ++void ++grub_releasemap () ++{ ++ int i=0; ++ for (i=grub_map_track_index-1; i >= 0; i--) ++ grub_ieee1275_release(grub_map_track[i].addr, grub_map_track[i].size); ++ grub_map_track_index = 0; ++ return; ++} ++ ++static void ++grub_track_map (grub_addr_t addr, grub_size_t size) ++{ ++ if (grub_map_track_index >= IEEE1275_MAX_MAP_RESOURCE) ++ return; ++ grub_map_track[grub_map_track_index].addr = addr; ++ grub_map_track[grub_map_track_index++].size = size; ++ return; ++} ++ + grub_err_t + grub_claimmap (grub_addr_t addr, grub_size_t size) + { +@@ -317,6 +345,7 @@ + return grub_errno; + } + ++ grub_track_map (addr, size); + return GRUB_ERR_NONE; + } + +--- a/include/grub/ieee1275/ieee1275.h ++++ b/include/grub/ieee1275/ieee1275.h +@@ -33,6 +33,12 @@ + unsigned int size; + }; + ++#define IEEE1275_MAX_MAP_RESOURCE 10 ++struct grub_map_track { ++ grub_addr_t addr; ++ grub_size_t size; ++}; ++ + #define IEEE1275_MAX_PROP_LEN 8192 + #define IEEE1275_MAX_PATH_LEN 256 + +@@ -228,6 +234,7 @@ + int EXPORT_FUNC(grub_ieee1275_get_block_size) (grub_ieee1275_ihandle_t ihandle); + + grub_err_t EXPORT_FUNC(grub_claimmap) (grub_addr_t addr, grub_size_t size); ++void EXPORT_FUNC(grub_releasemap) (void); + + int + EXPORT_FUNC(grub_ieee1275_map) (grub_addr_t phys, grub_addr_t virt, +--- a/grub-core/kern/ieee1275/init.c ++++ b/grub-core/kern/ieee1275/init.c +@@ -111,6 +111,7 @@ + void + grub_exit (void) + { ++ grub_releasemap(); + grub_ieee1275_exit (); + } + diff --git a/0067-Work-around-some-minor-include-path-weirdnesses.patch b/grub2-s390x-01-Changes-made-and-files-added-in-order-to-allow-s390x.patch similarity index 31% rename from 0067-Work-around-some-minor-include-path-weirdnesses.patch rename to grub2-s390x-01-Changes-made-and-files-added-in-order-to-allow-s390x.patch index 460d792707723c4de647d169db2f2316a995b5ce..957d0729d4efd30128e96a70954d5862dc3fce44 100644 --- a/0067-Work-around-some-minor-include-path-weirdnesses.patch +++ b/grub2-s390x-01-Changes-made-and-files-added-in-order-to-allow-s390x.patch @@ -1,29 +1,83 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Peter Jones -Date: Fri, 16 Mar 2018 13:28:57 -0400 -Subject: [PATCH] Work around some minor include path weirdnesses +From f38ada424e7d991a0121253ba1abc430b86a990b Mon Sep 17 00:00:00 2001 +From: John Jolly +Date: Wed, 22 Jan 2014 01:18:10 -0700 +Subject: [PATCH 1/3] - Changes made and files added in order to allow s390x + build -Signed-off-by: Peter Jones --- - include/grub/arm/efi/console.h | 24 ++++++++++++++++++++++++ - include/grub/arm64/efi/console.h | 24 ++++++++++++++++++++++++ - include/grub/i386/efi/console.h | 24 ++++++++++++++++++++++++ - include/grub/x86_64/efi/console.h | 24 ++++++++++++++++++++++++ - 4 files changed, 96 insertions(+) - create mode 100644 include/grub/arm/efi/console.h - create mode 100644 include/grub/arm64/efi/console.h - create mode 100644 include/grub/i386/efi/console.h - create mode 100644 include/grub/x86_64/efi/console.h + grub-core/kern/emu/cache_s.S | 1 + + grub-core/kern/emu/lite.c | 2 ++ + grub-core/kern/s390x/dl.c | 37 +++++++++++++++++++++++++++++++++++ + grub-core/lib/s390x/setjmp.S | 46 ++++++++++++++++++++++++++++++++++++++++++++ + grub-core/lib/setjmp.S | 2 ++ + include/grub/cache.h | 2 +- + include/grub/s390x/setjmp.h | 29 ++++++++++++++++++++++++++++ + include/grub/s390x/time.h | 27 ++++++++++++++++++++++++++ + include/grub/s390x/types.h | 32 ++++++++++++++++++++++++++++++ + 9 files changed, 177 insertions(+), 1 deletion(-) + create mode 100644 grub-core/kern/s390x/dl.c + create mode 100644 grub-core/lib/s390x/setjmp.S + create mode 100644 include/grub/s390x/setjmp.h + create mode 100644 include/grub/s390x/time.h + create mode 100644 include/grub/s390x/types.h -diff --git a/include/grub/arm/efi/console.h b/include/grub/arm/efi/console.h -new file mode 100644 -index 00000000000..1592f6f76b5 +--- a/grub-core/kern/emu/cache_s.S ++++ b/grub-core/kern/emu/cache_s.S +@@ -15,6 +15,7 @@ + #include "../powerpc/cache.S" + #elif defined(__ia64__) || defined(__arm__) || defined(__aarch64__) || \ + defined(__mips__) || defined(__riscv) ++#elif defined(__s390x__) + #else + #error "No target cpu type is defined" + #endif +--- a/grub-core/kern/emu/lite.c ++++ b/grub-core/kern/emu/lite.c +@@ -26,6 +26,8 @@ + #include "../arm64/dl.c" + #elif defined(__riscv) + #include "../riscv/dl.c" ++#elif defined(__s390x__) ++#include "../s390x/dl.c" + #else + #error "No target cpu type is defined" + #endif +--- a/grub-core/kern/dl.c ++++ b/grub-core/kern/dl.c +@@ -230,7 +230,7 @@ + const Elf_Shdr *s; + grub_size_t tsize = 0, talign = 1; + #if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ +- !defined (__loongarch__) ++ !defined (__loongarch__) && !defined (__s390x__) + grub_size_t tramp; + grub_size_t got; + grub_err_t err; +@@ -247,7 +247,7 @@ + } + + #if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ +- !defined (__loongarch__) ++ !defined (__loongarch__) && !defined (__s390x__) + err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got); + if (err) + return err; +@@ -311,7 +311,7 @@ + } + } + #if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \ +- !defined (__loongarch__) ++ !defined (__loongarch__) && !defined (__s390x__) + ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN); + mod->tramp = ptr; + mod->trampptr = ptr; --- /dev/null -+++ b/include/grub/arm/efi/console.h -@@ -0,0 +1,24 @@ ++++ b/grub-core/kern/s390x/dl.c +@@ -0,0 +1,40 @@ ++/* dl.c - arch-dependent part of loadable module support */ +/* + * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2005,2006,2007 Free Software Foundation, Inc. ++ * Copyright (C) 2002,2004,2005,2007,2009 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 @@ -39,21 +93,33 @@ index 00000000000..1592f6f76b5 + * along with GRUB. If not, see . + */ + -+#ifndef GRUB_ARM_EFI_CONSOLE_H -+#define GRUB_ARM_EFI_CONSOLE_H ++#include + -+#include ++/* Check if EHDR is a valid ELF header. */ ++grub_err_t ++grub_arch_dl_check_header (void *ehdr) ++{ ++ (void)(ehdr); ++ return GRUB_ERR_BUG; ++} + -+#endif /* ! GRUB_ARM_EFI_CONSOLE_H */ -diff --git a/include/grub/arm64/efi/console.h b/include/grub/arm64/efi/console.h -new file mode 100644 -index 00000000000..95689339384 ++/* Relocate symbols. */ ++grub_err_t ++grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr, ++ Elf_Shdr *s, grub_dl_segment_t seg) ++{ ++ (void)(mod); ++ (void)(ehdr); ++ (void)(s); ++ (void)(seg); ++ return GRUB_ERR_BUG; ++} --- /dev/null -+++ b/include/grub/arm64/efi/console.h -@@ -0,0 +1,24 @@ ++++ b/grub-core/lib/s390x/setjmp.S +@@ -0,0 +1,46 @@ +/* + * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2005,2006,2007 Free Software Foundation, Inc. ++ * Copyright (C) 2005,2007,2009 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 @@ -69,21 +135,62 @@ index 00000000000..95689339384 + * along with GRUB. If not, see . + */ + -+#ifndef GRUB_ARM64_EFI_CONSOLE_H -+#define GRUB_ARM64_EFI_CONSOLE_H ++#include ++#include + -+#include ++ .file "setjmp.S" + -+#endif /* ! GRUB_ARM64_EFI_CONSOLE_H */ -diff --git a/include/grub/i386/efi/console.h b/include/grub/i386/efi/console.h -new file mode 100644 -index 00000000000..9231375cb07 ++GRUB_MOD_LICENSE "GPLv3+" ++ ++ .text ++ ++/* ++ * int grub_setjmp (grub_jmp_buf env) ++ */ ++FUNCTION(grub_setjmp) ++ stmg %r11,%r15,0(%r2) ++ lghi %r2,0 ++ br %r14 ++ ++/* ++ * int grub_longjmp (grub_jmp_buf env, int val) ++ */ ++FUNCTION(grub_longjmp) ++ chi %r3,0 ++ jne .L2 ++ lghi %r3,1 ++.L2: ++ lmg %r11,%r15,0(%r2) ++ lgr %r2,%r3 ++ br %r14 +--- a/grub-core/lib/setjmp.S ++++ b/grub-core/lib/setjmp.S +@@ -23,6 +23,8 @@ + #include "./loongarch64/setjmp.S" + #elif defined(__riscv) + #include "./riscv/setjmp.S" ++#elif defined(__s390x__) ++#include "./s390x/setjmp.S" + #else + #error "Unknown target cpu type" + #endif +--- a/include/grub/cache.h ++++ b/include/grub/cache.h +@@ -23,7 +23,7 @@ + #include + #include + +-#if defined (__i386__) || defined (__x86_64__) ++#if defined (__i386__) || defined (__x86_64__) || defined (__s390x__) + static inline void + grub_arch_sync_caches (void *address __attribute__ ((unused)), + grub_size_t len __attribute__ ((unused))) --- /dev/null -+++ b/include/grub/i386/efi/console.h -@@ -0,0 +1,24 @@ ++++ b/include/grub/s390x/setjmp.h +@@ -0,0 +1,29 @@ +/* + * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2005,2006,2007 Free Software Foundation, Inc. ++ * Copyright (C) 2002,2004,2006,2007,2009 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 @@ -99,21 +206,23 @@ index 00000000000..9231375cb07 + * along with GRUB. If not, see . + */ + -+#ifndef GRUB_I386_EFI_CONSOLE_H -+#define GRUB_I386_EFI_CONSOLE_H ++#ifndef GRUB_SETJMP_CPU_HEADER ++#define GRUB_SETJMP_CPU_HEADER 1 ++ ++#include ++ ++typedef grub_uint64_t grub_jmp_buf[5]; + -+#include ++int grub_setjmp (grub_jmp_buf env) __attribute__ ((returns_twice)); ++void grub_longjmp (grub_jmp_buf env, int val) __attribute__ ((noreturn)); + -+#endif /* ! GRUB_I386_EFI_CONSOLE_H */ -diff --git a/include/grub/x86_64/efi/console.h b/include/grub/x86_64/efi/console.h -new file mode 100644 -index 00000000000..dba9d8678d0 ++#endif /* ! GRUB_SETJMP_CPU_HEADER */ --- /dev/null -+++ b/include/grub/x86_64/efi/console.h -@@ -0,0 +1,24 @@ ++++ b/include/grub/s390x/time.h +@@ -0,0 +1,27 @@ +/* + * GRUB -- GRand Unified Bootloader -+ * Copyright (C) 2002,2005,2006,2007 Free Software Foundation, Inc. ++ * Copyright (C) 2007 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 @@ -129,9 +238,59 @@ index 00000000000..dba9d8678d0 + * along with GRUB. If not, see . + */ + -+#ifndef GRUB_X86_64_EFI_CONSOLE_H -+#define GRUB_X86_64_EFI_CONSOLE_H ++#ifndef KERNEL_CPU_TIME_HEADER ++#define KERNEL_CPU_TIME_HEADER 1 ++ ++static __inline void ++grub_cpu_idle (void) ++{ ++} ++ ++#endif /* ! KERNEL_CPU_TIME_HEADER */ +--- /dev/null ++++ b/include/grub/s390x/types.h +@@ -0,0 +1,32 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2002,2004,2006,2007 Free Software Foundation, Inc. ++ * ++ * GRUB is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GRUB is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GRUB. If not, see . ++ */ ++ ++#ifndef GRUB_TYPES_CPU_HEADER ++#define GRUB_TYPES_CPU_HEADER 1 ++ ++/* The size of void *. */ ++#define GRUB_TARGET_SIZEOF_VOID_P 8 ++ ++/* The size of long. */ ++#define GRUB_TARGET_SIZEOF_LONG 8 ++ ++/* s390x is big-endian. */ ++#define GRUB_TARGET_WORDS_BIGENDIAN 1 ++ + -+#include ++#endif /* ! GRUB_TYPES_CPU_HEADER */ +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -407,6 +407,9 @@ + extra_dist = kern/i386/realmode.S; + extra_dist = boot/i386/pc/lzma_decode.S; + extra_dist = kern/mips/cache_flush.S; + -+#endif /* ! GRUB_X86_64_EFI_CONSOLE_H */ ++ extra_dist = kern/s390x/dl.c; ++ extra_dist = lib/s390x/setjmp.S; + }; + + program = { diff --git a/grub2-s390x-03-output-7-bit-ascii.patch b/grub2-s390x-03-output-7-bit-ascii.patch new file mode 100644 index 0000000000000000000000000000000000000000..7bf35950c93afd55bbedadeac3b5267dece2f9a8 --- /dev/null +++ b/grub2-s390x-03-output-7-bit-ascii.patch @@ -0,0 +1,530 @@ +Vn: + * recognize 'dev/sclp_line0' as 3215-look-alike. [bnc#876743] +Vn+1: + * revamp readkey_dumb(). +Vn+2: + * support hotkeys on all line-mode terminals, not only 3215. [bnc#885668] + +--- + grub-core/kern/emu/main.c | 8 + + grub-core/normal/menu_text.c | 54 +++++++- + grub-core/normal/term.c | 2 + grub-core/osdep/unix/emuconsole.c | 238 +++++++++++++++++++++++++++++++++++++- + include/grub/term.h | 4 + 5 files changed, 294 insertions(+), 12 deletions(-) + +--- a/grub-core/osdep/unix/emuconsole.c ++++ b/grub-core/osdep/unix/emuconsole.c +@@ -39,17 +39,61 @@ + + #include + ++#include ++#include ++ + extern struct grub_terminfo_output_state grub_console_terminfo_output; + static int original_fl; + static int saved_orig; + static struct termios orig_tty; + static struct termios new_tty; ++static int console_mode = 0; ++ ++#define MAX_LEN 1023 ++#if defined(__s390x__) ++static int ++dummy (void) ++{ ++ return 0; ++} ++#endif ++#if 0 ++static char msg[MAX_LEN+1]; ++static void ++dprint (int len) ++{ ++ if (len < 0) ++ return; ++ if (len > MAX_LEN) ++ len = MAX_LEN; ++ write (2, msg, len); ++} ++#define dprintf(fmt, vargs...) dprint(snprintf(msg, MAX_LEN, fmt, ## vargs)) ++#else ++#define dprintf(fmt, vargs...) {} ++#endif + + static void +-put (struct grub_term_output *term __attribute__ ((unused)), const int c) ++put (struct grub_term_output *term, const int c) + { + char chr = c; + ssize_t actual; ++ struct grub_terminfo_output_state *data ++ = (struct grub_terminfo_output_state *) term->data; ++ ++ if (term->flags & GRUB_TERM_DUMB) { ++ if (c == '\n') { ++ data->pos.y++; ++ data->pos.x = 0; ++ } else { ++ data->pos.x++; ++ } ++ if (0) { ++ if (c == ' ') chr = '_'; ++ if (c == GRUB_TERM_BACKSPACE) chr = '{'; ++ if (c == '\b') chr = '<'; ++ } ++ } + + actual = write (STDOUT_FILENO, &chr, 1); + if (actual < 1) +@@ -60,17 +104,152 @@ + } + + static int +-readkey (struct grub_term_input *term __attribute__ ((unused))) ++readkey (struct grub_term_input *term) + { + grub_uint8_t c; + ssize_t actual; + ++ fd_set readfds; ++ struct timeval timeout; ++ int sel; ++ FD_SET (0, &readfds); ++ timeout.tv_sec = 0; ++ timeout.tv_usec = 500000; ++ if ((sel=select (1, &readfds, (fd_set *)0, (fd_set *)0, &timeout)) <= 0) ++ { ++ if (sel < 0 && errno == EINTR) ++ return 0x03; /* '^C' */ ++ return -1; ++ } ++ + actual = read (STDIN_FILENO, &c, 1); + if (actual > 0) + return c; + return -1; + } + ++#define NO_KEY ((grub_uint8_t)-1) ++static int ++readkey_dumb (struct grub_term_input *term) ++{ ++ grub_uint8_t c; ++ static grub_uint8_t p = NO_KEY; ++ ++ c = readkey (term); ++ if (c == NO_KEY) ++ return -1; ++ if ((p == '^' || p == '\n') && c == '\n') /* solitary '^' or '\n'? */ ++ { ++ c = p; /* use immediately! */ ++ p = '\n'; ++ } ++ else if ((c == '\n' || c == '^') && p != c) /* non-duplicate specials? */ ++ { ++ p = c; /* remember! */ ++ c = NO_KEY; ++ } ++ else if (p == '^') ++ { ++ if (c != '^') ++ c &= 0x1F; ++ p = NO_KEY; ++ } ++ else ++ p = c; ++ return c; ++} ++ ++static void ++grub_dumb_putchar (struct grub_term_output *term, ++ const struct grub_unicode_glyph *c) ++{ ++ unsigned i; ++ ++ /* For now, do not try to use a surrogate pair. */ ++ if (c->base > 0xffff) ++ put (term, '?'); ++ else ++ put (term, (c->base & 0xffff)); ++ ++ if (0) { ++ for (i = 0; i < c->ncomb; i++) ++ if (c->base < 0xffff) ++ put (term, grub_unicode_get_comb (c)[i].code); ++ } ++} ++ ++static struct grub_term_coordinate ++grub_dumb_getxy (struct grub_term_output *term) ++{ ++ struct grub_terminfo_output_state *data ++ = (struct grub_terminfo_output_state *) term->data; ++ ++ dprintf ("<%d,%d>", data->pos.x, data->pos.y); ++ return data->pos; ++} ++ ++static struct grub_term_coordinate ++grub_dumb_getwh (struct grub_term_output *term) ++{ ++ static int once = 0; ++ struct grub_terminfo_output_state *data ++ = (struct grub_terminfo_output_state *) term->data; ++ ++ if (!once++) ++ dprintf ("dumb_getwh: w=%d h=%d\n", data->size.x, data->size.y); ++ return data->size; ++} ++ ++static void ++grub_dumb_gotoxy (struct grub_term_output *term, ++ struct grub_term_coordinate pos) ++{ ++ struct grub_terminfo_output_state *data ++ = (struct grub_terminfo_output_state *) term->data; ++ ++ if (pos.x > grub_term_width (term) || pos.y > grub_term_height (term)) ++ { ++ grub_error (GRUB_ERR_BUG, "invalid point (%u,%u)", pos.x, pos.y); ++ return; ++ } ++ ++ dprintf("goto(%d,%d)", pos.x, pos.y); ++ if (pos.x > (grub_term_width (term) - 4)) { ++ dprintf (" really?"); ++ //return; ++ } ++ ++ if (data->gotoxy) ++ { ++ int i; ++ dprintf ("data-gotoxy"); ++ if (data->pos.y != pos.y) { ++ put (term, '\n'); ++ ++ for (i = 1; i < pos.x; i++ ) ++ put (term, ' '); ++ } ++ } ++ else ++ { ++ int i = 0; ++ if (data->pos.y != pos.y || data->pos.x > pos.x) { ++ if (data->pos.y >= pos.y) data->pos.y = pos.y - 1; ++ if (pos.y - data->pos.y > 3) data->pos.y = pos.y - 2; ++ dprintf (" <%dnl>+%d", (pos.y - data->pos.y), pos.x); ++ for (i = data->pos.y; i < pos.y; i++ ) ++ put (term, '\n'); ++ } ++ for (i = data->pos.x; i < pos.x; i++ ) ++ put (term, ' '); ++ dprintf ("#%d", i); ++ grub_dumb_getxy (term); ++ } ++ ++ dprintf ("\n"); ++ data->pos = pos; ++} ++ + static grub_err_t + grub_console_init_input (struct grub_term_input *term) + { +@@ -105,7 +284,8 @@ + grub_console_init_output (struct grub_term_output *term) + { + struct winsize size; +- if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &size) >= 0) ++ if (ioctl (STDOUT_FILENO, TIOCGWINSZ, &size) >= 0 && ++ size.ws_col > 0 && size.ws_row > 0) + { + grub_console_terminfo_output.size.x = size.ws_col; + grub_console_terminfo_output.size.y = size.ws_row; +@@ -115,6 +295,8 @@ + grub_console_terminfo_output.size.x = 80; + grub_console_terminfo_output.size.y = 24; + } ++ if (console_mode == 3215) ++ grub_console_terminfo_output.size.x -= 1; + + grub_terminfo_output_init (term); + +@@ -161,24 +343,72 @@ + void + grub_console_init (void) + { ++#if ! defined(__s390x__) + const char *cs = nl_langinfo (CODESET); + if (cs && grub_strcasecmp (cs, "UTF-8")) + grub_console_term_output.flags = GRUB_TERM_CODE_TYPE_UTF8_LOGICAL; + else + grub_console_term_output.flags = GRUB_TERM_CODE_TYPE_ASCII; ++#else ++ char link[MAX_LEN+1]; ++ ssize_t len = readlink ("/proc/self/fd/0", link, MAX_LEN); ++ ++ if (len > 0) ++ link[len] = 0; ++ else ++ link[0] = 0; ++ if (grub_strncmp ("/dev/ttyS", link, 9) == 0 ) ++ console_mode = 3215; ++ else if (grub_strncmp ("/dev/3270/tty", link, 13) == 0 ) ++ console_mode = 3270; ++ else if (grub_strncmp ("/dev/sclp_line", link, 14) == 0 ) ++ console_mode = 3215; ++ grub_console_term_output.flags = GRUB_TERM_CODE_TYPE_ASCII; ++ switch (console_mode) ++ { ++ case 3215: ++ grub_console_term_output.flags |= GRUB_TERM_DUMB; ++ /* FALLTHROUGH */ ++ case 3270: ++ grub_console_term_output.flags |= GRUB_TERM_LINE; ++ grub_console_term_output.flags |= GRUB_TERM_NO_ECHO; ++ grub_console_terminfo_input.readkey = readkey_dumb; ++ break; ++ default: ++ break; ++ } ++#endif ++ if (grub_console_term_output.flags & GRUB_TERM_DUMB) ++ { ++ grub_console_term_output.putchar = grub_dumb_putchar, ++ grub_console_term_output.getxy = grub_dumb_getxy; ++ grub_console_term_output.getwh = grub_dumb_getwh; ++ grub_console_term_output.gotoxy = grub_dumb_gotoxy; ++ grub_console_term_output.cls = (void *) dummy; ++ grub_console_term_output.setcolorstate = (void *) dummy; ++ grub_console_term_output.setcursor = (void *) dummy; ++ grub_console_term_output.progress_update_divisor = GRUB_PROGRESS_NO_UPDATE; ++ } + grub_term_register_input ("console", &grub_console_term_input); + grub_term_register_output ("console", &grub_console_term_output); + grub_terminfo_init (); +- grub_terminfo_output_register (&grub_console_term_output, "vt100-color"); ++ grub_terminfo_output_register (&grub_console_term_output, ++ (grub_console_term_output.flags & GRUB_TERM_DUMB) ? "dumb":"vt100-color"); + } + + void + grub_console_fini (void) + { ++ dprintf( "grub_console_fini: %d\n", grub_console_term_output.flags & GRUB_TERM_DUMB); + if (saved_orig) + { + fcntl (STDIN_FILENO, F_SETFL, original_fl); + tcsetattr(STDIN_FILENO, TCSANOW, &orig_tty); + } ++ if (!(grub_console_term_output.flags & GRUB_TERM_DUMB)) ++ { ++ const char clear[] = { 0x1b, 'c', 0 }; ++ write (STDOUT_FILENO, clear, 2); ++ } + saved_orig = 0; + } +--- a/grub-core/normal/menu_text.c ++++ b/grub-core/normal/menu_text.c +@@ -113,6 +113,7 @@ + { + int i; + ++ if (! (term->flags & GRUB_TERM_DUMB)) { + grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); + + grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1, +@@ -142,7 +143,7 @@ + grub_putcode (GRUB_UNICODE_CORNER_LR, term); + + grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); +- ++ } + grub_term_gotoxy (term, + (struct grub_term_coordinate) { geo->first_entry_x - 1, + (geo->first_entry_y - 1 + geo->num_entries +@@ -155,6 +156,15 @@ + int ret = 0; + grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL); + ++ if (edit && (term->flags & GRUB_TERM_LINE)) ++ { ++ ret += grub_print_message_indented_real ++ (_("Minimum Emacs-like screen editing is supported. '^i' lists " ++ "completions. Type '^x' to boot, '^c' for a command-line " ++ "or '^[' to discard edits and return to the GRUB menu."), ++ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); ++ } ++ else + if (edit) + { + ret += grub_print_message_indented_real (_("Minimum Emacs-like screen editing is \ +@@ -165,10 +175,15 @@ + } + else + { ++#if defined(__s390x__hotkey) ++ ret += grub_print_message_indented_real ++ (_("Select a menu option by pressing the hotkey specified. "), ++ STANDARD_MARGIN, STANDARD_MARGIN, term, dry_run); ++#else + char *msg_translated; + + msg_translated = grub_xasprintf (_("Use the %C and %C keys to select which " +- "entry is highlighted."), ++ "entry is highlighted. "), + GRUB_UNICODE_UPARROW, + GRUB_UNICODE_DOWNARROW); + if (!msg_translated) +@@ -177,6 +192,7 @@ + STANDARD_MARGIN, term, dry_run); + + grub_free (msg_translated); ++#endif + + if (nested) + { +@@ -211,6 +227,10 @@ + + title = entry ? entry->title : ""; + title_len = grub_strlen (title); ++ ++ if ((data->term->flags & GRUB_TERM_DUMB) && title[0] == '\0') ++ return; ++ + unicode_title = grub_calloc (title_len, sizeof (*unicode_title)); + if (! unicode_title) + /* XXX How to show this error? */ +@@ -244,6 +264,14 @@ + if (data->geo.num_entries > 1) + grub_putcode (highlight ? '*' : ' ', data->term); + ++ if ((data->term->flags & GRUB_TERM_LINE) && title[0] != '\0') { ++ grub_putcode('(', data->term); ++ grub_putcode((entry && entry->hotkey >= '0' && entry->hotkey <= 'z') ? ++ entry->hotkey : ' ', data->term); ++ grub_putcode(')', data->term); ++ grub_putcode(' ', data->term); ++ } ++ + grub_print_ucs4_menu (unicode_title, + unicode_title + len, + 0, +@@ -416,6 +444,8 @@ + grub_term_highlight_color = old_color_highlight; + geo->timeout_y = geo->first_entry_y + geo->num_entries + + geo->border + empty_lines; ++ if (term->flags & GRUB_TERM_DUMB) ++ geo->timeout_y = 1; + if (bottom_message) + { + grub_term_gotoxy (term, +@@ -425,6 +455,8 @@ + print_message (nested, edit, term, 0); + geo->timeout_y += msg_num_lines; + } ++ if (term->flags & GRUB_TERM_DUMB) ++ geo->timeout_y = 1; + geo->right_margin = grub_term_width (term) + - geo->first_entry_x + - geo->entry_width - 1; +@@ -436,12 +468,19 @@ + struct menu_viewer_data *data = dataptr; + char *msg_translated = 0; + +- grub_term_gotoxy (data->term, ++ if (data->geo.timeout_y) ++ grub_term_gotoxy (data->term, + (struct grub_term_coordinate) { 0, data->geo.timeout_y }); + ++ if (data->term->flags & GRUB_TERM_DUMB) ++ { ++ if (! data->geo.timeout_y) ++ data->timeout_msg = TIMEOUT_TERSE; ++ data->geo.timeout_y = 0; ++ } + if (data->timeout_msg == TIMEOUT_TERSE + || data->timeout_msg == TIMEOUT_TERSE_NO_MARGIN) +- msg_translated = grub_xasprintf (_("%ds"), timeout); ++ msg_translated = grub_xasprintf (_(" %ds"), timeout); + else + msg_translated = grub_xasprintf (_("The highlighted entry will be executed automatically in %ds."), timeout); + if (!msg_translated) +@@ -471,6 +510,8 @@ + data->term); + grub_free (msg_translated); + ++ if (data->term->flags & GRUB_TERM_DUMB) ++ return; + grub_term_gotoxy (data->term, + (struct grub_term_coordinate) { + grub_term_cursor_x (&data->geo), +@@ -498,7 +539,7 @@ + data->first = entry; + complete_redraw = 1; + } +- if (complete_redraw) ++ if (complete_redraw || (data->term->flags & GRUB_TERM_DUMB)) + print_entries (data->menu, data); + else + { +@@ -528,6 +569,9 @@ + struct menu_viewer_data *data = dataptr; + int i; + ++ if ((data->term->flags & GRUB_TERM_DUMB)) ++ return; ++ + for (i = 0; i < data->geo.timeout_lines;i++) + { + grub_term_gotoxy (data->term, (struct grub_term_coordinate) { +--- a/grub-core/normal/term.c ++++ b/grub-core/normal/term.c +@@ -981,7 +981,7 @@ + { + print_ucs4_real (str, last_position, margin_left, margin_right, + term, 0, 0, 1, skip_lines, max_lines, +- contchar, 1, pos); ++ contchar, (term->flags & GRUB_TERM_DUMB)? 0 : 1, pos); + } + + void +--- a/grub-core/kern/emu/main.c ++++ b/grub-core/kern/emu/main.c +@@ -190,6 +190,12 @@ + NULL, help_filter, NULL + }; + ++void ++ignore (int num __attribute__ ((unused))) ++{ ++ return; ++} ++ + + + #pragma GCC diagnostic ignored "-Wmissing-prototypes" +@@ -259,7 +265,7 @@ + sleep (1); + } + +- signal (SIGINT, SIG_IGN); ++ signal (SIGINT, (sighandler_t) &ignore); + grub_console_init (); + grub_host_init (); + +--- a/include/grub/term.h ++++ b/include/grub/term.h +@@ -102,8 +102,10 @@ + #define GRUB_TERM_NO_EDIT (1 << 1) + /* Set when the terminal cannot do fancy things. */ + #define GRUB_TERM_DUMB (1 << 2) ++/* Set when the terminal is line oriented. */ ++#define GRUB_TERM_LINE (1 << 3) + /* Which encoding does terminal expect stream to be. */ +-#define GRUB_TERM_CODE_TYPE_SHIFT 3 ++#define GRUB_TERM_CODE_TYPE_SHIFT 4 + #define GRUB_TERM_CODE_TYPE_MASK (7 << GRUB_TERM_CODE_TYPE_SHIFT) + /* Only ASCII characters accepted. */ + #define GRUB_TERM_CODE_TYPE_ASCII (0 << GRUB_TERM_CODE_TYPE_SHIFT) diff --git a/grub2-s390x-04-grub2-install.patch b/grub2-s390x-04-grub2-install.patch new file mode 100644 index 0000000000000000000000000000000000000000..449696c089a2e75ae608e648eada19a24e010be9 --- /dev/null +++ b/grub2-s390x-04-grub2-install.patch @@ -0,0 +1,1276 @@ +From: Raymund Will +Subject: Allow s390x-emu to be "installed" +References: fate#314213, bnc#866867, bnc#868909, bnc#874155, bnc#876743, + bnc#879136, bnc#889562, bnc#889572 +Patch-Mainline: no + +V2: + * try harder to find root filesystem (incl. subvol-handling). + * read /etc/sysconfig/bootloader as final fallback. +V3: + * refresh initrd by default, prefer running kernel and + re-zipl despite minor issues. [bnc#866867, fate#314213] +V4: + * append 'quiet splash=silent' for 'initgrub'-boot. + * properly check for dracut script during 'grub2-install'. + * move 'zipl2grub.pl' to '/usr/sbin/grub2-zipl-setup'. +V5: + * actually call 'grub2-zipl-setup' from 'grub2-install'. + * handle 'GRUB{,_EMU}_CONMODE'. [bnc#868909] +V6: + * grub2-zipl-setup: support 'xz' initrd compression. [bnc#874155] +V7: + * dracut-grub2.sh: use 'showconsole' to determine console device. [bnc#876743] + * dracut-grub2.sh: and fall back to '/dev/console' (instead of 'tty1'). + * dracut-grub2.sh: introduce "debug()" helper function. +V8: + * grub2-zipl-setup: replace poor choice in '/sysroot/sys' check. [bnc#879136] + * grub2-zipl-setup: fix typo in '/sysroot/proc' check. +V9: + * grub2-zipl-setup: honor GRUB_DISABLE_LINUX_UUID. [bnc#885854] +V10: + * grub2-zipl-setup: fix stupid typo in previous fix. [bnc#889562, bnc#889572] +V11: + * grub2-zipl-setup: disable 'grub-mkrelpath' acrobatics. [bnc#889572] +V12: + * dracut-grub2.sh: try to mount '/.snapshots' if missing. [bnc#892014] + * dracut-grub2.sh: use '/dev/shm' for debug output, so it's accessible + from grub2-emu's shell. +V13: + * grub2-zipl-setup: make initrd mount '/boot', if needed. [bnc#873951, bnc#892088] + * dracut-grub2.sh: provide /boot from above to grub2-emu in chroot. +V14: + * grub2-zipl-setup: actually remove obsolete kernel/initrds. [bnc#892810] +V15: + * zipl2grub.conf: turn of zipl-prompt and quiescent plymouth. [bsc#898198] +V16: + * dracut-grub2.sh: force read-only '/usr' for kexec. [bsc#932951] +V17: + * grub2-zipl-setup: remove arybase dependency by not referencing $[. [bsc#1055280] +V18: + * dracut-zipl-refresh.sh.in: initial submission. [bsc#1127293] + * dracut-grub2.sh: try to call zipl-refresh on failed kexec and drop + to an emergency shell otherwise +V19: + * dracut-grub2.sh: use 'grep -P' instead of '-E'. [bsc#1136970] +V20: + * dracut-grub2.sh: add support for '/boot/writable'. [bsc#1190395] + + +--- + Makefile.util.def | 46 +++ + configure.ac | 9 + grub-core/Makefile.core.def | 7 + grub-core/osdep/basic/no_platform.c | 7 + grub-core/osdep/unix/platform.c | 11 + grub-core/osdep/windows/platform.c | 6 + include/grub/util/install.h | 4 + util/grub-install-common.c | 1 + util/grub-install.c | 43 +++ + util/s390x/dracut-grub2.sh.in | 141 +++++++++++ + util/s390x/dracut-module-setup.sh.in | 19 + + util/s390x/dracut-zipl-refresh.sh.in | 183 ++++++++++++++ + util/s390x/zipl2grub.conf.in | 26 ++ + util/s390x/zipl2grub.pl.in | 423 +++++++++++++++++++++++++++++++++ + 14 files changed, 923 insertions(+), 3 deletions(-) + +--- a/Makefile.util.def ++++ b/Makefile.util.def +@@ -377,6 +377,7 @@ + ldadd = grub-core/lib/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + cppflags = '-DGRUB_SETUP_FUNC=grub_util_bios_setup'; ++ emu_condition = COND_NOT_s390x; + }; + + program = { +@@ -397,6 +398,7 @@ + ldadd = grub-core/lib/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; + cppflags = '-DGRUB_SETUP_FUNC=grub_util_sparc_setup'; ++ emu_condition = COND_NOT_s390x; + }; + + program = { +@@ -412,6 +414,7 @@ + ldadd = libgrubkern.a; + ldadd = grub-core/lib/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; ++ emu_condition = COND_NOT_s390x; + }; + + program = { +@@ -442,6 +445,7 @@ + ldadd = libgrubkern.a; + ldadd = grub-core/lib/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBUTIL) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; ++ emu_condition = COND_NOT_s390x; + }; + + data = { +@@ -665,6 +669,7 @@ + common = grub-core/disk/host.c; + + common = util/resolve.c; ++ emu_condition = COND_s390x; + common = grub-core/kern/emu/argp_common.c; + common = grub-core/osdep/init.c; + +@@ -734,6 +739,46 @@ + }; + + script = { ++ name = grub-zipl-setup; ++ installdir = sbin; ++ common = util/s390x/zipl2grub.pl.in; ++ enable = emu; ++ emu_condition = COND_s390x; ++}; ++ ++data = { ++ name = zipl2grub.conf.in; ++ common = util/s390x/zipl2grub.conf.in; ++ installdir = grubconf; ++ enable = emu; ++ emu_condition = COND_s390x; ++}; ++ ++script = { ++ name = dracut-module-setup.sh; ++ common = util/s390x/dracut-module-setup.sh.in; ++ enable = emu; ++ emu_condition = COND_s390x; ++ installdir = platform; ++}; ++ ++script = { ++ name = dracut-grub.sh; ++ common = util/s390x/dracut-grub2.sh.in; ++ enable = emu; ++ emu_condition = COND_s390x; ++ installdir = platform; ++}; ++ ++script = { ++ name = dracut-zipl-refresh; ++ common = util/s390x/dracut-zipl-refresh.sh.in; ++ enable = emu; ++ emu_condition = COND_s390x; ++ installdir = platform; ++}; ++ ++script = { + name = grub-mkconfig_lib; + common = util/grub-mkconfig_lib.in; + installdir = noinst; +@@ -1381,6 +1426,7 @@ + ldadd = libgrubkern.a; + ldadd = grub-core/lib/gnulib/libgnu.a; + ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)'; ++ emu_condition = COND_NOT_s390x; + }; + + program = { +--- a/configure.ac ++++ b/configure.ac +@@ -211,9 +211,9 @@ + esac + fi + +-if test x"$target_cpu-$platform" = xsparc64-emu ; then +- target_m64=1 +-fi ++case x"$target_cpu-$platform" in ++ xsparc64-emu | xs390x-emu) target_m64=1 ;; ++esac + + case "$target_os" in + windows* | mingw32*) target_os=cygwin ;; +@@ -2158,6 +2158,9 @@ + AM_CONDITIONAL([COND_sparc64_emu], [test x$target_cpu = xsparc64 -a x$platform = xemu]) + AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi]) + AM_CONDITIONAL([COND_x86_64_xen], [test x$target_cpu = xx86_64 -a x$platform = xxen]) ++AM_CONDITIONAL([COND_s390x], [test x$target_cpu = xs390x ]) ++AM_CONDITIONAL([COND_NOT_s390x], [test x$target_cpu != xs390x ]) ++AM_CONDITIONAL([COND_s390x_emu], [test x$target_cpu = xs390x -a x$platform = xemu]) + + AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd]) + AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux]) +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1186,6 +1186,7 @@ + module = { + name = videotest; + common = commands/videotest.c; ++ emu_condition = COND_NOT_s390x; + }; + + module = { +@@ -1640,6 +1641,7 @@ + common = gfxmenu/gui_progress_bar.c; + common = gfxmenu/gui_util.c; + common = gfxmenu/gui_string_util.c; ++ emu_condition = COND_NOT_s390x; + }; + + module = { +@@ -2078,11 +2080,13 @@ + name = gfxterm; + common = term/gfxterm.c; + enable = videomodules; ++ emu_condition = COND_NOT_s390x; + }; + + module = { + name = gfxterm_background; + common = term/gfxterm_background.c; ++ emu_condition = COND_NOT_s390x; + }; + + module = { +@@ -2205,6 +2209,7 @@ + enable = x86_64_efi; + enable = emu; + enable = xen; ++ emu_condition = COND_NOT_s390x; + }; + + module = { +@@ -2251,6 +2256,7 @@ + module = { + name = gfxterm_menu; + common = tests/gfxterm_menu.c; ++ emu_condition = COND_NOT_s390x; + }; + + module = { +@@ -2412,6 +2418,7 @@ + enable = x86_64_efi; + enable = emu; + enable = xen; ++ emu_condition = COND_NOT_s390x; + }; + + module = { +--- a/grub-core/osdep/basic/no_platform.c ++++ b/grub-core/osdep/basic/no_platform.c +@@ -44,3 +44,10 @@ + { + grub_util_error ("%s", _("no SGI routines are available for your platform")); + } ++ ++void ++grub_install_zipl (const char *d, int i, int f) ++{ ++ grub_util_error ("%s", _("no zIPL routines are available for your platform")); ++} ++ +--- a/grub-core/osdep/unix/platform.c ++++ b/grub-core/osdep/unix/platform.c +@@ -239,3 +239,14 @@ + imgfile, destname, NULL }); + grub_util_warn ("%s", _("You will have to set `SystemPartition' and `OSLoader' manually.")); + } ++ ++void ++grub_install_zipl (const char *dest, int install, int force) ++{ ++ if (grub_util_exec ((const char * []){ PACKAGE"-zipl-setup", ++ verbosity ? "-v" : "", ++ install ? "" : "--debug", ++ !force ? "" : "--force", ++ "-z", dest, NULL })) ++ grub_util_error (_("`%s' failed.\n"), PACKAGE"-zipl-setup"); ++} +--- a/grub-core/osdep/windows/platform.c ++++ b/grub-core/osdep/windows/platform.c +@@ -434,3 +434,9 @@ + { + grub_util_error ("%s", _("no SGI routines are available for your platform")); + } ++ ++void ++grub_install_zipl (const char *d, int i, int f) ++{ ++ grub_util_error ("%s", _("no zIPL routines are available for your platform")); ++} +--- a/include/grub/util/install.h ++++ b/include/grub/util/install.h +@@ -110,6 +110,7 @@ + GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI, + GRUB_INSTALL_PLATFORM_RISCV32_EFI, + GRUB_INSTALL_PLATFORM_RISCV64_EFI, ++ GRUB_INSTALL_PLATFORM_S390X_EMU, + GRUB_INSTALL_PLATFORM_MAX + }; + +@@ -237,6 +238,9 @@ + grub_install_sgi_setup (const char *install_device, + const char *imgfile, const char *destname); + ++void ++grub_install_zipl (const char *d, int i, int f); ++ + int + grub_install_compress_gzip (const char *src, const char *dest); + int +--- a/util/grub-install-common.c ++++ b/util/grub-install-common.c +@@ -924,6 +924,7 @@ + [GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI] = { "loongarch64", "efi" }, + [GRUB_INSTALL_PLATFORM_RISCV32_EFI] = { "riscv32", "efi" }, + [GRUB_INSTALL_PLATFORM_RISCV64_EFI] = { "riscv64", "efi" }, ++ [GRUB_INSTALL_PLATFORM_S390X_EMU] = { "s390x", "emu" }, + }; + + char * +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -66,6 +66,7 @@ + static char *disk_module = NULL; + static char *efidir = NULL; + static char *macppcdir = NULL; ++static char *zipldir = NULL; + static int force = 0; + static int have_abstractions = 0; + static int have_cryptodisk = 0; +@@ -106,6 +107,7 @@ + OPTION_NO_BOOTSECTOR, + OPTION_NO_RS_CODES, + OPTION_MACPPC_DIRECTORY, ++ OPTION_ZIPL_DIRECTORY, + OPTION_LABEL_FONT, + OPTION_LABEL_COLOR, + OPTION_LABEL_BGCOLOR, +@@ -181,6 +183,11 @@ + efidir = xstrdup (arg); + return 0; + ++ case OPTION_ZIPL_DIRECTORY: ++ free (zipldir); ++ zipldir = xstrdup (arg); ++ return 0; ++ + case OPTION_DISK_MODULE: + free (disk_module); + disk_module = xstrdup (arg); +@@ -298,6 +305,8 @@ + N_("use DIR as the EFI System Partition root."), 2}, + {"macppc-directory", OPTION_MACPPC_DIRECTORY, N_("DIR"), 0, + N_("use DIR for PPC MAC install."), 2}, ++ {"zipl-directory", OPTION_ZIPL_DIRECTORY, N_("DIR"), 0, ++ N_("use DIR as the zIPL Boot Partition root."), 2}, + {"label-font", OPTION_LABEL_FONT, N_("FILE"), 0, N_("use FILE as font for label"), 2}, + {"label-color", OPTION_LABEL_COLOR, N_("COLOR"), 0, N_("use COLOR for label"), 2}, + {"label-bgcolor", OPTION_LABEL_BGCOLOR, N_("COLOR"), 0, N_("use COLOR for label background"), 2}, +@@ -334,6 +343,8 @@ + #else + return NULL; + #endif ++#elif defined (__s390x__) ++ return "s390x-emu"; + #else + return NULL; + #endif +@@ -510,6 +521,8 @@ + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: ++ ++ case GRUB_INSTALL_PLATFORM_S390X_EMU: + return 0; + + /* pacify warning. */ +@@ -939,6 +952,7 @@ + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: ++ case GRUB_INSTALL_PLATFORM_S390X_EMU: + break; + + case GRUB_INSTALL_PLATFORM_I386_QEMU: +@@ -990,6 +1004,7 @@ + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: ++ case GRUB_INSTALL_PLATFORM_S390X_EMU: + free (install_device); + install_device = NULL; + break; +@@ -1291,6 +1306,20 @@ + } + } + ++ if (platform == GRUB_INSTALL_PLATFORM_S390X_EMU) ++ { ++ if (!zipldir) ++ { ++ char *d = grub_util_path_concat (2, bootdir, "zipl"); ++ if (!grub_util_is_directory (d)) ++ { ++ free (d); ++ grub_util_error ("%s", _("cannot find zIPL directory")); ++ } ++ zipldir = d; ++ } ++ } ++ + size_t ndev = 0; + + /* Write device to a variable so we don't have to traverse /dev every time. */ +@@ -1543,6 +1572,7 @@ + case GRUB_INSTALL_PLATFORM_I386_XEN: + case GRUB_INSTALL_PLATFORM_X86_64_XEN: + case GRUB_INSTALL_PLATFORM_I386_XEN_PVH: ++ case GRUB_INSTALL_PLATFORM_S390X_EMU: + grub_util_warn ("%s", _("no hints available for your platform. Expect reduced performance")); + break; + /* pacify warning. */ +@@ -1661,6 +1691,10 @@ + strcpy (mkimage_target, "sparc64-ieee1275-raw"); + core_name = "core.img"; + break; ++ case GRUB_INSTALL_PLATFORM_S390X_EMU: ++ strcpy (mkimage_target, "grub2-emu"); ++ core_name = mkimage_target; ++ break; + /* pacify warning. */ + case GRUB_INSTALL_PLATFORM_MAX: + break; +@@ -1676,6 +1710,7 @@ + core_name); + char *prefix = xasprintf ("%s%s", prefix_drive ? : "", + relative_grubdir); ++ if (core_name != mkimage_target) + grub_install_make_image_wrap (/* source dir */ grub_install_source_directory, + /*prefix */ prefix, + /* output */ imgfile, +@@ -1714,6 +1749,10 @@ + /* image target */ mkimage_target, 0); + } + break; ++ ++ case GRUB_INSTALL_PLATFORM_S390X_EMU: ++ break; ++ + case GRUB_INSTALL_PLATFORM_ARM_EFI: + case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: +@@ -2013,6 +2052,10 @@ + } + break; + ++ case GRUB_INSTALL_PLATFORM_S390X_EMU: ++ grub_install_zipl (zipldir, install_bootsector, force); ++ break; ++ + case GRUB_INSTALL_PLATFORM_MIPSEL_LOONGSON: + case GRUB_INSTALL_PLATFORM_MIPSEL_QEMU_MIPS: + case GRUB_INSTALL_PLATFORM_MIPS_QEMU_MIPS: +--- /dev/null ++++ b/util/s390x/dracut-grub2.sh.in +@@ -0,0 +1,141 @@ ++#!/bin/sh ++# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- ++# ex: ts=8 sw=4 sts=4 et filetype=sh ++#getargbool() { true; } ++ ++if getargbool 0 initgrub && [ ! -e /grub2skip ] || [ -e /grub2force ]; then ++ #type getarg >/dev/null 2>&1 || . /lib/dracut-lib.sh ++ checkro() { ++ local tgt="$1" ++ local dev mp fs opts dc ++ local rofs=true ++ while read dev mp fs opts dc; do ++ [ "$mp" = "$tgt" ] || continue ++ case ",$opts," in ++ (*,ro,*) rofs=true;; ++ (*) rofs=false;; ++ esac ++ done < /proc/mounts ++ echo $rofs ++ } ++ checkd() { ++ [ -d $1 ] && echo true || echo false ++ } ++ checke() { ++ [ -e $1 ] && echo true || echo false ++ } ++ checksubvol() { ++ local tgt="$1" ++ local tst="$2" ++ if [ -n "$tst" -a -e "/sysroot$tgt/$tst" ]; then ++ echo true ++ elif grep -qP '^[^#\s]+\s+'"$tgt"'\s+' /sysroot/etc/fstab; then ++ echo false ++ else ++ echo true ++ fi ++ } ++ checksnap() { ++ # checksubvol /.snapshots grub-snapshot.cfg ++ if [ -e /sysroot/.snapshots/grub-snapshot.cfg ]; then ++ echo true ++ elif grep -qP '^[^#\s]+\s+/.snapshots\s+' /sysroot/etc/fstab; then ++ echo false ++ else ++ echo true ++ fi ++ } ++ checkboot() { ++ [ -d /boot/grub2 ] && echo false || echo true ++ } ++ getterm() { ++ local term="$(getarg TERM)" ++ [ -z "$term" ] && term=dumb ++ echo $term ++ } ++ debug() { ++ if [ -n "$1" ]; then ++ echo "$1" >> /dev/.grub2.debug ++ fi ++ shift; ++ [ -n "$*" ] || return 0 ++ echo "+ $*" >> /dev/.grub2.debug ++ "$@" >> /dev/.grub2.debug ++ } ++ ++ exec_prefix=@exec_prefix@ ++ bindir=@bindir@ ++ if [ -e /sysroot$bindir/grub2-emu ]; then ++ ++ export TERM=$(getterm) ++ export grub2rofs=$(checkro /sysroot) ++ export grub2roufs=$(checkro /sysroot/usr) ++ export grub2sysfs=$(checkd /sysroot/sys/devices/system/memory) ++ export grub2procfs=$(checkd /sysroot/proc/self) ++ export grub2bootfs=$(checkboot) ++ export grub2bootw=$(checksubvol /boot/writable) ++ export grub2devfs=$(checkd /sysroot/dev/disk) ++ export grub2snap=$(checksnap) ++ debug "" export -p ++ ++ _ctty="$(RD_DEBUG= getarg rd.ctty=)" && _ctty="/dev/${_ctty##*/}" ++ if [ -z "$_ctty" ]; then ++ _ctty=$(showconsole) ++ fi ++ if [ -z "$_ctty" ]; then ++ _ctty=console ++ while [ -f /sys/class/tty/$_ctty/active ]; do ++ _ctty=$(cat /sys/class/tty/$_ctty/active) ++ _ctty=${_ctty##* } # last one in the list ++ done ++ _ctty=/dev/$_ctty ++ fi ++ [ -c "$_ctty" ] || _ctty=/dev/console ++ case "$(/usr/bin/setsid --help 2>&1)" in *--ctty*) CTTY="--ctty";; esac ++ ++ CTTY="$CTTY --wait" ++ $grub2rofs || mount -o remount,ro /sysroot ++ $grub2roufs || mount -o remount,ro /sysroot/usr ++ $grub2sysfs || mount --bind {,/sysroot}/sys ++ $grub2procfs || mount --bind {,/sysroot}/proc ++ $grub2bootfs || mount --bind {,/sysroot}/boot ++ $grub2devfs || mount --bind {,/sysroot}/dev ++ $grub2snap || chroot /sysroot mount -rn /.snapshots ++ $grub2bootw || chroot /sysroot mount -rn /boot/writable ++ debug "" cat /proc/mounts ++ ++ debug "Trying grub2-emu (ro=$grub2rofs, TERM=$TERM, ctty=$_ctty)..." ++ setsid $CTTY -- chroot /sysroot $bindir/grub2-emu -X -X 0<>$_ctty 1>&0 2>&0 ++ ++ if [ -x /sysroot@libdir@/grub2/zipl-refresh ]; then ++ setsid $CTTY -- /sysroot@libdir@/grub2/zipl-refresh 0<>$_ctty 1>&0 2>&0 ++ if [ $? != 0 ]; then ++ warn "Not continuing" ++ emergency_shell -n grub2-emu-zipl-refresh ++ else ++ echo "+ reboot" >& $_ctty ++ sleep 3 ++ reboot ++ fi ++ else ++ echo " ++ Attention: 'grub2' failed to start the target kernel and 'zipl-refresh' ++ is not available. This should never happen. Please contact support." >& $_ctty ++ warn "Not continuing" ++ emergency_shell -n grub2-emu-kexec ++ fi ++ ++ $grub2snap || umount /sysroot/.snapshots ++ $grub2devfs || umount /sysroot/dev ++ $grub2bootw || umount /sysroot/boot/writable ++ $grub2bootfs || umount /sysroot/boot ++ $grub2procfs || umount /sysroot/proc ++ $grub2sysfs || umount /sysroot/sys ++ $grub2roufs || mount -o remount,rw /sysroot/usr ++ $grub2rofs || mount -o remount,rw /sysroot ++ else ++ warn "No $bindir/grub2-emu in /sysroot--dropping to emergency shell..." ++ emergency_shell -n no-grub2-emu ++ fi ++fi ++ +--- /dev/null ++++ b/util/s390x/dracut-module-setup.sh.in +@@ -0,0 +1,19 @@ ++#!/bin/bash ++# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- ++# ex: ts=8 sw=4 sts=4 et filetype=sh ++ ++# called by dracut ++check() { ++ local _arch=$(uname -m) ++ [ "$_arch" = "s390" -o "$_arch" = "s390x" ] || return 1 ++ return 0 ++} ++ ++# called by dracut ++install() { ++ inst_hook cleanup 99 "$moddir/grub2.sh" ++ inst_multiple showconsole ++ inst_multiple mount umount chroot cat grep /usr/bin/setsid ++ #inst_multiple grub2-emu kexec ++} ++ +--- /dev/null ++++ b/util/s390x/zipl2grub.conf.in +@@ -0,0 +1,26 @@ ++## This is the template for '@zipldir@/config' and is subject to ++## rpm's %config file handling in case of grub2-s390x-emu package update. ++ ++[defaultboot] ++defaultmenu = menu ++ ++[grub2] ++ target = @zipldir@ ++ ramdisk = @zipldir@/initrd,0x2000000 ++ image = @zipldir@/image ++ parameters = "root=@GRUB_DEVICE@ @GRUB_EMU_CONMODE@ @GRUB_CMDLINE_LINUX@ @GRUB_CMDLINE_LINUX_DEFAULT@ initgrub quiet splash=silent plymouth.enable=0 " ++ ++[skip-grub2] ++ target = @zipldir@ ++ ramdisk = @zipldir@/initrd,0x2000000 ++ image = @zipldir@/image ++ parameters = "root=@GRUB_DEVICE@ @GRUB_CONMODE@ @GRUB_CMDLINE_LINUX@ @GRUB_CMDLINE_LINUX_DEFAULT@ " ++ ++:menu ++ target = @zipldir@ ++ timeout = 16 ++ default = 1 ++ prompt = 0 ++ 1 = grub2 ++ 2 = skip-grub2 ++ +--- /dev/null ++++ b/util/s390x/zipl2grub.pl.in +@@ -0,0 +1,423 @@ ++#!/usr/bin/perl ++use strict; ++ ++my $C = $0; $C =~ s{^.*/}{}; ++ ++my $in = '@sysconfdir@/default/zipl2grub.conf.in'; ++my $default = '@sysconfdir@/default/grub'; ++my $fallback = '@sysconfdir@/zipl.conf'; ++my $sysconfbl = '@sysconfdir@/sysconfig/bootloader'; ++my $zipldir = ""; ++my $running = ""; ++my $refresh = 1; # needs to default to "on" until most bugs are shaken out! ++my $force = 0; ++my $verbose = 0; ++my $debug = 0; ++my $miss = 0; ++my $cfg = ""; ++my %fsdev = (); ++my %fstype = (); ++ ++my %C = ( ++ GRUB_CMDLINE_LINUX_DEFAULT => "quiet splash=silent", ++ GRUB_DISABLE_LINUX_UUID => "false", ++); ++ ++my %Mandatory = ( ++ GRUB_CMDLINE_LINUX_DEFAULT => 1, ++ GRUB_DEVICE => 1, ++); ++ ++sub Panic($$) { ++ printf( STDERR "%s", $_[1]); ++ exit( $_[0]); ++} ++sub Info($$) { ++ printf( STDERR "%s", $_[1]) if ($_[0] <= $verbose); ++} ++sub System(@) { ++ my (@C) =@_; ++ Info( 1, "+ " . join( " ", @C) . "\n"); ++ return 0 if ($debug); ++ system( @C); ++ if ($? == -1) { ++ Panic( $?, "$C[0]: Failed to execute: $!\n"); ++ } elsif ($? & 127) { ++ Panic( $?, sprintf( "$C[0]: Died with signal %d with%s coredump\n", ++ ($? & 127), ($? & 128) ? '' : 'out')); ++ } elsif ( $? >> 8 != 0 ) { ++ Panic( $?, "$C[0]: Failed\n"); ++ } ++ return( 0); ++} ++sub cp($$) { ++ my @C = ( "cp", "-p", $_[0], $_[1]); ++ System( @C); ++} ++sub rm($) { ++ return( 0) unless ( -l $_[0] || -e $_[0]); ++ Info( 2, "+ rm $_[0]\n"); ++ return 0 if ($debug); ++ unlink( $_[0]) || Panic( 1, "$C: unlink: $!.\n"); ++} ++sub mv($$) { ++ Info( 1, "+ mv $_[0] $_[1]\n"); ++ return 0 if ($debug); ++ rename($_[0], $_[1]) || Panic( 1, "$C: rename: $!.\n"); ++} ++sub ln($$) { ++ Info( 1, "+ ln -sf $_[0] $_[1]\n"); ++ return 0 if ($debug); ++ unlink( $_[1]) || Panic( 1, "$C: unlink: $!.\n") if ( -e $_[1]); ++ symlink($_[0], $_[1]) || Panic( 1, "$C: symlink: $!.\n"); ++} ++sub BootCopy($$$) { ++ my( $file, $dir, $tgt) = @_; ++ my $curr = "$dir/$tgt"; ++ my $prev = "$dir/$tgt.prev"; ++ Info(4, "Copy /boot/$file $dir $tgt\n"); ++ if ( -l $curr ) { ++ my $curf = readlink( $curr); ++ if ( $curf ne $file ) { ++ if ( -l $prev ) { ++ my $pref = readlink( $prev); ++ $pref = "$dir/$pref" unless ($pref =~ m{^/}); ++ rm( $pref); ++ } ++ mv( $curr, $prev); ++ } ++ } ++ cp( "/boot/$file", "$dir/$file"); ++ ln( $file, $curr); ++} ++sub MkInitrd($$$) { ++ my( $initrd, $dir, $version) = @_; ++ my @C = ( "dracut", "--hostonly", "--force"); ++ my $uuid; ++ if ( exists( $fsdev{"/boot"}) ) { ++ chomp( $uuid = qx{grub2-probe --target=fs_uuid /boot}); ++ my ($dev, $type) = ($fsdev{"/boot"}, $fstype{"/boot"}); ++ if ( $type eq "auto" ) { ++ chomp( $type = qx{grub2-probe --target=fs /boot}); ++ } ++ if ($C{GRUB_DISABLE_LINUX_UUID} eq "true" && ++ $dev =~ m{^(UUID=|/dev/disk/by-uuid/)}) { ++ chomp( $dev = qx{grub2-probe --target=device /boot}); ++ } ++ push @C, "--mount", "$dev /boot $type ro"; ++ } ++ push @C, "$dir/$initrd", $version; ++ System( @C); ++ ln( $initrd, "$dir/initrd"); ++} ++sub ChkInitrd($$) { ++ my( $dir, $initrd) = @_; ++ my $found = -1; ++ my $d = $dir; ++ my $pattern = qr{lib/dracut/hooks/cleanup/99-grub2.sh}; ++ my $show = "cleanup/99-grub2.sh"; ++ my $cat = undef; ++ my $magic; ++ ++ return $found unless (-r "$dir/$initrd"); ++ open( IN, "< $dir/$initrd") || return $found; ++ my $rd = sysread( IN, $magic, 6); ++ close( IN); ++ return $found unless (defined( $rd) && $rd == 6); ++ $cat = "xzcat" if ($magic eq "\xFD7zXZ\x00"); ++ $cat = "zcat" if (substr($magic, 0, 2) eq "\037\213"); ++ $cat = "cat" if (substr($magic, 0, 5) eq "07070"); ++ return $found unless (defined($cat)); ++ ++ my $modinst = "/usr/lib/dracut/modules.d/99grub2/module-setup.sh"; ++ if ( -r $modinst ) { ++ my( $hook, $ord, $script); ++ my $pat = qr{^\s*inst_hook\s+(\S+)\s+([0-9]+)\s+\"\$moddir/(grub2\.sh)\"}; ++ open( IN, "< $modinst") || die; ++ while ( ) { ++ next unless ($_ =~ $pat); ++ $show = "$1/$2-$3"; ++ $pattern = qr{lib/dracut/hooks/$show}o; ++ last; ++ } ++ close( IN); ++ } ++ ++ $found = 0; ++ Info( 3, "+ $cat $d/$initrd | cpio -it | grep '$show'\n"); ++ open( IN, "$cat $d/$initrd | cpio -it 2>/dev/null |") || ++ Panic( 1, "$C: cpio: $!.\n"); ++ while ( ) { ++ $found = 1 if ($_ =~ $pattern); ++ } ++ close( IN); ++ return $found; ++} ++ ++sub Usage($) { ++ my @cat = ("", ++ "Parameter error.", ++ "zIPL directory missing.", ++ "Configuration template missing.", ++ "Configuration template unreadable.", ++ "zIPL directory not accesible.", ++ "" ++ ); ++ my $msg = ""; ++ ++ $msg .= sprintf( "%s: %s\n", $C, $cat[$_[0]]) if ($_[0] > 0); ++ $msg .= "Usage: $C [-v] [-d] [-f] [-T template] [-z ZIPLDIR]\n"; ++ Panic( $_[0], $msg . "\n"); ++} ++ ++while ( $#ARGV >= 0 ) { ++ $_ = shift; ++ next if /^$/; ++ last if /^--$/; ++ (/^--verbose$/ || /^-v$/) && ($verbose++, next); ++ (/^--quiet$/ || /^-q$/) && ($verbose = 0, next); ++ (/^--debug$/ || /^-d$/) && ($debug = 1, $verbose++, next); ++ (/^--force$/ || /^-f$/) && ($force = $refresh = 1, next); ++ (/^--refresh$/ || /^-r$/) && ($refresh = 1, next); ++ (/^--keep$/ || /^-k$/) && ($refresh = 0, next); ++ (/^--?help/ || /^-h/) && (Usage(0)); ++ (/^--zipldir$/ || /^-z$/) && ($zipldir = shift || Usage(2), next); ++ (/^--template$/ || /^-T$/) && ($in = shift || Usage(3), next); ++ (/^-/) && (Usage(1)); ++ Usage(1); ++} ++Usage(4) if (! -r $in); ++ ++if ($zipldir) { ++ $C{zipldir} = $zipldir; # command-line wins ++} elsif ( exists( $C{zipldir}) ) { ++ $zipldir = $C{zipldir}; # otherwise fall back to config ++} else { ++ $zipldir = $C{zipldir} = "/boot/zipl"; # but don't proceed without... ++} ++Usage(5) if (! -d $zipldir); ++if ( $zipldir eq "/boot" ) { ++ Panic( 5, "$C: zIPL directory '/boot' not supported!\n"); ++} ++ ++if ( ! -r $default && ! -r $fallback && ! -r $sysconfbl ) { ++ Panic( 0, "$C: No configuration files found. Retry later!\n"); ++} ++if ( -r $default ) { ++ open( IN, "< $default") || die; ++ while ( ) { ++ chomp; ++ s{^\s*#.*$}{}; ++ next if m{^\s*$}; ++ s{x}{\x01xx\x01}g; ++ s{\\\"}{\x01x1\x01}g; ++ s{\\\'}{\x01x2\x01}g; ++ Info( 5, "<$_>\n"); ++ if ( m{^([^\s=]+)='([^']*)'\s*(?:#.*)?$} || ++ m{^([^\s=]+)="([^"]*)"\s*(?:#.*)?$} || ++ m{^([^\s=]+)=(\S*)\s*(?:#.*)?$} ) { ++ my ( $k, $v) = ($1, $2); ++ $v =~ s{\x01x2\x01}{\\'}g; ++ $v =~ s{\x01x1\x01}{\\"}g; ++ $v =~ s{\x01xx\x01}{x}g; ++ $C{$k} = $v; ++ next; ++ } ++ print( STDERR "$default:$.: parse error ignored.\n"); ++ } ++ close( IN); ++} ++if ( -r "/etc/fstab" ) { ++ my $regex = qr{^(\S+)\s+(\S+)\s+(\S+)\s+\S+\s+\S+\s+\S+\s*(?:#.*)?$}; ++ open( IN, "< /etc/fstab") || die; ++ while ( ) { ++ next if ( m{^\s*#} ); ++ my ($dev, $mp, $type) = (m{$regex}o); ++ $fsdev{$mp} = $dev; ++ $fstype{$mp} = $type; ++ } ++ close( IN); ++} ++ ++if ( ! exists( $C{GRUB_DEVICE}) && ++ $C{GRUB_CMDLINE_LINUX_DEFAULT} eq "quiet splash=silent" && ++ -r $fallback ) { ++ # configuration incomplete, let's try fallback ++ open( IN, "< $fallback") || die; ++ my $section = ""; ++ while( ){ ++ if ( m{^\[([^\]]+)\]\s*$} ) { ++ $section = $1; ++ } ++ if ( $section eq "ipl" && ++ m{^\s*parameters\s*=\s*\"root=(\S+)(?:\s*|\s+([^\"]+))\"} ) { ++ $C{GRUB_DEVICE} = $1; ++ $C{GRUB_CMDLINE_LINUX_DEFAULT} = $2 if (defined($2) && $2 !~ m{^\s*$}); ++ last; ++ } ++ } ++ close( IN); ++ $default = $fallback; ++} ++ ++if ( ! exists( $C{GRUB_DEVICE}) && exists( $fsdev{"/"}) ) { ++ my( $dev, $type, $subvol) = ( $fsdev{"/"}, $fstype{"/"}, ""); ++ if ( $dev !~ m{^(UUID=|/dev/disk/by-uuid/)} || ++ $C{GRUB_DISABLE_LINUX_UUID} ne "true" ) { ++ $C{GRUB_DEVICE} = $dev; ++ # grub2-mkrelpath fails on rollback -- and provides no known merit... ++ #chomp( $subvol = qx{grub2-mkrelpath /}) if ( $type eq "btrfs" ); ++ #$subvol =~ s{^/}{}; ++ #$C{GRUB_DEVICE} .= " rootflags=subvol=$subvol" if ($subvol); ++ } ++} ++if ( ! exists( $C{GRUB_DEVICE}) ) { ++ my( $dev, $uuid, $type, $subvol) = ("", "", "", ""); ++ chomp( $dev = qx{grub2-probe --target=device /}); ++ chomp( $uuid = qx{grub2-probe --device $dev --target=fs_uuid}); ++ if ( $dev ) { ++ if ( $uuid && $C{GRUB_DISABLE_LINUX_UUID} ne "true" ) { ++ $C{GRUB_DEVICE} = "UUID=$uuid"; ++ } else { ++ $C{GRUB_DEVICE} = "$dev"; ++ } ++ chomp( $type = qx{stat -f --printf='%T' /}); ++ # grub2-mkrelpath fails on rollback -- and provides no known merit... ++ #chomp( $subvol = qx{grub2-mkrelpath /}) if ( $type eq "btrfs" ); ++ #$subvol =~ s{^/}{}; ++ #$C{GRUB_DEVICE} .= " rootflags=subvol=$subvol" if ($subvol); ++ } ++} ++if ( $C{GRUB_CMDLINE_LINUX_DEFAULT} eq "quiet splash=silent" && ++ -r $sysconfbl) { ++ open( IN, "< $sysconfbl") || die; ++ while ( ) { ++ next if ( m{^\s*#} ); ++ if ( m{^DEFAULT_APPEND=".*"(?:\s*|\s+#.*)$} ) { ++ $C{GRUB_CMDLINE_LINUX_DEFAULT} = $1; ++ } ++ } ++ close( IN); ++} ++ ++if ( ! exists( $C{GRUB_DEVICE})) { ++ Panic( 0, "$C: Default not ready and no fallback. Please retry later!\n"); ++} ++ ++if ( ! exists( $C{GRUB_EMU_CONMODE}) && exists( $C{GRUB_CONMODE}) ) { ++ # GRUB_CONMODE is used for 'grub2-emu' as well ++ $C{GRUB_EMU_CONMODE} = $C{GRUB_CONMODE}; ++} ++if ( exists( $C{GRUB_EMU_CONMODE}) && !exists( $C{GRUB_CONMODE}) ) { ++ # pick up 'conmode=' from CMDLINE ++ my $found = ""; ++ foreach ( "GRUB_CMDLINE_LINUX", "GRUB_CMDLINE_LINUX_DEFAULT" ) { ++ next unless ($C{$_} =~ m{ ?conmode=(\S+) ?}); ++ $C{GRUB_CONMODE} = $1; ++ last; ++ } ++ if ( !exists( $C{GRUB_CONMODE}) && $C{GRUB_EMU_CONMODE} eq "3270" ) { ++ # force GRUB_CONMODE to 3215 for least surprise ++ $C{GRUB_CONMODE}="3215"; ++ } ++} ++if ( exists( $C{GRUB_EMU_CONMODE}) && exists( $C{GRUB_CONMODE})) { ++ # strip "conmode=" from GRUB_CMDLINE{,_LINUX}_DEFAULT ++ foreach ( "GRUB_CMDLINE_LINUX", "GRUB_CMDLINE_LINUX_DEFAULT" ) { ++ $C{$_} =~ s{( ?)conmode=\S+ ?}{$1}g; ++ } ++} ++foreach ("GRUB_EMU_CONMODE", "GRUB_CONMODE") { ++ next unless( exists( $C{$_}) ); ++ $C{$_} = "conmode=" . $C{$_}; ++} ++ ++if ( $debug && $verbose > 2 ) { ++ foreach ( sort( keys( %C)) ) { ++ printf( "%s=\"%s\"\n", $_, $C{$_}); ++ } ++} ++ ++open( IN, "< $in") || ++ Panic( 1, "$C: Failed to open 'zipl.conf' template: $!.\n"); ++while ( ) { ++ Info( 3, "$.. <$_$.. >"); ++ if ( $. == 1 && m{^## This} ) { ++ $_ = "## This file was written by 'grub2-install/$C'\n" . ++ "## filling '$in' as template\n"; ++ } elsif ( $. == 2 && m{^## rpm's} ) { ++ $_ = "## with values from '$default'.\n" . ++ "## In-place modifications will eventually go missing!\n"; ++ } ++ while ( m{\@([^\@\s]+)\@} ) { ++ my $k = $1; ++ my $v; ++ if ( exists( $C{$k}) ) { ++ $v = $C{$k}; ++ } elsif ( exists( $Mandatory{$k}) ) { ++ $v = "$k"; ++ $miss++; ++ } else { ++ $v = ""; ++ } ++ s{\@$k\@}{$v}g; ++ } ++ Info( 2, $_); ++ $cfg .= $_; ++} ++if ( $miss ) { ++ Info( 1, "Partially filled config:\n===\n$cfg===\n"); ++ Panic( 1, "$C: 'zipl.conf' template could not be filled. \n"); ++} ++ ++my $ziplconf = "$zipldir/config"; ++if ( ! $debug ) { ++ open( OUT, "> $ziplconf") || die; ++ print( OUT $cfg) || die; ++ close( OUT); ++} ++ ++# copy out kernel and initrd ++my $defimage = "/boot/image"; ++my $definitrd = "/boot/initrd"; ++my $ziplimage = "$zipldir/image"; ++my $ziplinitrd = "$zipldir/initrd"; ++my $Image = "$defimage"; ++ ++if ( ! $running && ! $force ) { ++ chomp( $running = qx{uname -r}); ++ Info( 1, "preferred kernel: '$running'\n"); ++ $Image .= "-$running"; ++} ++if ( ! -r $Image ) { ++ $Image = $defimage; ++} ++Panic( 1, "$C: kernel '$Image' not readable!?\n") unless (-r $Image); ++ ++if ( -l $Image ) { ++ $Image = readlink( $Image); ++} ++my ($image, $version) = ($Image =~ m{^(?:/boot/)?([^-]+-(.+))$}); ++my $initrd = "initrd-$version"; ++ ++if ( !defined($image) || !defined($version) || ! -r "/boot/$image" ) { ++ Panic( 1, "$C: weird $Image. This should never happen!\n"); ++} ++ ++if ( ! -r $ziplimage || ! -r $ziplinitrd || $refresh ) { ++ BootCopy( $image, $zipldir, "image"); ++ BootCopy( $initrd, $zipldir, "initrd") if (-r "/boot/$initrd"); ++} ++if ( $refresh || ChkInitrd( $zipldir, "initrd") <= 0 ) { ++ MkInitrd( $initrd, $zipldir, $version); ++} ++if ( ChkInitrd( $zipldir, "initrd") == 0 ) { ++ Info( 0, "$C: dracut does not work as expected! Help needed!\n"); ++ $miss++; ++} ++ ++# now: go for it! ++my @C = ( "/sbin/zipl", (($verbose) ? "-Vnc" : "-nc"), "$ziplconf" ); ++System( @C); ++exit( $miss); ++ +--- /dev/null ++++ b/util/s390x/dracut-zipl-refresh.sh.in +@@ -0,0 +1,183 @@ ++#!/bin/bash ++# ex: ts=8 sw=4 sts=4 et filetype=sh syntax=off ++ ++debug=false ++TIMEOUT=300 ++[ -n "$SYSROOT" ] || ++SYSROOT=/sysroot ++[ -d $SYSROOT/boot ] || SYSROOT= ++ ++sync() { $SYSROOT/usr/bin/sync "$@"; } ++readlink() { $SYSROOT/usr/bin/readlink "$@"; } ++newline() { echo ""; } ++verbose() { ++ local a ++ local m ++ [ -n "$*" ] || return 0 ++ m="+" ++ for a in "$@"; do ++ case "$a" in ++ (*" "*|*" "*|"") m="$m '$a'";; ++ (*) m="$m $a";; ++ esac ++ done ++ echo "$m" ++ [ -n "$SYSROOT" -o "$1" = "chroot" ] || return 0 ++ "$@" ++} ++ ++SYSK="$(readlink $SYSROOT/boot/image)" ++SYSK="${SYSK#image-}" ++ZIPK="$(readlink $SYSROOT/boot/zipl/image)" ++ZIPK="${ZIPK#image-}" ++PRVK="$(readlink $SYSROOT/boot/zipl/image.prev 2> /dev/null)" ++PRVK="${PRVK#image-}" ++RUNK="$(uname -r)" ++# if /boot/zipl is not accessible ZIPK will be empty, assume running kernel ++[ -n "$ZIPK" ] || ZIPK="$RUNK" ++ ++[ -n "$SYSROOT" ] || { ++ echo "$0 is not intended for interactive use!" ++ $debug || ++ exit 0 ++ ## test: ++ TIMEOUT=6 ++ RUNK=110; ZIPK=110; PRVK=101; SYSK=194 ++ ##RUNK=$PRVK; ZIPK=$SYSK # previous booted, newest is default ++ ##t=$ZIPK; ZIPK=$PRVK; PRVK=$t; SYSK=$PRVK # unknown booted ++ ##ZIPK=$SYSK; PRVK="" # no update ++ ##ZIPK=$SYSK # try previous ++ echo "R=$RUNK S=$SYSK Z=$ZIPK P=$PRVK" ++ #verbose echo "a b" z ++ #verbose echo "^h ^j" ^z ++} ++ ++trap newline EXIT ++ ++echo -n " ++ Attention: 'grub2' failed to start the target kernel" ++ ++if [ "$ZIPK" != "$RUNK" -a "$RUNK" != "$SYSK" ]; then ++ # i.e. "previous" has been selected via zipl, but it fails!? ++ [ "$RUNK" = "$PRVK" ] && ++ echo " from previous" || ++ echo " from unknown" ++ ++ echo " ZIPL kernel ($RUNK). If default ($ZIPK) ++ fails as well, please contact support." ++ exit 1 ++fi ++echo "." ++if [ "$ZIPK" = "$SYSK" ]; then ++ [ -z "$PRVK" ] && ++ echo " ++ No kernel update readily available/installed. Please contact support." || ++ echo " ++ You may want to try the previous kernel ($PRVK) with ++ 'IPL ... LOADPARM 4', as no update kernel is readily available/installed." ++ exit 1 ++fi ++ ++echo " ++ A newer kernel ($SYSK) is available and will be deployed ++ in $TIMEOUT seconds. To facilitate this, the affected file-systems have ++ to be made writable, then 'grub2-install --force' needs to be run, ++ and, on success, a 'reboot' will be initiated. ++ ++ Press 'c[Enter]' to interrupt, any other input will proceed... " ++ ++trap interrupted=1 INT ++interrupted=0 ++input="" ++read -t $TIMEOUT input ++case "$input" in ++ ([Cc]) interrupted=2 ;; ++esac ++if [ $interrupted != 0 ]; then ++ echo " ++ Automatic update cancelled..." ++ exit 1 ++fi ++trap - INT ++echo " ++ Attempting automatic update..." ++ ++ismounted() { ++ local mode="$1" ++ local tgt="$2" ++ local dev mp fs opts dc ++ while read dev mp fs opts dc; do ++ [ "$mp" = "$tgt" ] || continue ++ case ",$opts," in ++ (*,$mode,*) return 0;; ++ esac ++ done < /proc/mounts ++ return 1 ++} ++ismp() { ++ local sysr="$1" ++ local tgt="$2" ++ local dev mp fs opts dc ++ while read dev mp fs opts dc; do ++ case "$dev" in ++ ("#"*) continue;; ++ esac ++ [ "$mp" = "$tgt" ] || continue ++ return 0 ++ done < $sysr/etc/fstab ++ return 1 ++} ++chroot() { ++ local tgt="$1"; shift ++ if [ -z "$tgt" ]; then ++ echo -n "+" ++ verbose "$@" ++ else ++ /usr/bin/chroot "$tgt" "$@" ++ fi ++} ++cleanup() { ++ local mp ++ echo " # cleanup" ++ for mp in $UMOUNT; do ++ verbose chroot "$SYSROOT" umount $mp ++ done ++ for mp in $WMOUNT; do ++ verbose mount -o remount,ro $mp ++ done ++ sync; sync ++ [ -z "$EXIT" ] || echo "$EXIT" ++ echo "" ++} ++trap cleanup EXIT ++UMOUNT="" ++WMOUNT="" ++EXIT="" ++ ++echo " # prepare" ++# remount $SYSROOT{,/boot{,/zipl}} read-write ++for mp in {"",/boot{,/zipl}}; do ++ [ -n "$SYSROOT$mp" ] || continue ++ if ismounted rw $SYSROOT$mp; then ++ echo " # $mp: already read-write: ignore" ++ elif ismounted ro $SYSROOT$mp; then ++ verbose mount -o remount,rw $SYSROOT$mp ++ WMOUNT="$SYSROOT$mp $WMOUNT" ++ elif ismp "$SYSROOT" $mp; then ++ verbose chroot "$SYSROOT" mount -w $mp || exit 1 ++ UMOUNT="$mp $UMOUNT" ++ fi ++done ++if [ ! -w $SYSROOT/boot/zipl/config ]; then ++ EXIT="ERROR: $SYSROOT/boot/zipl/config not writable! Aborting..." ++ exit 1 ++fi ++echo " # action" ++verbose chroot "$SYSROOT" grub2-zipl-setup --force ++ret=$? ++if [ $ret != 0 ]; then ++ EXIT=" # failed ($ret)" ++else ++ EXIT=" # done" ++fi ++exit $ret diff --git a/grub2-s390x-05-grub2-mkconfig.patch b/grub2-s390x-05-grub2-mkconfig.patch new file mode 100644 index 0000000000000000000000000000000000000000..ccbe1bf840283943679fbe6b25ee844fdb0665ff --- /dev/null +++ b/grub2-s390x-05-grub2-mkconfig.patch @@ -0,0 +1,145 @@ +From: Raymund Will +Subject: Enable grub2-mkconfig for s390x-emu +References: fate#314213, bnc#868909 +Patch-Mainline: no + +V2: + * omit subvolume-prefix for platform "emu" +V3: + * add 'conmode=' to command-line if GRUB_CONMODE exists. [bnc#868909] +V4: + * remove 's' from possible hot-keys for "bootable snapshots". [bnc#885668] + +--- + util/grub.d/10_linux.in | 63 ++++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 51 insertions(+), 12 deletions(-) + +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -65,6 +65,10 @@ + LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID} + fi + ++if [ "x$GRUB_CONMODE" != "x" ]; then ++ GRUB_CMDLINE_LINUX="conmode=${GRUB_CONMODE} ${GRUB_CMDLINE_LINUX}" ++fi ++ + case x"$GRUB_FS" in + xbtrfs) + rootsubvol="`make_system_path_relative_to_its_root /`" +@@ -81,6 +85,21 @@ + + title_correction_code= + ++hotkey=1 ++incr_hotkey() ++{ ++ [ -z "$hotkey" ] && return ++ expr $hotkey + 1 ++} ++print_hotkey() ++{ ++ keys="123456789abdfgijklmnoprtuvwyz" ++ if [ -z "$hotkey" ]||[ $hotkey -eq 0 ]||[ $hotkey -gt 30 ]; then ++ return ++ fi ++ echo "--hotkey=$(expr substr $keys $hotkey 1)" ++} ++ + linux_entry () + { + os="$1" +@@ -110,9 +129,11 @@ + title_correction_code="${title_correction_code}if [ \"x\$default\" = '$quoted' ]; then default='$(echo "$replacement_title" | grub_quote)'; fi;" + grub_warn "$(gettext_printf "Please don't use old title \`%s' for GRUB_DEFAULT, use \`%s' (for versions before 2.00) or \`%s' (for 2.00 or later)" "$GRUB_ACTUAL_DEFAULT" "$replacement_title" "gnulinux-advanced-$boot_device_id>gnulinux-$version-$type-$boot_device_id")" + fi +- echo "menuentry '$(echo "$title" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" ++ echo "menuentry '$(echo "$title" | grub_quote)' $(print_hotkey) ${CLASS} \$menuentry_id_option 'gnulinux-$version-$type-$boot_device_id' {" | sed "s/^/$submenu_indentation/" ++ hotkey=$(incr_hotkey) + else +- echo "menuentry '$(echo "$os" | grub_quote)' ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/" ++ echo "menuentry '$(echo "$os" | grub_quote)' $(print_hotkey) ${CLASS} \$menuentry_id_option 'gnulinux-simple-$boot_device_id' {" | sed "s/^/$submenu_indentation/" ++ hotkey=$(incr_hotkey) + fi + if [ x$type != xrecovery ] ; then + save_default_entry | grub_add_tab +@@ -135,6 +156,7 @@ + + echo " insmod gzio" | sed "s/^/$submenu_indentation/" + ++ if [ $PLATFORM != emu ]; then # 'search' does not work for now + if [ x$dirname = x/ ]; then + if [ -z "${prepare_root_cache}" ]; then + prepare_root_cache="$(prepare_grub_to_access_device ${GRUB_DEVICE} | grub_add_tab)" +@@ -146,6 +168,7 @@ + fi + printf '%s\n' "${prepare_boot_cache}" | sed "s/^/$submenu_indentation/" + fi ++ fi + message="$(gettext_printf "Loading Linux %s ..." ${version})" + sed "s/^/$submenu_indentation/" << EOF + echo '$(echo "$message" | grub_quote)' +@@ -170,17 +193,15 @@ + + machine=`uname -m` + case "x$machine" in +- xi?86 | xx86_64) +- list= +- for i in /boot/vmlinuz-* /vmlinuz-* /boot/kernel-* ; do +- if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi +- done ;; +- *) +- list= +- for i in /boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* /boot/kernel-* ; do +- if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi +- done ;; ++ xi?86 | xx86_64) klist="/boot/vmlinuz-* /vmlinuz-* /boot/kernel-*" ;; ++ xs390 | xs390x) klist="/boot/image-* /boot/kernel-*" ;; ++ *) klist="/boot/vmlinuz-* /boot/vmlinux-* /vmlinuz-* /vmlinux-* \ ++ /boot/kernel-*" ;; + esac ++list= ++for i in $klist ; do ++ if grub_file_is_not_garbage "$i" ; then list="$list $i" ; fi ++done + + case "$machine" in + i?86) GENKERNEL_ARCH="x86" ;; +@@ -190,6 +211,15 @@ + *) GENKERNEL_ARCH="$machine" ;; + esac + ++PLATFORM="native" ++if [ -d /sys/firmware/efi ]&&[ "x${GRUB_USE_LINUXEFI}" = "xtrue" ]; then ++ PLATFORM="efi" ++else ++ case "$machine" in ++ s390*) PLATFORM="emu" ;; ++ esac ++fi ++ + prepare_boot_cache= + prepare_root_cache= + boot_device_id= +@@ -216,6 +246,11 @@ + basename=`basename $linux` + dirname=`dirname $linux` + rel_dirname=`make_system_path_relative_to_its_root $dirname` ++ if [ $PLATFORM != "emu" ]; then ++ hotkey=0 ++ else ++ rel_dirname=$dirname ++ fi + version=`echo $basename | sed -e "s,^[^0-9]*-,,g"` + alt_version=`echo $version | sed -e "s,\.old$,,g"` + linux_root_device_thisversion="${LINUX_ROOT_DEVICE}" +@@ -333,7 +368,8 @@ + boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")" + fi + # TRANSLATORS: %s is replaced with an OS name +- echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {" ++ echo "submenu '$(gettext_printf "Advanced options for %s" "${OS}" | grub_quote)' $(print_hotkey) \$menuentry_id_option 'gnulinux-advanced-$boot_device_id' {" ++ hotkey=$(incr_hotkey) + is_top_level=false + fi + diff --git a/grub2-s390x-06-loadparm.patch b/grub2-s390x-06-loadparm.patch new file mode 100644 index 0000000000000000000000000000000000000000..9c528a8b95b0392030b9f0eb08b3290b416cb6de --- /dev/null +++ b/grub2-s390x-06-loadparm.patch @@ -0,0 +1,45 @@ +From: Raymund Will +Subject: Allow s390x-emu to telecontrolled by LOADPARM +References: bsc#892852, bsc#891946 +Patch-Mainline: no + +--- + util/grub.d/00_header.in | 27 +++++++++++++++++++++++++++ + 1 file changed, 27 insertions(+) + +--- a/util/grub.d/00_header.in ++++ b/util/grub.d/00_header.in +@@ -54,6 +54,33 @@ + fi + + EOF ++if [ "`uname -m`" = "s390x" ]; then ++ cat <' ++ regexp -s 1:z_1 -s 2:z_2 '^([0-9][0-9>]*)\.([0-9][0-9.]*)$' "\$z_gp" ++ if [ ! "\$z_1" -o ! "\$z_2" ]; then break; fi ++ set z_gp="\$z_1>\$z_2" ++ done ++ if [ ! "\$z_gp" ]; then break; fi ++ set next_entry="\$z_gp" ++ unset z_gp ++ unset loadparm ++ break ++done ++EOF ++fi + if [ "x$GRUB_BUTTON_CMOS_ADDRESS" != "x" ]; then + cat < 0); +- $msg .= "Usage: $C [-v] [-d] [-f] [-T template] [-z ZIPLDIR]\n"; ++ $msg .= "Usage: $C [-v] [-d] [-f] [-T template] [-z ZIPLDIR] [-i imagepath]\n"; + Panic( $_[0], $msg . "\n"); + } + +@@ -183,6 +186,7 @@ + (/^--?help/ || /^-h/) && (Usage(0)); + (/^--zipldir$/ || /^-z$/) && ($zipldir = shift || Usage(2), next); + (/^--template$/ || /^-T$/) && ($in = shift || Usage(3), next); ++ (/^--image$/ || /^-i$/) && ($Image = shift || Usage(5), $force = 1, next); + (/^-/) && (Usage(1)); + Usage(1); + } +@@ -378,11 +382,8 @@ + } + + # copy out kernel and initrd +-my $defimage = "/boot/image"; +-my $definitrd = "/boot/initrd"; + my $ziplimage = "$zipldir/image"; + my $ziplinitrd = "$zipldir/initrd"; +-my $Image = "$defimage"; + + if ( ! $running && ! $force ) { + chomp( $running = qx{uname -r}); diff --git a/grub2-s390x-08-workaround-part-to-disk.patch b/grub2-s390x-08-workaround-part-to-disk.patch new file mode 100644 index 0000000000000000000000000000000000000000..d9ef34d54f091cd2b99e243ce4b76c29de0d3eed --- /dev/null +++ b/grub2-s390x-08-workaround-part-to-disk.patch @@ -0,0 +1,13 @@ +--- a/grub-core/osdep/linux/getroot.c ++++ b/grub-core/osdep/linux/getroot.c +@@ -740,6 +740,10 @@ + if (! realpath (os_dev, path)) + return NULL; + ++#ifdef __s390x__ ++ return path; ++#endif ++ + if (strncmp ("/dev/", path, 5) == 0) + { + char *p = path + 5; diff --git a/grub2-s390x-09-improve-zipl-setup.patch b/grub2-s390x-09-improve-zipl-setup.patch new file mode 100644 index 0000000000000000000000000000000000000000..bc22c8ecc9fb27154ca916a8e1fbb325c45fe488 --- /dev/null +++ b/grub2-s390x-09-improve-zipl-setup.patch @@ -0,0 +1,209 @@ +--- + util/s390x/zipl2grub.conf.in | 30 +++++++++++++++++++- + util/s390x/zipl2grub.pl.in | 64 +++++++++++++++++++++++++++++-------------- + 2 files changed, 73 insertions(+), 21 deletions(-) + +--- a/util/s390x/zipl2grub.conf.in ++++ b/util/s390x/zipl2grub.conf.in +@@ -10,17 +10,45 @@ defaultmenu = menu + image = @zipldir@/image + parameters = "root=@GRUB_DEVICE@ @GRUB_EMU_CONMODE@ @GRUB_CMDLINE_LINUX@ @GRUB_CMDLINE_LINUX_DEFAULT@ initgrub quiet splash=silent plymouth.enable=0 " + ++[grub2-mem1G] ++ target = @zipldir@ ++ image = @zipldir@/image ++ ramdisk = @zipldir@/initrd,0x2000000 ++ parameters = "root=@GRUB_DEVICE@ @GRUB_EMU_CONMODE@ @GRUB_CMDLINE_LINUX@ @GRUB_CMDLINE_LINUX_DEFAULT@ initgrub quiet splash=silent plymouth.enable=0 mem=1G " ++ + [skip-grub2] + target = @zipldir@ + ramdisk = @zipldir@/initrd,0x2000000 + image = @zipldir@/image + parameters = "root=@GRUB_DEVICE@ @GRUB_CONMODE@ @GRUB_CMDLINE_LINUX@ @GRUB_CMDLINE_LINUX_DEFAULT@ " ++#@ ++#@[grub2-previous] ++#@ target = @zipldir@ ++#@ image = @zipldir@/image.prev ++#@ ramdisk = @zipldir@/initrd.prev,0x2000000 ++#@ parameters = "root=@GRUB_DEVICE@ @GRUB_EMU_CONMODE@ @GRUB_CMDLINE_LINUX@ @GRUB_CMDLINE_LINUX_DEFAULT@ initgrub quiet splash=silent plymouth.enable=0 " ++#@ ++#@[grub2-mem1G-previous] ++#@ target = @zipldir@ ++#@ image = @zipldir@/image.prev ++#@ ramdisk = @zipldir@/initrd.prev,0x2000000 ++#@ parameters = "root=@GRUB_DEVICE@ @GRUB_EMU_CONMODE@ @GRUB_CMDLINE_LINUX@ @GRUB_CMDLINE_LINUX_DEFAULT@ initgrub quiet splash=silent plymouth.enable=0 mem=1G " ++#@ ++#@[skip-grub2-previous] ++#@ target = @zipldir@ ++#@ image = @zipldir@/image.prev ++#@ ramdisk = @zipldir@/initrd.prev,0x2000000 ++#@ parameters = "root=@GRUB_DEVICE@ @GRUB_CONMODE@ @GRUB_CMDLINE_LINUX@ @GRUB_CMDLINE_LINUX_DEFAULT@ " + + :menu + target = @zipldir@ +- timeout = 16 ++ timeout = 60 + default = 1 + prompt = 0 + 1 = grub2 + 2 = skip-grub2 ++ 3 = grub2-mem1G ++#@ 4 = grub2-previous ++#@ 5 = skip-grub2-previous ++#@ 6 = grub2-mem1G-previous + +--- a/util/s390x/zipl2grub.pl.in ++++ b/util/s390x/zipl2grub.pl.in +@@ -10,6 +10,7 @@ my $sysconfbl = '@sysconfdir@/sysconfig/ + my $defimage = "/boot/image"; + my $definitrd = "/boot/initrd"; + my $Image = "$defimage"; ++my $previous = ".prev"; + my $zipldir = ""; + my $running = ""; + my $refresh = 1; # needs to default to "on" until most bugs are shaken out! +@@ -44,12 +45,12 @@ sub System(@) { + return 0 if ($debug); + system( @C); + if ($? == -1) { +- Panic( $?, "$C[0]: Failed to execute: $!\n"); ++ Panic( 1, "$C[0]: Failed to execute: $!\n"); + } elsif ($? & 127) { +- Panic( $?, sprintf( "$C[0]: Died with signal %d with%s coredump\n", ++ Panic( 1, sprintf( "$C[0]: Died with signal %d with%s coredump\n", + ($? & 127), ($? & 128) ? '' : 'out')); + } elsif ( $? >> 8 != 0 ) { +- Panic( $?, "$C[0]: Failed\n"); ++ Panic( $? >> 8, "$C[0]: Failed\n"); + } + return( 0); + } +@@ -74,11 +75,13 @@ sub ln($$) { + unlink( $_[1]) || Panic( 1, "$C: unlink: $!.\n") if ( -e $_[1]); + symlink($_[0], $_[1]) || Panic( 1, "$C: symlink: $!.\n"); + } +-sub BootCopy($$$) { ++ ++sub ManagePrev($$$){ + my( $file, $dir, $tgt) = @_; + my $curr = "$dir/$tgt"; +- my $prev = "$dir/$tgt.prev"; +- Info(4, "Copy /boot/$file $dir $tgt\n"); ++ my $prev = "$dir/$tgt$previous"; ++ my $ret = 0; ++ Info(2, "Manage $prev\n"); + if ( -l $curr ) { + my $curf = readlink( $curr); + if ( $curf ne $file ) { +@@ -88,7 +91,21 @@ sub BootCopy($$$) { + rm( $pref); + } + mv( $curr, $prev); ++ $ret = 1; ++ } else { ++ Info(2, " nothing to do ($curr -> $file).\n"); + } ++ } else { ++ Info(2, " nothing to do ($curr no sym-link).\n"); ++ } ++ return $ret; ++} ++sub BootCopy($$$) { ++ my( $file, $dir, $tgt) = @_; ++ my $curr = "$dir/$tgt"; ++ Info(4, "Copy /boot/$file $dir $tgt\n"); ++ if ( $tgt eq "image" && ManagePrev( $file, $dir, $tgt)) { ++ ManagePrev( $file, $dir, "initrd") + } + cp( "/boot/$file", "$dir/$file"); + ln( $file, $curr); +@@ -163,7 +180,9 @@ sub Usage($) { + "zIPL directory missing.", + "Configuration template missing.", + "Configuration template unreadable.", +- "zIPL directory not accesible.", ++ "zIPL directory not accessible.", ++ "kernel image parameter missing.", ++ "kernel image unreadable.", + "" + ); + my $msg = ""; +@@ -186,7 +205,8 @@ while ( $#ARGV >= 0 ) { + (/^--?help/ || /^-h/) && (Usage(0)); + (/^--zipldir$/ || /^-z$/) && ($zipldir = shift || Usage(2), next); + (/^--template$/ || /^-T$/) && ($in = shift || Usage(3), next); +- (/^--image$/ || /^-i$/) && ($Image = shift || Usage(5), $force = 1, next); ++ (/^--image$/ || /^-i$/) && ($Image = shift || Usage(6), ++ -r "$Image" || Usage(7), $force = 1, next); + (/^-/) && (Usage(1)); + Usage(1); + } +@@ -345,7 +365,7 @@ if ( $debug && $verbose > 2 ) { + open( IN, "< $in") || + Panic( 1, "$C: Failed to open 'zipl.conf' template: $!.\n"); + while ( ) { +- Info( 3, "$.. <$_$.. >"); ++ Info( 4, "$.. <$_$.. >"); + if ( $. == 1 && m{^## This} ) { + $_ = "## This file was written by 'grub2-install/$C'\n" . + "## filling '$in' as template\n"; +@@ -366,7 +386,7 @@ while ( ) { + } + s{\@$k\@}{$v}g; + } +- Info( 2, $_); ++ Info( 3, $_); + $cfg .= $_; + } + if ( $miss ) { +@@ -374,13 +394,6 @@ if ( $miss ) { + Panic( 1, "$C: 'zipl.conf' template could not be filled. \n"); + } + +-my $ziplconf = "$zipldir/config"; +-if ( ! $debug ) { +- open( OUT, "> $ziplconf") || die; +- print( OUT $cfg) || die; +- close( OUT); +-} +- + # copy out kernel and initrd + my $ziplimage = "$zipldir/image"; + my $ziplinitrd = "$zipldir/initrd"; +@@ -399,15 +412,15 @@ if ( -l $Image ) { + $Image = readlink( $Image); + } + my ($image, $version) = ($Image =~ m{^(?:/boot/)?([^-]+-(.+))$}); +-my $initrd = "initrd-$version"; +- + if ( !defined($image) || !defined($version) || ! -r "/boot/$image" ) { + Panic( 1, "$C: weird $Image. This should never happen!\n"); + } ++my $initrd = "initrd-$version"; + + if ( ! -r $ziplimage || ! -r $ziplinitrd || $refresh ) { + BootCopy( $image, $zipldir, "image"); +- BootCopy( $initrd, $zipldir, "initrd") if (-r "/boot/$initrd"); ++ BootCopy( $initrd, $zipldir, "initrd") ++ if (-r "/boot/$initrd" && ! exists( $fsdev{"/boot"})); + } + if ( $refresh || ChkInitrd( $zipldir, "initrd") <= 0 ) { + MkInitrd( $initrd, $zipldir, $version); +@@ -417,6 +430,17 @@ if ( ChkInitrd( $zipldir, "initrd") == 0 + $miss++; + } + ++# write zipl config file ++my $ziplconf = "$zipldir/config"; ++$cfg =~ s{#@}{}g if ( -r "$ziplimage$previous" && -r "$ziplinitrd$previous" ); ++if ( ! $debug ) { ++ open( OUT, "> $ziplconf") || die; ++ print( OUT $cfg) || die; ++ close( OUT); ++} else { ++ print( STDERR $cfg); ++} ++ + # now: go for it! + my @C = ( "/sbin/zipl", (($verbose) ? "-Vnc" : "-nc"), "$ziplconf" ); + System( @C); diff --git a/grub2-s390x-11-secureboot.patch b/grub2-s390x-11-secureboot.patch new file mode 100644 index 0000000000000000000000000000000000000000..ca2e556a7dc3e96533a72834e8befc3068d2a86b --- /dev/null +++ b/grub2-s390x-11-secureboot.patch @@ -0,0 +1,133 @@ +--- + grub-core/loader/emu/linux.c | 4 ++-- + util/s390x/dracut-grub2.sh.in | 14 ++++++++++++-- + util/s390x/zipl2grub.conf.in | 1 + + util/s390x/zipl2grub.pl.in | 31 ++++++++++++++++++++++--------- + 4 files changed, 37 insertions(+), 13 deletions(-) + +--- a/util/s390x/dracut-grub2.sh.in ++++ b/util/s390x/dracut-grub2.sh.in +@@ -18,6 +18,9 @@ + done < /proc/mounts + echo $rofs + } ++ checkcat() { ++ [ -r $1 ] && cat $1 ++ } + checkd() { + [ -d $1 ] && echo true || echo false + } +@@ -76,6 +79,7 @@ + export grub2bootw=$(checksubvol /boot/writable) + export grub2devfs=$(checkd /sysroot/dev/disk) + export grub2snap=$(checksnap) ++ export grub2secure=$(checkcat /sys/firmware/ipl/secure) + debug "" export -p + + _ctty="$(RD_DEBUG= getarg rd.ctty=)" && _ctty="/dev/${_ctty##*/}" +@@ -107,7 +111,7 @@ + debug "Trying grub2-emu (ro=$grub2rofs, TERM=$TERM, ctty=$_ctty)..." + setsid $CTTY -- chroot /sysroot $bindir/grub2-emu -X -X 0<>$_ctty 1>&0 2>&0 + +- if [ -x /sysroot@libdir@/grub2/zipl-refresh ]; then ++ if [ "$grub2secure" != 1 ]&&[ -x /sysroot@libdir@/grub2/zipl-refresh ]; then + setsid $CTTY -- /sysroot@libdir@/grub2/zipl-refresh 0<>$_ctty 1>&0 2>&0 + if [ $? != 0 ]; then + warn "Not continuing" +@@ -117,12 +121,18 @@ + sleep 3 + reboot + fi +- else ++ elif [ "$grub2secure" != 1 ]; then + echo " + Attention: 'grub2' failed to start the target kernel and 'zipl-refresh' + is not available. This should never happen. Please contact support." >& $_ctty + warn "Not continuing" + emergency_shell -n grub2-emu-kexec ++ else ++ echo " ++ Attention: 'grub2' failed to start the target kernel and secure boot seems ++ active. Automatic recovery not available. Please contact support." >& $_ctty ++ warn "Not continuing" ++ emergency_shell -n grub2-emu-kexec + fi + + $grub2snap || umount /sysroot/.snapshots +--- a/util/s390x/zipl2grub.conf.in ++++ b/util/s390x/zipl2grub.conf.in +@@ -45,6 +45,7 @@ + timeout = 60 + default = 1 + prompt = 0 ++ secure = @SUSE_SECURE_BOOT@ + 1 = grub2 + 2 = skip-grub2 + 3 = grub2-mem1G +--- a/util/s390x/zipl2grub.pl.in ++++ b/util/s390x/zipl2grub.pl.in +@@ -21,6 +21,7 @@ + my $cfg = ""; + my %fsdev = (); + my %fstype = (); ++my %SBL = (); # key/value of $sysconfbl + + my %C = ( + GRUB_CMDLINE_LINUX_DEFAULT => "quiet splash=silent", +@@ -251,6 +252,15 @@ + } + close( IN); + } ++if ( -r $sysconfbl ) { ++ open( IN, "< $sysconfbl") || die; ++ while ( ) { ++ next if ( m{^\s*#} ); ++ next unless ( m{^\s*([^=#\s]+)="(.*)"(?:\s*|\s+#.*)$} ); ++ $SBL{$1} = $2; ++ } ++ close( IN); ++} + if ( -r "/etc/fstab" ) { + my $regex = qr{^(\S+)\s+(\S+)\s+(\S+)\s+\S+\s+\S+\s+\S+\s*(?:#.*)?$}; + open( IN, "< /etc/fstab") || die; +@@ -313,21 +323,21 @@ + } + } + if ( $C{GRUB_CMDLINE_LINUX_DEFAULT} eq "quiet splash=silent" && +- -r $sysconfbl) { +- open( IN, "< $sysconfbl") || die; +- while ( ) { +- next if ( m{^\s*#} ); +- if ( m{^DEFAULT_APPEND=".*"(?:\s*|\s+#.*)$} ) { +- $C{GRUB_CMDLINE_LINUX_DEFAULT} = $1; +- } +- } +- close( IN); ++ exists( $SBL{DEFAULT_APPEND}) ) { ++ $C{GRUB_CMDLINE_LINUX_DEFAULT} = $SBL{DEFAULT_APPEND}; + } + + if ( ! exists( $C{GRUB_DEVICE})) { + Panic( 0, "$C: Default not ready and no fallback. Please retry later!\n"); + } + ++if ( !exists( $C{SUSE_SECURE_BOOT}) ) { ++ $C{SUSE_SECURE_BOOT} = "0"; ++ if ( exists( $SBL{SECURE_BOOT}) && $SBL{SECURE_BOOT} =~ m{^(yes|true|1)$} ) { ++ $C{SUSE_SECURE_BOOT} = "1"; ++ } ++} ++ + if ( ! exists( $C{GRUB_EMU_CONMODE}) && exists( $C{GRUB_CONMODE}) ) { + # GRUB_CONMODE is used for 'grub2-emu' as well + $C{GRUB_EMU_CONMODE} = $C{GRUB_CONMODE}; +@@ -360,6 +370,9 @@ + foreach ( sort( keys( %C)) ) { + printf( "%s=\"%s\"\n", $_, $C{$_}); + } ++ foreach ( sort( keys( %SBL)) ) { ++ printf( "SBL: %s=\"%s\"\n", $_, $SBL{$_}); ++ } + } + + open( IN, "< $in") || diff --git a/grub2-s390x-12-zipl-setup-usrmerge.patch b/grub2-s390x-12-zipl-setup-usrmerge.patch new file mode 100644 index 0000000000000000000000000000000000000000..f6a99597e787979c883f5b740bf4ca1ec8c43670 --- /dev/null +++ b/grub2-s390x-12-zipl-setup-usrmerge.patch @@ -0,0 +1,84 @@ +--- + util/s390x/zipl2grub.pl.in | 41 ++++++++++++++++++++++++++++------------- + 1 file changed, 28 insertions(+), 13 deletions(-) + +Index: grub-2.06/util/s390x/zipl2grub.pl.in +=================================================================== +--- grub-2.06.orig/util/s390x/zipl2grub.pl.in ++++ grub-2.06/util/s390x/zipl2grub.pl.in +@@ -101,20 +101,22 @@ sub ManagePrev($$$){ + } + return $ret; + } +-sub BootCopy($$$) { +- my( $file, $dir, $tgt) = @_; ++sub BootCopy($$$$) { ++ my( $src, $file, $dir, $tgt) = @_; + my $curr = "$dir/$tgt"; +- Info(4, "Copy /boot/$file $dir $tgt\n"); ++ $src = "/boot/$src" unless ( -r $src ); ++ Info(4, "Copy $src $dir $tgt\n"); + if ( $tgt eq "image" && ManagePrev( $file, $dir, $tgt)) { + ManagePrev( $file, $dir, "initrd") + } +- cp( "/boot/$file", "$dir/$file"); ++ cp( $src, "$dir/$file"); + ln( $file, $curr); + } + sub MkInitrd($$$) { + my( $initrd, $dir, $version) = @_; + my @C = ( "dracut", "--hostonly", "--force"); + my $uuid; ++ push @C, "--quiet" unless ($verbose > 1); + if ( exists( $fsdev{"/boot"}) ) { + chomp( $uuid = qx{grub2-probe --target=fs_uuid /boot}); + my ($dev, $type) = ($fsdev{"/boot"}, $fstype{"/boot"}); +@@ -429,18 +431,31 @@ if ( ! -r $Image ) { + } + Panic( 1, "$C: kernel '$Image' not readable!?\n") unless (-r $Image); + +-if ( -l $Image ) { +- $Image = readlink( $Image); +-} +-my ($image, $version) = ($Image =~ m{^(?:/boot/)?([^-]+-(.+))$}); +-if ( !defined($image) || !defined($version) || ! -r "/boot/$image" ) { +- Panic( 1, "$C: weird $Image. This should never happen!\n"); ++my ($image, $version) = ($Image, undef); ++while ( !defined( $version) ) { ++ my ($i, $vr, $f) = ($image =~ m{^(?:/boot/)?([^-/]+)-([^/]+)-([^-/]+)$}); ++ Info( 4, "image='$image': "); ++ if ( defined($i) && defined($vr) && defined( $f) && -r "/boot/$i-$vr-$f" ) { ++ Info( 4, "matches pattern ('$vr'-'$f')\n"); ++ $version = "$vr-$f"; ++ last; ++ } ++ if ( -l $image ) { ++ Info( 4, "readlink...\n"); ++ $image = readlink( $image); ++ next; ++ } ++ Info( 4, "last resort: get_kernel_version from original '$Image'...\n"); ++ chomp( $version = qx{get_kernel_version $Image}); ++ Panic( 1, "$C: failed to get kernel version for '$Image'!\n") ++ unless ( defined( $version) && $version ); + } + my $initrd = "initrd-$version"; ++$image = "image-$version"; + + if ( ! -r $ziplimage || ! -r $ziplinitrd || $refresh ) { +- BootCopy( $image, $zipldir, "image"); +- BootCopy( $initrd, $zipldir, "initrd") ++ BootCopy( $Image, $image, $zipldir, "image"); ++ BootCopy( $initrd, $initrd, $zipldir, "initrd") + if (-r "/boot/$initrd" && ! exists( $fsdev{"/boot"})); + } + if ( $refresh || ChkInitrd( $zipldir, "initrd") <= 0 ) { +@@ -463,7 +478,7 @@ if ( ! $debug ) { + } + + # now: go for it! +-my @C = ( "/sbin/zipl", (($verbose) ? "-Vnc" : "-nc"), "$ziplconf" ); ++my @C = ( "/sbin/zipl", (($verbose > 1) ? "-Vnc" : "-nc"), "$ziplconf" ); + System( @C); + exit( $miss); + diff --git a/grub2-s390x-skip-zfcpdump-image.patch b/grub2-s390x-skip-zfcpdump-image.patch new file mode 100644 index 0000000000000000000000000000000000000000..70100b6ef59c8661f77618db5433cbe544727057 --- /dev/null +++ b/grub2-s390x-skip-zfcpdump-image.patch @@ -0,0 +1,15 @@ +--- a/util/grub-mkconfig_lib.in ++++ b/util/grub-mkconfig_lib.in +@@ -193,6 +193,12 @@ + *.rpmsave|*.rpmnew) return 1 ;; + README*|*/README*) return 1 ;; # documentation + *.sig) return 1 ;; # signatures ++ # Skip zfcpdump kernel from the grub boot menu (bsc#1166513) The zfcpdump ++ # kernel image is used by zipl to prepare a SCSI dump disc and is only ++ # intended to boot from that disk for creating kernel crash dumps, ++ # therefore booting it from grub is not making sense and also will result ++ # in unbootable system. ++ *-zfcpdump) return 1 ;; # s390 zfcpdump image + esac + else + return 1 diff --git a/grub2-secureboot-add-linuxefi.patch b/grub2-secureboot-add-linuxefi.patch new file mode 100644 index 0000000000000000000000000000000000000000..54bb6acff1f485adbac569704ec67e28b9a16ca9 --- /dev/null +++ b/grub2-secureboot-add-linuxefi.patch @@ -0,0 +1,450 @@ +From: Matthew Garrett +Date: 2012-07-10 11:58:52 EDT +Subject: [PATCH] Add support for linuxefi + +References: fate#314485 +Patch-Mainline: no + +Signed-off-by: Michael Chang + +v2: Adjust patch according to new upstream commits +4d4a8c96e verifiers: Add possibility to verify kernel and modules command lines +ca0a4f689 verifiers: File type for fine-grained signature-verification controlling +7d36709d5 i386: make struct linux_kernel_header architecture specific +4bc909bf8 Remove grub_efi_allocate_pages. +v3: +The upstream commit + +df84d6e94 efi: Print error messages to grub_efi_allocate_pages_real() + +adds grub_error() to set error message and return grub_errno. We have to +unset the grub_errno if we want to ignore the error and proceed, or +the inadvertently provoked error handler would lead to unspecified +consequence. + +--- + grub-core/Makefile.core.def | 8 + + grub-core/kern/efi/mm.c | 32 ++++ + grub-core/loader/i386/efi/linux.c | 371 +++++++++++++++++++++++++++++++++++++ + include/grub/efi/efi.h | 3 + + include/grub/i386/linux.h | 1 + + 5 files changed, 415 insertions(+), 0 deletions(-) + create mode 100644 grub-core/loader/i386/efi/linux.c + +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -1920,6 +1920,13 @@ + }; + + module = { ++ name = linuxefi; ++ efi = loader/i386/efi/linux.c; ++ enable = i386_efi; ++ enable = x86_64_efi; ++}; ++ ++module = { + name = chain; + efi = loader/efi/chainloader.c; + i386_pc = loader/i386/pc/chainloader.c; +--- a/grub-core/kern/efi/mm.c ++++ b/grub-core/kern/efi/mm.c +@@ -112,6 +112,38 @@ + } + } + ++/* Allocate pages below a specified address */ ++void * ++grub_efi_allocate_pages_max (grub_efi_physical_address_t max, ++ grub_efi_uintn_t pages) ++{ ++ grub_efi_status_t status; ++ grub_efi_boot_services_t *b; ++ grub_efi_physical_address_t address = max; ++ ++ if (max > 0xffffffff) ++ return 0; ++ ++ b = grub_efi_system_table->boot_services; ++ status = b->allocate_pages (GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); ++ ++ if (status != GRUB_EFI_SUCCESS) ++ return 0; ++ ++ if (address == 0) ++ { ++ /* Uggh, the address 0 was allocated... This is too annoying, ++ so reallocate another one. */ ++ address = max; ++ status = b->allocate_pages (GRUB_EFI_ALLOCATE_MAX_ADDRESS, GRUB_EFI_LOADER_DATA, pages, &address); ++ grub_efi_free_pages (0, pages); ++ if (status != GRUB_EFI_SUCCESS) ++ return 0; ++ } ++ ++ return (void *) ((grub_addr_t) address); ++} ++ + /* Allocate pages. Return the pointer to the first of allocated pages. */ + void * + grub_efi_allocate_pages_real (grub_efi_physical_address_t address, +--- /dev/null ++++ b/grub-core/loader/i386/efi/linux.c +@@ -0,0 +1,345 @@ ++/* ++ * GRUB -- GRand Unified Bootloader ++ * Copyright (C) 2012 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 . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++GRUB_MOD_LICENSE ("GPLv3+"); ++ ++static grub_dl_t my_mod; ++static int loaded; ++static void *kernel_mem; ++static grub_uint64_t kernel_size; ++static grub_uint8_t *initrd_mem; ++static grub_uint32_t handover_offset; ++struct linux_kernel_params *params; ++static char *linux_cmdline; ++ ++#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; ++} ++ ++static grub_err_t ++grub_linuxefi_unload (void) ++{ ++ grub_dl_unref (my_mod); ++ loaded = 0; ++ if (initrd_mem) ++ grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, BYTES_TO_PAGES(params->ramdisk_size)); ++ if (linux_cmdline) ++ grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)linux_cmdline, BYTES_TO_PAGES(params->cmdline_size + 1)); ++ if (kernel_mem) ++ grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); ++ if (params) ++ grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)params, BYTES_TO_PAGES(16384)); ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), ++ int argc, char *argv[]) ++{ ++ grub_file_t *files = 0; ++ int i, nfiles = 0; ++ grub_size_t size = 0; ++ grub_uint8_t *ptr; ++ ++ 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; ++ } ++ ++ files = grub_zalloc (argc * sizeof (files[0])); ++ if (!files) ++ goto fail; ++ ++ for (i = 0; i < argc; i++) ++ { ++ files[i] = grub_file_open (argv[i], GRUB_FILE_TYPE_LINUX_INITRD ++ | GRUB_FILE_TYPE_NO_DECOMPRESS); ++ if (! files[i]) ++ goto fail; ++ nfiles++; ++ size += ALIGN_UP (grub_file_size (files[i]), 4); ++ } ++ ++ initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size)); ++ ++ if (!initrd_mem) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd")); ++ goto fail; ++ } ++ ++ params->ramdisk_size = size; ++ params->ramdisk_image = (grub_uint32_t)(grub_addr_t) initrd_mem; ++ ++ ptr = initrd_mem; ++ ++ for (i = 0; i < nfiles; i++) ++ { ++ grub_ssize_t cursize = grub_file_size (files[i]); ++ if (grub_file_read (files[i], ptr, cursize) != cursize) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"), ++ argv[i]); ++ goto fail; ++ } ++ ptr += cursize; ++ grub_memset (ptr, 0, ALIGN_UP_OVERHEAD (cursize, 4)); ++ ptr += ALIGN_UP_OVERHEAD (cursize, 4); ++ } ++ ++ params->ramdisk_size = size; ++ ++ fail: ++ for (i = 0; i < nfiles; i++) ++ grub_file_close (files[i]); ++ grub_free (files); ++ ++ if (initrd_mem && grub_errno) ++ grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)initrd_mem, BYTES_TO_PAGES(size)); ++ ++ 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_i386_kernel_header lh; ++ grub_ssize_t len, start, filelen; ++ void *kernel; ++ 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; ++ ++ filelen = grub_file_size (file); ++ ++ kernel = grub_malloc(filelen); ++ ++ if (!kernel) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer")); ++ goto fail; ++ } ++ ++ if (grub_file_read (file, kernel, filelen) != filelen) ++ { ++ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"), argv[0]); ++ goto fail; ++ } ++ ++ grub_file_seek (file, 0); ++ ++ grub_free(kernel); ++ ++ params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384)); ++ ++ if (! params) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters"); ++ goto fail; ++ } ++ ++ grub_memset (params, 0, 16384); ++ ++ if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh)) ++ { ++ if (!grub_errno) ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), ++ argv[0]); ++ goto fail; ++ } ++ ++ if (lh.boot_flag != grub_cpu_to_le16 (0xaa55)) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number")); ++ goto fail; ++ } ++ ++ if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors")); ++ goto fail; ++ } ++ ++ if (lh.version < grub_cpu_to_le16 (0x020b)) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("kernel too old")); ++ goto fail; ++ } ++ ++ if (!lh.handover_offset) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover")); ++ goto fail; ++ } ++ ++ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff, ++ BYTES_TO_PAGES(lh.cmdline_size + 1)); ++ ++ if (!linux_cmdline) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline")); ++ goto fail; ++ } ++ ++ grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE)); ++ err = grub_create_loader_cmdline (argc, argv, ++ linux_cmdline + sizeof (LINUX_IMAGE) - 1, ++ lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1), ++ GRUB_VERIFY_KERNEL_CMDLINE); ++ if (err) ++ goto fail; ++ ++ lh.cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline; ++ ++ handover_offset = lh.handover_offset; ++ ++ start = (lh.setup_sects + 1) * 512; ++ len = grub_file_size(file) - start; ++ ++ kernel_mem = grub_efi_allocate_fixed (lh.pref_address, ++ BYTES_TO_PAGES(lh.init_size)); ++ ++ if (!kernel_mem) ++ { ++ grub_errno = GRUB_ERR_NONE; ++ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff, ++ BYTES_TO_PAGES(lh.init_size)); ++ } ++ ++ if (!kernel_mem) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel")); ++ goto fail; ++ } ++ ++ if (grub_file_seek (file, start) == (grub_off_t) -1) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), ++ argv[0]); ++ goto fail; ++ } ++ ++ if (grub_file_read (file, kernel_mem, len) != len && !grub_errno) ++ { ++ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), ++ argv[0]); ++ } ++ ++ if (grub_errno == GRUB_ERR_NONE) ++ { ++ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0); ++ loaded = 1; ++ lh.code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem; ++ } ++ ++ grub_memcpy(params, &lh, 2 * 512); ++ ++ params->type_of_loader = 0x21; ++ ++ fail: ++ ++ if (file) ++ grub_file_close (file); ++ ++ if (grub_errno != GRUB_ERR_NONE) ++ { ++ grub_dl_unref (my_mod); ++ loaded = 0; ++ } ++ ++ if (linux_cmdline && !loaded) ++ grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1)); ++ ++ if (kernel_mem && !loaded) ++ grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, BYTES_TO_PAGES(kernel_size)); ++ ++ if (params && !loaded) ++ grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)params, BYTES_TO_PAGES(16384)); ++ ++ return grub_errno; ++} ++ ++static grub_command_t cmd_linux, cmd_initrd; ++ ++GRUB_MOD_INIT(linuxefi) ++{ ++ 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(linuxefi) ++{ ++ grub_unregister_command (cmd_linux); ++ grub_unregister_command (cmd_initrd); ++} +--- a/include/grub/efi/efi.h ++++ b/include/grub/efi/efi.h +@@ -61,6 +61,9 @@ + grub_efi_uintn_t pages); + void * + EXPORT_FUNC(grub_efi_allocate_any_pages) (grub_efi_uintn_t pages); ++void * ++EXPORT_FUNC(grub_efi_allocate_pages_max) (grub_efi_physical_address_t max, ++ grub_efi_uintn_t pages); + void EXPORT_FUNC(grub_efi_free_pages) (grub_efi_physical_address_t address, + grub_efi_uintn_t pages); + grub_efi_uintn_t EXPORT_FUNC(grub_efi_find_mmap_size) (void); diff --git a/grub2-secureboot-chainloader.patch b/grub2-secureboot-chainloader.patch new file mode 100644 index 0000000000000000000000000000000000000000..245c20b84d0c5d5dd5e498da4ea8924891342ece --- /dev/null +++ b/grub2-secureboot-chainloader.patch @@ -0,0 +1,596 @@ +From 06ff1079788fedac5e3f1f12ed7bbe69228a7ae0 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Tue, 18 Dec 2012 16:54:03 +0800 +Subject: [PATCH] Add secureboot support on efi chainloader + +References: fate#314485 +Patch-Mainline: no + +Expand the chainloader to be able to verify the image by means of shim +lock protocol. The PE/COFF image is loaded and relocated by the +chainloader instead of calling LoadImage and StartImage UEFI boot +Service as they require positive verification result from keys enrolled +in KEK or DB. The shim will use MOK in addition to firmware enrolled +keys to verify the image. + +The chainloader module could be used to load other UEFI bootloaders, +such as xen.efi, and could be signed by any of MOK, KEK or DB. + +v1: +Use grub_efi_get_secureboot to get secure boot status + +Signed-off-by: Michael Chang +--- + grub-core/loader/efi/chainloader.c | 538 +++++++++++++++++++++++++++++++++-- + 1 files changed, 507 insertions(+), 31 deletions(-) + +--- a/grub-core/loader/efi/chainloader.c ++++ b/grub-core/loader/efi/chainloader.c +@@ -41,10 +41,24 @@ + #include + #endif + ++#ifdef __x86_64__ ++#define SUPPORT_SECURE_BOOT ++#endif ++ ++#ifdef SUPPORT_SECURE_BOOT ++#include ++#include ++#endif ++ + GRUB_MOD_LICENSE ("GPLv3+"); + + static grub_dl_t my_mod; + ++#ifdef SUPPORT_SECURE_BOOT ++static grub_efi_boolean_t debug_secureboot = 0; ++static grub_efi_status_t (__grub_efi_api *entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table); ++#endif ++ + static grub_err_t + grub_chainloader_unload (void *context) + { +@@ -209,6 +223,421 @@ + return file_path; + } + ++#ifdef SUPPORT_SECURE_BOOT ++#define SHIM_LOCK_GUID \ ++ { 0x605dab50, 0xe046, 0x4300, {0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23} } ++ ++struct grub_pe32_header_no_msdos_stub ++{ ++ char signature[GRUB_PE32_SIGNATURE_SIZE]; ++ struct grub_pe32_coff_header coff_header; ++ struct grub_pe64_optional_header optional_header; ++}; ++ ++struct pe_coff_loader_image_context ++{ ++ grub_efi_uint64_t image_address; ++ grub_efi_uint64_t image_size; ++ grub_efi_uint64_t entry_point; ++ grub_efi_uintn_t size_of_headers; ++ grub_efi_uint16_t image_type; ++ grub_efi_uint16_t number_of_sections; ++ struct grub_pe32_section_table *first_section; ++ struct grub_pe32_data_directory *reloc_dir; ++ struct grub_pe32_data_directory *sec_dir; ++ grub_efi_uint64_t number_of_rva_and_sizes; ++ struct grub_pe32_header_no_msdos_stub *pe_hdr; ++}; ++ ++struct grub_secureboot_chainloader_context ++{ ++ grub_efi_physical_address_t address; ++ grub_efi_uintn_t pages; ++ grub_ssize_t fsize; ++ grub_efi_device_path_t *file_path; ++ grub_efi_char16_t *cmdline; ++ grub_ssize_t cmdline_len; ++ grub_efi_handle_t dev_handle; ++}; ++ ++typedef struct pe_coff_loader_image_context pe_coff_loader_image_context_t; ++ ++struct grub_efi_shim_lock ++{ ++ grub_efi_status_t (*verify)(void *buffer, ++ grub_efi_uint32_t size); ++ grub_efi_status_t (*hash)(void *data, ++ grub_efi_int32_t datasize, ++ pe_coff_loader_image_context_t *context, ++ grub_efi_uint8_t *sha256hash, ++ grub_efi_uint8_t *sha1hash); ++ grub_efi_status_t (*context)(void *data, ++ grub_efi_uint32_t size, ++ pe_coff_loader_image_context_t *context); ++}; ++ ++typedef struct grub_efi_shim_lock grub_efi_shim_lock_t; ++ ++static grub_efi_boolean_t ++grub_secure_validate (void *data, grub_efi_uint32_t size) ++{ ++ grub_guid_t guid = SHIM_LOCK_GUID; ++ grub_efi_shim_lock_t *shim_lock; ++ ++ shim_lock = grub_efi_locate_protocol (&guid, NULL); ++ ++ if (!shim_lock) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "no shim lock protocol"); ++ return 0; ++ } ++ ++ if (shim_lock->verify (data, size) == GRUB_EFI_SUCCESS) ++ { ++ grub_dprintf ("chain", "verify success\n"); ++ return 1; ++ } ++ ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "verify failed"); ++ return 0; ++} ++ ++static grub_efi_boolean_t ++read_header (void *data, grub_efi_uint32_t size, pe_coff_loader_image_context_t *context) ++{ ++ 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); ++ ++ if (!shim_lock) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "no shim lock protocol"); ++ return 0; ++ } ++ ++ status = shim_lock->context (data, size, context); ++ ++ if (status == GRUB_EFI_SUCCESS) ++ { ++ grub_dprintf ("chain", "context success\n"); ++ return 1; ++ } ++ ++ switch (status) ++ { ++ case GRUB_EFI_UNSUPPORTED: ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error unsupported"); ++ break; ++ case GRUB_EFI_INVALID_PARAMETER: ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error invalid parameter"); ++ break; ++ default: ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "context error code"); ++ break; ++ } ++ ++ return 0; ++} ++ ++static void* ++image_address (void *image, grub_efi_uint64_t sz, grub_efi_uint64_t adr) ++{ ++ if (adr > sz) ++ return NULL; ++ ++ return ((grub_uint8_t*)image + adr); ++} ++ ++static grub_efi_status_t ++relocate_coff (pe_coff_loader_image_context_t *context, void *data) ++{ ++ struct grub_pe32_data_directory *reloc_base, *reloc_base_end; ++ grub_efi_uint64_t adjust; ++ grub_efi_uint16_t *reloc, *reloc_end; ++ char *fixup, *fixup_base, *fixup_data = NULL; ++ grub_efi_uint16_t *fixup_16; ++ grub_efi_uint32_t *fixup_32; ++ grub_efi_uint64_t *fixup_64; ++ ++ grub_efi_uint64_t size = context->image_size; ++ void *image_end = (char *)data + size; ++ ++ context->pe_hdr->optional_header.image_base = (grub_uint64_t)data; ++ ++ if (context->number_of_rva_and_sizes <= 5 || context->reloc_dir->size == 0) ++ { ++ grub_dprintf ("chain", "no need to reloc, we are done\n"); ++ return GRUB_EFI_SUCCESS; ++ } ++ ++ reloc_base = image_address (data, size, context->reloc_dir->rva); ++ reloc_base_end = image_address (data, size, context->reloc_dir->rva + context->reloc_dir->size -1); ++ ++ grub_dprintf ("chain", "reloc_base %p reloc_base_end %p\n", reloc_base, reloc_base_end); ++ ++ if (!reloc_base || !reloc_base_end) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc table overflows binary"); ++ return GRUB_EFI_UNSUPPORTED; ++ } ++ ++ adjust = (grub_uint64_t)data - context->image_address; ++ ++ while (reloc_base < reloc_base_end) ++ { ++ reloc = (grub_uint16_t *)((char*)reloc_base + sizeof (struct grub_pe32_data_directory)); ++ reloc_end = (grub_uint16_t *)((char*)reloc_base + reloc_base->size); ++ ++ if ((void *)reloc_end < data || (void *)reloc_end > image_end) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "Reloc table overflows binary"); ++ return GRUB_EFI_UNSUPPORTED; ++ } ++ ++ fixup_base = image_address(data, size, reloc_base->rva); ++ ++ if (!fixup_base) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid fixupbase"); ++ return GRUB_EFI_UNSUPPORTED; ++ } ++ ++ while (reloc < reloc_end) ++ { ++ fixup = fixup_base + (*reloc & 0xFFF); ++ switch ((*reloc) >> 12) ++ { ++ case GRUB_PE32_REL_BASED_ABSOLUTE: ++ break; ++ case GRUB_PE32_REL_BASED_HIGH: ++ fixup_16 = (grub_uint16_t *)fixup; ++ *fixup_16 = (grub_uint16_t) (*fixup_16 + ((grub_uint16_t)((grub_uint32_t)adjust >> 16))); ++ if (fixup_data != NULL) ++ { ++ *(grub_uint16_t *) fixup_data = *fixup_16; ++ fixup_data = fixup_data + sizeof (grub_uint16_t); ++ } ++ break; ++ case GRUB_PE32_REL_BASED_LOW: ++ fixup_16 = (grub_uint16_t *)fixup; ++ *fixup_16 = (grub_uint16_t) (*fixup_16 + (grub_uint16_t)adjust ); ++ if (fixup_data != NULL) ++ { ++ *(grub_uint16_t *) fixup_data = *fixup_16; ++ fixup_data = fixup_data + sizeof (grub_uint16_t); ++ } ++ break; ++ case GRUB_PE32_REL_BASED_HIGHLOW: ++ fixup_32 = (grub_uint32_t *)fixup; ++ *fixup_32 = *fixup_32 + (grub_uint32_t)adjust; ++ if (fixup_data != NULL) ++ { ++ fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint32_t)); ++ *(grub_uint32_t *) fixup_data = *fixup_32; ++ fixup_data += sizeof (grub_uint32_t); ++ } ++ break; ++ case GRUB_PE32_REL_BASED_DIR64: ++ fixup_64 = (grub_uint64_t *)fixup; ++ *fixup_64 = *fixup_64 + (grub_uint64_t)adjust; ++ if (fixup_data != NULL) ++ { ++ fixup_data = (char *)ALIGN_UP ((grub_addr_t)fixup_data, sizeof (grub_uint64_t)); ++ *(grub_uint64_t *) fixup_data = *fixup_64; ++ fixup_data += sizeof (grub_uint64_t); ++ } ++ break; ++ default: ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "unknown relocation"); ++ return GRUB_EFI_UNSUPPORTED; ++ } ++ reloc += 1; ++ } ++ reloc_base = (struct grub_pe32_data_directory *)reloc_end; ++ } ++ ++ return GRUB_EFI_SUCCESS; ++} ++ ++static grub_efi_device_path_t * ++grub_efi_get_media_file_path (grub_efi_device_path_t *dp) ++{ ++ while (1) ++ { ++ grub_efi_uint8_t type; ++ grub_efi_uint8_t subtype; ++ ++ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp)) ++ break; ++ ++ type = GRUB_EFI_DEVICE_PATH_TYPE (dp); ++ subtype = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp); ++ ++ if (type == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE && subtype == GRUB_EFI_FILE_PATH_DEVICE_PATH_SUBTYPE) ++ return dp; ++ ++ dp = GRUB_EFI_NEXT_DEVICE_PATH (dp); ++ } ++ ++ return NULL; ++} ++ ++static grub_efi_boolean_t ++handle_image (struct grub_secureboot_chainloader_context *load_context) ++{ ++ grub_efi_boot_services_t *b; ++ grub_efi_loaded_image_t *li, li_bak; ++ grub_efi_status_t efi_status; ++ void *data = (void *)(unsigned long)load_context->address; ++ grub_efi_uint32_t datasize = load_context->fsize; ++ char *buffer = NULL; ++ char *buffer_aligned = NULL; ++ grub_efi_uint32_t i, size; ++ struct grub_pe32_section_table *section; ++ char *base, *end; ++ pe_coff_loader_image_context_t context; ++ grub_uint32_t section_alignment; ++ grub_uint32_t buffer_size; ++ ++ b = grub_efi_system_table->boot_services; ++ ++ if (read_header (data, datasize, &context)) ++ { ++ grub_dprintf ("chain", "Succeed to read header\n"); ++ } ++ else ++ { ++ grub_dprintf ("chain", "Failed to read header\n"); ++ goto error_exit; ++ } ++ ++ section_alignment = context.pe_hdr->optional_header.section_alignment; ++ buffer_size = context.image_size + section_alignment; ++ ++ efi_status = b->allocate_pool (GRUB_EFI_LOADER_DATA, ++ buffer_size, (void**)&buffer); ++ ++ if (efi_status != GRUB_EFI_SUCCESS) ++ { ++ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory")); ++ goto error_exit; ++ } ++ ++ buffer_aligned = (char *)ALIGN_UP ((grub_addr_t)buffer, section_alignment); ++ ++ grub_memcpy (buffer_aligned, data, context.size_of_headers); ++ ++ section = context.first_section; ++ for (i = 0; i < context.number_of_sections; i++) ++ { ++ size = section->virtual_size; ++ if (size > section->raw_data_size) ++ size = section->raw_data_size; ++ ++ base = image_address (buffer_aligned, context.image_size, section->virtual_address); ++ end = image_address (buffer_aligned, context.image_size, section->virtual_address + size - 1); ++ ++ if (!base || !end) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid section size"); ++ goto error_exit; ++ } ++ ++ if (section->raw_data_size > 0) ++ grub_memcpy (base, (grub_efi_uint8_t*)data + section->raw_data_offset, size); ++ ++ if (size < section->virtual_size) ++ grub_memset (base + size, 0, section->virtual_size - size); ++ ++ grub_dprintf ("chain", "copied section %s\n", section->name); ++ section += 1; ++ } ++ ++ efi_status = relocate_coff (&context, buffer_aligned); ++ ++ if (efi_status != GRUB_EFI_SUCCESS) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "relocation failed"); ++ goto error_exit; ++ } ++ ++ entry_point = image_address (buffer_aligned, context.image_size, context.entry_point); ++ ++ if (!entry_point) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "invalid entry point"); ++ goto error_exit; ++ } ++ ++ li = grub_efi_get_loaded_image (grub_efi_image_handle); ++ if (!li) ++ { ++ grub_error (GRUB_ERR_BAD_ARGUMENT, "no loaded image available"); ++ goto error_exit; ++ } ++ ++ grub_memcpy (&li_bak, li, sizeof (grub_efi_loaded_image_t)); ++ li->image_base = buffer_aligned; ++ li->image_size = context.image_size; ++ li->load_options = load_context->cmdline; ++ li->load_options_size = load_context->cmdline_len; ++ li->file_path = grub_efi_get_media_file_path (load_context->file_path); ++ li->device_handle = load_context->dev_handle; ++ if (li->file_path) ++ { ++ grub_printf ("file path: "); ++ grub_efi_print_device_path (li->file_path); ++ } ++ else ++ { ++ grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file path found"); ++ goto error_exit; ++ } ++ ++ efi_status = entry_point (grub_efi_image_handle, grub_efi_system_table); ++ ++ grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t)); ++ efi_status = b->free_pool (buffer); ++ ++ return 1; ++ ++error_exit: ++ if (buffer) ++ b->free_pool (buffer); ++ ++ return 0; ++ ++} ++ ++static grub_err_t ++grub_secureboot_chainloader_unload (void* context) ++{ ++ grub_efi_boot_services_t *b; ++ struct grub_secureboot_chainloader_context *sb_context = (struct grub_secureboot_chainloader_context *)context; ++ ++ b = grub_efi_system_table->boot_services; ++ b->free_pages (sb_context->address, sb_context->pages); ++ grub_free (sb_context->file_path); ++ grub_free (sb_context->cmdline); ++ grub_free (sb_context); ++ ++ grub_dl_unref (my_mod); ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_secureboot_chainloader_boot (void *context) ++{ ++ struct grub_secureboot_chainloader_context *sb_context = (struct grub_secureboot_chainloader_context *)context; ++ ++ handle_image (sb_context); ++ grub_loader_unset (); ++ return grub_errno; ++} ++#endif ++ + static grub_err_t + grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) +@@ -222,11 +651,12 @@ + grub_efi_loaded_image_t *loaded_image; + char *filename; + void *boot_image = 0; +- grub_efi_handle_t dev_handle = 0; + grub_efi_physical_address_t address = 0; + grub_efi_uintn_t pages = 0; + grub_efi_char16_t *cmdline = NULL; + grub_efi_handle_t image_handle = NULL; ++ grub_ssize_t cmdline_len = 0; ++ grub_efi_handle_t dev_handle = 0; + + if (argc == 0) + return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); +@@ -236,12 +666,39 @@ + + b = grub_efi_system_table->boot_services; + ++ if (argc > 1) ++ { ++ int i; ++ grub_efi_char16_t *p16; ++ ++ for (i = 1, cmdline_len = 0; i < argc; i++) ++ cmdline_len += grub_strlen (argv[i]) + 1; ++ ++ cmdline_len *= sizeof (grub_efi_char16_t); ++ cmdline = p16 = grub_malloc (cmdline_len); ++ if (! cmdline) ++ goto fail; ++ ++ for (i = 1; i < argc; i++) ++ { ++ char *p8; ++ ++ p8 = argv[i]; ++ while (*p8) ++ *(p16++) = *(p8++); ++ ++ *(p16++) = ' '; ++ } ++ *(--p16) = 0; ++ } ++ + file = grub_file_open (filename, GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE); + if (! file) + goto fail; + +- /* Get the root device's device path. */ +- dev = grub_device_open (0); ++ /* Get the device path from filename. */ ++ char *devname = grub_file_get_device_name (filename); ++ dev = grub_device_open (devname); + if (dev == NULL) + ; + else if (dev->disk) +@@ -343,6 +800,28 @@ + } + #endif + ++#ifdef SUPPORT_SECURE_BOOT ++ /* FIXME is secure boot possible also with universal binaries? */ ++ if (debug_secureboot || (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED && grub_secure_validate ((void *)address, size))) ++ { ++ struct grub_secureboot_chainloader_context *sb_context; ++ ++ sb_context = grub_malloc (sizeof (*sb_context)); ++ if (!sb_context) ++ goto fail; ++ sb_context->cmdline = cmdline; ++ sb_context->cmdline_len = cmdline_len; ++ sb_context->fsize = size; ++ sb_context->dev_handle = dev_handle; ++ sb_context->address = address; ++ sb_context->pages = pages; ++ sb_context->file_path = file_path; ++ grub_file_close (file); ++ grub_loader_set_ex (grub_secureboot_chainloader_boot, grub_secureboot_chainloader_unload, sb_context, 0); ++ return 0; ++ } ++#endif ++ + status = b->load_image (0, grub_efi_image_handle, file_path, + boot_image, size, + &image_handle); +@@ -368,33 +847,10 @@ + loaded_image->device_handle = dev_handle; + + /* Build load options with arguments from chainloader command line. */ +- if (argc > 1) ++ if (cmdline) + { +- int i, len; +- grub_efi_char16_t *p16; +- +- for (i = 1, len = 0; i < argc; i++) +- len += grub_strlen (argv[i]) + 1; +- +- len *= sizeof (grub_efi_char16_t); +- cmdline = p16 = grub_malloc (len); +- if (! cmdline) +- goto fail; +- +- for (i = 1; i < argc; i++) +- { +- char *p8; +- +- p8 = argv[i]; +- while (*p8) +- *(p16++) = *(p8++); +- +- *(p16++) = ' '; +- } +- *(--p16) = 0; +- + loaded_image->load_options = cmdline; +- loaded_image->load_options_size = len; ++ loaded_image->load_options_size = cmdline_len; + } + + grub_file_close (file); diff --git a/grub2-secureboot-install-signed-grub.patch b/grub2-secureboot-install-signed-grub.patch new file mode 100644 index 0000000000000000000000000000000000000000..5c3dc5efe42c735f30ac9f6081babd65657f192f --- /dev/null +++ b/grub2-secureboot-install-signed-grub.patch @@ -0,0 +1,225 @@ +From 1ff2f31d12f7235423a1eb8a117e0c6f8b2f41c7 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Tue, 4 Jun 2019 12:32:35 +0800 +Subject: [PATCH] grub-install: handle signed grub installation on arm64-efi + +Use grub2-install to handle signed grub installation for arm64 UEFI secure +boot, the default behavior is auto, which will install signed grub whenever +detected. + +Two options, --suse-force-signed and --suse-inhibit-signed, can be used to +override the default auto detecting behavior. The former will force to use +prebuilt signed image and thus will fail if missing, the latter will always use +'mkimage' to create unsigned core image per the user's running environment. + +Signed-off-by: Michael Chang +--- + util/grub-install.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 85 insertions(+), 1 deletion(-) + +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -85,6 +85,15 @@ + + enum + { ++ SIGNED_GRUB_INHIBIT, ++ SIGNED_GRUB_AUTO, ++ SIGNED_GRUB_FORCE ++ }; ++ ++static int signed_grub_mode = SIGNED_GRUB_AUTO; ++ ++enum ++ { + OPTION_BOOT_DIRECTORY = 0x301, + OPTION_ROOT_DIRECTORY, + OPTION_TARGET, +@@ -109,6 +118,8 @@ + OPTION_NO_BOOTSECTOR, + OPTION_NO_RS_CODES, + OPTION_SUSE_ENABLE_TPM, ++ OPTION_SUSE_FORCE_SIGNED, ++ OPTION_SUSE_INHIBIT_SIGNED, + OPTION_MACPPC_DIRECTORY, + OPTION_ZIPL_DIRECTORY, + OPTION_LABEL_FONT, +@@ -238,6 +249,14 @@ + suse_enable_tpm = 1; + return 0; + ++ case OPTION_SUSE_FORCE_SIGNED: ++ signed_grub_mode = SIGNED_GRUB_FORCE; ++ return 0; ++ ++ case OPTION_SUSE_INHIBIT_SIGNED: ++ signed_grub_mode = SIGNED_GRUB_INHIBIT; ++ return 0; ++ + case OPTION_DEBUG: + verbosity++; + return 0; +@@ -300,7 +319,12 @@ + N_("Do not apply any reed-solomon codes when embedding core.img. " + "This option is only available on x86 BIOS targets."), 0}, + {"suse-enable-tpm", OPTION_SUSE_ENABLE_TPM, 0, 0, N_("install TPM modules"), 0}, +- ++ {"suse-force-signed", OPTION_SUSE_FORCE_SIGNED, 0, 0, ++ N_("force installation of signed grub" "%s." ++ "This option is only available on ARM64 EFI targets."), 0}, ++ {"suse-inhibit-signed", OPTION_SUSE_INHIBIT_SIGNED, 0, 0, ++ N_("inhibit installation of signed grub. " ++ "This option is only available on ARM64 EFI targets."), 0}, + {"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2}, + {"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2}, + {"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2}, +@@ -375,6 +399,22 @@ + free (plats); + return ret; + } ++ case OPTION_SUSE_FORCE_SIGNED: ++ { ++ const char *t = get_default_platform (); ++ char *ret; ++ if (grub_strcmp (t, "arm64-efi") == 0) ++ { ++ char *s = grub_util_path_concat (3, grub_util_get_pkglibdir (), t, "grub.efi"); ++ char *text2 = xasprintf (" [default=%s]", s); ++ ret = xasprintf (text, text2); ++ free (text2); ++ free (s); ++ } ++ else ++ ret = xasprintf (text, ""); ++ return ret; ++ } + case ARGP_KEY_HELP_POST_DOC: + return xasprintf (text, program_name, GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME); + default: +@@ -1681,13 +1721,34 @@ + + char mkimage_target[200]; + const char *core_name = NULL; ++ char *signed_imgfile = NULL; + + switch (platform) + { ++ case GRUB_INSTALL_PLATFORM_ARM64_EFI: ++ ++ if (signed_grub_mode > SIGNED_GRUB_INHIBIT) ++ { ++ signed_imgfile = grub_util_path_concat (2, grub_install_source_directory, "grub.efi"); ++ if (!grub_util_is_regular (signed_imgfile)) ++ { ++ if (signed_grub_mode >= SIGNED_GRUB_FORCE) ++ grub_util_error ("signed image `%s' does not exist\n", signed_imgfile); ++ else ++ { ++ free (signed_imgfile); ++ signed_imgfile = NULL; ++ } ++ } ++ } ++ ++ if (signed_imgfile) ++ fprintf (stderr, _("Use signed file in %s for installation.\n"), signed_imgfile); ++ ++ /* fallthrough. */ + case GRUB_INSTALL_PLATFORM_I386_EFI: + case GRUB_INSTALL_PLATFORM_X86_64_EFI: + case GRUB_INSTALL_PLATFORM_ARM_EFI: +- case GRUB_INSTALL_PLATFORM_ARM64_EFI: + case GRUB_INSTALL_PLATFORM_LOONGARCH64_EFI: + case GRUB_INSTALL_PLATFORM_RISCV32_EFI: + case GRUB_INSTALL_PLATFORM_RISCV64_EFI: +@@ -1758,13 +1819,75 @@ + core_name); + char *prefix = xasprintf ("%s%s", prefix_drive ? : "", + relative_grubdir); +- if (core_name != mkimage_target) ++ char *grub_efi_cfg = NULL; ++ ++ if ((core_name != mkimage_target) && !signed_imgfile) + grub_install_make_image_wrap (/* source dir */ grub_install_source_directory, + /*prefix */ prefix, + /* output */ imgfile, + /* memdisk */ NULL, + have_load_cfg ? load_cfg : NULL, + /* image target */ mkimage_target, 0); ++ else if (signed_imgfile) ++ { ++ FILE *grub_cfg_f; ++ ++ grub_install_copy_file (signed_imgfile, imgfile, 1); ++ grub_efi_cfg = grub_util_path_concat (2, platdir, "grub.cfg"); ++ grub_cfg_f = grub_util_fopen (grub_efi_cfg, "wb"); ++ if (!grub_cfg_f) ++ grub_util_error (_("Can't create file: %s"), strerror (errno)); ++ ++ if (have_abstractions) ++ { ++ fprintf (grub_cfg_f, "set prefix=(%s)%s\n", grub_drives[0], relative_grubdir); ++ fprintf (grub_cfg_f, "set root=%s\n", grub_drives[0]); ++ } ++ else if (prefix_drive) ++ { ++ char *uuid = NULL; ++ if (grub_fs->fs_uuid && grub_fs->fs_uuid (grub_dev, &uuid)) ++ { ++ grub_print_error (); ++ grub_errno = 0; ++ uuid = NULL; ++ } ++ if (!uuid) ++ grub_util_error ("cannot find fs uuid for %s", grub_fs->name); ++ ++ fprintf (grub_cfg_f, "search --fs-uuid --set=root %s\n", uuid); ++ fprintf (grub_cfg_f, "set prefix=($root)%s\n", relative_grubdir); ++ } ++ ++ if (have_load_cfg) ++ { ++ size_t len; ++ char *buf; ++ ++ FILE *fp = grub_util_fopen (load_cfg, "rb"); ++ if (!fp) ++ grub_util_error (_("Can't read file: %s"), strerror (errno)); ++ ++ fseek (fp, 0, SEEK_END); ++ len = ftell (fp); ++ fseek (fp, 0, SEEK_SET); ++ buf = xmalloc (len); ++ ++ if (fread (buf, 1, len, fp) != len) ++ grub_util_error (_("cannot read `%s': %s"), load_cfg, strerror (errno)); ++ ++ if (fwrite (buf, 1, len, grub_cfg_f) != len) ++ grub_util_error (_("cannot write `%s': %s"), grub_efi_cfg, strerror (errno)); ++ ++ free (buf); ++ fclose (fp); ++ } ++ ++ fprintf (grub_cfg_f, "source ${prefix}/grub.cfg\n"); ++ fclose (grub_cfg_f); ++ free (signed_imgfile); ++ signed_imgfile = NULL; ++ } + /* Backward-compatibility kludges. */ + switch (platform) + { +@@ -2061,6 +2184,13 @@ + grub_set_install_backup_ponr (); + + free (dst); ++ if (grub_efi_cfg) ++ { ++ dst = grub_util_path_concat (2, efidir, "grub.cfg"); ++ grub_install_copy_file (grub_efi_cfg, dst, 1); ++ free (dst); ++ free (grub_efi_cfg); ++ } + } + if (!removable && update_nvram) + { diff --git a/grub2-secureboot-no-insmod-on-sb.patch b/grub2-secureboot-no-insmod-on-sb.patch new file mode 100644 index 0000000000000000000000000000000000000000..63934069889dfc7c95de3df7457ee5d009f7d495 --- /dev/null +++ b/grub2-secureboot-no-insmod-on-sb.patch @@ -0,0 +1,51 @@ +From 29c89e27805f7a6a22bce11ed9bb430e19c972a9 Mon Sep 17 00:00:00 2001 +From: Colin Watson +Date: Tue, 23 Oct 2012 10:40:49 -0400 +Subject: [PATCH 449/482] Don't allow insmod when secure boot is enabled. + +References: fate#314485 +Patch-Mainline: no + +v2: +Use grub_efi_get_secureboot to get secure boot status + +Signed-off-by: Michael Chang +--- + grub-core/kern/dl.c | 17 +++++++++++++++++ + grub-core/kern/efi/efi.c | 28 ++++++++++++++++++++++++++++ + include/grub/efi/efi.h | 1 + + 3 files changed, 46 insertions(+) + +--- a/grub-core/kern/dl.c ++++ b/grub-core/kern/dl.c +@@ -38,6 +38,10 @@ + #define GRUB_MODULES_MACHINE_READONLY + #endif + ++#ifdef GRUB_MACHINE_EFI ++#include ++#endif ++ + + + #pragma GCC diagnostic ignored "-Wcast-align" +@@ -708,6 +712,19 @@ + + grub_boot_time ("Loading module %s", filename); + ++#ifdef GRUB_MACHINE_EFI ++ if (grub_efi_get_secureboot () == GRUB_EFI_SECUREBOOT_MODE_ENABLED) ++ { ++#if 0 ++ /* This is an error, but grub2-mkconfig still generates a pile of ++ * insmod commands, so emitting it would be mostly just obnoxious. */ ++ grub_error (GRUB_ERR_ACCESS_DENIED, ++ "Secure Boot forbids loading module from %s", filename); ++#endif ++ return 0; ++ } ++#endif ++ + file = grub_file_open (filename, GRUB_FILE_TYPE_GRUB_MODULE); + if (! file) + return 0; diff --git a/grub2-setup-try-fs-embed-if-mbr-gap-too-small.patch b/grub2-setup-try-fs-embed-if-mbr-gap-too-small.patch new file mode 100644 index 0000000000000000000000000000000000000000..30362ae27ed6e97ba5aa387a1c41e4c973e9a913 --- /dev/null +++ b/grub2-setup-try-fs-embed-if-mbr-gap-too-small.patch @@ -0,0 +1,61 @@ + +V2: Add fs_ prefix to fs functions by upstream commit ad4bfee + +Index: grub-2.06~rc1/util/setup.c +=================================================================== +--- grub-2.06~rc1.orig/util/setup.c ++++ grub-2.06~rc1/util/setup.c +@@ -530,8 +530,42 @@ SETUP (const char *dir, + err = grub_util_ldm_embed (dest_dev->disk, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); + else if (ctx.dest_partmap) +- err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec, +- GRUB_EMBED_PCBIOS, §ors, warn_small); ++ { ++ err = ctx.dest_partmap->embed (dest_dev->disk, &nsec, maxsec, ++ GRUB_EMBED_PCBIOS, §ors, warn_small); ++#ifdef GRUB_SETUP_BIOS ++ if ((err == GRUB_ERR_OUT_OF_RANGE || err == GRUB_ERR_FILE_NOT_FOUND) ++ && dest_dev->disk->id == root_dev->disk->id ++ && dest_dev->disk->dev->id == root_dev->disk->dev->id) ++ { ++ grub_fs_t root_fs; ++ ++ root_fs = grub_fs_probe (root_dev); ++ if (root_fs && root_fs->fs_embed) ++ { ++ grub_disk_addr_t *fs_sectors; ++ unsigned int fs_nsec; ++ ++ fs_sectors = NULL; ++ fs_nsec = core_sectors; ++ err = root_fs->fs_embed (root_dev, &fs_nsec, maxsec, ++ GRUB_EMBED_PCBIOS, &fs_sectors); ++ if (!err && fs_nsec >= core_sectors) ++ { ++ sectors = fs_sectors; ++ nsec = fs_nsec; ++ ctx.container = root_dev->disk->partition; ++ core_dev = root_dev; ++ } ++ else ++ { ++ if (fs_sectors) ++ grub_free (fs_sectors); ++ } ++ } ++ } ++#endif ++ } + else + err = fs->fs_embed (dest_dev, &nsec, maxsec, + GRUB_EMBED_PCBIOS, §ors); +@@ -643,7 +677,7 @@ SETUP (const char *dir, + + /* Write the core image onto the disk. */ + for (i = 0; i < nsec; i++) +- grub_disk_write (dest_dev->disk, sectors[i], 0, ++ grub_disk_write (core_dev->disk, sectors[i], 0, + GRUB_DISK_SECTOR_SIZE, + core_img + i * GRUB_DISK_SECTOR_SIZE); + #endif diff --git a/grub2-simplefb.patch b/grub2-simplefb.patch new file mode 100644 index 0000000000000000000000000000000000000000..8ea4759075abeb46a726ac82bb1d4a10d8657ecc --- /dev/null +++ b/grub2-simplefb.patch @@ -0,0 +1,13 @@ + + +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -116,7 +116,7 @@ + # FIXME: We need an interface to select vesafb in case efifb can't be used. + if [ "x$GRUB_GFXPAYLOAD_LINUX" = x ]; then + echo " load_video" | sed "s/^/$submenu_indentation/" +- if grep -qx "CONFIG_FB_EFI=y" "${config}" 2> /dev/null \ ++ if grep -qx "CONFIG_\(FB_EFI\|SYSFB_SIMPLEFB\)=y" "${config}" 2> /dev/null \ + && grep -qx "CONFIG_VT_HW_CONSOLE_BINDING=y" "${config}" 2> /dev/null; then + echo " set gfxpayload=keep" | sed "s/^/$submenu_indentation/" + fi diff --git a/grub2-suse-remove-linux-root-param.patch b/grub2-suse-remove-linux-root-param.patch new file mode 100644 index 0000000000000000000000000000000000000000..b25cd9e902c20827c42bac20401af5b82728379a --- /dev/null +++ b/grub2-suse-remove-linux-root-param.patch @@ -0,0 +1,75 @@ +--- a/util/grub-mkconfig.in ++++ b/util/grub-mkconfig.in +@@ -299,7 +299,8 @@ + GRUB_OS_PROBER_SKIP_LIST \ + GRUB_DISABLE_SUBMENU \ + SUSE_BTRFS_SNAPSHOT_BOOTING \ +- SUSE_CMDLINE_XENEFI ++ SUSE_CMDLINE_XENEFI \ ++ SUSE_REMOVE_LINUX_ROOT_PARAM + + if test "x${grub_cfg}" != "x"; then + rm -f "${grub_cfg}.new" +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -76,7 +76,7 @@ + else + rootsubvol="`make_system_path_relative_to_its_root /`" + rootsubvol="${rootsubvol#/}" +- if [ "x${rootsubvol}" != x ]; then ++ if [ "x${rootsubvol}" != x ] && [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" != "xtrue" ]; then + GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}" + fi + fi;; +@@ -87,6 +87,10 @@ + ;; + esac + ++if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then ++ LINUX_ROOT_DEVICE="" ++fi ++ + title_correction_code= + + hotkey=1 +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -100,7 +100,7 @@ + else + rootsubvol="`make_system_path_relative_to_its_root /`" + rootsubvol="${rootsubvol#/}" +- if [ "x${rootsubvol}" != x ]; then ++ if [ "x${rootsubvol}" != x ] && [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" != "xtrue" ]; then + GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}" + fi + fi;; +@@ -111,6 +111,10 @@ + ;; + esac + ++if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then ++ LINUX_ROOT_DEVICE="" ++fi ++ + title_correction_code= + + grub2_unquote () +--- a/util/s390x/zipl2grub.pl.in ++++ b/util/s390x/zipl2grub.pl.in +@@ -384,9 +384,13 @@ + } else { + $v = ""; + } +- if ($k eq "GRUB_DEVICE" && $v !~ /^UUID/ && ! -e $v) { +- s{root=\@$k\@}{}g; +- next; ++ if ($k eq "GRUB_DEVICE") { ++ if (($v !~ /^UUID/ && ! -e $v) || ++ (exists( $C{SUSE_REMOVE_LINUX_ROOT_PARAM}) && ++ $C{SUSE_REMOVE_LINUX_ROOT_PARAM} eq "true")) { ++ s{root=\@$k\@}{}g; ++ next; ++ } + } + s{\@$k\@}{$v}g; + } diff --git a/grub2-use-Unifont-for-starfield-theme-terminal.patch b/grub2-use-Unifont-for-starfield-theme-terminal.patch new file mode 100644 index 0000000000000000000000000000000000000000..b0ddea53ab9613e5536b144335755506d40ad8a1 --- /dev/null +++ b/grub2-use-Unifont-for-starfield-theme-terminal.patch @@ -0,0 +1,15 @@ +DejaVu Sans is proportional font and looks pretty bad in terminal +window. Use GNU Unifont instead. +Index: grub-2.02~beta2/themes/starfield/theme.txt +=================================================================== +--- grub-2.02~beta2.orig/themes/starfield/theme.txt ++++ grub-2.02~beta2/themes/starfield/theme.txt +@@ -25,7 +25,7 @@ message-font: "DejaVu Sans Regular 12" + message-color: "#000" + message-bg-color: "#fff" + terminal-box: "terminal_box_*.png" +-terminal-font: "DejaVu Sans Regular 12" ++terminal-font: "Gnu Unifont Mono Regular 16" + desktop-image: "starfield.png" + + #help bar at the bottom diff --git a/grub2-use-rpmsort-for-version-sorting.patch b/grub2-use-rpmsort-for-version-sorting.patch new file mode 100644 index 0000000000000000000000000000000000000000..740019c904945f3d4c8b708add9bf51907401b7d --- /dev/null +++ b/grub2-use-rpmsort-for-version-sorting.patch @@ -0,0 +1,143 @@ +v2: +Fix wrong sorting order if version contains "-" delimiter + +--- a/util/grub-mkconfig_lib.in ++++ b/util/grub-mkconfig_lib.in +@@ -203,12 +203,17 @@ + version_sort () + { + case $version_sort_sort_has_v in ++ rpmsort) ++ LC_ALL=C /usr/lib/rpm/rpmsort "$@";; + yes) + LC_ALL=C sort -V "$@";; + no) + LC_ALL=C sort -n "$@";; + *) +- if sort -V /dev/null 2>&1; then ++ if test -x /usr/lib/rpm/rpmsort; then ++ version_sort_sort_has_v=rpmsort ++ LC_ALL=C /usr/lib/rpm/rpmsort "$@" ++ elif sort -V /dev/null 2>&1; then + version_sort_sort_has_v=yes + LC_ALL=C sort -V "$@" + else +--- a/util/grub.d/10_linux.in ++++ b/util/grub.d/10_linux.in +@@ -229,12 +229,56 @@ + # yet, so it's empty. In a submenu it will be equal to '\t' (one tab). + submenu_indentation="" + ++listvrf="" ++pre_sort () { ++ local l="" ++ ++ for f in $list; do ++ vr="`echo $f | sed -e 's/[^-]*-//' -e 's/-\([^0-9]*\)$/\.\1/' -e 's/-/~/g' -e 's/~\([^~]*\)$/-\1/'`" ++ l="$l $vr" ++ listvrf="$listvrf $vr:$f" ++ done ++ ++ list=$l ++} ++ ++post_sort () { ++ local l="" ++ local vr="" ++ local f="" ++ local found="" ++ ++ for i in $reverse_sorted_list; do ++ found="" ++ for vrf in $listvrf; do ++ vr=${vrf%%:*} ++ f=${vrf#*:} ++ if test x"$vr" = x"$i"; then ++ l="$l $f" ++ found=$vrf ++ break ++ fi ++ done ++ if test -n "$found"; then ++ listvrf="`echo $listvrf | (sed -e 's!'$found'!!' 2>/dev/null || echo $listvrf)`" ++ fi ++ done ++ ++ for vrf in $listvrf; do ++ f=${vrf#*:} ++ l="$l $f" ++ done ++ ++ reverse_sorted_list=$l ++} ++pre_sort + # Perform a reverse version sort on the entire list. + # Temporarily replace the '.old' suffix by ' 1' and append ' 2' for all + # other files to order the '.old' files after their non-old counterpart + # in reverse-sorted order. + + reverse_sorted_list=$(echo $list | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//') ++post_sort + + if [ "x$GRUB_TOP_LEVEL" != x ]; then + reverse_sorted_list=$(grub_move_to_front "$GRUB_TOP_LEVEL" ${reverse_sorted_list}) +--- a/util/grub.d/20_linux_xen.in ++++ b/util/grub.d/20_linux_xen.in +@@ -255,13 +255,57 @@ + # yet, so it's empty. In a submenu it will be equal to '\t' (one tab). + submenu_indentation="" + ++listvrf="" ++pre_sort () { ++ local l="" ++ ++ for f in $linux_list; do ++ vr="`echo $f | sed -e 's/[^-]*-//' -e 's/-\([^0-9]*\)$/\.\1/' -e 's/-/~/g' -e 's/~\([^~]*\)$/-\1/'`" ++ l="$l $vr" ++ listvrf="$listvrf $vr:$f" ++ done ++ ++ linux_list=$l ++} ++ ++post_sort () { ++ local l="" ++ local vr="" ++ local f="" ++ local found="" ++ ++ for i in $reverse_sorted_linux_list; do ++ found="" ++ for vrf in $listvrf; do ++ vr=${vrf%%:*} ++ f=${vrf#*:} ++ if test x"$vr" = x"$i"; then ++ l="$l $f" ++ found=$vrf ++ break ++ fi ++ done ++ if test -n "$found"; then ++ listvrf="`echo $listvrf | (sed -e 's!'$found'!!' 2>/dev/null || echo $listvrf)`" ++ fi ++ done ++ ++ for vrf in $listvrf; do ++ f=${vrf#*:} ++ l="$l $f" ++ done ++ ++ reverse_sorted_linux_list=$l ++} + # Perform a reverse version sort on the entire xen_list and linux_list. + # Temporarily replace the '.old' suffix by ' 1' and append ' 2' for all + # other files to order the '.old' files after their non-old counterpart + # in reverse-sorted order. + + reverse_sorted_xen_list=$(echo ${xen_list} | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//') ++pre_sort + reverse_sorted_linux_list=$(echo ${linux_list} | tr ' ' '\n' | sed -e 's/\.old$/ 1/; / 1$/! s/$/ 2/' | version_sort -r | sed -e 's/ 1$/.old/; s/ 2$//') ++post_sort + + if [ "x$GRUB_TOP_LEVEL_XEN" != x ]; then + reverse_sorted_xen_list=$(grub_move_to_front "$GRUB_TOP_LEVEL_XEN" ${reverse_sorted_xen_list}) diff --git a/grub2-util-30_os-prober-multiple-initrd.patch b/grub2-util-30_os-prober-multiple-initrd.patch new file mode 100644 index 0000000000000000000000000000000000000000..9b87a25fe77afcf2035f29a3e10fbaa9077d4e65 --- /dev/null +++ b/grub2-util-30_os-prober-multiple-initrd.patch @@ -0,0 +1,11 @@ +--- a/util/grub.d/30_os-prober.in ++++ b/util/grub.d/30_os-prober.in +@@ -223,7 +223,7 @@ + + if [ "${LROOT}" != "${LBOOT}" ]; then + LKERNEL="${LKERNEL#/boot}" +- LINITRD="${LINITRD#/boot}" ++ LINITRD="$(echo $LINITRD | sed -e 's!^/boot!!' -e 's!\(\s\)/boot!\1!g')" + fi + + onstr="$(gettext_printf "(on %s)" "${DEVICE}")" diff --git a/grub2-vbe-blacklist-preferred-1440x900x32.patch b/grub2-vbe-blacklist-preferred-1440x900x32.patch new file mode 100644 index 0000000000000000000000000000000000000000..84f3758d1f43e45bdd3c7a7810541dc8fe0d028c --- /dev/null +++ b/grub2-vbe-blacklist-preferred-1440x900x32.patch @@ -0,0 +1,18 @@ +--- a/grub-core/video/i386/pc/vbe.c ++++ b/grub-core/video/i386/pc/vbe.c +@@ -1054,6 +1054,15 @@ + || vbe_mode_info.y_resolution > height) + /* Resolution exceeds that of preferred mode. */ + continue; ++ ++ /* Blacklist 1440x900x32 from preferred mode handling until a ++ better solution is available. This mode causes problems on ++ many Thinkpads. ++ */ ++ if (vbe_mode_info.x_resolution == 1440 && ++ vbe_mode_info.y_resolution == 900 && ++ vbe_mode_info.bits_per_pixel == 32) ++ continue; + } + else + { diff --git a/grub2-video-limit-the-resolution-for-fixed-bimap-font.patch b/grub2-video-limit-the-resolution-for-fixed-bimap-font.patch new file mode 100644 index 0000000000000000000000000000000000000000..7ef985353a5e0b225ff230223c899cd009bd0253 --- /dev/null +++ b/grub2-video-limit-the-resolution-for-fixed-bimap-font.patch @@ -0,0 +1,86 @@ +From 5f7f27d1198ef425f4943cc10132509415bbaf55 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Thu, 24 Jan 2019 16:41:04 +0800 +Subject: [PATCH] video: limit the resolution for fixed bimap font + +As grub uses fixed bitmap font and also its size is a fixed property, it is not +possible to accommodate to all resolutions, therefore we raise some limit to +the preferred resolution as most themes are designed on popular device and the +resolution in its prime, which is supposedly Full HD. + +This change also makes grub font readable on hiDPI device without going through +the steps in. + +https://wiki.archlinux.org/index.php/HiDPI#GRUB + +v2: efi_gop: Avoid high resolution when trying to keep current mode. + +--- + grub-core/video/efi_gop.c | 7 +++++++ + grub-core/video/i386/pc/vbe.c | 8 +++++++- + 2 files changed, 14 insertions(+), 1 deletion(-) + +--- a/grub-core/video/efi_gop.c ++++ b/grub-core/video/efi_gop.c +@@ -358,7 +358,7 @@ + grub_err_t err; + unsigned bpp; + int found = 0; +- int avoid_low_resolution = 1; ++ int avoid_extreme_resolution = 1; + unsigned long long best_volume = 0; + unsigned int preferred_width = 0, preferred_height = 0; + grub_uint8_t *buffer; +@@ -375,13 +375,21 @@ + preferred_height = 600; + grub_errno = GRUB_ERR_NONE; + } ++ else ++ { ++ /* Limit the range of preferred resolution not exceeding FHD ++ to keep the fixed bitmap font readable */ ++ preferred_width = (preferred_width < 1920) ? preferred_width : 1920; ++ preferred_height = (preferred_height < 1080) ? preferred_height : 1080; ++ } + } + + again: + /* Keep current mode if possible. */ + if (gop->mode->info && +- (!avoid_low_resolution || +- (gop->mode->info->width >= 800 && gop->mode->info->height >= 600))) ++ (!avoid_extreme_resolution || ++ ((gop->mode->info->width >= 800 && gop->mode->info->height >= 600) && ++ (gop->mode->info->width <= 1920 && gop->mode->info->height <= 1080)))) + { + bpp = grub_video_gop_get_bpp (gop->mode->info); + if (bpp && ((width == gop->mode->info->width +@@ -454,9 +462,9 @@ + + if (!found) + { +- if (avoid_low_resolution && gop->mode->info) ++ if (avoid_extreme_resolution && gop->mode->info) + { +- avoid_low_resolution = 0; ++ avoid_extreme_resolution = 0; + goto again; + } + grub_dprintf ("video", "GOP: no mode found\n"); +--- a/grub-core/video/i386/pc/vbe.c ++++ b/grub-core/video/i386/pc/vbe.c +@@ -994,7 +994,13 @@ + { + grub_vbe_get_preferred_mode (&width, &height); + if (grub_errno == GRUB_ERR_NONE) +- preferred_mode = 1; ++ { ++ preferred_mode = 1; ++ /* Limit the range of preferred resolution not exceeding FHD ++ to keep the fixed bitmap font readable */ ++ width = (width < 1920) ? width : 1920; ++ height = (height < 1080) ? height : 1080; ++ } + else + { + /* Fall back to 640x480. This is conservative, but the largest diff --git a/grub2-xen-linux16.patch b/grub2-xen-linux16.patch new file mode 100644 index 0000000000000000000000000000000000000000..85a92d1b08d5fc7456b4ad89b0e26db4e40f8959 --- /dev/null +++ b/grub2-xen-linux16.patch @@ -0,0 +1,29 @@ +--- a/grub-core/loader/i386/xen.c ++++ b/grub-core/loader/i386/xen.c +@@ -961,7 +961,7 @@ + return grub_errno; + } + +-static grub_command_t cmd_xen, cmd_initrd, cmd_module, cmd_multiboot; ++static grub_command_t cmd_xen, cmd_initrd, cmd_module, cmd_multiboot, cmd_xen16, cmd_initrd16; + + GRUB_MOD_INIT (xen) + { +@@ -973,6 +973,10 @@ + 0, N_("Load initrd.")); + cmd_module = grub_register_command ("module", grub_cmd_module, + 0, N_("Load module.")); ++ cmd_xen16 = grub_register_command ("linux16", grub_cmd_xen, ++ 0, N_("Load Linux.")); ++ cmd_initrd16 = grub_register_command ("initrd16", grub_cmd_initrd, ++ 0, N_("Load initrd.")); + my_mod = mod; + } + +@@ -982,4 +986,6 @@ + grub_unregister_command (cmd_initrd); + grub_unregister_command (cmd_multiboot); + grub_unregister_command (cmd_module); ++ grub_unregister_command (cmd_xen16); ++ grub_unregister_command (cmd_initrd16); + } diff --git a/grub2-zipl-setup-fix-btrfs-multipledev.patch b/grub2-zipl-setup-fix-btrfs-multipledev.patch new file mode 100644 index 0000000000000000000000000000000000000000..895103d336c53d3b230c4e5400d662efd564e7d4 --- /dev/null +++ b/grub2-zipl-setup-fix-btrfs-multipledev.patch @@ -0,0 +1,17 @@ +--- + util/s390x/zipl2grub.pl.in | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/util/s390x/zipl2grub.pl.in ++++ b/util/s390x/zipl2grub.pl.in +@@ -384,6 +384,10 @@ while ( ) { + } else { + $v = ""; + } ++ if ($k eq "GRUB_DEVICE" && $v !~ /^UUID/ && ! -e $v) { ++ s{root=\@$k\@}{}g; ++ next; ++ } + s{\@$k\@}{$v}g; + } + Info( 3, $_); diff --git a/grub2.spec b/grub2.spec index 371b97979601d49d2282c7667ed50a8b21d49280..ac7ad946b335b157885c48f6f43e44a4db1139ee 100644 --- a/grub2.spec +++ b/grub2.spec @@ -1,56 +1,57 @@ -%define anolis_release 14 -%global _lto_cflags %{nil} - +%define anolis_release 2 %undefine _hardened_build -%undefine _package_note_file -%global tarversion 2.06 +%if "0%{?product_family}" == "0" +%define efi_vendor %{_vendor} +%else +%define efi_vendor %{product_family} +%endif + +%global tarversion 2.12 %undefine _missing_build_ids_terminate_build %global _configure_gnuconfig_hack 0 -%global gnulibversion 9f48fb992a3d7e96610c4ce8be969cff2d61a01b +%global gnulibversion fixes Name: grub2 Epoch: 1 -Version: 2.06 +Version: 2.12 Release: %{anolis_release}%{?dist} Summary: Bootloader with support for Linux, Multiboot and more License: GPLv3+ URL: http://www.gnu.org/software/grub/ Source0: https://ftp.gnu.org/gnu/grub/grub-%{tarversion}.tar.xz Source1: grub.macros -Source2: gnulib-%{gnulibversion}.tar.gz -Source3: 99-grub-mkconfig.install +Source2: grub.patches Source4: http://unifoundry.com/pub/unifont/unifont-13.0.06/font-builds/unifont-13.0.06.pcf.gz Source5: theme.tar.bz2 Source6: gitignore -Source7: bootstrap -Source8: bootstrap.conf +Source7: 99-grub-mkconfig.install +Source8: gnulib-%{gnulibversion}.tar.gz Source9: strtoull_test.c Source10: 20-grub.install -Source11: grub.patches -Source12: sbat.csv.in +Source11: bootstrap +Source12: bootstrap.conf +Source13: sbat.csv.in +Source14: config_for_secure %include %{SOURCE1} +%include %{SOURCE2} + +BuildRequires: gcc efi-srpm-macros flex bison binutils python3 ncurses-devel xz-devel +BuildRequires: freetype-devel libusb-devel bzip2-devel rpm-devel rpm-libs +BuildRequires: autoconf automake device-mapper-devel freetype-devel git +BuildRequires: texinfo gettext-devel dejavu-sans-fonts help2man systemd fuse-devel +BuildRequires: libtasn1-devel -BuildRequires: gcc efi-srpm-macros -BuildRequires: flex bison binutils python3 -BuildRequires: ncurses-devel xz-devel bzip2-devel -BuildRequires: freetype-devel -BuildRequires: fuse-devel -BuildRequires: rpm-devel rpm-libs -BuildRequires: autoconf automake device-mapper-devel -BuildRequires: freetype-devel gettext-devel git -BuildRequires: texinfo -BuildRequires: dejavu-sans-fonts -BuildRequires: help2man -BuildRequires: systemd %ifarch %{efi_arch} BuildRequires: pesign >= 0.99-8 %endif +%if %{?_with_ccache: 1}%{?!_with_ccache: 0} +BuildRequires: ccache +%endif Obsoletes: %{name} <= %{evr} -Obsoletes: grub < 1:0.98 %if 0%{with_legacy_arch} Requires: %{name}-%{legacy_package_arch} = %{evr} @@ -58,28 +59,25 @@ Requires: %{name}-%{legacy_package_arch} = %{evr} Requires: %{name}-%{package_arch} = %{evr} %endif -%global desc \ -The GRand Unified Bootloader (GRUB) is a highly configurable and \ -customizable bootloader with modular architecture. It supports a rich \ -variety of kernel formats, file systems, computer architectures and \ -hardware devices.\ %{nil} -# generate with do-rebase -%include %{SOURCE11} - %description -%{desc} +GNU GRUB is a Multiboot boot loader. It was derived from GRUB, the GRand +Unified Bootloader, which was originally designed and implemented by +Erich Stefan Boleyn. + +Briefly, a boot loader is the first software program that runs when a +computer starts. It is responsible for loading and transferring control +to the operating system kernel software (such as the Hurd or Linux). The +kernel, in turn, initializes the rest of the operating system (e.g. GNU). %package common -Summary: grub2 common layout +Summary: common package for grub2 BuildArch: noarch -Conflicts: grubby < 8.40 -Requires(post): util-linux +Conflicts: grubby < 8.40-18 %description common -This package provides some directories which are required by various grub2 -subpackages. +Common package for grub2. %package doc Summary: Documentation files for %{name} @@ -89,50 +87,46 @@ BuildArch: noarch %description doc The %{name}-doc package contains documentation files for %{name}. -%package tools -Summary: Support tools for GRUB. +%package tools +Summary: tools package for grub2 Obsoletes: %{name}-tools < %{evr} -Requires: %{name}-common = %{epoch}:%{version}-%{release} -Requires: gettext-runtime os-prober which file -Requires(pre): dracut -Requires(post): dracut - -%description tools -%{desc} -This subpackage provides tools for support of all platforms. +Requires: %{name}-common = %{epoch}:%{version}-%{release} +Requires: gettext os-prober which file +Requires(pre): dracut +Requires(post): dracut -%ifarch x86_64 -%package tools-efi -Summary: Support tools for GRUB. -Requires: gettext-runtime os-prober which file -Requires: %{name}-common = %{epoch}:%{version}-%{release} -Obsoletes: %{name}-tools < %{evr} +%description tools +tools package for grub2. -%description tools-efi -%{desc} -This subpackage provides tools for support of EFI platforms. -%endif - -%package tools-minimal -Summary: Support tools for GRUB. -Requires: gettext-runtime -Requires: %{name}-common = %{epoch}:%{version}-%{release} -Obsoletes: %{name}-tools < %{evr} +%package tools-minimal +Summary: Support tools for GRUB. +Requires: gettext %{name}-common = %{epoch}:%{version}-%{release} +Obsoletes: %{name}-tools < %{evr} %description tools-minimal -%{desc} -This subpackage provides tools for support of all platforms. +Support tools for GRUB. -%package tools-extra -Summary: Support tools for GRUB. -Requires: gettext-runtime os-prober which file -Requires: %{name}-tools-minimal = %{epoch}:%{version}-%{release} -Requires: %{name}-common = %{epoch}:%{version}-%{release} -Obsoletes: %{name}-tools < %{evr} +%package tools-extra +Summary: Support tools for GRUB. +Requires: gettext os-prober which file +Requires: %{name}-tools-minimal = %{epoch}:%{version}-%{release} +Requires: %{name}-common = %{epoch}:%{version}-%{release} +Obsoletes: %{name}-tools < %{evr} %description tools-extra -%{desc} -This subpackage provides tools for support of all platforms. +Support tools for GRUB. + + +%ifarch x86_64 +%package tools-efi +Summary: efi packages for grub2-tools +Requires: grub2-common = %{epoch}:%{version}-%{release} +Requires: gettext os-prober which file +Obsoletes: grub2-tools < %{evr} + +%description tools-efi +Efi packages for grub2-tools. +%endif %if 0%{with_efi_arch} %{expand:%define_efi_variant %%{package_arch} -o} @@ -150,7 +144,6 @@ Summary: GRUB user-space emulation. Requires: %{name}-tools-minimal = %{epoch}:%{version}-%{release} %description emu -%{desc} This subpackage provides the GRUB user-space emulation support of all platforms. %package emu-modules @@ -158,7 +151,6 @@ Summary: GRUB user-space emulation modules. Requires: %{name}-tools-minimal = %{epoch}:%{version}-%{release} %description emu-modules -%{desc} This subpackage provides the GRUB user-space emulation modules. %endif @@ -169,7 +161,7 @@ mkdir grub-%{grubefiarch}-%{tarversion} grep -A100000 '# stuff "make" creates' .gitignore > grub-%{grubefiarch}-%{tarversion}/.gitignore cp %{SOURCE4} grub-%{grubefiarch}-%{tarversion}/unifont.pcf.gz sed -e "s,@@VERSION@@,%{version},g" -e "s,@@VERSION_RELEASE@@,%{version}-%{release},g" \ - %{SOURCE12} > grub-%{grubefiarch}-%{tarversion}/sbat.csv + %{SOURCE13} > grub-%{grubefiarch}-%{tarversion}/sbat.csv git add grub-%{grubefiarch}-%{tarversion} %endif %if 0%{with_alt_efi_arch} @@ -191,6 +183,11 @@ cp %{SOURCE4} grub-emu-%{tarversion}/unifont.pcf.gz git add grub-emu-%{tarversion} %endif git commit -m "After making subdirs" +sed -i '/videotest_checksum/d' grub-core/tests/lib/functional_test.c +sed -i '/gfxterm_menu/d' grub-core/tests/lib/functional_test.c +sed -i '/cmdline_cat_test/d' grub-core/tests/lib/functional_test.c +git add grub-core/tests/lib/functional_test.c +git commit -m "Disable partial grub_func_test cases" %build %if 0%{with_efi_arch} @@ -205,14 +202,15 @@ git commit -m "After making subdirs" %if 0%{with_emu_arch} %{expand:%do_emu_build} %endif -makeinfo --info --no-split -I docs -o docs/grub-dev.info \ - docs/grub-dev.texi -makeinfo --info --no-split -I docs -o docs/grub.info \ - docs/grub.texi -makeinfo --html --no-split -I docs -o docs/grub-dev.html \ - docs/grub-dev.texi -makeinfo --html --no-split -I docs -o docs/grub.html \ - docs/grub.texi +makeinfo --info --no-split -I docs -o docs/grub-dev.info docs/grub-dev.texi +makeinfo --info --no-split -I docs -o docs/grub.info docs/grub.texi +makeinfo --html --no-split -I docs -o docs/grub-dev.html docs/grub-dev.texi +makeinfo --html --no-split -I docs -o docs/grub.html docs/grub.texi + +%check +pushd %{_builddir}/%{?buildsubdir}/grub-%{grubefiarch}-%{tarversion}/grub-core +make check +popd %install set -e @@ -233,51 +231,58 @@ set -e rm -f $RPM_BUILD_ROOT%{_infodir}/dir ln -s %{name}-set-password ${RPM_BUILD_ROOT}/%{_sbindir}/%{name}-setpassword echo '.so man8/%{name}-set-password.8' > ${RPM_BUILD_ROOT}/%{_datadir}/man/man8/%{name}-setpassword.8 + %ifnarch x86_64 rm -vf ${RPM_BUILD_ROOT}/%{_bindir}/%{name}-render-label rm -vf ${RPM_BUILD_ROOT}/%{_sbindir}/%{name}-bios-setup rm -vf ${RPM_BUILD_ROOT}/%{_sbindir}/%{name}-macbless +%else +pushd %{buildroot}/usr/lib/grub/i386-pc/ +strip kernel.exec +strip lnxboot.image +popd %endif %{expand:%%do_install_protected_file %{name}-tools-minimal} %find_lang grub -# Install kernel-install scripts +mkdir -p %{buildroot}%{_datadir}/grub/themes + install -d -m 0755 %{buildroot}%{_prefix}/lib/kernel/install.d/ -install -D -m 0755 -t %{buildroot}%{_prefix}/lib/kernel/install.d/ %{SOURCE10} -install -D -m 0755 -t %{buildroot}%{_prefix}/lib/kernel/install.d/ %{SOURCE3} +install -m 0755 %{SOURCE10} %{buildroot}%{_prefix}/lib/kernel/install.d +install -m 0755 %{SOURCE7} %{buildroot}%{_prefix}/lib/kernel/install.d + install -d -m 0755 %{buildroot}%{_sysconfdir}/kernel/install.d/ -# Install systemd user service to set the boot_success flag -install -D -m 0755 -t %{buildroot}%{_userunitdir} \ - docs/grub-boot-success.{timer,service} -install -d -m 0755 %{buildroot}%{_userunitdir}/timers.target.wants -ln -s ../grub-boot-success.timer \ - %{buildroot}%{_userunitdir}/timers.target.wants -# Install systemd system-update unit to set boot_indeterminate for offline-upd -install -D -m 0755 -t %{buildroot}%{_unitdir} docs/grub-boot-indeterminate.service -install -d -m 0755 %{buildroot}%{_unitdir}/system-update.target.wants -install -d -m 0755 %{buildroot}%{_unitdir}/reboot.target.wants -ln -s ../grub-boot-indeterminate.service \ - %{buildroot}%{_unitdir}/system-update.target.wants -ln -s ../grub2-systemd-integration.service \ - %{buildroot}%{_unitdir}/reboot.target.wants +install -m 0644 /dev/null %{buildroot}%{_sysconfdir}/kernel/install.d/20-grubby.install +install -m 0644 /dev/null %{buildroot}%{_sysconfdir}/kernel/install.d/90-loaderentry.install + +#install -d -m 0755 %{buildroot}%{_userunitdir}/timers.target.wants +#install -m 0644 docs/grub-boot-success.timer %{buildroot}%{_userunitdir} +#install -m 0644 docs/grub-boot-success.service %{buildroot}%{_userunitdir} + +#install -d -m 0755 %{buildroot}%{_unitdir}/system-update.target.wants +#install -m 0644 docs/grub-boot-indeterminate.service %{buildroot}%{_unitdir} +#ln -s ../grub-boot-indeterminate.service %{buildroot}%{_unitdir}/system-update.target.wants + +#find %{buildroot}%{_unitdir}/ -type f -exec chmod a-x {} \; +mkdir %{buildroot}%{_sysconfdir}/default/grub.d %global finddebugroot "%{_builddir}/%{?buildsubdir}/debug" %global dip RPM_BUILD_ROOT=%{finddebugroot} %{__debug_install_post} -%define __debug_install_post ( \ - mkdir -p %{finddebugroot}/usr \ - mv ${RPM_BUILD_ROOT}/usr/bin %{finddebugroot}/usr/bin \ - mv ${RPM_BUILD_ROOT}/usr/sbin %{finddebugroot}/usr/sbin \ - %{dip} \ - install -m 0755 -d %{buildroot}/usr/lib/ %{buildroot}/usr/src/ \ - cp -al %{finddebugroot}/usr/lib/debug/ \\\ - %{buildroot}/usr/lib/debug/ \ - cp -al %{finddebugroot}/usr/src/debug/ \\\ - %{buildroot}/usr/src/debug/ ) \ - mv %{finddebugroot}/usr/bin %{buildroot}/usr/bin \ - mv %{finddebugroot}/usr/sbin %{buildroot}/usr/sbin \ - %{nil} +%define __debug_install_post ( \ + install -m 0755 -d %{finddebugroot}/usr \ + mv %{buildroot}%{_bindir} %{finddebugroot}%{_bindir} \ + mv %{buildroot}%{_sbindir} %{finddebugroot}%{_sbindir} \ + %{dip} \ + install -m 0755 -d %{buildroot}/usr/lib/ %{buildroot}/usr/src/ \ + cp -al %{finddebugroot}/usr/lib/debug/ \\\ + %{buildroot}/usr/lib/debug/ \ + cp -al %{finddebugroot}/usr/src/debug/ \\\ + %{buildroot}/usr/src/debug/ ) \ + mv %{finddebugroot}%{_bindir} %{buildroot}%{_bindir} \ + mv %{finddebugroot}%{_sbindir} %{buildroot}%{_sbindir} \ + %{nil} %undefine buildsubdir @@ -289,14 +294,16 @@ if [ -f /boot/grub2/user.cfg ]; then elif [ -f %{efi_esp_dir}/user.cfg ]; then if grep -q '^GRUB_PASSWORD=' %{efi_esp_dir}/user.cfg ; then sed -i 's/^GRUB_PASSWORD=/GRUB2_PASSWORD=/' \ - %{efi_esp_dir}/user.cfg + %{efi_esp_dir}/user.cfg fi elif [ -f /etc/grub.d/01_users ] && \ grep -q '^password_pbkdf2 root' /etc/grub.d/01_users ; then if [ -f %{efi_esp_dir}/grub.cfg ]; then + # on EFI we don't get permissions on the file, but + # the directory is protected. grep '^password_pbkdf2 root' /etc/grub.d/01_users | \ sed 's/^password_pbkdf2 root \(.*\)$/GRUB2_PASSWORD=\1/' \ - > %{efi_esp_dir}/user.cfg + > %{efi_esp_dir}/user.cfg fi if [ -f /boot/grub2/grub.cfg ]; then install -m 0600 /dev/null /boot/grub2/user.cfg @@ -307,183 +314,114 @@ elif [ -f /etc/grub.d/01_users ] && \ fi fi -%posttrans common -set -eu - -EFI_HOME=%{efi_esp_dir} -GRUB_HOME=/boot/grub2 -ESP_PATH=/boot/efi +%posttrans tools -if ! mountpoint -q ${ESP_PATH}; then - exit 0 # no ESP mounted, nothing to do -fi - -if test ! -f ${EFI_HOME}/grub.cfg; then - # there's no config in ESP, create one - grub2-mkconfig -o ${EFI_HOME}/grub.cfg -fi - -if grep -q "configfile" ${EFI_HOME}/grub.cfg; then - exit 0 # already unified, nothing to do -fi - -# create a stub grub2 config in EFI -BOOT_UUID=$(grub2-probe --target=fs_uuid ${GRUB_HOME}) -GRUB_DIR=$(grub2-mkrelpath ${GRUB_HOME}) - -cat << EOF > ${EFI_HOME}/grub.cfg.stb -search --no-floppy --fs-uuid --set=dev ${BOOT_UUID} -set prefix=(\$dev)${GRUB_DIR} -export \$prefix -configfile \$prefix/grub.cfg -EOF - -if test -f ${EFI_HOME}/grubenv; then - cp -a ${EFI_HOME}/grubenv ${EFI_HOME}/grubenv.rpmsave - mv --force ${EFI_HOME}/grubenv ${GRUB_HOME}/grubenv +if [ -f /etc/default/grub ]; then + if grep -q '^GRUB_ENABLE_BLSCFG=.*' /etc/default/grub; then + sed -i '/GRUB_ENABLE_BLSCFG=/d' /etc/default/grub + fi fi -cp -a ${EFI_HOME}/grub.cfg ${EFI_HOME}/grub.cfg.rpmsave -cp -a ${EFI_HOME}/grub.cfg ${GRUB_HOME}/ -mv ${EFI_HOME}/grub.cfg.stb ${EFI_HOME}/grub.cfg - %files common -f grub.lang +%defattr(-,root,root) +%license COPYING +%dir /boot/grub2/themes/system +%attr(0700,root,root) %dir /boot/grub2 +%ghost %config(noreplace) /boot/grub2/grubenv +%exclude /boot/grub2/* %dir %{_libdir}/grub/ +%{_datarootdir}/grub/themes/ %attr(0700,root,root) %dir %{_sysconfdir}/grub.d %{_prefix}/lib/kernel/install.d/20-grub.install %{_prefix}/lib/kernel/install.d/99-grub-mkconfig.install -%dir %{_datarootdir}/grub -%exclude %{_datarootdir}/grub/* -%dir /boot/%{name}/themes/ -%dir /boot/%{name}/themes/system -%attr(0700,root,root) %dir /boot/grub2 -%exclude /boot/grub2/* +%{_sysconfdir}/kernel/install.d/*.install %dir %attr(0700,root,root) %{efi_esp_dir} -%exclude %{efi_esp_dir}/* -%ghost %config(noreplace) %verify(not size mode md5 mtime) /boot/grub2/grubenv -%license COPYING - -%files doc -%doc THANKS NEWS INSTALL README TODO docs/grub.html docs/grub-dev.html docs/font_char_metrics.png - -%files tools-minimal -%{_sbindir}/%{name}-get-kernel-settings -%{_sbindir}/%{name}-probe -%{_sbindir}/%{name}-set-default -%{_sbindir}/%{name}-set*password -%{_bindir}/%{name}-editenv -%{_bindir}/%{name}-mkpasswd-pbkdf2 -%{_bindir}/%{name}-mount -%attr(4755, root, root) %{_sbindir}/%{name}-set-bootflag -%attr(0644,root,root) %config(noreplace) /etc/dnf/protected.d/%{name}-tools-minimal.conf - -%{_datadir}/man/man3/%{name}-get-kernel-settings* -%{_datadir}/man/man8/%{name}-set-default* -%{_datadir}/man/man8/%{name}-set*password* -%{_datadir}/man/man1/%{name}-editenv* -%{_datadir}/man/man1/%{name}-mkpasswd-* - -%ifarch x86_64 -%files tools-efi -%{_bindir}/%{name}-glue-efi -%{_bindir}/%{name}-render-label -%{_sbindir}/%{name}-macbless -%{_datadir}/man/man1/%{name}-glue-efi* -%{_datadir}/man/man1/%{name}-render-label* -%{_datadir}/man/man8/%{name}-macbless* -%endif +%{_datadir}/locale/* %files tools +%defattr(-,root,root) %{_sbindir}/%{name}-mkconfig -%{_sbindir}/%{name}-switch-to-blscfg -%{_sbindir}/%{name}-rpm-sort +#%{_sbindir}/%{name}-switch-to-blscfg +#%{_sbindir}/%{name}-rpm-sort %{_sbindir}/%{name}-reboot +%{_sbindir}/%{name}-install +%{_sbindir}/%{name}-sparc64-setup +%{_sbindir}/%{name}-ofpathname +%{_sbindir}/%{name}-probe +%{_bindir}/%{name}-glue-efi %{_bindir}/%{name}-file %{_bindir}/%{name}-menulst2cfg %{_bindir}/%{name}-mkimage %{_bindir}/%{name}-mkrelpath %{_bindir}/%{name}-script-check -%{_sbindir}/%{name}-install -%{_unitdir}/grub-boot-indeterminate.service -%{_unitdir}/system-update.target.wants -%{_unitdir}/%{name}-systemd-integration.service -%{_unitdir}/reboot.target.wants -%{_unitdir}/systemd-logind.service.d -%{_userunitdir}/grub-boot-success.timer -%{_userunitdir}/grub-boot-success.service -%{_userunitdir}/timers.target.wants -%{_sysconfdir}/grub.d/README -%{_libexecdir}/%{name} +#%{_libexecdir}/%{name} -%attr(0644,root,root) %ghost %config(noreplace) %{_sysconfdir}/default/grub %config %{_sysconfdir}/grub.d/??_* +#%exclude %{_sysconfdir}/grub.d/01_fallback_counting +%attr(0644,root,root) %ghost %config(noreplace) %{_sysconfdir}/default/grub +%dir %config(noreplace) %{_sysconfdir}/default/grub.d +%{_sysconfdir}/grub.d/README +#%{_userunitdir}/* +#%{_unitdir}/grub-boot-indeterminate.service +#%{_unitdir}/system-update.target.wants +#%attr(0644,root,root) %{_unitdir}/%{name}-systemd-integration.service +#%dir %{_unitdir}/systemd-logind.service.d +#%attr(0644,root,root) %{_unitdir}/systemd-logind.service.d/* %{_datarootdir}/grub/* +%{_datarootdir}/bash-completion/completions/grub %exclude %{_datarootdir}/grub/themes %exclude %{_datarootdir}/grub/*.h -%{_datarootdir}/bash-completion/completions/grub %{_infodir}/%{name}* -%{_datadir}/man/man?/* - -# exclude man pages from tools-extra -%exclude %{_datadir}/man/man8/%{name}-sparc64-setup* -%exclude %{_datadir}/man/man1/%{name}-fstest* -%exclude %{_datadir}/man/man1/%{name}-glue-efi* -%exclude %{_datadir}/man/man1/%{name}-kbdcomp* -%exclude %{_datadir}/man/man1/%{name}-mkfont* -%exclude %{_datadir}/man/man1/%{name}-mklayout* -%exclude %{_datadir}/man/man1/%{name}-mknetdir* -%exclude %{_datadir}/man/man1/%{name}-mkrescue* -%exclude %{_datadir}/man/man1/%{name}-mkstandalone* -%exclude %{_datadir}/man/man1/%{name}-syslinux2cfg* - -# exclude man pages from tools-minimal -%exclude %{_datadir}/man/man3/%{name}-get-kernel-settings* -%exclude %{_datadir}/man/man8/%{name}-set-default* -%exclude %{_datadir}/man/man8/%{name}-set*password* -%exclude %{_datadir}/man/man1/%{name}-editenv* -%exclude %{_datadir}/man/man1/%{name}-mkpasswd-* -%exclude %{_datadir}/man/man8/%{name}-macbless* -%exclude %{_datadir}/man/man1/%{name}-render-label* + %if %{with_legacy_arch} -%{_sbindir}/%{name}-install +%{_sbindir}/grub2-install %ifarch x86_64 -%{_sbindir}/%{name}-bios-setup +%{_sbindir}/grub2-bios-setup %else %exclude %{_sbindir}/%{name}-bios-setup -%exclude %{_datadir}/man/man8/%{name}-bios-setup* %endif -%exclude %{_sbindir}/%{name}-sparc64-setup -%exclude %{_datadir}/man/man8/%{name}-sparc64-setup* -%exclude %{_sbindir}/%{name}-ofpathname -%exclude %{_datadir}/man/man8/%{name}-ofpathname* +%ifarch %{sparc} +%{_sbindir}/grub2-sparc64-setup +%{_sbindir}/grub2-ofpathname +%else +%exclude %{_sbindir}/grub2-sparc64-setup +%exclude %{_sbindir}/grub2-ofpathname +%endif %endif +%files tools-minimal +%defattr(-,root,root) +#%attr(4755, root, root) %{_sbindir}/%{name}-set-bootflag +#%{_sbindir}/%{name}-get-kernel-settings +%{_sbindir}/%{name}-set*password +%{_sbindir}/%{name}-set-default +%{_bindir}/%{name}-editenv +%{_bindir}/%{name}-mkpasswd-pbkdf2 +%{_bindir}/%{name}-mount +%attr(0644,root,root) %config(noreplace) /etc/dnf/protected.d/%{name}-tools-minimal.conf + %files tools-extra +%defattr(-,root,root) +%{_sysconfdir}/sysconfig/grub %{_bindir}/%{name}-fstest %{_bindir}/%{name}-kbdcomp %{_bindir}/%{name}-mkfont %{_bindir}/%{name}-mklayout %{_bindir}/%{name}-mknetdir -%{_bindir}/%{name}-mkrescue %{_bindir}/%{name}-mkstandalone %{_bindir}/%{name}-syslinux2cfg -%{_sysconfdir}/sysconfig/grub -%{_datadir}/man/man1/%{name}-mkrescue* -%{_datadir}/man/man1/%{name}-fstest* -%{_datadir}/man/man1/%{name}-kbdcomp* -%{_datadir}/man/man1/%{name}-mkfont* -%{_datadir}/man/man1/%{name}-mklayout* -%{_datadir}/man/man1/%{name}-mknetdir* -%{_datadir}/man/man1/%{name}-mkstandalone* -%{_datadir}/man/man1/%{name}-syslinux2cfg* -%exclude %{_bindir}/%{name}-glue-efi -%exclude %{_sbindir}/%{name}-sparc64-setup -%exclude %{_sbindir}/%{name}-ofpathname -%exclude %{_datadir}/man/man1/%{name}-glue-efi* -%exclude %{_datadir}/man/man8/%{name}-ofpathname* -%exclude %{_datadir}/man/man8/%{name}-sparc64-setup* -%exclude %{_datarootdir}/grub/themes/starfield +%ifnarch %{sparc} +%{_bindir}/grub2-mkrescue +%endif + +%ifarch x86_64 +%files tools-efi +%defattr(-,root,root) +%{_sbindir}/%{name}-macbless +%{_bindir}/%{name}-render-label +%endif + %if 0%{with_efi_arch} %{expand:%define_efi_variant_files %%{package_arch} %%{grubefiname} %%{grubeficdname} %%{grubefiarch} %%{target_cpu_name} %%{grub_target_name}} @@ -498,14 +436,21 @@ mv ${EFI_HOME}/grub.cfg.stb ${EFI_HOME}/grub.cfg %if 0%{with_emu_arch} %files emu %{_bindir}/%{name}-emu* -%{_datadir}/man/man1/%{name}-emu* %files emu-modules %{_libdir}/grub/%{emuarch}-emu/* %exclude %{_libdir}/grub/%{emuarch}-emu/*.module %endif +%files doc +%defattr(-,root,root) +%doc INSTALL NEWS README THANKS TODO docs/grub.html docs/grub-dev.html docs/font_char_metrics.png +%{_datadir}/man/man* + %changelog +* Mon Mar 25 2024 mgb01105731 - 2.12-1 +- update to 2.12 + * Wed Dec 06 2023 happy_orange -2.06-14 - rebuild for loongarch diff --git a/grub2.yaml b/grub2.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a35e29a5211a8cad4e1bf066bf8e9ee46ad9eaf4 --- /dev/null +++ b/grub2.yaml @@ -0,0 +1,4 @@ +version_control: git +src_repo: https://git.savannah.gnu.org/git/grub.git +tag_prefix: grub- +seperator: . diff --git a/info-dir-entry.patch b/info-dir-entry.patch new file mode 100644 index 0000000000000000000000000000000000000000..0d57faa79f0a66e3a03402de3759ee7b67930812 --- /dev/null +++ b/info-dir-entry.patch @@ -0,0 +1,29 @@ +Index: grub-2.02~beta3/docs/grub.texi +=================================================================== +--- grub-2.02~beta3.orig/docs/grub.texi ++++ grub-2.02~beta3/docs/grub.texi +@@ -32,15 +32,15 @@ Invariant Sections. + + @dircategory Kernel + @direntry +-* GRUB: (grub). The GRand Unified Bootloader +-* grub-install: (grub)Invoking grub-install. Install GRUB on your drive +-* grub-mkconfig: (grub)Invoking grub-mkconfig. Generate GRUB configuration +-* grub-mkpasswd-pbkdf2: (grub)Invoking grub-mkpasswd-pbkdf2. +-* grub-mkrelpath: (grub)Invoking grub-mkrelpath. +-* grub-mkrescue: (grub)Invoking grub-mkrescue. Make a GRUB rescue image +-* grub-mount: (grub)Invoking grub-mount. Mount a file system using GRUB +-* grub-probe: (grub)Invoking grub-probe. Probe device information +-* grub-script-check: (grub)Invoking grub-script-check. ++* GRUB2: (grub2). The GRand Unified Bootloader ++* grub2-install: (grub2)Invoking grub-install. Install GRUB on your drive ++* grub2-mkconfig: (grub2)Invoking grub-mkconfig. Generate GRUB configuration ++* grub2-mkpasswd-pbkdf2: (grub2)Invoking grub-mkpasswd-pbkdf2. ++* grub2-mkrelpath: (grub2)Invoking grub-mkrelpath. ++* grub2-mkrescue: (grub2)Invoking grub-mkrescue. Make a GRUB rescue image ++* grub2-mount: (grub2)Invoking grub-mount. Mount a file system using GRUB ++* grub2-probe: (grub2)Invoking grub-probe. Probe device information ++* grub2-script-check: (grub2)Invoking grub-script-check. + @end direntry + + @setchapternewpage odd diff --git a/not-display-menu-when-boot-once.patch b/not-display-menu-when-boot-once.patch new file mode 100644 index 0000000000000000000000000000000000000000..57aee600b6fc76142ceeba7a09800f309dc2914b --- /dev/null +++ b/not-display-menu-when-boot-once.patch @@ -0,0 +1,31 @@ +From 78270522e8b8c0674941e0752c245dd8468e5bf8 Mon Sep 17 00:00:00 2001 +From: Michael Chang +Date: Wed, 1 Aug 2012 15:46:34 +0800 +Subject: [PATCH] not display menu when boot once + +References: bnc#771587 +Patch-Mainline: no + +We should prevent the menu from being displayed if boot once is +specified. This is in order to compliant with Grub1's behavior +and is better than current as it's not make any sense to bother +user to make decision when decision has been made. +--- + util/grub.d/00_header.in | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +Index: grub-2.02~beta2/util/grub.d/00_header.in +=================================================================== +--- grub-2.02~beta2.orig/util/grub.d/00_header.in ++++ grub-2.02~beta2/util/grub.d/00_header.in +@@ -304,7 +304,9 @@ make_timeout () + style="menu" + fi + cat << EOF +-if [ x\$feature_timeout_style = xy ] ; then ++if [ x\${boot_once} = xtrue ]; then ++ set timeout=0 ++elif [ x\$feature_timeout_style = xy ] ; then + set timeout_style=${style} + set timeout=${timeout} + EOF diff --git a/remove-the-items-of-unsupported-filesystems-in-fs.ls.patch b/remove-the-items-of-unsupported-filesystems-in-fs.ls.patch new file mode 100644 index 0000000000000000000000000000000000000000..a13277924d3fe9887c7ee60cae04a9ba292fa67b --- /dev/null +++ b/remove-the-items-of-unsupported-filesystems-in-fs.ls.patch @@ -0,0 +1,31 @@ +From 3a1e6b4f14c891a0faa31992d944dd35ef123b7f Mon Sep 17 00:00:00 2001 +From: Qiumiao Zhang +Date: Wed, 5 Jul 2023 16:53:49 +0800 +Subject: [PATCH] remove the items of unsupported filesystems in fs.lst + +--- + grub-core/Makefile.am | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am +index dd49939..fb487a8 100644 +--- a/grub-core/Makefile.am ++++ b/grub-core/Makefile.am +@@ -368,10 +368,13 @@ endif + # List files + + fs.lst: $(MARKER_FILES) ++ DISABLE_FS=(affs.marker afs.marker bfs.marker jfs.marker minix.marker minix2.marker minix3.marker minix_be.marker minix2_be.marker minix3_be.marker nilfs2.marker reiserfs.marker romfs.marker sfs.marker ufs1.marker ufs2.marker ufs1_be.marker); \ + (for pp in $^; do \ + b=`basename $$pp .marker`; \ + if grep 'FS_LIST_MARKER' $$pp >/dev/null 2>&1; then \ +- echo $$b; \ ++ if [[ ! "$${DISABLE_FS[@]}" =~ $$b ]]; then \ ++ echo $$b; \ ++ fi; \ + fi; \ + done) | sort -u > $@ + platform_DATA += fs.lst +-- +2.19.1 + diff --git a/rename-grub-info-file-to-grub2.patch b/rename-grub-info-file-to-grub2.patch new file mode 100644 index 0000000000000000000000000000000000000000..28172aba7515f57a92f880df6d790ab409e422b0 --- /dev/null +++ b/rename-grub-info-file-to-grub2.patch @@ -0,0 +1,36 @@ +From 031abf80020b2fa75850d6e09f4489b687a5cb19 Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Sun, 24 Jun 2012 15:40:40 +0200 +Subject: [PATCH] rename grub info file to grub2 + +Signed-off-by: Jiri Slaby + +From: Andrey Borzenkov +Do not rename file here. quilt does not support it and creates the +whole file if patch needs refreshing. It means that to regenerate two +files - Makefile.core.am and Makefile.util.am - it may be necessary to +manually rename it. +--- + +--- a/docs/Makefile.am ++++ b/docs/Makefile.am +@@ -1,7 +1,7 @@ + AUTOMAKE_OPTIONS = subdir-objects + + # AM_MAKEINFOFLAGS = --no-split --no-validate +-info_TEXINFOS = grub.texi grub-dev.texi ++info_TEXINFOS = grub2.texi grub-dev.texi + grub_TEXINFOS = fdl.texi + + EXTRA_DIST = font_char_metrics.png font_char_metrics.txt +--- a/docs/grub.texi ++++ b/docs/grub.texi +@@ -1,7 +1,7 @@ + \input texinfo + @c -*-texinfo-*- + @c %**start of header +-@setfilename grub.info ++@setfilename grub2.info + @include version.texi + @settitle GNU GRUB Manual @value{VERSION} + @c Unify all our little indices for now. diff --git a/safe_tpm_pcr_snapshot.patch b/safe_tpm_pcr_snapshot.patch new file mode 100644 index 0000000000000000000000000000000000000000..eb5ed71ce8e8fb962815b1073c229b1096a399d8 --- /dev/null +++ b/safe_tpm_pcr_snapshot.patch @@ -0,0 +1,99 @@ +--- + grub-core/commands/tpm.c | 46 ++++++++++++++++++++++++++++++++++++---------- + util/grub-install.c | 6 ++++-- + 2 files changed, 40 insertions(+), 12 deletions(-) + +--- a/grub-core/commands/tpm.c ++++ b/grub-core/commands/tpm.c +@@ -27,8 +27,10 @@ + #include + #include + #include ++#ifdef GRUB_MACHINE_EFI + #include + #include ++#endif + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -97,12 +99,6 @@ + .verify_string = grub_tpm_verify_string, + }; + +-/* +- * Preserve current PCR values and record them to an EFI variable +- */ +-#define GRUB2_PCR_BITMASK_DEFAULT ((1 << 16) - 1) +-#define GRUB2_PCR_BITMASK_ALL ((1 << 24) - 1) +- + static const struct grub_arg_option grub_tpm_record_pcrs_options[] = + { + { +@@ -118,6 +114,14 @@ + {0, 0, 0, 0, 0, 0} + }; + ++#ifdef GRUB_MACHINE_EFI ++ ++/* ++ * Preserve current PCR values and record them to an EFI variable ++ */ ++#define GRUB2_PCR_BITMASK_DEFAULT ((1 << 16) - 1) ++#define GRUB2_PCR_BITMASK_ALL ((1 << 24) - 1) ++ + static grub_err_t + grub_tpm_parse_pcr_index (const char *word, const char **end_ret, unsigned int *index) + { +@@ -269,6 +273,10 @@ + grub_size_t size = 0; + int n, rv = 1; + ++ /* To prevent error: unable to read PCR from TPM, if no TPM device available */ ++ if (!grub_tpm_present()) ++ return GRUB_ERR_NONE; ++ + if (argc == 0) + pcr_bitmask = GRUB2_PCR_BITMASK_DEFAULT; + else +@@ -297,6 +305,18 @@ + return rv; + } + ++#else ++ ++static grub_err_t ++grub_tpm_record_pcrs (grub_extcmd_context_t ctxt __attribute__((unused)), ++ int argc __attribute__((unused)), ++ char **args __attribute__((unused))) ++{ ++ return GRUB_ERR_NONE; ++} ++ ++#endif ++ + static grub_extcmd_t cmd; + + GRUB_MOD_INIT (tpm) +--- a/util/grub-install.c ++++ b/util/grub-install.c +@@ -1560,8 +1560,9 @@ + + grub_util_unlink (load_cfg); + +- if (1) ++ if (platform == GRUB_INSTALL_PLATFORM_X86_64_EFI && have_cryptodisk) + { ++ grub_install_push_module ("tpm"); + load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + fprintf (load_cfg_f, "tpm_record_pcrs 0-9\n"); +@@ -1569,7 +1570,8 @@ + + if (debug_image && debug_image[0]) + { +- load_cfg_f = grub_util_fopen (load_cfg, "wb"); ++ if (!load_cfg_f) ++ load_cfg_f = grub_util_fopen (load_cfg, "wb"); + have_load_cfg = 1; + fprintf (load_cfg_f, "set debug='%s'\n", + debug_image); diff --git a/sbat.csv.in b/sbat.csv.in old mode 100755 new mode 100644 index ea697f51ab1508325b8a241baa7e3683162d852d..f2bf0d0c61f07e452f7de2ff8337545f78783d2d --- a/sbat.csv.in +++ b/sbat.csv.in @@ -1,3 +1,3 @@ sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md -grub,1,Free Software Foundation,grub,@@VERSION@@,https//www.gnu.org/software/grub/ -grub.fedora,1,The Fedora Project,grub2,@@VERSION_RELEASE@@,https://src.fedoraproject.org/rpms/grub2 +grub,4,Free Software Foundation,grub,@@VERSION@@,https//www.gnu.org/software/grub/ +grub.openeuler,1,The openEuler Project,grub2,@@VERSION_RELEASE@@,https://gitee.com/src-openeuler/grub2 diff --git a/skip-verification-when-not-loading-grub.cfg.patch b/skip-verification-when-not-loading-grub.cfg.patch new file mode 100644 index 0000000000000000000000000000000000000000..bbedd6fdedc12bb61a15e2edaeb8d3f7e00cda0a --- /dev/null +++ b/skip-verification-when-not-loading-grub.cfg.patch @@ -0,0 +1,29 @@ +From c8b6446348a445a51024d04b2e8e5b417c3a1f73 Mon Sep 17 00:00:00 2001 +From: Qiumiao Zhang +Date: Wed, 31 May 2023 15:13:07 +0800 +Subject: [PATCH] skip verification when not loading grub.cfg + +Skip verification when just opening the grub.cfg without loading it. +There is no need to verify grub.cfg twice when tpcm is enabled. + +Signed-off-by: Qiumiao Zhang +--- + grub-core/normal/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c +index 1b426af..be6b7a3 100644 +--- a/grub-core/normal/main.c ++++ b/grub-core/normal/main.c +@@ -128,7 +128,7 @@ read_config_file (const char *config) + } + + /* Try to open the config file. */ +- rawfile = grub_file_open (config, GRUB_FILE_TYPE_CONFIG); ++ rawfile = grub_file_open (config, GRUB_FILE_TYPE_SKIP_SIGNATURE); + if (! rawfile) + return 0; + +-- +2.33.0 + diff --git a/tpm-record-pcrs.patch b/tpm-record-pcrs.patch new file mode 100644 index 0000000000000000000000000000000000000000..8872673f175f9f4c03393083280510b2b92ce659 --- /dev/null +++ b/tpm-record-pcrs.patch @@ -0,0 +1,235 @@ +--- a/grub-core/commands/tpm.c ++++ b/grub-core/commands/tpm.c +@@ -26,6 +26,9 @@ + #include + #include + #include ++#include ++#include ++#include + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -94,8 +97,214 @@ + .verify_string = grub_tpm_verify_string, + }; + ++/* ++ * Preserve current PCR values and record them to an EFI variable ++ */ ++#define GRUB2_PCR_BITMASK_DEFAULT ((1 << 16) - 1) ++#define GRUB2_PCR_BITMASK_ALL ((1 << 24) - 1) ++ ++static const struct grub_arg_option grub_tpm_record_pcrs_options[] = ++ { ++ { ++ .longarg = "efivar", ++ .shortarg = 'E', ++ .flags = 0, ++ .arg = NULL, ++ .type = ARG_TYPE_STRING, ++ .doc = ++ N_("The EFI variable to publish the PCRs to (default GrubPcrSnapshot)"), ++ }, ++ ++ {0, 0, 0, 0, 0, 0} ++ }; ++ ++static grub_err_t ++grub_tpm_parse_pcr_index (const char *word, const char **end_ret, unsigned int *index) ++{ ++ const char *end; ++ ++ if (!grub_isdigit (word[0])) ++ return GRUB_ERR_BAD_NUMBER; ++ ++ *index = grub_strtoul(word, &end, 0); ++ if (*index > 32) ++ return GRUB_ERR_BAD_NUMBER; ++ ++ *end_ret = end; ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm_parse_pcr_list (const char *arg, grub_uint32_t *bitmask) ++{ ++ const char *word, *end; ++ unsigned int index, last_index = 0; ++ ++ if (!grub_strcmp (arg, "all")) ++ { ++ *bitmask = GRUB2_PCR_BITMASK_ALL; ++ return GRUB_ERR_NONE; ++ } ++ ++ word = arg; ++ while (1) ++ { ++ if (grub_tpm_parse_pcr_index (word, &end, &index)) ++ goto bad_pcr_index; ++ ++ if (*end == '-') ++ { ++ if (grub_tpm_parse_pcr_index (end + 1, &end, &last_index) || last_index < index) ++ goto bad_pcr_index; ++ ++ while (index <= last_index) ++ *bitmask |= (1 << (index++)); ++ } ++ else ++ *bitmask |= (1 << index); ++ ++ if (*end == '\0') ++ break; ++ ++ if (*end != ',') ++ goto bad_pcr_index; ++ ++ word = end + 1; ++ } ++ ++ return GRUB_ERR_NONE; ++ ++bad_pcr_index: ++ return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("cannot parse PCR list \"%s\""), arg); ++} ++ ++static inline unsigned int ++nbits(grub_uint32_t mask) ++{ ++ unsigned int r = 0; ++ ++ for (; mask != 0; mask >>= 1) ++ r += (mask & 1); ++ return r; ++} ++ ++static grub_err_t ++grub_tpm_snapshot_pcrs (grub_uint32_t pcr_bitmask, const char *algo, ++ void **buffer_ret, grub_size_t *size_ret) ++{ ++ char *buffer; ++ grub_size_t size = 65536; ++ unsigned int wpos = 0; ++ grub_uint8_t pcr; ++ ++ buffer = grub_malloc (size); ++ for (pcr = 0; pcr < 32; ++pcr) ++ { ++ struct grub_tpm_digest *d; ++ unsigned int need, k; ++ ++ if (!(pcr_bitmask & (1 << pcr))) ++ continue; ++ ++ d = grub_tpm_read_pcr (pcr, algo); ++ if (d == NULL) ++ { ++ grub_error (GRUB_ERR_BAD_DEVICE, N_("unable to read PCR %d from TPM"), pcr); ++ continue; ++ } ++ ++ /* We need room for the PCR index, 2 spaces, newline, NUL. 16 should be enough. */ ++ need = 16 + grub_strlen(d->algorithm) + 2 * d->size; ++ if (wpos + need > size) ++ { ++ buffer = grub_realloc (buffer, size + need); ++ if (buffer == NULL) ++ return grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("Not enough memory when dumping PCR registers")); ++ } ++ ++ grub_snprintf (buffer + wpos, size - wpos, "%02d %s ", pcr, d->algorithm); ++ wpos = grub_strlen(buffer); ++ ++ for (k = 0; k < d->size; ++k) ++ { ++ grub_snprintf (buffer + wpos, size - wpos, "%02x", d->value[k]); ++ wpos += 2; ++ } ++ ++ buffer[wpos++] = '\n'; ++ buffer[wpos] = '\0'; ++ ++ grub_tpm_digest_free (d); ++ } ++ ++ *buffer_ret = buffer; ++ *size_ret = wpos; ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm_write_pcrs_to_efi (void *data, grub_size_t size, const char *var_name) ++{ ++ grub_guid_t vendor_guid = { 0x7ce323f2, 0xb841, 0x4d30, { 0xa0, 0xe9, 0x54, 0x74, 0xa7, 0x6c, 0x9a, 0x3f }}; ++ grub_err_t rc; ++ ++ rc = grub_efi_set_variable_with_attributes(var_name, &vendor_guid, ++ data, size, ++ GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | GRUB_EFI_VARIABLE_RUNTIME_ACCESS); ++ ++ if (rc) ++ return grub_error (GRUB_ERR_BAD_DEVICE, N_("Failed to publish PCR snapshot to UEFI variable %s"), var_name); ++ ++ return GRUB_ERR_NONE; ++} ++ ++static grub_err_t ++grub_tpm_record_pcrs (grub_extcmd_context_t ctxt, int argc, char **args) ++{ ++ struct grub_arg_list *state = ctxt->state; ++ grub_uint32_t pcr_bitmask = 0; ++ const char *efivar; ++ void *buffer = NULL; ++ grub_size_t size = 0; ++ int n, rv = 1; ++ ++ if (argc == 0) ++ pcr_bitmask = GRUB2_PCR_BITMASK_DEFAULT; ++ else ++ { ++ for (n = 0; n < argc; ++n) ++ if (grub_tpm_parse_pcr_list (args[n], &pcr_bitmask)) ++ return 1; ++ } ++ ++ if (grub_tpm_snapshot_pcrs (pcr_bitmask, NULL, &buffer, &size)) ++ goto out; ++ ++ if (state[0].set) ++ efivar = state[0].arg; ++ else ++ efivar = "GrubPcrSnapshot"; ++ ++ if (grub_tpm_write_pcrs_to_efi (buffer, size, efivar)) ++ goto out; ++ ++ rv = 0; ++ ++out: ++ if (buffer) ++ grub_free (buffer); ++ return rv; ++} ++ ++static grub_extcmd_t cmd; ++ + GRUB_MOD_INIT (tpm) + { ++ cmd = grub_register_extcmd ("tpm_record_pcrs", grub_tpm_record_pcrs, 0, ++ N_("LIST_OF_PCRS"), ++ N_("Snapshot one or more PCR values and record them in an EFI variable."), ++ grub_tpm_record_pcrs_options); + /* + * Even though this now calls ibmvtpm's grub_tpm_present() from GRUB_MOD_INIT(), + * it does seem to call it late enough in the initialization sequence so +@@ -109,6 +318,7 @@ + + GRUB_MOD_FINI (tpm) + { ++ grub_unregister_extcmd (cmd); + if (!grub_tpm_present()) + return; + grub_verifier_unregister (&grub_tpm_verifier); diff --git a/use-grub2-as-a-package-name.patch b/use-grub2-as-a-package-name.patch new file mode 100644 index 0000000000000000000000000000000000000000..896cd40fbab15dafbdd6ebb33ee1797455a44483 --- /dev/null +++ b/use-grub2-as-a-package-name.patch @@ -0,0 +1,25 @@ +From 3729b131ef1dcaa043242e8074418249695d381b Mon Sep 17 00:00:00 2001 +From: Jiri Slaby +Date: Sun, 24 Jun 2012 20:51:52 +0200 +Subject: [PATCH] use grub2 as a package name + +This will ease all of the renaming of directories and all the pkgdata +hacks. + +Signed-off-by: Jiri Slaby +--- + configure | 24 ++++++++++++------------ + configure.ac | 2 +- + 2 files changed, 13 insertions(+), 13 deletions(-) + +--- a/configure.ac ++++ b/configure.ac +@@ -34,7 +34,7 @@ + dnl the target type. See INSTALL for full list of variables and + dnl description of the relationships between them. + +-AC_INIT([GRUB],[2.12],[bug-grub@gnu.org]) ++AC_INIT([GRUB2],[2.12],[bug-grub@gnu.org]) + + AS_CASE(["$ERROR_PLATFORM_NOT_SUPPORT_SSP"], + [n | no | nO | N | No | NO], [ERROR_PLATFORM_NOT_SUPPORT_SSP=no],