Merge branch 'c8-beta' into a8-beta
This commit is contained in:
commit
f416e63f99
@ -1,4 +1,4 @@
|
||||
From fe8b1f619fafcd2438e3d86fb07c6a5e9280423c Mon Sep 17 00:00:00 2001
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Ian Page Hands <iphands@gmail.com>
|
||||
Date: Tue, 8 Jun 2021 13:48:56 -0400
|
||||
Subject: [PATCH] efinet: Add DHCP proxy support
|
||||
@ -51,6 +51,3 @@ index df7760ad2..25809050b 100644
|
||||
1, device, path);
|
||||
grub_dprintf ("efinet", "device: `%s' path: `%s'\n", *device, *path);
|
||||
}
|
||||
--
|
||||
2.34.1
|
||||
|
||||
|
@ -1,7 +1,8 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Renaud=20M=C3=A9trich?= <rmetrich@redhat.com>
|
||||
Date: Tue, 8 Feb 2022 08:39:10 +0100
|
||||
Subject: [PATCH] search: fixed bug stopping iteration when --no-floppy is used
|
||||
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
|
||||
@ -10,8 +11,11 @@ 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 <rmetrich@redhat.com>
|
||||
(cherry picked from commit e784b4b3367341b0468dd2a83b265d49383f48ae)
|
||||
(cherry picked from commit 8f4688fd61dcf35de3d7ebbc2b237cfa2f202930)
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 68ba54c2298604146be83cae144dafd1cfd1fe2d)
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
(cherry picked from commit 7ada55e3fcd16e00773d3918955b2b945b7f063a)
|
||||
(cherry picked from commit 44a58e304fd06155a56b650927728af01bbc647d)
|
||||
---
|
||||
grub-core/commands/search.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
@ -17,8 +17,10 @@ effective EFI device behind.
|
||||
This commit also refactors handling of --no-floppy option.
|
||||
|
||||
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
|
||||
(cherry picked from commit aedb45f32106dd2a64f906b0db6a76ee09f1b930)
|
||||
(cherry picked from commit 4fef28d5405f7f986dba6e503e48d6a408588382)
|
||||
[rharwood: apply rmetrich's flags initialization fix]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
(cherry picked from commit fdd8396f4fa750bbbabd4298f2593942f2b84710)
|
||||
(cherry picked from commit bea473b58726705bb83a3db88f52d46fdcc6150e)
|
||||
---
|
||||
grub-core/commands/search.c | 27 +++++++++++++++++++++++----
|
||||
grub-core/commands/search_wrap.c | 18 ++++++++++++------
|
||||
@ -86,7 +88,7 @@ index d3180bf66..2036a756b 100644
|
||||
.nhints = nhints,
|
||||
.count = 0,
|
||||
diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
|
||||
index 47fc8eb99..464e6ebb1 100644
|
||||
index 47fc8eb99..0b62acf85 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[] =
|
||||
@ -109,7 +111,7 @@ index 47fc8eb99..464e6ebb1 100644
|
||||
const char *id = 0;
|
||||
int i = 0, j = 0, nhints = 0;
|
||||
char **hints = NULL;
|
||||
+ enum search_flags flags;
|
||||
+ enum search_flags flags = 0;
|
||||
|
||||
if (state[SEARCH_HINT].set)
|
||||
for (i = 0; state[SEARCH_HINT].args[i]; i++)
|
||||
|
@ -50,10 +50,10 @@ The code is easily extensible to handle other arguments in the future if
|
||||
needed.
|
||||
|
||||
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
|
||||
(cherry picked from commit 73e183ce1e42bd97ae91a9254f8d4acd4d0b1cbc)
|
||||
(cherry picked from commit 174c3efcf17b1f5ad466f9c5fb83cd9554edb5f9)
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
(cherry picked from commit cc972c27314c841f80ab0fe8318fae06f078c680)
|
||||
(cherry picked from commit 84b0c3f965a3918be64ca850139bea7c32d23ae9)
|
||||
---
|
||||
NEWS | 2 +-
|
||||
grub-core/Makefile.core.def | 6 ++
|
||||
grub-core/commands/efi/connectefi.c | 205 ++++++++++++++++++++++++++++++++++++
|
||||
grub-core/commands/efi/lsefi.c | 1 +
|
||||
@ -61,22 +61,10 @@ Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
|
||||
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/NEWS b/NEWS
|
||||
index 2ebd54e78..b04041507 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -66,7 +66,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/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index 612df2e9c..ef06f8c95 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
@ -394,3 +382,16 @@ index 570a69361..4411ffa16 100644
|
||||
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 2ebd54e78..b04041507 100644
|
||||
--- a/NEWS
|
||||
+++ b/NEWS
|
||||
@@ -66,7 +66,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.
|
||||
|
@ -0,0 +1,203 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Thu, 11 Jul 2019 17:17:02 +0200
|
||||
Subject: [PATCH] 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>
|
||||
(cherry picked from commit 9035d4f9ea2f26a9d4412a0918d597ceb5365442)
|
||||
|
||||
Conflicts:
|
||||
grub-core/loader/i386/efi/linux.c
|
||||
Context diffs in includes.
|
||||
|
||||
Signed-off-by: Lenny Szubowicz <lszubowi@redhat.com>
|
||||
---
|
||||
grub-core/kern/efi/mm.c | 8 ++++----
|
||||
grub-core/loader/i386/efi/linux.c | 24 +++++++++++++++++-------
|
||||
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(+), 12 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
|
||||
index 2d9c9032b..9e76f23e5 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;
|
||||
@@ -472,7 +472,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)
|
||||
@@ -490,9 +490,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 576f8c07e..c5fdf522b 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>
|
||||
#include <grub/tpm.h>
|
||||
#include <grub/safemath.h>
|
||||
|
||||
@@ -113,7 +114,9 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
}
|
||||
|
||||
- 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"));
|
||||
@@ -217,8 +220,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
}
|
||||
|
||||
- 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");
|
||||
@@ -288,8 +294,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"));
|
||||
@@ -316,11 +325,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 */
|
@ -0,0 +1,109 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Fri, 12 Jul 2019 09:53:32 +0200
|
||||
Subject: [PATCH] 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 <pjones@redhat.com>
|
||||
(cherry picked from commit 7765a790dee00f2e0d414cf3a3d016c493cf0d9b)
|
||||
|
||||
Conflicts:
|
||||
grub-core/loader/i386/efi/linux.c
|
||||
git cherry-pick thought delete of prior def of MIN was a
|
||||
conflict.
|
||||
|
||||
Signed-off-by: Lenny Szubowicz <lszubowi@redhat.com>
|
||||
---
|
||||
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 c5fdf522b..73cd838e9 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -37,11 +37,16 @@ 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 void *initrd_mem;
|
||||
static grub_uint32_t handover_offset;
|
||||
struct linux_kernel_params *params;
|
||||
static char *linux_cmdline;
|
||||
|
||||
+#define MIN(a, b) \
|
||||
+ ({ typeof (a) _a = (a); \
|
||||
+ typeof (b) _b = (b); \
|
||||
+ _a < _b ? _a : _b; })
|
||||
+
|
||||
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
|
||||
|
||||
static grub_err_t
|
||||
@@ -75,6 +80,44 @@ grub_linuxefi_unload (void)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+#define BOUNCE_BUFFER_MAX 0x10000000ull
|
||||
+
|
||||
+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;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
@@ -133,7 +176,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]);
|
||||
- if (grub_file_read (files[i], ptr, cursize) != cursize)
|
||||
+ if (read (files[i], ptr, cursize) != cursize)
|
||||
{
|
||||
if (!grub_errno)
|
||||
grub_error (GRUB_ERR_FILE_READ_ERROR, N_("premature end of file %s"),
|
||||
@@ -161,11 +204,6 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
-#define MIN(a, b) \
|
||||
- ({ typeof (a) _a = (a); \
|
||||
- typeof (b) _b = (b); \
|
||||
- _a < _b ? _a : _b; })
|
||||
-
|
||||
static grub_err_t
|
||||
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
@ -0,0 +1,134 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Thu, 13 Sep 2018 14:42:34 -0400
|
||||
Subject: [PATCH] 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 <pjones@redhat.com>
|
||||
(cherry picked from commit 486cdd48889b30b03143c393e59a75ea040b5c40)
|
||||
---
|
||||
grub-core/loader/i386/efi/linux.c | 75 +++++++++++++++++++++------------------
|
||||
1 file changed, 41 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index 73cd838e9..c9650561f 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -258,32 +258,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
}
|
||||
|
||||
- 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");
|
||||
- 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));
|
||||
-
|
||||
- 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,
|
||||
- sizeof (*params)) - 0x1f1,
|
||||
- (grub_uint8_t *)kernel + 0x1f1,
|
||||
- (grub_uint8_t *)params + 0x1f1);
|
||||
- grub_memcpy ((grub_uint8_t *)params + 0x1f1,
|
||||
- (grub_uint8_t *)kernel + 0x1f1,
|
||||
- MIN((grub_size_t)0x202+setup_header_end_offset,sizeof (*params)) - 0x1f1);
|
||||
- lh = (struct linux_i386_kernel_header *)params;
|
||||
- grub_dprintf ("linux", "lh is at %p\n", lh);
|
||||
grub_dprintf ("linux", "checking lh->boot_flag\n");
|
||||
if (lh->boot_flag != grub_cpu_to_le16 (0xaa55))
|
||||
{
|
||||
@@ -331,6 +308,34 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
#endif
|
||||
|
||||
+ 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");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("linux", "params = %p\n", params);
|
||||
+
|
||||
+ 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",
|
||||
+ MIN((grub_size_t)0x202+setup_header_end_offset,
|
||||
+ sizeof (*params)) - 0x1f1,
|
||||
+ (grub_uint8_t *)kernel + 0x1f1,
|
||||
+ (grub_uint8_t *)params + 0x1f1);
|
||||
+ grub_memcpy ((grub_uint8_t *)params + 0x1f1,
|
||||
+ (grub_uint8_t *)kernel + 0x1f1,
|
||||
+ MIN((grub_size_t)0x202+setup_header_end_offset,sizeof (*params)) - 0x1f1);
|
||||
+
|
||||
+ lh = (struct linux_i386_kernel_header *)params;
|
||||
+ grub_dprintf ("linux", "new lh is at %p\n", lh);
|
||||
+
|
||||
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));
|
||||
@@ -356,8 +361,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;
|
||||
|
||||
- grub_dprintf ("linux", "computing handover offset\n");
|
||||
handover_offset = lh->handover_offset;
|
||||
+ grub_dprintf("linux", "handover_offset: %08x\n", handover_offset);
|
||||
|
||||
start = (lh->setup_sects + 1) * 512;
|
||||
|
||||
@@ -374,26 +379,28 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel"));
|
||||
goto fail;
|
||||
}
|
||||
-
|
||||
- grub_dprintf ("linux", "kernel_mem = %lx\n", (unsigned long) kernel_mem);
|
||||
+ grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem);
|
||||
|
||||
grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
|
||||
- loaded=1;
|
||||
+
|
||||
+ loaded = 1;
|
||||
+
|
||||
grub_dprintf ("linux", "setting lh->code32_start to %p\n", kernel_mem);
|
||||
lh->code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem;
|
||||
|
||||
grub_memcpy (kernel_mem, (char *)kernel + start, filelen - start);
|
||||
|
||||
- grub_dprintf ("linux", "setting lh->type_of_loader\n");
|
||||
lh->type_of_loader = 0x6;
|
||||
+ grub_dprintf ("linux", "setting lh->type_of_loader = 0x%02x\n",
|
||||
+ lh->type_of_loader);
|
||||
|
||||
- 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",
|
||||
+ "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);
|
||||
|
@ -0,0 +1,259 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Wed, 12 Sep 2018 16:03:55 -0400
|
||||
Subject: [PATCH] x86-efi: Make our own allocator for kernel stuff
|
||||
|
||||
This helps enable allocations above 4GB.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
(cherry picked from commit cfea4ae780f8860d472cd2d5a9765ec2fe2adc83)
|
||||
---
|
||||
grub-core/loader/i386/efi/linux.c | 167 +++++++++++++++++++++-----------------
|
||||
1 file changed, 94 insertions(+), 73 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index c9650561f..5eed2014c 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -49,6 +49,65 @@ static char *linux_cmdline;
|
||||
|
||||
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
|
||||
|
||||
+struct allocation_choice {
|
||||
+ grub_efi_physical_address_t addr;
|
||||
+ grub_efi_allocate_type_t alloc_type;
|
||||
+};
|
||||
+
|
||||
+static struct allocation_choice max_addresses[] =
|
||||
+ {
|
||||
+ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
||||
+ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
||||
+ { GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
||||
+ { 0, 0 }
|
||||
+ };
|
||||
+
|
||||
+static inline void
|
||||
+kernel_free(void *addr, grub_efi_uintn_t size)
|
||||
+{
|
||||
+ if (addr && size)
|
||||
+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)addr,
|
||||
+ BYTES_TO_PAGES(size));
|
||||
+}
|
||||
+
|
||||
+static void *
|
||||
+kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
|
||||
+{
|
||||
+ void *addr = 0;
|
||||
+ unsigned int i;
|
||||
+ grub_efi_physical_address_t prev_max = 0;
|
||||
+
|
||||
+ for (i = 0; max_addresses[i].addr != 0 && addr == 0; i++)
|
||||
+ {
|
||||
+ grub_uint64_t max = max_addresses[i].addr;
|
||||
+ grub_efi_uintn_t pages;
|
||||
+
|
||||
+ if (max == prev_max)
|
||||
+ continue;
|
||||
+
|
||||
+ pages = BYTES_TO_PAGES(size);
|
||||
+ grub_dprintf ("linux", "Trying to allocate %lu pages from %p\n",
|
||||
+ pages, (void *)max);
|
||||
+
|
||||
+ prev_max = max;
|
||||
+ addr = grub_efi_allocate_pages_real (max, pages,
|
||||
+ max_addresses[i].alloc_type,
|
||||
+ GRUB_EFI_LOADER_DATA);
|
||||
+ if (addr)
|
||||
+ grub_dprintf ("linux", "Allocated at %p\n", addr);
|
||||
+ }
|
||||
+
|
||||
+ while (grub_error_pop ())
|
||||
+ {
|
||||
+ ;
|
||||
+ }
|
||||
+
|
||||
+ if (addr == NULL)
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, "%s", errmsg);
|
||||
+
|
||||
+ return addr;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_linuxefi_boot (void)
|
||||
{
|
||||
@@ -64,19 +123,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));
|
||||
- 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));
|
||||
+
|
||||
+ kernel_free(initrd_mem, params->ramdisk_size);
|
||||
+ kernel_free(linux_cmdline, params->cmdline_size + 1);
|
||||
+ kernel_free(kernel_mem, kernel_size);
|
||||
+ kernel_free(params, sizeof(*params));
|
||||
+
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
@@ -157,19 +209,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
}
|
||||
|
||||
- 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"));
|
||||
- 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;
|
||||
+ grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem);
|
||||
|
||||
params->ramdisk_size = size;
|
||||
- params->ramdisk_image = (grub_uint32_t)(grub_addr_t) initrd_mem;
|
||||
+ params->ramdisk_image = initrd_mem;
|
||||
|
||||
ptr = initrd_mem;
|
||||
|
||||
@@ -230,7 +276,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
filelen = grub_file_size (file);
|
||||
|
||||
kernel = grub_malloc(filelen);
|
||||
-
|
||||
if (!kernel)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel buffer"));
|
||||
@@ -289,7 +334,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
}
|
||||
|
||||
-#if defined(__x86_64__) || defined(__aarch64__)
|
||||
+#if defined(__x86_64__)
|
||||
grub_dprintf ("linux", "checking lh->xloadflags\n");
|
||||
if (!(lh->xloadflags & LINUX_XLF_KERNEL_64))
|
||||
{
|
||||
@@ -308,17 +353,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
#endif
|
||||
|
||||
- params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS,
|
||||
- BYTES_TO_PAGES(sizeof(*params)));
|
||||
+ params = kernel_alloc (sizeof(*params), "cannot allocate kernel parameters");
|
||||
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");
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
+ goto fail;
|
||||
grub_dprintf ("linux", "params = %p\n", params);
|
||||
|
||||
grub_memset (params, 0, sizeof(*params));
|
||||
@@ -337,19 +374,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");
|
||||
- linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS,
|
||||
- BYTES_TO_PAGES(lh->cmdline_size + 1));
|
||||
+ linux_cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline"));
|
||||
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"));
|
||||
- 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,
|
||||
@@ -358,27 +386,24 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
GRUB_VERIFY_KERNEL_CMDLINE);
|
||||
|
||||
grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline);
|
||||
- grub_dprintf ("linux", "setting lh->cmd_line_ptr\n");
|
||||
- lh->cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_cmdline;
|
||||
+ grub_dprintf ("linux", "setting lh->cmd_line_ptr to 0x%08x\n",
|
||||
+ linux_cmdline);
|
||||
+ lh->cmd_line_ptr = linux_cmdline;
|
||||
|
||||
handover_offset = lh->handover_offset;
|
||||
- grub_dprintf("linux", "handover_offset: %08x\n", handover_offset);
|
||||
+ grub_dprintf("linux", "handover_offset: 0x%08x\n", handover_offset);
|
||||
|
||||
start = (lh->setup_sects + 1) * 512;
|
||||
|
||||
- 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(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_dprintf ("linux", "lh->pref_address: %p\n", (void *)(grub_addr_t)lh->pref_address);
|
||||
+ if (lh->pref_address < (grub_uint64_t)GRUB_EFI_MAX_ALLOCATION_ADDRESS)
|
||||
{
|
||||
- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate kernel"));
|
||||
- goto fail;
|
||||
+ max_addresses[0].addr = lh->pref_address;
|
||||
+ max_addresses[0].alloc_type = GRUB_EFI_ALLOCATE_ADDRESS;
|
||||
}
|
||||
+ kernel_mem = kernel_alloc (lh->init_size, N_("can't allocate kernel"));
|
||||
+ if (!kernel_mem)
|
||||
+ goto fail;
|
||||
grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem);
|
||||
|
||||
grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
|
||||
@@ -413,18 +438,14 @@ fail:
|
||||
loaded = 0;
|
||||
}
|
||||
|
||||
- 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));
|
||||
+ 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));
|
||||
+ kernel_free (kernel_mem, kernel_size);
|
||||
+ kernel_free (params, sizeof(*params));
|
||||
+ }
|
||||
|
||||
return grub_errno;
|
||||
}
|
@ -0,0 +1,172 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Wed, 12 Sep 2018 16:12:27 -0400
|
||||
Subject: [PATCH] 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
|
||||
params->code32_start is used.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
(cherry picked from commit 2b636967018431b046b625ad4753c8de51f7f6b2)
|
||||
---
|
||||
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 5eed2014c..e9d2c85b3 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -54,13 +54,22 @@ struct allocation_choice {
|
||||
grub_efi_allocate_type_t alloc_type;
|
||||
};
|
||||
|
||||
-static struct allocation_choice max_addresses[] =
|
||||
+static struct allocation_choice max_addresses[4] =
|
||||
{
|
||||
+ /* the kernel overrides this one with pref_address and
|
||||
+ * GRUB_EFI_ALLOCATE_ADDRESS */
|
||||
{ GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
||||
+ /* this one is always below 4GB, which we still *prefer* even if the flag
|
||||
+ * is set. */
|
||||
{ GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
||||
+ /* If the flag in params is set, this one gets changed to be above 4GB. */
|
||||
{ GRUB_EFI_MAX_ALLOCATION_ADDRESS, GRUB_EFI_ALLOCATE_MAX_ADDRESS },
|
||||
{ 0, 0 }
|
||||
};
|
||||
+static struct allocation_choice saved_addresses[4];
|
||||
+
|
||||
+#define save_addresses() grub_memcpy(saved_addresses, max_addresses, sizeof(max_addresses))
|
||||
+#define restore_addresses() grub_memcpy(max_addresses, saved_addresses, sizeof(max_addresses))
|
||||
|
||||
static inline void
|
||||
kernel_free(void *addr, grub_efi_uintn_t size)
|
||||
@@ -82,6 +91,11 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
|
||||
grub_uint64_t max = max_addresses[i].addr;
|
||||
grub_efi_uintn_t pages;
|
||||
|
||||
+ /*
|
||||
+ * When we're *not* loading the kernel, or >4GB allocations aren't
|
||||
+ * supported, these entries are basically all the same, so don't re-try
|
||||
+ * the same parameters.
|
||||
+ */
|
||||
if (max == prev_max)
|
||||
continue;
|
||||
|
||||
@@ -170,6 +184,9 @@ read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len)
|
||||
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))
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
@@ -214,8 +231,12 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem);
|
||||
|
||||
- params->ramdisk_size = size;
|
||||
- params->ramdisk_image = initrd_mem;
|
||||
+ params->ramdisk_size = LOW_U32(size);
|
||||
+ params->ramdisk_image = LOW_U32(initrd_mem);
|
||||
+#if defined(__x86_64__)
|
||||
+ params->ext_ramdisk_size = HIGH_U32(size);
|
||||
+ params->ext_ramdisk_image = HIGH_U32(initrd_mem);
|
||||
+#endif
|
||||
|
||||
ptr = initrd_mem;
|
||||
|
||||
@@ -353,6 +374,18 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
#endif
|
||||
|
||||
+#if defined(__x86_64__)
|
||||
+ if (lh->xloadflags & LINUX_XLF_CAN_BE_LOADED_ABOVE_4G)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "Loading kernel above 4GB is supported; enabling.\n");
|
||||
+ max_addresses[2].addr = GRUB_EFI_MAX_USABLE_ADDRESS;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "Loading kernel above 4GB is not supported\n");
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
params = kernel_alloc (sizeof(*params), "cannot allocate kernel parameters");
|
||||
if (!params)
|
||||
goto fail;
|
||||
@@ -387,21 +420,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",
|
||||
- linux_cmdline);
|
||||
- lh->cmd_line_ptr = linux_cmdline;
|
||||
+ LOW_U32(linux_cmdline));
|
||||
+ lh->cmd_line_ptr = LOW_U32(linux_cmdline);
|
||||
+#if defined(__x86_64__)
|
||||
+ if ((grub_efi_uintn_t)linux_cmdline > 0xffffffffull)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "setting params->ext_cmd_line_ptr to 0x%08x\n",
|
||||
+ HIGH_U32(linux_cmdline));
|
||||
+ params->ext_cmd_line_ptr = HIGH_U32(linux_cmdline);
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
handover_offset = lh->handover_offset;
|
||||
grub_dprintf("linux", "handover_offset: 0x%08x\n", handover_offset);
|
||||
|
||||
start = (lh->setup_sects + 1) * 512;
|
||||
|
||||
+ /*
|
||||
+ * AFAICS >4GB for kernel *cannot* work because of params->code32_start being
|
||||
+ * 32-bit and getting called unconditionally in head_64.S from either entry
|
||||
+ * point.
|
||||
+ *
|
||||
+ * so nerf that out here...
|
||||
+ */
|
||||
+ save_addresses();
|
||||
grub_dprintf ("linux", "lh->pref_address: %p\n", (void *)(grub_addr_t)lh->pref_address);
|
||||
if (lh->pref_address < (grub_uint64_t)GRUB_EFI_MAX_ALLOCATION_ADDRESS)
|
||||
{
|
||||
max_addresses[0].addr = lh->pref_address;
|
||||
max_addresses[0].alloc_type = GRUB_EFI_ALLOCATE_ADDRESS;
|
||||
}
|
||||
+ max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
|
||||
+ max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
|
||||
kernel_mem = kernel_alloc (lh->init_size, N_("can't allocate kernel"));
|
||||
+ restore_addresses();
|
||||
if (!kernel_mem)
|
||||
goto fail;
|
||||
grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem);
|
||||
@@ -410,8 +462,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
loaded = 1;
|
||||
|
||||
- grub_dprintf ("linux", "setting lh->code32_start to %p\n", kernel_mem);
|
||||
- lh->code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem;
|
||||
+ grub_dprintf ("linux", "setting lh->code32_start to 0x%08x\n",
|
||||
+ LOW_U32(kernel_mem));
|
||||
+ lh->code32_start = LOW_U32(kernel_mem);
|
||||
|
||||
grub_memcpy (kernel_mem, (char *)kernel + start, filelen - start);
|
||||
|
||||
diff --git a/include/grub/i386/linux.h b/include/grub/i386/linux.h
|
||||
index 8474a857e..a4b37dcce 100644
|
||||
--- a/include/grub/i386/linux.h
|
||||
+++ b/include/grub/i386/linux.h
|
||||
@@ -230,7 +230,11 @@ struct linux_kernel_params
|
||||
grub_uint32_t ofw_cif_handler; /* b8 */
|
||||
grub_uint32_t ofw_idt; /* bc */
|
||||
|
||||
- grub_uint8_t padding7[0x1b8 - 0xc0];
|
||||
+ grub_uint32_t ext_ramdisk_image; /* 0xc0 */
|
||||
+ grub_uint32_t ext_ramdisk_size; /* 0xc4 */
|
||||
+ grub_uint32_t ext_cmd_line_ptr; /* 0xc8 */
|
||||
+
|
||||
+ grub_uint8_t padding7[0x1b8 - 0xcc];
|
||||
|
||||
union
|
||||
{
|
@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Tue, 26 May 2020 16:59:28 +0200
|
||||
Subject: [PATCH] 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.
|
||||
|
||||
But the verifiers framework also allocates a buffer to copy the initrd in
|
||||
its grub_file_open() handler. It does this since the data to verify has to
|
||||
be passed as a single chunk to modules that use the verifiers framework.
|
||||
|
||||
If the initrd image size is big there may not be enough memory in the heap
|
||||
to allocate two buffers of that size. This causes an allocation failure in
|
||||
the verifiers framework and leads to the initrd not being read.
|
||||
|
||||
To prevent these allocation failures, let's reduce the maximum size of the
|
||||
bounce buffer used in the EFI loader. Since the data read can be copied to
|
||||
the actual initrd address in multilple chunks.
|
||||
|
||||
Resolves: rhbz#1838633
|
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
(cherry picked from commit 1c0d2ebdddf69962395f0fa4578446654512f3c4)
|
||||
---
|
||||
grub-core/loader/i386/efi/linux.c | 2 +-
|
||||
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 e9d2c85b3..a043df891 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -146,7 +146,7 @@ grub_linuxefi_unload (void)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
-#define BOUNCE_BUFFER_MAX 0x10000000ull
|
||||
+#define BOUNCE_BUFFER_MAX 0x1000000ull
|
||||
|
||||
static grub_ssize_t
|
||||
read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len)
|
@ -0,0 +1,221 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.ibm.com>
|
||||
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 <eric.snowberg@oracle.com>
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 7 ++
|
||||
grub-core/commands/ieee1275/ibmvtpm.c | 152 ++++++++++++++++++++++++++++++++++
|
||||
include/grub/ieee1275/ieee1275.h | 3 +
|
||||
3 files changed, 162 insertions(+)
|
||||
create mode 100644 grub-core/commands/ieee1275/ibmvtpm.c
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index ef06f8c95a..b11f74e6b2 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1104,6 +1104,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 <http://www.gnu.org/licenses/>.
|
||||
+ *
|
||||
+ * IBM vTPM support code.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/tpm.h>
|
||||
+#include <grub/ieee1275/ieee1275.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/misc.h>
|
||||
+
|
||||
+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 131808d619..87b9f95d34 100644
|
||||
--- a/include/grub/ieee1275/ieee1275.h
|
||||
+++ b/include/grub/ieee1275/ieee1275.h
|
||||
@@ -24,6 +24,9 @@
|
||||
#include <grub/types.h>
|
||||
#include <grub/machine/ieee1275.h>
|
||||
|
||||
+#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;
|
@ -0,0 +1,94 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.vnet.ibm.com>
|
||||
Date: Fri, 11 Feb 2022 16:34:23 -0500
|
||||
Subject: [PATCH] ibmvtpm: Backport ibmvtpm support to grub 2.02
|
||||
|
||||
Backport ibmvtpm support to grub 2.02 by making as few changes to the
|
||||
source as possible and building it into the core.
|
||||
|
||||
Since ibmvtpm support is built into grub 2.02 do not print the error
|
||||
message we would typically print if it was a module and the user had
|
||||
a choice to not use vTPM support if there was no vTPM by avoiding
|
||||
to use the module.
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 8 +-------
|
||||
grub-core/commands/ieee1275/ibmvtpm.c | 13 ++++++++++---
|
||||
include/grub/tpm.h | 2 +-
|
||||
3 files changed, 12 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index b11f74e6b2..637d7203e3 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -298,6 +298,7 @@ kernel = {
|
||||
powerpc_ieee1275 = kern/powerpc/cache.S;
|
||||
powerpc_ieee1275 = kern/powerpc/dl.c;
|
||||
powerpc_ieee1275 = kern/powerpc/compiler-rt.S;
|
||||
+ powerpc_ieee1275 = commands/ieee1275/ibmvtpm.c;
|
||||
|
||||
sparc64_ieee1275 = kern/sparc64/cache.S;
|
||||
sparc64_ieee1275 = kern/sparc64/dl.c;
|
||||
@@ -1104,13 +1105,6 @@ 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
|
||||
index e68b8448bc..728b2cbdcd 100644
|
||||
--- a/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
+++ b/grub-core/commands/ieee1275/ibmvtpm.c
|
||||
@@ -115,7 +115,8 @@ tpm2_log_event (unsigned char *buf,
|
||||
grub_size_t size, grub_uint8_t pcr,
|
||||
const char *description)
|
||||
{
|
||||
- static int error_displayed = 0;
|
||||
+ /* Do not print error since vTPM support is built-in */
|
||||
+ static int error_displayed = 1;
|
||||
int err;
|
||||
|
||||
err = ibmvtpm_2hash_ext_log (pcr, EV_IPL,
|
||||
@@ -132,8 +133,8 @@ tpm2_log_event (unsigned char *buf,
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
-grub_err_t
|
||||
-grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
+static 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();
|
||||
@@ -150,3 +151,9 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
+
|
||||
+grub_err_t grub_tpm_log_event(unsigned char *buf, grub_size_t size,
|
||||
+ grub_uint8_t pcr, const char *description)
|
||||
+{
|
||||
+ return _grub_tpm_measure(buf, size, pcr, description);
|
||||
+}
|
||||
diff --git a/include/grub/tpm.h b/include/grub/tpm.h
|
||||
index ce52be4ff7..52af2b8448 100644
|
||||
--- a/include/grub/tpm.h
|
||||
+++ b/include/grub/tpm.h
|
||||
@@ -69,7 +69,7 @@ typedef struct {
|
||||
grub_err_t EXPORT_FUNC(grub_tpm_measure) (unsigned char *buf, grub_size_t size,
|
||||
grub_uint8_t pcr, const char *kind,
|
||||
const char *description);
|
||||
-#if defined (GRUB_MACHINE_EFI)
|
||||
+#if defined (GRUB_MACHINE_EFI) || defined (GRUB_MACHINE_IEEE1275)
|
||||
grub_err_t grub_tpm_execute(PassThroughToTPM_InputParamBlock *inbuf,
|
||||
PassThroughToTPM_OutputParamBlock *outbuf);
|
||||
grub_err_t grub_tpm_log_event(unsigned char *buf, grub_size_t size,
|
112
SOURCES/0503-powerpc-do-CAS-in-a-more-compatible-way.patch
Normal file
112
SOURCES/0503-powerpc-do-CAS-in-a-more-compatible-way.patch
Normal file
@ -0,0 +1,112 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Fri, 8 Apr 2022 12:35:28 +1000
|
||||
Subject: [PATCH] powerpc: do CAS in a more compatible way
|
||||
|
||||
I wrongly assumed that the most compatible way to perform CAS
|
||||
negotiation was to only set the minimum number of vectors required
|
||||
to ask for more memory. It turns out that this messes up booting
|
||||
if the minimum VP capacity would be less than the default 10% in
|
||||
vector 4.
|
||||
|
||||
Linux configures the minimum capacity to be 1%, so copy it for that
|
||||
and for vector 3 which we now need to specify as well.
|
||||
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
(cherry picked from commit e6f02ad4e75cd995a8ee2954d28949c415b6cbfe)
|
||||
(cherry picked from commit 9f825ebc319c56ca503741e6dc1a0f27ff36fe2d)
|
||||
---
|
||||
grub-core/kern/ieee1275/init.c | 54 ++++++++++++++++++++++++------------------
|
||||
1 file changed, 31 insertions(+), 23 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index adf4bd5a88..1414695cc6 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -294,33 +294,37 @@ grub_ieee1275_total_mem (grub_uint64_t *total)
|
||||
|
||||
/* 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;
|
||||
+ 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;
|
||||
+ 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;
|
||||
+ 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;
|
||||
+ grub_uint8_t vec3_size;
|
||||
+ grub_uint16_t vec3;
|
||||
+ grub_uint8_t vec4_size;
|
||||
+ grub_uint16_t vec4;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Call ibm,client-architecture-support to try to get more RMA.
|
||||
@@ -341,13 +345,17 @@ grub_ieee1275_ibm_cas (void)
|
||||
} args;
|
||||
struct cas_vector vector = {
|
||||
.pvr_list = { { 0x00000000, 0xffffffff } }, /* any processor */
|
||||
- .num_vecs = 2 - 1,
|
||||
+ .num_vecs = 4 - 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
|
||||
},
|
||||
+ .vec3_size = 2 - 1,
|
||||
+ .vec3 = 0x00e0, // ask for FP + VMX + DFP but don't halt if unsatisfied
|
||||
+ .vec4_size = 2 - 1,
|
||||
+ .vec4 = 0x0001, // set required minimum capacity % to the lowest value
|
||||
};
|
||||
|
||||
INIT_IEEE1275_COMMON (&args.common, "call-method", 3, 2);
|
||||
@@ -360,7 +368,7 @@ grub_ieee1275_ibm_cas (void)
|
||||
args.ihandle = root;
|
||||
args.cas_addr = (grub_ieee1275_cell_t)&vector;
|
||||
|
||||
- grub_printf("Calling ibm,client-architecture-support...");
|
||||
+ grub_printf("Calling ibm,client-architecture-support from grub...");
|
||||
IEEE1275_CALL_ENTRY_FN (&args);
|
||||
grub_printf("done\n");
|
||||
|
@ -0,0 +1,73 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Thu, 24 Mar 2022 14:34:32 +1100
|
||||
Subject: [PATCH] powerpc: prefix detection: support device names with commas
|
||||
|
||||
Frustratingly, the device name itself can contain an embedded comma:
|
||||
e.g /pci@800000020000015/pci1014,034A@0/sas/disk@5000c50098a0ee8b
|
||||
|
||||
So my previous approach was wrong: we cannot rely upon the presence
|
||||
of a comma to say that a partition has been specified!
|
||||
|
||||
It turns out for prefixes like (,gpt2)/grub2 we really want to make
|
||||
up a full (device,partition)/patch prefix, because root discovery code
|
||||
in 10_linux will reset the root variable and use search to fill it again.
|
||||
If you have run grub-install, you probably don't have search built in,
|
||||
and if you don't have prefix containing (device,partition), grub will
|
||||
construct ($root)$prefix/powerpc-ieee1275/search.mod - but because $root
|
||||
has just been changed, this will no longer work, and the boot will fail!
|
||||
|
||||
Retain the gist of the logic, but instead of looking for a comma, look for
|
||||
a leading '('. This matches the earlier code better anyway.
|
||||
|
||||
There's certainly a better fix to be had. But any time you chose to build
|
||||
with a bare prefix like '/grub2', you're almost certainly going to build in
|
||||
search anyway, so this will do.
|
||||
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
(cherry picked from commit 80b6eb5e55e6d1a4c9896361e61de31c29e6939d)
|
||||
(cherry picked from commit f3df9f1c2335df22d020e80583d932e254594f0e)
|
||||
---
|
||||
grub-core/kern/main.c | 27 +++++++++++++++++++++------
|
||||
1 file changed, 21 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/main.c b/grub-core/kern/main.c
|
||||
index 40a709117f..abbf8af9e6 100644
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -241,14 +241,29 @@ grub_set_prefix_and_root (void)
|
||||
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.
|
||||
+ - Frustratingly, the device name itself can contain an embedded comma:
|
||||
+ /pci@800000020000015/pci1014,034A@0/sas/disk@5000c50098a0ee8b
|
||||
+ So we cannot even rely upon the presence of a comma to say that a
|
||||
+ partition has 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 we only have a path in $prefix, the code in normal to discover
|
||||
+ config files will try all disks, both without partitions and then with
|
||||
+ any partitions so we will cover both CDs and HDs.
|
||||
+
|
||||
+ However, it doesn't then set the prefix to be something like
|
||||
+ (discovered partition)/path, and so it is fragile against runtime
|
||||
+ changes to $root. For example some of the stuff done in 10_linux to
|
||||
+ reload $root sets root differently and then uses search to find it
|
||||
+ again. If the search module is not built in, when we change root, grub
|
||||
+ will look in (new root)/path/powerpc-ieee1275, that won't work, and we
|
||||
+ will not be able to load the search module and the boot will fail.
|
||||
+
|
||||
+ This is particularly likely to hit us in the grub-install
|
||||
+ (,msdos2)/grub2 case, so we act unless the supplied prefix starts with
|
||||
+ '(', which would likely indicate a partition has already been
|
||||
+ specified.
|
||||
*/
|
||||
- if (grub_strchr (device, ',') == NULL)
|
||||
+ if (prefix && prefix[0] != '(')
|
||||
grub_env_set ("prefix", path);
|
||||
else
|
||||
#endif
|
43
SOURCES/0505-make-ofdisk_retries-optional.patch
Normal file
43
SOURCES/0505-make-ofdisk_retries-optional.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegdo@br.ibm.com>
|
||||
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); }
|
@ -0,0 +1,71 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Thu, 28 Apr 2022 21:53:36 +0100
|
||||
Subject: [PATCH] loader/efi/chainloader: grub_load_and_start_image doesn't
|
||||
load and start
|
||||
|
||||
grub_load_and_start_image only loads an image - it still requires the
|
||||
caller to start it. This renames it to grub_load_image.
|
||||
|
||||
It's called from 2 places:
|
||||
- grub_cmd_chainloader when not using the shim protocol.
|
||||
- grub_secureboot_chainloader_boot if handle_image returns an error.
|
||||
In this case, the image is loaded and then nothing else happens which
|
||||
seems strange. I assume the intention is that it falls back to LoadImage
|
||||
and StartImage if handle_image fails, so I've made it do that.
|
||||
|
||||
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
(cherry picked from commit b4d70820a65c00561045856b7b8355461a9545f6)
|
||||
(cherry picked from commit 05b16a6be50b1910609740a66b561276fa490538)
|
||||
(cherry picked from commit 16486a34f3aa41a94e334e86db1a1e21e9b0a45f)
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 16 +++++++++++++---
|
||||
1 file changed, 13 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index 29663f7180..d75d345003 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -835,7 +835,7 @@ grub_secureboot_chainloader_unload (void)
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_load_and_start_image(void *boot_image)
|
||||
+grub_load_image(void *boot_image)
|
||||
{
|
||||
grub_efi_boot_services_t *b;
|
||||
grub_efi_status_t status;
|
||||
@@ -877,13 +877,23 @@ grub_load_and_start_image(void *boot_image)
|
||||
static grub_err_t
|
||||
grub_secureboot_chainloader_boot (void)
|
||||
{
|
||||
+ grub_efi_boot_services_t *b;
|
||||
int rc;
|
||||
+
|
||||
rc = handle_image ((void *)(unsigned long)address, fsize);
|
||||
if (rc == 0)
|
||||
{
|
||||
- grub_load_and_start_image((void *)(unsigned long)address);
|
||||
+ /* We weren't able to attempt to execute the image, so fall back
|
||||
+ * to LoadImage / StartImage.
|
||||
+ */
|
||||
+ rc = grub_load_image((void *)(unsigned long)address);
|
||||
+ if (rc == 0)
|
||||
+ grub_chainloader_boot ();
|
||||
}
|
||||
|
||||
+ b = grub_efi_system_table->boot_services;
|
||||
+ efi_call_1 (b->unload_image, image_handle);
|
||||
+
|
||||
grub_loader_unset ();
|
||||
return grub_errno;
|
||||
}
|
||||
@@ -1072,7 +1082,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
else if (rc == 0)
|
||||
{
|
||||
- grub_load_and_start_image(boot_image);
|
||||
+ grub_load_image(boot_image);
|
||||
grub_file_close (file);
|
||||
grub_device_close (dev);
|
||||
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
|
@ -0,0 +1,334 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Fri, 29 Apr 2022 21:13:08 +0100
|
||||
Subject: [PATCH] loader/efi/chainloader: simplify the loader state
|
||||
|
||||
When not using the shim lock protocol, the chainloader command retains
|
||||
the source buffer and device path passed to LoadImage, requiring the
|
||||
unload hook passed to grub_loader_set to free them. It isn't required
|
||||
to retain this state though - they aren't required by StartImage or
|
||||
anything else in the boot hook, so clean them up before
|
||||
grub_cmd_chainloader finishes.
|
||||
|
||||
This also wraps the loader state when using the shim lock protocol
|
||||
inside a struct.
|
||||
|
||||
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
(cherry picked from commit fa39862933b3be1553a580a3a5c28073257d8046)
|
||||
(cherry picked from commit 0333343ee99c4e88f062789263c94291c057251b)
|
||||
[rharwood: verifying twice]
|
||||
(cherry picked from commit 6080ad5d91d6a80d5f67c592dd33b6dd413e9453)
|
||||
[rharwood: double frees and unintialized, context fuzz - orig_dp]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 160 +++++++++++++++++++++++--------------
|
||||
1 file changed, 102 insertions(+), 58 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index d75d345003..afeb1fc97e 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -47,38 +47,21 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
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);
|
||||
+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;
|
||||
+};
|
||||
+static struct grub_secureboot_chainloader_context *sb_context;
|
||||
|
||||
static grub_err_t
|
||||
-grub_chainloader_unload (void)
|
||||
-{
|
||||
- grub_efi_boot_services_t *b;
|
||||
-
|
||||
- b = grub_efi_system_table->boot_services;
|
||||
- efi_call_1 (b->unload_image, image_handle);
|
||||
- grub_efi_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_chainloader_boot (void)
|
||||
+grub_start_image (grub_efi_handle_t handle)
|
||||
{
|
||||
grub_efi_boot_services_t *b;
|
||||
grub_efi_status_t status;
|
||||
@@ -86,7 +69,7 @@ grub_chainloader_boot (void)
|
||||
grub_efi_char16_t *exit_data = NULL;
|
||||
|
||||
b = grub_efi_system_table->boot_services;
|
||||
- status = efi_call_3 (b->start_image, image_handle, &exit_data_size, &exit_data);
|
||||
+ status = efi_call_3 (b->start_image, handle, &exit_data_size, &exit_data);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
if (exit_data)
|
||||
@@ -110,11 +93,37 @@ grub_chainloader_boot (void)
|
||||
if (exit_data)
|
||||
grub_efi_free_pool (exit_data);
|
||||
|
||||
- grub_loader_unset ();
|
||||
-
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+grub_chainloader_unload (void)
|
||||
+{
|
||||
+ grub_efi_loaded_image_t *loaded_image;
|
||||
+ grub_efi_boot_services_t *b;
|
||||
+
|
||||
+ loaded_image = grub_efi_get_loaded_image (image_handle);
|
||||
+ if (loaded_image != NULL)
|
||||
+ grub_free (loaded_image->load_options);
|
||||
+
|
||||
+ b = grub_efi_system_table->boot_services;
|
||||
+ efi_call_1 (b->unload_image, image_handle);
|
||||
+
|
||||
+ grub_dl_unref (my_mod);
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_chainloader_boot (void)
|
||||
+{
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ err = grub_start_image (image_handle);
|
||||
+
|
||||
+ grub_loader_unset ();
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
copy_file_path (grub_efi_file_path_device_path_t *fp,
|
||||
const char *str, grub_efi_uint16_t len)
|
||||
@@ -149,7 +158,7 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
|
||||
char *dir_start;
|
||||
char *dir_end;
|
||||
grub_size_t size;
|
||||
- grub_efi_device_path_t *d;
|
||||
+ grub_efi_device_path_t *d, *file_path;
|
||||
|
||||
dir_start = grub_strchr (filename, ')');
|
||||
if (! dir_start)
|
||||
@@ -520,10 +529,12 @@ 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)
|
||||
+handle_image (struct grub_secureboot_chainloader_context *load_context)
|
||||
{
|
||||
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;
|
||||
void *buffer = NULL;
|
||||
char *buffer_aligned = NULL;
|
||||
grub_efi_uint32_t i;
|
||||
@@ -534,6 +545,7 @@ handle_image (void *data, grub_efi_uint32_t datasize)
|
||||
grub_uint32_t buffer_size;
|
||||
int found_entry_point = 0;
|
||||
int rc;
|
||||
+ grub_efi_status_t (*entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table);
|
||||
|
||||
rc = read_header (data, datasize, &context);
|
||||
if (rc < 0)
|
||||
@@ -791,10 +803,10 @@ handle_image (void *data, grub_efi_uint32_t datasize)
|
||||
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;
|
||||
+ 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_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching file path found");
|
||||
@@ -823,19 +835,22 @@ error_exit:
|
||||
static grub_err_t
|
||||
grub_secureboot_chainloader_unload (void)
|
||||
{
|
||||
- grub_efi_free_pages (address, pages);
|
||||
- grub_free (file_path);
|
||||
- grub_free (cmdline);
|
||||
- cmdline = 0;
|
||||
- file_path = 0;
|
||||
- dev_handle = 0;
|
||||
+ grub_efi_free_pages (sb_context->address, sb_context->pages);
|
||||
+ grub_free (sb_context->file_path);
|
||||
+ grub_free (sb_context->cmdline);
|
||||
+ grub_free (sb_context);
|
||||
+
|
||||
+ sb_context = 0;
|
||||
|
||||
grub_dl_unref (my_mod);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_load_image(void *boot_image)
|
||||
+grub_load_image(grub_efi_device_path_t *file_path, void *boot_image,
|
||||
+ grub_efi_uintn_t image_size, grub_efi_handle_t dev_handle,
|
||||
+ grub_efi_char16_t *cmdline, grub_ssize_t cmdline_len,
|
||||
+ grub_efi_handle_t *image_handle_out)
|
||||
{
|
||||
grub_efi_boot_services_t *b;
|
||||
grub_efi_status_t status;
|
||||
@@ -844,7 +859,7 @@ grub_load_image(void *boot_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);
|
||||
+ boot_image, image_size, image_handle_out);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
if (status == GRUB_EFI_OUT_OF_RESOURCES)
|
||||
@@ -857,7 +872,7 @@ grub_load_image(void *boot_image)
|
||||
/* 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);
|
||||
+ loaded_image = grub_efi_get_loaded_image (*image_handle_out);
|
||||
if (! loaded_image)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS, "no loaded image available");
|
||||
@@ -879,20 +894,25 @@ grub_secureboot_chainloader_boot (void)
|
||||
{
|
||||
grub_efi_boot_services_t *b;
|
||||
int rc;
|
||||
+ grub_efi_handle_t handle = 0;
|
||||
|
||||
- rc = handle_image ((void *)(unsigned long)address, fsize);
|
||||
+ rc = handle_image (sb_context);
|
||||
if (rc == 0)
|
||||
{
|
||||
/* We weren't able to attempt to execute the image, so fall back
|
||||
* to LoadImage / StartImage.
|
||||
*/
|
||||
- rc = grub_load_image((void *)(unsigned long)address);
|
||||
+ rc = grub_load_image(sb_context->file_path,
|
||||
+ (void *)(unsigned long)sb_context->address,
|
||||
+ sb_context->fsize, sb_context->dev_handle,
|
||||
+ sb_context->cmdline, sb_context->cmdline_len,
|
||||
+ &handle);
|
||||
if (rc == 0)
|
||||
- grub_chainloader_boot ();
|
||||
+ grub_start_image (handle);
|
||||
}
|
||||
|
||||
b = grub_efi_system_table->boot_services;
|
||||
- efi_call_1 (b->unload_image, image_handle);
|
||||
+ efi_call_1 (b->unload_image, handle);
|
||||
|
||||
grub_loader_unset ();
|
||||
return grub_errno;
|
||||
@@ -906,10 +926,16 @@ 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_efi_device_path_t *dp = 0;
|
||||
+ grub_efi_device_path_t *dp = 0, *file_path = 0;
|
||||
char *filename;
|
||||
void *boot_image = 0;
|
||||
int rc;
|
||||
+ grub_efi_physical_address_t address = 0;
|
||||
+ grub_ssize_t fsize;
|
||||
+ grub_efi_uintn_t pages = 0;
|
||||
+ grub_efi_char16_t *cmdline = 0;
|
||||
+ 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"));
|
||||
@@ -917,12 +943,6 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
|
||||
- /* Initialize some global variables. */
|
||||
- address = 0;
|
||||
- image_handle = 0;
|
||||
- file_path = 0;
|
||||
- dev_handle = 0;
|
||||
-
|
||||
b = grub_efi_system_table->boot_services;
|
||||
|
||||
if (argc > 1)
|
||||
@@ -1074,17 +1094,35 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_dprintf ("chain", "linuxefi_secure_validate: %d\n", rc);
|
||||
if (rc > 0)
|
||||
{
|
||||
+ sb_context = grub_malloc (sizeof (*sb_context));
|
||||
+ if (sb_context == NULL)
|
||||
+ goto fail;
|
||||
+ sb_context->address = address;
|
||||
+ sb_context->fsize = fsize;
|
||||
+ sb_context->pages = pages;
|
||||
+ sb_context->file_path = file_path;
|
||||
+ sb_context->cmdline = cmdline;
|
||||
+ sb_context->cmdline_len = cmdline_len;
|
||||
+ sb_context->dev_handle = dev_handle;
|
||||
+
|
||||
grub_file_close (file);
|
||||
grub_device_close (dev);
|
||||
+
|
||||
grub_loader_set (grub_secureboot_chainloader_boot,
|
||||
grub_secureboot_chainloader_unload, 0);
|
||||
return 0;
|
||||
}
|
||||
else if (rc == 0)
|
||||
{
|
||||
- grub_load_image(boot_image);
|
||||
+ grub_load_image(file_path, boot_image, fsize, dev_handle, cmdline,
|
||||
+ cmdline_len, &image_handle);
|
||||
grub_file_close (file);
|
||||
grub_device_close (dev);
|
||||
+
|
||||
+ /* We're finished with the source image buffer and file path now */
|
||||
+ efi_call_2 (b->free_pages, address, pages);
|
||||
+ grub_free (file_path);
|
||||
+
|
||||
grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
|
||||
|
||||
return 0;
|
||||
@@ -1106,6 +1144,12 @@ fail:
|
||||
if (cmdline)
|
||||
grub_free (cmdline);
|
||||
|
||||
+ if (image_handle != 0)
|
||||
+ {
|
||||
+ efi_call_1 (b->unload_image, image_handle);
|
||||
+ image_handle = 0;
|
||||
+ }
|
||||
+
|
||||
grub_dl_unref (my_mod);
|
||||
|
||||
return grub_errno;
|
@ -0,0 +1,160 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
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 <chris.coulson@canonical.com>
|
||||
(cherry picked from commit 4322a64dde7e8fedb58e50b79408667129d45dd3)
|
||||
(cherry picked from commit 937ad0e2159b6b8cb0d2ce3515da3a8b797c7927)
|
||||
(cherry picked from commit 873038ae7048f6cae8a3ebb2f97a8d361a080e13)
|
||||
---
|
||||
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);
|
||||
|
149
SOURCES/0509-loader-efi-chainloader-Use-grub_loader_set_ex.patch
Normal file
149
SOURCES/0509-loader-efi-chainloader-Use-grub_loader_set_ex.patch
Normal file
@ -0,0 +1,149 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Fri, 29 Apr 2022 21:30:56 +0100
|
||||
Subject: [PATCH] loader/efi/chainloader: Use grub_loader_set_ex
|
||||
|
||||
This ports the EFI chainloader to use grub_loader_set_ex in order to fix
|
||||
a use-after-free bug that occurs when grub_cmd_chainloader is executed
|
||||
more than once before a boot attempt is performed.
|
||||
|
||||
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
(cherry picked from commit 4b7f0402b7cb0f67a93be736f2b75b818d7f44c9)
|
||||
(cherry picked from commit fc1a79bf0e0bc019362ace46d908a92b48dcd55b)
|
||||
(cherry picked from commit f5b653dfe00271384ff7fbd82db926ab95dbd80e)
|
||||
[rharwood: context sludge from previous commit]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 38 ++++++++++++++++++++++----------------
|
||||
1 file changed, 22 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index afeb1fc97e..720f6181e5 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -47,8 +47,6 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static grub_dl_t my_mod;
|
||||
|
||||
-static grub_efi_handle_t image_handle;
|
||||
-
|
||||
struct grub_secureboot_chainloader_context {
|
||||
grub_efi_physical_address_t address;
|
||||
grub_efi_uintn_t pages;
|
||||
@@ -58,7 +56,6 @@ struct grub_secureboot_chainloader_context {
|
||||
grub_ssize_t cmdline_len;
|
||||
grub_efi_handle_t dev_handle;
|
||||
};
|
||||
-static struct grub_secureboot_chainloader_context *sb_context;
|
||||
|
||||
static grub_err_t
|
||||
grub_start_image (grub_efi_handle_t handle)
|
||||
@@ -97,11 +94,14 @@ grub_start_image (grub_efi_handle_t handle)
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_chainloader_unload (void)
|
||||
+grub_chainloader_unload (void *context)
|
||||
{
|
||||
+ grub_efi_handle_t image_handle;
|
||||
grub_efi_loaded_image_t *loaded_image;
|
||||
grub_efi_boot_services_t *b;
|
||||
|
||||
+ image_handle = (grub_efi_handle_t) context;
|
||||
+
|
||||
loaded_image = grub_efi_get_loaded_image (image_handle);
|
||||
if (loaded_image != NULL)
|
||||
grub_free (loaded_image->load_options);
|
||||
@@ -114,10 +114,12 @@ grub_chainloader_unload (void)
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_chainloader_boot (void)
|
||||
+grub_chainloader_boot (void *context)
|
||||
{
|
||||
+ grub_efi_handle_t image_handle;
|
||||
grub_err_t err;
|
||||
|
||||
+ image_handle = (grub_efi_handle_t) context;
|
||||
err = grub_start_image (image_handle);
|
||||
|
||||
grub_loader_unset ();
|
||||
@@ -833,15 +835,17 @@ error_exit:
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_secureboot_chainloader_unload (void)
|
||||
+grub_secureboot_chainloader_unload (void *context)
|
||||
{
|
||||
+ struct grub_secureboot_chainloader_context *sb_context;
|
||||
+
|
||||
+ sb_context = (struct grub_secureboot_chainloader_context *) context;
|
||||
+
|
||||
grub_efi_free_pages (sb_context->address, sb_context->pages);
|
||||
grub_free (sb_context->file_path);
|
||||
grub_free (sb_context->cmdline);
|
||||
grub_free (sb_context);
|
||||
|
||||
- sb_context = 0;
|
||||
-
|
||||
grub_dl_unref (my_mod);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -890,12 +894,15 @@ grub_load_image(grub_efi_device_path_t *file_path, void *boot_image,
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_secureboot_chainloader_boot (void)
|
||||
+grub_secureboot_chainloader_boot (void *context)
|
||||
{
|
||||
+ struct grub_secureboot_chainloader_context *sb_context;
|
||||
grub_efi_boot_services_t *b;
|
||||
int rc;
|
||||
grub_efi_handle_t handle = 0;
|
||||
|
||||
+ sb_context = (struct grub_secureboot_chainloader_context *) context;
|
||||
+
|
||||
rc = handle_image (sb_context);
|
||||
if (rc == 0)
|
||||
{
|
||||
@@ -936,6 +943,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_efi_char16_t *cmdline = 0;
|
||||
grub_ssize_t cmdline_len = 0;
|
||||
grub_efi_handle_t dev_handle = 0;
|
||||
+ grub_efi_handle_t image_handle = 0;
|
||||
+ struct grub_secureboot_chainloader_context *sb_context = 0;
|
||||
|
||||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
@@ -1108,8 +1117,8 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_file_close (file);
|
||||
grub_device_close (dev);
|
||||
|
||||
- grub_loader_set (grub_secureboot_chainloader_boot,
|
||||
- grub_secureboot_chainloader_unload, 0);
|
||||
+ grub_loader_set_ex (grub_secureboot_chainloader_boot,
|
||||
+ grub_secureboot_chainloader_unload, sb_context, 0);
|
||||
return 0;
|
||||
}
|
||||
else if (rc == 0)
|
||||
@@ -1123,7 +1132,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
efi_call_2 (b->free_pages, address, pages);
|
||||
grub_free (file_path);
|
||||
|
||||
- grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
|
||||
+ grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, image_handle, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1145,10 +1154,7 @@ fail:
|
||||
grub_free (cmdline);
|
||||
|
||||
if (image_handle != 0)
|
||||
- {
|
||||
- efi_call_1 (b->unload_image, image_handle);
|
||||
- image_handle = 0;
|
||||
- }
|
||||
+ efi_call_1 (b->unload_image, image_handle);
|
||||
|
||||
grub_dl_unref (my_mod);
|
||||
|
@ -0,0 +1,43 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Mon, 2 May 2022 14:39:31 +0200
|
||||
Subject: [PATCH] loader/i386/efi/linux: Avoid a use-after-free in the linuxefi
|
||||
loader
|
||||
|
||||
In some error paths in grub_cmd_linux, the pointer to lh may be
|
||||
dereferenced after the buffer it points to has been freed. There aren't
|
||||
any security implications from this because nothing else uses the
|
||||
allocator after the buffer is freed and before the pointer is
|
||||
dereferenced, but fix it anyway.
|
||||
|
||||
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
(cherry picked from commit 8224f5a71af94bec8697de17e7e579792db9f9e2)
|
||||
(cherry picked from commit 4744b62e20d07674017213ac54d7442d679f9d1a)
|
||||
(cherry picked from commit 329633cb060957c3d2aca677ac733f07b213a63f)
|
||||
---
|
||||
grub-core/loader/i386/efi/linux.c | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index a043df891f..c9a2b47370 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -482,9 +482,6 @@ fail:
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
|
||||
- if (kernel)
|
||||
- grub_free (kernel);
|
||||
-
|
||||
if (grub_errno != GRUB_ERR_NONE)
|
||||
{
|
||||
grub_dl_unref (my_mod);
|
||||
@@ -500,6 +497,8 @@ fail:
|
||||
kernel_free (params, sizeof(*params));
|
||||
}
|
||||
|
||||
+ grub_free (kernel);
|
||||
+
|
||||
return grub_errno;
|
||||
}
|
||||
|
299
SOURCES/0511-loader-i386-efi-linux-Use-grub_loader_set_ex.patch
Normal file
299
SOURCES/0511-loader-i386-efi-linux-Use-grub_loader_set_ex.patch
Normal file
@ -0,0 +1,299 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Mon, 2 May 2022 17:04:23 +0200
|
||||
Subject: [PATCH] loader/i386/efi/linux: Use grub_loader_set_ex
|
||||
|
||||
This ports the linuxefi loader to use grub_loader_set_ex in order to fix
|
||||
a use-after-fre bug that occurs when grub_cmd_linux is executed more than
|
||||
once before a boot attempt is performed.
|
||||
|
||||
This is more complicated than for the chainloader command, as the initrd
|
||||
command needs access to the loader state. To solve this, the linuxefi
|
||||
module registers a dummy initrd command at startup that returns an error.
|
||||
The linuxefi command then registers a proper initrd command with a higher
|
||||
priority that is passed the loader state.
|
||||
|
||||
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
(cherry picked from commit 7cf736436b4c934df5ddfa6f44b46a7e07d99fdc)
|
||||
[rharwood/pjones: set kernel_size in context]
|
||||
(cherry picked from commit 9c056391f7a36ea480de9a759c12e55a90f2040a)
|
||||
[rharwood: verifying twice]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
(cherry picked from commit df804892f1a754d88a9779320f9429bf40d2a1b3)
|
||||
---
|
||||
grub-core/loader/i386/efi/linux.c | 146 +++++++++++++++++++++++---------------
|
||||
1 file changed, 87 insertions(+), 59 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index c9a2b47370..77a0734786 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -34,13 +34,19 @@
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static grub_dl_t my_mod;
|
||||
-static int loaded;
|
||||
-static void *kernel_mem;
|
||||
-static grub_uint64_t kernel_size;
|
||||
-static void *initrd_mem;
|
||||
-static grub_uint32_t handover_offset;
|
||||
-struct linux_kernel_params *params;
|
||||
-static char *linux_cmdline;
|
||||
+
|
||||
+static grub_command_t cmd_linux, cmd_initrd;
|
||||
+static grub_command_t cmd_linuxefi, cmd_initrdefi;
|
||||
+
|
||||
+struct grub_linuxefi_context {
|
||||
+ void *kernel_mem;
|
||||
+ grub_uint64_t kernel_size;
|
||||
+ grub_uint32_t handover_offset;
|
||||
+ struct linux_kernel_params *params;
|
||||
+ char *cmdline;
|
||||
+
|
||||
+ void *initrd_mem;
|
||||
+};
|
||||
|
||||
#define MIN(a, b) \
|
||||
({ typeof (a) _a = (a); \
|
||||
@@ -123,25 +129,32 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_linuxefi_boot (void)
|
||||
+grub_linuxefi_boot (void *data)
|
||||
{
|
||||
+ struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) data;
|
||||
+
|
||||
asm volatile ("cli");
|
||||
|
||||
- return grub_efi_linux_boot ((char *)kernel_mem,
|
||||
- handover_offset,
|
||||
- params);
|
||||
+ return grub_efi_linux_boot ((char *)context->kernel_mem,
|
||||
+ context->handover_offset,
|
||||
+ context->params);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_linuxefi_unload (void)
|
||||
+grub_linuxefi_unload (void *data)
|
||||
{
|
||||
+ struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) data;
|
||||
+ struct linux_kernel_params *params = context->params;
|
||||
+
|
||||
grub_dl_unref (my_mod);
|
||||
- loaded = 0;
|
||||
|
||||
- kernel_free(initrd_mem, params->ramdisk_size);
|
||||
- kernel_free(linux_cmdline, params->cmdline_size + 1);
|
||||
- kernel_free(kernel_mem, kernel_size);
|
||||
- kernel_free(params, sizeof(*params));
|
||||
+ kernel_free (context->initrd_mem, params->ramdisk_size);
|
||||
+ kernel_free (context->cmdline, params->cmdline_size + 1);
|
||||
+ kernel_free (context->kernel_mem, context->kernel_size);
|
||||
+ kernel_free (params, sizeof(*params));
|
||||
+ cmd_initrd->data = 0;
|
||||
+ cmd_initrdefi->data = 0;
|
||||
+ grub_free (context);
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -188,13 +201,14 @@ read(grub_file_t file, grub_uint8_t *bufp, grub_size_t len)
|
||||
#define HIGH_U32(val) ((grub_uint32_t)(((grub_addr_t)(val) >> 32) & 0xffffffffull))
|
||||
|
||||
static grub_err_t
|
||||
-grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
- int argc, char *argv[])
|
||||
+grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
|
||||
{
|
||||
grub_file_t *files = 0;
|
||||
int i, nfiles = 0;
|
||||
grub_size_t size = 0;
|
||||
grub_uint8_t *ptr;
|
||||
+ struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) cmd->data;
|
||||
+ struct linux_kernel_params *params;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
@@ -202,12 +216,14 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if (!loaded)
|
||||
+ if (!context)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_ARGUMENT, N_("you need to load the kernel first"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ params = context->params;
|
||||
+
|
||||
files = grub_calloc (argc, sizeof (files[0]));
|
||||
if (!files)
|
||||
goto fail;
|
||||
@@ -226,19 +242,19 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
}
|
||||
|
||||
- initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
|
||||
- if (initrd_mem == NULL)
|
||||
+ context->initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
|
||||
+ if (context->initrd_mem == NULL)
|
||||
goto fail;
|
||||
- grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem);
|
||||
+ grub_dprintf ("linux", "initrd_mem = %p\n", context->initrd_mem);
|
||||
|
||||
params->ramdisk_size = LOW_U32(size);
|
||||
- params->ramdisk_image = LOW_U32(initrd_mem);
|
||||
+ params->ramdisk_image = LOW_U32(context->initrd_mem);
|
||||
#if defined(__x86_64__)
|
||||
params->ext_ramdisk_size = HIGH_U32(size);
|
||||
- params->ext_ramdisk_image = HIGH_U32(initrd_mem);
|
||||
+ params->ext_ramdisk_image = HIGH_U32(context->initrd_mem);
|
||||
#endif
|
||||
|
||||
- ptr = initrd_mem;
|
||||
+ ptr = context->initrd_mem;
|
||||
|
||||
for (i = 0; i < nfiles; i++)
|
||||
{
|
||||
@@ -264,8 +280,8 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
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,
|
||||
+ if (context->initrd_mem && grub_errno)
|
||||
+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)context->initrd_mem,
|
||||
BYTES_TO_PAGES(size));
|
||||
|
||||
return grub_errno;
|
||||
@@ -281,6 +297,12 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
void *kernel = NULL;
|
||||
int setup_header_end_offset;
|
||||
int rc;
|
||||
+ void *kernel_mem = 0;
|
||||
+ grub_uint64_t kernel_size = 0;
|
||||
+ grub_uint32_t handover_offset;
|
||||
+ struct linux_kernel_params *params = 0;
|
||||
+ char *cmdline = 0;
|
||||
+ struct grub_linuxefi_context *context = 0;
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
|
||||
@@ -407,27 +429,27 @@ 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");
|
||||
- linux_cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline"));
|
||||
- if (!linux_cmdline)
|
||||
+ cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline"));
|
||||
+ if (!cmdline)
|
||||
goto fail;
|
||||
- grub_dprintf ("linux", "linux_cmdline = %p\n", linux_cmdline);
|
||||
+ grub_dprintf ("linux", "cmdline = %p\n", cmdline);
|
||||
|
||||
- grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
|
||||
+ grub_memcpy (cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
|
||||
grub_create_loader_cmdline (argc, argv,
|
||||
- linux_cmdline + sizeof (LINUX_IMAGE) - 1,
|
||||
+ cmdline + sizeof (LINUX_IMAGE) - 1,
|
||||
lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1),
|
||||
GRUB_VERIFY_KERNEL_CMDLINE);
|
||||
|
||||
- grub_dprintf ("linux", "cmdline:%s\n", linux_cmdline);
|
||||
+ grub_dprintf ("linux", "cmdline:%s\n", cmdline);
|
||||
grub_dprintf ("linux", "setting lh->cmd_line_ptr to 0x%08x\n",
|
||||
- LOW_U32(linux_cmdline));
|
||||
- lh->cmd_line_ptr = LOW_U32(linux_cmdline);
|
||||
+ LOW_U32(cmdline));
|
||||
+ lh->cmd_line_ptr = LOW_U32(cmdline);
|
||||
#if defined(__x86_64__)
|
||||
- if ((grub_efi_uintn_t)linux_cmdline > 0xffffffffull)
|
||||
+ if ((grub_efi_uintn_t)cmdline > 0xffffffffull)
|
||||
{
|
||||
grub_dprintf ("linux", "setting params->ext_cmd_line_ptr to 0x%08x\n",
|
||||
- HIGH_U32(linux_cmdline));
|
||||
- params->ext_cmd_line_ptr = HIGH_U32(linux_cmdline);
|
||||
+ HIGH_U32(cmdline));
|
||||
+ params->ext_cmd_line_ptr = HIGH_U32(cmdline);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -452,16 +474,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
|
||||
max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
|
||||
- kernel_mem = kernel_alloc (lh->init_size, N_("can't allocate kernel"));
|
||||
+ kernel_size = lh->init_size;
|
||||
+ kernel_mem = kernel_alloc (kernel_size, N_("can't allocate kernel"));
|
||||
restore_addresses();
|
||||
if (!kernel_mem)
|
||||
goto fail;
|
||||
grub_dprintf("linux", "kernel_mem = %p\n", kernel_mem);
|
||||
|
||||
- grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
|
||||
-
|
||||
- loaded = 1;
|
||||
-
|
||||
grub_dprintf ("linux", "setting lh->code32_start to 0x%08x\n",
|
||||
LOW_U32(kernel_mem));
|
||||
lh->code32_start = LOW_U32(kernel_mem);
|
||||
@@ -478,33 +497,42 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
"setting lh->ext_loader_{type,ver} = {0x%02x,0x%02x}\n",
|
||||
params->ext_loader_type, params->ext_loader_ver);
|
||||
|
||||
+ context = grub_zalloc (sizeof (*context));
|
||||
+ if (!context)
|
||||
+ goto fail;
|
||||
+ context->kernel_mem = kernel_mem;
|
||||
+ context->kernel_size = kernel_size;
|
||||
+ context->handover_offset = handover_offset;
|
||||
+ context->params = params;
|
||||
+ context->cmdline = cmdline;
|
||||
+
|
||||
+ grub_loader_set_ex (grub_linuxefi_boot, grub_linuxefi_unload, context, 0);
|
||||
+
|
||||
+ cmd_initrd->data = context;
|
||||
+ cmd_initrdefi->data = context;
|
||||
+
|
||||
+ grub_file_close (file);
|
||||
+ grub_free (kernel);
|
||||
+ return 0;
|
||||
+
|
||||
fail:
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
|
||||
- if (grub_errno != GRUB_ERR_NONE)
|
||||
- {
|
||||
- grub_dl_unref (my_mod);
|
||||
- loaded = 0;
|
||||
- }
|
||||
+ grub_dl_unref (my_mod);
|
||||
|
||||
- if (!loaded)
|
||||
- {
|
||||
- if (lh)
|
||||
- kernel_free (linux_cmdline, lh->cmdline_size + 1);
|
||||
+ if (lh)
|
||||
+ kernel_free (cmdline, lh->cmdline_size + 1);
|
||||
|
||||
- kernel_free (kernel_mem, kernel_size);
|
||||
- kernel_free (params, sizeof(*params));
|
||||
- }
|
||||
+ kernel_free (kernel_mem, kernel_size);
|
||||
+ kernel_free (params, sizeof(*params));
|
||||
|
||||
+ grub_free (context);
|
||||
grub_free (kernel);
|
||||
|
||||
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 =
|
@ -0,0 +1,77 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Chris Coulson <chris.coulson@canonical.com>
|
||||
Date: Tue, 3 May 2022 09:47:35 +0200
|
||||
Subject: [PATCH] loader/i386/efi/linux: Fix a memory leak in the initrd
|
||||
command
|
||||
|
||||
Subsequent invocations of the initrd command result in the previous
|
||||
initrd being leaked, so fix that.
|
||||
|
||||
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
|
||||
(cherry picked from commit d98af31ce1e31bb22163960d53f5eb28c66582a0)
|
||||
(cherry picked from commit 62234d6a00e6d1dd8e017ff161d359feb5234082)
|
||||
(cherry picked from commit bda5a10716dc9676400dce1374232452f46d0bc4)
|
||||
---
|
||||
grub-core/loader/i386/efi/linux.c | 21 ++++++++++++---------
|
||||
1 file changed, 12 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index 77a0734786..8337191921 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -209,6 +209,7 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
|
||||
grub_uint8_t *ptr;
|
||||
struct grub_linuxefi_context *context = (struct grub_linuxefi_context *) cmd->data;
|
||||
struct linux_kernel_params *params;
|
||||
+ void *initrd_mem = 0;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
@@ -242,19 +243,19 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
- context->initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
|
||||
- if (context->initrd_mem == NULL)
|
||||
+ initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
|
||||
+ if (initrd_mem == NULL)
|
||||
goto fail;
|
||||
- grub_dprintf ("linux", "initrd_mem = %p\n", context->initrd_mem);
|
||||
+ grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem);
|
||||
|
||||
params->ramdisk_size = LOW_U32(size);
|
||||
- params->ramdisk_image = LOW_U32(context->initrd_mem);
|
||||
+ params->ramdisk_image = LOW_U32(initrd_mem);
|
||||
#if defined(__x86_64__)
|
||||
params->ext_ramdisk_size = HIGH_U32(size);
|
||||
- params->ext_ramdisk_image = HIGH_U32(context->initrd_mem);
|
||||
+ params->ext_ramdisk_image = HIGH_U32(initrd_mem);
|
||||
#endif
|
||||
|
||||
- ptr = context->initrd_mem;
|
||||
+ ptr = initrd_mem;
|
||||
|
||||
for (i = 0; i < nfiles; i++)
|
||||
{
|
||||
@@ -273,6 +274,9 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
|
||||
ptr += ALIGN_UP_OVERHEAD (cursize, 4);
|
||||
}
|
||||
|
||||
+ kernel_free(context->initrd_mem, params->ramdisk_size);
|
||||
+
|
||||
+ context->initrd_mem = initrd_mem;
|
||||
params->ramdisk_size = size;
|
||||
|
||||
fail:
|
||||
@@ -280,9 +284,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
|
||||
grub_file_close (files[i]);
|
||||
grub_free (files);
|
||||
|
||||
- if (context->initrd_mem && grub_errno)
|
||||
- grub_efi_free_pages ((grub_efi_physical_address_t)(grub_addr_t)context->initrd_mem,
|
||||
- BYTES_TO_PAGES(size));
|
||||
+ if (initrd_mem && grub_errno)
|
||||
+ kernel_free (initrd_mem, size);
|
||||
|
||||
return grub_errno;
|
||||
}
|
@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 1499a5068839fa37cb77ecef4b5bdacbd1ed12ea)
|
||||
(cherry picked from commit 2ec50b289d8b24922433439533113087f111f110)
|
||||
(cherry picked from commit 17c36ae88d7d6040cabc01cd4a21e71ff4731668)
|
||||
---
|
||||
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 2efc31da94..f062fc21e7 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);
|
||||
|
@ -0,0 +1,200 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 882be97d1df6449b9fd4d593f0cb70005fde3494)
|
||||
(cherry picked from commit 3f6fc3ebfd58fcdb3fe6c2f7a5a4fa05772ae786)
|
||||
(cherry picked from commit aac5b8257d4078c3f764216aeae3367bdc19043f)
|
||||
---
|
||||
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)
|
@ -0,0 +1,30 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 8ce433557adeadbc46429aabb9f850b02ad2bdfb)
|
||||
(cherry picked from commit 6e10bba6a4cbfd6c7bf116f41fd4e037465e19d8)
|
||||
(cherry picked from commit 812272d919ecfd368c008f15b677d369616ada54)
|
||||
---
|
||||
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);
|
||||
|
@ -0,0 +1,172 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 0e1d163382669bd734439d8864ee969616d971d9)
|
||||
[rharwood: context conflict]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
(cherry picked from commit 4c631c8119206b3178912df2905434d967661c3d)
|
||||
(cherry picked from commit 6d5d5f51266b8113c6ba560835500e3c135f3722)
|
||||
---
|
||||
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. */
|
@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 1ae9a91d42cb40da8a6f11fac65541858e340afa)
|
||||
(cherry picked from commit 132ccc681cf642ad748580f26b54c9259a7f43fd)
|
||||
(cherry picked from commit 3a70e1f6e69af6e0d3c3cf526faa44dc0c80ac19)
|
||||
---
|
||||
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];
|
||||
|
@ -0,0 +1,42 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit c3a8ab0cbd24153ec7b1f84a96ddfdd72ef8d117)
|
||||
(cherry picked from commit 5d09addf58086aa11d5f9a91af5632ff87c2d2ee)
|
||||
(cherry picked from commit ff12584f9376a472f37d4ec14213fd29bf3b233a)
|
||||
---
|
||||
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]);
|
@ -0,0 +1,257 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit ab2e5d2e4bff488bbb557ed435a61ae102ef9f0c)
|
||||
(cherry picked from commit 1ff8df0d2dea8ec7c8575241d5e7d6622c204ec3)
|
||||
(cherry picked from commit b07767383b74a0ce7135c09ba8701510d4ad32f0)
|
||||
---
|
||||
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;
|
||||
|
@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit bc06e12b4de55cc6f926af9f064170c82b1403e9)
|
||||
(cherry picked from commit 5298bf758ea39a90537f9a1c76541ff2f21b970b)
|
||||
(cherry picked from commit aae6bac7f26c6b848156ed7adcff83309b833664)
|
||||
---
|
||||
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;
|
@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit f3a854def3e281b7ad4bbea730cd3046de1da52f)
|
||||
(cherry picked from commit db0154828989a0a52ee59a4dda8c3803752bc827)
|
||||
(cherry picked from commit 75afb375ef46bc99a7faf5879d0283934e34db97)
|
||||
---
|
||||
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)
|
@ -0,0 +1,55 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 41aeb2004db9924fecd9f2dd64bc2a5a5594a4b5)
|
||||
(cherry picked from commit 5f9582490792108306d047379fed2371bee286f8)
|
||||
(cherry picked from commit 7e4bf25d9bb5219fbf11c523296dc3bd78b80698)
|
||||
---
|
||||
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);
|
@ -0,0 +1,36 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit fdf32abc7a3928852422c0f291d8cd1dd6b34a8d)
|
||||
(cherry picked from commit f2c10aaf335b88a69885375c4d68ffab2429df77)
|
||||
(cherry picked from commit 4c942e1ba8d1f1199a58d2eb139022ae22f75cb2)
|
||||
---
|
||||
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 f902b13b44..7b2de12001 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
|
@ -0,0 +1,48 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit ee9591103004cd13b4efadda671536090ca7fd57)
|
||||
(cherry picked from commit acde668bb9d9fa862a1a63e3bbd5fa47fdfa9183)
|
||||
(cherry picked from commit e47ad2eb4fe38ef2bdcab52245286f31170e73e3)
|
||||
---
|
||||
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
|
46
SOURCES/0525-net-ip-Do-IP-fragment-maths-safely.patch
Normal file
46
SOURCES/0525-net-ip-Do-IP-fragment-maths-safely.patch
Normal file
@ -0,0 +1,46 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit eb74e5743ca7e18a5e75c392fe0b21d1549a1936)
|
||||
(cherry picked from commit 552ad34583e788542e9ca08524a0d4bc8f98c297)
|
||||
(cherry picked from commit 2c8cb7e3b8b48b136a950e5692fa6251b76df90e)
|
||||
---
|
||||
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 9a4e589aa3..c766ac65f5 100644
|
||||
--- a/grub-core/net/ip.c
|
||||
+++ b/grub-core/net/ip.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <grub/net/netbuff.h>
|
||||
#include <grub/mm.h>
|
||||
#include <grub/priority_queue.h>
|
||||
+#include <grub/safemath.h>
|
||||
#include <grub/time.h>
|
||||
|
||||
struct iphdr {
|
||||
@@ -552,7 +553,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)
|
||||
{
|
@ -0,0 +1,58 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit eb2e69fcf51307757e43f55ee8c9354d1ee42dd1)
|
||||
(cherry picked from commit d801a27e7acec6c1a83067fab0bb975877eaf704)
|
||||
(cherry picked from commit 4d8b6e36ddfda4084e370b3b08c432e8a462e9be)
|
||||
---
|
||||
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"));
|
||||
}
|
||||
|
@ -0,0 +1,73 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 6a97b3f4b1d5173aa516edc6dedbc63de7306d21)
|
||||
(cherry picked from commit e0589624e86bc96666cbdb62f6e55cafec2871b3)
|
||||
(cherry picked from commit 95ecbc0b9aacfd43ba96cccc50daaf39eccd9f7f)
|
||||
---
|
||||
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;
|
@ -0,0 +1,114 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit dada1dda695439bb55b2848dddc2d89843552f81)
|
||||
(cherry picked from commit 352c5ae8a9fc715712e6ecbd7ccb6218122c748f)
|
||||
(cherry picked from commit 61a010085ab9f0ecf42677773a6fc212f1579b0a)
|
||||
---
|
||||
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 a27c53eee1..b9e2a4d100 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 aa0424dcee..85be965470 100644
|
||||
--- a/grub-core/net/tftp.c
|
||||
+++ b/grub-core/net/tftp.c
|
||||
@@ -402,6 +402,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 9cf6da6897..0d31f00664 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);
|
@ -0,0 +1,53 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
Date: Thu, 4 Mar 2021 18:22:32 -0600
|
||||
Subject: [PATCH] misc: Format string for grub_error() should be a literal
|
||||
|
||||
Signed-off-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry-picked from commit 60875f4e15d704b875969b415501802b531c4db3)
|
||||
---
|
||||
grub-core/loader/efi/chainloader.c | 2 +-
|
||||
grub-core/net/tftp.c | 2 +-
|
||||
grub-core/script/lexer.c | 2 +-
|
||||
3 files changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index 720f6181e5..8e658f713e 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -79,7 +79,7 @@ grub_start_image (grub_efi_handle_t handle)
|
||||
*grub_utf16_to_utf8 ((grub_uint8_t *) buf,
|
||||
exit_data, exit_data_size) = 0;
|
||||
|
||||
- grub_error (GRUB_ERR_BAD_OS, buf);
|
||||
+ grub_error (GRUB_ERR_BAD_OS, "%s", buf);
|
||||
grub_free (buf);
|
||||
}
|
||||
}
|
||||
diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
|
||||
index 85be965470..69a9ba6979 100644
|
||||
--- a/grub-core/net/tftp.c
|
||||
+++ b/grub-core/net/tftp.c
|
||||
@@ -253,7 +253,7 @@ tftp_receive (grub_net_udp_socket_t sock __attribute__ ((unused)),
|
||||
case TFTP_ERROR:
|
||||
data->have_oack = 1;
|
||||
grub_netbuff_free (nb);
|
||||
- grub_error (GRUB_ERR_IO, (char *) tftph->u.err.errmsg);
|
||||
+ grub_error (GRUB_ERR_IO, "%s", tftph->u.err.errmsg);
|
||||
grub_error_save (&data->save_err);
|
||||
return GRUB_ERR_NONE;
|
||||
default:
|
||||
diff --git a/grub-core/script/lexer.c b/grub-core/script/lexer.c
|
||||
index 5fb0cbd0bc..27daad791c 100644
|
||||
--- a/grub-core/script/lexer.c
|
||||
+++ b/grub-core/script/lexer.c
|
||||
@@ -349,7 +349,7 @@ void
|
||||
grub_script_yyerror (struct grub_parser_param *state, char const *err)
|
||||
{
|
||||
if (err)
|
||||
- grub_error (GRUB_ERR_INVALID_COMMAND, err);
|
||||
+ grub_error (GRUB_ERR_INVALID_COMMAND, "%s", err);
|
||||
|
||||
grub_print_error ();
|
||||
state->err++;
|
37
SOURCES/0530-net-tftp-Avoid-a-trivial-UAF.patch
Normal file
37
SOURCES/0530-net-tftp-Avoid-a-trivial-UAF.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 956f4329cec23e4375182030ca9b2be631a61ba5)
|
||||
(cherry picked from commit dbe9abcdee6ce796811111b67e3f24eefe2135d1)
|
||||
(cherry picked from commit 72ae9c5d389d2c0337c44edead6e00db0bb84039)
|
||||
---
|
||||
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 69a9ba6979..09e1511ccf 100644
|
||||
--- a/grub-core/net/tftp.c
|
||||
+++ b/grub-core/net/tftp.c
|
||||
@@ -252,9 +252,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);
|
@ -0,0 +1,44 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit ec233d3ecf995293304de443579aab5c46c49e85)
|
||||
(cherry picked from commit d39cf87ed701b9f0900daed7f672e07994d37ce8)
|
||||
(cherry picked from commit e0aa5c3acec70eac3489d6df1893a93726cbce3a)
|
||||
---
|
||||
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 b52b558d63..5223ca57a4 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;
|
@ -0,0 +1,48 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit e9fb459638811c12b0989dbf64e3e124974ef617)
|
||||
(cherry picked from commit b604916beb6c39e8ed27f72851eb16f3eaa293c5)
|
||||
(cherry picked from commit c3c6b1167a43275991efd6847160a46ce3839fae)
|
||||
---
|
||||
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 5223ca57a4..7fa2dcaea7 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;
|
@ -0,0 +1,50 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
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 <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit d232ad41ac4979a9de4d746e5fdff9caf0e303de)
|
||||
(cherry picked from commit 8960e6d6137090a7e8c6592077da6e387a4ef972)
|
||||
(cherry picked from commit 9b6b9398c90dd76ce0b935d21c4ecb8954c4b2b7)
|
||||
---
|
||||
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 7fa2dcaea7..745f429b51 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)
|
||||
{
|
@ -0,0 +1,74 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
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 <sudhakar@linux.ibm.com>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit a3988cb3f0a108dd67ac127a79a4c8479d23334e)
|
||||
(cherry picked from commit 7125978aa7d6068812ef6da0ab38ce521ae7eba1)
|
||||
(cherry picked from commit e488538cbf9fc63796c7047550b0598e1ef95c03)
|
||||
---
|
||||
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 1cad2615f3..09dc932420 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;
|
||||
|
@ -0,0 +1,134 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
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 <sudhakar@linux.ibm.com>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 62d63d5e38c67a6e349148bf7cb87c560e935a7e)
|
||||
(cherry picked from commit 92219e6d379b5b4d30b05361830b72ab1d95d281)
|
||||
(cherry picked from commit c23d97e3b56594bf0f802d94062e14b221143115)
|
||||
---
|
||||
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 09dc932420..33e565b180 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)
|
||||
@@ -832,7 +851,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)
|
@ -0,0 +1,40 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Sudhakar Kuppusamy <sudhakar@linux.ibm.com>
|
||||
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 <sudhakar@linux.ibm.com>
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 9a891f638509e031d322c94e3cbcf38d36f3993a)
|
||||
(cherry picked from commit 13f9160ae0d2806baed459884999356817096cd7)
|
||||
(cherry picked from commit a48ba4d48b3c66431e6bbeb386078efc6602110c)
|
||||
---
|
||||
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 33e565b180..07ea34196c 100644
|
||||
--- a/grub-core/fs/f2fs.c
|
||||
+++ b/grub-core/fs/f2fs.c
|
||||
@@ -998,6 +998,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;
|
@ -0,0 +1,81 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Darren Kenny <darren.kenny@oracle.com>
|
||||
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 <darren.kenny@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 6d3f06c0b6a8992b9b1bb0e62af93ac5ff2781f0)
|
||||
[rharwood: we've an extra variable here]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
(cherry picked from commit e3e21b9a81aea09dd43368cf097c1029a8380d82)
|
||||
(cherry picked from commit ab14a39777edb60c99751d4fdf1cc254a4faebf5)
|
||||
---
|
||||
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 3faf9056c7..9da2952f70 100644
|
||||
--- a/grub-core/fs/btrfs.c
|
||||
+++ b/grub-core/fs/btrfs.c
|
||||
@@ -1834,6 +1834,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;
|
||||
@@ -1900,6 +1901,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;
|
||||
@@ -1910,6 +1923,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));
|
@ -0,0 +1,143 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Date: Thu, 3 Dec 2020 16:01:46 +0100
|
||||
Subject: [PATCH] efi: Return grub_efi_status_t from grub_efi_get_variable()
|
||||
|
||||
This is needed to properly detect and report UEFI Secure Boot status
|
||||
to the x86 Linux kernel. The functionality will be added by subsequent
|
||||
patches.
|
||||
|
||||
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit 04ae030d0eea8668d4417702d88bf2cf04713d80)
|
||||
---
|
||||
grub-core/commands/efi/efifwsetup.c | 8 ++++----
|
||||
grub-core/kern/efi/efi.c | 16 +++++++++-------
|
||||
grub-core/video/efi_gop.c | 2 +-
|
||||
include/grub/efi/efi.h | 7 ++++---
|
||||
4 files changed, 18 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/efi/efifwsetup.c b/grub-core/commands/efi/efifwsetup.c
|
||||
index 7a137a72a2..eaca032838 100644
|
||||
--- a/grub-core/commands/efi/efifwsetup.c
|
||||
+++ b/grub-core/commands/efi/efifwsetup.c
|
||||
@@ -38,8 +38,8 @@ grub_cmd_fwsetup (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_size_t oi_size;
|
||||
grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
|
||||
|
||||
- old_os_indications = grub_efi_get_variable ("OsIndications", &global,
|
||||
- &oi_size);
|
||||
+ grub_efi_get_variable ("OsIndications", &global, &oi_size,
|
||||
+ (void **) &old_os_indications);
|
||||
|
||||
if (old_os_indications != NULL && oi_size == sizeof (os_indications))
|
||||
os_indications |= *old_os_indications;
|
||||
@@ -63,8 +63,8 @@ efifwsetup_is_supported (void)
|
||||
grub_size_t oi_size = 0;
|
||||
grub_efi_guid_t global = GRUB_EFI_GLOBAL_VARIABLE_GUID;
|
||||
|
||||
- os_indications_supported = grub_efi_get_variable ("OsIndicationsSupported",
|
||||
- &global, &oi_size);
|
||||
+ grub_efi_get_variable ("OsIndicationsSupported", &global, &oi_size,
|
||||
+ (void **) &os_indications_supported);
|
||||
|
||||
if (!os_indications_supported)
|
||||
return 0;
|
||||
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
|
||||
index 2863956458..335033975d 100644
|
||||
--- a/grub-core/kern/efi/efi.c
|
||||
+++ b/grub-core/kern/efi/efi.c
|
||||
@@ -241,9 +241,9 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
|
||||
return grub_error (GRUB_ERR_IO, "could not set EFI variable `%s'", var);
|
||||
}
|
||||
|
||||
-void *
|
||||
+grub_efi_status_t
|
||||
grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
- grub_size_t *datasize_out)
|
||||
+ grub_size_t *datasize_out, void **data_out)
|
||||
{
|
||||
grub_efi_status_t status;
|
||||
grub_efi_uintn_t datasize = 0;
|
||||
@@ -252,13 +252,14 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
void *data;
|
||||
grub_size_t len, len16;
|
||||
|
||||
+ *data_out = NULL;
|
||||
*datasize_out = 0;
|
||||
|
||||
len = grub_strlen (var);
|
||||
len16 = len * GRUB_MAX_UTF16_PER_UTF8;
|
||||
var16 = grub_calloc (len16 + 1, sizeof (var16[0]));
|
||||
if (!var16)
|
||||
- return NULL;
|
||||
+ return GRUB_EFI_OUT_OF_RESOURCES;
|
||||
len16 = grub_utf8_to_utf16 (var16, len16, (grub_uint8_t *) var, len, NULL);
|
||||
var16[len16] = 0;
|
||||
|
||||
@@ -269,14 +270,14 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
if (status != GRUB_EFI_BUFFER_TOO_SMALL || !datasize)
|
||||
{
|
||||
grub_free (var16);
|
||||
- return NULL;
|
||||
+ return status;
|
||||
}
|
||||
|
||||
data = grub_malloc (datasize);
|
||||
if (!data)
|
||||
{
|
||||
grub_free (var16);
|
||||
- return NULL;
|
||||
+ return GRUB_EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data);
|
||||
@@ -284,12 +285,13 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
|
||||
if (status == GRUB_EFI_SUCCESS)
|
||||
{
|
||||
+ *data_out = data;
|
||||
*datasize_out = datasize;
|
||||
- return data;
|
||||
+ return status;
|
||||
}
|
||||
|
||||
grub_free (data);
|
||||
- return NULL;
|
||||
+ return status;
|
||||
}
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c
|
||||
index 9fcc41ac03..ec217db70f 100644
|
||||
--- a/grub-core/video/efi_gop.c
|
||||
+++ b/grub-core/video/efi_gop.c
|
||||
@@ -302,7 +302,7 @@ grub_video_gop_get_edid (struct grub_video_edid_info *edid_info)
|
||||
char edidname[] = "agp-internal-edid";
|
||||
grub_size_t datasize;
|
||||
grub_uint8_t *data;
|
||||
- data = grub_efi_get_variable (edidname, &efi_var_guid, &datasize);
|
||||
+ grub_efi_get_variable (edidname, &efi_var_guid, &datasize, (void **) &data);
|
||||
if (data && datasize > 16)
|
||||
{
|
||||
copy_size = datasize - 16;
|
||||
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
|
||||
index 4411ffa16b..90a85d7d9a 100644
|
||||
--- a/include/grub/efi/efi.h
|
||||
+++ b/include/grub/efi/efi.h
|
||||
@@ -113,9 +113,10 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo
|
||||
grub_efi_uintn_t descriptor_size,
|
||||
grub_efi_uint32_t descriptor_version,
|
||||
grub_efi_memory_descriptor_t *virtual_map);
|
||||
-void *EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
|
||||
- const grub_efi_guid_t *guid,
|
||||
- grub_size_t *datasize_out);
|
||||
+grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
|
||||
+ const grub_efi_guid_t *guid,
|
||||
+ grub_size_t *datasize_out,
|
||||
+ void **data_out);
|
||||
grub_err_t
|
||||
EXPORT_FUNC (grub_efi_set_variable) (const char *var,
|
||||
const grub_efi_guid_t *guid,
|
@ -0,0 +1,76 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Date: Thu, 3 Dec 2020 16:01:47 +0100
|
||||
Subject: [PATCH] efi: Add a function to read EFI variables with attributes
|
||||
|
||||
It will be used to properly detect and report UEFI Secure Boot status to
|
||||
the x86 Linux kernel. The functionality will be added by subsequent patches.
|
||||
|
||||
Signed-off-by: Ignat Korchagin <ignat@cloudflare.com>
|
||||
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
(cherry picked from commit ac5c9367548750e75ed1e7fc4354a3d20186d733)
|
||||
---
|
||||
grub-core/kern/efi/efi.c | 16 +++++++++++++---
|
||||
include/grub/efi/efi.h | 5 +++++
|
||||
2 files changed, 18 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
|
||||
index 335033975d..fccea20a01 100644
|
||||
--- a/grub-core/kern/efi/efi.c
|
||||
+++ b/grub-core/kern/efi/efi.c
|
||||
@@ -242,8 +242,11 @@ grub_efi_set_variable(const char *var, const grub_efi_guid_t *guid,
|
||||
}
|
||||
|
||||
grub_efi_status_t
|
||||
-grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
- grub_size_t *datasize_out, void **data_out)
|
||||
+grub_efi_get_variable_with_attributes (const char *var,
|
||||
+ const grub_efi_guid_t *guid,
|
||||
+ grub_size_t *datasize_out,
|
||||
+ void **data_out,
|
||||
+ grub_efi_uint32_t *attributes)
|
||||
{
|
||||
grub_efi_status_t status;
|
||||
grub_efi_uintn_t datasize = 0;
|
||||
@@ -280,7 +283,7 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
return GRUB_EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
- status = efi_call_5 (r->get_variable, var16, guid, NULL, &datasize, data);
|
||||
+ status = efi_call_5 (r->get_variable, var16, guid, attributes, &datasize, data);
|
||||
grub_free (var16);
|
||||
|
||||
if (status == GRUB_EFI_SUCCESS)
|
||||
@@ -294,6 +297,13 @@ grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
return status;
|
||||
}
|
||||
|
||||
+grub_efi_status_t
|
||||
+grub_efi_get_variable (const char *var, const grub_efi_guid_t *guid,
|
||||
+ grub_size_t *datasize_out, void **data_out)
|
||||
+{
|
||||
+ return grub_efi_get_variable_with_attributes (var, guid, datasize_out, data_out, NULL);
|
||||
+}
|
||||
+
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
/* Search the mods section from the PE32/PE32+ image. This code uses
|
||||
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
|
||||
index 90a85d7d9a..7af979b184 100644
|
||||
--- a/include/grub/efi/efi.h
|
||||
+++ b/include/grub/efi/efi.h
|
||||
@@ -113,6 +113,11 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo
|
||||
grub_efi_uintn_t descriptor_size,
|
||||
grub_efi_uint32_t descriptor_version,
|
||||
grub_efi_memory_descriptor_t *virtual_map);
|
||||
+grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable_with_attributes) (const char *variable,
|
||||
+ const grub_efi_guid_t *guid,
|
||||
+ grub_size_t *datasize_out,
|
||||
+ void **data_out,
|
||||
+ grub_efi_uint32_t *attributes);
|
||||
grub_efi_status_t EXPORT_FUNC (grub_efi_get_variable) (const char *variable,
|
||||
const grub_efi_guid_t *guid,
|
||||
grub_size_t *datasize_out,
|
31
SOURCES/0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch
Normal file
31
SOURCES/0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Wed, 11 May 2022 16:20:52 -0400
|
||||
Subject: [PATCH] Define GRUB_EFI_SHIM_LOCK_GUID
|
||||
|
||||
Added in f76a27996c34900f2c369a8a0d6ac72ae2faa988 ("efi: Make shim_lock
|
||||
GUID and protocol type public"), but that commit also manipulates the
|
||||
lock protocol definition and some other guids we don't care about right
|
||||
now.
|
||||
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
include/grub/efi/api.h | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
|
||||
index 37e7b16287..2a243fd290 100644
|
||||
--- a/include/grub/efi/api.h
|
||||
+++ b/include/grub/efi/api.h
|
||||
@@ -349,6 +349,11 @@
|
||||
{ 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \
|
||||
}
|
||||
|
||||
+#define GRUB_EFI_SHIM_LOCK_GUID \
|
||||
+ { 0x605dab50, 0xe046, 0x4300, \
|
||||
+ { 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
|
||||
+ }
|
||||
+
|
||||
struct grub_efi_sal_system_table
|
||||
{
|
||||
grub_uint32_t signature;
|
@ -0,0 +1,84 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
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 <pjones@redhat.com>
|
||||
(cherry picked from commit 2d6800450fa731d7b3ef9893986806e88e819eb6)
|
||||
(cherry picked from commit adaf6a5ae66fb8a23274e3030e9df2714d0fc396)
|
||||
---
|
||||
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 <grub/i386/relocator.h>
|
||||
-
|
||||
-#define CONCAT(a,b) CONCAT_(a, b)
|
||||
-#define CONCAT_(a,b) a ## b
|
||||
+#include <grub/misc.h>
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
|
||||
diff --git a/include/grub/misc.h b/include/grub/misc.h
|
||||
index 6be6a88f65..7ef1a1a87e 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);
|
||||
@@ -524,7 +532,20 @@ 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__))
|
||||
|
||||
#endif /* ! GRUB_MISC_HEADER */
|
@ -0,0 +1,94 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
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 <pjones@redhat.com>
|
||||
(cherry picked from commit 5fc601574fce99b32fe4dfb55bd8f3ab0175fd6a)
|
||||
(cherry picked from commit 31e581893c564582c729fd0c033d3ce021854be8)
|
||||
---
|
||||
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 39736f63c6..9556c15ff0 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,
|
@ -0,0 +1,48 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
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 <pjones@redhat.com>
|
||||
(cherry picked from commit 4fd282de00df05ce289467861deb7a0e186cfbd7)
|
||||
(cherry picked from commit cc7e60a9f3ad1fa74b9cd48a7e66b1976f9a554a)
|
||||
---
|
||||
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 859d71659a..b375e486a4 100644
|
||||
--- a/grub-core/kern/misc.c
|
||||
+++ b/grub-core/kern/misc.c
|
||||
@@ -1336,7 +1336,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 7ef1a1a87e..1b722c8185 100644
|
||||
--- a/include/grub/misc.h
|
||||
+++ b/include/grub/misc.h
|
||||
@@ -529,7 +529,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) \
|
32
SOURCES/0544-modules-make-.module_license-read-only.patch
Normal file
32
SOURCES/0544-modules-make-.module_license-read-only.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
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 <pjones@redhat.com>
|
||||
(cherry picked from commit 2eff3e2c9d9e6b75daa81b840c96f112ef7d5de6)
|
||||
(cherry picked from commit 3c3c1858d1c056eee660d67888be80e7eae498ca)
|
||||
---
|
||||
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 6a3e251b45..9ec6caf3f9 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
|
@ -0,0 +1,41 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
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 <pjones@redhat.com>
|
||||
(cherry picked from commit e85d1c4d795f8135ad0acfa36d64760d12d6fed1)
|
||||
(cherry picked from commit d3024204b2e2c69ecb91392eeb87c1e6835c3743)
|
||||
---
|
||||
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 \
|
@ -0,0 +1,37 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
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 <pjones@redhat.com>
|
||||
(cherry picked from commit 03215e342f552396ab08125ea769b1e166417ec1)
|
||||
(cherry picked from commit 91518751b9bcba078e3f4385f4b2f6c39cab49cd)
|
||||
---
|
||||
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 520126beab..ba1b33c20b 100644
|
||||
--- a/grub-core/kern/dl.c
|
||||
+++ b/grub-core/kern/dl.c
|
||||
@@ -290,6 +290,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;
|
@ -0,0 +1,83 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
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 <pjones@redhat.com>
|
||||
(cherry picked from commit 955f47aa8300387eecf18b0866d21dde7720593d)
|
||||
(cherry picked from commit 662744c2e986cb770fe49e71e019aaf33a66272d)
|
||||
---
|
||||
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 e1923cf725..24ab0f0074 100644
|
||||
--- a/grub-core/loader/arm64/linux.c
|
||||
+++ b/grub-core/loader/arm64/linux.c
|
||||
@@ -57,7 +57,7 @@ grub_armxx_efi_linux_check_image (struct linux_armxx_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 c03cc599f6..2241f6317b 100644
|
||||
--- a/include/grub/efi/pe32.h
|
||||
+++ b/include/grub/efi/pe32.h
|
||||
@@ -45,7 +45,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
|
||||
@@ -271,7 +294,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
|
||||
{
|
@ -0,0 +1,87 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Wed, 9 Feb 2022 16:08:20 -0500
|
||||
Subject: [PATCH] EFI: allocate kernel in EFI_RUNTIME_SERVICES_CODE instead of
|
||||
EFI_LOADER_DATA.
|
||||
|
||||
On some of the firmwares with more security mitigations, EFI_LOADER_DATA
|
||||
doesn't get you executable memory, and we take a fault and reboot when
|
||||
we enter kernel.
|
||||
|
||||
This patch correctly allocates the kernel code as EFI_RUNTIME_SERVICES_CODE
|
||||
rather than EFI_LOADER_DATA.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
[rharwood: use kernel_size]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
(cherry picked from commit 8b31058a12d3e85f0f0180ac90b98d6465fccbb7)
|
||||
(cherry picked from commit 460df66aab9b3a57fc0d14a21a595cd467c4b13e)
|
||||
---
|
||||
grub-core/loader/i386/efi/linux.c | 19 +++++++++++++------
|
||||
1 file changed, 13 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index 8337191921..3d4069e4c6 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -86,7 +86,9 @@ kernel_free(void *addr, grub_efi_uintn_t size)
|
||||
}
|
||||
|
||||
static void *
|
||||
-kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
|
||||
+kernel_alloc(grub_efi_uintn_t size,
|
||||
+ grub_efi_memory_type_t memtype,
|
||||
+ const char * const errmsg)
|
||||
{
|
||||
void *addr = 0;
|
||||
unsigned int i;
|
||||
@@ -112,7 +114,7 @@ kernel_alloc(grub_efi_uintn_t size, const char * const errmsg)
|
||||
prev_max = max;
|
||||
addr = grub_efi_allocate_pages_real (max, pages,
|
||||
max_addresses[i].alloc_type,
|
||||
- GRUB_EFI_LOADER_DATA);
|
||||
+ memtype);
|
||||
if (addr)
|
||||
grub_dprintf ("linux", "Allocated at %p\n", addr);
|
||||
}
|
||||
@@ -243,7 +245,8 @@ grub_cmd_initrd (grub_command_t cmd, int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
- initrd_mem = kernel_alloc(size, N_("can't allocate initrd"));
|
||||
+ initrd_mem = kernel_alloc(size, GRUB_EFI_RUNTIME_SERVICES_DATA,
|
||||
+ N_("can't allocate initrd"));
|
||||
if (initrd_mem == NULL)
|
||||
goto fail;
|
||||
grub_dprintf ("linux", "initrd_mem = %p\n", initrd_mem);
|
||||
@@ -411,7 +414,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
#endif
|
||||
|
||||
- params = kernel_alloc (sizeof(*params), "cannot allocate kernel parameters");
|
||||
+ params = kernel_alloc (sizeof(*params), GRUB_EFI_RUNTIME_SERVICES_DATA,
|
||||
+ "cannot allocate kernel parameters");
|
||||
if (!params)
|
||||
goto fail;
|
||||
grub_dprintf ("linux", "params = %p\n", params);
|
||||
@@ -432,7 +436,9 @@ 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");
|
||||
- cmdline = kernel_alloc (lh->cmdline_size + 1, N_("can't allocate cmdline"));
|
||||
+ cmdline = kernel_alloc (lh->cmdline_size + 1,
|
||||
+ GRUB_EFI_RUNTIME_SERVICES_DATA,
|
||||
+ N_("can't allocate cmdline"));
|
||||
if (!cmdline)
|
||||
goto fail;
|
||||
grub_dprintf ("linux", "cmdline = %p\n", cmdline);
|
||||
@@ -478,7 +484,8 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
max_addresses[1].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
|
||||
max_addresses[2].addr = GRUB_EFI_MAX_ALLOCATION_ADDRESS;
|
||||
kernel_size = lh->init_size;
|
||||
- kernel_mem = kernel_alloc (kernel_size, N_("can't allocate kernel"));
|
||||
+ kernel_mem = kernel_alloc (kernel_size, GRUB_EFI_RUNTIME_SERVICES_CODE,
|
||||
+ N_("can't allocate kernel"));
|
||||
restore_addresses();
|
||||
if (!kernel_mem)
|
||||
goto fail;
|
@ -0,0 +1,360 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
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 <pjones@redhat.com>
|
||||
(cherry picked from commit 31d52500b281619d92b03b2c2d30fe15aedaf326)
|
||||
(cherry picked from commit 04f1df6b665493e38de66018aebe377fdac4ceec)
|
||||
[rharwood: not risc-v yet]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
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/sparc64/dl.c | 9 +++++++++
|
||||
grub-core/kern/x86_64/dl.c | 13 +++++++++++++
|
||||
include/grub/dl.h | 2 ++
|
||||
docs/grub-dev.texi | 6 +++---
|
||||
12 files changed, 126 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 fb03373190..826f8e721e 100644
|
||||
--- a/grub-core/kern/arm64/dl.c
|
||||
+++ b/grub-core/kern/arm64/dl.c
|
||||
@@ -191,3 +191,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 ba1b33c20b..5c2153acf9 100644
|
||||
--- a/grub-core/kern/dl.c
|
||||
+++ b/grub-core/kern/dl.c
|
||||
@@ -278,7 +278,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__)
|
||||
grub_size_t tramp;
|
||||
grub_size_t got;
|
||||
@@ -286,16 +286,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__)
|
||||
@@ -324,6 +332,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;
|
||||
@@ -336,17 +347,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;
|
||||
}
|
||||
|
||||
@@ -355,7 +368,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 ebcf316298..3bb753a89b 100644
|
||||
--- a/grub-core/kern/ia64/dl.c
|
||||
+++ b/grub-core/kern/ia64/dl.c
|
||||
@@ -143,3 +143,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 3a7fa3ed3d..577e27d871 100644
|
||||
--- a/grub-core/kern/powerpc/dl.c
|
||||
+++ b/grub-core/kern/powerpc/dl.c
|
||||
@@ -165,3 +165,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/sparc64/dl.c b/grub-core/kern/sparc64/dl.c
|
||||
index 739be47174..c741c1782e 100644
|
||||
--- a/grub-core/kern/sparc64/dl.c
|
||||
+++ b/grub-core/kern/sparc64/dl.c
|
||||
@@ -184,3 +184,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 3a73e6e6ce..6c20b7c367 100644
|
||||
--- a/grub-core/kern/x86_64/dl.c
|
||||
+++ b/grub-core/kern/x86_64/dl.c
|
||||
@@ -114,3 +114,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 9ec6caf3f9..dd4c3e7ff4 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 03d53498c5..dbfb94bc06 100644
|
||||
--- a/docs/grub-dev.texi
|
||||
+++ b/docs/grub-dev.texi
|
||||
@@ -638,9 +638,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:
|
320
SOURCES/0550-nx-add-memory-attribute-get-set-API.patch
Normal file
320
SOURCES/0550-nx-add-memory-attribute-get-set-API.patch
Normal file
@ -0,0 +1,320 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
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 <pjones@redhat.com>
|
||||
[rharwood: add pjones's none/nyi fixup]
|
||||
(cherry picked from commit 35de78a8d32b9fad5291ec96fd3cbb9cf2f4a80b)
|
||||
(cherry picked from commit 46cb4f9557bdba1db0a17d012df705d94d81a9f6)
|
||||
[rharwood: context fuzz, guids]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
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 fccea20a01..09468dc5d5 100644
|
||||
--- a/grub-core/kern/efi/efi.c
|
||||
+++ b/grub-core/kern/efi/efi.c
|
||||
@@ -1093,3 +1093,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 9e76f23e5f..2cf4a4883a 100644
|
||||
--- a/grub-core/kern/efi/mm.c
|
||||
+++ b/grub-core/kern/efi/mm.c
|
||||
@@ -730,3 +730,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 2a243fd290..510a4030f5 100644
|
||||
--- a/include/grub/efi/api.h
|
||||
+++ b/include/grub/efi/api.h
|
||||
@@ -354,6 +354,11 @@
|
||||
{ 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23 } \
|
||||
}
|
||||
|
||||
+#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;
|
||||
@@ -2091,6 +2096,26 @@ struct grub_efi_rng_protocol
|
||||
};
|
||||
typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_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__)
|
||||
|
||||
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
|
||||
index 7af979b184..a635bcb0a9 100644
|
||||
--- a/include/grub/efi/efi.h
|
||||
+++ b/include/grub/efi/efi.h
|
||||
@@ -159,4 +159,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 <grub/types.h>
|
||||
#include <grub/symbol.h>
|
||||
+#include <grub/err.h>
|
||||
#include <config.h>
|
||||
|
||||
#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__);
|
||||
|
265
SOURCES/0551-nx-set-page-permissions-for-loaded-modules.patch
Normal file
265
SOURCES/0551-nx-set-page-permissions-for-loaded-modules.patch
Normal file
@ -0,0 +1,265 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
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 <pjones@redhat.com>
|
||||
[rharwood: arm tgptr -> tgaddr]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
(cherry-picked from commit ca74904ede0406b594cbedc52ce8e38a6633d2ae)
|
||||
(cherry picked from commit 2e2e72026f41cf7cffeb46a6a47f3c67d0b3be45)
|
||||
---
|
||||
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 5c2153acf9..68d3177f5e 100644
|
||||
--- a/grub-core/kern/dl.c
|
||||
+++ b/grub-core/kern/dl.c
|
||||
@@ -286,6 +286,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);
|
||||
@@ -385,6 +387,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;
|
||||
}
|
||||
|
||||
@@ -518,23 +521,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.
|
||||
@@ -661,6 +647,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))
|
||||
@@ -669,24 +656,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)
|
||||
{
|
||||
@@ -752,6 +810,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
|
||||
@@ -765,7 +824,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 dd4c3e7ff4..6f46b7e86f 100644
|
||||
--- a/include/grub/dl.h
|
||||
+++ b/include/grub/dl.h
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <grub/elf.h>
|
||||
#include <grub/list.h>
|
||||
#include <grub/misc.h>
|
||||
+#include <grub/mm.h>
|
||||
#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);
|
571
SOURCES/0552-nx-set-attrs-in-our-kernel-loaders.patch
Normal file
571
SOURCES/0552-nx-set-attrs-in-our-kernel-loaders.patch
Normal file
@ -0,0 +1,571 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Tue, 22 Mar 2022 10:57:07 -0400
|
||||
Subject: [PATCH] nx: set attrs in our kernel loaders
|
||||
|
||||
For NX, our kernel loaders need to set write and execute page
|
||||
permissions on allocated pages and the stack.
|
||||
|
||||
This patch adds those calls.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
[rharwood: fix aarch64 callsites]
|
||||
(cherry-picked from commit a9f79a997f01a83b36cdfa89ef2e72ac2a17c06c)
|
||||
[rharwood: double verification]
|
||||
(cherry picked from commit daba852bd3e4d7b7784b19cf7acf107dc3c0dce4)
|
||||
[rharwood: stack_attrs initialization, no risc-v, arm renames, arm age]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
grub-core/kern/efi/mm.c | 78 ++++++++++++++++++
|
||||
grub-core/loader/arm64/linux.c | 16 +++-
|
||||
grub-core/loader/arm64/xen_boot.c | 4 +-
|
||||
grub-core/loader/efi/chainloader.c | 11 +++
|
||||
grub-core/loader/efi/linux.c | 162 ++++++++++++++++++++++++++++++++++++-
|
||||
grub-core/loader/i386/efi/linux.c | 26 +++++-
|
||||
grub-core/loader/i386/linux.c | 5 ++
|
||||
include/grub/efi/efi.h | 6 +-
|
||||
include/grub/efi/linux.h | 17 +++-
|
||||
include/grub/efi/pe32.h | 2 +
|
||||
10 files changed, 312 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
|
||||
index 2cf4a4883a..8a896144df 100644
|
||||
--- a/grub-core/kern/efi/mm.c
|
||||
+++ b/grub-core/kern/efi/mm.c
|
||||
@@ -602,6 +602,82 @@ print_memory_map (grub_efi_memory_descriptor_t *memory_map,
|
||||
}
|
||||
#endif
|
||||
|
||||
+grub_addr_t grub_stack_addr = (grub_addr_t)-1ll;
|
||||
+grub_size_t grub_stack_size = 0;
|
||||
+
|
||||
+static void
|
||||
+grub_nx_init (void)
|
||||
+{
|
||||
+ grub_uint64_t attrs, stack_attrs;
|
||||
+ grub_err_t err;
|
||||
+ grub_addr_t stack_current, stack_end;
|
||||
+ const grub_uint64_t page_size = 4096;
|
||||
+ const grub_uint64_t page_mask = ~(page_size - 1);
|
||||
+
|
||||
+ /*
|
||||
+ * These are to confirm that the flags are working as expected when
|
||||
+ * debugging.
|
||||
+ */
|
||||
+ attrs = 0;
|
||||
+ stack_current = (grub_addr_t)grub_nx_init & page_mask;
|
||||
+ err = grub_get_mem_attrs (stack_current, page_size, &attrs);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_dprintf ("nx",
|
||||
+ "grub_get_mem_attrs(0x%"PRIxGRUB_UINT64_T", ...) -> 0x%x\n",
|
||||
+ stack_current, err);
|
||||
+ grub_error_pop ();
|
||||
+ }
|
||||
+ else
|
||||
+ grub_dprintf ("nx", "page attrs for grub_nx_init (%p) are %c%c%c\n",
|
||||
+ grub_dl_load_core,
|
||||
+ (attrs & GRUB_MEM_ATTR_R) ? 'r' : '-',
|
||||
+ (attrs & GRUB_MEM_ATTR_R) ? 'w' : '-',
|
||||
+ (attrs & GRUB_MEM_ATTR_R) ? 'x' : '-');
|
||||
+
|
||||
+ stack_current = (grub_addr_t)&stack_current & page_mask;
|
||||
+ err = grub_get_mem_attrs (stack_current, page_size, &stack_attrs);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_dprintf ("nx",
|
||||
+ "grub_get_mem_attrs(0x%"PRIxGRUB_UINT64_T", ...) -> 0x%x\n",
|
||||
+ stack_current, err);
|
||||
+ grub_error_pop ();
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ attrs = stack_attrs;
|
||||
+ grub_dprintf ("nx", "page attrs for stack (%p) are %c%c%c\n",
|
||||
+ &attrs,
|
||||
+ (attrs & GRUB_MEM_ATTR_R) ? 'r' : '-',
|
||||
+ (attrs & GRUB_MEM_ATTR_R) ? 'w' : '-',
|
||||
+ (attrs & GRUB_MEM_ATTR_R) ? 'x' : '-');
|
||||
+ }
|
||||
+
|
||||
+ for (stack_end = stack_current + page_size ;
|
||||
+ !(attrs & GRUB_MEM_ATTR_R);
|
||||
+ stack_end += page_size)
|
||||
+ {
|
||||
+ err = grub_get_mem_attrs (stack_current, page_size, &attrs);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_dprintf ("nx",
|
||||
+ "grub_get_mem_attrs(0x%"PRIxGRUB_UINT64_T", ...) -> 0x%x\n",
|
||||
+ stack_current, err);
|
||||
+ grub_error_pop ();
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ if (stack_end > stack_current)
|
||||
+ {
|
||||
+ grub_stack_addr = stack_current;
|
||||
+ grub_stack_size = stack_end - stack_current;
|
||||
+ grub_dprintf ("nx",
|
||||
+ "detected stack from 0x%"PRIxGRUB_ADDR" to 0x%"PRIxGRUB_ADDR"\n",
|
||||
+ grub_stack_addr, grub_stack_addr + grub_stack_size - 1);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
void
|
||||
grub_efi_mm_init (void)
|
||||
{
|
||||
@@ -615,6 +691,8 @@ grub_efi_mm_init (void)
|
||||
grub_efi_uint64_t required_pages;
|
||||
int mm_status;
|
||||
|
||||
+ grub_nx_init ();
|
||||
+
|
||||
/* Prepare a memory region to store two memory maps. */
|
||||
memory_map = grub_efi_allocate_any_pages (2 * BYTES_TO_PAGES (MEMORY_MAP_SIZE));
|
||||
if (! memory_map)
|
||||
diff --git a/grub-core/loader/arm64/linux.c b/grub-core/loader/arm64/linux.c
|
||||
index 24ab0f0074..37f5d0c7eb 100644
|
||||
--- a/grub-core/loader/arm64/linux.c
|
||||
+++ b/grub-core/loader/arm64/linux.c
|
||||
@@ -191,7 +191,8 @@ free_params (void)
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
-grub_armxx_efi_linux_boot_image (grub_addr_t addr, char *args)
|
||||
+grub_armxx_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args,
|
||||
+ int nx_supported)
|
||||
{
|
||||
grub_err_t retval;
|
||||
|
||||
@@ -201,7 +202,8 @@ grub_armxx_efi_linux_boot_image (grub_addr_t addr, char *args)
|
||||
|
||||
grub_dprintf ("linux", "linux command line: '%s'\n", args);
|
||||
|
||||
- retval = grub_efi_linux_boot ((char *)addr, handover_offset, (void *)addr);
|
||||
+ retval = grub_efi_linux_boot (addr, size, handover_offset,
|
||||
+ (void *)addr, nx_supported);
|
||||
|
||||
/* Never reached... */
|
||||
free_params();
|
||||
@@ -211,7 +213,10 @@ grub_armxx_efi_linux_boot_image (grub_addr_t addr, char *args)
|
||||
static grub_err_t
|
||||
grub_linux_boot (void)
|
||||
{
|
||||
- return grub_armxx_efi_linux_boot_image((grub_addr_t)kernel_addr, linux_args);
|
||||
+ return grub_armxx_efi_linux_boot_image((grub_addr_t)kernel_addr,
|
||||
+ (grub_size_t)kernel_size,
|
||||
+ linux_args,
|
||||
+ 0);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -340,6 +345,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
struct grub_armxx_linux_pe_header *pe;
|
||||
int rc;
|
||||
grub_err_t err;
|
||||
+ int nx_supported = 1;
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
|
||||
@@ -395,6 +401,10 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
}
|
||||
|
||||
+ err = grub_efi_check_nx_image_support((grub_addr_t) kernel_addr, kernel_size, &nx_supported);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
+
|
||||
pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
|
||||
handover_offset = pe->opt.entry_addr;
|
||||
|
||||
diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
|
||||
index 1a337866f0..1fd1bbb4bd 100644
|
||||
--- a/grub-core/loader/arm64/xen_boot.c
|
||||
+++ b/grub-core/loader/arm64/xen_boot.c
|
||||
@@ -266,7 +266,9 @@ xen_boot (void)
|
||||
return err;
|
||||
|
||||
return grub_armxx_efi_linux_boot_image (xen_hypervisor->start,
|
||||
- xen_hypervisor->cmdline);
|
||||
+ xen_hypervisor->size,
|
||||
+ xen_hypervisor->cmdline,
|
||||
+ 0);
|
||||
}
|
||||
|
||||
static void
|
||||
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
|
||||
index 8e658f713e..b72e6bd5e3 100644
|
||||
--- a/grub-core/loader/efi/chainloader.c
|
||||
+++ b/grub-core/loader/efi/chainloader.c
|
||||
@@ -1055,6 +1055,17 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * The OS kernel is going to set its own permissions when it takes over
|
||||
+ * paging a few million instructions from now, and load_image() will set up
|
||||
+ * anything that's needed based on the section headers, so there's no point
|
||||
+ * in doing anything but clearing the protection bits here.
|
||||
+ */
|
||||
+ grub_dprintf("nx", "setting attributes for %p (%lu bytes) to %llx\n",
|
||||
+ (void *)(grub_addr_t)address, fsize, 0llu);
|
||||
+ grub_update_mem_attrs (address, fsize,
|
||||
+ GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_W|GRUB_MEM_ATTR_X, 0);
|
||||
+
|
||||
#if defined (__i386__) || defined (__x86_64__)
|
||||
if (fsize >= (grub_ssize_t) sizeof (struct grub_macho_fat_header))
|
||||
{
|
||||
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
|
||||
index 927d89a90d..421502bd25 100644
|
||||
--- a/grub-core/loader/efi/linux.c
|
||||
+++ b/grub-core/loader/efi/linux.c
|
||||
@@ -66,16 +66,125 @@ grub_linuxefi_secure_validate (void *data, grub_uint32_t size)
|
||||
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
+#pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_efi_check_nx_image_support (grub_addr_t kernel_addr,
|
||||
+ grub_size_t kernel_size,
|
||||
+ int *nx_supported)
|
||||
+{
|
||||
+ struct grub_dos_header *doshdr;
|
||||
+ grub_size_t sz = sizeof (*doshdr);
|
||||
+
|
||||
+ struct grub_pe32_header_32 *pe32;
|
||||
+ struct grub_pe32_header_64 *pe64;
|
||||
+
|
||||
+ int image_is_compatible = 0;
|
||||
+ int is_64_bit;
|
||||
+
|
||||
+ if (kernel_size < sz)
|
||||
+ return grub_error (GRUB_ERR_BAD_OS, N_("kernel is too small"));
|
||||
+
|
||||
+ doshdr = (void *)kernel_addr;
|
||||
+
|
||||
+ if ((doshdr->magic & 0xffff) != GRUB_DOS_MAGIC)
|
||||
+ return grub_error (GRUB_ERR_BAD_OS, N_("kernel DOS magic is invalid"));
|
||||
+
|
||||
+ sz = doshdr->lfanew + sizeof (*pe32);
|
||||
+ if (kernel_size < sz)
|
||||
+ return grub_error (GRUB_ERR_BAD_OS, N_("kernel is too small"));
|
||||
+
|
||||
+ pe32 = (struct grub_pe32_header_32 *)(kernel_addr + doshdr->lfanew);
|
||||
+ pe64 = (struct grub_pe32_header_64 *)pe32;
|
||||
+
|
||||
+ if (grub_memcmp (pe32->signature, GRUB_PE32_SIGNATURE,
|
||||
+ GRUB_PE32_SIGNATURE_SIZE) != 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_OS, N_("kernel PE magic is invalid"));
|
||||
+
|
||||
+ switch (pe32->coff_header.machine)
|
||||
+ {
|
||||
+ case GRUB_PE32_MACHINE_ARMTHUMB_MIXED:
|
||||
+ case GRUB_PE32_MACHINE_I386:
|
||||
+ is_64_bit = 0;
|
||||
+ break;
|
||||
+ case GRUB_PE32_MACHINE_ARM64:
|
||||
+ case GRUB_PE32_MACHINE_IA64:
|
||||
+ case GRUB_PE32_MACHINE_X86_64:
|
||||
+ is_64_bit = 1;
|
||||
+ break;
|
||||
+ default:
|
||||
+ return grub_error (GRUB_ERR_BAD_OS, N_("PE machine type 0x%04hx unknown"),
|
||||
+ pe32->coff_header.machine);
|
||||
+ }
|
||||
+
|
||||
+ if (is_64_bit)
|
||||
+ {
|
||||
+ sz = doshdr->lfanew + sizeof (*pe64);
|
||||
+ if (kernel_size < sz)
|
||||
+ return grub_error (GRUB_ERR_BAD_OS, N_("kernel is too small"));
|
||||
+
|
||||
+ if (pe64->optional_header.dll_characteristics & GRUB_PE32_NX_COMPAT)
|
||||
+ image_is_compatible = 1;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ if (pe32->optional_header.dll_characteristics & GRUB_PE32_NX_COMPAT)
|
||||
+ image_is_compatible = 1;
|
||||
+ }
|
||||
+
|
||||
+ *nx_supported = image_is_compatible;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_efi_check_nx_required (int *nx_required)
|
||||
+{
|
||||
+ grub_efi_status_t status;
|
||||
+ grub_efi_guid_t guid = GRUB_EFI_SHIM_LOCK_GUID;
|
||||
+ grub_size_t mok_policy_sz = 0;
|
||||
+ char *mok_policy = NULL;
|
||||
+ grub_uint32_t mok_policy_attrs = 0;
|
||||
+
|
||||
+ status = grub_efi_get_variable_with_attributes ("MokPolicy", &guid,
|
||||
+ &mok_policy_sz,
|
||||
+ (void **)&mok_policy,
|
||||
+ &mok_policy_attrs);
|
||||
+ if (status == GRUB_EFI_NOT_FOUND ||
|
||||
+ mok_policy_sz == 0 ||
|
||||
+ mok_policy == NULL)
|
||||
+ {
|
||||
+ *nx_required = 0;
|
||||
+ return GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
+ *nx_required = 0;
|
||||
+ if (mok_policy_sz < 1 ||
|
||||
+ mok_policy_attrs != (GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS |
|
||||
+ GRUB_EFI_VARIABLE_RUNTIME_ACCESS) ||
|
||||
+ (mok_policy[mok_policy_sz-1] & GRUB_MOK_POLICY_NX_REQUIRED))
|
||||
+ *nx_required = 1;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
|
||||
typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
|
||||
|
||||
grub_err_t
|
||||
-grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset,
|
||||
- void *kernel_params)
|
||||
+grub_efi_linux_boot (grub_addr_t kernel_addr, grub_size_t kernel_size,
|
||||
+ grub_off_t handover_offset, void *kernel_params,
|
||||
+ int nx_supported)
|
||||
{
|
||||
grub_efi_loaded_image_t *loaded_image = NULL;
|
||||
handover_func hf;
|
||||
int offset = 0;
|
||||
+ grub_uint64_t stack_set_attrs = GRUB_MEM_ATTR_R |
|
||||
+ GRUB_MEM_ATTR_W |
|
||||
+ GRUB_MEM_ATTR_X;
|
||||
+ grub_uint64_t stack_clear_attrs = 0;
|
||||
+ grub_uint64_t kernel_set_attrs = stack_set_attrs;
|
||||
+ grub_uint64_t kernel_clear_attrs = stack_clear_attrs;
|
||||
+ grub_uint64_t attrs;
|
||||
+ int nx_required = 0;
|
||||
|
||||
#ifdef __x86_64__
|
||||
offset = 512;
|
||||
@@ -88,12 +197,57 @@ grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset,
|
||||
*/
|
||||
loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
if (loaded_image)
|
||||
- loaded_image->image_base = kernel_addr;
|
||||
+ loaded_image->image_base = (void *)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)handover_offset, kernel_params);
|
||||
+ (void *)kernel_addr, (void *)handover_offset, kernel_params);
|
||||
+
|
||||
+
|
||||
+ if (nx_required && !nx_supported)
|
||||
+ return grub_error (GRUB_ERR_BAD_OS, N_("kernel does not support NX loading required by policy"));
|
||||
+
|
||||
+ if (nx_supported)
|
||||
+ {
|
||||
+ kernel_set_attrs &= ~GRUB_MEM_ATTR_W;
|
||||
+ kernel_clear_attrs |= GRUB_MEM_ATTR_W;
|
||||
+ stack_set_attrs &= ~GRUB_MEM_ATTR_X;
|
||||
+ stack_clear_attrs |= GRUB_MEM_ATTR_X;
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("nx", "Setting attributes for 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" to r%cx\n",
|
||||
+ kernel_addr, kernel_addr + kernel_size - 1,
|
||||
+ (kernel_set_attrs & GRUB_MEM_ATTR_W) ? 'w' : '-');
|
||||
+ grub_update_mem_attrs (kernel_addr, kernel_size,
|
||||
+ kernel_set_attrs, kernel_clear_attrs);
|
||||
+
|
||||
+ grub_get_mem_attrs (kernel_addr, 4096, &attrs);
|
||||
+ grub_dprintf ("nx", "permissions for 0x%"PRIxGRUB_ADDR" are %s%s%s\n",
|
||||
+ (grub_addr_t)kernel_addr,
|
||||
+ (attrs & GRUB_MEM_ATTR_R) ? "r" : "-",
|
||||
+ (attrs & GRUB_MEM_ATTR_W) ? "w" : "-",
|
||||
+ (attrs & GRUB_MEM_ATTR_X) ? "x" : "-");
|
||||
+ if (grub_stack_addr != (grub_addr_t)-1ll)
|
||||
+ {
|
||||
+ grub_dprintf ("nx", "Setting attributes for stack at 0x%"PRIxGRUB_ADDR"-0x%"PRIxGRUB_ADDR" to rw%c\n",
|
||||
+ grub_stack_addr, grub_stack_addr + grub_stack_size - 1,
|
||||
+ (stack_set_attrs & GRUB_MEM_ATTR_X) ? 'x' : '-');
|
||||
+ grub_update_mem_attrs (grub_stack_addr, grub_stack_size,
|
||||
+ stack_set_attrs, stack_clear_attrs);
|
||||
+
|
||||
+ grub_get_mem_attrs (grub_stack_addr, 4096, &attrs);
|
||||
+ grub_dprintf ("nx", "permissions for 0x%"PRIxGRUB_ADDR" are %s%s%s\n",
|
||||
+ grub_stack_addr,
|
||||
+ (attrs & GRUB_MEM_ATTR_R) ? "r" : "-",
|
||||
+ (attrs & GRUB_MEM_ATTR_W) ? "w" : "-",
|
||||
+ (attrs & GRUB_MEM_ATTR_X) ? "x" : "-");
|
||||
+ }
|
||||
+
|
||||
+#if defined(__i386__) || defined(__x86_64__)
|
||||
+ asm volatile ("cli");
|
||||
+#endif
|
||||
+
|
||||
hf = (handover_func)((char *)kernel_addr + handover_offset + offset);
|
||||
grub_dprintf ("linux", "handover_func() = %p\n", hf);
|
||||
hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index 3d4069e4c6..d80d6ec312 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -44,7 +44,7 @@ struct grub_linuxefi_context {
|
||||
grub_uint32_t handover_offset;
|
||||
struct linux_kernel_params *params;
|
||||
char *cmdline;
|
||||
-
|
||||
+ int nx_supported;
|
||||
void *initrd_mem;
|
||||
};
|
||||
|
||||
@@ -110,13 +110,19 @@ kernel_alloc(grub_efi_uintn_t size,
|
||||
pages = BYTES_TO_PAGES(size);
|
||||
grub_dprintf ("linux", "Trying to allocate %lu pages from %p\n",
|
||||
pages, (void *)max);
|
||||
+ size = pages * GRUB_EFI_PAGE_SIZE;
|
||||
|
||||
prev_max = max;
|
||||
addr = grub_efi_allocate_pages_real (max, pages,
|
||||
max_addresses[i].alloc_type,
|
||||
memtype);
|
||||
if (addr)
|
||||
- grub_dprintf ("linux", "Allocated at %p\n", addr);
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "Allocated at %p\n", addr);
|
||||
+ grub_update_mem_attrs ((grub_addr_t)addr, size,
|
||||
+ GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_W,
|
||||
+ GRUB_MEM_ATTR_X);
|
||||
+ }
|
||||
}
|
||||
|
||||
while (grub_error_pop ())
|
||||
@@ -137,9 +143,11 @@ grub_linuxefi_boot (void *data)
|
||||
|
||||
asm volatile ("cli");
|
||||
|
||||
- return grub_efi_linux_boot ((char *)context->kernel_mem,
|
||||
+ return grub_efi_linux_boot ((grub_addr_t)context->kernel_mem,
|
||||
+ context->kernel_size,
|
||||
context->handover_offset,
|
||||
- context->params);
|
||||
+ context->params,
|
||||
+ context->nx_supported);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -308,7 +316,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_uint32_t handover_offset;
|
||||
struct linux_kernel_params *params = 0;
|
||||
char *cmdline = 0;
|
||||
+ int nx_supported = 1;
|
||||
struct grub_linuxefi_context *context = 0;
|
||||
+ grub_err_t err;
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
|
||||
@@ -352,6 +362,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
}
|
||||
|
||||
+ err = grub_efi_check_nx_image_support ((grub_addr_t)kernel, filelen,
|
||||
+ &nx_supported);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ return err;
|
||||
+ grub_dprintf ("linux", "nx is%s supported by this kernel\n",
|
||||
+ nx_supported ? "" : " not");
|
||||
+
|
||||
lh = (struct linux_i386_kernel_header *)kernel;
|
||||
grub_dprintf ("linux", "original lh is at %p\n", kernel);
|
||||
|
||||
@@ -515,6 +532,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
context->handover_offset = handover_offset;
|
||||
context->params = params;
|
||||
context->cmdline = cmdline;
|
||||
+ context->nx_supported = nx_supported;
|
||||
|
||||
grub_loader_set_ex (grub_linuxefi_boot, grub_linuxefi_unload, context, 0);
|
||||
|
||||
diff --git a/grub-core/loader/i386/linux.c b/grub-core/loader/i386/linux.c
|
||||
index ef8fcb9e1b..c160ddb0ea 100644
|
||||
--- a/grub-core/loader/i386/linux.c
|
||||
+++ b/grub-core/loader/i386/linux.c
|
||||
@@ -831,6 +831,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_memset (&linux_params, 0, sizeof (linux_params));
|
||||
grub_memcpy (&linux_params.setup_sects, &lh.setup_sects, sizeof (lh) - 0x1F1);
|
||||
|
||||
+ grub_dprintf("efi", "setting attributes for %p (%zu bytes) to +rw-x\n",
|
||||
+ &linux_params, sizeof (lh) + len);
|
||||
+ grub_update_mem_attrs ((grub_addr_t)&linux_params, sizeof (lh) + len,
|
||||
+ GRUB_MEM_ATTR_R|GRUB_MEM_ATTR_W, GRUB_MEM_ATTR_X);
|
||||
+
|
||||
linux_params.code32_start = prot_mode_target + lh.code32_start - GRUB_LINUX_BZIMAGE_ADDR;
|
||||
linux_params.kernel_alignment = (1 << align);
|
||||
linux_params.ps_mouse = linux_params.padding10 = 0;
|
||||
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
|
||||
index a635bcb0a9..8ca8c38f9a 100644
|
||||
--- a/include/grub/efi/efi.h
|
||||
+++ b/include/grub/efi/efi.h
|
||||
@@ -135,12 +135,16 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd,
|
||||
char **device,
|
||||
char **path);
|
||||
|
||||
+extern grub_addr_t EXPORT_VAR(grub_stack_addr);
|
||||
+extern grub_size_t EXPORT_VAR(grub_stack_size);
|
||||
+
|
||||
#if defined(__arm__) || defined(__aarch64__)
|
||||
void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void);
|
||||
grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *);
|
||||
#include <grub/cpu/linux.h>
|
||||
grub_err_t grub_armxx_efi_linux_check_image(struct linux_armxx_kernel_header *lh);
|
||||
-grub_err_t grub_armxx_efi_linux_boot_image(grub_addr_t addr, char *args);
|
||||
+grub_err_t grub_armxx_efi_linux_boot_image(grub_addr_t addr, grub_size_t size,
|
||||
+ char *args, int nx_enabled);
|
||||
#endif
|
||||
|
||||
grub_addr_t grub_efi_section_addr (const char *section);
|
||||
diff --git a/include/grub/efi/linux.h b/include/grub/efi/linux.h
|
||||
index 0033d9305a..8130b19590 100644
|
||||
--- a/include/grub/efi/linux.h
|
||||
+++ b/include/grub/efi/linux.h
|
||||
@@ -22,10 +22,23 @@
|
||||
#include <grub/err.h>
|
||||
#include <grub/symbol.h>
|
||||
|
||||
+#define GRUB_MOK_POLICY_NX_REQUIRED 0x1
|
||||
+
|
||||
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,
|
||||
- void *kernel_param);
|
||||
+EXPORT_FUNC(grub_efi_linux_boot) (grub_addr_t kernel_address,
|
||||
+ grub_size_t kernel_size,
|
||||
+ grub_off_t handover_offset,
|
||||
+ void *kernel_param, int nx_enabled);
|
||||
+
|
||||
+grub_err_t
|
||||
+EXPORT_FUNC(grub_efi_check_nx_image_support) (grub_addr_t kernel_addr,
|
||||
+ grub_size_t kernel_size,
|
||||
+ int *nx_supported);
|
||||
+
|
||||
+grub_err_t
|
||||
+EXPORT_FUNC(grub_efi_check_nx_required) (int *nx_required);
|
||||
|
||||
#endif /* ! GRUB_EFI_LINUX_HEADER */
|
||||
diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
|
||||
index 2241f6317b..45c9f8b756 100644
|
||||
--- a/include/grub/efi/pe32.h
|
||||
+++ b/include/grub/efi/pe32.h
|
||||
@@ -172,6 +172,8 @@ struct grub_pe32_optional_header
|
||||
struct grub_pe32_data_directory reserved_entry;
|
||||
};
|
||||
|
||||
+#define GRUB_PE32_NX_COMPAT 0x0100
|
||||
+
|
||||
struct grub_pe64_optional_header
|
||||
{
|
||||
grub_uint16_t magic;
|
@ -0,0 +1,38 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Tue, 22 Mar 2022 10:57:20 -0400
|
||||
Subject: [PATCH] nx: set the nx compatible flag in EFI grub images
|
||||
|
||||
For NX, we need the grub binary to announce that it is compatible with
|
||||
the NX feature. This implies that when loading the executable grub
|
||||
image, several attributes are true:
|
||||
|
||||
- the binary doesn't need an executable stack
|
||||
- the binary doesn't need sections to be both executable and writable
|
||||
- the binary knows how to use the EFI Memory Attributes protocol on code
|
||||
it is loading.
|
||||
|
||||
This patch adds a definition for the PE DLL Characteristics flag
|
||||
GRUB_PE32_NX_COMPAT, and changes grub-mkimage to set that flag.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
(cherry picked from commit 0c7f1aed5a87f75051b421903a900ccb4bbd795a)
|
||||
(cherry picked from commit 2f9446d488da96de963f4ffe03b0a1c60a4664f5)
|
||||
[rharwood: fix uninitialized use of stack_attrs]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
util/mkimage.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/util/mkimage.c b/util/mkimage.c
|
||||
index 16418e245d..c77025904c 100644
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -1358,6 +1358,7 @@ grub_install_generate_image (const char *dir, const char *prefix,
|
||||
section = (struct grub_pe32_section_table *)(o64 + 1);
|
||||
}
|
||||
|
||||
+ PE_OHDR (o32, o64, dll_characteristics) = grub_host_to_target16 (GRUB_PE32_NX_COMPAT);
|
||||
PE_OHDR (o32, o64, header_size) = grub_host_to_target32 (header_size);
|
||||
PE_OHDR (o32, o64, entry_addr) = grub_host_to_target32 (layout.start_address);
|
||||
PE_OHDR (o32, o64, image_base) = 0;
|
@ -0,0 +1,51 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Wed, 11 May 2022 16:37:14 -0400
|
||||
Subject: [PATCH] Fixup grub_efi_get_variable() type in our loaders
|
||||
|
||||
Has a new type now that we have 04ae030d0eea8668d4417702d88bf2cf04713d80
|
||||
("efi: Return grub_efi_status_t from grub_efi_get_variable()").
|
||||
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
grub-core/kern/efi/init.c | 4 ++--
|
||||
grub-core/kern/efi/sb.c | 4 ++--
|
||||
2 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
|
||||
index 501608f743..565ce541f5 100644
|
||||
--- a/grub-core/kern/efi/init.c
|
||||
+++ b/grub-core/kern/efi/init.c
|
||||
@@ -104,8 +104,8 @@ grub_efi_env_init (void)
|
||||
struct grub_envblk envblk_s = { NULL, 0 };
|
||||
grub_envblk_t envblk = &envblk_s;
|
||||
|
||||
- envblk_s.buf = grub_efi_get_variable ("GRUB_ENV", &efi_grub_guid,
|
||||
- &envblk_s.size);
|
||||
+ grub_efi_get_variable ("GRUB_ENV", &efi_grub_guid, &envblk_s.size,
|
||||
+ &envblk_s.buf);
|
||||
if (!envblk_s.buf || envblk_s.size < 1)
|
||||
return;
|
||||
|
||||
diff --git a/grub-core/kern/efi/sb.c b/grub-core/kern/efi/sb.c
|
||||
index d74778b0ca..f84d7d3080 100644
|
||||
--- a/grub-core/kern/efi/sb.c
|
||||
+++ b/grub-core/kern/efi/sb.c
|
||||
@@ -35,7 +35,7 @@ grub_efi_secure_boot (void)
|
||||
char *setup_mode = NULL;
|
||||
grub_efi_boolean_t ret = 0;
|
||||
|
||||
- secure_boot = grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize);
|
||||
+ grub_efi_get_variable("SecureBoot", &efi_var_guid, &datasize, &secure_boot);
|
||||
if (datasize != 1 || !secure_boot)
|
||||
{
|
||||
grub_dprintf ("secureboot", "No SecureBoot variable\n");
|
||||
@@ -43,7 +43,7 @@ grub_efi_secure_boot (void)
|
||||
}
|
||||
grub_dprintf ("secureboot", "SecureBoot: %d\n", *secure_boot);
|
||||
|
||||
- setup_mode = grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize);
|
||||
+ grub_efi_get_variable("SetupMode", &efi_var_guid, &datasize, &setup_mode);
|
||||
if (datasize != 1 || !setup_mode)
|
||||
{
|
||||
grub_dprintf ("secureboot", "No SetupMode variable\n");
|
@ -379,11 +379,11 @@ for x in grub-mkimage ; do \\\
|
||||
done \
|
||||
%{nil}
|
||||
|
||||
%global grub_modules " all_video boot blscfg btrfs \\\
|
||||
%global grub_modules " all_video boot blscfg \\\
|
||||
cat configfile cryptodisk echo ext2 \\\
|
||||
fat font gcry_rijndael gcry_rsa gcry_serpent \\\
|
||||
gcry_sha256 gcry_twofish gcry_whirlpool \\\
|
||||
gfxmenu gfxterm gzio halt hfsplus http \\\
|
||||
gfxmenu gfxterm gzio halt http \\\
|
||||
increment iso9660 jpeg loadenv loopback linux \\\
|
||||
lvm luks mdraid09 mdraid1x minicmd net \\\
|
||||
normal part_apple part_msdos part_gpt \\\
|
||||
@ -596,7 +596,7 @@ touch ${RPM_BUILD_ROOT}/boot/%{name}/grub.cfg \
|
||||
%{expand:%%files %{1}} \
|
||||
%defattr(-,root,root,-) \
|
||||
%config(noreplace) %{_sysconfdir}/%{name}.cfg \
|
||||
%ghost %config(noreplace) /boot/%{name}/grub.cfg \
|
||||
%ghost %config(noreplace) %attr(0700,root,root)/boot/%{name}/grub.cfg \
|
||||
%dir %attr(0700,root,root)/boot/loader/entries \
|
||||
%ifarch ppc64le \
|
||||
%dir %{_libdir}/grub/%{2}/ \
|
||||
|
@ -489,6 +489,66 @@ Patch0488: 0488-powerpc-fix-prefix-signed-grub-special-case-for-Powe.patch
|
||||
Patch0489: 0489-grub-mkconfig-restore-umask-for-grub.cfg.patch
|
||||
Patch0490: 0490-efinet-Add-DHCP-proxy-support.patch
|
||||
Patch0491: 0491-at_keyboard-Fix-unreliable-key-presses.patch
|
||||
Patch0492: 0492-search-fixed-bug-stopping-iteration-when-no-floppy-i.patch
|
||||
Patch0492: 0492-commands-search-Fix-bug-stopping-iteration-when-no-f.patch
|
||||
Patch0493: 0493-search-new-efidisk-only-option-on-EFI-systems.patch
|
||||
Patch0494: 0494-efi-new-connectefi-command.patch
|
||||
Patch0495: 0495-Try-to-pick-better-locations-for-kernel-and-initrd.patch
|
||||
Patch0496: 0496-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch
|
||||
Patch0497: 0497-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch
|
||||
Patch0498: 0498-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch
|
||||
Patch0499: 0499-x86-efi-Allow-initrd-params-cmdline-allocations-abov.patch
|
||||
Patch0500: 0500-x86-efi-Reduce-maximum-bounce-buffer-size-to-16-MiB.patch
|
||||
Patch0501: 0501-ibmvtpm-Add-support-for-trusted-boot-using-a-vTPM-2..patch
|
||||
Patch0502: 0502-ibmvtpm-Backport-ibmvtpm-support-to-grub-2.02.patch
|
||||
Patch0503: 0503-powerpc-do-CAS-in-a-more-compatible-way.patch
|
||||
Patch0504: 0504-powerpc-prefix-detection-support-device-names-with-c.patch
|
||||
Patch0505: 0505-make-ofdisk_retries-optional.patch
|
||||
Patch0506: 0506-loader-efi-chainloader-grub_load_and_start_image-doe.patch
|
||||
Patch0507: 0507-loader-efi-chainloader-simplify-the-loader-state.patch
|
||||
Patch0508: 0508-commands-boot-Add-API-to-pass-context-to-loader.patch
|
||||
Patch0509: 0509-loader-efi-chainloader-Use-grub_loader_set_ex.patch
|
||||
Patch0510: 0510-loader-i386-efi-linux-Avoid-a-use-after-free-in-the-.patch
|
||||
Patch0511: 0511-loader-i386-efi-linux-Use-grub_loader_set_ex.patch
|
||||
Patch0512: 0512-loader-i386-efi-linux-Fix-a-memory-leak-in-the-initr.patch
|
||||
Patch0513: 0513-kern-file-Do-not-leak-device_name-on-error-in-grub_f.patch
|
||||
Patch0514: 0514-video-readers-png-Abort-sooner-if-a-read-operation-f.patch
|
||||
Patch0515: 0515-video-readers-png-Refuse-to-handle-multiple-image-he.patch
|
||||
Patch0516: 0516-video-readers-png-Drop-greyscale-support-to-fix-heap.patch
|
||||
Patch0517: 0517-video-readers-png-Avoid-heap-OOB-R-W-inserting-huff-.patch
|
||||
Patch0518: 0518-video-readers-png-Sanity-check-some-huffman-codes.patch
|
||||
Patch0519: 0519-video-readers-jpeg-Abort-sooner-if-a-read-operation-.patch
|
||||
Patch0520: 0520-video-readers-jpeg-Do-not-reallocate-a-given-huff-ta.patch
|
||||
Patch0521: 0521-video-readers-jpeg-Refuse-to-handle-multiple-start-o.patch
|
||||
Patch0522: 0522-video-readers-jpeg-Block-int-underflow-wild-pointer-.patch
|
||||
Patch0523: 0523-normal-charset-Fix-array-out-of-bounds-formatting-un.patch
|
||||
Patch0524: 0524-net-netbuff-Block-overly-large-netbuff-allocs.patch
|
||||
Patch0525: 0525-net-ip-Do-IP-fragment-maths-safely.patch
|
||||
Patch0526: 0526-net-dns-Fix-double-free-addresses-on-corrupt-DNS-res.patch
|
||||
Patch0527: 0527-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch
|
||||
Patch0528: 0528-net-tftp-Prevent-a-UAF-and-double-free-from-a-failed.patch
|
||||
Patch0529: 0529-misc-Format-string-for-grub_error-should-be-a-litera.patch
|
||||
Patch0530: 0530-net-tftp-Avoid-a-trivial-UAF.patch
|
||||
Patch0531: 0531-net-http-Do-not-tear-down-socket-if-it-s-already-bee.patch
|
||||
Patch0532: 0532-net-http-Fix-OOB-write-for-split-http-headers.patch
|
||||
Patch0533: 0533-net-http-Error-out-on-headers-with-LF-without-CR.patch
|
||||
Patch0534: 0534-fs-f2fs-Do-not-read-past-the-end-of-nat-journal-entr.patch
|
||||
Patch0535: 0535-fs-f2fs-Do-not-read-past-the-end-of-nat-bitmap.patch
|
||||
Patch0536: 0536-fs-f2fs-Do-not-copy-file-names-that-are-too-long.patch
|
||||
Patch0537: 0537-fs-btrfs-Fix-several-fuzz-issues-with-invalid-dir-it.patch
|
||||
Patch0538: 0538-efi-Return-grub_efi_status_t-from-grub_efi_get_varia.patch
|
||||
Patch0539: 0539-efi-Add-a-function-to-read-EFI-variables-with-attrib.patch
|
||||
Patch0540: 0540-Define-GRUB_EFI_SHIM_LOCK_GUID.patch
|
||||
Patch0541: 0541-misc-Make-grub_min-and-grub_max-more-resilient.patch
|
||||
Patch0542: 0542-ReiserFS-switch-to-using-grub_min-grub_max.patch
|
||||
Patch0543: 0543-misc-make-grub_boot_time-also-call-grub_dprintf-boot.patch
|
||||
Patch0544: 0544-modules-make-.module_license-read-only.patch
|
||||
Patch0545: 0545-modules-strip-.llvm_addrsig-sections-and-similar.patch
|
||||
Patch0546: 0546-modules-Don-t-allocate-space-for-non-allocable-secti.patch
|
||||
Patch0547: 0547-pe-add-the-DOS-header-struct-and-fix-some-bad-naming.patch
|
||||
Patch0548: 0548-EFI-allocate-kernel-in-EFI_RUNTIME_SERVICES_CODE-ins.patch
|
||||
Patch0549: 0549-modules-load-module-sections-at-page-aligned-address.patch
|
||||
Patch0550: 0550-nx-add-memory-attribute-get-set-API.patch
|
||||
Patch0551: 0551-nx-set-page-permissions-for-loaded-modules.patch
|
||||
Patch0552: 0552-nx-set-attrs-in-our-kernel-loaders.patch
|
||||
Patch0553: 0553-nx-set-the-nx-compatible-flag-in-EFI-grub-images.patch
|
||||
Patch0554: 0554-Fixup-grub_efi_get_variable-type-in-our-loaders.patch
|
||||
|
@ -1,4 +1,4 @@
|
||||
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
|
||||
grub,1,Free Software Foundation,grub,2.02,https://www.gnu.org/software/grub/
|
||||
grub.rhel8,1,Red Hat Enterprise Linux 8,grub2,@@RHEL_VERSION@@,mail:secalert@redhat.com
|
||||
grub.almalinux8,1,AlmaLinux 8,grub2,@@VERSION@@,mail:security@almalinux.org
|
||||
grub,2,Free Software Foundation,grub,@@VERSION@@,https//www.gnu.org/software/grub/
|
||||
grub.rh,2,Red Hat,grub2,@@VERSION_RELEASE@@,mailto:secalert@redhat.com
|
||||
grub.almalinux8,2,AlmaLinux 8,grub2,@@VERSION_RELEASE@@,mail:security@almalinux.org
|
@ -7,7 +7,7 @@
|
||||
Name: grub2
|
||||
Epoch: 1
|
||||
Version: 2.02
|
||||
Release: 120%{?dist}.alma
|
||||
Release: 138%{?dist}.alma
|
||||
Summary: Bootloader with support for Linux, Multiboot and more
|
||||
Group: System Environment/Base
|
||||
License: GPLv3+
|
||||
@ -164,8 +164,8 @@ This subpackage provides tools for support of all platforms.
|
||||
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@@,%{evr},g" -e "s,@@RHEL_VERSION@@,%{rhel_evr},g" %{SOURCE19} \
|
||||
> grub-%{grubefiarch}-%{tarversion}/sbat.csv
|
||||
sed -e "s,@@VERSION@@,%{version},g" -e "s,@@VERSION_RELEASE@@,%{version}-%{release},g" \
|
||||
%{SOURCE19} > grub-%{grubefiarch}-%{tarversion}/sbat.csv
|
||||
git add grub-%{grubefiarch}-%{tarversion}
|
||||
%endif
|
||||
%if 0%{with_alt_efi_arch}
|
||||
@ -508,14 +508,55 @@ fi
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
<<<<<<< HEAD
|
||||
* Tue Apr 05 2022 Andrew Lukoshko <alukoshko@almalinux.org> - 2.06-120.alma
|
||||
- Use AlmaLinux cert and SBAT
|
||||
|
||||
* Fri Feb 28 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-120
|
||||
=======
|
||||
* Wed Jul 20 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-138
|
||||
- Rotate signing keys on ppc64le
|
||||
- Resolves: #2074762
|
||||
|
||||
* Fri Jun 03 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-137
|
||||
- CVE fixes for 2022-06-07
|
||||
- CVE-2022-28736 CVE-2022-28735 CVE-2022-28734 CVE-2022-28733
|
||||
- CVE-2021-3697 CVE-2021-3696 CVE-2021-3695
|
||||
- Resolves: #2070687
|
||||
|
||||
* Mon May 16 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-129
|
||||
- ppc64le: Slow boot after LPM
|
||||
- Resolves: #2070347
|
||||
|
||||
* Wed May 04 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-127
|
||||
- ppc64le: CAS improvements, prefix detection, and vTPM support
|
||||
- Resolves: #2076795
|
||||
- Resolves: #2026568
|
||||
- Resolves: #2051331
|
||||
|
||||
* Wed May 04 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-126
|
||||
- Fix rpm verification error on grub.cfg permissions
|
||||
- Resolves: #2071643
|
||||
|
||||
* Wed Apr 20 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-125
|
||||
- RHEL 8.6.0 import; no code changes
|
||||
- Resolves: #2062892
|
||||
|
||||
* Mon Mar 28 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-123
|
||||
- Bump for signing
|
||||
|
||||
* Wed Mar 09 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-122
|
||||
- Fix initialization on efidisk patch
|
||||
|
||||
* Tue Mar 08 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-121
|
||||
- Backport support for loading initrd above 4GB
|
||||
|
||||
* Mon Feb 28 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-120
|
||||
>>>>>>> c8-beta
|
||||
- Bump signing
|
||||
- Resolves: #2032294
|
||||
|
||||
* Fri Feb 28 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-119
|
||||
* Mon Feb 28 2022 Robbie Harwood <rharwood@redhat.com> - 2.06-119
|
||||
- Enable connectefi module
|
||||
- Resolves: #2032294
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user