Merge remote-tracking branch 'up/main' into main-riscv64

Signed-off-by: Jason Montleon <jmontleo@redhat.com>
This commit is contained in:
Jason Montleon 2024-08-13 09:01:20 -04:00
commit d1ab37254e
No known key found for this signature in database
GPG Key ID: B9439994459B6518
115 changed files with 1835 additions and 484 deletions

View File

@ -1,8 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 1 Jun 2017 10:06:38 -0400
Subject: [PATCH] XXX-pj-recheck Use grub_efi_...() memory helpers where
reasonable.
Subject: [PATCH] Use grub_efi_...() memory helpers where reasonable.
This uses grub_efi_allocate_pool(), grub_efi_free_pool(), and
grub_efi_free_pages() instead of open-coded efi_call_N() calls, so we

View File

@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Thu, 1 Jun 2017 10:07:50 -0400
Subject: [PATCH] XXX-pj-recheck Add PRIxGRUB_EFI_STATUS and use it.
Subject: [PATCH] Add PRIxGRUB_EFI_STATUS and use it.
This avoids syntax checkers getting confused about if it's llx or lx.

View File

@ -1,7 +1,7 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Tue, 9 Jul 2019 17:05:03 +0200
Subject: [PATCH] XXX-pj-check make better backtraces
Subject: [PATCH] make better backtraces
Signed-off-by: Peter Jones <pjones@redhat.com>
---

View File

@ -18,7 +18,8 @@ GRUB_PE32_NX_COMPAT, and changes grub-mkimage to set that flag.
Signed-off-by: Peter Jones <pjones@redhat.com>
---
util/mkimage.c | 1 +
1 file changed, 1 insertion(+)
include/grub/efi/pe32.h | 2 ++
2 files changed, 3 insertions(+)
diff --git a/util/mkimage.c b/util/mkimage.c
index e2bb4d4cd05..425d920ff92 100644
@ -32,3 +33,16 @@ index e2bb4d4cd05..425d920ff92 100644
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;
diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
index 4e6e9d254bd..9887e14b278 100644
--- a/include/grub/efi/pe32.h
+++ b/include/grub/efi/pe32.h
@@ -231,6 +231,8 @@ struct grub_pe64_optional_header
#define GRUB_PE32_SUBSYSTEM_EFI_APPLICATION 10
+#define GRUB_PE32_NX_COMPAT 0x0100
+
#define GRUB_PE32_NUM_DATA_DIRECTORIES 16
struct grub_pe32_section_table

View File

