005c99a035
- Fix CVE-2021-3981 (bsc#1189644) * 0001-grub-mkconfig-restore-umask-for-grub.cfg.patch - Fix can't allocate initrd error (bsc#1191378) * 0001-Factor-out-grub_efi_linux_boot.patch * 0002-Fix-race-in-EFI-validation.patch * 0003-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch * 0004-Try-to-pick-better-locations-for-kernel-and-initrd.patch * 0005-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch * 0006-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch * 0007-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch * 0008-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch * 0009-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch * 0010-efilinux-Fix-integer-overflows-in-grub_cmd_initrd.patch * 0011-Also-define-GRUB_EFI_MAX_ALLOCATION_ADDRESS-for-RISC.patch OBS-URL: https://build.opensuse.org/request/show/942210 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=400
201 lines
7.6 KiB
Diff
201 lines
7.6 KiB
Diff
From 384763d7990f769839ca74d6756fbd85580873d4 Mon Sep 17 00:00:00 2001
|
|
From: Peter Jones <pjones@redhat.com>
|
|
Date: Thu, 11 Jul 2019 17:17:02 +0200
|
|
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__.
|
|
- Get the comparison right to check the address we've allocated.
|
|
- Fix the allocation for the command line as well.
|
|
|
|
*But*, when we did this some systems started failing badly; coudln't
|
|
parse partition tables, etc. What's going on here is the disk controller
|
|
is silently failing DMAs to addresses above 4GB, so we're trying to parse
|
|
uninitialized (or HW zeroed) ram when looking for the partition table,
|
|
etc.
|
|
|
|
So to limit this, we make grub_malloc() pick addresses below 4GB on
|
|
x86_64, but the direct EFI page allocation functions can get addresses
|
|
above that.
|
|
|
|
Additionally, we now try to locate kernel+initrd+cmdline+etc below
|
|
0x7fffffff, and if they're too big to fit any memory window there, then
|
|
we try a higher address.
|
|
|
|
Signed-off-by: Peter Jones <pjones@redhat.com>
|
|
---
|
|
grub-core/kern/efi/mm.c | 8 ++++----
|
|
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/x86_64/efi/memory.h | 4 +++-
|
|
7 files changed, 28 insertions(+), 13 deletions(-)
|
|
|
|
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
|
|
index 4ff75a8ce..67a691d89 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,
|
|
grub_efi_boot_services_t *b;
|
|
grub_efi_physical_address_t address = max;
|
|
|
|
- if (max > 0xffffffff)
|
|
+ if (max > GRUB_EFI_MAX_USABLE_ADDRESS)
|
|
return 0;
|
|
|
|
b = grub_efi_system_table->boot_services;
|
|
@@ -480,7 +480,7 @@ filter_memory_map (grub_efi_memory_descriptor_t *memory_map,
|
|
{
|
|
if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY
|
|
#if 1
|
|
- && desc->physical_start <= GRUB_EFI_MAX_USABLE_ADDRESS
|
|
+ && desc->physical_start <= GRUB_EFI_MAX_ALLOCATION_ADDRESS
|
|
#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,
|
|
#if 1
|
|
if (BYTES_TO_PAGES (filtered_desc->physical_start)
|
|
+ filtered_desc->num_pages
|
|
- > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS))
|
|
+ > BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS))
|
|
filtered_desc->num_pages
|
|
- = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_USABLE_ADDRESS)
|
|
+ = (BYTES_TO_PAGES_DOWN (GRUB_EFI_MAX_ALLOCATION_ADDRESS)
|
|
- 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 0b3d20875..f3abbd025 100644
|
|
--- a/grub-core/loader/i386/efi/linux.c
|
|
+++ b/grub-core/loader/i386/efi/linux.c
|
|
@@ -27,6 +27,7 @@
|
|
#include <grub/lib/cmdline.h>
|
|
#include <grub/efi/efi.h>
|
|
#include <grub/efi/linux.h>
|
|
+#include <grub/cpu/efi/memory.h>
|
|
|
|
GRUB_MOD_LICENSE ("GPLv3+");
|
|
|
|
@@ -102,8 +103,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
|
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"));
|
|
@@ -187,8 +189,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
goto fail;
|
|
}
|
|
|
|
- params = grub_efi_allocate_pages_max (0x3fffffff,
|
|
+ params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS,
|
|
BYTES_TO_PAGES(sizeof(*params)));
|
|
+ if (!params)
|
|
+ params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS,
|
|
+ BYTES_TO_PAGES(sizeof(*params)));
|
|
if (! params)
|
|
{
|
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters");
|
|
@@ -258,8 +263,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
#endif
|
|
|
|
grub_dprintf ("linux", "setting up cmdline\n");
|
|
- linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff,
|
|
- BYTES_TO_PAGES(lh->cmdline_size + 1));
|
|
+ linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS,
|
|
+ BYTES_TO_PAGES(lh->cmdline_size + 1));
|
|
+ if (!linux_cmdline)
|
|
+ linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS,
|
|
+ BYTES_TO_PAGES(lh->cmdline_size + 1));
|
|
if (!linux_cmdline)
|
|
{
|
|
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline"));
|
|
@@ -285,11 +293,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
|
|
|
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,
|
|
+ kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS,
|
|
+ BYTES_TO_PAGES(lh->init_size));
|
|
+ if (!kernel_mem)
|
|
+ kernel_mem = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS,
|
|
BYTES_TO_PAGES(lh->init_size));
|
|
-
|
|
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 2c64918e3..a4c2ec835 100644
|
|
--- a/include/grub/arm/efi/memory.h
|
|
+++ b/include/grub/arm/efi/memory.h
|
|
@@ -2,5 +2,6 @@
|
|
#include <grub/efi/memory.h>
|
|
|
|
#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
|
|
+#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 c6cb32417..acb61dca4 100644
|
|
--- a/include/grub/arm64/efi/memory.h
|
|
+++ b/include/grub/arm64/efi/memory.h
|
|
@@ -2,5 +2,6 @@
|
|
#include <grub/efi/memory.h>
|
|
|
|
#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/i386/efi/memory.h b/include/grub/i386/efi/memory.h
|
|
index 2c64918e3..a4c2ec835 100644
|
|
--- a/include/grub/i386/efi/memory.h
|
|
+++ b/include/grub/i386/efi/memory.h
|
|
@@ -2,5 +2,6 @@
|
|
#include <grub/efi/memory.h>
|
|
|
|
#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
|
|
+#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 2c64918e3..a4c2ec835 100644
|
|
--- a/include/grub/ia64/efi/memory.h
|
|
+++ b/include/grub/ia64/efi/memory.h
|
|
@@ -2,5 +2,6 @@
|
|
#include <grub/efi/memory.h>
|
|
|
|
#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
|
|
+#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 46e9145a3..e81cfb322 100644
|
|
--- a/include/grub/x86_64/efi/memory.h
|
|
+++ b/include/grub/x86_64/efi/memory.h
|
|
@@ -2,9 +2,11 @@
|
|
#include <grub/efi/memory.h>
|
|
|
|
#if defined (__code_model_large__)
|
|
-#define GRUB_EFI_MAX_USABLE_ADDRESS 0xffffffff
|
|
+#define GRUB_EFI_MAX_USABLE_ADDRESS __UINTPTR_MAX__
|
|
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS 0x7fffffff
|
|
#else
|
|
#define GRUB_EFI_MAX_USABLE_ADDRESS 0x7fffffff
|
|
+#define GRUB_EFI_MAX_ALLOCATION_ADDRESS GRUB_EFI_MAX_USABLE_ADDRESS
|
|
#endif
|
|
|
|
#endif /* ! GRUB_MEMORY_CPU_HEADER */
|
|
--
|
|
2.31.1
|
|
|