Sync from SUSE:SLFO:Main grub2 revision 1dac218436a6d596013e239f4ee7d9e4
This commit is contained in:
commit
5a5e453693
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
|
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 fe7ed9104cef56f9e532a0c9a7164393d5d69ae1 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Fri, 17 Nov 2023 12:32:59 +0800
|
||||
Subject: [PATCH 1/4] 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 c79d4125a..d90ca06dc 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.42.1
|
||||
|
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:
|
||||
@@ -1454,8 +1493,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");
|
||||
@@ -1669,21 +1707,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)
|
||||
{
|
||||
@@ -1708,11 +1738,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
|
||||
|
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,35 @@
|
||||
From 652b221a5eacb1421891c1469608028e2c2f0615 Mon Sep 17 00:00:00 2001
|
||||
From: Glenn Washburn <development@efficientek.com>
|
||||
Date: Fri, 18 Aug 2023 12:27:22 -0500
|
||||
Subject: [PATCH] disk/cryptodisk: Fix missing change when updating to use
|
||||
grub_uuidcasecmp
|
||||
|
||||
This was causing the cryptomount command to return failure even though
|
||||
the crypto device was successfully added. Of course, this meant that any
|
||||
script using the return code would behave unexpectedly.
|
||||
|
||||
Fixes: 3cf2e848bc03 (disk/cryptodisk: Allows UUIDs to be compared in a dash-insensitive manner)
|
||||
|
||||
Suggested-by: Olaf Hering <olaf@aepfle.de>
|
||||
Signed-off-by: Glenn Washburn <development@efficientek.com>
|
||||
---
|
||||
grub-core/disk/cryptodisk.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/disk/cryptodisk.c b/grub-core/disk/cryptodisk.c
|
||||
index 802b191b2..c79d4125a 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1323,7 +1323,8 @@ grub_cryptodisk_scan_device (const char *name,
|
||||
dev = grub_cryptodisk_scan_device_real (name, source, cargs);
|
||||
if (dev)
|
||||
{
|
||||
- ret = (cargs->search_uuid != NULL && grub_strcasecmp (cargs->search_uuid, dev->uuid) == 0);
|
||||
+ ret = (cargs->search_uuid != NULL
|
||||
+ && grub_uuidcasecmp (cargs->search_uuid, dev->uuid, sizeof (dev->uuid)) == 0);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
--
|
||||
2.41.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
|
||||
|
33
0001-fs-btrfs-Zero-file-data-not-backed-by-extents.patch
Normal file
33
0001-fs-btrfs-Zero-file-data-not-backed-by-extents.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From f903b9a9adb64e733e581771d2a24efae7fbe529 Mon Sep 17 00:00:00 2001
|
||||
From: Fabian Vogt <fvogt@suse.de>
|
||||
Date: Thu, 5 Oct 2023 11:02:25 +0200
|
||||
Subject: [PATCH] fs/btrfs: Zero file data not backed by extents
|
||||
|
||||
Implicit holes in file data need to be zeroed explicitly, instead of
|
||||
just leaving the data in the buffer uninitialized.
|
||||
|
||||
This led to kernels randomly failing to boot in "fun" ways when loaded
|
||||
from btrfs with the no_holes feature enabled, because large blocks of
|
||||
zeros in the kernel file contained random data instead.
|
||||
|
||||
Signed-off-by: Fabian Vogt <fvogt@suse.de>
|
||||
---
|
||||
grub-core/fs/btrfs.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
|
||||
index 19bff4610..ba0c58352 100644
|
||||
--- a/grub-core/fs/btrfs.c
|
||||
+++ b/grub-core/fs/btrfs.c
|
||||
@@ -1603,6 +1603,8 @@ grub_btrfs_extent_read (struct grub_btrfs_data *data,
|
||||
csize = grub_le_to_cpu64 (key_out.offset) - pos;
|
||||
if (csize > len)
|
||||
csize = len;
|
||||
+
|
||||
+ grub_memset (buf, 0, csize);
|
||||
buf += csize;
|
||||
pos += csize;
|
||||
len -= csize;
|
||||
--
|
||||
2.42.0
|
||||
|
@ -0,0 +1,93 @@
|
||||
From 43651027d24e62a7a463254165e1e46e42aecdea Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Mon, 28 Aug 2023 16:31:57 +0300
|
||||
Subject: [PATCH 1/6] fs/ntfs: Fix an OOB write when parsing the
|
||||
$ATTRIBUTE_LIST attribute for the $MFT file
|
||||
|
||||
When parsing an extremely fragmented $MFT file, i.e., the file described
|
||||
using the $ATTRIBUTE_LIST attribute, current NTFS code will reuse a buffer
|
||||
containing bytes read from the underlying drive to store sector numbers,
|
||||
which are consumed later to read data from these sectors into another buffer.
|
||||
|
||||
These sectors numbers, two 32-bit integers, are always stored at predefined
|
||||
offsets, 0x10 and 0x14, relative to first byte of the selected entry within
|
||||
the $ATTRIBUTE_LIST attribute. Usually, this won't cause any problem.
|
||||
|
||||
However, when parsing a specially-crafted file system image, this may cause
|
||||
the NTFS code to write these integers beyond the buffer boundary, likely
|
||||
causing the GRUB memory allocator to misbehave or fail. These integers contain
|
||||
values which are controlled by on-disk structures of the NTFS file system.
|
||||
|
||||
Such modification and resulting misbehavior may touch a memory range not
|
||||
assigned to the GRUB and owned by firmware or another EFI application/driver.
|
||||
|
||||
This fix introduces checks to ensure that these sector numbers are never
|
||||
written beyond the boundary.
|
||||
|
||||
Fixes: CVE-2023-4692
|
||||
|
||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/ntfs.c | 18 +++++++++++++++++-
|
||||
1 file changed, 17 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
||||
index bbdbe24ad..c3c4db117 100644
|
||||
--- a/grub-core/fs/ntfs.c
|
||||
+++ b/grub-core/fs/ntfs.c
|
||||
@@ -184,7 +184,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
||||
}
|
||||
if (at->attr_end)
|
||||
{
|
||||
- grub_uint8_t *pa;
|
||||
+ grub_uint8_t *pa, *pa_end;
|
||||
|
||||
at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
||||
if (at->emft_buf == NULL)
|
||||
@@ -209,11 +209,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
||||
}
|
||||
at->attr_nxt = at->edat_buf;
|
||||
at->attr_end = at->edat_buf + u32at (pa, 0x30);
|
||||
+ pa_end = at->edat_buf + n;
|
||||
}
|
||||
else
|
||||
{
|
||||
at->attr_nxt = at->attr_end + u16at (pa, 0x14);
|
||||
at->attr_end = at->attr_end + u32at (pa, 4);
|
||||
+ pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
|
||||
}
|
||||
at->flags |= GRUB_NTFS_AF_ALST;
|
||||
while (at->attr_nxt < at->attr_end)
|
||||
@@ -230,6 +232,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
||||
at->flags |= GRUB_NTFS_AF_GPOS;
|
||||
at->attr_cur = at->attr_nxt;
|
||||
pa = at->attr_cur;
|
||||
+
|
||||
+ if ((pa >= pa_end) || (pa_end - pa < 0x18))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
grub_set_unaligned32 ((char *) pa + 0x10,
|
||||
grub_cpu_to_le32 (at->mft->data->mft_start));
|
||||
grub_set_unaligned32 ((char *) pa + 0x14,
|
||||
@@ -240,6 +249,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
|
||||
{
|
||||
if (*pa != attr)
|
||||
break;
|
||||
+
|
||||
+ if ((pa >= pa_end) || (pa_end - pa < 0x18))
|
||||
+ {
|
||||
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list");
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
if (read_attr
|
||||
(at, pa + 0x10,
|
||||
u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),
|
||||
--
|
||||
2.42.0
|
||||
|
@ -0,0 +1,51 @@
|
||||
From b541e93b4dab6f652941d086af4fe2da676d0ee3 Mon Sep 17 00:00:00 2001
|
||||
From: Lidong Chen <lidong.chen@oracle.com>
|
||||
Date: Thu, 28 Sep 2023 22:33:44 +0000
|
||||
Subject: [PATCH 1/3] fs/xfs: Incorrect short form directory data boundary
|
||||
check
|
||||
|
||||
After parsing of the current entry, the entry pointer is advanced
|
||||
to the next entry at the end of the "for" loop. In case where the
|
||||
last entry is at the end of the data boundary, the advanced entry
|
||||
pointer can point off the data boundary. The subsequent boundary
|
||||
check for the advanced entry pointer can cause a failure.
|
||||
|
||||
The fix is to include the boundary check into the "for" loop
|
||||
condition.
|
||||
|
||||
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
|
||||
Tested-by: Marta Lewandowska <mlewando@redhat.com>
|
||||
---
|
||||
grub-core/fs/xfs.c | 7 ++-----
|
||||
1 file changed, 2 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index b91cd32b4..ebf962793 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -810,7 +810,8 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
if (iterate_dir_call_hook (parent, "..", &ctx))
|
||||
return 1;
|
||||
|
||||
- for (i = 0; i < head->count; i++)
|
||||
+ for (i = 0; i < head->count &&
|
||||
+ (grub_uint8_t *) de < ((grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data)); i++)
|
||||
{
|
||||
grub_uint64_t ino;
|
||||
grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de);
|
||||
@@ -845,10 +846,6 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
de->name[de->len] = c;
|
||||
|
||||
de = grub_xfs_inline_next_de(dir->data, head, de);
|
||||
-
|
||||
- if ((grub_uint8_t *) de >= (grub_uint8_t *) dir + grub_xfs_fshelp_size (dir->data))
|
||||
- return grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
|
||||
-
|
||||
}
|
||||
break;
|
||||
}
|
||||
--
|
||||
2.42.1
|
||||
|
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:
|
163
0001-grub-install-bailout-root-device-probing.patch
Normal file
163
0001-grub-install-bailout-root-device-probing.patch
Normal file
@ -0,0 +1,163 @@
|
||||
From 58dcf7985b20de876a6fc44a591aa377d0a0302c 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.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
---
|
||||
grub-core/osdep/basic/no_platform.c | 5 +++++
|
||||
grub-core/osdep/unix/platform.c | 34 +++++++++++++++++++++++++++++
|
||||
grub-core/osdep/windows/platform.c | 6 +++++
|
||||
include/grub/util/install.h | 3 +++
|
||||
util/grub-install.c | 31 ++++++++++++++++++--------
|
||||
5 files changed, 70 insertions(+), 9 deletions(-)
|
||||
|
||||
--- a/grub-core/osdep/basic/no_platform.c
|
||||
+++ b/grub-core/osdep/basic/no_platform.c
|
||||
@@ -51,3 +51,8 @@
|
||||
grub_util_error ("%s", _("no zIPL routines are available for your platform"));
|
||||
}
|
||||
|
||||
+char *
|
||||
+grub_install_get_filesystem (const char *path)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
--- a/grub-core/osdep/unix/platform.c
|
||||
+++ b/grub-core/osdep/unix/platform.c
|
||||
@@ -250,3 +250,37 @@
|
||||
"-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;
|
||||
+}
|
||||
--- a/grub-core/osdep/windows/platform.c
|
||||
+++ b/grub-core/osdep/windows/platform.c
|
||||
@@ -440,3 +440,9 @@
|
||||
{
|
||||
grub_util_error ("%s", _("no zIPL routines are available for your platform"));
|
||||
}
|
||||
+
|
||||
+char *
|
||||
+grub_install_get_filesystem (const char *path)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
--- a/include/grub/util/install.h
|
||||
+++ b/include/grub/util/install.h
|
||||
@@ -251,6 +251,9 @@
|
||||
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
|
||||
--- a/util/grub-install.c
|
||||
+++ b/util/grub-install.c
|
||||
@@ -887,7 +887,6 @@
|
||||
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;
|
||||
@@ -1067,8 +1066,10 @@
|
||||
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);
|
||||
|
||||
rootdir_path = grub_canonicalize_file_name (t);
|
||||
@@ -1089,20 +1090,32 @@
|
||||
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);
|
||||
}
|
||||
|
||||
switch (platform)
|
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));
|
229
0001-kern-ieee1275-init-Restrict-high-memory-in-presence-.patch
Normal file
229
0001-kern-ieee1275-init-Restrict-high-memory-in-presence-.patch
Normal file
@ -0,0 +1,229 @@
|
||||
From 4bcf6f747c3ab0b998c6f5a361804e38bc9c4334 Mon Sep 17 00:00:00 2001
|
||||
From: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Date: Wed, 4 Oct 2023 11:32:35 -0400
|
||||
Subject: [PATCH] kern/ieee1275/init: Restrict high memory in presence of
|
||||
fadump on ppc64
|
||||
|
||||
When a kernel dump is present then restrict the high memory regions to
|
||||
avoid allocating memory where the kernel dump resides. Use the
|
||||
ibm,kernel-dump node under /rtas to determine whether a kernel dump
|
||||
exists and up to which limit GRUB can use available memory. Set the
|
||||
upper_mem_limit to the size of the kernel dump section of type
|
||||
REAL_MODE_REGION and therefore only allow GRUB's memory usage for high
|
||||
addresses from RMO_ADDR_MAX to upper_mem_limit. This means that GRUB can
|
||||
use high memory in the range of RMO_ADDR_MAX (768MB) to upper_mem_limit
|
||||
and the kernel-dump memory regions above upper_mem_limit remain
|
||||
untouched. This change has no effect on memory allocations below
|
||||
linux_rmo_save (typically at 640MB).
|
||||
|
||||
Also, fall back to allocating below rmo_linux_save in case the chunk of
|
||||
memory there would be larger than the chunk of memory above RMO_ADDR_MAX.
|
||||
This can for example occur if a free memory area is found starting at 300MB
|
||||
extending up to 1GB but a kernel dump is located at 768MB and therefore
|
||||
does not allow the allocation of the high memory area but requiring to use
|
||||
the chunk starting at 300MB to avoid an unnecessary out-of-memory condition.
|
||||
|
||||
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||||
Reviewed-by: Hari Bathini <hbathini@linux.ibm.com>
|
||||
Cc: Pavithra Prakash <pavrampu@in.ibm.com>
|
||||
Cc: Michael Ellerman <mpe@ellerman.id.au>
|
||||
Cc: Carolyn Scherrer <cpscherr@us.ibm.com>
|
||||
Cc: Mahesh Salgaonkar <mahesh@linux.ibm.com>
|
||||
Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/kern/ieee1275/init.c | 144 ++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 142 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
|
||||
index bd9a4804b..d6c9c9049 100644
|
||||
--- a/grub-core/kern/ieee1275/init.c
|
||||
+++ b/grub-core/kern/ieee1275/init.c
|
||||
@@ -17,6 +17,8 @@
|
||||
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
+#include <stddef.h> /* offsetof() */
|
||||
+
|
||||
#include <grub/kernel.h>
|
||||
#include <grub/dl.h>
|
||||
#include <grub/disk.h>
|
||||
@@ -196,6 +198,96 @@ grub_claim_heap (void)
|
||||
#else
|
||||
/* Helpers for mm on powerpc. */
|
||||
|
||||
+/* ibm,kernel-dump data structures */
|
||||
+struct kd_section
|
||||
+{
|
||||
+ grub_uint32_t flags;
|
||||
+ grub_uint16_t src_datatype;
|
||||
+#define KD_SRC_DATATYPE_REAL_MODE_REGION 0x0011
|
||||
+ grub_uint16_t error_flags;
|
||||
+ grub_uint64_t src_address;
|
||||
+ grub_uint64_t num_bytes;
|
||||
+ grub_uint64_t act_bytes;
|
||||
+ grub_uint64_t dst_address;
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+#define MAX_KD_SECTIONS 10
|
||||
+
|
||||
+struct kernel_dump
|
||||
+{
|
||||
+ grub_uint32_t format;
|
||||
+ grub_uint16_t num_sections;
|
||||
+ grub_uint16_t status_flags;
|
||||
+ grub_uint32_t offset_1st_section;
|
||||
+ grub_uint32_t num_blocks;
|
||||
+ grub_uint64_t start_block;
|
||||
+ grub_uint64_t num_blocks_avail;
|
||||
+ grub_uint32_t offet_path_string;
|
||||
+ grub_uint32_t max_time_allowed;
|
||||
+ struct kd_section kds[MAX_KD_SECTIONS]; /* offset_1st_section should point to kds[0] */
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
+/*
|
||||
+ * Determine if a kernel dump exists and if it does, then determine the highest
|
||||
+ * address that grub can use for memory allocations.
|
||||
+ * The caller must have initialized *highest to rmo_top. *highest will not
|
||||
+ * be modified if no kernel dump is found.
|
||||
+ */
|
||||
+static void
|
||||
+check_kernel_dump (grub_uint64_t *highest)
|
||||
+{
|
||||
+ struct kernel_dump kernel_dump;
|
||||
+ grub_ssize_t kernel_dump_size;
|
||||
+ grub_ieee1275_phandle_t rtas;
|
||||
+ struct kd_section *kds;
|
||||
+ grub_size_t i;
|
||||
+
|
||||
+ /* If there's a kernel-dump it must have at least one section */
|
||||
+ if (grub_ieee1275_finddevice ("/rtas", &rtas) ||
|
||||
+ grub_ieee1275_get_property (rtas, "ibm,kernel-dump", &kernel_dump,
|
||||
+ sizeof (kernel_dump), &kernel_dump_size) ||
|
||||
+ kernel_dump_size <= (grub_ssize_t) offsetof (struct kernel_dump, kds[1]))
|
||||
+ return;
|
||||
+
|
||||
+ kernel_dump_size = grub_min (kernel_dump_size, (grub_ssize_t) sizeof (kernel_dump));
|
||||
+
|
||||
+ if (grub_be_to_cpu32 (kernel_dump.format) != 1)
|
||||
+ {
|
||||
+ grub_printf (_("Error: ibm,kernel-dump has an unexpected format version '%u'\n"),
|
||||
+ grub_be_to_cpu32 (kernel_dump.format));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (grub_be_to_cpu16 (kernel_dump.num_sections) > MAX_KD_SECTIONS)
|
||||
+ {
|
||||
+ grub_printf (_("Error: Too many kernel dump sections: %d\n"),
|
||||
+ grub_be_to_cpu32 (kernel_dump.num_sections));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < grub_be_to_cpu16 (kernel_dump.num_sections); i++)
|
||||
+ {
|
||||
+ kds = (struct kd_section *) ((grub_addr_t) &kernel_dump +
|
||||
+ grub_be_to_cpu32 (kernel_dump.offset_1st_section) +
|
||||
+ i * sizeof (struct kd_section));
|
||||
+ /* sanity check the address is within the 'kernel_dump' struct */
|
||||
+ if ((grub_addr_t) kds > (grub_addr_t) &kernel_dump + kernel_dump_size + sizeof (*kds))
|
||||
+ {
|
||||
+ grub_printf (_("Error: 'kds' address beyond last available section\n"));
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if ((grub_be_to_cpu16 (kds->src_datatype) == KD_SRC_DATATYPE_REAL_MODE_REGION) &&
|
||||
+ (grub_be_to_cpu64 (kds->src_address) == 0))
|
||||
+ {
|
||||
+ *highest = grub_min (*highest, grub_be_to_cpu64 (kds->num_bytes));
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* How much memory does OF believe exists in total?
|
||||
*
|
||||
@@ -275,10 +367,31 @@ regions_claim (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
|
||||
*
|
||||
* Finally, we also want to make sure that when grub loads the kernel,
|
||||
* it isn't going to use up all the memory we're trying to reserve! So
|
||||
- * enforce our entire RUNTIME_MIN_SPACE here:
|
||||
+ * enforce our entire RUNTIME_MIN_SPACE here (no fadump):
|
||||
+ *
|
||||
+ * | Top of memory == upper_mem_limit -|
|
||||
+ * | |
|
||||
+ * | available |
|
||||
+ * | |
|
||||
+ * |---------- 768 MB ----------|
|
||||
+ * | |
|
||||
+ * | reserved |
|
||||
+ * | |
|
||||
+ * |--- 768 MB - runtime min space ---|
|
||||
+ * | |
|
||||
+ * | available |
|
||||
+ * | |
|
||||
+ * |---------- 0 MB ----------|
|
||||
+ *
|
||||
+ * In case fadump is used, we allow the following:
|
||||
*
|
||||
* |---------- Top of memory ----------|
|
||||
* | |
|
||||
+ * | unavailable |
|
||||
+ * | (kernel dump area) |
|
||||
+ * | |
|
||||
+ * |--------- upper_mem_limit ---------|
|
||||
+ * | |
|
||||
* | available |
|
||||
* | |
|
||||
* |---------- 768 MB ----------|
|
||||
@@ -333,17 +446,44 @@ regions_claim (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
|
||||
}
|
||||
else
|
||||
{
|
||||
+ grub_uint64_t upper_mem_limit = rmo_top;
|
||||
+ grub_uint64_t orig_addr = addr;
|
||||
+
|
||||
+ check_kernel_dump (&upper_mem_limit);
|
||||
+
|
||||
/*
|
||||
* we order these cases to prefer higher addresses and avoid some
|
||||
* splitting issues
|
||||
+ * The following shows the order of variables:
|
||||
+ * no kernel dump: linux_rmo_save < RMO_ADDR_MAX <= upper_mem_limit == rmo_top
|
||||
+ * with kernel dump: liuxx_rmo_save < RMO_ADDR_MAX <= upper_mem_limit <= rmo_top
|
||||
*/
|
||||
- if (addr < RMO_ADDR_MAX && (addr + len) > RMO_ADDR_MAX)
|
||||
+ if (addr < RMO_ADDR_MAX && (addr + len) > RMO_ADDR_MAX && upper_mem_limit >= RMO_ADDR_MAX)
|
||||
{
|
||||
grub_dprintf ("ieee1275",
|
||||
"adjusting region for RUNTIME_MIN_SPACE: (%llx -> %llx) -> (%llx -> %llx)\n",
|
||||
addr, addr + len, RMO_ADDR_MAX, addr + len);
|
||||
len = (addr + len) - RMO_ADDR_MAX;
|
||||
addr = RMO_ADDR_MAX;
|
||||
+
|
||||
+ /* We must not exceed the upper_mem_limit (assuming it's >= RMO_ADDR_MAX) */
|
||||
+ if (addr + len > upper_mem_limit)
|
||||
+ {
|
||||
+ /* take the bigger chunk from either below linux_rmo_save or above upper_mem_limit */
|
||||
+ len = upper_mem_limit - addr;
|
||||
+ if (orig_addr < linux_rmo_save && linux_rmo_save - orig_addr > len)
|
||||
+ {
|
||||
+ /* lower part is bigger */
|
||||
+ addr = orig_addr;
|
||||
+ len = linux_rmo_save - addr;
|
||||
+ }
|
||||
+
|
||||
+ grub_dprintf ("ieee1275", "re-adjusted region to: (%llx -> %llx)\n",
|
||||
+ addr, addr + len);
|
||||
+
|
||||
+ if (len == 0)
|
||||
+ return 0;
|
||||
+ }
|
||||
}
|
||||
else if ((addr < linux_rmo_save) && ((addr + len) > linux_rmo_save))
|
||||
{
|
||||
--
|
||||
2.42.0
|
||||
|
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__);
|
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,76 @@
|
||||
From 1fdc9daf97a1518960e5603dd43a5f353cb3ca89 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 30 Nov 2023 13:45:13 +0800
|
||||
Subject: [PATCH 1/2] mkstandalone: ensure stable timestamps for generated
|
||||
images
|
||||
|
||||
This change mirrors a previous fix [1] but is specific to images
|
||||
generated by grub-mkstandalone.
|
||||
|
||||
The former fix (85a7be241) focused on utilizing a stable timestamp
|
||||
during binary generation in the util/mkimage context. This commit
|
||||
extends that approach to the images produced by grub-mkstandalone,
|
||||
ensuring consistency and stability in timestamps across all generated
|
||||
binaries.
|
||||
|
||||
[1] 85a7be241 util/mkimage: Use stable timestamp when generating
|
||||
binaries.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Signed-off-by: Bernhard Wiedemann <bwiedemann@suse.com>
|
||||
---
|
||||
util/grub-mkstandalone.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/util/grub-mkstandalone.c b/util/grub-mkstandalone.c
|
||||
index bdbeea6a6..8e1229925 100644
|
||||
--- a/util/grub-mkstandalone.c
|
||||
+++ b/util/grub-mkstandalone.c
|
||||
@@ -30,6 +30,9 @@
|
||||
#pragma GCC diagnostic error "-Wmissing-prototypes"
|
||||
#pragma GCC diagnostic error "-Wmissing-declarations"
|
||||
|
||||
+/* use 2015-01-01T00:00:00+0000 as a stock timestamp */
|
||||
+#define STABLE_EMBEDDING_TIMESTAMP 1420070400
|
||||
+
|
||||
static char *output_image;
|
||||
static char **files;
|
||||
static int nfiles;
|
||||
@@ -184,7 +187,6 @@ add_tar_file (const char *from,
|
||||
struct head hd;
|
||||
grub_util_fd_t in;
|
||||
ssize_t r;
|
||||
- grub_uint32_t mtime = 0;
|
||||
grub_uint32_t size;
|
||||
|
||||
COMPILE_TIME_ASSERT (sizeof (hd) == 512);
|
||||
@@ -192,8 +194,6 @@ add_tar_file (const char *from,
|
||||
if (grub_util_is_special_file (from))
|
||||
return;
|
||||
|
||||
- mtime = grub_util_get_mtime (from);
|
||||
-
|
||||
optr = tcn = xmalloc (strlen (to) + 1);
|
||||
for (iptr = to; *iptr == '/'; iptr++);
|
||||
for (; *iptr; iptr++)
|
||||
@@ -234,7 +234,7 @@ add_tar_file (const char *from,
|
||||
memcpy (hd.gid, "0001750", 7);
|
||||
|
||||
set_tar_value (hd.size, optr - tcn, 12);
|
||||
- set_tar_value (hd.mtime, mtime, 12);
|
||||
+ set_tar_value (hd.mtime, STABLE_EMBEDDING_TIMESTAMP, 12);
|
||||
hd.typeflag = 'L';
|
||||
memcpy (hd.magic, MAGIC, sizeof (hd.magic));
|
||||
memcpy (hd.uname, "grub", 4);
|
||||
@@ -264,7 +264,7 @@ add_tar_file (const char *from,
|
||||
memcpy (hd.gid, "0001750", 7);
|
||||
|
||||
set_tar_value (hd.size, size, 12);
|
||||
- set_tar_value (hd.mtime, mtime, 12);
|
||||
+ set_tar_value (hd.mtime, STABLE_EMBEDDING_TIMESTAMP, 12);
|
||||
hd.typeflag = '0';
|
||||
memcpy (hd.magic, MAGIC, sizeof (hd.magic));
|
||||
memcpy (hd.uname, "grub", 4);
|
||||
--
|
||||
2.43.0
|
||||
|
@ -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
|
||||
|
177
0001-protectors-Add-key-protectors-framework.patch
Normal file
177
0001-protectors-Add-key-protectors-framework.patch
Normal file
@ -0,0 +1,177 @@
|
||||
From 5affde982dea827580e36ccc658e439397f51ce8 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] protectors: 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.
|
||||
|
||||
Signed-off-by: Hernan Gatta <hegatta@linux.microsoft.com>
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/Makefile.am | 1 +
|
||||
grub-core/Makefile.core.def | 1 +
|
||||
grub-core/kern/protectors.c | 75 +++++++++++++++++++++++++++++++++++++
|
||||
include/grub/protector.h | 48 ++++++++++++++++++++++++
|
||||
4 files changed, 125 insertions(+)
|
||||
create mode 100644 grub-core/kern/protectors.c
|
||||
create mode 100644 include/grub/protector.h
|
||||
|
||||
--- a/grub-core/Makefile.am
|
||||
+++ b/grub-core/Makefile.am
|
||||
@@ -90,6 +90,7 @@
|
||||
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/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
|
||||
--- a/grub-core/Makefile.core.def
|
||||
+++ b/grub-core/Makefile.core.def
|
||||
@@ -149,6 +149,7 @@
|
||||
common = kern/misc.c;
|
||||
common = kern/parser.c;
|
||||
common = kern/partition.c;
|
||||
+ common = kern/protectors.c;
|
||||
common = kern/rescue_parser.c;
|
||||
common = kern/rescue_reader.c;
|
||||
common = kern/term.c;
|
||||
--- /dev/null
|
||||
+++ b/grub-core/kern/protectors.c
|
||||
@@ -0,0 +1,75 @@
|
||||
+/*
|
||||
+ * 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/list.h>
|
||||
+#include <grub/misc.h>
|
||||
+#include <grub/mm.h>
|
||||
+#include <grub/protector.h>
|
||||
+
|
||||
+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);
|
||||
+}
|
||||
--- /dev/null
|
||||
+++ b/include/grub/protector.h
|
||||
@@ -0,0 +1,48 @@
|
||||
+/*
|
||||
+ * 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);
|
||||
+};
|
||||
+
|
||||
+extern struct grub_key_protector *EXPORT_VAR (grub_key_protectors);
|
||||
+
|
||||
+grub_err_t
|
||||
+EXPORT_FUNC (grub_key_protector_register) (struct grub_key_protector *protector);
|
||||
+
|
||||
+grub_err_t
|
||||
+EXPORT_FUNC (grub_key_protector_unregister) (struct grub_key_protector *protector);
|
||||
+
|
||||
+grub_err_t
|
||||
+EXPORT_FUNC (grub_key_protector_recover_key) (const char *protector,
|
||||
+ grub_uint8_t **key,
|
||||
+ grub_size_t *key_size);
|
||||
+
|
||||
+#endif /* ! GRUB_PROTECTOR_HEADER */
|
80
0001-protectors-Implement-NV-index.patch
Normal file
80
0001-protectors-Implement-NV-index.patch
Normal file
@ -0,0 +1,80 @@
|
||||
From c3efb4ecbe91b63c127b92122dad3fa53d4efc69 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] protectors: 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 rsa -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>
|
||||
---
|
||||
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 5274296b7..d3a64187a 100644
|
||||
--- a/grub-core/tpm2/module.c
|
||||
+++ b/grub-core/tpm2/module.c
|
||||
@@ -757,12 +757,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
|
||||
|
@ -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
|
204
0001-tpm2-Add-TPM2-types-structures-and-command-constants.patch
Normal file
204
0001-tpm2-Add-TPM2-types-structures-and-command-constants.patch
Normal file
@ -0,0 +1,204 @@
|
||||
From 5a417f32f1afe0ffca7f5cbff67145a157b1589b Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Tue, 7 Feb 2023 18:31:12 +0800
|
||||
Subject: [PATCH 1/4] tpm2: Add TPM2 types, structures, and command constants
|
||||
|
||||
Add new TPM2 types and structures as the preparation to support
|
||||
authorized policy.
|
||||
|
||||
* New types:
|
||||
TPM_ALG_ECDAA, TPM_ALG_ECDSA, TPM_ALG_ECSCHNORR, TPM_ALG_RSASSA,
|
||||
TPM_ALG_RSAPSS, TPM_ALG_SM2, and TPMI_ALG_SIG_SCHEME
|
||||
|
||||
* New structures:
|
||||
TPMS_EMPTY, TPMS_SIGNATURE_RSA, TPMS_SIGNATURE_ECC,
|
||||
TPMS_SIGNATURE_ECDSA, TPMS_SIGNATURE_ECDAA, TPMS_SIGNATURE_SM2,
|
||||
TPMS_SIGNATURE_ECSCHNORR, TPMU_SIGNATURE, and TPMT_TK_VERIFIED
|
||||
|
||||
* New command constants:
|
||||
TPM_CC_LoadExternal, TPM_CC_HashSequenceStart, TPM_CC_SequenceUpdate,
|
||||
TPM_CC_SequenceComplete, TPM_CC_Hash, TPM_CC_VerifySignature,
|
||||
TPM_CC_PolicyAuthorize
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
include/grub/tpm2/internal/structs.h | 86 ++++++++++++++++++++++++++++
|
||||
include/grub/tpm2/internal/types.h | 42 +++++++++-----
|
||||
2 files changed, 114 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/include/grub/tpm2/internal/structs.h b/include/grub/tpm2/internal/structs.h
|
||||
index 72d71eb70..db9eb6cf6 100644
|
||||
--- a/include/grub/tpm2/internal/structs.h
|
||||
+++ b/include/grub/tpm2/internal/structs.h
|
||||
@@ -672,4 +672,90 @@ struct TPMT_TK_CREATION
|
||||
};
|
||||
typedef struct TPMT_TK_CREATION TPMT_TK_CREATION;
|
||||
|
||||
+/* TPMS_EMPTY Structure */
|
||||
+struct TPMS_EMPTY {
|
||||
+ grub_uint8_t empty[1]; /* a structure with no member */
|
||||
+};
|
||||
+typedef struct TPMS_EMPTY TPMS_EMPTY;
|
||||
+
|
||||
+/* TPMS_SIGNATURE_RSA Structure */
|
||||
+struct TPMS_SIGNATURE_RSA {
|
||||
+ TPMI_ALG_HASH hash;
|
||||
+ TPM2B_PUBLIC_KEY_RSA sig;
|
||||
+};
|
||||
+typedef struct TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSA;
|
||||
+
|
||||
+/* Definition of Types for RSA Signature */
|
||||
+typedef TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSASSA;
|
||||
+typedef TPMS_SIGNATURE_RSA TPMS_SIGNATURE_RSAPSS;
|
||||
+
|
||||
+/* TPMS_SIGNATURE_ECC Structure */
|
||||
+struct TPMS_SIGNATURE_ECC {
|
||||
+ TPMI_ALG_HASH hash;
|
||||
+ TPM2B_ECC_PARAMETER signatureR;
|
||||
+ TPM2B_ECC_PARAMETER signatureS;
|
||||
+};
|
||||
+typedef struct TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECC;
|
||||
+
|
||||
+/* Definition of Types for ECC TPMS_SIGNATURE_ECC */
|
||||
+typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDSA;
|
||||
+typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECDAA;
|
||||
+typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_SM2;
|
||||
+typedef TPMS_SIGNATURE_ECC TPMS_SIGNATURE_ECSCHNORR;
|
||||
+
|
||||
+/* TPMU_SIGNATURE Structure */
|
||||
+union TPMU_SIGNATURE {
|
||||
+ TPMS_SIGNATURE_RSASSA rsassa;
|
||||
+ TPMS_SIGNATURE_RSAPSS rsapss;
|
||||
+ TPMS_SIGNATURE_ECDSA ecdsa;
|
||||
+ TPMS_SIGNATURE_ECDAA ecdaa;
|
||||
+ TPMS_SIGNATURE_SM2 sm2;
|
||||
+ TPMS_SIGNATURE_ECSCHNORR ecschnorr;
|
||||
+ TPMT_HA hmac;
|
||||
+ TPMS_SCHEME_HASH any;
|
||||
+ TPMS_EMPTY null;
|
||||
+};
|
||||
+typedef union TPMU_SIGNATURE TPMU_SIGNATURE;
|
||||
+
|
||||
+/* TPMT_SIGNATURE Structure */
|
||||
+struct TPMT_SIGNATURE {
|
||||
+ TPMI_ALG_SIG_SCHEME sigAlg;
|
||||
+ TPMU_SIGNATURE signature;
|
||||
+};
|
||||
+typedef struct TPMT_SIGNATURE TPMT_SIGNATURE;
|
||||
+
|
||||
+static inline TPMI_ALG_HASH
|
||||
+TPMT_SIGNATURE_get_hash_alg (TPMT_SIGNATURE *sig)
|
||||
+{
|
||||
+ switch (sig->sigAlg)
|
||||
+ {
|
||||
+ case TPM_ALG_RSASSA:
|
||||
+ return sig->signature.rsassa.hash;
|
||||
+ case TPM_ALG_RSAPSS:
|
||||
+ return sig->signature.rsapss.hash;
|
||||
+ case TPM_ALG_ECDSA:
|
||||
+ return sig->signature.ecdsa.hash;
|
||||
+ case TPM_ALG_ECDAA:
|
||||
+ return sig->signature.ecdaa.hash;
|
||||
+ case TPM_ALG_SM2:
|
||||
+ return sig->signature.sm2.hash;
|
||||
+ case TPM_ALG_ECSCHNORR:
|
||||
+ return sig->signature.ecschnorr.hash;
|
||||
+ case TPM_ALG_HMAC:
|
||||
+ return sig->signature.hmac.hashAlg;
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ return TPM_ALG_NULL;
|
||||
+}
|
||||
+
|
||||
+/* TPMT_TK_VERIFIED Structure */
|
||||
+struct TPMT_TK_VERIFIED {
|
||||
+ TPM_ST tag;
|
||||
+ TPMI_RH_HIERARCHY hierarchy;
|
||||
+ TPM2B_DIGEST digest;
|
||||
+};
|
||||
+typedef struct TPMT_TK_VERIFIED TPMT_TK_VERIFIED;
|
||||
+
|
||||
#endif /* ! GRUB_TPM2_INTERNAL_STRUCTS_HEADER */
|
||||
diff --git a/include/grub/tpm2/internal/types.h b/include/grub/tpm2/internal/types.h
|
||||
index 9714f75d4..a1902ef0c 100644
|
||||
--- a/include/grub/tpm2/internal/types.h
|
||||
+++ b/include/grub/tpm2/internal/types.h
|
||||
@@ -181,6 +181,9 @@ typedef grub_uint16_t TPM_ALG_ID;
|
||||
#define TPM_ALG_CFB ((TPM_ALG_ID) 0x0043)
|
||||
#define TPM_ALG_ECB ((TPM_ALG_ID) 0x0044)
|
||||
#define TPM_ALG_ECC ((TPM_ALG_ID) 0x0023)
|
||||
+#define TPM_ALG_ECDAA ((TPM_ALG_ID) 0x001A)
|
||||
+#define TPM_ALG_ECDSA ((TPM_ALG_ID) 0x0018)
|
||||
+#define TPM_ALG_ECSCHNORR ((TPM_ALG_ID) 0x001C)
|
||||
#define TPM_ALG_HMAC ((TPM_ALG_ID) 0x0005)
|
||||
#define TPM_ALG_KDF1_SP800_108 ((TPM_ALG_ID) 0x0022)
|
||||
#define TPM_ALG_KDF1_SP800_56A ((TPM_ALG_ID) 0x0020)
|
||||
@@ -189,10 +192,13 @@ typedef grub_uint16_t TPM_ALG_ID;
|
||||
#define TPM_ALG_MGF1 ((TPM_ALG_ID) 0x0007)
|
||||
#define TPM_ALG_NULL ((TPM_ALG_ID) 0x0010)
|
||||
#define TPM_ALG_RSA ((TPM_ALG_ID) 0x0001)
|
||||
+#define TPM_ALG_RSASSA ((TPM_ALG_ID) 0x0014)
|
||||
+#define TPM_ALG_RSAPSS ((TPM_ALG_ID) 0x0016)
|
||||
#define TPM_ALG_SHA1 ((TPM_ALG_ID) 0x0004)
|
||||
#define TPM_ALG_SHA256 ((TPM_ALG_ID) 0x000B)
|
||||
#define TPM_ALG_SHA384 ((TPM_ALG_ID) 0x000C)
|
||||
#define TPM_ALG_SHA512 ((TPM_ALG_ID) 0x000D)
|
||||
+#define TPM_ALG_SM2 ((TPM_ALG_ID) 0x001B)
|
||||
#define TPM_ALG_SM3_256 ((TPM_ALG_ID) 0x0012)
|
||||
#define TPM_ALG_SM4 ((TPM_ALG_ID) 0x0013)
|
||||
#define TPM_ALG_SYMCIPHER ((TPM_ALG_ID) 0x0025)
|
||||
@@ -299,20 +305,27 @@ typedef grub_uint16_t TPM2_ECC_CURVE;
|
||||
/* TPM_CC Constants */
|
||||
typedef grub_uint32_t TPM_CC;
|
||||
|
||||
-#define TPM_CC_EvictControl ((TPM_CC) 0x00000120)
|
||||
-#define TPM_CC_CreatePrimary ((TPM_CC) 0x00000131)
|
||||
-#define TPM_CC_Create ((TPM_CC) 0x00000153)
|
||||
-#define TPM_CC_FlushContext ((TPM_CC) 0x00000165)
|
||||
-#define TPM_CC_ReadPublic ((TPM_CC) 0x00000173)
|
||||
-#define TPM_CC_StartAuthSession ((TPM_CC) 0x00000176)
|
||||
-#define TPM_CC_PolicyPCR ((TPM_CC) 0x0000017f)
|
||||
-#define TPM_CC_NV_Read ((TPM_CC) 0x0000014e)
|
||||
-#define TPM_CC_NV_ReadPublic ((TPM_CC) 0x00000169)
|
||||
-#define TPM_CC_GetCapability ((TPM_CC) 0x0000017a)
|
||||
-#define TPM_CC_PCR_Read ((TPM_CC) 0x0000017e)
|
||||
-#define TPM_CC_Load ((TPM_CC) 0x00000157)
|
||||
-#define TPM_CC_Unseal ((TPM_CC) 0x0000015e)
|
||||
-#define TPM_CC_PolicyGetDigest ((TPM_CC) 0x00000189)
|
||||
+#define TPM_CC_EvictControl ((TPM_CC) 0x00000120)
|
||||
+#define TPM_CC_CreatePrimary ((TPM_CC) 0x00000131)
|
||||
+#define TPM_CC_Create ((TPM_CC) 0x00000153)
|
||||
+#define TPM_CC_FlushContext ((TPM_CC) 0x00000165)
|
||||
+#define TPM_CC_ReadPublic ((TPM_CC) 0x00000173)
|
||||
+#define TPM_CC_StartAuthSession ((TPM_CC) 0x00000176)
|
||||
+#define TPM_CC_PolicyPCR ((TPM_CC) 0x0000017f)
|
||||
+#define TPM_CC_NV_Read ((TPM_CC) 0x0000014e)
|
||||
+#define TPM_CC_NV_ReadPublic ((TPM_CC) 0x00000169)
|
||||
+#define TPM_CC_GetCapability ((TPM_CC) 0x0000017a)
|
||||
+#define TPM_CC_PCR_Read ((TPM_CC) 0x0000017e)
|
||||
+#define TPM_CC_Load ((TPM_CC) 0x00000157)
|
||||
+#define TPM_CC_LoadExternal ((TPM_CC) 0x00000167)
|
||||
+#define TPM_CC_Unseal ((TPM_CC) 0x0000015e)
|
||||
+#define TPM_CC_PolicyGetDigest ((TPM_CC) 0x00000189)
|
||||
+#define TPM_CC_HashSequenceStart ((TPM_CC) 0x00000186)
|
||||
+#define TPM_CC_SequenceUpdate ((TPM_CC) 0x0000015c)
|
||||
+#define TPM_CC_SequenceComplete ((TPM_CC) 0x0000013e)
|
||||
+#define TPM_CC_Hash ((TPM_CC) 0x0000017d)
|
||||
+#define TPM_CC_VerifySignature ((TPM_CC) 0x00000177)
|
||||
+#define TPM_CC_PolicyAuthorize ((TPM_CC) 0x0000016a)
|
||||
|
||||
/* Hash algorithm sizes */
|
||||
#define TPM_SHA1_DIGEST_SIZE 20
|
||||
@@ -354,6 +367,7 @@ typedef TPM_ALG_ID TPMI_ALG_ECC_SCHEME;
|
||||
typedef TPM_ALG_ID TPMI_ALG_ASYM_SCHEME;
|
||||
typedef TPM_ALG_ID TPMI_ALG_RSA_SCHEME;
|
||||
typedef TPM_ALG_ID TPMI_ALG_SYM;
|
||||
+typedef TPM_ALG_ID TPMI_ALG_SIG_SCHEME;
|
||||
|
||||
/* TPM_KEY_BITS Type */
|
||||
typedef grub_uint16_t TPM_KEY_BITS;
|
||||
--
|
||||
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
|
||||
|
60
0002-AUDIT-0-http-boot-tracker-bug.patch
Normal file
60
0002-AUDIT-0-http-boot-tracker-bug.patch
Normal file
@ -0,0 +1,60 @@
|
||||
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
|
||||
@@ -31,7 +31,8 @@
|
||||
|
||||
enum
|
||||
{
|
||||
- HTTP_PORT = 80
|
||||
+ HTTP_PORT = 80,
|
||||
+ HTTP_MAX_CHUNK_SIZE = GRUB_INT_MAX
|
||||
};
|
||||
|
||||
|
||||
@@ -86,6 +87,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)
|
||||
{
|
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)
|
||||
{
|
41
0002-cryptodisk-Fallback-to-passphrase.patch
Normal file
41
0002-cryptodisk-Fallback-to-passphrase.patch
Normal file
@ -0,0 +1,41 @@
|
||||
From 7cc578baf26986c2badce998125b429a2aeb4d33 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>
|
||||
---
|
||||
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 6620fca00..cf37a0934 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1191,11 +1191,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 */
|
@ -0,0 +1,58 @@
|
||||
From 0ed2458cc4eff6d9a9199527e2a0b6d445802f94 Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Mon, 28 Aug 2023 16:32:33 +0300
|
||||
Subject: [PATCH 2/6] fs/ntfs: Fix an OOB read when reading data from the
|
||||
resident $DATA attribute
|
||||
|
||||
When reading a file containing resident data, i.e., the file data is stored in
|
||||
the $DATA attribute within the NTFS file record, not in external clusters,
|
||||
there are no checks that this resident data actually fits the corresponding
|
||||
file record segment.
|
||||
|
||||
When parsing a specially-crafted file system image, the current NTFS code will
|
||||
read the file data from an arbitrary, attacker-chosen memory offset and of
|
||||
arbitrary, attacker-chosen length.
|
||||
|
||||
This allows an attacker to display arbitrary chunks of memory, which could
|
||||
contain sensitive information like password hashes or even plain-text,
|
||||
obfuscated passwords from BS EFI variables.
|
||||
|
||||
This fix implements a check to ensure that resident data is read from the
|
||||
corresponding file record segment only.
|
||||
|
||||
Fixes: CVE-2023-4693
|
||||
|
||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/ntfs.c | 13 ++++++++++++-
|
||||
1 file changed, 12 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
||||
index c3c4db117..a68e173d8 100644
|
||||
--- a/grub-core/fs/ntfs.c
|
||||
+++ b/grub-core/fs/ntfs.c
|
||||
@@ -401,7 +401,18 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
|
||||
{
|
||||
if (ofs + len > u32at (pa, 0x10))
|
||||
return grub_error (GRUB_ERR_BAD_FS, "read out of range");
|
||||
- grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len);
|
||||
+
|
||||
+ if (u32at (pa, 0x10) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
||||
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large");
|
||||
+
|
||||
+ if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
|
||||
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
|
||||
+
|
||||
+ if (u16at (pa, 0x14) + u32at (pa, 0x10) >
|
||||
+ (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa)
|
||||
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
|
||||
+
|
||||
+ grub_memcpy (dest, pa + u16at (pa, 0x14) + ofs, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
2.42.0
|
||||
|
171
0002-fs-xfs-Fix-XFS-directory-extent-parsing.patch
Normal file
171
0002-fs-xfs-Fix-XFS-directory-extent-parsing.patch
Normal file
@ -0,0 +1,171 @@
|
||||
From 4a6a5c4a6bb2426235364be9f3698763ddcf4775 Mon Sep 17 00:00:00 2001
|
||||
From: Jon DeVree <nuxi@vault24.org>
|
||||
Date: Tue, 17 Oct 2023 23:03:47 -0400
|
||||
Subject: [PATCH 2/3] fs/xfs: Fix XFS directory extent parsing
|
||||
|
||||
The XFS directory entry parsing code has never been completely correct
|
||||
for extent based directories. The parser correctly handles the case
|
||||
where the directory is contained in a single extent, but then mistakenly
|
||||
assumes the data blocks for the multiple extent case are each identical
|
||||
to the single extent case. The difference in the format of the data
|
||||
blocks between the two cases is tiny enough that its gone unnoticed for
|
||||
a very long time.
|
||||
|
||||
A recent change introduced some additional bounds checking into the XFS
|
||||
parser. Like GRUB's existing parser, it is correct for the single extent
|
||||
case but incorrect for the multiple extent case. When parsing a directory
|
||||
with multiple extents, this new bounds checking is sometimes (but not
|
||||
always) tripped and triggers an "invalid XFS directory entry" error. This
|
||||
probably would have continued to go unnoticed but the /boot/grub/<arch>
|
||||
directory is large enough that it often has multiple extents.
|
||||
|
||||
The difference between the two cases is that when there are multiple
|
||||
extents, the data blocks do not contain a trailer nor do they contain
|
||||
any leaf information. That information is stored in a separate set of
|
||||
extents dedicated to just the leaf information. These extents come after
|
||||
the directory entry extents and are not included in the inode size. So
|
||||
the existing parser already ignores the leaf extents.
|
||||
|
||||
The only reason to read the trailer/leaf information at all is so that
|
||||
the parser can avoid misinterpreting that data as directory entries. So
|
||||
this updates the parser as follows:
|
||||
|
||||
For the single extent case the parser doesn't change much:
|
||||
1. Read the size of the leaf information from the trailer
|
||||
2. Set the end pointer for the parser to the start of the leaf
|
||||
information. (The previous bounds checking set the end pointer to the
|
||||
start of the trailer, so this is actually a small improvement.)
|
||||
3. Set the entries variable to the expected number of directory entries.
|
||||
|
||||
For the multiple extent case:
|
||||
1. Set the end pointer to the end of the block.
|
||||
2. Do not set up the entries variable. Figuring out how many entries are
|
||||
in each individual block is complex and does not seem worth it when
|
||||
it appears to be safe to just iterate over the entire block.
|
||||
|
||||
The bounds check itself was also dependent upon the faulty XFS parser
|
||||
because it accidentally used "filename + length - 1". Presumably this
|
||||
was able to pass the fuzzer because in the old parser there was always
|
||||
8 bytes of slack space between the tail pointer and the actual end of
|
||||
the block. Since this is no longer the case the bounds check needs to be
|
||||
updated to "filename + length + 1" in order to prevent a regression in
|
||||
the handling of corrupt fliesystems.
|
||||
|
||||
Notes:
|
||||
* When there is only one extent there will only ever be one block. If
|
||||
more than one block is required then XFS will always switch to holding
|
||||
leaf information in a separate extent.
|
||||
* B-tree based directories seems to be parsed properly by the same code
|
||||
that handles multiple extents. This is unlikely to ever occur within
|
||||
/boot though because its only used when there are an extremely large
|
||||
number of directory entries.
|
||||
|
||||
Fixes: ef7850c75 (fs/xfs: Fix issues found while fuzzing the XFS filesystem)
|
||||
Fixes: b2499b29c (Adds support for the XFS filesystem.)
|
||||
Fixes: https://savannah.gnu.org/bugs/?64376
|
||||
|
||||
Signed-off-by: Jon DeVree <nuxi@vault24.org>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
Tested-by: Sebastian Andrzej Siewior <sebastian@breakpoint.cc>
|
||||
Tested-by: Marta Lewandowska <mlewando@redhat.com>
|
||||
---
|
||||
grub-core/fs/xfs.c | 52 +++++++++++++++++++++++++++++++++-------------
|
||||
1 file changed, 38 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index ebf962793..18edfcff4 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -223,6 +223,12 @@ struct grub_xfs_inode
|
||||
/* Size of struct grub_xfs_inode v2, up to unused4 member included. */
|
||||
#define XFS_V2_INODE_SIZE (XFS_V3_INODE_SIZE - 76)
|
||||
|
||||
+struct grub_xfs_dir_leaf_entry
|
||||
+{
|
||||
+ grub_uint32_t hashval;
|
||||
+ grub_uint32_t address;
|
||||
+} GRUB_PACKED;
|
||||
+
|
||||
struct grub_xfs_dirblock_tail
|
||||
{
|
||||
grub_uint32_t leaf_count;
|
||||
@@ -874,9 +880,8 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
{
|
||||
struct grub_xfs_dir2_entry *direntry =
|
||||
grub_xfs_first_de(dir->data, dirblock);
|
||||
- int entries;
|
||||
- struct grub_xfs_dirblock_tail *tail =
|
||||
- grub_xfs_dir_tail(dir->data, dirblock);
|
||||
+ int entries = -1;
|
||||
+ char *end = dirblock + dirblk_size;
|
||||
|
||||
numread = grub_xfs_read_file (dir, 0, 0,
|
||||
blk << dirblk_log2,
|
||||
@@ -887,14 +892,27 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
return 0;
|
||||
}
|
||||
|
||||
- entries = (grub_be_to_cpu32 (tail->leaf_count)
|
||||
- - grub_be_to_cpu32 (tail->leaf_stale));
|
||||
+ /*
|
||||
+ * Leaf and tail information are only in the data block if the number
|
||||
+ * of extents is 1.
|
||||
+ */
|
||||
+ 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);
|
||||
|
||||
- if (!entries)
|
||||
- continue;
|
||||
+ entries = grub_be_to_cpu32 (tail->leaf_count) - grub_be_to_cpu32 (tail->leaf_stale);
|
||||
+
|
||||
+ if (!entries)
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
/* Iterate over all entries within this block. */
|
||||
- while ((char *)direntry < (char *)tail)
|
||||
+ while ((char *) direntry < (char *) end)
|
||||
{
|
||||
grub_uint8_t *freetag;
|
||||
char *filename;
|
||||
@@ -914,7 +932,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
}
|
||||
|
||||
filename = (char *)(direntry + 1);
|
||||
- if (filename + direntry->len - 1 > (char *) tail)
|
||||
+ if (filename + direntry->len + 1 > (char *) end)
|
||||
return grub_error (GRUB_ERR_BAD_FS, "invalid XFS directory entry");
|
||||
|
||||
/* The byte after the filename is for the filetype, padding, or
|
||||
@@ -928,11 +946,17 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
return 1;
|
||||
}
|
||||
|
||||
- /* Check if last direntry in this block is
|
||||
- reached. */
|
||||
- entries--;
|
||||
- if (!entries)
|
||||
- break;
|
||||
+ /*
|
||||
+ * The expected number of directory entries is only tracked for the
|
||||
+ * single extent case.
|
||||
+ */
|
||||
+ if (dir->inode.nextents == grub_cpu_to_be32_compile_time (1))
|
||||
+ {
|
||||
+ /* Check if last direntry in this block is reached. */
|
||||
+ entries--;
|
||||
+ if (!entries)
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
/* Select the next directory entry. */
|
||||
direntry = grub_xfs_next_de(dir->data, direntry);
|
||||
--
|
||||
2.42.1
|
||||
|
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);
|
@ -0,0 +1,75 @@
|
||||
From bb9bbe0f66a8462a1b2477fbc2aa1d70973035d4 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Chang <mchang@suse.com>
|
||||
Date: Thu, 30 Nov 2023 16:30:45 +0800
|
||||
Subject: [PATCH 2/2] mkstandalone: ensure deterministic tar file creation by
|
||||
sorting contents
|
||||
|
||||
The add_tar_files() function currently iterates through a directory's
|
||||
content using readdir(), which doesn't guarantee a specific order. This
|
||||
lack of deterministic behavior impacts reproducibility in the build
|
||||
process.
|
||||
|
||||
This commit resolves the issue by introducing sorting functionality. The
|
||||
list retrieved by readdir() is now sorted alphabetically before
|
||||
incorporation into the tar archive, ensuring consistent and predictable
|
||||
file ordering within the archive.
|
||||
|
||||
Signed-off-by: Michael Chang <mchang@suse.com>
|
||||
Signed-off-by: Bernhard Wiedemann <bwiedemann@suse.com>
|
||||
---
|
||||
util/grub-mkstandalone.c | 26 +++++++++++++++++++++++---
|
||||
1 file changed, 23 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/util/grub-mkstandalone.c b/util/grub-mkstandalone.c
|
||||
index 8e1229925..e4b5bcab4 100644
|
||||
--- a/util/grub-mkstandalone.c
|
||||
+++ b/util/grub-mkstandalone.c
|
||||
@@ -205,22 +205,42 @@ add_tar_file (const char *from,
|
||||
{
|
||||
grub_util_fd_dir_t d;
|
||||
grub_util_fd_dirent_t de;
|
||||
+ char **from_files;
|
||||
+ grub_size_t alloc = 8, used = 0;
|
||||
+ grub_size_t i;
|
||||
|
||||
d = grub_util_fd_opendir (from);
|
||||
|
||||
+ from_files = xmalloc (alloc * sizeof (*from_files));
|
||||
while ((de = grub_util_fd_readdir (d)))
|
||||
{
|
||||
- char *fp, *tfp;
|
||||
if (strcmp (de->d_name, ".") == 0)
|
||||
continue;
|
||||
if (strcmp (de->d_name, "..") == 0)
|
||||
continue;
|
||||
- fp = grub_util_path_concat (2, from, de->d_name);
|
||||
- tfp = xasprintf ("%s/%s", to, de->d_name);
|
||||
+ if (alloc <= used)
|
||||
+ {
|
||||
+ alloc <<= 1;
|
||||
+ from_files = xrealloc (from_files, alloc * sizeof (*from_files));
|
||||
+ }
|
||||
+ from_files[used++] = xstrdup(de->d_name);
|
||||
+ }
|
||||
+ qsort (from_files, used, sizeof (*from_files), grub_qsort_strcmp);
|
||||
+
|
||||
+ for (i = 0; i < used; i++)
|
||||
+ {
|
||||
+ char *fp, *tfp;
|
||||
+
|
||||
+ fp = grub_util_path_concat (2, from, from_files[i]);
|
||||
+ tfp = xasprintf ("%s/%s", to, from_files[i]);
|
||||
add_tar_file (fp, tfp);
|
||||
+ free (tfp);
|
||||
free (fp);
|
||||
+ free (from_files[i]);
|
||||
}
|
||||
+
|
||||
grub_util_fd_closedir (d);
|
||||
+ free (from_files);
|
||||
free (tcn);
|
||||
return;
|
||||
}
|
||||
--
|
||||
2.43.0
|
||||
|
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."));
|
3569
0002-tpm2-Add-TPM-Software-Stack-TSS.patch
Normal file
3569
0002-tpm2-Add-TPM-Software-Stack-TSS.patch
Normal file
File diff suppressed because it is too large
Load Diff
427
0002-tpm2-Add-more-marshal-unmarshal-functions.patch
Normal file
427
0002-tpm2-Add-more-marshal-unmarshal-functions.patch
Normal file
@ -0,0 +1,427 @@
|
||||
From 1d34522075949581ccb34a08dd73607566517824 Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Tue, 7 Feb 2023 18:33:42 +0800
|
||||
Subject: [PATCH 2/4] tpm2: Add more marshal/unmarshal functions
|
||||
|
||||
Add a few more marshal/unmarshal functions to support authorized policy.
|
||||
|
||||
* Marshal:
|
||||
grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal()
|
||||
grub_tpm2_mu_TPMT_SENSITIVE_Marshal()
|
||||
grub_tpm2_mu_TPM2B_SENSITIVE_Marshal()
|
||||
grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal()
|
||||
grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal()
|
||||
grub_tpm2_mu_TPMU_HA_Marshal()
|
||||
grub_tpm2_mu_TPMT_HA_Marshal()
|
||||
grub_tpm2_mu_TPMU_SIGNATURE_Marshal()
|
||||
grub_tpm2_mu_TPMT_SIGNATURE_Marshal()
|
||||
grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal()
|
||||
|
||||
* Unmarshal:
|
||||
grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal()
|
||||
grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal()
|
||||
grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal()
|
||||
grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal()
|
||||
grub_tpm2_mu_TPMU_HA_Unmarshal()
|
||||
grub_tpm2_mu_TPMT_HA_Unmarshal()
|
||||
grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal()
|
||||
grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal()
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/tpm2/mu.c | 262 +++++++++++++++++++++++++++++++++++++++++
|
||||
include/grub/tpm2/mu.h | 75 ++++++++++++
|
||||
2 files changed, 337 insertions(+)
|
||||
|
||||
diff --git a/grub-core/tpm2/mu.c b/grub-core/tpm2/mu.c
|
||||
index 1617f37cd..3a9a3c1be 100644
|
||||
--- a/grub-core/tpm2/mu.c
|
||||
+++ b/grub-core/tpm2/mu.c
|
||||
@@ -383,6 +383,49 @@ grub_tpm2_mu_TPMS_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
|
||||
grub_tpm2_mu_TPM2B_Marshal (buffer, p->data.size, p->data.buffer);
|
||||
}
|
||||
|
||||
+void
|
||||
+grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPMI_ALG_PUBLIC type,
|
||||
+ const TPMU_SENSITIVE_COMPOSITE *p)
|
||||
+{
|
||||
+ switch(type)
|
||||
+ {
|
||||
+ case TPM_ALG_RSA:
|
||||
+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->rsa.size, p->rsa.buffer);
|
||||
+ break;
|
||||
+ case TPM_ALG_ECC:
|
||||
+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->ecc.size, p->ecc.buffer);
|
||||
+ break;
|
||||
+ case TPM_ALG_KEYEDHASH:
|
||||
+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->bits.size, p->bits.buffer);
|
||||
+ break;
|
||||
+ case TPM_ALG_SYMCIPHER:
|
||||
+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->sym.size, p->sym.buffer);
|
||||
+ break;
|
||||
+ default:
|
||||
+ buffer->error = 1;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPMT_SENSITIVE *p)
|
||||
+{
|
||||
+ grub_tpm2_buffer_pack_u16 (buffer, p->sensitiveType);
|
||||
+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->authValue.size, p->authValue.buffer);
|
||||
+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->seedValue.size, p->seedValue.buffer);
|
||||
+ grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (buffer, p->sensitiveType,
|
||||
+ &p->sensitive);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPM2B_SENSITIVE *p)
|
||||
+{
|
||||
+ grub_tpm2_buffer_pack_u16 (buffer, p->size);
|
||||
+ grub_tpm2_mu_TPMT_SENSITIVE_Marshal (buffer, &p->sensitiveArea);
|
||||
+}
|
||||
+
|
||||
void
|
||||
grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
|
||||
const TPM2B_SENSITIVE_CREATE *sensitiveCreate)
|
||||
@@ -405,6 +448,113 @@ grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buffer,
|
||||
grub_tpm2_buffer_pack_u16 (buffer, 0);
|
||||
}
|
||||
|
||||
+void
|
||||
+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPMS_SIGNATURE_RSA *p)
|
||||
+{
|
||||
+ grub_tpm2_buffer_pack_u16 (buffer, p->hash);
|
||||
+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->sig.size, p->sig.buffer);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPMS_SIGNATURE_ECC *p)
|
||||
+{
|
||||
+ grub_tpm2_buffer_pack_u16 (buffer, p->hash);
|
||||
+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->signatureR.size, p->signatureR.buffer);
|
||||
+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->signatureS.size, p->signatureS.buffer);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMU_HA_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPMI_ALG_HASH hashAlg,
|
||||
+ const TPMU_HA *p)
|
||||
+{
|
||||
+ switch (hashAlg)
|
||||
+ {
|
||||
+ case TPM_ALG_SHA1:
|
||||
+ for (grub_uint16_t i = 0; i < TPM_SHA1_DIGEST_SIZE; i++)
|
||||
+ grub_tpm2_buffer_pack_u8 (buffer, p->sha1[i]);
|
||||
+ break;
|
||||
+ case TPM_ALG_SHA256:
|
||||
+ for (grub_uint16_t i = 0; i < TPM_SHA256_DIGEST_SIZE; i++)
|
||||
+ grub_tpm2_buffer_pack_u8 (buffer, p->sha256[i]);
|
||||
+ break;
|
||||
+ case TPM_ALG_SHA384:
|
||||
+ for (grub_uint16_t i = 0; i < TPM_SHA384_DIGEST_SIZE; i++)
|
||||
+ grub_tpm2_buffer_pack_u8 (buffer, p->sha384[i]);
|
||||
+ break;
|
||||
+ case TPM_ALG_SHA512:
|
||||
+ for (grub_uint16_t i = 0; i < TPM_SHA512_DIGEST_SIZE; i++)
|
||||
+ grub_tpm2_buffer_pack_u8 (buffer, p->sha512[i]);
|
||||
+ break;
|
||||
+ default:
|
||||
+ buffer->error = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_HA_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPMT_HA *p)
|
||||
+{
|
||||
+ grub_tpm2_buffer_pack_u16 (buffer, p->hashAlg);
|
||||
+ grub_tpm2_mu_TPMU_HA_Marshal (buffer, p->hashAlg, &p->digest);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPMI_ALG_SIG_SCHEME sigAlg,
|
||||
+ const TPMU_SIGNATURE *p)
|
||||
+{
|
||||
+ switch (sigAlg)
|
||||
+ {
|
||||
+ case TPM_ALG_RSASSA:
|
||||
+ grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsassa);
|
||||
+ break;
|
||||
+ case TPM_ALG_RSAPSS:
|
||||
+ grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsapss);
|
||||
+ break;
|
||||
+ case TPM_ALG_ECDSA:
|
||||
+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdsa);
|
||||
+ break;
|
||||
+ case TPM_ALG_ECDAA:
|
||||
+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdaa);
|
||||
+ break;
|
||||
+ case TPM_ALG_SM2:
|
||||
+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->sm2);
|
||||
+ break;
|
||||
+ case TPM_ALG_ECSCHNORR:
|
||||
+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecschnorr);
|
||||
+ break;
|
||||
+ case TPM_ALG_HMAC:
|
||||
+ grub_tpm2_mu_TPMT_HA_Marshal (buffer, &p->hmac);
|
||||
+ break;
|
||||
+ case TPM_ALG_NULL:
|
||||
+ break;
|
||||
+ default:
|
||||
+ buffer->error = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPMT_SIGNATURE *p)
|
||||
+{
|
||||
+ grub_tpm2_buffer_pack_u16 (buffer, p->sigAlg);
|
||||
+ grub_tpm2_mu_TPMU_SIGNATURE_Marshal (buffer, p->sigAlg, &p->signature);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buffer,
|
||||
+ const TPMT_TK_VERIFIED *p)
|
||||
+{
|
||||
+ grub_tpm2_buffer_pack_u16 (buffer, p->tag);
|
||||
+ grub_tpm2_buffer_pack_u32 (buffer, p->hierarchy);
|
||||
+ grub_tpm2_mu_TPM2B_Marshal (buffer, p->digest.size, p->digest.buffer);
|
||||
+}
|
||||
+
|
||||
void
|
||||
grub_tpm2_mu_TPM2B_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
TPM2B* p)
|
||||
@@ -775,6 +925,24 @@ grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->digest);
|
||||
}
|
||||
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
+ TPMT_TK_HASHCHECK *p)
|
||||
+{
|
||||
+ grub_tpm2_buffer_unpack_u16 (buffer, &p->tag);
|
||||
+ grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy);
|
||||
+ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->digest);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
+ TPMT_TK_VERIFIED *p)
|
||||
+{
|
||||
+ grub_tpm2_buffer_unpack_u16 (buffer, &p->tag);
|
||||
+ grub_tpm2_buffer_unpack_u32 (buffer, &p->hierarchy);
|
||||
+ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*) &p->digest);
|
||||
+}
|
||||
+
|
||||
void
|
||||
grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
TPMS_PCR_SELECTION* pcrSelection)
|
||||
@@ -805,3 +973,97 @@ grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
for (grub_uint32_t i = 0; i < digest->count; i++)
|
||||
grub_tpm2_mu_TPM2B_DIGEST_Unmarshal (buf, &digest->digests[i]);
|
||||
}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
+ TPMS_SIGNATURE_RSA *rsa)
|
||||
+{
|
||||
+ grub_tpm2_buffer_unpack_u16 (buffer, &rsa->hash);
|
||||
+ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*)&rsa->sig);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
+ TPMS_SIGNATURE_ECC *ecc)
|
||||
+{
|
||||
+ grub_tpm2_buffer_unpack_u16 (buffer, &ecc->hash);
|
||||
+ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*)&ecc->signatureR);
|
||||
+ grub_tpm2_mu_TPM2B_Unmarshal (buffer, (TPM2B*)&ecc->signatureS);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
+ TPMI_ALG_HASH hashAlg,
|
||||
+ TPMU_HA *p)
|
||||
+{
|
||||
+ switch (hashAlg)
|
||||
+ {
|
||||
+ case TPM_ALG_SHA1:
|
||||
+ grub_tpm2_buffer_unpack (buffer, &p->sha1, TPM_SHA1_DIGEST_SIZE);
|
||||
+ break;
|
||||
+ case TPM_ALG_SHA256:
|
||||
+ grub_tpm2_buffer_unpack (buffer, &p->sha256, TPM_SHA256_DIGEST_SIZE);
|
||||
+ break;
|
||||
+ case TPM_ALG_SHA384:
|
||||
+ grub_tpm2_buffer_unpack (buffer, &p->sha384, TPM_SHA384_DIGEST_SIZE);
|
||||
+ break;
|
||||
+ case TPM_ALG_SHA512:
|
||||
+ grub_tpm2_buffer_unpack (buffer, &p->sha512, TPM_SHA512_DIGEST_SIZE);
|
||||
+ break;
|
||||
+ default:
|
||||
+ buffer->error = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
+ TPMT_HA *p)
|
||||
+{
|
||||
+ grub_tpm2_buffer_unpack_u16 (buffer, &p->hashAlg);
|
||||
+ grub_tpm2_mu_TPMU_HA_Unmarshal (buffer, p->hashAlg, &p->digest);
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
+ TPMI_ALG_SIG_SCHEME sigAlg,
|
||||
+ TPMU_SIGNATURE *p)
|
||||
+{
|
||||
+ switch (sigAlg)
|
||||
+ {
|
||||
+ case TPM_ALG_RSASSA:
|
||||
+ grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsassa);
|
||||
+ break;
|
||||
+ case TPM_ALG_RSAPSS:
|
||||
+ grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (buffer, (TPMS_SIGNATURE_RSA *)&p->rsapss);
|
||||
+ break;
|
||||
+ case TPM_ALG_ECDSA:
|
||||
+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdsa);
|
||||
+ break;
|
||||
+ case TPM_ALG_ECDAA:
|
||||
+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecdaa);
|
||||
+ break;
|
||||
+ case TPM_ALG_SM2:
|
||||
+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->sm2);
|
||||
+ break;
|
||||
+ case TPM_ALG_ECSCHNORR:
|
||||
+ grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (buffer, (TPMS_SIGNATURE_ECC *)&p->ecschnorr);
|
||||
+ break;
|
||||
+ case TPM_ALG_HMAC:
|
||||
+ grub_tpm2_mu_TPMT_HA_Unmarshal (buffer, &p->hmac);
|
||||
+ break;
|
||||
+ case TPM_ALG_NULL:
|
||||
+ break;
|
||||
+ default:
|
||||
+ buffer->error = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buffer,
|
||||
+ TPMT_SIGNATURE *p)
|
||||
+{
|
||||
+ grub_tpm2_buffer_unpack_u16 (buffer, &p->sigAlg);
|
||||
+ grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (buffer, p->sigAlg, &p->signature);
|
||||
+}
|
||||
diff --git a/include/grub/tpm2/mu.h b/include/grub/tpm2/mu.h
|
||||
index c545976db..afb842ab5 100644
|
||||
--- a/include/grub/tpm2/mu.h
|
||||
+++ b/include/grub/tpm2/mu.h
|
||||
@@ -147,6 +147,47 @@ grub_tpm2_mu_TPM2B_SENSITIVE_CREATE_Marshal (grub_tpm2_buffer_t buf,
|
||||
const TPM2B_SENSITIVE_CREATE *sensitiveCreate);
|
||||
|
||||
void
|
||||
+grub_tpm2_mu_TPMU_SENSITIVE_COMPOSITE_Marshal (grub_tpm2_buffer_t buf,
|
||||
+ const TPMI_ALG_PUBLIC type,
|
||||
+ const TPMU_SENSITIVE_COMPOSITE *p);
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_SENSITIVE_Marshal (grub_tpm2_buffer_t buf,
|
||||
+ const TPMT_SENSITIVE *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (grub_tpm2_buffer_t buf,
|
||||
+ const TPM2B_SENSITIVE *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Marshal (grub_tpm2_buffer_t buf,
|
||||
+ const TPMS_SIGNATURE_RSA *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMS_SIGNATURE_ECC_Marshal (grub_tpm2_buffer_t buf,
|
||||
+ const TPMS_SIGNATURE_ECC *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMU_HA_Marshal (grub_tpm2_buffer_t buf,
|
||||
+ const TPMI_ALG_HASH hashAlg,
|
||||
+ const TPMU_HA *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_HA_Marshal (grub_tpm2_buffer_t buf,
|
||||
+ const TPMT_HA *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMU_SIGNATURE_Marshal (grub_tpm2_buffer_t buf,
|
||||
+ const TPMI_ALG_SIG_SCHEME sigAlg,
|
||||
+ const TPMU_SIGNATURE *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_SIGNATURE_Marshal (grub_tpm2_buffer_t buf,
|
||||
+ const TPMT_SIGNATURE *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_TK_VERIFIED_Marshal (grub_tpm2_buffer_t buf,
|
||||
+ const TPMT_TK_VERIFIED *p);
|
||||
+void
|
||||
grub_tpm2_mu_TPM2B_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
TPM2B* p);
|
||||
|
||||
@@ -277,6 +318,14 @@ void
|
||||
grub_tpm2_mu_TPMT_TK_CREATION_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
TPMT_TK_CREATION *p);
|
||||
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_TK_HASHCHECK_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
+ TPMT_TK_HASHCHECK *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_TK_VERIFIED_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
+ TPMT_TK_VERIFIED *p);
|
||||
+
|
||||
void
|
||||
grub_tpm2_mu_TPMS_PCR_SELECTION_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
TPMS_PCR_SELECTION* pcrSelection);
|
||||
@@ -289,4 +338,30 @@ void
|
||||
grub_tpm2_mu_TPML_DIGEST_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
TPML_DIGEST* digest);
|
||||
|
||||
+void
|
||||
+grub_tpm2_mu_TPMS_SIGNATURE_RSA_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
+ TPMS_SIGNATURE_RSA *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMS_SIGNATURE_ECC_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
+ TPMS_SIGNATURE_ECC *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMU_HA_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
+ TPMI_ALG_HASH hashAlg,
|
||||
+ TPMU_HA *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_HA_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
+ TPMT_HA *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMU_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
+ TPMI_ALG_SIG_SCHEME sigAlg,
|
||||
+ TPMU_SIGNATURE *p);
|
||||
+
|
||||
+void
|
||||
+grub_tpm2_mu_TPMT_SIGNATURE_Unmarshal (grub_tpm2_buffer_t buf,
|
||||
+ TPMT_SIGNATURE *p);
|
||||
+
|
||||
#endif /* ! GRUB_TPM2_MU_HEADER */
|
||||
--
|
||||
2.35.3
|
||||
|
279
0003-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch
Normal file
279
0003-Handle-multi-arch-64-on-32-boot-in-linuxefi-loader.patch
Normal file
@ -0,0 +1,279 @@
|
||||
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
|
||||
@@ -138,7 +138,12 @@
|
||||
grub_uint32_t kernel_alignment;
|
||||
grub_uint8_t relocatable;
|
||||
grub_uint8_t min_alignment;
|
||||
- grub_uint8_t pad[2];
|
||||
+#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;
|
||||
grub_uint64_t hardware_subarch_data;
|
||||
--- 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,36 @@
|
||||
From 64494ffc442a5de05b237ad48d27c70d22849a44 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.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.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 cf37a0934..f42437f4e 100644
|
||||
--- a/grub-core/disk/cryptodisk.c
|
||||
+++ b/grub-core/disk/cryptodisk.c
|
||||
@@ -1348,7 +1348,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
|
||||
|
@ -0,0 +1,73 @@
|
||||
From 7e5f031a6a6a3decc2360a7b0c71abbe598e7354 Mon Sep 17 00:00:00 2001
|
||||
From: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Date: Mon, 28 Aug 2023 16:33:17 +0300
|
||||
Subject: [PATCH 3/6] fs/ntfs: Fix an OOB read when parsing directory entries
|
||||
from resident and non-resident index attributes
|
||||
|
||||
This fix introduces checks to ensure that index entries are never read
|
||||
beyond the corresponding directory index.
|
||||
|
||||
The lack of this check is a minor issue, likely not exploitable in any way.
|
||||
|
||||
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
|
||||
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||||
---
|
||||
grub-core/fs/ntfs.c | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
|
||||
index a68e173d8..2d78b96e1 100644
|
||||
--- a/grub-core/fs/ntfs.c
|
||||
+++ b/grub-core/fs/ntfs.c
|
||||
@@ -599,7 +599,7 @@ get_utf8 (grub_uint8_t *in, grub_size_t len)
|
||||
}
|
||||
|
||||
static int
|
||||
-list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
|
||||
+list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, grub_uint8_t *end_pos,
|
||||
grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
|
||||
{
|
||||
grub_uint8_t *np;
|
||||
@@ -610,6 +610,9 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
|
||||
grub_uint8_t namespace;
|
||||
char *ustr;
|
||||
|
||||
+ if ((pos >= end_pos) || (end_pos - pos < 0x52))
|
||||
+ break;
|
||||
+
|
||||
if (pos[0xC] & 2) /* end signature */
|
||||
break;
|
||||
|
||||
@@ -617,6 +620,9 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
|
||||
ns = *(np++);
|
||||
namespace = *(np++);
|
||||
|
||||
+ if (2 * ns > end_pos - pos - 0x52)
|
||||
+ break;
|
||||
+
|
||||
/*
|
||||
* Ignore files in DOS namespace, as they will reappear as Win32
|
||||
* names.
|
||||
@@ -806,7 +812,9 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
}
|
||||
|
||||
cur_pos += 0x10; /* Skip index root */
|
||||
- ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook, hook_data);
|
||||
+ ret = list_file (mft, cur_pos + u16at (cur_pos, 0),
|
||||
+ at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),
|
||||
+ hook, hook_data);
|
||||
if (ret)
|
||||
goto done;
|
||||
|
||||
@@ -893,6 +901,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
|
||||
(const grub_uint8_t *) "INDX")))
|
||||
goto done;
|
||||
ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)],
|
||||
+ indx + (mft->data->idx_size << GRUB_NTFS_BLK_SHR),
|
||||
hook, hook_data);
|
||||
if (ret)
|
||||
goto done;
|
||||
--
|
||||
2.42.0
|
||||
|
115
0003-fs-xfs-add-large-extent-counters-incompat-feature-su.patch
Normal file
115
0003-fs-xfs-add-large-extent-counters-incompat-feature-su.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From e7b1a524d5f86dcfddfbb069577e3b148dbb19cd Mon Sep 17 00:00:00 2001
|
||||
From: Anthony Iliopoulos via Grub-devel <grub-devel@gnu.org>
|
||||
Date: Thu, 26 Oct 2023 11:53:39 +0200
|
||||
Subject: [PATCH 3/3] fs/xfs: add large extent counters incompat feature
|
||||
support
|
||||
|
||||
XFS introduced 64-bit extent counters for inodes via a series of
|
||||
upstream commits, and the feature was marked as stable in v6.5 via
|
||||
commit 61d7e8274cd8 ("xfs: drop EXPERIMENTAL tag for large extent
|
||||
counts").
|
||||
|
||||
Further, xfsprogs release v6.5.0 switched this feature on by default in
|
||||
mkfs.xfs via commit e5b18d7d1d96 ("mkfs: enable large extent counts by
|
||||
default").
|
||||
|
||||
Filesystems formatted with large extent count support (nrext64=1) are
|
||||
thus currently not recognizable by grub, since this is an incompat
|
||||
feature. Add the required support so that those filesystems and inodes
|
||||
with large extent counters can be read by grub.
|
||||
|
||||
Signed-off-by: Anthony Iliopoulos <ailiop@suse.com>
|
||||
---
|
||||
grub-core/fs/xfs.c | 30 +++++++++++++++++++++++++-----
|
||||
1 file changed, 25 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
|
||||
index 18edfcff4..bc2224dbb 100644
|
||||
--- a/grub-core/fs/xfs.c
|
||||
+++ b/grub-core/fs/xfs.c
|
||||
@@ -79,6 +79,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
/* Inode flags2 flags */
|
||||
#define XFS_DIFLAG2_BIGTIME_BIT 3
|
||||
#define XFS_DIFLAG2_BIGTIME (1 << XFS_DIFLAG2_BIGTIME_BIT)
|
||||
+#define XFS_DIFLAG2_NREXT64_BIT 4
|
||||
+#define XFS_DIFLAG2_NREXT64 (1 << XFS_DIFLAG2_NREXT64_BIT)
|
||||
|
||||
/* incompat feature flags */
|
||||
#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
|
||||
@@ -86,6 +88,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
#define XFS_SB_FEAT_INCOMPAT_META_UUID (1 << 2) /* metadata UUID */
|
||||
#define XFS_SB_FEAT_INCOMPAT_BIGTIME (1 << 3) /* large timestamps */
|
||||
#define XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR (1 << 4) /* needs xfs_repair */
|
||||
+#define XFS_SB_FEAT_INCOMPAT_NREXT64 (1 << 5) /* large extent counters */
|
||||
|
||||
/*
|
||||
* Directory entries with ftype are explicitly handled by GRUB code.
|
||||
@@ -101,7 +104,8 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||
XFS_SB_FEAT_INCOMPAT_SPINODES | \
|
||||
XFS_SB_FEAT_INCOMPAT_META_UUID | \
|
||||
XFS_SB_FEAT_INCOMPAT_BIGTIME | \
|
||||
- XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR)
|
||||
+ XFS_SB_FEAT_INCOMPAT_NEEDSREPAIR | \
|
||||
+ XFS_SB_FEAT_INCOMPAT_NREXT64)
|
||||
|
||||
struct grub_xfs_sblock
|
||||
{
|
||||
@@ -203,7 +207,8 @@ struct grub_xfs_inode
|
||||
grub_uint16_t mode;
|
||||
grub_uint8_t version;
|
||||
grub_uint8_t format;
|
||||
- grub_uint8_t unused2[26];
|
||||
+ grub_uint8_t unused2[18];
|
||||
+ grub_uint64_t nextents_big;
|
||||
grub_uint64_t atime;
|
||||
grub_uint64_t mtime;
|
||||
grub_uint64_t ctime;
|
||||
@@ -545,11 +550,26 @@ get_fsb (const void *keys, int idx)
|
||||
return grub_be_to_cpu64 (grub_get_unaligned64 (p));
|
||||
}
|
||||
|
||||
+static int
|
||||
+grub_xfs_inode_has_large_extent_counts (const struct grub_xfs_inode *inode)
|
||||
+{
|
||||
+ return inode->version >= 3 &&
|
||||
+ (inode->flags2 & grub_cpu_to_be64_compile_time (XFS_DIFLAG2_NREXT64));
|
||||
+}
|
||||
+
|
||||
+static grub_uint64_t
|
||||
+grub_xfs_get_inode_nextents (struct grub_xfs_inode *inode)
|
||||
+{
|
||||
+ return (grub_xfs_inode_has_large_extent_counts (inode)) ?
|
||||
+ grub_be_to_cpu64 (inode->nextents_big) :
|
||||
+ grub_be_to_cpu32 (inode->nextents);
|
||||
+}
|
||||
+
|
||||
static grub_disk_addr_t
|
||||
grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
{
|
||||
struct grub_xfs_btree_node *leaf = 0;
|
||||
- int ex, nrec;
|
||||
+ grub_uint64_t ex, nrec;
|
||||
struct grub_xfs_extent *exts;
|
||||
grub_uint64_t ret = 0;
|
||||
|
||||
@@ -574,7 +594,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
/ (2 * sizeof (grub_uint64_t));
|
||||
do
|
||||
{
|
||||
- int i;
|
||||
+ grub_uint64_t i;
|
||||
|
||||
for (i = 0; i < nrec; i++)
|
||||
{
|
||||
@@ -621,7 +641,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
|
||||
grub_addr_t exts_end = 0;
|
||||
grub_addr_t data_end = 0;
|
||||
|
||||
- nrec = grub_be_to_cpu32 (node->inode.nextents);
|
||||
+ nrec = grub_xfs_get_inode_nextents (&node->inode);
|
||||
exts = (struct grub_xfs_extent *) grub_xfs_inode_data(&node->inode);
|
||||
|
||||
if (grub_mul (sizeof (struct grub_xfs_extent), nrec, &exts_end) ||
|
||||
--
|
||||
2.42.1
|
||||
|
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
|
||||
|
2052
0003-protectors-Add-TPM2-Key-Protector.patch
Normal file
2052
0003-protectors-Add-TPM2-Key-Protector.patch
Normal file
File diff suppressed because it is too large
Load Diff
543
0003-tpm2-Implement-more-TPM2-commands.patch
Normal file
543
0003-tpm2-Implement-more-TPM2-commands.patch
Normal file
@ -0,0 +1,543 @@
|
||||
From a49c4dcbcb04078434f461ed3356c04042be461a Mon Sep 17 00:00:00 2001
|
||||
From: Gary Lin <glin@suse.com>
|
||||
Date: Wed, 8 Feb 2023 10:30:55 +0800
|
||||
Subject: [PATCH 3/4] tpm2: Implement more TPM2 commands
|
||||
|
||||
This commit implements a few more TPM2 commands as the preparation for
|
||||
the authorized policy support.
|
||||
|
||||
* TPM2_LoadExternal
|
||||
This command is added to load the external public key to verify the
|
||||
signed policy digest
|
||||
* TPM2_HashSequenceStart, TPM2_SequenceUpdate, TPM2_SequenceComplete,
|
||||
and TPM2_Hash
|
||||
With those commands, we can use the TPM as a coprocessor to calculate
|
||||
the hash of a given binary blob.
|
||||
* TPM2_VerifySignature
|
||||
This command verifies the given signature with the given public key
|
||||
and returns the validation ticket to authorize the policy.
|
||||
* TPM2_PolicyAuthorize
|
||||
This command approves the given policy digest so that we can unseal
|
||||
the key with the newly authorized policy.
|
||||
|
||||
Signed-off-by: Gary Lin <glin@suse.com>
|
||||
---
|
||||
grub-core/tpm2/tpm2.c | 424 +++++++++++++++++++++++++
|
||||
include/grub/tpm2/internal/functions.h | 57 ++++
|
||||
2 files changed, 481 insertions(+)
|
||||
|
||||
diff --git a/grub-core/tpm2/tpm2.c b/grub-core/tpm2/tpm2.c
|
||||
index d67699a24..159353b08 100644
|
||||
--- a/grub-core/tpm2/tpm2.c
|
||||
+++ b/grub-core/tpm2/tpm2.c
|
||||
@@ -427,6 +427,73 @@ TPM2_Load (const TPMI_DH_OBJECT parent_handle,
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
|
||||
+TPM_RC
|
||||
+TPM2_LoadExternal (const TPMS_AUTH_COMMAND *authCommand,
|
||||
+ const TPM2B_SENSITIVE *inPrivate,
|
||||
+ const TPM2B_PUBLIC *inPublic,
|
||||
+ const TPMI_RH_HIERARCHY hierarchy,
|
||||
+ TPM_HANDLE *objectHandle,
|
||||
+ TPM2B_NAME *name,
|
||||
+ TPMS_AUTH_RESPONSE *authResponse)
|
||||
+{
|
||||
+ TPM_RC rc;
|
||||
+ struct grub_tpm2_buffer in;
|
||||
+ struct grub_tpm2_buffer out;
|
||||
+ TPM_HANDLE objectHandleTmp;
|
||||
+ TPM2B_NAME nameTmp;
|
||||
+ TPMS_AUTH_RESPONSE authResponseTmp;
|
||||
+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS;
|
||||
+ TPM_RC responseCode;
|
||||
+ grub_uint32_t param_size;
|
||||
+
|
||||
+ if (!inPublic)
|
||||
+ return TPM_RC_VALUE;
|
||||
+
|
||||
+ if (!objectHandle)
|
||||
+ objectHandle = &objectHandleTmp;
|
||||
+ if (!name)
|
||||
+ name = &nameTmp;
|
||||
+ if (!authResponse)
|
||||
+ authResponse = &authResponseTmp;
|
||||
+
|
||||
+ grub_memset (objectHandle, 0, sizeof (*objectHandle));
|
||||
+ grub_memset (name, 0, sizeof (*name));
|
||||
+ grub_memset (authResponse, 0, sizeof (*authResponse));
|
||||
+
|
||||
+ /* Marshal */
|
||||
+ grub_tpm2_buffer_init (&in);
|
||||
+ if (authCommand)
|
||||
+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
|
||||
+ if (inPrivate)
|
||||
+ grub_tpm2_mu_TPM2B_SENSITIVE_Marshal (&in, inPrivate);
|
||||
+ else
|
||||
+ grub_tpm2_buffer_pack_u16 (&in, 0);
|
||||
+ grub_tpm2_mu_TPM2B_PUBLIC_Marshal (&in, inPublic);
|
||||
+ grub_tpm2_buffer_pack_u32 (&in, hierarchy);
|
||||
+ if (in.error)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ /* Submit */
|
||||
+ grub_tpm2_buffer_init (&out);
|
||||
+ rc = grub_tpm2_submit_command (tag, TPM_CC_LoadExternal, &responseCode, &in, &out);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return rc;
|
||||
+ if (responseCode != TPM_RC_SUCCESS)
|
||||
+ return responseCode;
|
||||
+
|
||||
+ /* Unmarshal*/
|
||||
+ grub_tpm2_buffer_unpack_u32 (&out, objectHandle);
|
||||
+ if (tag == TPM_ST_SESSIONS)
|
||||
+ grub_tpm2_buffer_unpack_u32 (&out, ¶m_size);
|
||||
+ grub_tpm2_mu_TPM2B_Unmarshal (&out, (TPM2B*)name);
|
||||
+ if (tag == TPM_ST_SESSIONS)
|
||||
+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal (&out, authResponse);
|
||||
+ if (out.error)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ return TPM_RC_SUCCESS;
|
||||
+}
|
||||
+
|
||||
TPM_RC
|
||||
TPM2_Unseal (const TPMI_DH_OBJECT itemHandle,
|
||||
const TPMS_AUTH_COMMAND *authCommand,
|
||||
@@ -759,3 +826,360 @@ TPM2_EvictControl (const TPMI_RH_PROVISION auth,
|
||||
|
||||
return TPM_RC_SUCCESS;
|
||||
}
|
||||
+
|
||||
+TPM_RC
|
||||
+TPM2_HashSequenceStart (const TPMS_AUTH_COMMAND *authCommand,
|
||||
+ const TPM2B_AUTH *auth,
|
||||
+ const TPMI_ALG_HASH hashAlg,
|
||||
+ TPMI_DH_OBJECT *sequenceHandle,
|
||||
+ TPMS_AUTH_RESPONSE *authResponse)
|
||||
+{
|
||||
+ struct grub_tpm2_buffer in;
|
||||
+ struct grub_tpm2_buffer out;
|
||||
+ TPMI_DH_OBJECT sequenceHandleTmp;
|
||||
+ TPMS_AUTH_RESPONSE authResponseTmp;
|
||||
+ TPMI_ST_COMMAND_TAG tag = authCommand ? TPM_ST_SESSIONS : TPM_ST_NO_SESSIONS;
|
||||
+ TPM_RC responseCode;
|
||||
+ TPM_RC rc;
|
||||
+ grub_uint32_t parameterSize;
|
||||
+
|
||||
+ if (!auth)
|
||||
+ return TPM_RC_VALUE;
|
||||
+
|
||||
+ if (!sequenceHandle)
|
||||
+ sequenceHandle = &sequenceHandleTmp;
|
||||
+ if (!authResponse)
|
||||
+ authResponse = &authResponseTmp;
|
||||
+
|
||||
+ grub_memset (sequenceHandle, 0, sizeof (*sequenceHandle));
|
||||
+ grub_memset (authResponse, 0, sizeof (*authResponse));
|
||||
+
|
||||
+ /* Marshal */
|
||||
+ grub_tpm2_buffer_init (&in);
|
||||
+ if (authCommand)
|
||||
+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
|
||||
+ grub_tpm2_mu_TPM2B_Marshal (&in, auth->size, auth->buffer);
|
||||
+ grub_tpm2_buffer_pack_u16 (&in, hashAlg);
|
||||
+ if (in.error)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ /* Submit */
|
||||
+ grub_tpm2_buffer_init (&out);
|
||||
+ rc = grub_tpm2_submit_command (tag, TPM_CC_HashSequenceStart, &responseCode, &in,
|
||||
+ &out);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return rc;
|
||||
+ if (responseCode != TPM_RC_SUCCESS)
|
||||
+ return responseCode;
|
||||
+
|
||||
+ /* Unmarshal */
|
||||
+ grub_tpm2_buffer_unpack_u32 (&out, sequenceHandle);
|
||||
+ if (tag == TPM_ST_SESSIONS)
|
||||
+ {
|
||||
+ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize);
|
||||
+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse);
|
||||
+ }
|
||||
+ if (out.error)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ return TPM_RC_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+TPM_RC
|
||||
+TPM2_SequenceUpdate (const TPMI_DH_OBJECT sequenceHandle,
|
||||
+ const TPMS_AUTH_COMMAND *authCommand,
|
||||
+ const TPM2B_MAX_BUFFER *buffer,
|
||||
+ TPMS_AUTH_RESPONSE *authResponse)
|
||||
+{
|
||||
+ struct grub_tpm2_buffer in;
|
||||
+ struct grub_tpm2_buffer out;
|
||||
+ TPMS_AUTH_RESPONSE authResponseTmp;
|
||||
+ TPM_RC responseCode;
|
||||
+ TPM_RC rc;
|
||||
+ grub_uint32_t parameterSize;
|
||||
+
|
||||
+ if (!authCommand)
|
||||
+ return TPM_RC_VALUE;
|
||||
+
|
||||
+ if (!authResponse)
|
||||
+ authResponse = &authResponseTmp;
|
||||
+
|
||||
+ grub_memset (authResponse, 0, sizeof (*authResponse));
|
||||
+
|
||||
+ /* Marshal */
|
||||
+ grub_tpm2_buffer_init (&in);
|
||||
+ grub_tpm2_buffer_pack_u32 (&in, sequenceHandle);
|
||||
+ grub_tpm2_mu_TPMS_AUTH_COMMAND_Marshal (&in, authCommand);
|
||||
+ if (buffer)
|
||||
+ grub_tpm2_mu_TPM2B_Marshal (&in, buffer->size, buffer->buffer);
|
||||
+ else
|
||||
+ grub_tpm2_buffer_pack_u16 (&in, 0);
|
||||
+ if (in.error)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ /* Submit */
|
||||
+ grub_tpm2_buffer_init (&out);
|
||||
+ rc = grub_tpm2_submit_command (TPM_ST_SESSIONS, TPM_CC_SequenceUpdate,
|
||||
+ &responseCode, &in, &out);
|
||||
+ if (rc != TPM_RC_SUCCESS)
|
||||
+ return rc;
|
||||
+ if (responseCode != TPM_RC_SUCCESS)
|
||||
+ return responseCode;
|
||||
+
|
||||
+ /* Unmarshal */
|
||||
+ grub_tpm2_buffer_unpack_u32 (&out, ¶meterSize);
|
||||
+ grub_tpm2_mu_TPMS_AUTH_RESPONSE_Unmarshal(&out, authResponse);
|
||||
+ if (out.error)
|
||||
+ return TPM_RC_FAILURE;
|
||||
+
|
||||
+ return TPM_RC_SUCCESS;
|
||||
+}
|
||||
+
|
||||
+TPM_RC
|
||||
+TPM2_SequenceComplete (const TPMI_DH_OBJECT sequenceHandle,
|
||||
+ const TPMS_AUTH_COMMAND *authCommand,
|
||||
+ const TPM2B_MAX_BUFFER *buffer,
|
||||
+ const TPMI_RH_HIERARCHY hierarchy,
|
||||
+ TPM2B_DIGEST *result,
|
||||
+ TPMT_TK_HASHCHECK *validation,
|
||||
+ TPMS_AUTH_RESPONSE *authResponse)
|
||||
+{
|
||||
+ struct grub_tpm2_buffer in;
|
||||
+ struct grub_tpm2_buffer out;
|
||||
+ TPM2B_DIGEST resultTmp;
|
||||
+ TPMT_TK_HASHCHECK validationTmp;
|
||||
+ TPMS_AUTH_RESPONSE authResponseTmp;
|
||||
+ TPM_RC responseCode;
|
||||
+ TPM_RC rc;
|
||||