@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 8 Jan 2024 15:36:43 -0500
Subject: [PATCH] Revert "nx: set the nx compatible flag in EFI grub images"
This reverts commit 4ce56720d8e8c665c0c21d8116b7c4ad1ce6e9ee because it
breaks building until a9d405613774 ("nx: set attrs in our kernel
loaders") exists in this tree.
---
util/mkimage.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/util/mkimage.c b/util/mkimage.c
index 425d920ff92..e2bb4d4cd05 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -1438,7 +1438,6 @@ grub_install_generate_image (const char *dir, const char *prefix,
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdangling-pointer"
#endif
- 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;

View File

@ -0,0 +1,160 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marta Lewandowska <mlewando@redhat.com>
Date: Mon, 9 Oct 2023 08:53:18 +0200
Subject: [PATCH] add flag to only search root dev
fixes bz#2223437
Signed-off-by: Marta Lewandowska <mlewando@redhat.com>
---
grub-core/commands/search.c | 36 ++++++++++++++++++++++++++++++++++++
grub-core/commands/search_wrap.c | 5 +++++
grub-core/kern/misc.c | 30 ++++++++++++++++++++++++++++++
include/grub/misc.h | 1 +
include/grub/search.h | 3 ++-
5 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index 263f1501cdf..db8692ffbfb 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -86,6 +86,42 @@ iterate_device (const char *name, void *data)
grub_device_close (dev);
}
+ /* Skip it if it's not the root device when requested. */
+ if (ctx->flags & SEARCH_FLAGS_ROOTDEV_ONLY)
+ {
+ const char *root_dev;
+ root_dev = grub_env_get ("root");
+ if (root_dev != NULL && *root_dev != '\0')
+ {
+ char *root_disk = grub_malloc (grub_strlen(root_dev) + 1);
+ char *name_disk = grub_malloc (grub_strlen(name) + 1);
+ char *rem_1 = grub_malloc(grub_strlen(root_dev) + 1);
+ char *rem_2 = grub_malloc(grub_strlen(name) + 1);
+
+ if (root_disk != NULL && name_disk != NULL &&
+ rem_1 != NULL && rem_2 != NULL)
+ {
+ /* get just the disk name; partitions will be different. */
+ grub_str_sep (root_dev, root_disk, ',', rem_1);
+ grub_str_sep (name, name_disk, ',', rem_2);
+ if (root_disk != NULL && *root_disk != '\0' &&
+ name_disk != NULL && *name_disk != '\0')
+ if (grub_strcmp(root_disk, name_disk) != 0)
+ {
+ grub_free (root_disk);
+ grub_free (name_disk);
+ grub_free (rem_1);
+ grub_free (rem_2);
+ return 0;
+ }
+ }
+ grub_free (root_disk);
+ grub_free (name_disk);
+ grub_free (rem_1);
+ grub_free (rem_2);
+ }
+ }
+
#ifdef DO_SEARCH_FS_UUID
#define compare_fn grub_strcasecmp
#else
diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
index 318581f3b1e..4fe6440c65b 100644
--- a/grub-core/commands/search_wrap.c
+++ b/grub-core/commands/search_wrap.c
@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] =
ARG_TYPE_STRING},
{"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0},
{"efidisk-only", 0, 0, N_("Only probe EFI disks."), 0, 0},
+ {"root-dev-only", 'r', 0, N_("Only probe root device."), 0, 0},
{"hint", 'h', GRUB_ARG_OPTION_REPEATABLE,
N_("First try the device HINT. If HINT ends in comma, "
"also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
@@ -75,6 +76,7 @@ enum options
SEARCH_SET,
SEARCH_NO_FLOPPY,
SEARCH_EFIDISK_ONLY,
+ SEARCH_ROOTDEV_ONLY,
SEARCH_HINT,
SEARCH_HINT_IEEE1275,
SEARCH_HINT_BIOS,
@@ -189,6 +191,9 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
if (state[SEARCH_EFIDISK_ONLY].set)
flags |= SEARCH_FLAGS_EFIDISK_ONLY;
+ if (state[SEARCH_ROOTDEV_ONLY].set)
+ flags |= SEARCH_FLAGS_ROOTDEV_ONLY;
+
if (state[SEARCH_LABEL].set)
grub_search_label (id, var, flags, hints, nhints);
else if (state[SEARCH_FS_UUID].set)
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index f607244e7ae..96ab7c96b52 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -645,6 +645,36 @@ grub_reverse (char *str)
}
}
+/* Separate string into two parts, broken up by delimiter delim. */
+void
+grub_str_sep (const char *s, char *p, char delim, char *r)
+{
+ char* t = grub_strndup(s, grub_strlen(s));
+
+ if (t != NULL && *t != '\0')
+ {
+ char* tmp = t;
+
+ while (((*p = *t) != '\0') && ((*p = *t) != delim))
+ {
+ p++;
+ t++;
+ }
+ *p = '\0';
+
+ if (*t != '\0')
+ {
+ t++;
+ while ((*r++ = *t++) != '\0')
+ ;
+ *r = '\0';
+ }
+ grub_free (tmp);
+ }
+ else
+ grub_free (t);
+}
+
/* Divide N by D, return the quotient, and store the remainder in *R. */
grub_uint64_t
grub_divmod64 (grub_uint64_t n, grub_uint64_t d, grub_uint64_t *r)
diff --git a/include/grub/misc.h b/include/grub/misc.h
index c3c735371dc..3e9a00f0a9c 100644
--- a/include/grub/misc.h
+++ b/include/grub/misc.h
@@ -343,6 +343,7 @@ char *EXPORT_FUNC(grub_strdup) (const char *s) WARN_UNUSED_RESULT;
char *EXPORT_FUNC(grub_strndup) (const char *s, grub_size_t n) WARN_UNUSED_RESULT;
void *EXPORT_FUNC(grub_memset) (void *s, int c, grub_size_t n);
grub_size_t EXPORT_FUNC(grub_strlen) (const char *s) WARN_UNUSED_RESULT;
+void EXPORT_FUNC(grub_str_sep) (const char *s, char *p, char delim, char *r);
/* Replace all `ch' characters of `input' with `with' and copy the
result into `output'; return EOS address of `output'. */
diff --git a/include/grub/search.h b/include/grub/search.h
index ffd2411ca1a..9343c66b134 100644
--- a/include/grub/search.h
+++ b/include/grub/search.h
@@ -23,7 +23,8 @@ enum search_flags
{
SEARCH_FLAGS_NONE = 0,
SEARCH_FLAGS_NO_FLOPPY = 1,
- SEARCH_FLAGS_EFIDISK_ONLY = 2
+ SEARCH_FLAGS_EFIDISK_ONLY = 2,
+ SEARCH_FLAGS_ROOTDEV_ONLY = 4
};
void grub_search_fs_file (const char *key, const char *var,

View File

@ -1,84 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Marta Lewandowska <mlewando@redhat.com>
Date: Mon, 9 Oct 2023 08:53:18 +0200
Subject: [PATCH] add flag to only search root dev
fixes bz#2223437
Signed-off-by: Marta Lewandowska <mlewando@redhat.com>
---
grub-core/commands/search.c | 8 ++++++++
grub-core/commands/search_wrap.c | 5 +++++
include/grub/search.h | 3 ++-
3 files changed, 15 insertions(+), 1 deletion(-)
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index 263f1501cdf..1e7c7ebc7d6 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -59,6 +59,7 @@ static int
iterate_device (const char *name, void *data)
{
struct search_ctx *ctx = data;
+ const char *root_dev;
int found = 0;
/* Skip floppy drives when requested. */
@@ -86,6 +87,13 @@ iterate_device (const char *name, void *data)
grub_device_close (dev);
}
+ /* Skip it if it's not the root device when requested. */
+ root_dev = grub_env_get ("root");
+ if (ctx->flags & SEARCH_FLAGS_ROOTDEV_ONLY &&
+ (name[0] != root_dev[0] || name[1] != root_dev[1] ||
+ name[2] != root_dev[2]))
+ return 0;
+
#ifdef DO_SEARCH_FS_UUID
#define compare_fn grub_strcasecmp
#else
diff --git a/grub-core/commands/search_wrap.c b/grub-core/commands/search_wrap.c
index 318581f3b1e..4fe6440c65b 100644
--- a/grub-core/commands/search_wrap.c
+++ b/grub-core/commands/search_wrap.c
@@ -41,6 +41,7 @@ static const struct grub_arg_option options[] =
ARG_TYPE_STRING},
{"no-floppy", 'n', 0, N_("Do not probe any floppy drive."), 0, 0},
{"efidisk-only", 0, 0, N_("Only probe EFI disks."), 0, 0},
+ {"root-dev-only", 'r', 0, N_("Only probe root device."), 0, 0},
{"hint", 'h', GRUB_ARG_OPTION_REPEATABLE,
N_("First try the device HINT. If HINT ends in comma, "
"also try subpartitions"), N_("HINT"), ARG_TYPE_STRING},
@@ -75,6 +76,7 @@ enum options
SEARCH_SET,
SEARCH_NO_FLOPPY,
SEARCH_EFIDISK_ONLY,
+ SEARCH_ROOTDEV_ONLY,
SEARCH_HINT,
SEARCH_HINT_IEEE1275,
SEARCH_HINT_BIOS,
@@ -189,6 +191,9 @@ grub_cmd_search (grub_extcmd_context_t ctxt, int argc, char **args)
if (state[SEARCH_EFIDISK_ONLY].set)
flags |= SEARCH_FLAGS_EFIDISK_ONLY;
+ if (state[SEARCH_ROOTDEV_ONLY].set)
+ flags |= SEARCH_FLAGS_ROOTDEV_ONLY;
+
if (state[SEARCH_LABEL].set)
grub_search_label (id, var, flags, hints, nhints);
else if (state[SEARCH_FS_UUID].set)
diff --git a/include/grub/search.h b/include/grub/search.h
index ffd2411ca1a..9343c66b134 100644
--- a/include/grub/search.h
+++ b/include/grub/search.h
@@ -23,7 +23,8 @@ enum search_flags
{
SEARCH_FLAGS_NONE = 0,
SEARCH_FLAGS_NO_FLOPPY = 1,
- SEARCH_FLAGS_EFIDISK_ONLY = 2
+ SEARCH_FLAGS_EFIDISK_ONLY = 2,
+ SEARCH_FLAGS_ROOTDEV_ONLY = 4
};
void grub_search_fs_file (const char *key, const char *var,

View File

@ -1,5 +1,5 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
From: Peter Jones <pjones@redhat.com>
Date: Wed, 13 Mar 2024 15:11:15 -0600
Subject: [PATCH] make: use the _CPU variety of build flags for PROGRAM and
LIBRARY

View File

@ -1,5 +1,5 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
From: Matthew Garrett <mjg@redhat.com>
Date: Mon, 1 Apr 2024 13:20:18 -0600
Subject: [PATCH] Add support for Linux EFI stub loading.

View File

@ -1,5 +1,5 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
From: Raymund Will <rw@suse.com>
Date: Tue, 2 Apr 2024 16:39:53 -0600
Subject: [PATCH] Add secureboot support on efi chainloader
@ -180,40 +180,77 @@ supported yet. This patch might need a new revision once that's the case.
Signed-off-by: David Abdurachmanov <david.abdurachmanov@sifive.com>
---
grub-core/loader/efi/chainloader.c | 826 +++++++++++++++++++++++++++++++++----
grub-core/loader/efi/chainloader.c | 849 +++++++++++++++++++++++++++++++++----
grub-core/loader/efi/linux.c | 25 +-
grub-core/loader/i386/efi/linux.c | 17 +-
include/grub/efi/linux.h | 2 +-
include/grub/efi/pe32.h | 51 ++-
5 files changed, 833 insertions(+), 88 deletions(-)
5 files changed, 848 insertions(+), 96 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 2036924504b..00196114a2d 100644
index 2036924504b..e4ac39c87b4 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -32,6 +32,8 @@
@@ -32,6 +32,9 @@
#include <grub/efi/api.h>
#include <grub/efi/efi.h>
#include <grub/efi/disk.h>
+#include <grub/efi/pe32.h>
+#include <grub/efi/sb.h>
+#include <grub/efi/linux.h>
#include <grub/efi/memory.h>
#include <grub/command.h>
#include <grub/i18n.h>
@@ -45,6 +47,12 @@ GRUB_MOD_LICENSE ("GPLv3+");
@@ -45,13 +48,24 @@ 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);
+static grub_efi_status_t (__grub_efi_api *entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table);
+
static grub_err_t
grub_chainloader_unload (void *context)
{
@@ -209,25 +217,701 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
- grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
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);
@@ -66,12 +80,12 @@ grub_chainloader_unload (void *context)
static grub_err_t
grub_chainloader_boot (void *context)
{
- grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
grub_efi_boot_services_t *b;
grub_efi_status_t status;
grub_efi_uintn_t exit_data_size;
grub_efi_char16_t *exit_data = NULL;
+ image_handle = (grub_efi_handle_t) context;
b = grub_efi_system_table->boot_services;
status = b->start_image (image_handle, &exit_data_size, &exit_data);
if (status != GRUB_EFI_SUCCESS)
@@ -136,7 +150,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, *file_path;
+ grub_efi_device_path_t *d;
dir_start = grub_strchr (filename, ')');
if (! dir_start)
@@ -209,24 +223,701 @@ make_file_path (grub_efi_device_path_t *dp, const char *filename)
return file_path;
}
@ -264,7 +301,7 @@ index 2036924504b..00196114a2d 100644
+read_header (void *data, grub_efi_uint32_t size,
+ pe_coff_loader_image_context_t *context)
+{
+ grub_efi_guid_t guid = SHIM_LOCK_GUID;
+ grub_guid_t guid = SHIM_LOCK_GUID;
+ grub_efi_shim_lock_t *shim_lock;
+ grub_efi_status_t status;
+
@ -577,8 +614,8 @@ index 2036924504b..00196114a2d 100644
+ grub_dprintf ("chain", "image size is %08"PRIxGRUB_UINT64_T", datasize is %08x\n",
+ context.image_size, datasize);
+
+ efi_status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA,
+ buffer_size, &buffer);
+ efi_status = b->allocate_pool (GRUB_EFI_LOADER_DATA,
+ buffer_size, (void**)&buffer);
+
+ if (efi_status != GRUB_EFI_SUCCESS)
+ {
@ -805,19 +842,19 @@ index 2036924504b..00196114a2d 100644
+ }
+
+ grub_dprintf ("chain", "booting via entry point\n");
+ efi_status = efi_call_2 (entry_point, grub_efi_image_handle,
+ efi_status = entry_point (grub_efi_image_handle,
+ grub_efi_system_table);
+
+ grub_dprintf ("chain", "entry_point returned %ld\n", efi_status);
+ grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t));
+ efi_status = efi_call_1 (b->free_pool, buffer);
+ efi_status = b->free_pool (buffer);
+
+ return 1;
+
+error_exit:
+ grub_dprintf ("chain", "error_exit: grub_errno: %d\n", grub_errno);
+ if (buffer)
+ efi_call_1 (b->free_pool, buffer);
+ b->free_pool (buffer);
+
+ return 0;
+}
@ -828,7 +865,7 @@ index 2036924504b..00196114a2d 100644
+ grub_efi_boot_services_t *b;
+
+ b = grub_efi_system_table->boot_services;
+ efi_call_2 (b->free_pages, address, pages);
+ b->free_pages (address, pages);
+ grub_free (file_path);
+ grub_free (cmdline);
+ cmdline = 0;
@ -848,7 +885,7 @@ index 2036924504b..00196114a2d 100644
+
+ b = grub_efi_system_table->boot_services;
+
+ status = efi_call_6 (b->load_image, 0, grub_efi_image_handle, file_path,
+ status = b->load_image (0, grub_efi_image_handle, file_path,
+ boot_image, fsize, &image_handle);
+ if (status != GRUB_EFI_SUCCESS)
+ {
@ -902,23 +939,28 @@ index 2036924504b..00196114a2d 100644
grub_efi_status_t status;
grub_efi_boot_services_t *b;
grub_device_t dev = 0;
grub_efi_device_path_t *dp = NULL, *file_path = NULL;
- grub_efi_device_path_t *dp = NULL, *file_path = NULL;
- grub_efi_loaded_image_t *loaded_image;
+ grub_efi_device_path_t *dp = NULL;
char *filename;
void *boot_image = 0;
- grub_efi_handle_t dev_handle = 0;
- grub_efi_physical_address_t address = 0;
- grub_efi_uintn_t pages = 0;
- grub_efi_char16_t *cmdline = NULL;
- grub_efi_handle_t image_handle = NULL;
+ int rc;
grub_efi_physical_address_t address = 0;
grub_efi_uintn_t pages = 0;
grub_efi_char16_t *cmdline = NULL;
grub_efi_handle_t image_handle = NULL;
+ dev_handle = 0;
+
+ file_path = NULL;
+ address = 0;
+ pages = 0;
+ cmdline = NULL;
+ image_handle = NULL;
+ dev_handle = 0;
if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
filename = argv[0];
@@ -236,12 +920,42 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
@@ -236,12 +927,42 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
b = grub_efi_system_table->boot_services;
@ -963,7 +1005,7 @@ index 2036924504b..00196114a2d 100644
if (dev == NULL)
;
else if (dev->disk)
@@ -272,19 +986,16 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
@@ -272,19 +993,16 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
file_path = make_file_path (dp, filename);
if (file_path == NULL)
goto fail;
@ -986,7 +1028,7 @@ index 2036924504b..00196114a2d 100644
status = b->allocate_pages (GRUB_EFI_ALLOCATE_ANY_PAGES,
GRUB_EFI_LOADER_CODE,
@@ -298,7 +1009,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
@@ -298,7 +1016,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
}
boot_image = (void *) ((grub_addr_t) address);
@ -995,7 +1037,7 @@ index 2036924504b..00196114a2d 100644
{
if (grub_errno == GRUB_ERR_NONE)
grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
@@ -308,7 +1019,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
@@ -308,7 +1026,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
}
#if defined (__i386__) || defined (__x86_64__)
@ -1004,7 +1046,7 @@ index 2036924504b..00196114a2d 100644
{
struct grub_macho_fat_header *head = boot_image;
if (head->magic
@@ -317,6 +1028,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
@@ -317,6 +1035,14 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_uint32_t i;
struct grub_macho_fat_arch *archs
= (struct grub_macho_fat_arch *) (head + 1);
@ -1019,7 +1061,7 @@ index 2036924504b..00196114a2d 100644
for (i = 0; i < grub_cpu_to_le32 (head->nfat_arch); i++)
{
if (GRUB_MACHO_CPUTYPE_IS_HOST_CURRENT (archs[i].cputype))
@@ -331,83 +1050,39 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
@@ -331,83 +1057,39 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
> ~grub_cpu_to_le32 (archs[i].size)
|| grub_cpu_to_le32 (archs[i].offset)
+ grub_cpu_to_le32 (archs[i].size)
@ -1086,7 +1128,7 @@ index 2036924504b..00196114a2d 100644
+ grub_load_and_start_image(boot_image);
+ grub_file_close (file);
+ grub_device_close (dev);
+ grub_loader_set (grub_chainloader_boot, grub_chainloader_unload, 0);
+ grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, image_handle, 0);
- for (i = 1; i < argc; i++)
- {
@ -1120,7 +1162,7 @@ index 2036924504b..00196114a2d 100644
if (dev)
grub_device_close (dev);
@@ -421,6 +1096,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
@@ -421,6 +1103,9 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
if (address)
grub_efi_free_pages (address, pages);
@ -1258,10 +1300,10 @@ index d224daafa4f..b2cfd8c1f44 100644
grub_err_t
EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset,
diff --git a/include/grub/efi/pe32.h b/include/grub/efi/pe32.h
index 4e6e9d254bd..af6b95b6450 100644
index 9887e14b278..a39743396dc 100644
--- a/include/grub/efi/pe32.h
+++ b/include/grub/efi/pe32.h
@@ -236,7 +236,11 @@ struct grub_pe64_optional_header
@@ -238,7 +238,11 @@ struct grub_pe64_optional_header
struct grub_pe32_section_table
{
char name[8];
@ -1274,7 +1316,7 @@ index 4e6e9d254bd..af6b95b6450 100644
grub_uint32_t virtual_address;
grub_uint32_t raw_data_size;
grub_uint32_t raw_data_offset;
@@ -247,12 +251,18 @@ struct grub_pe32_section_table
@@ -249,12 +253,18 @@ struct grub_pe32_section_table
grub_uint32_t characteristics;
};
@ -1297,7 +1339,7 @@ index 4e6e9d254bd..af6b95b6450 100644
#define GRUB_PE32_SCN_ALIGN_1BYTES 0x00100000
#define GRUB_PE32_SCN_ALIGN_2BYTES 0x00200000
@@ -261,10 +271,26 @@ struct grub_pe32_section_table
@@ -263,10 +273,26 @@ struct grub_pe32_section_table
#define GRUB_PE32_SCN_ALIGN_16BYTES 0x00500000
#define GRUB_PE32_SCN_ALIGN_32BYTES 0x00600000
#define GRUB_PE32_SCN_ALIGN_64BYTES 0x00700000
@ -1324,7 +1366,7 @@ index 4e6e9d254bd..af6b95b6450 100644
#define GRUB_PE32_SIGNATURE_SIZE 4
#if GRUB_TARGET_SIZEOF_VOID_P == 8
@@ -290,6 +316,21 @@ struct grub_pe_image_header
@@ -292,6 +318,21 @@ struct grub_pe_image_header
#endif
};

View File

@ -1,166 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
Date: Wed, 3 Apr 2024 11:15:23 -0600
Subject: [PATCH] post-fixes: Add secureboot support on efi chainloader
---
grub-core/loader/efi/chainloader.c | 47 ++++++++++++++++++++++----------------
1 file changed, 27 insertions(+), 20 deletions(-)
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 00196114a2d..e4ac39c87b4 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -33,6 +33,7 @@
#include <grub/efi/efi.h>
#include <grub/efi/disk.h>
#include <grub/efi/pe32.h>
+#include <grub/efi/sb.h>
#include <grub/efi/linux.h>
#include <grub/efi/memory.h>
#include <grub/command.h>
@@ -47,19 +48,24 @@ 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);
+static grub_efi_status_t (__grub_efi_api *entry_point) (grub_efi_handle_t image_handle, grub_efi_system_table_t *system_table);
static grub_err_t
grub_chainloader_unload (void *context)
{
- grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
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);
@@ -74,12 +80,12 @@ grub_chainloader_unload (void *context)
static grub_err_t
grub_chainloader_boot (void *context)
{
- grub_efi_handle_t image_handle = (grub_efi_handle_t) context;
grub_efi_boot_services_t *b;
grub_efi_status_t status;
grub_efi_uintn_t exit_data_size;
grub_efi_char16_t *exit_data = NULL;
+ image_handle = (grub_efi_handle_t) context;
b = grub_efi_system_table->boot_services;
status = b->start_image (image_handle, &exit_data_size, &exit_data);
if (status != GRUB_EFI_SUCCESS)
@@ -144,7 +150,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, *file_path;
+ grub_efi_device_path_t *d;
dir_start = grub_strchr (filename, ')');
if (! dir_start)
@@ -264,7 +270,7 @@ static grub_efi_boolean_t
read_header (void *data, grub_efi_uint32_t size,
pe_coff_loader_image_context_t *context)
{
- grub_efi_guid_t guid = SHIM_LOCK_GUID;
+ grub_guid_t guid = SHIM_LOCK_GUID;
grub_efi_shim_lock_t *shim_lock;
grub_efi_status_t status;
@@ -577,8 +583,8 @@ handle_image (void *data, grub_efi_uint32_t datasize)
grub_dprintf ("chain", "image size is %08"PRIxGRUB_UINT64_T", datasize is %08x\n",
context.image_size, datasize);
- efi_status = efi_call_3 (b->allocate_pool, GRUB_EFI_LOADER_DATA,
- buffer_size, &buffer);
+ efi_status = b->allocate_pool (GRUB_EFI_LOADER_DATA,
+ buffer_size, (void**)&buffer);
if (efi_status != GRUB_EFI_SUCCESS)
{
@@ -805,19 +811,19 @@ handle_image (void *data, grub_efi_uint32_t datasize)
}
grub_dprintf ("chain", "booting via entry point\n");
- efi_status = efi_call_2 (entry_point, grub_efi_image_handle,
- grub_efi_system_table);
+ efi_status = entry_point (grub_efi_image_handle,
+ grub_efi_system_table);
grub_dprintf ("chain", "entry_point returned %ld\n", efi_status);
grub_memcpy (li, &li_bak, sizeof (grub_efi_loaded_image_t));
- efi_status = efi_call_1 (b->free_pool, buffer);
+ efi_status = b->free_pool (buffer);
return 1;
error_exit:
grub_dprintf ("chain", "error_exit: grub_errno: %d\n", grub_errno);
if (buffer)
- efi_call_1 (b->free_pool, buffer);
+ b->free_pool (buffer);
return 0;
}
@@ -828,7 +834,7 @@ grub_secureboot_chainloader_unload (void)
grub_efi_boot_services_t *b;
b = grub_efi_system_table->boot_services;
- efi_call_2 (b->free_pages, address, pages);
+ b->free_pages (address, pages);
grub_free (file_path);
grub_free (cmdline);
cmdline = 0;
@@ -848,8 +854,8 @@ grub_load_and_start_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);
+ status = b->load_image (0, grub_efi_image_handle, file_path,
+ boot_image, fsize, &image_handle);
if (status != GRUB_EFI_SUCCESS)
{
if (status == GRUB_EFI_OUT_OF_RESOURCES)
@@ -901,15 +907,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 = NULL, *file_path = NULL;
+ grub_efi_device_path_t *dp = NULL;
char *filename;
void *boot_image = 0;
int rc;
- grub_efi_physical_address_t address = 0;
- grub_efi_uintn_t pages = 0;
- grub_efi_char16_t *cmdline = NULL;
- grub_efi_handle_t image_handle = NULL;
+ file_path = NULL;
+ address = 0;
+ pages = 0;
+ cmdline = NULL;
+ image_handle = NULL;
dev_handle = 0;
if (argc == 0)
@@ -1077,7 +1084,7 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_load_and_start_image(boot_image);
grub_file_close (file);
grub_device_close (dev);
- 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;
}

View File

@ -13,7 +13,7 @@ Signed-off-by: Peter Jones <pjones@redhat.com>
2 files changed, 20 insertions(+)
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index f607244e7ae..70e6e0cef02 100644
index 96ab7c96b52..98700423d79 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -280,6 +280,24 @@ grub_real_dprintf (const char *file, const int line, const char *condition,
@ -42,10 +42,10 @@ index f607244e7ae..70e6e0cef02 100644
int
diff --git a/include/grub/misc.h b/include/grub/misc.h
index c3c735371dc..ef6d3a9ac2c 100644
index 3e9a00f0a9c..db517acd592 100644
--- a/include/grub/misc.h
+++ b/include/grub/misc.h
@@ -385,6 +385,8 @@ void EXPORT_FUNC(grub_real_dprintf) (const char *file,
@@ -386,6 +386,8 @@ void EXPORT_FUNC(grub_real_dprintf) (const char *file,
const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 4, 5)));
int EXPORT_FUNC(grub_printf) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2)));
int EXPORT_FUNC(grub_printf_) (const char *fmt, ...) __attribute__ ((format (GNU_PRINTF, 1, 2)));

