forked from pool/grub2
Accepting request 931473 from home:michael-chang:bsc:1192522
- Fix arm64 kernel image not aligned on 64k boundary (bsc#1192522) * 0001-arm64-Fix-EFI-loader-kernel-image-allocation.patch * 0002-Arm-check-for-the-PE-magic-for-the-compiled-arch.patch OBS-URL: https://build.opensuse.org/request/show/931473 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=397
This commit is contained in:
parent
da8194b45d
commit
fb89b0c9e2
179
0001-arm64-Fix-EFI-loader-kernel-image-allocation.patch
Normal file
179
0001-arm64-Fix-EFI-loader-kernel-image-allocation.patch
Normal file
@ -0,0 +1,179 @@
|
||||
From 10d0f70ac194931c63f2cbd6fdebd6697abae992 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Date: Mon, 2 Aug 2021 23:10:01 +1000
|
||||
Subject: [PATCH 1/2] arm64: Fix EFI loader kernel image allocation
|
||||
|
||||
We are currently allocating just enough memory for the file size,
|
||||
which means that the kernel BSS is in limbo (and not even zeroed).
|
||||
|
||||
We are also not honoring the alignment specified in the image
|
||||
PE header.
|
||||
|
||||
This makes us use the PE optional header in which the kernel puts the
|
||||
actual size it needs, including BSS, and make sure we clear it, and
|
||||
honors the specified alignment for the image.
|
||||
|
||||
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
---
|
||||
grub-core/loader/arm64/efi/linux.c | 92 ++++++++++++++++++++----------
|
||||
1 file changed, 63 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||
index b73105347..4da49a182 100644
|
||||
--- 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;
|
||||
|
||||
+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;
|
||||
@@ -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);
|
||||
- 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;
|
||||
}
|
||||
@@ -365,14 +366,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_arch_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_arch_kernel_header lh;
|
||||
- struct grub_armxx_linux_pe_header *pe;
|
||||
grub_err_t err;
|
||||
+ grub_off_t filelen;
|
||||
+ grub_uint32_t align = 0;
|
||||
+ void *kernel = NULL;
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
|
||||
@@ -386,39 +408,49 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
if (!file)
|
||||
goto fail;
|
||||
|
||||
- kernel_size = grub_file_size (file);
|
||||
+ filelen = grub_file_size (file);
|
||||
+ kernel = grub_malloc(filelen);
|
||||
+ if (!kernel)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel load buffer"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
|
||||
- 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)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"),
|
||||
+ argv[0]);
|
||||
+ goto fail;
|
||||
+ }
|
||||
|
||||
- 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;
|
||||
+ 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_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_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);
|
||||
-
|
||||
- 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);
|
||||
+ grub_free(kernel);
|
||||
+ kernel = NULL;
|
||||
|
||||
cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
|
||||
linux_args = grub_malloc (cmdline_size);
|
||||
@@ -442,6 +474,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
|
||||
fail:
|
||||
+ if (kernel)
|
||||
+ grub_free (kernel);
|
||||
+
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
|
||||
@@ -454,9 +489,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.31.1
|
||||
|
66
0002-Arm-check-for-the-PE-magic-for-the-compiled-arch.patch
Normal file
66
0002-Arm-check-for-the-PE-magic-for-the-compiled-arch.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From 337b3d963d28b3544e8817428fb68ca559613a39 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
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 <pjones@redhat.com>
|
||||
---
|
||||
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(-)
|
||||
|
||||
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||
index 4da49a182..87cb2f97c 100644
|
||||
--- a/grub-core/loader/arm64/efi/linux.c
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -376,7 +376,7 @@ parse_pe_header (void *kernel, grub_uint64_t *total_size,
|
||||
|
||||
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;
|
||||
diff --git a/include/grub/arm/linux.h b/include/grub/arm/linux.h
|
||||
index b582f67f6..966a5074f 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 de99d39c0..b4b91473a 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
|
||||
|
@ -1,3 +1,10 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Nov 11 07:45:11 UTC 2021 - Michael Chang <mchang@suse.com>
|
||||
|
||||
- Fix arm64 kernel image not aligned on 64k boundary (bsc#1192522)
|
||||
* 0001-arm64-Fix-EFI-loader-kernel-image-allocation.patch
|
||||
* 0002-Arm-check-for-the-PE-magic-for-the-compiled-arch.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Oct 21 12:51:46 UTC 2021 - Michael Chang <mchang@suse.com>
|
||||
|
||||
|
@ -312,6 +312,8 @@ Patch794: 0001-Filter-out-POSIX-locale-for-translation.patch
|
||||
Patch795: 0001-ieee1275-implement-FCP-methods-for-WWPN-and-LUNs.patch
|
||||
Patch796: 0001-disk-diskfilter-Use-nodes-in-logical-volume-s-segmen.patch
|
||||
Patch797: 0001-fs-xfs-Fix-unreadable-filesystem-with-v4-superblock.patch
|
||||
Patch798: 0001-arm64-Fix-EFI-loader-kernel-image-allocation.patch
|
||||
Patch799: 0002-Arm-check-for-the-PE-magic-for-the-compiled-arch.patch
|
||||
|
||||
Requires: gettext-runtime
|
||||
%if 0%{?suse_version} >= 1140
|
||||
@ -329,8 +331,8 @@ Requires: grub2-%{grubarch} = %{version}-%{release}
|
||||
%ifarch s390x
|
||||
# required utilities by grub2-s390x-04-grub2-install.patch
|
||||
# use 'showconsole' to determine console device. (bnc#876743)
|
||||
Requires: (/sbin/showconsole or /usr/sbin/showconsole)
|
||||
Requires: kexec-tools
|
||||
Requires: (/sbin/showconsole or /usr/sbin/showconsole)
|
||||
# for /sbin/zipl used by grub2-zipl-setup
|
||||
Requires: s390-tools
|
||||
%endif
|
||||
|
Loading…
Reference in New Issue
Block a user