From 340cd8a61077c1cbd6895fec1d16744d88d9315e Mon Sep 17 00:00:00 2001 From: Liwei Ge Date: Fri, 2 Sep 2022 15:30:37 +0800 Subject: [PATCH] arm64: Fix EFI loader kernel image allocation Signed-off-by: Liwei Ge --- ...x-EFI-loader-kernel-image-allocation.patch | 185 ++++++++++++++++++ grub.patches | 1 + grub2.spec | 5 +- 3 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 1003-arm64-Fix-EFI-loader-kernel-image-allocation.patch diff --git a/1003-arm64-Fix-EFI-loader-kernel-image-allocation.patch b/1003-arm64-Fix-EFI-loader-kernel-image-allocation.patch new file mode 100644 index 0000000..eb68c33 --- /dev/null +++ b/1003-arm64-Fix-EFI-loader-kernel-image-allocation.patch @@ -0,0 +1,185 @@ +From c0d084eeea91ae5e4a6509716f9055fb75da1e03 Mon Sep 17 00:00:00 2001 +From: Fedora Ninjas +Date: Fri, 2 Sep 2022 15:24:10 +0800 +Subject: [PATCH] arm64: Fix EFI loader kernel image allocation + +backport from https://github.com/rhboot/grub2/ +commit/188f3f977341cdbd7ac582e794ca31c5415495ce + +Signed-off-by: Fedora Ninjas +--- + grub-core/loader/arm64/linux.c | 100 ++++++++++++++++++++++----------- + 1 file changed, 66 insertions(+), 34 deletions(-) + +diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c +index 37f5d0c..81261c0 100644 +--- a/grub-core/loader/arm64/linux.c ++++ b/grub-core/loader/arm64/linux.c +@@ -41,6 +41,8 @@ GRUB_MOD_LICENSE ("GPLv3+"); + static grub_dl_t my_mod; + static int loaded; + ++static void *kernel_alloc_addr; ++static grub_uint32_t kernel_alloc_pages; + static void *kernel_addr; + static grub_uint64_t kernel_size; + static grub_uint32_t handover_offset; +@@ -229,9 +231,8 @@ grub_linux_unload (void) + 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)); ++ if (kernel_alloc_addr) ++ grub_efi_free_pages ((grub_addr_t) kernel_alloc_addr, kernel_alloc_pages); + grub_fdt_unload (); + return GRUB_ERR_NONE; + } +@@ -336,14 +337,35 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)), + return grub_errno; + } + ++static grub_err_t ++parse_pe_header (void *kernel, grub_uint64_t *total_size, ++ grub_uint32_t *entry_offset, ++ grub_uint32_t *alignment) ++{ ++ struct linux_armxx_kernel_header *lh = kernel; ++ struct grub_armxx_linux_pe_header *pe; ++ ++ pe = (void *)((unsigned long)kernel + lh->hdr_offset); ++ ++ 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; ++ *entry_offset = pe->opt.entry_addr; ++ *alignment = pe->opt.section_alignment; ++ ++ return GRUB_ERR_NONE; ++} ++ + static grub_err_t + grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + int argc, char *argv[]) + { + grub_file_t file = 0; +- struct linux_armxx_kernel_header lh; +- struct grub_armxx_linux_pe_header *pe; + int rc; ++ grub_off_t filelen; ++ grub_uint32_t align; ++ void *kernel = NULL; + grub_err_t err; + int nx_supported = 1; + +@@ -359,40 +381,24 @@ 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_armxx_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; + } + +- grub_file_seek (file, 0); +- if (grub_file_read (file, kernel_addr, kernel_size) +- < (grub_int64_t) kernel_size) ++ 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_secure_boot ()) + { +- 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, +@@ -405,8 +411,32 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + if (err != GRUB_ERR_NONE) + goto fail; + +- pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset); +- handover_offset = pe->opt.entry_addr; ++ if (grub_armxx_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; ++ 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(); ++ ++ 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; ++ } ++ kernel_addr = (void *)ALIGN_UP((grub_uint64_t)kernel_alloc_addr, align); ++ ++ grub_dprintf ("linux", "kernel @ %p\n", kernel_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); ++ grub_free(kernel); ++ kernel = NULL; + + cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE); + linux_args = grub_malloc (cmdline_size); +@@ -430,6 +460,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)), + } + + fail: ++ if (kernel) ++ grub_free (kernel); ++ + if (file) + grub_file_close (file); + +@@ -442,9 +475,8 @@ fail: + 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)); ++ if (kernel_alloc_addr && !loaded) ++ grub_efi_free_pages ((grub_addr_t) kernel_alloc_addr, kernel_alloc_pages); + + return grub_errno; + } +-- +2.27.0 + diff --git a/grub.patches b/grub.patches index 359dccc..4bc33e8 100644 --- a/grub.patches +++ b/grub.patches @@ -549,3 +549,4 @@ Patch0548: 0548-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch Patch0549: 0549-Fixup-grub_efi_get_variable-type-in-our-loaders.patch Patch1001: 1001-bls-make-list.patch Patch1002: 1002-Add-LoongArch64-support-and-update-interface-to-v40.patch +Patch1003: 1003-arm64-Fix-EFI-loader-kernel-image-allocation.patch diff --git a/grub2.spec b/grub2.spec index 8416300..5db14b9 100644 --- a/grub2.spec +++ b/grub2.spec @@ -1,4 +1,4 @@ -%define anolis_release .0.2 +%define anolis_release .0.3 %undefine _hardened_build %global tarversion 2.02 @@ -523,6 +523,9 @@ fi %endif %changelog +* Fri Sep 2 2022 Liwei Ge - 2.02-123.0.3.8 +- arm64: Fix EFI loader kernel image allocation + * Thu Jul 7 2022 QiMing Yang - 2.02-123.0.2.8 - Delete LoongArch64 support old version due to compile error - Add LoongArch64 support -- Gitee