View File

@ -1,5 +1,5 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
From: Peter Jones <pjones@redhat.com>
Date: Thu, 4 Apr 2024 11:57:54 -0600
Subject: [PATCH] Make a "gdb" dprintf that tells us load addresses.

View File

@ -3,7 +3,7 @@ From: Leo Sandoval <lsandova@redhat.com>
Date: Mon, 15 Apr 2024 09:24:47 -0600
Subject: [PATCH] Makefile.core.def: fix linux module
Set efi source file targets specifically for i386 and x86_64 archs,
Set EFI source file targets specifically for i386 and x86_64 archs,
otherwise we observe build failures at aarch64
../../grub-core/tests/videotest_checksum.c > videotest_checksum.marker.new || (rm -f videotest_checksum.marker; exit 1)

View File

@ -1,5 +1,5 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
From: Matthew Garrett <mjg@redhat.com>
Date: Mon, 15 Apr 2024 11:19:31 -0600
Subject: [PATCH] Add support for Linux EFI stub loading on arm architectures

View File

@ -1,5 +1,5 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
From: Peter Jones <pjones@redhat.com>
Date: Mon, 15 Apr 2024 12:58:13 -0600
Subject: [PATCH] arm/arm64 loader: Better memory allocation and error
messages.

View File

@ -1,5 +1,5 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Date: Tue, 16 Apr 2024 12:22:54 -0600
Subject: [PATCH] arm64: Fix EFI loader kernel image allocation

