diff options
Diffstat (limited to 'debian/patches/arm64-handover-to-kernel-if-sb-enabled.patch')
-rw-r--r-- | debian/patches/arm64-handover-to-kernel-if-sb-enabled.patch | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/debian/patches/arm64-handover-to-kernel-if-sb-enabled.patch b/debian/patches/arm64-handover-to-kernel-if-sb-enabled.patch new file mode 100644 index 0000000..e20d4ad --- /dev/null +++ b/debian/patches/arm64-handover-to-kernel-if-sb-enabled.patch @@ -0,0 +1,152 @@ +From: Emanuele Rocca <ema@debian.org> +Date: Fri, 31 Mar 2023 12:38:52 +0200 +Subject: Cherry-pick parts of "Load arm with SB enabled." + +Fix Secure Boot on arm64 by cherry-picking the relevant parts of upstream patch +"Load arm with SB enabled." + +Signed-off-by: Emanuele Rocca <ema@debian.org> + +Origin: vendor, https://github.com/rhboot/grub2/commit/2786ab864cf00c15123320671f653e9a36ba12b4 +--- + +Index: grub.git/grub-core/loader/arm64/linux.c +=================================================================== +--- grub.git.orig/grub-core/loader/arm64/linux.c ++++ grub.git/grub-core/loader/arm64/linux.c +@@ -16,6 +16,7 @@ + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. + */ + ++#include <grub/cache.h> + #include <grub/charset.h> + #include <grub/command.h> + #include <grub/err.h> +@@ -33,6 +34,7 @@ + #include <grub/i18n.h> + #include <grub/lib/cmdline.h> + #include <grub/verify.h> ++#include <grub/efi/sb.h> + + GRUB_MOD_LICENSE ("GPLv3+"); + +@@ -41,6 +43,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; +@@ -48,6 +51,15 @@ static grub_uint32_t cmdline_size; + static grub_addr_t initrd_start; + static grub_addr_t initrd_end; + ++struct grub_arm64_linux_pe_header ++{ ++ grub_uint32_t magic; ++ struct grub_pe32_coff_header coff; ++ struct grub_pe64_optional_header opt; ++}; ++ ++typedef void (*handover_func) (void *, grub_efi_system_table_t *); ++ + grub_err_t + grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh) + { +@@ -64,7 +76,8 @@ grub_arch_efi_linux_check_image (struct + 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; + +@@ -99,6 +112,27 @@ finalize_params_linux (void) + 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) { ++ grub_dprintf ("linux", "Error loading image with grub_efi_get_loaded_image()\n"); ++ 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: +@@ -116,6 +150,39 @@ grub_arch_efi_linux_boot_image (grub_add + grub_efi_loaded_image_t *loaded_image; + int len; + ++#ifdef __aarch64__ /* SB only enabled for arm64 */ ++ handover_func hf; ++ ++ if (grub_efi_get_secureboot() == GRUB_EFI_SECUREBOOT_MODE_ENABLED) { ++ grub_dprintf ("linux", "GRUB_EFI_SECUREBOOT_MODE enabled\n"); ++ /* ++ * 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; ++ grub_dprintf ("linux", "Loaded Image base address set to %p\n", kernel_addr); ++ } ++ else ++ grub_dprintf ("linux", "Loaded Image base address could not be set\n"); ++ ++ grub_dprintf ("linux", "kernel_addr: %p handover_offset: %p\n", ++ kernel_addr, (void *)(grub_efi_uintn_t)handover_offset); ++ ++ /* Invalidate the instruction cache */ ++ grub_arch_sync_caches((void *)kernel_addr, kernel_size); ++ ++ hf = (handover_func)((char *)kernel_addr + handover_offset); ++ hf (grub_efi_image_handle, grub_efi_system_table); ++ ++ return GRUB_ERR_BUG; ++ } ++ ++ grub_dprintf ("linux", "GRUB_EFI_SECUREBOOT_MODE is NOT enabled\n"); ++#endif ++ + mempath = grub_malloc (2 * sizeof (grub_efi_memory_mapped_device_path_t)); + if (!mempath) + return grub_errno; +@@ -285,6 +352,7 @@ grub_cmd_linux (grub_command_t cmd __att + { + grub_file_t file = 0; + struct linux_arch_kernel_header lh; ++ struct grub_arm64_linux_pe_header *pe; + grub_err_t err; + + grub_dl_ref (my_mod); +@@ -330,6 +398,9 @@ grub_cmd_linux (grub_command_t cmd __att + + 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) |