forked from pool/grub2
Accepting request 1188943 from home:michael-chang:branches:Base:System
- Fix error in grub-install when root is on tmpfs (bsc#1226100) * 0001-grub-install-bailout-root-device-probing.patch - Fix incorrect Platform tag in rpm header (bsc#1217967) OBS-URL: https://build.opensuse.org/request/show/1188943 OBS-URL: https://build.opensuse.org/package/show/Base:System/grub2?expand=0&rev=508
This commit is contained in:
commit
de8c74037b
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
## Default LFS
|
||||
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||
*.bsp filter=lfs diff=lfs merge=lfs -text
|
||||
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.gem filter=lfs diff=lfs merge=lfs -text
|
||||
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||
*.lz filter=lfs diff=lfs merge=lfs -text
|
||||
*.lzma filter=lfs diff=lfs merge=lfs -text
|
||||
*.obscpio filter=lfs diff=lfs merge=lfs -text
|
||||
*.oxt filter=lfs diff=lfs merge=lfs -text
|
||||
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||
*.png filter=lfs diff=lfs merge=lfs -text
|
||||
*.rpm filter=lfs diff=lfs merge=lfs -text
|
||||
*.tbz filter=lfs diff=lfs merge=lfs -text
|
||||
*.tbz2 filter=lfs diff=lfs merge=lfs -text
|
||||
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||
*.txz filter=lfs diff=lfs merge=lfs -text
|
||||
*.whl filter=lfs diff=lfs merge=lfs -text
|
||||
*.xz filter=lfs diff=lfs merge=lfs -text
|
||||
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||
*.zst filter=lfs diff=lfs merge=lfs -text
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.osc
|
@ -0,0 +1,51 @@
|
||||
From 28440c9b5f83b82b4715554fa5c2d3f013b769e6 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 26 Mar 2024 13:55:53 +0800
|
||||
Subject: [PATCH] 10_linux: Ensure persistence of root file system mounting
|
||||
|
||||
This commit addresses the issue where the by-uuid or by-partuuid device
|
||||
symlinks might be unavailable in an installation system. Despite the
|
||||
absence of these symlinks, the resulting system remains fully functional
|
||||
for mounting the root file system by using persistent names
|
||||
(root=(UUID|PARTUUID)=).
|
||||
|
||||
The patch implemented in this commit aims to prevent fallback to the OS
|
||||
name as the root= parameter, as persistent names are preferred for
|
||||
stability and predictability.
|
||||
|
||||
To achieve this, the fallback to the OS name won't be triggered if the
|
||||
corresponding by-uuid or by-partuuid symlinks are missing, ensuring the
|
||||
use of persistent names. Instead, a warning will be logged for the
|
||||
missing symlinks, providing visibility into the issue.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub.d/10_linux.in | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
|
||||
index 5531239eb..4d8bdeac2 100644
|
||||
--- a/util/grub.d/10_linux.in
|
||||
+++ b/util/grub.d/10_linux.in
|
||||
@@ -54,14 +54,16 @@ esac
|
||||
if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \
|
||||
|| ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
|
||||
&& [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \
|
||||
- || ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
|
||||
- && ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \
|
||||
|| ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
|
||||
LINUX_ROOT_DEVICE=${GRUB_DEVICE}
|
||||
elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \
|
||||
|| [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then
|
||||
+ test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ||
|
||||
+ echo "WARN: Use PARTUUID=${GRUB_DEVICE_PARTUUID} despite missing by-partuuid symlink" >&2
|
||||
LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID}
|
||||
else
|
||||
+ test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" ||
|
||||
+ echo "WARN: Use UUID=${GRUB_DEVICE_UUID} despite missing by-uuid symlink" >&2
|
||||
LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
|
||||
fi
|
||||
|
||||
--
|
||||
2.44.0
|
||||
|
68
0001-Add-grub_envblk_buf-helper-function.patch
Normal file
68
0001-Add-grub_envblk_buf-helper-function.patch
Normal file
@ -0,0 +1,68 @@
|
||||
From a326e486bdcf99e6be973ba54c0abfb6d2d95b73 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 17 Jan 2022 17:45:00 +0800
|
||||
Subject: [PATCH 1/5] Add grub_envblk_buf helper function
|
||||
|
||||
This helps in creation and initialization of memory buffer for
|
||||
environment block of given size.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/lib/envblk.c | 12 ++++++++++++
|
||||
include/grub/lib/envblk.h | 1 +
|
||||
util/grub-editenv.c | 4 +---
|
||||
3 files changed, 14 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/lib/envblk.c b/grub-core/lib/envblk.c
|
||||
index 2e4e78b132..24efbe7ffa 100644
|
||||
--- a/grub-core/lib/envblk.c
|
||||
+++ b/grub-core/lib/envblk.c
|
||||
@@ -23,6 +23,18 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/lib/envblk.h>
|
||||
|
||||
+char *
|
||||
+grub_envblk_buf (grub_size_t size)
|
||||
+{
|
||||
+ char *buf;
|
||||
+
|
||||
+ buf = grub_malloc (size);
|
||||
+ grub_memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
|
||||
+ grub_memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', size - sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
|
||||
+
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
grub_envblk_t
|
||||
grub_envblk_open (char *buf, grub_size_t size)
|
||||
{
|
||||
diff --git a/include/grub/lib/envblk.h b/include/grub/lib/envblk.h
|
||||
index c3e6559217..83f3fcf841 100644
|
||||
--- a/include/grub/lib/envblk.h
|
||||
+++ b/include/grub/lib/envblk.h
|
||||
@@ -31,6 +31,7 @@ struct grub_envblk
|
||||
};
|
||||
typedef struct grub_envblk *grub_envblk_t;
|
||||
|
||||
+char *grub_envblk_buf (grub_size_t size);
|
||||
grub_envblk_t grub_envblk_open (char *buf, grub_size_t size);
|
||||
int grub_envblk_set (grub_envblk_t envblk, const char *name, const char *value);
|
||||
void grub_envblk_delete (grub_envblk_t envblk, const char *name);
|
||||
diff --git a/util/grub-editenv.c b/util/grub-editenv.c
|
||||
index b8219335f7..a02d3f2a63 100644
|
||||
--- a/util/grub-editenv.c
|
||||
+++ b/util/grub-editenv.c
|
||||
@@ -210,9 +210,7 @@ create_envblk_fs (void)
|
||||
if (! fp)
|
||||
grub_util_error (_("cannot open `%s': %s"), device, strerror (errno));
|
||||
|
||||
- buf = xmalloc (size);
|
||||
- memcpy (buf, GRUB_ENVBLK_SIGNATURE, sizeof (GRUB_ENVBLK_SIGNATURE) - 1);
|
||||
- memset (buf + sizeof (GRUB_ENVBLK_SIGNATURE) - 1, '#', size - sizeof (GRUB_ENVBLK_SIGNATURE) + 1);
|
||||
+ buf = grub_envblk_buf (size);
|
||||
|
||||
if (fseek (fp, offset, SEEK_SET) < 0)
|
||||
grub_util_error (_("cannot seek `%s': %s"), device, strerror (errno));
|
||||
--
|
||||
2.34.1
|
||||
|
526
0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch
Normal file
526
0001-Add-support-for-Linux-EFI-stub-loading-on-aarch64.patch
Normal file
@ -0,0 +1,526 @@
|
||||
From db4da8095b5ba722d22502c8d090e66816a5577d Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Garrett <mjg@redhat.com>
|
||||
Date: Fri, 6 Nov 2020 08:36:36 +0000
|
||||
Subject: [PATCH 1/9] Add support for Linux EFI stub loading on aarch64.
|
||||
|
||||
Add support for Linux EFI stub loading on aarch64.
|
||||
|
||||
v1:
|
||||
Make efi handoff the default loader for arm64 platform.
|
||||
|
||||
v2:
|
||||
The efi shim_lock verifier has been moved to grub core so local
|
||||
shim_lock protocol is no longer needed here for aarch64 efi to verify
|
||||
the loaded kernel image. From now on the framework will take care the
|
||||
verificaion, consolidating the integration of various security verifiers
|
||||
like secure boot, gpg and tpm.
|
||||
|
||||
---
|
||||
grub-core/Makefile.core.def | 4 +-
|
||||
grub-core/loader/arm64/efi/linux.c | 443 +++++++++++++++++++++++++++++
|
||||
include/grub/arm/linux.h | 9 +
|
||||
include/grub/arm64/linux.h | 10 +
|
||||
4 files changed, 465 insertions(+), 1 deletion(-)
|
||||
create mode 100644 grub-core/loader/arm64/efi/linux.c
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1854,7 +1854,7 @@
|
||||
arm_coreboot = loader/arm/linux.c;
|
||||
arm_efi = loader/efi/linux.c;
|
||||
arm_uboot = loader/arm/linux.c;
|
||||
- arm64 = loader/efi/linux.c;
|
||||
+ arm64 = loader/arm64/efi/linux.c;
|
||||
loongarch64 = loader/efi/linux.c;
|
||||
riscv32 = loader/efi/linux.c;
|
||||
riscv64 = loader/efi/linux.c;
|
||||
@@ -1922,7 +1922,7 @@
|
||||
|
||||
module = {
|
||||
name = linuxefi;
|
||||
- efi = lib/fake_module.c;
|
||||
+ x86 = lib/fake_module.c;
|
||||
enable = i386_efi;
|
||||
enable = x86_64_efi;
|
||||
};
|
||||
--- /dev/null
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -0,0 +1,411 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/charset.h>
|
||||
+#include <grub/command.h>
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/file.h>
|
||||
+#include <grub/fdt.h>
|
||||
+#include <grub/linux.h>
|
||||
+#include <grub/loader.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/cpu/linux.h>
|
||||
+#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/fdtload.h>
|
||||
+#include <grub/efi/memory.h>
|
||||
+#include <grub/efi/pe32.h>
|
||||
+#include <grub/i18n.h>
|
||||
+#include <grub/lib/cmdline.h>
|
||||
+#include <grub/verify.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
+
|
||||
+static grub_dl_t my_mod;
|
||||
+static int loaded;
|
||||
+
|
||||
+static void *kernel_addr;
|
||||
+static grub_uint64_t kernel_size;
|
||||
+static grub_uint32_t handover_offset;
|
||||
+
|
||||
+static char *linux_args;
|
||||
+static grub_uint32_t cmdline_size;
|
||||
+
|
||||
+static grub_addr_t initrd_start;
|
||||
+static grub_addr_t initrd_end;
|
||||
+
|
||||
+#pragma GCC diagnostic push
|
||||
+#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
+
|
||||
+typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_efi_linux_boot (void *kernel_address, grub_off_t offset,
|
||||
+ void *kernel_params)
|
||||
+{
|
||||
+ handover_func hf;
|
||||
+
|
||||
+ hf = (handover_func)((char *)kernel_address + offset);
|
||||
+ hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
||||
+
|
||||
+ return GRUB_ERR_BUG;
|
||||
+}
|
||||
+
|
||||
+#pragma GCC diagnostic pop
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_arch_efi_linux_check_image (struct linux_arch_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)
|
||||
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
+ N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
|
||||
+
|
||||
+ grub_dprintf ("linux", "UEFI stub kernel:\n");
|
||||
+ grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+finalize_params_linux (void)
|
||||
+{
|
||||
+ grub_efi_loaded_image_t *loaded_image = NULL;
|
||||
+ int node, retval, len;
|
||||
+
|
||||
+ void *fdt;
|
||||
+
|
||||
+ fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
|
||||
+
|
||||
+ if (!fdt)
|
||||
+ goto failure;
|
||||
+
|
||||
+ node = grub_fdt_find_subnode (fdt, 0, "chosen");
|
||||
+ if (node < 0)
|
||||
+ node = grub_fdt_add_subnode (fdt, 0, "chosen");
|
||||
+
|
||||
+ if (node < 1)
|
||||
+ goto failure;
|
||||
+
|
||||
+ /* Set initrd info */
|
||||
+ if (initrd_start && initrd_end > initrd_start)
|
||||
+ {
|
||||
+ grub_dprintf ("linux", "Initrd @ %p-%p\n",
|
||||
+ (void *) initrd_start, (void *) initrd_end);
|
||||
+
|
||||
+ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
|
||||
+ initrd_start);
|
||||
+ if (retval)
|
||||
+ goto failure;
|
||||
+ retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
|
||||
+ initrd_end);
|
||||
+ if (retval)
|
||||
+ goto failure;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_fdt_install() != GRUB_ERR_NONE)
|
||||
+ goto failure;
|
||||
+
|
||||
+ grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n",
|
||||
+ fdt);
|
||||
+
|
||||
+ /* Convert command line to UCS-2 */
|
||||
+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
+ if (!loaded_image)
|
||||
+ goto failure;
|
||||
+
|
||||
+ loaded_image->load_options_size = len =
|
||||
+ (grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
|
||||
+ loaded_image->load_options =
|
||||
+ grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
|
||||
+ if (!loaded_image->load_options)
|
||||
+ return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
|
||||
+
|
||||
+ loaded_image->load_options_size =
|
||||
+ 2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
|
||||
+ (grub_uint8_t *) linux_args, len, NULL);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+failure:
|
||||
+ grub_fdt_unload();
|
||||
+ return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+free_params (void)
|
||||
+{
|
||||
+ grub_efi_loaded_image_t *loaded_image = NULL;
|
||||
+
|
||||
+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
+ if (loaded_image)
|
||||
+ {
|
||||
+ if (loaded_image->load_options)
|
||||
+ grub_efi_free_pages ((grub_efi_physical_address_t)(grub_efi_uintn_t)loaded_image->load_options,
|
||||
+ GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
|
||||
+ loaded_image->load_options = NULL;
|
||||
+ loaded_image->load_options_size = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_arch_efi_linux_boot_image (grub_addr_t addr,
|
||||
+ grub_size_t size __attribute__ ((unused)),
|
||||
+ char *args)
|
||||
+{
|
||||
+ grub_err_t retval;
|
||||
+
|
||||
+ retval = finalize_params_linux ();
|
||||
+ if (retval != GRUB_ERR_NONE)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ grub_dprintf ("linux", "linux command line: '%s'\n", args);
|
||||
+
|
||||
+ retval = grub_efi_linux_boot ((char *)addr, handover_offset, (void *)addr);
|
||||
+
|
||||
+ /* Never reached... */
|
||||
+ free_params();
|
||||
+ return retval;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_linux_boot (void)
|
||||
+{
|
||||
+ return (grub_arch_efi_linux_boot_image ((grub_addr_t)kernel_addr, kernel_size, linux_args));
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_linux_unload (void)
|
||||
+{
|
||||
+ grub_dl_unref (my_mod);
|
||||
+ loaded = 0;
|
||||
+ if (initrd_start)
|
||||
+ grub_efi_free_pages ((grub_efi_physical_address_t) initrd_start,
|
||||
+ GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start));
|
||||
+ initrd_start = initrd_end = 0;
|
||||
+ grub_free (linux_args);
|
||||
+ if (kernel_addr)
|
||||
+ grub_efi_free_pages ((grub_addr_t) kernel_addr,
|
||||
+ GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||
+ grub_fdt_unload ();
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+/*
|
||||
+ * As per linux/Documentation/arm/Booting
|
||||
+ * ARM initrd needs to be covered by kernel linear mapping,
|
||||
+ * so place it in the first 512MB of DRAM.
|
||||
+ *
|
||||
+ * As per linux/Documentation/arm64/booting.txt
|
||||
+ * ARM64 initrd needs to be contained entirely within a 1GB aligned window
|
||||
+ * of up to 32GB of size that covers the kernel image as well.
|
||||
+ * Since the EFI stub loader will attempt to load the kernel near start of
|
||||
+ * RAM, place the buffer in the first 32GB of RAM.
|
||||
+ */
|
||||
+#ifdef __arm__
|
||||
+#define INITRD_MAX_ADDRESS_OFFSET (512U * 1024 * 1024)
|
||||
+#else /* __aarch64__ */
|
||||
+#define INITRD_MAX_ADDRESS_OFFSET (32ULL * 1024 * 1024 * 1024)
|
||||
+#endif
|
||||
+
|
||||
+/*
|
||||
+ * This function returns a pointer to a legally allocated initrd buffer,
|
||||
+ * or NULL if unsuccessful
|
||||
+ */
|
||||
+static void *
|
||||
+allocate_initrd_mem (int initrd_pages)
|
||||
+{
|
||||
+ grub_addr_t max_addr;
|
||||
+
|
||||
+ if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE)
|
||||
+ return NULL;
|
||||
+
|
||||
+ max_addr += INITRD_MAX_ADDRESS_OFFSET - 1;
|
||||
+
|
||||
+ return grub_efi_allocate_pages_real (max_addr, initrd_pages,
|
||||
+ GRUB_EFI_ALLOCATE_MAX_ADDRESS,
|
||||
+ GRUB_EFI_LOADER_DATA);
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
+ int argc, char *argv[])
|
||||
+{
|
||||
+ struct grub_linux_initrd_context initrd_ctx = { 0, 0, 0 };
|
||||
+ int initrd_size, initrd_pages;
|
||||
+ void *initrd_mem = NULL;
|
||||
+
|
||||
+ if (argc == 0)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (!loaded)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("you need to load the kernel first"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_initrd_init (argc, argv, &initrd_ctx))
|
||||
+ goto fail;
|
||||
+
|
||||
+ initrd_size = grub_get_initrd_size (&initrd_ctx);
|
||||
+ grub_dprintf ("linux", "Loading initrd\n");
|
||||
+
|
||||
+ initrd_pages = (GRUB_EFI_BYTES_TO_PAGES (initrd_size));
|
||||
+ initrd_mem = allocate_initrd_mem (initrd_pages);
|
||||
+
|
||||
+ if (!initrd_mem)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_initrd_load (&initrd_ctx, initrd_mem))
|
||||
+ goto fail;
|
||||
+
|
||||
+ initrd_start = (grub_addr_t) initrd_mem;
|
||||
+ initrd_end = initrd_start + initrd_size;
|
||||
+ grub_dprintf ("linux", "[addr=%p, size=0x%x]\n",
|
||||
+ (void *) initrd_start, initrd_size);
|
||||
+
|
||||
+ fail:
|
||||
+ grub_initrd_close (&initrd_ctx);
|
||||
+ if (initrd_mem && !initrd_start)
|
||||
+ grub_efi_free_pages ((grub_addr_t) initrd_mem, initrd_pages);
|
||||
+
|
||||
+ return grub_errno;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
+ int argc, char *argv[])
|
||||
+{
|
||||
+ grub_file_t file = 0;
|
||||
+ struct linux_arch_kernel_header lh;
|
||||
+ struct grub_armxx_linux_pe_header *pe;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ grub_dl_ref (my_mod);
|
||||
+
|
||||
+ if (argc == 0)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ file = grub_file_open (argv[0], GRUB_FILE_TYPE_LINUX_KERNEL);
|
||||
+ if (!file)
|
||||
+ goto fail;
|
||||
+
|
||||
+ kernel_size = grub_file_size (file);
|
||||
+
|
||||
+ if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
+
|
||||
+ grub_loader_unset();
|
||||
+
|
||||
+ grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size);
|
||||
+ kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||
+ grub_dprintf ("linux", "kernel numpages: %lld\n",
|
||||
+ (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||
+ if (!kernel_addr)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ grub_file_seek (file, 0);
|
||||
+ if (grub_file_read (file, kernel_addr, kernel_size)
|
||||
+ < (grub_int64_t) kernel_size)
|
||||
+ {
|
||||
+ if (!grub_errno)
|
||||
+ grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]);
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
|
||||
+
|
||||
+ pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
|
||||
+ handover_offset = pe->opt.entry_addr;
|
||||
+
|
||||
+ cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
|
||||
+ linux_args = grub_malloc (cmdline_size);
|
||||
+ if (!linux_args)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ grub_memcpy (linux_args, LINUX_IMAGE, sizeof (LINUX_IMAGE));
|
||||
+ err = grub_create_loader_cmdline (argc, argv,
|
||||
+ linux_args + sizeof (LINUX_IMAGE) - 1,
|
||||
+ cmdline_size,
|
||||
+ GRUB_VERIFY_KERNEL_CMDLINE);
|
||||
+ if (err)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (grub_errno == GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_loader_set (grub_linux_boot, grub_linux_unload, 0);
|
||||
+ loaded = 1;
|
||||
+ }
|
||||
+
|
||||
+fail:
|
||||
+ if (file)
|
||||
+ grub_file_close (file);
|
||||
+
|
||||
+ if (grub_errno != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_dl_unref (my_mod);
|
||||
+ loaded = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (linux_args && !loaded)
|
||||
+ grub_free (linux_args);
|
||||
+
|
||||
+ if (kernel_addr && !loaded)
|
||||
+ grub_efi_free_pages ((grub_addr_t) kernel_addr,
|
||||
+ GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||
+
|
||||
+ return grub_errno;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static grub_command_t cmd_linux, cmd_initrd;
|
||||
+
|
||||
+GRUB_MOD_INIT (linux)
|
||||
+{
|
||||
+ cmd_linux = grub_register_command ("linux", grub_cmd_linux, 0,
|
||||
+ N_("Load Linux."));
|
||||
+ cmd_initrd = grub_register_command ("initrd", grub_cmd_initrd, 0,
|
||||
+ N_("Load initrd."));
|
||||
+ my_mod = mod;
|
||||
+}
|
||||
+
|
||||
+GRUB_MOD_FINI (linux)
|
||||
+{
|
||||
+ grub_unregister_command (cmd_linux);
|
||||
+ grub_unregister_command (cmd_initrd);
|
||||
+}
|
||||
--- a/include/grub/arm/linux.h
|
||||
+++ b/include/grub/arm/linux.h
|
||||
@@ -20,10 +20,22 @@
|
||||
#ifndef GRUB_ARM_LINUX_HEADER
|
||||
#define GRUB_ARM_LINUX_HEADER 1
|
||||
|
||||
+#include <grub/efi/pe32.h>
|
||||
#include "system.h"
|
||||
|
||||
#include <grub/efi/pe32.h>
|
||||
|
||||
+struct grub_arm_linux_pe_header
|
||||
+{
|
||||
+ grub_uint32_t magic;
|
||||
+ struct grub_pe32_coff_header coff;
|
||||
+ struct grub_pe32_optional_header opt;
|
||||
+};
|
||||
+
|
||||
+#if defined(__arm__)
|
||||
+# define grub_armxx_linux_pe_header grub_arm_linux_pe_header
|
||||
+#endif
|
||||
+
|
||||
#if defined GRUB_MACHINE_UBOOT
|
||||
# include <grub/uboot/uboot.h>
|
||||
# define LINUX_ADDRESS (start_of_ram + 0x8000)
|
||||
--- /dev/null
|
||||
+++ b/include/grub/arm64/linux.h
|
||||
@@ -0,0 +1,39 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * 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/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef GRUB_ARM64_LINUX_HEADER
|
||||
+#define GRUB_ARM64_LINUX_HEADER 1
|
||||
+
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/efi/pe32.h>
|
||||
+
|
||||
+#define GRUB_LINUX_ARM64_MAGIC_SIGNATURE 0x644d5241 /* 'ARM\x64' */
|
||||
+
|
||||
+struct grub_arm64_linux_pe_header
|
||||
+{
|
||||
+ grub_uint32_t magic;
|
||||
+ struct grub_pe32_coff_header coff;
|
||||
+ struct grub_pe64_optional_header opt;
|
||||
+};
|
||||
+
|
||||
+#if defined(__aarch64__)
|
||||
+# define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE
|
||||
+# define grub_armxx_linux_pe_header grub_arm64_linux_pe_header
|
||||
+#endif
|
||||
+
|
||||
+#endif /* ! GRUB_ARM64_LINUX_HEADER */
|
215
0001-Factor-out-grub_efi_linux_boot.patch
Normal file
215
0001-Factor-out-grub_efi_linux_boot.patch
Normal file
@ -0,0 +1,215 @@
|
||||
From 82d95254ca0496c8843113665bb9a99876101025 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 8 Oct 2021 13:36:45 +0800
|
||||
Subject: [PATCH 01/11] Factor out grub_efi_linux_boot
|
||||
|
||||
Both x86 and arm64 on efi are using handover protocol to boot linux
|
||||
kernel. To enable better code reuse, factor out grub_efi_linux_boot from
|
||||
arm64 so that it can be shared with x86 platform for the common fixes.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/loader/arm64/efi/linux.c | 35 +-----------------
|
||||
grub-core/loader/efi/linux.c | 58 ++++++++++++++++++++++++++++++
|
||||
grub-core/loader/i386/efi/linux.c | 13 ++-----
|
||||
include/grub/efi/linux.h | 29 +++++++++++++++
|
||||
5 files changed, 92 insertions(+), 44 deletions(-)
|
||||
create mode 100644 grub-core/loader/efi/linux.c
|
||||
create mode 100644 include/grub/efi/linux.h
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1860,6 +1860,9 @@
|
||||
riscv64 = loader/efi/linux.c;
|
||||
emu = loader/emu/linux.c;
|
||||
common = loader/linux.c;
|
||||
+ i386_efi = loader/efi/linux_boot.c;
|
||||
+ x86_64_efi = loader/efi/linux_boot.c;
|
||||
+ arm64 = loader/efi/linux_boot.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
--- a/grub-core/loader/arm64/efi/linux.c
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -33,6 +33,7 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/verify.h>
|
||||
+#include <grub/efi/linux.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -51,40 +52,6 @@
|
||||
static grub_addr_t initrd_start;
|
||||
static grub_addr_t initrd_end;
|
||||
|
||||
-#pragma GCC diagnostic push
|
||||
-#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
-
|
||||
-typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
|
||||
-
|
||||
-static grub_err_t
|
||||
-grub_efi_linux_boot (void *kernel_address, grub_off_t offset,
|
||||
- void *kernel_params)
|
||||
-{
|
||||
- grub_efi_loaded_image_t *loaded_image = NULL;
|
||||
- handover_func hf;
|
||||
-
|
||||
- /*
|
||||
- * Since the EFI loader is not calling the LoadImage() and StartImage()
|
||||
- * services for loading the kernel and booting respectively, it has to
|
||||
- * set the Loaded Image base address.
|
||||
- */
|
||||
- loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
- if (loaded_image)
|
||||
- loaded_image->image_base = 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_address, (void *)(grub_efi_uintn_t)offset, kernel_params);
|
||||
- hf = (handover_func)((char *)kernel_address + offset);
|
||||
- grub_dprintf ("linux", "handover_func() = %p\n", hf);
|
||||
- hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
||||
-
|
||||
- return GRUB_ERR_BUG;
|
||||
-}
|
||||
-
|
||||
-#pragma GCC diagnostic pop
|
||||
-
|
||||
static grub_err_t
|
||||
grub_arch_efi_linux_check_image (struct linux_arch_kernel_header * lh)
|
||||
{
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/linux.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -40,26 +41,18 @@
|
||||
|
||||
#define BYTES_TO_PAGES(bytes) (((bytes) + 0xfff) >> 12)
|
||||
|
||||
-typedef void(*handover_func)(void *, grub_efi_system_table_t *, struct linux_kernel_params *);
|
||||
-
|
||||
static grub_err_t
|
||||
grub_linuxefi_boot (void)
|
||||
{
|
||||
- handover_func hf;
|
||||
int offset = 0;
|
||||
|
||||
#ifdef __x86_64__
|
||||
offset = 512;
|
||||
#endif
|
||||
-
|
||||
- hf = (handover_func)((char *)kernel_mem + handover_offset + offset);
|
||||
-
|
||||
asm volatile ("cli");
|
||||
|
||||
- hf (grub_efi_image_handle, grub_efi_system_table, params);
|
||||
-
|
||||
- /* Not reached */
|
||||
- return GRUB_ERR_NONE;
|
||||
+ return grub_efi_linux_boot ((char *)kernel_mem, handover_offset + offset,
|
||||
+ params);
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
--- /dev/null
|
||||
+++ b/include/grub/efi/linux.h
|
||||
@@ -0,0 +1,29 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * 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/>.
|
||||
+ */
|
||||
+#ifndef GRUB_EFI_LINUX_HEADER
|
||||
+#define GRUB_EFI_LINUX_HEADER 1
|
||||
+
|
||||
+#include <grub/efi/api.h>
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/symbol.h>
|
||||
+
|
||||
+grub_err_t
|
||||
+EXPORT_FUNC(grub_efi_linux_boot) (void *kernel_address, grub_off_t offset,
|
||||
+ void *kernel_param);
|
||||
+
|
||||
+#endif /* ! GRUB_EFI_LINUX_HEADER */
|
||||
--- /dev/null
|
||||
+++ b/grub-core/loader/efi/linux_boot.c
|
||||
@@ -0,0 +1,58 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2014 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/cpu/linux.h>
|
||||
+#include <grub/efi/efi.h>
|
||||
+#include <grub/efi/pe32.h>
|
||||
+#include <grub/efi/linux.h>
|
||||
+
|
||||
+#pragma GCC diagnostic push
|
||||
+#pragma GCC diagnostic ignored "-Wcast-align"
|
||||
+
|
||||
+typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_efi_linux_boot (void *kernel_addr, grub_off_t offset,
|
||||
+ void *kernel_params)
|
||||
+{
|
||||
+ grub_efi_loaded_image_t *loaded_image = NULL;
|
||||
+ handover_func hf;
|
||||
+
|
||||
+ /*
|
||||
+ * Since the EFI loader is not calling the LoadImage() and StartImage()
|
||||
+ * services for loading the kernel and booting respectively, it has to
|
||||
+ * set the Loaded Image base address.
|
||||
+ */
|
||||
+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
+ if (loaded_image)
|
||||
+ loaded_image->image_base = 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)offset, kernel_params);
|
||||
+ hf = (handover_func)((char *)kernel_addr + offset);
|
||||
+ hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
||||
+
|
||||
+ return GRUB_ERR_BUG;
|
||||
+}
|
||||
+
|
||||
+#pragma GCC diagnostic pop
|
66
0001-Fix-infinite-boot-loop-on-headless-system-in-qemu.patch
Normal file
66
0001-Fix-infinite-boot-loop-on-headless-system-in-qemu.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From f76317d9dc35dbc576820ba6c2a6a8e41f5338b5 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 19 May 2022 13:08:12 +0800
|
||||
Subject: [PATCH] Fix infinite boot loop on headless system in qemu
|
||||
|
||||
After finishing headless virtual machine installation via serial
|
||||
console, the reboot fails in grub with infinte boot loop and also
|
||||
keyboard input for serial console is unresponsive.
|
||||
|
||||
The cause of infinte loop boils down to legacy vga driver in grub
|
||||
crashes when '-dispaly none' is used as qemu's display type described in
|
||||
the manual as:
|
||||
|
||||
"Do not display video output. The guest will still see an emulated
|
||||
graphics card, but its output will not be displayed tothe QEMU user.
|
||||
This option differs from the -nographic option in that it only affects
|
||||
what is done with video output; -nographic also changes the destination
|
||||
of the serial and parallel port data."
|
||||
|
||||
Given there's no sensible way found to skip the emulated device from the
|
||||
legacy vga module, we ended up removing it from all_video dependency so
|
||||
it wouldn't be loaded by default. In any case, the vbe module remain
|
||||
loaded and should fulfill the requirement of most hardwares even twenty
|
||||
years old or more.
|
||||
|
||||
The unresponsive serial input is also fixed by ensuring that console
|
||||
input is loaded via appended so that they won't fail altogether with
|
||||
errors by other console device if specifying on the same list.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/genmoddep.awk | 3 +++
|
||||
util/grub.d/00_header.in | 10 +++++++++-
|
||||
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/grub-core/genmoddep.awk
|
||||
+++ b/grub-core/genmoddep.awk
|
||||
@@ -98,6 +98,9 @@
|
||||
}
|
||||
modlist = ""
|
||||
while (getline <"video.lst") {
|
||||
+ if ($1 == "vga") {
|
||||
+ continue;
|
||||
+ }
|
||||
modlist = modlist " " $1;
|
||||
}
|
||||
printf "all_video:%s\n", modlist;
|
||||
--- a/util/grub.d/00_header.in
|
||||
+++ b/util/grub.d/00_header.in
|
||||
@@ -287,7 +287,15 @@
|
||||
;;
|
||||
x*)
|
||||
cat << EOF
|
||||
-terminal_output ${GRUB_TERMINAL_OUTPUT}
|
||||
+
|
||||
+for i in ${GRUB_TERMINAL_OUTPUT}; do
|
||||
+ if [ x\${use_append} = xtrue ]; then
|
||||
+ terminal_output --append \$i
|
||||
+ elif terminal_output \$i; then
|
||||
+ use_append=true;
|
||||
+ fi
|
||||
+done
|
||||
+
|
||||
EOF
|
||||
;;
|
||||
esac
|
286
0001-Improve-TPM-key-protection-on-boot-interruptions.patch
Normal file
286
0001-Improve-TPM-key-protection-on-boot-interruptions.patch
Normal file
@ -0,0 +1,286 @@
|
||||
From 27b3e919b9b51a4fedeb3a5aef19c87f0cd7b687 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 17 Nov 2023 12:32:59 +0800
|
||||
Subject: [PATCH] Improve TPM key protection on boot interruptions
|
||||
|
||||
The unattended boot process for full disk encryption relies on an
|
||||
authorized TPM policy to ensure the system's integrity before releasing
|
||||
the key to grub. Subsequently, grub assumes responsibility for securing
|
||||
the boot process, directing it towards a trusted default without any
|
||||
expected interruptions. Any interruption during this process indicates
|
||||
potential modification attempts, and releasing the obtained key to the
|
||||
next stage should not occur in such cases.
|
||||
|
||||
This commit addresses a vulnerability associated with interrupted boot
|
||||
processes that could potentially enable malicious modifications to the
|
||||
default or trusted boot target. To reinforce system security, the code
|
||||
has been updated to incorporate measures that discard the TPM protected
|
||||
key in the event of boot interruptions.
|
||||
|
||||
Furthermore, this patch aims to enhance code readability by renaming
|
||||
structures and function names related to cryptographic keys, improving
|
||||
clarity and maintainability.
|
||||
|
||||
By implementing these changes, this enhancement seeks to fortify the
|
||||
protection of TPM keys, thereby ensuring a more robust defense against
|
||||
potential unauthorized modifications during the boot process.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 38 ++++++++++++++++++++++++++---------
|
||||
grub-core/disk/cryptodisk.c | 8 +++++++-
|
||||
grub-core/loader/linux.c | 6 +++---
|
||||
grub-core/normal/main.c | 2 +-
|
||||
grub-core/normal/menu.c | 7 +++++++
|
||||
grub-core/normal/menu_entry.c | 2 +-
|
||||
include/grub/crypttab.h | 18 ++++++++++-------
|
||||
7 files changed, 59 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index c2217ca98..9397bede9 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -9,17 +9,20 @@
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
-struct grub_key_publisher *kpuber;
|
||||
+grub_crypto_key_list_t *cryptokey_lst;
|
||||
|
||||
grub_err_t
|
||||
-grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path)
|
||||
+grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey)
|
||||
{
|
||||
- struct grub_key_publisher *cur = NULL;
|
||||
+ grub_crypto_key_list_t *cur = NULL;
|
||||
|
||||
- FOR_LIST_ELEMENTS (cur, kpuber)
|
||||
+ FOR_LIST_ELEMENTS (cur, cryptokey_lst)
|
||||
if (grub_uuidcasecmp (cur->name, uuid, sizeof (cur->name)) == 0)
|
||||
break;
|
||||
|
||||
+ if (!cur && !uuid)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
if (!cur)
|
||||
cur = grub_zalloc (sizeof (*cur));
|
||||
if (!cur)
|
||||
@@ -44,21 +47,24 @@ grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len,
|
||||
cur->path = grub_strdup (path);
|
||||
}
|
||||
|
||||
+ if (is_tpmkey >= 0)
|
||||
+ cur->is_tpmkey = is_tpmkey;
|
||||
+
|
||||
if (!cur->name)
|
||||
{
|
||||
cur->name = grub_strdup (uuid);
|
||||
- grub_list_push (GRUB_AS_LIST_P (&kpuber), GRUB_AS_LIST (cur));
|
||||
+ grub_list_push (GRUB_AS_LIST_P (&cryptokey_lst), GRUB_AS_LIST (cur));
|
||||
}
|
||||
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
void
|
||||
-grub_initrd_discard_key (void)
|
||||
+grub_cryptokey_discard (void)
|
||||
{
|
||||
- struct grub_key_publisher *cur, *nxt;
|
||||
+ grub_crypto_key_list_t *cur, *nxt;
|
||||
|
||||
- FOR_LIST_ELEMENTS_SAFE (cur, nxt, kpuber)
|
||||
+ FOR_LIST_ELEMENTS_SAFE (cur, nxt, cryptokey_lst)
|
||||
{
|
||||
grub_list_remove (GRUB_AS_LIST (cur));
|
||||
grub_memset (cur->key, 0, cur->key_len);
|
||||
@@ -69,6 +75,20 @@ grub_initrd_discard_key (void)
|
||||
}
|
||||
}
|
||||
|
||||
+void
|
||||
+grub_cryptokey_tpmkey_discard (void)
|
||||
+{
|
||||
+ grub_crypto_key_list_t *cur = NULL;
|
||||
+
|
||||
+ FOR_LIST_ELEMENTS (cur, cryptokey_lst)
|
||||
+ if (cur->is_tpmkey)
|
||||
+ break;
|
||||
+
|
||||
+ /* Discard all keys if any of them is tpm */
|
||||
+ if (cur)
|
||||
+ grub_cryptokey_discard();
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **argv)
|
||||
@@ -92,7 +112,7 @@ grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
|
||||
/*FIXME: Validate UUID string*/
|
||||
- return grub_initrd_publish_key (argv[1], NULL, 0, path);
|
||||
+ return grub_cryptokey_add_or_update (argv[1], NULL, 0, path, -1);
|
||||
}
|
||||
|
||||
static grub_command_t cmd;
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index aa0d43562..babc94868 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1071,6 +1071,9 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
struct cryptodisk_read_hook_ctx read_hook_data = {0};
|
||||
int askpass = 0;
|
||||
char *part = NULL;
|
||||
+#ifndef GRUB_UTIL
|
||||
+ int is_tpmkey = 0;
|
||||
+#endif
|
||||
|
||||
dev = grub_cryptodisk_get_by_source_disk (source);
|
||||
|
||||
@@ -1183,6 +1186,9 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
ret = grub_cryptodisk_insert (dev, name, source);
|
||||
if (ret != GRUB_ERR_NONE)
|
||||
goto error;
|
||||
+#ifndef GRUB_UTIL
|
||||
+ is_tpmkey = 1;
|
||||
+#endif
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
@@ -1244,7 +1250,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
|
||||
#ifndef GRUB_UTIL
|
||||
if (cargs->key_data && dev)
|
||||
- grub_initrd_publish_key (dev->uuid, (const char *)cargs->key_data, cargs->key_len, NULL);
|
||||
+ grub_cryptokey_add_or_update (dev->uuid, (const char *)cargs->key_data, cargs->key_len, NULL, is_tpmkey);
|
||||
#endif
|
||||
if (askpass)
|
||||
{
|
||||
diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
|
||||
index 9ee8f3790..e5e792958 100644
|
||||
--- a/grub-core/loader/linux.c
|
||||
+++ b/grub-core/loader/linux.c
|
||||
@@ -226,13 +226,13 @@ grub_initrd_init (int argc, char *argv[],
|
||||
int i;
|
||||
int newc = 0;
|
||||
struct dir *root = 0;
|
||||
- struct grub_key_publisher *pk;
|
||||
+ grub_crypto_key_list_t *pk;
|
||||
int numkey = 0;
|
||||
|
||||
initrd_ctx->nfiles = 0;
|
||||
initrd_ctx->components = 0;
|
||||
|
||||
- FOR_LIST_ELEMENTS (pk, kpuber)
|
||||
+ FOR_LIST_ELEMENTS (pk, cryptokey_lst)
|
||||
if (pk->key && pk->path)
|
||||
numkey++;
|
||||
|
||||
@@ -305,7 +305,7 @@ grub_initrd_init (int argc, char *argv[],
|
||||
goto overflow;
|
||||
}
|
||||
|
||||
- FOR_LIST_ELEMENTS (pk, kpuber)
|
||||
+ FOR_LIST_ELEMENTS (pk, cryptokey_lst)
|
||||
if (pk->key && pk->path)
|
||||
{
|
||||
grub_initrd_component (pk->key, pk->key_len, pk->path, initrd_ctx);
|
||||
diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
|
||||
index a3f711d1d..1b426af69 100644
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -479,7 +479,7 @@ grub_cmdline_run (int nested, int force_auth)
|
||||
return;
|
||||
}
|
||||
|
||||
- grub_initrd_discard_key ();
|
||||
+ grub_cryptokey_discard ();
|
||||
grub_normal_reader_init (nested);
|
||||
|
||||
while (1)
|
||||
diff --git a/grub-core/normal/menu.c b/grub-core/normal/menu.c
|
||||
index 14b0ab1ec..1df2638d7 100644
|
||||
--- a/grub-core/normal/menu.c
|
||||
+++ b/grub-core/normal/menu.c
|
||||
@@ -32,6 +32,7 @@
|
||||
#include <grub/script_sh.h>
|
||||
#include <grub/gfxterm.h>
|
||||
#include <grub/dl.h>
|
||||
+#include <grub/crypttab.h>
|
||||
|
||||
/* Time to delay after displaying an error message about a default/fallback
|
||||
entry failing to boot. */
|
||||
@@ -708,6 +709,7 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
if (grub_key_is_interrupt (key))
|
||||
{
|
||||
timeout = -1;
|
||||
+ grub_cryptokey_tpmkey_discard();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -790,6 +792,11 @@ run_menu (grub_menu_t menu, int nested, int *auto_boot, int *notify_boot)
|
||||
clear_timeout ();
|
||||
}
|
||||
|
||||
+ /* Timeout is interrupted by external input, Forget tpmkey if timeout
|
||||
+ * is not cut by enter */
|
||||
+ if (c != '\n' && c != '\r')
|
||||
+ grub_cryptokey_tpmkey_discard();
|
||||
+
|
||||
switch (c)
|
||||
{
|
||||
case GRUB_TERM_KEY_HOME:
|
||||
diff --git a/grub-core/normal/menu_entry.c b/grub-core/normal/menu_entry.c
|
||||
index 384ab9ce3..e5ba91ea4 100644
|
||||
--- a/grub-core/normal/menu_entry.c
|
||||
+++ b/grub-core/normal/menu_entry.c
|
||||
@@ -1263,7 +1263,7 @@ grub_menu_entry_run (grub_menu_entry_t entry)
|
||||
return;
|
||||
}
|
||||
|
||||
- grub_initrd_discard_key();
|
||||
+ grub_cryptokey_discard();
|
||||
|
||||
screen = make_screen (entry);
|
||||
if (! screen)
|
||||
diff --git a/include/grub/crypttab.h b/include/grub/crypttab.h
|
||||
index 113c53cfc..f86404686 100644
|
||||
--- a/include/grub/crypttab.h
|
||||
+++ b/include/grub/crypttab.h
|
||||
@@ -4,21 +4,25 @@
|
||||
#include <grub/types.h>
|
||||
#include <grub/err.h>
|
||||
|
||||
-struct grub_key_publisher
|
||||
+typedef struct grub_crypto_key_list
|
||||
{
|
||||
- struct grub_key_publisher *next;
|
||||
- struct grub_key_publisher **prev;
|
||||
+ struct grub_crypto_key_list *next;
|
||||
+ struct grub_crypto_key_list **prev;
|
||||
char *name; /* UUID */
|
||||
char *path;
|
||||
char *key;
|
||||
grub_size_t key_len;
|
||||
-};
|
||||
+ int is_tpmkey;
|
||||
+} grub_crypto_key_list_t;
|
||||
|
||||
-extern struct grub_key_publisher *EXPORT_VAR (kpuber);
|
||||
+extern grub_crypto_key_list_t *EXPORT_VAR (cryptokey_lst);
|
||||
|
||||
grub_err_t
|
||||
-grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path);
|
||||
+grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey);
|
||||
|
||||
void
|
||||
-grub_initrd_discard_key (void);
|
||||
+grub_cryptokey_discard (void);
|
||||
+
|
||||
+void
|
||||
+grub_cryptokey_tpmkey_discard (void);
|
||||
#endif /* ! GRUB_CRYPTTAB_HEADER */
|
||||
--
|
||||
2.35.3
|
||||
|
82
0001-Make-grub.cfg-compatible-to-old-binaries.patch
Normal file
82
0001-Make-grub.cfg-compatible-to-old-binaries.patch
Normal file
@ -0,0 +1,82 @@
|
||||
From b8457f2e271917c5c83a4fee286bafedf8c5790c Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 8 Aug 2023 17:57:24 +0800
|
||||
Subject: [PATCH] Make grub.cfg compatible to old binaries
|
||||
|
||||
The new added fwsetup test in the topmost menu is always executed
|
||||
regardless older grub may not be able to handle and thus trapped in a
|
||||
boot loop between grub and fwsetup.
|
||||
|
||||
This in particular is to make sure a smooth transition if grub is rolled
|
||||
back to older release and needs to boot newer snapshots.
|
||||
|
||||
Also removing dashes in the UUID that every version released in the wild
|
||||
can handle.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub-probe.c | 20 +++++++++++++++++++-
|
||||
util/grub.d/30_uefi-firmware.in | 16 ++++++++++------
|
||||
2 files changed, 29 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/util/grub-probe.c b/util/grub-probe.c
|
||||
index e7efcc268..99c738e44 100644
|
||||
--- a/util/grub-probe.c
|
||||
+++ b/util/grub-probe.c
|
||||
@@ -290,8 +290,26 @@ probe_cryptodisk_uuid (grub_disk_t disk, char delim)
|
||||
}
|
||||
if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
{
|
||||
+ grub_size_t i, j;
|
||||
const char *uu = grub_util_cryptodisk_get_uuid (disk);
|
||||
- grub_printf ("%s%c", uu, delim);
|
||||
+ grub_size_t len = grub_strlen (uu);
|
||||
+ char *p = grub_malloc (len + 1);
|
||||
+
|
||||
+ /* Removing dash in the UUID string
|
||||
+ * This keeps old grub binary to work with newer config in a system,
|
||||
+ * especially for snapshots. It is a temporary change to make sure smooth
|
||||
+ * transition from 2.06 to 2.12-rc1 and this hunk can be removed
|
||||
+ * after 2.12-rc1 release stablized.
|
||||
+ */
|
||||
+ for (i = 0, j = 0; i < len; i++)
|
||||
+ {
|
||||
+ if (uu[i] != '-')
|
||||
+ p[j++] = uu[i];
|
||||
+ }
|
||||
+ p[j] = '\0';
|
||||
+
|
||||
+ grub_printf ("%s%c", p, delim);
|
||||
+ grub_free (p);
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/util/grub.d/30_uefi-firmware.in b/util/grub.d/30_uefi-firmware.in
|
||||
index 1c2365ddb..96ff112e5 100644
|
||||
--- a/util/grub.d/30_uefi-firmware.in
|
||||
+++ b/util/grub.d/30_uefi-firmware.in
|
||||
@@ -32,11 +32,15 @@ gettext_printf "Adding boot menu entry for UEFI Firmware Settings ...\n" >&2
|
||||
|
||||
cat << EOF
|
||||
if [ "\$grub_platform" = "efi" ]; then
|
||||
- fwsetup --is-supported
|
||||
- if [ "\$?" = 0 ]; then
|
||||
- menuentry '$LABEL' \$menuentry_id_option 'uefi-firmware' {
|
||||
- fwsetup
|
||||
- }
|
||||
- fi
|
||||
+ menuentry '$LABEL' \$menuentry_id_option 'uefi-firmware' {
|
||||
+ fwsetup --is-supported
|
||||
+ if [ "\$?" = 0 ]; then
|
||||
+ fwsetup
|
||||
+ else
|
||||
+ echo "Your firmware doesn't support setup menu entry from a boot loader"
|
||||
+ echo "Press any key to return ..."
|
||||
+ read
|
||||
+ fi
|
||||
+ }
|
||||
fi
|
||||
EOF
|
||||
--
|
||||
2.41.0
|
||||
|
150
0001-Unify-the-check-to-enable-btrfs-relative-path.patch
Normal file
150
0001-Unify-the-check-to-enable-btrfs-relative-path.patch
Normal file
@ -0,0 +1,150 @@
|
||||
From 80bb1b17b3f596dbd7331cf9cb20a46c8ef9800b Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 22 Aug 2020 02:32:43 +0800
|
||||
Subject: [PATCH] Unify the check to enable btrfs relative path
|
||||
|
||||
This unified the test in grub-install and grub-mkconfig that the path to
|
||||
default or selected btrfs subvolume/snapshot is used if the root file
|
||||
system is btrfs and the config has enabled btrfs snapshot booting.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub-install.c | 67 +++++++++++++++++++++++++++------------
|
||||
util/grub-mkconfig_lib.in | 3 +-
|
||||
2 files changed, 48 insertions(+), 22 deletions(-)
|
||||
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -886,6 +886,7 @@
|
||||
const char *efi_file = NULL;
|
||||
char **grub_devices;
|
||||
grub_fs_t grub_fs;
|
||||
+ grub_fs_t root_fs;
|
||||
grub_device_t grub_dev = NULL;
|
||||
enum grub_install_plat platform;
|
||||
char *grubdir, *device_map;
|
||||
@@ -898,6 +899,8 @@
|
||||
int efidir_is_mac = 0;
|
||||
int is_prep = 0;
|
||||
const char *pkgdatadir;
|
||||
+ char *rootdir_path;
|
||||
+ char **rootdir_devices;
|
||||
|
||||
grub_util_host_init (&argc, &argv);
|
||||
product_version = xstrdup (PACKAGE_VERSION);
|
||||
@@ -911,9 +914,6 @@
|
||||
|
||||
grub_util_load_config (&config);
|
||||
|
||||
- if (config.is_suse_btrfs_snapshot_enabled)
|
||||
- use_relative_path_on_btrfs = 1;
|
||||
-
|
||||
if (!bootloader_id && config.grub_distributor)
|
||||
{
|
||||
char *ptr;
|
||||
@@ -1064,6 +1064,45 @@
|
||||
grub_hostfs_init ();
|
||||
grub_host_init ();
|
||||
|
||||
+ {
|
||||
+ char *rootdir_grub_devname;
|
||||
+ grub_device_t rootdir_grub_dev;
|
||||
+ char *t = grub_util_path_concat (2, "/", rootdir);
|
||||
+
|
||||
+ rootdir_path = grub_canonicalize_file_name (t);
|
||||
+ if (!rootdir_path)
|
||||
+ grub_util_error (_("failed to get canonical path of `%s'"), t);
|
||||
+
|
||||
+ rootdir_devices = grub_guess_root_devices (rootdir_path);
|
||||
+ if (!rootdir_devices || !rootdir_devices[0])
|
||||
+ grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
|
||||
+ rootdir_path);
|
||||
+
|
||||
+ for (curdev = rootdir_devices; *curdev; curdev++)
|
||||
+ grub_util_pull_device (*curdev);
|
||||
+
|
||||
+ rootdir_grub_devname = grub_util_get_grub_dev (rootdir_devices[0]);
|
||||
+ if (!rootdir_grub_devname)
|
||||
+ grub_util_error (_("cannot find a GRUB drive for %s. Check your device.map"),
|
||||
+ rootdir_devices[0]);
|
||||
+
|
||||
+ rootdir_grub_dev = grub_device_open (rootdir_grub_devname);
|
||||
+ if (! rootdir_grub_dev)
|
||||
+ grub_util_error ("%s", grub_errmsg);
|
||||
+
|
||||
+ root_fs = grub_fs_probe (rootdir_grub_dev);
|
||||
+ if (!root_fs)
|
||||
+ grub_util_error ("%s", grub_errmsg);
|
||||
+
|
||||
+ if (config.is_suse_btrfs_snapshot_enabled
|
||||
+ && grub_strncmp(root_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0)
|
||||
+ use_relative_path_on_btrfs = 1;
|
||||
+
|
||||
+ free (t);
|
||||
+ free (rootdir_grub_devname);
|
||||
+ grub_device_close (rootdir_grub_dev);
|
||||
+ }
|
||||
+
|
||||
switch (platform)
|
||||
{
|
||||
case GRUB_INSTALL_PLATFORM_I386_EFI:
|
||||
@@ -1478,8 +1517,7 @@
|
||||
debug_image);
|
||||
}
|
||||
|
||||
- if (config.is_suse_btrfs_snapshot_enabled
|
||||
- && grub_strncmp(grub_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0)
|
||||
+ if (use_relative_path_on_btrfs)
|
||||
{
|
||||
if (!load_cfg_f)
|
||||
load_cfg_f = grub_util_fopen (load_cfg, "wb");
|
||||
@@ -1670,21 +1708,13 @@
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
- if (config.is_suse_btrfs_snapshot_enabled
|
||||
- && grub_strncmp(grub_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0)
|
||||
+ if (use_relative_path_on_btrfs)
|
||||
{
|
||||
char *subvol = NULL;
|
||||
char *mount_path = NULL;
|
||||
- char **rootdir_devices = NULL;
|
||||
- char *t = grub_util_path_concat (2, "/", rootdir);
|
||||
- char *rootdir_path = grub_canonicalize_file_name (t);
|
||||
-
|
||||
- if (rootdir_path && grub_util_is_directory (rootdir_path))
|
||||
- rootdir_devices = grub_guess_root_devices (rootdir_path);
|
||||
-
|
||||
- if (rootdir_devices && rootdir_devices[0])
|
||||
- if (grub_strcmp (rootdir_devices[0], grub_devices[0]) == 0)
|
||||
- subvol = grub_util_get_btrfs_subvol (platdir, &mount_path);
|
||||
+
|
||||
+ if (grub_strcmp (rootdir_devices[0], grub_devices[0]) == 0)
|
||||
+ subvol = grub_util_get_btrfs_subvol (platdir, &mount_path);
|
||||
|
||||
if (subvol && mount_path)
|
||||
{
|
||||
@@ -1709,11 +1739,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
- free (t);
|
||||
- free (rootdir_path);
|
||||
- for (curdev = rootdir_devices; *curdev; curdev++)
|
||||
- free (*curdev);
|
||||
- free (rootdir_devices);
|
||||
free (subvol);
|
||||
free (mount_path);
|
||||
}
|
||||
--- a/util/grub-mkconfig_lib.in
|
||||
+++ b/util/grub-mkconfig_lib.in
|
||||
@@ -49,7 +49,8 @@
|
||||
|
||||
make_system_path_relative_to_its_root ()
|
||||
{
|
||||
- if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] ; then
|
||||
+ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" = "xtrue" ] &&
|
||||
+ [ "x${GRUB_FS}" = "xbtrfs" ] ; then
|
||||
"${grub_mkrelpath}" -r "$1"
|
||||
else
|
||||
"${grub_mkrelpath}" "$1"
|
289
0001-Workaround-volatile-efi-boot-variable.patch
Normal file
289
0001-Workaround-volatile-efi-boot-variable.patch
Normal file
@ -0,0 +1,289 @@
|
||||
From 71575829c303fe8522b46fc96b1f99f1aa4178e7 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 19 Mar 2021 22:58:45 +0800
|
||||
Subject: [PATCH] Workaround volatile efi boot variable
|
||||
|
||||
The efi variable in Microsoft Azure virtual machine is volatile that it cannot
|
||||
persist across power cycling. If we use efi variable to communicate with efi
|
||||
boot manager for booting a distribution, the process would silently fail as the
|
||||
default loader in the efi system partition will start to take over the process
|
||||
whenever the efi variable evaporated.
|
||||
|
||||
That will lead to undefined symbol error one day as the default path didn't
|
||||
receive any grub update so it cannot keep up with new ABI requirement by
|
||||
updated grub modules.
|
||||
|
||||
The patch will try to workaround the problem by providing grub update to the
|
||||
default path along with the distribution specific one. To avoid negative side
|
||||
effects of inadvertently overwritting other loader intended in default path,
|
||||
care must be taken to ensure that:
|
||||
|
||||
1. The workaround only takes place on detected Azure virtual machine
|
||||
2. The default path is not in use by shim for the secure boot
|
||||
---
|
||||
Makefile.util.def | 1 +
|
||||
.../osdep/basic/efi_removable_fallback.c | 26 +++
|
||||
grub-core/osdep/efi_removable_fallback.c | 5 +
|
||||
.../osdep/linux/efi_removable_fallback.c | 151 ++++++++++++++++++
|
||||
include/grub/util/install.h | 3 +
|
||||
util/grub-install.c | 19 +++
|
||||
6 files changed, 205 insertions(+)
|
||||
create mode 100644 grub-core/osdep/basic/efi_removable_fallback.c
|
||||
create mode 100644 grub-core/osdep/efi_removable_fallback.c
|
||||
create mode 100644 grub-core/osdep/linux/efi_removable_fallback.c
|
||||
|
||||
--- a/Makefile.util.def
|
||||
+++ b/Makefile.util.def
|
||||
@@ -681,6 +681,9 @@
|
||||
common = grub-core/osdep/journaled_fs.c;
|
||||
extra_dist = grub-core/osdep/basic/journaled_fs.c;
|
||||
extra_dist = grub-core/osdep/linux/journaled_fs.c;
|
||||
+ common = grub-core/osdep/efi_removable_fallback.c;
|
||||
+ extra_dist = grub-core/osdep/basic/efi_removable_fallback.c;
|
||||
+ extra_dist = grub-core/osdep/linux/efi_removable_fallback.c;
|
||||
|
||||
ldadd = '$(LIBLZMA)';
|
||||
ldadd = libgrubmods.a;
|
||||
--- /dev/null
|
||||
+++ b/grub-core/osdep/basic/efi_removable_fallback.c
|
||||
@@ -0,0 +1,26 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/util/install.h>
|
||||
+
|
||||
+const char *
|
||||
+grub_install_efi_removable_fallback (const char *efidir, enum grub_install_plat platform)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
--- /dev/null
|
||||
+++ b/grub-core/osdep/efi_removable_fallback.c
|
||||
@@ -0,0 +1,5 @@
|
||||
+#ifdef __linux__
|
||||
+#include "linux/efi_removable_fallback.c"
|
||||
+#else
|
||||
+#include "basic/efi_removable_fallback.c"
|
||||
+#endif
|
||||
--- /dev/null
|
||||
+++ b/grub-core/osdep/linux/efi_removable_fallback.c
|
||||
@@ -0,0 +1,151 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
+ *
|
||||
+ * 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <config.h>
|
||||
+
|
||||
+#include <grub/util/install.h>
|
||||
+#include <grub/emu/exec.h>
|
||||
+#include <grub/emu/misc.h>
|
||||
+#include <string.h>
|
||||
+
|
||||
+static char *
|
||||
+get_dmi_id (const char *id)
|
||||
+{
|
||||
+ FILE *fp;
|
||||
+ char *buf = NULL;
|
||||
+ size_t len = 0;
|
||||
+
|
||||
+ char *dmi_entry;
|
||||
+
|
||||
+ dmi_entry = grub_util_path_concat (2, "/sys/class/dmi/id", id);
|
||||
+
|
||||
+ fp = grub_util_fopen (dmi_entry, "r");
|
||||
+ if (!fp)
|
||||
+ {
|
||||
+ free (dmi_entry);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (getline (&buf, &len, fp) == -1)
|
||||
+ {
|
||||
+ fclose (fp);
|
||||
+ free (dmi_entry);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ fclose (fp);
|
||||
+ free (dmi_entry);
|
||||
+ return buf;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static struct dmi {
|
||||
+ const char *id;
|
||||
+ const char *val;
|
||||
+} azure_dmi [3] = {
|
||||
+ {"bios_vendor", "Microsoft Corporation"},
|
||||
+ {"product_name", "Virtual Machine"},
|
||||
+ {"sys_vendor", "Microsoft Corporation"},
|
||||
+};
|
||||
+
|
||||
+static int
|
||||
+is_azure (void)
|
||||
+{
|
||||
+ int i;
|
||||
+ int n = sizeof (azure_dmi) / sizeof (struct dmi);
|
||||
+
|
||||
+ for (i = 0; i < n; ++i)
|
||||
+ {
|
||||
+ char *val;
|
||||
+
|
||||
+ val = get_dmi_id (azure_dmi[i].id);
|
||||
+ if (!val)
|
||||
+ break;
|
||||
+ if (strncmp (val, azure_dmi[i].val, strlen (azure_dmi[i].val)) != 0)
|
||||
+ {
|
||||
+ free (val);
|
||||
+ break;
|
||||
+ }
|
||||
+ free (val);
|
||||
+ }
|
||||
+
|
||||
+ return (i == n) ? 1 : 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+guess_shim_installed (const char *instdir)
|
||||
+{
|
||||
+ const char *shim[] = {"fallback.efi", "MokManager.efi", NULL};
|
||||
+ const char **s;
|
||||
+
|
||||
+ for (s = shim; *s ; ++s)
|
||||
+ {
|
||||
+ char *p = grub_util_path_concat (2, instdir, *s);
|
||||
+
|
||||
+ if (access (p, F_OK) == 0)
|
||||
+ {
|
||||
+ free (p);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ free (p);
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+const char *
|
||||
+grub_install_efi_removable_fallback (const char *efidir, enum grub_install_plat platform)
|
||||
+{
|
||||
+ char *instdir;
|
||||
+
|
||||
+ if (!is_azure ())
|
||||
+ return NULL;
|
||||
+
|
||||
+ instdir = grub_util_path_concat (3, efidir, "EFI", "BOOT");
|
||||
+
|
||||
+ if (guess_shim_installed (instdir))
|
||||
+ {
|
||||
+ grub_util_info ("skip removable fallback occupied by shim");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ free (instdir);
|
||||
+
|
||||
+ switch (platform)
|
||||
+ {
|
||||
+ case GRUB_INSTALL_PLATFORM_I386_EFI:
|
||||
+ return "BOOTIA32.EFI";
|
||||
+ case GRUB_INSTALL_PLATFORM_X86_64_EFI:
|
||||
+ return "BOOTX64.EFI";
|
||||
+ case GRUB_INSTALL_PLATFORM_IA64_EFI:
|
||||
+ return "BOOTIA64.EFI";
|
||||
+ case GRUB_INSTALL_PLATFORM_ARM_EFI:
|
||||
+ return "BOOTARM.EFI";
|
||||
+ case GRUB_INSTALL_PLATFORM_ARM64_EFI:
|
||||
+ return "BOOTAA64.EFI";
|
||||
+ case GRUB_INSTALL_PLATFORM_RISCV32_EFI:
|
||||
+ return "BOOTRISCV32.EFI";
|
||||
+ case GRUB_INSTALL_PLATFORM_RISCV64_EFI:
|
||||
+ return "BOOTRISCV64.EFI";
|
||||
+ default:
|
||||
+ grub_util_error ("%s", _("You've found a bug"));
|
||||
+ break;
|
||||
+ }
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -303,4 +303,7 @@
|
||||
|
||||
int
|
||||
grub_install_sync_fs_journal (const char *path);
|
||||
+
|
||||
+const char *
|
||||
+grub_install_efi_removable_fallback (const char *efidir, enum grub_install_plat platform);
|
||||
#endif
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -901,6 +901,7 @@
|
||||
const char *pkgdatadir;
|
||||
char *rootdir_path;
|
||||
char **rootdir_devices;
|
||||
+ char *efidir_root;
|
||||
|
||||
grub_util_host_init (&argc, &argv);
|
||||
product_version = xstrdup (PACKAGE_VERSION);
|
||||
@@ -1175,6 +1176,7 @@
|
||||
}
|
||||
if (!efidir)
|
||||
grub_util_error ("%s", _("cannot find EFI directory"));
|
||||
+ efidir_root = grub_strdup (efidir);
|
||||
efidir_device_names = grub_guess_root_devices (efidir);
|
||||
if (!efidir_device_names || !efidir_device_names[0])
|
||||
grub_util_error (_("cannot find a device for %s (is /dev mounted?)"),
|
||||
@@ -2217,6 +2219,23 @@
|
||||
free (grub_efi_cfg);
|
||||
}
|
||||
}
|
||||
+ if (!removable)
|
||||
+ {
|
||||
+ const char *f;
|
||||
+
|
||||
+ f = grub_install_efi_removable_fallback (efidir_root, platform);
|
||||
+ if (f)
|
||||
+ {
|
||||
+ char *t = grub_util_path_concat (3, efidir_root, "EFI", "BOOT");
|
||||
+ char *dst = grub_util_path_concat (2, t, f);
|
||||
+
|
||||
+ grub_install_mkdir_p (t);
|
||||
+ fprintf (stderr, _("Install to %s as fallback.\n"), dst);
|
||||
+ grub_install_copy_file (imgfile, dst, 1);
|
||||
+ grub_free (t);
|
||||
+ grub_free (dst);
|
||||
+ }
|
||||
+ }
|
||||
if (!removable && update_nvram)
|
||||
{
|
||||
char * efifile_path;
|
4923
0001-add-support-for-UEFI-network-protocols.patch
Normal file
4923
0001-add-support-for-UEFI-network-protocols.patch
Normal file
File diff suppressed because it is too large
Load Diff
179
0001-arm64-Fix-EFI-loader-kernel-image-allocation.patch
Normal file
179
0001-arm64-Fix-EFI-loader-kernel-image-allocation.patch
Normal file
@ -0,0 +1,179 @@
|
||||
From 10d0f70ac194931c63f2cbd6fdebd6697abae992 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
Date: Mon, 2 Aug 2021 23:10:01 +1000
|
||||
Subject: [PATCH 1/2] arm64: Fix EFI loader kernel image allocation
|
||||
|
||||
We are currently allocating just enough memory for the file size,
|
||||
which means that the kernel BSS is in limbo (and not even zeroed).
|
||||
|
||||
We are also not honoring the alignment specified in the image
|
||||
PE header.
|
||||
|
||||
This makes us use the PE optional header in which the kernel puts the
|
||||
actual size it needs, including BSS, and make sure we clear it, and
|
||||
honors the specified alignment for the image.
|
||||
|
||||
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
---
|
||||
grub-core/loader/arm64/efi/linux.c | 92 ++++++++++++++++++++----------
|
||||
1 file changed, 63 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||
index b73105347..4da49a182 100644
|
||||
--- a/grub-core/loader/arm64/efi/linux.c
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -39,6 +39,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
static grub_dl_t my_mod;
|
||||
static int loaded;
|
||||
|
||||
+static void *kernel_alloc_addr;
|
||||
+static grub_uint32_t kernel_alloc_pages;
|
||||
static void *kernel_addr;
|
||||
static grub_uint64_t kernel_size;
|
||||
static grub_uint32_t handover_offset;
|
||||
@@ -258,9 +260,8 @@ grub_linux_unload (void)
|
||||
GRUB_EFI_BYTES_TO_PAGES (initrd_end - initrd_start));
|
||||
initrd_start = initrd_end = 0;
|
||||
grub_free (linux_args);
|
||||
- if (kernel_addr)
|
||||
- grub_efi_free_pages ((grub_addr_t) kernel_addr,
|
||||
- GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||
+ if (kernel_alloc_addr)
|
||||
+ grub_efi_free_pages ((grub_addr_t) kernel_alloc_addr, kernel_alloc_pages);
|
||||
grub_fdt_unload ();
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
@@ -365,14 +366,35 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+parse_pe_header (void *kernel, grub_uint64_t *total_size,
|
||||
+ grub_uint32_t *entry_offset,
|
||||
+ grub_uint32_t *alignment)
|
||||
+{
|
||||
+ struct linux_arch_kernel_header *lh = kernel;
|
||||
+ struct grub_armxx_linux_pe_header *pe;
|
||||
+
|
||||
+ pe = (void *)((unsigned long)kernel + lh->hdr_offset);
|
||||
+
|
||||
+ if (pe->opt.magic != GRUB_PE32_PE64_MAGIC)
|
||||
+ return grub_error(GRUB_ERR_BAD_OS, "Invalid PE optional header magic");
|
||||
+
|
||||
+ *total_size = pe->opt.image_size;
|
||||
+ *entry_offset = pe->opt.entry_addr;
|
||||
+ *alignment = pe->opt.section_alignment;
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char *argv[])
|
||||
{
|
||||
grub_file_t file = 0;
|
||||
- struct linux_arch_kernel_header lh;
|
||||
- struct grub_armxx_linux_pe_header *pe;
|
||||
grub_err_t err;
|
||||
+ grub_off_t filelen;
|
||||
+ grub_uint32_t align = 0;
|
||||
+ void *kernel = NULL;
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
|
||||
@@ -386,39 +408,49 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
if (!file)
|
||||
goto fail;
|
||||
|
||||
- kernel_size = grub_file_size (file);
|
||||
+ filelen = grub_file_size (file);
|
||||
+ kernel = grub_malloc(filelen);
|
||||
+ if (!kernel)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("cannot allocate kernel load buffer"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
|
||||
- if (grub_file_read (file, &lh, sizeof (lh)) < (long) sizeof (lh))
|
||||
- return grub_errno;
|
||||
+ if (grub_file_read (file, kernel, filelen) < (grub_ssize_t)filelen)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_FILE_READ_ERROR, N_("Can't read kernel %s"),
|
||||
+ argv[0]);
|
||||
+ goto fail;
|
||||
+ }
|
||||
|
||||
- if (grub_arch_efi_linux_check_image (&lh) != GRUB_ERR_NONE)
|
||||
+ grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
|
||||
+
|
||||
+ if (grub_arch_efi_linux_check_image (kernel) != GRUB_ERR_NONE)
|
||||
+ goto fail;
|
||||
+ if (parse_pe_header (kernel, &kernel_size, &handover_offset, &align) != GRUB_ERR_NONE)
|
||||
goto fail;
|
||||
+ grub_dprintf ("linux", "kernel mem size : %lld\n", (long long) kernel_size);
|
||||
+ grub_dprintf ("linux", "kernel entry offset : %d\n", handover_offset);
|
||||
+ grub_dprintf ("linux", "kernel alignment : 0x%x\n", align);
|
||||
|
||||
grub_loader_unset();
|
||||
|
||||
- grub_dprintf ("linux", "kernel file size: %lld\n", (long long) kernel_size);
|
||||
- kernel_addr = grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||
- grub_dprintf ("linux", "kernel numpages: %lld\n",
|
||||
- (long long) GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||
- if (!kernel_addr)
|
||||
+ kernel_alloc_pages = GRUB_EFI_BYTES_TO_PAGES (kernel_size + align - 1);
|
||||
+ kernel_alloc_addr = grub_efi_allocate_any_pages (kernel_alloc_pages);
|
||||
+ grub_dprintf ("linux", "kernel numpages: %d\n", kernel_alloc_pages);
|
||||
+ if (!kernel_alloc_addr)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
goto fail;
|
||||
}
|
||||
-
|
||||
- grub_file_seek (file, 0);
|
||||
- if (grub_file_read (file, kernel_addr, kernel_size)
|
||||
- < (grub_int64_t) kernel_size)
|
||||
- {
|
||||
- if (!grub_errno)
|
||||
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"), argv[0]);
|
||||
- goto fail;
|
||||
- }
|
||||
+ kernel_addr = (void *)ALIGN_UP((grub_uint64_t)kernel_alloc_addr, align);
|
||||
|
||||
grub_dprintf ("linux", "kernel @ %p\n", kernel_addr);
|
||||
-
|
||||
- pe = (void *)((unsigned long)kernel_addr + lh.hdr_offset);
|
||||
- handover_offset = pe->opt.entry_addr;
|
||||
+ grub_memcpy (kernel_addr, kernel, grub_min(filelen, kernel_size));
|
||||
+ if (kernel_size > filelen)
|
||||
+ grub_memset ((char *)kernel_addr + filelen, 0, kernel_size - filelen);
|
||||
+ grub_free(kernel);
|
||||
+ kernel = NULL;
|
||||
|
||||
cmdline_size = grub_loader_cmdline_size (argc, argv) + sizeof (LINUX_IMAGE);
|
||||
linux_args = grub_malloc (cmdline_size);
|
||||
@@ -442,6 +474,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
}
|
||||
|
||||
fail:
|
||||
+ if (kernel)
|
||||
+ grub_free (kernel);
|
||||
+
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
|
||||
@@ -454,9 +489,8 @@ fail:
|
||||
if (linux_args && !loaded)
|
||||
grub_free (linux_args);
|
||||
|
||||
- if (kernel_addr && !loaded)
|
||||
- grub_efi_free_pages ((grub_addr_t) kernel_addr,
|
||||
- GRUB_EFI_BYTES_TO_PAGES (kernel_size));
|
||||
+ if (kernel_alloc_addr && !loaded)
|
||||
+ grub_efi_free_pages ((grub_addr_t) kernel_alloc_addr, kernel_alloc_pages);
|
||||
|
||||
return grub_errno;
|
||||
}
|
||||
--
|
||||
2.31.1
|
||||
|
1613
0001-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch
Normal file
1613
0001-blscfg-add-blscfg-module-to-parse-Boot-Loader-Specif.patch
Normal file
File diff suppressed because it is too large
Load Diff
205
0001-clean-up-crypttab-and-linux-modules-dependency.patch
Normal file
205
0001-clean-up-crypttab-and-linux-modules-dependency.patch
Normal file
@ -0,0 +1,205 @@
|
||||
From e9422d6869f1b2d78a7cfbfcae1610953d87705b Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 16 Feb 2023 21:28:07 +0800
|
||||
Subject: [PATCH 1/2] clean up crypttab and linux modules dependency
|
||||
|
||||
The linux module could have quite a few dependency to other modules, the
|
||||
i386-pc build in particular has many.
|
||||
|
||||
linux: normal vbe video boot cmdline relocator mmap
|
||||
|
||||
That will be easy to cause loop dependency if one of these modules has
|
||||
to require function from linux. To avoid falling into the pitfall in
|
||||
future extension, we move away the key publish related function from
|
||||
linux to crypttab module in that it is also a right thing to do.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 48 +++++++++++++++++++++++++++++-
|
||||
grub-core/disk/cryptodisk.c | 2 +-
|
||||
grub-core/loader/linux.c | 55 +----------------------------------
|
||||
include/grub/crypttab.h | 22 ++++++++++++++
|
||||
include/grub/linux.h | 3 --
|
||||
5 files changed, 71 insertions(+), 59 deletions(-)
|
||||
create mode 100644 include/grub/crypttab.h
|
||||
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -3,10 +3,56 @@
|
||||
#include <grub/command.h>
|
||||
#include <grub/misc.h>
|
||||
#include <grub/i18n.h>
|
||||
-#include <grub/linux.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/list.h>
|
||||
+#include <grub/crypttab.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
+struct grub_key_publisher *kpuber;
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path)
|
||||
+{
|
||||
+ struct grub_key_publisher *cur = NULL;
|
||||
+
|
||||
+ FOR_LIST_ELEMENTS (cur, kpuber)
|
||||
+ if (grub_uuidcasecmp (cur->name, uuid, sizeof (cur->name)) == 0)
|
||||
+ break;
|
||||
+
|
||||
+ if (!cur)
|
||||
+ cur = grub_zalloc (sizeof (*cur));
|
||||
+ if (!cur)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ if (key && key_len)
|
||||
+ {
|
||||
+ grub_free (cur->key);
|
||||
+ cur->key = grub_malloc (key_len);
|
||||
+ if (!cur->key)
|
||||
+ {
|
||||
+ grub_free (cur);
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+ grub_memcpy (cur->key, key, key_len);
|
||||
+ cur->key_len = key_len;
|
||||
+ }
|
||||
+
|
||||
+ if (path)
|
||||
+ {
|
||||
+ grub_free (cur->path);
|
||||
+ cur->path = grub_strdup (path);
|
||||
+ }
|
||||
+
|
||||
+ if (!cur->name)
|
||||
+ {
|
||||
+ cur->name = grub_strdup (uuid);
|
||||
+ grub_list_push (GRUB_AS_LIST_P (&kpuber), GRUB_AS_LIST (cur));
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **argv)
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -31,7 +31,7 @@
|
||||
#ifdef GRUB_UTIL
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#else
|
||||
-#include <grub/linux.h>
|
||||
+#include <grub/crypttab.h>
|
||||
#endif
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
--- a/grub-core/loader/linux.c
|
||||
+++ b/grub-core/loader/linux.c
|
||||
@@ -6,6 +6,7 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/safemath.h>
|
||||
#include <grub/list.h>
|
||||
+#include <grub/crypttab.h>
|
||||
|
||||
struct newc_head
|
||||
{
|
||||
@@ -40,18 +41,6 @@
|
||||
struct dir *child;
|
||||
};
|
||||
|
||||
-struct grub_key_publisher
|
||||
-{
|
||||
- struct grub_key_publisher *next;
|
||||
- struct grub_key_publisher **prev;
|
||||
- char *name; /* UUID */
|
||||
- char *path;
|
||||
- char *key;
|
||||
- grub_size_t key_len;
|
||||
-};
|
||||
-
|
||||
-static struct grub_key_publisher *kpuber;
|
||||
-
|
||||
static char
|
||||
hex (grub_uint8_t val)
|
||||
{
|
||||
@@ -436,45 +425,3 @@
|
||||
root = 0;
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
-
|
||||
-grub_err_t
|
||||
-grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path)
|
||||
-{
|
||||
- struct grub_key_publisher *cur = NULL;
|
||||
-
|
||||
- FOR_LIST_ELEMENTS (cur, kpuber)
|
||||
- if (grub_uuidcasecmp (cur->name, uuid, sizeof (cur->name)) == 0)
|
||||
- break;
|
||||
-
|
||||
- if (!cur)
|
||||
- cur = grub_zalloc (sizeof (*cur));
|
||||
- if (!cur)
|
||||
- return grub_errno;
|
||||
-
|
||||
- if (key && key_len)
|
||||
- {
|
||||
- grub_free (cur->key);
|
||||
- cur->key = grub_malloc (key_len);
|
||||
- if (!cur->key)
|
||||
- {
|
||||
- grub_free (cur);
|
||||
- return grub_errno;
|
||||
- }
|
||||
- grub_memcpy (cur->key, key, key_len);
|
||||
- cur->key_len = key_len;
|
||||
- }
|
||||
-
|
||||
- if (path)
|
||||
- {
|
||||
- grub_free (cur->path);
|
||||
- cur->path = grub_strdup (path);
|
||||
- }
|
||||
-
|
||||
- if (!cur->name)
|
||||
- {
|
||||
- cur->name = grub_strdup (uuid);
|
||||
- grub_list_push (GRUB_AS_LIST_P (&kpuber), GRUB_AS_LIST (cur));
|
||||
- }
|
||||
-
|
||||
- return GRUB_ERR_NONE;
|
||||
-}
|
||||
--- /dev/null
|
||||
+++ b/include/grub/crypttab.h
|
||||
@@ -0,0 +1,22 @@
|
||||
+#ifndef GRUB_CRYPTTAB_HEADER
|
||||
+#define GRUB_CRYPTTAB_HEADER 1
|
||||
+
|
||||
+#include <grub/types.h>
|
||||
+#include <grub/err.h>
|
||||
+
|
||||
+struct grub_key_publisher
|
||||
+{
|
||||
+ struct grub_key_publisher *next;
|
||||
+ struct grub_key_publisher **prev;
|
||||
+ char *name; /* UUID */
|
||||
+ char *path;
|
||||
+ char *key;
|
||||
+ grub_size_t key_len;
|
||||
+};
|
||||
+
|
||||
+extern struct grub_key_publisher *EXPORT_VAR (kpuber);
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path);
|
||||
+
|
||||
+#endif /* ! GRUB_CRYPTTAB_HEADER */
|
||||
--- a/include/grub/linux.h
|
||||
+++ b/include/grub/linux.h
|
||||
@@ -22,6 +22,3 @@
|
||||
grub_err_t
|
||||
grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
|
||||
void *target);
|
||||
-
|
||||
-grub_err_t
|
||||
-grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path);
|
@ -0,0 +1,37 @@
|
||||
From 5846e14a4dbf0c73969a32625d841e4f842ccdea Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 31 Jan 2024 18:44:27 +0800
|
||||
Subject: [PATCH] disk: Optimize disk iteration by moving memdisk to the end
|
||||
|
||||
When performing file or UUID-based searches, prioritize returning
|
||||
operating system disk devices over the memdisk. The memdisk, typically
|
||||
used for internal grub data, is moved to the last position in the search
|
||||
order. This improves search efficiency and prevents potential unexpected
|
||||
results.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
include/grub/disk.h | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/include/grub/disk.h b/include/grub/disk.h
|
||||
index bf0958885..f4fd7a00f 100644
|
||||
--- a/include/grub/disk.h
|
||||
+++ b/include/grub/disk.h
|
||||
@@ -244,7 +244,12 @@ grub_disk_dev_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data)
|
||||
|
||||
for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++)
|
||||
for (p = grub_disk_dev_list; p; p = p->next)
|
||||
- if (p->disk_iterate && (p->disk_iterate) (hook, hook_data, pull))
|
||||
+ if (p->id != GRUB_DISK_DEVICE_MEMDISK_ID && p->disk_iterate && (p->disk_iterate) (hook, hook_data, pull))
|
||||
+ return 1;
|
||||
+
|
||||
+ for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++)
|
||||
+ for (p = grub_disk_dev_list; p; p = p->next)
|
||||
+ if (p->id == GRUB_DISK_DEVICE_MEMDISK_ID && p->disk_iterate && (p->disk_iterate) (hook, hook_data, pull))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
--
|
||||
2.43.0
|
||||
|
103
0001-efi-linux-provide-linux-command.patch
Normal file
103
0001-efi-linux-provide-linux-command.patch
Normal file
@ -0,0 +1,103 @@
|
||||
From 987ab0dfbe7ef42bb6386fb7b428d3b965ba6d2b Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 7 Sep 2020 17:02:57 +0800
|
||||
Subject: [PATCH] efi/linux: provide linux command
|
||||
|
||||
The linux kernel's efi handover entry point is used to boot efistub of
|
||||
the linux kernel. Since then the efistub has been improved with many new
|
||||
features and fixes that ordinary 32-bit entry point cannot provide.
|
||||
|
||||
Besides, nearly every x86 efi kernel is built with efistub enabled so it
|
||||
is of little value to keep 32-bit entry as default to boot kernel
|
||||
without needed kconfig options enabled.
|
||||
|
||||
For all good reasons, making efi handover the default entry point for
|
||||
booting kernel in x86 efi platform so that linux command works in the
|
||||
same way to linuxefi. This can also reduce the complexity of providing
|
||||
general grub configuation for x86 system due to the linux command may
|
||||
not be available in signed image for UEFI Secure Boot and linuxefi is
|
||||
not available for leagcy bios booting.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 6 ++++--
|
||||
grub-core/gensyminfo.sh.in | 3 +++
|
||||
grub-core/loader/i386/efi/linux.c | 17 +++++++++++++----
|
||||
3 files changed, 20 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1840,7 +1840,9 @@
|
||||
|
||||
module = {
|
||||
name = linux;
|
||||
- x86 = loader/i386/linux.c;
|
||||
+ i386_pc = loader/i386/linux.c;
|
||||
+ i386_efi = loader/i386/efi/linux.c;
|
||||
+ x86_64_efi = loader/i386/efi/linux.c;
|
||||
i386_xen_pvh = loader/i386/linux.c;
|
||||
xen = loader/i386/xen.c;
|
||||
i386_pc = lib/i386/pc/vesa_modes_table.c;
|
||||
@@ -1856,8 +1858,6 @@
|
||||
loongarch64 = loader/efi/linux.c;
|
||||
riscv32 = loader/efi/linux.c;
|
||||
riscv64 = loader/efi/linux.c;
|
||||
- i386_efi = loader/efi/linux.c;
|
||||
- x86_64_efi = loader/efi/linux.c;
|
||||
emu = loader/emu/linux.c;
|
||||
common = loader/linux.c;
|
||||
};
|
||||
@@ -1922,7 +1922,7 @@
|
||||
|
||||
module = {
|
||||
name = linuxefi;
|
||||
- efi = loader/i386/efi/linux.c;
|
||||
+ efi = lib/fake_module.c;
|
||||
enable = i386_efi;
|
||||
enable = x86_64_efi;
|
||||
};
|
||||
--- a/grub-core/gensyminfo.sh.in
|
||||
+++ b/grub-core/gensyminfo.sh.in
|
||||
@@ -35,3 +35,6 @@
|
||||
|
||||
# Print all undefined symbols used by module
|
||||
@TARGET_NM@ -u @TARGET_NMFLAGS_MINUS_P@ -p $module | sed "s@^\([^ ]*\).*@undefined $modname \1@g"
|
||||
+
|
||||
+# Specify linuxefi module should load default linux
|
||||
+test "$modname" = "linuxefi" && echo "undefined $modname grub_initrd_init" || true
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -333,20 +333,29 @@
|
||||
}
|
||||
|
||||
static grub_command_t cmd_linux, cmd_initrd;
|
||||
+static grub_command_t cmd_linuxefi, cmd_initrdefi;
|
||||
|
||||
-GRUB_MOD_INIT(linuxefi)
|
||||
+GRUB_MOD_INIT(linux)
|
||||
{
|
||||
- cmd_linux =
|
||||
+ cmd_linuxefi =
|
||||
grub_register_command ("linuxefi", grub_cmd_linux,
|
||||
0, N_("Load Linux."));
|
||||
- cmd_initrd =
|
||||
+ cmd_initrdefi =
|
||||
grub_register_command ("initrdefi", grub_cmd_initrd,
|
||||
0, N_("Load initrd."));
|
||||
+ cmd_linux =
|
||||
+ grub_register_command ("linux", grub_cmd_linux,
|
||||
+ 0, N_("Load Linux."));
|
||||
+ cmd_initrd =
|
||||
+ grub_register_command ("initrd", grub_cmd_initrd,
|
||||
+ 0, N_("Load initrd."));
|
||||
my_mod = mod;
|
||||
}
|
||||
|
||||
-GRUB_MOD_FINI(linuxefi)
|
||||
+GRUB_MOD_FINI(linux)
|
||||
{
|
||||
+ grub_unregister_command (cmd_linuxefi);
|
||||
+ grub_unregister_command (cmd_initrdefi);
|
||||
grub_unregister_command (cmd_linux);
|
||||
grub_unregister_command (cmd_initrd);
|
||||
}
|
39
0001-font-Try-memdisk-fonts-with-the-same-name.patch
Normal file
39
0001-font-Try-memdisk-fonts-with-the-same-name.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From d02304f70b5b9c79761d8084ab9dfc66d84688e2 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 30 Nov 2022 17:02:50 +0800
|
||||
Subject: [PATCH] font: Try memdisk fonts with the same name
|
||||
|
||||
---
|
||||
grub-core/font/font.c | 16 +++++++++++++++-
|
||||
1 file changed, 15 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
|
||||
index 18de52562..92ff415bf 100644
|
||||
--- a/grub-core/font/font.c
|
||||
+++ b/grub-core/font/font.c
|
||||
@@ -451,7 +451,21 @@ grub_font_load (const char *filename)
|
||||
#endif
|
||||
|
||||
if (filename[0] == '(' || filename[0] == '/' || filename[0] == '+')
|
||||
- file = grub_buffile_open (filename, GRUB_FILE_TYPE_FONT, 1024);
|
||||
+ {
|
||||
+ char *n = grub_strdup (filename);
|
||||
+ char *p = grub_strrchr (n, '/');
|
||||
+ if (p)
|
||||
+ {
|
||||
+ char *q = grub_strrchr (p, '.');
|
||||
+ if (q)
|
||||
+ *q = 0;
|
||||
+ p++;
|
||||
+ file = try_open_from_prefix ("(memdisk)", p);
|
||||
+ }
|
||||
+ grub_free (n);
|
||||
+ if (!file)
|
||||
+ file = grub_buffile_open (filename, GRUB_FILE_TYPE_FONT, 1024);
|
||||
+ }
|
||||
else
|
||||
{
|
||||
file = try_open_from_prefix ("(memdisk)", filename);
|
||||
--
|
||||
2.41.0
|
||||
|
@ -0,0 +1,48 @@
|
||||
From 045aae8fe7238aabc217700df4d17d83b7d891f3 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 23 Jan 2024 12:46:16 +0800
|
||||
Subject: [PATCH] fs/xfs: always verify the total number of entries is not zero
|
||||
|
||||
---
|
||||
grub-core/fs/xfs.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index bc2224dbb..1ce5fa4fc 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -900,6 +900,8 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
{
|
||||
struct grub_xfs_dir2_entry *direntry =
|
||||
grub_xfs_first_de(dir->data, dirblock);
|
||||
+ struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock);
|
||||
+
|
||||
int entries = -1;
|
||||
char *end = dirblock + dirblk_size;
|
||||
|
||||
@@ -918,18 +920,16 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
*/
|
||||
if (dir->inode.nextents == grub_cpu_to_be32_compile_time (1))
|
||||
{
|
||||
- struct grub_xfs_dirblock_tail *tail = grub_xfs_dir_tail (dir->data, dirblock);
|
||||
-
|
||||
end = (char *) tail;
|
||||
|
||||
/* Subtract the space used by leaf nodes. */
|
||||
end -= grub_be_to_cpu32 (tail->leaf_count) * sizeof (struct grub_xfs_dir_leaf_entry);
|
||||
+ }
|
||||
|
||||
- entries = grub_be_to_cpu32 (tail->leaf_count) - grub_be_to_cpu32 (tail->leaf_stale);
|
||||
+ entries = grub_be_to_cpu32 (tail->leaf_count) - grub_be_to_cpu32 (tail->leaf_stale);
|
||||
|
||||
- if (!entries)
|
||||
- continue;
|
||||
- }
|
||||
+ if (!entries)
|
||||
+ continue;
|
||||
|
||||
/* Iterate over all entries within this block. */
|
||||
while ((char *) direntry < (char *) end)
|
||||
--
|
||||
2.43.0
|
||||
|
101
0001-grub-install-Add-SUSE-signed-image-support-for-power.patch
Normal file
101
0001-grub-install-Add-SUSE-signed-image-support-for-power.patch
Normal file
@ -0,0 +1,101 @@
|
||||
From 83a6f72e1896bd012b7fbca21317e96c2c22b327 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Suchanek <msuchanek@suse.de>
|
||||
Date: Wed, 12 Jan 2022 19:25:54 +0100
|
||||
Subject: [PATCH] grub-install: Add SUSE signed image support for powerpc.
|
||||
|
||||
Signed-off-by: Michal Suchanek <msuchanek@suse.de>
|
||||
---
|
||||
grub-core/osdep/linux/platform.c | 13 +++++++++++++
|
||||
include/grub/util/install.h | 3 +++
|
||||
util/grub-install.c | 29 ++++++++++++++++++++++++++---
|
||||
3 files changed, 42 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/grub-core/osdep/linux/platform.c
|
||||
+++ b/grub-core/osdep/linux/platform.c
|
||||
@@ -154,3 +154,16 @@
|
||||
grub_util_info ("... not found");
|
||||
return "i386-pc";
|
||||
}
|
||||
+
|
||||
+int
|
||||
+grub_install_get_powerpc_secure_boot (void)
|
||||
+{
|
||||
+ int32_t ret = -1;
|
||||
+ FILE *fp = grub_util_fopen ("/proc/device-tree/ibm,secure-boot", "rb");
|
||||
+ if (fp) {
|
||||
+ if (fread (&ret , 1, sizeof(ret), fp) > 0)
|
||||
+ ret = grub_be_to_cpu32(ret);
|
||||
+ fclose(fp);
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -233,6 +233,9 @@
|
||||
grub_install_get_default_x86_platform (void);
|
||||
|
||||
int
|
||||
+grub_install_get_powerpc_secure_boot (void);
|
||||
+
|
||||
+int
|
||||
grub_install_register_efi (grub_device_t efidir_grub_dev,
|
||||
const char *efifile_path,
|
||||
const char *efi_distributor);
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -321,10 +321,10 @@
|
||||
{"suse-enable-tpm", OPTION_SUSE_ENABLE_TPM, 0, 0, N_("install TPM modules"), 0},
|
||||
{"suse-force-signed", OPTION_SUSE_FORCE_SIGNED, 0, 0,
|
||||
N_("force installation of signed grub" "%s."
|
||||
- "This option is only available on ARM64 EFI targets."), 0},
|
||||
+ "This option is only available on ARM64 EFI and powerpc targets."), 0},
|
||||
{"suse-inhibit-signed", OPTION_SUSE_INHIBIT_SIGNED, 0, 0,
|
||||
N_("inhibit installation of signed grub. "
|
||||
- "This option is only available on ARM64 EFI targets."), 0},
|
||||
+ "This option is only available on ARM64 EFI and powerpc targets."), 0},
|
||||
{"debug", OPTION_DEBUG, 0, OPTION_HIDDEN, 0, 2},
|
||||
{"no-floppy", OPTION_NO_FLOPPY, 0, OPTION_HIDDEN, 0, 2},
|
||||
{"debug-image", OPTION_DEBUG_IMAGE, N_("STRING"), OPTION_HIDDEN, 0, 2},
|
||||
@@ -1749,6 +1749,7 @@
|
||||
char mkimage_target[200];
|
||||
const char *core_name = NULL;
|
||||
char *signed_imgfile = NULL;
|
||||
+ int ppc_sb_state = -1;
|
||||
|
||||
switch (platform)
|
||||
{
|
||||
@@ -1796,11 +1797,33 @@
|
||||
grub_install_get_platform_platform (platform));
|
||||
break;
|
||||
|
||||
+
|
||||
+ case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
|
||||
+ ppc_sb_state = grub_install_get_powerpc_secure_boot();
|
||||
+
|
||||
+ if ((signed_grub_mode >= SIGNED_GRUB_FORCE) || ((signed_grub_mode == SIGNED_GRUB_AUTO) && (ppc_sb_state > 0)))
|
||||
+ {
|
||||
+ signed_imgfile = grub_util_path_concat (2, grub_install_source_directory, "grub.elf");
|
||||
+ if (!grub_util_is_regular (signed_imgfile))
|
||||
+ {
|
||||
+ if ((signed_grub_mode >= SIGNED_GRUB_FORCE) || (ppc_sb_state > 1))
|
||||
+ grub_util_error ("signed image `%s' does not exist\n", signed_imgfile);
|
||||
+ else
|
||||
+ {
|
||||
+ free (signed_imgfile);
|
||||
+ signed_imgfile = NULL;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (signed_imgfile)
|
||||
+ fprintf (stderr, _("Use signed file in %s for installation.\n"), signed_imgfile);
|
||||
+
|
||||
+ /* fallthrough. */
|
||||
case GRUB_INSTALL_PLATFORM_I386_COREBOOT:
|
||||
case GRUB_INSTALL_PLATFORM_ARM_COREBOOT:
|
||||
case GRUB_INSTALL_PLATFORM_I386_MULTIBOOT:
|
||||
case GRUB_INSTALL_PLATFORM_I386_IEEE1275:
|
||||
- case GRUB_INSTALL_PLATFORM_POWERPC_IEEE1275:
|
||||
case GRUB_INSTALL_PLATFORM_I386_XEN:
|
||||
case GRUB_INSTALL_PLATFORM_X86_64_XEN:
|
||||
case GRUB_INSTALL_PLATFORM_I386_XEN_PVH:
|
298
0001-grub-install-bailout-root-device-probing.patch
Normal file
298
0001-grub-install-bailout-root-device-probing.patch
Normal file
@ -0,0 +1,298 @@
|
||||
From db67bd0800c69f94fa3696351e7387515464d30c Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 10 Feb 2022 22:16:58 +0800
|
||||
Subject: [PATCH] grub-install: bailout root device probing
|
||||
|
||||
The root device is probed to test if the filesystem is btrfs in order to setup
|
||||
boot configs for snapshot booting. However when the root device is a lvm thin
|
||||
volume, due to lack in grub support, the probing will be errored out and entire
|
||||
installation process aborts.
|
||||
|
||||
Here we call out stat to bailout the situation whenever grub fails to probe
|
||||
filesystem in it's own right.
|
||||
|
||||
stat -f -c %T /
|
||||
|
||||
The command is also used by grub-mkconfig for the same purpose.
|
||||
|
||||
v2:
|
||||
|
||||
Test the root device first before probing to avoid encountering
|
||||
unexpected errors. If this test fails, the device is considered
|
||||
irrelevant and of no interest, as it is not useful.
|
||||
|
||||
v2.1:
|
||||
Besides verifying that the target's canonical path can be resolved,
|
||||
ensure that the target is a block device file.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/osdep/basic/no_platform.c | 5 +++
|
||||
grub-core/osdep/unix/getroot.c | 67 +++++++++++++++++++++++++++++
|
||||
grub-core/osdep/unix/platform.c | 34 +++++++++++++++
|
||||
grub-core/osdep/windows/platform.c | 6 +++
|
||||
include/grub/emu/getroot.h | 3 ++
|
||||
include/grub/util/install.h | 3 ++
|
||||
util/grub-install.c | 45 +++++++++++++++----
|
||||
7 files changed, 154 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/basic/no_platform.c b/grub-core/osdep/basic/no_platform.c
|
||||
index a173dafe9..dfbdd58e4 100644
|
||||
--- a/grub-core/osdep/basic/no_platform.c
|
||||
+++ b/grub-core/osdep/basic/no_platform.c
|
||||
@@ -51,3 +51,8 @@ grub_install_zipl (const char *d, int i, int f)
|
||||
grub_util_error ("%s", _("no zIPL routines are available for your platform"));
|
||||
}
|
||||
|
||||
+char *
|
||||
+grub_install_get_filesystem (const char *path)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
diff --git a/grub-core/osdep/unix/getroot.c b/grub-core/osdep/unix/getroot.c
|
||||
index c7aa202ab..f4658b27c 100644
|
||||
--- a/grub-core/osdep/unix/getroot.c
|
||||
+++ b/grub-core/osdep/unix/getroot.c
|
||||
@@ -489,6 +489,73 @@ grub_find_device (const char *dir, dev_t dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef __linux__
|
||||
+int
|
||||
+grub_can_guess_from_mountinfo (const char *dir_in)
|
||||
+{
|
||||
+ char **cur;
|
||||
+ char **os_dev = NULL;
|
||||
+ char *dir = grub_canonicalize_file_name (dir_in);
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if (!dir)
|
||||
+ return 0;
|
||||
+
|
||||
+ os_dev = grub_find_root_devices_from_mountinfo (dir, NULL);
|
||||
+
|
||||
+ if (!os_dev)
|
||||
+ os_dev = find_root_devices_from_libzfs (dir);
|
||||
+
|
||||
+ if (!os_dev)
|
||||
+ {
|
||||
+ free (dir);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ for (cur = os_dev; *cur; cur++)
|
||||
+ {
|
||||
+ if (strcmp (*cur, "/dev/root") == 0
|
||||
+ || strncmp (*cur, "/dev/dm-", sizeof ("/dev/dm-") - 1) == 0)
|
||||
+ /* Assume known and good names */
|
||||
+ continue;
|
||||
+ else
|
||||
+ {
|
||||
+ struct stat st;
|
||||
+
|
||||
+ char *tmp = grub_canonicalize_file_name (*cur);
|
||||
+ if (tmp == NULL)
|
||||
+ break;
|
||||
+
|
||||
+ if (strncmp (tmp, "/dev/dm-", sizeof ("/dev/dm-") - 1) == 0)
|
||||
+ continue;
|
||||
+
|
||||
+ if (lstat (tmp, &st) < 0)
|
||||
+ {
|
||||
+ free (tmp);
|
||||
+ break;
|
||||
+ }
|
||||
+ free (tmp);
|
||||
+ if (! S_ISBLK (st.st_mode))
|
||||
+ /* only block device allowed */
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (*cur == NULL)
|
||||
+ /* no bogus device left, good */
|
||||
+ ret = 1;
|
||||
+ else
|
||||
+ grub_util_info ("`%s' is not os device", *cur);
|
||||
+
|
||||
+ for (cur = os_dev; *cur; cur++)
|
||||
+ free (*cur);
|
||||
+ free (os_dev);
|
||||
+ free (dir);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+#endif /* __linux__ */
|
||||
+
|
||||
char **
|
||||
grub_guess_root_devices (const char *dir_in)
|
||||
{
|
||||
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
|
||||
index 90ac93725..01a1114cd 100644
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -250,3 +250,37 @@ grub_install_zipl (const char *dest, int install, int force)
|
||||
"-z", dest, NULL }))
|
||||
grub_util_error (_("`%s' failed.\n"), PACKAGE"-zipl-setup");
|
||||
}
|
||||
+
|
||||
+char *
|
||||
+grub_install_get_filesystem (const char *path)
|
||||
+{
|
||||
+ int fd;
|
||||
+ pid_t pid;
|
||||
+ FILE *fp;
|
||||
+ ssize_t len;
|
||||
+ char *buf = NULL;
|
||||
+ size_t bufsz = 0;
|
||||
+
|
||||
+ pid = grub_util_exec_pipe ((const char * []){ "stat", "-f", "-c", "%T", path, NULL }, &fd);
|
||||
+ if (!pid)
|
||||
+ return NULL;
|
||||
+
|
||||
+ fp = fdopen (fd, "r");
|
||||
+ if (!fp)
|
||||
+ return NULL;
|
||||
+
|
||||
+ len = getline (&buf, &bufsz, fp);
|
||||
+ if (len == -1)
|
||||
+ {
|
||||
+ free (buf);
|
||||
+ fclose (fp);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ fclose (fp);
|
||||
+
|
||||
+ if (len > 0 && buf[len - 1] == '\n')
|
||||
+ buf[len - 1] = '\0';
|
||||
+
|
||||
+ return buf;
|
||||
+}
|
||||
diff --git a/grub-core/osdep/windows/platform.c b/grub-core/osdep/windows/platform.c
|
||||
index d352d5abd..0ecc0afa7 100644
|
||||
--- a/grub-core/osdep/windows/platform.c
|
||||
+++ b/grub-core/osdep/windows/platform.c
|
||||
@@ -440,3 +440,9 @@ grub_install_zipl (const char *d, int i, int f)
|
||||
{
|
||||
grub_util_error ("%s", _("no zIPL routines are available for your platform"));
|
||||
}
|
||||
+
|
||||
+char *
|
||||
+grub_install_get_filesystem (const char *path)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
diff --git a/include/grub/emu/getroot.h b/include/grub/emu/getroot.h
|
||||
index 9c642ae3f..d7e9928bf 100644
|
||||
--- a/include/grub/emu/getroot.h
|
||||
+++ b/include/grub/emu/getroot.h
|
||||
@@ -35,6 +35,9 @@ enum grub_dev_abstraction_types {
|
||||
|
||||
char *grub_find_device (const char *dir, dev_t dev);
|
||||
void grub_util_pull_device (const char *osname);
|
||||
+#ifdef __linux__
|
||||
+int grub_can_guess_from_mountinfo (const char *dir);
|
||||
+#endif
|
||||
char **grub_guess_root_devices (const char *dir);
|
||||
int grub_util_get_dev_abstraction (const char *os_dev);
|
||||
char *grub_make_system_path_relative_to_its_root (const char *path);
|
||||
diff --git a/include/grub/util/install.h b/include/grub/util/install.h
|
||||
index 65f3a9c52..7d83e1c0b 100644
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -251,6 +251,9 @@ grub_install_sgi_setup (const char *install_device,
|
||||
void
|
||||
grub_install_zipl (const char *d, int i, int f);
|
||||
|
||||
+char *
|
||||
+grub_install_get_filesystem (const char *path);
|
||||
+
|
||||
int
|
||||
grub_install_compress_gzip (const char *src, const char *dest);
|
||||
int
|
||||
diff --git a/util/grub-install.c b/util/grub-install.c
|
||||
index 5c178ade1..c12772b05 100644
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -922,7 +922,6 @@ main (int argc, char *argv[])
|
||||
const char *efi_file = NULL;
|
||||
char **grub_devices;
|
||||
grub_fs_t grub_fs;
|
||||
- grub_fs_t root_fs;
|
||||
grub_device_t grub_dev = NULL;
|
||||
enum grub_install_plat platform;
|
||||
char *grubdir, *device_map;
|
||||
@@ -1102,10 +1101,22 @@ main (int argc, char *argv[])
|
||||
grub_host_init ();
|
||||
|
||||
{
|
||||
- char *rootdir_grub_devname;
|
||||
- grub_device_t rootdir_grub_dev;
|
||||
+ grub_device_t rootdir_grub_dev = NULL;
|
||||
+ char *rootdir_grub_devname = NULL;
|
||||
+ char *root_fs_name = NULL;
|
||||
+
|
||||
char *t = grub_util_path_concat (2, "/", rootdir);
|
||||
|
||||
+#ifdef __linux__
|
||||
+ if (!grub_can_guess_from_mountinfo (t))
|
||||
+ {
|
||||
+ free(t);
|
||||
+ /* We can safely ignore the root probe here; whichever cannot be
|
||||
+ * reliably detected is irrelevant and of no interest */
|
||||
+ goto skip_root_probe;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
rootdir_path = grub_canonicalize_file_name (t);
|
||||
if (!rootdir_path)
|
||||
grub_util_error (_("failed to get canonical path of `%s'"), t);
|
||||
@@ -1124,22 +1135,38 @@ main (int argc, char *argv[])
|
||||
rootdir_devices[0]);
|
||||
|
||||
rootdir_grub_dev = grub_device_open (rootdir_grub_devname);
|
||||
- if (! rootdir_grub_dev)
|
||||
- grub_util_error ("%s", grub_errmsg);
|
||||
+ if (!rootdir_grub_dev)
|
||||
+ {
|
||||
+ root_fs_name = grub_install_get_filesystem (t);
|
||||
+ if (root_fs_name)
|
||||
+ grub_errno = 0;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ grub_fs_t root_fs = grub_fs_probe (rootdir_grub_dev);
|
||||
+ if (root_fs)
|
||||
+ root_fs_name = grub_strdup (root_fs->name);
|
||||
+ }
|
||||
|
||||
- root_fs = grub_fs_probe (rootdir_grub_dev);
|
||||
- if (!root_fs)
|
||||
+ if (!root_fs_name)
|
||||
grub_util_error ("%s", grub_errmsg);
|
||||
|
||||
if (config.is_suse_btrfs_snapshot_enabled
|
||||
- && grub_strncmp(root_fs->name, "btrfs", sizeof ("btrfs") - 1) == 0)
|
||||
+ && root_fs_name
|
||||
+ && grub_strncmp(root_fs_name, "btrfs", sizeof ("btrfs") - 1) == 0)
|
||||
use_relative_path_on_btrfs = 1;
|
||||
|
||||
+ free (root_fs_name);
|
||||
free (t);
|
||||
free (rootdir_grub_devname);
|
||||
- grub_device_close (rootdir_grub_dev);
|
||||
+ if (rootdir_grub_dev)
|
||||
+ grub_device_close (rootdir_grub_dev);
|
||||
}
|
||||
|
||||
+#ifdef __linux__
|
||||
+ skip_root_probe:
|
||||
+#endif
|
||||
+
|
||||
switch (platform)
|
||||
{
|
||||
case GRUB_INSTALL_PLATFORM_I386_EFI:
|
||||
--
|
||||
2.45.2
|
||||
|
110
0001-grub-probe-Deduplicate-probed-partmap-output.patch
Normal file
110
0001-grub-probe-Deduplicate-probed-partmap-output.patch
Normal file
@ -0,0 +1,110 @@
|
||||
From ed0ac581ad3866197fc05c7cf48e39419a51f606 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 18 Mar 2022 13:19:33 +0800
|
||||
Subject: [PATCH] grub-probe: Deduplicate probed partmap output
|
||||
|
||||
If the target device being probed is staked on top of other physical or logical
|
||||
devices, all containing device's partition map type will be printed once if
|
||||
--target=partmap is used. This usually results in duplicated output as same
|
||||
partition map type.
|
||||
|
||||
This in turn may clutter grub.cfg with many duplicated insmod part_[a-z]+ if
|
||||
the /boot is RAIDed because --target=partmap output is used to producing
|
||||
partmap modules required to access disk device.
|
||||
|
||||
Let's deduplicate that to make the grub.cfg looks better and disciplined.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub-probe.c | 59 +++++++++++++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 55 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/util/grub-probe.c b/util/grub-probe.c
|
||||
index c08e46bbb..fb94f28fd 100644
|
||||
--- a/util/grub-probe.c
|
||||
+++ b/util/grub-probe.c
|
||||
@@ -153,6 +153,50 @@ do_print (const char *x, void *data)
|
||||
grub_printf ("%s%c", x, delim);
|
||||
}
|
||||
|
||||
+static int
|
||||
+check_duplicate_partmap (const char *name)
|
||||
+{
|
||||
+ static int alloc, used;
|
||||
+ static char **partmaps;
|
||||
+ int i;
|
||||
+
|
||||
+ if (!name)
|
||||
+ {
|
||||
+ if (partmaps)
|
||||
+ {
|
||||
+ for (i= 0; i < used; ++i)
|
||||
+ free (partmaps[i]);
|
||||
+ free (partmaps);
|
||||
+ partmaps = NULL;
|
||||
+ alloc = 0;
|
||||
+ used = 0;
|
||||
+ }
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
+ for (i= 0; i < used; ++i)
|
||||
+ if (strcmp (partmaps[i], name) == 0)
|
||||
+ return 1;
|
||||
+
|
||||
+ if (alloc <= used)
|
||||
+ {
|
||||
+ alloc = (alloc) ? (alloc << 1) : 4;
|
||||
+ partmaps = xrealloc (partmaps, alloc * sizeof (*partmaps));
|
||||
+ }
|
||||
+
|
||||
+ partmaps[used++] = strdup (name);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+do_print_partmap (const char *x, void *data)
|
||||
+{
|
||||
+ char delim = *(const char *) data;
|
||||
+ if (check_duplicate_partmap (x) != 0)
|
||||
+ return;
|
||||
+ grub_printf ("%s%c", x, delim);
|
||||
+}
|
||||
+
|
||||
static void
|
||||
probe_partmap (grub_disk_t disk, char delim)
|
||||
{
|
||||
@@ -165,10 +209,14 @@ probe_partmap (grub_disk_t disk, char delim)
|
||||
}
|
||||
|
||||
for (part = disk->partition; part; part = part->parent)
|
||||
- printf ("%s%c", part->partmap->name, delim);
|
||||
+ {
|
||||
+ if (check_duplicate_partmap (part->partmap->name) != 0)
|
||||
+ continue;
|
||||
+ printf ("%s%c", part->partmap->name, delim);
|
||||
+ }
|
||||
|
||||
if (disk->dev->id == GRUB_DISK_DEVICE_DISKFILTER_ID)
|
||||
- grub_diskfilter_get_partmap (disk, do_print, &delim);
|
||||
+ grub_diskfilter_get_partmap (disk, do_print_partmap, &delim);
|
||||
|
||||
/* In case of LVM/RAID, check the member devices as well. */
|
||||
if (disk->dev->disk_memberlist)
|
||||
@@ -674,8 +722,11 @@ probe (const char *path, char **device_names, char delim)
|
||||
probe_cryptodisk_uuid (dev->disk, delim);
|
||||
|
||||
else if (print == PRINT_PARTMAP)
|
||||
- /* Check if dev->disk itself is contained in a partmap. */
|
||||
- probe_partmap (dev->disk, delim);
|
||||
+ {
|
||||
+ /* Check if dev->disk itself is contained in a partmap. */
|
||||
+ probe_partmap (dev->disk, delim);
|
||||
+ check_duplicate_partmap (NULL);
|
||||
+ }
|
||||
|
||||
else if (print == PRINT_PARTUUID)
|
||||
{
|
||||
--
|
||||
2.35.1
|
||||
|
@ -0,0 +1,44 @@
|
||||
From a59b58f6ae327a8f6949991cb5531db01e1ba14d Mon Sep 17 00:00:00 2001
|
||||
From: Wen Xiong <wenxiong@linux.ibm.com>
|
||||
Date: Tue, 7 Feb 2023 15:10:15 -0500
|
||||
Subject: [PATCH] grub2: Can't setup a default boot device correctly on nvme
|
||||
device in Beta3
|
||||
|
||||
The patch in Bug 200486 - SUSE1205666 - SLES15SP5 Beta1: Setup multiple dev path
|
||||
for a nvmf boot device in grub2 caused the issue. That patch didn't consider
|
||||
nvme devices carefully.
|
||||
|
||||
The new patch will check "nvme-of" instead of "nvme" to call
|
||||
build_multi_boot_device().
|
||||
|
||||
Signed-off-by: Wen Xiong<wenxiong@linux.ibm.com>
|
||||
---
|
||||
grub-core/osdep/unix/platform.c | 10 +++++++---
|
||||
1 file changed, 7 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/unix/platform.c b/grub-core/osdep/unix/platform.c
|
||||
index db8fa4b95..fb47c0ffa 100644
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -288,11 +288,15 @@ grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
- else if (grub_strstr(install_device, "nvme"))
|
||||
- boot_device = build_multi_boot_device(install_device);
|
||||
- else
|
||||
+ else {
|
||||
boot_device = get_ofpathname (install_device);
|
||||
|
||||
+ if (grub_strstr(boot_device, "nvme-of")) {
|
||||
+ free (boot_device);
|
||||
+ boot_device = build_multi_boot_device(install_device);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (grub_util_exec ((const char * []){ "nvsetenv", "boot-device",
|
||||
boot_device, NULL }))
|
||||
{
|
||||
--
|
||||
2.39.1
|
||||
|
164
0001-grub2-Set-multiple-device-path-for-a-nvmf-boot-devic.patch
Normal file
164
0001-grub2-Set-multiple-device-path-for-a-nvmf-boot-devic.patch
Normal file
@ -0,0 +1,164 @@
|
||||
From 3e77c5494fd06f430588ae9c304fea370439d531 Mon Sep 17 00:00:00 2001
|
||||
From: Wen Xiong <Wen Xiong>
|
||||
Date: Thu, 15 Dec 2022 21:33:41 -0500
|
||||
Subject: [PATCH] grub2: Set multiple device path for a nvmf boot device
|
||||
|
||||
nvmf support native multipath(ANA) by default.
|
||||
The patch added the support for setting multiple
|
||||
device path for a nvmf boot device.
|
||||
|
||||
localhost:~ grub2-install -v /dev/nvme1n1p1
|
||||
...
|
||||
...
|
||||
...
|
||||
grub2-install: info: executing nvsetenv boot-device /pci@800000020000132/fibre-channel@0,1/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec /pci@800000020000132/fibre-channel@0,1/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec.
|
||||
Installation finished. No error reported.
|
||||
|
||||
localhost:~ # bootlist -m normal -o
|
||||
nvme7n1
|
||||
nvme5n1
|
||||
nvme1n1
|
||||
nvme4n1
|
||||
|
||||
localhost:~ # bootlist -m normal -r
|
||||
/pci@800000020000132/fibre-channel@0,1/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
/pci@800000020000132/fibre-channel@0/nvme-of/controller@5005076810193675,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
/pci@800000020000132/fibre-channel@0/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
/pci@800000020000132/fibre-channel@0,1/nvme-of/controller@50050768101935e5,ffff:nqn=nqn.1986-03.com.ibm:nvme:2145.0000020420006CEA/namespace@ec
|
||||
|
||||
Signed-off-by: Wen Xiong <wenxiong@linux.ibm.com>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 6 ++---
|
||||
grub-core/osdep/unix/platform.c | 48 +++++++++++++++++++++++++++++++++
|
||||
include/grub/util/install.h | 3 +++
|
||||
include/grub/util/ofpath.h | 9 +++++++
|
||||
4 files changed, 63 insertions(+), 3 deletions(-)
|
||||
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -209,7 +209,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
xrealpath (const char *in)
|
||||
{
|
||||
char *out;
|
||||
@@ -224,7 +224,7 @@
|
||||
return out;
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
block_device_get_sysfs_path_and_link(const char *devicenode)
|
||||
{
|
||||
char *rpath;
|
||||
@@ -535,7 +535,7 @@
|
||||
|
||||
}
|
||||
|
||||
-static char *
|
||||
+char *
|
||||
nvme_get_syspath(const char *nvmedev)
|
||||
{
|
||||
char *sysfs_path, *controller_node;
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <config.h>
|
||||
|
||||
#include <grub/util/install.h>
|
||||
+#include <grub/util/ofpath.h>
|
||||
#include <grub/emu/hostdisk.h>
|
||||
#include <grub/util/misc.h>
|
||||
#include <grub/misc.h>
|
||||
@@ -131,6 +132,51 @@
|
||||
return rc;
|
||||
}
|
||||
|
||||
+char *
|
||||
+build_multi_boot_device(const char *install_device)
|
||||
+{
|
||||
+ char *sysfs_path;
|
||||
+ char *nvme_ns;
|
||||
+ unsigned int nsid;
|
||||
+ char *ptr;
|
||||
+ char *boot_device_string;
|
||||
+ struct dirent *ep;
|
||||
+ DIR *dp;
|
||||
+
|
||||
+ nvme_ns = strchr(install_device, 'n');
|
||||
+ nsid = of_path_get_nvme_nsid(nvme_ns);
|
||||
+ sysfs_path = nvme_get_syspath(nvme_ns);
|
||||
+ strcat(sysfs_path, "/device");
|
||||
+ sysfs_path = xrealpath(sysfs_path);
|
||||
+
|
||||
+ dp = opendir(sysfs_path);
|
||||
+ ptr = boot_device_string = xmalloc (1000);
|
||||
+
|
||||
+ /* We cannot have a boot list with more than five entries */
|
||||
+ while((ep = readdir(dp)) != NULL){
|
||||
+ char *nvme_device;
|
||||
+
|
||||
+ if (grub_strstr(ep->d_name, "nvme")) {
|
||||
+ nvme_device = xasprintf ("%s%s%x ",
|
||||
+ get_ofpathname(ep->d_name),"/namespace@", nsid);
|
||||
+ if ((strlen(boot_device_string) + strlen(nvme_device)) >= 200*5 - 1) {
|
||||
+ grub_util_warn (_("More than five entries cannot be specified in the bootlist"));
|
||||
+ free(nvme_device);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ strncpy(ptr, nvme_device, strlen(nvme_device));
|
||||
+ ptr += strlen(nvme_device);
|
||||
+ free(nvme_device);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ *--ptr = '\0';
|
||||
+ closedir(dp);
|
||||
+
|
||||
+ return boot_device_string;
|
||||
+}
|
||||
+
|
||||
int
|
||||
grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
|
||||
const char *efifile_path,
|
||||
@@ -242,6 +288,8 @@
|
||||
}
|
||||
*ptr = '\0';
|
||||
}
|
||||
+ else if (grub_strstr(install_device, "nvme"))
|
||||
+ boot_device = build_multi_boot_device(install_device);
|
||||
else
|
||||
boot_device = get_ofpathname (install_device);
|
||||
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -241,6 +241,9 @@
|
||||
const char *efi_distributor,
|
||||
const char *force_disk);
|
||||
|
||||
+char *
|
||||
+build_multi_boot_device(const char *install_device);
|
||||
+
|
||||
void
|
||||
grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
int partno, const char *relpath);
|
||||
--- a/include/grub/util/ofpath.h
|
||||
+++ b/include/grub/util/ofpath.h
|
||||
@@ -32,4 +32,13 @@
|
||||
|
||||
char* of_find_fc_host(char* host_wwpn);
|
||||
|
||||
+char* nvme_get_syspath(const char *nvmedev);
|
||||
+
|
||||
+char* block_device_get_sysfs_path_and_link(const char *devicenode);
|
||||
+
|
||||
+char* xrealpath (const char *in);
|
||||
+
|
||||
+unsigned int of_path_get_nvme_nsid(const char* devname);
|
||||
+
|
||||
+
|
||||
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
|
142
0001-ieee1275-Avoiding-many-unecessary-open-close.patch
Normal file
142
0001-ieee1275-Avoiding-many-unecessary-open-close.patch
Normal file
@ -0,0 +1,142 @@
|
||||
From e9d3202d5cffb89223ff61ac93de86a0cac1b50c Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegodo@linux.vnet.ibm.com>
|
||||
Date: Thu, 19 Nov 2020 10:47:25 -0300
|
||||
Subject: [PATCH] ieee1275: Avoiding many unecessary open/close
|
||||
|
||||
This patch aims to change the grub_ofdisk_open and grub_ofdisk_close behaviors. Since some devices (Fibre Channel and NVMe) can have a long time for shutdown notification, we should avoid open and close the disks as much as we can.
|
||||
|
||||
So, we are changing how those functions works. The grub_ofdisk_close will take care of just changing the disk element status, by doing a soft close, i.e, the firmware will not be called. On the other hand, the grub_ofdisk_open will take care of closing the current disk opened only if the disk requested in the current call is different from the current one. This close will be responsible to request the firmware to actually close the disk.
|
||||
|
||||
Yet, this patch modifies the grub_ofdisk_get_block_size function, avoiding open and close calls inside of it.
|
||||
|
||||
Thank you Michael Chang (mchang@suse.com) for all support.
|
||||
|
||||
Signed-off-by: Diego Domingos <diegodo@linux.vnet.ibm.com>
|
||||
---
|
||||
grub-core/disk/ieee1275/ofdisk.c | 64 +++++++++++++++++---------------
|
||||
1 file changed, 35 insertions(+), 29 deletions(-)
|
||||
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -44,7 +44,7 @@
|
||||
};
|
||||
|
||||
static grub_err_t
|
||||
-grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size,
|
||||
+grub_ofdisk_get_block_size (grub_uint32_t *block_size,
|
||||
struct ofdisk_hash_ent *op);
|
||||
|
||||
#define OFDISK_HASH_SZ 8
|
||||
@@ -461,6 +461,7 @@
|
||||
grub_ssize_t actual;
|
||||
grub_uint32_t block_size = 0;
|
||||
grub_err_t err;
|
||||
+ struct ofdisk_hash_ent *op;
|
||||
|
||||
if (grub_strncmp (name, "ieee1275/", sizeof ("ieee1275/") - 1) != 0)
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE,
|
||||
@@ -471,6 +472,35 @@
|
||||
|
||||
grub_dprintf ("disk", "Opening `%s'.\n", devpath);
|
||||
|
||||
+ op = ofdisk_hash_find (devpath);
|
||||
+ if (!op)
|
||||
+ op = ofdisk_hash_add (devpath, NULL);
|
||||
+ if (!op)
|
||||
+ {
|
||||
+ grub_free (devpath);
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+
|
||||
+ /* Check if the call to open is the same to the last disk already opened */
|
||||
+ if (last_devpath && !grub_strcmp(op->open_path,last_devpath))
|
||||
+ {
|
||||
+ goto finish;
|
||||
+ }
|
||||
+
|
||||
+ /* If not, we need to close the previous disk and open the new one */
|
||||
+ else {
|
||||
+ if (last_ihandle){
|
||||
+ grub_ieee1275_close (last_ihandle);
|
||||
+ }
|
||||
+ last_ihandle = 0;
|
||||
+ last_devpath = NULL;
|
||||
+
|
||||
+ grub_ieee1275_open (op->open_path, &last_ihandle);
|
||||
+ if (! last_ihandle)
|
||||
+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
|
||||
+ last_devpath = op->open_path;
|
||||
+ }
|
||||
+
|
||||
if (grub_ieee1275_finddevice (devpath, &dev))
|
||||
{
|
||||
grub_free (devpath);
|
||||
@@ -491,25 +521,18 @@
|
||||
return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a block device");
|
||||
}
|
||||
|
||||
+
|
||||
+ finish:
|
||||
/* XXX: There is no property to read the number of blocks. There
|
||||
should be a property `#blocks', but it is not there. Perhaps it
|
||||
is possible to use seek for this. */
|
||||
disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
|
||||
|
||||
{
|
||||
- struct ofdisk_hash_ent *op;
|
||||
- op = ofdisk_hash_find (devpath);
|
||||
- if (!op)
|
||||
- op = ofdisk_hash_add (devpath, NULL);
|
||||
- if (!op)
|
||||
- {
|
||||
- grub_free (devpath);
|
||||
- return grub_errno;
|
||||
- }
|
||||
disk->id = (unsigned long) op;
|
||||
disk->data = op->open_path;
|
||||
|
||||
- err = grub_ofdisk_get_block_size (devpath, &block_size, op);
|
||||
+ err = grub_ofdisk_get_block_size (&block_size, op);
|
||||
if (err)
|
||||
{
|
||||
grub_free (devpath);
|
||||
@@ -528,13 +551,6 @@
|
||||
static void
|
||||
grub_ofdisk_close (grub_disk_t disk)
|
||||
{
|
||||
- if (disk->data == last_devpath)
|
||||
- {
|
||||
- if (last_ihandle)
|
||||
- grub_ieee1275_close (last_ihandle);
|
||||
- last_ihandle = 0;
|
||||
- last_devpath = NULL;
|
||||
- }
|
||||
disk->data = 0;
|
||||
}
|
||||
|
||||
@@ -681,7 +697,7 @@
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_ofdisk_get_block_size (const char *device, grub_uint32_t *block_size,
|
||||
+grub_ofdisk_get_block_size (grub_uint32_t *block_size,
|
||||
struct ofdisk_hash_ent *op)
|
||||
{
|
||||
struct size_args_ieee1275
|
||||
@@ -694,16 +710,6 @@
|
||||
grub_ieee1275_cell_t size2;
|
||||
} args_ieee1275;
|
||||
|
||||
- if (last_ihandle)
|
||||
- grub_ieee1275_close (last_ihandle);
|
||||
-
|
||||
- last_ihandle = 0;
|
||||
- last_devpath = NULL;
|
||||
-
|
||||
- grub_ieee1275_open (device, &last_ihandle);
|
||||
- if (! last_ihandle)
|
||||
- return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
|
||||
-
|
||||
*block_size = 0;
|
||||
|
||||
if (op->block_size_fails >= 2)
|
250
0001-ieee1275-add-support-for-NVMeoFC.patch
Normal file
250
0001-ieee1275-add-support-for-NVMeoFC.patch
Normal file
@ -0,0 +1,250 @@
|
||||
From c125cb45a7885d7bf168a05cfa4da3e681244649 Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegodo@br.ibm.com>
|
||||
Date: Tue, 15 Feb 2022 13:11:48 -0500
|
||||
Subject: [PATCH 1/4] ieee1275: add support for NVMeoFC
|
||||
|
||||
Implements the functions to scan and discovery of NVMeoFC.
|
||||
---
|
||||
grub-core/disk/ieee1275/ofdisk.c | 217 ++++++++++++++++++++++++++++++-
|
||||
1 file changed, 213 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
||||
index 410f4b849..852bb95be 100644
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -206,12 +206,10 @@ dev_iterate_real (const char *name, const char *path)
|
||||
return;
|
||||
}
|
||||
|
||||
+
|
||||
static void
|
||||
-dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
+dev_iterate_fcp_disks(const struct grub_ieee1275_devalias *alias)
|
||||
{
|
||||
- if (grub_strcmp (alias->type, "fcp") == 0)
|
||||
- {
|
||||
-
|
||||
/* If we are dealing with fcp devices, we need
|
||||
* to find the WWPNs and LUNs to iterate them */
|
||||
grub_ieee1275_ihandle_t ihandle;
|
||||
@@ -323,6 +321,217 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
grub_free (buf);
|
||||
return;
|
||||
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+dev_iterate_fcp_nvmeof (const struct grub_ieee1275_devalias *alias)
|
||||
+{
|
||||
+
|
||||
+
|
||||
+ char *bufptr;
|
||||
+ grub_ieee1275_ihandle_t ihandle;
|
||||
+
|
||||
+
|
||||
+ // Create the structs for the parameters passing to PFW
|
||||
+ struct nvme_args_
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t method;
|
||||
+ grub_ieee1275_cell_t ihandle;
|
||||
+ grub_ieee1275_cell_t catch_result;
|
||||
+ grub_ieee1275_cell_t nentries;
|
||||
+ grub_ieee1275_cell_t table;
|
||||
+ } nvme_discovery_controllers_args, nvme_controllers_args, nvme_namespaces_args;
|
||||
+
|
||||
+
|
||||
+ // Create the structs for the results from PFW
|
||||
+
|
||||
+ struct discovery_controllers_table_struct_
|
||||
+ {
|
||||
+ grub_uint64_t table[256];
|
||||
+ grub_uint32_t len;
|
||||
+ } discovery_controllers_table;
|
||||
+
|
||||
+ /* struct nvme_controllers_table_entry
|
||||
+ * this the return of nvme-controllers method tables, containing:
|
||||
+ * - 2-byte controller ID
|
||||
+ * - 256-byte transport address string
|
||||
+ * - 256-byte field containing null-terminated NVM subsystem NQN string up to 223 characters
|
||||
+ */
|
||||
+ struct nvme_controllers_table_entry_
|
||||
+ {
|
||||
+ grub_uint16_t id;
|
||||
+ char wwpn[256];
|
||||
+ char nqn[256];
|
||||
+ };
|
||||
+
|
||||
+ struct nvme_controllers_table_entry_* nvme_controllers_table = grub_malloc(sizeof(struct nvme_controllers_table_entry_)*256);
|
||||
+
|
||||
+ grub_uint32_t nvme_controllers_table_entries;
|
||||
+
|
||||
+ struct nvme_controllers_table_entry_real
|
||||
+ {
|
||||
+ grub_uint16_t id;
|
||||
+ char wwpn[256];
|
||||
+ char nqn[256];
|
||||
+ };
|
||||
+
|
||||
+ /* Allocate memory for building the NVMeoF path */
|
||||
+ char *buf = grub_malloc (grub_strlen (alias->path) + 512);
|
||||
+ if (!buf)
|
||||
+ {
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Copy the alias->path to buf so we can work with */
|
||||
+ bufptr = grub_stpcpy (buf, alias->path);
|
||||
+ grub_snprintf (bufptr, 32, "/nvme-of");
|
||||
+
|
||||
+ /*
|
||||
+ * Open the nvme-of layer
|
||||
+ * Ex. /pci@bus/fibre-channel@@dev,func/nvme-of
|
||||
+ */
|
||||
+ if(grub_ieee1275_open (buf, &ihandle))
|
||||
+ {
|
||||
+ grub_dprintf("disk", "failed to open the disk while iterating FCP disk path=%s\n", buf);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Call to nvme-discovery-controllers method from the nvme-of layer
|
||||
+ * to get a list of the NVMe discovery controllers per the binding
|
||||
+ */
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&nvme_discovery_controllers_args.common, "call-method", 2, 2);
|
||||
+ nvme_discovery_controllers_args.method = (grub_ieee1275_cell_t) "nvme-discovery-controllers";
|
||||
+ nvme_discovery_controllers_args.ihandle = ihandle;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_discovery_controllers_args) == -1)
|
||||
+ {
|
||||
+ grub_dprintf("disk", "failed to get the targets while iterating FCP disk path=%s\n", buf);
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* After closing the device, the info is lost. So lets copy each buffer in the buffers table */
|
||||
+
|
||||
+ discovery_controllers_table.len = (grub_uint32_t) nvme_discovery_controllers_args.nentries;
|
||||
+
|
||||
+ unsigned int i=0;
|
||||
+ for(i = 0; i < discovery_controllers_table.len; i++){
|
||||
+ discovery_controllers_table.table[i] = ((grub_uint64_t*)nvme_discovery_controllers_args.table)[i];
|
||||
+ }
|
||||
+
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+
|
||||
+ grub_dprintf("ofdisk","NVMeoF: Found %d discovery controllers\n",discovery_controllers_table.len);
|
||||
+
|
||||
+ /* For each nvme discovery controller */
|
||||
+ int current_buffer_index;
|
||||
+ for(current_buffer_index = 0; current_buffer_index < (int) discovery_controllers_table.len; current_buffer_index++){
|
||||
+
|
||||
+
|
||||
+ grub_snprintf (bufptr, 64, "/nvme-of/controller@%" PRIxGRUB_UINT64_T ",ffff",
|
||||
+ discovery_controllers_table.table[current_buffer_index]);
|
||||
+
|
||||
+ grub_dprintf("ofdisk","nvmeof controller=%s\n",buf);
|
||||
+
|
||||
+ if(grub_ieee1275_open (buf, &ihandle))
|
||||
+ {
|
||||
+ grub_dprintf("ofdisk", "failed to open the disk while getting nvme-controllers path=%s\n", buf);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&nvme_controllers_args.common, "call-method", 2, 2);
|
||||
+ nvme_controllers_args.method = (grub_ieee1275_cell_t) "nvme-controllers";
|
||||
+ nvme_controllers_args.ihandle = ihandle;
|
||||
+ nvme_controllers_args.catch_result = 0;
|
||||
+
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_controllers_args) == -1)
|
||||
+ {
|
||||
+ grub_dprintf("ofdisk", "failed to get the nvme-controllers while iterating FCP disk path\n");
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ /* Copy the buffer list to nvme_controllers_table */
|
||||
+ nvme_controllers_table_entries = ((grub_uint32_t) nvme_controllers_args.nentries);
|
||||
+ struct nvme_controllers_table_entry_* nvme_controllers_table_ = (struct nvme_controllers_table_entry_*) nvme_controllers_args.table;
|
||||
+
|
||||
+ for(i = 0; i < nvme_controllers_table_entries; i++){
|
||||
+ nvme_controllers_table[i].id = (grub_uint16_t) nvme_controllers_table_[i].id;
|
||||
+ grub_strcpy(nvme_controllers_table[i].wwpn, nvme_controllers_table_[i].wwpn);
|
||||
+ grub_strcpy(nvme_controllers_table[i].nqn, nvme_controllers_table_[i].nqn);
|
||||
+ }
|
||||
+
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+
|
||||
+ int nvme_controller_index;
|
||||
+ int bufptr_pos2;
|
||||
+ grub_dprintf("ofdisk","NVMeoF: found %d nvme controllers\n",(int) nvme_controllers_args.nentries);
|
||||
+
|
||||
+ /* For each nvme controller */
|
||||
+ for(nvme_controller_index = 0; nvme_controller_index < (int) nvme_controllers_args.nentries; nvme_controller_index++){
|
||||
+ /* Open the nvme controller
|
||||
+ * /pci@bus/fibre-channel@dev,func/nvme-of/controller@transport-addr,ctlr-id:nqn=tgt-subsystem-nqn
|
||||
+ */
|
||||
+
|
||||
+ bufptr_pos2 = grub_snprintf (bufptr, 512, "/nvme-of/controller@%s,ffff:nqn=%s",
|
||||
+ nvme_controllers_table[nvme_controller_index].wwpn, nvme_controllers_table[nvme_controller_index].nqn);
|
||||
+
|
||||
+ grub_dprintf("ofdisk","NVMeoF: nvmeof controller=%s\n",buf);
|
||||
+
|
||||
+ if(grub_ieee1275_open (buf, &ihandle)){
|
||||
+ grub_dprintf("ofdisk","failed to open the path=%s\n",buf);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ INIT_IEEE1275_COMMON (&nvme_namespaces_args.common, "call-method", 2, 2);
|
||||
+ nvme_namespaces_args.method = (grub_ieee1275_cell_t) "get-namespace-list";
|
||||
+ nvme_namespaces_args.ihandle = ihandle;
|
||||
+ nvme_namespaces_args.catch_result = 0;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&nvme_namespaces_args) == -1)
|
||||
+ {
|
||||
+ grub_dprintf("ofdisk", "failed to get the nvme-namespace-list while iterating FCP disk path\n");
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ grub_uint32_t *namespaces = (grub_uint32_t*) nvme_namespaces_args.table;
|
||||
+ grub_dprintf("ofdisk","NVMeoF: found %d namespaces\n",(int)nvme_namespaces_args.nentries);
|
||||
+
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+
|
||||
+ grub_uint32_t namespace_index = 0;
|
||||
+ for(namespace_index=0; namespace_index < nvme_namespaces_args.nentries; namespace_index++){
|
||||
+ grub_snprintf (bufptr+bufptr_pos2, 512, "/namespace@%"PRIxGRUB_UINT32_T,namespaces[namespace_index]);
|
||||
+ grub_dprintf("ofdisk","NVMeoF: namespace=%s\n",buf);
|
||||
+ dev_iterate_real(buf,buf);
|
||||
+ }
|
||||
+
|
||||
+ dev_iterate_real(buf,buf);
|
||||
+ }
|
||||
+ }
|
||||
+ grub_free(buf);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
+{
|
||||
+ if (grub_strcmp (alias->type, "fcp") == 0)
|
||||
+ {
|
||||
+ // Iterate disks
|
||||
+ dev_iterate_fcp_disks(alias);
|
||||
+
|
||||
+ // Iterate NVMeoF
|
||||
+ dev_iterate_fcp_nvmeof(alias);
|
||||
+
|
||||
}
|
||||
else if (grub_strcmp (alias->type, "vscsi") == 0)
|
||||
{
|
||||
--
|
||||
2.35.3
|
||||
|
146
0001-ieee1275-implement-FCP-methods-for-WWPN-and-LUNs.patch
Normal file
146
0001-ieee1275-implement-FCP-methods-for-WWPN-and-LUNs.patch
Normal file
@ -0,0 +1,146 @@
|
||||
From a37d0cc089edd66ab35f1a27b0da09dd2f02deb3 Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegodo@br.ibm.com>
|
||||
Date: Mon, 24 Jun 2019 10:15:56 -0400
|
||||
Subject: [PATCH] ieee1275: implement FCP methods for WWPN and LUNs
|
||||
|
||||
This patch enables the fcp-targets and fcp-luns methods which are
|
||||
responsible to get WWPNs and LUNs for fibre channel devices.
|
||||
|
||||
Those methods are specially necessary if the boot directory and grub
|
||||
installation are in different FCP disks, allowing the dev_iterate()
|
||||
to find the WWPNs and LUNs when called by searchfs.uuid tool.
|
||||
---
|
||||
grub-core/disk/ieee1275/ofdisk.c | 117 ++++++++++++++++++++++++++++++-
|
||||
1 file changed, 116 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
||||
index ea7f78ac7..258a6e389 100644
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -209,7 +209,122 @@ dev_iterate_real (const char *name, const char *path)
|
||||
static void
|
||||
dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
{
|
||||
- if (grub_strcmp (alias->type, "vscsi") == 0)
|
||||
+ if (grub_strcmp (alias->type, "fcp") == 0)
|
||||
+ {
|
||||
+
|
||||
+ /* If we are dealing with fcp devices, we need
|
||||
+ * to find the WWPNs and LUNs to iterate them */
|
||||
+ grub_ieee1275_ihandle_t ihandle;
|
||||
+ grub_uint64_t *ptr_targets, *ptr_luns, k, l;
|
||||
+ unsigned int i, j, pos;
|
||||
+ char *buf, *bufptr;
|
||||
+
|
||||
+ struct set_fcp_targets_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t method;
|
||||
+ grub_ieee1275_cell_t ihandle;
|
||||
+ grub_ieee1275_cell_t catch_result;
|
||||
+ grub_ieee1275_cell_t nentries;
|
||||
+ grub_ieee1275_cell_t table;
|
||||
+ } args_targets;
|
||||
+
|
||||
+ struct set_fcp_luns_args
|
||||
+ {
|
||||
+ struct grub_ieee1275_common_hdr common;
|
||||
+ grub_ieee1275_cell_t method;
|
||||
+ grub_ieee1275_cell_t ihandle;
|
||||
+ grub_ieee1275_cell_t wwpn_h;
|
||||
+ grub_ieee1275_cell_t wwpn_l;
|
||||
+ grub_ieee1275_cell_t catch_result;
|
||||
+ grub_ieee1275_cell_t nentries;
|
||||
+ grub_ieee1275_cell_t table;
|
||||
+ } args_luns;
|
||||
+
|
||||
+ struct args_ret
|
||||
+ {
|
||||
+ grub_uint64_t addr;
|
||||
+ grub_uint64_t len;
|
||||
+ };
|
||||
+
|
||||
+ if(grub_ieee1275_open (alias->path, &ihandle))
|
||||
+ {
|
||||
+ grub_dprintf("disk", "failed to open the disk while iterating FCP disk path=%s\n", alias->path);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ /* Setup the fcp-targets method to call via pfw*/
|
||||
+ INIT_IEEE1275_COMMON (&args_targets.common, "call-method", 2, 3);
|
||||
+ args_targets.method = (grub_ieee1275_cell_t) "fcp-targets";
|
||||
+ args_targets.ihandle = ihandle;
|
||||
+
|
||||
+ /* Setup the fcp-luns method to call via pfw */
|
||||
+ INIT_IEEE1275_COMMON (&args_luns.common, "call-method", 4, 3);
|
||||
+ args_luns.method = (grub_ieee1275_cell_t) "fcp-luns";
|
||||
+ args_luns.ihandle = ihandle;
|
||||
+
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args_targets) == -1)
|
||||
+ {
|
||||
+ grub_dprintf("disk", "failed to get the targets while iterating FCP disk path=%s\n", alias->path);
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ buf = grub_malloc (grub_strlen (alias->path) + 32 + 32);
|
||||
+
|
||||
+ if (!buf)
|
||||
+ {
|
||||
+ grub_ieee1275_close(ihandle);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ bufptr = grub_stpcpy (buf, alias->path);
|
||||
+
|
||||
+ /* Iterate over entries returned by pfw. Each entry contains a
|
||||
+ * pointer to wwpn table and his length. */
|
||||
+ struct args_ret *targets_table = (struct args_ret *)(args_targets.table);
|
||||
+ for (i=0; i< args_targets.nentries; i++)
|
||||
+ {
|
||||
+ ptr_targets = (grub_uint64_t*)(grub_uint32_t) targets_table[i].addr;
|
||||
+ /* Iterate over all wwpns in given table */
|
||||
+ for(k=0;k<targets_table[i].len;k++)
|
||||
+ {
|
||||
+ args_luns.wwpn_l = (grub_ieee1275_cell_t) (*ptr_targets);
|
||||
+ args_luns.wwpn_h = (grub_ieee1275_cell_t) (*ptr_targets >> 32);
|
||||
+ pos=grub_snprintf (bufptr, 32, "/disk@%" PRIxGRUB_UINT64_T,
|
||||
+ *ptr_targets++);
|
||||
+ /* Get the luns for given wwpn target */
|
||||
+ if (IEEE1275_CALL_ENTRY_FN (&args_luns) == -1)
|
||||
+ {
|
||||
+ grub_dprintf("disk", "failed to get the LUNS while iterating FCP disk path=%s\n", buf);
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ grub_free (buf);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ struct args_ret *luns_table = (struct args_ret *)(args_luns.table);
|
||||
+
|
||||
+ /* Iterate over all LUNs */
|
||||
+ for(j=0;j<args_luns.nentries; j++)
|
||||
+ {
|
||||
+ ptr_luns = (grub_uint64_t*) (grub_uint32_t) luns_table[j].addr;
|
||||
+ for(l=0;l<luns_table[j].len;l++)
|
||||
+ {
|
||||
+ grub_snprintf (&bufptr[pos], 30, ",%" PRIxGRUB_UINT64_T,
|
||||
+ *ptr_luns++);
|
||||
+ dev_iterate_real(buf,buf);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ grub_ieee1275_close (ihandle);
|
||||
+ grub_free (buf);
|
||||
+ return;
|
||||
+
|
||||
+ }
|
||||
+ else if (grub_strcmp (alias->type, "vscsi") == 0)
|
||||
{
|
||||
static grub_ieee1275_ihandle_t ihandle;
|
||||
struct set_color_args
|
||||
--
|
||||
2.31.1
|
||||
|
172
0001-ieee1275-ofdisk-retry-on-open-and-read-failure.patch
Normal file
172
0001-ieee1275-ofdisk-retry-on-open-and-read-failure.patch
Normal file
@ -0,0 +1,172 @@
|
||||
From f4728ed5307b6be6377b7bdafcab55fd3676a761 Mon Sep 17 00:00:00 2001
|
||||
From: Mukesh Kumar Chaurasiya <mchauras@linux.ibm.com>
|
||||
Date: Mon, 17 Jul 2023 16:02:34 +0530
|
||||
Subject: [PATCH] ieee1275/ofdisk: retry on open and read failure
|
||||
|
||||
Sometimes, when booting from a very busy SAN, the access to the
|
||||
disk can fail and then grub will eventually drop to grub prompt.
|
||||
This scenario is more frequent when deploying many machines at
|
||||
the same time using the same SAN.
|
||||
This patch aims to force the ofdisk module to retry the open or
|
||||
read function for network disks excluding after it fails. We use
|
||||
DEFAULT_RETRY_TIMEOUT, which is 15 seconds to specify the time it'll
|
||||
retry to access the disk before it definitely fails. The timeout can be
|
||||
changed by setting the environment variable ofdisk_retry_timeout.
|
||||
If the environment variable fails to read, grub will consider the
|
||||
default value of 15 seconds.
|
||||
|
||||
Signed-off-by: Diego Domingos <diegodo@linux.vnet.ibm.com>
|
||||
Signed-off-by: Mukesh Kumar Chaurasiya <mchauras@linux.ibm.com>
|
||||
---
|
||||
docs/grub.texi | 8 ++++
|
||||
grub-core/disk/ieee1275/ofdisk.c | 80 +++++++++++++++++++++++++++++++-
|
||||
2 files changed, 86 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/docs/grub.texi b/docs/grub.texi
|
||||
index d3f0f6577..c8ebc083d 100644
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -3315,6 +3315,7 @@ These variables have special meaning to GRUB.
|
||||
* net_default_ip::
|
||||
* net_default_mac::
|
||||
* net_default_server::
|
||||
+* ofdisk_retry_timeout::
|
||||
* pager::
|
||||
* prefix::
|
||||
* pxe_blksize::
|
||||
@@ -3744,6 +3745,13 @@ The default is the value of @samp{color_normal} (@pxref{color_normal}).
|
||||
@xref{Network}.
|
||||
|
||||
|
||||
+@node ofdisk_retry_timeout
|
||||
+@subsection ofdisk_retry_timeout
|
||||
+
|
||||
+The time in seconds till which the grub will retry to open or read a disk in
|
||||
+case of failure to do so. This value defaults to 15 seconds.
|
||||
+
|
||||
+
|
||||
@node pager
|
||||
@subsection pager
|
||||
|
||||
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
||||
index 7197d5401..f96bbb58c 100644
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -24,6 +24,9 @@
|
||||
#include <grub/ieee1275/ofdisk.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/time.h>
|
||||
+#include <grub/env.h>
|
||||
+
|
||||
+#define RETRY_DEFAULT_TIMEOUT 15
|
||||
|
||||
static char *last_devpath;
|
||||
static grub_ieee1275_ihandle_t last_ihandle;
|
||||
@@ -783,7 +786,7 @@ compute_dev_path (const char *name)
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_ofdisk_open (const char *name, grub_disk_t disk)
|
||||
+grub_ofdisk_open_real (const char *name, grub_disk_t disk)
|
||||
{
|
||||
grub_ieee1275_phandle_t dev;
|
||||
char *devpath;
|
||||
@@ -879,6 +882,56 @@ grub_ofdisk_open (const char *name, grub_disk_t disk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static grub_uint64_t
|
||||
+grub_ofdisk_disk_timeout (grub_disk_t disk)
|
||||
+{
|
||||
+ grub_uint64_t retry;
|
||||
+ const char *timeout = grub_env_get ("ofdisk_retry_timeout");
|
||||
+
|
||||
+ if (!(grub_strstr (disk->name, "fibre-channel@") ||
|
||||
+ grub_strstr (disk->name, "vfc-client")) ||
|
||||
+ grub_strstr(disk->name, "nvme-of"))
|
||||
+ {
|
||||
+ /* Do not retry in case of non network drives */
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if (timeout != NULL)
|
||||
+ {
|
||||
+ retry = grub_strtoul (timeout, 0, 10);
|
||||
+ if (grub_errno != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ return RETRY_DEFAULT_TIMEOUT;
|
||||
+ }
|
||||
+ if (retry)
|
||||
+ return retry;
|
||||
+ }
|
||||
+ return RETRY_DEFAULT_TIMEOUT;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_ofdisk_open (const char *name, grub_disk_t disk)
|
||||
+{
|
||||
+ grub_err_t err;
|
||||
+ grub_uint64_t timeout = grub_get_time_ms () + (grub_ofdisk_disk_timeout (disk) * 1000);
|
||||
+ _Bool cont;
|
||||
+ do
|
||||
+ {
|
||||
+ err = grub_ofdisk_open_real (name, disk);
|
||||
+ cont = grub_get_time_ms () < timeout;
|
||||
+ if (err == GRUB_ERR_UNKNOWN_DEVICE && cont)
|
||||
+ {
|
||||
+ grub_dprintf ("ofdisk","Failed to open disk %s. Retrying...\n", name);
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ else
|
||||
+ break;
|
||||
+ grub_millisleep (1000);
|
||||
+ } while (cont);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
grub_ofdisk_close (grub_disk_t disk)
|
||||
{
|
||||
@@ -915,7 +968,7 @@ grub_ofdisk_prepare (grub_disk_t disk, grub_disk_addr_t sector)
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
-grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
+grub_ofdisk_read_real (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
grub_size_t size, char *buf)
|
||||
{
|
||||
grub_err_t err;
|
||||
@@ -934,6 +987,29 @@ grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+grub_ofdisk_read (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
+ grub_size_t size, char *buf)
|
||||
+{
|
||||
+ grub_err_t err;
|
||||
+ grub_uint64_t timeout = grub_get_time_ms () + (grub_ofdisk_disk_timeout (disk) * 1000);
|
||||
+ _Bool cont;
|
||||
+ do
|
||||
+ {
|
||||
+ err = grub_ofdisk_read_real (disk, sector, size, buf);
|
||||
+ cont = grub_get_time_ms () < timeout;
|
||||
+ if (err == GRUB_ERR_UNKNOWN_DEVICE && cont)
|
||||
+ {
|
||||
+ grub_dprintf ("ofdisk","Failed to read disk %s. Retrying...\n", (char*)disk->data);
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+ else
|
||||
+ break;
|
||||
+ grub_millisleep (1000);
|
||||
+ } while (cont);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_ofdisk_write (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
grub_size_t size, const char *buf)
|
||||
--
|
||||
2.41.0
|
||||
|
@ -0,0 +1,90 @@
|
||||
From ca30b3c6fd8c848f510445316d0c4a8fca6061ba Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegodo@br.ibm.com>
|
||||
Date: Wed, 24 Jun 2020 08:17:18 -0400
|
||||
Subject: [PATCH 1/2] ieee1275/powerpc: implements fibre channel discovery for
|
||||
ofpathname
|
||||
|
||||
grub-ofpathname doesn't work with fibre channel because there is no
|
||||
function currently implemented for it.
|
||||
This patch enables it by prividing a function that looks for the port
|
||||
name, building the entire path for OF devices.
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 48 ++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 48 insertions(+)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index a6153d359..f2bc9fc5c 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -399,6 +399,37 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
}
|
||||
#endif
|
||||
|
||||
+static void
|
||||
+of_fc_port_name(const char *path, const char *subpath, char *port_name)
|
||||
+{
|
||||
+ char *bname, *basepath, *p;
|
||||
+ int fd;
|
||||
+
|
||||
+ bname = xmalloc(sizeof(char)*150);
|
||||
+ basepath = xmalloc(strlen(path));
|
||||
+
|
||||
+ /* Generate the path to get port name information from the drive */
|
||||
+ strncpy(basepath,path,subpath-path);
|
||||
+ basepath[subpath-path-1] = '\0';
|
||||
+ p = get_basename(basepath);
|
||||
+ snprintf(bname,sizeof(char)*150,"%s/fc_transport/%s/port_name",basepath,p);
|
||||
+
|
||||
+ /* Read the information from the port name */
|
||||
+ fd = open (bname, O_RDONLY);
|
||||
+ if (fd < 0)
|
||||
+ grub_util_error (_("cannot open `%s': %s"), bname, strerror (errno));
|
||||
+
|
||||
+ if (read(fd,port_name,sizeof(char)*19) < 0)
|
||||
+ grub_util_error (_("cannot read `%s': %s"), bname, strerror (errno));
|
||||
+
|
||||
+ sscanf(port_name,"0x%s",port_name);
|
||||
+
|
||||
+ close(fd);
|
||||
+
|
||||
+ free(bname);
|
||||
+ free(basepath);
|
||||
+}
|
||||
+
|
||||
static int
|
||||
vendor_is_ATA(const char *path)
|
||||
{
|
||||
@@ -577,6 +608,16 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
|
||||
digit_string = trailing_digits (device);
|
||||
if (strncmp (of_path, "/vdevice/", sizeof ("/vdevice/") - 1) == 0)
|
||||
{
|
||||
+ if(strstr(of_path,"vfc-client"))
|
||||
+ {
|
||||
+ char * port_name = xmalloc(sizeof(char)*17);
|
||||
+ of_fc_port_name(sysfs_path, p, port_name);
|
||||
+
|
||||
+ snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name);
|
||||
+ free(port_name);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
unsigned long id = 0x8000 | (tgt << 8) | (bus << 5) | lun;
|
||||
if (*digit_string == '\0')
|
||||
{
|
||||
@@ -590,6 +631,13 @@ of_path_of_scsi(const char *sys_devname __attribute__((unused)), const char *dev
|
||||
snprintf(disk, sizeof (disk),
|
||||
"/%s@%04lx000000000000:%c", disk_name, id, 'a' + (part - 1));
|
||||
}
|
||||
+ }
|
||||
+ } else if (strstr(of_path,"fibre-channel")||(strstr(of_path,"vfc-client"))){
|
||||
+ char * port_name = xmalloc(sizeof(char)*17);
|
||||
+ of_fc_port_name(sysfs_path, p, port_name);
|
||||
+
|
||||
+ snprintf(disk,sizeof(disk),"/%s@%s", disk_name, port_name);
|
||||
+ free(port_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
--
|
||||
2.26.2
|
||||
|
396
0001-install-fix-software-raid1-on-esp.patch
Normal file
396
0001-install-fix-software-raid1-on-esp.patch
Normal file
@ -0,0 +1,396 @@
|
||||
From 6444774dae24f439dae3b4bc8d73449d50f06240 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 31 Dec 2020 21:54:07 +0800
|
||||
Subject: [PATCH] install: fix software raid1 on esp
|
||||
|
||||
While running grub-install on an efi system where efi system partition
|
||||
is configured as mdadm software raid1, it fails with errors like this:
|
||||
|
||||
grub2-install: info: copying `/boot/grub2/x86_64-efi/core.efi' -> `/boot/efi/EFI/opensuse/grubx64.efi'.
|
||||
grub2-install: info: Registering with EFI: distributor = `opensuse', path = `\EFI\opensuse\grubx64.efi', ESP at mduuid/9182c46b9d469f79b48850b68f3371a5.
|
||||
grub2-install: info: executing efibootmgr --version </dev/null >/dev/null.
|
||||
grub2-install: info: executing modprobe -q efivars.
|
||||
grub2-install: info: executing efibootmgr -c -d.
|
||||
efibootmgr: option requires an argument -- 'd'
|
||||
efibootmgr version 14
|
||||
usage: efibootmgr [options]
|
||||
|
||||
This should work with mdadm raid1 with metadata 0.9 and 1.0 whose
|
||||
superblocks are at the end of device. However
|
||||
grub_install_register_efi() doesn't seem to work if the target is
|
||||
multiple devices so that it errors out.
|
||||
|
||||
The patch changes grub_install_register_efi() to accept multiple devices
|
||||
that can be used to creating efi boot entries for probed raid1 member
|
||||
devices on mounted efi system partition.
|
||||
|
||||
This patch also adds check for metadata 0.9 or 1.0 or the validation
|
||||
will fail to continue the install.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/disk/diskfilter.c | 27 +++----
|
||||
grub-core/disk/mdraid1x_linux.c | 3 +
|
||||
grub-core/osdep/basic/no_platform.c | 3 +-
|
||||
grub-core/osdep/unix/platform.c | 57 +++++++++++----
|
||||
grub-core/osdep/windows/platform.c | 3 +-
|
||||
include/grub/diskfilter.h | 3 +-
|
||||
include/grub/util/install.h | 5 +-
|
||||
util/grub-install.c | 107 ++++++++++++++++++++++++++--
|
||||
8 files changed, 171 insertions(+), 37 deletions(-)
|
||||
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -159,8 +159,8 @@
|
||||
for (m = arr->pvs; m; m = m->next)
|
||||
if (m->disk && m->disk->id == disk->id
|
||||
&& m->disk->dev->id == disk->dev->id
|
||||
- && m->part_start == grub_partition_get_start (disk->partition)
|
||||
- && m->part_size == grub_disk_native_sectors (disk))
|
||||
+ && grub_partition_get_start (m->disk->partition) == grub_partition_get_start (disk->partition)
|
||||
+ && grub_disk_native_sectors (m->disk) == grub_disk_native_sectors (disk))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1340,19 +1340,23 @@
|
||||
? (grub_memcmp (pv->id.uuid, id->uuid, id->uuidlen) == 0)
|
||||
: (pv->id.id == id->id))
|
||||
{
|
||||
+ char *part_name = NULL;
|
||||
struct grub_diskfilter_lv *lv;
|
||||
/* FIXME: Check whether the update time of the superblocks are
|
||||
the same. */
|
||||
- if (pv->disk && grub_disk_native_sectors (disk) >= pv->part_size)
|
||||
+ if (pv->disk && grub_disk_native_sectors (disk) >= grub_disk_native_sectors (pv->disk))
|
||||
return GRUB_ERR_NONE;
|
||||
- pv->disk = grub_disk_open (disk->name);
|
||||
+ if (disk->partition)
|
||||
+ {
|
||||
+ char *p = grub_partition_get_name (disk->partition);
|
||||
+ if (p)
|
||||
+ part_name = grub_xasprintf ("%s,%s", disk->name, p);
|
||||
+ grub_free (p);
|
||||
+ }
|
||||
+ pv->disk = grub_disk_open (part_name ? : disk->name);
|
||||
+ grub_free (part_name);
|
||||
if (!pv->disk)
|
||||
return grub_errno;
|
||||
- /* This could happen to LVM on RAID, pv->disk points to the
|
||||
- raid device, we shouldn't change it. */
|
||||
- pv->start_sector -= pv->part_start;
|
||||
- pv->part_start = grub_partition_get_start (disk->partition);
|
||||
- pv->part_size = grub_disk_native_sectors (disk);
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
{
|
||||
@@ -1369,7 +1373,6 @@
|
||||
#endif
|
||||
if (start_sector != (grub_uint64_t)-1)
|
||||
pv->start_sector = start_sector;
|
||||
- pv->start_sector += pv->part_start;
|
||||
/* Add the device to the array. */
|
||||
for (lv = array->lvs; lv; lv = lv->next)
|
||||
if (!lv->became_readable_at && lv->fullname && is_lv_readable (lv, 0))
|
||||
@@ -1457,8 +1460,8 @@
|
||||
{
|
||||
if (pv->disk && pv->disk->id == disk->id
|
||||
&& pv->disk->dev->id == disk->dev->id
|
||||
- && pv->part_start == grub_partition_get_start (disk->partition)
|
||||
- && pv->part_size == grub_disk_native_sectors (disk))
|
||||
+ && grub_partition_get_start (pv->disk->partition) == grub_partition_get_start (disk->partition)
|
||||
+ && grub_disk_native_sectors (pv->disk) == grub_disk_native_sectors (disk))
|
||||
{
|
||||
if (vg_out)
|
||||
*vg_out = vg;
|
||||
--- a/grub-core/disk/mdraid1x_linux.c
|
||||
+++ b/grub-core/disk/mdraid1x_linux.c
|
||||
@@ -208,6 +208,9 @@
|
||||
grub_le_to_cpu32 (sb.chunksize),
|
||||
grub_le_to_cpu32 (sb.layout),
|
||||
grub_le_to_cpu32 (sb.level));
|
||||
+#ifdef GRUB_UTIL
|
||||
+ array->mdraid1x_minor_version = minor_version;
|
||||
+#endif
|
||||
|
||||
return array;
|
||||
}
|
||||
--- a/grub-core/osdep/basic/no_platform.c
|
||||
+++ b/grub-core/osdep/basic/no_platform.c
|
||||
@@ -33,7 +33,8 @@
|
||||
void
|
||||
grub_install_register_efi (grub_device_t efidir_grub_dev,
|
||||
const char *efifile_path,
|
||||
- const char *efi_distributor)
|
||||
+ const char *efi_distributor,
|
||||
+ const char *force_disk)
|
||||
{
|
||||
grub_util_error ("%s", _("no EFI routines are available for your platform"));
|
||||
}
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -132,15 +132,14 @@
|
||||
}
|
||||
|
||||
int
|
||||
-grub_install_register_efi (grub_device_t efidir_grub_dev,
|
||||
+grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
|
||||
const char *efifile_path,
|
||||
- const char *efi_distributor)
|
||||
+ const char *efi_distributor,
|
||||
+ const char *force_disk)
|
||||
{
|
||||
- const char * efidir_disk;
|
||||
- int efidir_part;
|
||||
int ret;
|
||||
- efidir_disk = grub_util_biosdisk_get_osdev (efidir_grub_dev->disk);
|
||||
- efidir_part = efidir_grub_dev->disk->partition ? efidir_grub_dev->disk->partition->number + 1 : 1;
|
||||
+ const grub_disk_t *curdisk;
|
||||
+ int ndev = 0;
|
||||
|
||||
if (grub_util_exec_redirect_null ((const char * []){ "efibootmgr", "--version", NULL }))
|
||||
{
|
||||
@@ -158,22 +157,50 @@
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
- char *efidir_part_str = xasprintf ("%d", efidir_part);
|
||||
+ for (curdisk = efidir_grub_disk; *curdisk; curdisk++)
|
||||
+ ndev++;
|
||||
|
||||
- if (!verbosity)
|
||||
- ret = grub_util_exec ((const char * []){ "efibootmgr", "-q",
|
||||
+ for (curdisk = efidir_grub_disk; *curdisk; curdisk++)
|
||||
+ {
|
||||
+ const char * efidir_disk;
|
||||
+ int efidir_part;
|
||||
+ char *efidir_part_str;
|
||||
+ char *new_efi_distributor = NULL;
|
||||
+ grub_disk_t disk = *curdisk;
|
||||
+
|
||||
+ efidir_disk = force_disk ? : grub_util_biosdisk_get_osdev (disk);
|
||||
+ if (!efidir_disk)
|
||||
+ grub_util_error (_("%s: no device for efi"), disk->name);
|
||||
+
|
||||
+ efidir_part = disk->partition ? disk->partition->number + 1 : 1;
|
||||
+ efidir_part_str = xasprintf ("%d", efidir_part);
|
||||
+ if (ndev > 1)
|
||||
+ {
|
||||
+ const char *p = grub_strrchr (efidir_disk, '/');
|
||||
+ new_efi_distributor = xasprintf ("%s (%s%d)\n",
|
||||
+ efi_distributor,
|
||||
+ p ? p + 1: efidir_disk,
|
||||
+ efidir_part);
|
||||
+ }
|
||||
+
|
||||
+ if (!verbosity)
|
||||
+ ret = grub_util_exec ((const char * []){ "efibootmgr", "-q",
|
||||
"-c", "-d", efidir_disk,
|
||||
"-p", efidir_part_str, "-w",
|
||||
- "-L", efi_distributor, "-l",
|
||||
+ "-L", new_efi_distributor ? : efi_distributor, "-l",
|
||||
efifile_path, NULL });
|
||||
- else
|
||||
- ret = grub_util_exec ((const char * []){ "efibootmgr",
|
||||
+ else
|
||||
+ ret = grub_util_exec ((const char * []){ "efibootmgr",
|
||||
"-c", "-d", efidir_disk,
|
||||
"-p", efidir_part_str, "-w",
|
||||
- "-L", efi_distributor, "-l",
|
||||
+ "-L", new_efi_distributor ? : efi_distributor, "-l",
|
||||
efifile_path, NULL });
|
||||
- free (efidir_part_str);
|
||||
- return ret;
|
||||
+ free (efidir_part_str);
|
||||
+ free (new_efi_distributor);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ }
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
void
|
||||
--- a/grub-core/osdep/windows/platform.c
|
||||
+++ b/grub-core/osdep/windows/platform.c
|
||||
@@ -204,7 +204,8 @@
|
||||
int
|
||||
grub_install_register_efi (grub_device_t efidir_grub_dev,
|
||||
const char *efifile_path,
|
||||
- const char *efi_distributor)
|
||||
+ const char *efi_distributor,
|
||||
+ const char *force_disk)
|
||||
{
|
||||
grub_uint16_t *boot_order, *new_boot_order;
|
||||
grub_uint16_t *distributor16;
|
||||
--- a/include/grub/diskfilter.h
|
||||
+++ b/include/grub/diskfilter.h
|
||||
@@ -49,6 +49,7 @@
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
struct grub_diskfilter *driver;
|
||||
+ grub_uint8_t mdraid1x_minor_version;
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -66,8 +67,6 @@
|
||||
/* Optional. */
|
||||
char *name;
|
||||
grub_disk_t disk;
|
||||
- grub_disk_addr_t part_start;
|
||||
- grub_disk_addr_t part_size;
|
||||
grub_disk_addr_t start_sector; /* Sector number where the data area starts. */
|
||||
struct grub_diskfilter_pv *next;
|
||||
/* Optional. */
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -236,9 +236,10 @@
|
||||
grub_install_get_powerpc_secure_boot (void);
|
||||
|
||||
int
|
||||
-grub_install_register_efi (grub_device_t efidir_grub_dev,
|
||||
+grub_install_register_efi (const grub_disk_t *efidir_grub_disk,
|
||||
const char *efifile_path,
|
||||
- const char *efi_distributor);
|
||||
+ const char *efi_distributor,
|
||||
+ const char *force_disk);
|
||||
|
||||
void
|
||||
grub_install_register_ieee1275 (int is_prep, const char *install_device,
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -1719,6 +1719,40 @@
|
||||
}
|
||||
}
|
||||
prefix_drive = xasprintf ("(%s)", grub_drives[0]);
|
||||
+
|
||||
+ if (platform == GRUB_INSTALL_PLATFORM_X86_64_EFI
|
||||
+ && grub_dev->disk
|
||||
+ && grub_dev->disk->partition
|
||||
+ && grub_fs->fs_uuid)
|
||||
+ {
|
||||
+ int raid_level;
|
||||
+ char *uuid = NULL;
|
||||
+ char *escaped_relpath = NULL;
|
||||
+
|
||||
+ raid_level = probe_raid_level (grub_dev->disk);
|
||||
+ if (raid_level != 1)
|
||||
+ goto out;
|
||||
+
|
||||
+ escaped_relpath = escape (relative_grubdir);
|
||||
+ if (!escaped_relpath)
|
||||
+ goto out;
|
||||
+
|
||||
+ if (grub_fs->fs_uuid (grub_dev, &uuid) || !uuid)
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ grub_errno = 0;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (!load_cfg_f)
|
||||
+ load_cfg_f = grub_util_fopen (load_cfg, "wb");
|
||||
+ have_load_cfg = 1;
|
||||
+ fprintf (load_cfg_f, "search --no-floppy --fs-uuid --set=root --hint='%s' %s\n", grub_drives[0], uuid);
|
||||
+ fprintf (load_cfg_f, "set prefix=($root)'%s'\n", escaped_relpath);
|
||||
+ grub_install_push_module ("search");
|
||||
+ out:
|
||||
+ grub_free (escaped_relpath);
|
||||
+ }
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
@@ -2258,9 +2292,13 @@
|
||||
{
|
||||
/* Try to make this image bootable using the EFI Boot Manager, if available. */
|
||||
int ret;
|
||||
- ret = grub_install_register_efi (efidir_grub_dev,
|
||||
+ grub_disk_t efidir_grub_disk[2];
|
||||
+ efidir_grub_disk[0] = efidir_grub_dev->disk;
|
||||
+ efidir_grub_disk[1] = NULL;
|
||||
+ ret = grub_install_register_efi (efidir_grub_disk,
|
||||
"\\System\\Library\\CoreServices",
|
||||
- efi_distributor);
|
||||
+ efi_distributor,
|
||||
+ NULL);
|
||||
if (ret)
|
||||
grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
|
||||
strerror (ret));
|
||||
@@ -2314,7 +2352,11 @@
|
||||
{
|
||||
char * efifile_path;
|
||||
char * part;
|
||||
+ int raid_level;
|
||||
int ret;
|
||||
+ grub_disk_t *efidir_grub_disk;
|
||||
+ grub_disk_memberlist_t list = NULL, cur;
|
||||
+ char * force_disk = NULL;
|
||||
|
||||
/* Try to make this image bootable using the EFI Boot Manager, if available. */
|
||||
if (!efi_distributor || efi_distributor[0] == '\0')
|
||||
@@ -2331,8 +2373,65 @@
|
||||
efidir_grub_dev->disk->name,
|
||||
(part ? ",": ""), (part ? : ""));
|
||||
grub_free (part);
|
||||
- ret = grub_install_register_efi (efidir_grub_dev,
|
||||
- efifile_path, efi_distributor);
|
||||
+
|
||||
+ raid_level = probe_raid_level (efidir_grub_dev->disk);
|
||||
+ if (raid_level >= 0 && raid_level != 1)
|
||||
+ grub_util_warn (_("unsupported raid level %d detected for efi system partition"), raid_level);
|
||||
+ if (raid_level == 1 && !efidir_grub_dev->disk->partition)
|
||||
+ {
|
||||
+ const char *raidname = NULL;
|
||||
+
|
||||
+ if (efidir_grub_dev->disk->dev->disk_raidname)
|
||||
+ raidname = efidir_grub_dev->disk->dev->disk_raidname (efidir_grub_dev->disk);
|
||||
+ if (raidname
|
||||
+ && (grub_strncmp (raidname, "mdraid09", sizeof ("mdraid09")) == 0
|
||||
+ || (grub_strcmp (raidname, "mdraid1x") == 0
|
||||
+ && ((struct grub_diskfilter_lv *) efidir_grub_dev->disk->data)->vg->mdraid1x_minor_version == 0)))
|
||||
+ {
|
||||
+ if (efidir_grub_dev->disk->dev->disk_memberlist)
|
||||
+ list = efidir_grub_dev->disk->dev->disk_memberlist (efidir_grub_dev->disk);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ grub_util_warn (_("this array has metadata at the start and may not be suitable as a efi system partition."
|
||||
+ " please ensure that your firmware understands md/v1.x metadata, or use --metadata=0.90"
|
||||
+ " to create the array."));
|
||||
+ /* Try to continue regardless metadata, nothing to lose here */
|
||||
+ if (efidir_grub_dev->disk->dev->disk_memberlist)
|
||||
+ list = efidir_grub_dev->disk->dev->disk_memberlist (efidir_grub_dev->disk);
|
||||
+ }
|
||||
+ }
|
||||
+ else if (raid_level == 1)
|
||||
+ force_disk = grub_util_get_os_disk (install_device);
|
||||
+ if (list)
|
||||
+ {
|
||||
+ int i;
|
||||
+ int ndisk = 0;
|
||||
+
|
||||
+ for (cur = list; cur; cur = cur->next)
|
||||
+ ++ndisk;
|
||||
+ efidir_grub_disk = xcalloc (ndisk + 1, sizeof (*efidir_grub_disk));
|
||||
+ for (cur = list, i = 0; i < ndisk; cur = cur->next, i++)
|
||||
+ efidir_grub_disk[i] = cur->disk;
|
||||
+ efidir_grub_disk[ndisk] = NULL;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ efidir_grub_disk = xcalloc (2, sizeof (*efidir_grub_disk));
|
||||
+ efidir_grub_disk[0] = efidir_grub_dev->disk;
|
||||
+ efidir_grub_disk[1] = NULL;
|
||||
+ }
|
||||
+ ret = grub_install_register_efi (efidir_grub_disk,
|
||||
+ efifile_path, efi_distributor,
|
||||
+ force_disk);
|
||||
+ while (list)
|
||||
+ {
|
||||
+ cur = list;
|
||||
+ list = list->next;
|
||||
+ grub_free (cur);
|
||||
+ }
|
||||
+ grub_free (force_disk);
|
||||
+ grub_free (efidir_grub_disk);
|
||||
if (ret)
|
||||
grub_util_error (_("efibootmgr failed to register the boot entry: %s"),
|
||||
strerror (ret));
|
109
0001-kern-mm.c-Make-grub_calloc-inline.patch
Normal file
109
0001-kern-mm.c-Make-grub_calloc-inline.patch
Normal file
@ -0,0 +1,109 @@
|
||||
From c2475f1337dff2e2a3e45514119d5186e55753c1 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 13 Aug 2020 09:36:45 +0800
|
||||
Subject: [PATCH] kern/mm.c : Make grub_calloc inline
|
||||
|
||||
To circumvent the situation that symbol 'grub_calloc' not found would
|
||||
happen if system is using stray grub (ie not managed by system update)
|
||||
as stage1 that can be too old to load updated modules.
|
||||
---
|
||||
grub-core/kern/mm.c | 28 ----------------------------
|
||||
include/grub/mm.h | 32 +++++++++++++++++++++++++++++++-
|
||||
2 files changed, 31 insertions(+), 29 deletions(-)
|
||||
|
||||
--- a/grub-core/kern/mm.c
|
||||
+++ b/grub-core/kern/mm.c
|
||||
@@ -63,14 +63,10 @@
|
||||
|
||||
#include <config.h>
|
||||
#include <grub/mm.h>
|
||||
-#include <grub/misc.h>
|
||||
-#include <grub/err.h>
|
||||
#include <grub/types.h>
|
||||
#include <grub/disk.h>
|
||||
#include <grub/dl.h>
|
||||
-#include <grub/i18n.h>
|
||||
#include <grub/mm_private.h>
|
||||
-#include <grub/safemath.h>
|
||||
|
||||
#ifdef MM_DEBUG
|
||||
# undef grub_calloc
|
||||
@@ -553,30 +549,6 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Allocate NMEMB instances of SIZE bytes and return the pointer, or error on
|
||||
- * integer overflow.
|
||||
- */
|
||||
-void *
|
||||
-grub_calloc (grub_size_t nmemb, grub_size_t size)
|
||||
-{
|
||||
- void *ret;
|
||||
- grub_size_t sz = 0;
|
||||
-
|
||||
- if (grub_mul (nmemb, size, &sz))
|
||||
- {
|
||||
- grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- ret = grub_memalign (0, sz);
|
||||
- if (!ret)
|
||||
- return NULL;
|
||||
-
|
||||
- grub_memset (ret, 0, sz);
|
||||
- return ret;
|
||||
-}
|
||||
-
|
||||
/* Allocate SIZE bytes and return the pointer. */
|
||||
void *
|
||||
grub_malloc (grub_size_t size)
|
||||
--- a/include/grub/mm.h
|
||||
+++ b/include/grub/mm.h
|
||||
@@ -47,7 +47,6 @@
|
||||
#endif
|
||||
|
||||
void grub_mm_init_region (void *addr, grub_size_t size);
|
||||
-void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size);
|
||||
void *EXPORT_FUNC(grub_malloc) (grub_size_t size);
|
||||
void *EXPORT_FUNC(grub_zalloc) (grub_size_t size);
|
||||
void EXPORT_FUNC(grub_free) (void *ptr);
|
||||
@@ -55,6 +54,37 @@
|
||||
#ifndef GRUB_MACHINE_EMU
|
||||
void *EXPORT_FUNC(grub_memalign) (grub_size_t align, grub_size_t size);
|
||||
#endif
|
||||
+#if !defined(GRUB_UTIL) && !defined (GRUB_MACHINE_EMU)
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/i18n.h>
|
||||
+#include <grub/safemath.h>
|
||||
+/*
|
||||
+ * Allocate NMEMB instances of SIZE bytes and return the pointer, or error on
|
||||
+ * integer overflow.
|
||||
+ */
|
||||
+static inline void *
|
||||
+grub_calloc (grub_size_t nmemb, grub_size_t size)
|
||||
+{
|
||||
+ void *ret;
|
||||
+ grub_size_t sz = 0;
|
||||
+
|
||||
+ if (grub_mul (nmemb, size, &sz))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ret = grub_memalign (0, sz);
|
||||
+ if (!ret)
|
||||
+ return NULL;
|
||||
+
|
||||
+ grub_memset (ret, 0, sz);
|
||||
+ return ret;
|
||||
+}
|
||||
+#else
|
||||
+void *EXPORT_FUNC(grub_calloc) (grub_size_t nmemb, grub_size_t size);
|
||||
+#endif
|
||||
|
||||
void grub_mm_check_real (const char *file, int line);
|
||||
#define grub_mm_check() grub_mm_check_real (GRUB_FILE, __LINE__);
|
197
0001-key_protector-Add-key-protectors-framework.patch
Normal file
197
0001-key_protector-Add-key-protectors-framework.patch
Normal file
@ -0,0 +1,197 @@
|
||||
From bf09618c47c6632b763960e265436294ab98dd43 Mon Sep 17 00:00:00 2001
|
||||
From: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Date: Tue, 1 Feb 2022 05:02:53 -0800
|
||||
Subject: [PATCH 1/5] key_protector: Add key protectors framework
|
||||
|
||||
A key protector encapsulates functionality to retrieve an unlocking key
|
||||
for a fully-encrypted disk from a specific source. A key protector
|
||||
module registers itself with the key protectors framework when it is
|
||||
loaded and unregisters when unloaded. Additionally, a key protector may
|
||||
accept parameters that describe how it should operate.
|
||||
|
||||
The key protectors framework, besides offering registration and
|
||||
unregistration functions, also offers a one-stop routine for finding and
|
||||
invoking a key protector by name. If a key protector with the specified
|
||||
name exists and if an unlocking key is successfully retrieved by it, the
|
||||
function returns to the caller the retrieved key and its length.
|
||||
|
||||
Cc: Vladimir Serbinenko <phcoder@gmail.com>
|
||||
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/Makefile.am | 1 +
|
||||
grub-core/Makefile.core.def | 5 +++
|
||||
grub-core/disk/key_protector.c | 78 ++++++++++++++++++++++++++++++++++
|
||||
include/grub/key_protector.h | 46 ++++++++++++++++++++
|
||||
4 files changed, 130 insertions(+)
|
||||
create mode 100644 grub-core/disk/key_protector.c
|
||||
create mode 100644 include/grub/key_protector.h
|
||||
|
||||
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
|
||||
index f18550c1c..9d3d5f519 100644
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -90,6 +90,7 @@ endif
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
|
||||
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/key_protector.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
|
||||
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
|
||||
diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
|
||||
index bc893e547..4307b8e2d 100644
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1302,6 +1302,11 @@ module = {
|
||||
common = disk/raid6_recover.c;
|
||||
};
|
||||
|
||||
+module = {
|
||||
+ name = key_protector;
|
||||
+ common = disk/key_protector.c;
|
||||
+};
|
||||
+
|
||||
module = {
|
||||
name = scsi;
|
||||
common = disk/scsi.c;
|
||||
diff --git a/grub-core/disk/key_protector.c b/grub-core/disk/key_protector.c
|
||||
new file mode 100644
|
||||
index 000000000..b84afe1c7
|
||||
--- /dev/null
|
||||
+++ b/grub-core/disk/key_protector.c
|
||||
@@ -0,0 +1,78 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2022 Microsoft 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/>.
|
||||
+ */
|
||||
+
|
||||
+#include <grub/dl.h>
|
||||
+#include <grub/list.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/key_protector.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
+
|
||||
+struct grub_key_protector *grub_key_protectors = NULL;
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_register (struct grub_key_protector *protector)
|
||||
+{
|
||||
+ if (protector == NULL || protector->name == NULL || grub_strlen (protector->name) == 0)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ if (grub_key_protectors &&
|
||||
+ grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors),
|
||||
+ protector->name))
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ grub_list_push (GRUB_AS_LIST_P (&grub_key_protectors),
|
||||
+ GRUB_AS_LIST (protector));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_unregister (struct grub_key_protector *protector)
|
||||
+{
|
||||
+ if (protector == NULL)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ grub_list_remove (GRUB_AS_LIST (protector));
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_recover_key (const char *protector, grub_uint8_t **key,
|
||||
+ grub_size_t *key_size)
|
||||
+{
|
||||
+ struct grub_key_protector *kp = NULL;
|
||||
+
|
||||
+ if (grub_key_protectors == NULL)
|
||||
+ return GRUB_ERR_OUT_OF_RANGE;
|
||||
+
|
||||
+ if (protector == NULL || grub_strlen (protector) == 0)
|
||||
+ return GRUB_ERR_BAD_ARGUMENT;
|
||||
+
|
||||
+ kp = grub_named_list_find (GRUB_AS_NAMED_LIST (grub_key_protectors),
|
||||
+ protector);
|
||||
+ if (kp == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
+ N_("A key protector with name '%s' could not be found. "
|
||||
+ "Is the name spelled correctly and is the "
|
||||
+ "corresponding module loaded?"), protector);
|
||||
+
|
||||
+ return kp->recover_key (key, key_size);
|
||||
+}
|
||||
diff --git a/include/grub/key_protector.h b/include/grub/key_protector.h
|
||||
new file mode 100644
|
||||
index 000000000..6e6a6fb24
|
||||
--- /dev/null
|
||||
+++ b/include/grub/key_protector.h
|
||||
@@ -0,0 +1,46 @@
|
||||
+/*
|
||||
+ * GRUB -- GRand Unified Bootloader
|
||||
+ * Copyright (C) 2022 Microsoft 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/>.
|
||||
+ */
|
||||
+
|
||||
+#ifndef GRUB_PROTECTOR_HEADER
|
||||
+#define GRUB_PROTECTOR_HEADER 1
|
||||
+
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/types.h>
|
||||
+
|
||||
+struct grub_key_protector
|
||||
+{
|
||||
+ struct grub_key_protector *next;
|
||||
+ struct grub_key_protector **prev;
|
||||
+
|
||||
+ const char *name;
|
||||
+
|
||||
+ grub_err_t (*recover_key) (grub_uint8_t **key, grub_size_t *key_size);
|
||||
+};
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_register (struct grub_key_protector *protector);
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_unregister (struct grub_key_protector *protector);
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_key_protector_recover_key (const char *protector,
|
||||
+ grub_uint8_t **key,
|
||||
+ grub_size_t *key_size);
|
||||
+
|
||||
+#endif /* ! GRUB_PROTECTOR_HEADER */
|
||||
--
|
||||
2.35.3
|
||||
|
@ -0,0 +1,43 @@
|
||||
From d683bed5c76c54e6bc5c26eef2f8d7136a3c75c4 Mon Sep 17 00:00:00 2001
|
||||
From: Ard Biesheuvel <ardb@kernel.org>
|
||||
Date: Thu, 11 Aug 2022 16:51:57 +0200
|
||||
Subject: [PATCH] loader/arm64/efi/linux: Remove magic number header field
|
||||
check
|
||||
|
||||
The "ARM\x64" magic number in the file header identifies an image as one
|
||||
that implements the bare metal boot protocol, allowing the loader to
|
||||
simply move the file to a suitably aligned address in memory, with
|
||||
sufficient headroom for the trailing .bss segment (the required memory
|
||||
size is described in the header as well).
|
||||
|
||||
Note of this matters for GRUB, as it only supports EFI boot. EFI does
|
||||
not care about this magic number, and nor should GRUB: this prevents us
|
||||
from booting other PE linux images, such as the generic EFI zboot
|
||||
decompressor, which is a pure PE/COFF image, and does not implement the
|
||||
bare metal boot protocol.
|
||||
|
||||
So drop the magic number check.
|
||||
|
||||
Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/loader/arm64/efi/linux.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/arm64/efi/linux.c b/grub-core/loader/arm64/efi/linux.c
|
||||
index 33df0e1fd..a9f5e05e4 100644
|
||||
--- a/grub-core/loader/arm64/efi/linux.c
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -57,9 +57,6 @@ static grub_addr_t initrd_end;
|
||||
static grub_err_t
|
||||
grub_arch_efi_linux_check_image (struct linux_arch_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)
|
||||
return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
|
||||
--
|
||||
2.43.0
|
||||
|
142
0001-luks2-Use-grub-tpm2-token-for-TPM2-protected-volume-.patch
Normal file
142
0001-luks2-Use-grub-tpm2-token-for-TPM2-protected-volume-.patch
Normal file
@ -0,0 +1,142 @@
|
||||
From 06af22d6c893b0249712e9a486e0cbae15160e5c Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 23 Oct 2023 16:11:53 +0800
|
||||
Subject: [PATCH] luks2: Use grub-tpm2 token for TPM2-protected volume unlock
|
||||
|
||||
This commit enables the use of the grub-tpm2 token for unlocking LUKS2
|
||||
volumes protected by TPM2. The token tracks keyslots associated with a
|
||||
sealed key, making the unsealing process more efficient and secure.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/disk/luks2.c | 81 ++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 79 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/luks2.c b/grub-core/disk/luks2.c
|
||||
index d5106402f..fe5ba777a 100644
|
||||
--- a/grub-core/disk/luks2.c
|
||||
+++ b/grub-core/disk/luks2.c
|
||||
@@ -124,6 +124,14 @@ struct grub_luks2_digest
|
||||
};
|
||||
typedef struct grub_luks2_digest grub_luks2_digest_t;
|
||||
|
||||
+struct grub_luks2_token_tpm
|
||||
+{
|
||||
+ grub_uint64_t idx;
|
||||
+ grub_uint64_t keyslots;
|
||||
+ const char *timestamp;
|
||||
+};
|
||||
+typedef struct grub_luks2_token_tpm grub_luks2_token_tpm_t;
|
||||
+
|
||||
gcry_err_code_t AF_merge (const gcry_md_spec_t * hash, grub_uint8_t * src,
|
||||
grub_uint8_t * dst, grub_size_t blocksize,
|
||||
grub_size_t blocknumbers);
|
||||
@@ -257,6 +265,39 @@ luks2_parse_digest (grub_luks2_digest_t *out, const grub_json_t *digest)
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+luks2_parse_token_tpm (grub_luks2_token_tpm_t *out, const grub_json_t *token)
|
||||
+{
|
||||
+ grub_json_t keyslots, o;
|
||||
+ grub_size_t i, size;
|
||||
+ grub_uint64_t bit;
|
||||
+ const char *type;
|
||||
+
|
||||
+ if (grub_json_getstring (&type, token, "type"))
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid token type");
|
||||
+ else if (grub_strcmp (type, "grub-tpm2"))
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ if (grub_json_getvalue (&keyslots, token, "keyslots") ||
|
||||
+ grub_json_getstring (&out->timestamp, token, "timestamp"))
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Missing token parameters");
|
||||
+
|
||||
+ if (grub_json_getsize (&size, &keyslots))
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ "Token references no keyslots");
|
||||
+
|
||||
+ out->keyslots = 0;
|
||||
+ for (i = 0; i < size; i++)
|
||||
+ {
|
||||
+ if (grub_json_getchild (&o, &keyslots, i) ||
|
||||
+ grub_json_getuint64 (&bit, &o, NULL))
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "Invalid keyslot");
|
||||
+ out->keyslots |= (1 << bit);
|
||||
+ }
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
luks2_get_keyslot (grub_luks2_keyslot_t *k, grub_luks2_digest_t *d, grub_luks2_segment_t *s,
|
||||
const grub_json_t *root, grub_size_t keyslot_json_idx)
|
||||
@@ -561,13 +602,14 @@ luks2_recover_key (grub_disk_t source,
|
||||
{
|
||||
grub_uint8_t candidate_key[GRUB_CRYPTODISK_MAX_KEYLEN];
|
||||
char cipher[32], *json_header = NULL, *ptr;
|
||||
- grub_size_t candidate_key_len = 0, json_idx, size;
|
||||
+ grub_size_t candidate_key_len = 0, json_idx, size, tsize;
|
||||
grub_luks2_header_t header;
|
||||
grub_luks2_keyslot_t keyslot;
|
||||
grub_luks2_digest_t digest;
|
||||
grub_luks2_segment_t segment;
|
||||
+ grub_luks2_token_tpm_t token_tpm;
|
||||
gcry_err_code_t gcry_ret;
|
||||
- grub_json_t *json = NULL, keyslots;
|
||||
+ grub_json_t *json = NULL, keyslots, tokens;
|
||||
grub_err_t ret;
|
||||
|
||||
if (cargs->key_data == NULL || cargs->key_len == 0)
|
||||
@@ -605,6 +647,37 @@ luks2_recover_key (grub_disk_t source,
|
||||
goto err;
|
||||
}
|
||||
|
||||
+ token_tpm.keyslots = 0;
|
||||
+ tsize = 0;
|
||||
+ if (cargs->protectors)
|
||||
+ {
|
||||
+ int i;
|
||||
+ for (i = 0; cargs->protectors[i]; i++)
|
||||
+ if (grub_strcmp(cargs->protectors[i], "tpm2") == 0)
|
||||
+ break;
|
||||
+
|
||||
+ if (!cargs->protectors[i] ||
|
||||
+ cargs->key_cache[i].invalid ||
|
||||
+ grub_json_getvalue (&tokens, json, "tokens") ||
|
||||
+ grub_json_getsize (&tsize, &tokens))
|
||||
+ grub_dprintf ("luks2", "No valid token or not a tpm2 protector\n");
|
||||
+ }
|
||||
+
|
||||
+ for (json_idx = 0; json_idx < tsize; json_idx++)
|
||||
+ {
|
||||
+ grub_json_t token;
|
||||
+
|
||||
+ if (grub_json_getchild (&token, &tokens, json_idx) ||
|
||||
+ grub_json_getuint64 (&token_tpm.idx, &token, NULL) ||
|
||||
+ grub_json_getchild (&token, &token, 0) ||
|
||||
+ luks2_parse_token_tpm (&token_tpm, &token))
|
||||
+ {
|
||||
+ grub_dprintf ("luks2", "Could not parse token index %" PRIuGRUB_SIZE "\n", json_idx);
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (grub_disk_native_sectors (source) == GRUB_DISK_SIZE_UNKNOWN)
|
||||
{
|
||||
/* FIXME: Allow use of source disk, and maybe cause errors in read. */
|
||||
@@ -641,6 +714,10 @@ luks2_recover_key (grub_disk_t source,
|
||||
continue;
|
||||
}
|
||||
|
||||
+ if (token_tpm.keyslots &&
|
||||
+ !(token_tpm.keyslots & (1 << keyslot.idx)))
|
||||
+ continue;
|
||||
+
|
||||
grub_dprintf ("luks2", "Trying keyslot \"%" PRIuGRUB_UINT64_T "\"\n", keyslot.idx);
|
||||
|
||||
/* Sector size should be one of 512, 1024, 2048, or 4096. */
|
||||
--
|
||||
2.42.0
|
||||
|
@ -0,0 +1,60 @@
|
||||
From d35ff22516b161f6d472f7f5371a89597b072d04 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 6 May 2024 10:34:22 +0800
|
||||
Subject: [PATCH] net/drivers/ieee1275/ofnet: Remove 200 ms timeout in
|
||||
get_card_packet() to reduce input latency
|
||||
|
||||
When GRUB image is netbooted on ppc64le, the keyboard input exhibits
|
||||
significant latency, reports even say that characters are processed
|
||||
about once per second. This issue makes interactively trying to debug
|
||||
a ppc64le config very difficult.
|
||||
|
||||
It seems that the latency is largely caused by a 200 ms timeout in the
|
||||
idle event loop, during which the network card interface is consistently
|
||||
polled for incoming packets. Often, no packets arrive during this
|
||||
period, so the timeout nearly always expires, which blocks the response
|
||||
to key inputs.
|
||||
|
||||
Furthermore, this 200 ms timeout might not need to be enforced at this
|
||||
basic layer, considering that GRUB performs synchronous reads and its
|
||||
timeout management is actually handled by higher layers, not directly in
|
||||
the card instance. Additionally, the idle polling, which reacts to
|
||||
unsolicited packets like ICMP and SLAAC, would be fine at a less frequent
|
||||
polling interval, rather than needing a timeout for receiving a response.
|
||||
|
||||
For these reasons, we believe the timeout in get_card_packet() should be
|
||||
effectively removed. According to test results, the delay has disappeared,
|
||||
and it is now much easier to use interactively.
|
||||
|
||||
Signed-Off-by: Michael Chang <mchang@suse.com>
|
||||
Tested-by: Tony Jones <tonyj@suse.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/net/drivers/ieee1275/ofnet.c | 8 ++------
|
||||
1 file changed, 2 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c
|
||||
index 78f03df8e..3bf48b3f0 100644
|
||||
--- a/grub-core/net/drivers/ieee1275/ofnet.c
|
||||
+++ b/grub-core/net/drivers/ieee1275/ofnet.c
|
||||
@@ -82,15 +82,11 @@ get_card_packet (struct grub_net_card *dev)
|
||||
grub_ssize_t actual;
|
||||
int rc;
|
||||
struct grub_ofnetcard_data *data = dev->data;
|
||||
- grub_uint64_t start_time;
|
||||
struct grub_net_buff *nb;
|
||||
|
||||
- start_time = grub_get_time_ms ();
|
||||
- do
|
||||
- rc = grub_ieee1275_read (data->handle, dev->rcvbuf, dev->rcvbufsize, &actual);
|
||||
- while ((actual <= 0 || rc < 0) && (grub_get_time_ms () - start_time < 200));
|
||||
+ rc = grub_ieee1275_read (data->handle, dev->rcvbuf, dev->rcvbufsize, &actual);
|
||||
|
||||
- if (actual <= 0)
|
||||
+ if (actual <= 0 || rc < 0)
|
||||
return NULL;
|
||||
|
||||
nb = grub_netbuff_alloc (actual + 2);
|
||||
--
|
||||
2.45.2
|
||||
|
170
0001-ofdisk-Enhance-canonical-path-handling-for-bootpath.patch
Normal file
170
0001-ofdisk-Enhance-canonical-path-handling-for-bootpath.patch
Normal file
@ -0,0 +1,170 @@
|
||||
From 84b95a121a4401be854614419ded3d383e14ac1f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 22 Mar 2024 17:38:45 +0800
|
||||
Subject: [PATCH] ofdisk: Enhance canonical path handling for bootpath
|
||||
|
||||
This commit addresses an issue where redundant canonical path
|
||||
translation is performed on the bootpath, potentially leading to
|
||||
incorrect results and subsequent boot failures, particularly in cases
|
||||
where firmware translations are inconsistent.
|
||||
|
||||
To mitigate this, the commit introduces a check to determine if the
|
||||
bootpath is already in canonical form, avoiding unnecessary translation.
|
||||
Additionally, improvements have been made to enhance the resilience of
|
||||
device iteration, enhancing compatibility with cross-device booting
|
||||
scenarios and addressing potential issues related to firmware-based
|
||||
canonical path retrieval.
|
||||
|
||||
These changes aim to improve the reliability and stability of the boot
|
||||
process.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/disk/ieee1275/ofdisk.c | 75 +++++++++++++++++++++++---------
|
||||
1 file changed, 55 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/ieee1275/ofdisk.c b/grub-core/disk/ieee1275/ofdisk.c
|
||||
index c5c20a5ec..36ee5314d 100644
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -35,8 +35,13 @@ static grub_ieee1275_ihandle_t last_ihandle;
|
||||
#define IEEE1275_DISK_ALIAS "/disk@"
|
||||
#define IEEE1275_NVMEOF_DISK_ALIAS "/nvme-of/controller@"
|
||||
|
||||
+/* Used to check boot_type, print debug message if doesn't match, this can be
|
||||
+ * useful to measure boot delays */
|
||||
static char *boot_type;
|
||||
+/* Used to restrict fcp to a physical boot path */
|
||||
static char *boot_parent;
|
||||
+/* Knowing the nvmeof in advance to avoid blind open test during iteration to
|
||||
+ * validate a path */
|
||||
static int is_boot_nvmeof;
|
||||
|
||||
struct ofdisk_hash_ent
|
||||
@@ -540,20 +545,30 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
{
|
||||
if (grub_strcmp (alias->type, "fcp") == 0)
|
||||
{
|
||||
- if (boot_type &&
|
||||
- grub_strcmp (boot_type, alias->type) != 0)
|
||||
+ if (boot_parent &&
|
||||
+ grub_strcmp (boot_parent, alias->path) != 0)
|
||||
{
|
||||
- grub_dprintf ("ofdisk", "Skipped device: %s, type %s did not match boot_type %s\n",
|
||||
- alias->path, alias->type, boot_type);
|
||||
+ grub_dprintf ("ofdisk", "Skipped device: %s, doesn't match boot_parent %s\n",
|
||||
+ alias->path, boot_parent);
|
||||
goto iter_children;
|
||||
}
|
||||
|
||||
- if (grub_strcmp (boot_parent, alias->path) == 0)
|
||||
+ /* Allow set boot_parent and boot_type to NULL to force iteration */
|
||||
+ if (!boot_parent)
|
||||
{
|
||||
- if (is_boot_nvmeof)
|
||||
- dev_iterate_fcp_nvmeof(alias);
|
||||
- else
|
||||
- dev_iterate_fcp_disks(alias);
|
||||
+ grub_dprintf ("ofdisk", "iterate %s\n", alias->path);
|
||||
+ dev_iterate_fcp_nvmeof(alias);
|
||||
+ dev_iterate_fcp_disks(alias);
|
||||
+ }
|
||||
+ else if (is_boot_nvmeof)
|
||||
+ {
|
||||
+ grub_dprintf ("ofdisk", "iterate nvmeof: %s\n", alias->path);
|
||||
+ dev_iterate_fcp_nvmeof(alias);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ grub_dprintf ("ofdisk", "iterate fcp: %s\n", alias->path);
|
||||
+ dev_iterate_fcp_disks(alias);
|
||||
}
|
||||
}
|
||||
else if (grub_strcmp (alias->type, "vscsi") == 0)
|
||||
@@ -575,9 +590,8 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
if (boot_type &&
|
||||
grub_strcmp (boot_type, alias->type) != 0)
|
||||
{
|
||||
- grub_dprintf ("ofdisk", "Skipped device: %s, type %s did not match boot_type %s\n",
|
||||
+ grub_dprintf ("ofdisk", "WARN: device: %s, type %s not match boot_type %s\n",
|
||||
alias->path, alias->type, boot_type);
|
||||
- return;
|
||||
}
|
||||
|
||||
if (grub_ieee1275_open (alias->path, &ihandle))
|
||||
@@ -646,9 +660,8 @@ dev_iterate (const struct grub_ieee1275_devalias *alias)
|
||||
if (boot_type &&
|
||||
grub_strcmp (boot_type, alias->type) != 0)
|
||||
{
|
||||
- grub_dprintf ("ofdisk", "Skipped device: %s, type %s did not match boot_type %s\n",
|
||||
+ grub_dprintf ("ofdisk", "WARN: device: %s, type %s not match boot_type %s\n",
|
||||
alias->path, alias->type, boot_type);
|
||||
- goto iter_children;
|
||||
}
|
||||
|
||||
buf = grub_malloc (grub_strlen (alias->path) +
|
||||
@@ -1116,13 +1129,37 @@ get_parent_devname (const char *devname, int *is_nvmeof)
|
||||
return parent;
|
||||
}
|
||||
|
||||
+
|
||||
+static int
|
||||
+is_canonical (const char *path)
|
||||
+{
|
||||
+ if (grub_strstr (path, IEEE1275_DISK_ALIAS) ||
|
||||
+ grub_strstr (path, IEEE1275_NVMEOF_DISK_ALIAS))
|
||||
+ return 1;
|
||||
+ else
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static char *
|
||||
get_boot_device_parent (const char *bootpath, int *is_nvmeof)
|
||||
{
|
||||
- char *dev, *canon, *parent;
|
||||
+ char *canon, *parent;
|
||||
+
|
||||
+ if (is_canonical (bootpath))
|
||||
+ {
|
||||
+ early_log ("Use %s as canonical\n", bootpath);
|
||||
+ canon = grub_strdup (bootpath);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ char *dev;
|
||||
|
||||
- dev = grub_ieee1275_get_aliasdevname (bootpath);
|
||||
- canon = grub_ieee1275_canonicalise_devname (dev);
|
||||
+ dev = grub_ieee1275_get_aliasdevname (bootpath);
|
||||
+ canon = grub_ieee1275_canonicalise_devname (dev);
|
||||
+ early_log ("bootpath: %s \n", bootpath);
|
||||
+ early_log ("alias: %s\n", dev);
|
||||
+ early_log ("canonical: %s\n", canon);
|
||||
+ }
|
||||
|
||||
if (!canon)
|
||||
{
|
||||
@@ -1131,8 +1168,6 @@ get_boot_device_parent (const char *bootpath, int *is_nvmeof)
|
||||
grub_print_error ();
|
||||
return NULL;
|
||||
}
|
||||
- else
|
||||
- early_log ("%s is canonical %s\n", bootpath, canon);
|
||||
|
||||
parent = get_parent_devname (canon, is_nvmeof);
|
||||
early_log ("%s is parent of %s\n", parent, canon);
|
||||
@@ -1179,9 +1214,9 @@ insert_bootpath (void)
|
||||
boot_parent = get_boot_device_parent (bootpath, &is_boot_nvmeof);
|
||||
boot_type = grub_ieee1275_get_device_type (boot_parent);
|
||||
if (boot_type)
|
||||
- early_log ("the boot device type %s is used for root device discovery, others excluded\n", boot_type);
|
||||
+ early_log ("the boot device type: %s\n", boot_type);
|
||||
else
|
||||
- early_log ("unknown boot device type, will use all devices to discover root and may be slow\n");
|
||||
+ early_log ("the boot device type is unknown\n");
|
||||
}
|
||||
grub_free (type);
|
||||
grub_free (bootpath);
|
||||
--
|
||||
2.44.0
|
||||
|
238
0001-ofdisk-enhance-boot-time-by-focusing-on-boot-disk-re.patch
Normal file
238
0001-ofdisk-enhance-boot-time-by-focusing-on-boot-disk-re.patch
Normal file
@ -0,0 +1,238 @@
|
||||
From b353ca96bf002a9262fdf74637f39615d003d069 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 8 Dec 2023 11:51:57 +0800
|
||||
Subject: [PATCH 1/2] ofdisk: enhance boot time by focusing on boot disk
|
||||
relevance
|
||||
|
||||
After a historical review, it's clear that a boot delay regression
|
||||
coincided with the introduction of the fcp iterating patch. Reverting
|
||||
this patch has shown promising signs in mitigating the issue. In order
|
||||
to improve the efficiency, a more refined discovery process is proposed,
|
||||
aiming to exclude device types differing from the boot disk to curtail
|
||||
unnecessary iterations.
|
||||
|
||||
This patch extends prior efforts by exclusively targeting root device
|
||||
discovery linked to the boot disk, verifying device types to prevent
|
||||
process elongation.
|
||||
|
||||
It is worth noting that grub's opportunistic approach to assembling the
|
||||
root device, seeking accessible results in parallel during iteration,
|
||||
sometimes allows even a partially assembled RAID, albeit in a degraded
|
||||
mode. However, delays stem from unrelated devices appearing before the
|
||||
actual boot device.
|
||||
|
||||
To streamline the boot process, the patch utilizes parent nodes in
|
||||
conjunction with block device nodes to extract essential boot-related
|
||||
information. This refined identification method efficiently limits the
|
||||
application's scope to devices connected to the chosen boot device,
|
||||
notably optimizing subsequent device iteration. By adeptly filtering out
|
||||
devices not linked to the same FCP (Fibre Channel Protocol) device, it
|
||||
significantly enhances boot efficiency, ensuring a more streamlined and
|
||||
efficient boot process.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/disk/ieee1275/ofdisk.c | 136 +++++++++++++++++++++++++++++--
|
||||
1 file changed, 131 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -31,6 +31,13 @@
|
||||
static char *last_devpath;
|
||||
static grub_ieee1275_ihandle_t last_ihandle;
|
||||
|
||||
+#define IEEE1275_DISK_ALIAS "/disk@"
|
||||
+#define IEEE1275_NVMEOF_DISK_ALIAS "/nvme-of/controller@"
|
||||
+
|
||||
+static char *boot_type;
|
||||
+static char *boot_parent;
|
||||
+static int is_boot_nvmeof;
|
||||
+
|
||||
struct ofdisk_hash_ent
|
||||
{
|
||||
char *devpath;
|
||||
@@ -529,12 +536,21 @@
|
||||
{
|
||||
if (grub_strcmp (alias->type, "fcp") == 0)
|
||||
{
|
||||
- // Iterate disks
|
||||
- dev_iterate_fcp_disks(alias);
|
||||
-
|
||||
- // Iterate NVMeoF
|
||||
- dev_iterate_fcp_nvmeof(alias);
|
||||
+ if (boot_type &&
|
||||
+ grub_strcmp (boot_type, alias->type) != 0)
|
||||
+ {
|
||||
+ grub_dprintf ("ofdisk", "Skipped device: %s, type %s did not match boot_type %s\n",
|
||||
+ alias->path, alias->type, boot_type);
|
||||
+ goto iter_children;
|
||||
+ }
|
||||
|
||||
+ if (grub_strcmp (boot_parent, alias->path) == 0)
|
||||
+ {
|
||||
+ if (is_boot_nvmeof)
|
||||
+ dev_iterate_fcp_nvmeof(alias);
|
||||
+ else
|
||||
+ dev_iterate_fcp_disks(alias);
|
||||
+ }
|
||||
}
|
||||
else if (grub_strcmp (alias->type, "vscsi") == 0)
|
||||
{
|
||||
@@ -552,6 +568,14 @@
|
||||
char *buf, *bufptr;
|
||||
unsigned i;
|
||||
|
||||
+ if (boot_type &&
|
||||
+ grub_strcmp (boot_type, alias->type) != 0)
|
||||
+ {
|
||||
+ grub_dprintf ("ofdisk", "Skipped device: %s, type %s did not match boot_type %s\n",
|
||||
+ alias->path, alias->type, boot_type);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
if (grub_ieee1275_open (alias->path, &ihandle))
|
||||
return;
|
||||
|
||||
@@ -615,6 +639,14 @@
|
||||
grub_uint16_t table_size;
|
||||
grub_ieee1275_ihandle_t ihandle;
|
||||
|
||||
+ if (boot_type &&
|
||||
+ grub_strcmp (boot_type, alias->type) != 0)
|
||||
+ {
|
||||
+ grub_dprintf ("ofdisk", "Skipped device: %s, type %s did not match boot_type %s\n",
|
||||
+ alias->path, alias->type, boot_type);
|
||||
+ goto iter_children;
|
||||
+ }
|
||||
+
|
||||
buf = grub_malloc (grub_strlen (alias->path) +
|
||||
sizeof ("/disk@7766554433221100"));
|
||||
if (!buf)
|
||||
@@ -674,6 +706,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
+ iter_children:
|
||||
{
|
||||
struct grub_ieee1275_devalias child;
|
||||
|
||||
@@ -1046,6 +1079,68 @@
|
||||
.next = 0
|
||||
};
|
||||
|
||||
+static char *
|
||||
+get_parent_devname (const char *devname, int *is_nvmeof)
|
||||
+{
|
||||
+ char *parent, *pptr;
|
||||
+
|
||||
+ if (is_nvmeof)
|
||||
+ *is_nvmeof = 0;
|
||||
+
|
||||
+ parent = grub_strdup (devname);
|
||||
+
|
||||
+ if (parent == NULL)
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ pptr = grub_strstr (parent, IEEE1275_DISK_ALIAS);
|
||||
+
|
||||
+ if (pptr != NULL)
|
||||
+ {
|
||||
+ *pptr = '\0';
|
||||
+ return parent;
|
||||
+ }
|
||||
+
|
||||
+ pptr = grub_strstr (parent, IEEE1275_NVMEOF_DISK_ALIAS);
|
||||
+
|
||||
+ if (pptr != NULL)
|
||||
+ {
|
||||
+ *pptr = '\0';
|
||||
+ if (is_nvmeof)
|
||||
+ *is_nvmeof = 1;
|
||||
+ return parent;
|
||||
+ }
|
||||
+
|
||||
+ return parent;
|
||||
+}
|
||||
+
|
||||
+static char *
|
||||
+get_boot_device_parent (const char *bootpath, int *is_nvmeof)
|
||||
+{
|
||||
+ char *dev, *canon, *parent;
|
||||
+
|
||||
+ dev = grub_ieee1275_get_aliasdevname (bootpath);
|
||||
+ canon = grub_ieee1275_canonicalise_devname (dev);
|
||||
+
|
||||
+ if (!canon)
|
||||
+ {
|
||||
+ /* This should not happen. */
|
||||
+ grub_error (GRUB_ERR_BAD_DEVICE, "canonicalise devname failed");
|
||||
+ grub_print_error ();
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ else
|
||||
+ grub_dprintf ("ofdisk", "%s is canonical %s\n", bootpath, canon);
|
||||
+
|
||||
+ parent = get_parent_devname (canon, is_nvmeof);
|
||||
+ grub_dprintf ("ofdisk", "%s is parent of %s\n", parent, canon);
|
||||
+
|
||||
+ grub_free (canon);
|
||||
+ return parent;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
insert_bootpath (void)
|
||||
{
|
||||
@@ -1081,6 +1176,12 @@
|
||||
char *device = grub_ieee1275_get_devname (bootpath);
|
||||
op = ofdisk_hash_add (device, NULL);
|
||||
op->is_boot = 1;
|
||||
+ boot_parent = get_boot_device_parent (bootpath, &is_boot_nvmeof);
|
||||
+ boot_type = grub_ieee1275_get_device_type (boot_parent);
|
||||
+ if (boot_type)
|
||||
+ grub_dprintf ("ofdisk", "the boot device type %s is used for root device discovery, others excluded\n", boot_type);
|
||||
+ else
|
||||
+ grub_dprintf ("ofdisk", "unknown boot device type, will use all devices to discover root and may be slow\n");
|
||||
}
|
||||
grub_free (type);
|
||||
grub_free (bootpath);
|
||||
@@ -1097,12 +1198,37 @@
|
||||
grub_disk_dev_unregister (&grub_ofdisk_dev);
|
||||
}
|
||||
|
||||
+static const char *
|
||||
+grub_env_get_boot_type (struct grub_env_var *var __attribute__ ((unused)),
|
||||
+ const char *val __attribute__ ((unused)))
|
||||
+{
|
||||
+ static char *ret;
|
||||
+
|
||||
+ if (!ret)
|
||||
+ ret = grub_xasprintf("boot: %s type: %s is_nvmeof: %d",
|
||||
+ boot_parent,
|
||||
+ boot_type ? : "unknown",
|
||||
+ is_boot_nvmeof);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+static char *
|
||||
+grub_env_set_boot_type (struct grub_env_var *var __attribute__ ((unused)),
|
||||
+ const char *val __attribute__ ((unused)))
|
||||
+{
|
||||
+ /* READ ONLY */
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
void
|
||||
grub_ofdisk_init (void)
|
||||
{
|
||||
grub_disk_firmware_fini = grub_ofdisk_fini;
|
||||
|
||||
insert_bootpath ();
|
||||
+ grub_register_variable_hook ("ofdisk_boot_type", grub_env_get_boot_type,
|
||||
+ grub_env_set_boot_type );
|
||||
|
||||
grub_disk_dev_register (&grub_ofdisk_dev);
|
||||
}
|
@ -0,0 +1,58 @@
|
||||
From b0f9dcabe96e5689ecfba9b6abcd27e685eabd48 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 11 May 2022 09:56:11 -0400
|
||||
Subject: [PATCH] ofdisk: improve boot time by lookup boot disk first
|
||||
|
||||
While booting lvm, grub will try to build up logical volumes via hooks
|
||||
to disk iteration where on-disk metadata can be read and parsed. However
|
||||
the process can become very slow on multipath as reachable disks are
|
||||
duplicated by multiple I/O paths and they all get inspected.
|
||||
|
||||
Fortunately grub allows lvm to be lazy binding and opportunistic that
|
||||
root volume can be created when it's needed using a smaller set of
|
||||
discovered disks. The disk iteration can also be controlled by pull
|
||||
methods to only returning specified disks. That said we may be able to
|
||||
take advantage of existing design to cause less overhead in lvm
|
||||
construction.
|
||||
|
||||
This patch will return boot disks in OpenFirmware so they can be used
|
||||
first. If lvm managed to create root volume out of those boot disks then
|
||||
it is all very nice as they are readily available. Otherwise disk
|
||||
scanning will be performed to present all discoverable disks to grub as
|
||||
what it was done in the past. The result maybe again time consuming but
|
||||
we have nothing to lose here.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/disk/ieee1275/ofdisk.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -491,10 +491,11 @@
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
- if (pull != GRUB_DISK_PULL_NONE)
|
||||
+ if (pull > GRUB_DISK_PULL_REMOVABLE)
|
||||
return 0;
|
||||
|
||||
- scan ();
|
||||
+ if (pull == GRUB_DISK_PULL_REMOVABLE)
|
||||
+ scan ();
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE (ofdisk_hash); i++)
|
||||
{
|
||||
@@ -532,6 +533,12 @@
|
||||
if (!ent->is_boot && ent->is_removable)
|
||||
continue;
|
||||
|
||||
+ if (pull == GRUB_DISK_PULL_NONE && !ent->is_boot)
|
||||
+ continue;
|
||||
+
|
||||
+ if (pull == GRUB_DISK_PULL_REMOVABLE && ent->is_boot)
|
||||
+ continue;
|
||||
+
|
||||
if (hook (ent->grub_shortest, hook_data))
|
||||
return 1;
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
From 468628bdc39800341e7aa6ff7795cc0d93cfaf3f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 11 Apr 2023 10:59:34 +0800
|
||||
Subject: [PATCH 1/2] openfw: Ensure get_devargs and get_devname functions are
|
||||
consistent
|
||||
|
||||
Commit 165c9b234 changed the logic of ieee1275_get_devargs() to use the
|
||||
first or second occurrence of a colon as a separator between device name
|
||||
and arguments. However, this didn't align with the complementary
|
||||
function ieee1275_get_devname, which uses the first occurrence of a
|
||||
colon after the namespace keyword as arguments for the nvme-of device.
|
||||
|
||||
This commit addresses the inconsistency by ensuring that both functions
|
||||
follow a common logic. Now, get_devargs and get_devname functions are
|
||||
consistent with each other, making it easier to understand and maintain
|
||||
the codebase.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/kern/ieee1275/openfw.c | 15 +++++++++------
|
||||
1 file changed, 9 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c
|
||||
index e2ffec32d..3bbd07d95 100644
|
||||
--- a/grub-core/kern/ieee1275/openfw.c
|
||||
+++ b/grub-core/kern/ieee1275/openfw.c
|
||||
@@ -354,13 +354,16 @@ static char *
|
||||
grub_ieee1275_get_devargs (const char *path)
|
||||
{
|
||||
char *colon = grub_strchr (path, ':');
|
||||
- char *colon_check = colon;
|
||||
|
||||
- /* Find the last occurence of colon */
|
||||
- while(colon_check){
|
||||
- colon = colon_check;
|
||||
- colon_check = grub_strchr (colon+1, ':');
|
||||
- }
|
||||
+ /* Use the same logic in grub_ieee1275_get_devname for nvme-of arguments */
|
||||
+ if (grub_strstr(path, "nvme-of"))
|
||||
+ {
|
||||
+ char *namespace_split = grub_strstr(path,"/namespace@");
|
||||
+ if (namespace_split)
|
||||
+ colon = grub_strchr (namespace_split, ':');
|
||||
+ else
|
||||
+ colon = NULL;
|
||||
+ }
|
||||
|
||||
if (! colon)
|
||||
return 0;
|
||||
--
|
||||
2.39.2
|
||||
|
@ -0,0 +1,60 @@
|
||||
From 72a582b1c3954f9b917a4d687c95fc94faf551c6 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 24 Jan 2024 18:03:51 +0800
|
||||
Subject: [PATCH] squash! ieee1275/ofpath: enable NVMeoF logical device
|
||||
translation
|
||||
|
||||
Fixes build error on gcc-14:
|
||||
|
||||
[ 73s] In file included from ../grub-core/osdep/ofpath.c:2:
|
||||
[ 73s] ../grub-core/osdep/linux/ofpath.c: In function 'of_find_fc_host':
|
||||
[ 73s] ../grub-core/osdep/linux/ofpath.c:427:22: error: allocation of insufficient size '8' for type 'struct ofpath_files_list_root' with size '16' [-Werror=alloc-size]
|
||||
[ 73s] 427 | portnames_file_list=malloc(sizeof(portnames_file_list));
|
||||
[ 73s] | ^
|
||||
[ 73s] ../grub-core/osdep/linux/ofpath.c: In function 'of_path_of_nvme':
|
||||
[ 73s] ../grub-core/osdep/linux/ofpath.c:589:21: error: allocation of insufficient size '8' for type 'struct ofpath_nvmeof_info' with size '32' [-Werror=alloc-size]
|
||||
[ 73s] 589 | nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
[ 73s] | ^
|
||||
[ 73s] ../grub-core/osdep/linux/ofpath.c:618:21: error: allocation of insufficient size '8' for type 'struct ofpath_nvmeof_info' with size '32' [-Werror=alloc-size]
|
||||
[ 73s] 618 | nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
[ 73s] | ^
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 7129099db..55ed7ddf2 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -424,7 +424,7 @@ of_find_fc_host(char* host_wwpn){
|
||||
|
||||
struct ofpath_files_list_root* portnames_file_list;
|
||||
|
||||
- portnames_file_list=malloc(sizeof(portnames_file_list));
|
||||
+ portnames_file_list=malloc(sizeof(*portnames_file_list));
|
||||
portnames_file_list->items=0;
|
||||
portnames_file_list->first=NULL;
|
||||
|
||||
@@ -586,7 +586,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
/* If is a NVMeoF */
|
||||
if(strstr(sysfs_path,"nvme-fabrics")){
|
||||
struct ofpath_nvmeof_info* nvmeof_info;
|
||||
- nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
+ nvmeof_info = malloc(sizeof(*nvmeof_info));
|
||||
|
||||
of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info);
|
||||
|
||||
@@ -615,7 +615,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
sysfs_path = nvme_get_syspath (device);
|
||||
if(strstr(sysfs_path,"nvme-fabrics")){
|
||||
struct ofpath_nvmeof_info* nvmeof_info;
|
||||
- nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
+ nvmeof_info = malloc(sizeof(*nvmeof_info));
|
||||
|
||||
of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info);
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
@ -0,0 +1,40 @@
|
||||
From 60d1d3b959e72c2cbd014be311c350a9b11b1289 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 7 Sep 2021 10:06:50 +0800
|
||||
Subject: [PATCH] templates: Follow the path of usr merged kernel config
|
||||
|
||||
The background for usr merge can be found at:
|
||||
|
||||
https://www.freedesktop.org/wiki/Software/systemd/TheCaseForTheUsrMerge/
|
||||
|
||||
This patch adapts related mkconfig scripts to follow the usr merge for
|
||||
looking up kernel configs.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub.d/10_linux.in | 2 +-
|
||||
util/grub.d/20_linux_xen.in | 2 +-
|
||||
2 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/util/grub.d/10_linux.in
|
||||
+++ b/util/grub.d/10_linux.in
|
||||
@@ -351,7 +351,7 @@
|
||||
fi
|
||||
|
||||
config=
|
||||
- for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do
|
||||
+ for i in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" "/usr/lib/modules/${version}/config" ; do
|
||||
if test -e "${i}" ; then
|
||||
config="${i}"
|
||||
break
|
||||
--- a/util/grub.d/20_linux_xen.in
|
||||
+++ b/util/grub.d/20_linux_xen.in
|
||||
@@ -307,7 +307,7 @@
|
||||
version=$(echo $basename | sed -e "s,^[^0-9]*-,,g")
|
||||
dirname=$(dirname $i)
|
||||
config=
|
||||
- for j in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" ; do
|
||||
+ for j in "${dirname}/config-${version}" "${dirname}/config-${alt_version}" "/etc/kernels/kernel-config-${version}" "/usr/lib/modules/${version}/config" ; do
|
||||
if test -e "${j}" ; then
|
||||
config="${j}"
|
||||
break
|
97
0001-tpm2-Add-extra-RSA-SRK-types.patch
Normal file
97
0001-tpm2-Add-extra-RSA-SRK-types.patch
Normal file
@ -0,0 +1,97 @@
|
||||
From f41a45b080cb9c6f59879a3e23f9ec2380015a16 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 25 Apr 2024 16:21:45 +0800
|
||||
Subject: [PATCH] tpm2: Add extra RSA SRK types
|
||||
|
||||
Since fde-tools may set RSA3072 and RSA4096 as the SRK type, grub2 has
|
||||
to support those parameters.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/tpm2/args.c | 12 ++++++++++++
|
||||
grub-core/tpm2/module.c | 16 ++++++++++++++--
|
||||
util/grub-protect.c | 4 ++--
|
||||
3 files changed, 28 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/grub-core/tpm2/args.c b/grub-core/tpm2/args.c
|
||||
index c11280ab9..d140364d2 100644
|
||||
--- a/grub-core/tpm2/args.c
|
||||
+++ b/grub-core/tpm2/args.c
|
||||
@@ -92,6 +92,18 @@ grub_tpm2_protector_parse_asymmetric (const char *value,
|
||||
srk_type->type = TPM_ALG_RSA;
|
||||
srk_type->detail.rsa_bits = 2048;
|
||||
}
|
||||
+ else if (grub_strcasecmp (value, "RSA") == 0 ||
|
||||
+ grub_strcasecmp (value, "RSA3072") == 0)
|
||||
+ {
|
||||
+ srk_type->type = TPM_ALG_RSA;
|
||||
+ srk_type->detail.rsa_bits = 3072;
|
||||
+ }
|
||||
+ else if (grub_strcasecmp (value, "RSA") == 0 ||
|
||||
+ grub_strcasecmp (value, "RSA4096") == 0)
|
||||
+ {
|
||||
+ srk_type->type = TPM_ALG_RSA;
|
||||
+ srk_type->detail.rsa_bits = 4096;
|
||||
+ }
|
||||
else
|
||||
return grub_error (GRUB_ERR_OUT_OF_RANGE,
|
||||
N_("Value '%s' is not a valid asymmetric key type"),
|
||||
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
|
||||
index b754b38df..8b72ed6fa 100644
|
||||
--- a/grub-core/tpm2/module.c
|
||||
+++ b/grub-core/tpm2/module.c
|
||||
@@ -136,8 +136,8 @@ static const struct grub_arg_option grub_tpm2_protector_init_cmd_options[] =
|
||||
.arg = NULL,
|
||||
.type = ARG_TYPE_STRING,
|
||||
.doc =
|
||||
- N_("In SRK mode, the type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)"
|
||||
- "(default: ECC)"),
|
||||
+ N_("In SRK mode, the type of SRK: RSA (RSA2048), RSA3072, RSA4096, "
|
||||
+ "and ECC (ECC_NIST_P256). (default: ECC)"),
|
||||
},
|
||||
/* NV Index-mode options */
|
||||
{
|
||||
@@ -541,6 +541,10 @@ srk_type_to_name (grub_srk_type_t srk_type)
|
||||
{
|
||||
case 2048:
|
||||
return "RSA2048";
|
||||
+ case 3072:
|
||||
+ return "RSA3072";
|
||||
+ case 4096:
|
||||
+ return "RSA4096";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,6 +565,14 @@ grub_tpm2_protector_load_key (const struct grub_tpm2_protector_context *ctx,
|
||||
.type = TPM_ALG_ECC,
|
||||
.detail.ecc_curve = TPM_ECC_NIST_P256,
|
||||
},
|
||||
+ {
|
||||
+ .type = TPM_ALG_RSA,
|
||||
+ .detail.rsa_bits = 4096,
|
||||
+ },
|
||||
+ {
|
||||
+ .type = TPM_ALG_RSA,
|
||||
+ .detail.rsa_bits = 3072,
|
||||
+ },
|
||||
{
|
||||
.type = TPM_ALG_RSA,
|
||||
.detail.rsa_bits = 2048,
|
||||
diff --git a/util/grub-protect.c b/util/grub-protect.c
|
||||
index 869f45861..00be03ca0 100644
|
||||
--- a/util/grub-protect.c
|
||||
+++ b/util/grub-protect.c
|
||||
@@ -199,8 +199,8 @@ static struct argp_option grub_protect_options[] =
|
||||
.arg = "TYPE",
|
||||
.flags = 0,
|
||||
.doc =
|
||||
- N_("The type of SRK: RSA (RSA2048) and ECC (ECC_NIST_P256)."
|
||||
- "(default: ECC)"),
|
||||
+ N_("The type of SRK: RSA (RSA2048), RSA3072, RSA4096, "
|
||||
+ "and ECC (ECC_NIST_P256). (default: ECC)"),
|
||||
.group = 0
|
||||
},
|
||||
{
|
||||
--
|
||||
2.35.3
|
||||
|
82
0001-tpm2-Implement-NV-index.patch
Normal file
82
0001-tpm2-Implement-NV-index.patch
Normal file
@ -0,0 +1,82 @@
|
||||
From 947009d79e3f17b10a7753bdde8d3a4a7b757bed Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Colp <patrick.colp@oracle.com>
|
||||
Date: Mon, 31 Jul 2023 07:01:45 -0700
|
||||
Subject: [PATCH 1/4] tpm2: Implement NV index
|
||||
|
||||
Currently with the TPM2 protector, only SRK mode is supported and
|
||||
NV index support is just a stub. Implement the NV index option.
|
||||
|
||||
Note: This only extends support on the unseal path. grub2_protect
|
||||
has not been updated. tpm2-tools can be used to insert a key into
|
||||
the NV index.
|
||||
|
||||
An example of inserting a key using tpm2-tools:
|
||||
|
||||
# Get random key.
|
||||
tpm2_getrandom 32 > key.dat
|
||||
|
||||
# Create primary object.
|
||||
tpm2_createprimary -C o -g sha256 -G ecc -c primary.ctx
|
||||
|
||||
# Create policy object. `pcrs.dat` contains the PCR values to seal against.
|
||||
tpm2_startauthsession -S session.dat
|
||||
tpm2_policypcr -S session.dat -l sha256:7,11 -f pcrs.dat -L policy.dat
|
||||
tpm2_flushcontext session.dat
|
||||
|
||||
# Seal key into TPM.
|
||||
cat key.dat | tpm2_create -C primary.ctx -u key.pub -r key.priv -L policy.dat -i-
|
||||
tpm2_load -C primary.ctx -u key.pub -r key.priv -n sealing.name -c sealing.ctx
|
||||
tpm2_evictcontrol -C o -c sealing.ctx 0x81000000
|
||||
|
||||
Then to unseal the key in grub, add this to grub.cfg:
|
||||
|
||||
tpm2_key_protector_init --mode=nv --nvindex=0x81000000 --pcrs=7,11
|
||||
cryptomount -u <UUID> --protector tpm2
|
||||
|
||||
Signed-off-by: Patrick Colp <patrick.colp@oracle.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/tpm2/module.c | 25 ++++++++++++++++++++-----
|
||||
1 file changed, 20 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
|
||||
index e83b02865..b754b38df 100644
|
||||
--- a/grub-core/tpm2/module.c
|
||||
+++ b/grub-core/tpm2/module.c
|
||||
@@ -1035,12 +1035,27 @@ static grub_err_t
|
||||
grub_tpm2_protector_nv_recover (const struct grub_tpm2_protector_context *ctx,
|
||||
grub_uint8_t **key, grub_size_t *key_size)
|
||||
{
|
||||
- (void)ctx;
|
||||
- (void)key;
|
||||
- (void)key_size;
|
||||
+ TPM_HANDLE sealed_handle = ctx->nv;
|
||||
+ tpm2key_policy_t policy_seq = NULL;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ /* Create a basic policy sequence based on the given PCR selection */
|
||||
+ err = grub_tpm2_protector_simple_policy_seq (ctx, &policy_seq);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ goto exit;
|
||||
+
|
||||
+ err = grub_tpm2_protector_unseal (policy_seq, sealed_handle, key, key_size);
|
||||
+
|
||||
+ /* Pop error messages on success */
|
||||
+ if (err == GRUB_ERR_NONE)
|
||||
+ while (grub_error_pop ());
|
||||
+
|
||||
+exit:
|
||||
+ TPM2_FlushContext (sealed_handle);
|
||||
|
||||
- return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
- N_("NV Index mode is not implemented yet"));
|
||||
+ grub_tpm2key_free_policy_seq (policy_seq);
|
||||
+
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
--
|
||||
2.35.3
|
||||
|
171
0001-tpm2-Support-authorized-policy.patch
Normal file
171
0001-tpm2-Support-authorized-policy.patch
Normal file
@ -0,0 +1,171 @@
|
||||
From 26a66098d5fa50b9462c8c815429a4c18f20310b Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 6 Apr 2023 16:00:25 +0800
|
||||
Subject: [PATCH] tpm2: Support authorized policy
|
||||
|
||||
This commit handles the TPM2_PolicyAuthorize command from the key file
|
||||
in TPM 2.0 Key File format.
|
||||
|
||||
TPM2_PolicyAuthorize is the essential command to support authorized
|
||||
policy which allows the users to sign TPM policies with their own keys.
|
||||
Per TPM 2.0 Key File(*1), CommandPolicy for TPM2_PolicyAuthorize
|
||||
comprises 'TPM2B_PUBLIC pubkey', 'TPM2B_DIGEST policy_ref', and
|
||||
'TPMT_SIGNATURE signature'. To verify the signature, the current policy
|
||||
digest is hashed with the hash algorithm written in 'signature', and then
|
||||
'signature' is verified with the hashed policy digest and 'pubkey'. Once
|
||||
TPM accepts 'signature', TPM2_PolicyAuthorize is invoked to authorize the
|
||||
signed policy.
|
||||
|
||||
To create the key file with authorized policy, here are the pcr-oracle(*2)
|
||||
commands:
|
||||
|
||||
# Generate the RSA key and create the authorized policy file
|
||||
$ pcr-oracle \
|
||||
--rsa-generate-key \
|
||||
--private-key policy-key.pem \
|
||||
--auth authorized.policy \
|
||||
create-authorized-policy 0,2,4,7,9
|
||||
|
||||
# Seal the secret with the authorized policy
|
||||
$ pcr-oracle \
|
||||
--key-format tpm2.0 \
|
||||
--auth authorized.policy \
|
||||
--input disk-secret.txt \
|
||||
--output sealed.key \
|
||||
seal-secret
|
||||
|
||||
# Sign the predicted PCR policy
|
||||
$ pcr-oracle \
|
||||
--key-format tpm2.0 \
|
||||
--private-key policy-key.pem \
|
||||
--from eventlog \
|
||||
--stop-event "grub-file=grub.cfg" \
|
||||
--after \
|
||||
--input sealed.key \
|
||||
--output sealed.tpm \
|
||||
sign 0,2,4,7,9
|
||||
|
||||
Then specify the key file and the key protector to grub.cfg in the EFI
|
||||
system partition:
|
||||
|
||||
tpm2_key_protector_init -a RSA --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm
|
||||
cryptomount -u <PART_UUID> -P tpm2
|
||||
|
||||
For any change in the boot components, just run the 'sign' command again
|
||||
to update the signature in sealed.tpm, and TPM can unseal the key file
|
||||
with the updated PCR policy.
|
||||
|
||||
(*1) https://www.hansenpartnership.com/draft-bottomley-tpm2-keys.html
|
||||
(*2) https://github.com/okirch/pcr-oracle
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/tpm2/module.c | 84 +++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 84 insertions(+)
|
||||
|
||||
diff --git a/grub-core/tpm2/module.c b/grub-core/tpm2/module.c
|
||||
index 3db25ceca..e83b02865 100644
|
||||
--- a/grub-core/tpm2/module.c
|
||||
+++ b/grub-core/tpm2/module.c
|
||||
@@ -650,6 +650,87 @@ grub_tpm2_protector_policypcr (TPMI_SH_AUTH_SESSION session,
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+grub_tpm2_protector_policyauthorize (TPMI_SH_AUTH_SESSION session,
|
||||
+ struct grub_tpm2_buffer *cmd_buf)
|
||||
+{
|
||||
+ TPM2B_PUBLIC pubkey;
|
||||
+ TPM2B_DIGEST policy_ref;
|
||||
+ TPMT_SIGNATURE signature;
|
||||
+ TPM2B_DIGEST pcr_policy;
|
||||
+ TPM2B_DIGEST pcr_policy_hash;
|
||||
+ TPMI_ALG_HASH sig_hash;
|
||||
+ TPMT_TK_VERIFIED verification_ticket;
|
||||
+ TPM_HANDLE pubkey_handle = 0;
|
||||
+ TPM2B_NAME pubname;
|
||||
+ TPM_RC rc;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ grub_tpm2_mu_TPM2B_PUBLIC_Unmarshal (cmd_buf, &pubkey);
|
||||
+ grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (cmd_buf, &policy_ref);
|
||||
+ grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (cmd_buf, &signature);
|
||||
+ if (cmd_buf->error != 0)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("Failed to unmarshal the buffer for TPM2_PolicyAuthorize"));
|
||||
+
|
||||
+ /* Retrieve Policy Digest */
|
||||
+ rc = TPM2_PolicyGetDigest (session, NULL, &pcr_policy, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to get policy digest (TPM2_PolicyGetDigest: 0x%x)."),
|
||||
+ rc);
|
||||
+
|
||||
+ /* Calculate the digest of the polcy for VerifySignature */
|
||||
+ sig_hash = TPMT_SIGNATURE_get_hash_alg (&signature);
|
||||
+ if (sig_hash == TPM_ALG_NULL)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ N_("Failed to get the hash algorithm of the signature"));
|
||||
+
|
||||
+ rc = TPM2_Hash (NULL, (TPM2B_MAX_BUFFER *)&pcr_policy, sig_hash,
|
||||
+ TPM_RH_NULL, &pcr_policy_hash, NULL, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to create PCR policy hash (TPM2_Hash: 0x%x)"),
|
||||
+ rc);
|
||||
+
|
||||
+ /* Load the public key */
|
||||
+ rc = TPM2_LoadExternal (NULL, NULL, &pubkey, TPM_RH_OWNER,
|
||||
+ &pubkey_handle, &pubname, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to load public key (TPM2_LoadExternal: 0x%x)"),
|
||||
+ rc);
|
||||
+
|
||||
+ /* Verify the signature against the public key and the policy digest */
|
||||
+ rc = TPM2_VerifySignature (pubkey_handle, NULL, &pcr_policy_hash, &signature,
|
||||
+ &verification_ticket, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to verify signature (TPM2_VerifySignature: 0x%x)"),
|
||||
+ rc);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ /* Authorize the signed policy with the public key and the verification ticket */
|
||||
+ rc = TPM2_PolicyAuthorize (session, NULL, &pcr_policy, &policy_ref, &pubname,
|
||||
+ &verification_ticket, NULL);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_BAD_DEVICE,
|
||||
+ N_("Failed to authorize PCR policy (TPM2_PolicyAuthorize: 0x%x)"),
|
||||
+ rc);
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ err = GRUB_ERR_NONE;
|
||||
+
|
||||
+error:
|
||||
+ TPM2_FlushContext (pubkey_handle);
|
||||
+
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSION session)
|
||||
{
|
||||
@@ -669,6 +750,9 @@ grub_tpm2_protector_enforce_policy (tpm2key_policy_t policy, TPMI_SH_AUTH_SESSIO
|
||||
case TPM_CC_PolicyPCR:
|
||||
err = grub_tpm2_protector_policypcr (session, &buf);
|
||||
break;
|
||||
+ case TPM_CC_PolicyAuthorize:
|
||||
+ err = grub_tpm2_protector_policyauthorize (session, &buf);
|
||||
+ break;
|
||||
default:
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
N_("Unknown TPM Command: 0x%x"), policy->cmd_code);
|
||||
--
|
||||
2.35.3
|
||||
|
188
0001-util-bash-completion-Fix-for-bash-completion-2.12.patch
Normal file
188
0001-util-bash-completion-Fix-for-bash-completion-2.12.patch
Normal file
@ -0,0 +1,188 @@
|
||||
From 200dc727d1fdf3bac7aa725569b60a54b3841867 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Fri, 22 Mar 2024 16:23:38 +0800
|
||||
Subject: [PATCH] util/bash-completion: Fix for bash-completion 2.12
|
||||
|
||||
_split_longopt() was the bash-completion private API and removed since
|
||||
bash-completion 2.12. This commit initializes the bash-completion
|
||||
general variables with _init_completion() to avoid the potential
|
||||
'command not found' error.
|
||||
|
||||
Although bash-completion 2.12 introduces _comp_initialize() to deprecate
|
||||
_init_completion(), _init_completion() is still chosen for the better
|
||||
backward compatibility.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
.../bash-completion.d/grub-completion.bash.in | 61 +++++++------------
|
||||
1 file changed, 22 insertions(+), 39 deletions(-)
|
||||
|
||||
diff --git a/util/bash-completion.d/grub-completion.bash.in b/util/bash-completion.d/grub-completion.bash.in
|
||||
index 4c88ee901..749a5d3cf 100644
|
||||
--- a/util/bash-completion.d/grub-completion.bash.in
|
||||
+++ b/util/bash-completion.d/grub-completion.bash.in
|
||||
@@ -151,13 +151,10 @@ __grub_list_modules () {
|
||||
# grub-set-default & grub-reboot
|
||||
#
|
||||
__grub_set_entry () {
|
||||
- local cur prev split=false
|
||||
+ local cur prev words cword split
|
||||
+ _init_completion -s || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
-
|
||||
- _split_longopt && split=true
|
||||
|
||||
case "$prev" in
|
||||
--boot-directory)
|
||||
@@ -180,11 +177,10 @@ __grub_set_entry () {
|
||||
# grub-editenv
|
||||
#
|
||||
__grub_editenv () {
|
||||
- local cur prev
|
||||
+ local cur prev words cword
|
||||
+ _init_completion || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
|
||||
case "$prev" in
|
||||
create|list|set|unset)
|
||||
@@ -201,10 +197,10 @@ __grub_editenv () {
|
||||
# grub-mkconfig
|
||||
#
|
||||
__grub_mkconfig () {
|
||||
- local cur prev
|
||||
+ local cur prev words cword
|
||||
+ _init_completion || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
|
||||
if [[ "$cur" == -* ]]; then
|
||||
__grubcomp "$(__grub_get_options_from_help)"
|
||||
@@ -217,13 +213,10 @@ __grub_mkconfig () {
|
||||
# grub-setup
|
||||
#
|
||||
__grub_setup () {
|
||||
- local cur prev split=false
|
||||
+ local cur prev words cword split
|
||||
+ _init_completion -s || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
-
|
||||
- _split_longopt && split=true
|
||||
|
||||
case "$prev" in
|
||||
-d|--directory)
|
||||
@@ -246,15 +239,12 @@ __grub_setup () {
|
||||
# grub-install
|
||||
#
|
||||
__grub_install () {
|
||||
- local cur prev last split=false
|
||||
+ local cur prev words cword split last
|
||||
+ _init_completion -s || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
last=$(__grub_get_last_option)
|
||||
|
||||
- _split_longopt && split=true
|
||||
-
|
||||
case "$prev" in
|
||||
--boot-directory)
|
||||
_filedir -d
|
||||
@@ -287,10 +277,10 @@ __grub_install () {
|
||||
# grub-mkfont
|
||||
#
|
||||
__grub_mkfont () {
|
||||
- local cur
|
||||
+ local cur prev words cword
|
||||
+ _init_completion || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
|
||||
if [[ "$cur" == -* ]]; then
|
||||
__grubcomp "$(__grub_get_options_from_help)"
|
||||
@@ -304,11 +294,10 @@ __grub_mkfont () {
|
||||
# grub-mkrescue
|
||||
#
|
||||
__grub_mkrescue () {
|
||||
- local cur prev last
|
||||
+ local cur prev words cword last
|
||||
+ _init_completion || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
last=$(__grub_get_last_option)
|
||||
|
||||
if [[ "$cur" == -* ]]; then
|
||||
@@ -330,13 +319,10 @@ __grub_mkrescue () {
|
||||
# grub-mkimage
|
||||
#
|
||||
__grub_mkimage () {
|
||||
- local cur prev split=false
|
||||
+ local cur prev words cword split
|
||||
+ _init_completion -s || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
-
|
||||
- _split_longopt && split=true
|
||||
|
||||
case "$prev" in
|
||||
-d|--directory|-p|--prefix)
|
||||
@@ -367,10 +353,10 @@ __grub_mkimage () {
|
||||
# grub-mkpasswd-pbkdf2
|
||||
#
|
||||
__grub_mkpasswd_pbkdf2 () {
|
||||
- local cur
|
||||
+ local cur prev words cword
|
||||
+ _init_completion || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
|
||||
if [[ "$cur" == -* ]]; then
|
||||
__grubcomp "$(__grub_get_options_from_help)"
|
||||
@@ -384,13 +370,10 @@ __grub_mkpasswd_pbkdf2 () {
|
||||
# grub-probe
|
||||
#
|
||||
__grub_probe () {
|
||||
- local cur prev split=false
|
||||
+ local cur prev words cword split
|
||||
+ _init_completion -s || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
- prev=${COMP_WORDS[COMP_CWORD-1]}
|
||||
-
|
||||
- _split_longopt && split=true
|
||||
|
||||
case "$prev" in
|
||||
-t|--target)
|
||||
@@ -417,10 +400,10 @@ __grub_probe () {
|
||||
# grub-script-check
|
||||
#
|
||||
__grub_script_check () {
|
||||
- local cur
|
||||
+ local cur prev words cword
|
||||
+ _init_completion || return
|
||||
|
||||
COMPREPLY=()
|
||||
- cur=`_get_cword`
|
||||
|
||||
if [[ "$cur" == -* ]]; then
|
||||
__grubcomp "$(__grub_get_options_from_help)"
|
||||
--
|
||||
2.35.3
|
||||
|
33
0001-util-enable-grub-protect-only-for-EFI-systems.patch
Normal file
33
0001-util-enable-grub-protect-only-for-EFI-systems.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From 6ce53d4db8430de5526ea4c48beac8139ba60925 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Mon, 20 May 2024 14:19:58 +0800
|
||||
Subject: [PATCH] util: enable grub-protect only for EFI systems
|
||||
|
||||
Add 'enable = efi;' back to the grub-protect section to enable the
|
||||
utility only for EFI systems.
|
||||
|
||||
The restriction was relaxed in the upstreaming patch to enable the
|
||||
grub-emu TPM2 testcases. Since we already build the utility natively for
|
||||
the architectures with EFI support, there is no need to build the
|
||||
program again for grub-emu.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
Makefile.util.def | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def
|
||||
index 90850125d..5085152b0 100644
|
||||
--- a/Makefile.util.def
|
||||
+++ b/Makefile.util.def
|
||||
@@ -210,6 +210,7 @@ program = {
|
||||
program = {
|
||||
name = grub-protect;
|
||||
mansection = 1;
|
||||
+ enable = efi;
|
||||
|
||||
common = grub-core/kern/emu/argp_common.c;
|
||||
common = grub-core/osdep/init.c;
|
||||
--
|
||||
2.35.3
|
||||
|
@ -0,0 +1,83 @@
|
||||
From 6c06378c1bf6ae21788427e62ab0011b7f1bc2f0 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 25 Nov 2022 16:11:24 +0800
|
||||
Subject: [PATCH] xen_boot: add missing grub_arch_efi_linux_load_image_header
|
||||
|
||||
The new xen_boot module has used grub_arch_efi_linux_load_image_header
|
||||
exported by grub-core/loader/arm64/linux.c. It is not a problem for
|
||||
upstream but many downstream projects may not use it and take
|
||||
grub-core/loader/arm64/efi/linux.c as a replacement as PE entry is the
|
||||
preferred way in combination with shim loader.
|
||||
|
||||
This patch did a trivial workaround just adding back the dropped
|
||||
defintion to the xen_boot itself.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/loader/arm64/xen_boot.c | 50 +++++++++++++++++++++++++++++++
|
||||
1 file changed, 50 insertions(+)
|
||||
|
||||
diff --git a/grub-core/loader/arm64/xen_boot.c b/grub-core/loader/arm64/xen_boot.c
|
||||
index 26e1472c9..b82a2db89 100644
|
||||
--- a/grub-core/loader/arm64/xen_boot.c
|
||||
+++ b/grub-core/loader/arm64/xen_boot.c
|
||||
@@ -84,6 +84,56 @@ static int loaded;
|
||||
static struct xen_boot_binary *xen_hypervisor;
|
||||
static struct xen_boot_binary *module_head;
|
||||
|
||||
+/* The function is exported by grub-core/loader/arm64/linux.c that is not built
|
||||
+ * because we use PE entry provided by grub-core/loader/arm64/efi/linux.c
|
||||
+ */
|
||||
+static bool initrd_use_loadfile2 = false;
|
||||
+
|
||||
+grub_err_t
|
||||
+grub_arch_efi_linux_load_image_header (grub_file_t file,
|
||||
+ struct linux_arch_kernel_header * lh)
|
||||
+{
|
||||
+ grub_file_seek (file, 0);
|
||||
+ if (grub_file_read (file, lh, sizeof (*lh)) < (grub_ssize_t) sizeof (*lh))
|
||||
+ return grub_error(GRUB_ERR_FILE_READ_ERROR, "failed to read Linux image header");
|
||||
+
|
||||
+ if ((lh->code0 & 0xffff) != GRUB_PE32_MAGIC)
|
||||
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
|
||||
+ N_("plain image kernel not supported - rebuild with CONFIG_(U)EFI_STUB enabled"));
|
||||
+
|
||||
+ grub_dprintf ("linux", "UEFI stub kernel:\n");
|
||||
+ grub_dprintf ("linux", "PE/COFF header @ %08x\n", lh->hdr_offset);
|
||||
+
|
||||
+ /*
|
||||
+ * The PE/COFF spec permits the COFF header to appear anywhere in the file, so
|
||||
+ * we need to double check whether it was where we expected it, and if not, we
|
||||
+ * must load it from the correct offset into the pe_image_header field of
|
||||
+ * struct linux_arch_kernel_header.
|
||||
+ */
|
||||
+ if ((grub_uint8_t *) lh + lh->hdr_offset != (grub_uint8_t *) &lh->pe_image_header)
|
||||
+ {
|
||||
+ if (grub_file_seek (file, lh->hdr_offset) == (grub_off_t) -1
|
||||
+ || grub_file_read (file, &lh->pe_image_header,
|
||||
+ sizeof (struct grub_pe_image_header))
|
||||
+ != sizeof (struct grub_pe_image_header))
|
||||
+ return grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image header");
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * Linux kernels built for any architecture are guaranteed to support the
|
||||
+ * LoadFile2 based initrd loading protocol if the image version is >= 1.
|
||||
+ */
|
||||
+ if (lh->pe_image_header.optional_header.major_image_version >= 1)
|
||||
+ initrd_use_loadfile2 = true;
|
||||
+ else
|
||||
+ initrd_use_loadfile2 = false;
|
||||
+
|
||||
+ grub_dprintf ("linux", "LoadFile2 initrd loading %sabled\n",
|
||||
+ initrd_use_loadfile2 ? "en" : "dis");
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
static __inline grub_addr_t
|
||||
xen_boot_address_align (grub_addr_t start, grub_size_t align)
|
||||
{
|
||||
--
|
||||
2.41.0
|
||||
|
58
0002-AUDIT-0-http-boot-tracker-bug.patch
Normal file
58
0002-AUDIT-0-http-boot-tracker-bug.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From b5c3492f31a98f5ef0f9bec2c0665ad0b71ad5cb Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Krahmer <krahmer@suse.com>
|
||||
Date: Tue, 28 Nov 2017 17:24:38 +0800
|
||||
Subject: [PATCH] AUDIT-0: http boot tracker bug
|
||||
|
||||
Fixing a memory leak in case of error, and a integer overflow, leading to a
|
||||
heap overflow due to overly large chunk sizes.
|
||||
|
||||
We need to check against some maximum value, otherwise values like 0xffffffff
|
||||
will eventually lead in the allocation functions to small sized buffers, since
|
||||
the len is rounded up to the next reasonable alignment. The following memcpy
|
||||
will then smash the heap, leading to RCE.
|
||||
|
||||
This is no big issue for pure http boot, since its going to execute an
|
||||
untrusted kernel anyway, but it will break trusted boot scenarios, where only
|
||||
signed code is allowed to be executed.
|
||||
|
||||
v2: Fix GCC 13 build failure (bsc#1201089)
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/net/efi/net.c | 4 +++-
|
||||
grub-core/net/http.c | 5 ++++-
|
||||
2 files changed, 7 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/grub-core/net/efi/net.c
|
||||
+++ b/grub-core/net/efi/net.c
|
||||
@@ -654,8 +654,10 @@
|
||||
|
||||
rd = efi_net_interface (read, file, chunk, sz);
|
||||
|
||||
- if (rd <= 0)
|
||||
+ if (rd <= 0) {
|
||||
+ grub_free (chunk);
|
||||
return rd;
|
||||
+ }
|
||||
|
||||
if (buf)
|
||||
{
|
||||
--- a/grub-core/net/http.c
|
||||
+++ b/grub-core/net/http.c
|
||||
@@ -30,6 +30,7 @@
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define HTTP_PORT ((grub_uint16_t) 80)
|
||||
+#define HTTP_MAX_CHUNK_SIZE GRUB_INT_MAX
|
||||
|
||||
typedef struct http_data
|
||||
{
|
||||
@@ -82,6 +83,8 @@
|
||||
if (data->in_chunk_len == 2)
|
||||
{
|
||||
data->chunk_rem = grub_strtoul (ptr, 0, 16);
|
||||
+ if (data->chunk_rem > HTTP_MAX_CHUNK_SIZE)
|
||||
+ return GRUB_ERR_NET_PACKET_TOO_BIG;
|
||||
grub_errno = GRUB_ERR_NONE;
|
||||
if (data->chunk_rem == 0)
|
||||
{
|
411
0002-Add-BLS-support-to-grub-mkconfig.patch
Normal file
411
0002-Add-BLS-support-to-grub-mkconfig.patch
Normal file
@ -0,0 +1,411 @@
|
||||
From 439de947262b0d8d4a02ca5afb1ef4f15853962c Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Fri, 9 Dec 2016 15:40:29 -0500
|
||||
Subject: [PATCH 2/9] Add BLS support to grub-mkconfig
|
||||
|
||||
GRUB now has BootLoaderSpec support, the user can choose to use this by
|
||||
setting GRUB_ENABLE_BLSCFG to true in /etc/default/grub. On this setup,
|
||||
the boot menu entries are not added to the grub.cfg, instead BLS config
|
||||
files are parsed by blscfg command and the entries created dynamically.
|
||||
|
||||
A 10_linux_bls grub.d snippet to generate menu entries from BLS files
|
||||
is also added that can be used on platforms where the bootloader doesn't
|
||||
have BLS support and only can parse a normal grub configuration file.
|
||||
|
||||
Portions of the 10_linux_bls were taken from the ostree-grub-generator
|
||||
script that's included in the OSTree project.
|
||||
|
||||
Fixes to support multi-devices and generate a BLS section even if no
|
||||
kernels are found in the boot directory were proposed by Yclept Nemo
|
||||
and Tom Gundersen respectively.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
[javierm: remove outdated URL for BLS document]
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
[iwienand@redhat.com: skip machine ID check when updating entries]
|
||||
Signed-off-by: Ian Wienand <iwienand@redhat.com>
|
||||
[rharwood: commit message composits, drop man pages]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
util/grub-mkconfig.in | 9 +-
|
||||
util/grub-mkconfig_lib.in | 22 +++-
|
||||
util/grub.d/10_linux.in | 244 +++++++++++++++++++++++++++++++++++++-
|
||||
3 files changed, 269 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/util/grub-mkconfig.in b/util/grub-mkconfig.in
|
||||
index cf5b79342..7af15df94 100644
|
||||
--- a/util/grub-mkconfig.in
|
||||
+++ b/util/grub-mkconfig.in
|
||||
@@ -49,6 +49,8 @@ grub_script_check="${bindir}/@grub_script_check@"
|
||||
export TEXTDOMAIN=@PACKAGE@
|
||||
export TEXTDOMAINDIR="@localedir@"
|
||||
|
||||
+export GRUB_GRUBENV_UPDATE="yes"
|
||||
+
|
||||
. "${pkgdatadir}/grub-mkconfig_lib"
|
||||
|
||||
# Usage: usage
|
||||
@@ -58,6 +60,7 @@ usage () {
|
||||
gettext "Generate a grub config file"; echo
|
||||
echo
|
||||
print_option_help "-o, --output=$(gettext FILE)" "$(gettext "output generated config to FILE [default=stdout]")"
|
||||
+ print_option_help "--no-grubenv-update" "$(gettext "do not update variables in the grubenv file")"
|
||||
print_option_help "-h, --help" "$(gettext "print this message and exit")"
|
||||
print_option_help "-V, --version" "$(gettext "print the version information and exit")"
|
||||
echo
|
||||
@@ -93,6 +96,9 @@ do
|
||||
--output=*)
|
||||
grub_cfg=`echo "$option" | sed 's/--output=//'`
|
||||
;;
|
||||
+ --no-grubenv-update)
|
||||
+ GRUB_GRUBENV_UPDATE="no"
|
||||
+ ;;
|
||||
-*)
|
||||
gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
|
||||
usage
|
||||
@@ -300,7 +306,8 @@ export GRUB_DEFAULT \
|
||||
GRUB_DISABLE_SUBMENU \
|
||||
SUSE_BTRFS_SNAPSHOT_BOOTING \
|
||||
SUSE_CMDLINE_XENEFI \
|
||||
- SUSE_REMOVE_LINUX_ROOT_PARAM
|
||||
+ SUSE_REMOVE_LINUX_ROOT_PARAM \
|
||||
+ GRUB_ENABLE_BLSCFG
|
||||
|
||||
if test "x${grub_cfg}" != "x"; then
|
||||
rm -f "${grub_cfg}.new"
|
||||
diff --git a/util/grub-mkconfig_lib.in b/util/grub-mkconfig_lib.in
|
||||
index 22fb7668f..5db4337c6 100644
|
||||
--- a/util/grub-mkconfig_lib.in
|
||||
+++ b/util/grub-mkconfig_lib.in
|
||||
@@ -30,6 +30,9 @@ fi
|
||||
if test "x$grub_file" = x; then
|
||||
grub_file="${bindir}/@grub_file@"
|
||||
fi
|
||||
+if test "x$grub_editenv" = x; then
|
||||
+ grub_editenv="${bindir}/@grub_editenv@"
|
||||
+fi
|
||||
if test "x$grub_mkrelpath" = x; then
|
||||
grub_mkrelpath="${bindir}/@grub_mkrelpath@"
|
||||
fi
|
||||
@@ -123,8 +126,19 @@ EOF
|
||||
fi
|
||||
}
|
||||
|
||||
+prepare_grub_to_access_device_with_variable ()
|
||||
+{
|
||||
+ device_variable="$1"
|
||||
+ shift
|
||||
+ prepare_grub_to_access_device "$@"
|
||||
+ unset "device_variable"
|
||||
+}
|
||||
+
|
||||
prepare_grub_to_access_device ()
|
||||
{
|
||||
+ if [ -z "$device_variable" ]; then
|
||||
+ device_variable="root"
|
||||
+ fi
|
||||
old_ifs="$IFS"
|
||||
IFS='
|
||||
'
|
||||
@@ -159,18 +173,18 @@ prepare_grub_to_access_device ()
|
||||
# otherwise set root as per value in device.map.
|
||||
fs_hint="`"${grub_probe}" --device $@ --target=compatibility_hint`"
|
||||
if [ "x$fs_hint" != x ]; then
|
||||
- echo "set root='$fs_hint'"
|
||||
+ echo "set ${device_variable}='$fs_hint'"
|
||||
fi
|
||||
if [ "x${GRUB_DISABLE_UUID}" != "xtrue" ] && fs_uuid="`"${grub_probe}" --device $@ --target=fs_uuid 2> /dev/null`" ; then
|
||||
hints="`"${grub_probe}" --device $@ --target=hints_string 2> /dev/null`" || hints=
|
||||
if [ "x$hints" != x ]; then
|
||||
echo "if [ x\$feature_platform_search_hint = xy ]; then"
|
||||
- echo " search --no-floppy --fs-uuid --set=root ${hints} ${fs_uuid}"
|
||||
+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${hints} ${fs_uuid}"
|
||||
echo "else"
|
||||
- echo " search --no-floppy --fs-uuid --set=root ${fs_uuid}"
|
||||
+ echo " search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}"
|
||||
echo "fi"
|
||||
else
|
||||
- echo "search --no-floppy --fs-uuid --set=root ${fs_uuid}"
|
||||
+ echo "search --no-floppy --fs-uuid --set=${device_variable} ${fs_uuid}"
|
||||
fi
|
||||
fi
|
||||
IFS="$old_ifs"
|
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
|
||||
index 5531239eb..49eccbeaf 100644
|
||||
--- a/util/grub.d/10_linux.in
|
||||
+++ b/util/grub.d/10_linux.in
|
||||
@@ -91,6 +91,244 @@ if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then
|
||||
LINUX_ROOT_DEVICE=""
|
||||
fi
|
||||
|
||||
+populate_header_warn()
|
||||
+{
|
||||
+if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then
|
||||
+ bls_parser="10_linux script"
|
||||
+else
|
||||
+ bls_parser="blscfg command"
|
||||
+fi
|
||||
+cat <<EOF
|
||||
+
|
||||
+# This section was generated by a script. Do not modify the generated file - all changes
|
||||
+# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec files.
|
||||
+#
|
||||
+# The $bls_parser parses the BootLoaderSpec files stored in /boot/loader/entries and
|
||||
+# populates the boot menu. Please refer to the Boot Loader Specification documentation
|
||||
+# for the files format: https://systemd.io/BOOT_LOADER_SPECIFICATION/.
|
||||
+
|
||||
+EOF
|
||||
+}
|
||||
+
|
||||
+read_config()
|
||||
+{
|
||||
+ config_file=${1}
|
||||
+ title=""
|
||||
+ initrd=""
|
||||
+ options=""
|
||||
+ linux=""
|
||||
+ grub_arg=""
|
||||
+
|
||||
+ while read -r line
|
||||
+ do
|
||||
+ record=$(echo ${line} | cut -f 1 -d ' ')
|
||||
+ value=$(echo ${line} | cut -s -f2- -d ' ')
|
||||
+ case "${record}" in
|
||||
+ "title")
|
||||
+ title=${value}
|
||||
+ ;;
|
||||
+ "initrd")
|
||||
+ initrd=${value}
|
||||
+ ;;
|
||||
+ "linux")
|
||||
+ linux=${value}
|
||||
+ ;;
|
||||
+ "options")
|
||||
+ options=${value}
|
||||
+ ;;
|
||||
+ "grub_arg")
|
||||
+ grub_arg=${value}
|
||||
+ ;;
|
||||
+ esac
|
||||
+ done < ${config_file}
|
||||
+}
|
||||
+
|
||||
+blsdir="/boot/loader/entries"
|
||||
+
|
||||
+get_sorted_bls()
|
||||
+{
|
||||
+ if ! [ -d "${blsdir}" ]; then
|
||||
+ return
|
||||
+ fi
|
||||
+
|
||||
+ local IFS=$'\n'
|
||||
+
|
||||
+ files=($(for bls in ${blsdir}/*.conf; do
|
||||
+ if ! [[ -e "${bls}" ]] ; then
|
||||
+ continue
|
||||
+ fi
|
||||
+ bls="${bls%.conf}"
|
||||
+ bls="${bls##*/}"
|
||||
+ echo "${bls}"
|
||||
+ done | ${kernel_sort} 2>/dev/null | tac)) || :
|
||||
+
|
||||
+ echo "${files[@]}"
|
||||
+}
|
||||
+
|
||||
+update_bls_cmdline()
|
||||
+{
|
||||
+ local cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
|
||||
+ local -a files=($(get_sorted_bls))
|
||||
+
|
||||
+ for bls in "${files[@]}"; do
|
||||
+ local options="${cmdline}"
|
||||
+ if [ -z "${bls##*debug*}" ]; then
|
||||
+ options="${options} ${GRUB_CMDLINE_LINUX_DEBUG}"
|
||||
+ fi
|
||||
+ options="$(echo "${options}" | sed -e 's/\//\\\//g')"
|
||||
+ sed -i -e "s/^options.*/options ${options}/" "${blsdir}/${bls}.conf"
|
||||
+ done
|
||||
+}
|
||||
+
|
||||
+populate_menu()
|
||||
+{
|
||||
+ local -a files=($(get_sorted_bls))
|
||||
+
|
||||
+ gettext_printf "Generating boot entries from BLS files...\n" >&2
|
||||
+
|
||||
+ for bls in "${files[@]}"; do
|
||||
+ read_config "${blsdir}/${bls}.conf"
|
||||
+
|
||||
+ menu="${menu}menuentry '${title}' ${grub_arg} --id=${bls} {\n"
|
||||
+ menu="${menu}\t linux ${linux} ${options}\n"
|
||||
+ if [ -n "${initrd}" ] ; then
|
||||
+ menu="${menu}\t initrd ${boot_prefix}${initrd}\n"
|
||||
+ fi
|
||||
+ menu="${menu}}\n\n"
|
||||
+ done
|
||||
+ # The printf command seems to be more reliable across shells for special character (\n, \t) evaluation
|
||||
+ printf "$menu"
|
||||
+}
|
||||
+
|
||||
+# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed.
|
||||
+if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null; then
|
||||
+ GRUB_ENABLE_BLSCFG="true"
|
||||
+fi
|
||||
+
|
||||
+if [ "x${GRUB_ENABLE_BLSCFG}" = "xtrue" ]; then
|
||||
+ if [ x$dirname = x/ ]; then
|
||||
+ if [ -z "${prepare_root_cache}" ]; then
|
||||
+ prepare_grub_to_access_device ${GRUB_DEVICE}
|
||||
+ fi
|
||||
+ else
|
||||
+ if [ -z "${prepare_boot_cache}" ]; then
|
||||
+ prepare_grub_to_access_device ${GRUB_DEVICE_BOOT}
|
||||
+ fi
|
||||
+ fi
|
||||
+
|
||||
+ if [ -d /sys/firmware/efi ]; then
|
||||
+ bootefi_device="`${grub_probe} --target=device /boot/efi/`"
|
||||
+ prepare_grub_to_access_device_with_variable boot ${bootefi_device}
|
||||
+ else
|
||||
+ boot_device="`${grub_probe} --target=device /boot/`"
|
||||
+ prepare_grub_to_access_device_with_variable boot ${boot_device}
|
||||
+ fi
|
||||
+
|
||||
+ arch="$(uname -m)"
|
||||
+ if [ "x${arch}" = "xppc64le" ] && [ -d /sys/firmware/opal ]; then
|
||||
+
|
||||
+ BLS_POPULATE_MENU="true"
|
||||
+ petitboot_path="/sys/firmware/devicetree/base/ibm,firmware-versions/petitboot"
|
||||
+
|
||||
+ if test -e ${petitboot_path}; then
|
||||
+ read -r -d '' petitboot_version < ${petitboot_path}
|
||||
+ petitboot_version="$(echo ${petitboot_version//v})"
|
||||
+
|
||||
+ if test -n ${petitboot_version}; then
|
||||
+ major_version="$(echo ${petitboot_version} | cut -d . -f1)"
|
||||
+ minor_version="$(echo ${petitboot_version} | cut -d . -f2)"
|
||||
+
|
||||
+ re='^[0-9]+$'
|
||||
+ if [[ $major_version =~ $re ]] && [[ $minor_version =~ $re ]] &&
|
||||
+ ([[ ${major_version} -gt 1 ]] ||
|
||||
+ [[ ${major_version} -eq 1 &&
|
||||
+ ${minor_version} -ge 8 ]]); then
|
||||
+ BLS_POPULATE_MENU="false"
|
||||
+ fi
|
||||
+ fi
|
||||
+ fi
|
||||
+ fi
|
||||
+
|
||||
+ populate_header_warn
|
||||
+
|
||||
+ cat << EOF
|
||||
+# The kernelopts variable should be defined in the grubenv file. But to ensure that menu
|
||||
+# entries populated from BootLoaderSpec files that use this variable work correctly even
|
||||
+# without a grubenv file, define a fallback kernelopts variable if this has not been set.
|
||||
+#
|
||||
+# The kernelopts variable in the grubenv file can be modified using the grubby tool or by
|
||||
+# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX
|
||||
+# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both
|
||||
+# the kernelopts variable in the grubenv file and the fallback kernelopts variable.
|
||||
+if [ -z "\${kernelopts}" ]; then
|
||||
+ set kernelopts="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
|
||||
+fi
|
||||
+EOF
|
||||
+
|
||||
+ update_bls_cmdline
|
||||
+
|
||||
+ if [ "x${BLS_POPULATE_MENU}" = "xtrue" ]; then
|
||||
+ populate_menu
|
||||
+ else
|
||||
+ cat << EOF
|
||||
+
|
||||
+insmod blscfg
|
||||
+blscfg
|
||||
+EOF
|
||||
+ fi
|
||||
+
|
||||
+ if [ "x${GRUB_GRUBENV_UPDATE}" = "xyes" ]; then
|
||||
+ blsdir="/boot/loader/entries"
|
||||
+ [ -d "${blsdir}" ] && GRUB_BLS_FS="$(${grub_probe} --target=fs ${blsdir})"
|
||||
+ if [ "x${GRUB_BLS_FS}" = "xbtrfs" ] || [ "x${GRUB_BLS_FS}" = "xzfs" ]; then
|
||||
+ blsdir=$(make_system_path_relative_to_its_root "${blsdir}")
|
||||
+ if [ "x${blsdir}" != "x/loader/entries" ] && [ "x${blsdir}" != "x/boot/loader/entries" ]; then
|
||||
+ ${grub_editenv} - set blsdir="${blsdir}"
|
||||
+ fi
|
||||
+ fi
|
||||
+
|
||||
+ if [ -n "${GRUB_EARLY_INITRD_LINUX_CUSTOM}" ]; then
|
||||
+ ${grub_editenv} - set early_initrd="${GRUB_EARLY_INITRD_LINUX_CUSTOM}"
|
||||
+ fi
|
||||
+
|
||||
+ if [ -n "${GRUB_DEFAULT_DTB}" ]; then
|
||||
+ ${grub_editenv} - set devicetree="${GRUB_DEFAULT_DTB}"
|
||||
+ fi
|
||||
+
|
||||
+ if [ -n "${GRUB_SAVEDEFAULT}" ]; then
|
||||
+ ${grub_editenv} - set save_default="${GRUB_SAVEDEFAULT}"
|
||||
+ fi
|
||||
+ fi
|
||||
+
|
||||
+ exit 0
|
||||
+fi
|
||||
+
|
||||
+mktitle ()
|
||||
+{
|
||||
+ local title_type
|
||||
+ local version
|
||||
+ local OS_NAME
|
||||
+ local OS_VERS
|
||||
+
|
||||
+ title_type=$1 && shift
|
||||
+ version=$1 && shift
|
||||
+
|
||||
+ OS_NAME="$(eval $(grep ^NAME= /etc/os-release) ; echo ${NAME})"
|
||||
+ OS_VERS="$(eval $(grep ^VERSION= /etc/os-release) ; echo ${VERSION})"
|
||||
+
|
||||
+ case $title_type in
|
||||
+ recovery)
|
||||
+ title=$(printf '%s (%s) %s (recovery mode)' \
|
||||
+ "${OS_NAME}" "${version}" "${OS_VERS}")
|
||||
+ ;;
|
||||
+ *)
|
||||
+ title=$(printf '%s (%s) %s' \
|
||||
+ "${OS_NAME}" "${version}" "${OS_VERS}")
|
||||
+ ;;
|
||||
+ esac
|
||||
+ echo -n ${title}
|
||||
+}
|
||||
+
|
||||
title_correction_code=
|
||||
|
||||
hotkey=1
|
||||
@@ -124,6 +362,7 @@ linux_entry ()
|
||||
if [ -z "$boot_device_id" ]; then
|
||||
boot_device_id="$(grub_get_device_id "${GRUB_DEVICE}")"
|
||||
fi
|
||||
+
|
||||
if [ x$type != xsimple ] ; then
|
||||
case $type in
|
||||
recovery)
|
||||
@@ -298,6 +537,7 @@ fi
|
||||
is_top_level=true
|
||||
for linux in ${reverse_sorted_list}; do
|
||||
gettext_printf "Found linux image: %s\n" "$linux" >&2
|
||||
+
|
||||
basename=`basename $linux`
|
||||
dirname=`dirname $linux`
|
||||
rel_dirname=`make_system_path_relative_to_its_root $dirname`
|
||||
@@ -348,7 +588,9 @@ for linux in ${reverse_sorted_list}; do
|
||||
for i in ${initrd}; do
|
||||
initrd_display="${initrd_display} ${dirname}/${i}"
|
||||
done
|
||||
- gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
|
||||
+ if [ "x${GRUB_ENABLE_BLSCFG}" != "xtrue" ]; then
|
||||
+ gettext_printf "Found initrd image: %s\n" "$(echo $initrd_display)" >&2
|
||||
+ fi
|
||||
fi
|
||||
|
||||
config=
|
||||
--
|
||||
2.44.0
|
||||
|
53
0002-Add-grub_disk_write_tail-helper-function.patch
Normal file
53
0002-Add-grub_disk_write_tail-helper-function.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From c0d00403a297d6023eab6189ba87dc8a3f6d1e85 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 7 Feb 2022 20:44:40 +0800
|
||||
Subject: [PATCH 2/5] Add grub_disk_write_tail helper function
|
||||
|
||||
This helps in writing data to partition where the end of buffer is
|
||||
aligned to end of partition.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/lib/disk.c | 18 ++++++++++++++++++
|
||||
include/grub/disk.h | 3 +++
|
||||
2 files changed, 21 insertions(+)
|
||||
|
||||
--- a/grub-core/lib/disk.c
|
||||
+++ b/grub-core/lib/disk.c
|
||||
@@ -52,6 +52,24 @@
|
||||
}
|
||||
|
||||
grub_err_t
|
||||
+grub_disk_write_tail (grub_disk_t disk, grub_size_t size, const void *buf)
|
||||
+{
|
||||
+ grub_partition_t part;
|
||||
+ grub_disk_addr_t sector;
|
||||
+ grub_off_t offset;
|
||||
+
|
||||
+ if (!disk->partition)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ part = disk->partition;
|
||||
+ sector = part->len;
|
||||
+ sector -= (size + GRUB_DISK_SECTOR_SIZE - 1) >> GRUB_DISK_SECTOR_BITS;
|
||||
+ offset = size & (GRUB_DISK_SECTOR_SIZE - 1);
|
||||
+
|
||||
+ return grub_disk_write (disk, sector, offset, size, buf);
|
||||
+}
|
||||
+
|
||||
+grub_err_t
|
||||
grub_disk_write (grub_disk_t disk, grub_disk_addr_t sector,
|
||||
grub_off_t offset, grub_size_t size, const void *buf)
|
||||
{
|
||||
--- a/include/grub/disk.h
|
||||
+++ b/include/grub/disk.h
|
||||
@@ -252,6 +252,9 @@
|
||||
grub_off_t offset,
|
||||
grub_size_t size,
|
||||
void *buf);
|
||||
+grub_err_t grub_disk_write_tail (grub_disk_t disk,
|
||||
+ grub_size_t size,
|
||||
+ const void *buf);
|
||||
grub_err_t grub_disk_write (grub_disk_t disk,
|
||||
grub_disk_addr_t sector,
|
||||
grub_off_t offset,
|
57
0002-Arm-check-for-the-PE-magic-for-the-compiled-arch.patch
Normal file
57
0002-Arm-check-for-the-PE-magic-for-the-compiled-arch.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 337b3d963d28b3544e8817428fb68ca559613a39 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Thu, 9 Sep 2021 10:59:28 -0400
|
||||
Subject: [PATCH 2/2] Arm: check for the PE magic for the compiled arch
|
||||
|
||||
In "arm64: Fix EFI loader kernel image allocation", Ben fixed the kernel
|
||||
alignment to match the alignment given in the PE header. In doing so, a
|
||||
check for valid PE magic was added, which was hard-coded to the value
|
||||
seen on Aarch64 (GRUB_PE32_PE64_MAGIC).
|
||||
|
||||
Unfortunately, this code is shared between 64-bit and 32-bit, and so
|
||||
that value broke 32-bit Arm systems.
|
||||
|
||||
This patch adds a constant definition for GRUB_PE32_PEXX_MAGIC, which is
|
||||
either GRUB_PE32_PE64_MAGIC or GRUB_PE32_PE32_MAGIC, depending on which
|
||||
platform is being built, and uses it in the header magic check.
|
||||
|
||||
Resolves: rhbz#2000756
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
---
|
||||
grub-core/loader/arm64/efi/linux.c | 2 +-
|
||||
include/grub/arm/linux.h | 1 +
|
||||
include/grub/arm64/linux.h | 1 +
|
||||
3 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/grub-core/loader/arm64/efi/linux.c
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -376,7 +376,7 @@
|
||||
|
||||
pe = (void *)((unsigned long)kernel + lh->hdr_offset);
|
||||
|
||||
- if (pe->opt.magic != GRUB_PE32_PE64_MAGIC)
|
||||
+ if (pe->opt.magic != GRUB_PE32_PEXX_MAGIC)
|
||||
return grub_error(GRUB_ERR_BAD_OS, "Invalid PE optional header magic");
|
||||
|
||||
*total_size = pe->opt.image_size;
|
||||
--- a/include/grub/arm/linux.h
|
||||
+++ b/include/grub/arm/linux.h
|
||||
@@ -33,6 +33,7 @@
|
||||
};
|
||||
|
||||
#if defined(__arm__)
|
||||
+# define GRUB_PE32_PEXX_MAGIC GRUB_PE32_PE32_MAGIC
|
||||
# define grub_armxx_linux_pe_header grub_arm_linux_pe_header
|
||||
#endif
|
||||
|
||||
--- a/include/grub/arm64/linux.h
|
||||
+++ b/include/grub/arm64/linux.h
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
#if defined(__aarch64__)
|
||||
# define GRUB_LINUX_ARMXX_MAGIC_SIGNATURE GRUB_LINUX_ARM64_MAGIC_SIGNATURE
|
||||
+# define GRUB_PE32_PEXX_MAGIC GRUB_PE32_PE64_MAGIC
|
||||
# define grub_armxx_linux_pe_header grub_arm64_linux_pe_header
|
||||
#endif
|
||||
|
92
0002-Fix-race-in-EFI-validation.patch
Normal file
92
0002-Fix-race-in-EFI-validation.patch
Normal file
@ -0,0 +1,92 @@
|
||||
From e72dcb40356f56efd86ab88c2f5cb7411d1e898b Mon Sep 17 00:00:00 2001
|
||||
From: Matthew Garrett <mjg59@coreos.com>
|
||||
Date: Tue, 14 Jul 2015 16:58:51 -0700
|
||||
Subject: [PATCH 02/11] Fix race in EFI validation
|
||||
|
||||
---
|
||||
grub-core/loader/i386/efi/linux.c | 40 +++++++------------------------
|
||||
1 file changed, 9 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index 06814cae3..1e09c88ab 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -154,7 +154,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
grub_file_t file = 0;
|
||||
struct linux_i386_kernel_header lh;
|
||||
grub_ssize_t len, start, filelen;
|
||||
- void *kernel;
|
||||
+ void *kernel = NULL;
|
||||
grub_err_t err;
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
@@ -185,10 +185,6 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- grub_file_seek (file, 0);
|
||||
-
|
||||
- grub_free(kernel);
|
||||
-
|
||||
params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384));
|
||||
|
||||
if (! params)
|
||||
@@ -199,13 +195,7 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
|
||||
grub_memset (params, 0, 16384);
|
||||
|
||||
- if (grub_file_read (file, &lh, sizeof (lh)) != sizeof (lh))
|
||||
- {
|
||||
- if (!grub_errno)
|
||||
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||
- argv[0]);
|
||||
- goto fail;
|
||||
- }
|
||||
+ grub_memcpy (&lh, kernel, sizeof (lh));
|
||||
|
||||
if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
|
||||
{
|
||||
@@ -271,26 +261,11 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if (grub_file_seek (file, start) == (grub_off_t) -1)
|
||||
- {
|
||||
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||
- argv[0]);
|
||||
- goto fail;
|
||||
- }
|
||||
-
|
||||
- if (grub_file_read (file, kernel_mem, len) != len && !grub_errno)
|
||||
- {
|
||||
- grub_error (GRUB_ERR_BAD_OS, N_("premature end of file %s"),
|
||||
- argv[0]);
|
||||
- }
|
||||
-
|
||||
- if (grub_errno == GRUB_ERR_NONE)
|
||||
- {
|
||||
- grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
|
||||
- loaded = 1;
|
||||
- lh.code32_start = (grub_uint32_t)(grub_addr_t) kernel_mem;
|
||||
- }
|
||||
+ grub_memcpy (kernel_mem, (char *)kernel + start, len);
|
||||
+ grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
|
||||
+ loaded=1;
|
||||
|
||||
+ lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem;
|
||||
/* Grub linuxefi erroneously initialize linux's boot_params with non-zero values. (bsc#1025563)
|
||||
|
||||
From https://www.kernel.org/doc/Documentation/x86/boot.txt:
|
||||
@@ -307,6 +282,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
if (file)
|
||||
grub_file_close (file);
|
||||
|
||||
+ if (kernel)
|
||||
+ grub_free (kernel);
|
||||
+
|
||||
if (grub_errno != GRUB_ERR_NONE)
|
||||
{
|
||||
grub_dl_unref (my_mod);
|
||||
--
|
||||
2.31.1
|
||||
|
@ -0,0 +1,57 @@
|
||||
From f01314a822dbe9ad39b2f7d0f3717ef6e4c24f4a Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 15 Apr 2022 21:45:04 +0800
|
||||
Subject: [PATCH 2/2] Mark environmet blocks as used for image embedding.
|
||||
|
||||
Now that grub will attempt to use full btrfs bootloader area, the
|
||||
embedded image could have overlapped with environment blocks if it's
|
||||
size grows too much. Let's define a dedicated area for environment
|
||||
blocks to the used block mappings for the embedding process so it can be
|
||||
skipped.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/fs/btrfs.c | 3 ++-
|
||||
include/grub/fs.h | 2 ++
|
||||
util/grub-editenv.c | 2 +-
|
||||
3 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/grub-core/fs/btrfs.c
|
||||
+++ b/grub-core/fs/btrfs.c
|
||||
@@ -2637,7 +2637,7 @@
|
||||
|
||||
static const struct {
|
||||
struct embed_region available;
|
||||
- struct embed_region used[6];
|
||||
+ struct embed_region used[7];
|
||||
} btrfs_head = {
|
||||
.available = {0, GRUB_DISK_KiB_TO_SECTORS (1024)}, /* The first 1 MiB. */
|
||||
.used = {
|
||||
@@ -2645,6 +2645,7 @@
|
||||
{GRUB_DISK_KiB_TO_SECTORS (64) - 1, 1}, /* Overflow guard. */
|
||||
{GRUB_DISK_KiB_TO_SECTORS (64), GRUB_DISK_KiB_TO_SECTORS (4)}, /* 4 KiB superblock. */
|
||||
{GRUB_DISK_KiB_TO_SECTORS (68), 1}, /* Overflow guard. */
|
||||
+ {GRUB_DISK_KiB_TO_SECTORS (ENV_BTRFS_OFFSET) - 1, 3}, /* Environment Block. */
|
||||
{GRUB_DISK_KiB_TO_SECTORS (1024) - 1, 1}, /* Overflow guard. */
|
||||
{0, 0} /* Array terminator. */
|
||||
}
|
||||
--- a/include/grub/fs.h
|
||||
+++ b/include/grub/fs.h
|
||||
@@ -128,4 +128,6 @@
|
||||
|
||||
grub_fs_t EXPORT_FUNC(grub_fs_probe) (grub_device_t device);
|
||||
|
||||
+#define ENV_BTRFS_OFFSET (256)
|
||||
+
|
||||
#endif /* ! GRUB_FS_HEADER */
|
||||
--- a/util/grub-editenv.c
|
||||
+++ b/util/grub-editenv.c
|
||||
@@ -128,7 +128,7 @@
|
||||
int offset;
|
||||
int size;
|
||||
} fs_envblk_spec[] = {
|
||||
- { "btrfs", 256 * 1024, GRUB_DISK_SECTOR_SIZE },
|
||||
+ { "btrfs", ENV_BTRFS_OFFSET * 1024, GRUB_DISK_SECTOR_SIZE },
|
||||
{ NULL, 0, 0 }
|
||||
};
|
||||
|
@ -0,0 +1,59 @@
|
||||
From 9f18541245858f53fea72d8d60304f9015d88b5f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 17 Mar 2023 22:00:23 +0800
|
||||
Subject: [PATCH 2/2] Restrict cryptsetup key file permission for better
|
||||
security
|
||||
|
||||
GRUB's default permission 777 for concatenated initrd files was too
|
||||
permissive for the cryptsetup key file, causing a complaint from
|
||||
systemd-cryptsetup during boot. This commit replaces the 0777 permission
|
||||
with a more secure 0400 permission for the key file.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/loader/linux.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/grub-core/loader/linux.c
|
||||
+++ b/grub-core/loader/linux.c
|
||||
@@ -32,6 +32,7 @@
|
||||
char *buf;
|
||||
char *newc_name;
|
||||
grub_off_t size;
|
||||
+ grub_uint32_t mode;
|
||||
};
|
||||
|
||||
struct dir
|
||||
@@ -203,6 +204,7 @@
|
||||
grub_memcpy (comp->buf, buf, bufsz);
|
||||
initrd_ctx->nfiles++;
|
||||
comp->size = bufsz;
|
||||
+ comp->mode = 0100400;
|
||||
if (grub_add (initrd_ctx->size, comp->size,
|
||||
&initrd_ctx->size))
|
||||
goto overflow;
|
||||
@@ -272,6 +274,7 @@
|
||||
grub_initrd_close (initrd_ctx);
|
||||
return grub_errno;
|
||||
}
|
||||
+ initrd_ctx->components[i].mode = 0100777;
|
||||
name_len = grub_strlen (initrd_ctx->components[i].newc_name) + 1;
|
||||
if (grub_add (initrd_ctx->size,
|
||||
ALIGN_UP (sizeof (struct newc_head) + name_len, 4),
|
||||
@@ -374,6 +377,7 @@
|
||||
if (initrd_ctx->components[i].newc_name)
|
||||
{
|
||||
grub_size_t dir_size;
|
||||
+ grub_uint32_t mode = initrd_ctx->components[i].mode;
|
||||
|
||||
if (insert_dir (initrd_ctx->components[i].newc_name, &root, ptr,
|
||||
&dir_size))
|
||||
@@ -385,7 +389,7 @@
|
||||
ptr += dir_size;
|
||||
ptr = make_header (ptr, initrd_ctx->components[i].newc_name,
|
||||
grub_strlen (initrd_ctx->components[i].newc_name) + 1,
|
||||
- 0100777,
|
||||
+ mode,
|
||||
initrd_ctx->components[i].size);
|
||||
newc = 1;
|
||||
}
|
197
0002-Restrict-file-access-on-cryptodisk-print.patch
Normal file
197
0002-Restrict-file-access-on-cryptodisk-print.patch
Normal file
@ -0,0 +1,197 @@
|
||||
From 912384e63c1e3b6aa9d90effb71cd535a17da1e2 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 18 Nov 2023 19:02:31 +0800
|
||||
Subject: [PATCH 2/4] Restrict file access on cryptodisk print
|
||||
|
||||
When the encrypted partition is automatically unlocked by TPM, granting
|
||||
access to the system upon validation of its known good state, there's a
|
||||
potential vulnerability. Grub gains access to file systems that were
|
||||
previously inaccessible to the public, enabling certain commands from
|
||||
the grub console to print content. This arises due to grub lacking
|
||||
restrictions similar to those imposed by password authentication, which
|
||||
typically occurs before privileged access is granted.
|
||||
|
||||
Although the automatic unlocking process ensures system integrity and a
|
||||
secure environment for grub to operate in, it doesn't directly address
|
||||
the issue of authentication for viewing encrypted partition content.
|
||||
|
||||
This commit addresses this security loophole by implementing a file
|
||||
filter upon adding a TPM key. The newly added file filter will
|
||||
specifically verify if the disk is encrypted, denying access and
|
||||
returning an "Access Denied: prohibited to view encrypted data" error
|
||||
message to alert the user.
|
||||
|
||||
Since the policy to filter out unwanted commands from leaking encrypted
|
||||
content is irreversible, it is advisable to make the loaded module
|
||||
persistent to prevent its removal.
|
||||
|
||||
This enhancement aims to bolster security measures and prevent
|
||||
unauthorized access to encrypted data.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 35 ++++++++++++++++++++++++++++++++++-
|
||||
grub-core/disk/diskfilter.c | 35 +++++++++++++++++++++++++++++++++++
|
||||
include/grub/disk.h | 10 ++++++++++
|
||||
include/grub/file.h | 1 +
|
||||
4 files changed, 80 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index 9397bede9..d3acc4b59 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -6,11 +6,39 @@
|
||||
#include <grub/mm.h>
|
||||
#include <grub/list.h>
|
||||
#include <grub/crypttab.h>
|
||||
+#include <grub/file.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
grub_crypto_key_list_t *cryptokey_lst;
|
||||
|
||||
+static grub_file_t
|
||||
+grub_nocat_open (grub_file_t io, enum grub_file_type type)
|
||||
+{
|
||||
+ grub_disk_t disk;
|
||||
+
|
||||
+ /* Network device */
|
||||
+ if (!io->device->disk)
|
||||
+ return io;
|
||||
+
|
||||
+ disk = io->device->disk;
|
||||
+
|
||||
+ if (grub_disk_is_crypto (disk))
|
||||
+ {
|
||||
+ switch (type & GRUB_FILE_TYPE_MASK)
|
||||
+ {
|
||||
+ case GRUB_FILE_TYPE_CAT:
|
||||
+ case GRUB_FILE_TYPE_HEXCAT:
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to view encrypted data"));
|
||||
+ return NULL;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return io;
|
||||
+}
|
||||
+
|
||||
grub_err_t
|
||||
grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key_len, const char *path, int is_tpmkey)
|
||||
{
|
||||
@@ -48,7 +76,11 @@ grub_cryptokey_add_or_update (const char *uuid, const char *key, grub_size_t key
|
||||
}
|
||||
|
||||
if (is_tpmkey >= 0)
|
||||
- cur->is_tpmkey = is_tpmkey;
|
||||
+ {
|
||||
+ cur->is_tpmkey = is_tpmkey;
|
||||
+ if (is_tpmkey)
|
||||
+ grub_file_filter_register (GRUB_FILE_FILTER_NOCAT, grub_nocat_open);
|
||||
+ }
|
||||
|
||||
if (!cur->name)
|
||||
{
|
||||
@@ -121,6 +153,7 @@ GRUB_MOD_INIT(crypttab)
|
||||
{
|
||||
cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry,
|
||||
N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description"));
|
||||
+ grub_dl_set_persistent (mod);
|
||||
}
|
||||
|
||||
GRUB_MOD_FINI(crypttab)
|
||||
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
|
||||
index 5c5fabe1a..b0c1c880d 100644
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -558,6 +558,39 @@ find_lv (const char *name)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static int
|
||||
+grub_diskfilter_has_cryptodisk (const struct grub_diskfilter_lv *lv)
|
||||
+{
|
||||
+ struct grub_diskfilter_pv *pv;
|
||||
+
|
||||
+ if (!lv)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (lv->vg->pvs)
|
||||
+ for (pv = lv->vg->pvs; pv; pv = pv->next)
|
||||
+ {
|
||||
+ if (!pv->disk)
|
||||
+ {
|
||||
+ grub_dprintf ("diskfilter", _("Couldn't find physical volume `%s'."
|
||||
+ " Some modules may be missing from core image."),
|
||||
+ pv->name);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ switch (pv->disk->dev->id)
|
||||
+ {
|
||||
+ case GRUB_DISK_DEVICE_CRYPTODISK_ID:
|
||||
+ return 1;
|
||||
+ case GRUB_DISK_DEVICE_DISKFILTER_ID:
|
||||
+ return grub_diskfilter_has_cryptodisk (pv->disk->data);
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_diskfilter_open (const char *name, grub_disk_t disk)
|
||||
{
|
||||
@@ -589,6 +622,8 @@ grub_diskfilter_open (const char *name, grub_disk_t disk)
|
||||
|
||||
disk->total_sectors = lv->size;
|
||||
disk->max_agglomerate = GRUB_DISK_MAX_MAX_AGGLOMERATE;
|
||||
+ disk->is_crypto_diskfilter = grub_diskfilter_has_cryptodisk (lv);
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
diff --git a/include/grub/disk.h b/include/grub/disk.h
|
||||
index 3b3db6222..63982f16c 100644
|
||||
--- a/include/grub/disk.h
|
||||
+++ b/include/grub/disk.h
|
||||
@@ -147,6 +147,8 @@ struct grub_disk
|
||||
|
||||
/* Device-specific data. */
|
||||
void *data;
|
||||
+
|
||||
+ int is_crypto_diskfilter;
|
||||
};
|
||||
typedef struct grub_disk *grub_disk_t;
|
||||
|
||||
@@ -314,4 +316,12 @@ void grub_mdraid1x_fini (void);
|
||||
void grub_diskfilter_fini (void);
|
||||
#endif
|
||||
|
||||
+static inline int
|
||||
+grub_disk_is_crypto (grub_disk_t disk)
|
||||
+{
|
||||
+ return ((disk->is_crypto_diskfilter ||
|
||||
+ disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID) ?
|
||||
+ 1 : 0);
|
||||
+}
|
||||
+
|
||||
#endif /* ! GRUB_DISK_HEADER */
|
||||
diff --git a/include/grub/file.h b/include/grub/file.h
|
||||
index fde58f0fa..fcfd32ce2 100644
|
||||
--- a/include/grub/file.h
|
||||
+++ b/include/grub/file.h
|
||||
@@ -185,6 +185,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook);
|
||||
/* Filters with lower ID are executed first. */
|
||||
typedef enum grub_file_filter_id
|
||||
{
|
||||
+ GRUB_FILE_FILTER_NOCAT,
|
||||
GRUB_FILE_FILTER_VERIFY,
|
||||
GRUB_FILE_FILTER_GZIO,
|
||||
GRUB_FILE_FILTER_XZIO,
|
||||
--
|
||||
2.42.1
|
||||
|
@ -0,0 +1,40 @@
|
||||
From e27acddebd30175587155613042abffd2e9a5de8 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Salter <msalter@redhat.com>
|
||||
Date: Mon, 17 Apr 2017 08:44:29 -0400
|
||||
Subject: [PATCH 2/9] arm64: make sure fdt has #address-cells and #size-cells
|
||||
properties
|
||||
|
||||
Recent upstream changes to kexec-tools relies on #address-cells
|
||||
and #size-cells properties in the FDT. If grub2 needs to create
|
||||
a chosen node, it is likely because firmware did not provide one.
|
||||
In that case, set #address-cells and #size-cells properties to
|
||||
make sure they exist.
|
||||
---
|
||||
grub-core/loader/arm64/efi/linux.c | 16 +++++++++++++++-
|
||||
1 file changed, 15 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/grub-core/loader/arm64/efi/linux.c
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -99,7 +99,21 @@
|
||||
|
||||
node = grub_fdt_find_subnode (fdt, 0, "chosen");
|
||||
if (node < 0)
|
||||
- node = grub_fdt_add_subnode (fdt, 0, "chosen");
|
||||
+ {
|
||||
+ /*
|
||||
+ * If we have to create a chosen node, Make sure we
|
||||
+ * have #address-cells and #size-cells properties.
|
||||
+ */
|
||||
+ retval = grub_fdt_set_prop32(fdt, 0, "#address-cells", 2);
|
||||
+ if (retval)
|
||||
+ goto failure;
|
||||
+
|
||||
+ retval = grub_fdt_set_prop32(fdt, 0, "#size-cells", 2);
|
||||
+ if (retval)
|
||||
+ goto failure;
|
||||
+
|
||||
+ node = grub_fdt_add_subnode (fdt, 0, "chosen");
|
||||
+ }
|
||||
|
||||
if (node < 1)
|
||||
goto failure;
|
47
0002-cmdline-Provide-cmdline-functions-as-module.patch
Normal file
47
0002-cmdline-Provide-cmdline-functions-as-module.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From 42cb0ebbffd660608612f9e32150a6596c6933c4 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 17 Aug 2020 17:25:56 +0800
|
||||
Subject: [PATCH 2/2] cmdline: Provide cmdline functions as module
|
||||
|
||||
The command line processing is needed by many loader modules, hence we should
|
||||
make it a sharable one rather than belonging to linux loader. This can cut the
|
||||
dependency to linux module among multiple loaders like multiboot linuxefi and
|
||||
so on to make custom boot image much more flexible to compose.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 6 +++++-
|
||||
grub-core/lib/cmdline.c | 3 +++
|
||||
2 files changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -1860,7 +1860,6 @@
|
||||
x86_64_efi = loader/efi/linux.c;
|
||||
emu = loader/emu/linux.c;
|
||||
common = loader/linux.c;
|
||||
- common = lib/cmdline.c;
|
||||
};
|
||||
|
||||
module = {
|
||||
@@ -2611,3 +2610,8 @@
|
||||
efi = commands/bli.c;
|
||||
enable = efi;
|
||||
};
|
||||
+
|
||||
+module = {
|
||||
+ name = cmdline;
|
||||
+ common = lib/cmdline.c;
|
||||
+};
|
||||
--- a/grub-core/lib/cmdline.c
|
||||
+++ b/grub-core/lib/cmdline.c
|
||||
@@ -19,6 +19,9 @@
|
||||
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/misc.h>
|
||||
+#include <grub/dl.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static unsigned int check_arg (char *c, int *has_space)
|
||||
{
|
43
0002-cryptodisk-Fallback-to-passphrase.patch
Normal file
43
0002-cryptodisk-Fallback-to-passphrase.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From e62b26f9765e309691e014f322d4b02b220956a1 Mon Sep 17 00:00:00 2001
|
||||
From: Patrick Colp <patrick.colp@oracle.com>
|
||||
Date: Sun, 30 Jul 2023 12:58:18 -0700
|
||||
Subject: [PATCH 2/4] cryptodisk: Fallback to passphrase
|
||||
|
||||
If a protector is specified, but it fails to unlock the disk, fall back
|
||||
to asking for the passphrase. However, an error was set indicating that
|
||||
the protector(s) failed. Later code (e.g., LUKS code) fails as
|
||||
`grub_errno` is now set. Print the existing errors out first, before
|
||||
proceeding with the passphrase.
|
||||
|
||||
Signed-off-by: Patrick Colp <patrick.colp@oracle.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index af4104178..f9842f776 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1193,11 +1193,16 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
source->name, source->partition != NULL ? "," : "",
|
||||
part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||
grub_free (part);
|
||||
- goto error;
|
||||
}
|
||||
|
||||
if (!cargs->key_len)
|
||||
{
|
||||
+ if (grub_errno)
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
/* Get the passphrase from the user, if no key data. */
|
||||
askpass = 1;
|
||||
part = grub_partition_get_name (source->partition);
|
||||
--
|
||||
2.35.3
|
||||
|
@ -0,0 +1,88 @@
|
||||
From 2271da7522d8406c528d2a9079d810e140f8041a Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 3 Feb 2023 19:40:31 +0800
|
||||
Subject: [PATCH 2/2] discard cached key before entering grub shell and editor
|
||||
mode
|
||||
|
||||
The cached key is cleared in case of anyone poking around it by means of
|
||||
the interactive shell offerings.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 16 ++++++++++++++++
|
||||
grub-core/normal/main.c | 2 ++
|
||||
grub-core/normal/menu_entry.c | 3 +++
|
||||
include/grub/crypttab.h | 2 ++
|
||||
4 files changed, 23 insertions(+)
|
||||
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -53,6 +53,22 @@
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+void
|
||||
+grub_initrd_discard_key (void)
|
||||
+{
|
||||
+ struct grub_key_publisher *cur, *nxt;
|
||||
+
|
||||
+ FOR_LIST_ELEMENTS_SAFE (cur, nxt, kpuber)
|
||||
+ {
|
||||
+ grub_list_remove (GRUB_AS_LIST (cur));
|
||||
+ grub_memset (cur->key, 0, cur->key_len);
|
||||
+ grub_free (cur->name);
|
||||
+ grub_free (cur->path);
|
||||
+ grub_free (cur->key);
|
||||
+ grub_free (cur);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **argv)
|
||||
--- a/grub-core/normal/main.c
|
||||
+++ b/grub-core/normal/main.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#ifdef GRUB_MACHINE_IEEE1275
|
||||
#include <grub/ieee1275/ieee1275.h>
|
||||
#endif
|
||||
+#include <grub/crypttab.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -478,6 +479,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
+ grub_initrd_discard_key ();
|
||||
grub_normal_reader_init (nested);
|
||||
|
||||
while (1)
|
||||
--- a/grub-core/normal/menu_entry.c
|
||||
+++ b/grub-core/normal/menu_entry.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/charset.h>
|
||||
#include <grub/safemath.h>
|
||||
+#include <grub/crypttab.h>
|
||||
|
||||
enum update_mode
|
||||
{
|
||||
@@ -1262,6 +1263,8 @@
|
||||
return;
|
||||
}
|
||||
|
||||
+ grub_initrd_discard_key();
|
||||
+
|
||||
screen = make_screen (entry);
|
||||
if (! screen)
|
||||
return;
|
||||
--- a/include/grub/crypttab.h
|
||||
+++ b/include/grub/crypttab.h
|
||||
@@ -19,4 +19,6 @@
|
||||
grub_err_t
|
||||
grub_initrd_publish_key (const char *uuid, const char *key, grub_size_t key_len, const char *path);
|
||||
|
||||
+void
|
||||
+grub_initrd_discard_key (void);
|
||||
#endif /* ! GRUB_CRYPTTAB_HEADER */
|
373
0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch
Normal file
373
0002-ieee1275-ofpath-enable-NVMeoF-logical-device-transla.patch
Normal file
@ -0,0 +1,373 @@
|
||||
From 9e61624db77e5073961126457f599bc70e877fd1 Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegodo@br.ibm.com>
|
||||
Date: Tue, 15 Mar 2022 15:59:41 -0400
|
||||
Subject: [PATCH 2/4] ieee1275/ofpath: enable NVMeoF logical device translation
|
||||
|
||||
This patch add code to enable the translation of logical devices to the of NVMeoFC paths.
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 260 +++++++++++++++++++++++++++++++--
|
||||
include/grub/util/ofpath.h | 29 ++++
|
||||
2 files changed, 280 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 89beceef4..212782d3f 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -137,7 +137,7 @@ trim_newline (char *path)
|
||||
*end-- = '\0';
|
||||
}
|
||||
|
||||
-#define MAX_DISK_CAT 64
|
||||
+#define MAX_DISK_CAT 512
|
||||
|
||||
static char *
|
||||
find_obppath (const char *sysfs_path_orig)
|
||||
@@ -313,6 +313,69 @@ get_basename(char *p)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+
|
||||
+void
|
||||
+add_filename_to_pile(char *filename, struct ofpath_files_list_root* root){
|
||||
+ struct ofpath_files_list_node* file;
|
||||
+
|
||||
+ file = malloc(sizeof(struct ofpath_files_list_node));
|
||||
+
|
||||
+ file->filename = filename;
|
||||
+
|
||||
+ if(root->first == NULL){
|
||||
+ root->items = 1;
|
||||
+ root->first = file;
|
||||
+ file->next = NULL;
|
||||
+ } else {
|
||||
+ root->items++;
|
||||
+ file->next = root->first;
|
||||
+ root->first = file;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
+void
|
||||
+find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth){
|
||||
+ struct dirent *ep;
|
||||
+ struct stat statbuf;
|
||||
+ DIR *dp;
|
||||
+
|
||||
+ if(depth > max_depth){
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if((dp = opendir(directory)) == NULL){
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ while((ep = readdir(dp)) != NULL){
|
||||
+
|
||||
+ char* full_path = malloc(1024*sizeof(char));
|
||||
+ snprintf(full_path,1024,"%s/%s",directory,ep->d_name);
|
||||
+
|
||||
+ lstat(full_path,&statbuf);
|
||||
+
|
||||
+ if(S_ISLNK(statbuf.st_mode)){
|
||||
+
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if(!strcmp(ep->d_name,".") || !strcmp(ep->d_name,"..")){
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if(!strcmp(ep->d_name,filename)){
|
||||
+ add_filename_to_pile(full_path, root);
|
||||
+ }
|
||||
+
|
||||
+ find_file(filename, full_path, root, max_depth, depth+1);
|
||||
+
|
||||
+ }
|
||||
+ closedir(dp);
|
||||
+}
|
||||
+
|
||||
+
|
||||
static char *
|
||||
of_path_of_vdisk(const char *sys_devname __attribute__((unused)),
|
||||
const char *device,
|
||||
@@ -351,7 +414,142 @@ of_path_of_ide(const char *sys_devname __attribute__((unused)), const char *devi
|
||||
return ret;
|
||||
}
|
||||
|
||||
-#ifdef __sparc__
|
||||
+char*
|
||||
+of_find_fc_host(char* host_wwpn){
|
||||
+
|
||||
+ FILE* fp;
|
||||
+ char *buf;
|
||||
+ char portname_filename[sizeof("port_name")] = "port_name";
|
||||
+ char devices_path[sizeof("/sys/devices")] = "/sys/devices";
|
||||
+
|
||||
+ struct ofpath_files_list_root* portnames_file_list;
|
||||
+
|
||||
+ portnames_file_list=malloc(sizeof(portnames_file_list));
|
||||
+ portnames_file_list->items=0;
|
||||
+ portnames_file_list->first=NULL;
|
||||
+
|
||||
+ find_file(portname_filename, devices_path, portnames_file_list, 10, 0);
|
||||
+
|
||||
+ struct ofpath_files_list_node* node = portnames_file_list->first;
|
||||
+ while(node != NULL){
|
||||
+ fp = fopen(node->filename,"r");
|
||||
+ buf = malloc(sizeof(char)*512);
|
||||
+ fscanf(fp, "%s", buf);
|
||||
+ fclose(fp);
|
||||
+ if((strcmp(buf,host_wwpn) == 0) && grub_strstr(node->filename, "fc_host")){
|
||||
+ return node->filename;
|
||||
+ }
|
||||
+ node = node->next;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+of_path_get_nvmeof_adapter_info(char* sysfs_path,
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info){
|
||||
+
|
||||
+ FILE *fp;
|
||||
+ char *buf, *buf2, *buf3;
|
||||
+
|
||||
+ nvmeof_info->host_wwpn = malloc(sizeof(char)*256);
|
||||
+ nvmeof_info->target_wwpn = malloc(sizeof(char)*256);
|
||||
+ nvmeof_info->nqn = malloc(sizeof(char)*256);
|
||||
+
|
||||
+ buf = malloc(sizeof(char)*512);
|
||||
+ snprintf(buf,512,"%s/subsysnqn",sysfs_path);
|
||||
+ fp = fopen(buf,"r");
|
||||
+ fscanf(fp, "%s", nvmeof_info->nqn);
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ snprintf(buf,512,"%s/cntlid",sysfs_path);
|
||||
+ fp = fopen(buf,"r");
|
||||
+ fscanf(fp, "%u", &(nvmeof_info->cntlid));
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ //snprintf(buf,512,"%s/nsid",sysfs_path);
|
||||
+ //fp = fopen(buf,"r");
|
||||
+ //fscanf(fp, "%u", &(nvmeof_info->nsid));
|
||||
+ //fclose(fp);
|
||||
+
|
||||
+ snprintf(buf,512,"%s/address",sysfs_path);
|
||||
+ fp = fopen(buf,"r");
|
||||
+ buf2 = malloc(sizeof(char)*512);
|
||||
+ fscanf(fp, "%s", buf2);
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ nvmeof_info->host_wwpn = strrchr(buf2,'-')+1;
|
||||
+
|
||||
+ buf3=strchr(buf2,'-')+1;
|
||||
+ buf3=strchr(buf3,'-')+1;
|
||||
+ nvmeof_info->target_wwpn = buf3;
|
||||
+ buf3 = strchr(nvmeof_info->target_wwpn,',');
|
||||
+ *buf3 = '\0';
|
||||
+
|
||||
+
|
||||
+ free(buf);
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+#define MAX_NVME_NSID_DIGITS 6
|
||||
+
|
||||
+static char *
|
||||
+of_path_get_nvme_controller_name_node(const char* devname)
|
||||
+{
|
||||
+ char *controller_node, *end;
|
||||
+
|
||||
+ controller_node = strdup(devname);
|
||||
+
|
||||
+ end = grub_strchr(controller_node+1, 'n');
|
||||
+
|
||||
+ if(end != NULL){
|
||||
+ *end = '\0';
|
||||
+ }
|
||||
+
|
||||
+ return controller_node;
|
||||
+}
|
||||
+
|
||||
+unsigned int
|
||||
+of_path_get_nvme_nsid(const char* devname)
|
||||
+{
|
||||
+ unsigned int nsid;
|
||||
+ char *sysfs_path, *buf;
|
||||
+ FILE *fp;
|
||||
+
|
||||
+ buf=malloc(sizeof(char)*512);
|
||||
+
|
||||
+ sysfs_path = block_device_get_sysfs_path_and_link (devname);
|
||||
+
|
||||
+ snprintf(buf,512,"%s/%s/nsid",sysfs_path,devname);
|
||||
+ fp = fopen(buf,"r");
|
||||
+ fscanf(fp, "%u", &(nsid));
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ free(sysfs_path);
|
||||
+ free(buf);
|
||||
+
|
||||
+ return nsid;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static char *
|
||||
+nvme_get_syspath(const char *nvmedev)
|
||||
+{
|
||||
+ char *sysfs_path, *controller_node;
|
||||
+ sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
|
||||
+
|
||||
+ if(strstr(sysfs_path,"nvme-subsystem")){
|
||||
+ controller_node = of_path_get_nvme_controller_name_node(nvmedev);
|
||||
+ strcat(sysfs_path,"/");
|
||||
+ strcat(sysfs_path,controller_node);
|
||||
+ sysfs_path = xrealpath(sysfs_path);
|
||||
+ }
|
||||
+
|
||||
+ return sysfs_path;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static char *
|
||||
of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
const char *device,
|
||||
@@ -360,6 +558,7 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
{
|
||||
char *sysfs_path, *of_path, disk[MAX_DISK_CAT];
|
||||
const char *digit_string, *part_end;
|
||||
+ int chars_written;
|
||||
|
||||
digit_string = trailing_digits (device);
|
||||
part_end = devicenode + strlen (devicenode) - 1;
|
||||
@@ -379,15 +578,61 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
/* Remove the p. */
|
||||
*end = '\0';
|
||||
sscanf (digit_string, "%d", &part);
|
||||
- snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1));
|
||||
- sysfs_path = block_device_get_sysfs_path_and_link (nvmedev);
|
||||
+
|
||||
+ sysfs_path = nvme_get_syspath(nvmedev);
|
||||
+
|
||||
+ /* If is a NVMeoF */
|
||||
+ if(strstr(sysfs_path,"nvme-fabrics")){
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info;
|
||||
+ nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
+
|
||||
+ of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info);
|
||||
+
|
||||
+ sysfs_path = of_find_fc_host(nvmeof_info->host_wwpn);
|
||||
+
|
||||
+ chars_written = snprintf(disk,sizeof(disk),"/nvme-of/controller@%s,%x:nqn=%s",
|
||||
+ nvmeof_info->target_wwpn,
|
||||
+ 0xffff,
|
||||
+ nvmeof_info->nqn);
|
||||
+
|
||||
+ unsigned int nsid = of_path_get_nvme_nsid(nvmedev);
|
||||
+
|
||||
+ if(nsid){
|
||||
+ snprintf(disk+chars_written,sizeof(disk) - chars_written,
|
||||
+ "/namespace@%x:%d",nsid, part);
|
||||
+ }
|
||||
+
|
||||
+ } else {
|
||||
+ snprintf (disk, sizeof (disk), "/disk@1:%c", 'a' + (part - 1));
|
||||
+ }
|
||||
free (nvmedev);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We do not have the parition. */
|
||||
- snprintf (disk, sizeof (disk), "/disk@1");
|
||||
- sysfs_path = block_device_get_sysfs_path_and_link (device);
|
||||
+ sysfs_path = nvme_get_syspath (device);
|
||||
+ if(strstr(sysfs_path,"nvme-fabrics")){
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info;
|
||||
+ nvmeof_info = malloc(sizeof(nvmeof_info));
|
||||
+
|
||||
+ of_path_get_nvmeof_adapter_info(sysfs_path, nvmeof_info);
|
||||
+
|
||||
+ sysfs_path = of_find_fc_host(nvmeof_info->host_wwpn);
|
||||
+
|
||||
+ chars_written = snprintf(disk,sizeof(disk),"/nvme-of/controller@%s,%x:nqn=%s",
|
||||
+ nvmeof_info->target_wwpn,
|
||||
+ 0xffff,
|
||||
+ nvmeof_info->nqn);
|
||||
+
|
||||
+ unsigned int nsid = of_path_get_nvme_nsid(device);
|
||||
+ if(nsid){
|
||||
+ snprintf(disk+chars_written,sizeof(disk) - chars_written,
|
||||
+ "/namespace@%x",nsid);
|
||||
+ }
|
||||
+ } else {
|
||||
+ snprintf (disk, sizeof (disk), "/disk@1");
|
||||
+ }
|
||||
+
|
||||
}
|
||||
|
||||
of_path = find_obppath (sysfs_path);
|
||||
@@ -398,7 +643,6 @@ of_path_of_nvme(const char *sys_devname __attribute__((unused)),
|
||||
free (sysfs_path);
|
||||
return of_path;
|
||||
}
|
||||
-#endif
|
||||
|
||||
static void
|
||||
of_fc_port_name(const char *path, const char *subpath, char *port_name)
|
||||
@@ -840,11 +1084,9 @@ grub_util_devname_to_ofpath (const char *sys_devname)
|
||||
/* All the models I've seen have a devalias "floppy".
|
||||
New models have no floppy at all. */
|
||||
ofpath = xstrdup ("floppy");
|
||||
-#ifdef __sparc__
|
||||
else if (device[0] == 'n' && device[1] == 'v' && device[2] == 'm'
|
||||
&& device[3] == 'e')
|
||||
ofpath = of_path_of_nvme (name_buf, device, devnode, devicenode);
|
||||
-#endif
|
||||
else
|
||||
{
|
||||
grub_util_warn (_("unknown device type %s"), device);
|
||||
diff --git a/include/grub/util/ofpath.h b/include/grub/util/ofpath.h
|
||||
index b43c523cb..a0ec30620 100644
|
||||
--- a/include/grub/util/ofpath.h
|
||||
+++ b/include/grub/util/ofpath.h
|
||||
@@ -3,4 +3,33 @@
|
||||
|
||||
char *grub_util_devname_to_ofpath (const char *devname);
|
||||
|
||||
+struct ofpath_files_list_node {
|
||||
+ char* filename;
|
||||
+ struct ofpath_files_list_node* next;
|
||||
+};
|
||||
+
|
||||
+struct ofpath_files_list_root {
|
||||
+ int items;
|
||||
+ struct ofpath_files_list_node* first;
|
||||
+};
|
||||
+
|
||||
+struct ofpath_nvmeof_info {
|
||||
+ char* host_wwpn;
|
||||
+ char* target_wwpn;
|
||||
+ char* nqn;
|
||||
+ int cntlid;
|
||||
+ int nsid;
|
||||
+};
|
||||
+
|
||||
+void of_path_get_nvmeof_adapter_info(char* sysfs_path,
|
||||
+ struct ofpath_nvmeof_info* nvmeof_info);
|
||||
+
|
||||
+unsigned int of_path_get_nvme_nsid(const char* devname);
|
||||
+
|
||||
+void add_filename_to_pile(char *filename, struct ofpath_files_list_root* root);
|
||||
+
|
||||
+void find_file(char* filename, char* directory, struct ofpath_files_list_root* root, int max_depth, int depth);
|
||||
+
|
||||
+char* of_find_fc_host(char* host_wwpn);
|
||||
+
|
||||
#endif /* ! GRUB_OFPATH_MACHINE_UTIL_HEADER */
|
||||
--
|
||||
2.35.3
|
||||
|
107
0002-ieee1275-powerpc-enables-device-mapper-discovery.patch
Normal file
107
0002-ieee1275-powerpc-enables-device-mapper-discovery.patch
Normal file
@ -0,0 +1,107 @@
|
||||
From 8b31ebfa42eb5af0633191d26fcdcea8c539e521 Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegodo@br.ibm.com>
|
||||
Date: Wed, 24 Jun 2020 08:22:50 -0400
|
||||
Subject: [PATCH 2/2] ieee1275/powerpc: enables device mapper discovery
|
||||
|
||||
this patch enables the device mapper discovery on ofpath.c. Currently,
|
||||
when we are dealing with a device like /dev/dm-* the ofpath returns null
|
||||
since there is no function implemented to handle this case.
|
||||
|
||||
This patch implements a function that will look into /sys/block/dm-*
|
||||
devices and search recursively inside slaves directory to find the root
|
||||
disk.
|
||||
|
||||
v2:
|
||||
Fix gcc-12 error: pointer 'device_path' may be used after 'free'
|
||||
[-Werror=use-after-free]
|
||||
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 64 ++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 63 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
+#include <dirent.h>
|
||||
|
||||
#ifdef __sparc__
|
||||
typedef enum
|
||||
@@ -754,13 +755,74 @@
|
||||
return new;
|
||||
}
|
||||
|
||||
+static char *
|
||||
+get_slave_from_dm(const char * device){
|
||||
+ char *curr_device, *tmp;
|
||||
+ char *directory;
|
||||
+ char *ret = NULL;
|
||||
+
|
||||
+ directory = grub_strdup (device);
|
||||
+ tmp = get_basename(directory);
|
||||
+ curr_device = grub_strdup (tmp);
|
||||
+ *tmp = '\0';
|
||||
+
|
||||
+ /* Recursively check for slaves devices so we can find the root device */
|
||||
+ while ((curr_device[0] == 'd') && (curr_device[1] == 'm') && (curr_device[2] == '-')){
|
||||
+ DIR *dp;
|
||||
+ struct dirent *ep;
|
||||
+ char* device_path;
|
||||
+
|
||||
+ device_path = grub_xasprintf ("/sys/block/%s/slaves", curr_device);
|
||||
+ dp = opendir(device_path);
|
||||
+ free(device_path);
|
||||
+
|
||||
+ if (dp != NULL)
|
||||
+ {
|
||||
+ ep = readdir (dp);
|
||||
+ while (ep != NULL){
|
||||
+
|
||||
+ /* avoid some system directories */
|
||||
+ if (!strcmp(ep->d_name,"."))
|
||||
+ goto next_dir;
|
||||
+ if (!strcmp(ep->d_name,".."))
|
||||
+ goto next_dir;
|
||||
+
|
||||
+ free (curr_device);
|
||||
+ free (ret);
|
||||
+ curr_device = grub_strdup (ep->d_name);
|
||||
+ ret = grub_xasprintf ("%s%s", directory, curr_device);
|
||||
+ break;
|
||||
+
|
||||
+ next_dir:
|
||||
+ ep = readdir (dp);
|
||||
+ continue;
|
||||
+ }
|
||||
+ closedir (dp);
|
||||
+ }
|
||||
+ else
|
||||
+ grub_util_warn (_("cannot open directory `/sys/block/%s/slaves'"), curr_device);
|
||||
+ }
|
||||
+
|
||||
+ free (directory);
|
||||
+ free (curr_device);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
char *
|
||||
grub_util_devname_to_ofpath (const char *sys_devname)
|
||||
{
|
||||
- char *name_buf, *device, *devnode, *devicenode, *ofpath;
|
||||
+ char *name_buf, *device, *devnode, *devicenode, *ofpath, *realname;
|
||||
|
||||
name_buf = xrealpath (sys_devname);
|
||||
|
||||
+ realname = get_slave_from_dm (name_buf);
|
||||
+ if (realname)
|
||||
+ {
|
||||
+ free (name_buf);
|
||||
+ name_buf = realname;
|
||||
+ }
|
||||
+
|
||||
device = get_basename (name_buf);
|
||||
devnode = strip_trailing_digits (name_buf);
|
||||
devicenode = strip_trailing_digits (device);
|
164
0002-ofdisk-add-early_log-support.patch
Normal file
164
0002-ofdisk-add-early_log-support.patch
Normal file
@ -0,0 +1,164 @@
|
||||
From 8959b9d97b00f791ffe02b5e3ec3fdf6bff25838 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 12 Dec 2023 15:34:18 +0800
|
||||
Subject: [PATCH 2/2] ofdisk: add early_log support
|
||||
|
||||
The command ofdisk_early_msg can be used to review debug message logged
|
||||
before output console is initialized.
|
||||
|
||||
For eg:
|
||||
|
||||
grub> ofdisk_early_msg
|
||||
/vdevice/v-scsi@71000002/disk@8000000000000000 is canonical
|
||||
/vdevice/v-scsi@71000002/disk@8000000000000000
|
||||
|
||||
/vdevice/v-scsi@71000002 is parent of
|
||||
/vdevice/v-scsi@71000002/disk@80000000
|
||||
00000000
|
||||
|
||||
the boot device type vscsi is used for root device discovery, others excluded
|
||||
|
||||
We can use it in conjunction with the $ofdisk_boot_type variable to get
|
||||
better understanding the boot device information.
|
||||
|
||||
grub> echo $ofdisk_boot_type
|
||||
boot: /vdevice/v-scsi@71000002 type: vscsi is_nvmeof? 0
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/disk/ieee1275/ofdisk.c | 75 +++++++++++++++++++++++++++++---
|
||||
1 file changed, 70 insertions(+), 5 deletions(-)
|
||||
|
||||
--- a/grub-core/disk/ieee1275/ofdisk.c
|
||||
+++ b/grub-core/disk/ieee1275/ofdisk.c
|
||||
@@ -25,6 +25,7 @@
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/time.h>
|
||||
#include <grub/env.h>
|
||||
+#include <grub/command.h>
|
||||
|
||||
#define RETRY_DEFAULT_TIMEOUT 15
|
||||
|
||||
@@ -60,6 +61,9 @@
|
||||
#define OFDISK_HASH_SZ 8
|
||||
static struct ofdisk_hash_ent *ofdisk_hash[OFDISK_HASH_SZ];
|
||||
|
||||
+static void early_log (const char *fmt, ...);
|
||||
+static void print_early_log (void);
|
||||
+
|
||||
static int
|
||||
ofdisk_hash_fn (const char *devpath)
|
||||
{
|
||||
@@ -1132,10 +1136,10 @@
|
||||
return NULL;
|
||||
}
|
||||
else
|
||||
- grub_dprintf ("ofdisk", "%s is canonical %s\n", bootpath, canon);
|
||||
+ early_log ("%s is canonical %s\n", bootpath, canon);
|
||||
|
||||
parent = get_parent_devname (canon, is_nvmeof);
|
||||
- grub_dprintf ("ofdisk", "%s is parent of %s\n", parent, canon);
|
||||
+ early_log ("%s is parent of %s\n", parent, canon);
|
||||
|
||||
grub_free (canon);
|
||||
return parent;
|
||||
@@ -1179,9 +1183,9 @@
|
||||
boot_parent = get_boot_device_parent (bootpath, &is_boot_nvmeof);
|
||||
boot_type = grub_ieee1275_get_device_type (boot_parent);
|
||||
if (boot_type)
|
||||
- grub_dprintf ("ofdisk", "the boot device type %s is used for root device discovery, others excluded\n", boot_type);
|
||||
+ early_log ("the boot device type %s is used for root device discovery, others excluded\n", boot_type);
|
||||
else
|
||||
- grub_dprintf ("ofdisk", "unknown boot device type, will use all devices to discover root and may be slow\n");
|
||||
+ early_log ("unknown boot device type, will use all devices to discover root and may be slow\n");
|
||||
}
|
||||
grub_free (type);
|
||||
grub_free (bootpath);
|
||||
@@ -1205,7 +1209,7 @@
|
||||
static char *ret;
|
||||
|
||||
if (!ret)
|
||||
- ret = grub_xasprintf("boot: %s type: %s is_nvmeof: %d",
|
||||
+ ret = grub_xasprintf("boot: %s type: %s is_nvmeof? %d",
|
||||
boot_parent,
|
||||
boot_type ? : "unknown",
|
||||
is_boot_nvmeof);
|
||||
@@ -1221,6 +1225,17 @@
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+grub_cmd_early_msg (struct grub_command *cmd __attribute__ ((unused)),
|
||||
+ int argc __attribute__ ((unused)),
|
||||
+ char *argv[] __attribute__ ((unused)))
|
||||
+{
|
||||
+ print_early_log ();
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static grub_command_t cmd_early_msg;
|
||||
+
|
||||
void
|
||||
grub_ofdisk_init (void)
|
||||
{
|
||||
@@ -1230,6 +1245,9 @@
|
||||
grub_register_variable_hook ("ofdisk_boot_type", grub_env_get_boot_type,
|
||||
grub_env_set_boot_type );
|
||||
|
||||
+ cmd_early_msg =
|
||||
+ grub_register_command ("ofdisk_early_msg", grub_cmd_early_msg,
|
||||
+ 0, N_("Show early boot message in ofdisk."));
|
||||
grub_disk_dev_register (&grub_ofdisk_dev);
|
||||
}
|
||||
|
||||
@@ -1278,3 +1296,50 @@
|
||||
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+struct ofdisk_early_msg
|
||||
+{
|
||||
+ struct ofdisk_early_msg *next;
|
||||
+ char *msg;
|
||||
+};
|
||||
+
|
||||
+static struct ofdisk_early_msg *early_msg_head;
|
||||
+static struct ofdisk_early_msg **early_msg_last = &early_msg_head;
|
||||
+
|
||||
+static void
|
||||
+early_log (const char *fmt, ...)
|
||||
+{
|
||||
+ struct ofdisk_early_msg *n;
|
||||
+ va_list args;
|
||||
+
|
||||
+ grub_error_push ();
|
||||
+ n = grub_malloc (sizeof (*n));
|
||||
+ if (!n)
|
||||
+ {
|
||||
+ grub_errno = 0;
|
||||
+ grub_error_pop ();
|
||||
+ return;
|
||||
+ }
|
||||
+ n->next = 0;
|
||||
+
|
||||
+ va_start (args, fmt);
|
||||
+ n->msg = grub_xvasprintf (fmt, args);
|
||||
+ va_end (args);
|
||||
+
|
||||
+ *early_msg_last = n;
|
||||
+ early_msg_last = &n->next;
|
||||
+
|
||||
+ grub_errno = 0;
|
||||
+ grub_error_pop ();
|
||||
+}
|
||||
+
|
||||
+static void
|
||||
+print_early_log (void)
|
||||
+{
|
||||
+ struct ofdisk_early_msg *cur;
|
||||
+
|
||||
+ if (!early_msg_head)
|
||||
+ grub_printf ("no early log is available\n");
|
||||
+ for (cur = early_msg_head; cur; cur = cur->next)
|
||||
+ grub_printf ("%s\n", cur->msg);
|
||||
+}
|
205
0002-prep_loadenv-Fix-regex-for-Open-Firmware-device-spec.patch
Normal file
205
0002-prep_loadenv-Fix-regex-for-Open-Firmware-device-spec.patch
Normal file
@ -0,0 +1,205 @@
|
||||
From 990902e28c390217d25ea474e5ef163d79eadc7f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 31 Mar 2023 15:19:58 +0800
|
||||
Subject: [PATCH 2/2] prep_loadenv: Fix regex for Open Firmware device
|
||||
specifier with encoded commas
|
||||
|
||||
The Open Firmware device specifier allows for comma-separated properties
|
||||
of a component, but this conflicts with the way that grub separates
|
||||
device and partition in its device specifier. To address this, grub
|
||||
encodes commas in Open Firmware device strings with a leading backslash
|
||||
as an established convention.
|
||||
|
||||
However, the regular expression used to extract the boot device
|
||||
substring from the $cmdpath environment variable did not properly retain
|
||||
commas with leading backslashes as part of the device. This could cause
|
||||
the comma to be incorrectly interpreted as a partition delimiter and
|
||||
result in a broken name for the boot disk.
|
||||
|
||||
To fix this issue, we have updated the regular expression to properly
|
||||
handle the encoded comma in the Open Firmware device specifier, ensuring
|
||||
that the correct boot device is identified and used.
|
||||
|
||||
v2:
|
||||
Fix the issue of freeing an uninitialized pointer in early_prep_loadenv.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/prep_loadenv.c | 108 ++++++++++++++++++++++--------
|
||||
1 file changed, 79 insertions(+), 29 deletions(-)
|
||||
|
||||
--- a/grub-core/commands/prep_loadenv.c
|
||||
+++ b/grub-core/commands/prep_loadenv.c
|
||||
@@ -15,7 +15,7 @@
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
static char *
|
||||
-match_substr (regmatch_t *match, const char *str)
|
||||
+match_substr (const regmatch_t *match, const char *str)
|
||||
{
|
||||
if (match->rm_so != -1)
|
||||
{
|
||||
@@ -185,24 +185,18 @@
|
||||
return err;
|
||||
}
|
||||
|
||||
-static grub_err_t
|
||||
-boot_disk_prep_partname (char **name)
|
||||
+static regmatch_t *
|
||||
+regex_match_str (const char *pattern, const char *str, grub_size_t *nmatch)
|
||||
{
|
||||
regex_t regex;
|
||||
int ret;
|
||||
grub_size_t s;
|
||||
char *comperr;
|
||||
- const char *cmdpath;
|
||||
regmatch_t *matches = NULL;
|
||||
grub_err_t err = GRUB_ERR_NONE;
|
||||
|
||||
- *name = NULL;
|
||||
-
|
||||
- cmdpath = grub_env_get ("cmdpath");
|
||||
- if (!cmdpath)
|
||||
- return GRUB_ERR_NONE;
|
||||
-
|
||||
- ret = regcomp (®ex, "\\(([^,]+)(,?.*)?\\)(.*)", REG_EXTENDED);
|
||||
+ *nmatch = 0;
|
||||
+ ret = regcomp (®ex, pattern, REG_EXTENDED);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
@@ -210,22 +204,11 @@
|
||||
if (! matches)
|
||||
goto fail;
|
||||
|
||||
- ret = regexec (®ex, cmdpath, regex.re_nsub + 1, matches, 0);
|
||||
- if (!ret)
|
||||
+ ret = regexec (®ex, str, regex.re_nsub + 1, matches, 0);
|
||||
+ if (ret == 0)
|
||||
{
|
||||
- char *devname = devname = match_substr (matches + 1, cmdpath);
|
||||
- if (!devname)
|
||||
- {
|
||||
- err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "%s contains no disk name", cmdpath);
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- err = prep_partname (devname, name);
|
||||
- out:
|
||||
- grub_free (devname);
|
||||
- regfree (®ex);
|
||||
- grub_free (matches);
|
||||
- return err;
|
||||
+ *nmatch = regex.re_nsub + 1;
|
||||
+ return matches;
|
||||
}
|
||||
|
||||
fail:
|
||||
@@ -235,13 +218,60 @@
|
||||
if (!comperr)
|
||||
{
|
||||
regfree (®ex);
|
||||
- return grub_errno;
|
||||
+ return NULL;
|
||||
}
|
||||
regerror (ret, ®ex, comperr, s);
|
||||
err = grub_error (GRUB_ERR_TEST_FAILURE, "%s", comperr);
|
||||
regfree (®ex);
|
||||
grub_free (comperr);
|
||||
- return err;
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+boot_disk_prep_partname (const char *varname, char **name)
|
||||
+{
|
||||
+ const char *cmdpath;
|
||||
+ regmatch_t *matches;
|
||||
+ grub_size_t nmatch;
|
||||
+ char *devname = NULL;
|
||||
+
|
||||
+ *name = NULL;
|
||||
+
|
||||
+ if (varname)
|
||||
+ cmdpath = grub_env_get (varname);
|
||||
+ else
|
||||
+ cmdpath = grub_env_get ("cmdpath");
|
||||
+ if (!cmdpath)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ matches = regex_match_str("\\((.*)\\)(.*)", cmdpath, &nmatch);
|
||||
+ if (matches && nmatch >= 2)
|
||||
+ devname = match_substr (matches + 1, cmdpath);
|
||||
+ if (devname == NULL)
|
||||
+ goto quit;
|
||||
+ grub_free (matches);
|
||||
+
|
||||
+ matches = regex_match_str ("(.*[^\\])(,.*)", devname, &nmatch);
|
||||
+ if (matches && nmatch >= 2)
|
||||
+ {
|
||||
+ char *n = match_substr (matches + 1, devname);
|
||||
+ grub_free (devname);
|
||||
+ devname = n;
|
||||
+ }
|
||||
+ else
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ if (devname)
|
||||
+ {
|
||||
+ grub_printf ("search prep from disk `%s'\n", devname);
|
||||
+ prep_partname (devname, name);
|
||||
+ }
|
||||
+
|
||||
+ quit:
|
||||
+ grub_free (devname);
|
||||
+ grub_free (matches);
|
||||
+ if (grub_errno)
|
||||
+ grub_print_error ();
|
||||
+ return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
@@ -274,13 +304,31 @@
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+static grub_err_t
|
||||
+grub_cmd_prep_partname (grub_command_t cmd __attribute__ ((unused)),
|
||||
+ int argc,
|
||||
+ char **argv)
|
||||
+{
|
||||
+ char *prep = NULL;
|
||||
+ const char *varname = NULL;
|
||||
+
|
||||
+ if (argc > 0)
|
||||
+ varname = argv[0];
|
||||
+
|
||||
+ boot_disk_prep_partname(varname, &prep);
|
||||
+ if (prep)
|
||||
+ grub_printf ("prep: %s\n", prep);
|
||||
+
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
early_prep_loadenv (void)
|
||||
{
|
||||
grub_err_t err;
|
||||
- char *prep;
|
||||
+ char *prep = NULL;
|
||||
|
||||
- err = boot_disk_prep_partname (&prep);
|
||||
+ err = boot_disk_prep_partname (NULL, &prep);
|
||||
if (err == GRUB_ERR_NONE && prep)
|
||||
err = prep_read_envblk (prep);
|
||||
if (err == GRUB_ERR_BAD_FILE_TYPE || err == GRUB_ERR_FILE_NOT_FOUND)
|
||||
@@ -296,6 +344,10 @@
|
||||
{
|
||||
early_env_hook = early_prep_loadenv;
|
||||
cmd_prep_load =
|
||||
+ grub_register_command("prep_partname", grub_cmd_prep_partname,
|
||||
+ "VARNAME",
|
||||
+ N_("Get partition name of PReP."));
|
||||
+ cmd_prep_load =
|
||||
grub_register_command("prep_load_env", grub_cmd_prep_loadenv,
|
||||
"DEVICE",
|
||||
N_("Load variables from environment block file."));
|
4489
0002-tpm2-Add-TPM-Software-Stack-TSS.patch
Normal file
4489
0002-tpm2-Add-TPM-Software-Stack-TSS.patch
Normal file
File diff suppressed because it is too large
Load Diff
385
0003-Add-grub2-switch-to-blscfg.patch
Normal file
385
0003-Add-grub2-switch-to-blscfg.patch
Normal file
@ -0,0 +1,385 @@
|
||||
From 90153f1c9631498723450d84e014e25865fecc1b Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Thu, 15 Mar 2018 14:12:40 -0400
|
||||
Subject: [PATCH 3/9] Add grub2-switch-to-blscfg
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
[jhlavac: Use ${etcdefaultgrub} instead of /etc/default/grub]
|
||||
Signed-off-by: Jan Hlavac <jhlavac@redhat.com>
|
||||
[rharwood: skip on ostree installations, migrate man to h2m]
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
Makefile.util.def | 7 +
|
||||
docs/man/grub-switch-to-blscfg.h2m | 2 +
|
||||
util/grub-switch-to-blscfg.in | 317 +++++++++++++++++++++++++++++
|
||||
util/grub.d/10_linux.in | 2 +-
|
||||
4 files changed, 327 insertions(+), 1 deletion(-)
|
||||
create mode 100644 docs/man/grub-switch-to-blscfg.h2m
|
||||
create mode 100644 util/grub-switch-to-blscfg.in
|
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def
|
||||
index 6bb30c165..ffedea24a 100644
|
||||
--- a/Makefile.util.def
|
||||
+++ b/Makefile.util.def
|
||||
@@ -1460,6 +1460,13 @@ program = {
|
||||
ldadd = '$(LIBINTL) $(LIBDEVMAPPER) $(LIBZFS) $(LIBNVPAIR) $(LIBGEOM)';
|
||||
};
|
||||
|
||||
+script = {
|
||||
+ name = grub-switch-to-blscfg;
|
||||
+ common = util/grub-switch-to-blscfg.in;
|
||||
+ mansection = 8;
|
||||
+ installdir = sbin;
|
||||
+};
|
||||
+
|
||||
program = {
|
||||
name = grub-glue-efi;
|
||||
mansection = 1;
|
||||
diff --git a/docs/man/grub-switch-to-blscfg.h2m b/docs/man/grub-switch-to-blscfg.h2m
|
||||
new file mode 100644
|
||||
index 000000000..fa341426a
|
||||
--- /dev/null
|
||||
+++ b/docs/man/grub-switch-to-blscfg.h2m
|
||||
@@ -0,0 +1,2 @@
|
||||
+[NAME]
|
||||
+grub-switch-to-blscfg \- switch to using BLS config files
|
||||
diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in
|
||||
new file mode 100644
|
||||
index 000000000..a851424be
|
||||
--- /dev/null
|
||||
+++ b/util/grub-switch-to-blscfg.in
|
||||
@@ -0,0 +1,317 @@
|
||||
+#! /bin/sh
|
||||
+#
|
||||
+# Set a default boot entry for GRUB.
|
||||
+# Copyright (C) 2004,2009 Free Software Foundation, Inc.
|
||||
+#
|
||||
+# 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/>.
|
||||
+
|
||||
+#set -eu
|
||||
+
|
||||
+# Initialize some variables.
|
||||
+prefix=@prefix@
|
||||
+exec_prefix=@exec_prefix@
|
||||
+sbindir=@sbindir@
|
||||
+bindir=@bindir@
|
||||
+sysconfdir="@sysconfdir@"
|
||||
+PACKAGE_NAME=@PACKAGE_NAME@
|
||||
+PACKAGE_VERSION=@PACKAGE_VERSION@
|
||||
+datarootdir="@datarootdir@"
|
||||
+datadir="@datadir@"
|
||||
+if [ ! -v pkgdatadir ]; then
|
||||
+ pkgdatadir="${datadir}/@PACKAGE@"
|
||||
+fi
|
||||
+
|
||||
+self=`basename $0`
|
||||
+
|
||||
+grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@"
|
||||
+grub_editenv=${bindir}/@grub_editenv@
|
||||
+etcdefaultgrub=/etc/default/grub
|
||||
+
|
||||
+eval "$("${grub_get_kernel_settings}")" || true
|
||||
+
|
||||
+EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g')
|
||||
+if [ -d /sys/firmware/efi/efivars/ ]; then
|
||||
+ startlink=/etc/grub2-efi.cfg
|
||||
+ grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'`
|
||||
+else
|
||||
+ startlink=/etc/grub2.cfg
|
||||
+ grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
|
||||
+fi
|
||||
+
|
||||
+blsdir=`echo "/@bootdirname@/loader/entries" | sed 's,//*,/,g'`
|
||||
+
|
||||
+backupsuffix=.bak
|
||||
+
|
||||
+arch="$(uname -m)"
|
||||
+
|
||||
+export TEXTDOMAIN=@PACKAGE@
|
||||
+export TEXTDOMAINDIR="@localedir@"
|
||||
+
|
||||
+. "${pkgdatadir}/grub-mkconfig_lib"
|
||||
+
|
||||
+# Usage: usage
|
||||
+# Print the usage.
|
||||
+usage () {
|
||||
+ gettext_printf "Usage: %s\n" "$self"
|
||||
+ gettext "Switch to BLS config files.\n"; echo
|
||||
+ echo
|
||||
+ print_option_help "-h, --help" "$(gettext "print this message and exit")"
|
||||
+ print_option_help "-V, --version" "$(gettext "print the version information and exit")"
|
||||
+ echo
|
||||
+ print_option_help "--backup-suffix=$(gettext "SUFFIX")" "$backupsuffix"
|
||||
+ print_option_help "--bls-directory=$(gettext "DIR")" "$blsdir"
|
||||
+ print_option_help "--config-file=$(gettext "FILE")" "$startlink"
|
||||
+ print_option_help "--grub-defaults=$(gettext "FILE")" "$etcdefaultgrub"
|
||||
+ print_option_help "--grub-directory=$(gettext "DIR")" "$grubdir"
|
||||
+ # echo
|
||||
+ # gettext "Report bugs to <bug-grub@gnu.org>."; echo
|
||||
+}
|
||||
+
|
||||
+argument () {
|
||||
+ opt=$1
|
||||
+ shift
|
||||
+
|
||||
+ if test $# -eq 0; then
|
||||
+ gettext_printf "%s: option requires an argument -- \`%s'\n" "$self" "$opt" 1>&2
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ echo $1
|
||||
+}
|
||||
+
|
||||
+# Check the arguments.
|
||||
+while test $# -gt 0
|
||||
+do
|
||||
+ option=$1
|
||||
+ shift
|
||||
+
|
||||
+ case "$option" in
|
||||
+ -h | --help)
|
||||
+ usage
|
||||
+ exit 0 ;;
|
||||
+ -V | --version)
|
||||
+ echo "$self (${PACKAGE_NAME}) ${PACKAGE_VERSION}"
|
||||
+ exit 0 ;;
|
||||
+
|
||||
+ --backup-suffix)
|
||||
+ backupsuffix=`argument $option "$@"`
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --backup-suffix=*)
|
||||
+ backupsuffix=`echo "$option" | sed 's/--backup-suffix=//'`
|
||||
+ ;;
|
||||
+
|
||||
+ --bls-directory)
|
||||
+ blsdir=`argument $option "$@"`
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --bls-directory=*)
|
||||
+ blsdir=`echo "$option" | sed 's/--bls-directory=//'`
|
||||
+ ;;
|
||||
+
|
||||
+ --config-file)
|
||||
+ startlink=`argument $option "$@"`
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --config-file=*)
|
||||
+ startlink=`echo "$option" | sed 's/--config-file=//'`
|
||||
+ ;;
|
||||
+
|
||||
+ --grub-defaults)
|
||||
+ etcdefaultgrub=`argument $option "$@"`
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --grub-defaults=*)
|
||||
+ etcdefaultgrub=`echo "$option" | sed 's/--grub-defaults=//'`
|
||||
+ ;;
|
||||
+
|
||||
+ --grub-directory)
|
||||
+ grubdir=`argument $option "$@"`
|
||||
+ shift
|
||||
+ ;;
|
||||
+ --grub-directory=*)
|
||||
+ grubdir=`echo "$option" | sed 's/--grub-directory=//'`
|
||||
+ ;;
|
||||
+
|
||||
+ *)
|
||||
+ gettext_printf "Unrecognized option \`%s'\n" "$option" 1>&2
|
||||
+ usage
|
||||
+ exit 1
|
||||
+ ;;
|
||||
+ esac
|
||||
+done
|
||||
+
|
||||
+find_grub_cfg() {
|
||||
+ local candidate=""
|
||||
+ while [ -e "${candidate}" -o $# -gt 0 ]
|
||||
+ do
|
||||
+ if [ ! -e "${candidate}" ] ; then
|
||||
+ candidate="$1"
|
||||
+ shift
|
||||
+ fi
|
||||
+
|
||||
+ if [ -L "${candidate}" ]; then
|
||||
+ candidate="$(realpath "${candidate}")"
|
||||
+ fi
|
||||
+
|
||||
+ if [ -f "${candidate}" ]; then
|
||||
+ export GRUB_CONFIG_FILE="${candidate}"
|
||||
+ return 0
|
||||
+ fi
|
||||
+ done
|
||||
+ return 1
|
||||
+}
|
||||
+
|
||||
+if ! find_grub_cfg ${startlink} ${grubdir}/grub.cfg ; then
|
||||
+ gettext_printf "Couldn't find config file\n" 1>&2
|
||||
+ exit 1
|
||||
+fi
|
||||
+
|
||||
+if [ ! -d "${blsdir}" ]; then
|
||||
+ install -m 700 -d "${blsdir}"
|
||||
+fi
|
||||
+
|
||||
+if [ -f /etc/machine-id ]; then
|
||||
+ MACHINE_ID=$(cat /etc/machine-id)
|
||||
+else
|
||||
+ MACHINE_ID=$(dmesg | sha256sum)
|
||||
+fi
|
||||
+
|
||||
+mkbls() {
|
||||
+ local kernelver=$1 && shift
|
||||
+ local datetime=$1 && shift
|
||||
+ local kernelopts=$1 && shift
|
||||
+
|
||||
+ local debugname=""
|
||||
+ local debugid=""
|
||||
+ local flavor=""
|
||||
+
|
||||
+ if [ "$kernelver" == *\+* ] ; then
|
||||
+ local flavor=-"${kernelver##*+}"
|
||||
+ if [ "${flavor}" == "-debug" ]; then
|
||||
+ local debugname=" with debugging"
|
||||
+ local debugid="-debug"
|
||||
+ fi
|
||||
+ fi
|
||||
+ (
|
||||
+ source /etc/os-release
|
||||
+
|
||||
+ cat <<EOF
|
||||
+title ${NAME} (${kernelver}) ${VERSION}${debugname}
|
||||
+version ${kernelver}${debugid}
|
||||
+linux /vmlinuz-${kernelver}
|
||||
+initrd /initramfs-${kernelver}.img
|
||||
+options ${kernelopts}
|
||||
+grub_users \$grub_users
|
||||
+grub_arg --unrestricted
|
||||
+grub_class kernel${flavor}
|
||||
+EOF
|
||||
+ ) | cat
|
||||
+}
|
||||
+
|
||||
+copy_bls() {
|
||||
+ for kernelver in $(cd /lib/modules/ ; ls -1) "" ; do
|
||||
+ bls_target="${blsdir}/${MACHINE_ID}-${kernelver}.conf"
|
||||
+ linux="/vmlinuz-${kernelver}"
|
||||
+ linux_path="/boot${linux}"
|
||||
+ kernel_dir="/lib/modules/${kernelver}"
|
||||
+
|
||||
+ if [ ! -d "${kernel_dir}" ] ; then
|
||||
+ continue
|
||||
+ fi
|
||||
+ if [ ! -f "${linux_path}" ]; then
|
||||
+ continue
|
||||
+ fi
|
||||
+
|
||||
+ linux_relpath="$("${grub_mkrelpath}" "${linux_path}")"
|
||||
+ bootprefix="${linux_relpath%%"${linux}"}"
|
||||
+ cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
|
||||
+
|
||||
+ mkbls "${kernelver}" \
|
||||
+ "$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${kernel_dir}")")" \
|
||||
+ "${bootprefix}" "${cmdline}" >"${bls_target}"
|
||||
+
|
||||
+ if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
|
||||
+ bls_debug="$(echo ${bls_target} | sed -e "s/${kernelver}/${kernelver}~debug/")"
|
||||
+ cp -aT "${bls_target}" "${bls_debug}"
|
||||
+ title="$(grep '^title[ \t]' "${bls_debug}" | sed -e 's/^title[ \t]*//')"
|
||||
+ options="$(echo "${cmdline} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 's/\//\\\//g')"
|
||||
+ sed -i -e "s/^title.*/title ${title}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${bls_debug}"
|
||||
+ sed -i -e "s/^options.*/options ${options}/" "${bls_debug}"
|
||||
+ fi
|
||||
+ done
|
||||
+
|
||||
+ if [ -f "/boot/vmlinuz-0-rescue-${MACHINE_ID}" ]; then
|
||||
+ mkbls "0-rescue-${MACHINE_ID}" "0" "${bootprefix}" >"${blsdir}/${MACHINE_ID}-0-rescue.conf"
|
||||
+ fi
|
||||
+}
|
||||
+
|
||||
+# The grub2 EFI binary is not copied to the ESP as a part of an ostree
|
||||
+# transaction. Make sure a grub2 version with BLS support is installed
|
||||
+# but only do this if the blsdir is not set, to make sure that the BLS
|
||||
+# parsing module will search for the BLS snippets in the default path.
|
||||
+if test -f /run/ostree-booted && test -d /sys/firmware/efi/efivars && \
|
||||
+ ! ${grub_editenv} - list | grep -q blsdir && \
|
||||
+ mountpoint -q /boot; then
|
||||
+ grub_binary="$(find /usr/lib/ostree-boot/efi/EFI/${EFIDIR}/ -name grub*.efi)"
|
||||
+ install -m 700 ${grub_binary} ${grubdir} || exit 1
|
||||
+ # Create a hidden file to indicate that grub2 now has BLS support.
|
||||
+ touch /boot/grub2/.grub2-blscfg-supported
|
||||
+fi
|
||||
+
|
||||
+GENERATE=0
|
||||
+if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \
|
||||
+ | grep -vq '^GRUB_ENABLE_BLSCFG="*true"*\s*$' ; then
|
||||
+ if ! sed -i"${backupsuffix}" \
|
||||
+ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=true,' \
|
||||
+ "${etcdefaultgrub}" ; then
|
||||
+ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ GENERATE=1
|
||||
+elif ! grep -q '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" ; then
|
||||
+ if ! echo 'GRUB_ENABLE_BLSCFG=true' >> "${etcdefaultgrub}" ; then
|
||||
+ gettext_printf "Updating %s failed\n" "${etcdefaultgrub}"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+ GENERATE=1
|
||||
+fi
|
||||
+
|
||||
+if [ "${GENERATE}" -eq 1 ] ; then
|
||||
+ copy_bls
|
||||
+
|
||||
+ if [ $arch = "x86_64" ] && [ ! -d /sys/firmware/efi ]; then
|
||||
+ mod_dir="i386-pc"
|
||||
+ elif [ $arch = "ppc64" -o $arch = "ppc64le" ] && [ ! -d /sys/firmware/opal ]; then
|
||||
+ mod_dir="powerpc-ieee1275"
|
||||
+ fi
|
||||
+
|
||||
+ if [ -n "${mod_dir}" ]; then
|
||||
+ for mod in blscfg increment; do
|
||||
+ install -m 700 ${prefix}/lib/grub/${mod_dir}/${mod}.mod ${grubdir}/$mod_dir/ || exit 1
|
||||
+ done
|
||||
+ fi
|
||||
+
|
||||
+ cp -af "${GRUB_CONFIG_FILE}" "${GRUB_CONFIG_FILE}${backupsuffix}"
|
||||
+ if ! grub2-mkconfig -o "${GRUB_CONFIG_FILE}" ; then
|
||||
+ install -m 700 "${GRUB_CONFIG_FILE}${backupsuffix}" "${GRUB_CONFIG_FILE}"
|
||||
+ sed -i"${backupsuffix}" \
|
||||
+ -e 's,^GRUB_ENABLE_BLSCFG=.*,GRUB_ENABLE_BLSCFG=false,' \
|
||||
+ "${etcdefaultgrub}"
|
||||
+ gettext_printf "Updating %s failed\n" "${GRUB_CONFIG_FILE}"
|
||||
+ exit 1
|
||||
+ fi
|
||||
+fi
|
||||
+
|
||||
+# Bye.
|
||||
+exit 0
|
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
|
||||
index 49eccbeaf..45eefb332 100644
|
||||
--- a/util/grub.d/10_linux.in
|
||||
+++ b/util/grub.d/10_linux.in
|
||||
@@ -147,7 +147,7 @@ blsdir="/boot/loader/entries"
|
||||
|
||||
get_sorted_bls()
|
||||
{
|
||||
- if ! [ -d "${blsdir}" ]; then
|
||||
+ if ! [ -d "${blsdir}" ] || [ -f /run/ostree-booted ] || [ -d /ostree/repo ]; then
|
||||
return
|
||||
fi
|
||||
|
||||
--
|
||||
2.44.0
|
||||
|
277
0003-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch
Normal file
277
0003-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch
Normal file
@ -0,0 +1,277 @@
|
||||
From 25069a23257ba9c6db644bbe6114dafb879063e5 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 8 Jul 2019 12:32:37 +0200
|
||||
Subject: [PATCH 03/11] Handle multi-arch (64-on-32) boot in linuxefi loader.
|
||||
|
||||
Allow booting 64-bit kernels on 32-bit EFI on x86.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
---
|
||||
grub-core/loader/efi/linux.c | 11 ++-
|
||||
grub-core/loader/i386/efi/linux.c | 127 +++++++++++++++++++-----------
|
||||
include/grub/i386/linux.h | 7 +-
|
||||
3 files changed, 97 insertions(+), 48 deletions(-)
|
||||
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -44,14 +44,10 @@
|
||||
static grub_err_t
|
||||
grub_linuxefi_boot (void)
|
||||
{
|
||||
- int offset = 0;
|
||||
-
|
||||
-#ifdef __x86_64__
|
||||
- offset = 512;
|
||||
-#endif
|
||||
asm volatile ("cli");
|
||||
|
||||
- return grub_efi_linux_boot ((char *)kernel_mem, handover_offset + offset,
|
||||
+ return grub_efi_linux_boot ((char *)kernel_mem,
|
||||
+ handover_offset,
|
||||
params);
|
||||
}
|
||||
|
||||
@@ -147,14 +143,20 @@
|
||||
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[])
|
||||
{
|
||||
grub_file_t file = 0;
|
||||
- struct linux_i386_kernel_header lh;
|
||||
- grub_ssize_t len, start, filelen;
|
||||
+ struct linux_i386_kernel_header *lh = NULL;
|
||||
+ grub_ssize_t start, filelen;
|
||||
void *kernel = NULL;
|
||||
+ int setup_header_end_offset;
|
||||
grub_err_t err;
|
||||
|
||||
grub_dl_ref (my_mod);
|
||||
@@ -185,45 +187,79 @@
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- params = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(16384));
|
||||
-
|
||||
+ params = grub_efi_allocate_pages_max (0x3fffffff,
|
||||
+ BYTES_TO_PAGES(sizeof(*params)));
|
||||
if (! params)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- grub_memset (params, 0, 16384);
|
||||
+ grub_dprintf ("linux", "params = %p\n", params);
|
||||
|
||||
- grub_memcpy (&lh, kernel, sizeof (lh));
|
||||
+ grub_memset (params, 0, sizeof(*params));
|
||||
|
||||
- if (lh.boot_flag != grub_cpu_to_le16 (0xaa55))
|
||||
+ 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))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS, N_("invalid magic number"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if (lh.setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
|
||||
+ grub_dprintf ("linux", "checking lh->setup_sects\n");
|
||||
+ if (lh->setup_sects > GRUB_LINUX_MAX_SETUP_SECTS)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS, N_("too many setup sectors"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if (lh.version < grub_cpu_to_le16 (0x020b))
|
||||
+ grub_dprintf ("linux", "checking lh->version\n");
|
||||
+ if (lh->version < grub_cpu_to_le16 (0x020b))
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS, N_("kernel too old"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- if (!lh.handover_offset)
|
||||
+ grub_dprintf ("linux", "checking lh->handover_offset\n");
|
||||
+ if (!lh->handover_offset)
|
||||
{
|
||||
grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support EFI handover"));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff,
|
||||
- BYTES_TO_PAGES(lh.cmdline_size + 1));
|
||||
+#if defined(__x86_64__) || defined(__aarch64__)
|
||||
+ grub_dprintf ("linux", "checking lh->xloadflags\n");
|
||||
+ if (!(lh->xloadflags & LINUX_XLF_KERNEL_64))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_OS, N_("kernel doesn't support 64-bit CPUs"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+#endif
|
||||
|
||||
+#if defined(__i386__)
|
||||
+ if ((lh->xloadflags & LINUX_XLF_KERNEL_64) &&
|
||||
+ !(lh->xloadflags & LINUX_XLF_EFI_HANDOVER_32))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_OS,
|
||||
+ N_("kernel doesn't support 32-bit handover"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
+ grub_dprintf ("linux", "setting up cmdline\n");
|
||||
+ linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff,
|
||||
+ BYTES_TO_PAGES(lh->cmdline_size + 1));
|
||||
if (!linux_cmdline)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline"));
|
||||
@@ -233,27 +269,26 @@
|
||||
grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
|
||||
err = grub_create_loader_cmdline (argc, argv,
|
||||
linux_cmdline + sizeof (LINUX_IMAGE) - 1,
|
||||
- lh.cmdline_size - (sizeof (LINUX_IMAGE) - 1),
|
||||
+ lh->cmdline_size - (sizeof (LINUX_IMAGE) - 1),
|
||||
GRUB_VERIFY_KERNEL_CMDLINE);
|
||||
if (err)
|
||||
goto fail;
|
||||
|
||||
- lh.cmd_line_ptr = (grub_uint32_t)(grub_addr_t)linux_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;
|
||||
|
||||
- handover_offset = lh.handover_offset;
|
||||
+ grub_dprintf ("linux", "computing handover offset\n");
|
||||
+ handover_offset = lh->handover_offset;
|
||||
|
||||
- start = (lh.setup_sects + 1) * 512;
|
||||
- len = grub_file_size(file) - start;
|
||||
+ start = (lh->setup_sects + 1) * 512;
|
||||
|
||||
- kernel_mem = grub_efi_allocate_fixed (lh.pref_address,
|
||||
- BYTES_TO_PAGES(lh.init_size));
|
||||
+ kernel_mem = grub_efi_allocate_pages_max(lh->pref_address,
|
||||
+ BYTES_TO_PAGES(lh->init_size));
|
||||
|
||||
if (!kernel_mem)
|
||||
- {
|
||||
- grub_errno = GRUB_ERR_NONE;
|
||||
- kernel_mem = grub_efi_allocate_pages_max(0x3fffffff,
|
||||
- BYTES_TO_PAGES(lh.init_size));
|
||||
- }
|
||||
+ kernel_mem = grub_efi_allocate_pages_max(0x3fffffff,
|
||||
+ BYTES_TO_PAGES(lh->init_size));
|
||||
|
||||
if (!kernel_mem)
|
||||
{
|
||||
@@ -261,21 +296,23 @@
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- grub_memcpy (kernel_mem, (char *)kernel + start, len);
|
||||
+ grub_dprintf ("linux", "kernel_mem = %lx\n", (unsigned long) kernel_mem);
|
||||
+
|
||||
grub_loader_set (grub_linuxefi_boot, grub_linuxefi_unload, 0);
|
||||
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;
|
||||
|
||||
- lh.code32_start = (grub_uint32_t)(grub_uint64_t) kernel_mem;
|
||||
- /* Grub linuxefi erroneously initialize linux's boot_params with non-zero values. (bsc#1025563)
|
||||
+ grub_memcpy (kernel_mem, (char *)kernel + start, filelen - start);
|
||||
|
||||
- From https://www.kernel.org/doc/Documentation/x86/boot.txt:
|
||||
- The memory for struct boot_params could be allocated anywhere (even above 4G)
|
||||
- and initialized to all zero.
|
||||
- Then, the setup header at offset 0x01f1 of kernel image on should be
|
||||
- loaded into struct boot_params and examined. */
|
||||
- grub_memcpy (¶ms->setup_sects, &lh.setup_sects, sizeof (lh) - 0x01f1);
|
||||
+ grub_dprintf ("linux", "setting lh->type_of_loader\n");
|
||||
+ lh->type_of_loader = 0x6;
|
||||
|
||||
- params->type_of_loader = 0x21;
|
||||
+ 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);
|
||||
|
||||
fail:
|
||||
|
||||
@@ -291,8 +328,10 @@
|
||||
loaded = 0;
|
||||
}
|
||||
|
||||
- if (linux_cmdline && !loaded)
|
||||
- grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)linux_cmdline, BYTES_TO_PAGES(lh.cmdline_size + 1));
|
||||
+ 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 (kernel_mem && !loaded)
|
||||
grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, BYTES_TO_PAGES(kernel_size));
|
||||
--- a/include/grub/i386/linux.h
|
||||
+++ b/include/grub/i386/linux.h
|
||||
@@ -148,6 +148,11 @@
|
||||
grub_uint32_t kernel_alignment;
|
||||
grub_uint8_t relocatable;
|
||||
grub_uint8_t min_alignment;
|
||||
+#define LINUX_XLF_KERNEL_64 (1<<0)
|
||||
+#define LINUX_XLF_CAN_BE_LOADED_ABOVE_4G (1<<1)
|
||||
+#define LINUX_XLF_EFI_HANDOVER_32 (1<<2)
|
||||
+#define LINUX_XLF_EFI_HANDOVER_64 (1<<3)
|
||||
+#define LINUX_XLF_EFI_KEXEC (1<<4)
|
||||
grub_uint16_t xloadflags;
|
||||
grub_uint32_t cmdline_size;
|
||||
grub_uint32_t hardware_subarch;
|
||||
--- a/grub-core/loader/efi/linux_boot.c
|
||||
+++ b/grub-core/loader/efi/linux_boot.c
|
||||
@@ -30,11 +30,16 @@
|
||||
typedef void (*handover_func) (void *, grub_efi_system_table_t *, void *);
|
||||
|
||||
grub_err_t
|
||||
-grub_efi_linux_boot (void *kernel_addr, grub_off_t offset,
|
||||
+grub_efi_linux_boot (void *kernel_addr, grub_off_t handover_offset,
|
||||
void *kernel_params)
|
||||
{
|
||||
grub_efi_loaded_image_t *loaded_image = NULL;
|
||||
handover_func hf;
|
||||
+ int offset = 0;
|
||||
+
|
||||
+#ifdef __x86_64__
|
||||
+ offset = 512;
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* Since the EFI loader is not calling the LoadImage() and StartImage()
|
||||
@@ -48,8 +53,8 @@
|
||||
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)offset, kernel_params);
|
||||
- hf = (handover_func)((char *)kernel_addr + offset);
|
||||
+ kernel_addr, (void *)(grub_efi_uintn_t)handover_offset, kernel_params);
|
||||
+ hf = (handover_func)((char *)kernel_addr + handover_offset + offset);
|
||||
hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
||||
|
||||
return GRUB_ERR_BUG;
|
57
0003-Make-grub_error-more-verbose.patch
Normal file
57
0003-Make-grub_error-more-verbose.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 3526c4e467ee01a3cfd2f4d627433d078a1ab780 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Mon, 27 Aug 2018 13:14:06 -0400
|
||||
Subject: [PATCH 3/9] Make grub_error() more verbose
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
---
|
||||
grub-core/kern/efi/mm.c | 17 ++++++++++++++---
|
||||
grub-core/kern/err.c | 13 +++++++++++--
|
||||
include/grub/err.h | 5 ++++-
|
||||
3 files changed, 29 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/grub-core/kern/err.c
|
||||
+++ b/grub-core/kern/err.c
|
||||
@@ -33,15 +33,24 @@
|
||||
static int grub_error_stack_pos;
|
||||
static int grub_error_stack_assert;
|
||||
|
||||
+#ifdef grub_error
|
||||
+#undef grub_error
|
||||
+#endif
|
||||
+
|
||||
grub_err_t
|
||||
-grub_error (grub_err_t n, const char *fmt, ...)
|
||||
+grub_error (grub_err_t n, const char *file, const int line, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
+ int m;
|
||||
|
||||
grub_errno = n;
|
||||
|
||||
+ m = grub_snprintf (grub_errmsg, sizeof (grub_errmsg), "%s:%d:", file, line);
|
||||
+ if (m < 0)
|
||||
+ m = 0;
|
||||
+
|
||||
va_start (ap, fmt);
|
||||
- grub_vsnprintf (grub_errmsg, sizeof (grub_errmsg), _(fmt), ap);
|
||||
+ grub_vsnprintf (grub_errmsg + m, sizeof (grub_errmsg) - m, _(fmt), ap);
|
||||
va_end (ap);
|
||||
|
||||
return n;
|
||||
--- a/include/grub/err.h
|
||||
+++ b/include/grub/err.h
|
||||
@@ -86,8 +86,11 @@
|
||||
extern grub_err_t EXPORT_VAR(grub_errno);
|
||||
extern char EXPORT_VAR(grub_errmsg)[GRUB_MAX_ERRMSG];
|
||||
|
||||
-grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *fmt, ...)
|
||||
- __attribute__ ((format (GNU_PRINTF, 2, 3)));
|
||||
+grub_err_t EXPORT_FUNC(grub_error) (grub_err_t n, const char *file, const int line, const char *fmt, ...)
|
||||
+ __attribute__ ((format (GNU_PRINTF, 4, 5)));
|
||||
+
|
||||
+#define grub_error(n, fmt, ...) grub_error (n, __FILE__, __LINE__, fmt, ##__VA_ARGS__)
|
||||
+
|
||||
void EXPORT_FUNC(grub_fatal) (const char *fmt, ...) __attribute__ ((noreturn));
|
||||
void EXPORT_FUNC(grub_error_push) (void);
|
||||
int EXPORT_FUNC(grub_error_pop) (void);
|
117
0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch
Normal file
117
0003-Restrict-ls-and-auto-file-completion-on-cryptodisk-p.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From 6c8d390809956d355fed8bc830f64e86838e3e82 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sat, 18 Nov 2023 21:42:00 +0800
|
||||
Subject: [PATCH 3/4] Restrict 'ls' and auto file completion on cryptodisk
|
||||
print
|
||||
|
||||
The 'ls' command allows file listing, while file completion assists in
|
||||
providing matched file names by partially inputting via the TAB key.
|
||||
Both functionalities should be restricted when the disk is automatically
|
||||
unlocked for the same reasons as highlighted in the previous patch
|
||||
addressing the limitation on file access to the cryptodisk.
|
||||
|
||||
Given that no file is explicitly opened for listing, employing file
|
||||
filters becomes impractical. Consequently, this patch focuses on
|
||||
modifying relevant routines separately to incorporate necessary checks.
|
||||
The objective is to introduce measures that prevent 'ls' and auto file
|
||||
completion from accessing encrypted data when the disk is automatically
|
||||
unlocked.
|
||||
|
||||
By implementing these modifications, any attempt to utilize 'ls' or file
|
||||
completion on the cryptodisk will result in an "Access Denied:
|
||||
prohibited to browse encrypted data" error message, thus effectively
|
||||
alerting the user about the restricted access.
|
||||
|
||||
While protecting content within disk files from viewing is essential,
|
||||
it's equally crucial to restrict access to in-memory content. This
|
||||
includes prohibiting access to the decrypted in-memory copies of disk
|
||||
files.
|
||||
|
||||
This enhancement aims to fortify security protocols by extending
|
||||
restrictions to additional functionalities beyond direct file access.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/ls.c | 8 ++++++++
|
||||
grub-core/commands/minicmd.c | 6 ++++++
|
||||
grub-core/kern/corecmd.c | 8 ++++++++
|
||||
grub-core/normal/completion.c | 8 ++++++++
|
||||
4 files changed, 30 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c
|
||||
index 8e98c73cc..aeb336a73 100644
|
||||
--- a/grub-core/commands/ls.c
|
||||
+++ b/grub-core/commands/ls.c
|
||||
@@ -183,6 +183,14 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
|
||||
if (! dev)
|
||||
goto fail;
|
||||
|
||||
+ if (dev->disk &&
|
||||
+ grub_disk_is_crypto (dev->disk) &&
|
||||
+ grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
path = grub_strchr (dirname, ')');
|
||||
if (! path)
|
||||
diff --git a/grub-core/commands/minicmd.c b/grub-core/commands/minicmd.c
|
||||
index fa498931e..8f2ac0539 100644
|
||||
--- a/grub-core/commands/minicmd.c
|
||||
+++ b/grub-core/commands/minicmd.c
|
||||
@@ -101,6 +101,12 @@ grub_mini_cmd_dump (struct grub_command *cmd __attribute__ ((unused)),
|
||||
if (argc == 0)
|
||||
return grub_error (GRUB_ERR_BAD_ARGUMENT, "no address specified");
|
||||
|
||||
+ /* NOCAT filter is applied to prevent cat alike command from revealing file
|
||||
+ * content, the dump command should also be prohibited to revealing memory
|
||||
+ * content as well */
|
||||
+ if (grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ return grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited by security policy"));
|
||||
+
|
||||
#if GRUB_CPU_SIZEOF_VOID_P == GRUB_CPU_SIZEOF_LONG
|
||||
#define grub_strtoaddr grub_strtoul
|
||||
#else
|
||||
diff --git a/grub-core/kern/corecmd.c b/grub-core/kern/corecmd.c
|
||||
index 62d434ba9..b639bc3ae 100644
|
||||
--- a/grub-core/kern/corecmd.c
|
||||
+++ b/grub-core/kern/corecmd.c
|
||||
@@ -135,6 +135,14 @@ grub_core_cmd_ls (struct grub_command *cmd __attribute__ ((unused)),
|
||||
if (! dev)
|
||||
goto fail;
|
||||
|
||||
+ if (dev->disk &&
|
||||
+ grub_disk_is_crypto (dev->disk) &&
|
||||
+ grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
path = grub_strchr (argv[0], ')');
|
||||
if (! path)
|
||||
diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c
|
||||
index 18cadfa85..d003ec37d 100644
|
||||
--- a/grub-core/normal/completion.c
|
||||
+++ b/grub-core/normal/completion.c
|
||||
@@ -259,6 +259,14 @@ complete_file (void)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
+ if (dev->disk &&
|
||||
+ grub_disk_is_crypto (dev->disk) &&
|
||||
+ grub_file_filters[GRUB_FILE_FILTER_NOCAT])
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED, N_("prohibited to browse encrypted content"));
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
fs = grub_fs_probe (dev);
|
||||
if (! fs)
|
||||
{
|
||||
--
|
||||
2.42.1
|
||||
|
1114
0003-bootp-New-net_bootp6-command.patch
Normal file
1114
0003-bootp-New-net_bootp6-command.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,38 @@
|
||||
From 370e435b6ada53314888f04dcd8f096fc11cfadb Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 3 Aug 2023 15:52:52 +0800
|
||||
Subject: [PATCH 3/4] cryptodisk: wipe out the cached keys from protectors
|
||||
|
||||
An attacker may insert a malicious disk with the same crypto UUID and
|
||||
trick grub2 to mount the fake root. Even though the key from the key
|
||||
protector fails to unlock the fake root, it's not wiped out cleanly so
|
||||
the attacker could dump the memory to retrieve the secret key. To defend
|
||||
such attack, wipe out the cached key when we don't need it.
|
||||
|
||||
Cc: Fabian Vogt <fvogt@suse.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index f9842f776..aa0d43562 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1355,7 +1355,11 @@ grub_cryptodisk_clear_key_cache (struct grub_cryptomount_args *cargs)
|
||||
return;
|
||||
|
||||
for (i = 0; cargs->protectors[i]; i++)
|
||||
- grub_free (cargs->key_cache[i].key);
|
||||
+ {
|
||||
+ if (cargs->key_cache[i].key)
|
||||
+ grub_memset (cargs->key_cache[i].key, 0, cargs->key_cache[i].key_len);
|
||||
+ grub_free (cargs->key_cache[i].key);
|
||||
+ }
|
||||
|
||||
grub_free (cargs->key_cache);
|
||||
}
|
||||
--
|
||||
2.35.3
|
||||
|
137
0003-grub-install-support-prep-environment-block.patch
Normal file
137
0003-grub-install-support-prep-environment-block.patch
Normal file
@ -0,0 +1,137 @@
|
||||
From c31fc5aa0ded9ce1e774d0a3526cfee19be1b77f Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 7 Feb 2022 20:49:01 +0800
|
||||
Subject: [PATCH 3/5] grub-install: support prep environment block
|
||||
|
||||
The grub-install can be instructed to create environment block at end of
|
||||
PReP paritition with probed device identities and properties in
|
||||
variables to facilitate root device discovery. So far these variables
|
||||
are defined for this purpose:
|
||||
|
||||
ENV_FS_UUID - The filesystem uuid for the grub root device
|
||||
ENV_CRYPTO_UUID - The crytodisk uuid for the grub root device separated
|
||||
by space
|
||||
ENV_GRUB_DIR - The path to grub prefix directory
|
||||
ENV_HINT - The recommended hint string for searching root device
|
||||
|
||||
The size of environment block is defined in GRUB_ENVBLK_PREP_SIZE which
|
||||
is 4096 bytes and can be extended in the future.
|
||||
|
||||
v2: Improve detection of ENV_CRYPTO_UUID by traversing all members of
|
||||
the logical disk and utilize a space as a separator when multiple UUIDs
|
||||
are found (bsc#1216075).
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
include/grub/lib/envblk.h | 3 +++
|
||||
util/grub-install.c | 38 ++++++++++++++++++++++++++++++++++++++
|
||||
2 files changed, 41 insertions(+)
|
||||
|
||||
--- a/include/grub/lib/envblk.h
|
||||
+++ b/include/grub/lib/envblk.h
|
||||
@@ -24,6 +24,9 @@
|
||||
|
||||
#ifndef ASM_FILE
|
||||
|
||||
+#include <grub/disk.h>
|
||||
+#define GRUB_ENVBLK_PREP_SIZE (GRUB_DISK_SECTOR_SIZE << 3)
|
||||
+
|
||||
struct grub_envblk
|
||||
{
|
||||
char *buf;
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <grub/util/ofpath.h>
|
||||
#include <grub/hfsplus.h>
|
||||
#include <grub/time.h>
|
||||
+#include <grub/lib/envblk.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -609,6 +610,41 @@
|
||||
}
|
||||
}
|
||||
|
||||
+static char *
|
||||
+cryptodisk_uuids (grub_disk_t disk, int in_recurse)
|
||||
+{
|
||||
+ grub_disk_memberlist_t list = NULL, tmp;
|
||||
+ static char *ret;
|
||||
+
|
||||
+ if (!in_recurse)
|
||||
+ ret = NULL;
|
||||
+
|
||||
+ if (disk->dev->disk_memberlist)
|
||||
+ list = disk->dev->disk_memberlist (disk);
|
||||
+
|
||||
+ while (list)
|
||||
+ {
|
||||
+ ret = cryptodisk_uuids (list->disk, 1);
|
||||
+ tmp = list->next;
|
||||
+ free (list);
|
||||
+ list = tmp;
|
||||
+ }
|
||||
+
|
||||
+ if (disk->dev->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
+ {
|
||||
+ if (!ret)
|
||||
+ ret = grub_strdup (grub_util_cryptodisk_get_uuid (disk));
|
||||
+ else
|
||||
+ {
|
||||
+ char *s = grub_xasprintf ("%s %s", grub_util_cryptodisk_get_uuid (disk), ret);
|
||||
+ grub_free (ret);
|
||||
+ ret = s;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
is_same_disk (const char *a, const char *b)
|
||||
{
|
||||
@@ -2138,6 +2174,43 @@
|
||||
if (write_to_disk (ins_dev, imgfile))
|
||||
grub_util_error ("%s", _("failed to copy Grub to the PReP partition"));
|
||||
grub_set_install_backup_ponr ();
|
||||
+
|
||||
+ if ((signed_grub_mode >= SIGNED_GRUB_FORCE) || ((signed_grub_mode == SIGNED_GRUB_AUTO) && (ppc_sb_state > 0)))
|
||||
+ {
|
||||
+ char *uuid = NULL;
|
||||
+ grub_envblk_t envblk = NULL;
|
||||
+ char *buf;
|
||||
+ char *cryptouuid = NULL;
|
||||
+
|
||||
+ if (grub_dev->disk)
|
||||
+ cryptouuid = cryptodisk_uuids (grub_dev->disk, 0);
|
||||
+
|
||||
+ if (grub_fs->fs_uuid && grub_fs->fs_uuid (grub_dev, &uuid))
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ grub_errno = 0;
|
||||
+ uuid = NULL;
|
||||
+ }
|
||||
+ buf = grub_envblk_buf (GRUB_ENVBLK_PREP_SIZE);
|
||||
+ envblk = grub_envblk_open (buf, GRUB_ENVBLK_PREP_SIZE);
|
||||
+ if (uuid)
|
||||
+ grub_envblk_set (envblk, "ENV_FS_UUID", uuid);
|
||||
+ if (cryptouuid)
|
||||
+ grub_envblk_set (envblk, "ENV_CRYPTO_UUID", cryptouuid);
|
||||
+ if (relative_grubdir)
|
||||
+ grub_envblk_set (envblk, "ENV_GRUB_DIR", relative_grubdir);
|
||||
+ if (have_abstractions)
|
||||
+ grub_envblk_set (envblk, "ENV_HINT", grub_dev->disk->name);
|
||||
+ if (use_relative_path_on_btrfs)
|
||||
+ grub_envblk_set (envblk, "btrfs_relative_path", "1");
|
||||
+ if (envblk)
|
||||
+ {
|
||||
+ fprintf (stderr, _("Write environment block to PReP.\n"));
|
||||
+ if (grub_disk_write_tail (ins_dev->disk, envblk->size, envblk->buf))
|
||||
+ grub_util_error ("%s", _("failed to write environment block to the PReP partition"));
|
||||
+ }
|
||||
+ grub_envblk_close (envblk);
|
||||
+ }
|
||||
grub_device_close (ins_dev);
|
||||
if (update_nvram)
|
||||
grub_install_register_ieee1275 (1, grub_util_get_os_disk (install_device),
|
62
0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch
Normal file
62
0003-ieee1275-change-the-logic-of-ieee1275_get_devargs.patch
Normal file
@ -0,0 +1,62 @@
|
||||
From 1729400ab816804a28ebf50cb1310607b2c4b75e Mon Sep 17 00:00:00 2001
|
||||
From: Diego Domingos <diegodo@br.ibm.com>
|
||||
Date: Fri, 25 Feb 2022 12:49:51 -0500
|
||||
Subject: [PATCH 3/4] ieee1275: change the logic of ieee1275_get_devargs()
|
||||
|
||||
Usually grub will parse the PFW arguments by searching for the first occurence of the character ':'.
|
||||
However, we can have this char more than once on NQN.
|
||||
This patch changes the logic to find the last occurence of this char so we can get the proper values
|
||||
for NVMeoFC
|
||||
---
|
||||
grub-core/kern/ieee1275/openfw.c | 21 ++++++++++++++++++++-
|
||||
1 file changed, 20 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/openfw.c b/grub-core/kern/ieee1275/openfw.c
|
||||
index f819bd106..655a71310 100644
|
||||
--- a/grub-core/kern/ieee1275/openfw.c
|
||||
+++ b/grub-core/kern/ieee1275/openfw.c
|
||||
@@ -354,6 +354,13 @@ static char *
|
||||
grub_ieee1275_get_devargs (const char *path)
|
||||
{
|
||||
char *colon = grub_strchr (path, ':');
|
||||
+ char *colon_check = colon;
|
||||
+
|
||||
+ /* Find the last occurence of colon */
|
||||
+ while(colon_check){
|
||||
+ colon = colon_check;
|
||||
+ colon_check = grub_strchr (colon+1, ':');
|
||||
+ }
|
||||
|
||||
if (! colon)
|
||||
return 0;
|
||||
@@ -368,6 +375,18 @@ grub_ieee1275_get_devname (const char *path)
|
||||
char *colon = grub_strchr (path, ':');
|
||||
int pathlen = grub_strlen (path);
|
||||
struct grub_ieee1275_devalias curalias;
|
||||
+
|
||||
+ /* Check some special cases */
|
||||
+ if(grub_strstr(path, "nvme-of")){
|
||||
+ char *namespace_split = grub_strstr(path,"/namespace@");
|
||||
+ if(namespace_split){
|
||||
+ colon = grub_strchr (namespace_split, ':');
|
||||
+ } else {
|
||||
+ colon = NULL;
|
||||
+ }
|
||||
+
|
||||
+ }
|
||||
+
|
||||
if (colon)
|
||||
pathlen = (int)(colon - path);
|
||||
|
||||
@@ -693,7 +712,7 @@ grub_ieee1275_get_boot_dev (void)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64);
|
||||
+ bootpath = (char *) grub_malloc ((grub_size_t) bootpath_size + 64 + 256);
|
||||
if (! bootpath)
|
||||
{
|
||||
grub_print_error ();
|
||||
--
|
||||
2.35.3
|
||||
|
2263
0003-key_protector-Add-TPM2-Key-Protector.patch
Normal file
2263
0003-key_protector-Add-TPM2-Key-Protector.patch
Normal file
File diff suppressed because it is too large
Load Diff
298
0004-Add-suport-for-signing-grub-with-an-appended-signatu.patch
Normal file
298
0004-Add-suport-for-signing-grub-with-an-appended-signatu.patch
Normal file
@ -0,0 +1,298 @@
|
||||
From cf6b16f113b1b5e6efce79b569be1de3e504de8f Mon Sep 17 00:00:00 2001
|
||||
From: Rashmica Gupta <rashmica.g@gmail.com>
|
||||
Date: Thu, 11 Jun 2020 11:26:23 +1000
|
||||
Subject: [PATCH 04/23] Add suport for signing grub with an appended signature
|
||||
|
||||
Add infrastructure to allow firmware to verify the integrity of grub
|
||||
by use of a Linux-kernel-module-style appended signature. We initially
|
||||
target powerpc-ieee1275, but the code should be extensible to other
|
||||
platforms.
|
||||
|
||||
Usually these signatures are appended to a file without modifying the
|
||||
ELF file itself. (This is what the 'sign-file' tool does, for example.)
|
||||
The verifier loads the signed file from the file system and looks at the
|
||||
end of the file for the appended signature. However, on powerpc-ieee1275
|
||||
platforms, the bootloader is often stored directly in the PReP partition
|
||||
as raw bytes without a file-system. This makes determining the location
|
||||
of an appended signature more difficult.
|
||||
|
||||
To address this, we add a new ELF note.
|
||||
|
||||
The name field of shall be the string "Appended-Signature", zero-padded
|
||||
to 4 byte alignment. The type field shall be 0x41536967 (the ASCII values
|
||||
for the string "ASig"). It must be the final section in the ELF binary.
|
||||
|
||||
The description shall contain the appended signature structure as defined
|
||||
by the Linux kernel. The description will also be padded to be a multiple
|
||||
of 4 bytes. The padding shall be added before the appended signature
|
||||
structure (not at the end) so that the final bytes of a signed ELF file
|
||||
are the appended signature magic.
|
||||
|
||||
A subsequent patch documents how to create a grub core.img validly signed
|
||||
under this scheme.
|
||||
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
Signed-off-by: Rashmica Gupta <rashmica.g@gmail.com>
|
||||
|
||||
---
|
||||
|
||||
You can experiment with this code with a patched version of SLOF
|
||||
that verifies these signatures. You can find one at:
|
||||
https://github.com/daxtens/SLOF
|
||||
|
||||
I will be proposing this for inclusion in a future Power Architecture
|
||||
Platform Reference (PAPR).
|
||||
---
|
||||
include/grub/util/install.h | 8 ++++++--
|
||||
include/grub/util/mkimage.h | 4 ++--
|
||||
util/grub-install-common.c | 15 +++++++++++---
|
||||
util/grub-mkimage.c | 11 +++++++++++
|
||||
util/grub-mkimagexx.c | 39 ++++++++++++++++++++++++++++++++++++-
|
||||
util/mkimage.c | 13 +++++++------
|
||||
6 files changed, 76 insertions(+), 14 deletions(-)
|
||||
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -67,6 +67,9 @@
|
||||
N_("SBAT metadata"), 0 }, \
|
||||
{ "disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, \
|
||||
N_("disable shim_lock verifier"), 0 }, \
|
||||
+ { "appended-signature-size", GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE,\
|
||||
+ "SIZE", 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), \
|
||||
+ 1}, \
|
||||
{ "verbose", 'v', 0, 0, \
|
||||
N_("print verbose messages."), 1 }
|
||||
|
||||
@@ -130,7 +133,8 @@
|
||||
GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS,
|
||||
GRUB_INSTALL_OPTIONS_DTB,
|
||||
GRUB_INSTALL_OPTIONS_SBAT,
|
||||
- GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK
|
||||
+ GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK,
|
||||
+ GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE
|
||||
};
|
||||
|
||||
extern char *grub_install_source_directory;
|
||||
@@ -190,7 +194,7 @@
|
||||
size_t npubkeys,
|
||||
char *config_path,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
- int note,
|
||||
+ int note, size_t appsig_size,
|
||||
grub_compression_t comp, const char *dtb_file,
|
||||
const char *sbat_path, const int disable_shim_lock);
|
||||
|
||||
--- a/include/grub/util/mkimage.h
|
||||
+++ b/include/grub/util/mkimage.h
|
||||
@@ -51,12 +51,12 @@
|
||||
const struct grub_install_image_target_desc *image_target);
|
||||
void
|
||||
grub_mkimage_generate_elf32 (const struct grub_install_image_target_desc *image_target,
|
||||
- int note, char **core_img, size_t *core_size,
|
||||
+ int note, size_t appsig_size, char **core_img, size_t *core_size,
|
||||
Elf32_Addr target_addr,
|
||||
struct grub_mkimage_layout *layout);
|
||||
void
|
||||
grub_mkimage_generate_elf64 (const struct grub_install_image_target_desc *image_target,
|
||||
- int note, char **core_img, size_t *core_size,
|
||||
+ int note, size_t appsig_size, char **core_img, size_t *core_size,
|
||||
Elf64_Addr target_addr,
|
||||
struct grub_mkimage_layout *layout);
|
||||
|
||||
--- a/util/grub-install-common.c
|
||||
+++ b/util/grub-install-common.c
|
||||
@@ -466,10 +466,12 @@
|
||||
static char *sbat;
|
||||
static int disable_shim_lock;
|
||||
static grub_compression_t compression;
|
||||
+static size_t appsig_size;
|
||||
|
||||
int
|
||||
grub_install_parse (int key, char *arg)
|
||||
{
|
||||
+ const char *end;
|
||||
switch (key)
|
||||
{
|
||||
case GRUB_INSTALL_OPTIONS_INSTALL_CORE_COMPRESS:
|
||||
@@ -567,6 +569,12 @@
|
||||
grub_util_error (_("Unrecognized compression `%s'"), arg);
|
||||
case GRUB_INSTALL_OPTIONS_GRUB_MKIMAGE:
|
||||
return 1;
|
||||
+ case GRUB_INSTALL_OPTIONS_APPENDED_SIGNATURE_SIZE:
|
||||
+ grub_errno = 0;
|
||||
+ appsig_size = grub_strtol(arg, &end, 10);
|
||||
+ if (grub_errno)
|
||||
+ return 0;
|
||||
+ return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
@@ -679,9 +687,11 @@
|
||||
*p = '\0';
|
||||
|
||||
grub_util_info ("grub-mkimage --directory '%s' --prefix '%s' --output '%s'"
|
||||
- " --format '%s' --compression '%s'%s%s%s\n",
|
||||
+ " --format '%s' --compression '%s'"
|
||||
+ " --appended-signature-size %zu%s%s%s\n",
|
||||
dir, prefix, outname,
|
||||
mkimage_target, compnames[compression],
|
||||
+ appsig_size,
|
||||
note ? " --note" : "",
|
||||
disable_shim_lock ? " --disable-shim-lock" : "", s);
|
||||
free (s);
|
||||
@@ -693,7 +703,7 @@
|
||||
grub_install_generate_image (dir, prefix, fp, outname,
|
||||
modules.entries, memdisk_path,
|
||||
pubkeys, npubkeys, config_path, tgt,
|
||||
- note, compression, dtb, sbat,
|
||||
+ note, appsig_size, compression, dtb, sbat,
|
||||
disable_shim_lock);
|
||||
while (dc--)
|
||||
grub_install_pop_module ();
|
||||
--- a/util/grub-mkimage.c
|
||||
+++ b/util/grub-mkimage.c
|
||||
@@ -84,6 +84,7 @@
|
||||
{"sbat", 's', N_("FILE"), 0, N_("SBAT metadata"), 0},
|
||||
{"disable-shim-lock", GRUB_INSTALL_OPTIONS_DISABLE_SHIM_LOCK, 0, 0, N_("disable shim_lock verifier"), 0},
|
||||
{"verbose", 'v', 0, 0, N_("print verbose messages."), 0},
|
||||
+ {"appended-signature-size", 'S', N_("SIZE"), 0, N_("Add a note segment reserving SIZE bytes for an appended signature"), 0},
|
||||
{ 0, 0, 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -128,6 +129,7 @@
|
||||
char *sbat;
|
||||
int note;
|
||||
int disable_shim_lock;
|
||||
+ size_t appsig_size;
|
||||
const struct grub_install_image_target_desc *image_target;
|
||||
grub_compression_t comp;
|
||||
};
|
||||
@@ -138,6 +140,7 @@
|
||||
/* Get the input argument from argp_parse, which we
|
||||
know is a pointer to our arguments structure. */
|
||||
struct arguments *arguments = state->input;
|
||||
+ const char* end;
|
||||
|
||||
switch (key)
|
||||
{
|
||||
@@ -170,6 +173,13 @@
|
||||
arguments->note = 1;
|
||||
break;
|
||||
|
||||
+ case 'S':
|
||||
+ grub_errno = 0;
|
||||
+ arguments->appsig_size = grub_strtol(arg, &end, 10);
|
||||
+ if (grub_errno)
|
||||
+ return 0;
|
||||
+ break;
|
||||
+
|
||||
case 'm':
|
||||
if (arguments->memdisk)
|
||||
free (arguments->memdisk);
|
||||
@@ -324,6 +334,7 @@
|
||||
arguments.memdisk, arguments.pubkeys,
|
||||
arguments.npubkeys, arguments.config,
|
||||
arguments.image_target, arguments.note,
|
||||
+ arguments.appsig_size,
|
||||
arguments.comp, arguments.dtb,
|
||||
arguments.sbat, arguments.disable_shim_lock);
|
||||
|
||||
--- a/util/grub-mkimagexx.c
|
||||
+++ b/util/grub-mkimagexx.c
|
||||
@@ -85,6 +85,15 @@
|
||||
struct grub_ieee1275_note_desc descriptor;
|
||||
};
|
||||
|
||||
+#define GRUB_APPENDED_SIGNATURE_NOTE_NAME "Appended-Signature"
|
||||
+#define GRUB_APPENDED_SIGNATURE_NOTE_TYPE 0x41536967 /* "ASig" */
|
||||
+
|
||||
+struct grub_appended_signature_note
|
||||
+{
|
||||
+ Elf32_Nhdr header;
|
||||
+ char name[ALIGN_UP(sizeof (GRUB_APPENDED_SIGNATURE_NOTE_NAME), 4)];
|
||||
+};
|
||||
+
|
||||
#define GRUB_XEN_NOTE_NAME "Xen"
|
||||
|
||||
struct fixup_block_list
|
||||
@@ -208,7 +217,7 @@
|
||||
|
||||
void
|
||||
SUFFIX (grub_mkimage_generate_elf) (const struct grub_install_image_target_desc *image_target,
|
||||
- int note, char **core_img, size_t *core_size,
|
||||
+ int note, size_t appsig_size, char **core_img, size_t *core_size,
|
||||
Elf_Addr target_addr,
|
||||
struct grub_mkimage_layout *layout)
|
||||
{
|
||||
@@ -222,6 +231,12 @@
|
||||
int shnum = 4;
|
||||
int string_size = sizeof (".text") + sizeof ("mods") + 1;
|
||||
|
||||
+ if (appsig_size)
|
||||
+ {
|
||||
+ phnum++;
|
||||
+ footer_size += ALIGN_UP(sizeof (struct grub_appended_signature_note) + appsig_size, 4);
|
||||
+ }
|
||||
+
|
||||
if (image_target->id != IMAGE_LOONGSON_ELF)
|
||||
phnum += 2;
|
||||
|
||||
@@ -485,6 +500,28 @@
|
||||
phdr->p_offset = grub_host_to_target32 (header_size + program_size);
|
||||
}
|
||||
|
||||
+ if (appsig_size) {
|
||||
+ int note_size = ALIGN_UP(sizeof (struct grub_appended_signature_note) + appsig_size, 4);
|
||||
+ struct grub_appended_signature_note *note_ptr = (struct grub_appended_signature_note *)
|
||||
+ (elf_img + program_size + header_size + (note ? sizeof (struct grub_ieee1275_note) : 0));
|
||||
+
|
||||
+ note_ptr->header.n_namesz = grub_host_to_target32 (sizeof (GRUB_APPENDED_SIGNATURE_NOTE_NAME));
|
||||
+ /* needs to sit at the end, so we round this up and sign some zero padding */
|
||||
+ note_ptr->header.n_descsz = grub_host_to_target32 (ALIGN_UP(appsig_size, 4));
|
||||
+ note_ptr->header.n_type = grub_host_to_target32 (GRUB_APPENDED_SIGNATURE_NOTE_TYPE);
|
||||
+ strcpy (note_ptr->name, GRUB_APPENDED_SIGNATURE_NOTE_NAME);
|
||||
+
|
||||
+ phdr++;
|
||||
+ phdr->p_type = grub_host_to_target32 (PT_NOTE);
|
||||
+ phdr->p_flags = grub_host_to_target32 (PF_R);
|
||||
+ phdr->p_align = grub_host_to_target32 (image_target->voidp_sizeof);
|
||||
+ phdr->p_vaddr = 0;
|
||||
+ phdr->p_paddr = 0;
|
||||
+ phdr->p_filesz = grub_host_to_target32 (note_size);
|
||||
+ phdr->p_memsz = 0;
|
||||
+ phdr->p_offset = grub_host_to_target32 (header_size + program_size + (note ? sizeof (struct grub_ieee1275_note) : 0));
|
||||
+ }
|
||||
+
|
||||
{
|
||||
char *str_start = (elf_img + sizeof (*ehdr) + phnum * sizeof (*phdr)
|
||||
+ shnum * sizeof (*shdr));
|
||||
--- a/util/mkimage.c
|
||||
+++ b/util/mkimage.c
|
||||
@@ -885,8 +885,9 @@
|
||||
char *memdisk_path, char **pubkey_paths,
|
||||
size_t npubkeys, char *config_path,
|
||||
const struct grub_install_image_target_desc *image_target,
|
||||
- int note, grub_compression_t comp, const char *dtb_path,
|
||||
- const char *sbat_path, int disable_shim_lock)
|
||||
+ int note, size_t appsig_size, grub_compression_t comp,
|
||||
+ const char *dtb_path, const char *sbat_path,
|
||||
+ int disable_shim_lock)
|
||||
{
|
||||
char *kernel_img, *core_img;
|
||||
size_t total_module_size, core_size;
|
||||
@@ -1810,11 +1811,11 @@
|
||||
else
|
||||
target_addr = image_target->link_addr;
|
||||
if (image_target->voidp_sizeof == 4)
|
||||
- grub_mkimage_generate_elf32 (image_target, note, &core_img, &core_size,
|
||||
- target_addr, &layout);
|
||||
+ grub_mkimage_generate_elf32 (image_target, note, appsig_size, &core_img,
|
||||
+ &core_size, target_addr, &layout);
|
||||
else
|
||||
- grub_mkimage_generate_elf64 (image_target, note, &core_img, &core_size,
|
||||
- target_addr, &layout);
|
||||
+ grub_mkimage_generate_elf64 (image_target, note, appsig_size, &core_img,
|
||||
+ &core_size, target_addr, &layout);
|
||||
}
|
||||
break;
|
||||
}
|
279
0004-Introduce-prep_load_env-command.patch
Normal file
279
0004-Introduce-prep_load_env-command.patch
Normal file
@ -0,0 +1,279 @@
|
||||
From 3cf4fdf8d17423dea4e5913ab14fb6305f3c2571 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 18 Feb 2022 21:43:38 +0800
|
||||
Subject: [PATCH 4/5] Introduce prep_load_env command
|
||||
|
||||
This command will accept grub disk device and perform load_env for
|
||||
environment block located at end of PReP partition which belongs to that
|
||||
input disk device. All variables read from that environment block are
|
||||
exported to grub as environment variables.
|
||||
|
||||
Please note there's no support for whitelist variables and also
|
||||
--skip-sig option compared to ordinary load_env command.
|
||||
|
||||
v2:
|
||||
To avoid disrupting the boot process with errors, it's important to log
|
||||
any errors that may occur and always return GRUB_ERR_NONE.
|
||||
|
||||
v3:
|
||||
Making the new module powerpc_ieee1275 specific.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 5 +
|
||||
grub-core/commands/prep_loadenv.c | 227 ++++++++++++++++++++++++++++++
|
||||
2 files changed, 232 insertions(+)
|
||||
create mode 100644 grub-core/commands/prep_loadenv.c
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -2679,3 +2679,9 @@
|
||||
common = lib/libtasn1_wrap/tests/Test_strings.c;
|
||||
common = lib/libtasn1_wrap/wrap_tests.c;
|
||||
};
|
||||
+
|
||||
+module = {
|
||||
+ name = prep_loadenv;
|
||||
+ common = commands/prep_loadenv.c;
|
||||
+ enable = powerpc_ieee1275;
|
||||
+};
|
||||
--- /dev/null
|
||||
+++ b/grub-core/commands/prep_loadenv.c
|
||||
@@ -0,0 +1,237 @@
|
||||
+#include <grub/dl.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/file.h>
|
||||
+#include <grub/disk.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/err.h>
|
||||
+#include <grub/env.h>
|
||||
+#include <grub/partition.h>
|
||||
+#include <grub/lib/envblk.h>
|
||||
+#include <grub/extcmd.h>
|
||||
+#include <grub/i18n.h>
|
||||
+#include <grub/gpt_partition.h>
|
||||
+
|
||||
+GRUB_MOD_LICENSE ("GPLv3+");
|
||||
+
|
||||
+static char *
|
||||
+match_substr (regmatch_t *match, const char *str)
|
||||
+{
|
||||
+ if (match->rm_so != -1)
|
||||
+ {
|
||||
+ char *substr;
|
||||
+ regoff_t sz = match->rm_eo - match->rm_so;
|
||||
+
|
||||
+ if (!sz)
|
||||
+ return NULL;
|
||||
+ substr = grub_malloc (1 + sz);
|
||||
+ if (!substr)
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ grub_memcpy (substr, str + match->rm_so, sz);
|
||||
+ substr[sz] = '\0';
|
||||
+ return substr;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+is_prep_partition (grub_device_t dev)
|
||||
+{
|
||||
+ if (!dev->disk)
|
||||
+ return 0;
|
||||
+ if (!dev->disk->partition)
|
||||
+ return 0;
|
||||
+ if (grub_strcmp (dev->disk->partition->partmap->name, "msdos") == 0)
|
||||
+ return (dev->disk->partition->msdostype == 0x41);
|
||||
+
|
||||
+ if (grub_strcmp (dev->disk->partition->partmap->name, "gpt") == 0)
|
||||
+ {
|
||||
+ struct grub_gpt_partentry gptdata;
|
||||
+ grub_partition_t p = dev->disk->partition;
|
||||
+ int ret = 0;
|
||||
+ dev->disk->partition = dev->disk->partition->parent;
|
||||
+
|
||||
+ if (grub_disk_read (dev->disk, p->offset, p->index,
|
||||
+ sizeof (gptdata), &gptdata) == 0)
|
||||
+ {
|
||||
+ const grub_guid_t template = {
|
||||
+ grub_cpu_to_le32_compile_time (0x9e1a2d38),
|
||||
+ grub_cpu_to_le16_compile_time (0xc612),
|
||||
+ grub_cpu_to_le16_compile_time (0x4316),
|
||||
+ { 0xaa, 0x26, 0x8b, 0x49, 0x52, 0x1e, 0x5a, 0x8b }
|
||||
+ };
|
||||
+
|
||||
+ ret = grub_memcmp (&template, &gptdata.type,
|
||||
+ sizeof (template)) == 0;
|
||||
+ }
|
||||
+ dev->disk->partition = p;
|
||||
+ return ret;
|
||||
+ }
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+part_hook (grub_disk_t disk, const grub_partition_t partition, void *data)
|
||||
+{
|
||||
+ char **ret = data;
|
||||
+ char *partition_name, *devname;
|
||||
+ grub_device_t dev;
|
||||
+
|
||||
+ partition_name = grub_partition_get_name (partition);
|
||||
+ if (! partition_name)
|
||||
+ return 2;
|
||||
+
|
||||
+ devname = grub_xasprintf ("%s,%s", disk->name, partition_name);
|
||||
+ grub_free (partition_name);
|
||||
+ if (!devname)
|
||||
+ return 2;
|
||||
+
|
||||
+ dev = grub_device_open (devname);
|
||||
+ if (!dev)
|
||||
+ {
|
||||
+ grub_free (devname);
|
||||
+ return 2;
|
||||
+ }
|
||||
+ if (is_prep_partition (dev))
|
||||
+ {
|
||||
+ *ret = devname;
|
||||
+ return 1;
|
||||
+ }
|
||||
+ grub_free (devname);
|
||||
+ grub_device_close (dev);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+set_var (const char *name, const char *value,
|
||||
+ void *hook_data __attribute__ ((unused)))
|
||||
+{
|
||||
+ grub_env_set (name, value);
|
||||
+ grub_env_export (name);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+prep_read_envblk (const char *devname)
|
||||
+{
|
||||
+ char *buf = NULL;
|
||||
+ grub_device_t dev = NULL;
|
||||
+ grub_envblk_t envblk = NULL;
|
||||
+
|
||||
+ dev = grub_device_open (devname);
|
||||
+ if (!dev)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ if (!dev->disk || !dev->disk->partition)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_DEVICE, "disk device required");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+
|
||||
+ buf = grub_malloc (GRUB_ENVBLK_PREP_SIZE);
|
||||
+ if (!buf)
|
||||
+ goto fail;
|
||||
+
|
||||
+ if (grub_disk_read (dev->disk, dev->disk->partition->len - (GRUB_ENVBLK_PREP_SIZE >> GRUB_DISK_SECTOR_BITS), 0, GRUB_ENVBLK_PREP_SIZE, buf))
|
||||
+ goto fail;
|
||||
+
|
||||
+ envblk = grub_envblk_open (buf, GRUB_ENVBLK_PREP_SIZE);
|
||||
+ if (!envblk)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid environment block");
|
||||
+ goto fail;
|
||||
+ }
|
||||
+ grub_envblk_iterate (envblk, NULL, set_var);
|
||||
+
|
||||
+ fail:
|
||||
+ if (envblk)
|
||||
+ grub_envblk_close (envblk);
|
||||
+ else
|
||||
+ grub_free (buf);
|
||||
+ if (dev)
|
||||
+ grub_device_close (dev);
|
||||
+ return grub_errno;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+prep_partname (const char *devname, char **prep)
|
||||
+{
|
||||
+ grub_device_t dev = NULL;
|
||||
+ grub_err_t err;
|
||||
+ int ret;
|
||||
+
|
||||
+ dev = grub_device_open (devname);
|
||||
+ if (!dev)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ /* Only needed for disk device */
|
||||
+ if (!dev->disk)
|
||||
+ {
|
||||
+ err = GRUB_ERR_NONE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ ret = grub_partition_iterate (dev->disk, part_hook, prep);
|
||||
+ if (ret == 1 && *prep)
|
||||
+ {
|
||||
+ err = GRUB_ERR_NONE;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ else if (ret == 0 && grub_errno == GRUB_ERR_NONE)
|
||||
+ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "no prep partition");
|
||||
+ else
|
||||
+ err = grub_errno;
|
||||
+
|
||||
+ out:
|
||||
+ grub_device_close (dev);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
+grub_cmd_prep_loadenv (grub_command_t cmd __attribute__ ((unused)),
|
||||
+ int argc,
|
||||
+ char **argv)
|
||||
+{
|
||||
+ char *devname, *prep = NULL;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ if (argc < 1)
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT, "device name required");
|
||||
+
|
||||
+ devname = grub_file_get_device_name(argv[0]);
|
||||
+ if (!devname)
|
||||
+ return grub_errno;
|
||||
+
|
||||
+ err = prep_partname (devname, &prep);
|
||||
+ if (prep == NULL || err != GRUB_ERR_NONE)
|
||||
+ goto out;
|
||||
+
|
||||
+ err = prep_read_envblk (prep);
|
||||
+
|
||||
+ out:
|
||||
+ grub_free (devname);
|
||||
+ grub_free (prep);
|
||||
+
|
||||
+ if (err)
|
||||
+ grub_print_error ();
|
||||
+ return GRUB_ERR_NONE;
|
||||
+}
|
||||
+
|
||||
+static grub_command_t cmd_prep_load;
|
||||
+
|
||||
+GRUB_MOD_INIT(prep_loadenv)
|
||||
+{
|
||||
+ cmd_prep_load =
|
||||
+ grub_register_command("prep_load_env", grub_cmd_prep_loadenv,
|
||||
+ "DEVICE",
|
||||
+ N_("Load variables from environment block file."));
|
||||
+}
|
||||
+
|
||||
+GRUB_MOD_FINI(prep_loadenv)
|
||||
+{
|
||||
+ grub_unregister_command (cmd_prep_load);
|
||||
+}
|
91
0004-Key-revocation-on-out-of-bound-file-access.patch
Normal file
91
0004-Key-revocation-on-out-of-bound-file-access.patch
Normal file
@ -0,0 +1,91 @@
|
||||
From 6547d22fc9e20720d1a896be82b2d50d842f86b0 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Mon, 20 Nov 2023 09:25:53 +0800
|
||||
Subject: [PATCH 4/4] Key revocation on out of bound file access
|
||||
|
||||
After successful disk unlocking, grub now takes on the responsibility of
|
||||
safeguarding passwords or TPM keys exclusively within authenticated
|
||||
cryptodisk files. Any attempt to access boot-related files outside this
|
||||
trust realm triggers immediate key revocation, preventing potential
|
||||
compromise by out of bound access.
|
||||
|
||||
This patch strengthens security measures by restricting grub's access to
|
||||
system boot files, except for essential internal processes like memdisk
|
||||
and procfs, ensuring key protection against potential breaches due to
|
||||
inadvertent customizations in grub.cfg.
|
||||
|
||||
Signed-Off-by Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/crypttab.c | 36 +++++++++++++++++++++++++++++++++++
|
||||
include/grub/file.h | 1 +
|
||||
2 files changed, 37 insertions(+)
|
||||
|
||||
diff --git a/grub-core/commands/crypttab.c b/grub-core/commands/crypttab.c
|
||||
index d3acc4b59..e09296c57 100644
|
||||
--- a/grub-core/commands/crypttab.c
|
||||
+++ b/grub-core/commands/crypttab.c
|
||||
@@ -121,6 +121,41 @@ grub_cryptokey_tpmkey_discard (void)
|
||||
grub_cryptokey_discard();
|
||||
}
|
||||
|
||||
+static grub_file_t
|
||||
+grub_distrust_open (grub_file_t io,
|
||||
+ enum grub_file_type type __attribute__ ((unused)))
|
||||
+{
|
||||
+ grub_disk_t disk = io->device->disk;
|
||||
+
|
||||
+ if (io->device->disk &&
|
||||
+ (io->device->disk->dev->id == GRUB_DISK_DEVICE_MEMDISK_ID
|
||||
+ || io->device->disk->dev->id == GRUB_DISK_DEVICE_PROCFS_ID))
|
||||
+ return io;
|
||||
+
|
||||
+ /* Ensure second stage files is in a protected location or grub won't hand
|
||||
+ * over the key and discards it */
|
||||
+ switch (type & GRUB_FILE_TYPE_MASK)
|
||||
+ {
|
||||
+ case GRUB_FILE_TYPE_ACPI_TABLE:
|
||||
+ case GRUB_FILE_TYPE_CONFIG:
|
||||
+ case GRUB_FILE_TYPE_DEVICE_TREE_IMAGE:
|
||||
+ case GRUB_FILE_TYPE_FONT:
|
||||
+ case GRUB_FILE_TYPE_GRUB_MODULE:
|
||||
+ case GRUB_FILE_TYPE_GRUB_MODULE_LIST:
|
||||
+ case GRUB_FILE_TYPE_LINUX_KERNEL:
|
||||
+ case GRUB_FILE_TYPE_LINUX_INITRD:
|
||||
+ case GRUB_FILE_TYPE_LOADENV:
|
||||
+ case GRUB_FILE_TYPE_THEME:
|
||||
+ if (!disk || !grub_disk_is_crypto (disk))
|
||||
+ grub_cryptokey_discard ();
|
||||
+ break;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return io;
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_crypttab_entry (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc, char **argv)
|
||||
@@ -153,6 +188,7 @@ GRUB_MOD_INIT(crypttab)
|
||||
{
|
||||
cmd = grub_register_command ("crypttab_entry", grub_cmd_crypttab_entry,
|
||||
N_("VOLUME-NAME ENCRYPTED-DEVICE KEY-FILE") , N_("No description"));
|
||||
+ grub_file_filter_register (GRUB_FILE_FILTER_DISTRUST, grub_distrust_open);
|
||||
grub_dl_set_persistent (mod);
|
||||
}
|
||||
|
||||
diff --git a/include/grub/file.h b/include/grub/file.h
|
||||
index fcfd32ce2..daf23a9c9 100644
|
||||
--- a/include/grub/file.h
|
||||
+++ b/include/grub/file.h
|
||||
@@ -185,6 +185,7 @@ extern grub_disk_read_hook_t EXPORT_VAR(grub_file_progress_hook);
|
||||
/* Filters with lower ID are executed first. */
|
||||
typedef enum grub_file_filter_id
|
||||
{
|
||||
+ GRUB_FILE_FILTER_DISTRUST,
|
||||
GRUB_FILE_FILTER_NOCAT,
|
||||
GRUB_FILE_FILTER_VERIFY,
|
||||
GRUB_FILE_FILTER_GZIO,
|
||||
--
|
||||
2.42.1
|
||||
|
183
0004-Try-to-pick-better-locations-for-kernel-and-initrd.patch
Normal file
183
0004-Try-to-pick-better-locations-for-kernel-and-initrd.patch
Normal file
@ -0,0 +1,183 @@
|
||||
From 384763d7990f769839ca74d6756fbd85580873d4 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Thu, 11 Jul 2019 17:17:02 +0200
|
||||
Subject: [PATCH 04/11] Try to pick better locations for kernel and initrd
|
||||
|
||||
- Don't limit allocations on 64-bit platforms to < 0x[37f]fffffff if
|
||||
we're using the "large" code model ; use __UINTPTR_MAX__.
|
||||
- Get the comparison right to check the address we've allocated.
|
||||
- Fix the allocation for the command line as well.
|
||||
|
||||
*But*, when we did this some systems started failing badly; coudln't
|
||||
parse partition tables, etc. What's going on here is the disk controller
|
||||
is silently failing DMAs to addresses above 4GB, so we're trying to parse
|
||||
uninitialized (or HW zeroed) ram when looking for the partition table,
|
||||
etc.
|
||||
|
||||
So to limit this, we make grub_malloc() pick addresses below 4GB on
|
||||
x86_64, but the direct EFI page allocation functions can get addresses
|
||||
above that.
|
||||
|
||||
Additionally, we now try to locate kernel+initrd+cmdline+etc below
|
||||
0x7fffffff, and if they're too big to fit any memory window there, then
|
||||
we try a higher address.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
---
|
||||
grub-core/kern/efi/mm.c | 8 ++++----
|
||||
grub-core/loader/i386/efi/linux.c | 25 +++++++++++++++++--------
|
||||
include/grub/arm/efi/memory.h | 1 +
|
||||
include/grub/arm64/efi/memory.h | 1 +
|
||||
include/grub/i386/efi/memory.h | 1 +
|
||||
include/grub/ia64/efi/memory.h | 1 +
|
||||
include/grub/x86_64/efi/memory.h | 4 +++-
|
||||
7 files changed, 28 insertions(+), 13 deletions(-)
|
||||
|
||||
--- a/grub-core/kern/efi/mm.c
|
||||
+++ b/grub-core/kern/efi/mm.c
|
||||
@@ -121,7 +121,7 @@
|
||||
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;
|
||||
@@ -481,7 +481,7 @@
|
||||
{
|
||||
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)
|
||||
@@ -499,9 +499,9 @@
|
||||
#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
|
||||
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <grub/lib/cmdline.h>
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/efi/linux.h>
|
||||
+#include <grub/cpu/efi/memory.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -102,8 +103,9 @@
|
||||
size += ALIGN_UP (grub_file_size (files[i]), 4);
|
||||
}
|
||||
|
||||
- initrd_mem = grub_efi_allocate_pages_max (0x3fffffff, BYTES_TO_PAGES(size));
|
||||
-
|
||||
+ initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS, BYTES_TO_PAGES(size));
|
||||
+ if (!initrd_mem)
|
||||
+ initrd_mem = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS, BYTES_TO_PAGES(size));
|
||||
if (!initrd_mem)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate initrd"));
|
||||
@@ -187,8 +189,11 @@
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- params = grub_efi_allocate_pages_max (0x3fffffff,
|
||||
+ params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_ALLOCATION_ADDRESS,
|
||||
BYTES_TO_PAGES(sizeof(*params)));
|
||||
+ if (!params)
|
||||
+ params = grub_efi_allocate_pages_max (GRUB_EFI_MAX_USABLE_ADDRESS,
|
||||
+ BYTES_TO_PAGES(sizeof(*params)));
|
||||
if (! params)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, "cannot allocate kernel parameters");
|
||||
@@ -258,8 +263,11 @@
|
||||
#endif
|
||||
|
||||
grub_dprintf ("linux", "setting up cmdline\n");
|
||||
- linux_cmdline = grub_efi_allocate_pages_max(0x3fffffff,
|
||||
- BYTES_TO_PAGES(lh->cmdline_size + 1));
|
||||
+ linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_ALLOCATION_ADDRESS,
|
||||
+ BYTES_TO_PAGES(lh->cmdline_size + 1));
|
||||
+ if (!linux_cmdline)
|
||||
+ linux_cmdline = grub_efi_allocate_pages_max(GRUB_EFI_MAX_USABLE_ADDRESS,
|
||||
+ BYTES_TO_PAGES(lh->cmdline_size + 1));
|
||||
if (!linux_cmdline)
|
||||
{
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("can't allocate cmdline"));
|
||||
@@ -285,11 +293,12 @@
|
||||
|
||||
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"));
|
||||
--- 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 */
|
||||
--- 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 */
|
||||
--- 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 */
|
||||
--- 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 */
|
||||
--- 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 */
|
301
0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch
Normal file
301
0004-arm-arm64-loader-Better-memory-allocation-and-error-.patch
Normal file
@ -0,0 +1,301 @@
|
||||
From 5d417346956bc3108183020a8a9f20ddda034b48 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Thu, 11 Jul 2019 14:38:57 +0200
|
||||
Subject: [PATCH 4/9] arm/arm64 loader: Better memory allocation and error
|
||||
messages.
|
||||
|
||||
On mustang, our memory map looks like:
|
||||
|
||||
Type Physical start - end #Pages Size Attributes
|
||||
reserved 0000004000000000-00000040001fffff 00000200 2MiB UC WC WT WB
|
||||
conv-mem 0000004000200000-0000004393ffffff 00393e00 14654MiB UC WC WT WB
|
||||
ldr-code 0000004394000000-00000043f7ffffff 00064000 1600MiB UC WC WT WB
|
||||
BS-data 00000043f8000000-00000043f801ffff 00000020 128KiB UC WC WT WB
|
||||
conv-mem 00000043f8020000-00000043fa15bfff 0000213c 34032KiB UC WC WT WB
|
||||
ldr-code 00000043fa15c000-00000043fa2a1fff 00000146 1304KiB UC WC WT WB
|
||||
ldr-data 00000043fa2a2000-00000043fa3e8fff 00000147 1308KiB UC WC WT WB
|
||||
conv-mem 00000043fa3e9000-00000043fa3e9fff 00000001 4KiB UC WC WT WB
|
||||
ldr-data 00000043fa3ea000-00000043fa3eafff 00000001 4KiB UC WC WT WB
|
||||
ldr-code 00000043fa3eb000-00000043fa4affff 000000c5 788KiB UC WC WT WB
|
||||
BS-code 00000043fa4b0000-00000043fa59ffff 000000f0 960KiB UC WC WT WB
|
||||
RT-code 00000043fa5a0000-00000043fa5affff 00000010 64KiB RT UC WC WT WB
|
||||
RT-data 00000043fa5b0000-00000043fa5bffff 00000010 64KiB RT UC WC WT WB
|
||||
RT-code 00000043fa5c0000-00000043fa5cffff 00000010 64KiB RT UC WC WT WB
|
||||
ldr-data 00000043fa5d0000-00000043fa5d0fff 00000001 4KiB UC WC WT WB
|
||||
BS-code 00000043fa5d1000-00000043fa5ddfff 0000000d 52KiB UC WC WT WB
|
||||
reserved 00000043fa5de000-00000043fa60ffff 00000032 200KiB UC WC WT WB
|
||||
ACPI-rec 00000043fa610000-00000043fa6affff 000000a0 640KiB UC WC WT WB
|
||||
ACPI-nvs 00000043fa6b0000-00000043fa6bffff 00000010 64KiB UC WC WT WB
|
||||
ACPI-rec 00000043fa6c0000-00000043fa70ffff 00000050 320KiB UC WC WT WB
|
||||
RT-code 00000043fa710000-00000043fa72ffff 00000020 128KiB RT UC WC WT WB
|
||||
RT-data 00000043fa730000-00000043fa78ffff 00000060 384KiB RT UC WC WT WB
|
||||
RT-code 00000043fa790000-00000043fa79ffff 00000010 64KiB RT UC WC WT WB
|
||||
RT-data 00000043fa7a0000-00000043fa99ffff 00000200 2MiB RT UC WC WT WB
|
||||
RT-code 00000043fa9a0000-00000043fa9affff 00000010 64KiB RT UC WC WT WB
|
||||
RT-data 00000043fa9b0000-00000043fa9cffff 00000020 128KiB RT UC WC WT WB
|
||||
BS-code 00000043fa9d0000-00000043fa9d9fff 0000000a 40KiB UC WC WT WB
|
||||
reserved 00000043fa9da000-00000043fa9dbfff 00000002 8KiB UC WC WT WB
|
||||
conv-mem 00000043fa9dc000-00000043fc29dfff 000018c2 25352KiB UC WC WT WB
|
||||
BS-data 00000043fc29e000-00000043fc78afff 000004ed 5044KiB UC WC WT WB
|
||||
conv-mem 00000043fc78b000-00000043fca01fff 00000277 2524KiB UC WC WT WB
|
||||
BS-data 00000043fca02000-00000043fcea3fff 000004a2 4744KiB UC WC WT WB
|
||||
conv-mem 00000043fcea4000-00000043fcea4fff 00000001 4KiB UC WC WT WB
|
||||
BS-data 00000043fcea5000-00000043fd192fff 000002ee 3000KiB UC WC WT WB
|
||||
conv-mem 00000043fd193000-00000043fd2b0fff 0000011e 1144KiB UC WC WT WB
|
||||
BS-data 00000043fd2b1000-00000043ff80ffff 0000255f 38268KiB UC WC WT WB
|
||||
BS-code 00000043ff810000-00000043ff99ffff 00000190 1600KiB UC WC WT WB
|
||||
RT-code 00000043ff9a0000-00000043ff9affff 00000010 64KiB RT UC WC WT WB
|
||||
conv-mem 00000043ff9b0000-00000043ff9bffff 00000010 64KiB UC WC WT WB
|
||||
RT-data 00000043ff9c0000-00000043ff9effff 00000030 192KiB RT UC WC WT WB
|
||||
conv-mem 00000043ff9f0000-00000043ffa05fff 00000016 88KiB UC WC WT WB
|
||||
BS-data 00000043ffa06000-00000043ffffffff 000005fa 6120KiB UC WC WT WB
|
||||
MMIO 0000000010510000-0000000010510fff 00000001 4KiB RT
|
||||
MMIO 0000000010548000-0000000010549fff 00000002 8KiB RT
|
||||
MMIO 0000000017000000-0000000017001fff 00000002 8KiB RT
|
||||
MMIO 000000001c025000-000000001c025fff 00000001 4KiB RT
|
||||
|
||||
This patch adds a requirement when we're trying to find the base of ram, that
|
||||
the memory we choose is actually /allocatable/ conventional memory, not merely
|
||||
write-combining. On this machine that means we wind up with an allocation
|
||||
around 0x4392XXXXXX, which is a reasonable address.
|
||||
|
||||
This also changes grub_efi_allocate_pages_real() so that if 0 is allocated, it
|
||||
tries to allocate again starting with the same max address it did the first
|
||||
time, rather than interposing GRUB_EFI_MAX_USABLE_ADDRESS there, so that any
|
||||
per-platform constraints on its given address are maintained.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
|
||||
squash! arm/arm64 loader: Better memory allocation and error messages.
|
||||
|
||||
Use PRIxGRUB_* conversion specifier in printf's format string to
|
||||
correspond properly to the data type of arguments.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/kern/efi/mm.c | 33 ++++++++++---
|
||||
grub-core/loader/arm64/efi/linux.c | 78 ++++++++++++++++++++++--------
|
||||
2 files changed, 84 insertions(+), 27 deletions(-)
|
||||
|
||||
--- a/grub-core/kern/efi/mm.c
|
||||
+++ b/grub-core/kern/efi/mm.c
|
||||
@@ -153,6 +153,7 @@
|
||||
{
|
||||
grub_efi_status_t status;
|
||||
grub_efi_boot_services_t *b;
|
||||
+ grub_efi_physical_address_t ret = address;
|
||||
|
||||
/* Limit the memory access to less than 4GB for 32-bit platforms. */
|
||||
if (address > GRUB_EFI_MAX_USABLE_ADDRESS)
|
||||
@@ -169,19 +170,22 @@
|
||||
}
|
||||
|
||||
b = grub_efi_system_table->boot_services;
|
||||
- status = b->allocate_pages (alloctype, memtype, pages, &address);
|
||||
+ status = b->allocate_pages (alloctype, memtype, pages, &ret);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
+ grub_dprintf ("efi",
|
||||
+ "allocate_pages(%d, %d, 0x%0" PRIxGRUB_SIZE ", 0x%016" PRIxGRUB_UINT64_T ") = 0x%016" PRIxGRUB_SIZE "\n",
|
||||
+ alloctype, memtype, pages, address, status);
|
||||
grub_error (GRUB_ERR_OUT_OF_MEMORY, N_("out of memory"));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- if (address == 0)
|
||||
+ if (ret == 0)
|
||||
{
|
||||
/* Uggh, the address 0 was allocated... This is too annoying,
|
||||
so reallocate another one. */
|
||||
- address = GRUB_EFI_MAX_USABLE_ADDRESS;
|
||||
- status = b->allocate_pages (alloctype, memtype, pages, &address);
|
||||
+ ret = address;
|
||||
+ status = b->allocate_pages (alloctype, memtype, pages, &ret);
|
||||
grub_efi_free_pages (0, pages);
|
||||
if (status != GRUB_EFI_SUCCESS)
|
||||
{
|
||||
@@ -190,9 +194,9 @@
|
||||
}
|
||||
}
|
||||
|
||||
- grub_efi_store_alloc (address, pages);
|
||||
+ grub_efi_store_alloc (ret, pages);
|
||||
|
||||
- return (void *) ((grub_addr_t) address);
|
||||
+ return (void *) ((grub_addr_t) ret);
|
||||
}
|
||||
|
||||
void *
|
||||
@@ -711,8 +715,21 @@
|
||||
for (desc = memory_map, *base_addr = GRUB_EFI_MAX_USABLE_ADDRESS;
|
||||
(grub_addr_t) desc < ((grub_addr_t) memory_map + memory_map_size);
|
||||
desc = NEXT_MEMORY_DESCRIPTOR (desc, desc_size))
|
||||
- if (desc->attribute & GRUB_EFI_MEMORY_WB)
|
||||
- *base_addr = grub_min (*base_addr, desc->physical_start);
|
||||
+ {
|
||||
+ if (desc->type == GRUB_EFI_CONVENTIONAL_MEMORY &&
|
||||
+ (desc->attribute & GRUB_EFI_MEMORY_WB))
|
||||
+ {
|
||||
+ *base_addr = grub_min (*base_addr, desc->physical_start);
|
||||
+ grub_dprintf ("efi", "setting base_addr=0x%016" PRIxGRUB_ADDR "\n", *base_addr);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ grub_dprintf ("efi", "ignoring address 0x%016" PRIxGRUB_UINT64_T "\n", desc->physical_start);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (*base_addr == GRUB_EFI_MAX_USABLE_ADDRESS)
|
||||
+ grub_dprintf ("efi", "base_addr 0x%016" PRIxGRUB_ADDR " is probably wrong.\n", *base_addr);
|
||||
|
||||
grub_free(memory_map);
|
||||
|
||||
--- a/grub-core/loader/arm64/efi/linux.c
|
||||
+++ b/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -89,13 +89,15 @@
|
||||
{
|
||||
grub_efi_loaded_image_t *loaded_image = NULL;
|
||||
int node, retval, len;
|
||||
-
|
||||
+ grub_err_t err = GRUB_ERR_NONE;
|
||||
void *fdt;
|
||||
|
||||
fdt = grub_fdt_load (GRUB_EFI_LINUX_FDT_EXTRA_SPACE);
|
||||
-
|
||||
if (!fdt)
|
||||
- goto failure;
|
||||
+ {
|
||||
+ err = grub_error(GRUB_ERR_BAD_OS, "failed to load FDT");
|
||||
+ goto failure;
|
||||
+ }
|
||||
|
||||
node = grub_fdt_find_subnode (fdt, 0, "chosen");
|
||||
if (node < 0)
|
||||
@@ -106,17 +108,26 @@
|
||||
*/
|
||||
retval = grub_fdt_set_prop32(fdt, 0, "#address-cells", 2);
|
||||
if (retval)
|
||||
- goto failure;
|
||||
+ {
|
||||
+ err = grub_error(retval, "Could not find #address-cells");
|
||||
+ goto failure;
|
||||
+ }
|
||||
|
||||
retval = grub_fdt_set_prop32(fdt, 0, "#size-cells", 2);
|
||||
if (retval)
|
||||
- goto failure;
|
||||
+ {
|
||||
+ err = grub_error(retval, "Could not find #size-cells");
|
||||
+ goto failure;
|
||||
+ }
|
||||
|
||||
node = grub_fdt_add_subnode (fdt, 0, "chosen");
|
||||
}
|
||||
|
||||
if (node < 1)
|
||||
- goto failure;
|
||||
+ {
|
||||
+ err = grub_error(grub_errno, "failed to load chosen fdt node.");
|
||||
+ goto failure;
|
||||
+ }
|
||||
|
||||
/* Set initrd info */
|
||||
if (initrd_start && initrd_end > initrd_start)
|
||||
@@ -127,15 +138,26 @@
|
||||
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-start",
|
||||
initrd_start);
|
||||
if (retval)
|
||||
- goto failure;
|
||||
+ {
|
||||
+ err = grub_error(retval, "Failed to set linux,initrd-start property");
|
||||
+ goto failure;
|
||||
+ }
|
||||
+
|
||||
retval = grub_fdt_set_prop64 (fdt, node, "linux,initrd-end",
|
||||
initrd_end);
|
||||
if (retval)
|
||||
- goto failure;
|
||||
+ {
|
||||
+ err = grub_error(retval, "Failed to set linux,initrd-end property");
|
||||
+ goto failure;
|
||||
+ }
|
||||
}
|
||||
|
||||
- if (grub_fdt_install() != GRUB_ERR_NONE)
|
||||
- goto failure;
|
||||
+ retval = grub_fdt_install();
|
||||
+ if (retval != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ err = grub_error(retval, "Failed to install fdt");
|
||||
+ goto failure;
|
||||
+ }
|
||||
|
||||
grub_dprintf ("linux", "Installed/updated FDT configuration table @ %p\n",
|
||||
fdt);
|
||||
@@ -143,14 +165,20 @@
|
||||
/* Convert command line to UCS-2 */
|
||||
loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
if (!loaded_image)
|
||||
- goto failure;
|
||||
+ {
|
||||
+ err = grub_error(grub_errno, "Failed to install fdt");
|
||||
+ goto failure;
|
||||
+ }
|
||||
|
||||
loaded_image->load_options_size = len =
|
||||
(grub_strlen (linux_args) + 1) * sizeof (grub_efi_char16_t);
|
||||
loaded_image->load_options =
|
||||
grub_efi_allocate_any_pages (GRUB_EFI_BYTES_TO_PAGES (loaded_image->load_options_size));
|
||||
if (!loaded_image->load_options)
|
||||
- return grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
|
||||
+ {
|
||||
+ err = grub_error(GRUB_ERR_BAD_OS, "failed to create kernel parameters");
|
||||
+ goto failure;
|
||||
+ }
|
||||
|
||||
loaded_image->load_options_size =
|
||||
2 * grub_utf8_to_utf16 (loaded_image->load_options, len,
|
||||
@@ -160,7 +188,7 @@
|
||||
|
||||
failure:
|
||||
grub_fdt_unload();
|
||||
- return grub_error(GRUB_ERR_BAD_OS, "failed to install/update FDT");
|
||||
+ return err;
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -246,16 +274,28 @@
|
||||
static void *
|
||||
allocate_initrd_mem (int initrd_pages)
|
||||
{
|
||||
- grub_addr_t max_addr;
|
||||
+ grub_addr_t max_addr = 0;
|
||||
+ grub_err_t err;
|
||||
+ void *ret;
|
||||
+
|
||||
+ err = grub_efi_get_ram_base (&max_addr);
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ grub_error (err, "grub_efi_get_ram_base() failed");
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
- if (grub_efi_get_ram_base (&max_addr) != GRUB_ERR_NONE)
|
||||
- return NULL;
|
||||
+ grub_dprintf ("linux", "max_addr: 0x%016lx, INITRD_MAX_ADDRESS_OFFSET: 0x%016llx\n",
|
||||
+ max_addr, INITRD_MAX_ADDRESS_OFFSET);
|
||||
|
||||
max_addr += INITRD_MAX_ADDRESS_OFFSET - 1;
|
||||
+ grub_dprintf ("linux", "calling grub_efi_allocate_pages_real (0x%016lx, 0x%08x, EFI_ALLOCATE_MAX_ADDRESS, EFI_LOADER_DATA)", max_addr, initrd_pages);
|
||||
|
||||
- return grub_efi_allocate_pages_real (max_addr, initrd_pages,
|
||||
- GRUB_EFI_ALLOCATE_MAX_ADDRESS,
|
||||
- GRUB_EFI_LOADER_DATA);
|
||||
+ ret = grub_efi_allocate_pages_real (max_addr, initrd_pages,
|
||||
+ GRUB_EFI_ALLOCATE_MAX_ADDRESS,
|
||||
+ GRUB_EFI_LOADER_DATA);
|
||||
+ grub_dprintf ("linux", "got 0x%016llx\n", (unsigned long long)ret);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static grub_err_t
|
30
0004-blscfg-Don-t-root-device-in-emu-builds.patch
Normal file
30
0004-blscfg-Don-t-root-device-in-emu-builds.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 2fccb958910afaaf03cbec1a6b98ad197d088ad4 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Thu, 25 Aug 2022 17:57:55 -0400
|
||||
Subject: [PATCH 4/9] blscfg: Don't root device in emu builds
|
||||
|
||||
Otherwise, we end up looking for kernel/initrd in /boot/boot which
|
||||
doesn't work at all. Non-emu builds need to be looking in
|
||||
($root)/boot/, which is what this is for.
|
||||
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index 7132555df..150ca96f4 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -41,7 +41,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
#define GRUB_BLS_CONFIG_PATH "/loader/entries/"
|
||||
#ifdef GRUB_MACHINE_EMU
|
||||
-#define GRUB_BOOT_DEVICE "/boot"
|
||||
+#define GRUB_BOOT_DEVICE ""
|
||||
#else
|
||||
#define GRUB_BOOT_DEVICE "($root)"
|
||||
#endif
|
||||
--
|
||||
2.44.0
|
||||
|
356
0004-cryptodisk-Support-key-protectors.patch
Normal file
356
0004-cryptodisk-Support-key-protectors.patch
Normal file
@ -0,0 +1,356 @@
|
||||
From 7ce7b7889ce73174a0d8091978254ecf2d2e205f Mon Sep 17 00:00:00 2001
|
||||
From: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Date: Tue, 1 Feb 2022 05:02:56 -0800
|
||||
Subject: [PATCH 4/5] cryptodisk: Support key protectors
|
||||
|
||||
Add a new parameter to cryptomount to support the key protectors framework: -P.
|
||||
The parameter is used to automatically retrieve a key from specified key
|
||||
protectors. The parameter may be repeated to specify any number of key
|
||||
protectors. These are tried in order until one provides a usable key for any
|
||||
given disk.
|
||||
|
||||
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Glenn Washburn <development@efficientek.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
Makefile.util.def | 1 +
|
||||
grub-core/disk/cryptodisk.c | 172 +++++++++++++++++++++++++++++-------
|
||||
include/grub/cryptodisk.h | 16 ++++
|
||||
3 files changed, 158 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/Makefile.util.def b/Makefile.util.def
|
||||
index 3b9435307..252d70af2 100644
|
||||
--- a/Makefile.util.def
|
||||
+++ b/Makefile.util.def
|
||||
@@ -40,6 +40,7 @@ library = {
|
||||
common = grub-core/disk/luks.c;
|
||||
common = grub-core/disk/luks2.c;
|
||||
common = grub-core/disk/geli.c;
|
||||
+ common = grub-core/disk/key_protector.c;
|
||||
common = grub-core/disk/cryptodisk.c;
|
||||
common = grub-core/disk/AFSplitter.c;
|
||||
common = grub-core/lib/pbkdf2.c;
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 2246af51b..b7648ffb7 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <grub/file.h>
|
||||
#include <grub/procfs.h>
|
||||
#include <grub/partition.h>
|
||||
+#include <grub/key_protector.h>
|
||||
|
||||
#ifdef GRUB_UTIL
|
||||
#include <grub/emu/hostdisk.h>
|
||||
@@ -44,7 +45,8 @@ enum
|
||||
OPTION_KEYFILE,
|
||||
OPTION_KEYFILE_OFFSET,
|
||||
OPTION_KEYFILE_SIZE,
|
||||
- OPTION_HEADER
|
||||
+ OPTION_HEADER,
|
||||
+ OPTION_PROTECTOR
|
||||
};
|
||||
|
||||
static const struct grub_arg_option options[] =
|
||||
@@ -58,6 +60,8 @@ static const struct grub_arg_option options[] =
|
||||
{"keyfile-offset", 'O', 0, N_("Key file offset (bytes)"), 0, ARG_TYPE_INT},
|
||||
{"keyfile-size", 'S', 0, N_("Key file data size (bytes)"), 0, ARG_TYPE_INT},
|
||||
{"header", 'H', 0, N_("Read header from file"), 0, ARG_TYPE_STRING},
|
||||
+ {"protector", 'P', GRUB_ARG_OPTION_REPEATABLE,
|
||||
+ N_("Unlock volume(s) using key protector(s)."), 0, ARG_TYPE_STRING},
|
||||
{0, 0, 0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -1061,6 +1065,7 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
grub_err_t ret = GRUB_ERR_NONE;
|
||||
grub_cryptodisk_t dev;
|
||||
grub_cryptodisk_dev_t cr;
|
||||
+ int i;
|
||||
struct cryptodisk_read_hook_ctx read_hook_data = {0};
|
||||
int askpass = 0;
|
||||
char *part = NULL;
|
||||
@@ -1113,41 +1118,112 @@ grub_cryptodisk_scan_device_real (const char *name,
|
||||
goto error_no_close;
|
||||
if (!dev)
|
||||
continue;
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- if (!cargs->key_len)
|
||||
- {
|
||||
- /* Get the passphrase from the user, if no key data. */
|
||||
- askpass = 1;
|
||||
- part = grub_partition_get_name (source->partition);
|
||||
- grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
- source->partition != NULL ? "," : "",
|
||||
- part != NULL ? part : N_("UNKNOWN"),
|
||||
- dev->uuid);
|
||||
- grub_free (part);
|
||||
-
|
||||
- cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
||||
- if (cargs->key_data == NULL)
|
||||
- goto error_no_close;
|
||||
-
|
||||
- if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||
- {
|
||||
- grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||
- goto error;
|
||||
- }
|
||||
- cargs->key_len = grub_strlen ((char *) cargs->key_data);
|
||||
- }
|
||||
+ if (dev == NULL)
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_MODULE,
|
||||
+ "no cryptodisk module can handle this device");
|
||||
+ goto error_no_close;
|
||||
+ }
|
||||
|
||||
- ret = cr->recover_key (source, dev, cargs);
|
||||
- if (ret != GRUB_ERR_NONE)
|
||||
- goto error;
|
||||
+ if (cargs->protectors)
|
||||
+ {
|
||||
+ for (i = 0; cargs->protectors[i]; i++)
|
||||
+ {
|
||||
+ if (cargs->key_cache[i].invalid)
|
||||
+ continue;
|
||||
+
|
||||
+ if (cargs->key_cache[i].key == NULL)
|
||||
+ {
|
||||
+ ret = grub_key_protector_recover_key (cargs->protectors[i],
|
||||
+ &cargs->key_cache[i].key,
|
||||
+ &cargs->key_cache[i].key_len);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ if (grub_errno)
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ grub_errno = GRUB_ERR_NONE;
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("cryptodisk",
|
||||
+ "failed to recover a key from key protector "
|
||||
+ "%s, will not try it again for any other "
|
||||
+ "disks, if any, during this invocation of "
|
||||
+ "cryptomount\n",
|
||||
+ cargs->protectors[i]);
|
||||
+
|
||||
+ cargs->key_cache[i].invalid = 1;
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ cargs->key_data = cargs->key_cache[i].key;
|
||||
+ cargs->key_len = cargs->key_cache[i].key_len;
|
||||
+
|
||||
+ ret = cr->recover_key (source, dev, cargs);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ {
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_dprintf ("cryptodisk",
|
||||
+ "recovered a key from key protector %s but it "
|
||||
+ "failed to unlock %s%s%s (%s)\n",
|
||||
+ cargs->protectors[i], source->name,
|
||||
+ source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||
+ grub_free (part);
|
||||
+ continue;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ret = grub_cryptodisk_insert (dev, name, source);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ goto error;
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- ret = grub_cryptodisk_insert (dev, name, source);
|
||||
- if (ret != GRUB_ERR_NONE)
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_error (GRUB_ERR_ACCESS_DENIED,
|
||||
+ N_("no key protector provided a usable key for %s%s%s (%s)"),
|
||||
+ source->name, source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||
+ grub_free (part);
|
||||
goto error;
|
||||
+ }
|
||||
+
|
||||
+ if (!cargs->key_len)
|
||||
+ {
|
||||
+ /* Get the passphrase from the user, if no key data. */
|
||||
+ askpass = 1;
|
||||
+ part = grub_partition_get_name (source->partition);
|
||||
+ grub_printf_ (N_("Enter passphrase for %s%s%s (%s): "), source->name,
|
||||
+ source->partition != NULL ? "," : "",
|
||||
+ part != NULL ? part : N_("UNKNOWN"), dev->uuid);
|
||||
+ grub_free (part);
|
||||
+
|
||||
+ cargs->key_data = grub_malloc (GRUB_CRYPTODISK_MAX_PASSPHRASE);
|
||||
+ if (cargs->key_data == NULL)
|
||||
+ goto error;
|
||||
+
|
||||
+ if (!grub_password_get ((char *) cargs->key_data, GRUB_CRYPTODISK_MAX_PASSPHRASE))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_ARGUMENT, "passphrase not supplied");
|
||||
+ goto error;
|
||||
+ }
|
||||
+ cargs->key_len = grub_strlen ((char *) cargs->key_data);
|
||||
+ }
|
||||
+
|
||||
+ ret = cr->recover_key (source, dev, cargs);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ goto error;
|
||||
+
|
||||
+ ret = grub_cryptodisk_insert (dev, name, source);
|
||||
+ if (ret != GRUB_ERR_NONE)
|
||||
+ goto error;
|
||||
|
||||
- goto cleanup;
|
||||
- }
|
||||
- grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk module can handle this device");
|
||||
goto cleanup;
|
||||
|
||||
error:
|
||||
@@ -1259,6 +1335,20 @@ grub_cryptodisk_scan_device (const char *name,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+static void
|
||||
+grub_cryptodisk_clear_key_cache (struct grub_cryptomount_args *cargs)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ if (cargs->key_cache == NULL || cargs->protectors == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; cargs->protectors[i]; i++)
|
||||
+ grub_free (cargs->key_cache[i].key);
|
||||
+
|
||||
+ grub_free (cargs->key_cache);
|
||||
+}
|
||||
+
|
||||
static grub_err_t
|
||||
grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
@@ -1271,6 +1361,10 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
if (grub_cryptodisk_list == NULL)
|
||||
return grub_error (GRUB_ERR_BAD_MODULE, "no cryptodisk modules loaded");
|
||||
|
||||
+ if (state[OPTION_PASSWORD].set && state[OPTION_PROTECTOR].set) /* password and key protector */
|
||||
+ return grub_error (GRUB_ERR_BAD_ARGUMENT,
|
||||
+ "a password and a key protector cannot both be set");
|
||||
+
|
||||
if (state[OPTION_PASSWORD].set) /* password */
|
||||
{
|
||||
cargs.key_data = (grub_uint8_t *) state[OPTION_PASSWORD].arg;
|
||||
@@ -1363,6 +1457,15 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
return grub_errno;
|
||||
}
|
||||
|
||||
+ if (state[OPTION_PROTECTOR].set) /* key protector(s) */
|
||||
+ {
|
||||
+ cargs.key_cache = grub_zalloc (state[OPTION_PROTECTOR].set * sizeof (*cargs.key_cache));
|
||||
+ if (cargs.key_cache == NULL)
|
||||
+ return grub_error (GRUB_ERR_OUT_OF_MEMORY,
|
||||
+ "no memory for key protector key cache");
|
||||
+ cargs.protectors = state[OPTION_PROTECTOR].args;
|
||||
+ }
|
||||
+
|
||||
if (state[OPTION_UUID].set) /* uuid */
|
||||
{
|
||||
int found_uuid;
|
||||
@@ -1371,6 +1474,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
dev = grub_cryptodisk_get_by_uuid (args[0]);
|
||||
if (dev)
|
||||
{
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
grub_dprintf ("cryptodisk",
|
||||
"already mounted as crypto%lu\n", dev->id);
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -1379,6 +1483,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
cargs.check_boot = state[OPTION_BOOT].set;
|
||||
cargs.search_uuid = args[0];
|
||||
found_uuid = grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
|
||||
if (found_uuid)
|
||||
return GRUB_ERR_NONE;
|
||||
@@ -1398,6 +1503,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
cargs.check_boot = state[OPTION_BOOT].set;
|
||||
grub_device_iterate (&grub_cryptodisk_scan_device, &cargs);
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
else
|
||||
@@ -1421,6 +1527,7 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
disk = grub_disk_open (diskname);
|
||||
if (!disk)
|
||||
{
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
if (disklast)
|
||||
*disklast = ')';
|
||||
return grub_errno;
|
||||
@@ -1431,12 +1538,14 @@ grub_cmd_cryptomount (grub_extcmd_context_t ctxt, int argc, char **args)
|
||||
{
|
||||
grub_dprintf ("cryptodisk", "already mounted as crypto%lu\n", dev->id);
|
||||
grub_disk_close (disk);
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
if (disklast)
|
||||
*disklast = ')';
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
dev = grub_cryptodisk_scan_device_real (diskname, disk, &cargs);
|
||||
+ grub_cryptodisk_clear_key_cache (&cargs);
|
||||
|
||||
grub_disk_close (disk);
|
||||
if (disklast)
|
||||
@@ -1590,6 +1699,7 @@ GRUB_MOD_INIT (cryptodisk)
|
||||
cmd = grub_register_extcmd ("cryptomount", grub_cmd_cryptomount, 0,
|
||||
N_("[ [-p password] | [-k keyfile"
|
||||
" [-O keyoffset] [-S keysize] ] ] [-H file]"
|
||||
+ " [-P protector [-P protector ...]]"
|
||||
" <SOURCE|-u UUID|-a|-b>"),
|
||||
N_("Mount a crypto device."), options);
|
||||
grub_procfs_register ("luks_script", &luks_script);
|
||||
diff --git a/include/grub/cryptodisk.h b/include/grub/cryptodisk.h
|
||||
index d94df68b6..0b41e249e 100644
|
||||
--- a/include/grub/cryptodisk.h
|
||||
+++ b/include/grub/cryptodisk.h
|
||||
@@ -70,6 +70,18 @@ typedef gcry_err_code_t
|
||||
(*grub_cryptodisk_rekey_func_t) (struct grub_cryptodisk *dev,
|
||||
grub_uint64_t zoneno);
|
||||
|
||||
+struct grub_cryptomount_cached_key
|
||||
+{
|
||||
+ grub_uint8_t *key;
|
||||
+ grub_size_t key_len;
|
||||
+
|
||||
+ /*
|
||||
+ * The key protector associated with this cache entry failed, so avoid it
|
||||
+ * even if the cached entry (an instance of this structure) is empty.
|
||||
+ */
|
||||
+ int invalid;
|
||||
+};
|
||||
+
|
||||
struct grub_cryptomount_args
|
||||
{
|
||||
/* scan: Flag to indicate that only bootable volumes should be decrypted */
|
||||
@@ -81,6 +93,10 @@ struct grub_cryptomount_args
|
||||
/* recover_key: Length of key_data */
|
||||
grub_size_t key_len;
|
||||
grub_file_t hdr_file;
|
||||
+ /* recover_key: Names of the key protectors to use (NULL-terminated) */
|
||||
+ char **protectors;
|
||||
+ /* recover_key: Key cache to avoid invoking the same key protector twice */
|
||||
+ struct grub_cryptomount_cached_key *key_cache;
|
||||
};
|
||||
typedef struct grub_cryptomount_args *grub_cryptomount_args_t;
|
||||
|
||||
--
|
||||
2.35.3
|
||||
|
91
0004-diskfilter-look-up-cryptodisk-devices-first.patch
Normal file
91
0004-diskfilter-look-up-cryptodisk-devices-first.patch
Normal file
@ -0,0 +1,91 @@
|
||||
From 91a99dffbe78b91a0c18b32ebecf755ba9d74032 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Thu, 10 Aug 2023 10:19:29 +0800
|
||||
Subject: [PATCH 4/4] diskfilter: look up cryptodisk devices first
|
||||
|
||||
When using disk auto-unlocking with TPM 2.0, the typical grub.cfg may
|
||||
look like this:
|
||||
|
||||
tpm2_key_protector_init --tpm2key=(hd0,gpt1)/boot/grub2/sealed.tpm
|
||||
cryptomount -u <PART-UUID> -P tpm2
|
||||
search --fs-uuid --set=root <FS-UUID>
|
||||
|
||||
Since the disk search order is based on the order of module loading, the
|
||||
attacker could insert a malicious disk with the same FS-UUID root to
|
||||
trick grub2 to boot into the malicious root and further dump memory to
|
||||
steal the unsealed key.
|
||||
|
||||
Do defend against such an attack, we can specify the hint provided by
|
||||
'grub-probe' to search the encrypted partition first:
|
||||
|
||||
search --fs-uuid --set=root --hint='cryptouuid/<PART-UUID>' <FS-UUID>
|
||||
|
||||
However, for LVM on an encrypted partition, the search hint provided by
|
||||
'grub-probe' is:
|
||||
|
||||
--hint='lvmid/<VG-UUID>/<LV-UUID>'
|
||||
|
||||
It doesn't guarantee to look up the logical volume from the encrypted
|
||||
partition, so the attacker may have the chance to fool grub2 to boot
|
||||
into the malicious disk.
|
||||
|
||||
To minimize the attack surface, this commit tweaks the disk device search
|
||||
in diskfilter to look up cryptodisk devices first and then others, so
|
||||
that the auto-unlocked disk will be found first, not the attacker's disk.
|
||||
|
||||
Cc: Fabian Vogt <fvogt@suse.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
---
|
||||
grub-core/disk/diskfilter.c | 35 ++++++++++++++++++++++++++---------
|
||||
1 file changed, 26 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/grub-core/disk/diskfilter.c b/grub-core/disk/diskfilter.c
|
||||
index 41e177549..c45bef1ca 100644
|
||||
--- a/grub-core/disk/diskfilter.c
|
||||
+++ b/grub-core/disk/diskfilter.c
|
||||
@@ -322,15 +322,32 @@ scan_devices (const char *arname)
|
||||
int need_rescan;
|
||||
|
||||
for (pull = 0; pull < GRUB_DISK_PULL_MAX; pull++)
|
||||
- for (p = grub_disk_dev_list; p; p = p->next)
|
||||
- if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
|
||||
- && p->disk_iterate)
|
||||
- {
|
||||
- if ((p->disk_iterate) (scan_disk_hook, NULL, pull))
|
||||
- return;
|
||||
- if (arname && is_lv_readable (find_lv (arname), 1))
|
||||
- return;
|
||||
- }
|
||||
+ {
|
||||
+ /* look up the crytodisk devices first */
|
||||
+ for (p = grub_disk_dev_list; p; p = p->next)
|
||||
+ if (p->id == GRUB_DISK_DEVICE_CRYPTODISK_ID
|
||||
+ && p->disk_iterate)
|
||||
+ {
|
||||
+ if ((p->disk_iterate) (scan_disk_hook, NULL, pull))
|
||||
+ return;
|
||||
+ if (arname && is_lv_readable (find_lv (arname), 1))
|
||||
+ return;
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* check the devices other than crytodisk */
|
||||
+ for (p = grub_disk_dev_list; p; p = p->next)
|
||||
+ if (p->id == GRUB_DISK_DEVICE_CRYPTODISK_ID)
|
||||
+ continue;
|
||||
+ else if (p->id != GRUB_DISK_DEVICE_DISKFILTER_ID
|
||||
+ && p->disk_iterate)
|
||||
+ {
|
||||
+ if ((p->disk_iterate) (scan_disk_hook, NULL, pull))
|
||||
+ return;
|
||||
+ if (arname && is_lv_readable (find_lv (arname), 1))
|
||||
+ return;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
scan_depth = 0;
|
||||
need_rescan = 1;
|
||||
--
|
||||
2.35.3
|
||||
|
116
0004-efinet-UEFI-IPv6-PXE-support.patch
Normal file
116
0004-efinet-UEFI-IPv6-PXE-support.patch
Normal file
@ -0,0 +1,116 @@
|
||||
From ca482c7c1efe5faf792bf0912a116ea8e0642e24 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 15 Apr 2015 14:48:30 +0800
|
||||
Subject: [PATCH 4/8] efinet: UEFI IPv6 PXE support
|
||||
|
||||
When grub2 image is booted from UEFI IPv6 PXE, the DHCPv6 Reply packet is
|
||||
cached in firmware buffer which can be obtained by PXE Base Code protocol. The
|
||||
network interface can be setup through the parameters in that obtained packet.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Signed-off-by: Ken Lin <ken.lin@hpe.com>
|
||||
---
|
||||
grub-core/net/drivers/efi/efinet.c | 24 +++++++++++++----
|
||||
include/grub/efi/api.h | 55 +++++++++++++++++++++++++++++++++++++-
|
||||
2 files changed, 73 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/grub-core/net/drivers/efi/efinet.c
|
||||
+++ b/grub-core/net/drivers/efi/efinet.c
|
||||
@@ -400,6 +400,18 @@
|
||||
continue;
|
||||
pxe_mode = pxe->mode;
|
||||
|
||||
+ if (pxe_mode->using_ipv6)
|
||||
+ {
|
||||
+ grub_net_configure_by_dhcpv6_reply (card->name, card, 0,
|
||||
+ (struct grub_net_dhcp6_packet *)
|
||||
+ &pxe_mode->dhcp_ack,
|
||||
+ sizeof (pxe_mode->dhcp_ack),
|
||||
+ 1, device, path);
|
||||
+ if (grub_errno)
|
||||
+ grub_print_error ();
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
inter = grub_net_configure_by_dhcp_ack (card->name, card, 0,
|
||||
(struct grub_net_bootp_packet *)
|
||||
&pxe_mode->dhcp_ack,
|
||||
@@ -428,6 +440,7 @@
|
||||
vlan_dp = (grub_efi_device_path_t *) ((grub_efi_uint8_t *) vlan_dp + vlan_dp_len);
|
||||
}
|
||||
}
|
||||
+ }
|
||||
return;
|
||||
}
|
||||
}
|
||||
--- a/include/grub/efi/api.h
|
||||
+++ b/include/grub/efi/api.h
|
||||
@@ -1523,14 +1523,67 @@
|
||||
|
||||
typedef grub_uint8_t grub_efi_pxe_packet_t[1472];
|
||||
|
||||
+typedef struct {
|
||||
+ grub_uint8_t addr[4];
|
||||
+} grub_efi_pxe_ipv4_address_t;
|
||||
+
|
||||
+typedef struct {
|
||||
+ grub_uint8_t addr[16];
|
||||
+} grub_efi_pxe_ipv6_address_t;
|
||||
+
|
||||
+typedef struct {
|
||||
+ grub_uint8_t addr[32];
|
||||
+} grub_efi_pxe_mac_address_t;
|
||||
+
|
||||
+typedef union {
|
||||
+ grub_uint32_t addr[4];
|
||||
+ grub_efi_pxe_ipv4_address_t v4;
|
||||
+ grub_efi_pxe_ipv6_address_t v6;
|
||||
+} grub_efi_pxe_ip_address_t;
|
||||
+
|
||||
+#define GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT 8
|
||||
+typedef struct {
|
||||
+ grub_uint8_t filters;
|
||||
+ grub_uint8_t ip_cnt;
|
||||
+ grub_uint16_t reserved;
|
||||
+ grub_efi_pxe_ip_address_t ip_list[GRUB_EFI_PXE_BASE_CODE_MAX_IPCNT];
|
||||
+} grub_efi_pxe_ip_filter_t;
|
||||
+
|
||||
+typedef struct {
|
||||
+ grub_efi_pxe_ip_address_t ip_addr;
|
||||
+ grub_efi_pxe_mac_address_t mac_addr;
|
||||
+} grub_efi_pxe_arp_entry_t;
|
||||
+
|
||||
+typedef struct {
|
||||
+ grub_efi_pxe_ip_address_t ip_addr;
|
||||
+ grub_efi_pxe_ip_address_t subnet_mask;
|
||||
+ grub_efi_pxe_ip_address_t gw_addr;
|
||||
+} grub_efi_pxe_route_entry_t;
|
||||
+
|
||||
+
|
||||
+#define GRUB_EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES 8
|
||||
+#define GRUB_EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES 8
|
||||
+
|
||||
typedef struct grub_efi_pxe_mode
|
||||
{
|
||||
- grub_uint8_t unused[52];
|
||||
+ grub_uint8_t started;
|
||||
+ grub_uint8_t ipv6_available;
|
||||
+ grub_uint8_t ipv6_supported;
|
||||
+ grub_uint8_t using_ipv6;
|
||||
+ grub_uint8_t unused[16];
|
||||
+ grub_efi_pxe_ip_address_t station_ip;
|
||||
+ grub_efi_pxe_ip_address_t subnet_mask;
|
||||
grub_efi_pxe_packet_t dhcp_discover;
|
||||
grub_efi_pxe_packet_t dhcp_ack;
|
||||
grub_efi_pxe_packet_t proxy_offer;
|
||||
grub_efi_pxe_packet_t pxe_discover;
|
||||
grub_efi_pxe_packet_t pxe_reply;
|
||||
+ grub_efi_pxe_packet_t pxe_bis_reply;
|
||||
+ grub_efi_pxe_ip_filter_t ip_filter;
|
||||
+ grub_uint32_t arp_cache_entries;
|
||||
+ grub_efi_pxe_arp_entry_t arp_cache[GRUB_EFI_PXE_BASE_CODE_MAX_ARP_ENTRIES];
|
||||
+ grub_uint32_t route_table_entries;
|
||||
+ grub_efi_pxe_route_entry_t route_table[GRUB_EFI_PXE_BASE_CODE_MAX_ROUTE_ENTRIES];
|
||||
} grub_efi_pxe_mode_t;
|
||||
|
||||
typedef struct grub_efi_pxe
|
28
0004-ofpath-controller-name-update.patch
Normal file
28
0004-ofpath-controller-name-update.patch
Normal file
@ -0,0 +1,28 @@
|
||||
From 7717cd9c27f18703287403af1a955588e3d0261f Mon Sep 17 00:00:00 2001
|
||||
From: mamatha <mainamdar@in.ibm.com>
|
||||
Date: Sat, 24 Sep 2022 11:22:39 +0530
|
||||
Subject: [PATCH 4/4] ofpath controller name update
|
||||
|
||||
patch to update ofpath controller name
|
||||
|
||||
Signed-off-by: mamatha <mainamdar@in.ibm.com>
|
||||
---
|
||||
grub-core/osdep/linux/ofpath.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/grub-core/osdep/linux/ofpath.c b/grub-core/osdep/linux/ofpath.c
|
||||
index 212782d3f..7d31cfd0f 100644
|
||||
--- a/grub-core/osdep/linux/ofpath.c
|
||||
+++ b/grub-core/osdep/linux/ofpath.c
|
||||
@@ -483,6 +483,8 @@ of_path_get_nvmeof_adapter_info(char* sysfs_path,
|
||||
buf3=strchr(buf2,'-')+1;
|
||||
buf3=strchr(buf3,'-')+1;
|
||||
nvmeof_info->target_wwpn = buf3;
|
||||
+ buf3=strchr(buf3,'x')+1;
|
||||
+ nvmeof_info->target_wwpn = buf3;
|
||||
buf3 = strchr(nvmeof_info->target_wwpn,',');
|
||||
*buf3 = '\0';
|
||||
|
||||
--
|
||||
2.35.3
|
||||
|
121
0005-blscfg-check-for-mounted-boot-in-emu.patch
Normal file
121
0005-blscfg-check-for-mounted-boot-in-emu.patch
Normal file
@ -0,0 +1,121 @@
|
||||
From 6d33393fd3c538aaead2698777c02d6d6d0221c9 Mon Sep 17 00:00:00 2001
|
||||
From: Robbie Harwood <rharwood@redhat.com>
|
||||
Date: Tue, 7 Mar 2023 18:59:40 -0500
|
||||
Subject: [PATCH 5/9] blscfg: check for mounted /boot in emu
|
||||
|
||||
Irritatingly, BLS defines paths relatives to the mountpoint of the
|
||||
filesystem which contains its snippets, not / or any other fixed
|
||||
location. So grub2-emu needs to know whether /boot is a separate
|
||||
filesysem from / and conditionally prepend a path.
|
||||
|
||||
Signed-off-by: Robbie Harwood <rharwood@redhat.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 54 +++++++++++++++++++++++++++++++++----
|
||||
1 file changed, 49 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index 150ca96f4..6495891b9 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -40,8 +40,9 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
#include "loadenv.h"
|
||||
|
||||
#define GRUB_BLS_CONFIG_PATH "/loader/entries/"
|
||||
+
|
||||
#ifdef GRUB_MACHINE_EMU
|
||||
-#define GRUB_BOOT_DEVICE ""
|
||||
+#define GRUB_BOOT_DEVICE "/boot"
|
||||
#else
|
||||
#define GRUB_BOOT_DEVICE "($root)"
|
||||
#endif
|
||||
@@ -54,8 +55,50 @@ struct keyval
|
||||
|
||||
static struct bls_entry *entries = NULL;
|
||||
|
||||
+/* Cache probing in frob_boot_device(). Used for linux entry also.
|
||||
+ * Always true in non-emu, meaning to prefix things with GRUB_BOOT_DEVICE. */
|
||||
+static int separate_boot = -1;
|
||||
+
|
||||
#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
|
||||
|
||||
+/* BLS appears to make paths relative to the filesystem that snippets are
|
||||
+ * on, not /. Attempt to cope. */
|
||||
+static char *frob_boot_device(char *tmp)
|
||||
+{
|
||||
+#ifdef GRUB_MACHINE_EMU
|
||||
+ grub_file_t f;
|
||||
+ char *line = NULL;
|
||||
+
|
||||
+ if (separate_boot != -1)
|
||||
+ goto probed;
|
||||
+
|
||||
+ separate_boot = 0;
|
||||
+
|
||||
+ f = grub_file_open ("/proc/mounts", GRUB_FILE_TYPE_CONFIG);
|
||||
+ if (f == NULL)
|
||||
+ goto probed;
|
||||
+
|
||||
+ while ((line = grub_file_getline (f)))
|
||||
+ {
|
||||
+ if (grub_strstr (line, " " GRUB_BOOT_DEVICE " "))
|
||||
+ {
|
||||
+ separate_boot = 1;
|
||||
+ grub_free (line);
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ grub_free(line);
|
||||
+ }
|
||||
+
|
||||
+ grub_file_close (f);
|
||||
+ probed:
|
||||
+ if (!separate_boot)
|
||||
+ return grub_stpcpy (tmp, " ");
|
||||
+#endif
|
||||
+
|
||||
+ return grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+}
|
||||
+
|
||||
static int bls_add_keyval(struct bls_entry *entry, char *key, char *val)
|
||||
{
|
||||
char *k, *v;
|
||||
@@ -842,7 +885,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
|
||||
{
|
||||
grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]);
|
||||
- tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+ tmp = frob_boot_device (tmp);
|
||||
tmp = grub_stpcpy (tmp, initrd_prefix);
|
||||
tmp = grub_stpcpy (tmp, early_initrds[i]);
|
||||
grub_free(early_initrds[i]);
|
||||
@@ -851,7 +894,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
|
||||
{
|
||||
grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]);
|
||||
- tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+ tmp = frob_boot_device (tmp);
|
||||
tmp = grub_stpcpy (tmp, initrds[i]);
|
||||
}
|
||||
tmp = grub_stpcpy (tmp, "\n");
|
||||
@@ -888,7 +931,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
}
|
||||
char *tmp = dt;
|
||||
tmp = grub_stpcpy (dt, "devicetree");
|
||||
- tmp = grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+ tmp = frob_boot_device (tmp);
|
||||
if (add_dt_prefix)
|
||||
tmp = grub_stpcpy (tmp, prefix);
|
||||
tmp = grub_stpcpy (tmp, devicetree);
|
||||
@@ -907,7 +950,8 @@ static void create_entry (struct bls_entry *entry)
|
||||
"linux %s%s%s%s\n"
|
||||
"%s%s",
|
||||
savedefault ? "savedefault\n" : "",
|
||||
- GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "",
|
||||
+ separate_boot ? GRUB_BOOT_DEVICE : "",
|
||||
+ clinux, options ? " " : "", options ? options : "",
|
||||
initrd ? initrd : "", dt ? dt : "");
|
||||
|
||||
grub_normal_add_menu_entry (argc, argv, classes, id, users, hotkey, NULL, src, 0, 0, &index, entry);
|
||||
--
|
||||
2.44.0
|
||||
|
59
0005-docs-grub-Document-signing-grub-under-UEFI.patch
Normal file
59
0005-docs-grub-Document-signing-grub-under-UEFI.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From f7b9580133cf346d77f345d175fa5cb8a591be16 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Sat, 15 Aug 2020 02:00:57 +1000
|
||||
Subject: [PATCH 05/23] docs/grub: Document signing grub under UEFI
|
||||
|
||||
Before adding information about how grub is signed with an appended
|
||||
signature scheme, it's worth adding some information about how it
|
||||
can currently be signed for UEFI.
|
||||
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
---
|
||||
docs/grub.texi | 22 +++++++++++++++++++++-
|
||||
1 file changed, 21 insertions(+), 1 deletion(-)
|
||||
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -6345,6 +6345,7 @@
|
||||
* Secure Boot Advanced Targeting:: Embedded information for generation number based revocation
|
||||
* Measured Boot:: Measuring boot components
|
||||
* Lockdown:: Lockdown when booting on a secure setup
|
||||
+* Signing GRUB itself:: Ensuring the integrity of the GRUB core image
|
||||
@end menu
|
||||
|
||||
@node Authentication and authorisation
|
||||
@@ -6423,7 +6424,7 @@
|
||||
|
||||
GRUB's @file{core.img} can optionally provide enforcement that all files
|
||||
subsequently read from disk are covered by a valid digital signature.
|
||||
-This document does @strong{not} cover how to ensure that your
|
||||
+This section does @strong{not} cover how to ensure that your
|
||||
platform's firmware (e.g., Coreboot) validates @file{core.img}.
|
||||
|
||||
If environment variable @code{check_signatures}
|
||||
@@ -6586,6 +6587,25 @@
|
||||
The @samp{lockdown} variable is set to @samp{y} when the GRUB is locked down.
|
||||
Otherwise it does not exit.
|
||||
|
||||
+@node Signing GRUB itself
|
||||
+@section Signing GRUB itself
|
||||
+
|
||||
+To ensure a complete secure-boot chain, there must be a way for the code that
|
||||
+loads GRUB to verify the integrity of the core image.
|
||||
+
|
||||
+This is ultimately platform-specific and individual platforms can define their
|
||||
+own mechanisms. However, there are general-purpose mechanisms that can be used
|
||||
+with GRUB.
|
||||
+
|
||||
+@section Signing GRUB for UEFI secure boot
|
||||
+
|
||||
+On UEFI platforms, @file{core.img} is a PE binary. Therefore, it can be signed
|
||||
+with a tool such as @command{pesign} or @command{sbsign}. Refer to the
|
||||
+suggestions in @pxref{UEFI secure boot and shim} to ensure that the final
|
||||
+image works under UEFI secure boot and can maintain the secure-boot chain. It
|
||||
+will also be necessary to enrol the public key used into a relevant firmware
|
||||
+key database.
|
||||
+
|
||||
@node Platform limitations
|
||||
@chapter Platform limitations
|
||||
|
164
0005-export-environment-at-start-up.patch
Normal file
164
0005-export-environment-at-start-up.patch
Normal file
@ -0,0 +1,164 @@
|
||||
From 496b6b20cbce3fc27228d1d8290089fb7107b8de Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 18 Feb 2022 21:51:16 +0800
|
||||
Subject: [PATCH 5/5] export environment at start up
|
||||
|
||||
If the prep_loadenv module is built into the core image, it will read
|
||||
the environment block automatically during start up and export all
|
||||
variables. The will ease integration with those without early scripts to
|
||||
running the command.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/Makefile.core.def | 2 +
|
||||
grub-core/commands/prep_loadenv.c | 77 +++++++++++++++++++++++++++++++
|
||||
grub-core/kern/env.c | 2 +
|
||||
grub-core/kern/main.c | 3 ++
|
||||
include/grub/env.h | 1 +
|
||||
5 files changed, 85 insertions(+)
|
||||
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -2678,4 +2678,6 @@
|
||||
name = prep_loadenv;
|
||||
common = commands/prep_loadenv.c;
|
||||
enable = powerpc_ieee1275;
|
||||
+ cflags = '$(CFLAGS_POSIX) $(CFLAGS_GNULIB)';
|
||||
+ cppflags = '$(CPPFLAGS_POSIX) $(CPPFLAGS_GNULIB)';
|
||||
};
|
||||
--- a/grub-core/commands/prep_loadenv.c
|
||||
+++ b/grub-core/commands/prep_loadenv.c
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <grub/extcmd.h>
|
||||
#include <grub/i18n.h>
|
||||
#include <grub/gpt_partition.h>
|
||||
+#include <regex.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -185,6 +186,65 @@
|
||||
}
|
||||
|
||||
static grub_err_t
|
||||
+boot_disk_prep_partname (char **name)
|
||||
+{
|
||||
+ regex_t regex;
|
||||
+ int ret;
|
||||
+ grub_size_t s;
|
||||
+ char *comperr;
|
||||
+ const char *cmdpath;
|
||||
+ regmatch_t *matches = NULL;
|
||||
+ grub_err_t err = GRUB_ERR_NONE;
|
||||
+
|
||||
+ *name = NULL;
|
||||
+
|
||||
+ cmdpath = grub_env_get ("cmdpath");
|
||||
+ if (!cmdpath)
|
||||
+ return GRUB_ERR_NONE;
|
||||
+
|
||||
+ ret = regcomp (®ex, "\\(([^,]+)(,?.*)?\\)(.*)", REG_EXTENDED);
|
||||
+ if (ret)
|
||||
+ goto fail;
|
||||
+
|
||||
+ matches = grub_calloc (regex.re_nsub + 1, sizeof (*matches));
|
||||
+ if (! matches)
|
||||
+ goto fail;
|
||||
+
|
||||
+ ret = regexec (®ex, cmdpath, regex.re_nsub + 1, matches, 0);
|
||||
+ if (!ret)
|
||||
+ {
|
||||
+ char *devname = devname = match_substr (matches + 1, cmdpath);
|
||||
+ if (!devname)
|
||||
+ {
|
||||
+ err = grub_error (GRUB_ERR_FILE_NOT_FOUND, "%s contains no disk name", cmdpath);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ err = prep_partname (devname, name);
|
||||
+ out:
|
||||
+ grub_free (devname);
|
||||
+ regfree (®ex);
|
||||
+ grub_free (matches);
|
||||
+ return err;
|
||||
+ }
|
||||
+
|
||||
+ fail:
|
||||
+ grub_free (matches);
|
||||
+ s = regerror (ret, ®ex, 0, 0);
|
||||
+ comperr = grub_malloc (s);
|
||||
+ if (!comperr)
|
||||
+ {
|
||||
+ regfree (®ex);
|
||||
+ return grub_errno;
|
||||
+ }
|
||||
+ regerror (ret, ®ex, comperr, s);
|
||||
+ err = grub_error (GRUB_ERR_TEST_FAILURE, "%s", comperr);
|
||||
+ regfree (®ex);
|
||||
+ grub_free (comperr);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
+static grub_err_t
|
||||
grub_cmd_prep_loadenv (grub_command_t cmd __attribute__ ((unused)),
|
||||
int argc,
|
||||
char **argv)
|
||||
@@ -214,10 +274,27 @@
|
||||
return GRUB_ERR_NONE;
|
||||
}
|
||||
|
||||
+static void
|
||||
+early_prep_loadenv (void)
|
||||
+{
|
||||
+ grub_err_t err;
|
||||
+ char *prep;
|
||||
+
|
||||
+ err = boot_disk_prep_partname (&prep);
|
||||
+ if (err == GRUB_ERR_NONE && prep)
|
||||
+ err = prep_read_envblk (prep);
|
||||
+ if (err == GRUB_ERR_BAD_FILE_TYPE || err == GRUB_ERR_FILE_NOT_FOUND)
|
||||
+ grub_error_pop ();
|
||||
+ if (err != GRUB_ERR_NONE)
|
||||
+ grub_print_error ();
|
||||
+ grub_free (prep);
|
||||
+}
|
||||
+
|
||||
static grub_command_t cmd_prep_load;
|
||||
|
||||
GRUB_MOD_INIT(prep_loadenv)
|
||||
{
|
||||
+ early_env_hook = early_prep_loadenv;
|
||||
cmd_prep_load =
|
||||
grub_register_command("prep_load_env", grub_cmd_prep_loadenv,
|
||||
"DEVICE",
|
||||
--- a/grub-core/kern/env.c
|
||||
+++ b/grub-core/kern/env.c
|
||||
@@ -28,6 +28,8 @@
|
||||
/* The current context. */
|
||||
struct grub_env_context *grub_current_context = &initial_context;
|
||||
|
||||
+void (*early_env_hook) (void) = NULL;
|
||||
+
|
||||
/* Return the hash representation of the string S. */
|
||||
static unsigned int
|
||||
grub_env_hashval (const char *s)
|
||||
--- a/grub-core/kern/main.c
|
||||
+++ b/grub-core/kern/main.c
|
||||
@@ -309,6 +309,9 @@
|
||||
|
||||
grub_boot_time ("Before execution of embedded config.");
|
||||
|
||||
+ if (early_env_hook != NULL)
|
||||
+ early_env_hook ();
|
||||
+
|
||||
if (load_config)
|
||||
grub_parser_execute (load_config);
|
||||
|
||||
--- a/include/grub/env.h
|
||||
+++ b/include/grub/env.h
|
||||
@@ -69,5 +69,6 @@
|
||||
grub_err_t
|
||||
grub_env_extractor_close (int source);
|
||||
|
||||
+extern void (*EXPORT_VAR (early_env_hook)) (void);
|
||||
|
||||
#endif /* ! GRUB_ENV_HEADER */
|
48
0005-grub.texi-Add-net_bootp6-doument.patch
Normal file
48
0005-grub.texi-Add-net_bootp6-doument.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 2c997c8c058b41d3a59a81f2bf654288b7cdf8f2 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Tue, 5 May 2015 14:19:24 +0800
|
||||
Subject: [PATCH 5/8] grub.texi: Add net_bootp6 doument
|
||||
|
||||
Update grub documentation for net_bootp6 command.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Signed-off-by: Ken Lin <ken.lin@hpe.com>
|
||||
---
|
||||
docs/grub.texi | 17 +++++++++++++++++
|
||||
1 file changed, 17 insertions(+)
|
||||
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -5894,6 +5894,7 @@
|
||||
* net_add_dns:: Add a DNS server
|
||||
* net_add_route:: Add routing entry
|
||||
* net_bootp:: Perform a bootp/DHCP autoconfiguration
|
||||
+* net_bootp6:: Perform a DHCPv6 autoconfiguration
|
||||
* net_del_addr:: Remove IP address from interface
|
||||
* net_del_dns:: Remove a DNS server
|
||||
* net_del_route:: Remove a route entry
|
||||
@@ -5951,6 +5952,24 @@
|
||||
|
||||
@end deffn
|
||||
|
||||
+
|
||||
+@node net_bootp6
|
||||
+@subsection net_bootp6
|
||||
+
|
||||
+@deffn Command net_bootp6 [@var{card}]
|
||||
+Perform configuration of @var{card} using DHCPv6 protocol. If no card name is
|
||||
+specified, try to configure all existing cards. If configuration was
|
||||
+successful, interface with name @var{card}@samp{:dhcp6} and configured address
|
||||
+is added to @var{card}.
|
||||
+
|
||||
+@table @samp
|
||||
+@item 1 (Domain Name Server)
|
||||
+Adds all servers from option value to the list of servers used during name
|
||||
+resolution.
|
||||
+@end table
|
||||
+
|
||||
+@end deffn
|
||||
+
|
||||
|
||||
@node net_del_addr
|
||||
@subsection net_del_addr
|
1600
0005-util-grub-protect-Add-new-tool.patch
Normal file
1600
0005-util-grub-protect-Add-new-tool.patch
Normal file
File diff suppressed because it is too large
Load Diff
105
0005-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch
Normal file
105
0005-x86-efi-Use-bounce-buffers-for-reading-to-addresses-.patch
Normal file
@ -0,0 +1,105 @@
|
||||
From a33acb675fe0d0464637175e4f06176e4c329025 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Fri, 12 Jul 2019 09:53:32 +0200
|
||||
Subject: [PATCH 05/11] 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>
|
||||
---
|
||||
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 f3abbd025..d6bed4fb4 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -35,11 +35,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
|
||||
@@ -68,6 +73,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[])
|
||||
@@ -120,7 +163,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"),
|
||||
@@ -145,11 +188,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[])
|
||||
--
|
||||
2.31.1
|
||||
|
168
0006-Follow-the-device-where-blscfg-is-discovered.patch
Normal file
168
0006-Follow-the-device-where-blscfg-is-discovered.patch
Normal file
@ -0,0 +1,168 @@
|
||||
From 6523d493b0772316a3fbb249eb070ada5d266a98 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Wed, 28 Jun 2023 14:32:40 +0800
|
||||
Subject: [PATCH 6/9] Follow the device where blscfg is discovered
|
||||
|
||||
Previously, the code assumed that GRUB_BOOT_DEVICE "($root)" was always
|
||||
the correct device for the discovered bls menu. However, this assumption
|
||||
could lead to inaccuracies when attempting to load bls for devices other
|
||||
than $root.
|
||||
|
||||
This patch introduces a more robust approach by utilizing the `struct
|
||||
find_entry_info *info->devid` parameter, representing the device used to
|
||||
discover the bls directory. This change ensures consistency in
|
||||
subsequent translations to native GRUB commands, eliminating potential
|
||||
discrepancies in device identification during the blscfg process.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 40 +++++++++++++++++++++++++------------
|
||||
include/grub/menu.h | 1 +
|
||||
2 files changed, 28 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index 6495891b9..c872bcef0 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -55,15 +55,18 @@ struct keyval
|
||||
|
||||
static struct bls_entry *entries = NULL;
|
||||
|
||||
-/* Cache probing in frob_boot_device(). Used for linux entry also.
|
||||
- * Always true in non-emu, meaning to prefix things with GRUB_BOOT_DEVICE. */
|
||||
-static int separate_boot = -1;
|
||||
-
|
||||
#define FOR_BLS_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
|
||||
|
||||
/* BLS appears to make paths relative to the filesystem that snippets are
|
||||
* on, not /. Attempt to cope. */
|
||||
-static char *frob_boot_device(char *tmp)
|
||||
+#ifdef GRUB_MACHINE_EMU
|
||||
+/* Cache probing in frob_boot_device(). Used for linux entry also.
|
||||
+ * Unused in non-emu, meaning to prefix things with device of parent blsdir. */
|
||||
+static int separate_boot = -1;
|
||||
+static char *frob_boot_device(char *tmp, const char *bootdev UNUSED)
|
||||
+#else
|
||||
+static char *frob_boot_device(char *tmp, const char *bootdev)
|
||||
+#endif
|
||||
{
|
||||
#ifdef GRUB_MACHINE_EMU
|
||||
grub_file_t f;
|
||||
@@ -94,9 +97,11 @@ static char *frob_boot_device(char *tmp)
|
||||
probed:
|
||||
if (!separate_boot)
|
||||
return grub_stpcpy (tmp, " ");
|
||||
-#endif
|
||||
-
|
||||
return grub_stpcpy (tmp, " " GRUB_BOOT_DEVICE);
|
||||
+#else
|
||||
+ tmp = grub_stpcpy (tmp, " ");
|
||||
+ return grub_stpcpy (tmp, bootdev);
|
||||
+#endif
|
||||
}
|
||||
|
||||
static int bls_add_keyval(struct bls_entry *entry, char *key, char *val)
|
||||
@@ -568,6 +573,9 @@ static int read_entry (
|
||||
if (rc < 0)
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ if (info->devid)
|
||||
+ entry->devid = grub_strdup(info->devid);
|
||||
|
||||
if (!rc)
|
||||
bls_add_entry(entry);
|
||||
@@ -772,6 +780,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
char *id = entry->filename;
|
||||
char *dotconf = id;
|
||||
char *hotkey = NULL;
|
||||
+ char *bootdev = entry->devid ? grub_xasprintf("(%s)", entry->devid) : grub_strdup (GRUB_BOOT_DEVICE);
|
||||
|
||||
char *users = NULL;
|
||||
char **classes = NULL;
|
||||
@@ -865,12 +874,12 @@ static void create_entry (struct bls_entry *entry)
|
||||
char *tmp;
|
||||
|
||||
for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
|
||||
- initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \
|
||||
+ initrd_size += sizeof (" ") + grub_strlen (bootdev) \
|
||||
+ grub_strlen(initrd_prefix) \
|
||||
+ grub_strlen (early_initrds[i]) + 1;
|
||||
|
||||
for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
|
||||
- initrd_size += sizeof (" " GRUB_BOOT_DEVICE) \
|
||||
+ initrd_size += sizeof (" ") + grub_strlen (bootdev) \
|
||||
+ grub_strlen (initrds[i]) + 1;
|
||||
initrd_size += 1;
|
||||
|
||||
@@ -885,7 +894,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
for (i = 0; early_initrds != NULL && early_initrds[i] != NULL; i++)
|
||||
{
|
||||
grub_dprintf ("blscfg", "adding early initrd %s\n", early_initrds[i]);
|
||||
- tmp = frob_boot_device (tmp);
|
||||
+ tmp = frob_boot_device (tmp, bootdev);
|
||||
tmp = grub_stpcpy (tmp, initrd_prefix);
|
||||
tmp = grub_stpcpy (tmp, early_initrds[i]);
|
||||
grub_free(early_initrds[i]);
|
||||
@@ -894,7 +903,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
for (i = 0; initrds != NULL && initrds[i] != NULL; i++)
|
||||
{
|
||||
grub_dprintf ("blscfg", "adding initrd %s\n", initrds[i]);
|
||||
- tmp = frob_boot_device (tmp);
|
||||
+ tmp = frob_boot_device (tmp, bootdev);
|
||||
tmp = grub_stpcpy (tmp, initrds[i]);
|
||||
}
|
||||
tmp = grub_stpcpy (tmp, "\n");
|
||||
@@ -916,7 +925,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
}
|
||||
}
|
||||
|
||||
- dt_size = sizeof("devicetree " GRUB_BOOT_DEVICE) + grub_strlen(devicetree) + 1;
|
||||
+ dt_size = sizeof("devicetree ") + grub_strlen(bootdev) + grub_strlen(devicetree) + 1;
|
||||
|
||||
if (add_dt_prefix)
|
||||
{
|
||||
@@ -931,7 +940,7 @@ static void create_entry (struct bls_entry *entry)
|
||||
}
|
||||
char *tmp = dt;
|
||||
tmp = grub_stpcpy (dt, "devicetree");
|
||||
- tmp = frob_boot_device (tmp);
|
||||
+ tmp = frob_boot_device (tmp, bootdev);
|
||||
if (add_dt_prefix)
|
||||
tmp = grub_stpcpy (tmp, prefix);
|
||||
tmp = grub_stpcpy (tmp, devicetree);
|
||||
@@ -950,7 +959,11 @@ static void create_entry (struct bls_entry *entry)
|
||||
"linux %s%s%s%s\n"
|
||||
"%s%s",
|
||||
savedefault ? "savedefault\n" : "",
|
||||
+#ifdef GRUB_MACHINE_EMU
|
||||
separate_boot ? GRUB_BOOT_DEVICE : "",
|
||||
+#else
|
||||
+ bootdev,
|
||||
+#endif
|
||||
clinux, options ? " " : "", options ? options : "",
|
||||
initrd ? initrd : "", dt ? dt : "");
|
||||
|
||||
@@ -969,6 +982,7 @@ finish:
|
||||
grub_free (args);
|
||||
grub_free (argv);
|
||||
grub_free (src);
|
||||
+ grub_free (bootdev);
|
||||
}
|
||||
|
||||
struct find_entry_info {
|
||||
diff --git a/include/grub/menu.h b/include/grub/menu.h
|
||||
index 43080828c..76b191c33 100644
|
||||
--- a/include/grub/menu.h
|
||||
+++ b/include/grub/menu.h
|
||||
@@ -28,6 +28,7 @@ struct bls_entry
|
||||
int nkeyvals;
|
||||
char *filename;
|
||||
int visible;
|
||||
+ const char *devid;
|
||||
};
|
||||
|
||||
struct grub_menu_entry_class
|
||||
--
|
||||
2.44.0
|
||||
|
@ -0,0 +1,98 @@
|
||||
From 8191aae462f8b755972a0a801f4adbdd6ecaa66c Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 14 Jul 2016 18:45:14 +0800
|
||||
Subject: [PATCH 6/8] bootp: Add processing DHCPACK packet from HTTP Boot
|
||||
|
||||
The vendor class identifier with the string "HTTPClient" is used to denote the
|
||||
packet as responding to HTTP boot request. In DHCP4 config, the filename for
|
||||
HTTP boot is the URL of the boot file while for PXE boot it is the path to the
|
||||
boot file. As a consequence, the next-server becomes obseleted because the HTTP
|
||||
URL already contains the server address for the boot file. For DHCP6 config,
|
||||
there's no difference definition in existing config as dhcp6.bootfile-url can
|
||||
be used to specify URL for both HTTP and PXE boot file.
|
||||
|
||||
This patch adds processing for "HTTPClient" vendor class identifier in DHCPACK
|
||||
packet by treating it as HTTP format, not as the PXE format.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Signed-off-by: Ken Lin <ken.lin@hpe.com>
|
||||
---
|
||||
grub-core/net/bootp.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
include/grub/net.h | 1 +
|
||||
2 files changed, 66 insertions(+), 2 deletions(-)
|
||||
|
||||
--- a/grub-core/net/bootp.c
|
||||
+++ b/grub-core/net/bootp.c
|
||||
@@ -352,6 +352,53 @@
|
||||
if (!inter)
|
||||
return 0;
|
||||
|
||||
+ /* FIXME: Introduce new http flag for better synergy with existing tftp code base */
|
||||
+ if (size > OFFSET_OF (vendor, bp))
|
||||
+ {
|
||||
+ char *cidvar;
|
||||
+ const char *cid;
|
||||
+
|
||||
+ opt = find_dhcp_option (bp, size, GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER, &opt_len);
|
||||
+ if (opt && opt_len)
|
||||
+ grub_env_set_net_property (name, "vendor_class_identifier", (const char *) opt, opt_len);
|
||||
+ cidvar = grub_xasprintf ("net_%s_%s", name, "vendor_class_identifier");
|
||||
+ cid = grub_env_get (cidvar);
|
||||
+ grub_free (cidvar);
|
||||
+
|
||||
+ if (cid && grub_strcmp (cid, "HTTPClient") == 0)
|
||||
+ {
|
||||
+ char *proto, *ip, *pa;
|
||||
+
|
||||
+ /* FIXME: Provide better URL function that returns in place pointers
|
||||
+ * so that we don't have to free them.
|
||||
+ */
|
||||
+ if (!dissect_url (bp->boot_file, &proto, &ip, &pa))
|
||||
+ return inter;
|
||||
+
|
||||
+ if (is_def)
|
||||
+ {
|
||||
+ grub_net_default_server = grub_strdup (ip);
|
||||
+ grub_env_set ("net_default_interface", name);
|
||||
+ grub_env_export ("net_default_interface");
|
||||
+ }
|
||||
+ if (device && !*device)
|
||||
+ {
|
||||
+ *device = grub_xasprintf ("%s,%s", proto, ip);
|
||||
+ grub_print_error ();
|
||||
+ }
|
||||
+
|
||||
+ boot_file = pa;
|
||||
+ boot_file_len = grub_strlen (pa);
|
||||
+
|
||||
+ /* FIXME: Don't use malloc buffer here */
|
||||
+ grub_free (proto);
|
||||
+ grub_free (ip);
|
||||
+
|
||||
+ /* FIXME: NEED TO FREE boot_file */
|
||||
+ goto boot_file;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
opt = find_dhcp_option (bp, size, GRUB_NET_DHCP_OVERLOAD, &opt_len);
|
||||
if (opt && opt_len == 1)
|
||||
overload = *opt;
|
||||
@@ -428,6 +475,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
+boot_file:
|
||||
+
|
||||
if (boot_file)
|
||||
{
|
||||
grub_env_set_net_property (name, "boot_file", boot_file, boot_file_len);
|
||||
--- a/include/grub/net.h
|
||||
+++ b/include/grub/net.h
|
||||
@@ -530,6 +530,7 @@
|
||||
GRUB_NET_DHCP_MESSAGE_TYPE = 53,
|
||||
GRUB_NET_DHCP_SERVER_IDENTIFIER = 54,
|
||||
GRUB_NET_DHCP_PARAMETER_REQUEST_LIST = 55,
|
||||
+ GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER = 60,
|
||||
GRUB_NET_BOOTP_CLIENT_ID = 61,
|
||||
GRUB_NET_DHCP_TFTP_SERVER_NAME = 66,
|
||||
GRUB_NET_DHCP_BOOTFILE_NAME = 67,
|
@ -0,0 +1,66 @@
|
||||
From ac539a315495792cd75fe8ab1c474f26e0a78852 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Sat, 15 Aug 2020 02:19:36 +1000
|
||||
Subject: [PATCH 06/23] docs/grub: Document signing grub with an appended
|
||||
signature
|
||||
|
||||
Signing grub for firmware that verifies an appended signature is a
|
||||
bit fiddly. I don't want people to have to figure it out from scratch
|
||||
so document it here.
|
||||
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
---
|
||||
docs/grub.texi | 42 ++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 42 insertions(+)
|
||||
|
||||
--- a/docs/grub.texi
|
||||
+++ b/docs/grub.texi
|
||||
@@ -6606,6 +6606,48 @@
|
||||
will also be necessary to enrol the public key used into a relevant firmware
|
||||
key database.
|
||||
|
||||
+@section Signing GRUB with an appended signature
|
||||
+
|
||||
+The @file{core.img} itself can be signed with a Linux kernel module-style
|
||||
+appended signature.
|
||||
+
|
||||
+To support IEEE1275 platforms where the boot image is often loaded directly
|
||||
+from a disk partition rather than from a file system, the @file{core.img}
|
||||
+can specify the size and location of the appended signature with an ELF
|
||||
+note added by @command{grub-install}.
|
||||
+
|
||||
+An image can be signed this way using the @command{sign-file} command from
|
||||
+the Linux kernel:
|
||||
+
|
||||
+@example
|
||||
+@group
|
||||
+# grub.key is your private key and certificate.der is your public key
|
||||
+
|
||||
+# Determine the size of the appended signature. It depends on the signing
|
||||
+# certificate and the hash algorithm
|
||||
+touch empty
|
||||
+sign-file SHA256 grub.key certificate.der empty empty.sig
|
||||
+SIG_SIZE=`stat -c '%s' empty.sig`
|
||||
+rm empty empty.sig
|
||||
+
|
||||
+# Build a grub image with $SIG_SIZE reserved for the signature
|
||||
+grub-install --appended-signature-size $SIG_SIZE --modules="..." ...
|
||||
+
|
||||
+# Replace the reserved size with a signature:
|
||||
+# cut off the last $SIG_SIZE bytes with truncate's minus modifier
|
||||
+truncate -s -$SIG_SIZE /boot/grub/powerpc-ieee1275/core.elf core.elf.unsigned
|
||||
+# sign the trimmed file with an appended signature, restoring the correct size
|
||||
+sign-file SHA256 grub.key certificate.der core.elf.unsigned core.elf.signed
|
||||
+
|
||||
+# Don't forget to install the signed image as required
|
||||
+# (e.g. on powerpc-ieee1275, to the PReP partition)
|
||||
+@end group
|
||||
+@end example
|
||||
+
|
||||
+As with UEFI secure boot, it is necessary to build in the required modules,
|
||||
+or sign them separately.
|
||||
+
|
||||
+
|
||||
@node Platform limitations
|
||||
@chapter Platform limitations
|
||||
|
@ -0,0 +1,59 @@
|
||||
From 3741c6807923ae97b0d87e61c59c8de8af544484 Mon Sep 17 00:00:00 2001
|
||||
From: Javier Martinez Canillas <javierm@redhat.com>
|
||||
Date: Thu, 23 Apr 2020 15:06:46 +0200
|
||||
Subject: [PATCH 6/9] efi: Set image base address before jumping to the PE/COFF
|
||||
entry point
|
||||
|
||||
Upstream GRUB uses the EFI LoadImage() and StartImage() to boot the Linux
|
||||
kernel. But our custom EFI loader that supports Secure Boot instead uses
|
||||
the EFI handover protocol (for x86) or jumping directly to the PE/COFF
|
||||
entry point (for aarch64).
|
||||
|
||||
This is done to allow the bootloader to verify the images using the shim
|
||||
lock protocol to avoid booting untrusted binaries.
|
||||
|
||||
Since the bootloader loads the kernel from the boot media instead of using
|
||||
LoadImage(), it is responsible to set the Loaded Image base address before
|
||||
booting the kernel.
|
||||
|
||||
Otherwise the kernel EFI stub will complain that it was not set correctly
|
||||
and print the following warning message:
|
||||
|
||||
EFI stub: ERROR: FIRMWARE BUG: efi_loaded_image_t::image_base has bogus value
|
||||
|
||||
Resolves: rhbz#1825411
|
||||
|
||||
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
|
||||
---
|
||||
grub-core/loader/arm64/efi/linux.c | 12 ++++++++++++
|
||||
1 file changed, 12 insertions(+)
|
||||
|
||||
Index: grub-2.06~rc1/grub-core/loader/arm64/efi/linux.c
|
||||
===================================================================
|
||||
--- grub-2.06~rc1.orig/grub-core/loader/arm64/efi/linux.c
|
||||
+++ grub-2.06~rc1/grub-core/loader/arm64/efi/linux.c
|
||||
@@ -58,9 +58,24 @@ static grub_err_t
|
||||
grub_efi_linux_boot (void *kernel_address, grub_off_t offset,
|
||||
void *kernel_params)
|
||||
{
|
||||
+ grub_efi_loaded_image_t *loaded_image = NULL;
|
||||
handover_func hf;
|
||||
|
||||
+ /*
|
||||
+ * Since the EFI loader is not calling the LoadImage() and StartImage()
|
||||
+ * services for loading the kernel and booting respectively, it has to
|
||||
+ * set the Loaded Image base address.
|
||||
+ */
|
||||
+ loaded_image = grub_efi_get_loaded_image (grub_efi_image_handle);
|
||||
+ if (loaded_image)
|
||||
+ loaded_image->image_base = 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_address, (void *)(grub_efi_uintn_t)offset, kernel_params);
|
||||
hf = (handover_func)((char *)kernel_address + offset);
|
||||
+ grub_dprintf ("linux", "handover_func() = %p\n", hf);
|
||||
hf (grub_efi_image_handle, grub_efi_system_table, kernel_params);
|
||||
|
||||
return GRUB_ERR_BUG;
|
133
0006-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch
Normal file
133
0006-x86-efi-Re-arrange-grub_cmd_linux-a-little-bit.patch
Normal file
@ -0,0 +1,133 @@
|
||||
From 24b5c0a3788c5c02b72ea61312f5cf8c39429db1 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Thu, 13 Sep 2018 14:42:34 -0400
|
||||
Subject: [PATCH 06/11] 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>
|
||||
---
|
||||
grub-core/loader/i386/efi/linux.c | 73 +++++++++++++++++--------------
|
||||
1 file changed, 40 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index d6bed4fb4..096a52eb5 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -227,32 +227,9 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- 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));
|
||||
+ lh = (struct linux_i386_kernel_header *)kernel;
|
||||
+ grub_dprintf ("linux", "original lh is at %p\n", kernel);
|
||||
|
||||
- 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))
|
||||
{
|
||||
@@ -300,6 +277,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 %" PRIuGRUB_SIZE " 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));
|
||||
@@ -324,8 +329,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;
|
||||
|
||||
@@ -342,24 +347,26 @@ 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:
|
||||
|
||||
--
|
||||
2.31.1
|
||||
|
@ -0,0 +1,43 @@
|
||||
From 4773f90bdefb72dde55fb5961f7f37b467307016 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Axtens <dja@axtens.net>
|
||||
Date: Thu, 30 Jul 2020 00:13:21 +1000
|
||||
Subject: [PATCH 07/23] dl: provide a fake grub_dl_set_persistent for the emu
|
||||
target
|
||||
|
||||
Trying to start grub-emu with a module that calls grub_dl_set_persistent
|
||||
will crash because grub-emu fakes modules and passes NULL to the module
|
||||
init function.
|
||||
|
||||
Provide an empty function for the emu case.
|
||||
|
||||
Fixes: ee7808e2197c (dl: Add support for persistent modules)
|
||||
Signed-off-by: Daniel Axtens <dja@axtens.net>
|
||||
---
|
||||
include/grub/dl.h | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
--- a/include/grub/dl.h
|
||||
+++ b/include/grub/dl.h
|
||||
@@ -242,11 +242,22 @@
|
||||
return 0;
|
||||
}
|
||||
|
||||
+#ifdef GRUB_MACHINE_EMU
|
||||
+/*
|
||||
+ * Under grub-emu, modules are faked and NULL is passed to GRUB_MOD_INIT.
|
||||
+ * So we fake this out to avoid a NULL deref.
|
||||
+ */
|
||||
+static inline void
|
||||
+grub_dl_set_persistent (grub_dl_t mod __attribute__((unused)))
|
||||
+{
|
||||
+}
|
||||
+#else
|
||||
static inline void
|
||||
grub_dl_set_persistent (grub_dl_t mod)
|
||||
{
|
||||
mod->persistent = 1;
|
||||
}
|
||||
+#endif
|
||||
|
||||
static inline int
|
||||
grub_dl_is_persistent (grub_dl_t mod)
|
387
0007-efinet-Setting-network-from-UEFI-device-path.patch
Normal file
387
0007-efinet-Setting-network-from-UEFI-device-path.patch
Normal file
@ -0,0 +1,387 @@
|
||||
From 369df8e3006000a4acacc674f5882d8729781811 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Sun, 10 Jul 2016 23:46:31 +0800
|
||||
Subject: [PATCH 7/8] efinet: Setting network from UEFI device path
|
||||
|
||||
The PXE Base Code protocol used to obtain cached PXE DHCPACK packet is no
|
||||
longer provided for HTTP Boot. Instead, we have to get the HTTP boot
|
||||
information from the device path nodes defined in following UEFI Specification
|
||||
sections.
|
||||
|
||||
9.3.5.12 IPv4 Device Path
|
||||
9.3.5.13 IPv6 Device Path
|
||||
9.3.5.23 Uniform Resource Identifiers (URI) Device Path
|
||||
|
||||
This patch basically does:
|
||||
|
||||
include/grub/efi/api.h:
|
||||
Add new structure of Uniform Resource Identifiers (URI) Device Path
|
||||
|
||||
grub-core/net/drivers/efi/efinet.c:
|
||||
Check if PXE Base Code is available, if not it will try to obtain the netboot
|
||||
information from the device path where the image booted from. The DHCPACK
|
||||
packet is recoverd from the information in device patch and feed into the same
|
||||
DHCP packet processing functions to ensure the network interface is setting up
|
||||
the same way it used to be.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Signed-off-by: Ken Lin <ken.lin@hpe.com>
|
||||
---
|
||||
grub-core/net/drivers/efi/efinet.c | 268 +++++++++++++++++++++++++++++++++++--
|
||||
include/grub/efi/api.h | 11 ++
|
||||
2 files changed, 270 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/grub-core/net/drivers/efi/efinet.c
|
||||
+++ b/grub-core/net/drivers/efi/efinet.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <grub/efi/api.h>
|
||||
#include <grub/efi/efi.h>
|
||||
#include <grub/i18n.h>
|
||||
+#include <grub/net/netbuff.h>
|
||||
|
||||
GRUB_MOD_LICENSE ("GPLv3+");
|
||||
|
||||
@@ -341,6 +342,221 @@
|
||||
grub_free (handles);
|
||||
}
|
||||
|
||||
+static struct grub_net_buff *
|
||||
+grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *use_ipv6)
|
||||
+{
|
||||
+ grub_efi_uint16_t uri_len;
|
||||
+ grub_efi_device_path_t *ldp, *ddp;
|
||||
+ grub_efi_uri_device_path_t *uri_dp;
|
||||
+ struct grub_net_buff *nb;
|
||||
+ grub_err_t err;
|
||||
+
|
||||
+ ddp = grub_efi_duplicate_device_path (dp);
|
||||
+ ldp = grub_efi_find_last_device_path (ddp);
|
||||
+
|
||||
+ if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
|
||||
+ || GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ uri_len = GRUB_EFI_DEVICE_PATH_LENGTH (ldp) > 4 ? GRUB_EFI_DEVICE_PATH_LENGTH (ldp) - 4 : 0;
|
||||
+
|
||||
+ if (!uri_len)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ uri_dp = (grub_efi_uri_device_path_t *) ldp;
|
||||
+
|
||||
+ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||
+ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
+ ldp->length = sizeof (*ldp);
|
||||
+
|
||||
+ ldp = grub_efi_find_last_device_path (ddp);
|
||||
+
|
||||
+ if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
|
||||
+ || (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
|
||||
+ && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE))
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ nb = grub_netbuff_alloc (512);
|
||||
+ if (!nb)
|
||||
+ return NULL;
|
||||
+
|
||||
+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE)
|
||||
+ {
|
||||
+ grub_efi_ipv4_device_path_t *ipv4 = (grub_efi_ipv4_device_path_t *) ldp;
|
||||
+ struct grub_net_bootp_packet *bp;
|
||||
+ grub_uint8_t *ptr;
|
||||
+
|
||||
+ bp = (struct grub_net_bootp_packet *) nb->tail;
|
||||
+ err = grub_netbuff_put (nb, sizeof (*bp) + 4);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (sizeof(bp->boot_file) < uri_len)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ grub_memcpy (bp->boot_file, uri_dp->uri, uri_len);
|
||||
+ grub_memcpy (&bp->your_ip, ipv4->local_ip_address, sizeof (bp->your_ip));
|
||||
+ grub_memcpy (&bp->server_ip, ipv4->remote_ip_address, sizeof (bp->server_ip));
|
||||
+
|
||||
+ bp->vendor[0] = GRUB_NET_BOOTP_RFC1048_MAGIC_0;
|
||||
+ bp->vendor[1] = GRUB_NET_BOOTP_RFC1048_MAGIC_1;
|
||||
+ bp->vendor[2] = GRUB_NET_BOOTP_RFC1048_MAGIC_2;
|
||||
+ bp->vendor[3] = GRUB_NET_BOOTP_RFC1048_MAGIC_3;
|
||||
+
|
||||
+ ptr = nb->tail;
|
||||
+ err = grub_netbuff_put (nb, sizeof (ipv4->subnet_mask) + 2);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ *ptr++ = GRUB_NET_BOOTP_NETMASK;
|
||||
+ *ptr++ = sizeof (ipv4->subnet_mask);
|
||||
+ grub_memcpy (ptr, ipv4->subnet_mask, sizeof (ipv4->subnet_mask));
|
||||
+
|
||||
+ ptr = nb->tail;
|
||||
+ err = grub_netbuff_put (nb, sizeof (ipv4->gateway_ip_address) + 2);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ *ptr++ = GRUB_NET_BOOTP_ROUTER;
|
||||
+ *ptr++ = sizeof (ipv4->gateway_ip_address);
|
||||
+ grub_memcpy (ptr, ipv4->gateway_ip_address, sizeof (ipv4->gateway_ip_address));
|
||||
+
|
||||
+ ptr = nb->tail;
|
||||
+ err = grub_netbuff_put (nb, sizeof ("HTTPClient") + 1);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ *ptr++ = GRUB_NET_BOOTP_VENDOR_CLASS_IDENTIFIER;
|
||||
+ *ptr++ = sizeof ("HTTPClient") - 1;
|
||||
+ grub_memcpy (ptr, "HTTPClient", sizeof ("HTTPClient") - 1);
|
||||
+
|
||||
+ ptr = nb->tail;
|
||||
+ err = grub_netbuff_put (nb, 1);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ *ptr = GRUB_NET_BOOTP_END;
|
||||
+ *use_ipv6 = 0;
|
||||
+
|
||||
+ ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||
+ ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
+ ldp->length = sizeof (*ldp);
|
||||
+ ldp = grub_efi_find_last_device_path (ddp);
|
||||
+
|
||||
+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_MAC_ADDRESS_DEVICE_PATH_SUBTYPE)
|
||||
+ {
|
||||
+ grub_efi_mac_address_device_path_t *mac = (grub_efi_mac_address_device_path_t *) ldp;
|
||||
+ bp->hw_type = mac->if_type;
|
||||
+ bp->hw_len = sizeof (bp->mac_addr);
|
||||
+ grub_memcpy (bp->mac_addr, mac->mac_address, bp->hw_len);
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ grub_efi_ipv6_device_path_t *ipv6 = (grub_efi_ipv6_device_path_t *) ldp;
|
||||
+
|
||||
+ struct grub_net_dhcp6_packet *d6p;
|
||||
+ struct grub_net_dhcp6_option *opt;
|
||||
+ struct grub_net_dhcp6_option_iana *iana;
|
||||
+ struct grub_net_dhcp6_option_iaaddr *iaaddr;
|
||||
+
|
||||
+ d6p = (struct grub_net_dhcp6_packet *)nb->tail;
|
||||
+ err = grub_netbuff_put (nb, sizeof(*d6p));
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ d6p->message_type = GRUB_NET_DHCP6_REPLY;
|
||||
+
|
||||
+ opt = (struct grub_net_dhcp6_option *)nb->tail;
|
||||
+ err = grub_netbuff_put (nb, sizeof(*opt));
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IA_NA);
|
||||
+ opt->len = grub_cpu_to_be16_compile_time (sizeof(*iana) + sizeof(*opt) + sizeof(*iaaddr));
|
||||
+
|
||||
+ err = grub_netbuff_put (nb, sizeof(*iana));
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ opt = (struct grub_net_dhcp6_option *)nb->tail;
|
||||
+ err = grub_netbuff_put (nb, sizeof(*opt));
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_IAADDR);
|
||||
+ opt->len = grub_cpu_to_be16_compile_time (sizeof (*iaaddr));
|
||||
+
|
||||
+ iaaddr = (struct grub_net_dhcp6_option_iaaddr *)nb->tail;
|
||||
+ err = grub_netbuff_put (nb, sizeof(*iaaddr));
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ grub_memcpy (iaaddr->addr, ipv6->local_ip_address, sizeof(ipv6->local_ip_address));
|
||||
+
|
||||
+ opt = (struct grub_net_dhcp6_option *)nb->tail;
|
||||
+ err = grub_netbuff_put (nb, sizeof(*opt) + uri_len);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_BOOTFILE_URL);
|
||||
+ opt->len = grub_cpu_to_be16 (uri_len);
|
||||
+ grub_memcpy (opt->data, uri_dp->uri, uri_len);
|
||||
+
|
||||
+ *use_ipv6 = 1;
|
||||
+ }
|
||||
+
|
||||
+ grub_free (ddp);
|
||||
+ return nb;
|
||||
+}
|
||||
+
|
||||
static void
|
||||
grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
|
||||
char **path)
|
||||
@@ -361,6 +577,11 @@
|
||||
grub_efi_device_path_t *cdp;
|
||||
struct grub_efi_pxe *pxe;
|
||||
struct grub_efi_pxe_mode *pxe_mode;
|
||||
+ grub_uint8_t *packet_buf;
|
||||
+ grub_size_t packet_bufsz ;
|
||||
+ int ipv6;
|
||||
+ struct grub_net_buff *nb = NULL;
|
||||
+
|
||||
if (card->driver != &efidriver)
|
||||
continue;
|
||||
cdp = grub_efi_get_device_path (card->efi_handle);
|
||||
@@ -380,11 +601,21 @@
|
||||
ldp = grub_efi_find_last_device_path (dp);
|
||||
if (GRUB_EFI_DEVICE_PATH_TYPE (ldp) != GRUB_EFI_MESSAGING_DEVICE_PATH_TYPE
|
||||
|| (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV4_DEVICE_PATH_SUBTYPE
|
||||
- && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE))
|
||||
+ && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_IPV6_DEVICE_PATH_SUBTYPE
|
||||
+ && GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) != GRUB_EFI_URI_DEVICE_PATH_SUBTYPE))
|
||||
continue;
|
||||
dup_dp = grub_efi_duplicate_device_path (dp);
|
||||
if (!dup_dp)
|
||||
continue;
|
||||
+
|
||||
+ if (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp) == GRUB_EFI_URI_DEVICE_PATH_SUBTYPE)
|
||||
+ {
|
||||
+ dup_ldp = grub_efi_find_last_device_path (dup_dp);
|
||||
+ dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||
+ dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
+ dup_ldp->length = sizeof (*dup_ldp);
|
||||
+ }
|
||||
+
|
||||
dup_ldp = grub_efi_find_last_device_path (dup_dp);
|
||||
dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
||||
dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
@@ -396,16 +627,31 @@
|
||||
}
|
||||
pxe = grub_efi_open_protocol (hnd, &pxe_io_guid,
|
||||
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
- if (! pxe)
|
||||
- continue;
|
||||
- pxe_mode = pxe->mode;
|
||||
+ if (!pxe)
|
||||
+ {
|
||||
+ nb = grub_efinet_create_dhcp_ack_from_device_path (dp, &ipv6);
|
||||
+ if (!nb)
|
||||
+ {
|
||||
+ grub_print_error ();
|
||||
+ continue;
|
||||
+ }
|
||||
+ packet_buf = nb->head;
|
||||
+ packet_bufsz = nb->tail - nb->head;
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ pxe_mode = pxe->mode;
|
||||
+ packet_buf = (grub_uint8_t *) &pxe_mode->dhcp_ack;
|
||||
+ packet_bufsz = sizeof (pxe_mode->dhcp_ack);
|
||||
+ ipv6 = pxe_mode->using_ipv6;
|
||||
+ }
|
||||
|
||||
- if (pxe_mode->using_ipv6)
|
||||
+ if (ipv6)
|
||||
{
|
||||
grub_net_configure_by_dhcpv6_reply (card->name, card, 0,
|
||||
(struct grub_net_dhcp6_packet *)
|
||||
- &pxe_mode->dhcp_ack,
|
||||
- sizeof (pxe_mode->dhcp_ack),
|
||||
+ packet_buf,
|
||||
+ packet_bufsz,
|
||||
1, device, path);
|
||||
if (grub_errno)
|
||||
grub_print_error ();
|
||||
@@ -414,8 +660,8 @@
|
||||
{
|
||||
inter = grub_net_configure_by_dhcp_ack (card->name, card, 0,
|
||||
(struct grub_net_bootp_packet *)
|
||||
- &pxe_mode->dhcp_ack,
|
||||
- sizeof (pxe_mode->dhcp_ack),
|
||||
+ packet_buf,
|
||||
+ packet_bufsz,
|
||||
1, device, path);
|
||||
|
||||
if (inter != NULL)
|
||||
@@ -441,6 +687,10 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
+
|
||||
+ if (nb)
|
||||
+ grub_netbuff_free (nb);
|
||||
+
|
||||
return;
|
||||
}
|
||||
}
|
||||
--- a/include/grub/efi/api.h
|
||||
+++ b/include/grub/efi/api.h
|
||||
@@ -876,6 +876,8 @@
|
||||
grub_efi_uint16_t remote_port;
|
||||
grub_efi_uint16_t protocol;
|
||||
grub_efi_uint8_t static_ip_address;
|
||||
+ grub_efi_ipv4_address_t gateway_ip_address;
|
||||
+ grub_efi_ipv4_address_t subnet_mask;
|
||||
} GRUB_PACKED;
|
||||
typedef struct grub_efi_ipv4_device_path grub_efi_ipv4_device_path_t;
|
||||
|
||||
@@ -939,6 +941,15 @@
|
||||
} GRUB_PACKED;
|
||||
typedef struct grub_efi_vlan_device_path grub_efi_vlan_device_path_t;
|
||||
|
||||
+#define GRUB_EFI_URI_DEVICE_PATH_SUBTYPE 24
|
||||
+
|
||||
+struct grub_efi_uri_device_path
|
||||
+{
|
||||
+ grub_efi_device_path_t header;
|
||||
+ grub_efi_uint8_t uri[0];
|
||||
+} GRUB_PACKED;
|
||||
+typedef struct grub_efi_uri_device_path grub_efi_uri_device_path_t;
|
||||
+
|
||||
#define GRUB_EFI_VENDOR_MESSAGING_DEVICE_PATH_SUBTYPE 10
|
||||
|
||||
/* Media Device Path. */
|
279
0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch
Normal file
279
0007-grub-switch-to-blscfg-adapt-to-openSUSE.patch
Normal file
@ -0,0 +1,279 @@
|
||||
From 96e5a28d120856057fe7fc9b281f11f8933063b7 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 30 Jun 2023 14:37:41 +0800
|
||||
Subject: [PATCH 7/9] grub-switch-to-blscfg: adapt to openSUSE
|
||||
|
||||
A few tweaks to make it 'just works' for openSUSE:
|
||||
|
||||
- remove RHEL specific $grub_get_kernel_settings and all reference to it.
|
||||
- make $grubdir and $startlink to the path in openSUSE
|
||||
- change the bls template to openSUSE
|
||||
- make $cmdline account for btrfs subvolumes, among others
|
||||
- remove RHEL specific $GRUB_LINUX_MAKE_DEBUG and all related code
|
||||
- remove ostree specific hack
|
||||
- ignore increment.mod
|
||||
- fix error in dash shell script
|
||||
- fix kernel flavor parsing in openSUSE
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
util/grub-switch-to-blscfg.in | 156 ++++++++++++++++++++--------------
|
||||
1 file changed, 94 insertions(+), 62 deletions(-)
|
||||
|
||||
diff --git a/util/grub-switch-to-blscfg.in b/util/grub-switch-to-blscfg.in
|
||||
index a851424be..145c22add 100644
|
||||
--- a/util/grub-switch-to-blscfg.in
|
||||
+++ b/util/grub-switch-to-blscfg.in
|
||||
@@ -28,27 +28,24 @@ PACKAGE_NAME=@PACKAGE_NAME@
|
||||
PACKAGE_VERSION=@PACKAGE_VERSION@
|
||||
datarootdir="@datarootdir@"
|
||||
datadir="@datadir@"
|
||||
-if [ ! -v pkgdatadir ]; then
|
||||
+if [ -z "${pkgdatadir+x}" ]; then
|
||||
pkgdatadir="${datadir}/@PACKAGE@"
|
||||
fi
|
||||
|
||||
self=`basename $0`
|
||||
|
||||
-grub_get_kernel_settings="${sbindir}/@grub_get_kernel_settings@"
|
||||
grub_editenv=${bindir}/@grub_editenv@
|
||||
-etcdefaultgrub=/etc/default/grub
|
||||
+grub_probe="${sbindir}/@grub_probe@"
|
||||
+etcdefaultgrub=${sysconfdir}/default/grub
|
||||
|
||||
-eval "$("${grub_get_kernel_settings}")" || true
|
||||
-
|
||||
-EFIDIR=$(grep ^ID= /etc/os-release | sed -e 's/^ID=//' -e 's/rhel/redhat/' -e 's/\"//g')
|
||||
-if [ -d /sys/firmware/efi/efivars/ ]; then
|
||||
- startlink=/etc/grub2-efi.cfg
|
||||
- grubdir=`echo "/@bootdirname@/efi/EFI/${EFIDIR}/" | sed 's,//*,/,g'`
|
||||
-else
|
||||
- startlink=/etc/grub2.cfg
|
||||
- grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
|
||||
+if test -f "$etcdefaultgrub" ; then
|
||||
+ # shellcheck source=/etc/default/grub
|
||||
+ . "$etcdefaultgrub"
|
||||
fi
|
||||
|
||||
+grubdir=`echo "/@bootdirname@/@grubdirname@" | sed 's,//*,/,g'`
|
||||
+startlink="${grubdir}/grub.cfg"
|
||||
+
|
||||
blsdir=`echo "/@bootdirname@/loader/entries" | sed 's,//*,/,g'`
|
||||
|
||||
backupsuffix=.bak
|
||||
@@ -58,19 +55,80 @@ arch="$(uname -m)"
|
||||
export TEXTDOMAIN=@PACKAGE@
|
||||
export TEXTDOMAINDIR="@localedir@"
|
||||
|
||||
+# shellcheck source=/usr/share/grub2/grub-mkconfig_lib
|
||||
. "${pkgdatadir}/grub-mkconfig_lib"
|
||||
|
||||
+# FIXME: Abort if grub_probe fails
|
||||
+
|
||||
+GRUB_DEVICE="`${grub_probe} --target=device /`"
|
||||
+GRUB_DEVICE_UUID="`${grub_probe} --device ${GRUB_DEVICE} --target=fs_uuid 2> /dev/null`" || true
|
||||
+GRUB_DEVICE_PARTUUID="`${grub_probe} --device ${GRUB_DEVICE} --target=partuuid 2> /dev/null`" || true
|
||||
+GRUB_FS="`${grub_probe} --device ${GRUB_DEVICE} --target=fs 2> /dev/null || echo unknown`"
|
||||
+
|
||||
+# loop-AES arranges things so that /dev/loop/X can be our root device, but
|
||||
+# the initrds that Linux uses don't like that.
|
||||
+case ${GRUB_DEVICE} in
|
||||
+ /dev/loop/*|/dev/loop[0-9])
|
||||
+ GRUB_DEVICE=$(losetup "${GRUB_DEVICE}" | sed -e "s/^[^(]*(\([^)]\+\)).*/\1/")
|
||||
+ ;;
|
||||
+esac
|
||||
+
|
||||
+# Default to disabling partition uuid support to maintian compatibility with
|
||||
+# older kernels.
|
||||
+GRUB_DISABLE_LINUX_PARTUUID=${GRUB_DISABLE_LINUX_PARTUUID-true}
|
||||
+
|
||||
+# btrfs may reside on multiple devices. We cannot pass them as value of root= parameter
|
||||
+# and mounting btrfs requires user space scanning, so force UUID in this case.
|
||||
+if ( [ "x${GRUB_DEVICE_UUID}" = "x" ] && [ "x${GRUB_DEVICE_PARTUUID}" = "x" ] ) \
|
||||
+ || ( [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ] \
|
||||
+ && [ "x${GRUB_DISABLE_LINUX_PARTUUID}" = "xtrue" ] ) \
|
||||
+ || ( ! test -e "/dev/disk/by-uuid/${GRUB_DEVICE_UUID}" \
|
||||
+ && ! test -e "/dev/disk/by-partuuid/${GRUB_DEVICE_PARTUUID}" ) \
|
||||
+ || ( test -e "${GRUB_DEVICE}" && uses_abstraction "${GRUB_DEVICE}" lvm ); then
|
||||
+ LINUX_ROOT_DEVICE=${GRUB_DEVICE}
|
||||
+elif [ "x${GRUB_DEVICE_UUID}" = "x" ] \
|
||||
+ || [ "x${GRUB_DISABLE_LINUX_UUID}" = "xtrue" ]; then
|
||||
+ LINUX_ROOT_DEVICE=PARTUUID=${GRUB_DEVICE_PARTUUID}
|
||||
+else
|
||||
+ LINUX_ROOT_DEVICE=UUID=${GRUB_DEVICE_UUID}
|
||||
+fi
|
||||
+
|
||||
+if [ "x$GRUB_CONMODE" != "x" ]; then
|
||||
+ GRUB_CMDLINE_LINUX="conmode=${GRUB_CONMODE} ${GRUB_CMDLINE_LINUX}"
|
||||
+fi
|
||||
+
|
||||
+case x"$GRUB_FS" in
|
||||
+ xbtrfs)
|
||||
+ if [ "x${SUSE_BTRFS_SNAPSHOT_BOOTING}" != "xtrue" ]; then
|
||||
+ rootsubvol="`make_system_path_relative_to_its_root /`"
|
||||
+ rootsubvol="${rootsubvol#/}"
|
||||
+ if [ "x${rootsubvol}" != x ] && [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" != "xtrue" ]; then
|
||||
+ GRUB_CMDLINE_LINUX="rootflags=subvol=${rootsubvol} ${GRUB_CMDLINE_LINUX}"
|
||||
+ fi
|
||||
+ fi
|
||||
+ ;;
|
||||
+ xzfs)
|
||||
+ rpool=`${grub_probe} --device ${GRUB_DEVICE} --target=fs_label 2>/dev/null || true`
|
||||
+ bootfs="`make_system_path_relative_to_its_root / | sed -e "s,@$,,"`"
|
||||
+ LINUX_ROOT_DEVICE="ZFS=${rpool}${bootfs%/}"
|
||||
+ ;;
|
||||
+esac
|
||||
+
|
||||
+if [ "x$SUSE_REMOVE_LINUX_ROOT_PARAM" = "xtrue" ]; then
|
||||
+ LINUX_ROOT_DEVICE=""
|
||||
+fi
|
||||
+
|
||||
# Usage: usage
|
||||
# Print the usage.
|
||||
usage () {
|
||||
gettext_printf "Usage: %s\n" "$self"
|
||||
- gettext "Switch to BLS config files.\n"; echo
|
||||
+ gettext "Switch to BLS config files. Only for testing purpose !!!\n"; echo
|
||||
echo
|
||||
print_option_help "-h, --help" "$(gettext "print this message and exit")"
|
||||
print_option_help "-V, --version" "$(gettext "print the version information and exit")"
|
||||
echo
|
||||
print_option_help "--backup-suffix=$(gettext "SUFFIX")" "$backupsuffix"
|
||||
- print_option_help "--bls-directory=$(gettext "DIR")" "$blsdir"
|
||||
+ print_option_help "--bls-directory=$(gettext "DIR")" "Noop, always $blsdir"
|
||||
print_option_help "--config-file=$(gettext "FILE")" "$startlink"
|
||||
print_option_help "--grub-defaults=$(gettext "FILE")" "$etcdefaultgrub"
|
||||
print_option_help "--grub-directory=$(gettext "DIR")" "$grubdir"
|
||||
@@ -112,11 +170,15 @@ do
|
||||
;;
|
||||
|
||||
--bls-directory)
|
||||
- blsdir=`argument $option "$@"`
|
||||
+ # blsdir=`argument $option "$@"`
|
||||
+ gettext_printf "WARN: --bls-directory is currently disabled, it's always $blsdir !!!\n"
|
||||
+ gettext_printf "WARN: use kernel-install instead if you want to test bls directory on ESP !!!\n"
|
||||
shift
|
||||
;;
|
||||
--bls-directory=*)
|
||||
- blsdir=`echo "$option" | sed 's/--bls-directory=//'`
|
||||
+ # blsdir=`echo "$option" | sed 's/--bls-directory=//'`
|
||||
+ gettext_printf "WARN: --bls-directory is currently disabled, it's always $blsdir !!!\n"
|
||||
+ gettext_printf "WARN: use kernel-install instead if you want to test bls directory on ESP !!!\n"
|
||||
;;
|
||||
|
||||
--config-file)
|
||||
@@ -172,7 +234,7 @@ find_grub_cfg() {
|
||||
return 1
|
||||
}
|
||||
|
||||
-if ! find_grub_cfg ${startlink} ${grubdir}/grub.cfg ; then
|
||||
+if ! find_grub_cfg "${startlink}" ; then
|
||||
gettext_printf "Couldn't find config file\n" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -190,27 +252,24 @@ fi
|
||||
mkbls() {
|
||||
local kernelver=$1 && shift
|
||||
local datetime=$1 && shift
|
||||
+ local prefix=$1 && shift
|
||||
local kernelopts=$1 && shift
|
||||
|
||||
- local debugname=""
|
||||
- local debugid=""
|
||||
local flavor=""
|
||||
|
||||
- if [ "$kernelver" == *\+* ] ; then
|
||||
- local flavor=-"${kernelver##*+}"
|
||||
- if [ "${flavor}" == "-debug" ]; then
|
||||
- local debugname=" with debugging"
|
||||
- local debugid="-debug"
|
||||
- fi
|
||||
- fi
|
||||
+ case "$kernelver" in
|
||||
+ *-*-*)
|
||||
+ flavor=-"${kernelver##*-}"
|
||||
+ ;;
|
||||
+ esac
|
||||
(
|
||||
- source /etc/os-release
|
||||
+ . /etc/os-release
|
||||
|
||||
cat <<EOF
|
||||
-title ${NAME} (${kernelver}) ${VERSION}${debugname}
|
||||
-version ${kernelver}${debugid}
|
||||
-linux /vmlinuz-${kernelver}
|
||||
-initrd /initramfs-${kernelver}.img
|
||||
+title ${NAME} (${kernelver}) ${VERSION}
|
||||
+version ${kernelver}
|
||||
+linux ${prefix}/vmlinuz-${kernelver}
|
||||
+initrd ${prefix}/initrd-${kernelver}
|
||||
options ${kernelopts}
|
||||
grub_users \$grub_users
|
||||
grub_arg --unrestricted
|
||||
@@ -233,42 +292,15 @@ copy_bls() {
|
||||
continue
|
||||
fi
|
||||
|
||||
- linux_relpath="$("${grub_mkrelpath}" "${linux_path}")"
|
||||
- bootprefix="${linux_relpath%%"${linux}"}"
|
||||
+ bootprefix="$(make_system_path_relative_to_its_root /boot)"
|
||||
cmdline="root=${LINUX_ROOT_DEVICE} ro ${GRUB_CMDLINE_LINUX} ${GRUB_CMDLINE_LINUX_DEFAULT}"
|
||||
|
||||
mkbls "${kernelver}" \
|
||||
"$(date -u +%Y%m%d%H%M%S -d "$(stat -c '%y' "${kernel_dir}")")" \
|
||||
"${bootprefix}" "${cmdline}" >"${bls_target}"
|
||||
-
|
||||
- if [ "x$GRUB_LINUX_MAKE_DEBUG" = "xtrue" ]; then
|
||||
- bls_debug="$(echo ${bls_target} | sed -e "s/${kernelver}/${kernelver}~debug/")"
|
||||
- cp -aT "${bls_target}" "${bls_debug}"
|
||||
- title="$(grep '^title[ \t]' "${bls_debug}" | sed -e 's/^title[ \t]*//')"
|
||||
- options="$(echo "${cmdline} ${GRUB_CMDLINE_LINUX_DEBUG}" | sed -e 's/\//\\\//g')"
|
||||
- sed -i -e "s/^title.*/title ${title}${GRUB_LINUX_DEBUG_TITLE_POSTFIX}/" "${bls_debug}"
|
||||
- sed -i -e "s/^options.*/options ${options}/" "${bls_debug}"
|
||||
- fi
|
||||
done
|
||||
-
|
||||
- if [ -f "/boot/vmlinuz-0-rescue-${MACHINE_ID}" ]; then
|
||||
- mkbls "0-rescue-${MACHINE_ID}" "0" "${bootprefix}" >"${blsdir}/${MACHINE_ID}-0-rescue.conf"
|
||||
- fi
|
||||
}
|
||||
|
||||
-# The grub2 EFI binary is not copied to the ESP as a part of an ostree
|
||||
-# transaction. Make sure a grub2 version with BLS support is installed
|
||||
-# but only do this if the blsdir is not set, to make sure that the BLS
|
||||
-# parsing module will search for the BLS snippets in the default path.
|
||||
-if test -f /run/ostree-booted && test -d /sys/firmware/efi/efivars && \
|
||||
- ! ${grub_editenv} - list | grep -q blsdir && \
|
||||
- mountpoint -q /boot; then
|
||||
- grub_binary="$(find /usr/lib/ostree-boot/efi/EFI/${EFIDIR}/ -name grub*.efi)"
|
||||
- install -m 700 ${grub_binary} ${grubdir} || exit 1
|
||||
- # Create a hidden file to indicate that grub2 now has BLS support.
|
||||
- touch /boot/grub2/.grub2-blscfg-supported
|
||||
-fi
|
||||
-
|
||||
GENERATE=0
|
||||
if grep '^GRUB_ENABLE_BLSCFG=.*' "${etcdefaultgrub}" \
|
||||
| grep -vq '^GRUB_ENABLE_BLSCFG="*true"*\s*$' ; then
|
||||
@@ -297,9 +329,7 @@ if [ "${GENERATE}" -eq 1 ] ; then
|
||||
fi
|
||||
|
||||
if [ -n "${mod_dir}" ]; then
|
||||
- for mod in blscfg increment; do
|
||||
- install -m 700 ${prefix}/lib/grub/${mod_dir}/${mod}.mod ${grubdir}/$mod_dir/ || exit 1
|
||||
- done
|
||||
+ install -m 700 "${pkgdatadir}/${mod_dir}/blscfg.mod" "${grubdir}/$mod_dir/" || exit 1
|
||||
fi
|
||||
|
||||
cp -af "${GRUB_CONFIG_FILE}" "${GRUB_CONFIG_FILE}${backupsuffix}"
|
||||
@@ -311,6 +341,8 @@ if [ "${GENERATE}" -eq 1 ] ; then
|
||||
gettext_printf "Updating %s failed\n" "${GRUB_CONFIG_FILE}"
|
||||
exit 1
|
||||
fi
|
||||
+else
|
||||
+ gettext_printf "Do nothing because \$GRUB_ENABLE_BLSCFG is already true in %s\n" "${GRUB_CONFIG_FILE}"
|
||||
fi
|
||||
|
||||
# Bye.
|
||||
--
|
||||
2.45.2
|
||||
|
249
0007-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch
Normal file
249
0007-x86-efi-Make-our-own-allocator-for-kernel-stuff.patch
Normal file
@ -0,0 +1,249 @@
|
||||
From 2a84f1a50c6f8770808fd4ec590eb8cff4228aed Mon Sep 17 00:00:00 2001
|
||||
From: Peter Jones <pjones@redhat.com>
|
||||
Date: Wed, 12 Sep 2018 16:03:55 -0400
|
||||
Subject: [PATCH 07/11] x86-efi: Make our own allocator for kernel stuff
|
||||
|
||||
This helps enable allocations above 4GB.
|
||||
|
||||
Signed-off-by: Peter Jones <pjones@redhat.com>
|
||||
---
|
||||
grub-core/loader/i386/efi/linux.c | 155 ++++++++++++++++++------------
|
||||
1 file changed, 94 insertions(+), 61 deletions(-)
|
||||
|
||||
diff --git a/grub-core/loader/i386/efi/linux.c b/grub-core/loader/i386/efi/linux.c
|
||||
index 096a52eb5..d284db5d1 100644
|
||||
--- a/grub-core/loader/i386/efi/linux.c
|
||||
+++ b/grub-core/loader/i386/efi/linux.c
|
||||
@@ -47,6 +47,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 %" PRIuGRUB_SIZE" pages from %p\n",
|
||||
+ pages, (void *)(grub_addr_t)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)
|
||||
{
|
||||
@@ -62,14 +121,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;
|
||||
}
|
||||
|
||||
@@ -146,17 +203,13 @@ grub_cmd_initrd (grub_command_t cmd __attribute__ ((unused)),
|
||||
size += ALIGN_UP (grub_file_size (files[i]), 4);
|
||||
}
|
||||
|
||||
- initrd_mem = grub_efi_allocate_pages_max (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;
|
||||
- }
|
||||
+ 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;
|
||||
|
||||
@@ -214,7 +267,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"));
|
||||
@@ -258,7 +310,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))
|
||||
{
|
||||
@@ -277,17 +329,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));
|
||||
@@ -306,16 +350,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;
|
||||
- }
|
||||
+ goto fail;
|
||||
+ grub_dprintf ("linux", "linux_cmdline = %p\n", linux_cmdline);
|
||||
|
||||
grub_memcpy (linux_cmdline, LINUX_IMAGE, sizeof (LINUX_IMAGE));
|
||||
err = grub_create_loader_cmdline (argc, argv,
|
||||
@@ -326,27 +364,24 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
goto fail;
|
||||
|
||||
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);
|
||||
@@ -382,16 +417,14 @@ grub_cmd_linux (grub_command_t cmd __attribute__ ((unused)),
|
||||
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 (kernel_mem && !loaded)
|
||||
- grub_efi_free_pages((grub_efi_physical_address_t)(grub_addr_t)kernel_mem, BYTES_TO_PAGES(kernel_size));
|
||||
+ if (!loaded)
|
||||
+ {
|
||||
+ if (lh)
|
||||
+ kernel_free (linux_cmdline, lh->cmdline_size + 1);
|
||||
|
||||
- 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;
|
||||
}
|
||||
--
|
||||
2.31.1
|
||||
|
75
0008-blscfg-reading-bls-fragments-if-boot-present.patch
Normal file
75
0008-blscfg-reading-bls-fragments-if-boot-present.patch
Normal file
@ -0,0 +1,75 @@
|
||||
From 2b0e6effc31ec166bbbe35a3cd2b4c73051f38bb Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 16 Jun 2023 15:54:50 +0800
|
||||
Subject: [PATCH 8/9] blscfg: reading bls fragments if boot present
|
||||
|
||||
The Boot Loader Specification (BLS) designates the EFI System Partition
|
||||
(ESP) as a primary location for $BOOT, where boot menu entries can be
|
||||
stored. The specification encourages boot loaders to retrieve menu
|
||||
entries from the ESP, even when XBOOTLDR is present.
|
||||
|
||||
This commit aligns with the BLS specification by introducing the
|
||||
capability to search for the ESP in addition to the default root
|
||||
partition or any specified location via blscfg's command line. The $boot
|
||||
environment variable is utilized as a reference to the ESP device for
|
||||
the blscfg command. Initialization of $boot in grub.cfg is demonstrated
|
||||
as follows:
|
||||
|
||||
insmod part_gpt
|
||||
insmod fat
|
||||
search --no-floppy --fs-uuid --set=boot F414-5A9F
|
||||
|
||||
If $boot is unset, no additional search for the BLS location will be
|
||||
performed.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/commands/blscfg.c | 10 ++++++++++
|
||||
util/grub.d/10_linux.in | 3 ++-
|
||||
2 files changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
|
||||
index c872bcef0..cbe2a289e 100644
|
||||
--- a/grub-core/commands/blscfg.c
|
||||
+++ b/grub-core/commands/blscfg.c
|
||||
@@ -1186,6 +1186,7 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
|
||||
char *entry_id = NULL;
|
||||
bool show_default = true;
|
||||
bool show_non_default = true;
|
||||
+ const char *boot = NULL;
|
||||
|
||||
if (argc == 1) {
|
||||
if (grub_strcmp (args[0], "default") == 0) {
|
||||
@@ -1205,6 +1206,15 @@ grub_cmd_blscfg (grub_extcmd_context_t ctxt UNUSED,
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
+ boot = grub_env_get("boot");
|
||||
+ path = (boot) ? grub_xasprintf("(%s)" GRUB_BLS_CONFIG_PATH, boot) : NULL;
|
||||
+ if (path)
|
||||
+ {
|
||||
+ bls_load_entries(path);
|
||||
+ grub_print_error();
|
||||
+ }
|
||||
+ grub_free(path);
|
||||
+
|
||||
return bls_create_entries(show_default, show_non_default, entry_id);
|
||||
}
|
||||
|
||||
diff --git a/util/grub.d/10_linux.in b/util/grub.d/10_linux.in
|
||||
index 45eefb332..edf0fca55 100644
|
||||
--- a/util/grub.d/10_linux.in
|
||||
+++ b/util/grub.d/10_linux.in
|
||||
@@ -201,7 +201,8 @@ populate_menu()
|
||||
}
|
||||
|
||||
# Make BLS the default if GRUB_ENABLE_BLSCFG was not set and grubby is not installed.
|
||||
-if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null; then
|
||||
+# FIXME: The test should be aligned to openSUSE, grubby is not our default tool
|
||||
+if [ -z "${GRUB_ENABLE_BLSCFG}" ] && ! command -v new-kernel-pkg >/dev/null && false; then
|
||||
GRUB_ENABLE_BLSCFG="true"
|
||||
fi
|
||||
|
||||
--
|
||||
2.44.0
|
||||
|
331
0008-efinet-Setting-DNS-server-from-UEFI-protocol.patch
Normal file
331
0008-efinet-Setting-DNS-server-from-UEFI-protocol.patch
Normal file
@ -0,0 +1,331 @@
|
||||
From 0c7ae6d7527d08e54a6eeebddb6c5c697c4b37d2 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 14 Jul 2016 17:48:45 +0800
|
||||
Subject: [PATCH 8/8] efinet: Setting DNS server from UEFI protocol
|
||||
|
||||
In the URI device path node, any name rahter than address can be used for
|
||||
looking up the resources so that DNS service become needed to get answer of the
|
||||
name's address. Unfortunately the DNS is not defined in any of the device path
|
||||
nodes so that we use the EFI_IP4_CONFIG2_PROTOCOL and EFI_IP6_CONFIG_PROTOCOL
|
||||
to obtain it.
|
||||
|
||||
These two protcols are defined the sections of UEFI specification.
|
||||
|
||||
27.5 EFI IPv4 Configuration II Protocol
|
||||
27.7 EFI IPv6 Configuration Protocol
|
||||
|
||||
include/grub/efi/api.h:
|
||||
Add new structure and protocol UUID of EFI_IP4_CONFIG2_PROTOCOL and
|
||||
EFI_IP6_CONFIG_PROTOCOL.
|
||||
|
||||
grub-core/net/drivers/efi/efinet.c:
|
||||
Use the EFI_IP4_CONFIG2_PROTOCOL and EFI_IP6_CONFIG_PROTOCOL to obtain the list
|
||||
of DNS server address for IPv4 and IPv6 respectively. The address of DNS
|
||||
servers is structured into DHCPACK packet and feed into the same DHCP packet
|
||||
processing functions to ensure the network interface is setting up the same way
|
||||
it used to be.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Signed-off-by: Ken Lin <ken.lin@hpe.com>
|
||||
---
|
||||
grub-core/net/drivers/efi/efinet.c | 163 +++++++++++++++++++++++++++++++++++++
|
||||
include/grub/efi/api.h | 76 +++++++++++++++++
|
||||
2 files changed, 239 insertions(+)
|
||||
|
||||
--- a/grub-core/net/drivers/efi/efinet.c
|
||||
+++ b/grub-core/net/drivers/efi/efinet.c
|
||||
@@ -30,6 +30,8 @@
|
||||
/* GUID. */
|
||||
static grub_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID;
|
||||
static grub_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID;
|
||||
+static grub_guid_t ip4_config_guid = GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID;
|
||||
+static grub_guid_t ip6_config_guid = GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID;
|
||||
|
||||
static grub_err_t
|
||||
send_card_buffer (struct grub_net_card *dev,
|
||||
@@ -342,6 +344,125 @@
|
||||
grub_free (handles);
|
||||
}
|
||||
|
||||
+static grub_efi_handle_t
|
||||
+grub_efi_locate_device_path (grub_efi_guid_t *protocol, grub_efi_device_path_t *device_path,
|
||||
+ grub_efi_device_path_t **r_device_path)
|
||||
+{
|
||||
+ grub_efi_handle_t handle;
|
||||
+ grub_efi_status_t status;
|
||||
+
|
||||
+ status = grub_efi_system_table->boot_services->locate_device_path (
|
||||
+ protocol, &device_path, &handle);
|
||||
+
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ return 0;
|
||||
+
|
||||
+ if (r_device_path)
|
||||
+ *r_device_path = device_path;
|
||||
+
|
||||
+ return handle;
|
||||
+}
|
||||
+
|
||||
+static grub_efi_ipv4_address_t *
|
||||
+grub_dns_server_ip4_address (grub_efi_device_path_t *dp, grub_efi_uintn_t *num_dns)
|
||||
+{
|
||||
+ grub_efi_handle_t hnd;
|
||||
+ grub_efi_status_t status;
|
||||
+ grub_efi_ip4_config2_protocol_t *conf;
|
||||
+ grub_efi_ipv4_address_t *addrs;
|
||||
+ grub_efi_uintn_t data_size = 1 * sizeof (grub_efi_ipv4_address_t);
|
||||
+
|
||||
+ hnd = grub_efi_locate_device_path (&ip4_config_guid, dp, NULL);
|
||||
+
|
||||
+ if (!hnd)
|
||||
+ return 0;
|
||||
+
|
||||
+ conf = grub_efi_open_protocol (hnd, &ip4_config_guid,
|
||||
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
+
|
||||
+ if (!conf)
|
||||
+ return 0;
|
||||
+
|
||||
+ addrs = grub_malloc (data_size);
|
||||
+ if (!addrs)
|
||||
+ return 0;
|
||||
+
|
||||
+ status = conf->get_data (conf,
|
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER,
|
||||
+ &data_size, addrs);
|
||||
+
|
||||
+ if (status == GRUB_EFI_BUFFER_TOO_SMALL)
|
||||
+ {
|
||||
+ grub_free (addrs);
|
||||
+ addrs = grub_malloc (data_size);
|
||||
+ if (!addrs)
|
||||
+ return 0;
|
||||
+
|
||||
+ status = conf->get_data (conf,
|
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER,
|
||||
+ &data_size, addrs);
|
||||
+ }
|
||||
+
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ {
|
||||
+ grub_free (addrs);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ *num_dns = data_size / sizeof (grub_efi_ipv4_address_t);
|
||||
+ return addrs;
|
||||
+}
|
||||
+
|
||||
+static grub_efi_ipv6_address_t *
|
||||
+grub_dns_server_ip6_address (grub_efi_device_path_t *dp, grub_efi_uintn_t *num_dns)
|
||||
+{
|
||||
+ grub_efi_handle_t hnd;
|
||||
+ grub_efi_status_t status;
|
||||
+ grub_efi_ip6_config_protocol_t *conf;
|
||||
+ grub_efi_ipv6_address_t *addrs;
|
||||
+ grub_efi_uintn_t data_size = 1 * sizeof (grub_efi_ipv6_address_t);
|
||||
+
|
||||
+ hnd = grub_efi_locate_device_path (&ip6_config_guid, dp, NULL);
|
||||
+
|
||||
+ if (!hnd)
|
||||
+ return 0;
|
||||
+
|
||||
+ conf = grub_efi_open_protocol (hnd, &ip6_config_guid,
|
||||
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||
+
|
||||
+ if (!conf)
|
||||
+ return 0;
|
||||
+
|
||||
+ addrs = grub_malloc (data_size);
|
||||
+ if (!addrs)
|
||||
+ return 0;
|
||||
+
|
||||
+ status = conf->get_data (conf,
|
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER,
|
||||
+ &data_size, addrs);
|
||||
+
|
||||
+ if (status == GRUB_EFI_BUFFER_TOO_SMALL)
|
||||
+ {
|
||||
+ grub_free (addrs);
|
||||
+ addrs = grub_malloc (data_size);
|
||||
+ if (!addrs)
|
||||
+ return 0;
|
||||
+
|
||||
+ status = conf->get_data (conf,
|
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER,
|
||||
+ &data_size, addrs);
|
||||
+ }
|
||||
+
|
||||
+ if (status != GRUB_EFI_SUCCESS)
|
||||
+ {
|
||||
+ grub_free (addrs);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ *num_dns = data_size / sizeof (grub_efi_ipv6_address_t);
|
||||
+ return addrs;
|
||||
+}
|
||||
+
|
||||
static struct grub_net_buff *
|
||||
grub_efinet_create_dhcp_ack_from_device_path (grub_efi_device_path_t *dp, int *use_ipv6)
|
||||
{
|
||||
@@ -394,6 +515,8 @@
|
||||
grub_efi_ipv4_device_path_t *ipv4 = (grub_efi_ipv4_device_path_t *) ldp;
|
||||
struct grub_net_bootp_packet *bp;
|
||||
grub_uint8_t *ptr;
|
||||
+ grub_efi_ipv4_address_t *dns;
|
||||
+ grub_efi_uintn_t num_dns;
|
||||
|
||||
bp = (struct grub_net_bootp_packet *) nb->tail;
|
||||
err = grub_netbuff_put (nb, sizeof (*bp) + 4);
|
||||
@@ -455,6 +578,25 @@
|
||||
*ptr++ = sizeof ("HTTPClient") - 1;
|
||||
grub_memcpy (ptr, "HTTPClient", sizeof ("HTTPClient") - 1);
|
||||
|
||||
+ dns = grub_dns_server_ip4_address (dp, &num_dns);
|
||||
+ if (dns)
|
||||
+ {
|
||||
+ grub_efi_uintn_t size_dns = sizeof (*dns) * num_dns;
|
||||
+
|
||||
+ ptr = nb->tail;
|
||||
+ err = grub_netbuff_put (nb, size_dns + 2);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ *ptr++ = GRUB_NET_BOOTP_DNS;
|
||||
+ *ptr++ = size_dns;
|
||||
+ grub_memcpy (ptr, dns, size_dns);
|
||||
+ grub_free (dns);
|
||||
+ }
|
||||
+
|
||||
ptr = nb->tail;
|
||||
err = grub_netbuff_put (nb, 1);
|
||||
if (err)
|
||||
@@ -487,6 +629,8 @@
|
||||
struct grub_net_dhcp6_option *opt;
|
||||
struct grub_net_dhcp6_option_iana *iana;
|
||||
struct grub_net_dhcp6_option_iaaddr *iaaddr;
|
||||
+ grub_efi_ipv6_address_t *dns;
|
||||
+ grub_efi_uintn_t num_dns;
|
||||
|
||||
d6p = (struct grub_net_dhcp6_packet *)nb->tail;
|
||||
err = grub_netbuff_put (nb, sizeof(*d6p));
|
||||
@@ -550,6 +694,25 @@
|
||||
opt->len = grub_cpu_to_be16 (uri_len);
|
||||
grub_memcpy (opt->data, uri_dp->uri, uri_len);
|
||||
|
||||
+ dns = grub_dns_server_ip6_address (dp, &num_dns);
|
||||
+ if (dns)
|
||||
+ {
|
||||
+ grub_efi_uintn_t size_dns = sizeof (*dns) * num_dns;
|
||||
+
|
||||
+ opt = (struct grub_net_dhcp6_option *)nb->tail;
|
||||
+ err = grub_netbuff_put (nb, sizeof(*opt) + size_dns);
|
||||
+ if (err)
|
||||
+ {
|
||||
+ grub_free (ddp);
|
||||
+ grub_netbuff_free (nb);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ opt->code = grub_cpu_to_be16_compile_time (GRUB_NET_DHCP6_OPTION_DNS_SERVERS);
|
||||
+ opt->len = grub_cpu_to_be16 (size_dns);
|
||||
+ grub_memcpy (opt->data, dns, size_dns);
|
||||
+ grub_free (dns);
|
||||
+ }
|
||||
+
|
||||
*use_ipv6 = 1;
|
||||
}
|
||||
|
||||
--- a/include/grub/efi/api.h
|
||||
+++ b/include/grub/efi/api.h
|
||||
@@ -379,6 +379,16 @@
|
||||
{0xb6, 0xc7, 0x44, 0x0b, 0x29, 0xbb, 0x8c, 0x4f } \
|
||||
}
|
||||
|
||||
+#define GRUB_EFI_IP4_CONFIG2_PROTOCOL_GUID \
|
||||
+ { 0x5b446ed1, 0xe30b, 0x4faa, \
|
||||
+ { 0x87, 0x1a, 0x36, 0x54, 0xec, 0xa3, 0x60, 0x80 } \
|
||||
+ }
|
||||
+
|
||||
+#define GRUB_EFI_IP6_CONFIG_PROTOCOL_GUID \
|
||||
+ { 0x937fe521, 0x95ae, 0x4d1a, \
|
||||
+ { 0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \
|
||||
+ }
|
||||
+
|
||||
struct grub_efi_sal_system_table
|
||||
{
|
||||
grub_uint32_t signature;
|
||||
@@ -1879,4 +1889,70 @@
|
||||
} GRUB_PACKED;
|
||||
typedef struct initrd_media_device_path initrd_media_device_path_t;
|
||||
|
||||
+enum grub_efi_ip4_config2_data_type {
|
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_INTERFACEINFO,
|
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_POLICY,
|
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MANUAL_ADDRESS,
|
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_GATEWAY,
|
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_DNSSERVER,
|
||||
+ GRUB_EFI_IP4_CONFIG2_DATA_TYPE_MAXIMUM
|
||||
+};
|
||||
+typedef enum grub_efi_ip4_config2_data_type grub_efi_ip4_config2_data_type_t;
|
||||
+
|
||||
+struct grub_efi_ip4_config2_protocol
|
||||
+{
|
||||
+ grub_efi_status_t (__grub_efi_api *set_data) (struct grub_efi_ip4_config2_protocol *this,
|
||||
+ grub_efi_ip4_config2_data_type_t data_type,
|
||||
+ grub_efi_uintn_t data_size,
|
||||
+ void *data);
|
||||
+
|
||||
+ grub_efi_status_t (__grub_efi_api *get_data) (struct grub_efi_ip4_config2_protocol *this,
|
||||
+ grub_efi_ip4_config2_data_type_t data_type,
|
||||
+ grub_efi_uintn_t *data_size,
|
||||
+ void *data);
|
||||
+
|
||||
+ grub_efi_status_t (__grub_efi_api *register_data_notify) (struct grub_efi_ip4_config2_protocol *this,
|
||||
+ grub_efi_ip4_config2_data_type_t data_type,
|
||||
+ grub_efi_event_t event);
|
||||
+
|
||||
+ grub_efi_status_t (__grub_efi_api *unregister_datanotify) (struct grub_efi_ip4_config2_protocol *this,
|
||||
+ grub_efi_ip4_config2_data_type_t data_type,
|
||||
+ grub_efi_event_t event);
|
||||
+};
|
||||
+typedef struct grub_efi_ip4_config2_protocol grub_efi_ip4_config2_protocol_t;
|
||||
+
|
||||
+enum grub_efi_ip6_config_data_type {
|
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_INTERFACEINFO,
|
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_ALT_INTERFACEID,
|
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_POLICY,
|
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DUP_ADDR_DETECT_TRANSMITS,
|
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_MANUAL_ADDRESS,
|
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_GATEWAY,
|
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_DNSSERVER,
|
||||
+ GRUB_EFI_IP6_CONFIG_DATA_TYPE_MAXIMUM
|
||||
+};
|
||||
+typedef enum grub_efi_ip6_config_data_type grub_efi_ip6_config_data_type_t;
|
||||
+
|
||||
+struct grub_efi_ip6_config_protocol
|
||||
+{
|
||||
+ grub_efi_status_t (__grub_efi_api *set_data) (struct grub_efi_ip6_config_protocol *this,
|
||||
+ grub_efi_ip6_config_data_type_t data_type,
|
||||
+ grub_efi_uintn_t data_size,
|
||||
+ void *data);
|
||||
+
|
||||
+ grub_efi_status_t (__grub_efi_api *get_data) (struct grub_efi_ip6_config_protocol *this,
|
||||
+ grub_efi_ip6_config_data_type_t data_type,
|
||||
+ grub_efi_uintn_t *data_size,
|
||||
+ void *data);
|
||||
+
|
||||
+ grub_efi_status_t (__grub_efi_api *register_data_notify) (struct grub_efi_ip6_config_protocol *this,
|
||||
+ grub_efi_ip6_config_data_type_t data_type,
|
||||
+ grub_efi_event_t event);
|
||||
+
|
||||
+ grub_efi_status_t (__grub_efi_api *unregister_datanotify) (struct grub_efi_ip6_config_protocol *this,
|
||||
+ grub_efi_ip6_config_data_type_t data_type,
|
||||
+ grub_efi_event_t event);
|
||||
+};
|
||||
+typedef struct grub_efi_ip6_config_protocol grub_efi_ip6_config_protocol_t;
|
||||
+
|
||||
#endif /* ! GRUB_EFI_API_HEADER */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user