View File

@ -1,5 +1,5 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
From: Peter Jones <pjones@redhat.com>
Date: Tue, 16 Apr 2024 12:51:50 -0600
Subject: [PATCH] pe: add the DOS header struct and fix some bad naming.
@ -34,7 +34,7 @@ index cb9de5565de..ecaa8c18c4d 100644
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 af6b95b6450..5b5977ae86d 100644
index a39743396dc..13fdd0e7d98 100644
--- a/include/grub/efi/pe32.h
+++ b/include/grub/efi/pe32.h
@@ -46,7 +46,30 @@
@ -69,7 +69,7 @@ index af6b95b6450..5b5977ae86d 100644
struct grub_msdos_image_header
{
@@ -291,7 +314,8 @@ struct grub_pe32_section_table
@@ -293,7 +316,8 @@ struct grub_pe32_section_table
#define GRUB_PE32_SCN_MEM_READ 0x40000000
#define GRUB_PE32_SCN_MEM_WRITE 0x80000000

View File

@ -1,5 +1,5 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
From: Jeremy Linton <jeremy.linton@arm.com>
Date: Tue, 16 Apr 2024 13:26:55 -0600
Subject: [PATCH] Correct BSS zeroing on aarch64

View File

@ -1,5 +1,5 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
From: Maximilian Luz <luzmaximilian@gmail.com>
Date: Tue, 16 Apr 2024 14:21:49 -0600
Subject: [PATCH] arm64: Use proper memory type for kernel allocation

View File

@ -0,0 +1,28 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nicolas Frayer <nfrayer@redhat.com>
Date: Wed, 17 Jan 2024 21:15:14 +0100
Subject: [PATCH] Ignore warnings for incompatible types
Add -Wno-incompatible-pointer-types to ignore warnings for incompatible
types
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
---
configure.ac | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index d223fe3ef6e..4788f3d6adc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2166,8 +2166,8 @@ if test x"$enable_wextra" != xno ; then
HOST_CFLAGS="$HOST_CFLAGS -Wextra"
fi
-TARGET_CFLAGS="$TARGET_CFLAGS -Werror=trampolines -fno-trampolines"
-HOST_CFLAGS="$HOST_CFLAGS -Werror=trampolines -fno-trampolines"
+TARGET_CFLAGS="$TARGET_CFLAGS -Werror=trampolines -fno-trampolines -Wno-incompatible-pointer-types"
+HOST_CFLAGS="$HOST_CFLAGS -Werror=trampolines -fno-trampolines -Wno-incompatible-pointer-types"
TARGET_CPP="$TARGET_CC -E"
TARGET_CCAS=$TARGET_CC

View File

@ -0,0 +1,180 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nicolas Frayer <nfrayer@redhat.com>
Date: Thu, 16 May 2024 10:58:32 +0200
Subject: [PATCH] cmd/search: Rework of CVE-2023-4001 fix
The initial fix implemented a new flag that forces the grub cfg
stub to be located on the same disk as grub. This created several
issues such as RAID machines not being able to boot as their
partition names under grub were different from the partition where
grub is located. It also simply means that any machines with the
/boot partition located on a disk other than the one containing grub
won't boot.
This commit denies booting if the grub cfg stub is located on a USB
drive with a duplicated UUID (UUID being the same as the partition
containing the actual grub cfg stub)
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
---
grub-core/commands/search.c | 134 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 126 insertions(+), 8 deletions(-)
diff --git a/grub-core/commands/search.c b/grub-core/commands/search.c
index db8692ffbfb..9dd937e6df4 100644
--- a/grub-core/commands/search.c
+++ b/grub-core/commands/search.c
@@ -30,6 +30,8 @@
#include <grub/i18n.h>
#include <grub/disk.h>
#include <grub/partition.h>
+#include <grub/efi/api.h>
+#include <grub/time.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -54,6 +56,100 @@ struct search_ctx
int is_cache;
};
+static int
+is_device_usb (const char *name)
+{
+ int ret = 0;
+
+ grub_device_t dev = grub_device_open(name);
+
+ if (dev)
+ {
+ struct grub_efidisk_data
+ {
+ grub_efi_handle_t handle;
+ grub_efi_device_path_t *device_path;
+ grub_efi_device_path_t *last_device_path;
+ grub_efi_block_io_t *block_io;
+ struct grub_efidisk_data *next;
+ };
+
+ if (dev->disk && dev->disk->data)
+ {
+ struct grub_efidisk_data *dp = dev->disk->data;
+
+ if ( GRUB_EFI_DEVICE_PATH_TYPE (dp->last_device_path) == GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE &&
+ GRUB_EFI_DEVICE_PATH_SUBTYPE (dp->last_device_path) == GRUB_EFI_USB_DEVICE_PATH_SUBTYPE)
+ {
+ ret = 1;
+ }
+ }
+ grub_device_close(dev);
+ }
+
+ return ret;
+}
+
+static int
+get_device_uuid(const char *name, char** quid)
+{
+ int ret = 0;
+
+ grub_device_t dev_part = grub_device_open(name);
+
+ if (dev_part)
+ {
+ grub_fs_t fs;
+
+ fs = grub_fs_probe (dev_part);
+
+#ifdef DO_SEARCH_FS_UUID
+#define read_fn fs_uuid
+#else
+#define read_fn fs_label
+#endif
+ if (fs && fs->read_fn)
+ {
+ fs->read_fn (dev_part, quid);
+
+ if (grub_errno == GRUB_ERR_NONE && *quid)
+ {
+ ret = 1;
+ }
+
+ }
+ grub_device_close (dev_part);
+ }
+
+ return ret;
+}
+struct uuid_context {
+ char* name;
+ char* uuid;
+};
+
+static int
+check_for_duplicate (const char *name, void *data)
+{
+ int ret = 0;
+ struct uuid_context * uuid_ctx = (struct uuid_context *)data;
+ char *quid = 0;
+
+ get_device_uuid(name, &quid);
+
+ if (quid == NULL)
+ return 0;
+
+ if (!grub_strcasecmp(quid, uuid_ctx->uuid) && grub_strcasecmp(name, uuid_ctx->name))
+ {
+ ret = 1;
+ }
+
+ grub_free(quid);
+
+ return ret;
+}
+
/* Helper for FUNC_NAME. */
static int
iterate_device (const char *name, void *data)
@@ -106,14 +202,36 @@ iterate_device (const char *name, void *data)
grub_str_sep (name, name_disk, ',', rem_2);
if (root_disk != NULL && *root_disk != '\0' &&
name_disk != NULL && *name_disk != '\0')
- if (grub_strcmp(root_disk, name_disk) != 0)
- {
- grub_free (root_disk);
- grub_free (name_disk);
- grub_free (rem_1);
- grub_free (rem_2);
- return 0;
- }
+ {
+ grub_device_t dev, dev_part;
+
+ if (is_device_usb(name) && !is_device_usb(root_dev))
+ {
+ char *quid_name = NULL;
+ int longlist = 0;
+ struct uuid_context uuid_ctx;
+ int ret = 0;
+
+ get_device_uuid(name, &quid_name);
+ if (!grub_strcmp(quid_name, ctx->key))
+ {
+ uuid_ctx.name = name;
+ uuid_ctx.uuid = quid_name;
+
+ ret = grub_device_iterate (check_for_duplicate, &uuid_ctx);
+
+ if (ret)
+ {
+ grub_printf("Duplicated media UUID found, rebooting ...\n");
+ grub_sleep(10);
+ grub_reboot();
+ }
+ }
+
+ if (quid_name) grub_free (quid_name);
+
+ }
+ }
}
grub_free (root_disk);
grub_free (name_disk);

View File

@ -1,36 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Montleon <jason@montleon.com>
Date: Fri, 3 May 2024 13:18:37 -0400
Subject: [PATCH] Use medany instead of large model for RISCV
Signed-off-by: Jason Montleon <jason@montleon.com>
---
configure.ac | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/configure.ac b/configure.ac
index d223fe3ef6e..6a6688e362a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1313,7 +1313,7 @@ AC_SUBST(TARGET_LDFLAGS_OLDMAGIC)
LDFLAGS="$TARGET_LDFLAGS"
-if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64 ; then
+if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 ; then
# Use large model to support 4G memory
AC_CACHE_CHECK([whether option -mcmodel=large works], grub_cv_cc_mcmodel, [
CFLAGS="$TARGET_CFLAGS -mcmodel=large"
@@ -1323,9 +1323,11 @@ if test "$target_cpu" = x86_64 || test "$target_cpu" = sparc64 || test "$target_
])
if test "x$grub_cv_cc_mcmodel" = xyes; then
TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=large"
- elif test "$target_cpu" = sparc64 || test "$target_cpu" = riscv64; then
+ elif test "$target_cpu" = sparc64; then
TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany"
fi
+elif test "$target_cpu" = riscv64 ; then
+ TARGET_CFLAGS="$TARGET_CFLAGS -mcmodel=medany"
fi
if test "$target_cpu"-"$platform" = x86_64-efi; then

View File

@ -0,0 +1,69 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Leo Sandoval <lsandova@redhat.com>
Date: Wed, 29 May 2024 17:35:35 -0600
Subject: [PATCH] loader/efi/linux.c: read the kernel image before header
Signed-off-by: Leo Sandoval <lsandova@redhat.com>
---
grub-core/loader/efi/linux.c | 34 ++++++++++++++++++++--------------
1 file changed, 20 insertions(+), 14 deletions(-)
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index d9ded7c4f12..3ada50ed969 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -559,6 +559,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
grub_file_t file = 0;
struct linux_arch_kernel_header lh;
grub_off_t filelen;
+ grub_off_t filereadlen;
grub_uint32_t align;
grub_uint32_t code_size;
void *kernel = NULL;
@@ -592,6 +593,25 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
if (!file)
goto fail;
+ filelen = grub_file_size (file);
+ kernel = grub_malloc(filelen);
+ if (!kernel)
+ {
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel load buffer"));
+ goto fail;
+ }
+
+ filereadlen = grub_file_read (file, kernel, filelen);
+ grub_dprintf ("linux", "filelen : %lld\n", (long long) filelen);
+ grub_dprintf ("linux", "filereadlen : %lld\n", (long long) filereadlen);
+
+ if (filereadlen < filelen)
+ {
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"),
+ argv[0]);
+ goto fail;
+ }
+
if (grub_arch_efi_linux_load_image_header (file, &lh) != GRUB_ERR_NONE)
#if !defined(__i386__) && !defined(__x86_64__)
goto fail;
@@ -612,20 +632,6 @@ fallback:
}
#endif
- filelen = grub_file_size (file);
- kernel = grub_malloc(filelen);
- if (!kernel)
- {
- grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel load buffer"));
- goto fail;
- }
-
- if (grub_file_read (file, kernel, filelen) < (grub_ssize_t)filelen)
- {
- grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"),
- argv[0]);
- goto fail;
- }
#if !defined(__i386__) && !defined(__x86_64__)
if (parse_pe_header (kernel, &kernel_size, &handover_offset, &align, &code_size) != GRUB_ERR_NONE)

View File

@ -0,0 +1,580 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Wed, 3 Jul 2024 17:54:41 -0600
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 stack_attrs undefined, fix aarch64 callsites]
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
---
grub-core/kern/efi/mm.c | 79 ++++++++++++++++
grub-core/loader/arm64/xen_boot.c | 5 +-
grub-core/loader/efi/chainloader.c | 11 +++
grub-core/loader/efi/linux.c | 188 ++++++++++++++++++++++++++++++++++---
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 | 16 +++-
include/grub/efi/pe32.h | 2 +
9 files changed, 319 insertions(+), 19 deletions(-)
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index 560b859b6f4..464fe1c3c01 100644
--- a/grub-core/kern/efi/mm.c
+++ b/grub-core/kern/efi/mm.c
@@ -603,6 +603,83 @@ 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);
+ }
+}
+
+
+
static grub_err_t
grub_efi_mm_add_regions (grub_size_t required_bytes, unsigned int flags)
{
@@ -615,6 +692,8 @@ grub_efi_mm_add_regions (grub_size_t required_bytes, unsigned int flags)
grub_err_t err;
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/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
index 9838a0f878b..5d7c8603db9 100644
--- a/grub-core/loader/arm64/xen_boot.c
+++ b/grub-core/loader/arm64/xen_boot.c
@@ -252,7 +252,10 @@ xen_boot (void)
return err;
return grub_arch_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 badff5e50b5..5cd6f6a5993 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -1078,6 +1078,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 3ada50ed969..fe48001442a 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -96,16 +96,127 @@ static grub_efi_load_file2_t initrd_lf2 = {
#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 k_add,
+ grub_size_t k_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 (k_size < sz)
+ return grub_error (GRUB_ERR_BAD_OS, N_("kernel is too small"));
+
+ doshdr = (void *)k_add;
+
+ 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 (k_size < sz)
+ return grub_error (GRUB_ERR_BAD_OS, N_("kernel is too small"));
+
+ pe32 = (struct grub_pe32_header_32 *)(k_add + 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:
+ case GRUB_PE32_MACHINE_RISCV32:
+ is_64_bit = 0;
+ break;
+ case GRUB_PE32_MACHINE_ARM64:
+ case GRUB_PE32_MACHINE_IA64:
+ case GRUB_PE32_MACHINE_RISCV64:
+ 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 (k_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_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_address, grub_off_t ho_offset,
- void *kernel_params)
+grub_efi_linux_boot (grub_addr_t k_address, grub_size_t k_size,
+ grub_off_t h_offset, void *k_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;
@@ -118,14 +229,59 @@ grub_efi_linux_boot (void *kernel_address, grub_off_t ho_offset,
*/
loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
if (loaded_image)
- loaded_image->image_base = kernel_address;
+ loaded_image->image_base = (void *)k_address;
else
grub_dprintf ("linux", "Loaded Image base address could not be set\n");
grub_dprintf ("linux", "kernel_address: %p handover_offset: %p params: %p\n",
- kernel_address, (void *)(grub_efi_uintn_t)ho_offset, kernel_params);
- hf = (handover_func)((char *)kernel_address + ho_offset + offset);
- hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
+ (void *)k_address, (void *)h_offset, k_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",
+ k_address, k_address + k_size - 1,
+ (kernel_set_attrs & GRUB_MEM_ATTR_W) ? 'w' : '-');
+ grub_update_mem_attrs (k_address, k_size,
+ kernel_set_attrs, kernel_clear_attrs);
+
+ grub_get_mem_attrs (k_address, 4096, &attrs);
+ grub_dprintf ("nx", "permissions for 0x%"PRIxGRUB_ADDR" are %s%s%s\n",
+ (grub_addr_t)k_address,
+ (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 *)k_address + h_offset + offset);
+ hf (grub_efi_image_handle, grub_efi_system_table, k_params);
return GRUB_ERR_BUG;
}
@@ -287,13 +443,15 @@ free_params (void)
}
grub_err_t
-grub_arch_efi_linux_boot_image (grub_addr_t addr, char *args)
+grub_arch_efi_linux_boot_image (grub_addr_t addr, grub_size_t size, char *args,
+ int nx_supported)
{
grub_err_t retval;
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();
@@ -308,7 +466,10 @@ grub_linux_boot (void)
return grub_errno;
#endif
- return grub_arch_efi_linux_boot_image ((grub_addr_t) kernel_addr, linux_args);
+ return grub_arch_efi_linux_boot_image((grub_addr_t)kernel_addr,
+ (grub_size_t)kernel_size,
+ linux_args,
+ 0);
}
static grub_err_t
@@ -560,10 +721,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
struct linux_arch_kernel_header lh;
grub_off_t filelen;
grub_off_t filereadlen;
- grub_uint32_t align;
- grub_uint32_t code_size;
void *kernel = NULL;
grub_err_t err;
+ int nx_supported = 1;
grub_dl_ref (my_mod);
@@ -634,6 +794,8 @@ fallback:
#if !defined(__i386__) && !defined(__x86_64__)
+ grub_uint32_t align;
+ grub_uint32_t code_size;
if (parse_pe_header (kernel, &kernel_size, &handover_offset, &align, &code_size) != GRUB_ERR_NONE)
goto fail;
grub_dprintf ("linux", "kernel mem size : %lld\n", (long long) kernel_size);
@@ -641,6 +803,10 @@ fallback:
grub_dprintf ("linux", "kernel alignment : 0x%x\n", align);
grub_dprintf ("linux", "kernel size : 0x%x\n", code_size);
+ err = grub_efi_check_nx_image_support((grub_addr_t)kernel, filelen, &nx_supported);
+ if (err != GRUB_ERR_NONE)
+ goto fail;
+
grub_loader_unset();
kernel_alloc_pages = GRUB_EFI_BYTES_TO_PAGES (kernel_size + align - 1);
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
index f97b123a51e..abbf6b24f50 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;
};
@@ -134,13 +134,19 @@ kernel_alloc(kernel_alloc_purpose_t purpose,
pages = BYTES_TO_PAGES(size);
grub_dprintf ("linux", "Trying to allocate %lu pages from %p\n",
(unsigned long)pages, (void *)(unsigned long)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 ())
@@ -161,9 +167,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
@@ -331,7 +339,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);
@@ -361,6 +371,13 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
+ 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);
@@ -530,6 +547,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 5a257552234..90121e9bc5a 100644
--- a/grub-core/loader/i386/linux.c
+++ b/grub-core/loader/i386/linux.c
@@ -817,6 +817,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
kernel_offset += len;
}
+ 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.padding11 = 0;
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
index c40684821e1..2c0e7f24bda 100644
--- a/include/grub/efi/efi.h
+++ b/include/grub/efi/efi.h
@@ -190,6 +190,9 @@ extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd,
void *
EXPORT_FUNC (grub_efi_find_configuration_table) (const grub_guid_t *target_guid);
+extern grub_addr_t EXPORT_VAR(grub_stack_addr);
+extern grub_size_t EXPORT_VAR(grub_stack_size);
+
#if defined(__arm__) || defined(__aarch64__) || defined(__riscv) || defined(__loongarch__)
void *EXPORT_FUNC(grub_efi_get_firmware_fdt)(void);
grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *);
@@ -197,7 +200,8 @@ grub_err_t EXPORT_FUNC(grub_efi_get_ram_base)(grub_addr_t *);
#include <grub/file.h>
grub_err_t grub_arch_efi_linux_load_image_header(grub_file_t file,
struct linux_arch_kernel_header *lh);
-grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, char *args);
+grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size,
+ char *args, int nx_enabled);
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 c806a7757f3..5b4e626c37c 100644
--- a/include/grub/efi/linux.h
+++ b/include/grub/efi/linux.h
@@ -22,8 +22,20 @@
#include <grub/err.h>
#include <grub/symbol.h>
+#define GRUB_MOK_POLICY_NX_REQUIRED 0x1
+
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 13fdd0e7d98..a4d62373cc9 100644
--- a/include/grub/efi/pe32.h
+++ b/include/grub/efi/pe32.h
@@ -194,6 +194,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;

View File

@ -0,0 +1,183 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Julian Andres Klode <julian.klode@canonical.com>
Date: Tue, 9 Jul 2024 16:46:05 -0600
Subject: [PATCH] efi: Provide wrappers for load_image, start_image,
These can be used to register a different implementation later,
for example, when shim provides a protocol with those functions.
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
---
grub-core/kern/efi/efi.c | 57 ++++++++++++++++++++++++++++++++++++++
grub-core/loader/efi/chainloader.c | 13 ++++-----
include/grub/efi/efi.h | 37 +++++++++++++++++++++++++
3 files changed, 100 insertions(+), 7 deletions(-)
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
index cdfc11565c7..b5b8a329622 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -1131,6 +1131,63 @@ grub_efi_find_configuration_table (const grub_guid_t *target_guid)
return 0;
}
+static const grub_efi_loader_t *override_loader = NULL;
+
+grub_err_t
+grub_efi_register_loader (const grub_efi_loader_t *loader)
+{
+ if (override_loader != NULL)
+ return grub_error (GRUB_ERR_BUG, "trying to register different loader");
+ override_loader = loader;
+ return GRUB_ERR_NONE;
+}
+
+grub_err_t
+grub_efi_unregister_loader (const grub_efi_loader_t *loader)
+{
+ if (loader != override_loader)
+ return grub_error (GRUB_ERR_BUG, "trying to unregister different loader");
+
+ override_loader = NULL;
+ return GRUB_ERR_NONE;
+}
+
+grub_efi_status_t
+grub_efi_load_image (grub_efi_boolean_t boot_policy,
+ grub_efi_handle_t parent_image_handle,
+ grub_efi_device_path_t *file_path, void *source_buffer,
+ grub_efi_uintn_t source_size,
+ grub_efi_handle_t *image_handle)
+{
+ if (override_loader != NULL)
+ return override_loader->load_image (boot_policy, parent_image_handle,
+ file_path, source_buffer, source_size,
+ image_handle);
+ return grub_efi_system_table->boot_services->load_image (
+ boot_policy, parent_image_handle, file_path, source_buffer, source_size,
+ image_handle);
+}
+
+grub_efi_status_t
+grub_efi_start_image (grub_efi_handle_t image_handle,
+ grub_efi_uintn_t *exit_data_size,
+ grub_efi_char16_t **exit_data)
+{
+ if (override_loader != NULL)
+ return override_loader->start_image (image_handle, exit_data_size,
+ exit_data);
+ return grub_efi_system_table->boot_services->start_image (
+ image_handle, exit_data_size, exit_data);
+}
+
+grub_efi_status_t
+grub_efi_unload_image (grub_efi_handle_t image_handle)
+{
+ if (override_loader != NULL)
+ return override_loader->unload_image (image_handle);
+ return grub_efi_system_table->boot_services->unload_image (image_handle);
+}
+
grub_err_t
grub_efi_status_to_err (grub_efi_status_t status)
{
diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c
index 5cd6f6a5993..9b1cc3fd41d 100644
--- a/grub-core/loader/efi/chainloader.c
+++ b/grub-core/loader/efi/chainloader.c
@@ -69,7 +69,7 @@ grub_start_image (grub_efi_handle_t handle)
b = grub_efi_system_table->boot_services;
- status = b->start_image (handle, &exit_data_size, &exit_data);
+ status = grub_efi_start_image (handle, &exit_data_size, &exit_data);
if (status != GRUB_EFI_SUCCESS)
{
if (exit_data)
@@ -101,7 +101,6 @@ 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;
@@ -109,8 +108,7 @@ grub_chainloader_unload (void *context)
if (loaded_image != NULL)
grub_free (loaded_image->load_options);
- b = grub_efi_system_table->boot_services;
- b->unload_image (image_handle);
+ grub_efi_unload_image (image_handle);
grub_dl_unref (my_mod);
return GRUB_ERR_NONE;
@@ -871,8 +869,8 @@ grub_load_image(grub_efi_device_path_t *file_path, void *boot_image,
b = grub_efi_system_table->boot_services;
- status = b->load_image (0, grub_efi_image_handle, file_path,
- boot_image, image_size, image_handle_out);
+ status = grub_efi_load_image (0, grub_efi_image_handle, file_path,
+ boot_image, image_size, image_handle_out);
if (status != GRUB_EFI_SUCCESS)
{
if (status == GRUB_EFI_OUT_OF_RESOURCES)
@@ -1198,7 +1196,8 @@ fail:
if (cmdline)
grub_free (cmdline);
- b->unload_image (image_handle);
+ if (image_handle != NULL)
+ grub_efi_unload_image (image_handle);
grub_dl_unref (my_mod);
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
index 2c0e7f24bda..7eed1bd791d 100644
--- a/include/grub/efi/efi.h
+++ b/include/grub/efi/efi.h
@@ -202,6 +202,43 @@ grub_err_t grub_arch_efi_linux_load_image_header(grub_file_t file,
struct linux_arch_kernel_header *lh);
grub_err_t grub_arch_efi_linux_boot_image(grub_addr_t addr, grub_size_t size,
char *args, int nx_enabled);
+grub_efi_status_t
+EXPORT_FUNC (grub_efi_load_image) (grub_efi_boolean_t boot_policy,
+ grub_efi_handle_t parent_image_handle,
+ grub_efi_device_path_t *file_path,
+ void *source_buffer, grub_efi_uintn_t source_size,
+ grub_efi_handle_t *image_handle);
+
+grub_efi_status_t
+EXPORT_FUNC (grub_efi_start_image) (grub_efi_handle_t image_handle,
+ grub_efi_uintn_t *exit_data_size,
+ grub_efi_char16_t **exit_data);
+
+grub_efi_status_t
+EXPORT_FUNC (grub_efi_unload_image) (grub_efi_handle_t image_handle);
+
+typedef struct grub_efi_loader
+{
+ grub_efi_status_t (__grub_efi_api *load_image) (grub_efi_boolean_t boot_policy,
+ grub_efi_handle_t parent_image_handle,
+ grub_efi_device_path_t *file_path,
+ void *source_buffer,
+ grub_efi_uintn_t source_size,
+ grub_efi_handle_t *image_handle);
+
+ grub_efi_status_t (__grub_efi_api *start_image) (grub_efi_handle_t image_handle,
+ grub_efi_uintn_t *exit_data_size,
+ grub_efi_char16_t **exit_data);
+
+ grub_efi_status_t (__grub_efi_api *unload_image) (grub_efi_handle_t image_handle);
+} grub_efi_loader_t;
+
+grub_err_t
+EXPORT_FUNC (grub_efi_register_loader) (const grub_efi_loader_t *loader);
+
+grub_err_t
+EXPORT_FUNC (grub_efi_unregister_loader) (const grub_efi_loader_t *loader);
+
grub_addr_t grub_efi_section_addr (const char *section);

View File

@ -0,0 +1,66 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mate Kukri <mate.kukri@canonical.com>
Date: Wed, 10 Jul 2024 12:07:17 -0600
Subject: [PATCH] efi: Disallow fallback to legacy Linux loader when shim says
NX is required.
Signed-off-by: Mate Kukri <mate.kukri@canonical.com>
---
grub-core/loader/efi/linux.c | 13 ++++++++-----
include/grub/efi/api.h | 2 ++
2 files changed, 10 insertions(+), 5 deletions(-)
diff --git a/grub-core/loader/efi/linux.c b/grub-core/loader/efi/linux.c
index da5dcafad8b..21aad881ba0 100644
--- a/grub-core/loader/efi/linux.c
+++ b/grub-core/loader/efi/linux.c
@@ -724,6 +724,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
void *kernel = NULL;
grub_err_t err;
int nx_supported = 1;
+ int nx_required = 0;
grub_dl_ref (my_mod);
@@ -756,21 +757,23 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
goto fail;
}
+#if !defined(__i386__) && !defined(__x86_64__)
if (grub_arch_efi_linux_load_image_header (file, &lh) != GRUB_ERR_NONE)
-#if !defined(__i386__) && !defined(__x86_64__)
goto fail;
#else
- goto fallback;
-
- if (!initrd_use_loadfile2)
+ if (grub_arch_efi_linux_load_image_header (file, &lh) != GRUB_ERR_NONE ||
+ !initrd_use_loadfile2)
{
+ /* We cannot use the legacy loader when NX is required */
+ if (grub_efi_check_nx_required(&nx_required))
+ goto fail;
+
/*
* This is a EFI stub image but it is too old to implement the LoadFile2
* based initrd loading scheme, and Linux/x86 does not support the DT
* based method either. So fall back to the x86-specific loader that
* enters Linux in EFI mode but without going through its EFI stub.
*/
-fallback:
grub_file_close (file);
return grub_cmd_linux_x86_legacy (cmd, argc, argv);
}
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index da51f57fd4a..637b1272d17 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -2011,6 +2011,8 @@ struct grub_efi_block_io
};
typedef struct grub_efi_block_io grub_efi_block_io_t;
+#define GRUB_MOK_POLICY_NX_REQUIRED 0x1
+
struct grub_efi_shim_lock_protocol
{
/*

Some files were not shown because too many files have changed in this diff Show More